ctdb-scripts: Improve update and listing code
[samba4-gss.git] / python / samba / tests / krb5 / group_tests.py
blob1214fa2bd8898a62dcc1a52a7faa67668f88ff2c
1 #!/usr/bin/env python3
2 # Unix SMB/CIFS implementation.
3 # Copyright (C) Stefan Metzmacher 2020
4 # Copyright (C) Catalyst.Net Ltd 2022
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 3 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20 import sys
21 import os
23 sys.path.insert(0, 'bin/python')
24 os.environ['PYTHONUNBUFFERED'] = '1'
26 import random
27 import re
29 import ldb
31 from samba import werror
32 from samba.dcerpc import netlogon, security
33 from samba.tests import DynamicTestCase, env_get_var_value
34 from samba.tests.krb5 import kcrypto
35 from samba.tests.krb5.kdc_base_test import GroupType, KDCBaseTest, Principal
36 from samba.tests.krb5.raw_testcase import RawKerberosTest
37 from samba.tests.krb5.rfc4120_constants import (
38 KRB_TGS_REP,
39 NT_PRINCIPAL,
42 SidType = RawKerberosTest.SidType
44 global_asn1_print = False
45 global_hexdump = False
48 @DynamicTestCase
49 class GroupTests(KDCBaseTest):
50 # Placeholder objects that represent the user account undergoing testing.
51 user = object()
52 trust_user = object()
54 # Constants for group SID attributes.
55 default_attrs = security.SE_GROUP_DEFAULT_FLAGS
56 resource_attrs = default_attrs | security.SE_GROUP_RESOURCE
58 asserted_identity = security.SID_AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY
60 trust_domain = 'S-1-5-21-123-456-789'
62 def setUp(self):
63 super().setUp()
64 self.do_asn1_print = global_asn1_print
65 self.do_hexdump = global_hexdump
67 @classmethod
68 def setUpDynamicTestCases(cls):
69 FILTER = env_get_var_value('FILTER', allow_missing=True)
70 SKIP_INVALID = env_get_var_value('SKIP_INVALID', allow_missing=True)
72 for case in cls.cases:
73 invalid = case.pop('configuration_invalid', False)
74 if SKIP_INVALID and invalid:
75 # Some group setups are invalid on Windows, so we allow them to
76 # be skipped.
77 continue
78 name = case.pop('test')
79 name = re.sub(r'\W+', '_', name)
80 if FILTER and not re.search(FILTER, name):
81 continue
83 cls.generate_dynamic_test('test_group', name,
84 dict(case))
86 def test_set_universal_primary_group(self):
87 samdb = self.get_samdb()
89 # Create a universal group.
90 universal_dn = self.create_group(samdb,
91 self.get_new_username(),
92 gtype=GroupType.UNIVERSAL.value)
94 # Get the SID of the universal group.
95 universal_sid = self.get_objectSid(samdb, universal_dn)
97 # Create a user account belonging to the group.
98 creds = self.get_cached_creds(
99 account_type=self.AccountType.USER,
100 opts={
101 'member_of': (
102 universal_dn,
104 'kerberos_enabled': False,
106 use_cache=False)
108 # Set the user's primary group.
109 self.set_primary_group(samdb, creds.get_dn(), universal_sid)
111 def test_set_domain_local_primary_group(self):
112 samdb = self.get_samdb()
114 # Create a domain-local group.
115 domain_local_dn = self.create_group(samdb,
116 self.get_new_username(),
117 gtype=GroupType.DOMAIN_LOCAL.value)
119 # Get the SID of the domain-local group.
120 domain_local_sid = self.get_objectSid(samdb, domain_local_dn)
122 # Create a user account belonging to the group.
123 creds = self.get_cached_creds(
124 account_type=self.AccountType.USER,
125 opts={
126 'member_of': (
127 domain_local_dn,
129 'kerberos_enabled': False,
131 use_cache=False)
133 # Setting the user's primary group fails.
134 self.set_primary_group(
135 samdb, creds.get_dn(), domain_local_sid,
136 expected_error=ldb.ERR_UNWILLING_TO_PERFORM,
137 expected_werror=werror.WERR_MEMBER_NOT_IN_GROUP)
139 def test_change_universal_primary_group_to_global(self):
140 samdb = self.get_samdb()
142 # Create a universal group.
143 universal_dn = self.create_group(samdb,
144 self.get_new_username(),
145 gtype=GroupType.UNIVERSAL.value)
147 # Get the SID of the universal group.
148 universal_sid = self.get_objectSid(samdb, universal_dn)
150 # Create a user account belonging to the group.
151 creds = self.get_cached_creds(
152 account_type=self.AccountType.USER,
153 opts={
154 'member_of': (
155 universal_dn,
157 'kerberos_enabled': False,
159 use_cache=False)
161 # Set the user's primary group.
162 self.set_primary_group(samdb, creds.get_dn(), universal_sid)
164 # Change the group to a global group.
165 self.set_group_type(samdb,
166 ldb.Dn(samdb, universal_dn),
167 GroupType.GLOBAL)
169 def test_change_universal_primary_group_to_domain_local(self):
170 samdb = self.get_samdb()
172 # Create a universal group.
173 universal_dn = self.create_group(samdb,
174 self.get_new_username(),
175 gtype=GroupType.UNIVERSAL.value)
177 # Get the SID of the universal group.
178 universal_sid = self.get_objectSid(samdb, universal_dn)
180 # Create a user account belonging to the group.
181 creds = self.get_cached_creds(
182 account_type=self.AccountType.USER,
183 opts={
184 'member_of': (
185 universal_dn,
187 'kerberos_enabled': False,
189 use_cache=False)
191 # Set the user's primary group.
192 self.set_primary_group(samdb, creds.get_dn(), universal_sid)
194 # Change the group to a domain-local group. This works, even though the
195 # group is still the user's primary group.
196 self.set_group_type(samdb,
197 ldb.Dn(samdb, universal_dn),
198 GroupType.DOMAIN_LOCAL)
200 # Check the groups in a SamInfo structure returned by SamLogon.
201 def test_samlogon_SamInfo(self):
202 samdb = self.get_samdb()
204 # Create a universal and a domain-local group.
205 universal_dn = self.create_group(samdb,
206 self.get_new_username(),
207 gtype=GroupType.UNIVERSAL.value)
208 domain_local_dn = self.create_group(samdb,
209 self.get_new_username(),
210 gtype=GroupType.DOMAIN_LOCAL.value)
212 # Create a user account belonging to both groups.
213 creds = self.get_cached_creds(
214 account_type=self.AccountType.USER,
215 opts={
216 'member_of': (
217 universal_dn,
218 domain_local_dn,
220 'kerberos_enabled': False,
223 # Get the SID and RID of the user account.
224 user_sid = creds.get_sid()
225 user_rid = int(user_sid.rsplit('-', 1)[1])
227 # Get the SID and RID of the universal group.
228 universal_sid = self.get_objectSid(samdb, universal_dn)
229 universal_rid = int(universal_sid.rsplit('-', 1)[1])
231 # We don't expect the EXTRA_SIDS flag to be set.
232 unexpected_flags = netlogon.NETLOGON_EXTRA_SIDS
234 # Do a SamLogon call and check we get back the right structure.
235 interactive = netlogon.NetlogonInteractiveInformation
236 level = netlogon.NetlogonValidationSamInfo
237 validation = self._test_samlogon(creds=creds,
238 logon_type=interactive,
239 validation_level=level)
240 self.assertIsInstance(validation, netlogon.netr_SamInfo2)
242 base = validation.base
244 # Check some properties of the base structure.
245 self.assertEqual(user_rid, base.rid)
246 self.assertEqual(security.DOMAIN_RID_USERS, base.primary_gid)
247 self.assertEqual(samdb.get_domain_sid(), str(base.domain_sid))
248 self.assertFalse(unexpected_flags & base.user_flags,
249 f'0x{unexpected_flags:x} unexpectedly set in '
250 f'user_flags (0x{base.user_flags:x})')
252 # Check we have two groups in the base.
253 self.assertEqual(2, base.groups.count)
255 rids = base.groups.rids
257 # The first group should be Domain Users.
258 self.assertEqual(security.DOMAIN_RID_USERS, rids[0].rid)
259 self.assertEqual(self.default_attrs, rids[0].attributes)
261 # The second should be our universal group.
262 self.assertEqual(universal_rid, rids[1].rid)
263 self.assertEqual(self.default_attrs, rids[1].attributes)
265 # The domain-local group is nowhere to be found.
267 # Check the groups in a SamInfo2 structure returned by SamLogon.
268 def test_samlogon_SamInfo2(self):
269 samdb = self.get_samdb()
271 # Create a universal and a domain-local group.
272 universal_dn = self.create_group(samdb,
273 self.get_new_username(),
274 gtype=GroupType.UNIVERSAL.value)
275 domain_local_dn = self.create_group(samdb,
276 self.get_new_username(),
277 gtype=GroupType.DOMAIN_LOCAL.value)
279 # Create a user account belonging to both groups.
280 creds = self.get_cached_creds(
281 account_type=self.AccountType.USER,
282 opts={
283 'member_of': (
284 universal_dn,
285 domain_local_dn,
287 'kerberos_enabled': False,
290 # Get the SID and RID of the user account.
291 user_sid = creds.get_sid()
292 user_rid = int(user_sid.rsplit('-', 1)[1])
294 # Get the SID and RID of the universal group.
295 universal_sid = self.get_objectSid(samdb, universal_dn)
296 universal_rid = int(universal_sid.rsplit('-', 1)[1])
298 # Get the SID of the domain-local group.
299 domain_local_sid = self.get_objectSid(samdb, domain_local_dn)
301 # We expect the EXTRA_SIDS flag to be set.
302 expected_flags = netlogon.NETLOGON_EXTRA_SIDS
304 # Do a SamLogon call and check we get back the right structure.
305 interactive = netlogon.NetlogonInteractiveInformation
306 level = netlogon.NetlogonValidationSamInfo2
307 validation = self._test_samlogon(creds=creds,
308 logon_type=interactive,
309 validation_level=level)
310 self.assertIsInstance(validation, netlogon.netr_SamInfo3)
312 base = validation.base
314 # Check some properties of the base structure.
315 self.assertEqual(user_rid, base.rid)
316 self.assertEqual(security.DOMAIN_RID_USERS, base.primary_gid)
317 self.assertEqual(samdb.get_domain_sid(), str(base.domain_sid))
318 self.assertTrue(expected_flags & base.user_flags,
319 f'0x{expected_flags:x} unexpectedly reset in '
320 f'user_flags (0x{base.user_flags:x})')
322 # Check we have two groups in the base.
323 self.assertEqual(2, base.groups.count)
325 rids = base.groups.rids
327 # The first group should be Domain Users.
328 self.assertEqual(security.DOMAIN_RID_USERS, rids[0].rid)
329 self.assertEqual(self.default_attrs, rids[0].attributes)
331 # The second should be our universal group.
332 self.assertEqual(universal_rid, rids[1].rid)
333 self.assertEqual(self.default_attrs, rids[1].attributes)
335 # Check that we have one group in the SIDs array.
336 self.assertEqual(1, validation.sidcount)
338 sids = validation.sids
340 # That group should be our domain-local group.
341 self.assertEqual(domain_local_sid, str(sids[0].sid))
342 self.assertEqual(self.resource_attrs, sids[0].attributes)
344 # Check the groups in a SamInfo4 structure returned by SamLogon.
345 def test_samlogon_SamInfo4(self):
346 samdb = self.get_samdb()
348 # Create a universal and a domain-local group.
349 universal_dn = self.create_group(samdb,
350 self.get_new_username(),
351 gtype=GroupType.UNIVERSAL.value)
352 domain_local_dn = self.create_group(samdb,
353 self.get_new_username(),
354 gtype=GroupType.DOMAIN_LOCAL.value)
356 # Create a user account belonging to both groups.
357 creds = self.get_cached_creds(
358 account_type=self.AccountType.USER,
359 opts={
360 'member_of': (
361 universal_dn,
362 domain_local_dn,
364 'kerberos_enabled': False,
367 # Get the SID and RID of the user account.
368 user_sid = creds.get_sid()
369 user_rid = int(user_sid.rsplit('-', 1)[1])
371 # Get the SID and RID of the universal group.
372 universal_sid = self.get_objectSid(samdb, universal_dn)
373 universal_rid = int(universal_sid.rsplit('-', 1)[1])
375 # Get the SID of the domain-local group.
376 domain_local_sid = self.get_objectSid(samdb, domain_local_dn)
378 # We expect the EXTRA_SIDS flag to be set.
379 expected_flags = netlogon.NETLOGON_EXTRA_SIDS
381 # Do a SamLogon call and check we get back the right structure.
382 interactive = netlogon.NetlogonInteractiveInformation
383 level = netlogon.NetlogonValidationSamInfo4
384 validation = self._test_samlogon(creds=creds,
385 logon_type=interactive,
386 validation_level=level)
387 self.assertIsInstance(validation, netlogon.netr_SamInfo6)
389 base = validation.base
391 # Check some properties of the base structure.
392 self.assertEqual(user_rid, base.rid)
393 self.assertEqual(security.DOMAIN_RID_USERS, base.primary_gid)
394 self.assertEqual(samdb.get_domain_sid(), str(base.domain_sid))
395 self.assertTrue(expected_flags & base.user_flags,
396 f'0x{expected_flags:x} unexpectedly reset in '
397 f'user_flags (0x{base.user_flags:x})')
399 # Check we have two groups in the base.
400 self.assertEqual(2, base.groups.count)
402 rids = base.groups.rids
404 # The first group should be Domain Users.
405 self.assertEqual(security.DOMAIN_RID_USERS, rids[0].rid)
406 self.assertEqual(self.default_attrs, rids[0].attributes)
408 # The second should be our universal group.
409 self.assertEqual(universal_rid, rids[1].rid)
410 self.assertEqual(self.default_attrs, rids[1].attributes)
412 # Check that we have one group in the SIDs array.
413 self.assertEqual(1, validation.sidcount)
415 sids = validation.sids
417 # That group should be our domain-local group.
418 self.assertEqual(domain_local_sid, str(sids[0].sid))
419 self.assertEqual(self.resource_attrs, sids[0].attributes)
421 # A list of test cases.
422 cases = [
423 # AS-REQ tests.
425 'test': 'universal; as-req to krbtgt',
426 'groups': {
427 # A Universal group containing the user.
428 'foo': (GroupType.UNIVERSAL, {user}),
430 # Make an AS-REQ to the krbtgt with the user's account.
431 'as:to_krbtgt': True,
432 'as:expected': {
433 # Ignoring the user ID, or base RID, expect the PAC to contain
434 # precisely the following SIDS in any order:
435 ('foo', SidType.BASE_SID, default_attrs),
436 (asserted_identity, SidType.EXTRA_SID, default_attrs),
437 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
438 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
439 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
443 'test': 'universal; as-req to service',
444 'groups': {
445 'foo': (GroupType.UNIVERSAL, {user}),
447 # The same again, but this time perform the AS-REQ to a service.
448 'as:to_krbtgt': False,
449 'as:expected': {
450 ('foo', SidType.BASE_SID, default_attrs),
451 (asserted_identity, SidType.EXTRA_SID, default_attrs),
452 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
453 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
454 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
458 'test': 'global; as-req to krbtgt',
459 'groups': {
460 # The behaviour should be the same with a Global group.
461 'foo': (GroupType.GLOBAL, {user}),
463 'as:to_krbtgt': True,
464 'as:expected': {
465 ('foo', SidType.BASE_SID, default_attrs),
466 (asserted_identity, SidType.EXTRA_SID, default_attrs),
467 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
468 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
469 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
473 'test': 'global; as-req to service',
474 'groups': {
475 'foo': (GroupType.GLOBAL, {user}),
477 'as:to_krbtgt': False,
478 'as:expected': {
479 ('foo', SidType.BASE_SID, default_attrs),
480 (asserted_identity, SidType.EXTRA_SID, default_attrs),
481 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
482 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
483 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
487 'test': 'domain-local; as-req to krbtgt',
488 'groups': {
489 # A Domain-local group containing the user.
490 'foo': (GroupType.DOMAIN_LOCAL, {user}),
492 'as:to_krbtgt': True,
493 'as:expected': {
494 # A TGT will not contain domain-local groups the user belongs
495 # to.
496 (asserted_identity, SidType.EXTRA_SID, default_attrs),
497 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
498 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
499 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
503 'test': 'domain-local; compression; as-req to service',
504 'groups': {
505 'foo': (GroupType.DOMAIN_LOCAL, {user}),
507 'as:to_krbtgt': False,
508 'as:expected': {
509 # However, a service ticket will include domain-local
510 # groups. The account supports SID compression, so they are
511 # added as resource SIDs.
512 ('foo', SidType.RESOURCE_SID, resource_attrs),
513 (asserted_identity, SidType.EXTRA_SID, default_attrs),
514 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
515 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
516 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
520 'test': 'domain-local; no compression; as-req to service',
521 'groups': {
522 'foo': (GroupType.DOMAIN_LOCAL, {user}),
524 'as:to_krbtgt': False,
525 # This time, the target account disclaims support for SID
526 # compression.
527 'as:compression': False,
528 'as:expected': {
529 # The SIDs in the PAC are the same, except the group SID is
530 # placed in Extra SIDs, not Resource SIDs.
531 ('foo', SidType.EXTRA_SID, resource_attrs),
532 (asserted_identity, SidType.EXTRA_SID, default_attrs),
533 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
534 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
535 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
539 'test': 'nested domain-local; as-req to krbtgt',
540 'groups': {
541 # A Universal group containing a Domain-local group containing
542 # the user.
543 'universal': (GroupType.UNIVERSAL, {'dom-local'}),
544 'dom-local': (GroupType.DOMAIN_LOCAL, {user}),
546 # It is not possible in Windows for a Universal group to contain a
547 # Domain-local group without exploiting bugs. This flag provides a
548 # convenient means by which these tests can be skipped.
549 'configuration_invalid': True,
550 'as:to_krbtgt': True,
551 'as:expected': {
552 # While Windows would exclude the universal group from the PAC,
553 # expecting its inclusion is more sensible on the whole.
554 ('universal', SidType.BASE_SID, default_attrs),
555 (asserted_identity, SidType.EXTRA_SID, default_attrs),
556 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
557 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
558 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
562 'test': 'nested domain-local; compression; as-req to service',
563 'groups': {
564 'universal': (GroupType.UNIVERSAL, {'dom-local'}),
565 'dom-local': (GroupType.DOMAIN_LOCAL, {user}),
567 'configuration_invalid': True,
568 'as:to_krbtgt': False,
569 'as:expected': {
570 # A service ticket is expected to include both SIDs.
571 ('universal', SidType.BASE_SID, default_attrs),
572 ('dom-local', SidType.RESOURCE_SID, resource_attrs),
573 (asserted_identity, SidType.EXTRA_SID, default_attrs),
574 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
575 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
576 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
580 'test': 'nested domain-local; no compression; as-req to service',
581 'groups': {
582 'universal': (GroupType.UNIVERSAL, {'dom-local'}),
583 'dom-local': (GroupType.DOMAIN_LOCAL, {user}),
585 'configuration_invalid': True,
586 'as:to_krbtgt': False,
587 'as:compression': False,
588 'as:expected': {
589 # As before, but disclaiming SID compression support, so the
590 # domain-local SID goes in Extra SIDs.
591 ('universal', SidType.BASE_SID, default_attrs),
592 ('dom-local', SidType.EXTRA_SID, resource_attrs),
593 (asserted_identity, SidType.EXTRA_SID, default_attrs),
594 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
595 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
596 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
600 'test': 'nested universal; as-req to krbtgt',
601 'groups': {
602 # A similar scenario, except flipped around: a Domain-local
603 # group containing a Universal group containing the user.
604 'dom-local': (GroupType.DOMAIN_LOCAL, {'universal'}),
605 'universal': (GroupType.UNIVERSAL, {user}),
607 'as:to_krbtgt': True,
608 'as:expected': {
609 # Expect the Universal group's inclusion in the PAC.
610 ('universal', SidType.BASE_SID, default_attrs),
611 (asserted_identity, SidType.EXTRA_SID, default_attrs),
612 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
613 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
614 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
618 'test': 'nested universal; compression; as-req to service',
619 'groups': {
620 'dom-local': (GroupType.DOMAIN_LOCAL, {'universal'}),
621 'universal': (GroupType.UNIVERSAL, {user}),
623 'as:to_krbtgt': False,
624 'as:expected': {
625 # Expect a service ticket to contain both SIDs.
626 ('universal', SidType.BASE_SID, default_attrs),
627 ('dom-local', SidType.RESOURCE_SID, resource_attrs),
628 (asserted_identity, SidType.EXTRA_SID, default_attrs),
629 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
630 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
631 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
635 'test': 'nested universal; no compression; as-req to service',
636 'groups': {
637 'dom-local': (GroupType.DOMAIN_LOCAL, {'universal'}),
638 'universal': (GroupType.UNIVERSAL, {user}),
640 'as:to_krbtgt': False,
641 'as:compression': False,
642 'as:expected': {
643 # As before, but disclaiming SID compression support, so the
644 # domain-local SID goes in Extra SIDs.
645 ('universal', SidType.BASE_SID, default_attrs),
646 ('dom-local', SidType.EXTRA_SID, resource_attrs),
647 (asserted_identity, SidType.EXTRA_SID, default_attrs),
648 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
649 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
650 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
653 # TGS-REQ tests.
655 'test': 'tgs-req to krbtgt',
656 'groups': {
657 # A Universal group containing the user.
658 'foo': (GroupType.UNIVERSAL, {user}),
660 'as:to_krbtgt': True,
661 'as:expected': {
662 ('foo', SidType.BASE_SID, default_attrs),
663 (asserted_identity, SidType.EXTRA_SID, default_attrs),
664 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
665 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
666 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
668 # Make a TGS-REQ to the krbtgt with the user's account.
669 'tgs:to_krbtgt': True,
670 'tgs:expected': {
671 # Expect the same results as with an AS-REQ.
672 ('foo', SidType.BASE_SID, default_attrs),
673 (asserted_identity, SidType.EXTRA_SID, default_attrs),
674 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
675 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
676 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
680 'test': 'tgs-req to service',
681 'groups': {
682 # A Universal group containing the user.
683 'foo': (GroupType.UNIVERSAL, {user}),
685 'as:to_krbtgt': True,
686 'as:expected': {
687 ('foo', SidType.BASE_SID, default_attrs),
688 (asserted_identity, SidType.EXTRA_SID, default_attrs),
689 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
690 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
691 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
693 # Make a TGS-REQ to a service with the user's account.
694 'tgs:to_krbtgt': False,
695 'tgs:expected': {
696 ('foo', SidType.BASE_SID, default_attrs),
697 (asserted_identity, SidType.EXTRA_SID, default_attrs),
698 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
699 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
700 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
704 'test': 'domain-local; tgs-req to krbtgt',
705 'groups': {
706 # A Domain-local group containing the user.
707 'foo': (GroupType.UNIVERSAL, {user}),
709 'as:to_krbtgt': True,
710 'as:expected': {
711 ('foo', SidType.BASE_SID, default_attrs),
712 (asserted_identity, SidType.EXTRA_SID, default_attrs),
713 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
714 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
715 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
717 'tgs:to_krbtgt': True,
718 'tgs:expected': {
719 # Expect the same results as with an AS-REQ.
720 ('foo', SidType.BASE_SID, default_attrs),
721 (asserted_identity, SidType.EXTRA_SID, default_attrs),
722 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
723 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
724 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
728 'test': 'domain-local; compression; tgs-req to service',
729 'groups': {
730 # A Domain-local group containing the user.
731 'foo': (GroupType.DOMAIN_LOCAL, {user}),
733 'as:to_krbtgt': True,
734 'as:expected': {
735 # The Domain-local group is not present in the PAC after an
736 # AS-REQ.
737 (asserted_identity, SidType.EXTRA_SID, default_attrs),
738 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
739 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
740 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
742 'tgs:to_krbtgt': False,
743 'tgs:expected': {
744 # Now it's added as a resource SID after the TGS-REQ.
745 ('foo', SidType.RESOURCE_SID, resource_attrs),
746 (asserted_identity, SidType.EXTRA_SID, default_attrs),
747 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
748 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
749 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
753 'test': 'domain-local; no compression; tgs-req to service',
754 'groups': {
755 # A Domain-local group containing the user.
756 'foo': (GroupType.DOMAIN_LOCAL, {user}),
758 'as:to_krbtgt': True,
759 # This time, the target account disclaims support for SID
760 # compression.
761 'as:expected': {
762 (asserted_identity, SidType.EXTRA_SID, default_attrs),
763 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
764 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
765 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
767 'tgs:to_krbtgt': False,
768 'tgs:compression': False,
769 'tgs:expected': {
770 # The SIDs in the PAC are the same, except the group SID is
771 # placed in Extra SIDs, not Resource SIDs.
772 ('foo', SidType.EXTRA_SID, resource_attrs),
773 (asserted_identity, SidType.EXTRA_SID, default_attrs),
774 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
775 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
776 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
780 'test': 'exclude asserted identity; tgs-req to krbtgt',
781 'groups': {
782 'foo': (GroupType.UNIVERSAL, {user}),
784 'as:to_krbtgt': True,
785 'tgs:to_krbtgt': True,
786 'tgs:sids': {
787 # Remove the Asserted Identity SID from the PAC.
788 ('foo', SidType.BASE_SID, default_attrs),
789 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
790 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
792 'tgs:expected': {
793 # It should not be re-added in the TGS-REQ.
794 ('foo', SidType.BASE_SID, default_attrs),
795 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
796 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
797 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
801 'test': 'exclude asserted identity; tgs-req to service',
802 'groups': {
803 'foo': (GroupType.UNIVERSAL, {user}),
805 'as:to_krbtgt': True,
806 # Nor should it be re-added if the TGS-REQ is directed to a
807 # service.
808 'tgs:to_krbtgt': False,
809 'tgs:sids': {
810 ('foo', SidType.BASE_SID, default_attrs),
811 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
812 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
814 'tgs:expected': {
815 ('foo', SidType.BASE_SID, default_attrs),
816 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
817 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
818 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
822 'test': 'exclude claims valid; tgs-req to krbtgt',
823 'groups': {
824 'foo': (GroupType.UNIVERSAL, {user}),
826 'as:to_krbtgt': True,
827 'tgs:to_krbtgt': True,
828 'tgs:sids': {
829 # Remove the Claims Valid SID from the PAC.
830 ('foo', SidType.BASE_SID, default_attrs),
831 (asserted_identity, SidType.EXTRA_SID, default_attrs),
832 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
834 'tgs:expected': {
835 # It should not be re-added in the TGS-REQ.
836 ('foo', SidType.BASE_SID, default_attrs),
837 (asserted_identity, SidType.EXTRA_SID, default_attrs),
838 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
839 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
843 'test': 'exclude claims valid; tgs-req to service',
844 'groups': {
845 'foo': (GroupType.UNIVERSAL, {user}),
847 'as:to_krbtgt': True,
848 # Nor should it be re-added if the TGS-REQ is directed to a
849 # service.
850 'tgs:to_krbtgt': False,
851 'tgs:sids': {
852 ('foo', SidType.BASE_SID, default_attrs),
853 (asserted_identity, SidType.EXTRA_SID, default_attrs),
854 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
856 'tgs:expected': {
857 ('foo', SidType.BASE_SID, default_attrs),
858 (asserted_identity, SidType.EXTRA_SID, default_attrs),
859 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
860 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
864 'test': 'user group removal; tgs-req to krbtgt',
865 'groups': {
866 # The user has been removed from the group...
867 'foo': (GroupType.UNIVERSAL, {}),
869 'as:to_krbtgt': True,
870 'tgs:to_krbtgt': True,
871 'tgs:sids': {
872 # ...but the user's PAC still contains the group SID.
873 ('foo', SidType.BASE_SID, default_attrs),
874 (asserted_identity, SidType.EXTRA_SID, default_attrs),
875 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
876 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
878 'tgs:expected': {
879 # The group SID should not be removed when a TGS-REQ is
880 # performed.
881 ('foo', SidType.BASE_SID, default_attrs),
882 (asserted_identity, SidType.EXTRA_SID, default_attrs),
883 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
884 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
885 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
889 'test': 'user group removal; tgs-req to service',
890 'groups': {
891 'foo': (GroupType.UNIVERSAL, {}),
893 'as:to_krbtgt': True,
894 # Likewise, but to a service.
895 'tgs:to_krbtgt': False,
896 'tgs:sids': {
897 ('foo', SidType.BASE_SID, default_attrs),
898 (asserted_identity, SidType.EXTRA_SID, default_attrs),
899 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
900 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
902 'tgs:expected': {
903 ('foo', SidType.BASE_SID, default_attrs),
904 (asserted_identity, SidType.EXTRA_SID, default_attrs),
905 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
906 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
907 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
911 'test': 'nested group removal; tgs-req to krbtgt',
912 'groups': {
913 # A Domain-local group contains a Universal group, of which the
914 # user is no longer a member...
915 'dom-local': (GroupType.DOMAIN_LOCAL, {'universal'}),
916 'universal': (GroupType.UNIVERSAL, {}),
918 'as:to_krbtgt': True,
919 'tgs:to_krbtgt': True,
920 'tgs:sids': {
921 # ...but the user's PAC still contains the group SID.
922 ('universal', SidType.BASE_SID, default_attrs),
923 (asserted_identity, SidType.EXTRA_SID, default_attrs),
924 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
925 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
927 'tgs:expected': {
928 # The group SID should not be removed when a TGS-REQ is
929 # performed.
930 ('universal', SidType.BASE_SID, default_attrs),
931 (asserted_identity, SidType.EXTRA_SID, default_attrs),
932 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
933 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
934 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
938 'test': 'nested group removal; compression; tgs-req to service',
939 'groups': {
940 # A Domain-local group contains a Universal group, of which the
941 # user is no longer a member...
942 'dom-local': (GroupType.DOMAIN_LOCAL, {'universal'}),
943 'universal': (GroupType.UNIVERSAL, {}),
945 'as:to_krbtgt': True,
946 'tgs:to_krbtgt': False,
947 'tgs:sids': {
948 # ...but the user's PAC still contains the group SID.
949 ('universal', SidType.BASE_SID, default_attrs),
950 (asserted_identity, SidType.EXTRA_SID, default_attrs),
951 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
952 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
954 'tgs:expected': {
955 # Both SIDs should be present in the PAC when a TGS-REQ is
956 # performed.
957 ('universal', SidType.BASE_SID, default_attrs),
958 ('dom-local', SidType.RESOURCE_SID, resource_attrs),
959 (asserted_identity, SidType.EXTRA_SID, default_attrs),
960 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
961 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
962 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
966 'test': 'nested group removal; no compression; tgs-req to service',
967 'groups': {
968 'dom-local': (GroupType.DOMAIN_LOCAL, {'universal'}),
969 'universal': (GroupType.UNIVERSAL, {}),
971 'as:to_krbtgt': True,
972 'tgs:to_krbtgt': False,
973 # The same again, but with the server not supporting compression.
974 'tgs:compression': False,
975 'tgs:sids': {
976 ('universal', SidType.BASE_SID, default_attrs),
977 (asserted_identity, SidType.EXTRA_SID, default_attrs),
978 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
979 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
981 'tgs:expected': {
982 # The domain-local SID will go into Extra SIDs.
983 ('universal', SidType.BASE_SID, default_attrs),
984 ('dom-local', SidType.EXTRA_SID, resource_attrs),
985 (asserted_identity, SidType.EXTRA_SID, default_attrs),
986 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
987 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
988 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
992 'test': 'user group addition; tgs-req to krbtgt',
993 'groups': {
994 # The user is a member of the group...
995 'foo': (GroupType.UNIVERSAL, {user}),
997 'as:to_krbtgt': True,
998 'tgs:to_krbtgt': True,
999 'tgs:sids': {
1000 # ...but the user's PAC still lacks the group SID.
1001 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1002 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1003 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
1005 'tgs:expected': {
1006 # The group SID should be omitted when a TGS-REQ is
1007 # performed.
1008 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1009 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1010 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
1011 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
1015 'test': 'user group addition; tgs-req to service',
1016 'groups': {
1017 'foo': (GroupType.UNIVERSAL, {user}),
1019 'as:to_krbtgt': True,
1020 # Likewise, but to a service.
1021 'tgs:to_krbtgt': False,
1022 'tgs:sids': {
1023 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1024 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1025 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
1027 'tgs:expected': {
1028 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1029 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1030 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
1031 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
1035 'test': 'nested group addition; tgs-req to krbtgt',
1036 'groups': {
1037 # A Domain-local group contains a Universal group, of which the
1038 # user is now a member...
1039 'dom-local': (GroupType.DOMAIN_LOCAL, {'universal'}),
1040 'universal': (GroupType.UNIVERSAL, {user}),
1042 'as:to_krbtgt': True,
1043 'tgs:to_krbtgt': True,
1044 'tgs:sids': {
1045 # ...but the user's PAC still lacks the group SID.
1046 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1047 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1048 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
1050 'tgs:expected': {
1051 # The group SID should still be missing when a TGS-REQ is
1052 # performed.
1053 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1054 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1055 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
1056 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
1060 'test': 'nested group addition; compression; tgs-req to service',
1061 'groups': {
1062 # A Domain-local group contains a Universal group, of which the
1063 # user is now a member...
1064 'dom-local': (GroupType.DOMAIN_LOCAL, {'universal'}),
1065 'universal': (GroupType.UNIVERSAL, {user}),
1067 'as:to_krbtgt': True,
1068 'tgs:to_krbtgt': False,
1069 'tgs:sids': {
1070 # ...but the user's PAC still lacks the group SID.
1071 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1072 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1073 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
1075 'tgs:expected': {
1076 # Both SIDs should be omitted from the PAC when a TGS-REQ is
1077 # performed.
1078 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1079 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1080 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
1081 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
1085 'test': 'nested group addition; no compression; tgs-req to service',
1086 'groups': {
1087 'dom-local': (GroupType.DOMAIN_LOCAL, {'universal'}),
1088 'universal': (GroupType.UNIVERSAL, {user}),
1090 'as:to_krbtgt': True,
1091 'tgs:to_krbtgt': False,
1092 # The same again, but with the server not supporting compression.
1093 'tgs:compression': False,
1094 'tgs:sids': {
1095 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1096 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1097 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
1099 'tgs:expected': {
1100 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1101 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1102 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
1103 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
1107 'test': 'resource sids given; tgs-req to krbtgt',
1108 'groups': {
1109 # A couple of independent domain-local groups.
1110 'dom-local-0': (GroupType.DOMAIN_LOCAL, {}),
1111 'dom-local-1': (GroupType.DOMAIN_LOCAL, {}),
1113 'as:to_krbtgt': True,
1114 'tgs:to_krbtgt': True,
1115 'tgs:sids': {
1116 # The TGT contains two resource SIDs for the domain-local
1117 # groups.
1118 ('dom-local-0', SidType.RESOURCE_SID, resource_attrs),
1119 ('dom-local-1', SidType.RESOURCE_SID, default_attrs),
1120 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1121 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1122 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
1124 'tgs:expected': {
1125 # The resource SIDs remain after performing a TGS-REQ to the
1126 # krbtgt.
1127 ('dom-local-0', SidType.RESOURCE_SID, resource_attrs),
1128 ('dom-local-1', SidType.RESOURCE_SID, default_attrs),
1129 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1130 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1131 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
1132 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
1136 'test': 'resource sids wrongly given; tgs-req to krbtgt',
1137 'groups': {
1138 'dom-local-0': (GroupType.DOMAIN_LOCAL, {}),
1139 'dom-local-1': (GroupType.DOMAIN_LOCAL, {}),
1141 'as:to_krbtgt': True,
1142 'tgs:to_krbtgt': True,
1143 # Though we have provided resource SIDs, we have reset the flag
1144 # indicating that they are present.
1145 'tgs:reset_user_flags': netlogon.NETLOGON_RESOURCE_GROUPS,
1146 'tgs:sids': {
1147 ('dom-local-0', SidType.RESOURCE_SID, resource_attrs),
1148 ('dom-local-1', SidType.RESOURCE_SID, default_attrs),
1149 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1150 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1151 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
1153 'tgs:expected': {
1154 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1155 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1156 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
1157 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
1158 # The resource SIDs remain in the PAC.
1159 ('dom-local-0', SidType.RESOURCE_SID, resource_attrs),
1160 ('dom-local-1', SidType.RESOURCE_SID, default_attrs),
1164 'test': 'resource sids claimed given; tgs-req to krbtgt',
1165 'groups': {
1167 'as:to_krbtgt': True,
1168 'tgs:to_krbtgt': True,
1169 # Though we claim to have provided resource SIDs, we have not
1170 # actually done so.
1171 'tgs:set_user_flags': netlogon.NETLOGON_RESOURCE_GROUPS,
1172 'tgs:sids': {
1173 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1174 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1175 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
1177 'tgs:expected': {
1178 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1179 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1180 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
1181 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
1185 'test': 'resource sids given; compression; tgs-req to service',
1186 'groups': {
1187 'dom-local-0': (GroupType.DOMAIN_LOCAL, {}),
1188 'dom-local-1': (GroupType.DOMAIN_LOCAL, {}),
1190 'as:to_krbtgt': True,
1191 'tgs:to_krbtgt': False,
1192 'tgs:sids': {
1193 ('dom-local-0', SidType.RESOURCE_SID, resource_attrs),
1194 ('dom-local-1', SidType.RESOURCE_SID, default_attrs),
1195 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1196 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1197 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
1199 'tgs:expected': {
1200 # The resource SIDs are removed upon issuing a service ticket.
1201 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1202 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1203 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
1204 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
1208 'test': 'resource sids given; no compression; tgs-req to service',
1209 'groups': {
1210 'dom-local-0': (GroupType.DOMAIN_LOCAL, {}),
1211 'dom-local-1': (GroupType.DOMAIN_LOCAL, {}),
1213 'as:to_krbtgt': True,
1214 'tgs:to_krbtgt': False,
1215 # Compression is disabled on the service account.
1216 'tgs:compression': False,
1217 'tgs:sids': {
1218 ('dom-local-0', SidType.RESOURCE_SID, resource_attrs),
1219 ('dom-local-1', SidType.RESOURCE_SID, default_attrs),
1220 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1221 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1222 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
1224 'tgs:expected': {
1225 # The resource SIDs are again removed.
1226 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1227 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1228 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
1229 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
1232 # Testing operability with older Samba versions.
1234 'test': 'domain-local; Samba 4.17; tgs-req to krbtgt',
1235 'groups': {
1236 'foo': (GroupType.DOMAIN_LOCAL, {user}),
1238 'as:to_krbtgt': True,
1239 'tgs:to_krbtgt': True,
1240 'tgs:sids': {
1241 # In Samba 4.17, domain-local groups are contained within the
1242 # TGT, and do not have the SE_GROUP_RESOURCE bit set.
1243 ('foo', SidType.BASE_SID, default_attrs),
1244 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1245 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1247 'tgs:expected': {
1248 # After the TGS-REQ, the domain-local group remains in the PAC
1249 # with its original attributes.
1250 ('foo', SidType.BASE_SID, default_attrs),
1251 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1252 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1253 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
1257 'test': 'domain-local; Samba 4.17; compression; tgs-req to service',
1258 'groups': {
1259 'foo': (GroupType.DOMAIN_LOCAL, {user}),
1261 'as:to_krbtgt': True,
1262 # The same scenario, but requesting a service ticket.
1263 'tgs:to_krbtgt': False,
1264 'tgs:compression': True,
1265 'tgs:sids': {
1266 ('foo', SidType.BASE_SID, default_attrs),
1267 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1268 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1270 'tgs:expected': {
1271 # The domain-local group remains in the PAC...
1272 ('foo', SidType.BASE_SID, default_attrs),
1273 # and another copy is added in Resource SIDs. This one has the
1274 # SE_GROUP_RESOURCE bit set.
1275 ('foo', SidType.RESOURCE_SID, resource_attrs),
1276 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1277 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1278 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
1282 'test': 'domain-local; Samba 4.17; no compression; tgs-req to service',
1283 'groups': {
1284 'foo': (GroupType.DOMAIN_LOCAL, {user}),
1286 'as:to_krbtgt': True,
1287 'tgs:to_krbtgt': False,
1288 # In this case compression is disabled on the service.
1289 'tgs:compression': False,
1290 'tgs:sids': {
1291 ('foo', SidType.BASE_SID, default_attrs),
1292 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1293 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1295 'tgs:expected': {
1296 ('foo', SidType.BASE_SID, default_attrs),
1297 # Without compression, the extra SID appears in Extra SIDs.
1298 ('foo', SidType.EXTRA_SID, resource_attrs),
1299 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1300 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1301 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
1304 # Simulate a ticket coming in over a trust.
1306 'test': 'from trust; to krbtgt',
1307 'groups': {
1308 # The user belongs to a couple of domain-local groups in our
1309 # domain.
1310 'foo': (GroupType.DOMAIN_LOCAL, {trust_user}),
1311 'bar': (GroupType.DOMAIN_LOCAL, {'foo'}),
1313 'as:to_krbtgt': True,
1314 'tgs:to_krbtgt': True,
1315 # The user SID is from a different domain.
1316 'tgs:user_sid': trust_user,
1317 'tgs:sids': {
1318 (trust_user, SidType.BASE_SID, default_attrs),
1319 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1320 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1321 # This dummy resource SID comes from the trusted domain.
1322 (f'{trust_domain}-333', SidType.RESOURCE_SID, resource_attrs),
1324 'tgs:expected': {
1325 # After performing a TGS-REQ to the krbtgt, the PAC remains
1326 # unchanged.
1327 (trust_user, SidType.BASE_SID, default_attrs),
1328 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1329 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1330 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
1331 (f'{trust_domain}-333', SidType.RESOURCE_SID, resource_attrs),
1335 'test': 'from trust; compression; to service',
1336 'groups': {
1337 'foo': (GroupType.DOMAIN_LOCAL, {trust_user}),
1338 'bar': (GroupType.DOMAIN_LOCAL, {'foo'}),
1340 'as:to_krbtgt': True,
1341 # The same thing, but to a service.
1342 'tgs:to_krbtgt': False,
1343 'tgs:compression': True,
1344 'tgs:user_sid': trust_user,
1345 'tgs:sids': {
1346 (trust_user, SidType.BASE_SID, default_attrs),
1347 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1348 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1349 (f'{trust_domain}-333', SidType.RESOURCE_SID, resource_attrs),
1351 'tgs:expected': {
1352 (trust_user, SidType.BASE_SID, default_attrs),
1353 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1354 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1355 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
1356 # The resource SIDs are added to the PAC.
1357 ('foo', SidType.RESOURCE_SID, resource_attrs),
1358 ('bar', SidType.RESOURCE_SID, resource_attrs),
1361 # Simulate a ticket coming in over a trust
1363 'test': 'from trust; no compression; to service',
1364 'groups': {
1365 'foo': (GroupType.DOMAIN_LOCAL, {trust_user}),
1366 'bar': (GroupType.DOMAIN_LOCAL, {'foo'}),
1368 'as:to_krbtgt': True,
1369 'tgs:to_krbtgt': False,
1370 # And again, but this time compression is disabled.
1371 'tgs:compression': False,
1372 'tgs:user_sid': trust_user,
1373 'tgs:sids': {
1374 (trust_user, SidType.BASE_SID, default_attrs),
1375 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1376 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1377 (f'{trust_domain}-333', SidType.RESOURCE_SID, resource_attrs),
1379 'tgs:expected': {
1380 (trust_user, SidType.BASE_SID, default_attrs),
1381 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1382 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1383 (security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
1384 # The resource SIDs are added again, but this time to Extra
1385 # SIDs.
1386 ('foo', SidType.EXTRA_SID, resource_attrs),
1387 ('bar', SidType.EXTRA_SID, resource_attrs),
1390 # Test a group being the primary one for the user.
1392 'test': 'primary universal; as-req to krbtgt',
1393 'groups': {
1394 'foo': (GroupType.UNIVERSAL, {user}),
1396 # Set this group as our primary group.
1397 'primary_group': 'foo',
1398 'as:to_krbtgt': True,
1399 'as:expected': {
1400 # It appears in the PAC as normal.
1401 ('foo', SidType.BASE_SID, default_attrs),
1402 ('foo', SidType.PRIMARY_GID, None),
1403 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1404 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1405 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
1409 'test': 'primary universal; as-req to service',
1410 'groups': {
1411 'foo': (GroupType.UNIVERSAL, {user}),
1413 # Set this group as our primary group.
1414 'primary_group': 'foo',
1415 # The request is made to a service.
1416 'as:to_krbtgt': False,
1417 'as:expected': {
1418 # The group appears in the PAC as normal.
1419 ('foo', SidType.BASE_SID, default_attrs),
1420 ('foo', SidType.PRIMARY_GID, None),
1421 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1422 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1423 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
1426 # Test domain-local primary groups.
1428 'test': 'primary domain-local; as-req to krbtgt',
1429 'groups': {
1430 'foo': (GroupType.DOMAIN_LOCAL, {user}),
1432 # Though Windows normally disallows setting a domain-local group as
1433 # a primary group, Samba does not.
1434 'primary_group': 'foo',
1435 'as:to_krbtgt': True,
1436 'as:expected': {
1437 # The domain-local group appears as our primary GID, but does
1438 # not appear in the base SIDs.
1439 ('foo', SidType.PRIMARY_GID, None),
1440 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1441 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1442 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
1446 'test': 'primary domain-local; compression; as-req to service',
1447 'groups': {
1448 'foo': (GroupType.DOMAIN_LOCAL, {user}),
1450 'primary_group': 'foo',
1451 # The same test, but the request is made to a service.
1452 'as:to_krbtgt': False,
1453 'as:expected': {
1454 # The domain-local still only appears as our primary GID.
1455 ('foo', SidType.PRIMARY_GID, None),
1456 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1457 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1458 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
1462 'test': 'primary domain-local; no compression; as-req to service',
1463 'groups': {
1464 'foo': (GroupType.DOMAIN_LOCAL, {user}),
1466 'primary_group': 'foo',
1467 'as:to_krbtgt': False,
1468 # This time, the target account disclaims support for SID
1469 # compression.
1470 'as:compression': False,
1471 'as:expected': {
1472 ('foo', SidType.PRIMARY_GID, None),
1473 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1474 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1475 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
1479 'test': 'primary domain-local; tgs-req to krbtgt',
1480 'groups': {
1481 'foo': (GroupType.DOMAIN_LOCAL, {user}),
1483 # Though Windows normally disallows setting a domain-local group as
1484 # a primary group, Samba does not.
1485 'primary_group': 'foo',
1486 'as:to_krbtgt': True,
1487 'as:expected': {
1488 # The domain-local group appears as our primary GID, but does
1489 # not appear in the base SIDs.
1490 ('foo', SidType.PRIMARY_GID, None),
1491 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1492 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1493 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
1495 'tgs:to_krbtgt': True,
1496 'tgs:expected': {
1497 # The domain-local group does not appear in the base SIDs.
1498 ('foo', SidType.PRIMARY_GID, None),
1499 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1500 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1501 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
1505 'test': 'primary domain-local; compression; tgs-req to service',
1506 'groups': {
1507 'foo': (GroupType.DOMAIN_LOCAL, {user}),
1509 # Though Windows normally disallows setting a domain-local group as
1510 # a primary group, Samba does not.
1511 'primary_group': 'foo',
1512 'as:to_krbtgt': True,
1513 'as:expected': {
1514 # The domain-local group appears as our primary GID, but does
1515 # not appear in the base SIDs.
1516 ('foo', SidType.PRIMARY_GID, None),
1517 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1518 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1519 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
1521 # The service is made to a service.
1522 'tgs:to_krbtgt': False,
1523 'tgs:expected': {
1524 # The domain-local still only appears as our primary GID.
1525 ('foo', SidType.PRIMARY_GID, None),
1526 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1527 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1528 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
1532 'test': 'primary domain-local; no compression; tgs-req to service',
1533 'groups': {
1534 'foo': (GroupType.DOMAIN_LOCAL, {user}),
1536 # Though Windows normally disallows setting a domain-local group as
1537 # a primary group, Samba does not.
1538 'primary_group': 'foo',
1539 'as:to_krbtgt': True,
1540 'as:expected': {
1541 # The domain-local group appears as our primary GID, but does
1542 # not appear in the base SIDs.
1543 ('foo', SidType.PRIMARY_GID, None),
1544 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1545 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1546 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
1548 'tgs:to_krbtgt': False,
1549 # The service does not support compression.
1550 'tgs:compression': False,
1551 'tgs:expected': {
1552 ('foo', SidType.PRIMARY_GID, None),
1553 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1554 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1555 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
1558 # Test the scenario where we belong to a now-domain-local group, and
1559 # possess an old TGT issued when the group was still our primary one.
1561 'test': 'old primary domain-local; tgs-req to krbtgt',
1562 'groups': {
1563 # A domain-local group to which we belong.
1564 'foo': (GroupType.DOMAIN_LOCAL, {user}),
1566 'as:to_krbtgt': True,
1567 'tgs:to_krbtgt': True,
1568 'tgs:sids': {
1569 # In the PAC, the group has the attributes of an ordinary
1570 # group...
1571 ('foo', SidType.BASE_SID, default_attrs),
1572 # ...and remains our primary one.
1573 ('foo', SidType.PRIMARY_GID, None),
1574 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1575 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1576 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
1578 'tgs:expected': {
1579 # The groups don't change.
1580 ('foo', SidType.BASE_SID, default_attrs),
1581 ('foo', SidType.PRIMARY_GID, None),
1582 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1583 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1584 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
1588 'test': 'old primary domain-local; compression; tgs-req to service',
1589 'groups': {
1590 'foo': (GroupType.DOMAIN_LOCAL, {user}),
1592 'as:to_krbtgt': True,
1593 # The TGS request is made to a service.
1594 'tgs:to_krbtgt': False,
1595 'tgs:sids': {
1596 ('foo', SidType.BASE_SID, default_attrs),
1597 ('foo', SidType.PRIMARY_GID, None),
1598 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1599 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1600 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
1602 'tgs:expected': {
1603 ('foo', SidType.BASE_SID, default_attrs),
1604 ('foo', SidType.PRIMARY_GID, None),
1605 # The group is added a second time to the PAC, now as a
1606 # resource group.
1607 ('foo', SidType.RESOURCE_SID, resource_attrs),
1608 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1609 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1610 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
1614 'test': 'old primary domain-local; no compression; tgs-req to service',
1615 'groups': {
1616 'foo': (GroupType.DOMAIN_LOCAL, {user}),
1618 'as:to_krbtgt': True,
1619 'tgs:to_krbtgt': False,
1620 # The target service doesn't support SID compression.
1621 'tgs:compression': False,
1622 'tgs:sids': {
1623 ('foo', SidType.BASE_SID, default_attrs),
1624 ('foo', SidType.PRIMARY_GID, None),
1625 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1626 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1627 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
1629 'tgs:expected': {
1630 ('foo', SidType.BASE_SID, default_attrs),
1631 ('foo', SidType.PRIMARY_GID, None),
1632 # This time, the group is added to Extra SIDs.
1633 ('foo', SidType.EXTRA_SID, resource_attrs),
1634 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1635 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1636 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
1639 # Test the scenario where we possess an old TGT issued when a
1640 # now-domain-local group was still our primary one. We no longer belong
1641 # to that group, which itself belongs to another domain-local group.
1643 'test': 'old primary domain-local; transitive; tgs-req to krbtgt',
1644 'groups': {
1645 'bar': (GroupType.DOMAIN_LOCAL, {'foo'}),
1646 'foo': (GroupType.DOMAIN_LOCAL, {}),
1648 'as:to_krbtgt': True,
1649 'tgs:to_krbtgt': True,
1650 'tgs:sids': {
1651 # In the PAC, the group has the attributes of an ordinary
1652 # group...
1653 ('foo', SidType.BASE_SID, default_attrs),
1654 # ...and remains our primary one.
1655 ('foo', SidType.PRIMARY_GID, None),
1656 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1657 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1658 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
1660 'tgs:expected': {
1661 # The groups don't change.
1662 ('foo', SidType.BASE_SID, default_attrs),
1663 ('foo', SidType.PRIMARY_GID, None),
1664 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1665 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1666 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
1670 'test': 'old primary domain-local; transitive; compression; tgs-req to service',
1671 'groups': {
1672 'bar': (GroupType.DOMAIN_LOCAL, {'foo'}),
1673 'foo': (GroupType.DOMAIN_LOCAL, {}),
1675 'as:to_krbtgt': True,
1676 # The TGS request is made to a service.
1677 'tgs:to_krbtgt': False,
1678 'tgs:sids': {
1679 ('foo', SidType.BASE_SID, default_attrs),
1680 ('foo', SidType.PRIMARY_GID, None),
1681 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1682 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1683 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
1685 'tgs:expected': {
1686 ('foo', SidType.BASE_SID, default_attrs),
1687 ('foo', SidType.PRIMARY_GID, None),
1688 # The second resource group is added to the PAC as a resource
1689 # group.
1690 ('bar', SidType.RESOURCE_SID, resource_attrs),
1691 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1692 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1693 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
1697 'test': 'old primary domain-local; transitive; no compression; tgs-req to service',
1698 'groups': {
1699 'bar': (GroupType.DOMAIN_LOCAL, {'foo'}),
1700 'foo': (GroupType.DOMAIN_LOCAL, {}),
1702 'as:to_krbtgt': True,
1703 'tgs:to_krbtgt': False,
1704 # The target service doesn't support SID compression.
1705 'tgs:compression': False,
1706 'tgs:sids': {
1707 ('foo', SidType.BASE_SID, default_attrs),
1708 ('foo', SidType.PRIMARY_GID, None),
1709 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1710 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1711 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
1713 'tgs:expected': {
1714 ('foo', SidType.BASE_SID, default_attrs),
1715 ('foo', SidType.PRIMARY_GID, None),
1716 # This time, the group is added to Extra SIDs.
1717 ('bar', SidType.EXTRA_SID, resource_attrs),
1718 (asserted_identity, SidType.EXTRA_SID, default_attrs),
1719 (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
1720 (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
1725 # This is the main function to handle a single testcase.
1726 def _test_group_with_args(self, case):
1727 # The group arrangement for the test.
1728 group_setup = case.pop('groups')
1730 # A group that should be the primary group for the user.
1731 primary_group = case.pop('primary_group', None)
1733 # Whether the AS-REQ or TGS-REQ should be directed to the krbtgt.
1734 as_to_krbtgt = case.pop('as:to_krbtgt')
1735 tgs_to_krbtgt = case.pop('tgs:to_krbtgt', None)
1737 # Whether the target server of the AS-REQ or TGS-REQ should support
1738 # resource SID compression.
1739 as_compression = case.pop('as:compression', None)
1740 tgs_compression = case.pop('tgs:compression', None)
1742 # Optional SIDs to replace those in the PAC prior to a TGS-REQ.
1743 tgs_sids = case.pop('tgs:sids', None)
1745 # Optional user SID to replace that in the PAC prior to a TGS-REQ.
1746 tgs_user_sid = case.pop('tgs:user_sid', None)
1748 # User flags that may be set or reset in the PAC prior to a TGS-REQ.
1749 tgs_set_user_flags = case.pop('tgs:set_user_flags', None)
1750 tgs_reset_user_flags = case.pop('tgs:reset_user_flags', None)
1752 # The SIDs we expect to see in the PAC after a AS-REQ or a TGS-REQ.
1753 as_expected = case.pop('as:expected', None)
1754 tgs_expected = case.pop('tgs:expected', None)
1756 # There should be no parameters remaining in the testcase.
1757 self.assertFalse(case, 'unexpected parameters in testcase')
1759 if as_expected is None:
1760 self.assertIsNotNone(tgs_expected,
1761 'no set of expected SIDs is provided')
1763 if as_to_krbtgt is None:
1764 as_to_krbtgt = False
1766 if not as_to_krbtgt:
1767 self.assertIsNone(tgs_expected,
1768 "if we're performing a TGS-REQ, then AS-REQ "
1769 "should be directed to the krbtgt")
1771 if tgs_to_krbtgt is None:
1772 tgs_to_krbtgt = False
1773 else:
1774 self.assertIsNotNone(tgs_expected,
1775 'specified TGS request to krbtgt, but no '
1776 'expected SIDs provided')
1778 if tgs_compression is not None:
1779 self.assertIsNotNone(tgs_expected,
1780 'specified compression for TGS request, but '
1781 'no expected SIDs provided')
1783 if tgs_user_sid is not None:
1784 self.assertIsNotNone(tgs_sids,
1785 'specified TGS-REQ user SID, but no '
1786 'accompanying SIDs provided')
1788 if tgs_set_user_flags is None:
1789 tgs_set_user_flags = 0
1790 else:
1791 self.assertIsNotNone(tgs_sids,
1792 'specified TGS-REQ set user flags, but no '
1793 'accompanying SIDs provided')
1795 if tgs_reset_user_flags is None:
1796 tgs_reset_user_flags = 0
1797 else:
1798 self.assertIsNotNone(tgs_sids,
1799 'specified TGS-REQ reset user flags, but no '
1800 'accompanying SIDs provided')
1802 samdb = self.get_samdb()
1804 domain_sid = samdb.get_domain_sid()
1806 # Create the user account. It needs to be freshly created rather than
1807 # cached because we will probably add it to one or more groups.
1808 user_creds = self.get_cached_creds(
1809 account_type=self.AccountType.USER,
1810 use_cache=False)
1811 user_dn = user_creds.get_dn()
1812 user_sid = user_creds.get_sid()
1813 user_name = user_creds.get_username()
1814 salt = user_creds.get_salt()
1816 trust_user_rid = random.randint(2000, 0xfffffffe)
1817 trust_user_sid = f'{self.trust_domain}-{trust_user_rid}'
1819 cname = self.PrincipalName_create(name_type=NT_PRINCIPAL,
1820 names=user_name.split('/'))
1822 preauth_key = self.PasswordKey_from_creds(user_creds,
1823 kcrypto.Enctype.AES256)
1825 ts_enc_padata = self.get_enc_timestamp_pa_data_from_key(preauth_key)
1826 padata = [ts_enc_padata]
1828 target_creds, sname = self.get_target(as_to_krbtgt,
1829 compression=as_compression)
1830 decryption_key = self.TicketDecryptionKey_from_creds(target_creds)
1832 target_supported_etypes = target_creds.tgs_supported_enctypes
1833 realm = target_creds.get_realm()
1835 # Initialise the group mapping with the user and trust principals.
1836 user_principal = Principal(user_dn, user_sid)
1837 trust_principal = Principal(None, trust_user_sid)
1838 preexisting_groups = {
1839 self.user: user_principal,
1840 self.trust_user: trust_principal,
1842 if primary_group is not None:
1843 primary_groups = {
1844 user_principal: primary_group,
1846 else:
1847 primary_groups = None
1848 groups = self.setup_groups(samdb,
1849 preexisting_groups,
1850 group_setup,
1851 primary_groups)
1852 del group_setup
1854 if tgs_user_sid is None:
1855 tgs_user_sid = user_sid
1856 elif tgs_user_sid in groups:
1857 tgs_user_sid = groups[tgs_user_sid].sid
1859 tgs_domain_sid, tgs_user_rid = tgs_user_sid.rsplit('-', 1)
1861 expected_groups = self.map_sids(as_expected, groups,
1862 domain_sid)
1863 tgs_sids_mapped = self.map_sids(tgs_sids, groups,
1864 tgs_domain_sid)
1865 tgs_expected_mapped = self.map_sids(tgs_expected, groups,
1866 tgs_domain_sid)
1868 till = self.get_KerberosTime(offset=36000)
1869 kdc_options = '0'
1871 etypes = self.get_default_enctypes(user_creds)
1873 # Perform an AS-REQ with the user account.
1874 as_rep, kdc_exchange_dict = self._test_as_exchange(
1875 creds=user_creds,
1876 cname=cname,
1877 realm=realm,
1878 sname=sname,
1879 till=till,
1880 expected_error_mode=0,
1881 expected_crealm=realm,
1882 expected_cname=cname,
1883 expected_srealm=realm,
1884 expected_sname=sname,
1885 expected_salt=salt,
1886 etypes=etypes,
1887 padata=padata,
1888 kdc_options=kdc_options,
1889 expected_account_name=user_name,
1890 expected_groups=expected_groups,
1891 expected_sid=user_sid,
1892 expected_domain_sid=domain_sid,
1893 expected_supported_etypes=target_supported_etypes,
1894 preauth_key=preauth_key,
1895 ticket_decryption_key=decryption_key)
1896 self.check_as_reply(as_rep)
1898 ticket = kdc_exchange_dict['rep_ticket_creds']
1900 if tgs_expected is None:
1901 # We're not performing a TGS-REQ, so we're done.
1902 self.assertIsNone(tgs_sids,
1903 'provided SIDs to populate PAC for TGS-REQ, but '
1904 'failed to specify expected SIDs')
1905 return
1907 if tgs_sids is not None:
1908 # Replace the SIDs in the PAC with the ones provided by the test.
1909 ticket = self.ticket_with_sids(ticket,
1910 tgs_sids_mapped,
1911 tgs_domain_sid,
1912 tgs_user_rid,
1913 set_user_flags=tgs_set_user_flags,
1914 reset_user_flags=tgs_reset_user_flags)
1916 target_creds, sname = self.get_target(tgs_to_krbtgt,
1917 compression=tgs_compression)
1918 decryption_key = self.TicketDecryptionKey_from_creds(target_creds)
1920 subkey = self.RandomKey(ticket.session_key.etype)
1922 requester_sid = None
1923 if tgs_to_krbtgt:
1924 requester_sid = user_sid
1926 expect_resource_groups_flag = None
1927 if tgs_reset_user_flags & netlogon.NETLOGON_RESOURCE_GROUPS:
1928 expect_resource_groups_flag = False
1929 elif tgs_set_user_flags & netlogon.NETLOGON_RESOURCE_GROUPS:
1930 expect_resource_groups_flag = True
1932 # Perform a TGS-REQ with the user account.
1934 kdc_exchange_dict = self.tgs_exchange_dict(
1935 creds=user_creds,
1936 expected_crealm=ticket.crealm,
1937 expected_cname=cname,
1938 expected_srealm=realm,
1939 expected_sname=sname,
1940 expected_account_name=user_name,
1941 expected_groups=tgs_expected_mapped,
1942 expected_sid=tgs_user_sid,
1943 expected_requester_sid=requester_sid,
1944 expected_domain_sid=tgs_domain_sid,
1945 expected_supported_etypes=target_supported_etypes,
1946 expect_resource_groups_flag=expect_resource_groups_flag,
1947 ticket_decryption_key=decryption_key,
1948 check_rep_fn=self.generic_check_kdc_rep,
1949 check_kdc_private_fn=self.generic_check_kdc_private,
1950 tgt=ticket,
1951 authenticator_subkey=subkey,
1952 kdc_options=kdc_options)
1954 rep = self._generic_kdc_exchange(kdc_exchange_dict,
1955 cname=None,
1956 realm=realm,
1957 sname=sname,
1958 till_time=till,
1959 etypes=etypes)
1960 self.check_reply(rep, KRB_TGS_REP)
1963 if __name__ == '__main__':
1964 global_asn1_print = False
1965 global_hexdump = False
1966 import unittest
1967 unittest.main()