CVE-2020-25719 tests/krb5: Add tests for requester SID PAC buffer
authorJoseph Sutton <josephsutton@catalyst.net.nz>
Tue, 26 Oct 2021 08:04:25 +0000 (21:04 +1300)
committerJule Anger <janger@samba.org>
Tue, 9 Nov 2021 19:45:33 +0000 (19:45 +0000)
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
selftest/knownfail_heimdal_kdc
selftest/knownfail_mit_kdc

index 53d7dd4effbac007f2f399279c38406413d974ee..2005d71fa81a394e8f5c6b63b09dcc2a05c40bae 100755 (executable)
@@ -510,6 +510,13 @@ class KdcTgsTests(KDCBaseTest):
         tgt = self._get_tgt(creds)
         self._user2user(tgt, creds, expected_error=0)
 
+    def test_tgs_req_no_requester_sid(self):
+        creds = self._get_creds()
+        tgt = self._get_tgt(creds, remove_requester_sid=True)
+
+        self._run_tgs(tgt, expected_error=0, expect_pac=True,
+                      expect_requester_sid=False)  # Note: not expected
+
     def test_tgs_req_no_pac_attrs(self):
         creds = self._get_creds()
         tgt = self._get_tgt(creds, remove_pac_attrs=True)
@@ -517,6 +524,17 @@ class KdcTgsTests(KDCBaseTest):
         self._run_tgs(tgt, expected_error=0, expect_pac=True,
                       expect_pac_attrs=False)
 
+    def test_tgs_req_from_rodc_no_requester_sid(self):
+        creds = self._get_creds(replication_allowed=True,
+                                revealed_to_rodc=True)
+        tgt = self._get_tgt(creds, from_rodc=True, remove_requester_sid=True)
+
+        samdb = self.get_samdb()
+        sid = self.get_objectSid(samdb, creds.get_dn())
+
+        self._run_tgs(tgt, expected_error=0, expect_pac=True,
+                      expect_requester_sid=True, expected_sid=sid)
+
     def test_tgs_req_from_rodc_no_pac_attrs(self):
         creds = self._get_creds(replication_allowed=True,
                                 revealed_to_rodc=True)
@@ -617,6 +635,27 @@ class KdcTgsTests(KDCBaseTest):
         self._user2user(tgt, creds,
                         expected_error=KDC_ERR_CLIENT_NAME_MISMATCH)
 
+    def test_requester_sid_mismatch_existing(self):
+        creds = self._get_creds()
+        existing_rid = self._get_existing_rid()
+        tgt = self._get_tgt(creds, new_rid=existing_rid,
+                            can_modify_logon_info=False)
+        self._run_tgs(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH)
+
+    def test_logon_info_sid_mismatch_existing(self):
+        creds = self._get_creds()
+        existing_rid = self._get_existing_rid()
+        tgt = self._get_tgt(creds, new_rid=existing_rid,
+                            can_modify_requester_sid=False)
+        self._run_tgs(tgt, expected_error=0)
+
+    def test_logon_info_only_sid_mismatch_existing(self):
+        creds = self._get_creds()
+        existing_rid = self._get_existing_rid()
+        tgt = self._get_tgt(creds, new_rid=existing_rid,
+                            remove_requester_sid=True)
+        self._run_tgs(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH)
+
     # Test changing the SID in the PAC to a non-existent one.
     def test_tgs_sid_mismatch_nonexisting(self):
         creds = self._get_creds()
@@ -652,6 +691,27 @@ class KdcTgsTests(KDCBaseTest):
         self._user2user(tgt, creds,
                         expected_error=KDC_ERR_CLIENT_NAME_MISMATCH)
 
