Store the type of 'sec channel' that we establish to the DC. If we are a
authorAndrew Bartlett <abartlet@samba.org>
Wed, 16 Apr 2003 10:20:14 +0000 (10:20 +0000)
committerAndrew Bartlett <abartlet@samba.org>
Wed, 16 Apr 2003 10:20:14 +0000 (10:20 +0000)
workstation, we have to use the workstation type, if we have a BDC account,
we must use the BDC type - even if we are pretending to be a workstation
at the moment.

Also actually store and retreive the last change time, so we can do
periodic password changes again (for RPC at least).

And finally, a couple of minor fixes to 'net'.

Andrew Bartlett
(This used to be commit 6e6b7b79edae3efd0197651e9a8ce6775c001cf2)

23 files changed:
source3/auth/auth_domain.c
source3/include/secrets.h
source3/libads/kerberos_verify.c
source3/libads/ldap.c
source3/libads/util.c
source3/libsmb/trusts_util.c
source3/nsswitch/winbindd_ads.c
source3/nsswitch/winbindd_cm.c
source3/nsswitch/winbindd_misc.c
source3/nsswitch/winbindd_pam.c
source3/passdb/machine_sid.c
source3/passdb/secrets.c
source3/rpc_client/cli_netlogon.c
source3/rpcclient/cmd_netlogon.c
source3/rpcclient/rpcclient.c
source3/smbd/change_trust_pw.c
source3/smbd/process.c
source3/utils/net.c
source3/utils/net.h
source3/utils/net_ads.c
source3/utils/net_rpc.c
source3/utils/net_rpc_join.c
source3/utils/net_rpc_samsync.c

index 7dca5914f0b4d99a9ddaee53b87da66660765e32..db5f7d82b085b05819301be15449fa3e6cc04842 100644 (file)
@@ -352,6 +352,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);
@@ -400,6 +405,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"));
@@ -422,7 +428,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;
@@ -447,7 +453,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;
 }
 
index 07faf28d439dcd7eb56da4fbf6bf3dba2651d0cd..dacfef26ead28525dd16878392e0f4f97e8e2309 100644 (file)
@@ -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"
 
index 6a50137400f194a61c2a4315d0936d01ad2495c4..35d429ca2abb97905d8a99b4936d9ba23097355f 100644 (file)
@@ -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;
index baedfb28dbbe38ed2b76022dd3df7ad77df4d9ba..3ce80975da48aafbc4d9a38abde51bc73a32c65d 100644 (file)
@@ -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;
index 335cabc95261429172f0255b421f05553721292b..9912a7ba8317ebc782c0b4ad2ae10c69af8044e2 100644 (file)
@@ -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);
     }
index b8f84ba890adc8553e966a9951f8d27cf66d0178..d5a02bb6259ea83e4472d1b690920312005406ef 100644 (file)
 **********************************************************/
 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",
@@ -60,7 +61,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;
@@ -74,7 +77,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", 
@@ -83,7 +86,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;
                }
        }
@@ -97,22 +100,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);
        
 }
 
