CVE-2022-37966 python:tests/krb5: add 'force_nt4_hash' for account creation of KDCBas...
authorStefan Metzmacher <metze@samba.org>
Tue, 29 Nov 2022 15:42:58 +0000 (16:42 +0100)
committerStefan Metzmacher <metze@samba.org>
Wed, 14 Dec 2022 10:28:17 +0000 (10:28 +0000)
This will allow us to create tests accounts with only an nt4 hash
stored, without any aes keys.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15237

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
(cherry picked from commit 77bd3258f1db0ddf4639a83a81a1aad3ee52c87d)

[jsutton@samba.org Fixed conflicts in parameters]

python/samba/tests/krb5/kdc_base_test.py

index 45a23b97eff196ecbd32d0fbf008b358279aab27..801d69ca43a584c8edfee35c050cd857e850c78f 100644 (file)
@@ -248,7 +248,7 @@ class KDCBaseTest(RawKerberosTest):
     def create_account(self, samdb, name, account_type=AccountType.USER,
                        spn=None, upn=None, additional_details=None,
                        ou=None, account_control=0, add_dollar=True,
-                       expired_password=False):
+                       expired_password=False, force_nt4_hash=False):
         '''Create an account for testing.
            The dn of the created account is added to self.accounts,
            which is used by tearDownClass to clean up the created accounts.
@@ -311,6 +311,26 @@ class KDCBaseTest(RawKerberosTest):
             details.update(additional_details)
         samdb.add(details)
 
+        expected_kvno = 1
+
+        if force_nt4_hash:
+            admin_creds = self.get_admin_creds()
+            lp = self.get_lp()
+            net_ctx = net.Net(admin_creds, lp, server=self.dc_host)
+            domain = samdb.domain_netbios_name().upper()
+
+            password = generate_random_password(32, 32)
+            utf16pw = ('"%s"' % password).encode('utf-16-le')
+
+            try:
+                net_ctx.set_password(newpassword=password,
+                                     account_name=account_name,
+                                     domain_name=domain,
+                                     force_samr_18=True)
+                expected_kvno += 1
+            except Exception as e:
+                self.fail(e)
+
         creds = KerberosCredentials()
         creds.guess(self.get_lp())
         creds.set_realm(samdb.domain_dns_name().upper())
@@ -336,8 +356,8 @@ class KDCBaseTest(RawKerberosTest):
                            attrs=['msDS-KeyVersionNumber'])
         kvno = res[0].get('msDS-KeyVersionNumber', idx=0)
         if kvno is not None:
-            self.assertEqual(int(kvno), 1)
-        creds.set_kvno(1)
+            self.assertEqual(int(kvno), expected_kvno)
+        creds.set_kvno(expected_kvno)
 
         return (creds, dn)
 
@@ -701,7 +721,8 @@ class KDCBaseTest(RawKerberosTest):
             'delegation_from_dn': None,
             'trusted_to_auth_for_delegation': False,
             'fast_support': False,
-            'id': None
+            'id': None,
+            'force_nt4_hash': False,
         }
 
         account_opts = {
@@ -744,7 +765,8 @@ class KDCBaseTest(RawKerberosTest):
                             delegation_from_dn,
                             trusted_to_auth_for_delegation,
                             fast_support,
-                            id):
+                            id,
+                            force_nt4_hash):
         if account_type is self.AccountType.USER:
             self.assertIsNone(spn)
             self.assertIsNone(delegation_to_spn)
@@ -798,9 +820,13 @@ class KDCBaseTest(RawKerberosTest):
                                         additional_details=details,
                                         account_control=user_account_control,
                                         add_dollar=add_dollar,
+                                        force_nt4_hash=force_nt4_hash,
                                         expired_password=expired_password)
 
-        keys = self.get_keys(samdb, dn)
+        expected_etypes = None
+        if force_nt4_hash:
+            expected_etypes = {kcrypto.Enctype.RC4}
+        keys = self.get_keys(samdb, dn, expected_etypes=expected_etypes)
         self.creds_set_keys(creds, keys)
 
         # Handle secret replication to the RODC.