From: Joseph Sutton Date: Wed, 15 Mar 2023 22:30:56 +0000 (+1300) Subject: tests/krb5: Test that RODC-issued claims are regenerated X-Git-Tag: talloc-2.4.1~1392 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e1a573a6595363e05a3baef5ffe625317aaef9de;p=thirdparty%2Fsamba.git tests/krb5: Test that RODC-issued claims are regenerated Signed-off-by: Joseph Sutton Reviewed-by: Andrew Bartlett --- diff --git a/python/samba/tests/krb5/claims_tests.py b/python/samba/tests/krb5/claims_tests.py index 13f7d229b33..7c2c8370e3e 100755 --- a/python/samba/tests/krb5/claims_tests.py +++ b/python/samba/tests/krb5/claims_tests.py @@ -258,6 +258,30 @@ class ClaimsTests(KDCBaseTest): def test_delegation_claims_remove_claims(self): self.run_delegation_test(remove_claims=True) + def test_rodc_issued_claims_modify(self): + self.run_rodc_tgs_test(remove_claims=False, delete_claim=False) + + def test_rodc_issued_claims_delete(self): + self.run_rodc_tgs_test(remove_claims=False, delete_claim=True) + + def test_rodc_issued_claims_remove_claims_modify(self): + self.run_rodc_tgs_test(remove_claims=True, delete_claim=False) + + def test_rodc_issued_claims_remove_claims_delete(self): + self.run_rodc_tgs_test(remove_claims=True, delete_claim=True) + + def test_rodc_issued_device_claims_modify(self): + self.run_device_rodc_tgs_test(remove_claims=False, delete_claim=False) + + def test_rodc_issued_device_claims_delete(self): + self.run_device_rodc_tgs_test(remove_claims=False, delete_claim=True) + + def test_rodc_issued_device_claims_remove_claims_modify(self): + self.run_device_rodc_tgs_test(remove_claims=True, delete_claim=False) + + def test_rodc_issued_device_claims_remove_claims_delete(self): + self.run_device_rodc_tgs_test(remove_claims=True, delete_claim=True) + # Create a user account with an applicable claim for the 'middleName' # attribute. After obtaining a TGT, from which we optionally remove the # claims, change the middleName attribute values for the account in the @@ -479,6 +503,230 @@ class ClaimsTests(KDCBaseTest): additional_tickets=additional_tickets) self.check_reply(rep, KRB_TGS_REP) + def run_rodc_tgs_test(self, remove_claims, delete_claim): + samdb = self.get_samdb() + # Create a user account permitted to replicate to the RODC. + user_creds = self.get_cached_creds( + account_type=self.AccountType.USER, + opts={ + # Set the value of the claim attribute. + 'additional_details': (('middleName', 'foo'),), + 'allowed_replication_mock': True, + 'revealed_to_mock_rodc': True, + }, + use_cache=False) + user_dn = user_creds.get_dn() + + # Create a claim that applies to the user. + claim_id = self.get_new_username() + self.create_claim(claim_id, + enabled=True, + attribute='middleName', + single_valued=True, + source_type='AD', + for_classes=['user'], + value_type=claims.CLAIM_TYPE_STRING) + + expected_claims = { + claim_id: { + 'source_type': claims.CLAIMS_SOURCE_TYPE_AD, + 'type': claims.CLAIM_TYPE_STRING, + 'values': ('foo',), + }, + } + + # Get a TGT for the user. + tgt = self.get_tgt(user_creds, expect_pac=True, + expect_client_claims=True, + expected_client_claims=expected_claims) + + # Modify the TGT to be issued by an RODC. Optionally remove the client + # claims. + if remove_claims: + tgt = self.remove_client_claims_tgt_from_rodc(tgt) + else: + tgt = self.issued_by_rodc(tgt) + + # Modify or delete the value of the attribute used for the claim. Modify + # our test expectations accordingly. + msg = ldb.Message(user_dn) + if delete_claim: + msg['middleName'] = ldb.MessageElement([], + ldb.FLAG_MOD_DELETE, + 'middleName') + expected_claims = None + unexpected_claims = {claim_id} + else: + msg['middleName'] = ldb.MessageElement('bar', + ldb.FLAG_MOD_REPLACE, + 'middleName') + expected_claims = { + claim_id: { + 'source_type': claims.CLAIMS_SOURCE_TYPE_AD, + 'type': claims.CLAIM_TYPE_STRING, + 'values': ('bar',), + }, + } + unexpected_claims = None + samdb.modify(msg) + + target_creds = self.get_service_creds() + + # Get a service ticket for the user. The claim value should have + # changed, indicating that the client claims have been regenerated or + # removed, depending on whether the corresponding attribute is still + # present on the account. + self.get_service_ticket( + tgt, target_creds, + expect_pac=True, + # Expect the CLIENT_CLAIMS_INFO PAC buffer. It may be empty. + expect_client_claims=True, + expected_client_claims=expected_claims, + unexpected_client_claims=unexpected_claims) + + def run_device_rodc_tgs_test(self, remove_claims, delete_claim): + samdb = self.get_samdb() + + # Create the user account. + user_creds = self.get_cached_creds( + account_type=self.AccountType.USER) + user_name = user_creds.get_username() + + # Create a machine account permitted to replicate to the RODC. + mach_creds = self.get_cached_creds( + account_type=self.AccountType.COMPUTER, + opts={ + # Set the value of the claim attribute. + 'additional_details': (('middleName', 'foo'),), + 'allowed_replication_mock': True, + 'revealed_to_mock_rodc': True, + }, + use_cache=False) + mach_dn = mach_creds.get_dn() + + # Create a claim that applies to the computer. + claim_id = self.get_new_username() + self.create_claim(claim_id, + enabled=True, + attribute='middleName', + single_valued=True, + source_type='AD', + for_classes=['computer'], + value_type=claims.CLAIM_TYPE_STRING) + + expected_claims = { + claim_id: { + 'source_type': claims.CLAIMS_SOURCE_TYPE_AD, + 'type': claims.CLAIM_TYPE_STRING, + 'values': ('foo',), + }, + } + + # Get a TGT for the user. + user_tgt = self.get_tgt(user_creds) + + # Get a TGT for the computer. + mach_tgt = self.get_tgt(mach_creds, expect_pac=True, + expect_client_claims=True, + expected_client_claims=expected_claims) + + # Modify the computer's TGT to be issued by an RODC. Optionally remove + # the client claims. + if remove_claims: + mach_tgt = self.remove_client_claims_tgt_from_rodc(mach_tgt) + else: + mach_tgt = self.issued_by_rodc(mach_tgt) + + # Modify or delete the value of the attribute used for the claim. Modify + # our test expectations accordingly. + msg = ldb.Message(mach_dn) + if delete_claim: + msg['middleName'] = ldb.MessageElement([], + ldb.FLAG_MOD_DELETE, + 'middleName') + expected_claims = None + unexpected_claims = {claim_id} + else: + msg['middleName'] = ldb.MessageElement('bar', + ldb.FLAG_MOD_REPLACE, + 'middleName') + expected_claims = { + claim_id: { + 'source_type': claims.CLAIMS_SOURCE_TYPE_AD, + 'type': claims.CLAIM_TYPE_STRING, + 'values': ('bar',), + }, + } + unexpected_claims = None + samdb.modify(msg) + + subkey = self.RandomKey(user_tgt.session_key.etype) + + armor_subkey = self.RandomKey(subkey.etype) + explicit_armor_key = self.generate_armor_key(armor_subkey, + mach_tgt.session_key) + armor_key = kcrypto.cf2(explicit_armor_key.key, + subkey.key, + b'explicitarmor', + b'tgsarmor') + armor_key = Krb5EncryptionKey(armor_key, None) + + target_creds = self.get_service_creds() + target_name = target_creds.get_username() + if target_name[-1] == '$': + target_name = target_name[:-1] + + sname = self.PrincipalName_create(name_type=NT_PRINCIPAL, + names=['host', target_name]) + srealm = target_creds.get_realm() + + decryption_key = self.TicketDecryptionKey_from_creds( + target_creds) + + target_supported_etypes = target_creds.tgs_supported_enctypes + + etypes = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) + + kdc_options = '0' + pac_options = '1' # claims support + + # Perform a TGS-REQ for the user. The device claim value should have + # changed, indicating that the computer's client claims have been + # regenerated or removed, depending on whether the corresponding + # attribute is still present on the account. + + kdc_exchange_dict = self.tgs_exchange_dict( + expected_crealm=user_tgt.crealm, + expected_cname=user_tgt.cname, + expected_srealm=srealm, + expected_sname=sname, + expected_account_name=user_name, + ticket_decryption_key=decryption_key, + generate_fast_fn=self.generate_simple_fast, + generate_fast_armor_fn=self.generate_ap_req, + check_rep_fn=self.generic_check_kdc_rep, + check_kdc_private_fn=self.generic_check_kdc_private, + tgt=user_tgt, + armor_key=armor_key, + armor_tgt=mach_tgt, + armor_subkey=armor_subkey, + pac_options=pac_options, + authenticator_subkey=subkey, + kdc_options=kdc_options, + expect_pac=True, + expected_supported_etypes=target_supported_etypes, + # Expect the DEVICE_CLAIMS_INFO PAC buffer. It may be empty. + expect_device_claims=True, + expected_device_claims=expected_claims, + unexpected_device_claims=unexpected_claims) + + rep = self._generic_kdc_exchange(kdc_exchange_dict, + cname=None, + realm=srealm, + sname=sname, + etypes=etypes) + self.check_reply(rep, KRB_TGS_REP) + @staticmethod def freeze(m): return frozenset((k, v) for k, v in m.items()) diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc index cc818e4040d..a72f53ec503 100644 --- a/selftest/knownfail_heimdal_kdc +++ b/selftest/knownfail_heimdal_kdc @@ -143,6 +143,14 @@ ^samba.tests.krb5.claims_tests.samba.tests.krb5.claims_tests.ClaimsTests.test_delegation_claims_remove_claims.ad_dc ^samba.tests.krb5.claims_tests.samba.tests.krb5.claims_tests.ClaimsTests.test_device_claims_device_to_service_no_claims_valid_sid.ad_dc ^samba.tests.krb5.claims_tests.samba.tests.krb5.claims_tests.ClaimsTests.test_device_claims_device_to_service_no_compound_id.ad_dc +^samba.tests.krb5.claims_tests.samba.tests.krb5.claims_tests.ClaimsTests.test_rodc_issued_claims_delete.ad_dc +^samba.tests.krb5.claims_tests.samba.tests.krb5.claims_tests.ClaimsTests.test_rodc_issued_claims_modify.ad_dc +^samba.tests.krb5.claims_tests.samba.tests.krb5.claims_tests.ClaimsTests.test_rodc_issued_claims_remove_claims_delete.ad_dc +^samba.tests.krb5.claims_tests.samba.tests.krb5.claims_tests.ClaimsTests.test_rodc_issued_claims_remove_claims_modify.ad_dc +^samba.tests.krb5.claims_tests.samba.tests.krb5.claims_tests.ClaimsTests.test_rodc_issued_device_claims_delete.ad_dc +^samba.tests.krb5.claims_tests.samba.tests.krb5.claims_tests.ClaimsTests.test_rodc_issued_device_claims_modify.ad_dc +^samba.tests.krb5.claims_tests.samba.tests.krb5.claims_tests.ClaimsTests.test_rodc_issued_device_claims_remove_claims_delete.ad_dc +^samba.tests.krb5.claims_tests.samba.tests.krb5.claims_tests.ClaimsTests.test_rodc_issued_device_claims_remove_claims_modify.ad_dc ^samba.tests.krb5.claims_tests.samba.tests.krb5.claims_tests.ClaimsTests.test_tgs_claims.ad_dc ^samba.tests.krb5.claims_tests.samba.tests.krb5.claims_tests.ClaimsTests.test_tgs_claims_remove_claims.ad_dc ^samba.tests.krb5.claims_tests.samba.tests.krb5.claims_tests.ClaimsTests.test_tgs_claims_remove_claims_to_krbtgt.ad_dc diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc index e790f290668..3d4876ff00b 100644 --- a/selftest/knownfail_mit_kdc +++ b/selftest/knownfail_mit_kdc @@ -547,6 +547,14 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ ^samba.tests.krb5.claims_tests.samba.tests.krb5.claims_tests.ClaimsTests.test_delegation_claims_remove_claims.ad_dc ^samba.tests.krb5.claims_tests.samba.tests.krb5.claims_tests.ClaimsTests.test_device_claims_device_to_service_no_claims_valid_sid.ad_dc ^samba.tests.krb5.claims_tests.samba.tests.krb5.claims_tests.ClaimsTests.test_device_claims_device_to_service_no_compound_id.ad_dc +^samba.tests.krb5.claims_tests.samba.tests.krb5.claims_tests.ClaimsTests.test_rodc_issued_claims_delete.ad_dc +^samba.tests.krb5.claims_tests.samba.tests.krb5.claims_tests.ClaimsTests.test_rodc_issued_claims_modify.ad_dc +^samba.tests.krb5.claims_tests.samba.tests.krb5.claims_tests.ClaimsTests.test_rodc_issued_claims_remove_claims_delete.ad_dc +^samba.tests.krb5.claims_tests.samba.tests.krb5.claims_tests.ClaimsTests.test_rodc_issued_claims_remove_claims_modify.ad_dc +^samba.tests.krb5.claims_tests.samba.tests.krb5.claims_tests.ClaimsTests.test_rodc_issued_device_claims_delete.ad_dc +^samba.tests.krb5.claims_tests.samba.tests.krb5.claims_tests.ClaimsTests.test_rodc_issued_device_claims_modify.ad_dc +^samba.tests.krb5.claims_tests.samba.tests.krb5.claims_tests.ClaimsTests.test_rodc_issued_device_claims_remove_claims_delete.ad_dc +^samba.tests.krb5.claims_tests.samba.tests.krb5.claims_tests.ClaimsTests.test_rodc_issued_device_claims_remove_claims_modify.ad_dc ^samba.tests.krb5.claims_tests.samba.tests.krb5.claims_tests.ClaimsTests.test_tgs_claims.ad_dc ^samba.tests.krb5.claims_tests.samba.tests.krb5.claims_tests.ClaimsTests.test_tgs_claims_remove_claims.ad_dc ^samba.tests.krb5.claims_tests.samba.tests.krb5.claims_tests.ClaimsTests.test_tgs_claims_remove_claims_to_krbtgt.ad_dc