From 573389c8cc8d74ad8560bc3531be5e2207d1bdaa Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Thu, 2 Dec 2010 09:55:56 +0100 Subject: 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. --- source4/dsdb/samdb/ldb_modules/password_hash.c | 53 +++++++++++++++----------- source4/dsdb/tests/python/passwords.py | 19 +++++++++ 2 files changed, 50 insertions(+), 22 deletions(-) (limited to 'source4/dsdb') 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) -- cgit