[SCM] Samba Shared Repository - branch master updated - release-4-0-0alpha8-288-g2481ce8

Andrew Bartlett abartlet at samba.org
Thu Jul 9 04:57:07 GMT 2009


The branch, master has been updated
       via  2481ce89427ef38b47fb29d16c15b77e9d2c20b9 (commit)
       via  2c873c43534d61cd411b5c8d56425fd9c2ddd128 (commit)
      from  fbaa8497a5c8c209de9ca86bebf8387e6d33a608 (commit)

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


- Log -----------------------------------------------------------------
commit 2481ce89427ef38b47fb29d16c15b77e9d2c20b9
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Thu Jul 9 14:53:26 2009 +1000

    s4:dsdb Allow unicodePwd to be set when adding a user
    
    Windows 7 sets it's join password using the unicodePwd attribute (as a
    quoted, utf16 string), and does so during the LDAPAdd of the object.
    Previously, this code only handled unicodePwd for modifies.
    
    Andrew Bartlett

commit 2c873c43534d61cd411b5c8d56425fd9c2ddd128
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Thu Jul 9 10:08:02 2009 +1000

    Add const

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

Summary of changes:
 source4/dsdb/common/util.c                     |    4 +-
 source4/dsdb/samdb/ldb_modules/password_hash.c |  169 ++++++++++++------------
 2 files changed, 86 insertions(+), 87 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c
