Fix Bug #5710 and make machine account password changing work again.
authorGünther Deschner <gd@samba.org>
Thu, 21 Aug 2008 13:05:35 +0000 (15:05 +0200)
committerGünther Deschner <gd@samba.org>
Thu, 21 Aug 2008 21:45:24 +0000 (23:45 +0200)
When we negotiated NETLOGON_NEG_PASSWORD_SET2 we need to use
NetrServerPasswordSet2 to change the machine password.

Tested with NT4, W2k, W2k3 and W2k8.

Guenther
(This used to be commit 5820360451e4db0fad0472f814cae667b2ea51fd)

source3/libsmb/trusts_util.c

index f4fdf9eb6fe898db3123587895d20f2809fc7695..08a49930b4d3e7e834fa13b230096671a61ccbe9 100644 (file)
 
 static NTSTATUS just_change_the_password(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, 
                                         const unsigned char orig_trust_passwd_hash[16],
+                                        const char *new_trust_pwd_cleartext,
                                         const unsigned char new_trust_passwd_hash[16],
                                         uint32 sec_channel_type)
 {
        NTSTATUS result;
+       uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
 
-       /* Check if the netlogon pipe is open using schannel. If so we
-          already have valid creds. If not we must set them up. */
-
-       if (cli->auth->auth_type != PIPE_AUTH_TYPE_SCHANNEL) {
-               uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
-
-               result = rpccli_netlogon_setup_creds(cli, 
-                                       cli->desthost, /* server name */
-                                       lp_workgroup(), /* domain */
-                                       global_myname(), /* client name */
-                                       global_myname(), /* machine account name */
-                                       orig_trust_passwd_hash,
-                                       sec_channel_type,
-                                       &neg_flags);
-
-               if (!NT_STATUS_IS_OK(result)) {
-                       DEBUG(3,("just_change_the_password: unable to setup creds (%s)!\n",
-                                nt_errstr(result)));
-                       return result;
-               }
+       result = rpccli_netlogon_setup_creds(cli,
+                                            cli->desthost, /* server name */
+                                            lp_workgroup(), /* domain */
+                                            global_myname(), /* client name */
+                                            global_myname(), /* machine account name */
+                                            orig_trust_passwd_hash,
+                                            sec_channel_type,
+                                            &neg_flags);
+
+       if (!NT_STATUS_IS_OK(result)) {
+               DEBUG(3,("just_change_the_password: unable to setup creds (%s)!\n",
+                        nt_errstr(result)));
+               return result;
        }
 
-       {
+       if (neg_flags & NETLOGON_NEG_PASSWORD_SET2) {
+
+               struct netr_Authenticator clnt_creds, srv_cred;
+               struct netr_CryptPassword new_password;
+               struct samr_CryptPassword password_buf;
+
+               netlogon_creds_client_step(cli->dc, &clnt_creds);
+
+               encode_pw_buffer(password_buf.data, new_trust_pwd_cleartext, STR_UNICODE);
+
+               SamOEMhash(password_buf.data, cli->dc->sess_key, 516);
+               memcpy(new_password.data, password_buf.data, 512);
+               new_password.length = IVAL(password_buf.data, 512);
+
+               result = rpccli_netr_ServerPasswordSet2(cli, mem_ctx,
+                                                      cli->dc->remote_machine,
+                                                      cli->dc->mach_acct,
+                                                      sec_channel_type,
+                                                      global_myname(),
+                                                      &clnt_creds,
+                                                      &srv_cred,
+                                                      &new_password);
+
+               /* Always check returned credentials. */
+               if (!netlogon_creds_client_check(cli->dc, &srv_cred.cred)) {
+                       DEBUG(0,("rpccli_netr_ServerPasswordSet2: "
+                               "credentials chain check failed\n"));
+                       return NT_STATUS_ACCESS_DENIED;
+               }
+
+       } else {
+
                struct netr_Authenticator clnt_creds, srv_cred;
                struct samr_Password new_password;
 
@@ -118,8 +144,11 @@ NTSTATUS trust_pw_change_and_store_it(struct rpc_pipe_client *cli, TALLOC_CTX *m
        
        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, sec_channel_type);
+       nt_status = just_change_the_password(cli, mem_ctx,
+                                            orig_trust_passwd_hash,
+                                            new_trust_passwd,
+                                            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",