@@ -127,35 +134,21 @@ NTSTATUS trust_pw_find_change_and_store_it(struct cli_state *cli, TALLOC_CTX *me
  
 BOOL is_trusted_domain(const char* dom_name)
 {
-       int enum_ctx = 0;
-       const int trustdom_size = 10;
-       int num_domains, i;
-       TRUSTDOM **domains;
-       NTSTATUS result;
-       fstring trustdom_name;
        DOM_SID trustdom_sid;
-       TALLOC_CTX *mem_ctx;
-       
-       /*
-        * Query the secrets db as an ultimate source of information
-        * about trusted domain names. This is PDC or BDC case.
-        */
-       mem_ctx = talloc_init("is_trusted_domain");
-       
-       do {
-               result = secrets_get_trusted_domains(mem_ctx, &enum_ctx, trustdom_size,
-                                                    &num_domains, &domains);
-               /* compare each returned entry against incoming connection's domain */
-               for (i = 0; i < num_domains; i++) {
-                       pull_ucs2_fstring(trustdom_name, domains[i]->name);
-                       if (strequal(trustdom_name, dom_name)) {
-                               talloc_destroy(mem_ctx);
-                               return True;
-                       }
-               }
-       } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
+       char *pass = NULL;
+       time_t lct;
+       BOOL ret;
 
-       talloc_destroy(mem_ctx);
+       if (lp_server_role() == ROLE_DOMAIN_BDC || lp_server_role() == ROLE_DOMAIN_PDC) {
+               /*
+                * Query the secrets db as an ultimate source of information
+                * about trusted domain names. This is PDC or BDC case.
+                */
+               ret = secrets_fetch_trusted_domain_password(dom_name, &pass, &trustdom_sid, &lct);
+               SAFE_FREE(pass);
+               if (ret) 
+                       return ret;
+       }
 
        /*
         * Query the trustdom_cache updated periodically. The only
index de3757aa44c01b6fea48c41ca7a736016d2596a8..beb40af79de15b492890b264a5384e0f95ec2af4 100644 (file)
@@ -56,7 +56,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);
index 1b49d8ce013e564851bc747e4b9b214df79b953a..dbcfdcf88f9887c7261e714101c75be8f0bcb757 100644 (file)
@@ -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);
index 52889e85d420969a0a9be323e8bf85fa72ecacf2..fb56d0e65747660e81c0e0530d9767e263109a03 100644 (file)
@@ -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)
 {
index e49a95f4b879045f8feaa02cc67437bb4c484b9f..2998372bd21b08e95f47d4dd947c56716f5960d8 100644 (file)
@@ -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)));
index 071af50877efcd9cfccac99903c6a8c3cbebd164..a578ecc7113d3f0f249eba6a4a2369f822e4f00d 100644 (file)
@@ -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;
index 64fedc7284eaac26b52494a7069ba6287bf6a95f..138a9231fd3ebbb92abdf93b3eb7a9b30ef15bea 100644 (file)
@@ -221,6 +221,20 @@ BOOL secrets_lock_trust_account_password(const char *domain, BOOL dolock)
        return True;
 }
 
+/************************************************************************
+ 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
@@ -228,19 +242,20 @@ BOOL secrets_lock_trust_account_password(const char *domain, BOOL dolock)
 ************************************************************************/
 
 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;
 }
 
@@ -369,14 +388,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;
 }
 
@@ -385,14 +432,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;
 }
 
@@ -637,7 +715,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;
                
        /*
index 61d4b5972319d4d3944b7c55a7ad751951594de2..ce0dd95e94a36974457498bee4b374731ee95919 100644 (file)
@@ -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, 
index 7a77d125a6ff97154f24c01507bdec0078bf63cd..32fa9c3699f2501f222eef150a9670ece9c00c09 100644 (file)
@@ -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");
index efc883ff9ff1a2fcef89388361b7ff8479d6dfaa..bf016e94c7c69cfe0db33d56e4ba148241f88a0e 100644 (file)
@@ -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;
                }
index a14097873304b25f30d06bca1e4054805f9e5992..8aff96d0d6d628330bd8ed896810fd87fa0cb54f 100644 (file)
 
 #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;
 }
index de1bea493fa484419146364e98bb20eb32e59683..54fd4a90d99d4a967b05bbbd0a19790fbb981c57 100644 (file)
@@ -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;
     }
index 9d8441e649a32a21c74d1540687751e2a14c890a..5d526e22dfe102fc7d7803de3c6e822ad27ad697 100644 (file)
@@ -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 
@@ -602,11 +623,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())
@@ -615,7 +636,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 */
 
@@ -624,9 +645,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);
index c1b49a919b48b0eaad911bd63f53500d2fbe3769..f83d0169bfda70985b713c1b24dc995b1fb8f375 100644 (file)
@@ -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;
index 5a8265f0b9e59a6c37432cb66f8acbd563f09adf..91f82a5dbe01542a56cdd4dc1e8cd513055f764c 100644 (file)
@@ -575,7 +575,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;
        }
 
@@ -607,7 +607,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;
@@ -648,6 +648,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];
 
@@ -656,6 +658,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);
 
@@ -680,7 +687,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;
@@ -703,7 +710,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;
        }
@@ -956,7 +963,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();
 
index a35cdd0b5bb373ce100fdc4552155d967c5dcca4..9ae50aaf0ddce1a2cdb4e95fec9c13b4fb6c0582 100644 (file)
@@ -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,19 +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 ((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);
 }
 
 
@@ -2179,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");
@@ -2245,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},
index e2fd9aa4341267b908143aaf41794e7ad1ded71d..35564b1e10c27a924892f46ff4ceb1037e630231 100644 (file)
@@ -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);
index b886119eef9f2cac96fb98288af57ef2712ef2e7..909ed298cb3a090543f5b74f888f6f299750ab26 100644 (file)
@@ -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");