CVE-2020-25719 tests/krb5: Add tests for using a ticket with a renamed account
authorJoseph Sutton <josephsutton@catalyst.net.nz>
Fri, 29 Oct 2021 02:07:07 +0000 (15:07 +1300)
committerJule Anger <janger@samba.org>
Mon, 8 Nov 2021 09:52:12 +0000 (10:52 +0100)
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561

Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
python/samba/tests/krb5/kdc_tgs_tests.py
python/samba/tests/krb5/test_ccache.py
python/samba/tests/krb5/test_ldap.py
python/samba/tests/krb5/test_rpc.py
python/samba/tests/krb5/test_smb.py
selftest/knownfail_mit_kdc

index cfe1ad42d615d60bb8f8c8d6956ec99b7f3e5911..abac5a47a560799124ab9fc3cf5c14127bba3271 100755 (executable)
@@ -1769,6 +1769,23 @@ class KdcTgsTests(KDCBaseTest):
         pac = self.get_ticket_pac(ticket)
         self.assertIsNotNone(pac)
 
+    def test_tgs_rename(self):
+        creds = self.get_cached_creds(account_type=self.AccountType.USER,
+                                      use_cache=False)
+        tgt = self.get_tgt(creds)
+
+        # Rename the account.
+        new_name = self.get_new_username()
+
+        samdb = self.get_samdb()
+        msg = ldb.Message(creds.get_dn())
+        msg['sAMAccountName'] = ldb.MessageElement(new_name,
+                                                   ldb.FLAG_MOD_REPLACE,
+                                                   'sAMAccountName')
+        samdb.modify(msg)
+
+        self._run_tgs(tgt, expected_error=KDC_ERR_C_PRINCIPAL_UNKNOWN)
+
     def _get_tgt(self,
                  client_creds,
                  renewable=False,
index d21ec84796e5fe1486130482839d1e1f5d99b1e8..75038ea5cc15217058f048ea0fb9091edf53e7e0 100755 (executable)
@@ -20,6 +20,8 @@
 import sys
 import os
 
+import ldb
+
 from ldb import SCOPE_SUBTREE
 from samba import NTSTATUSError, gensec
 from samba.auth import AuthContext
@@ -42,13 +44,16 @@ class CcacheTests(KDCBaseTest):
     """
 
     def test_ccache(self):
-        self._run_ccache_test("ccacheusr")
+        self._run_ccache_test()
+
+    def test_ccache_rename(self):
+        self._run_ccache_test(rename=True)
 
     def test_ccache_no_pac(self):
-        self._run_ccache_test("ccacheusr_nopac", include_pac=False,
+        self._run_ccache_test(include_pac=False,
                               expect_anon=True, allow_error=True)
 
-    def _run_ccache_test(self, user_name, include_pac=True,
+    def _run_ccache_test(self, rename=False, include_pac=True,
                          expect_anon=False, allow_error=False):
         # Create a user account and a machine account, along with a Kerberos
         # credentials cache file where the service ticket authenticating the
@@ -60,7 +65,10 @@ class CcacheTests(KDCBaseTest):
         samdb = self.get_samdb()
 
         # Create the user account.
-        (user_credentials, _) = self.create_account(samdb, user_name)
+        user_credentials = self.get_cached_creds(
+            account_type=self.AccountType.USER,
+            use_cache=False)
+        user_name = user_credentials.get_username()
 
         # Create the machine account.
         (mach_credentials, _) = self.create_account(
@@ -80,6 +88,24 @@ class CcacheTests(KDCBaseTest):
         # Remove the cached credentials file.
         self.addCleanup(os.remove, cachefile.name)
 
+        # Retrieve the user account's SID.
+        ldb_res = samdb.search(scope=SCOPE_SUBTREE,
+                               expression="(sAMAccountName=%s)" % user_name,
+                               attrs=["objectSid"])
+        self.assertEqual(1, len(ldb_res))
+        sid = ndr_unpack(security.dom_sid, ldb_res[0]["objectSid"][0])
+
+        if rename:
+            # Rename the account.
+
+            new_name = self.get_new_username()
+
+            msg = ldb.Message(user_credentials.get_dn())
+            msg['sAMAccountName'] = ldb.MessageElement(new_name,
+                                                       ldb.FLAG_MOD_REPLACE,
+                                                       'sAMAccountName')
+            samdb.modify(msg)
+
         # Authenticate in-process to the machine account using the user's
         # cached credentials.
 
@@ -121,13 +147,6 @@ class CcacheTests(KDCBaseTest):
         # Ensure that the first SID contained within the obtained security
         # token is the SID of the user we created.
 
-        # Retrieve the user account's SID.
-        ldb_res = samdb.search(scope=SCOPE_SUBTREE,
-                               expression="(sAMAccountName=%s)" % user_name,
-                               attrs=["objectSid"])
-        self.assertEqual(1, len(ldb_res))
-        sid = ndr_unpack(security.dom_sid, ldb_res[0]["objectSid"][0])
-
         # Retrieve the SIDs from the security token.
         try:
             session = gensec_server.session_info()
index 0205bdf6fb730d8ffa3b55c86edcbda847d8b2fd..c1375730e6fbd07af46ac5d47c21f26239ccfed2 100755 (executable)
@@ -20,6 +20,8 @@
 import sys
 import os
 
+import ldb
+
 from ldb import LdbError, ERR_OPERATIONS_ERROR, SCOPE_BASE, SCOPE_SUBTREE
 from samba.dcerpc import security
 from samba.ndr import ndr_unpack
@@ -41,13 +43,16 @@ class LdapTests(KDCBaseTest):
     """
 
     def test_ldap(self):
-        self._run_ldap_test("ldapusr")
+        self._run_ldap_test()
+
+    def test_ldap_rename(self):
+        self._run_ldap_test(rename=True)
 
     def test_ldap_no_pac(self):
-        self._run_ldap_test("ldapusr_nopac", include_pac=False,
+        self._run_ldap_test(include_pac=False,
                             expect_anon=True, allow_error=True)
 
-    def _run_ldap_test(self, user_name, include_pac=True,
+    def _run_ldap_test(self, rename=False, include_pac=True,
                        expect_anon=False, allow_error=False):
         # Create a user account and a machine account, along with a Kerberos
         # credentials cache file where the service ticket authenticating the
@@ -59,7 +64,10 @@ class LdapTests(KDCBaseTest):
         service = "ldap"
 
         # Create the user account.
-        (user_credentials, _) = self.create_account(samdb, user_name)
+        user_credentials = self.get_cached_creds(
+            account_type=self.AccountType.USER,
+            use_cache=False)
+        user_name = user_credentials.get_username()
 
         mach_credentials = self.get_dc_creds()
 
@@ -75,9 +83,6 @@ class LdapTests(KDCBaseTest):
         # Remove the cached credentials file.
         self.addCleanup(os.remove, cachefile.name)
 
-        # Authenticate in-process to the machine account using the user's
-        # cached credentials.
-
         # Retrieve the user account's SID.
         ldb_res = samdb.search(scope=SCOPE_SUBTREE,
                                expression="(sAMAccountName=%s)" % user_name,
@@ -85,6 +90,20 @@ class LdapTests(KDCBaseTest):
         self.assertEqual(1, len(ldb_res))
         sid = ndr_unpack(security.dom_sid, ldb_res[0]["objectSid"][0])
 
+        if rename:
+            # Rename the account.
+
+            new_name = self.get_new_username()
+
+            msg = ldb.Message(user_credentials.get_dn())
+            msg['sAMAccountName'] = ldb.MessageElement(new_name,
+                                                       ldb.FLAG_MOD_REPLACE,
+                                                       'sAMAccountName')
+            samdb.modify(msg)
+
+        # Authenticate in-process to the machine account using the user's
+        # cached credentials.
+
         # Connect to the machine account and retrieve the user SID.
         try:
             ldb_as_user = SamDB(url="ldap://%s" % mach_name,
index 0f2170a8dede8eb8cc38e6d0e7c3d042a2bfcbc6..03c125f518a7308df2639be936805263c8979088 100755 (executable)
@@ -20,6 +20,8 @@
 import sys
 import os
 
+import ldb
+
 from samba import NTSTATUSError, credentials
 from samba.dcerpc import lsa
 from samba.ntstatus import NT_STATUS_NO_IMPERSONATION_TOKEN
@@ -39,13 +41,16 @@ class RpcTests(KDCBaseTest):
     """
 
     def test_rpc(self):
-        self._run_rpc_test("rpcusr")
+        self._run_rpc_test()
+
+    def test_rpc_rename(self):
+        self._run_rpc_test(rename=True)
 
     def test_rpc_no_pac(self):
-        self._run_rpc_test("rpcusr_nopac", include_pac=False,
+        self._run_rpc_test(include_pac=False,
                            expect_anon=True, allow_error=True)
 
-    def _run_rpc_test(self, user_name, include_pac=True,
+    def _run_rpc_test(self, rename=False, include_pac=True,
                       expect_anon=False, allow_error=False):
         # Create a user account and a machine account, along with a Kerberos
         # credentials cache file where the service ticket authenticating the
@@ -57,7 +62,10 @@ class RpcTests(KDCBaseTest):
         service = "cifs"
 
         # Create the user account.
-        (user_credentials, _) = self.create_account(samdb, user_name)
+        user_credentials = self.get_cached_creds(
+            account_type=self.AccountType.USER,
+            use_cache=False)
+        user_name = user_credentials.get_username()
 
         mach_credentials = self.get_dc_creds()
 
@@ -73,6 +81,17 @@ class RpcTests(KDCBaseTest):
         # Remove the cached credentials file.
         self.addCleanup(os.remove, cachefile.name)
 
+        if rename:
+            # Rename the account.
+
+            new_name = self.get_new_username()
+
+            msg = ldb.Message(user_credentials.get_dn())
+            msg['sAMAccountName'] = ldb.MessageElement(new_name,
+                                                       ldb.FLAG_MOD_REPLACE,
+                                                       'sAMAccountName')
+            samdb.modify(msg)
+
         # Authenticate in-process to the machine account using the user's
         # cached credentials.
 
index 7408e5dbecea1704b803bc544ea85ca1f311c507..47e9e48c971d1fcce5f96219340d8b70d6bad454 100755 (executable)
@@ -20,6 +20,8 @@
 import sys
 import os
 
+import ldb
+
 from ldb import SCOPE_SUBTREE
 from samba import NTSTATUSError
 from samba.dcerpc import security
@@ -43,13 +45,16 @@ class SmbTests(KDCBaseTest):
     """
 
     def test_smb(self):
-        self._run_smb_test("smbusr")
+        self._run_smb_test()
+
+    def test_smb_rename(self):
+        self._run_smb_test(rename=True)
 
     def test_smb_no_pac(self):
-        self._run_smb_test("smbusr_nopac", include_pac=False,
+        self._run_smb_test(include_pac=False,
                            expect_error=True)
 
-    def _run_smb_test(self, user_name, include_pac=True,
+    def _run_smb_test(self, rename=False, include_pac=True,
                       expect_error=False):
         # Create a user account and a machine account, along with a Kerberos
         # credentials cache file where the service ticket authenticating the
@@ -62,7 +67,12 @@ class SmbTests(KDCBaseTest):
         share = "tmp"
 
         # Create the user account.
-        (user_credentials, _) = self.create_account(samdb, user_name)
+        user_credentials = self.get_cached_creds(
+            account_type=self.AccountType.USER,
+            use_cache=False)
+        user_name = user_credentials.get_username()
+
+        mach_credentials = self.get_dc_creds()
 
         mach_credentials = self.get_dc_creds()
 
@@ -78,6 +88,24 @@ class SmbTests(KDCBaseTest):
         # Remove the cached credentials file.
         self.addCleanup(os.remove, cachefile.name)
 
+        # Retrieve the user account's SID.
+        ldb_res = samdb.search(scope=SCOPE_SUBTREE,
+                               expression="(sAMAccountName=%s)" % user_name,
+                               attrs=["objectSid"])
+        self.assertEqual(1, len(ldb_res))
+        sid = ndr_unpack(security.dom_sid, ldb_res[0]["objectSid"][0])
+
+        if rename:
+            # Rename the account.
+
+            new_name = self.get_new_username()
+
+            msg = ldb.Message(user_credentials.get_dn())
+            msg['sAMAccountName'] = ldb.MessageElement(new_name,
+                                                       ldb.FLAG_MOD_REPLACE,
+                                                       'sAMAccountName')
+            samdb.modify(msg)
+
         # Set the Kerberos 5 credentials cache environment variable. This is
         # required because the codepath that gets run (gse_krb5) looks for it
         # in here and not in the credentials object.
@@ -88,13 +116,6 @@ class SmbTests(KDCBaseTest):
         # Authenticate in-process to the machine account using the user's
         # cached credentials.
 
-        # Retrieve the user account's SID.
-        ldb_res = samdb.search(scope=SCOPE_SUBTREE,
-                               expression="(sAMAccountName=%s)" % user_name,
-                               attrs=["objectSid"])
-        self.assertEqual(1, len(ldb_res))
-        sid = ndr_unpack(security.dom_sid, ldb_res[0]["objectSid"][0])
-
         # Connect to a share and retrieve the user SID.
         s3_lp = s3param.get_context()
         s3_lp.load(self.get_lp().configfile)
index b4e819c83dfb103e2a964eebd8fdf13b92fe4259..8cd36fe2d9670770c306809e8844b62836650587 100644 (file)
@@ -417,6 +417,7 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_
 ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_sid_mismatch_nonexisting
 ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_authdata_no_pac
 ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_no_pac
+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rename
 ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_allowed_denied
 ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_denied
 ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_no_krbtgt_link