+    def test_requester_sid_mismatch_nonexisting(self):
+        creds = self._get_creds()
+        nonexistent_rid = self._get_non_existent_rid()
+        tgt = self._get_tgt(creds, new_rid=nonexistent_rid,
+                            can_modify_logon_info=False)
+        self._run_tgs(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH)
+
+    def test_logon_info_sid_mismatch_nonexisting(self):
+        creds = self._get_creds()
+        nonexistent_rid = self._get_non_existent_rid()
+        tgt = self._get_tgt(creds, new_rid=nonexistent_rid,
+                            can_modify_requester_sid=False)
+        self._run_tgs(tgt, expected_error=0)
+
+    def test_logon_info_only_sid_mismatch_nonexisting(self):
+        creds = self._get_creds()
+        nonexistent_rid = self._get_non_existent_rid()
+        tgt = self._get_tgt(creds, new_rid=nonexistent_rid,
+                            remove_requester_sid=True)
+        self._run_tgs(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH)
+
     # Test with an RODC-issued ticket where the client is revealed to the RODC.
     def test_tgs_rodc_revealed(self):
         creds = self._get_creds(replication_allowed=True,
@@ -728,6 +788,33 @@ class KdcTgsTests(KDCBaseTest):
         self._user2user(tgt, creds,
                         expected_error=KDC_ERR_CLIENT_NAME_MISMATCH)
 
+    def test_tgs_rodc_requester_sid_mismatch_existing(self):
+        creds = self._get_creds(replication_allowed=True,
+                                revealed_to_rodc=True)
+        existing_rid = self._get_existing_rid(replication_allowed=True,
+                                              revealed_to_rodc=True)
+        tgt = self._get_tgt(creds, from_rodc=True, new_rid=existing_rid,
+                            can_modify_logon_info=False)
+        self._run_tgs(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH)
+
+    def test_tgs_rodc_logon_info_sid_mismatch_existing(self):
+        creds = self._get_creds(replication_allowed=True,
+                                revealed_to_rodc=True)
+        existing_rid = self._get_existing_rid(replication_allowed=True,
+                                              revealed_to_rodc=True)
+        tgt = self._get_tgt(creds, from_rodc=True, new_rid=existing_rid,
+                            can_modify_requester_sid=False)
+        self._run_tgs(tgt, expected_error=0)
+
+    def test_tgs_rodc_logon_info_only_sid_mismatch_existing(self):
+        creds = self._get_creds(replication_allowed=True,
+                                revealed_to_rodc=True)
+        existing_rid = self._get_existing_rid(replication_allowed=True,
+                                              revealed_to_rodc=True)
+        tgt = self._get_tgt(creds, from_rodc=True, new_rid=existing_rid,
+                            remove_requester_sid=True)
+        self._run_tgs(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH)
+
     # Test with an RODC-issued ticket where the SID in the PAC is changed to a
     # non-existent one.
     def test_tgs_rodc_sid_mismatch_nonexisting(self):
@@ -768,6 +855,30 @@ class KdcTgsTests(KDCBaseTest):
         self._user2user(tgt, creds,
                         expected_error=KDC_ERR_CLIENT_NAME_MISMATCH)
 
+    def test_tgs_rodc_requester_sid_mismatch_nonexisting(self):
+        creds = self._get_creds(replication_allowed=True,
+                                revealed_to_rodc=True)
+        nonexistent_rid = self._get_non_existent_rid()
+        tgt = self._get_tgt(creds, from_rodc=True, new_rid=nonexistent_rid,
+                            can_modify_logon_info=False)
+        self._run_tgs(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH)
+
+    def test_tgs_rodc_logon_info_sid_mismatch_nonexisting(self):
+        creds = self._get_creds(replication_allowed=True,
+                                revealed_to_rodc=True)
+        nonexistent_rid = self._get_non_existent_rid()
+        tgt = self._get_tgt(creds, from_rodc=True, new_rid=nonexistent_rid,
+                            can_modify_requester_sid=False)
+        self._run_tgs(tgt, expected_error=0)
+
+    def test_tgs_rodc_logon_info_only_sid_mismatch_nonexisting(self):
+        creds = self._get_creds(replication_allowed=True,
+                                revealed_to_rodc=True)
+        nonexistent_rid = self._get_non_existent_rid()
+        tgt = self._get_tgt(creds, from_rodc=True, new_rid=nonexistent_rid,
+                            remove_requester_sid=True)
+        self._run_tgs(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH)
+
     # Test with an RODC-issued ticket where the client is not revealed to the
     # RODC.
     def test_tgs_rodc_not_revealed(self):
@@ -1235,6 +1346,99 @@ class KdcTgsTests(KDCBaseTest):
                       expect_pac_attrs=True,
                       expect_pac_attrs_pac_request=True)
 
