diff options
author | Andrew Bartlett <abartlet@samba.org> | 2003-04-21 14:09:03 +0000 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2003-04-21 14:09:03 +0000 |
commit | f071020f5e49837154581c97c5af5f84d0e2de89 (patch) | |
tree | 14c4f4c08cc935145926000a886f8dd718c66e93 | |
parent | 06c99d15e217e265d51778268d5b859dff3c478c (diff) | |
download | samba-f071020f5e49837154581c97c5af5f84d0e2de89.tar.gz samba-f071020f5e49837154581c97c5af5f84d0e2de89.tar.bz2 samba-f071020f5e49837154581c97c5af5f84d0e2de89.zip |
Merge from HEAD - save the type of channel used to contact the DC.
This allows us to join as a BDC, without appearing on the network as one
until we have the database replicated, and the admin changes the configuration.
This also change the SID retreval order from secrets.tdb, so we no longer
require a 'net rpc getsid' - the sid fetch during the domain join is sufficient.
Also minor fixes to 'net'.
Andrew Bartlett
(This used to be commit 876e00fd112e4aaf7519eec27f382eb99ec7562a)
-rw-r--r-- | source3/auth/auth_domain.c | 10 | ||||
-rw-r--r-- | source3/include/secrets.h | 4 | ||||
-rw-r--r-- | source3/libads/kerberos_verify.c | 2 | ||||
-rw-r--r-- | source3/libads/ldap.c | 8 | ||||
-rw-r--r-- | source3/libads/util.c | 8 | ||||
-rw-r--r-- | source3/libsmb/trust_passwd.c | 32 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_ads.c | 2 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_cm.c | 8 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_misc.c | 7 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_pam.c | 19 | ||||
-rw-r--r-- | source3/param/loadparm.c | 1 | ||||
-rw-r--r-- | source3/passdb/machine_sid.c | 15 | ||||
-rw-r--r-- | source3/passdb/secrets.c | 102 | ||||
-rw-r--r-- | source3/rpc_client/cli_netlogon.c | 18 | ||||
-rw-r--r-- | source3/rpcclient/cmd_netlogon.c | 10 | ||||
-rw-r--r-- | source3/rpcclient/rpcclient.c | 5 | ||||
-rw-r--r-- | source3/smbd/change_trust_pw.c | 95 | ||||
-rw-r--r-- | source3/smbd/process.c | 6 | ||||
-rw-r--r-- | source3/utils/net.c | 32 | ||||
-rw-r--r-- | source3/utils/net.h | 2 | ||||
-rw-r--r-- | source3/utils/net_ads.c | 17 | ||||
-rw-r--r-- | source3/utils/net_rpc.c | 85 | ||||
-rw-r--r-- | source3/utils/net_rpc_join.c | 62 | ||||
-rw-r--r-- | source3/utils/net_rpc_samsync.c | 11 |
24 files changed, 360 insertions, 201 deletions
diff --git a/source3/auth/auth_domain.c b/source3/auth/auth_domain.c index 24a5bb562c..e49a41763b 100644 --- a/source3/auth/auth_domain.c +++ b/source3/auth/auth_domain.c @@ -347,6 +347,11 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx, "Error was %s.\n", user_info->smb_name.str, user_info->domain.str, cli->srv_name_slash, nt_errstr(nt_status))); + + /* map to something more useful */ + if (NT_STATUS_EQUAL(nt_status, NT_STATUS_UNSUCCESSFUL)) { + nt_status = NT_STATUS_NO_LOGON_SERVERS; + } } else { nt_status = make_server_info_info3(mem_ctx, user_info->internal_username.str, user_info->smb_name.str, domain, server_info, &info3); @@ -395,6 +400,7 @@ static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context, unsigned char trust_passwd[16]; time_t last_change_time; const char *domain = lp_workgroup(); + uint32 sec_channel_type = 0; if (!user_info || !server_info || !auth_context) { DEBUG(1,("check_ntdomain_security: Critical variables not present. Failing.\n")); @@ -417,7 +423,7 @@ static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context, * No need to become_root() as secrets_init() is done at startup. */ - if (!secrets_fetch_trust_account_password(domain, trust_passwd, &last_change_time)) + if (!secrets_fetch_trust_account_password(domain, trust_passwd, &last_change_time, &sec_channel_type)) { DEBUG(0, ("check_ntdomain_security: could not fetch trust account password for domain '%s'\n", domain)); return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; @@ -442,7 +448,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, global_myname(), SEC_CHAN_WKSTA, trust_passwd, last_change_time); + password_server, global_myname(), sec_channel_type,trust_passwd, last_change_time); return nt_status; } diff --git a/source3/include/secrets.h b/source3/include/secrets.h index 183b29d7a8..84db527065 100644 --- a/source3/include/secrets.h +++ b/source3/include/secrets.h @@ -26,7 +26,9 @@ */ #define SECRETS_MACHINE_ACCT_PASS "SECRETS/$MACHINE.ACC" #define SECRETS_MACHINE_PASSWORD "SECRETS/MACHINE_PASSWORD" - +#define SECRETS_MACHINE_LAST_CHANGE_TIME "SECRETS/MACHINE_LAST_CHANGE_TIME" +#define SECRETS_MACHINE_SEC_CHANNEL_TYPE "SECRETS/MACHINE_SEC_CHANNEL_TYPE" +#define SECRETS_MACHINE_TRUST_ACCOUNT_NAME "SECRETS/SECRETS_MACHINE_TRUST_ACCOUNT_NAME" /* this one is for storing trusted domain account password */ #define SECRETS_DOMTRUST_ACCT_PASS "SECRETS/$DOMTRUST.ACC" diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 6a50137400..35d429ca2a 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -53,7 +53,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, return NT_STATUS_LOGON_FAILURE; } - password_s = secrets_fetch_machine_password(); + password_s = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL); if (!password_s) { DEBUG(1,("failed to fetch machine password\n")); return NT_STATUS_LOGON_FAILURE; diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index baedfb28db..3ce80975da 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1024,6 +1024,7 @@ char *ads_ou_string(const char *org_unit) add a machine account to the ADS server */ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, + uint32 account_type, const char *org_unit) { ADS_STATUS ret, status; @@ -1073,7 +1074,7 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, if (!(samAccountName = talloc_asprintf(ctx, "%s$", hostname))) goto done; - acct_control = UF_WORKSTATION_TRUST_ACCOUNT | UF_DONT_EXPIRE_PASSWD; + acct_control = account_type | UF_DONT_EXPIRE_PASSWD; #ifndef ENCTYPE_ARCFOUR_HMAC acct_control |= UF_USE_DES_KEY_ONLY; #endif @@ -1335,7 +1336,8 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) * @param org_unit Organizational unit to place machine in * @return status of join **/ -ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *hostname, const char *org_unit) +ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *hostname, + uint32 account_type, const char *org_unit) { ADS_STATUS status; LDAPMessage *res; @@ -1356,7 +1358,7 @@ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *hostname, const char *org } } - status = ads_add_machine_acct(ads, host, org_unit); + status = ads_add_machine_acct(ads, host, account_type, org_unit); if (!ADS_ERR_OK(status)) { DEBUG(0, ("ads_add_machine_acct: %s\n", ads_errstr(status))); return status; diff --git a/source3/libads/util.c b/source3/libads/util.c index 335cabc952..9912a7ba83 100644 --- a/source3/libads/util.c +++ b/source3/libads/util.c @@ -29,21 +29,23 @@ ADS_STATUS ads_change_trust_account_password(ADS_STRUCT *ads, char *host_princip char *new_password; char *service_principal; ADS_STATUS ret; - - if ((password = secrets_fetch_machine_password()) == NULL) { + uint32 sec_channel_type; + + if ((password = secrets_fetch_machine_password(lp_workgroup(), NULL, &sec_channel_type)) == NULL) { DEBUG(1,("Failed to retrieve password for principal %s\n", host_principal)); return ADS_ERROR_SYSTEM(ENOENT); } tmp_password = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH); new_password = strdup(tmp_password); + asprintf(&service_principal, "HOST/%s", host_principal); ret = kerberos_set_password(ads->auth.kdc_server, service_principal, password, service_principal, new_password, ads->auth.time_offset); if (!ADS_ERR_OK(ret)) goto failed; - if (!secrets_store_machine_password(new_password)) { + if (!secrets_store_machine_password(new_password, lp_workgroup(), sec_channel_type)) { DEBUG(1,("Failed to save machine password\n")); return ADS_ERROR_SYSTEM(EACCES); } diff --git a/source3/libsmb/trust_passwd.c b/source3/libsmb/trust_passwd.c index cf9fd58b13..0d015128a6 100644 --- a/source3/libsmb/trust_passwd.c +++ b/source3/libsmb/trust_passwd.c @@ -1,7 +1,7 @@ /* * Unix SMB/CIFS implementation. - * Routines to change trust account passwords. - * Copyright (C) Andrew Bartlett 2001. + * Routines to operate on various trust relationships + * Copyright (C) Andrew Bartlett 2001 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,12 +30,13 @@ **********************************************************/ static NTSTATUS just_change_the_password(struct cli_state *cli, TALLOC_CTX *mem_ctx, unsigned char orig_trust_passwd_hash[16], - unsigned char new_trust_passwd_hash[16]) + unsigned char new_trust_passwd_hash[16], + uint32 sec_channel_type) { NTSTATUS result; uint32 neg_flags = 0x000001ff; - result = cli_nt_setup_creds(cli, get_sec_chan(), orig_trust_passwd_hash, &neg_flags, 2); + result = cli_nt_setup_creds(cli, sec_channel_type, orig_trust_passwd_hash, &neg_flags, 2); if (!NT_STATUS_IS_OK(result)) { DEBUG(1,("just_change_the_password: unable to setup creds (%s)!\n", @@ -59,7 +60,9 @@ static NTSTATUS just_change_the_password(struct cli_state *cli, TALLOC_CTX *mem_ **********************************************************/ NTSTATUS trust_pw_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx, - unsigned char orig_trust_passwd_hash[16]) + const char *domain, + unsigned char orig_trust_passwd_hash[16], + uint32 sec_channel_type) { unsigned char new_trust_passwd_hash[16]; char *new_trust_passwd; @@ -73,7 +76,7 @@ NTSTATUS trust_pw_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx E_md4hash(new_trust_passwd, new_trust_passwd_hash); nt_status = just_change_the_password(cli, mem_ctx, orig_trust_passwd_hash, - new_trust_passwd_hash); + new_trust_passwd_hash, sec_channel_type); if (NT_STATUS_IS_OK(nt_status)) { DEBUG(3,("%s : trust_pw_change_and_store_it: Changed password.\n", @@ -82,7 +85,7 @@ NTSTATUS trust_pw_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx * Return the result of trying to write the new password * back into the trust account file. */ - if (!secrets_store_machine_password(new_trust_passwd)) { + if (!secrets_store_machine_password(new_trust_passwd, domain, sec_channel_type)) { nt_status = NT_STATUS_UNSUCCESSFUL; } } @@ -96,21 +99,26 @@ NTSTATUS trust_pw_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx already setup the connection to the NETLOGON pipe **********************************************************/ -NTSTATUS trust_pw_find_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx, +NTSTATUS trust_pw_find_change_and_store_it(struct cli_state *cli, + TALLOC_CTX *mem_ctx, const char *domain) { unsigned char old_trust_passwd_hash[16]; char *up_domain; - + uint32 sec_channel_type = 0; + up_domain = talloc_strdup(mem_ctx, domain); if (!secrets_fetch_trust_account_password(domain, old_trust_passwd_hash, - NULL)) { + NULL, &sec_channel_type)) { DEBUG(0, ("could not fetch domain secrets for domain %s!\n", domain)); return NT_STATUS_UNSUCCESSFUL; } - return trust_pw_change_and_store_it(cli, mem_ctx, old_trust_passwd_hash); + return trust_pw_change_and_store_it(cli, mem_ctx, domain, + old_trust_passwd_hash, + sec_channel_type); -} +} + diff --git a/source3/nsswitch/winbindd_ads.c b/source3/nsswitch/winbindd_ads.c index f6fc3a8d6c..63dc90bc28 100644 --- a/source3/nsswitch/winbindd_ads.c +++ b/source3/nsswitch/winbindd_ads.c @@ -55,7 +55,7 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain) /* the machine acct password might have change - fetch it every time */ SAFE_FREE(ads->auth.password); - ads->auth.password = secrets_fetch_machine_password(); + ads->auth.password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL); if (primary_realm) { SAFE_FREE(ads->auth.realm); diff --git a/source3/nsswitch/winbindd_cm.c b/source3/nsswitch/winbindd_cm.c index 706408901e..7502f3696b 100644 --- a/source3/nsswitch/winbindd_cm.c +++ b/source3/nsswitch/winbindd_cm.c @@ -853,7 +853,9 @@ CLI_POLICY_HND *cm_get_sam_group_handle(char *domain, DOM_SID *domain_sid, /* 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, const unsigned char *trust_passwd, +NTSTATUS cm_get_netlogon_cli(const char *domain, + const unsigned char *trust_passwd, + uint32 sec_channel_type, struct cli_state **cli) { NTSTATUS result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; @@ -876,7 +878,7 @@ NTSTATUS cm_get_netlogon_cli(const char *domain, const unsigned char *trust_pass DEBUG(0,("cm_get_netlogon_cli: mutex grab failed for %s\n", conn->controller)); } - result = cli_nt_setup_creds(conn->cli, get_sec_chan(), trust_passwd, &neg_flags, 2); + result = cli_nt_setup_creds(conn->cli, sec_channel_type, trust_passwd, &neg_flags, 2); if (got_mutex) secrets_named_mutex_release(lock_name); @@ -896,7 +898,7 @@ NTSTATUS cm_get_netlogon_cli(const char *domain, const unsigned char *trust_pass } /* Try again */ - result = cli_nt_setup_creds( conn->cli, get_sec_chan(),trust_passwd, &neg_flags, 2); + result = cli_nt_setup_creds( conn->cli, sec_channel_type,trust_passwd, &neg_flags, 2); if (got_mutex) secrets_named_mutex_release(lock_name); diff --git a/source3/nsswitch/winbindd_misc.c b/source3/nsswitch/winbindd_misc.c index 52889e85d4..fb56d0e657 100644 --- a/source3/nsswitch/winbindd_misc.c +++ b/source3/nsswitch/winbindd_misc.c @@ -34,13 +34,14 @@ enum winbindd_result winbindd_check_machine_acct(struct winbindd_cli_state *stat uchar trust_passwd[16]; int num_retries = 0; struct cli_state *cli; + uint32 sec_channel_type; DEBUG(3, ("[%5d]: check machine account\n", state->pid)); /* Get trust account password */ again: if (!secrets_fetch_trust_account_password( - lp_workgroup(), trust_passwd, NULL)) { + lp_workgroup(), trust_passwd, NULL, &sec_channel_type)) { result = NT_STATUS_INTERNAL_ERROR; goto done; } @@ -49,7 +50,7 @@ enum winbindd_result winbindd_check_machine_acct(struct winbindd_cli_state *stat the trust account password. */ /* Don't shut this down - it belongs to the connection cache code */ - result = cm_get_netlogon_cli(lp_workgroup(), trust_passwd, &cli); + result = cm_get_netlogon_cli(lp_workgroup(), trust_passwd, sec_channel_type, &cli); if (!NT_STATUS_IS_OK(result)) { DEBUG(3, ("could not open handle to NETLOGON pipe\n")); @@ -234,7 +235,7 @@ enum winbindd_result winbindd_netbios_name(struct winbindd_cli_state *state) return WINBINDD_OK; } -/* What's my name again? */ +/* Where can I find the privilaged pipe? */ enum winbindd_result winbindd_priv_pipe_dir(struct winbindd_cli_state *state) { diff --git a/source3/nsswitch/winbindd_pam.c b/source3/nsswitch/winbindd_pam.c index e49a95f4b8..2998372bd2 100644 --- a/source3/nsswitch/winbindd_pam.c +++ b/source3/nsswitch/winbindd_pam.c @@ -61,7 +61,7 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state) fstring name_domain, name_user; unsigned char trust_passwd[16]; time_t last_change_time; - uint32 smb_uid_low; + uint32 sec_channel_type; NET_USER_INFO_3 info3; struct cli_state *cli = NULL; uchar chal[8]; @@ -111,21 +111,20 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state) */ if (!secrets_fetch_trust_account_password( - lp_workgroup(), trust_passwd, &last_change_time)) { + lp_workgroup(), trust_passwd, &last_change_time, + &sec_channel_type)) { DEBUG(0, ("winbindd_pam_auth: could not fetch trust account " "password for domain %s\n", lp_workgroup())); result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; goto done; } - /* We really don't care what LUID we give the user. */ - - generate_random_buffer( (unsigned char *)&smb_uid_low, 4, False); - ZERO_STRUCT(info3); /* Don't shut this down - it belongs to the connection cache code */ - result = cm_get_netlogon_cli(lp_workgroup(), trust_passwd, &cli); + result = cm_get_netlogon_cli(lp_workgroup(), trust_passwd, + sec_channel_type, + &cli); if (!NT_STATUS_IS_OK(result)) { DEBUG(3, ("could not open handle to NETLOGON pipe\n")); @@ -169,6 +168,7 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state) NTSTATUS result; unsigned char trust_passwd[16]; time_t last_change_time; + uint32 sec_channel_type; NET_USER_INFO_3 info3; struct cli_state *cli = NULL; TALLOC_CTX *mem_ctx = NULL; @@ -256,7 +256,8 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state) */ if (!secrets_fetch_trust_account_password ( - contact_domain, trust_passwd, &last_change_time)) { + contact_domain, trust_passwd, &last_change_time, + &sec_channel_type)) { DEBUG(0, ("winbindd_pam_auth: could not fetch trust account " "password for domain %s\n", contact_domain)); result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; @@ -266,7 +267,7 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state) ZERO_STRUCT(info3); /* Don't shut this down - it belongs to the connection cache code */ - result = cm_get_netlogon_cli(contact_domain, trust_passwd, &cli); + result = cm_get_netlogon_cli(contact_domain, trust_passwd, sec_channel_type, &cli); if (!NT_STATUS_IS_OK(result)) { DEBUG(3, ("could not open handle to NETLOGON pipe (error: %s)\n", nt_errstr(result))); diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 3d5713d678..a89330fd5b 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -2031,6 +2031,7 @@ BOOL lp_add_home(const char *pszHomename, int iDefaultService, } else { pstrcpy(newHomedir, lp_pathname(iDefaultService)); string_sub(newHomedir,"%H", pszHomedir, sizeof(newHomedir)); + string_sub(newHomedir,"%S", pszHomename, sizeof(newHomedir)); } string_set(&ServicePtrs[i]->szPath, newHomedir); diff --git a/source3/passdb/machine_sid.c b/source3/passdb/machine_sid.c index 071af50877..a578ecc711 100644 --- a/source3/passdb/machine_sid.c +++ b/source3/passdb/machine_sid.c @@ -78,6 +78,7 @@ static void generate_random_sid(DOM_SID *sid) static BOOL pdb_generate_sam_sid(void) { + DOM_SID domain_sid; char *fname = NULL; BOOL is_dc = False; @@ -97,8 +98,14 @@ static BOOL pdb_generate_sam_sid(void) break; } + if (is_dc) { + if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) { + sid_copy(global_sam_sid, &domain_sid); + return True; + } + } + if (secrets_fetch_domain_sid(global_myname(), global_sam_sid)) { - DOM_SID domain_sid; /* We got our sid. If not a pdc/bdc, we're done. */ if (!is_dc) @@ -117,11 +124,11 @@ static BOOL pdb_generate_sam_sid(void) if (!sid_equal(&domain_sid, global_sam_sid)) { - /* Domain name sid doesn't match global sam sid. Re-store global sam sid as domain sid. */ + /* Domain name sid doesn't match global sam sid. Re-store domain sid as 'local' sid. */ DEBUG(0,("pdb_generate_sam_sid: Mismatched SIDs as a pdc/bdc.\n")); - if (!secrets_store_domain_sid(lp_workgroup(), global_sam_sid)) { - DEBUG(0,("pdb_generate_sam_sid: Can't re-store domain SID as a pdc/bdc.\n")); + if (!secrets_store_domain_sid(global_myname(), &domain_sid)) { + DEBUG(0,("pdb_generate_sam_sid: Can't re-store domain SID for local sid as PDC/BDC.\n")); return False; } return True; diff --git a/source3/passdb/secrets.c b/source3/passdb/secrets.c index db08d02714..63e67aa16a 100644 --- a/source3/passdb/secrets.c +++ b/source3/passdb/secrets.c @@ -222,25 +222,40 @@ BOOL secrets_lock_trust_account_password(const char *domain, BOOL dolock) } /************************************************************************ + Routine to get the default secure channel type for trust accounts +************************************************************************/ + +uint32 get_default_sec_channel(void) +{ + if (lp_server_role() == ROLE_DOMAIN_BDC || + lp_server_role() == ROLE_DOMAIN_PDC) { + return SEC_CHAN_BDC; + } else { + return SEC_CHAN_WKSTA; + } +} + +/************************************************************************ Routine to get the trust account password for a domain. The user of this function must have locked the trust password file using the above call. ************************************************************************/ BOOL secrets_fetch_trust_account_password(const char *domain, uint8 ret_pwd[16], - time_t *pass_last_set_time) + time_t *pass_last_set_time, + uint32 *channel) { struct machine_acct_pass *pass; char *plaintext; size_t size; - plaintext = secrets_fetch_machine_password(); + plaintext = secrets_fetch_machine_password(domain, pass_last_set_time, + channel); if (plaintext) { /* we have an ADS password - use that */ DEBUG(4,("Using ADS machine password\n")); E_md4hash(plaintext, ret_pwd); SAFE_FREE(plaintext); - pass_last_set_time = 0; return True; } @@ -257,6 +272,10 @@ BOOL secrets_fetch_trust_account_password(const char *domain, uint8 ret_pwd[16], if (pass_last_set_time) *pass_last_set_time = pass->mod_time; memcpy(ret_pwd, pass->hash, 16); SAFE_FREE(pass); + + if (channel) + *channel = get_default_sec_channel(); + return True; } @@ -356,14 +375,42 @@ BOOL secrets_store_trusted_domain_password(const char* domain, smb_ucs2_t *uni_d the password is assumed to be a null terminated ascii string ************************************************************************/ -BOOL secrets_store_machine_password(const char *pass) +BOOL secrets_store_machine_password(const char *pass, const char *domain, uint32 sec_channel) { - char *key; + char *key = NULL; BOOL ret; - asprintf(&key, "%s/%s", SECRETS_MACHINE_PASSWORD, lp_workgroup()); + uint32 last_change_time; + uint32 sec_channel_type; + + asprintf(&key, "%s/%s", SECRETS_MACHINE_PASSWORD, domain); + if (!key) + return False; strupper(key); + ret = secrets_store(key, pass, strlen(pass)+1); - free(key); + SAFE_FREE(key); + + if (!ret) + return ret; + + asprintf(&key, "%s/%s", SECRETS_MACHINE_LAST_CHANGE_TIME, domain); + if (!key) + return False; + strupper(key); + + SIVAL(&last_change_time, 0, time(NULL)); + ret = secrets_store(key, &last_change_time, sizeof(last_change_time)); + SAFE_FREE(key); + + asprintf(&key, "%s/%s", SECRETS_MACHINE_SEC_CHANNEL_TYPE, domain); + if (!key) + return False; + strupper(key); + + SIVAL(&sec_channel_type, 0, sec_channel); + ret = secrets_store(key, &sec_channel_type, sizeof(sec_channel_type)); + SAFE_FREE(key); + return ret; } @@ -372,14 +419,45 @@ BOOL secrets_store_machine_password(const char *pass) Routine to fetch the plaintext machine account password for a realm the password is assumed to be a null terminated ascii string ************************************************************************/ -char *secrets_fetch_machine_password(void) +char *secrets_fetch_machine_password(const char *domain, + time_t *pass_last_set_time, + uint32 *channel) { - char *key; + char *key = NULL; char *ret; - asprintf(&key, "%s/%s", SECRETS_MACHINE_PASSWORD, lp_workgroup()); + asprintf(&key, "%s/%s", SECRETS_MACHINE_PASSWORD, domain); strupper(key); ret = (char *)secrets_fetch(key, NULL); - free(key); + SAFE_FREE(key); + + if (pass_last_set_time) { + size_t size; + uint32 *last_set_time; + asprintf(&key, "%s/%s", SECRETS_MACHINE_LAST_CHANGE_TIME, domain); + strupper(key); + last_set_time = secrets_fetch(key, &size); + if (last_set_time) { + *pass_last_set_time = IVAL(last_set_time,0); + } else { + *pass_last_set_time = 0; + } + SAFE_FREE(key); + } + + if (channel) { + size_t size; + uint32 *channel_type; + asprintf(&key, "%s/%s", SECRETS_MACHINE_SEC_CHANNEL_TYPE, domain); + strupper(key); + channel_type = secrets_fetch(key, &size); + if (channel_type) { + *channel = IVAL(channel_type,0); + } else { + *channel = get_default_sec_channel(); + } + SAFE_FREE(key); + } + return ret; } @@ -623,7 +701,7 @@ BOOL must_use_pdc( const char *domain ) time_t last_change_time; unsigned char passwd[16]; - if ( !secrets_fetch_trust_account_password(domain, passwd, &last_change_time) ) + if ( !secrets_fetch_trust_account_password(domain, passwd, &last_change_time, NULL) ) return False; /* diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c index 61d4b59723..ce0dd95e94 100644 --- a/source3/rpc_client/cli_netlogon.c +++ b/source3/rpc_client/cli_netlogon.c @@ -227,24 +227,6 @@ password ?).\n", cli->desthost )); return result; } -/* Return the secure channel type depending on the server role. */ - -uint16 get_sec_chan(void) -{ - uint16 sec_chan = SEC_CHAN_WKSTA; - - switch (lp_server_role()) { - case ROLE_DOMAIN_PDC: - sec_chan = SEC_CHAN_DOMAIN; - break; - case ROLE_DOMAIN_BDC: - sec_chan = SEC_CHAN_BDC; - break; - } - - return sec_chan; -} - /* Initialize domain session credentials */ NTSTATUS cli_nt_setup_creds(struct cli_state *cli, diff --git a/source3/rpcclient/cmd_netlogon.c b/source3/rpcclient/cmd_netlogon.c index 7a77d125a6..32fa9c3699 100644 --- a/source3/rpcclient/cmd_netlogon.c +++ b/source3/rpcclient/cmd_netlogon.c @@ -152,6 +152,7 @@ static NTSTATUS cmd_netlogon_sam_sync(struct cli_state *cli, SAM_DELTA_CTR *deltas; DOM_CRED ret_creds; uint32 neg_flags = 0x000001ff; + uint32 sec_channel_type = 0; if (argc > 2) { fprintf(stderr, "Usage: %s [database_id]\n", argv[0]); @@ -169,12 +170,12 @@ static NTSTATUS cmd_netlogon_sam_sync(struct cli_state *cli, /* Initialise session credentials */ if (!secrets_fetch_trust_account_password(lp_workgroup(), trust_passwd, - NULL)) { + NULL, &sec_channel_type)) { fprintf(stderr, "could not fetch trust account password\n"); goto done; } - result = cli_nt_setup_creds(cli, get_sec_chan(), trust_passwd, &neg_flags, 2); + result = cli_nt_setup_creds(cli, sec_channel_type, trust_passwd, &neg_flags, 2); if (!NT_STATUS_IS_OK(result)) { fprintf(stderr, "Error initialising session creds\n"); @@ -213,6 +214,7 @@ static NTSTATUS cmd_netlogon_sam_deltas(struct cli_state *cli, SAM_DELTA_CTR *deltas; UINT64_S seqnum; uint32 neg_flags = 0x000001ff; + uint32 sec_channel_type = 0; if (argc != 3) { fprintf(stderr, "Usage: %s database_id seqnum\n", argv[0]); @@ -233,12 +235,12 @@ static NTSTATUS cmd_netlogon_sam_deltas(struct cli_state *cli, /* Initialise session credentials */ if (!secrets_fetch_trust_account_password(lp_workgroup(), trust_passwd, - NULL)) { + NULL, &sec_channel_type)) { fprintf(stderr, "could not fetch trust account password\n"); goto done; } - result = cli_nt_setup_creds(cli, get_sec_chan(), trust_passwd, &neg_flags, 2); + result = cli_nt_setup_creds(cli, sec_channel_type, trust_passwd, &neg_flags, 2); if (!NT_STATUS_IS_OK(result)) { fprintf(stderr, "Error initialising session creds\n"); diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c index efc883ff9f..bf016e94c7 100644 --- a/source3/rpcclient/rpcclient.c +++ b/source3/rpcclient/rpcclient.c @@ -393,15 +393,16 @@ static NTSTATUS do_cmd(struct cli_state *cli, if (cmd_entry->pipe_idx == PI_NETLOGON) { uchar trust_password[16]; + uint32 sec_channel_type; if (!secrets_fetch_trust_account_password(lp_workgroup(), trust_password, - NULL)) { + NULL, &sec_channel_type)) { return NT_STATUS_UNSUCCESSFUL; } if (!cli_nt_open_netlogon(cli, trust_password, - SEC_CHAN_WKSTA)) { + sec_channel_type)) { DEBUG(0, ("Could not initialise NETLOGON pipe\n")); return NT_STATUS_UNSUCCESSFUL; } diff --git a/source3/smbd/change_trust_pw.c b/source3/smbd/change_trust_pw.c index a140978733..8aff96d0d6 100644 --- a/source3/smbd/change_trust_pw.c +++ b/source3/smbd/change_trust_pw.c @@ -24,26 +24,36 @@ #include "includes.h" -/********************************************************* - Change the domain password on the PDC. -**********************************************************/ +/************************************************************************ + Change the trust account password for a domain. +************************************************************************/ -static NTSTATUS modify_trust_password( const char *domain, const char *remote_machine, - unsigned char orig_trust_passwd_hash[16]) +NTSTATUS change_trust_account_password( const char *domain, const char *remote_machine) { + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + struct in_addr pdc_ip; + fstring dc_name; struct cli_state *cli; - DOM_SID domain_sid; - NTSTATUS nt_status; - /* - * Ensure we have the domain SID for this domain. - */ + if (remote_machine == NULL || !strcmp(remote_machine, "*")) { + /* Use the PDC *only* for this */ + + if ( !get_pdc_ip(domain, &pdc_ip) ) { + DEBUG(0,("Can't get IP for PDC for domain %s\n", domain)); + goto failed; + } - if (!secrets_fetch_domain_sid(domain, &domain_sid)) { - DEBUG(0, ("modify_trust_password: unable to fetch domain sid.\n")); - return NT_STATUS_UNSUCCESSFUL; + if ( !lookup_dc_name(global_myname(), domain, &pdc_ip, dc_name) ) + goto failed; } - + /* supoport old deprecated "smbpasswd -j DOMAIN -r MACHINE" behavior */ + else { + fstrcpy( dc_name, remote_machine ); + } + + /* if this next call fails, then give up. We can't do + password changes on BDC's --jerry */ + if (!NT_STATUS_IS_OK(cli_full_connection(&cli, global_myname(), remote_machine, NULL, 0, "IPC$", "IPC", @@ -51,7 +61,8 @@ static NTSTATUS modify_trust_password( const char *domain, const char *remote_ma "", 0, NULL))) { DEBUG(0,("modify_trust_password: Connection to %s failed!\n", remote_machine)); - return NT_STATUS_UNSUCCESSFUL; + nt_status = NT_STATUS_UNSUCCESSFUL; + goto failed; } /* @@ -65,64 +76,22 @@ static NTSTATUS modify_trust_password( const char *domain, const char *remote_ma cli_nt_session_close(cli); cli_ulogoff(cli); cli_shutdown(cli); - return NT_STATUS_UNSUCCESSFUL; + nt_status = NT_STATUS_UNSUCCESSFUL; + goto failed; } - nt_status = trust_pw_change_and_store_it(cli, cli->mem_ctx, - orig_trust_passwd_hash); + nt_status = trust_pw_find_change_and_store_it(cli, cli->mem_ctx, + domain); cli_nt_session_close(cli); cli_ulogoff(cli); cli_shutdown(cli); - return nt_status; -} - -/************************************************************************ - Change the trust account password for a domain. -************************************************************************/ - -NTSTATUS change_trust_account_password( const char *domain, const char *remote_machine) -{ - unsigned char old_trust_passwd_hash[16]; - time_t lct; - NTSTATUS res = NT_STATUS_UNSUCCESSFUL; - struct in_addr pdc_ip; - fstring dc_name; - - - if(!secrets_fetch_trust_account_password(domain, old_trust_passwd_hash, &lct)) { - DEBUG(0,("change_trust_account_password: unable to read the machine account password for domain %s.\n", - domain)); - return NT_STATUS_UNSUCCESSFUL; - } - - if (remote_machine == NULL || !strcmp(remote_machine, "*")) { - /* Use the PDC *only* for this */ - - if ( !get_pdc_ip(domain, &pdc_ip) ) { - DEBUG(0,("Can't get IP for PDC for domain %s\n", domain)); - goto failed; - } - - if ( !lookup_dc_name(global_myname(), domain, &pdc_ip, dc_name) ) - goto failed; - } - /* supoport old deprecated "smbpasswd -j DOMAIN -r MACHINE" behavior */ - else { - fstrcpy( dc_name, remote_machine ); - } - - /* if this next call fails, then give up. We can't do - password changes on BDC's --jerry */ - - res = modify_trust_password(domain, dc_name, old_trust_passwd_hash); - failed: - if (!NT_STATUS_IS_OK(res)) { + if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(0,("%s : change_trust_account_password: Failed to change password for domain %s.\n", timestring(False), domain)); } - return res; + return nt_status; } diff --git a/source3/smbd/process.c b/source3/smbd/process.c index de1bea493f..54fd4a90d9 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -1179,9 +1179,11 @@ machine %s in domain %s.\n", global_myname(), lp_workgroup() )); return True; } - if(!secrets_fetch_trust_account_password(lp_workgroup(), trust_passwd_hash, &lct)) { + if(!secrets_fetch_trust_account_password(lp_workgroup(), + trust_passwd_hash, + &lct, NULL)) { DEBUG(0,("process: unable to read the machine account password for \ -machine %s in domain %s.\n", global_myname(), lp_workgroup() )); +machine %s in domain %s.\n", global_myname(), lp_workgroup())); secrets_lock_trust_account_password(lp_workgroup(), False); return True; } diff --git a/source3/utils/net.c b/source3/utils/net.c index 67d3176b4d..b404bac595 100644 --- a/source3/utils/net.c +++ b/source3/utils/net.c @@ -68,7 +68,7 @@ int opt_force = 0; int opt_port = 0; int opt_maxusers = -1; const char *opt_comment = ""; -char *opt_container = "cn=Users"; +const char *opt_container = "cn=Users"; int opt_flags = -1; int opt_timeout = 0; const char *opt_target_workgroup = NULL; @@ -77,6 +77,27 @@ static int opt_machine_pass = 0; BOOL opt_have_ip = False; struct in_addr opt_dest_ip; +uint32 get_sec_channel_type(const char *param) +{ + if (!(param && *param)) { + return get_default_sec_channel(); + } else { + if (strcasecmp(param, "PDC")==0) { + return SEC_CHAN_BDC; + } else if (strcasecmp(param, "BDC")==0) { + return SEC_CHAN_BDC; + } else if (strcasecmp(param, "MEMBER")==0) { + return SEC_CHAN_WKSTA; +#if 0 + } else if (strcasecmp(param, "DOMAIN")==0) { + return SEC_CHAN_DOMAIN; +#endif + } else { + return get_default_sec_channel(); + } + } +} + /* run a function from a function table. If not found then call the specified usage function @@ -623,11 +644,11 @@ static struct functable net_func[] = { } if (!opt_workgroup) { - opt_workgroup = lp_workgroup(); + opt_workgroup = smb_xstrdup(lp_workgroup()); } if (!opt_target_workgroup) { - opt_target_workgroup = strdup(lp_workgroup()); + opt_target_workgroup = smb_xstrdup(lp_workgroup()); } if (!init_names()) @@ -636,7 +657,7 @@ static struct functable net_func[] = { load_interfaces(); if (opt_machine_pass) { - char *user; + char *user = NULL; /* it is very useful to be able to make ads queries as the machine account for testing purposes and for domain leave */ @@ -645,9 +666,10 @@ static struct functable net_func[] = { exit(1); } + opt_password = secrets_fetch_machine_password(opt_workgroup, NULL, NULL); + asprintf(&user,"%s$", global_myname()); opt_user_name = user; - opt_password = secrets_fetch_machine_password(); if (!opt_password) { d_printf("ERROR: Unable to fetch machine password\n"); exit(1); diff --git a/source3/utils/net.h b/source3/utils/net.h index c1b49a919b..f83d0169bf 100644 --- a/source3/utils/net.h +++ b/source3/utils/net.h @@ -38,7 +38,7 @@ extern int opt_maxusers; extern const char *opt_comment; -extern char *opt_container; +extern const char *opt_container; extern int opt_flags; extern const char *opt_comment; diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index 71b7a0802f..3615fd0e94 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -564,7 +564,7 @@ static int net_ads_leave(int argc, const char **argv) if (!opt_password) { char *user_name; asprintf(&user_name, "%s$", global_myname()); - opt_password = secrets_fetch_machine_password(); + opt_password = secrets_fetch_machine_password(opt_target_workgroup, NULL, NULL); opt_user_name = user_name; } @@ -596,7 +596,7 @@ static int net_ads_join_ok(void) asprintf(&user_name, "%s$", global_myname()); opt_user_name = user_name; - opt_password = secrets_fetch_machine_password(); + opt_password = secrets_fetch_machine_password(opt_target_workgroup, NULL, NULL); if (!(ads = ads_startup())) { return -1; @@ -637,6 +637,8 @@ int net_ads_join(int argc, const char **argv) void *res; DOM_SID dom_sid; char *ou_str; + uint32 sec_channel_type; + uint32 account_type = UF_WORKSTATION_TRUST_ACCOUNT; if (argc > 0) org_unit = argv[0]; @@ -645,6 +647,11 @@ int net_ads_join(int argc, const char **argv) return -1; } + /* check what type of join + TODO: make this variable like RPC + */ + account_type = UF_WORKSTATION_TRUST_ACCOUNT; + tmp_password = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH); password = strdup(tmp_password); @@ -669,7 +676,7 @@ int net_ads_join(int argc, const char **argv) return -1; } - rc = ads_join_realm(ads, global_myname(), org_unit); + rc = ads_join_realm(ads, global_myname(), account_type, org_unit); if (!ADS_ERR_OK(rc)) { d_printf("ads_join_realm: %s\n", ads_errstr(rc)); return -1; @@ -692,7 +699,7 @@ int net_ads_join(int argc, const char **argv) return -1; } - if (!secrets_store_machine_password(password)) { + if (!secrets_store_machine_password(password, lp_workgroup(), sec_channel_type)) { DEBUG(1,("Failed to save machine password\n")); return -1; } @@ -945,7 +952,7 @@ int net_ads_changetrustpw(int argc, const char **argv) asprintf(&user_name, "%s$", global_myname()); opt_user_name = user_name; - opt_password = secrets_fetch_machine_password(); + opt_password = secrets_fetch_machine_password(opt_target_workgroup, NULL, NULL); use_in_memory_ccache(); diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index fcd8a54118..9ae50aaf0d 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -235,8 +235,9 @@ int net_rpc_changetrustpw(int argc, const char **argv) * @return Normal NTSTATUS return. **/ -static NTSTATUS rpc_join_oldstyle_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx, - int argc, const char **argv) { +static NTSTATUS rpc_join_oldstyle_internals(const DOM_SID *domain_sid, struct cli_state *cli, + TALLOC_CTX *mem_ctx, + int argc, const char **argv) { fstring trust_passwd; unsigned char orig_trust_passwd_hash[16]; @@ -254,10 +255,22 @@ static NTSTATUS rpc_join_oldstyle_internals(const DOM_SID *domain_sid, struct cl E_md4hash(trust_passwd, orig_trust_passwd_hash); - result = trust_pw_change_and_store_it(cli, mem_ctx, orig_trust_passwd_hash); + result = trust_pw_change_and_store_it(cli, mem_ctx, opt_target_workgroup, + orig_trust_passwd_hash, + SEC_CHAN_WKSTA); + + /* SEC_CHAN_WKSTA specified specifically, as you cannot use this + to join a BDC to the domain (MS won't allow it, and is *really* + insecure) */ if (NT_STATUS_IS_OK(result)) - printf("Joined domain %s.\n",lp_workgroup()); + printf("Joined domain %s.\n",opt_target_workgroup); + + + if (!secrets_store_domain_sid(opt_target_workgroup, domain_sid)) { + DEBUG(0, ("error storing domain sid for %s\n", opt_target_workgroup)); + result = NT_STATUS_UNSUCCESSFUL; + } return result; } @@ -274,7 +287,38 @@ static NTSTATUS rpc_join_oldstyle_internals(const DOM_SID *domain_sid, struct cl static int net_rpc_join_oldstyle(int argc, const char **argv) { - return run_rpc_command(NULL, PI_NETLOGON, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, rpc_join_oldstyle_internals, + uint32 sec_channel_type; + /* check what type of join */ + if (argc >= 0) { + sec_channel_type = get_sec_channel_type(argv[0]); + } else { + sec_channel_type = get_sec_channel_type(NULL); + } + + if (sec_channel_type != SEC_CHAN_WKSTA) + return 1; + + return run_rpc_command(NULL, PI_NETLOGON, + NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, + rpc_join_oldstyle_internals, + argc, argv); +} + +/** + * Join a domain, the old way. + * + * @param argc Standard main() style argc + * @param argc Standard main() style argv. Initial components are already + * stripped + * + * @return A shell status integer (0 for success) + **/ + +static int net_rpc_oldjoin(int argc, const char **argv) +{ + return run_rpc_command(NULL, PI_NETLOGON, + NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, + rpc_join_oldstyle_internals, argc, argv); } @@ -287,11 +331,13 @@ static int net_rpc_join_oldstyle(int argc, const char **argv) static int rpc_join_usage(int argc, const char **argv) { - d_printf("net rpc join -U <username>[%%password] [options]\n"\ + d_printf("net rpc join -U <username>[%%password] <type>[options]\n"\ "\t to join a domain with admin username & password\n"\ - "\t\t password will be prompted if none is specified\n"); - d_printf("net rpc join [options except -U]\n"\ - "\t to join a domain created in server manager\n\n\n"); + "\t\t password will be prompted if needed and none is specified\n"\ + "\t <type> can be (default MEMBER)\n"\ + "\t\t BDC - Join as a BDC\n"\ + "\t\t PDC - Join as a PDC\n"\ + "\t\t MEMBER - Join as a MEMBER server\n"); net_common_flags_usage(argc, argv); return -1; @@ -311,21 +357,10 @@ static int rpc_join_usage(int argc, const char **argv) int net_rpc_join(int argc, const char **argv) { - struct functable func[] = { - {"oldstyle", net_rpc_join_oldstyle}, - {NULL, NULL} - }; - - if (argc == 0) { - if (opt_user_specified) - return net_rpc_join_newstyle(argc, argv); - if ((net_rpc_join_oldstyle(argc, argv) == 0)) - return 0; - - return net_rpc_join_newstyle(argc, argv); - } - - return net_run_function(argc, argv, func, rpc_join_usage); + if ((net_rpc_join_oldstyle(argc, argv) == 0)) + return 0; + + return net_rpc_join_newstyle(argc, argv); } @@ -2181,6 +2216,7 @@ int net_rpc_usage(int argc, const char **argv) { d_printf(" net rpc info \t\t\tshow basic info about a domain \n"); d_printf(" net rpc join \t\t\tto join a domain \n"); + d_printf(" net rpc oldjoin \t\t\tto join a domain created in server manager\n\n\n"); d_printf(" net rpc testjoin \t\ttests that a join is valid\n"); d_printf(" net rpc user \t\t\tto add, delete and list users\n"); d_printf(" net rpc group \t\tto list groups\n"); @@ -2247,6 +2283,7 @@ int net_rpc(int argc, const char **argv) struct functable func[] = { {"info", net_rpc_info}, {"join", net_rpc_join}, + {"oldjoin", net_rpc_oldjoin}, {"testjoin", net_rpc_testjoin}, {"user", net_rpc_user}, {"group", net_rpc_group}, diff --git a/source3/utils/net_rpc_join.c b/source3/utils/net_rpc_join.c index e2fd9aa434..35564b1e10 100644 --- a/source3/utils/net_rpc_join.c +++ b/source3/utils/net_rpc_join.c @@ -62,18 +62,12 @@ int net_rpc_join_ok(const char *domain) } if (!secrets_fetch_trust_account_password(domain, - stored_md4_trust_password, NULL)) { + stored_md4_trust_password, + NULL, &channel)) { DEBUG(0,("Could not retreive domain trust secret")); goto done; } - if (lp_server_role() == ROLE_DOMAIN_BDC || - lp_server_role() == ROLE_DOMAIN_PDC) { - channel = SEC_CHAN_BDC; - } else { - channel = SEC_CHAN_WKSTA; - } - CHECK_RPC_ERR(cli_nt_setup_creds(cli, channel, stored_md4_trust_password, &neg_flags, 2), @@ -108,7 +102,8 @@ int net_rpc_join_newstyle(int argc, const char **argv) struct cli_state *cli; TALLOC_CTX *mem_ctx; - uint32 acb_info; + uint32 acb_info = ACB_WSTRUST; + uint32 sec_channel_type; /* rpc variables */ @@ -121,10 +116,11 @@ int net_rpc_join_newstyle(int argc, const char **argv) char *clear_trust_password = NULL; fstring ucs2_trust_password; int ucs2_pw_len; - uchar pwbuf[516], sess_key[16]; + uchar pwbuf[516]; SAM_USERINFO_CTR ctr; SAM_USER_INFO_24 p24; SAM_USER_INFO_10 p10; + uchar md4_trust_password[16]; /* Misc */ @@ -135,6 +131,25 @@ int net_rpc_join_newstyle(int argc, const char **argv) uint32 flags = 0x3e8; char *acct_name; const char *const_acct_name; + uint32 neg_flags = 0x000001ff; + + /* check what type of join */ + if (argc >= 0) { + sec_channel_type = get_sec_channel_type(argv[0]); + } else { + sec_channel_type = get_sec_channel_type(NULL); + } + + switch (sec_channel_type) { + case SEC_CHAN_WKSTA: + acb_info = ACB_WSTRUST; + case SEC_CHAN_BDC: + acb_info = ACB_SVRTRUST; +#if 0 + case SEC_CHAN_DOMAIN: + acb_info = ACB_DOMTRUST; +#endif + } /* Connect to remote machine */ @@ -189,8 +204,6 @@ int net_rpc_join_newstyle(int argc, const char **argv) strlower(acct_name); const_acct_name = acct_name; - acb_info = ((lp_server_role() == ROLE_DOMAIN_BDC) || lp_server_role() == ROLE_DOMAIN_PDC) ? ACB_SVRTRUST : ACB_WSTRUST; - result = cli_samr_create_dom_user(cli, mem_ctx, &domain_pol, acct_name, acb_info, 0xe005000b, &user_pol, @@ -245,6 +258,7 @@ int net_rpc_join_newstyle(int argc, const char **argv) char *str; str = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH); clear_trust_password = strdup(str); + E_md4hash(clear_trust_password, md4_trust_password); } ucs2_pw_len = push_ucs2(NULL, ucs2_trust_password, @@ -287,8 +301,22 @@ int net_rpc_join_newstyle(int argc, const char **argv) as a normal user with "Add workstation to domain" privilege. */ result = cli_samr_set_userinfo2(cli, mem_ctx, &user_pol, 0x10, - sess_key, &ctr); + cli->user_session_key, &ctr); + + /* Now check the whole process from top-to-bottom */ + cli_samr_close(cli, mem_ctx, &user_pol); + cli_nt_session_close(cli); /* Done with this pipe */ + if (!cli_nt_session_open(cli, PI_NETLOGON)) { + DEBUG(0,("Error connecting to NETLOGON pipe\n")); + goto done; + } + + CHECK_RPC_ERR(cli_nt_setup_creds(cli, + sec_channel_type, + md4_trust_password, &neg_flags, 2), + "error in domain join verification"); + /* Now store the secret in the secrets database */ strupper(domain); @@ -298,14 +326,11 @@ int net_rpc_join_newstyle(int argc, const char **argv) goto done; } - if (!secrets_store_machine_password(clear_trust_password)) { + if (!secrets_store_machine_password(clear_trust_password, domain, sec_channel_type)) { DEBUG(0, ("error storing plaintext domain secrets for %s\n", domain)); } - /* Now check the whole process from top-to-bottom */ - cli_samr_close(cli, mem_ctx, &user_pol); - cli_nt_session_close(cli); /* Done with this pipe */ - + /* double-check, connection from scratch */ retval = net_rpc_join_ok(domain); done: @@ -317,7 +342,6 @@ done: /* Display success or failure */ if (retval != 0) { - trust_password_delete(domain); fprintf(stderr,"Unable to join domain %s.\n",domain); } else { printf("Joined domain %s.\n",domain); diff --git a/source3/utils/net_rpc_samsync.c b/source3/utils/net_rpc_samsync.c index b886119eef..909ed298cb 100644 --- a/source3/utils/net_rpc_samsync.c +++ b/source3/utils/net_rpc_samsync.c @@ -198,6 +198,7 @@ int rpc_samdump(int argc, const char **argv) struct cli_state *cli = NULL; uchar trust_password[16]; DOM_CRED ret_creds; + uint32 sec_channel; ZERO_STRUCT(ret_creds); @@ -210,12 +211,12 @@ int rpc_samdump(int argc, const char **argv) if (!secrets_fetch_trust_account_password(lp_workgroup(), trust_password, - NULL)) { + NULL, &sec_channel)) { DEBUG(0,("Could not fetch trust account password\n")); goto fail; } - if (!cli_nt_open_netlogon(cli, trust_password, SEC_CHAN_BDC)) { + if (!cli_nt_open_netlogon(cli, trust_password, sec_channel)) { DEBUG(0,("Error connecting to NETLOGON pipe\n")); goto fail; } @@ -810,6 +811,7 @@ int rpc_vampire(int argc, const char **argv) DOM_CRED ret_creds; uint32 neg_flags = 0x000001ff; DOM_SID dom_sid; + uint32 sec_channel; ZERO_STRUCT(ret_creds); @@ -825,12 +827,13 @@ int rpc_vampire(int argc, const char **argv) } if (!secrets_fetch_trust_account_password(lp_workgroup(), - trust_password, NULL)) { + trust_password, NULL, + &sec_channel)) { d_printf("Could not retrieve domain trust secret\n"); goto fail; } - result = cli_nt_setup_creds(cli, SEC_CHAN_BDC, trust_password, + result = cli_nt_setup_creds(cli, sec_channel, trust_password, &neg_flags, 2); if (!NT_STATUS_IS_OK(result)) { d_printf("Failed to setup BDC creds\n"); |