[SCM] Samba Shared Repository - branch master updated

Matthias Dieter Wallnöfer mdw at samba.org
Mon May 10 11:13:39 MDT 2010


The branch, master has been updated
       via  6131caa... s4:passwords.py - add a python unittest for additional testing of my passwords work
       via  0293515... s4:samdb_set_password - adapt it for the user password change handling
       via  6e8098b... s4:samdb_set_password/samdb_set_password_sid - Rework
       via  fc8e3ff... s4:password_hash - Implement password restrictions
       via  6a69ec2... s4:password_hash - Rework to handle password changes
       via  12c4b09... s4:password_hash - Rework unique value checks
       via  3ce4a0c... s4:password_hash - Various (mostly cosmetic) prework
       via  726fb35... s4:dsdb: add new controls
       via  1913e03... s4:setup: mark DSDB_CONTROL_DN_STORAGE_FORMAT_OID 1.3.6.1.4.1.7165.4.3.4 as allocated
      from  658dac9... v2 Latest enhancements in ldapcmp tool

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


- Log -----------------------------------------------------------------
commit 6131caad8f35b6fb3d3fe79c67f59ee228bef6c1
Author: Matthias Dieter Wallnöfer <mwallnoefer at yahoo.de>
Date:   Sat Apr 10 20:04:13 2010 +0200

    s4:passwords.py - add a python unittest for additional testing of my passwords work
    
    This performs checks on direct password changes over LDB/LDAP. Indirect
    password changes over the RPCs are already tested by some torture suite (SAMR
    passwords). So no need to do this again here.

commit 029351571a5bd65a467ff9e7844a7a1ef3d688a0
Author: Matthias Dieter Wallnöfer <mwallnoefer at yahoo.de>
Date:   Thu Dec 3 10:48:44 2009 +0100

    s4:samdb_set_password - adapt it for the user password change handling
    
    Make use of the new "change old password checked" control.

commit 6e8098b261b9357204c8fa5534871a4c137ca1c5
Author: Matthias Dieter Wallnöfer <mwallnoefer at yahoo.de>
Date:   Sat Sep 26 12:09:07 2009 +0200

    s4:samdb_set_password/samdb_set_password_sid - Rework
    
    Adapt the two functions for the restructured "password_hash" module. This
    means that basically all checks are now performed in the mentioned module.
    
    An exception consists in the SAMR password change calls since they need very
    precise NTSTATUS return codes on wrong constraints ("samr_password.c") file

commit fc8e3ffb5f261e7efdcbcef46b1f13c3b5599730
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon May 10 17:36:54 2010 +0200

    s4:password_hash - Implement password restrictions
    
    Based on the Patch from Matthias Dieter Wallnöfer <mwallnoefer at yahoo.de>.
    
    metze

commit 6a69ec2f5a046194c9f4dc108c0680ab263790c4
Author: Matthias Dieter Wallnöfer <mwallnoefer at yahoo.de>
Date:   Wed Sep 23 19:25:54 2009 +0200

    s4:password_hash - Rework to handle password changes
    
    - Implement the password restrictions as specified in "samdb_set_password"
      (complexity, minimum password length, minimum password age...).
    - We support only (administrative) password reset operations at the moment
    - Support password (administrative) reset and change operations (consider
      MS-ADTS 3.1.1.3.1.5)

commit 12c4b09fd511eaa0671ccf0b05d8407f97167105
Author: Matthias Dieter Wallnöfer <mwallnoefer at yahoo.de>
Date:   Fri Oct 23 12:51:47 2009 +0200

    s4:password_hash - Rework unique value checks
    
    Windows Server performs the constraint checks in a different way than we do.
    All testing has been done using "passwords.py".

commit 3ce4a0c5f26faad40f0b77f2da11b918b11ef3d2
Author: Matthias Dieter Wallnöfer <mwallnoefer at yahoo.de>
Date:   Fri Oct 23 12:51:47 2009 +0200

    s4:password_hash - Various (mostly cosmetic) prework
    
    - Enhance comments
    - Get some more attributes from the domain and user object (needed later)
    - Check for right objectclass on change/set operations (instances of
      "user" and/or "inetOrgPerson") - otherwise forward the request
    - (Cosmetic) cleanup in asynchronous results regarding return values

