[SCM] Samba Shared Repository - branch master updated - release-4-0-0alpha8-1341-g9bf74d0

Günther Deschner gd at samba.org
Wed Sep 2 02:48:15 MDT 2009


The branch, master has been updated
       via  9bf74d0ed9c7496bb133e5108ba297abb1b00747 (commit)
       via  2b8afd2257d8c9886f785929ca8dfcd04eb45755 (commit)
       via  71e9dfc0cd7d054dd52508faa4c07db9205b541a (commit)
      from  bde679e6f84b16d63a8007fe48789ee7951b9f34 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 9bf74d0ed9c7496bb133e5108ba297abb1b00747
Author: Günther Deschner <gd at samba.org>
Date:   Fri Aug 28 16:04:08 2009 +0200

    s4-smbtorture: test netr_ServerSetPassword2 against Samba3.
    
    Guenther

commit 2b8afd2257d8c9886f785929ca8dfcd04eb45755
Author: Günther Deschner <gd at samba.org>
Date:   Thu Aug 27 23:30:50 2009 +0200

    s3-netlogon: implement _netr_ServerPasswordSet2.
    
    Guenther

commit 71e9dfc0cd7d054dd52508faa4c07db9205b541a
Author: Günther Deschner <gd at samba.org>
Date:   Thu Aug 27 23:30:14 2009 +0200

    s3-netlogon: rework _netr_ServerPasswordSet.
    
    Guenther

-----------------------------------------------------------------------

Summary of changes:
 source3/rpc_server/srv_netlog_nt.c |  241 ++++++++++++++++++++++++++----------
 source4/torture/rpc/netlogon.c     |    1 +
 2 files changed, 174 insertions(+), 68 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/rpc_server/srv_netlog_nt.c b/source3/rpc_server/srv_netlog_nt.c