+    def test_as_requester_sid(self):
+        creds = self._get_creds()
+
+        samdb = self.get_samdb()
+        sid = self.get_objectSid(samdb, creds.get_dn())
+
+        self.get_tgt(creds, pac_request=None,
+                     expect_pac=True,
+                     expected_sid=sid,
+                     expect_requester_sid=True)
+
+    def test_tgs_requester_sid(self):
+        creds = self._get_creds()
+
+        samdb = self.get_samdb()
+        sid = self.get_objectSid(samdb, creds.get_dn())
+
+        tgt = self.get_tgt(creds, pac_request=None,
+                           expect_pac=True,
+                           expected_sid=sid,
+                           expect_requester_sid=True)
+
+        self._run_tgs(tgt, expected_error=0, expect_pac=True,
+                      expected_sid=sid,
+                      expect_requester_sid=True)
+
+    def test_tgs_requester_sid_renew(self):
+        creds = self._get_creds()
+
+        samdb = self.get_samdb()
+        sid = self.get_objectSid(samdb, creds.get_dn())
+
+        tgt = self.get_tgt(creds, pac_request=None,
+                           expect_pac=True,
+                           expected_sid=sid,
+                           expect_requester_sid=True)
+        tgt = self._modify_tgt(tgt, renewable=True)
+
+        self._renew_tgt(tgt, expected_error=0, expect_pac=True,
+                        expected_sid=sid,
+                        expect_requester_sid=True)
+
+    def test_tgs_requester_sid_rodc_renew(self):
+        creds = self._get_creds(replication_allowed=True,
+                                revealed_to_rodc=True)
+
+        samdb = self.get_samdb()
+        sid = self.get_objectSid(samdb, creds.get_dn())
+
+        tgt = self.get_tgt(creds, pac_request=None,
+                           expect_pac=True,
+                           expected_sid=sid,
+                           expect_requester_sid=True)
+        tgt = self._modify_tgt(tgt, from_rodc=True, renewable=True)
+
+        self._renew_tgt(tgt, expected_error=0, expect_pac=True,
+                        expected_sid=sid,
+                        expect_requester_sid=True)
+
+    def test_tgs_requester_sid_missing_renew(self):
+        creds = self._get_creds()
+
+        samdb = self.get_samdb()
+        sid = self.get_objectSid(samdb, creds.get_dn())
+
+        tgt = self.get_tgt(creds, pac_request=None,
+                           expect_pac=True,
+                           expected_sid=sid,
+                           expect_requester_sid=True)
+        tgt = self._modify_tgt(tgt, renewable=True,
+                               remove_requester_sid=True)
+
+        self._renew_tgt(tgt, expected_error=0, expect_pac=True,
+                        expect_requester_sid=False)  # Note: not expected
+
+    def test_tgs_requester_sid_missing_rodc_renew(self):
+        creds = self._get_creds(replication_allowed=True,
+                                revealed_to_rodc=True)
+
+        samdb = self.get_samdb()
+        sid = self.get_objectSid(samdb, creds.get_dn())
+
+        tgt = self.get_tgt(creds, pac_request=None,
+                           expect_pac=True,
+                           expected_sid=sid,
+                           expect_requester_sid=True)
+        tgt = self._modify_tgt(tgt, from_rodc=True, renewable=True,
+                               remove_requester_sid=True)
+
+        self._renew_tgt(tgt, expected_error=0, expect_pac=True,
+                        expected_sid=sid,
+                        expect_requester_sid=True)
+
     def test_tgs_pac_request_none(self):
         creds = self._get_creds()
         tgt = self.get_tgt(creds, pac_request=None)
