From 54abd2aa66069e6baf7769c496f46d9dba18db39 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 30 Sep 2005 17:13:37 +0000 Subject: r10656: BIG merge from trunk. Features not copied over * \PIPE\unixinfo * winbindd's {group,alias}membership new functions * winbindd's lookupsids() functionality * swat (trunk changes to be reverted as per discussion with Deryck) (This used to be commit 939c3cb5d78e3a2236209b296aa8aba8bdce32d3) --- source3/nsswitch/winbindd_pam.c | 172 ++++++++++++++-------------------------- 1 file changed, 58 insertions(+), 114 deletions(-) (limited to 'source3/nsswitch/winbindd_pam.c') diff --git a/source3/nsswitch/winbindd_pam.c b/source3/nsswitch/winbindd_pam.c index a0712144ee..c2324291a6 100644 --- a/source3/nsswitch/winbindd_pam.c +++ b/source3/nsswitch/winbindd_pam.c @@ -37,7 +37,7 @@ static NTSTATUS append_info3_as_ndr(TALLOC_CTX *mem_ctx, if (!prs_init(&ps, 256 /* Random, non-zero number */, mem_ctx, MARSHALL)) { return NT_STATUS_NO_MEMORY; } - if (!net_io_user_info3("", info3, &ps, 1, 3)) { + if (!net_io_user_info3("", info3, &ps, 1, 3, False)) { prs_mem_free(&ps); return NT_STATUS_UNSUCCESSFUL; } @@ -227,15 +227,11 @@ enum winbindd_result winbindd_dual_pam_auth(struct winbindd_domain *domain, { NTSTATUS result; fstring name_domain, name_user; - const char *srv_name_slash; NET_USER_INFO_3 info3; - unsigned char *session_key; - struct rpc_pipe_client *pipe_cli; + struct rpc_pipe_client *netlogon_pipe; uchar chal[8]; DATA_BLOB lm_resp; DATA_BLOB nt_resp; - DOM_CRED ret_creds; - DOM_CRED *credentials; int attempts = 0; unsigned char local_lm_response[24]; unsigned char local_nt_response[24]; @@ -311,7 +307,6 @@ enum winbindd_result winbindd_dual_pam_auth(struct winbindd_domain *domain, local_nt_response, sizeof(local_nt_response)); } - /* what domain should we contact? */ @@ -333,49 +328,30 @@ enum winbindd_result winbindd_dual_pam_auth(struct winbindd_domain *domain, contact_domain = find_our_domain(); } - srv_name_slash = talloc_asprintf(state->mem_ctx, "\\\\%s", - contact_domain->dcname); - if (srv_name_slash == NULL) { - DEBUG(0, ("talloc_asprintf failed\n")); - return WINBINDD_ERROR; - } - /* check authentication loop */ do { - DOM_CRED clnt_creds; ZERO_STRUCT(info3); - ZERO_STRUCT(ret_creds); retry = False; - result = cm_connect_netlogon(contact_domain, state->mem_ctx, - &pipe_cli, &session_key, - &credentials); + result = cm_connect_netlogon(contact_domain, &netlogon_pipe); if (!NT_STATUS_IS_OK(result)) { DEBUG(3, ("could not open handle to NETLOGON pipe\n")); goto done; } - credentials->timestamp.time = time(NULL); - memcpy(&clnt_creds, credentials, sizeof(clnt_creds)); - - /* Calculate the new credentials. */ - cred_create(session_key, &credentials->challenge, - clnt_creds.timestamp, &(clnt_creds.challenge)); - - result = rpccli_netlogon_sam_network_logon(pipe_cli, - state->mem_ctx, - srv_name_slash, - &clnt_creds, - &ret_creds, - name_user, - name_domain, - global_myname(), - chal, lm_resp, - nt_resp, &info3, - session_key); + result = rpccli_netlogon_sam_network_logon(netlogon_pipe, + state->mem_ctx, + contact_domain->dcname, /* server name */ + name_user, /* user name */ + name_domain, /* target domain */ + global_myname(), /* workstation */ + chal, + lm_resp, + nt_resp, + &info3); attempts += 1; /* We have to try a second time as cm_connect_netlogon @@ -404,21 +380,11 @@ enum winbindd_result winbindd_dual_pam_auth(struct winbindd_domain *domain, } while ( (attempts < 2) && retry ); - /* Only check creds if we got a connection. */ - if (contact_domain->conn.cli && - !(NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND) || - NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))) { - if (!clnt_deal_with_creds(session_key, credentials, &ret_creds)) { - DEBUG(3, ("DC %s sent wrong credentials\n", - pipe_cli->cli->srv_name_slash)); - result = NT_STATUS_ACCESS_DENIED; - } - } - if (NT_STATUS_IS_OK(result)) { /* Check if the user is in the right group */ - if (!NT_STATUS_IS_OK(result = check_info3_in_group(state->mem_ctx, &info3, state->request.data.auth.require_membership_of_sid))) { + if (!NT_STATUS_IS_OK(result = check_info3_in_group(state->mem_ctx, &info3, + state->request.data.auth.require_membership_of_sid))) { DEBUG(3, ("User %s is not in the required group (%s), so plaintext authentication is rejected\n", state->request.data.auth.user, state->request.data.auth.require_membership_of_sid)); @@ -426,8 +392,10 @@ enum winbindd_result winbindd_dual_pam_auth(struct winbindd_domain *domain, } done: + /* give us a more useful (more correct?) error code */ - if ((NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND) || (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)))) { + if ((NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND) || + (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)))) { result = NT_STATUS_NO_LOGON_SERVERS; } @@ -450,7 +418,9 @@ done: char *afsname = SMB_STRDUP(lp_afs_username_map()); char *cell; - if (afsname == NULL) goto no_token; + if (afsname == NULL) { + goto no_token; + } afsname = realloc_string_sub(afsname, "%D", name_domain); afsname = realloc_string_sub(afsname, "%u", name_user); @@ -466,7 +436,9 @@ done: afsname = realloc_string_sub(afsname, "%s", sidstr); } - if (afsname == NULL) goto no_token; + if (afsname == NULL) { + goto no_token; + } strlower_m(afsname); @@ -474,7 +446,9 @@ done: cell = strchr(afsname, '@'); - if (cell == NULL) goto no_token; + if (cell == NULL) { + goto no_token; + } *cell = '\0'; cell += 1; @@ -565,16 +539,12 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, struct winbindd_cli_state *state) { NTSTATUS result; - const char *srv_name_slash; NET_USER_INFO_3 info3; - unsigned char *session_key; - struct rpc_pipe_client *pipe_cli; - DOM_CRED *credentials; + struct rpc_pipe_client *netlogon_pipe; const char *name_user = NULL; const char *name_domain = NULL; const char *workstation; struct winbindd_domain *contact_domain; - DOM_CRED ret_creds; int attempts = 0; BOOL retry; @@ -618,9 +588,10 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, goto done; } - lm_resp = data_blob_talloc(state->mem_ctx, state->request.data.auth_crap.lm_resp, state->request.data.auth_crap.lm_resp_len); - nt_resp = data_blob_talloc(state->mem_ctx, state->request.data.auth_crap.nt_resp, state->request.data.auth_crap.nt_resp_len); - + lm_resp = data_blob_talloc(state->mem_ctx, state->request.data.auth_crap.lm_resp, + state->request.data.auth_crap.lm_resp_len); + nt_resp = data_blob_talloc(state->mem_ctx, state->request.data.auth_crap.nt_resp, + state->request.data.auth_crap.nt_resp_len); /* what domain should we contact? */ @@ -631,33 +602,20 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, result = NT_STATUS_NO_SUCH_USER; goto done; } - } else { if (is_myname(name_domain)) { DEBUG(3, ("Authentication for domain %s (local domain to this server) not supported at this stage\n", name_domain)); result = NT_STATUS_NO_SUCH_USER; goto done; } - contact_domain = find_our_domain(); } - srv_name_slash = talloc_asprintf(state->mem_ctx, "\\\\%s", - contact_domain->dcname); - if (srv_name_slash == NULL) { - DEBUG(0, ("talloc_asprintf failed\n")); - return WINBINDD_ERROR; - } - do { - DOM_CRED clnt_creds; ZERO_STRUCT(info3); - ZERO_STRUCT(ret_creds); retry = False; - result = cm_connect_netlogon(contact_domain, state->mem_ctx, - &pipe_cli, &session_key, - &credentials); + result = cm_connect_netlogon(contact_domain, &netlogon_pipe); if (!NT_STATUS_IS_OK(result)) { DEBUG(3, ("could not open handle to NETLOGON pipe (error: %s)\n", @@ -665,25 +623,16 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, goto done; } - credentials->timestamp.time = time(NULL); - memcpy(&clnt_creds, credentials, sizeof(clnt_creds)); - - /* Calculate the new credentials. */ - cred_create(session_key, &credentials->challenge, - clnt_creds.timestamp, &(clnt_creds.challenge)); - - result = rpccli_netlogon_sam_network_logon(pipe_cli, - state->mem_ctx, - srv_name_slash, - &clnt_creds, - &ret_creds, - name_user, - name_domain, - global_myname(), - state->request.data.auth_crap.chal, - lm_resp, - nt_resp, &info3, - session_key); + result = rpccli_netlogon_sam_network_logon(netlogon_pipe, + state->mem_ctx, + contact_domain->dcname, + name_user, + name_domain, + global_myname(), + state->request.data.auth_crap.chal, + lm_resp, + nt_resp, + &info3); attempts += 1; @@ -712,19 +661,9 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, } while ( (attempts < 2) && retry ); - /* Only check creds if we got a connection. */ - if (contact_domain->conn.cli && - !(NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND) || - (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)))) { - if (!clnt_deal_with_creds(session_key, credentials, &ret_creds)) { - DEBUG(3, ("DC %s sent wrong credentials\n", - pipe_cli->cli->srv_name_slash)); - result = NT_STATUS_ACCESS_DENIED; - } - } - if (NT_STATUS_IS_OK(result)) { - if (!NT_STATUS_IS_OK(result = check_info3_in_group(state->mem_ctx, &info3, state->request.data.auth_crap.require_membership_of_sid))) { + if (!NT_STATUS_IS_OK(result = check_info3_in_group(state->mem_ctx, &info3, + state->request.data.auth_crap.require_membership_of_sid))) { DEBUG(3, ("User %s is not in the required group (%s), so plaintext authentication is rejected\n", state->request.data.auth_crap.user, state->request.data.auth_crap.require_membership_of_sid)); @@ -736,14 +675,14 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, } else if (state->request.flags & WBFLAG_PAM_UNIX_NAME) { /* ntlm_auth should return the unix username, per 'winbind use default domain' settings and the like */ - + fstring username_out; const char *nt_username, *nt_domain; if (!(nt_username = unistr2_tdup(state->mem_ctx, &(info3.uni_user_name)))) { /* If the server didn't give us one, just use the one we sent them */ nt_username = name_user; } - + if (!(nt_domain = unistr2_tdup(state->mem_ctx, &(info3.uni_logon_dom)))) { /* If the server didn't give us one, just use the one we sent them */ nt_domain = name_domain; @@ -762,29 +701,34 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, } if (state->request.flags & WBFLAG_PAM_USER_SESSION_KEY) { - memcpy(state->response.data.auth.user_session_key, info3.user_sess_key, sizeof(state->response.data.auth.user_session_key) /* 16 */); + memcpy(state->response.data.auth.user_session_key, info3.user_sess_key, + sizeof(state->response.data.auth.user_session_key) /* 16 */); } if (state->request.flags & WBFLAG_PAM_LMKEY) { - memcpy(state->response.data.auth.first_8_lm_hash, info3.lm_sess_key, sizeof(state->response.data.auth.first_8_lm_hash) /* 8 */); + memcpy(state->response.data.auth.first_8_lm_hash, info3.lm_sess_key, + sizeof(state->response.data.auth.first_8_lm_hash) /* 8 */); } } done: + /* give us a more useful (more correct?) error code */ - if ((NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND) || (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)))) { + if ((NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND) || + (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)))) { result = NT_STATUS_NO_LOGON_SERVERS; } if (state->request.flags & WBFLAG_PAM_NT_STATUS_SQUASH) { result = nt_status_squash(result); } - + state->response.data.auth.nt_status = NT_STATUS_V(result); fstrcpy(state->response.data.auth.nt_status_string, nt_errstr(result)); - + /* we might have given a more useful error above */ - if (!*state->response.data.auth.error_string) + if (!*state->response.data.auth.error_string) { fstrcpy(state->response.data.auth.error_string, get_friendly_nt_error_msg(result)); + } state->response.data.auth.pam_error = nt_status_to_pam(result); DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, -- cgit