mirror of
https://github.com/samba-team/samba.git
synced 2025-01-13 13:18:06 +03:00
tests/krb5: Allow changing the SID of a user's PAC
This lets us simulate a ticket of a user from another domain. Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abartlet@samba.org>
This commit is contained in:
parent
11aa940fb3
commit
bd4af42130
@ -107,7 +107,11 @@ class GroupTests(KDCBaseTest):
|
|||||||
# Get a ticket with the SIDs in the PAC replaced with ones we specify. This
|
# Get a ticket with the SIDs in the PAC replaced with ones we specify. This
|
||||||
# is useful for creating arbitrary tickets that can be used to perform a
|
# is useful for creating arbitrary tickets that can be used to perform a
|
||||||
# TGS-REQ.
|
# TGS-REQ.
|
||||||
def ticket_with_sids(self, ticket, new_sids, domain_sid):
|
def ticket_with_sids(self,
|
||||||
|
ticket,
|
||||||
|
new_sids,
|
||||||
|
domain_sid,
|
||||||
|
user_rid):
|
||||||
krbtgt_creds = self.get_krbtgt_creds()
|
krbtgt_creds = self.get_krbtgt_creds()
|
||||||
krbtgt_key = self.TicketDecryptionKey_from_creds(krbtgt_creds)
|
krbtgt_key = self.TicketDecryptionKey_from_creds(krbtgt_creds)
|
||||||
|
|
||||||
@ -117,14 +121,19 @@ class GroupTests(KDCBaseTest):
|
|||||||
|
|
||||||
modify_pac_fn = partial(self.set_pac_sids,
|
modify_pac_fn = partial(self.set_pac_sids,
|
||||||
new_sids=new_sids,
|
new_sids=new_sids,
|
||||||
domain_sid=domain_sid)
|
domain_sid=domain_sid,
|
||||||
|
user_rid=user_rid)
|
||||||
|
|
||||||
return self.modified_ticket(ticket,
|
return self.modified_ticket(ticket,
|
||||||
modify_pac_fn=modify_pac_fn,
|
modify_pac_fn=modify_pac_fn,
|
||||||
checksum_keys=checksum_keys)
|
checksum_keys=checksum_keys)
|
||||||
|
|
||||||
# Replace the SIDs in a PAC with 'new_sids'.
|
# Replace the SIDs in a PAC with 'new_sids'.
|
||||||
def set_pac_sids(self, pac, new_sids, domain_sid):
|
def set_pac_sids(self,
|
||||||
|
pac,
|
||||||
|
new_sids,
|
||||||
|
domain_sid,
|
||||||
|
user_rid):
|
||||||
base_sids = []
|
base_sids = []
|
||||||
extra_sids = []
|
extra_sids = []
|
||||||
resource_sids = []
|
resource_sids = []
|
||||||
@ -167,6 +176,10 @@ class GroupTests(KDCBaseTest):
|
|||||||
else:
|
else:
|
||||||
self.fail(f'invalid SID type {sid_type}')
|
self.fail(f'invalid SID type {sid_type}')
|
||||||
|
|
||||||
|
found_logon_info = True
|
||||||
|
|
||||||
|
user_sid = security.dom_sid(f'{domain_sid}-{user_rid}')
|
||||||
|
|
||||||
pac_buffers = pac.buffers
|
pac_buffers = pac.buffers
|
||||||
for pac_buffer in pac_buffers:
|
for pac_buffer in pac_buffers:
|
||||||
# Find the LOGON_INFO PAC buffer.
|
# Find the LOGON_INFO PAC buffer.
|
||||||
@ -191,6 +204,9 @@ class GroupTests(KDCBaseTest):
|
|||||||
else:
|
else:
|
||||||
logon_info.info3.base.groups.rids = None
|
logon_info.info3.base.groups.rids = None
|
||||||
|
|
||||||
|
logon_info.info3.base.domain_sid = security.dom_sid(domain_sid)
|
||||||
|
logon_info.info3.base.rid = int(user_rid)
|
||||||
|
|
||||||
# Add Resource SIDs and set the RESOURCE_GROUPS flag as needed.
|
# Add Resource SIDs and set the RESOURCE_GROUPS flag as needed.
|
||||||
logon_info.resource_groups.groups.count = len(resource_sids)
|
logon_info.resource_groups.groups.count = len(resource_sids)
|
||||||
if resource_sids:
|
if resource_sids:
|
||||||
@ -205,9 +221,18 @@ class GroupTests(KDCBaseTest):
|
|||||||
logon_info.info3.base.user_flags &= ~(
|
logon_info.info3.base.user_flags &= ~(
|
||||||
netlogon.NETLOGON_RESOURCE_GROUPS)
|
netlogon.NETLOGON_RESOURCE_GROUPS)
|
||||||
|
|
||||||
break
|
found_logon_info = True
|
||||||
else:
|
|
||||||
self.fail('no LOGON_INFO PAC buffer')
|
# Also replace the user's SID in the UPN DNS buffer.
|
||||||
|
elif pac_buffer.type == krb5pac.PAC_TYPE_UPN_DNS_INFO:
|
||||||
|
upn_dns_info_ex = pac_buffer.info.ex
|
||||||
|
|
||||||
|
upn_dns_info_ex.objectsid = user_sid
|
||||||
|
|
||||||
|
# But don't replace the user's SID in the Requester SID buffer, or
|
||||||
|
# we'll get a SID mismatch.
|
||||||
|
|
||||||
|
self.assertTrue(found_logon_info, 'no LOGON_INFO PAC buffer')
|
||||||
|
|
||||||
pac.buffers = pac_buffers
|
pac.buffers = pac_buffers
|
||||||
|
|
||||||
@ -1019,6 +1044,9 @@ class GroupTests(KDCBaseTest):
|
|||||||
# Optional SIDs to replace those in the PAC prior to a TGS-REQ.
|
# Optional SIDs to replace those in the PAC prior to a TGS-REQ.
|
||||||
tgs_sids = case.pop('tgs:sids', None)
|
tgs_sids = case.pop('tgs:sids', None)
|
||||||
|
|
||||||
|
# Optional user SID to replace that in the PAC prior to a TGS-REQ.
|
||||||
|
tgs_user_sid = case.pop('tgs:user_sid', None)
|
||||||
|
|
||||||
# The SIDs we expect to see in the PAC after a AS-REQ or a TGS-REQ.
|
# The SIDs we expect to see in the PAC after a AS-REQ or a TGS-REQ.
|
||||||
as_expected = case.pop('as:expected', None)
|
as_expected = case.pop('as:expected', None)
|
||||||
tgs_expected = case.pop('tgs:expected', None)
|
tgs_expected = case.pop('tgs:expected', None)
|
||||||
@ -1050,6 +1078,11 @@ class GroupTests(KDCBaseTest):
|
|||||||
'specified compression for TGS request, but '
|
'specified compression for TGS request, but '
|
||||||
'no expected SIDs provided')
|
'no expected SIDs provided')
|
||||||
|
|
||||||
|
if tgs_user_sid is not None:
|
||||||
|
self.assertIsNotNone(tgs_sids,
|
||||||
|
'specified TGS-REQ user SID, but no '
|
||||||
|
'accompanying SIDs provided')
|
||||||
|
|
||||||
samdb = self.get_samdb()
|
samdb = self.get_samdb()
|
||||||
|
|
||||||
domain_sid = samdb.get_domain_sid()
|
domain_sid = samdb.get_domain_sid()
|
||||||
@ -1083,9 +1116,19 @@ class GroupTests(KDCBaseTest):
|
|||||||
groups = self.setup_groups(samdb, group_setup, user_principal)
|
groups = self.setup_groups(samdb, group_setup, user_principal)
|
||||||
del group_setup
|
del group_setup
|
||||||
|
|
||||||
expected_groups = self.map_sids(as_expected, groups, domain_sid)
|
if tgs_user_sid is None:
|
||||||
tgs_sids_mapped = self.map_sids(tgs_sids, groups, domain_sid)
|
tgs_user_sid = user_sid
|
||||||
tgs_expected_mapped = self.map_sids(tgs_expected, groups, domain_sid)
|
elif tgs_user_sid in groups:
|
||||||
|
tgs_user_sid = groups[tgs_user_sid].sid
|
||||||
|
|
||||||
|
tgs_domain_sid, tgs_user_rid = tgs_user_sid.rsplit('-', 1)
|
||||||
|
|
||||||
|
expected_groups = self.map_sids(as_expected, groups,
|
||||||
|
domain_sid)
|
||||||
|
tgs_sids_mapped = self.map_sids(tgs_sids, groups,
|
||||||
|
tgs_domain_sid)
|
||||||
|
tgs_expected_mapped = self.map_sids(tgs_expected, groups,
|
||||||
|
tgs_domain_sid)
|
||||||
|
|
||||||
till = self.get_KerberosTime(offset=36000)
|
till = self.get_KerberosTime(offset=36000)
|
||||||
kdc_options = '0'
|
kdc_options = '0'
|
||||||
@ -1128,13 +1171,20 @@ class GroupTests(KDCBaseTest):
|
|||||||
|
|
||||||
if tgs_sids is not None:
|
if tgs_sids is not None:
|
||||||
# Replace the SIDs in the PAC with the ones provided by the test.
|
# Replace the SIDs in the PAC with the ones provided by the test.
|
||||||
ticket = self.ticket_with_sids(ticket, tgs_sids_mapped, domain_sid)
|
ticket = self.ticket_with_sids(ticket,
|
||||||
|
tgs_sids_mapped,
|
||||||
|
tgs_domain_sid,
|
||||||
|
tgs_user_rid)
|
||||||
|
|
||||||
target_creds, sname = self.get_target(tgs_to_krbtgt, tgs_compression)
|
target_creds, sname = self.get_target(tgs_to_krbtgt, tgs_compression)
|
||||||
decryption_key = self.TicketDecryptionKey_from_creds(target_creds)
|
decryption_key = self.TicketDecryptionKey_from_creds(target_creds)
|
||||||
|
|
||||||
subkey = self.RandomKey(ticket.session_key.etype)
|
subkey = self.RandomKey(ticket.session_key.etype)
|
||||||
|
|
||||||
|
requester_sid = None
|
||||||
|
if tgs_to_krbtgt:
|
||||||
|
requester_sid = user_sid
|
||||||
|
|
||||||
# Perform a TGS-REQ with the user account.
|
# Perform a TGS-REQ with the user account.
|
||||||
|
|
||||||
kdc_exchange_dict = self.tgs_exchange_dict(
|
kdc_exchange_dict = self.tgs_exchange_dict(
|
||||||
@ -1144,8 +1194,9 @@ class GroupTests(KDCBaseTest):
|
|||||||
expected_sname=sname,
|
expected_sname=sname,
|
||||||
expected_account_name=user_name,
|
expected_account_name=user_name,
|
||||||
expected_groups=tgs_expected_mapped,
|
expected_groups=tgs_expected_mapped,
|
||||||
expected_sid=user_sid,
|
expected_sid=tgs_user_sid,
|
||||||
expected_domain_sid=domain_sid,
|
expected_requester_sid=requester_sid,
|
||||||
|
expected_domain_sid=tgs_domain_sid,
|
||||||
expected_supported_etypes=target_supported_etypes,
|
expected_supported_etypes=target_supported_etypes,
|
||||||
ticket_decryption_key=decryption_key,
|
ticket_decryption_key=decryption_key,
|
||||||
check_rep_fn=self.generic_check_kdc_rep,
|
check_rep_fn=self.generic_check_kdc_rep,
|
||||||
|
@ -2456,6 +2456,7 @@ class RawKerberosTest(TestCaseInTempDir):
|
|||||||
unexpected_groups=None,
|
unexpected_groups=None,
|
||||||
expected_upn_name=None,
|
expected_upn_name=None,
|
||||||
expected_sid=None,
|
expected_sid=None,
|
||||||
|
expected_requester_sid=None,
|
||||||
expected_domain_sid=None,
|
expected_domain_sid=None,
|
||||||
expected_supported_etypes=None,
|
expected_supported_etypes=None,
|
||||||
expected_flags=None,
|
expected_flags=None,
|
||||||
@ -2526,6 +2527,7 @@ class RawKerberosTest(TestCaseInTempDir):
|
|||||||
'unexpected_groups': unexpected_groups,
|
'unexpected_groups': unexpected_groups,
|
||||||
'expected_upn_name': expected_upn_name,
|
'expected_upn_name': expected_upn_name,
|
||||||
'expected_sid': expected_sid,
|
'expected_sid': expected_sid,
|
||||||
|
'expected_requester_sid': expected_requester_sid,
|
||||||
'expected_domain_sid': expected_domain_sid,
|
'expected_domain_sid': expected_domain_sid,
|
||||||
'expected_supported_etypes': expected_supported_etypes,
|
'expected_supported_etypes': expected_supported_etypes,
|
||||||
'expected_flags': expected_flags,
|
'expected_flags': expected_flags,
|
||||||
@ -2592,6 +2594,7 @@ class RawKerberosTest(TestCaseInTempDir):
|
|||||||
unexpected_groups=None,
|
unexpected_groups=None,
|
||||||
expected_upn_name=None,
|
expected_upn_name=None,
|
||||||
expected_sid=None,
|
expected_sid=None,
|
||||||
|
expected_requester_sid=None,
|
||||||
expected_domain_sid=None,
|
expected_domain_sid=None,
|
||||||
expected_supported_etypes=None,
|
expected_supported_etypes=None,
|
||||||
expected_flags=None,
|
expected_flags=None,
|
||||||
@ -2663,6 +2666,7 @@ class RawKerberosTest(TestCaseInTempDir):
|
|||||||
'unexpected_groups': unexpected_groups,
|
'unexpected_groups': unexpected_groups,
|
||||||
'expected_upn_name': expected_upn_name,
|
'expected_upn_name': expected_upn_name,
|
||||||
'expected_sid': expected_sid,
|
'expected_sid': expected_sid,
|
||||||
|
'expected_requester_sid': expected_requester_sid,
|
||||||
'expected_domain_sid': expected_domain_sid,
|
'expected_domain_sid': expected_domain_sid,
|
||||||
'expected_supported_etypes': expected_supported_etypes,
|
'expected_supported_etypes': expected_supported_etypes,
|
||||||
'expected_flags': expected_flags,
|
'expected_flags': expected_flags,
|
||||||
@ -3378,12 +3382,15 @@ class RawKerberosTest(TestCaseInTempDir):
|
|||||||
expected_types.append(krb5pac.PAC_TYPE_ATTRIBUTES_INFO)
|
expected_types.append(krb5pac.PAC_TYPE_ATTRIBUTES_INFO)
|
||||||
|
|
||||||
expect_requester_sid = kdc_exchange_dict['expect_requester_sid']
|
expect_requester_sid = kdc_exchange_dict['expect_requester_sid']
|
||||||
|
expected_requester_sid = kdc_exchange_dict['expected_requester_sid']
|
||||||
|
|
||||||
if expect_requester_sid is None:
|
if expect_requester_sid is None:
|
||||||
if self.expect_extra_pac_buffers:
|
if self.expect_extra_pac_buffers:
|
||||||
expect_requester_sid = expect_extra_pac_buffers
|
expect_requester_sid = expect_extra_pac_buffers
|
||||||
else:
|
else:
|
||||||
require_strict.add(krb5pac.PAC_TYPE_REQUESTER_SID)
|
require_strict.add(krb5pac.PAC_TYPE_REQUESTER_SID)
|
||||||
|
if expected_requester_sid is not None:
|
||||||
|
expect_requester_sid = True
|
||||||
if expect_requester_sid:
|
if expect_requester_sid:
|
||||||
expected_types.append(krb5pac.PAC_TYPE_REQUESTER_SID)
|
expected_types.append(krb5pac.PAC_TYPE_REQUESTER_SID)
|
||||||
|
|
||||||
@ -3482,8 +3489,11 @@ class RawKerberosTest(TestCaseInTempDir):
|
|||||||
and expect_requester_sid):
|
and expect_requester_sid):
|
||||||
requester_sid = pac_buffer.info.sid
|
requester_sid = pac_buffer.info.sid
|
||||||
|
|
||||||
|
if expected_requester_sid is None:
|
||||||
|
expected_requester_sid = expected_sid
|
||||||
if expected_sid is not None:
|
if expected_sid is not None:
|
||||||
self.assertEqual(expected_sid, str(requester_sid))
|
self.assertEqual(expected_requester_sid,
|
||||||
|
str(requester_sid))
|
||||||
|
|
||||||
elif pac_buffer.type in {krb5pac.PAC_TYPE_CLIENT_CLAIMS_INFO,
|
elif pac_buffer.type in {krb5pac.PAC_TYPE_CLIENT_CLAIMS_INFO,
|
||||||
krb5pac.PAC_TYPE_DEVICE_CLAIMS_INFO}:
|
krb5pac.PAC_TYPE_DEVICE_CLAIMS_INFO}:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user