diff options
Diffstat (limited to 'source3/auth/auth_domain.c')
-rw-r--r-- | source3/auth/auth_domain.c | 118 |
1 files changed, 77 insertions, 41 deletions
diff --git a/source3/auth/auth_domain.c b/source3/auth/auth_domain.c index 3352c5f9c8..af353ef812 100644 --- a/source3/auth/auth_domain.c +++ b/source3/auth/auth_domain.c @@ -21,9 +21,6 @@ #include "includes.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_AUTH - BOOL global_machine_password_needs_changing = False; extern pstring global_myname; @@ -69,7 +66,7 @@ static NTSTATUS connect_to_domain_password_server(struct cli_state **cli, fstrcpy(remote_machine, server); } - standard_sub_basic(current_user_info.smb_name, remote_machine, sizeof(remote_machine)); + standard_sub_basic(current_user_info.smb_name, remote_machine); strupper(remote_machine); if(!resolve_name( remote_machine, &dest_ip, 0x20)) { @@ -87,25 +84,21 @@ static NTSTATUS connect_to_domain_password_server(struct cli_state **cli, logonserver. We can avoid a 30-second timeout if the DC is down if the SAMLOGON request fails as it is only over UDP. */ - /* we use a mutex to prevent two connections at once - when a - Win2k PDC get two connections where one hasn't completed a - session setup yet it will send a TCP reset to the first - connection (tridge) */ - - /* - * With NT4.x DC's *all* authentication must be serialized to avoid - * ACCESS_DENIED errors if 2 auths are done from the same machine. JRA. - */ - - if (!grab_server_mutex(server)) + /* we use a mutex to prevent two connections at once - when a NT PDC gets + two connections where one hasn't completed a negprot yet it will send a + TCP reset to the first connection (tridge) */ + if (!message_named_mutex(server, 20)) { + DEBUG(1,("connect_to_domain_password_server: domain mutex failed for %s\n", server)); return NT_STATUS_UNSUCCESSFUL; + } /* Attempt connection */ result = cli_full_connection(cli, global_myname, server, &dest_ip, 0, "IPC$", "IPC", "", "", "", 0); + message_named_mutex_release(server); + if (!NT_STATUS_IS_OK(result)) { - release_server_mutex(); return result; } @@ -128,14 +121,12 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(*cli))); cli_nt_session_close(*cli); cli_ulogoff(*cli); cli_shutdown(*cli); - release_server_mutex(); return NT_STATUS_UNSUCCESSFUL; } snprintf((*cli)->mach_acct, sizeof((*cli)->mach_acct) - 1, "%s$", setup_creds_as); if (!(*cli)->mach_acct) { - release_server_mutex(); return NT_STATUS_NO_MEMORY; } @@ -147,12 +138,9 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(*cli))); cli_nt_session_close(*cli); cli_ulogoff(*cli); cli_shutdown(*cli); - release_server_mutex(); return result; } - /* We exit here with the mutex *locked*. JRA */ - return NT_STATUS_OK; } @@ -282,13 +270,14 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx, auth_serversupplied_info **server_info, char *server, char *setup_creds_as, uint16 sec_chan, - unsigned char trust_passwd[16], + unsigned char *trust_passwd, time_t last_change_time) { fstring remote_machine; NET_USER_INFO_3 info3; struct cli_state *cli = NULL; NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + struct passwd *pass; /* * At this point, smb_apasswd points to the lanman response to @@ -332,15 +321,63 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx, user_info->domain.str, cli->srv_name_slash, nt_errstr(nt_status))); } else { - nt_status = make_server_info_info3(mem_ctx, user_info->internal_username.str, - user_info->smb_name.str, domain, server_info, &info3); -#if 0 - /* The stuff doesn't work right yet */ - SMB_ASSERT(sizeof((*server_info)->session_key) == sizeof(info3.user_sess_key)); - memcpy((*server_info)->session_key, info3.user_sess_key, sizeof((*server_info)->session_key)/* 16 */); - SamOEMhash((*server_info)->session_key, trust_passwd, sizeof((*server_info)->session_key)); -#endif + char *dom_user; + + /* Check DOMAIN\username first to catch winbind users, then + just the username for local users. */ + + dom_user = talloc_asprintf(mem_ctx, "%s%s%s", user_info->domain.str, + lp_winbind_separator(), + user_info->internal_username.str); + + if (!dom_user) { + DEBUG(0, ("talloc_asprintf failed!\n")); + nt_status = NT_STATUS_NO_MEMORY; + } else { + + if (!(pass = Get_Pwnam(dom_user))) + pass = Get_Pwnam(user_info->internal_username.str); + + if (pass) { + make_server_info_pw(server_info, pass); + if (!server_info) { + nt_status = NT_STATUS_NO_MEMORY; + } + } else { + nt_status = NT_STATUS_NO_SUCH_USER; + } + } + } + /* Store the user group information in the server_info returned to the caller. */ + + if (NT_STATUS_IS_OK(nt_status) && (info3.num_groups2 != 0)) { + int i; + NT_USER_TOKEN *ptok; + auth_serversupplied_info *pserver_info = *server_info; + + if ((pserver_info->ptok = malloc( sizeof(NT_USER_TOKEN) ) ) == NULL) { + DEBUG(0, ("domain_client_validate: out of memory allocating rid group membership\n")); + nt_status = NT_STATUS_NO_MEMORY; + free_server_info(server_info); + goto done; + } + + ptok = pserver_info->ptok; + ptok->num_sids = (size_t)info3.num_groups2; + + if ((ptok->user_sids = (DOM_SID *)malloc( sizeof(DOM_SID) * ptok->num_sids )) == NULL) { + DEBUG(0, ("domain_client_validate: Out of memory allocating group SIDS\n")); + nt_status = NT_STATUS_NO_MEMORY; + free_server_info(server_info); + goto done; + } + + for (i = 0; i < ptok->num_sids; i++) { + sid_copy(&ptok->user_sids[i], &info3.dom_sid.sid); + sid_append_rid(&ptok->user_sids[i], info3.gids[i].g_rid); + } + uni_group_cache_store_netlogon(mem_ctx, &info3); } @@ -360,6 +397,8 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx, } #endif /* 0 */ + done: + /* Note - once the cli stream is shutdown the mem_ctx used to allocate the other_sids and gids structures has been deleted - so these pointers are no longer valid..... */ @@ -367,7 +406,6 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx, cli_nt_session_close(cli); cli_ulogoff(cli); cli_shutdown(cli); - release_server_mutex(); return nt_status; } @@ -410,7 +448,7 @@ static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context, if (!secrets_fetch_trust_account_password(domain, trust_passwd, &last_change_time)) { - DEBUG(0, ("check_ntdomain_security: could not fetch trust account password for domain '%s'\n", domain)); + DEBUG(0, ("check_ntdomain_security: could not fetch trust account password for domain %s\n", lp_workgroup())); return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; } @@ -435,15 +473,14 @@ static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context, } /* module initialisation */ -NTSTATUS auth_init_ntdomain(struct auth_context *auth_context, const char* param, auth_methods **auth_method) +BOOL auth_init_ntdomain(struct auth_context *auth_context, auth_methods **auth_method) { if (!make_auth_methods(auth_context, auth_method)) { - return NT_STATUS_NO_MEMORY; + return False; } - (*auth_method)->name = "ntdomain"; (*auth_method)->auth = check_ntdomain_security; - return NT_STATUS_OK; + return True; } @@ -490,7 +527,7 @@ static NTSTATUS check_trustdomain_security(const struct auth_context *auth_conte } /* - * Get the trusted account password for the trusted domain + * Get the machine account password for the trusted domain * No need to become_root() as secrets_init() is done at startup. */ @@ -523,13 +560,12 @@ static NTSTATUS check_trustdomain_security(const struct auth_context *auth_conte } /* module initialisation */ -NTSTATUS auth_init_trustdomain(struct auth_context *auth_context, const char* param, auth_methods **auth_method) +BOOL auth_init_trustdomain(struct auth_context *auth_context, auth_methods **auth_method) { if (!make_auth_methods(auth_context, auth_method)) { - return NT_STATUS_NO_MEMORY; + return False; } - (*auth_method)->name = "trustdomain"; (*auth_method)->auth = check_trustdomain_security; - return NT_STATUS_OK; + return True; } |