diff options
-rw-r--r-- | source3/auth/auth_domain.c | 7 | ||||
-rw-r--r-- | source3/libsmb/namequery_dc.c | 27 | ||||
-rw-r--r-- | source3/libsmb/trusts_util.c | 2 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_ads.c | 4 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_cm.c | 61 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_misc.c | 14 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_pam.c | 118 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_rpc.c | 22 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_util.c | 10 |
9 files changed, 144 insertions, 121 deletions
diff --git a/source3/auth/auth_domain.c b/source3/auth/auth_domain.c index 43e7597cd9..0f34bcc0e2 100644 --- a/source3/auth/auth_domain.c +++ b/source3/auth/auth_domain.c @@ -165,6 +165,9 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx, if ( !NT_STATUS_IS_OK(nt_status) ) { DEBUG(0,("domain_client_validate: Domain password server not available.\n")); + if (NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCESS_DENIED)) { + return NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE; + } return nt_status; } @@ -290,7 +293,7 @@ static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context, /* we need our DC to send the net_sam_logon() request to */ - if ( !get_dc_name(domain, dc_name, &dc_ip) ) { + if ( !get_dc_name(domain, NULL, dc_name, &dc_ip) ) { DEBUG(5,("check_trustdomain_security: unable to locate a DC for domain %s\n", user_info->domain.str)); return NT_STATUS_NO_LOGON_SERVERS; @@ -385,7 +388,7 @@ static NTSTATUS check_trustdomain_security(const struct auth_context *auth_conte /* use get_dc_name() for consistency even through we know that it will be a netbios name */ - if ( !get_dc_name(user_info->domain.str, dc_name, &dc_ip) ) { + if ( !get_dc_name(user_info->domain.str, NULL, dc_name, &dc_ip) ) { DEBUG(5,("check_trustdomain_security: unable to locate a DC for domain %s\n", user_info->domain.str)); return NT_STATUS_NO_LOGON_SERVERS; diff --git a/source3/libsmb/namequery_dc.c b/source3/libsmb/namequery_dc.c index df7f856cd7..31d759e0d2 100644 --- a/source3/libsmb/namequery_dc.c +++ b/source3/libsmb/namequery_dc.c @@ -29,27 +29,23 @@ Find the name and IP address for a server in he realm/domain *************************************************************************/ -static BOOL ads_dc_name(const char *domain, struct in_addr *dc_ip, fstring srv_name) +static BOOL ads_dc_name(const char *domain, const char *realm, struct in_addr *dc_ip, fstring srv_name) { ADS_STRUCT *ads; - const char *realm = domain; - if (strequal(realm, lp_workgroup())) + if (!realm && strequal(domain, lp_workgroup())) realm = lp_realm(); ads = ads_init(realm, domain, NULL); if (!ads) return False; - /* we don't need to bind, just connect */ - ads->auth.flags |= ADS_AUTH_NO_BIND; - DEBUG(4,("ads_dc_name: domain=%s\n", domain)); #ifdef HAVE_ADS - /* a full ads_connect() is actually overkill, as we don't srictly need - to do the SASL auth in order to get the info we need, but libads - doesn't offer a better way right now */ + /* we don't need to bind, just connect */ + ads->auth.flags |= ADS_AUTH_NO_BIND; + ads_connect(ads); #endif @@ -157,7 +153,7 @@ static BOOL rpc_dc_name(const char *domain, fstring srv_name, struct in_addr *ip wrapper around ads and rpc methods of finds DC's **********************************************************************/ -BOOL get_dc_name(const char *domain, fstring srv_name, struct in_addr *ip_out) +BOOL get_dc_name(const char *domain, const char *realm, fstring srv_name, struct in_addr *ip_out) { struct in_addr dc_ip; BOOL ret; @@ -167,15 +163,14 @@ BOOL get_dc_name(const char *domain, fstring srv_name, struct in_addr *ip_out) ret = False; - if ( strequal(lp_workgroup(), domain) || strequal(lp_realm(), domain) ) + if ( strequal(lp_workgroup(), domain) || strequal(lp_realm(), realm) ) our_domain = True; - /* always try to obey what the admin specified in smb.conf. - If it is not our domain, assume that domain names with periods - in them are realm names */ + /* always try to obey what the admin specified in smb.conf + (for the local domain) */ - if ( (our_domain && lp_security()==SEC_ADS) || strchr_m(domain, '.') ) { - ret = ads_dc_name(domain, &dc_ip, srv_name); + if ( (our_domain && lp_security()==SEC_ADS) || realm ) { + ret = ads_dc_name(domain, realm, &dc_ip, srv_name); } if (!ret) { diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index 7c1000b9a5..b420e4fa08 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -144,7 +144,7 @@ BOOL enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain, /* lookup a DC first */ - if ( !get_dc_name(domain, dc_name, &dc_ip) ) { + if ( !get_dc_name(domain, NULL, dc_name, &dc_ip) ) { DEBUG(3,("enumerate_domain_trusts: can't locate a DC for domain %s\n", domain)); return False; diff --git a/source3/nsswitch/winbindd_ads.c b/source3/nsswitch/winbindd_ads.c index 3a70c1a01e..5e12b0fbb5 100644 --- a/source3/nsswitch/winbindd_ads.c +++ b/source3/nsswitch/winbindd_ads.c @@ -842,7 +842,6 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain, struct cli_state *cli = NULL; /* i think we only need our forest and downlevel trusted domains */ uint32 flags = DS_DOMAIN_IN_FOREST | DS_DOMAIN_DIRECT_OUTBOUND; - char *contact_domain_name; DEBUG(3,("ads: trusted_domains\n")); @@ -851,8 +850,7 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain, *names = NULL; *dom_sids = NULL; - contact_domain_name = *domain->alt_name ? domain->alt_name : domain->name; - if ( !NT_STATUS_IS_OK(result = cm_fresh_connection(contact_domain_name, PI_NETLOGON, &cli)) ) { + if ( !NT_STATUS_IS_OK(result = cm_fresh_connection(domain, PI_NETLOGON, &cli)) ) { DEBUG(5, ("trusted_domains: Could not open a connection to %s for PIPE_NETLOGON (%s)\n", domain->name, nt_errstr(result))); return NT_STATUS_UNSUCCESSFUL; diff --git a/source3/nsswitch/winbindd_cm.c b/source3/nsswitch/winbindd_cm.c index 73c8a6b783..bdbf80eb2f 100644 --- a/source3/nsswitch/winbindd_cm.c +++ b/source3/nsswitch/winbindd_cm.c @@ -113,8 +113,8 @@ static void cm_get_ipc_userpass(char **username, char **domain, char **password) /* Open a connction to the remote server, cache failures for 30 seconds */ -static NTSTATUS cm_open_connection(const char *domain, const int pipe_index, - struct winbindd_cm_conn *new_conn) +static NTSTATUS cm_open_connection(const struct winbindd_domain *domain, const int pipe_index, + struct winbindd_cm_conn *new_conn) { NTSTATUS result; char *machine_password; @@ -125,21 +125,22 @@ static NTSTATUS cm_open_connection(const char *domain, const int pipe_index, ZERO_STRUCT(dc_ip); - fstrcpy(new_conn->domain, domain); - fstrcpy(new_conn->pipe_name, get_pipe_name_from_index(pipe_index)); + fstrcpy(new_conn->domain, domain->name); /* connection failure cache has been moved inside of get_dc_name so we can deal with half dead DC's --jerry */ - if (!get_dc_name(domain, new_conn->controller, &dc_ip)) { + if (!get_dc_name(domain->name, domain->alt_name[0] ? domain->alt_name : NULL, + new_conn->controller, &dc_ip)) { result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; - add_failed_connection_entry(domain, "", result); + add_failed_connection_entry(domain->name, "", result); return result; } /* Initialise SMB connection */ + fstrcpy(new_conn->pipe_name, get_pipe_name_from_index(pipe_index)); - /* grab stored passwords */ +/* grab stored passwords */ machine_password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL); if (asprintf(&machine_krb5_principal, "%s$@%s", global_myname(), lp_realm()) == -1) { @@ -181,7 +182,7 @@ static NTSTATUS cm_open_connection(const char *domain, const int pipe_index, if (!NT_STATUS_IS_OK(result = cli_session_setup_spnego(new_conn->cli, machine_krb5_principal, machine_password, - domain))) { + domain->name))) { DEBUG(4,("failed kerberos session setup with %s\n", nt_errstr(result))); } } @@ -201,7 +202,7 @@ static NTSTATUS cm_open_connection(const char *domain, const int pipe_index, if (!cli_session_setup(new_conn->cli, ipc_username, ipc_password, strlen(ipc_password)+1, ipc_password, strlen(ipc_password)+1, - domain)) { + domain->name)) { result = cli_nt_error(new_conn->cli); DEBUG(4,("failed authenticated session setup with %s\n", nt_errstr(result))); if (NT_STATUS_IS_OK(result)) @@ -258,13 +259,13 @@ static NTSTATUS cm_open_connection(const char *domain, const int pipe_index, SAFE_FREE(machine_password); if (!NT_STATUS_IS_OK(result)) { - add_failed_connection_entry(domain, new_conn->controller, result); + add_failed_connection_entry(domain->name, new_conn->controller, result); return result; } /* set the domain if empty; needed for schannel connections */ if ( !*new_conn->cli->domain ) - fstrcpy( new_conn->cli->domain, domain ); + fstrcpy( new_conn->cli->domain, domain->name ); if ( !cli_nt_session_open (new_conn->cli, pipe_index) ) { @@ -278,7 +279,7 @@ static NTSTATUS cm_open_connection(const char *domain, const int pipe_index, * specific UUID right now, i'm not going to bother. --jerry */ if ( !is_win2k_pipe(pipe_index) ) - add_failed_connection_entry(domain, new_conn->controller, result); + add_failed_connection_entry(domain->name, new_conn->controller, result); cli_shutdown(new_conn->cli); return result; } @@ -291,7 +292,7 @@ static NTSTATUS cm_open_connection(const char *domain, const int pipe_index, setup cli_state struct ************************************************************************/ -NTSTATUS cm_fresh_connection(const char *domain, const int pipe_index, +NTSTATUS cm_fresh_connection(struct winbindd_domain *domain, const int pipe_index, struct cli_state **cli) { NTSTATUS result; @@ -338,13 +339,13 @@ static BOOL connection_ok(struct winbindd_cm_conn *conn) /* Search the cache for a connection. If there is a broken one, shut it down properly and return NULL. */ -static void find_cm_connection(const char *domain, const char *pipe_name, +static void find_cm_connection(struct winbindd_domain *domain, const char *pipe_name, struct winbindd_cm_conn **conn_out) { struct winbindd_cm_conn *conn; for (conn = cm_conns; conn; ) { - if (strequal(conn->domain, domain) && + if (strequal(conn->domain, domain->name) && strequal(conn->pipe_name, pipe_name)) { if (!connection_ok(conn)) { /* Dead connection - remove it. */ @@ -367,7 +368,7 @@ static void find_cm_connection(const char *domain, const char *pipe_name, /* Initialize a new connection up to the RPC BIND. */ -static NTSTATUS new_cm_connection(const char *domain, const char *pipe_name, +static NTSTATUS new_cm_connection(struct winbindd_domain *domain, const char *pipe_name, struct winbindd_cm_conn **conn_out) { struct winbindd_cm_conn *conn; @@ -380,7 +381,7 @@ static NTSTATUS new_cm_connection(const char *domain, const char *pipe_name, if (!NT_STATUS_IS_OK(result = cm_open_connection(domain, get_pipe_index(pipe_name), conn))) { DEBUG(3, ("Could not open a connection to %s for %s (%s)\n", - domain, pipe_name, nt_errstr(result))); + domain->name, pipe_name, nt_errstr(result))); SAFE_FREE(conn); return result; } @@ -392,7 +393,7 @@ static NTSTATUS new_cm_connection(const char *domain, const char *pipe_name, /* 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, +static NTSTATUS get_connection_from_cache(struct winbindd_domain *domain, const char *pipe_name, struct winbindd_cm_conn **conn_out) { find_cm_connection(domain, pipe_name, conn_out); @@ -406,7 +407,7 @@ static NTSTATUS get_connection_from_cache(const char *domain, const char *pipe_n /********************************************************************************** **********************************************************************************/ -BOOL cm_check_for_native_mode_win2k( const char *domain ) +BOOL cm_check_for_native_mode_win2k( struct winbindd_domain *domain ) { NTSTATUS result; struct winbindd_cm_conn conn; @@ -419,7 +420,7 @@ BOOL cm_check_for_native_mode_win2k( const char *domain ) if ( !NT_STATUS_IS_OK(result = cm_open_connection(domain, PI_LSARPC_DS, &conn)) ) { DEBUG(5, ("cm_check_for_native_mode_win2k: Could not open a connection to %s for PIPE_LSARPC (%s)\n", - domain, nt_errstr(result))); + domain->name, nt_errstr(result))); return False; } @@ -450,7 +451,7 @@ done: /* Return a LSA policy handle on a domain */ -NTSTATUS cm_get_lsa_handle(const char *domain, CLI_POLICY_HND **return_hnd) +NTSTATUS cm_get_lsa_handle(struct winbindd_domain *domain, CLI_POLICY_HND **return_hnd) { struct winbindd_cm_conn *conn; uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED; @@ -503,7 +504,7 @@ NTSTATUS cm_get_lsa_handle(const char *domain, CLI_POLICY_HND **return_hnd) /* Return a SAM policy handle on a domain */ -NTSTATUS cm_get_sam_handle(char *domain, CLI_POLICY_HND **return_hnd) +NTSTATUS cm_get_sam_handle(struct winbindd_domain *domain, CLI_POLICY_HND **return_hnd) { struct winbindd_cm_conn *conn; uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED; @@ -561,7 +562,7 @@ NTSTATUS cm_get_sam_handle(char *domain, CLI_POLICY_HND **return_hnd) /* Get a handle on a netlogon pipe. This is a bit of a hack to re-use the netlogon pipe as no handle is returned. */ -NTSTATUS cm_get_netlogon_cli(const char *domain, +NTSTATUS cm_get_netlogon_cli(struct winbindd_domain *domain, const unsigned char *trust_passwd, uint32 sec_channel_type, BOOL fresh, @@ -571,7 +572,6 @@ NTSTATUS cm_get_netlogon_cli(const char *domain, struct winbindd_cm_conn *conn; fstring lock_name; BOOL got_mutex; - struct winbindd_domain *wb_domain = NULL; if (!cli) return NT_STATUS_INVALID_PARAMETER; @@ -613,16 +613,9 @@ NTSTATUS cm_get_netlogon_cli(const char *domain, if ( sec_channel_type == SEC_CHAN_DOMAIN ) fstr_sprintf(conn->cli->mach_acct, "%s$", lp_workgroup()); - /* we need the short form of the domain name for the schanel - rpc bind. What if we fail? I don't think we should ever get - a request for a domain name not in our list but I'm not bailing - out if we do since I'm not 10% certain about this --jerry */ - - if ( (wb_domain = find_domain_from_name( domain )) != NULL ) { - DEBUG(5,("cm_get_netlogon_cli: Using short for of domain name [%s] for netlogon rpc bind\n", - wb_domain->name)); - fstrcpy( conn->cli->domain, wb_domain->name); - } + + fstrcpy( conn->cli->domain, domain->name); + result = cli_nt_establish_netlogon(conn->cli, sec_channel_type, trust_passwd); diff --git a/source3/nsswitch/winbindd_misc.c b/source3/nsswitch/winbindd_misc.c index 63bda0d1df..08b5be827d 100644 --- a/source3/nsswitch/winbindd_misc.c +++ b/source3/nsswitch/winbindd_misc.c @@ -37,7 +37,8 @@ enum winbindd_result winbindd_check_machine_acct(struct winbindd_cli_state *stat struct cli_state *cli; uint32 sec_channel_type; const char *contact_domain_name = NULL; - + struct winbindd_domain *contact_domain; + DEBUG(3, ("[%5lu]: check machine account\n", (unsigned long)state->pid)); /* Get trust account password */ @@ -57,12 +58,19 @@ enum winbindd_result winbindd_check_machine_acct(struct winbindd_cli_state *stat if ( !contact_domain_name || !*contact_domain_name ) contact_domain_name = lp_workgroup(); - + + contact_domain = find_domain_from_name(contact_domain_name); + if (!contact_domain) { + result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; + DEBUG(1, ("%s is not a trusted domain\n", contact_domain_name)); + goto done; + } + /* This call does a cli_nt_setup_creds() which implicitly checks the trust account password. */ /* Don't shut this down - it belongs to the connection cache code */ - result = cm_get_netlogon_cli(contact_domain_name, + result = cm_get_netlogon_cli(contact_domain, trust_passwd, sec_channel_type, True, &cli); if (!NT_STATUS_IS_OK(result)) { diff --git a/source3/nsswitch/winbindd_pam.c b/source3/nsswitch/winbindd_pam.c index 54513b1bc1..196ceea9a0 100644 --- a/source3/nsswitch/winbindd_pam.c +++ b/source3/nsswitch/winbindd_pam.c @@ -75,7 +75,7 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state) int attempts = 0; unsigned char local_lm_response[24]; unsigned char local_nt_response[24]; - const char *contact_domain; + struct winbindd_domain *contact_domain; BOOL retry; /* Ensure null termination */ @@ -107,21 +107,15 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state) lm_resp = data_blob_talloc(mem_ctx, local_lm_response, sizeof(local_lm_response)); nt_resp = data_blob_talloc(mem_ctx, local_nt_response, sizeof(local_nt_response)); - if ( !get_trust_pw(name_domain, trust_passwd, &last_change_time, &sec_channel_type) ) { - result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; - goto done; - } - /* what domain should we contact? */ if ( IS_DC ) { - if (!find_domain_from_name(name_domain)) { - DEBUG(3, ("Cannot change password for [%s] -> [%s]\\[%s] as %s is not a trusted domain\n", + if (!(contact_domain = find_domain_from_name(name_domain))) { + DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n", state->request.data.auth.user, name_domain, name_user, name_domain)); result = NT_STATUS_NO_SUCH_USER; goto done; } - contact_domain = name_domain; } else { if (is_myname(name_domain)) { @@ -129,8 +123,20 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state) result = NT_STATUS_NO_SUCH_USER; goto done; } - contact_domain = lp_workgroup(); + + if (!(contact_domain = find_our_domain())) { + DEBUG(1, ("Authenticatoin for [%s] -> [%s]\\[%s] in our domain failed - we can't find our domain!\n", + state->request.data.auth.user, name_domain, name_user)); + result = NT_STATUS_NO_SUCH_USER; + goto done; + } + } + + if ( !get_trust_pw(contact_domain->name, trust_passwd, &last_change_time, &sec_channel_type) ) { + result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; + goto done; } + /* check authentication loop */ do { @@ -194,7 +200,10 @@ done: state->response.data.auth.nt_status = NT_STATUS_V(result); fstrcpy(state->response.data.auth.nt_status_string, nt_errstr(result)); - fstrcpy(state->response.data.auth.error_string, get_friendly_nt_error_msg(result)); + + /* we might have given a more useful error above */ + 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, ("Plain-text authentication for user %s returned %s (PAM: %d)\n", @@ -221,10 +230,10 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state) NET_USER_INFO_3 info3; struct cli_state *cli = NULL; TALLOC_CTX *mem_ctx = NULL; - char *user = NULL; - const char *domain = NULL; + char *name_user = NULL; + const char *name_domain = NULL; const char *workstation; - const char *contact_domain; + struct winbindd_domain *contact_domain; DOM_CRED ret_creds; int attempts = 0; BOOL retry; @@ -255,7 +264,7 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state) goto done; } - if (pull_utf8_talloc(mem_ctx, &user, state->request.data.auth_crap.user) == (size_t)-1) { + if (pull_utf8_talloc(mem_ctx, &name_user, state->request.data.auth_crap.user) == (size_t)-1) { DEBUG(0, ("winbindd_pam_auth_crap: pull_utf8_talloc failed!\n")); result = NT_STATUS_UNSUCCESSFUL; goto done; @@ -268,24 +277,19 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state) result = NT_STATUS_UNSUCCESSFUL; goto done; } - domain = dom; + name_domain = dom; } else if (lp_winbind_use_default_domain()) { - domain = lp_workgroup(); + name_domain = lp_workgroup(); } else { DEBUG(5,("no domain specified with username (%s) - failing auth\n", - user)); - result = NT_STATUS_INVALID_PARAMETER; + name_user)); + result = NT_STATUS_NO_SUCH_USER; goto done; } DEBUG(3, ("[%5lu]: pam auth crap domain: %s user: %s\n", (unsigned long)state->pid, - domain, user)); + name_domain, name_user)); - if ( !get_trust_pw(domain, trust_passwd, &last_change_time, &sec_channel_type) ) { - result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; - goto done; - } - if (*state->request.data.auth_crap.workstation) { char *wrk = NULL; if (pull_utf8_talloc(mem_ctx, &wrk, state->request.data.auth_crap.workstation) == (size_t)-1) { @@ -312,23 +316,37 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state) /* what domain should we contact? */ + + /* what domain should we contact? */ + if ( IS_DC ) { - if (!find_domain_from_name(domain)) { - DEBUG(3, ("Cannot change password for [%s] -> [%s]\\[%s] as %s is not a trusted domain\n", - state->request.data.auth.user, domain, user, domain)); + if (!(contact_domain = find_domain_from_name(name_domain))) { + DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n", + state->request.data.auth.user, name_domain, name_user, name_domain)); result = NT_STATUS_NO_SUCH_USER; goto done; } - contact_domain = domain; + } else { - if (is_myname(domain)) { - DEBUG(3, ("Authentication for domain %s (local domain to this server) not supported at this stage\n", domain)); + 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 = lp_workgroup(); + + if (!(contact_domain = find_our_domain())) { + DEBUG(1, ("Authenticatoin for [%s] -> [%s]\\[%s] in our domain failed - we can't find our domain!\n", + state->request.data.auth.user, name_domain, name_user)); + result = NT_STATUS_NO_SUCH_USER; + goto done; + } } + if ( !get_trust_pw(contact_domain->name, trust_passwd, &last_change_time, &sec_channel_type) ) { + result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; + goto done; + } + do { ZERO_STRUCT(info3); ZERO_STRUCT(ret_creds); @@ -345,7 +363,7 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state) result = cli_netlogon_sam_network_logon(cli, mem_ctx, &ret_creds, - user, domain, + name_user, name_domain, workstation, state->request.data.auth_crap.chal, lm_resp, nt_resp, @@ -369,7 +387,7 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state) if ( NT_STATUS_V(result) == NT_STATUS_V(NT_STATUS_ACCESS_DENIED) ) { DEBUG(3,("winbindd_pam_auth_crap: sam_logon returned ACCESS_DENIED. Maybe the trust account " "password was changed and we didn't know it. Killing connections to domain %s\n", - domain)); + contact_domain->name)); winbindd_cm_flush(); retry = True; cli = NULL; @@ -381,7 +399,7 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state) if (NT_STATUS_IS_OK(result)) { netsamlogon_cache_store( cli->mem_ctx, &info3 ); - wcache_invalidate_samlogon(find_domain_from_name(domain), &info3); + wcache_invalidate_samlogon(find_domain_from_name(name_domain), &info3); if (state->request.flags & WBFLAG_PAM_INFO3_NDR) { result = append_info3_as_ndr(mem_ctx, state, &info3); @@ -393,12 +411,12 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state) const char *nt_username, *nt_domain; if (!(nt_username = unistr2_tdup(mem_ctx, &(info3.uni_user_name)))) { /* If the server didn't give us one, just use the one we sent them */ - nt_username = user; + nt_username = name_user; } if (!(nt_domain = unistr2_tdup(mem_ctx, &(info3.uni_logon_dom)))) { /* If the server didn't give us one, just use the one we sent them */ - nt_domain = domain; + nt_domain = name_domain; } fill_domain_username(username_out, nt_domain, nt_username); @@ -437,8 +455,8 @@ done: DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, ("NTLM CRAP authentication for user [%s]\\[%s] returned %s (PAM: %d)\n", - domain, - user, + name_domain, + name_user, state->response.data.auth.nt_status_string, state->response.data.auth.pam_error)); @@ -456,10 +474,19 @@ enum winbindd_result winbindd_pam_chauthtok(struct winbindd_cli_state *state) char *oldpass, *newpass; fstring domain, user; CLI_POLICY_HND *hnd; + TALLOC_CTX *mem_ctx; + struct winbindd_domain *contact_domain; DEBUG(3, ("[%5lu]: pam chauthtok %s\n", (unsigned long)state->pid, state->request.data.chauthtok.user)); + if (!(mem_ctx = talloc_init("winbind password change for (utf8) %s", + state->request.data.chauthtok.user))) { + DEBUG(0, ("winbindd_pam_auth_crap: could not talloc_init()!\n")); + result = NT_STATUS_NO_MEMORY; + goto done; + } + /* Setup crap */ if (state == NULL) @@ -467,7 +494,7 @@ enum winbindd_result winbindd_pam_chauthtok(struct winbindd_cli_state *state) parse_domain_user(state->request.data.chauthtok.user, domain, user); - if (!find_domain_from_name(domain)) { + if (!(contact_domain = find_domain_from_name(domain))) { DEBUG(3, ("Cannot change password for [%s] -> [%s]\\[%s] as %s is not a trusted domain\n", state->request.data.chauthtok.user, domain, user, domain)); result = NT_STATUS_NO_SUCH_USER; @@ -481,17 +508,15 @@ enum winbindd_result winbindd_pam_chauthtok(struct winbindd_cli_state *state) /* Get sam handle */ - if ( NT_STATUS_IS_ERR(result = cm_get_sam_handle(domain, &hnd)) ) { + if ( NT_STATUS_IS_ERR(result = cm_get_sam_handle(contact_domain, &hnd)) ) { DEBUG(1, ("could not get SAM handle on DC for %s\n", domain)); goto done; } - if (!cli_oem_change_password(hnd->cli, user, newpass, oldpass)) { + if (!NT_STATUS_IS_OK(result = cli_samr_chgpasswd_user(hnd->cli, mem_ctx, + user, newpass, oldpass))) { DEBUG(1, ("password change failed for user %s/%s\n", domain, user)); - result = NT_STATUS_WRONG_PASSWORD; - } else { - result = NT_STATUS_OK; } done: @@ -507,5 +532,8 @@ done: state->response.data.auth.nt_status_string, state->response.data.auth.pam_error)); + if (mem_ctx) + talloc_destroy(mem_ctx); + return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR; } diff --git a/source3/nsswitch/winbindd_rpc.c b/source3/nsswitch/winbindd_rpc.c index 813621f3f7..f619aa3564 100644 --- a/source3/nsswitch/winbindd_rpc.c +++ b/source3/nsswitch/winbindd_rpc.c @@ -53,7 +53,7 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain, do { /* Get sam handle */ - if ( !NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd)) ) + if ( !NT_STATUS_IS_OK(result = cm_get_sam_handle(domain, &hnd)) ) return result; /* Get domain handle */ @@ -163,7 +163,7 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain, retry = 0; do { - if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd))) + if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain, &hnd))) return result; status = cli_samr_open_domain(hnd->cli, mem_ctx, @@ -228,7 +228,7 @@ static NTSTATUS enum_local_groups(struct winbindd_domain *domain, retry = 0; do { - if ( !NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd)) ) + if ( !NT_STATUS_IS_OK(result = cm_get_sam_handle(domain, &hnd)) ) return result; result = cli_samr_open_domain( hnd->cli, mem_ctx, &hnd->pol, @@ -300,7 +300,7 @@ static NTSTATUS name_to_sid(struct winbindd_domain *domain, retry = 0; do { - if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(domain->name, &hnd))) { + if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(domain, &hnd))) { return result; } @@ -340,7 +340,7 @@ static NTSTATUS sid_to_name(struct winbindd_domain *domain, retry = 0; do { - if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(domain->name, &hnd))) + if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(domain, &hnd))) return result; result = cli_lsa_lookup_sids(hnd->cli, mem_ctx, &hnd->pol, @@ -409,7 +409,7 @@ static NTSTATUS query_user(struct winbindd_domain *domain, do { /* Get sam handle; if we fail here there is no hope */ - if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd))) + if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain, &hnd))) goto done; /* Get domain handle */ @@ -510,7 +510,7 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain, do { /* Get sam handle; if we fail here there is no hope */ - if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd))) + if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain, &hnd))) goto done; /* Get domain handle */ @@ -598,7 +598,7 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, retry = 0; do { /* Get sam handle */ - if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd))) + if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain, &hnd))) goto done; /* Get domain handle */ @@ -876,7 +876,7 @@ static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq) } #endif /* HAVE_LDAP */ /* Get sam handle */ - if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd))) + if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain, &hnd))) goto done; /* Get domain handle */ @@ -932,7 +932,7 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain, retry = 0; do { - if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(lp_workgroup(), &hnd))) + if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(find_our_domain(), &hnd))) goto done; result = cli_lsa_enum_trust_dom(hnd->cli, mem_ctx, @@ -961,7 +961,7 @@ static NTSTATUS domain_sid(struct winbindd_domain *domain, DOM_SID *sid) retry = 0; do { /* Get lsa handle */ - if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(domain->name, &hnd))) + if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(domain, &hnd))) goto done; result = cli_lsa_query_info_policy(hnd->cli, mem_ctx, diff --git a/source3/nsswitch/winbindd_util.c b/source3/nsswitch/winbindd_util.c index 1f9537ac25..22192e4582 100644 --- a/source3/nsswitch/winbindd_util.c +++ b/source3/nsswitch/winbindd_util.c @@ -82,7 +82,6 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const DOM_SID *sid) { struct winbindd_domain *domain; - char *contact_name; const char *alternative_name = NULL; /* ignore alt_name if we are not in an AD domain */ @@ -135,12 +134,11 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const sid_copy(&domain->sid, sid); } - /* see if this is a native mode win2k domain (use realm name if possible) */ + /* see if this is a native mode win2k domain */ - contact_name = *domain->alt_name ? domain->alt_name : domain->name; - domain->native_mode = cm_check_for_native_mode_win2k( contact_name ); + domain->native_mode = cm_check_for_native_mode_win2k( domain ); - DEBUG(3,("add_trusted_domain: %s is a %s mode domain\n", contact_name, + DEBUG(3,("add_trusted_domain: %s is a %s mode domain\n", domain->name, domain->native_mode ? "native" : "mixed (or NT4)" )); /* Link to domain list */ @@ -298,7 +296,7 @@ BOOL init_domain_list(void) * * @note Do *not* pass lp_workgroup() to this function. domain_list * may modify it's value, and free that pointer. Instead, our local - * domain may be found by looking at the first entry in domain_list() + * domain may be found by calling find_our_domain(). * directly. * * |