mirror of
https://github.com/samba-team/samba.git
synced 2025-01-12 09:18:10 +03:00
This puts real netlogon connection caching to winbind. This becomes
important once we start doing schannel, as there would be a lot more roundtrips for the second PIPE open and bind. With this patch logging in to a member server is a matter of two (three if you count the ack...) packets between us and the DC. Volker
This commit is contained in:
parent
9abe3b2383
commit
5b3cb7725a
@ -130,7 +130,6 @@ static NTSTATUS connect_to_domain_password_server(struct cli_state **cli,
|
|||||||
struct in_addr dest_ip;
|
struct in_addr dest_ip;
|
||||||
fstring remote_machine;
|
fstring remote_machine;
|
||||||
NTSTATUS result;
|
NTSTATUS result;
|
||||||
uint32 neg_flags = 0x000001ff;
|
|
||||||
|
|
||||||
*retry = False;
|
*retry = False;
|
||||||
|
|
||||||
@ -214,7 +213,7 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(*cli)));
|
|||||||
return NT_STATUS_NO_MEMORY;
|
return NT_STATUS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = cli_nt_setup_creds(*cli, sec_chan, trust_passwd, &neg_flags, 2);
|
result = cli_nt_establish_netlogon(*cli, sec_chan, trust_passwd);
|
||||||
|
|
||||||
if (!NT_STATUS_IS_OK(result)) {
|
if (!NT_STATUS_IS_OK(result)) {
|
||||||
DEBUG(0,("connect_to_domain_password_server: unable to setup the NETLOGON credentials to machine \
|
DEBUG(0,("connect_to_domain_password_server: unable to setup the NETLOGON credentials to machine \
|
||||||
@ -341,6 +340,7 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
nt_status = cli_netlogon_sam_network_logon(cli, mem_ctx,
|
nt_status = cli_netlogon_sam_network_logon(cli, mem_ctx,
|
||||||
|
NULL,
|
||||||
user_info->smb_name.str, user_info->domain.str,
|
user_info->smb_name.str, user_info->domain.str,
|
||||||
user_info->wksta_name.str, chal,
|
user_info->wksta_name.str, chal,
|
||||||
user_info->lm_resp, user_info->nt_resp,
|
user_info->lm_resp, user_info->nt_resp,
|
||||||
|
@ -704,7 +704,7 @@ success:
|
|||||||
Resolve via "lmhosts" method.
|
Resolve via "lmhosts" method.
|
||||||
*********************************************************/
|
*********************************************************/
|
||||||
|
|
||||||
static BOOL resolve_lmhosts(const char *name, int name_type,
|
BOOL resolve_lmhosts(const char *name, int name_type,
|
||||||
struct in_addr **return_iplist, int *return_count)
|
struct in_addr **return_iplist, int *return_count)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -415,21 +415,19 @@ static NTSTATUS cm_open_connection(const char *domain, const int pipe_index,
|
|||||||
static BOOL connection_ok(struct winbindd_cm_conn *conn)
|
static BOOL connection_ok(struct winbindd_cm_conn *conn)
|
||||||
{
|
{
|
||||||
if (!conn) {
|
if (!conn) {
|
||||||
smb_panic("Invalid paramater passed to conneciton_ok(): conn was NULL!\n");
|
smb_panic("Invalid parameter passed to connection_ok(): conn was NULL!\n");
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!conn->cli) {
|
if (!conn->cli) {
|
||||||
DEBUG(0, ("Connection to %s for domain %s (pipe %s) has NULL conn->cli!\n",
|
DEBUG(3, ("Connection to %s for domain %s (pipe %s) has NULL conn->cli!\n",
|
||||||
conn->controller, conn->domain, conn->pipe_name));
|
conn->controller, conn->domain, conn->pipe_name));
|
||||||
smb_panic("connection_ok: conn->cli was null!");
|
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!conn->cli->initialised) {
|
if (!conn->cli->initialised) {
|
||||||
DEBUG(0, ("Connection to %s for domain %s (pipe %s) was never initialised!\n",
|
DEBUG(3, ("Connection to %s for domain %s (pipe %s) was never initialised!\n",
|
||||||
conn->controller, conn->domain, conn->pipe_name));
|
conn->controller, conn->domain, conn->pipe_name));
|
||||||
smb_panic("connection_ok: conn->cli->initialised is False!");
|
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -442,13 +440,13 @@ static BOOL connection_ok(struct winbindd_cm_conn *conn)
|
|||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get a connection to the remote DC and open the pipe. If there is already a connection, use that */
|
/* Search the cache for a connection. If there is a broken one,
|
||||||
|
shut it down properly and return NULL. */
|
||||||
|
|
||||||
static NTSTATUS get_connection_from_cache(const char *domain, const char *pipe_name,
|
static void find_cm_connection(const char *domain, const char *pipe_name,
|
||||||
struct winbindd_cm_conn **conn_out)
|
struct winbindd_cm_conn **conn_out)
|
||||||
{
|
{
|
||||||
struct winbindd_cm_conn *conn, conn_temp;
|
struct winbindd_cm_conn *conn, conn_temp;
|
||||||
NTSTATUS result;
|
|
||||||
|
|
||||||
for (conn = cm_conns; conn; conn = conn->next) {
|
for (conn = cm_conns; conn; conn = conn->next) {
|
||||||
if (strequal(conn->domain, domain) &&
|
if (strequal(conn->domain, domain) &&
|
||||||
@ -467,7 +465,17 @@ static NTSTATUS get_connection_from_cache(const char *domain, const char *pipe_n
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!conn) {
|
*conn_out = conn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize a new connection up to the RPC BIND. */
|
||||||
|
|
||||||
|
static NTSTATUS new_cm_connection(const char *domain, const char *pipe_name,
|
||||||
|
struct winbindd_cm_conn **conn_out)
|
||||||
|
{
|
||||||
|
struct winbindd_cm_conn *conn;
|
||||||
|
NTSTATUS result;
|
||||||
|
|
||||||
if (!(conn = malloc(sizeof(*conn))))
|
if (!(conn = malloc(sizeof(*conn))))
|
||||||
return NT_STATUS_NO_MEMORY;
|
return NT_STATUS_NO_MEMORY;
|
||||||
|
|
||||||
@ -480,12 +488,23 @@ static NTSTATUS get_connection_from_cache(const char *domain, const char *pipe_n
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
DLIST_ADD(cm_conns, conn);
|
DLIST_ADD(cm_conns, conn);
|
||||||
}
|
|
||||||
|
|
||||||
*conn_out = conn;
|
*conn_out = conn;
|
||||||
return NT_STATUS_OK;
|
return NT_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get a connection to the remote DC and open the pipe. If there is already a connection, use that */
|
||||||
|
|
||||||
|
static NTSTATUS get_connection_from_cache(const char *domain, const char *pipe_name,
|
||||||
|
struct winbindd_cm_conn **conn_out)
|
||||||
|
{
|
||||||
|
find_cm_connection(domain, pipe_name, conn_out);
|
||||||
|
|
||||||
|
if (conn_out != NULL)
|
||||||
|
return NT_STATUS_OK;
|
||||||
|
|
||||||
|
return new_cm_connection(domain, pipe_name, conn_out);
|
||||||
|
}
|
||||||
|
|
||||||
/**********************************************************************************
|
/**********************************************************************************
|
||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
@ -856,11 +875,11 @@ CLI_POLICY_HND *cm_get_sam_group_handle(char *domain, DOM_SID *domain_sid,
|
|||||||
NTSTATUS cm_get_netlogon_cli(const char *domain,
|
NTSTATUS cm_get_netlogon_cli(const char *domain,
|
||||||
const unsigned char *trust_passwd,
|
const unsigned char *trust_passwd,
|
||||||
uint32 sec_channel_type,
|
uint32 sec_channel_type,
|
||||||
|
BOOL fresh,
|
||||||
struct cli_state **cli)
|
struct cli_state **cli)
|
||||||
{
|
{
|
||||||
NTSTATUS result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
|
NTSTATUS result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
|
||||||
struct winbindd_cm_conn *conn;
|
struct winbindd_cm_conn *conn;
|
||||||
uint32 neg_flags = 0x000001ff;
|
|
||||||
fstring lock_name;
|
fstring lock_name;
|
||||||
BOOL got_mutex;
|
BOOL got_mutex;
|
||||||
|
|
||||||
@ -869,7 +888,30 @@ NTSTATUS cm_get_netlogon_cli(const char *domain,
|
|||||||
|
|
||||||
/* Open an initial conection - keep the mutex. */
|
/* Open an initial conection - keep the mutex. */
|
||||||
|
|
||||||
if (!NT_STATUS_IS_OK(result = get_connection_from_cache(domain, PIPE_NETLOGON, &conn)))
|
find_cm_connection(domain, PIPE_NETLOGON, &conn);
|
||||||
|
|
||||||
|
if ( fresh && (conn != NULL) ) {
|
||||||
|
cli_shutdown(conn->cli);
|
||||||
|
conn->cli = NULL;
|
||||||
|
|
||||||
|
conn = NULL;
|
||||||
|
|
||||||
|
/* purge connection from cache */
|
||||||
|
find_cm_connection(domain, PIPE_NETLOGON, &conn);
|
||||||
|
if (conn != NULL) {
|
||||||
|
DEBUG(0,("Could not purge connection\n"));
|
||||||
|
return NT_STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conn != NULL) {
|
||||||
|
*cli = conn->cli;
|
||||||
|
return NT_STATUS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = new_cm_connection(domain, PIPE_NETLOGON, &conn);
|
||||||
|
|
||||||
|
if (!NT_STATUS_IS_OK(result))
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
snprintf(lock_name, sizeof(lock_name), "NETLOGON\\%s", conn->controller);
|
snprintf(lock_name, sizeof(lock_name), "NETLOGON\\%s", conn->controller);
|
||||||
@ -878,39 +920,17 @@ NTSTATUS cm_get_netlogon_cli(const char *domain,
|
|||||||
DEBUG(0,("cm_get_netlogon_cli: mutex grab failed for %s\n", conn->controller));
|
DEBUG(0,("cm_get_netlogon_cli: mutex grab failed for %s\n", conn->controller));
|
||||||
}
|
}
|
||||||
|
|
||||||
result = cli_nt_setup_creds(conn->cli, sec_channel_type, trust_passwd, &neg_flags, 2);
|
result = cli_nt_establish_netlogon(conn->cli, sec_channel_type, trust_passwd);
|
||||||
|
|
||||||
if (got_mutex)
|
if (got_mutex)
|
||||||
secrets_named_mutex_release(lock_name);
|
secrets_named_mutex_release(lock_name);
|
||||||
|
|
||||||
if (!NT_STATUS_IS_OK(result)) {
|
|
||||||
DEBUG(0, ("error connecting to domain password server: %s\n",
|
|
||||||
nt_errstr(result)));
|
|
||||||
|
|
||||||
/* Hit the cache code again. This cleans out the old connection and gets a new one */
|
|
||||||
if (conn->cli->fd == -1) {
|
|
||||||
if (!NT_STATUS_IS_OK(result = get_connection_from_cache(domain, PIPE_NETLOGON, &conn)))
|
|
||||||
return result;
|
|
||||||
|
|
||||||
snprintf(lock_name, sizeof(lock_name), "NETLOGON\\%s", conn->controller);
|
|
||||||
if (!(got_mutex = secrets_named_mutex(lock_name, WINBIND_SERVER_MUTEX_WAIT_TIME))) {
|
|
||||||
DEBUG(0,("cm_get_netlogon_cli: mutex grab failed for %s\n", conn->controller));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Try again */
|
|
||||||
result = cli_nt_setup_creds( conn->cli, sec_channel_type,trust_passwd, &neg_flags, 2);
|
|
||||||
|
|
||||||
if (got_mutex)
|
|
||||||
secrets_named_mutex_release(lock_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!NT_STATUS_IS_OK(result)) {
|
if (!NT_STATUS_IS_OK(result)) {
|
||||||
cli_shutdown(conn->cli);
|
cli_shutdown(conn->cli);
|
||||||
DLIST_REMOVE(cm_conns, conn);
|
DLIST_REMOVE(cm_conns, conn);
|
||||||
SAFE_FREE(conn);
|
SAFE_FREE(conn);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
*cli = conn->cli;
|
*cli = conn->cli;
|
||||||
|
|
||||||
|
@ -50,7 +50,9 @@ enum winbindd_result winbindd_check_machine_acct(struct winbindd_cli_state *stat
|
|||||||
the trust account password. */
|
the trust account password. */
|
||||||
|
|
||||||
/* Don't shut this down - it belongs to the connection cache code */
|
/* Don't shut this down - it belongs to the connection cache code */
|
||||||
result = cm_get_netlogon_cli(lp_workgroup(), trust_passwd, sec_channel_type, &cli);
|
result = cm_get_netlogon_cli(lp_workgroup(),
|
||||||
|
trust_passwd, sec_channel_type,
|
||||||
|
True, &cli);
|
||||||
|
|
||||||
if (!NT_STATUS_IS_OK(result)) {
|
if (!NT_STATUS_IS_OK(result)) {
|
||||||
DEBUG(3, ("could not open handle to NETLOGON pipe\n"));
|
DEBUG(3, ("could not open handle to NETLOGON pipe\n"));
|
||||||
|
@ -68,6 +68,8 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
|
|||||||
TALLOC_CTX *mem_ctx = NULL;
|
TALLOC_CTX *mem_ctx = NULL;
|
||||||
DATA_BLOB lm_resp;
|
DATA_BLOB lm_resp;
|
||||||
DATA_BLOB nt_resp;
|
DATA_BLOB nt_resp;
|
||||||
|
DOM_CRED ret_creds;
|
||||||
|
int attempts = 0;
|
||||||
|
|
||||||
/* Ensure null termination */
|
/* Ensure null termination */
|
||||||
state->request.data.auth.user[sizeof(state->request.data.auth.user)-1]='\0';
|
state->request.data.auth.user[sizeof(state->request.data.auth.user)-1]='\0';
|
||||||
@ -119,12 +121,13 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
ZERO_STRUCT(info3);
|
ZERO_STRUCT(info3);
|
||||||
|
ZERO_STRUCT(ret_creds);
|
||||||
|
|
||||||
/* Don't shut this down - it belongs to the connection cache code */
|
/* Don't shut this down - it belongs to the connection cache code */
|
||||||
result = cm_get_netlogon_cli(lp_workgroup(), trust_passwd,
|
result = cm_get_netlogon_cli(lp_workgroup(), trust_passwd,
|
||||||
sec_channel_type,
|
sec_channel_type, False, &cli);
|
||||||
&cli);
|
|
||||||
|
|
||||||
if (!NT_STATUS_IS_OK(result)) {
|
if (!NT_STATUS_IS_OK(result)) {
|
||||||
DEBUG(3, ("could not open handle to NETLOGON pipe\n"));
|
DEBUG(3, ("could not open handle to NETLOGON pipe\n"));
|
||||||
@ -132,10 +135,21 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
|
|||||||
}
|
}
|
||||||
|
|
||||||
result = cli_netlogon_sam_network_logon(cli, mem_ctx,
|
result = cli_netlogon_sam_network_logon(cli, mem_ctx,
|
||||||
|
&ret_creds,
|
||||||
name_user, name_domain,
|
name_user, name_domain,
|
||||||
global_myname(), chal,
|
global_myname(), chal,
|
||||||
lm_resp, nt_resp,
|
lm_resp, nt_resp,
|
||||||
&info3);
|
&info3);
|
||||||
|
attempts += 1;
|
||||||
|
|
||||||
|
/* We have to try a second time as cm_get_netlogon_cli
|
||||||
|
might not yet have noticed that the DC has killed
|
||||||
|
our connection. */
|
||||||
|
|
||||||
|
} while ( (attempts < 2) && (cli->fd == -1) );
|
||||||
|
|
||||||
|
|
||||||
|
clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &ret_creds);
|
||||||
|
|
||||||
uni_group_cache_store_netlogon(mem_ctx, &info3);
|
uni_group_cache_store_netlogon(mem_ctx, &info3);
|
||||||
done:
|
done:
|
||||||
@ -176,6 +190,8 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
|
|||||||
const char *domain = NULL;
|
const char *domain = NULL;
|
||||||
const char *contact_domain;
|
const char *contact_domain;
|
||||||
const char *workstation;
|
const char *workstation;
|
||||||
|
DOM_CRED ret_creds;
|
||||||
|
int attempts = 0;
|
||||||
|
|
||||||
DATA_BLOB lm_resp, nt_resp;
|
DATA_BLOB lm_resp, nt_resp;
|
||||||
|
|
||||||
@ -264,22 +280,38 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
ZERO_STRUCT(info3);
|
ZERO_STRUCT(info3);
|
||||||
|
ZERO_STRUCT(ret_creds);
|
||||||
|
|
||||||
/* Don't shut this down - it belongs to the connection cache code */
|
/* Don't shut this down - it belongs to the connection cache code */
|
||||||
result = cm_get_netlogon_cli(contact_domain, trust_passwd, sec_channel_type, &cli);
|
result = cm_get_netlogon_cli(contact_domain, trust_passwd,
|
||||||
|
sec_channel_type, False, &cli);
|
||||||
|
|
||||||
if (!NT_STATUS_IS_OK(result)) {
|
if (!NT_STATUS_IS_OK(result)) {
|
||||||
DEBUG(3, ("could not open handle to NETLOGON pipe (error: %s)\n", nt_errstr(result)));
|
DEBUG(3, ("could not open handle to NETLOGON pipe (error: %s)\n",
|
||||||
|
nt_errstr(result)));
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = cli_netlogon_sam_network_logon(cli, mem_ctx,
|
result = cli_netlogon_sam_network_logon(cli, mem_ctx,
|
||||||
|
&ret_creds,
|
||||||
user, domain,
|
user, domain,
|
||||||
workstation, state->request.data.auth_crap.chal,
|
workstation,
|
||||||
|
state->request.data.auth_crap.chal,
|
||||||
lm_resp, nt_resp,
|
lm_resp, nt_resp,
|
||||||
&info3);
|
&info3);
|
||||||
|
|
||||||
|
attempts += 1;
|
||||||
|
|
||||||
|
/* We have to try a second time as cm_get_netlogon_cli
|
||||||
|
might not yet have noticed that the DC has killed
|
||||||
|
our connection. */
|
||||||
|
|
||||||
|
} while ( (attempts < 2) && (cli->fd == -1) );
|
||||||
|
|
||||||
|
clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &ret_creds);
|
||||||
|
|
||||||
if (NT_STATUS_IS_OK(result)) {
|
if (NT_STATUS_IS_OK(result)) {
|
||||||
uni_group_cache_store_netlogon(mem_ctx, &info3);
|
uni_group_cache_store_netlogon(mem_ctx, &info3);
|
||||||
if (state->request.data.auth_crap.flags & WINBIND_PAM_INFO3_NDR) {
|
if (state->request.data.auth_crap.flags & WINBIND_PAM_INFO3_NDR) {
|
||||||
|
@ -472,6 +472,7 @@ NTSTATUS cli_netlogon_sam_deltas(struct cli_state *cli, TALLOC_CTX *mem_ctx,
|
|||||||
/* Logon domain user */
|
/* Logon domain user */
|
||||||
|
|
||||||
NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx,
|
NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx,
|
||||||
|
DOM_CRED *ret_creds,
|
||||||
const char *username, const char *password,
|
const char *username, const char *password,
|
||||||
int logon_type)
|
int logon_type)
|
||||||
{
|
{
|
||||||
@ -486,6 +487,7 @@ NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx,
|
|||||||
|
|
||||||
ZERO_STRUCT(q);
|
ZERO_STRUCT(q);
|
||||||
ZERO_STRUCT(r);
|
ZERO_STRUCT(r);
|
||||||
|
ZERO_STRUCT(dummy_rtn_creds);
|
||||||
|
|
||||||
/* Initialise parse structures */
|
/* Initialise parse structures */
|
||||||
|
|
||||||
@ -498,8 +500,8 @@ NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx,
|
|||||||
|
|
||||||
q.validation_level = validation_level;
|
q.validation_level = validation_level;
|
||||||
|
|
||||||
memset(&dummy_rtn_creds, '\0', sizeof(dummy_rtn_creds));
|
if (ret_creds == NULL)
|
||||||
dummy_rtn_creds.timestamp.time = time(NULL);
|
ret_creds = &dummy_rtn_creds;
|
||||||
|
|
||||||
ctr.switch_value = logon_type;
|
ctr.switch_value = logon_type;
|
||||||
|
|
||||||
@ -542,7 +544,7 @@ NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
init_sam_info(&q.sam_id, cli->srv_name_slash, global_myname(),
|
init_sam_info(&q.sam_id, cli->srv_name_slash, global_myname(),
|
||||||
&clnt_creds, &dummy_rtn_creds, logon_type,
|
&clnt_creds, ret_creds, logon_type,
|
||||||
&ctr);
|
&ctr);
|
||||||
|
|
||||||
/* Marshall data and send request */
|
/* Marshall data and send request */
|
||||||
@ -563,6 +565,7 @@ NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx,
|
|||||||
/* Return results */
|
/* Return results */
|
||||||
|
|
||||||
result = r.status;
|
result = r.status;
|
||||||
|
memcpy(ret_creds, &r.srv_creds, sizeof(*ret_creds));
|
||||||
|
|
||||||
done:
|
done:
|
||||||
prs_mem_free(&qbuf);
|
prs_mem_free(&qbuf);
|
||||||
@ -579,6 +582,7 @@ NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx,
|
|||||||
**/
|
**/
|
||||||
|
|
||||||
NTSTATUS cli_netlogon_sam_network_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx,
|
NTSTATUS cli_netlogon_sam_network_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx,
|
||||||
|
DOM_CRED *ret_creds,
|
||||||
const char *username, const char *domain, const char *workstation,
|
const char *username, const char *domain, const char *workstation,
|
||||||
const uint8 chal[8],
|
const uint8 chal[8],
|
||||||
DATA_BLOB lm_response, DATA_BLOB nt_response,
|
DATA_BLOB lm_response, DATA_BLOB nt_response,
|
||||||
@ -598,6 +602,7 @@ NTSTATUS cli_netlogon_sam_network_logon(struct cli_state *cli, TALLOC_CTX *mem_c
|
|||||||
|
|
||||||
ZERO_STRUCT(q);
|
ZERO_STRUCT(q);
|
||||||
ZERO_STRUCT(r);
|
ZERO_STRUCT(r);
|
||||||
|
ZERO_STRUCT(dummy_rtn_creds);
|
||||||
|
|
||||||
workstation_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", workstation);
|
workstation_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", workstation);
|
||||||
|
|
||||||
@ -617,8 +622,8 @@ NTSTATUS cli_netlogon_sam_network_logon(struct cli_state *cli, TALLOC_CTX *mem_c
|
|||||||
|
|
||||||
q.validation_level = validation_level;
|
q.validation_level = validation_level;
|
||||||
|
|
||||||
memset(&dummy_rtn_creds, '\0', sizeof(dummy_rtn_creds));
|
if (ret_creds == NULL)
|
||||||
dummy_rtn_creds.timestamp.time = time(NULL);
|
ret_creds = &dummy_rtn_creds;
|
||||||
|
|
||||||
ctr.switch_value = NET_LOGON_TYPE;
|
ctr.switch_value = NET_LOGON_TYPE;
|
||||||
|
|
||||||
@ -629,7 +634,7 @@ NTSTATUS cli_netlogon_sam_network_logon(struct cli_state *cli, TALLOC_CTX *mem_c
|
|||||||
lm_response.data, lm_response.length, nt_response.data, nt_response.length);
|
lm_response.data, lm_response.length, nt_response.data, nt_response.length);
|
||||||
|
|
||||||
init_sam_info(&q.sam_id, cli->srv_name_slash, global_myname(),
|
init_sam_info(&q.sam_id, cli->srv_name_slash, global_myname(),
|
||||||
&clnt_creds, &dummy_rtn_creds, NET_LOGON_TYPE,
|
&clnt_creds, ret_creds, NET_LOGON_TYPE,
|
||||||
&ctr);
|
&ctr);
|
||||||
|
|
||||||
/* Marshall data and send request */
|
/* Marshall data and send request */
|
||||||
@ -659,6 +664,7 @@ NTSTATUS cli_netlogon_sam_network_logon(struct cli_state *cli, TALLOC_CTX *mem_c
|
|||||||
/* Return results */
|
/* Return results */
|
||||||
|
|
||||||
result = r.status;
|
result = r.status;
|
||||||
|
memcpy(ret_creds, &r.srv_creds, sizeof(*ret_creds));
|
||||||
|
|
||||||
done:
|
done:
|
||||||
prs_mem_free(&qbuf);
|
prs_mem_free(&qbuf);
|
||||||
|
@ -1563,8 +1563,8 @@ BOOL cli_nt_session_open(struct cli_state *cli, const int pipe_idx)
|
|||||||
Open a session to the NETLOGON pipe using schannel.
|
Open a session to the NETLOGON pipe using schannel.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
BOOL cli_nt_open_netlogon(struct cli_state *cli, const char *trust_password,
|
NTSTATUS cli_nt_establish_netlogon(struct cli_state *cli, int sec_chan,
|
||||||
int sec_chan)
|
const char *trust_password)
|
||||||
{
|
{
|
||||||
NTSTATUS result;
|
NTSTATUS result;
|
||||||
uint32 neg_flags = 0x000001ff;
|
uint32 neg_flags = 0x000001ff;
|
||||||
@ -1573,22 +1573,12 @@ BOOL cli_nt_open_netlogon(struct cli_state *cli, const char *trust_password,
|
|||||||
if (lp_client_schannel() != False)
|
if (lp_client_schannel() != False)
|
||||||
neg_flags |= NETLOGON_NEG_SCHANNEL;
|
neg_flags |= NETLOGON_NEG_SCHANNEL;
|
||||||
|
|
||||||
|
|
||||||
if (!cli_nt_session_open(cli, PI_NETLOGON)) {
|
|
||||||
return False;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!secrets_init()) {
|
|
||||||
DEBUG(3,("Failed to init secrets.tdb\n"));
|
|
||||||
return False;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = cli_nt_setup_creds(cli, sec_chan, trust_password,
|
result = cli_nt_setup_creds(cli, sec_chan, trust_password,
|
||||||
&neg_flags, 2);
|
&neg_flags, 2);
|
||||||
|
|
||||||
if (!NT_STATUS_IS_OK(result)) {
|
if (!NT_STATUS_IS_OK(result)) {
|
||||||
cli_nt_session_close(cli);
|
cli_nt_session_close(cli);
|
||||||
return False;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((lp_client_schannel() == True) &&
|
if ((lp_client_schannel() == True) &&
|
||||||
@ -1596,12 +1586,12 @@ BOOL cli_nt_open_netlogon(struct cli_state *cli, const char *trust_password,
|
|||||||
|
|
||||||
DEBUG(3, ("Server did not offer schannel\n"));
|
DEBUG(3, ("Server did not offer schannel\n"));
|
||||||
cli_nt_session_close(cli);
|
cli_nt_session_close(cli);
|
||||||
return False;
|
return NT_STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((lp_client_schannel() == False) ||
|
if ((lp_client_schannel() == False) ||
|
||||||
((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
|
((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
|
||||||
return True;
|
return NT_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Server offered schannel, so try it. */
|
/* Server offered schannel, so try it. */
|
||||||
@ -1624,7 +1614,7 @@ BOOL cli_nt_open_netlogon(struct cli_state *cli, const char *trust_password,
|
|||||||
"Error was %s\n",
|
"Error was %s\n",
|
||||||
PIPE_NETLOGON, cli->desthost,
|
PIPE_NETLOGON, cli->desthost,
|
||||||
cli_errstr(cli)));
|
cli_errstr(cli)));
|
||||||
return False;
|
return NT_STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
cli->nt_pipe_fnum = (uint16)fnum;
|
cli->nt_pipe_fnum = (uint16)fnum;
|
||||||
@ -1635,7 +1625,7 @@ BOOL cli_nt_open_netlogon(struct cli_state *cli, const char *trust_password,
|
|||||||
"Error was %s\n",
|
"Error was %s\n",
|
||||||
PIPE_NETLOGON, cli->desthost,
|
PIPE_NETLOGON, cli->desthost,
|
||||||
cli_errstr(cli)));
|
cli_errstr(cli)));
|
||||||
return False;
|
return NT_STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
cli->nt_pipe_fnum = (uint16)fnum;
|
cli->nt_pipe_fnum = (uint16)fnum;
|
||||||
@ -1645,17 +1635,17 @@ BOOL cli_nt_open_netlogon(struct cli_state *cli, const char *trust_password,
|
|||||||
DEBUG(0,("Pipe hnd state failed. Error was %s\n",
|
DEBUG(0,("Pipe hnd state failed. Error was %s\n",
|
||||||
cli_errstr(cli)));
|
cli_errstr(cli)));
|
||||||
cli_close(cli, cli->nt_pipe_fnum);
|
cli_close(cli, cli->nt_pipe_fnum);
|
||||||
return False;
|
return NT_STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!rpc_pipe_bind(cli, PI_NETLOGON, global_myname(), True)) {
|
if (!rpc_pipe_bind(cli, PI_NETLOGON, global_myname(), True)) {
|
||||||
DEBUG(2,("rpc bind to %s failed\n", PIPE_NETLOGON));
|
DEBUG(2,("rpc bind to %s failed\n", PIPE_NETLOGON));
|
||||||
cli_close(cli, cli->nt_pipe_fnum);
|
cli_close(cli, cli->nt_pipe_fnum);
|
||||||
return False;
|
return NT_STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return True;
|
return NT_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -275,6 +275,7 @@ static NTSTATUS cmd_netlogon_sam_logon(struct cli_state *cli,
|
|||||||
const char *username, *password;
|
const char *username, *password;
|
||||||
uint32 neg_flags = 0x000001ff;
|
uint32 neg_flags = 0x000001ff;
|
||||||
int auth_level = 2;
|
int auth_level = 2;
|
||||||
|
DOM_CRED ret_creds;
|
||||||
|
|
||||||
/* Check arguments */
|
/* Check arguments */
|
||||||
|
|
||||||
@ -299,7 +300,13 @@ static NTSTATUS cmd_netlogon_sam_logon(struct cli_state *cli,
|
|||||||
|
|
||||||
/* Perform the sam logon */
|
/* Perform the sam logon */
|
||||||
|
|
||||||
result = cli_netlogon_sam_logon(cli, mem_ctx, username, password, logon_type);
|
ZERO_STRUCT(ret_creds);
|
||||||
|
|
||||||
|
result = cli_netlogon_sam_logon(cli, mem_ctx, &ret_creds, username, password, logon_type);
|
||||||
|
|
||||||
|
clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &ret_creds);
|
||||||
|
|
||||||
|
result = cli_netlogon_sam_logon(cli, mem_ctx, &ret_creds, username, password, logon_type);
|
||||||
|
|
||||||
if (!NT_STATUS_IS_OK(result))
|
if (!NT_STATUS_IS_OK(result))
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -391,6 +391,14 @@ static NTSTATUS do_cmd(struct cli_state *cli,
|
|||||||
|
|
||||||
/* Open pipe */
|
/* Open pipe */
|
||||||
|
|
||||||
|
if (cmd_entry->pipe_idx != -1) {
|
||||||
|
if (!cli_nt_session_open(cli, cmd_entry->pipe_idx)) {
|
||||||
|
DEBUG(0, ("Could not initialise %s\n",
|
||||||
|
get_pipe_name_from_index(cmd_entry->pipe_idx)));
|
||||||
|
return NT_STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (cmd_entry->pipe_idx == PI_NETLOGON) {
|
if (cmd_entry->pipe_idx == PI_NETLOGON) {
|
||||||
uchar trust_password[16];
|
uchar trust_password[16];
|
||||||
uint32 sec_channel_type;
|
uint32 sec_channel_type;
|
||||||
@ -401,19 +409,11 @@ static NTSTATUS do_cmd(struct cli_state *cli,
|
|||||||
return NT_STATUS_UNSUCCESSFUL;
|
return NT_STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cli_nt_open_netlogon(cli, trust_password,
|
if (!NT_STATUS_IS_OK(cli_nt_establish_netlogon(cli, sec_channel_type,
|
||||||
sec_channel_type)) {
|
trust_password))) {
|
||||||
DEBUG(0, ("Could not initialise NETLOGON pipe\n"));
|
DEBUG(0, ("Could not initialise NETLOGON pipe\n"));
|
||||||
return NT_STATUS_UNSUCCESSFUL;
|
return NT_STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (cmd_entry->pipe_idx != -1) {
|
|
||||||
if (!cli_nt_session_open(cli, cmd_entry->pipe_idx)) {
|
|
||||||
DEBUG(0, ("Could not initialise %s\n",
|
|
||||||
get_pipe_name_from_index(cmd_entry->pipe_idx)));
|
|
||||||
return NT_STATUS_UNSUCCESSFUL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Run command */
|
/* Run command */
|
||||||
|
@ -209,6 +209,11 @@ int rpc_samdump(int argc, const char **argv)
|
|||||||
|
|
||||||
fstrcpy(cli->domain, lp_workgroup());
|
fstrcpy(cli->domain, lp_workgroup());
|
||||||
|
|
||||||
|
if (!cli_nt_session_open(cli, PI_NETLOGON)) {
|
||||||
|
DEBUG(0,("Could not open connection to NETLOGON pipe\n"));
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
if (!secrets_fetch_trust_account_password(lp_workgroup(),
|
if (!secrets_fetch_trust_account_password(lp_workgroup(),
|
||||||
trust_password,
|
trust_password,
|
||||||
NULL, &sec_channel)) {
|
NULL, &sec_channel)) {
|
||||||
@ -216,7 +221,8 @@ int rpc_samdump(int argc, const char **argv)
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cli_nt_open_netlogon(cli, trust_password, sec_channel)) {
|
if (!NT_STATUS_IS_OK(cli_nt_establish_netlogon(cli, sec_channel,
|
||||||
|
trust_password))) {
|
||||||
DEBUG(0,("Error connecting to NETLOGON pipe\n"));
|
DEBUG(0,("Error connecting to NETLOGON pipe\n"));
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user