index 313005b..cbae2ec 100644
--- a/source4/dsdb/common/util.c
+++ b/source4/dsdb/common/util.c
@@ -529,7 +529,7 @@ NTTIME samdb_result_force_password_change(struct ldb_context *sam_ldb,
 /*
   pull a samr_Password structutre from a result set. 
 */
-struct samr_Password *samdb_result_hash(TALLOC_CTX *mem_ctx, struct ldb_message *msg, const char *attr)
+struct samr_Password *samdb_result_hash(TALLOC_CTX *mem_ctx, const struct ldb_message *msg, const char *attr)
 {
 	struct samr_Password *hash = NULL;
 	const struct ldb_val *val = ldb_msg_find_ldb_val(msg, attr);
@@ -543,7 +543,7 @@ struct samr_Password *samdb_result_hash(TALLOC_CTX *mem_ctx, struct ldb_message
 /*
   pull an array of samr_Password structutres from a result set. 
 */
-uint_t samdb_result_hashes(TALLOC_CTX *mem_ctx, struct ldb_message *msg, 
+uint_t samdb_result_hashes(TALLOC_CTX *mem_ctx, const struct ldb_message *msg, 
 			   const char *attr, struct samr_Password **hashes)
 {
 	uint_t count = 0;
diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c
index 5a9926b..44b7ef9 100644
--- a/source4/dsdb/samdb/ldb_modules/password_hash.c
+++ b/source4/dsdb/samdb/ldb_modules/password_hash.c
@@ -1432,6 +1432,67 @@ static int setup_password_fields(struct setup_password_fields_io *io)
 	return LDB_SUCCESS;
 }
 
+static int setup_io(struct ph_context *ac, 
+		    const struct ldb_message *new_msg, 
+		    const struct ldb_message *searched_msg, 
+		    struct setup_password_fields_io *io) 
+{ 
+	const struct ldb_val *quoted_utf16;
+	struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
+
+	ZERO_STRUCTP(io);
+
+	/* Some operations below require kerberos contexts */
+	if (smb_krb5_init_context(ac,
+				  ldb_get_event_context(ldb),
+				  (struct loadparm_context *)ldb_get_opaque(ldb, "loadparm"),
+				  &io->smb_krb5_context) != 0) {
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
+
+	io->ac				= ac;
+	io->domain			= ac->domain;
+
+	io->u.user_account_control	= samdb_result_uint(searched_msg, "userAccountControl", 0);
+	io->u.sAMAccountName		= samdb_result_string(searched_msg, "samAccountName", NULL);
+	io->u.user_principal_name	= samdb_result_string(searched_msg, "userPrincipalName", NULL);
+	io->u.is_computer		= ldb_msg_check_string_attribute(searched_msg, "objectClass", "computer");
+
+	io->n.cleartext_utf8		= ldb_msg_find_ldb_val(new_msg, "userPassword");
+	io->n.cleartext_utf16		= ldb_msg_find_ldb_val(new_msg, "clearTextPassword");
+
+	/* this rather strange looking piece of code is there to
+	   handle a ldap client setting a password remotely using the
+	   unicodePwd ldap field. The syntax is that the password is
+	   in UTF-16LE, with a " at either end. Unfortunately the
+	   unicodePwd field is also used to store the nt hashes
+	   internally in Samba, and is used in the nt hash format on
+	   the wire in DRS replication, so we have a single name for
+	   two distinct values. The code below leaves us with a small
+	   chance (less than 1 in 2^32) of a mixup, if someone manages
+	   to create a MD4 hash which starts and ends in 0x22 0x00, as
+	   that would then be treated as a UTF16 password rather than
+	   a nthash */
+	quoted_utf16			= ldb_msg_find_ldb_val(new_msg, "unicodePwd");
+	if (quoted_utf16 && 
+	    quoted_utf16->length >= 4 &&
+	    quoted_utf16->data[0] == '"' && 
+	    quoted_utf16->data[1] == 0 && 
+	    quoted_utf16->data[quoted_utf16->length-2] == '"' && 
+	    quoted_utf16->data[quoted_utf16->length-1] == 0) {
+		io->n.quoted_utf16.data = talloc_memdup(io->ac, quoted_utf16->data+2, quoted_utf16->length-4);
+		io->n.quoted_utf16.length = quoted_utf16->length-4;
+		io->n.cleartext_utf16 = &io->n.quoted_utf16;
+		io->n.nt_hash = NULL;
+	} else {
+		io->n.nt_hash		= samdb_result_hash(io->ac, new_msg, "unicodePwd");
+	}
+
+	io->n.lm_hash			= samdb_result_hash(io->ac, new_msg, "dBCSPwd");
+
+	return LDB_SUCCESS;
+}
+
 static struct ph_context *ph_init_context(struct ldb_module *module,
 					  struct ldb_request *req)
 {
@@ -1743,50 +1804,32 @@ static int password_hash_add_do_add(struct ph_context *ac)
 {
 	struct ldb_context *ldb;
 	struct ldb_request *down_req;
-	struct smb_krb5_context *smb_krb5_context;
 	struct ldb_message *msg;
 	struct setup_password_fields_io io;
 	int ret;
 
-	ldb = ldb_module_get_ctx(ac->module);
+	/* Prepare the internal data structure containing the passwords */
+	ret = setup_io(ac, ac->req->op.add.message, ac->req->op.add.message, &io);
+	if (ret != LDB_SUCCESS) {
+		return ret;
+	}
 
 	msg = ldb_msg_copy_shallow(ac, ac->req->op.add.message);
 	if (msg == NULL) {
 		return LDB_ERR_OPERATIONS_ERROR;
 	}
 
-	/* Some operations below require kerberos contexts */
-	if (smb_krb5_init_context(ac,
-				  ldb_get_event_context(ldb),
-				  (struct loadparm_context *)ldb_get_opaque(ldb, "loadparm"),
-				  &smb_krb5_context) != 0) {
-		return LDB_ERR_OPERATIONS_ERROR;
-	}
-
-	ZERO_STRUCT(io);
-	io.ac				= ac;
-	io.domain			= ac->domain;
-	io.smb_krb5_context		= smb_krb5_context;
-
-	io.u.user_account_control	= samdb_result_uint(msg, "userAccountControl", 0);
-	io.u.sAMAccountName		= samdb_result_string(msg, "samAccountName", NULL);
-	io.u.user_principal_name	= samdb_result_string(msg, "userPrincipalName", NULL);
-	io.u.is_computer		= ldb_msg_check_string_attribute(msg, "objectClass", "computer");
-
-	io.n.cleartext_utf8		= ldb_msg_find_ldb_val(msg, "userPassword");
-	io.n.cleartext_utf16		= ldb_msg_find_ldb_val(msg, "clearTextPassword");
-	io.n.nt_hash			= samdb_result_hash(io.ac, msg, "unicodePwd");
-	io.n.lm_hash			= samdb_result_hash(io.ac, msg, "dBCSPwd");
-
-	/* remove attributes */
-	if (io.n.cleartext_utf8) ldb_msg_remove_attr(msg, "userPassword");
-	if (io.n.cleartext_utf16) ldb_msg_remove_attr(msg, "clearTextPassword");
-	if (io.n.nt_hash) ldb_msg_remove_attr(msg, "unicodePwd");
-	if (io.n.lm_hash) ldb_msg_remove_attr(msg, "dBCSPwd");
+	/* remove attributes that we just read into 'io' */
+	ldb_msg_remove_attr(msg, "userPassword");
+	ldb_msg_remove_attr(msg, "clearTextPassword");
+	ldb_msg_remove_attr(msg, "unicodePwd");
+	ldb_msg_remove_attr(msg, "dBCSPwd");
 	ldb_msg_remove_attr(msg, "pwdLastSet");
 	io.o.kvno = samdb_result_uint(msg, "msDs-KeyVersionNumber", 1) - 1;
 	ldb_msg_remove_attr(msg, "msDs-KeyVersionNumber");
 
+	ldb = ldb_module_get_ctx(ac->module);
+
 	ret = setup_password_fields(&io);
 	if (ret != LDB_SUCCESS) {
 		return ret;
@@ -2096,12 +2139,9 @@ static int password_hash_mod_do_mod(struct ph_context *ac)
 {
 	struct ldb_context *ldb;
 	struct ldb_request *mod_req;
-	struct smb_krb5_context *smb_krb5_context;
 	struct ldb_message *msg;
-	struct ldb_message *orig_msg;
-	struct ldb_message *searched_msg;
+	const struct ldb_message *searched_msg;
 	struct setup_password_fields_io io;
-	const struct ldb_val *quoted_utf16;
 	int ret;
 
 	ldb = ldb_module_get_ctx(ac->module);
@@ -2115,59 +2155,18 @@ static int password_hash_mod_do_mod(struct ph_context *ac)
 	/* modify dn */
 	msg->dn = ac->req->op.mod.message->dn;
 
-	/* Some operations below require kerberos contexts */
-	if (smb_krb5_init_context(ac,
-				  ldb_get_event_context(ldb),
-				  (struct loadparm_context *)ldb_get_opaque(ldb, "loadparm"),
-				  &smb_krb5_context) != 0) {
-		return LDB_ERR_OPERATIONS_ERROR;
-	}
-
-	orig_msg	= discard_const(ac->req->op.mod.message);
-	searched_msg	= ac->search_res->message;
-
-	ZERO_STRUCT(io);
-	io.ac				= ac;
-	io.domain			= ac->domain;
-	io.smb_krb5_context		= smb_krb5_context;
-
-	io.u.user_account_control	= samdb_result_uint(searched_msg, "userAccountControl", 0);
-	io.u.sAMAccountName		= samdb_result_string(searched_msg, "samAccountName", NULL);
-	io.u.user_principal_name	= samdb_result_string(searched_msg, "userPrincipalName", NULL);
-	io.u.is_computer		= ldb_msg_check_string_attribute(searched_msg, "objectClass", "computer");
-
-	io.n.cleartext_utf8		= ldb_msg_find_ldb_val(orig_msg, "userPassword");
-	io.n.cleartext_utf16		= ldb_msg_find_ldb_val(orig_msg, "clearTextPassword");
-
-	/* this rather strange looking piece of code is there to
-	   handle a ldap client setting a password remotely using the
-	   unicodePwd ldap field. The syntax is that the password is
-	   in UTF-16LE, with a " at either end. Unfortunately the
-	   unicodePwd field is also used to store the nt hashes
-	   internally in Samba, and is used in the nt hash format on
-	   the wire in DRS replication, so we have a single name for
-	   two distinct values. The code below leaves us with a small
-	   chance (less than 1 in 2^32) of a mixup, if someone manages
-	   to create a MD4 hash which starts and ends in 0x22 0x00, as
-	   that would then be treated as a UTF16 password rather than
-	   a nthash */
-	quoted_utf16			= ldb_msg_find_ldb_val(orig_msg, "unicodePwd");
-	if (quoted_utf16 && 
-	    quoted_utf16->length >= 4 &&
-	    quoted_utf16->data[0] == '"' && 
-	    quoted_utf16->data[1] == 0 && 
-	    quoted_utf16->data[quoted_utf16->length-2] == '"' && 
-	    quoted_utf16->data[quoted_utf16->length-1] == 0) {
-		io.n.quoted_utf16.data = talloc_memdup(orig_msg, quoted_utf16->data+2, quoted_utf16->length-4);
-		io.n.quoted_utf16.length = quoted_utf16->length-4;
-		io.n.cleartext_utf16 = &io.n.quoted_utf16;
-		io.n.nt_hash = NULL;
-	} else {
-		io.n.nt_hash		= samdb_result_hash(io.ac, orig_msg, "unicodePwd");
+	/* Prepare the internal data structure containing the passwords */
+	ret = setup_io(ac, 
+		       ac->req->op.mod.message, 
+		       ac->search_res->message, 
+		       &io);
+	if (ret != LDB_SUCCESS) {
+		return ret;
 	}
+	
+	searched_msg = ac->search_res->message;
 
-	io.n.lm_hash			= samdb_result_hash(io.ac, orig_msg, "dBCSPwd");
-
+	/* Fill in some final details (only relevent once the password has been set) */
 	io.o.kvno			= samdb_result_uint(searched_msg, "msDs-KeyVersionNumber", 0);
 	io.o.nt_history_len		= samdb_result_hashes(io.ac, searched_msg, "ntPwdHistory", &io.o.nt_history);
 	io.o.lm_history_len		= samdb_result_hashes(io.ac, searched_msg, "lmPwdHistory", &io.o.lm_history);


-- 
Samba Shared Repository


More information about the samba-cvs mailing list