diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/auth/auth.c | 1 | ||||
-rw-r--r-- | source3/auth/auth_domain.c | 137 | ||||
-rw-r--r-- | source3/libsmb/cli_netlogon.c | 13 | ||||
-rw-r--r-- | source3/libsmb/trust_passwd.c | 3 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_cm.c | 6 | ||||
-rw-r--r-- | source3/rpcclient/samsync.c | 2 | ||||
-rw-r--r-- | source3/utils/net_rpc_join.c | 4 |
7 files changed, 139 insertions, 27 deletions
diff --git a/source3/auth/auth.c b/source3/auth/auth.c index 9b78cec95b..e3af9dada6 100644 --- a/source3/auth/auth.c +++ b/source3/auth/auth.c @@ -31,6 +31,7 @@ const struct auth_init_function builtin_auth_init_functions[] = { { "unix", auth_init_unix }, { "smbserver", auth_init_smbserver }, { "ntdomain", auth_init_ntdomain }, + { "trustdomain", auth_init_trustdomain }, { "winbind", auth_init_winbind }, #ifdef DEVELOPER { "name_to_ntstatus", auth_init_name_to_ntstatus }, diff --git a/source3/auth/auth_domain.c b/source3/auth/auth_domain.c index 6c858e056c..b57bd2bfcc 100644 --- a/source3/auth/auth_domain.c +++ b/source3/auth/auth_domain.c @@ -38,7 +38,10 @@ extern userdom_struct current_user_info; **/ static NTSTATUS connect_to_domain_password_server(struct cli_state **cli, - char *server, unsigned char *trust_passwd) + const char *server, + const char *setup_creds_as, + uint16 sec_chan, + const unsigned char *trust_passwd) { struct in_addr dest_ip; fstring remote_machine; @@ -121,7 +124,13 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(*cli))); return NT_STATUS_UNSUCCESSFUL; } - result = new_cli_nt_setup_creds(*cli, trust_passwd); + snprintf((*cli)->mach_acct, sizeof((*cli)->mach_acct) - 1, "%s$", setup_creds_as); + + if (!(*cli)->mach_acct) { + return NT_STATUS_NO_MEMORY; + } + + result = new_cli_nt_setup_creds(*cli, sec_chan, trust_passwd); if (!NT_STATUS_IS_OK(result)) { DEBUG(0,("connect_to_domain_password_server: unable to setup the PDC credentials to machine \ @@ -142,7 +151,9 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(*cli))); static NTSTATUS attempt_connect_to_dc(struct cli_state **cli, const char *domain, struct in_addr *ip, - unsigned char *trust_passwd) + const char *setup_creds_as, + uint16 sec_chan, + const unsigned char *trust_passwd) { fstring dc_name; @@ -156,7 +167,7 @@ static NTSTATUS attempt_connect_to_dc(struct cli_state **cli, if (!lookup_dc_name(global_myname, domain, ip, dc_name)) return NT_STATUS_UNSUCCESSFUL; - return connect_to_domain_password_server(cli, dc_name, trust_passwd); + return connect_to_domain_password_server(cli, dc_name, setup_creds_as, sec_chan, trust_passwd); } /*********************************************************************** @@ -165,6 +176,8 @@ static NTSTATUS attempt_connect_to_dc(struct cli_state **cli, ************************************************************************/ static NTSTATUS find_connect_pdc(struct cli_state **cli, const char *domain, + const char *setup_creds_as, + uint16 sec_chan, unsigned char *trust_passwd, time_t last_change_time) { @@ -197,8 +210,10 @@ static NTSTATUS find_connect_pdc(struct cli_state **cli, if(!is_local_net(ip_list[i])) continue; - if(NT_STATUS_IS_OK(nt_status = attempt_connect_to_dc(cli, domain, - &ip_list[i], trust_passwd))) + if(NT_STATUS_IS_OK(nt_status = + attempt_connect_to_dc(cli, domain, + &ip_list[i], setup_creds_as, + sec_chan, trust_passwd))) break; zero_ip(&ip_list[i]); /* Tried and failed. */ @@ -211,9 +226,11 @@ static NTSTATUS find_connect_pdc(struct cli_state **cli, i = (sys_random() % count); if (!is_zero_ip(ip_list[i])) { - if (!NT_STATUS_IS_OK(nt_status = attempt_connect_to_dc(cli, domain, - &ip_list[i], trust_passwd))) - zero_ip(&ip_list[i]); /* Tried and failed. */ + if (!NT_STATUS_IS_OK(nt_status = + attempt_connect_to_dc(cli, domain, + &ip_list[i], setup_creds_as, + sec_chan, trust_passwd))) + zero_ip(&ip_list[i]); /* Tried and failed. */ } } @@ -231,7 +248,7 @@ static NTSTATUS find_connect_pdc(struct cli_state **cli, continue; if (NT_STATUS_IS_OK(nt_status = attempt_connect_to_dc(cli, domain, - &ip_list[i], trust_passwd))) + &ip_list[i], setup_creds_as, sec_chan, trust_passwd))) break; } } @@ -251,7 +268,9 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx, const char *domain, uchar chal[8], auth_serversupplied_info **server_info, - char *server, unsigned char *trust_passwd, + char *server, char *setup_creds_as, + uint16 sec_chan, + unsigned char *trust_passwd, time_t last_change_time) { fstring remote_machine; @@ -271,9 +290,9 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx, while (!NT_STATUS_IS_OK(nt_status) && next_token(&server,remote_machine,LIST_SEP,sizeof(remote_machine))) { if(strequal(remote_machine, "*")) { - nt_status = find_connect_pdc(&cli, domain, trust_passwd, last_change_time); + nt_status = find_connect_pdc(&cli, domain, setup_creds_as, sec_chan, trust_passwd, last_change_time); } else { - nt_status = connect_to_domain_password_server(&cli, remote_machine, trust_passwd); + nt_status = connect_to_domain_password_server(&cli, remote_machine, setup_creds_as, sec_chan, trust_passwd); } } @@ -429,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_domain_security: could not fetch trust account password for domain %s\n", lp_workgroup())); + DEBUG(0, ("check_ntdomain_security: could not fetch trust account password for domain %s\n", lp_workgroup())); return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; } @@ -449,8 +468,7 @@ static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context, nt_status = domain_client_validate(mem_ctx, user_info, domain, (uchar *)auth_context->challenge.data, server_info, - password_server, trust_passwd, last_change_time); - + password_server, global_myname, SEC_CHAN_WKSTA, trust_passwd, last_change_time); return nt_status; } @@ -464,3 +482,90 @@ BOOL auth_init_ntdomain(struct auth_context *auth_context, auth_methods **auth_m (*auth_method)->auth = check_ntdomain_security; return True; } + + +/**************************************************************************** + Check for a valid username and password in a trusted domain +****************************************************************************/ + +static NTSTATUS check_trustdomain_security(const struct auth_context *auth_context, + void *my_private_data, + TALLOC_CTX *mem_ctx, + const auth_usersupplied_info *user_info, + auth_serversupplied_info **server_info) +{ + NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE; + unsigned char trust_md4_password[16]; + char *trust_password; + time_t last_change_time; + DOM_SID sid; + + if (!user_info || !server_info || !auth_context) { + DEBUG(1,("check_trustdomain_security: Critical variables not present. Failing.\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + /* + * Check that the requested domain is not our own machine name. + * If it is, we should never check the PDC here, we use our own local + * password file. + */ + + if(is_netbios_alias_or_name(user_info->domain.str)) { + DEBUG(3,("check_trustdomain_security: Requested domain was for this machine.\n")); + return NT_STATUS_LOGON_FAILURE; + } + + /* + * Check that the requested domain is not our own domain, + * If it is, we should use our own local password file. + */ + + if(strequal(lp_workgroup(), (user_info->domain.str))) { + DEBUG(3,("check_trustdomain_security: Requested domain was for this domain.\n")); + return NT_STATUS_LOGON_FAILURE; + } + + /* + * Get the machine account password for the trusted domain + * No need to become_root() as secrets_init() is done at startup. + */ + + if (!secrets_fetch_trusted_domain_password(user_info->domain.str, &trust_password, &sid, &last_change_time)) + { + DEBUG(0, ("check_trustdomain_security: could not fetch trust account password for domain %s\n", user_info->domain.str)); + return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; + } + +#ifdef DEBUG_PASSWORD + DEBUG(100, ("Trust password for domain %s is %s\n", user_info->domain.str, trust_password)); +#endif + E_md4hash((uchar *)trust_password, trust_md4_password); + SAFE_FREE(trust_password); + +#if 0 + /* Test if machine password is expired and need to be changed */ + if (time(NULL) > last_change_time + lp_machine_password_timeout()) + { + global_machine_password_needs_changing = True; + } +#endif + + nt_status = domain_client_validate(mem_ctx, user_info, user_info->domain.str, + (uchar *)auth_context->challenge.data, + server_info, "*" /* Do a lookup */, + lp_workgroup(), SEC_CHAN_DOMAIN, trust_md4_password, last_change_time); + + return nt_status; +} + +/* module initialisation */ +BOOL auth_init_trustdomain(struct auth_context *auth_context, auth_methods **auth_method) +{ + if (!make_auth_methods(auth_context, auth_method)) { + return False; + } + + (*auth_method)->auth = check_trustdomain_security; + return True; +} diff --git a/source3/libsmb/cli_netlogon.c b/source3/libsmb/cli_netlogon.c index d550c3e9fa..590f5f525e 100644 --- a/source3/libsmb/cli_netlogon.c +++ b/source3/libsmb/cli_netlogon.c @@ -93,14 +93,15 @@ Ensure that the server credential returned matches the session key encrypt of the server challenge originally received. JRA. ****************************************************************************/ -NTSTATUS new_cli_net_auth2(struct cli_state *cli, uint16 sec_chan, +NTSTATUS new_cli_net_auth2(struct cli_state *cli, + uint16 sec_chan, uint32 neg_flags, DOM_CHAL *srv_chal) { prs_struct qbuf, rbuf; NET_Q_AUTH_2 q; NET_R_AUTH_2 r; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - extern pstring global_myname; + extern pstring global_myname; prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); @@ -163,7 +164,8 @@ password ?).\n", cli->desthost )); /* Initialize domain session credentials */ NTSTATUS new_cli_nt_setup_creds(struct cli_state *cli, - unsigned char mach_pwd[16]) + uint16 sec_chan, + const unsigned char mach_pwd[16]) { DOM_CHAL clnt_chal; DOM_CHAL srv_chal; @@ -185,7 +187,7 @@ NTSTATUS new_cli_nt_setup_creds(struct cli_state *cli, /**************** Long-term Session key **************/ /* calculate the session key */ - cred_session_key(&clnt_chal, &srv_chal, (char *)mach_pwd, + cred_session_key(&clnt_chal, &srv_chal, mach_pwd, cli->sess_key); memset((char *)cli->sess_key+8, '\0', 8); @@ -201,8 +203,7 @@ NTSTATUS new_cli_nt_setup_creds(struct cli_state *cli, * Receive an auth-2 challenge response and check it. */ - result = new_cli_net_auth2(cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ? - SEC_CHAN_WKSTA : SEC_CHAN_BDC, 0x000001ff, + result = new_cli_net_auth2(cli, sec_chan, 0x000001ff, &srv_chal); if (!NT_STATUS_IS_OK(result)) { DEBUG(0,("cli_nt_setup_creds: auth2 challenge failed %s\n", diff --git a/source3/libsmb/trust_passwd.c b/source3/libsmb/trust_passwd.c index 069be7f15e..1f52ab3611 100644 --- a/source3/libsmb/trust_passwd.c +++ b/source3/libsmb/trust_passwd.c @@ -35,7 +35,8 @@ static NTSTATUS just_change_the_password(struct cli_state *cli, TALLOC_CTX *mem_ unsigned char new_trust_passwd_hash[16]) { NTSTATUS result; - result = new_cli_nt_setup_creds(cli, orig_trust_passwd_hash); + result = new_cli_nt_setup_creds(cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ? + SEC_CHAN_WKSTA : SEC_CHAN_BDC, orig_trust_passwd_hash); if (!NT_STATUS_IS_OK(result)) { DEBUG(0,("just_change_the_password: unable to setup creds (%s)!\n", diff --git a/source3/nsswitch/winbindd_cm.c b/source3/nsswitch/winbindd_cm.c index dcbd47303f..6ac682fbab 100644 --- a/source3/nsswitch/winbindd_cm.c +++ b/source3/nsswitch/winbindd_cm.c @@ -766,7 +766,8 @@ NTSTATUS cm_get_netlogon_cli(char *domain, unsigned char *trust_passwd, return result; } - result = new_cli_nt_setup_creds(conn->cli, trust_passwd); + result = new_cli_nt_setup_creds(conn->cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ? + SEC_CHAN_WKSTA : SEC_CHAN_BDC, trust_passwd); if (!NT_STATUS_IS_OK(result)) { DEBUG(0, ("error connecting to domain password server: %s\n", @@ -779,7 +780,8 @@ NTSTATUS cm_get_netlogon_cli(char *domain, unsigned char *trust_passwd, } /* Try again */ - result = new_cli_nt_setup_creds(conn->cli, trust_passwd); + result = new_cli_nt_setup_creds(conn->cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ? + SEC_CHAN_WKSTA : SEC_CHAN_BDC, trust_passwd); } if (!NT_STATUS_IS_OK(result)) { diff --git a/source3/rpcclient/samsync.c b/source3/rpcclient/samsync.c index 3a0bc2d6f6..d09ae775ec 100644 --- a/source3/rpcclient/samsync.c +++ b/source3/rpcclient/samsync.c @@ -278,7 +278,7 @@ static NTSTATUS sam_sync(struct cli_state *cli, unsigned char trust_passwd[16], /* Request a challenge */ - if (!NT_STATUS_IS_OK(new_cli_nt_setup_creds(cli, trust_passwd))) { + if (!NT_STATUS_IS_OK(new_cli_nt_setup_creds(cli, SEC_CHAN_BDC, trust_passwd))) { DEBUG(0, ("Error initialising session creds\n")); goto done; } diff --git a/source3/utils/net_rpc_join.c b/source3/utils/net_rpc_join.c index 2fde6291c2..86a00eb9af 100644 --- a/source3/utils/net_rpc_join.c +++ b/source3/utils/net_rpc_join.c @@ -273,7 +273,9 @@ int net_rpc_join(int argc, const char **argv) goto done; } - CHECK_RPC_ERR(new_cli_nt_setup_creds(cli, stored_md4_trust_password), + CHECK_RPC_ERR(new_cli_nt_setup_creds(cli, + (acb_info & ACB_SVRTRUST) ? SEC_CHAN_BDC : SEC_CHAN_WKSTA, + stored_md4_trust_password), "error in domain join verification"); retval = 0; /* Success! */ |