]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
tests: Add a test case for msDS-PasswordReversibleEncryptionEnabled
authorTim Beale <timbeale@catalyst.net.nz>
Mon, 7 May 2018 05:33:51 +0000 (17:33 +1200)
committerGarming Sam <garming@samba.org>
Fri, 11 May 2018 04:01:24 +0000 (06:01 +0200)
Add a test for the 'msDS-PasswordReversibleEncryptionEnabled' attribute
on the PSO. The Effective-PasswordReversibleEncryptionEnabled is
based on the PSO setting (if one applies) or else the
DOMAIN_PASSWORD_STORE_CLEARTEXT bit for the domain's pwdProperties.
This indicates whether the user's cleartext password is to be stored
in the supplementalCredentials attribute (as 'Primary:CLEARTEXT').

The password_hash tests already text the cleartext behaviour, so I've
added an additional test case for PSOs. Note that supplementary-
credential information is not returned over LDAP (the password_hash
test uses a local LDB connection), so it made more sense to extend
the password_hash tests than to check this behaviour as part of the
PSO tests (i.e. rather than in password_settings.py).

Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Garming Sam <garming@catalyst.net.nz>
Signed-off-by: Tim Beale <timbeale@catalyst.net.nz>
python/samba/tests/password_hash.py
python/samba/tests/password_hash_gpgme.py
selftest/knownfail.d/password_hash_gpgme [new file with mode: 0644]

index 0a295d57c0ddd74aca8e7839fb04ac8d512ac51a..4c4dbcf2fd749ff6a7595de85a3a574de835a042 100644 (file)
@@ -70,6 +70,17 @@ class PassWordHashTests(TestCase):
         self.lp = samba.tests.env_loadparm()
         super(PassWordHashTests, self).setUp()
 
+    def set_store_cleartext(self, cleartext):
+        # get the current pwdProperties
+        pwdProperties = self.ldb.get_pwdProperties()
+        # update the clear-text properties flag
+        props = int(pwdProperties)
+        if cleartext:
+            props |= DOMAIN_PASSWORD_STORE_CLEARTEXT
+        else:
+            props &= ~DOMAIN_PASSWORD_STORE_CLEARTEXT
+        self.ldb.set_pwdProperties(str(props))
+
     # Add a user to ldb, this will exercise the password_hash code
     # and calculate the appropriate supplemental credentials
     def add_user(self, options=None, clear_text=False, ldb=None):
@@ -109,14 +120,11 @@ class PassWordHashTests(TestCase):
 
         account_control = 0
         if clear_text:
-            # get the current pwdProperties
+            # Restore the current domain setting on exit.
             pwdProperties = self.ldb.get_pwdProperties()
-            # enable clear text properties
-            props = int(pwdProperties)
-            props |= DOMAIN_PASSWORD_STORE_CLEARTEXT
-            self.ldb.set_pwdProperties(str(props))
-            # Restore the value on exit.
             self.addCleanup(self.ldb.set_pwdProperties, pwdProperties)
+            # Update the domain setting
+            self.set_store_cleartext(clear_text)
             account_control |= UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED
 
         # (Re)adds the test user USER_NAME with password USER_PASS
index 25a8a0c79162eff402b6338f6131cf33fe0be9a2..6dafaa81acadfa606dbf71cb47a26d089ea5bb49 100644 (file)
@@ -28,12 +28,14 @@ kerberos newer keys are generated.
 from samba.tests.password_hash import (
     PassWordHashTests,
     get_package,
-    USER_PASS
+    USER_PASS,
+    USER_NAME
 )
 from samba.ndr import ndr_unpack
 from samba.dcerpc import drsblobs
 import binascii
-
+from samba.tests.pso import PasswordSettings
+import samba
 
 class PassWordHashGpgmeTests(PassWordHashTests):
 
