diff options
author | Matthias Dieter Wallnöfer <mdw@samba.org> | 2010-12-02 09:55:56 +0100 |
---|---|---|
committer | Matthias Dieter Wallnöfer <mdw@samba.org> | 2010-12-02 11:51:06 +0100 |
commit | 573389c8cc8d74ad8560bc3531be5e2207d1bdaa (patch) | |
tree | 1b1161255389623f55b1b833be9ce5bcc7c61bb8 /source4 | |
parent | f62972b7617c6349f238f1420e7b7296065e866b (diff) | |
download | samba-573389c8cc8d74ad8560bc3531be5e2207d1bdaa.tar.gz samba-573389c8cc8d74ad8560bc3531be5e2207d1bdaa.tar.bz2 samba-573389c8cc8d74ad8560bc3531be5e2207d1bdaa.zip |
s4:password_hash LDB module - allow empty ("") passwords
This seems to have been broken some time ago - till someone on the
mailing list noticed it.
I've also added a testsuite (and some additional SamDB python helpers) which
should prove this.
Diffstat (limited to 'source4')
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/password_hash.c | 53 | ||||
-rwxr-xr-x | source4/dsdb/tests/python/passwords.py | 19 | ||||
-rw-r--r-- | source4/scripting/python/samba/samdb.py | 30 |
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" |