summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/dsdb/samdb/ldb_modules/password_hash.c53
-rwxr-xr-xsource4/dsdb/tests/python/passwords.py19
-rw-r--r--source4/scripting/python/samba/samdb.py30
3 files changed, 80 insertions, 22 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c
index 35d2729297..4e2e96fa65 100644
--- a/source4/dsdb/samdb/ldb_modules/password_hash.c
+++ b/source4/dsdb/samdb/ldb_modules/password_hash.c
@@ -1298,18 +1298,22 @@ static int setup_given_passwords(struct setup_password_fields_io *io,
(void *)&cleartext_utf16_blob->data,
&cleartext_utf16_blob->length,
false)) {
- talloc_free(cleartext_utf16_blob);
- ldb_asprintf_errstring(ldb,
- "setup_password_fields: "
- "failed to generate UTF16 password from cleartext UTF8 password for user %s", io->u.sAMAccountName);
- return LDB_ERR_CONSTRAINT_VIOLATION;
- } else {
- g->cleartext_utf16 = cleartext_utf16_blob;
+ if (g->cleartext_utf8->length != 0) {
+ talloc_free(cleartext_utf16_blob);
+ ldb_asprintf_errstring(ldb,
+ "setup_password_fields: "
+ "failed to generate UTF16 password from cleartext UTF8 one for user '%s'!",
+ io->u.sAMAccountName);
+ return LDB_ERR_CONSTRAINT_VIOLATION;
+ } else {
+ /* passwords with length "0" are valid! */
+ cleartext_utf16_blob->data = NULL;
+ cleartext_utf16_blob->length = 0;
+ }
}
+ g->cleartext_utf16 = cleartext_utf16_blob;
} else if (g->cleartext_utf16) {
- char *cleartext_utf8_str;
struct ldb_val *cleartext_utf8_blob;
- size_t converted_pw_len;
cleartext_utf8_blob = talloc(io->ac, struct ldb_val);
if (!cleartext_utf8_blob) {
@@ -1319,20 +1323,25 @@ static int setup_given_passwords(struct setup_password_fields_io *io,
CH_UTF16MUNGED, CH_UTF8,
g->cleartext_utf16->data,
g->cleartext_utf16->length,
- (void *)&cleartext_utf8_str,
- &converted_pw_len, false)) {
- /* We must bail out here, the input wasn't even a
- * multiple of 2 bytes */
- talloc_free(cleartext_utf8_blob);
- ldb_asprintf_errstring(ldb,
- "setup_password_fields: "
- "UTF16 password for user %s had odd length (length must be a multiple of 2)", io->u.sAMAccountName);
- return LDB_ERR_CONSTRAINT_VIOLATION;
- } else {
- *cleartext_utf8_blob = data_blob_const(cleartext_utf8_str,
- converted_pw_len);
- g->cleartext_utf8 = cleartext_utf8_blob;
+ (void *)&cleartext_utf8_blob->data,
+ &cleartext_utf8_blob->length,
+ false)) {
+ if (g->cleartext_utf16->length != 0) {
+ /* We must bail out here, the input wasn't even
+ * a multiple of 2 bytes */
+ talloc_free(cleartext_utf8_blob);
+ ldb_asprintf_errstring(ldb,
+ "setup_password_fields: "
+ "failed to generate UTF8 password from cleartext UTF 16 one for user '%s' - the latter had odd length (length must be a multiple of 2)!",
+ io->u.sAMAccountName);
+ return LDB_ERR_CONSTRAINT_VIOLATION;
+ } else {
+ /* passwords with length "0" are valid! */
+ cleartext_utf8_blob->data = NULL;
+ cleartext_utf8_blob->length = 0;
+ }
}
+ g->cleartext_utf8 = cleartext_utf8_blob;
}
if (g->cleartext_utf16) {
diff --git a/source4/dsdb/tests/python/passwords.py b/source4/dsdb/tests/python/passwords.py
index 198b314cc0..e43298e34d 100755
--- a/source4/dsdb/tests/python/passwords.py
+++ b/source4/dsdb/tests/python/passwords.py
@@ -887,6 +887,25 @@ userPassword: thatsAcomplPASS4
# Reset the test "dSHeuristics" (reactivate "userPassword" pwd changes)
ldb.set_dsheuristics("000000001")
+ def test_zero_length(self):
+ # Get the old "minPwdLength"
+ minPwdLength = ldb.get_minPwdLength()
+ # Set it temporarely to "0"
+ ldb.set_minPwdLength("0")
+
+ # Get the old "pwdProperties"
+ pwdProperties = ldb.get_pwdProperties()
+ # Set them temporarely to "0" (to deactivate eventually the complexity)
+ ldb.set_pwdProperties("0")
+
+ ldb.setpassword("(sAMAccountName=testuser)", "")
+
+ # Reset the "pwdProperties" as they were before
+ ldb.set_pwdProperties(pwdProperties)
+
+ # Reset the "minPwdLength" as it was before
+ ldb.set_minPwdLength(minPwdLength)
+
def tearDown(self):
super(PasswordTests, self).tearDown()
delete_force(self.ldb, "cn=testuser,cn=users," + self.base_dn)
diff --git a/source4/scripting/python/samba/samdb.py b/source4/scripting/python/samba/samdb.py
index a7f474d134..99f141e664 100644
--- a/source4/scripting/python/samba/samdb.py
+++ b/source4/scripting/python/samba/samdb.py
@@ -637,6 +637,36 @@ accountExpires: %u
else:
return res[0]["minPwdAge"][0]
+ def set_minPwdLength(self, value):
+ m = ldb.Message()
+ m.dn = ldb.Dn(self, self.domain_dn())
+ m["minPwdLength"] = ldb.MessageElement(value, ldb.FLAG_MOD_REPLACE, "minPwdLength")
+ self.modify(m)
+
+ def get_minPwdLength(self):
+ res = self.search(self.domain_dn(), scope=ldb.SCOPE_BASE, attrs=["minPwdLength"])
+ if len(res) == 0:
+ return None
+ elif not "minPwdLength" in res[0]:
+ return None
+ else:
+ return res[0]["minPwdLength"][0]
+
+ def set_pwdProperties(self, value):
+ m = ldb.Message()
+ m.dn = ldb.Dn(self, self.domain_dn())
+ m["pwdProperties"] = ldb.MessageElement(value, ldb.FLAG_MOD_REPLACE, "pwdProperties")
+ self.modify(m)
+
+ def get_pwdProperties(self):
+ res = self.search(self.domain_dn(), scope=ldb.SCOPE_BASE, attrs=["pwdProperties"])
+ if len(res) == 0:
+ return None
+ elif not "pwdProperties" in res[0]:
+ return None
+ else:
+ return res[0]["pwdProperties"][0]
+
def set_dsheuristics(self, dsheuristics):
m = ldb.Message()
m.dn = ldb.Dn(self, "CN=Directory Service,CN=Windows NT,CN=Services,%s"