index 3daf45b..0b476e1 100644
--- a/source3/rpc_server/srv_netlog_nt.c
+++ b/source3/rpc_server/srv_netlog_nt.c
@@ -491,7 +491,8 @@ NTSTATUS _netr_ServerAuthenticate3(pipes_struct *p,
 		   NETLOGON_NEG_FULL_SYNC_REPL |
 		   NETLOGON_NEG_MULTIPLE_SIDS |
 		   NETLOGON_NEG_REDO |
-		   NETLOGON_NEG_PASSWORD_CHANGE_REFUSAL;
+		   NETLOGON_NEG_PASSWORD_CHANGE_REFUSAL |
+		   NETLOGON_NEG_PASSWORD_SET2;
 
 	/* Ensure we support strong (128-bit) keys. */
 	if (in_neg_flags & NETLOGON_NEG_STRONG_KEYS) {
@@ -655,6 +656,120 @@ static NTSTATUS netr_creds_server_step_check(pipes_struct *p,
 }
 
 /*************************************************************************
+ *************************************************************************/
+
+static NTSTATUS netr_find_machine_account(TALLOC_CTX *mem_ctx,
+					  const char *account_name,
+					  struct samu **sampassp)
+{
+	struct samu *sampass;
+	bool ret = false;
+	uint32_t acct_ctrl;
+
+	sampass = samu_new(mem_ctx);
+	if (!sampass) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	become_root();
+	ret = pdb_getsampwnam(sampass, account_name);
+	unbecome_root();
+
+	if (!ret) {
+		TALLOC_FREE(sampass);
+		return NT_STATUS_ACCESS_DENIED;
+	}
+
+	/* Ensure the account exists and is a machine account. */
+
+	acct_ctrl = pdb_get_acct_ctrl(sampass);
+
+	if (!(acct_ctrl & ACB_WSTRUST ||
+	      acct_ctrl & ACB_SVRTRUST ||
+	      acct_ctrl & ACB_DOMTRUST)) {
+		TALLOC_FREE(sampass);
+		return NT_STATUS_NO_SUCH_USER;
+	}
+
+	if (acct_ctrl & ACB_DISABLED) {
+		TALLOC_FREE(sampass);
+		return NT_STATUS_ACCOUNT_DISABLED;
+	}
+
+	*sampassp = sampass;
+
+	return NT_STATUS_OK;
+}
+
+/*************************************************************************
+ *************************************************************************/
+
+static NTSTATUS netr_set_machine_account_password(TALLOC_CTX *mem_ctx,
+						  struct samu *sampass,
+						  DATA_BLOB *plaintext_blob,
+						  struct samr_Password *nt_hash,
+						  struct samr_Password *lm_hash)
+{
+	NTSTATUS status;
+	const uchar *old_pw;
+	const char *plaintext = NULL;
+	size_t plaintext_len;
+	struct samr_Password nt_hash_local;
+
+	if (!sampass) {
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	if (plaintext_blob) {
+		if (!convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX,
+					   plaintext_blob->data, plaintext_blob->length,
+					   &plaintext, &plaintext_len, false))
+		{
+			plaintext = NULL;
+			mdfour(nt_hash_local.hash, plaintext_blob->data, plaintext_blob->length);
+			nt_hash = &nt_hash_local;
+		}
+	}
+
+	if (plaintext) {
+		if (!pdb_set_plaintext_passwd(sampass, plaintext)) {
+			return NT_STATUS_ACCESS_DENIED;
+		}
+
+		goto done;
+	}
+
+	if (nt_hash) {
+		old_pw = pdb_get_nt_passwd(sampass);
+
+		if (old_pw && memcmp(nt_hash->hash, old_pw, 16) == 0) {
+			/* Avoid backend modificiations and other fun if the
+			   client changed the password to the *same thing* */
+		} else {
+			/* LM password should be NULL for machines */
+			if (!pdb_set_lanman_passwd(sampass, NULL, PDB_CHANGED)) {
+				return NT_STATUS_NO_MEMORY;
+			}
+			if (!pdb_set_nt_passwd(sampass, nt_hash->hash, PDB_CHANGED)) {
+				return NT_STATUS_NO_MEMORY;
+			}
+
+			if (!pdb_set_pass_last_set_time(sampass, time(NULL), PDB_CHANGED)) {
+				/* Not quite sure what this one qualifies as, but this will do */
+				return NT_STATUS_UNSUCCESSFUL;
+			}
+		}
+	}
+
+ done:
+	become_root();
+	status = pdb_update_sam_account(sampass);
+	unbecome_root();
+
+	return status;
+}
+
+/*************************************************************************
  _netr_ServerPasswordSet
  *************************************************************************/
 
@@ -663,10 +778,7 @@ NTSTATUS _netr_ServerPasswordSet(pipes_struct *p,
 {
 	NTSTATUS status = NT_STATUS_OK;
 	struct samu *sampass=NULL;
-	bool ret = False;
 	int i;
-	uint32 acct_ctrl;
-	const uchar *old_pw;
 	struct netlogon_creds_CredentialState *creds;
 
 	DEBUG(5,("_netr_ServerPasswordSet: %d\n", __LINE__));
@@ -690,37 +802,6 @@ NTSTATUS _netr_ServerPasswordSet(pipes_struct *p,
 	DEBUG(3,("_netr_ServerPasswordSet: Server Password Set by remote machine:[%s] on account [%s]\n",
 			r->in.computer_name, creds->computer_name));
 
-	sampass = samu_new( NULL );
-	if (!sampass) {
-		return NT_STATUS_NO_MEMORY;
-	}
-
-	become_root();
-	ret = pdb_getsampwnam(sampass, creds->account_name);
-	unbecome_root();
-
-	if (!ret) {
-		TALLOC_FREE(sampass);
-		return NT_STATUS_ACCESS_DENIED;
-	}
-
-	/* Ensure the account exists and is a machine account. */
-
-	acct_ctrl = pdb_get_acct_ctrl(sampass);
-
-	if (!(acct_ctrl & ACB_WSTRUST ||
-		      acct_ctrl & ACB_SVRTRUST ||
-		      acct_ctrl & ACB_DOMTRUST)) {
-		TALLOC_FREE(sampass);
-		return NT_STATUS_NO_SUCH_USER;
-	}
-
-	if (pdb_get_acct_ctrl(sampass) & ACB_DISABLED) {
-		TALLOC_FREE(sampass);
-		return NT_STATUS_ACCOUNT_DISABLED;
-	}
-
-	/* Woah - what does this to to the credential chain ? JRA */
 	netlogon_creds_des_decrypt(creds, r->in.new_password);
 
 	DEBUG(100,("_netr_ServerPasswordSet: new given value was :\n"));
@@ -728,37 +809,71 @@ NTSTATUS _netr_ServerPasswordSet(pipes_struct *p,
 		DEBUG(100,("%02X ", r->in.new_password->hash[i]));
 	DEBUG(100,("\n"));
 
-	old_pw = pdb_get_nt_passwd(sampass);
+	status = netr_find_machine_account(p->mem_ctx,
+					   creds->account_name,
+					   &sampass);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
 
-	if (old_pw && memcmp(r->in.new_password->hash, old_pw, 16) == 0) {
-		/* Avoid backend modificiations and other fun if the
-		   client changed the password to the *same thing* */
+	status = netr_set_machine_account_password(sampass,
+						   sampass,
+						   NULL,
+						   r->in.new_password,
+						   NULL);
+	TALLOC_FREE(sampass);
+	return status;
+}
 
-		ret = True;
-	} else {
+/****************************************************************
+ _netr_ServerPasswordSet2
+****************************************************************/
 
-		/* LM password should be NULL for machines */
-		if (!pdb_set_lanman_passwd(sampass, NULL, PDB_CHANGED)) {
-			TALLOC_FREE(sampass);
-			return NT_STATUS_NO_MEMORY;
-		}
+NTSTATUS _netr_ServerPasswordSet2(pipes_struct *p,
+				  struct netr_ServerPasswordSet2 *r)
+{
+	NTSTATUS status;
+	struct netlogon_creds_CredentialState *creds;
+	struct samu *sampass;
+	DATA_BLOB plaintext;
+	struct samr_CryptPassword password_buf;
 
-		if (!pdb_set_nt_passwd(sampass, r->in.new_password->hash, PDB_CHANGED)) {
-			TALLOC_FREE(sampass);
-			return NT_STATUS_NO_MEMORY;
-		}
+	become_root();
+	status = netr_creds_server_step_check(p, p->mem_ctx,
+					      r->in.computer_name,
+					      r->in.credential,
+					      r->out.return_authenticator,
+					      &creds);
+	unbecome_root();
 
-		if (!pdb_set_pass_last_set_time(sampass, time(NULL), PDB_CHANGED)) {
-			TALLOC_FREE(sampass);
-			/* Not quite sure what this one qualifies as, but this will do */
-			return NT_STATUS_UNSUCCESSFUL;
-		}
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(2,("_netr_ServerPasswordSet2: netlogon_creds_server_step "
+			"failed. Rejecting auth request from client %s machine account %s\n",
+			r->in.computer_name, creds->computer_name));
+		TALLOC_FREE(creds);
+		return status;
+	}
+
+	memcpy(password_buf.data, r->in.new_password->data, 512);
+	SIVAL(password_buf.data, 512, r->in.new_password->length);
+	netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
 
-		become_root();
-		status = pdb_update_sam_account(sampass);
-		unbecome_root();
+	if (!extract_pw_from_buffer(p->mem_ctx, password_buf.data, &plaintext)) {
+		return NT_STATUS_WRONG_PASSWORD;
 	}
 
+	status = netr_find_machine_account(p->mem_ctx,
+					   creds->account_name,
+					   &sampass);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
+	status = netr_set_machine_account_password(sampass,
+						   sampass,
+						   &plaintext,
+						   NULL,
+						   NULL);
 	TALLOC_FREE(sampass);
 	return status;
 }
@@ -1309,16 +1424,6 @@ NTSTATUS _netr_LogonGetDomainInfo(pipes_struct *p,
 /****************************************************************
 ****************************************************************/
 
-NTSTATUS _netr_ServerPasswordSet2(pipes_struct *p,
-				  struct netr_ServerPasswordSet2 *r)
-{
-	p->rng_fault_state = true;
-	return NT_STATUS_NOT_IMPLEMENTED;
-}
-
-/****************************************************************
-****************************************************************/
-
 WERROR _netr_ServerPasswordGet(pipes_struct *p,
 			       struct netr_ServerPasswordGet *r)
 {
diff --git a/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c
index 9a73cfe..40561dc 100644
--- a/source4/torture/rpc/netlogon.c
+++ b/source4/torture/rpc/netlogon.c
@@ -2749,6 +2749,7 @@ struct torture_suite *torture_rpc_netlogon_s3(TALLOC_CTX *mem_ctx)
 	torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
 	torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
 	torture_rpc_tcase_add_test_creds(tcase, "SetPassword_with_flags", test_SetPassword_with_flags);
+	torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
 	torture_rpc_tcase_add_test(tcase, "LogonControl", test_LogonControl);
 	torture_rpc_tcase_add_test(tcase, "LogonControl2", test_LogonControl2);
 	torture_rpc_tcase_add_test(tcase, "LogonControl2Ex", test_LogonControl2Ex);


-- 
Samba Shared Repository


More information about the samba-cvs mailing list