1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-01 05:47:28 +03:00
samba-mirror/python/samba/tests/krb5/device_tests.py
Joseph Sutton 3ef68efca2 tests/krb5: Fix comments
Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>

Autobuild-User(master): Andrew Bartlett <abartlet@samba.org>
Autobuild-Date(master): Thu Nov  2 20:13:50 UTC 2023 on atb-devel-224
2023-11-02 20:13:50 +00:00

2212 lines
111 KiB
Python
Executable File

#!/usr/bin/env python3
# Unix SMB/CIFS implementation.
# Copyright (C) Stefan Metzmacher 2020
# Copyright (C) Catalyst.Net Ltd 2022
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
import sys
import os
sys.path.insert(0, 'bin/python')
os.environ['PYTHONUNBUFFERED'] = '1'
import random
import re
from samba.dcerpc import netlogon, security
from samba.tests import DynamicTestCase, env_get_var_value
from samba.tests.krb5 import kcrypto
from samba.tests.krb5.kdc_base_test import GroupType, KDCBaseTest, Principal
from samba.tests.krb5.raw_testcase import Krb5EncryptionKey, RawKerberosTest
from samba.tests.krb5.rfc4120_constants import (
AES256_CTS_HMAC_SHA1_96,
ARCFOUR_HMAC_MD5,
KRB_TGS_REP,
)
SidType = RawKerberosTest.SidType
global_asn1_print = False
global_hexdump = False
@DynamicTestCase
class DeviceTests(KDCBaseTest):
# Placeholder objects that represent accounts undergoing testing.
user = object()
mach = object()
trust_user = object()
trust_mach = object()
# Constants for group SID attributes.
default_attrs = security.SE_GROUP_DEFAULT_FLAGS
resource_attrs = default_attrs | security.SE_GROUP_RESOURCE
asserted_identity = security.SID_AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY
compounded_auth = security.SID_COMPOUNDED_AUTHENTICATION
user_trust_domain = 'S-1-5-21-123-456-111'
mach_trust_domain = 'S-1-5-21-123-456-222'
def setUp(self):
super().setUp()
self.do_asn1_print = global_asn1_print
self.do_hexdump = global_hexdump
# Some general information on how Windows handles device info:
# All the SIDs in the computer's info3.sids end up in device.domain_groups
# (if they are in any domain), or in device.sids (if they are not). Even if
# netlogon.NETLOGON_EXTRA_SIDS is not set.
# The remainder of the SIDs in device.domain_groups come from an LDAP
# search of the computer's domain-local groups.
# None of the SIDs in the computer's logon_info.resource_groups.groups go
# anywhere. Even if netlogon.NETLOGON_RESOURCE_GROUPS is set.
# In summary:
# info3.base.groups => device.groups
# info3.sids => device.sids (if not in a domain)
# info3.sids => device.domain_groups (if in a domain)
# searched-for domain-local groups => device.domain_groups
# These searched-for domain-local groups are based on _all_ the groups in
# info3.base.groups and info3.sids. So if the account is no longer a member
# of a (universal or global) group that belongs to a domain-local group,
# but has that universal or global group in info3.base.groups or
# info3.sids, then the domain-local group will still get added to the
# PAC. But the resource groups don't affect this (presumably, they are
# being filtered out). Also, those groups the search is based on do not go
# in themselves, even if they are domain-local groups.
cases = [
{
# Make a TGS request to the krbtgt.
'test': 'basic to krbtgt',
'as:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'as:mach:expected': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
# Indicate this request is to the krbtgt.
'tgs:to_krbtgt': True,
'tgs:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
},
{
# Make a TGS request to a service that supports SID compression.
'test': 'device to service compressed',
'as:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'as:mach:expected': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:to_krbtgt': False,
'tgs:compression': True,
'tgs:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
# The compounded authentication SID indicates that we used FAST
# with a device's TGT.
(compounded_auth, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:device:expected': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
frozenset([(security.SID_CLAIMS_VALID, SidType.RESOURCE_SID, default_attrs)]),
},
},
{
# Make a TGS request to a service that lacks support for SID
# compression.
'test': 'device to service uncompressed',
'as:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'as:mach:expected': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:to_krbtgt': False,
# SID compression is unsupported.
'tgs:compression': False,
# There is no change in the reply PAC.
'tgs:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(compounded_auth, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:device:expected': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
frozenset([(security.SID_CLAIMS_VALID, SidType.RESOURCE_SID, default_attrs)]),
},
},
{
# Make a TGS request to a service that lacks support for compound
# identity.
'test': 'device to service no compound id',
'as:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'as:mach:expected': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:to_krbtgt': False,
# Compound identity is unsupported.
'tgs:compound_id': False,
'tgs:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
# The Compounded Authentication SID should not be present.
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
},
{
'test': 'universal groups to krbtgt',
'groups': {
# The user and computer each belong to a couple of universal
# groups.
'group0': (GroupType.UNIVERSAL, {'group1'}),
'group1': (GroupType.UNIVERSAL, {user}),
'group2': (GroupType.UNIVERSAL, {'group3'}),
'group3': (GroupType.UNIVERSAL, {mach}),
},
'as:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
# The user's groups appear in the PAC of the TGT.
('group0', SidType.BASE_SID, default_attrs),
('group1', SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'as:mach:expected': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
# So too for the computer's groups.
('group2', SidType.BASE_SID, default_attrs),
('group3', SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:to_krbtgt': True,
'tgs:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
# The user's groups appear in the TGS reply PAC.
('group0', SidType.BASE_SID, default_attrs),
('group1', SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
},
{
'test': 'universal groups to service',
'groups': {
'group0': (GroupType.UNIVERSAL, {'group1'}),
'group1': (GroupType.UNIVERSAL, {user}),
'group2': (GroupType.UNIVERSAL, {'group3'}),
'group3': (GroupType.UNIVERSAL, {mach}),
},
'as:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
('group0', SidType.BASE_SID, default_attrs),
('group1', SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'as:mach:expected': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
('group2', SidType.BASE_SID, default_attrs),
('group3', SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:to_krbtgt': False,
'tgs:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
('group0', SidType.BASE_SID, default_attrs),
('group1', SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(compounded_auth, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:device:expected': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
# The computer's groups appear in the device info structure of
# the TGS reply PAC.
('group2', SidType.BASE_SID, default_attrs),
('group3', SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
frozenset([(security.SID_CLAIMS_VALID, SidType.RESOURCE_SID, default_attrs)]),
},
},
{
'test': 'domain-local groups to krbtgt',
'groups': {
# The user and computer each belong to a couple of domain-local
# groups.
'group0': (GroupType.DOMAIN_LOCAL, {'group1'}),
'group1': (GroupType.DOMAIN_LOCAL, {user}),
'group2': (GroupType.DOMAIN_LOCAL, {'group3'}),
'group3': (GroupType.DOMAIN_LOCAL, {mach}),
},
'as:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
# The user's domain-local group memberships do not appear.
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'as:mach:expected': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
# Nor do the computer's.
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:to_krbtgt': True,
'tgs:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
# The user's groups do not appear in the TGS reply PAC.
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
},
{
'test': 'domain-local groups to service compressed',
'groups': {
'group0': (GroupType.DOMAIN_LOCAL, {'group1'}),
'group1': (GroupType.DOMAIN_LOCAL, {user}),
'group2': (GroupType.DOMAIN_LOCAL, {'group3'}),
'group3': (GroupType.DOMAIN_LOCAL, {mach}),
},
'as:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'as:mach:expected': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:to_krbtgt': False,
'tgs:compression': True,
'tgs:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
# These groups appear as resource SIDs.
('group0', SidType.RESOURCE_SID, resource_attrs),
('group1', SidType.RESOURCE_SID, resource_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(compounded_auth, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:device:expected': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
# The computer's groups appear together as resource SIDs.
frozenset([
('group2', SidType.RESOURCE_SID, resource_attrs),
('group3', SidType.RESOURCE_SID, resource_attrs),
]),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
frozenset([(security.SID_CLAIMS_VALID, SidType.RESOURCE_SID, default_attrs)]),
},
},
{
'test': 'domain-local groups to service uncompressed',
'groups': {
'group0': (GroupType.DOMAIN_LOCAL, {'group1'}),
'group1': (GroupType.DOMAIN_LOCAL, {user}),
'group2': (GroupType.DOMAIN_LOCAL, {'group3'}),
'group3': (GroupType.DOMAIN_LOCAL, {mach}),
},
'as:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'as:mach:expected': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:to_krbtgt': False,
'tgs:compression': False,
'tgs:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
# The user's groups now appear as extra SIDs.
('group0', SidType.EXTRA_SID, resource_attrs),
('group1', SidType.EXTRA_SID, resource_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(compounded_auth, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:device:expected': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
# The computer's groups are still resource SIDs.
frozenset([
('group2', SidType.RESOURCE_SID, resource_attrs),
('group3', SidType.RESOURCE_SID, resource_attrs),
]),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
frozenset([(security.SID_CLAIMS_VALID, SidType.RESOURCE_SID, default_attrs)]),
},
},
# Test what happens if the computer is removed from a group prior to
# the TGS request.
{
'test': 'remove transitive domain-local groups to krbtgt',
'groups': {
# The computer is transitively a member of a couple of
# domain-local groups...
'dom-local-outer-0': (GroupType.DOMAIN_LOCAL, {'dom-local-inner'}),
'dom-local-outer-1': (GroupType.DOMAIN_LOCAL, {'universal-inner'}),
# ...via another domain-local group and a universal group.
'dom-local-inner': (GroupType.DOMAIN_LOCAL, {mach}),
'universal-inner': (GroupType.UNIVERSAL, {mach}),
},
# Just prior to the TGS request, the computer is removed from both
# inner groups. Domain-local groups will have not been added to the
# PAC at this point.
'tgs:mach:removed': {
'dom-local-inner',
'universal-inner',
},
'as:mach:expected': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
# Only the universal group appears in the PAC.
('universal-inner', SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:to_krbtgt': True,
'tgs:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
},
{
'test': 'remove transitive domain-local groups to service compressed',
'groups': {
'dom-local-outer-0': (GroupType.DOMAIN_LOCAL, {'dom-local-inner'}),
'dom-local-outer-1': (GroupType.DOMAIN_LOCAL, {'universal-inner'}),
'dom-local-inner': (GroupType.DOMAIN_LOCAL, {mach}),
'universal-inner': (GroupType.UNIVERSAL, {mach}),
},
'tgs:mach:removed': {
'dom-local-inner',
'universal-inner',
},
'as:mach:expected': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
('universal-inner', SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:to_krbtgt': False,
'tgs:compression': True,
'tgs:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(compounded_auth, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:device:expected': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
# The universal group appears in the device info...
('universal-inner', SidType.BASE_SID, default_attrs),
# ...along with the second domain-local group, even though the
# computer no longer belongs to it.
frozenset([
('dom-local-outer-1', SidType.RESOURCE_SID, resource_attrs),
]),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
frozenset([(security.SID_CLAIMS_VALID, SidType.RESOURCE_SID, default_attrs)]),
},
},
{
'test': 'remove transitive domain-local groups to service uncompressed',
'groups': {
'dom-local-outer-0': (GroupType.DOMAIN_LOCAL, {'dom-local-inner'}),
'dom-local-outer-1': (GroupType.DOMAIN_LOCAL, {'universal-inner'}),
'dom-local-inner': (GroupType.DOMAIN_LOCAL, {mach}),
'universal-inner': (GroupType.UNIVERSAL, {mach}),
},
'tgs:mach:removed': {
'dom-local-inner',
'universal-inner',
},
'as:mach:expected': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
('universal-inner', SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:to_krbtgt': False,
'tgs:compression': False,
'tgs:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(compounded_auth, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:device:expected': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
('universal-inner', SidType.BASE_SID, default_attrs),
frozenset([
('dom-local-outer-1', SidType.RESOURCE_SID, resource_attrs),
]),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
frozenset([(security.SID_CLAIMS_VALID, SidType.RESOURCE_SID, default_attrs)]),
},
},
# Test what happens if the computer is added to a group prior to the
# TGS request.
{
'test': 'add transitive domain-local groups to krbtgt',
'groups': {
# We create a pair of groups, to be used presently.
'dom-local-outer': (GroupType.DOMAIN_LOCAL, {'universal-inner'}),
'universal-inner': (GroupType.UNIVERSAL, {}),
},
# Just prior to the TGS request, the computer is added to the inner
# group.
'tgs:mach:added': {
'universal-inner',
},
'as:mach:expected': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:to_krbtgt': True,
'tgs:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
},
{
'test': 'add transitive domain-local groups to service compressed',
'groups': {
'dom-local-outer': (GroupType.DOMAIN_LOCAL, {'universal-inner'}),
'universal-inner': (GroupType.UNIVERSAL, {}),
},
'tgs:mach:added': {
'universal-inner',
},
'as:mach:expected': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:to_krbtgt': False,
'tgs:compression': True,
'tgs:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(compounded_auth, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:device:expected': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
# The computer was not a member of the universal group at the
# time of obtaining a TGT, and said group did not make it into
# the PAC. Group expansion is only concerned with domain-local
# groups, none of which the machine currently belongs
# to. Therefore, neither group is present in the device info
# structure.
(asserted_identity, SidType.EXTRA_SID, default_attrs),
frozenset([(security.SID_CLAIMS_VALID, SidType.RESOURCE_SID, default_attrs)]),
},
},
{
'test': 'add transitive domain-local groups to service uncompressed',
'groups': {
'dom-local-outer': (GroupType.DOMAIN_LOCAL, {'universal-inner'}),
'universal-inner': (GroupType.UNIVERSAL, {}),
},
'tgs:mach:added': {
'universal-inner',
},
'as:mach:expected': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:to_krbtgt': False,
'tgs:compression': False,
'tgs:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(compounded_auth, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:device:expected': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
frozenset([(security.SID_CLAIMS_VALID, SidType.RESOURCE_SID, default_attrs)]),
},
},
# Simulate a machine ticket coming in over a trust.
{
'test': 'from trust domain-local groups to service compressed',
'groups': {
# The machine belongs to a couple of domain-local groups in our
# domain.
'foo': (GroupType.DOMAIN_LOCAL, {trust_mach}),
'bar': (GroupType.DOMAIN_LOCAL, {'foo'}),
},
'tgs:to_krbtgt': False,
'tgs:compression': True,
# The machine SID is from a different domain.
'tgs:mach_sid': trust_mach,
'tgs:mach:sids': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
# This dummy resource SID comes from the trusted domain.
(f'{mach_trust_domain}-333', SidType.RESOURCE_SID, resource_attrs),
},
'tgs:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(compounded_auth, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:device:expected': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
# The domain-local groups end up in the device info.
frozenset([
('foo', SidType.RESOURCE_SID, resource_attrs),
('bar', SidType.RESOURCE_SID, resource_attrs),
]),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
frozenset([(security.SID_CLAIMS_VALID, SidType.RESOURCE_SID, default_attrs)]),
},
},
{
'test': 'from trust domain-local groups to service uncompressed',
'groups': {
'foo': (GroupType.DOMAIN_LOCAL, {trust_mach}),
'bar': (GroupType.DOMAIN_LOCAL, {'foo'}),
},
'tgs:to_krbtgt': False,
'tgs:compression': False,
'tgs:mach_sid': trust_mach,
'tgs:mach:sids': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
(f'{mach_trust_domain}-333', SidType.RESOURCE_SID, resource_attrs),
},
'tgs:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(compounded_auth, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:device:expected': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
frozenset([
('foo', SidType.RESOURCE_SID, resource_attrs),
('bar', SidType.RESOURCE_SID, resource_attrs),
]),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
frozenset([(security.SID_CLAIMS_VALID, SidType.RESOURCE_SID, default_attrs)]),
},
},
# Simulate the user ticket coming in over a trust.
{
'test': 'user from trust domain-local groups to krbtgt',
'groups': {
# The user belongs to a couple of domain-local groups in our
# domain.
'group0': (GroupType.DOMAIN_LOCAL, {trust_user}),
'group1': (GroupType.DOMAIN_LOCAL, {'group0'}),
},
'tgs:to_krbtgt': True,
# Both SIDs are from a different domain.
'tgs:user_sid': trust_user,
'tgs:user:sids': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
# This dummy resource SID comes from the trusted domain.
(f'{mach_trust_domain}-333', SidType.RESOURCE_SID, resource_attrs),
},
'tgs:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
# The dummy resource SID remains in the PAC.
(f'{mach_trust_domain}-333', SidType.RESOURCE_SID, resource_attrs),
},
},
{
'test': 'user from trust domain-local groups to service compressed',
'groups': {
'group0': (GroupType.DOMAIN_LOCAL, {trust_user}),
'group1': (GroupType.DOMAIN_LOCAL, {'group0'}),
},
'tgs:to_krbtgt': False,
'tgs:compression': True,
'tgs:user_sid': trust_user,
'tgs:user:sids': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
# This dummy resource SID comes from the trusted domain.
(f'{mach_trust_domain}-333', SidType.RESOURCE_SID, resource_attrs),
},
'tgs:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(compounded_auth, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
('group0', SidType.RESOURCE_SID, resource_attrs),
('group1', SidType.RESOURCE_SID, resource_attrs),
},
'tgs:device:expected': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
frozenset([(security.SID_CLAIMS_VALID, SidType.RESOURCE_SID, default_attrs)]),
},
},
{
'test': 'user from trust domain-local groups to service uncompressed',
'groups': {
'group0': (GroupType.DOMAIN_LOCAL, {trust_user}),
'group1': (GroupType.DOMAIN_LOCAL, {'group0'}),
},
'tgs:to_krbtgt': False,
'tgs:compression': False,
'tgs:user_sid': trust_user,
'tgs:user:sids': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
# This dummy resource SID comes from the trusted domain.
(f'{mach_trust_domain}-333', SidType.RESOURCE_SID, resource_attrs),
},
'tgs:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(compounded_auth, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
('group0', SidType.EXTRA_SID, resource_attrs),
('group1', SidType.EXTRA_SID, resource_attrs),
},
'tgs:device:expected': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
frozenset([(security.SID_CLAIMS_VALID, SidType.RESOURCE_SID, default_attrs)]),
},
},
# Simulate both tickets coming in over a trust.
{
'test': 'both from trust domain-local groups to krbtgt',
'groups': {
# The user and machine each belong to a couple of domain-local
# groups in our domain.
'group0': (GroupType.DOMAIN_LOCAL, {trust_user}),
'group1': (GroupType.DOMAIN_LOCAL, {'group0'}),
'group2': (GroupType.DOMAIN_LOCAL, {trust_mach}),
'group3': (GroupType.DOMAIN_LOCAL, {'group2'}),
},
'tgs:to_krbtgt': True,
# Both SIDs are from a different domain.
'tgs:user_sid': trust_user,
'tgs:mach_sid': trust_mach,
'tgs:user:sids': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
# This dummy resource SID comes from the trusted domain.
(f'{mach_trust_domain}-333', SidType.RESOURCE_SID, resource_attrs),
},
'tgs:mach:sids': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
# This dummy resource SID comes from the trusted domain.
(f'{mach_trust_domain}-444', SidType.RESOURCE_SID, resource_attrs),
},
'tgs:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
# The dummy resource SID remains in the PAC.
(f'{mach_trust_domain}-333', SidType.RESOURCE_SID, resource_attrs),
},
},
{
'test': 'both from trust domain-local groups to service compressed',
'groups': {
# The machine belongs to a couple of domain-local groups in our
# domain.
'group0': (GroupType.DOMAIN_LOCAL, {trust_user}),
'group1': (GroupType.DOMAIN_LOCAL, {'group0'}),
'group2': (GroupType.DOMAIN_LOCAL, {trust_mach}),
'group3': (GroupType.DOMAIN_LOCAL, {'group2'}),
},
'tgs:to_krbtgt': False,
'tgs:compression': True,
'tgs:user_sid': trust_user,
'tgs:mach_sid': trust_mach,
'tgs:user:sids': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
# This dummy resource SID comes from the trusted domain.
(f'{mach_trust_domain}-333', SidType.RESOURCE_SID, resource_attrs),
},
'tgs:mach:sids': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
# This dummy resource SID comes from the trusted domain.
(f'{mach_trust_domain}-444', SidType.RESOURCE_SID, resource_attrs),
},
'tgs:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(compounded_auth, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
('group0', SidType.RESOURCE_SID, resource_attrs),
('group1', SidType.RESOURCE_SID, resource_attrs),
},
'tgs:device:expected': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
# The domain-local groups end up in the device info.
frozenset([
('group2', SidType.RESOURCE_SID, resource_attrs),
('group3', SidType.RESOURCE_SID, resource_attrs),
]),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
frozenset([(security.SID_CLAIMS_VALID, SidType.RESOURCE_SID, default_attrs)]),
},
},
{
'test': 'both from trust domain-local groups to service uncompressed',
'groups': {
'group0': (GroupType.DOMAIN_LOCAL, {trust_user}),
'group1': (GroupType.DOMAIN_LOCAL, {'group0'}),
'group2': (GroupType.DOMAIN_LOCAL, {trust_mach}),
'group3': (GroupType.DOMAIN_LOCAL, {'group2'}),
},
'tgs:to_krbtgt': False,
'tgs:compression': False,
'tgs:user_sid': trust_user,
'tgs:mach_sid': trust_mach,
'tgs:user:sids': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
# This dummy resource SID comes from the trusted domain.
(f'{mach_trust_domain}-333', SidType.RESOURCE_SID, resource_attrs),
},
'tgs:mach:sids': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
# This dummy resource SID comes from the trusted domain.
(f'{mach_trust_domain}-444', SidType.RESOURCE_SID, resource_attrs),
},
'tgs:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(compounded_auth, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
('group0', SidType.EXTRA_SID, resource_attrs),
('group1', SidType.EXTRA_SID, resource_attrs),
},
'tgs:device:expected': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
frozenset([
('group2', SidType.RESOURCE_SID, resource_attrs),
('group3', SidType.RESOURCE_SID, resource_attrs),
]),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
frozenset([(security.SID_CLAIMS_VALID, SidType.RESOURCE_SID, default_attrs)]),
},
},
# Test how resource SIDs are propagated into the device info structure.
{
'test': 'mach resource sids',
'tgs:mach:sids': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
# Of these SIDs, the Base SIDs and Extra SIDs are all
# propagated into the device info structure, regardless of
# their attrs, while the Resource SIDs are all dropped.
(123, SidType.BASE_SID, default_attrs),
(333, SidType.BASE_SID, default_attrs),
(333, SidType.BASE_SID, resource_attrs),
(1000, SidType.BASE_SID, resource_attrs),
(497, SidType.EXTRA_SID, resource_attrs), # the Claims Valid RID.
(333, SidType.RESOURCE_SID, default_attrs),
(498, SidType.RESOURCE_SID, resource_attrs),
(99999, SidType.RESOURCE_SID, default_attrs),
(12345678, SidType.RESOURCE_SID, resource_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:to_krbtgt': False,
'tgs:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(compounded_auth, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:device:expected': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
(123, SidType.BASE_SID, default_attrs),
(333, SidType.BASE_SID, default_attrs),
(333, SidType.BASE_SID, resource_attrs),
(1000, SidType.BASE_SID, resource_attrs),
frozenset({
(497, SidType.RESOURCE_SID, resource_attrs),
}),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
frozenset([(security.SID_CLAIMS_VALID, SidType.RESOURCE_SID, default_attrs)]),
},
},
# Add a Base SID to the user's PAC, and confirm it is propagated into
# the PAC of the service ticket.
{
'test': 'base sid to krbtgt',
'tgs:user:sids': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(123, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:to_krbtgt': True,
'tgs:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(123, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
},
{
'test': 'base sid to service',
'tgs:user:sids': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(123, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:to_krbtgt': False,
'tgs:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(123, SidType.BASE_SID, default_attrs),
(compounded_auth, SidType.EXTRA_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:device:expected': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
frozenset([(security.SID_CLAIMS_VALID, SidType.RESOURCE_SID, default_attrs)]),
},
},
# Add a Base SID with resource attrs to the user's PAC, and confirm it
# is propagated into the PAC of the service ticket.
{
'test': 'base sid resource attrs to krbtgt',
'tgs:user:sids': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(123, SidType.BASE_SID, resource_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:to_krbtgt': True,
'tgs:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(123, SidType.BASE_SID, resource_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
},
{
'test': 'base sid resource attrs to service',
'tgs:user:sids': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(123, SidType.BASE_SID, resource_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:to_krbtgt': False,
'tgs:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(123, SidType.BASE_SID, resource_attrs),
(compounded_auth, SidType.EXTRA_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:device:expected': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
frozenset([(security.SID_CLAIMS_VALID, SidType.RESOURCE_SID, default_attrs)]),
},
},
# Add a couple of Extra SIDs to the user's PAC, and confirm they are
# propagated into the PAC of the service ticket.
{
'test': 'extra sids to krbtgt',
'tgs:user:sids': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
('S-1-5-2-3-4', SidType.EXTRA_SID, default_attrs),
('S-1-5-2-3-5', SidType.EXTRA_SID, resource_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:to_krbtgt': True,
'tgs:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
('S-1-5-2-3-4', SidType.EXTRA_SID, default_attrs),
('S-1-5-2-3-5', SidType.EXTRA_SID, resource_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
},
{
'test': 'extra sids to service',
'tgs:user:sids': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
('S-1-5-2-3-4', SidType.EXTRA_SID, default_attrs),
('S-1-5-2-3-5', SidType.EXTRA_SID, resource_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:to_krbtgt': False,
'tgs:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
('S-1-5-2-3-4', SidType.EXTRA_SID, default_attrs),
('S-1-5-2-3-5', SidType.EXTRA_SID, resource_attrs),
(compounded_auth, SidType.EXTRA_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:device:expected': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
frozenset([(security.SID_CLAIMS_VALID, SidType.RESOURCE_SID, default_attrs)]),
},
},
# Test what happens if we remove the CLAIMS_VALID and ASSERTED_IDENTITY
# SIDs from either of the PACs, so we can see at what point these SIDs
# are added.
{
'test': 'removed special sids to krbtgt',
'tgs:user:sids': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
('S-1-5-2-3-4', SidType.EXTRA_SID, default_attrs),
# We don't specify asserted identity or claims valid SIDs for
# the user...
},
'tgs:mach:sids': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
# ...nor for the computer.
},
'tgs:to_krbtgt': True,
'tgs:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
('S-1-5-2-3-4', SidType.EXTRA_SID, default_attrs),
# They don't show up in the service ticket.
},
},
{
'test': 'removed special sids to service',
'tgs:user:sids': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
('S-1-5-2-3-4', SidType.EXTRA_SID, default_attrs),
},
'tgs:mach:sids': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
},
'tgs:to_krbtgt': False,
'tgs:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
('S-1-5-2-3-4', SidType.EXTRA_SID, default_attrs),
(compounded_auth, SidType.EXTRA_SID, default_attrs),
},
'tgs:device:expected': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
# These special SIDs don't show up in the device info either.
},
},
# Test a group being the primary one for the user and machine.
{
'test': 'primary universal to krbtgt',
'groups': {
'primary-user': (GroupType.UNIVERSAL, {user}),
'primary-mach': (GroupType.UNIVERSAL, {mach}),
},
# Set these groups as the account's primary groups.
'primary_group': 'primary-user',
'mach:primary_group': 'primary-mach',
'as:expected': {
# They appear in the PAC as normal.
('primary-user', SidType.BASE_SID, default_attrs),
('primary-user', SidType.PRIMARY_GID, None),
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'as:mach:expected': {
('primary-mach', SidType.BASE_SID, default_attrs),
('primary-mach', SidType.PRIMARY_GID, None),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:to_krbtgt': True,
'tgs:expected': {
('primary-user', SidType.BASE_SID, default_attrs),
('primary-user', SidType.PRIMARY_GID, None),
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
},
{
'test': 'primary universal to service compressed',
'groups': {
'primary-user': (GroupType.UNIVERSAL, {user}),
'primary-mach': (GroupType.UNIVERSAL, {mach}),
},
'primary_group': 'primary-user',
'mach:primary_group': 'primary-mach',
'as:expected': {
('primary-user', SidType.BASE_SID, default_attrs),
('primary-user', SidType.PRIMARY_GID, None),
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'as:mach:expected': {
('primary-mach', SidType.BASE_SID, default_attrs),
('primary-mach', SidType.PRIMARY_GID, None),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:to_krbtgt': False,
'tgs:compression': True,
'tgs:expected': {
('primary-user', SidType.BASE_SID, default_attrs),
('primary-user', SidType.PRIMARY_GID, None),
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(compounded_auth, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:device:expected': {
('primary-mach', SidType.BASE_SID, default_attrs),
('primary-mach', SidType.PRIMARY_GID, None),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
frozenset([(security.SID_CLAIMS_VALID, SidType.RESOURCE_SID, default_attrs)]),
},
},
{
'test': 'primary universal to service uncompressed',
'groups': {
'primary-user': (GroupType.UNIVERSAL, {user}),
'primary-mach': (GroupType.UNIVERSAL, {mach}),
},
'primary_group': 'primary-user',
'mach:primary_group': 'primary-mach',
'as:expected': {
('primary-user', SidType.BASE_SID, default_attrs),
('primary-user', SidType.PRIMARY_GID, None),
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'as:mach:expected': {
('primary-mach', SidType.BASE_SID, default_attrs),
('primary-mach', SidType.PRIMARY_GID, None),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:to_krbtgt': False,
# SID compression is unsupported.
'tgs:compression': False,
'tgs:expected': {
('primary-user', SidType.BASE_SID, default_attrs),
('primary-user', SidType.PRIMARY_GID, None),
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(compounded_auth, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:device:expected': {
('primary-mach', SidType.BASE_SID, default_attrs),
('primary-mach', SidType.PRIMARY_GID, None),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
frozenset([(security.SID_CLAIMS_VALID, SidType.RESOURCE_SID, default_attrs)]),
},
},
# Test domain-local primary groups.
{
'test': 'primary domain-local to krbtgt',
'groups': {
'primary-user': (GroupType.DOMAIN_LOCAL, {user}),
'primary-mach': (GroupType.DOMAIN_LOCAL, {mach}),
},
# Though Windows normally disallows setting domain-locals group as
# primary groups, Samba does not.
'primary_group': 'primary-user',
'mach:primary_group': 'primary-mach',
'as:expected': {
# The domain-local groups appear as our primary GIDs, but do
# not appear in the base SIDs.
('primary-user', SidType.PRIMARY_GID, None),
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'as:mach:expected': {
('primary-mach', SidType.PRIMARY_GID, None),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:to_krbtgt': True,
'tgs:expected': {
('primary-user', SidType.PRIMARY_GID, None),
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
},
{
'test': 'primary domain-local to service compressed',
'groups': {
'primary-user': (GroupType.DOMAIN_LOCAL, {user}),
'primary-mach': (GroupType.DOMAIN_LOCAL, {mach}),
},
'primary_group': 'primary-user',
'mach:primary_group': 'primary-mach',
'as:expected': {
('primary-user', SidType.PRIMARY_GID, None),
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'as:mach:expected': {
('primary-mach', SidType.PRIMARY_GID, None),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:to_krbtgt': False,
'tgs:compression': True,
'tgs:expected': {
('primary-user', SidType.PRIMARY_GID, None),
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(compounded_auth, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:device:expected': {
('primary-mach', SidType.PRIMARY_GID, None),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
frozenset([(security.SID_CLAIMS_VALID, SidType.RESOURCE_SID, default_attrs)]),
},
},
{
'test': 'primary domain-local to service uncompressed',
'groups': {
'primary-user': (GroupType.DOMAIN_LOCAL, {user}),
'primary-mach': (GroupType.DOMAIN_LOCAL, {mach}),
},
'primary_group': 'primary-user',
'mach:primary_group': 'primary-mach',
'as:expected': {
('primary-user', SidType.PRIMARY_GID, None),
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'as:mach:expected': {
('primary-mach', SidType.PRIMARY_GID, None),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:to_krbtgt': False,
# SID compression is unsupported.
'tgs:compression': False,
'tgs:expected': {
('primary-user', SidType.PRIMARY_GID, None),
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(compounded_auth, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:device:expected': {
('primary-mach', SidType.PRIMARY_GID, None),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
frozenset([(security.SID_CLAIMS_VALID, SidType.RESOURCE_SID, default_attrs)]),
},
},
# Test the scenario where we belong to a now-domain-local group, and
# possess an old TGT issued when the group was still our primary one.
{
'test': 'old primary domain-local to krbtgt',
'groups': {
# Domain-local groups to which the accounts belong.
'primary-user': (GroupType.DOMAIN_LOCAL, {user}),
'primary-mach': (GroupType.DOMAIN_LOCAL, {mach}),
},
'tgs:user:sids': {
# In the PACs, the groups have the attributes of an ordinary
# group...
('primary-user', SidType.BASE_SID, default_attrs),
# ...and remain our primary ones.
('primary-user', SidType.PRIMARY_GID, None),
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:mach:sids': {
('primary-mach', SidType.BASE_SID, default_attrs),
('primary-mach', SidType.PRIMARY_GID, None),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:to_krbtgt': True,
'tgs:expected': {
# The groups don't change.
('primary-user', SidType.BASE_SID, default_attrs),
('primary-user', SidType.PRIMARY_GID, None),
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
},
{
'test': 'old primary domain-local to service compressed',
'groups': {
'primary-user': (GroupType.DOMAIN_LOCAL, {user}),
'primary-mach': (GroupType.DOMAIN_LOCAL, {mach}),
},
'tgs:user:sids': {
('primary-user', SidType.BASE_SID, default_attrs),
('primary-user', SidType.PRIMARY_GID, None),
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:mach:sids': {
('primary-mach', SidType.BASE_SID, default_attrs),
('primary-mach', SidType.PRIMARY_GID, None),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:to_krbtgt': False,
'tgs:compression': True,
'tgs:expected': {
('primary-user', SidType.BASE_SID, default_attrs),
('primary-user', SidType.PRIMARY_GID, None),
# The groups are added a second time to the PAC, now as
# resource groups.
('primary-user', SidType.RESOURCE_SID, resource_attrs),
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(compounded_auth, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:device:expected': {
('primary-mach', SidType.BASE_SID, default_attrs),
('primary-mach', SidType.PRIMARY_GID, None),
frozenset([('primary-mach', SidType.RESOURCE_SID, resource_attrs)]),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
frozenset([(security.SID_CLAIMS_VALID, SidType.RESOURCE_SID, default_attrs)]),
},
},
{
'test': 'old primary domain-local to service uncompressed',
'groups': {
'primary-user': (GroupType.DOMAIN_LOCAL, {user}),
'primary-mach': (GroupType.DOMAIN_LOCAL, {mach}),
},
'tgs:user:sids': {
('primary-user', SidType.BASE_SID, default_attrs),
('primary-user', SidType.PRIMARY_GID, None),
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:mach:sids': {
('primary-mach', SidType.BASE_SID, default_attrs),
('primary-mach', SidType.PRIMARY_GID, None),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:to_krbtgt': False,
# SID compression is unsupported.
'tgs:compression': False,
'tgs:expected': {
('primary-user', SidType.BASE_SID, default_attrs),
('primary-user', SidType.PRIMARY_GID, None),
# This time, the group is added to Extra SIDs.
('primary-user', SidType.EXTRA_SID, resource_attrs),
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(compounded_auth, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:device:expected': {
('primary-mach', SidType.BASE_SID, default_attrs),
('primary-mach', SidType.PRIMARY_GID, None),
frozenset([('primary-mach', SidType.RESOURCE_SID, resource_attrs)]),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
frozenset([(security.SID_CLAIMS_VALID, SidType.RESOURCE_SID, default_attrs)]),
},
},
# Test the scenario where each account possesses an old TGT issued when
# a now-domain-local group was still its primary one. The accounts no
# longer belong to those groups, which themselves belong to other
# domain-local groups.
{
'test': 'old primary domain-local transitive to krbtgt',
'groups': {
'user-outer': (GroupType.DOMAIN_LOCAL, {'user-inner'}),
'user-inner': (GroupType.DOMAIN_LOCAL, {}),
'mach-outer': (GroupType.DOMAIN_LOCAL, {'mach-inner'}),
'mach-inner': (GroupType.DOMAIN_LOCAL, {}),
},
'tgs:user:sids': {
# In the PACs, the groups have the attributes of an ordinary
# group...
('user-inner', SidType.BASE_SID, default_attrs),
# ...and remain our primary ones.
('user-inner', SidType.PRIMARY_GID, None),
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:mach:sids': {
('mach-inner', SidType.BASE_SID, default_attrs),
('mach-inner', SidType.PRIMARY_GID, None),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:to_krbtgt': True,
'tgs:expected': {
# The groups don't change.
('user-inner', SidType.BASE_SID, default_attrs),
('user-inner', SidType.PRIMARY_GID, None),
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
},
{
'test': 'old primary domain-local transitive to service compressed',
'groups': {
'user-outer': (GroupType.DOMAIN_LOCAL, {'user-inner'}),
'user-inner': (GroupType.DOMAIN_LOCAL, {}),
'mach-outer': (GroupType.DOMAIN_LOCAL, {'mach-inner'}),
'mach-inner': (GroupType.DOMAIN_LOCAL, {}),
},
'tgs:user:sids': {
('user-inner', SidType.BASE_SID, default_attrs),
('user-inner', SidType.PRIMARY_GID, None),
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:mach:sids': {
('mach-inner', SidType.BASE_SID, default_attrs),
('mach-inner', SidType.PRIMARY_GID, None),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:to_krbtgt': False,
'tgs:compression': True,
'tgs:expected': {
('user-inner', SidType.BASE_SID, default_attrs),
('user-inner', SidType.PRIMARY_GID, None),
# The second resource groups are added a second time to the PAC
# as resource groups.
('user-outer', SidType.RESOURCE_SID, resource_attrs),
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(compounded_auth, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:device:expected': {
('mach-inner', SidType.BASE_SID, default_attrs),
('mach-inner', SidType.PRIMARY_GID, None),
frozenset([('mach-outer', SidType.RESOURCE_SID, resource_attrs)]),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
frozenset([(security.SID_CLAIMS_VALID, SidType.RESOURCE_SID, default_attrs)]),
},
},
{
'test': 'old primary domain-local transitive to service uncompressed',
'groups': {
'user-outer': (GroupType.DOMAIN_LOCAL, {'user-inner'}),
'user-inner': (GroupType.DOMAIN_LOCAL, {}),
'mach-outer': (GroupType.DOMAIN_LOCAL, {'mach-inner'}),
'mach-inner': (GroupType.DOMAIN_LOCAL, {}),
},
'tgs:user:sids': {
('user-inner', SidType.BASE_SID, default_attrs),
('user-inner', SidType.PRIMARY_GID, None),
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:mach:sids': {
('mach-inner', SidType.BASE_SID, default_attrs),
('mach-inner', SidType.PRIMARY_GID, None),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:to_krbtgt': False,
# SID compression is unsupported.
'tgs:compression': False,
'tgs:expected': {
('user-inner', SidType.BASE_SID, default_attrs),
('user-inner', SidType.PRIMARY_GID, None),
# This time, the group is added to Extra SIDs.
('user-outer', SidType.EXTRA_SID, resource_attrs),
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(compounded_auth, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:device:expected': {
('mach-inner', SidType.BASE_SID, default_attrs),
('mach-inner', SidType.PRIMARY_GID, None),
frozenset([('mach-outer', SidType.RESOURCE_SID, resource_attrs)]),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
frozenset([(security.SID_CLAIMS_VALID, SidType.RESOURCE_SID, default_attrs)]),
},
},
# Test how the various categories of SIDs are propagated into the
# device info structure.
{
'test': 'device info sid grouping',
'tgs:mach:sids': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
# These base SIDs are simply propagated into the device info,
# irrespective of whatever attributes they have.
(1, SidType.BASE_SID, default_attrs),
(2, SidType.BASE_SID, 12345),
# Extra SIDs not from a domain are also propagated.
('S-1-5-2-3-4', SidType.EXTRA_SID, 789),
('S-1-5-20', SidType.EXTRA_SID, 999),
('S-1-5-21', SidType.EXTRA_SID, 999),
('S-1-6-0', SidType.EXTRA_SID, 999),
('S-1-6-2-3-4', SidType.EXTRA_SID, 789),
# Extra SIDs from our own domain are collated into a group.
(3, SidType.EXTRA_SID, default_attrs),
(4, SidType.EXTRA_SID, 12345),
# Extra SIDs from other domains are collated into separate groups.
('S-1-5-21-0-0-0-490', SidType.EXTRA_SID, 5),
('S-1-5-21-0-0-0-491', SidType.EXTRA_SID, 6),
('S-1-5-21-0-0-1-492', SidType.EXTRA_SID, 7),
('S-1-5-21-0-0-1-493', SidType.EXTRA_SID, 8),
('S-1-5-21-0-0-1-494', SidType.EXTRA_SID, 9),
# A non-domain SID (too few subauths), ...
('S-1-5-21-242424-12345-2', SidType.EXTRA_SID, 1111111111),
# ... a domain SID, ...
('S-1-5-21-242424-12345-321321-2', SidType.EXTRA_SID, 1111111111),
# ... and a non-domain SID (too many subauths).
('S-1-5-21-242424-12345-321321-654321-2', SidType.EXTRA_SID, default_attrs),
# Special SIDs.
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:to_krbtgt': False,
'tgs:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(compounded_auth, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:device:expected': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
# Base SIDs.
(1, SidType.BASE_SID, default_attrs),
(2, SidType.BASE_SID, 12345),
# Extra SIDs from other domains.
('S-1-5-2-3-4', SidType.EXTRA_SID, 789),
('S-1-5-20', SidType.EXTRA_SID, 999),
('S-1-5-21', SidType.EXTRA_SID, 999),
('S-1-6-0', SidType.EXTRA_SID, 999),
('S-1-6-2-3-4', SidType.EXTRA_SID, 789),
# Extra SIDs from our own domain.
frozenset({
(3, SidType.RESOURCE_SID, default_attrs),
(4, SidType.RESOURCE_SID, 12345),
}),
# Extra SIDs from other domains.
frozenset({
('S-1-5-21-0-0-0-490', SidType.RESOURCE_SID, 5),
('S-1-5-21-0-0-0-491', SidType.RESOURCE_SID, 6),
# These SIDs end up placed with the CLAIMS_VALID SID.
(security.SID_CLAIMS_VALID, SidType.RESOURCE_SID, default_attrs),
}),
frozenset({
('S-1-5-21-0-0-1-492', SidType.RESOURCE_SID, 7),
('S-1-5-21-0-0-1-493', SidType.RESOURCE_SID, 8),
('S-1-5-21-0-0-1-494', SidType.RESOURCE_SID, 9),
}),
# Non-domain SID.
('S-1-5-21-242424-12345-2', SidType.EXTRA_SID, 1111111111),
# Domain SID.
frozenset({
('S-1-5-21-242424-12345-321321-2', SidType.RESOURCE_SID, 1111111111),
}),
# Non-domain SID.
('S-1-5-21-242424-12345-321321-654321-2', SidType.EXTRA_SID, default_attrs),
# Special SIDs.
(asserted_identity, SidType.EXTRA_SID, default_attrs),
},
},
{
# Test RODC-issued device claims.
'test': 'rodc-issued device claims attack',
'groups': {
# A couple of groups to which the machine belongs.
'dom-local': (GroupType.DOMAIN_LOCAL, {mach}),
'universal': (GroupType.UNIVERSAL, {mach}),
},
'as:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:mach:sids': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
# Try to sneak a few extra SIDs into the machine's RODC-issued
# PAC.
(security.BUILTIN_RID_ADMINISTRATORS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_ENTERPRISE_READONLY_DCS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_KRBTGT, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_CERT_ADMINS, SidType.RESOURCE_SID, resource_attrs),
(security.SID_NT_SYSTEM, SidType.EXTRA_SID, default_attrs),
# Don't include the groups of which the machine is a member.
},
# The armor ticket was issued by an RODC.
'tgs:mach:from_rodc': True,
'tgs:to_krbtgt': False,
'tgs:compression': True,
'tgs:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(compounded_auth, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:device:expected': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
# The machine's groups are now included.
('universal', SidType.BASE_SID, default_attrs),
frozenset([
('dom-local', SidType.RESOURCE_SID, resource_attrs),
# Note that we're not considered a "member" of 'Allowed
# RODC Password Replication Group'.
]),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
frozenset([(security.SID_CLAIMS_VALID, SidType.RESOURCE_SID, default_attrs)]),
# The device groups should have been regenerated, our extra
# SIDs removed, and our elevation of privilege attack foiled.
},
},
{
'test': 'rodc-issued without claims valid',
'as:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:mach:sids': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
# The Claims Valid SID is missing.
},
# The armor ticket was issued by an RODC.
'tgs:mach:from_rodc': True,
'tgs:to_krbtgt': False,
'tgs:compression': True,
'tgs:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(compounded_auth, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:device:expected': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
# The Claims Valid SID is still added to the device info.
frozenset([(security.SID_CLAIMS_VALID, SidType.RESOURCE_SID, default_attrs)]),
},
},
{
'test': 'rodc-issued without asserted identity',
'as:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:mach:sids': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
# The Asserted Identity SID is missing.
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
# The armor ticket was issued by an RODC.
'tgs:mach:from_rodc': True,
'tgs:to_krbtgt': False,
'tgs:compression': True,
'tgs:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(compounded_auth, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:device:expected': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
# The Asserted Identity SID is not added to the device info.
frozenset([(security.SID_CLAIMS_VALID, SidType.RESOURCE_SID, default_attrs)]),
},
},
{
'test': 'rodc-issued asserted identity without attributes',
'as:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:mach:sids': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
# The Asserted Identity SID has no attributes set.
(asserted_identity, SidType.EXTRA_SID, 0),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
# The armor ticket was issued by an RODC.
'tgs:mach:from_rodc': True,
'tgs:to_krbtgt': False,
'tgs:compression': True,
'tgs:expected': {
(security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_USERS, SidType.PRIMARY_GID, None),
(asserted_identity, SidType.EXTRA_SID, default_attrs),
(compounded_auth, SidType.EXTRA_SID, default_attrs),
(security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
},
'tgs:device:expected': {
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.BASE_SID, default_attrs),
(security.DOMAIN_RID_DOMAIN_MEMBERS, SidType.PRIMARY_GID, None),
# The Asserted Identity SID appears in the device info with its
# attributes as normal.
(asserted_identity, SidType.EXTRA_SID, default_attrs),
frozenset([(security.SID_CLAIMS_VALID, SidType.RESOURCE_SID, default_attrs)]),
},
},
]
@classmethod
def setUpDynamicTestCases(cls):
FILTER = env_get_var_value('FILTER', allow_missing=True)
SKIP_INVALID = env_get_var_value('SKIP_INVALID', allow_missing=True)
for case in cls.cases:
invalid = case.pop('configuration_invalid', False)
if SKIP_INVALID and invalid:
# Some group setups are invalid on Windows, so we allow them to
# be skipped.
continue
name = case.pop('test')
name = re.sub(r'\W+', '_', name)
if FILTER and not re.search(FILTER, name):
continue
cls.generate_dynamic_test('test_device_info', name,
dict(case))
def _test_device_info_with_args(self, case):
# The group arrangement for the test.
group_setup = case.pop('groups', None)
# Groups that should be the primary group for the user and machine
# respectively.
primary_group = case.pop('primary_group', None)
mach_primary_group = case.pop('mach:primary_group', None)
# Whether the TGS-REQ should be directed to the krbtgt.
tgs_to_krbtgt = case.pop('tgs:to_krbtgt', None)
# Whether the target server of the TGS-REQ should support compound
# identity or resource SID compression.
tgs_compound_id = case.pop('tgs:compound_id', None)
tgs_compression = case.pop('tgs:compression', None)
# Optional SIDs to replace those in the PACs prior to a TGS-REQ.
tgs_user_sids = case.pop('tgs:user:sids', None)
tgs_mach_sids = case.pop('tgs:mach:sids', None)
# Whether the machine's TGT should be issued by an RODC.
tgs_mach_from_rodc = case.pop('tgs:mach:from_rodc', None)
# Optional groups which the machine is added to or removed from prior
# to a TGS-REQ, to test how the groups in the device PAC are expanded.
tgs_mach_added = case.pop('tgs:mach:added', None)
tgs_mach_removed = case.pop('tgs:mach:removed', None)
# Optional account SIDs to replace those in the PACs prior to a
# TGS-REQ.
tgs_user_sid = case.pop('tgs:user_sid', None)
tgs_mach_sid = case.pop('tgs:mach_sid', None)
# User flags that may be set or reset in the PAC prior to a TGS-REQ.
tgs_mach_set_user_flags = case.pop('tgs:mach:set_user_flags', None)
tgs_mach_reset_user_flags = case.pop('tgs:mach:reset_user_flags', None)
# 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_mach_expected = case.pop('as:mach:expected', None)
tgs_expected = case.pop('tgs:expected', None)
tgs_device_expected = case.pop('tgs:device:expected', None)
# There should be no parameters remaining in the testcase.
self.assertFalse(case, 'unexpected parameters in testcase')
if as_expected is None:
self.assertIsNotNone(tgs_expected,
'no set of expected SIDs is provided')
if as_mach_expected is None:
self.assertIsNotNone(tgs_expected,
'no set of expected machine SIDs is provided')
if tgs_to_krbtgt is None:
tgs_to_krbtgt = False
if tgs_compound_id is None and not tgs_to_krbtgt:
# Assume the service supports compound identity by default.
tgs_compound_id = True
if tgs_to_krbtgt:
self.assertIsNone(tgs_device_expected,
'device SIDs are not added for a krbtgt request')
self.assertIsNotNone(tgs_expected,
'no set of expected TGS SIDs is provided')
if tgs_user_sid is not None:
self.assertIsNotNone(tgs_user_sids,
'specified TGS-REQ user SID, but no '
'accompanying user SIDs provided')
if tgs_mach_sid is not None:
self.assertIsNotNone(tgs_mach_sids,
'specified TGS-REQ mach SID, but no '
'accompanying machine SIDs provided')
if tgs_mach_set_user_flags is None:
tgs_mach_set_user_flags = 0
else:
self.assertIsNotNone(tgs_mach_sids,
'specified TGS-REQ set user flags, but no '
'accompanying machine SIDs provided')
if tgs_mach_reset_user_flags is None:
tgs_mach_reset_user_flags = 0
else:
self.assertIsNotNone(tgs_mach_sids,
'specified TGS-REQ reset user flags, but no '
'accompanying machine SIDs provided')
if tgs_mach_from_rodc is None:
tgs_mach_from_rodc = False
user_use_cache = not group_setup and (
not primary_group)
mach_use_cache = not group_setup and (
not mach_primary_group) and (
not tgs_mach_added) and (
not tgs_mach_removed)
samdb = self.get_samdb()
domain_sid = samdb.get_domain_sid()
# Create the user account. It needs to be freshly created rather than
# cached if there is a possibility of adding it to one or more groups.
user_creds = self.get_cached_creds(
account_type=self.AccountType.USER,
use_cache=user_use_cache)
user_dn = user_creds.get_dn()
user_sid = user_creds.get_sid()
user_name = user_creds.get_username()
trust_user_rid = random.randint(2000, 0xfffffffe)
trust_user_sid = f'{self.user_trust_domain}-{trust_user_rid}'
trust_mach_rid = random.randint(2000, 0xfffffffe)
trust_mach_sid = f'{self.mach_trust_domain}-{trust_mach_rid}'
# Create the machine account. It needs to be freshly created rather
# than cached if there is a possibility of adding it to one or more
# groups.
if tgs_mach_from_rodc:
# If the machine's TGT is to be issued by an RODC, ensure the
# machine account is allowed to replicate to an RODC.
mach_opts = {
'allowed_replication_mock': True,
'revealed_to_mock_rodc': True,
}
else:
mach_opts = None
mach_creds = self.get_cached_creds(
account_type=self.AccountType.COMPUTER,
opts=mach_opts,
use_cache=mach_use_cache)
mach_dn = mach_creds.get_dn()
mach_dn_str = str(mach_dn)
mach_sid = mach_creds.get_sid()
user_principal = Principal(user_dn, user_sid)
mach_principal = Principal(mach_dn, mach_sid)
trust_user_principal = Principal(None, trust_user_sid)
trust_mach_principal = Principal(None, trust_mach_sid)
preexisting_groups = {
self.user: user_principal,
self.mach: mach_principal,
self.trust_user: trust_user_principal,
self.trust_mach: trust_mach_principal,
}
primary_groups = {}
if primary_group is not None:
primary_groups[user_principal] = primary_group
if mach_primary_group is not None:
primary_groups[mach_principal] = mach_primary_group
groups = self.setup_groups(samdb,
preexisting_groups,
group_setup,
primary_groups)
del group_setup
if tgs_user_sid is None:
tgs_user_sid = user_sid
elif tgs_user_sid in groups:
tgs_user_sid = groups[tgs_user_sid].sid
tgs_user_domain_sid, tgs_user_rid = tgs_user_sid.rsplit('-', 1)
if tgs_mach_sid is None:
tgs_mach_sid = mach_sid
elif tgs_mach_sid in groups:
tgs_mach_sid = groups[tgs_mach_sid].sid
tgs_mach_domain_sid, tgs_mach_rid = tgs_mach_sid.rsplit('-', 1)
expected_groups = self.map_sids(as_expected, groups,
domain_sid)
mach_expected_groups = self.map_sids(as_mach_expected, groups,
domain_sid)
tgs_user_sids_mapped = self.map_sids(tgs_user_sids, groups,
tgs_user_domain_sid)
tgs_mach_sids_mapped = self.map_sids(tgs_mach_sids, groups,
tgs_mach_domain_sid)
tgs_expected_mapped = self.map_sids(tgs_expected, groups,
tgs_user_domain_sid)
tgs_device_expected_mapped = self.map_sids(tgs_device_expected, groups,
tgs_mach_domain_sid)
user_tgt = self.get_tgt(user_creds,
expected_groups=expected_groups,
unexpected_groups=None)
mach_tgt = self.get_tgt(mach_creds,
expected_groups=mach_expected_groups,
unexpected_groups=None)
if tgs_user_sids is not None:
# Replace the SIDs in the user's PAC with the ones provided by the
# test.
user_tgt = self.ticket_with_sids(user_tgt,
tgs_user_sids_mapped,
tgs_user_domain_sid,
tgs_user_rid)
if tgs_mach_sids is not None:
# Replace the SIDs in the machine's PAC with the ones provided by
# the test.
mach_tgt = self.ticket_with_sids(mach_tgt,
tgs_mach_sids_mapped,
tgs_mach_domain_sid,
tgs_mach_rid,
set_user_flags=tgs_mach_set_user_flags,
reset_user_flags=tgs_mach_reset_user_flags,
from_rodc=tgs_mach_from_rodc)
elif tgs_mach_from_rodc:
mach_tgt = self.issued_by_rodc(mach_tgt)
if tgs_mach_removed is not None:
for removed in tgs_mach_removed:
group_dn = self.map_to_dn(removed, groups, domain_sid=None)
self.remove_from_group(mach_dn, group_dn)
if tgs_mach_added is not None:
for added in tgs_mach_added:
group_dn = self.map_to_dn(added, groups, domain_sid=None)
self.add_to_group(mach_dn_str, group_dn, 'member',
expect_attr=False)
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, sname = self.get_target(
to_krbtgt=tgs_to_krbtgt,
compound_id=tgs_compound_id,
compression=tgs_compression)
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
requester_sid = None
if tgs_to_krbtgt:
requester_sid = user_sid
expect_resource_groups_flag = None
if tgs_mach_reset_user_flags & netlogon.NETLOGON_RESOURCE_GROUPS:
expect_resource_groups_flag = False
elif tgs_mach_set_user_flags & netlogon.NETLOGON_RESOURCE_GROUPS:
expect_resource_groups_flag = True
# Perform a TGS-REQ with the user account.
kdc_exchange_dict = self.tgs_exchange_dict(
creds=user_creds,
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,
expect_pac_attrs=tgs_to_krbtgt,
expect_pac_attrs_pac_request=tgs_to_krbtgt,
expected_sid=tgs_user_sid,
expected_requester_sid=requester_sid,
expected_domain_sid=tgs_user_domain_sid,
expected_device_domain_sid=tgs_mach_domain_sid,
expected_supported_etypes=target_supported_etypes,
expect_resource_groups_flag=expect_resource_groups_flag,
expected_groups=tgs_expected_mapped,
expect_device_info=bool(tgs_compound_id),
expected_device_groups=tgs_device_expected_mapped)
rep = self._generic_kdc_exchange(kdc_exchange_dict,
cname=None,
realm=srealm,
sname=sname,
etypes=etypes)
self.check_reply(rep, KRB_TGS_REP)
if __name__ == '__main__':
global_asn1_print = False
global_hexdump = False
import unittest
unittest.main()