Merge from HEAD - save the type of channel used to contact the DC.
authorAndrew Bartlett <abartlet@samba.org>
Mon, 21 Apr 2003 14:09:03 +0000 (14:09 +0000)
committerAndrew Bartlett <abartlet@samba.org>
Mon, 21 Apr 2003 14:09:03 +0000 (14:09 +0000)
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)

24 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/trust_passwd.c
source3/nsswitch/winbindd_ads.c
source3/nsswitch/winbindd_cm.c
source3/nsswitch/winbindd_misc.c
source3/nsswitch/winbindd_pam.c
source3/param/loadparm.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 24a5bb562cbc1e24eff2c00ef4c11b721824ee5d..e49a41763bb07538947c8b28644cfe2183df12b1 100644 (file)
@@ -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;
 }
 
index 183b29d7a8a594baf9cb826cc70b9db6da8e6f93..84db527065b2689e51dc19e369c7ee66fe62418a 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 cf9fd58b13f18743484ae4b133019240c3a6ea57..0d015128a6e727e6c48a45022a109fd338e6a82b 100644 (file)
@@ -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
 **********************************************************/
 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);
        
-}                                       
+}
+
index f6fc3a8d6c9cf006ab2adba91e4d94351efd55d9..63dc90bc28a4fa91b376f77ab77e04bdc7a84102 100644 (file)
@@ -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);
index 706408901e517b8d78b0e021243a78d9bcc9951d..7502f3696b1c860c1116fabdb349b7e6f8c9718e 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 3d5713d678c88aa821c1e352f4d536b18eaaa757..a89330fd5beccc54540be7c9ac3c9c14953ffd31 100644 (file)
@@ -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);
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 db08d0271455f475b8d7b2c19240bb5e47fce39f..63e67aa16afc5c9fd35e9a933a5a29c5a0b6f965 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;
 }
 
@@ -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;
                
        /*
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 67d3176b4d75c3e5961439f7f84bbb00bd51787b..b404bac59522cabe098dfde756063ca9feb44952 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 
@@ -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);
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 71b7a0802f23da2df0877ceb8f5c4aee98b72f9d..3615fd0e949dbce8d5abb8f2510d87f14a739e82 100644 (file)
@@ -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();
 
index fcd8a541185a9cffaf514cc530593cdbfde70dce..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,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},
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");