commit 726fb35f9f226a488c2b9793e4daa6cab63daa73
Author: Matthias Dieter Wallnöfer <mwallnoefer at yahoo.de>
Date:   Wed Sep 23 19:25:54 2009 +0200

    s4:dsdb: add new controls
    
    - Add a new control for getting status informations (domain informations,
      password change status) directly from the module
    - Add a new control for allowing direct hash changes
    - Introduce an addtional control "change_old password checked" for the password

commit 1913e03bd418808193e6ff0d595a6ce827d1e22e
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon May 10 12:25:32 2010 +0200

    s4:setup: mark DSDB_CONTROL_DN_STORAGE_FORMAT_OID 1.3.6.1.4.1.7165.4.3.4 as allocated
    
    metze

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

Summary of changes:
 source4/dsdb/common/util.c                     |  402 +++-----
 source4/dsdb/samdb/ldb_modules/password_hash.c | 1191 ++++++++++++++++++------
 source4/dsdb/samdb/samdb.h                     |   21 +
 source4/kdc/kpasswdd.c                         |   35 +-
 source4/lib/ldb/tests/python/passwords.py      |  579 ++++++++++++
 source4/rpc_server/samr/dcesrv_samr.c          |   12 +-
 source4/rpc_server/samr/samr_password.c        |  105 +--
 source4/selftest/tests.sh                      |    1 +
 source4/setup/schema_samba4.ldif               |    9 +-
 9 files changed, 1671 insertions(+), 684 deletions(-)
 create mode 100755 source4/lib/ldb/tests/python/passwords.py


Changeset truncated at 500 lines:

diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c
index 2948be0..5deb1d0 100644
--- a/source4/dsdb/common/util.c
+++ b/source4/dsdb/common/util.c
@@ -1892,276 +1892,194 @@ enum samr_ValidationStatus samdb_check_password(const DATA_BLOB *password,
 }
 
 /*
+ * Callback for "samdb_set_password" password change
+ */
+int samdb_set_password_callback(struct ldb_request *req, struct ldb_reply *ares)
+{
+	int ret;
+
+	if (!ares) {
+		return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
+	}
+
+	if (ares->error != LDB_SUCCESS) {
+		ret = ares->error;
+		req->context = talloc_steal(req,
+					    ldb_reply_get_control(ares, DSDB_CONTROL_PASSWORD_CHANGE_STATUS_OID));
+		talloc_free(ares);
+		return ldb_request_done(req, ret);
+	}
+
+	if (ares->type != LDB_REPLY_DONE) {
+		talloc_free(ares);
+		return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
+	}
+
+	req->context = talloc_steal(req,
+				    ldb_reply_get_control(ares, DSDB_CONTROL_PASSWORD_CHANGE_STATUS_OID));
+	talloc_free(ares);
+	return ldb_request_done(req, LDB_SUCCESS);
+}
+
+/*
  * Sets the user password using plaintext UTF16 (attribute "new_password") or
  * LM (attribute "lmNewHash") or NT (attribute "ntNewHash") hash. Also pass
  * as parameter if it's a user change or not ("userChange"). The "rejectReason"
  * gives some more informations if the changed failed.
  *
- * The caller should have a LDB transaction wrapping this.
- *
  * Results: NT_STATUS_OK, NT_STATUS_INTERNAL_DB_CORRUPTION,
  *   NT_STATUS_INVALID_PARAMETER, NT_STATUS_UNSUCCESSFUL,
- *   NT_STATUS_PASSWORD_RESTRICTION
+ *   NT_STATUS_WRONG_PASSWORD, NT_STATUS_PASSWORD_RESTRICTION
  */
-NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ctx,
+NTSTATUS samdb_set_password(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
 			    struct ldb_dn *user_dn, struct ldb_dn *domain_dn,
-			    struct ldb_message *mod,
 			    const DATA_BLOB *new_password,
-			    struct samr_Password *param_lmNewHash,
-			    struct samr_Password *param_ntNewHash,
+			    struct samr_Password *lmNewHash,
+			    struct samr_Password *ntNewHash,
 			    bool user_change,
 			    enum samPwdChangeReason *reject_reason,
 			    struct samr_DomInfo1 **_dominfo)
 {
-	const char * const user_attrs[] = { "userAccountControl",
-					    "lmPwdHistory",
-					    "ntPwdHistory", 
-					    "dBCSPwd", "unicodePwd", 
-					    "objectSid", 
-					    "pwdLastSet", NULL };
-	const char * const domain_attrs[] = { "minPwdLength", "pwdProperties",
-					      "pwdHistoryLength",
-					      "maxPwdAge", "minPwdAge", NULL };
-	NTTIME pwdLastSet;
-	uint32_t minPwdLength, pwdProperties, pwdHistoryLength;
-	int64_t maxPwdAge, minPwdAge;
-	uint32_t userAccountControl;
-	struct samr_Password *sambaLMPwdHistory, *sambaNTPwdHistory,
-		*lmPwdHash, *ntPwdHash, *lmNewHash, *ntNewHash;
-	struct samr_Password local_lmNewHash, local_ntNewHash;
-	int sambaLMPwdHistory_len, sambaNTPwdHistory_len;
-	struct dom_sid *domain_sid;
-	struct ldb_message **res;
-	bool restrictions;
-	int count;
-	time_t now = time(NULL);
-	NTTIME now_nt;
-	unsigned int i;
+	struct ldb_message *msg;
+	struct ldb_message_element *el;
+	struct ldb_request *req;
+	struct dsdb_control_password_change_status *pwd_stat = NULL;
+	int ret;
+	NTSTATUS status;
 
-	/* we need to know the time to compute password age */
-	unix_to_nt_time(&now_nt, now);
+#define CHECK_RET(x) \
+	if (x != LDB_SUCCESS) { \
+		talloc_free(msg); \
+		return NT_STATUS_NO_MEMORY; \
+	}
 
-	/* pull all the user parameters */
-	count = gendb_search_dn(ctx, mem_ctx, user_dn, &res, user_attrs);
-	if (count != 1) {
-		return NT_STATUS_INTERNAL_DB_CORRUPTION;
+	msg = ldb_msg_new(mem_ctx);
+	if (msg == NULL) {
+		return NT_STATUS_NO_MEMORY;
 	}
-	userAccountControl = samdb_result_uint(res[0], "userAccountControl", 0);
-	sambaLMPwdHistory_len = samdb_result_hashes(mem_ctx, res[0],
-					 "lmPwdHistory", &sambaLMPwdHistory);
-	sambaNTPwdHistory_len = samdb_result_hashes(mem_ctx, res[0],
-					 "ntPwdHistory", &sambaNTPwdHistory);
-	lmPwdHash = samdb_result_hash(mem_ctx, res[0], "dBCSPwd");
-	ntPwdHash = samdb_result_hash(mem_ctx, res[0], "unicodePwd");
-	pwdLastSet = samdb_result_uint64(res[0], "pwdLastSet", 0);
-
-	/* Copy parameters */
-	lmNewHash = param_lmNewHash;
-	ntNewHash = param_ntNewHash;
-
-	/* Only non-trust accounts have restrictions (possibly this
-	 * test is the wrong way around, but I like to be restrictive
-	 * if possible */
-	restrictions = !(userAccountControl & (UF_INTERDOMAIN_TRUST_ACCOUNT
-					       |UF_WORKSTATION_TRUST_ACCOUNT
-					       |UF_SERVER_TRUST_ACCOUNT)); 
-
-	if (domain_dn != NULL) {
-		/* pull the domain parameters */
-		count = gendb_search_dn(ctx, mem_ctx, domain_dn, &res,
-								domain_attrs);
-		if (count != 1) {
-			DEBUG(2, ("samdb_set_password: Domain DN %s is invalid, for user %s\n", 
-				  ldb_dn_get_linearized(domain_dn),
-				  ldb_dn_get_linearized(user_dn)));
-			return NT_STATUS_NO_SUCH_DOMAIN;
+	msg->dn = user_dn;
+	if ((new_password != NULL)
+			&& ((lmNewHash == NULL) && (ntNewHash == NULL))) {
+		/* we have the password as plaintext UTF16 */
+		CHECK_RET(samdb_msg_add_value(ldb, mem_ctx, msg,
+			"clearTextPassword", new_password));
+		el = ldb_msg_find_element(msg, "clearTextPassword");
+		el->flags = LDB_FLAG_MOD_REPLACE;
+	} else if ((new_password == NULL)
+			&& ((lmNewHash != NULL) || (ntNewHash != NULL))) {
+		/* we have a password as LM and/or NT hash */
+		if (lmNewHash != NULL) {
+			CHECK_RET(samdb_msg_add_hash(ldb, mem_ctx, msg,
+				"dBCSPwd", lmNewHash));
+			el = ldb_msg_find_element(msg, "dBCSPwd");
+			el->flags = LDB_FLAG_MOD_REPLACE;
 		}
-	} else {
-		/* work out the domain sid, and pull the domain from there */
-		domain_sid = samdb_result_sid_prefix(mem_ctx, res[0],
-								"objectSid");
-		if (domain_sid == NULL) {
-			return NT_STATUS_INTERNAL_DB_CORRUPTION;
+		if (ntNewHash != NULL) {
+			CHECK_RET(samdb_msg_add_hash(ldb, mem_ctx, msg,
+				"unicodePwd", ntNewHash));
+			el = ldb_msg_find_element(msg, "unicodePwd");
+			el->flags = LDB_FLAG_MOD_REPLACE;
 		}
+	} else {
+		/* the password wasn't specified correctly */
+		talloc_free(msg);
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	/* build modify request */
+	ret = ldb_build_mod_req(&req, ldb, mem_ctx, msg, NULL, NULL,
+				samdb_set_password_callback, NULL);
+        if (ret != LDB_SUCCESS) {
+		talloc_free(msg);
+		return NT_STATUS_NO_MEMORY;
+        }
 
-		count = gendb_search(ctx, mem_ctx, NULL, &res, domain_attrs, 
-				"(objectSid=%s)",
-				ldap_encode_ndr_dom_sid(mem_ctx, domain_sid));
-		if (count != 1) {
-			DEBUG(2, ("samdb_set_password: Could not find domain to match SID: %s, for user %s\n", 
-				  dom_sid_string(mem_ctx, domain_sid),
-				  ldb_dn_get_linearized(user_dn)));
-			return NT_STATUS_NO_SUCH_DOMAIN;
+	if (user_change) {
+		/* a user password change and we've checked already the old
+		 * password somewhere else (callers responsability) */
+		ret = ldb_request_add_control(req,
+					      DSDB_CONTROL_PASSWORD_CHANGE_OLD_PW_CHECKED_OID,
+					      true, NULL);
+		if (ret != LDB_SUCCESS) {
+			talloc_free(req);
+			talloc_free(msg);
+			return NT_STATUS_NO_MEMORY;
 		}
 	}
+	ret = ldb_request_add_control(req,
+				      DSDB_CONTROL_PASSWORD_HASH_VALUES_OID,
+				      true, NULL);
+	if (ret != LDB_SUCCESS) {
+		talloc_free(req);
+		talloc_free(msg);
+		return NT_STATUS_NO_MEMORY;
+	}
+	ret = ldb_request_add_control(req,
+				      DSDB_CONTROL_PASSWORD_CHANGE_STATUS_OID,
+				      true, NULL);
+	if (ret != LDB_SUCCESS) {
+		talloc_free(req);
+		talloc_free(msg);
+		return NT_STATUS_NO_MEMORY;
+	}
 
-	minPwdLength = samdb_result_uint(res[0], "minPwdLength", 0);
-	pwdProperties = samdb_result_uint(res[0], "pwdProperties", 0);
-	pwdHistoryLength = samdb_result_uint(res[0], "pwdHistoryLength", 0);
-	maxPwdAge = samdb_result_int64(res[0], "maxPwdAge", 0);
-	minPwdAge = samdb_result_int64(res[0], "minPwdAge", 0);
+	ret = dsdb_autotransaction_request(ldb, req);
 
-	if ((userAccountControl & UF_PASSWD_NOTREQD) != 0) {
-		/* see [MS-ADTS] 2.2.15 */
-		minPwdLength = 0;
+	if (req->context != NULL) {
+		pwd_stat = talloc_steal(mem_ctx,
+					((struct ldb_control *)req->context)->data);
 	}
 
+	talloc_free(req);
+	talloc_free(msg);
+
+	/* Sets the domain info (if requested) */
 	if (_dominfo != NULL) {
 		struct samr_DomInfo1 *dominfo;
-		/* on failure we need to fill in the reject reasons */
-		dominfo = talloc(mem_ctx, struct samr_DomInfo1);
+
+		dominfo = talloc_zero(mem_ctx, struct samr_DomInfo1);
 		if (dominfo == NULL) {
 			return NT_STATUS_NO_MEMORY;
 		}
-		dominfo->min_password_length     = minPwdLength;
-		dominfo->password_properties     = pwdProperties;
-		dominfo->password_history_length = pwdHistoryLength;
-		dominfo->max_password_age        = maxPwdAge;
-		dominfo->min_password_age        = minPwdAge;
-		*_dominfo = dominfo;
-	}
-
-	if ((restrictions != 0) && (new_password != 0)) {
-		char *new_pass;
 
-		/* checks if the "minPwdLength" property is satisfied */
-		if ((restrictions != 0)
-			&& (minPwdLength > utf16_len_n(
-				new_password->data, new_password->length)/2)) {
-			if (reject_reason) {
-				*reject_reason = SAM_PWD_CHANGE_PASSWORD_TOO_SHORT;
-			}
-			return NT_STATUS_PASSWORD_RESTRICTION;
+		if (pwd_stat != NULL) {
+			dominfo->min_password_length     = pwd_stat->domain_data.minPwdLength;
+			dominfo->password_properties     = pwd_stat->domain_data.pwdProperties;
+			dominfo->password_history_length = pwd_stat->domain_data.pwdHistoryLength;
+			dominfo->max_password_age        = pwd_stat->domain_data.maxPwdAge;
+			dominfo->min_password_age        = pwd_stat->domain_data.minPwdAge;
 		}
 
-		/* Create the NT hash */
-		mdfour(local_ntNewHash.hash, new_password->data,
-							new_password->length);
-
-		ntNewHash = &local_ntNewHash;
-
-		/* Only check complexity if we can convert it at all.  Assuming unconvertable passwords are 'strong' */
-		if (convert_string_talloc_convenience(mem_ctx,
-			  lp_iconv_convenience(ldb_get_opaque(ctx, "loadparm")),
-			  CH_UTF16, CH_UNIX,
-			  new_password->data, new_password->length,
-			  (void **)&new_pass, NULL, false)) {
-
-			/* checks the password complexity */
-			if ((restrictions != 0)
-				&& ((pwdProperties
-					& DOMAIN_PASSWORD_COMPLEX) != 0)
-				&& (!check_password_quality(new_pass))) {
-				if (reject_reason) {
-					*reject_reason = SAM_PWD_CHANGE_NOT_COMPLEX;
-				}
-				return NT_STATUS_PASSWORD_RESTRICTION;
-			}
-
-			/* compute the new lm hashes (for checking history - case insenitivly!) */
-			if (E_deshash(new_pass, local_lmNewHash.hash)) {
-				lmNewHash = &local_lmNewHash;
-			}
-		}
+		*_dominfo = dominfo;
 	}
 
-	if ((restrictions != 0) && user_change) {
-		/* are all password changes disallowed? */
-		if ((pwdProperties & DOMAIN_REFUSE_PASSWORD_CHANGE) != 0) {
-			if (reject_reason) {
-				*reject_reason = SAM_PWD_CHANGE_NO_ERROR;
-			}
-			return NT_STATUS_PASSWORD_RESTRICTION;
-		}
-
-		/* can this user change the password? */
-		if ((userAccountControl & UF_PASSWD_CANT_CHANGE) != 0) {
-			if (reject_reason) {
-				*reject_reason = SAM_PWD_CHANGE_NO_ERROR;
-			}
-			return NT_STATUS_PASSWORD_RESTRICTION;
-		}
-
-		/* Password minimum age: yes, this is a minus. The ages are in negative 100nsec units! */
-		if (pwdLastSet - minPwdAge > now_nt) {
-			if (reject_reason) {
-				*reject_reason = SAM_PWD_CHANGE_NO_ERROR;
-			}
-			return NT_STATUS_PASSWORD_RESTRICTION;
-		}
-
-		/* check the immediately past password */
-		if (pwdHistoryLength > 0) {
-			if (lmNewHash && lmPwdHash && memcmp(lmNewHash->hash,
-					lmPwdHash->hash, 16) == 0) {
-				if (reject_reason) {
-					*reject_reason = SAM_PWD_CHANGE_PWD_IN_HISTORY;
-				}
-				return NT_STATUS_PASSWORD_RESTRICTION;
-			}
-			if (ntNewHash && ntPwdHash && memcmp(ntNewHash->hash,
-					ntPwdHash->hash, 16) == 0) {
-				if (reject_reason) {
-					*reject_reason = SAM_PWD_CHANGE_PWD_IN_HISTORY;
-				}
-				return NT_STATUS_PASSWORD_RESTRICTION;
-			}
-		}
-
-		/* check the password history */
-		sambaLMPwdHistory_len = MIN(sambaLMPwdHistory_len,
-							pwdHistoryLength);
-		sambaNTPwdHistory_len = MIN(sambaNTPwdHistory_len,
-							pwdHistoryLength);
-
-		for (i=0; lmNewHash && i<sambaLMPwdHistory_len;i++) {
-			if (memcmp(lmNewHash->hash, sambaLMPwdHistory[i].hash,
-					16) == 0) {
-				if (reject_reason) {
-					*reject_reason = SAM_PWD_CHANGE_PWD_IN_HISTORY;
-				}
-				return NT_STATUS_PASSWORD_RESTRICTION;
-			}
-		}
-		for (i=0; ntNewHash && i<sambaNTPwdHistory_len;i++) {
-			if (memcmp(ntNewHash->hash, sambaNTPwdHistory[i].hash,
-					 16) == 0) {
-				if (reject_reason) {
-					*reject_reason = SAM_PWD_CHANGE_PWD_IN_HISTORY;
-				}
-				return NT_STATUS_PASSWORD_RESTRICTION;
-			}
+	if (reject_reason != NULL) {
+		if (pwd_stat != NULL) {
+			*reject_reason = pwd_stat->reject_reason;
+		} else {
+			*reject_reason = SAM_PWD_CHANGE_NO_ERROR;
 		}
 	}
 
-#define CHECK_RET(x) do { if (x != 0) return NT_STATUS_NO_MEMORY; } while(0)
+	if (pwd_stat != NULL) {
+		talloc_free(pwd_stat);
+	}
 
-	/* the password is acceptable. Start forming the new fields */
-	if (new_password != NULL) {
-		/* if we know the cleartext UTF16 password, then set it.
-		 * Modules in ldb will set all the appropriate
-		 * hashes */
-		CHECK_RET(ldb_msg_add_value(mod, "clearTextPassword", new_password, NULL));
+	/* TODO: Error results taken from "password_hash" module. Are they
+	   correct? */
+	if (ret == LDB_ERR_UNWILLING_TO_PERFORM) {
+		status = NT_STATUS_WRONG_PASSWORD;
+	} else if (ret == LDB_ERR_CONSTRAINT_VIOLATION) {
+		status = NT_STATUS_PASSWORD_RESTRICTION;
+	} else if (ret != LDB_SUCCESS) {
+		status = NT_STATUS_UNSUCCESSFUL;
 	} else {
-		/* we don't have the cleartext, so set what we have of the
-		 * hashes */
-
-		if (lmNewHash) {
-			CHECK_RET(samdb_msg_add_hash(ctx, mem_ctx, mod, "dBCSPwd", lmNewHash));
-		}
-
-		if (ntNewHash) {
-			CHECK_RET(samdb_msg_add_hash(ctx, mem_ctx, mod, "unicodePwd", ntNewHash));
-		}
+		status = NT_STATUS_OK;
 	}
 
-	if (reject_reason) {
-		*reject_reason = SAM_PWD_CHANGE_NO_ERROR;
-	}
-	return NT_STATUS_OK;
+	return status;
 }
 
-
 /*
  * Sets the user password using plaintext UTF16 (attribute "new_password") or
  * LM (attribute "lmNewHash") or NT (attribute "ntNewHash") hash. Also pass
@@ -2176,7 +2094,7 @@ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ctx,
  *
  * Results: NT_STATUS_OK, NT_STATUS_INTERNAL_DB_CORRUPTION,
  *   NT_STATUS_INVALID_PARAMETER, NT_STATUS_UNSUCCESSFUL,
- *   NT_STATUS_PASSWORD_RESTRICTION
+ *   NT_STATUS_WRONG_PASSWORD, NT_STATUS_PASSWORD_RESTRICTION
  */
 NTSTATUS samdb_set_password_sid(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
 				const struct dom_sid *user_sid,
@@ -2189,7 +2107,6 @@ NTSTATUS samdb_set_password_sid(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
 {
 	NTSTATUS nt_status;
 	struct ldb_dn *user_dn;
-	struct ldb_message *msg;
 	int ret;
 
 	ret = ldb_transaction_start(ldb);
@@ -2208,45 +2125,18 @@ NTSTATUS samdb_set_password_sid(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
 		return NT_STATUS_NO_SUCH_USER;
 	}
 
-	msg = ldb_msg_new(mem_ctx);
-	if (msg == NULL) {
-		ldb_transaction_cancel(ldb);
-		talloc_free(user_dn);
-		return NT_STATUS_NO_MEMORY;
-	}
-
-	msg->dn = ldb_dn_copy(msg, user_dn);
-	if (!msg->dn) {
-		ldb_transaction_cancel(ldb);
-		talloc_free(user_dn);
-		talloc_free(msg);
-		return NT_STATUS_NO_MEMORY;
-	}
-
 	nt_status = samdb_set_password(ldb, mem_ctx,
 				       user_dn, NULL,
-				       msg, new_password,
+				       new_password,
 				       lmNewHash, ntNewHash,
 				       user_change,
 				       reject_reason, _dominfo);
 	if (!NT_STATUS_IS_OK(nt_status)) {
 		ldb_transaction_cancel(ldb);
 		talloc_free(user_dn);
-		talloc_free(msg);
 		return nt_status;
 	}
 
-	/* modify the samdb record */
-	ret = dsdb_replace(ldb, msg, 0);
-	if (ret != LDB_SUCCESS) {
-		ldb_transaction_cancel(ldb);
-		talloc_free(user_dn);
-		talloc_free(msg);
-		return NT_STATUS_ACCESS_DENIED;
-	}
-
-	talloc_free(msg);
-
 	ret = ldb_transaction_commit(ldb);
 	if (ret != LDB_SUCCESS) {
 		DEBUG(0,("Failed to commit transaction to change password on %s: %s\n",
diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c
index 426e9a1..08aa545 100644
--- a/source4/dsdb/samdb/ldb_modules/password_hash.c
+++ b/source4/dsdb/samdb/ldb_modules/password_hash.c
@@ -4,7 +4,8 @@
    Copyright (C) Simo Sorce  2004-2008
    Copyright (C) Andrew Bartlett <abartlet at samba.org> 2005-2006
    Copyright (C) Andrew Tridgell 2004
-   Copyright (C) Stefan Metzmacher 2007
+   Copyright (C) Stefan Metzmacher 2007-2010
+   Copyright (C) Matthias Dieter Wallnöfer 2009-2010
 


-- 
Samba Shared Repository


More information about the samba-cvs mailing list