@@ -1733,16 +1937,20 @@ class KdcTgsTests(KDCBaseTest):
         return (1 << 30) - 1
 
     def _run_tgs(self, tgt, expected_error, expect_pac=True,
-                 expect_pac_attrs=None, expect_pac_attrs_pac_request=None):
+                 expect_pac_attrs=None, expect_pac_attrs_pac_request=None,
+                 expect_requester_sid=None, expected_sid=None):
         target_creds = self.get_service_creds()
         return self._tgs_req(
             tgt, expected_error, target_creds,
             expect_pac=expect_pac,
             expect_pac_attrs=expect_pac_attrs,
-            expect_pac_attrs_pac_request=expect_pac_attrs_pac_request)
+            expect_pac_attrs_pac_request=expect_pac_attrs_pac_request,
+            expect_requester_sid=expect_requester_sid,
+            expected_sid=expected_sid)
 
     def _renew_tgt(self, tgt, expected_error, expect_pac=True,
-                   expect_pac_attrs=None, expect_pac_attrs_pac_request=None):
+                   expect_pac_attrs=None, expect_pac_attrs_pac_request=None,
+                   expect_requester_sid=None, expected_sid=None):
         krbtgt_creds = self.get_krbtgt_creds()
         kdc_options = str(krb5_asn1.KDCOptions('renew'))
         return self._tgs_req(
@@ -1750,7 +1958,9 @@ class KdcTgsTests(KDCBaseTest):
             kdc_options=kdc_options,
             expect_pac=expect_pac,
             expect_pac_attrs=expect_pac_attrs,
-            expect_pac_attrs_pac_request=expect_pac_attrs_pac_request)
+            expect_pac_attrs_pac_request=expect_pac_attrs_pac_request,
+            expect_requester_sid=expect_requester_sid,
+            expected_sid=expected_sid)
 
     def _validate_tgt(self, tgt, expected_error, expect_pac=True):
         krbtgt_creds = self.get_krbtgt_creds()
@@ -1809,7 +2019,9 @@ class KdcTgsTests(KDCBaseTest):
                  expect_pac=True,
                  expect_pac_attrs=None,
                  expect_pac_attrs_pac_request=None,
+                 expect_requester_sid=None,
                  expect_edata=False,
+                 expected_sid=None,
                  expected_status=None):
         srealm = target_creds.get_realm()
 
@@ -1865,6 +2077,8 @@ class KdcTgsTests(KDCBaseTest):
             expect_pac=expect_pac,
             expect_pac_attrs=expect_pac_attrs,
             expect_pac_attrs_pac_request=expect_pac_attrs_pac_request,
+            expect_requester_sid=expect_requester_sid,
+            expected_sid=expected_sid,
             expect_claims=expect_claims)
 
         rep = self._generic_kdc_exchange(kdc_exchange_dict,
index 7119dbe7a4042a7719d3d44cec4b6ce4e15dece8..749a8892ab0cbbad098384b840b15655e144c056 100644 (file)
 ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_user_pac_request_false
 ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_user_pac_request_none
 ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_user_pac_request_true
+#
+# PAC requester SID tests
+#
+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_as_requester_sid
+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_logon_info_only_sid_mismatch_existing
+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_logon_info_only_sid_mismatch_nonexisting
+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_requester_sid_mismatch_existing
+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_requester_sid_mismatch_nonexisting
+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_req_from_rodc_no_requester_sid
+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid
+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_renew
+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_rodc_renew
+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_renew
+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_rodc_renew
+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_logon_info_only_sid_mismatch_existing
+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_logon_info_only_sid_mismatch_nonexisting
+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_requester_sid_mismatch_existing
+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_requester_sid_mismatch_nonexisting
index 546316413b950591033b3073116b0012a1ec696b..176c0747b485bd6a6e28f9fcfa7a3161c63a2390 100644 (file)
@@ -485,3 +485,23 @@ 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_user2user_user_pac_request_none
 ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_user_pac_request_true
 ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_pac_request_false
+#
+# PAC requester SID tests
+#
+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_as_requester_sid
+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_logon_info_only_sid_mismatch_existing
+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_logon_info_only_sid_mismatch_nonexisting
+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_requester_sid_mismatch_existing
+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_requester_sid_mismatch_nonexisting
+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_req_from_rodc_no_requester_sid
+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid
+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_renew
+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_rodc_renew
+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_renew
+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_rodc_renew
+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_logon_info_only_sid_mismatch_existing
+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_logon_info_only_sid_mismatch_nonexisting
+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_logon_info_sid_mismatch_existing
+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_logon_info_sid_mismatch_nonexisting
+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_requester_sid_mismatch_existing
+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_requester_sid_mismatch_nonexisting