@@ -125,6 +127,67 @@ class PassWordHashGpgmeTests(PassWordHashTests):
                         binascii.a2b_hex(ct_package.data))
         self.assertEquals(USER_PASS.encode('utf-16-le'), ct.cleartext)
 
+    def assert_cleartext(self, expect_cleartext, password=None):
+        """Checks cleartext is (or isn't) returned as expected"""
+        sc = self.get_supplemental_creds()
+        if expect_cleartext:
+            (pos, ct_package) = get_package(sc, "Primary:CLEARTEXT")
+            self.assertTrue(ct_package != None, "Failed to retrieve cleartext")
+
+            # Check the clear-text value is correct.
+            ct = ndr_unpack(drsblobs.package_PrimaryCLEARTEXTBlob,
+                            binascii.a2b_hex(ct_package.data))
+            self.assertEquals(password.encode('utf-16-le'), ct.cleartext)
+        else:
+            ct_package = get_package(sc, "Primary:CLEARTEXT")
+            self.assertTrue(ct_package == None,
+                            "Got cleartext when we shouldn't have")
+
+    def test_supplementalCredentials_cleartext_pso(self):
+        """Checks that a PSO's cleartext setting can override the domain's"""
+
+        # create a user that stores plain-text passwords
+        self.add_user(clear_text=True)
+
+        # check that clear-text is present in the supplementary-credentials
+        self.assert_cleartext(expect_cleartext=True, password=USER_PASS)
+
+        # create a PSO overriding the plain-text setting & apply it to the user
+        no_plaintext_pso = PasswordSettings("no-plaintext-PSO", self.ldb,
+                                            precedence=200,
+                                            store_plaintext=False)
+        self.addCleanup(self.ldb.delete, no_plaintext_pso.dn)
+        userdn = "cn=" + USER_NAME + ",cn=users," + self.base_dn
+        no_plaintext_pso.apply_to(userdn)
+
+        # set the password to update the cleartext password stored
+        new_password = samba.generate_random_password(32, 32)
+        self.ldb.setpassword("(sAMAccountName=%s)" % USER_NAME, new_password)
+
+        # this time cleartext shouldn't be in the supplementary creds
+        self.assert_cleartext(expect_cleartext=False)
+
+        # unapply PSO, update password, and check we get the cleartext again
+        no_plaintext_pso.unapply(userdn)
+        new_password = samba.generate_random_password(32, 32)
+        self.ldb.setpassword("(sAMAccountName=%s)" % USER_NAME, new_password)
+        self.assert_cleartext(expect_cleartext=True, password=new_password)
+
+        # Now update the domain setting and check we no longer get cleartext
+        self.set_store_cleartext(False)
+        new_password = samba.generate_random_password(32, 32)
+        self.ldb.setpassword("(sAMAccountName=%s)" % USER_NAME, new_password)
+        self.assert_cleartext(expect_cleartext=False)
+
+        # create a PSO overriding the domain setting & apply it to the user
+        plaintext_pso = PasswordSettings("plaintext-PSO", self.ldb,
+                                         precedence=100, store_plaintext=True)
+        self.addCleanup(self.ldb.delete, plaintext_pso.dn)
+        plaintext_pso.apply_to(userdn)
+        new_password = samba.generate_random_password(32, 32)
+        self.ldb.setpassword("(sAMAccountName=%s)" % USER_NAME, new_password)
+        self.assert_cleartext(expect_cleartext=True, password=new_password)
+
     def test_userPassword_multiple_hashes(self):
         self.add_user(options=[(
             "password hash userPassword schemes",
diff --git a/selftest/knownfail.d/password_hash_gpgme b/selftest/knownfail.d/password_hash_gpgme
new file mode 100644 (file)
index 0000000..a382714
--- /dev/null
@@ -0,0 +1,2 @@
+samba.tests.password_hash_gpgme.samba.tests.password_hash_gpgme.PassWordHashGpgmeTests.test_supplementalCredentials_cleartext_pso\(ad_dc:local\)
+