[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Tue Nov 8 03:38:01 UTC 2022


The branch, master has been updated
       via  612eeff2704 tests/krb5: Add tests of PAC group handling
       via  53f9ac4b6fc tests/krb5: Allow checking domain SID in PAC
       via  8556576d8df tests/krb5: Overhaul PAC logon info group checking
       via  5a613db6f51 tests/krb5: Add (un)expected group parameters to get_service_ticket() and get_tgt()
       via  f59f6968003 tests/krb5: Allow creating accounts without Resource SID compression support
       via  29723765b31 tests/krb5: Allow adding multiple members to a group
       via  3a13e3b6667 tests/krb5: Allow creating groups with a specified type
       via  6674f67537d tests/krb5: Fix bits_to_etypes() to not fail on Resource SID compression bit
       via  90f39b69591 tests/krb5: Remember to pass in expected_groups parameter
       via  0161d375746 tests/krb5: Remove unused copy-and-paste remnant
       via  bdbe5c5a324 s4:kdc: add initial support for compound claims
       via  f96fbe6eb1f s4:kdc: fetch client_claims_blob from samba_kdc_get_pac_blobs()
       via  03250eefaaf s4:kdc: pass client_claims, device_info, device_claims into samba_make_krb5_pac()
       via  aa62775eb4f s4-auth: Make PAC parameters const
       via  7d3416e8cb6 krb5: Detect support for krb5_const_pac type
       via  6fe6992258d wafsamba: Have CHECK_C_PROTOTYPE() pass through 'lib' into CHECK_CODE()
       via  a3ee0ce255c wscript: Correctly determine dependencies for system Heimdal build
       via  77bb72d6720 build: Remove unused dependencies
      from  be1431a8930 smbd: Don't hide directories with "hide new files timeout"

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 612eeff2704bf6705b2ccce4006f7d9c6f0ee06a
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Thu Nov 3 14:49:17 2022 +1300

    tests/krb5: Add tests of PAC group handling
    
    In which we make AS and TGS requests and verify the SIDs we expect are
    returned in the PAC.
    
    Example command to test against Windows Server 2019 functional level
    2016 with FAST enabled:
    
    ADMIN_USERNAME=Administrator ADMIN_PASSWORD=locDCpass1 \
    CLAIMS_SUPPORT=1 COMPOUND_ID_SUPPORT=1 DC_SERVER=ADDC.EXAMPLE.COM \
    DOMAIN=EXAMPLE EXPECT_PAC=1 FAST_SUPPORT=1 KRB5_CONFIG=krb5.conf \
    PYTHONPATH=bin/python REALM=EXAMPLE.COM SERVER=ADDC.EXAMPLE.COM \
    SKIP_INVALID=1 SMB_CONF_PATH=smb.conf STRICT_CHECKING=1 \
    TKT_SIG_SUPPORT=1 python3 python/samba/tests/krb5/group_tests.py
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    
    Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
    Autobuild-Date(master): Tue Nov  8 03:37:37 UTC 2022 on sn-devel-184

commit 53f9ac4b6fc41cef4966b1f5eca0485be621f786
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Thu Nov 3 14:55:36 2022 +1300

    tests/krb5: Allow checking domain SID in PAC
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 8556576d8df47710757ff4e32b04668fa5045daf
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Thu Nov 3 14:54:23 2022 +1300

    tests/krb5: Overhaul PAC logon info group checking
    
    We can now verify attributes of SIDs and the PAC locations in which SIDs
    are placed. We also gain the ability to assert that no SIDs are present
    in the PAC other than the ones we expect.
    
    We lighten somewhat the requirement that no duplicates are present among
    the SIDs, as such a situation may arise even with Windows, especially if
    group types are changed. For example, if a Universal group containing a
    user is changed to a Domain-Local group in between an AS-REQ and a
    TGS-REQ, the group's SID will be added to the PAC once for each request.
    We only verify that there are no exact duplicates (SID, attributes, and
    PAC location all being identical).
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 5a613db6f511cfe3739cfe04cefa84e4f6681c99
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Thu Nov 3 14:51:26 2022 +1300

    tests/krb5: Add (un)expected group parameters to get_service_ticket() and get_tgt()
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit f59f6968003a3b314fb21ca84548806c03ae0b0a
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Thu Nov 3 14:48:09 2022 +1300

    tests/krb5: Allow creating accounts without Resource SID compression support
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 29723765b31866524b7db5c37600b8f6c9c0a2e7
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Thu Nov 3 14:47:51 2022 +1300

    tests/krb5: Allow adding multiple members to a group
    
    As well as passing in a single 'str', we can now choose to pass a
    collection of member DN strings.
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 3a13e3b6667909fbdafaf95be88106d138013f9c
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Thu Nov 3 14:46:53 2022 +1300

    tests/krb5: Allow creating groups with a specified type
    
    This will be useful for testing the handling of Domain-Local groups.
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 6674f67537d0cac81e40c2b88e882944cb368ad7
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Thu Nov 3 14:46:38 2022 +1300

    tests/krb5: Fix bits_to_etypes() to not fail on Resource SID compression bit
    
    It's not an encryption type bit, so we should ignore it here.
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 90f39b695916bb99c7a8d3cb5d6a1153b61b1dec
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Wed Nov 2 17:27:12 2022 +1300

    tests/krb5: Remember to pass in expected_groups parameter
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 0161d375746a1f5e145147d3ea4eb35f163bb5ec
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Thu Nov 3 14:48:48 2022 +1300

    tests/krb5: Remove unused copy-and-paste remnant
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit bdbe5c5a3241488ff638350aaf6e74d157490bb9
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Feb 25 00:28:01 2022 +0100

    s4:kdc: add initial support for compound claims
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit f96fbe6eb1f1f0fcf6ce2d72df5cc631f427bcf1
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Feb 25 00:19:06 2022 +0100

    s4:kdc: fetch client_claims_blob from samba_kdc_get_pac_blobs()
    
    The blob will be empty until we properly support claims.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 03250eefaaf21e819e8e855fc0db6ae25da6a9ee
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Feb 24 23:57:31 2022 +0100

    s4:kdc: pass client_claims, device_info, device_claims into samba_make_krb5_pac()
    
    This allows us to add claims blobs to the PAC once we have the ability
    to create them.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit aa62775eb4ff6e4cd50d8ef932a2c299509c39d9
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Tue Nov 1 19:01:15 2022 +1300

    s4-auth: Make PAC parameters const
    
    These functions have no need to modify the PACs passed in, and this
    change permits us to operate on const PACs in the KDC.
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 7d3416e8cb686453ecbedbc085073af95835001e
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Wed Nov 2 14:56:34 2022 +1300

    krb5: Detect support for krb5_const_pac type
    
    We can't unconditionally assume (as we did in
    third_party/heimdal_build/wscript_configure) that Heimdal has this type,
    since we may have an older system Heimdal that lacks it. We must also
    check whether krb5_pac_get_buffer() is usable with krb5_const_pac, and
    declare krb5_const_pac as a non-const typedef if not.
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 6fe6992258d2c59dfc8cb979deb25ba6020a1c06
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Thu Nov 3 17:35:58 2022 +1300

    wafsamba: Have CHECK_C_PROTOTYPE() pass through 'lib' into CHECK_CODE()
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit a3ee0ce255c7acb7abf58e70b75025b5fefdb275
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Thu Nov 3 17:35:35 2022 +1300

    wscript: Correctly determine dependencies for system Heimdal build
    
    Previously, the call to CHECK_BUNDLED_SYSTEM() in
    check_system_heimdal_lib() could have us pick up MIT Kerberos headers
    when we should only be using system Heimdal headers. Now, we just
    perform an explicit check for the functions we require, which should
    avoid any use of the MIT libraries.
    
    We also remove some library checks for Heimdal components that we don't
    use directly, restricting the checks to only the functions we need.
    
    Finally, we no longer need to recurse into third_party/heimdal_build
    when performing a system Heimdal build.
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 77bb72d67204b58d0ae7a183e2a8988597faf15c
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Thu Nov 3 17:31:20 2022 +1300

    build: Remove unused dependencies
    
    We don't need to include these any more, and removing them allows us to
    simplify the build system for system Heimdal builds.
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 auth/kerberos/wscript_build                      |    2 +-
 buildtools/wafsamba/samba_conftests.py           |    5 +-
 lib/krb5_wrap/krb5_samba.h                       |   13 +-
 lib/krb5_wrap/wscript_configure                  |   18 +
 python/samba/tests/krb5/group_tests.py           | 1203 ++++++++++++++++++++++
 python/samba/tests/krb5/kdc_base_test.py         |   40 +-
 python/samba/tests/krb5/protected_users_tests.py |    6 -
 python/samba/tests/krb5/raw_testcase.py          |  152 ++-
 python/samba/tests/krb5/s4u_tests.py             |   41 +-
 python/samba/tests/usage.py                      |    1 +
 selftest/knownfail_heimdal_kdc                   |   21 +
 selftest/knownfail_mit_kdc                       |   35 +
 source4/auth/kerberos/kerberos_pac.c             |    4 +-
 source4/auth/kerberos/wscript_build              |    2 +-
 source4/kdc/mit_samba.c                          |    6 +-
 source4/kdc/pac-glue.c                           |   75 +-
 source4/kdc/pac-glue.h                           |   10 +-
 source4/kdc/wdc-samba4.c                         |   84 +-
 source4/libcli/wscript_build                     |    1 -
 source4/selftest/tests.py                        |    4 +
 third_party/heimdal_build/wscript_configure      |    3 +-
 wscript                                          |    1 +
 wscript_build_system_heimdal                     |    8 +-
 wscript_configure_system_heimdal                 |   41 +-
 24 files changed, 1668 insertions(+), 108 deletions(-)
 create mode 100644 lib/krb5_wrap/wscript_configure
 create mode 100755 python/samba/tests/krb5/group_tests.py


Changeset truncated at 500 lines:

diff --git a/auth/kerberos/wscript_build b/auth/kerberos/wscript_build
index 1fa1b51138d..bf8b05c5364 100644
--- a/auth/kerberos/wscript_build
+++ b/auth/kerberos/wscript_build
@@ -1,4 +1,4 @@
 #!/usr/bin/env python
 bld.SAMBA_SUBSYSTEM('KRB5_PAC',
                     source='gssapi_pac.c kerberos_pac.c gssapi_helper.c',
-                    deps='gssapi_krb5 ndr-krb5pac krb5samba')
+                    deps='gssapi ndr-krb5pac krb5samba')
diff --git a/buildtools/wafsamba/samba_conftests.py b/buildtools/wafsamba/samba_conftests.py
index ef632ba9033..2c3149c0fa2 100644
--- a/buildtools/wafsamba/samba_conftests.py
+++ b/buildtools/wafsamba/samba_conftests.py
@@ -126,7 +126,7 @@ def CHECK_LARGEFILE(conf, define='HAVE_LARGEFILE'):
 
 
 @conf
-def CHECK_C_PROTOTYPE(conf, function, prototype, define, headers=None, msg=None):
+def CHECK_C_PROTOTYPE(conf, function, prototype, define, headers=None, msg=None, lib=None):
     '''verify that a C prototype matches the one on the current system'''
     if not conf.CHECK_DECLS(function, headers=headers):
         return False
@@ -138,7 +138,8 @@ def CHECK_C_PROTOTYPE(conf, function, prototype, define, headers=None, msg=None)
                            headers=headers,
                            link=False,
                            execute=False,
-                           msg=msg)
+                           msg=msg,
+                           lib=lib)
 
 
 @conf
diff --git a/lib/krb5_wrap/krb5_samba.h b/lib/krb5_wrap/krb5_samba.h
index 93a010323bf..79178ac8008 100644
--- a/lib/krb5_wrap/krb5_samba.h
+++ b/lib/krb5_wrap/krb5_samba.h
@@ -135,7 +135,18 @@ typedef struct {
 #endif /* HAVE_E_DATA_POINTER_IN_KRB5_ERROR */
 
 #ifndef HAVE_KRB5_CONST_PAC
-typedef krb5_pac krb5_const_pac;
+#ifdef KRB5_CONST_PAC_GET_BUFFER
+typedef const struct krb5_pac_data *krb5_const_pac;
+#else
+/*
+ * Certain Heimdal versions include a version of krb5_pac_get_buffer() that is
+ * unusable in certain cases, taking a krb5_pac when a krb5_const_pac may be all
+ * that we can supply. Furthermore, MIT Kerberos doesn't declare krb5_const_pac
+ * at all. In such cases, we must declare krb5_const_pac as a non-const typedef
+ * so that the build can succeed.
+ */
+typedef struct krb5_pac_data *krb5_const_pac;
+#endif
 #endif
 
 krb5_error_code smb_krb5_parse_name(krb5_context context,
diff --git a/lib/krb5_wrap/wscript_configure b/lib/krb5_wrap/wscript_configure
new file mode 100644
index 00000000000..b595eef679c
--- /dev/null
+++ b/lib/krb5_wrap/wscript_configure
@@ -0,0 +1,18 @@
+#!/usr/bin/env python
+
+# Check whether we have the krb5_const_pac type, if we aren't sure already.
+if conf.CONFIG_SET('HAVE_KRB5_CONST_PAC') or (
+        conf.CHECK_TYPE('krb5_const_pac',
+                        headers='krb5.h',
+                        lib='krb5')):
+    # If the type is available, check whether krb5_pac_get_buffer() accepts it
+    # as its second parameter, or whether it takes krb5_pac instead.
+    conf.CHECK_C_PROTOTYPE('krb5_pac_get_buffer',
+                           'krb5_error_code krb5_pac_get_buffer('
+                           '    krb5_context context,'
+                           '    krb5_const_pac p,'
+                           '    uint32_t type,'
+                           '    krb5_data *data)',
+                           define='KRB5_CONST_PAC_GET_BUFFER',
+                           headers='krb5.h',
+                           lib='krb5')
diff --git a/python/samba/tests/krb5/group_tests.py b/python/samba/tests/krb5/group_tests.py
new file mode 100755
index 00000000000..471b06e6cbb
--- /dev/null
+++ b/python/samba/tests/krb5/group_tests.py
@@ -0,0 +1,1203 @@
+#!/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 os
+import re
+import sys
+
+from enum import Enum
+from functools import partial
+
+import ldb
+
+from samba.dcerpc import krb5pac, netlogon, samr, security
+from samba.dsdb import (
+    GTYPE_SECURITY_DOMAIN_LOCAL_GROUP,
+    GTYPE_SECURITY_GLOBAL_GROUP,
+    GTYPE_SECURITY_UNIVERSAL_GROUP,
+)
+from samba.tests import DynamicTestCase, env_get_var_value
+from samba.tests.krb5 import kcrypto
+from samba.tests.krb5.kdc_base_test import KDCBaseTest
+from samba.tests.krb5.raw_testcase import RawKerberosTest
+from samba.tests.krb5.rfc4120_constants import (
+    KRB_TGS_REP,
+    NT_PRINCIPAL,
+)
+
+SidType = RawKerberosTest.SidType
+
+sys.path.insert(0, 'bin/python')
+os.environ['PYTHONUNBUFFERED'] = '1'
+
+global_asn1_print = False
+global_hexdump = False
+
+
+class GroupType(Enum):
+    GLOBAL = GTYPE_SECURITY_GLOBAL_GROUP
+    DOMAIN_LOCAL = GTYPE_SECURITY_DOMAIN_LOCAL_GROUP
+    UNIVERSAL = GTYPE_SECURITY_UNIVERSAL_GROUP
+
+
+# This simple class encapsulates the DN and SID of a Principal.
+class Principal:
+    def __init__(self, dn, sid):
+        if not isinstance(dn, ldb.Dn):
+            raise AssertionError(f'expected {dn} to be an ldb.Dn')
+
+        self.dn = dn
+        self.sid = sid
+
+
+ at DynamicTestCase
+class GroupTests(KDCBaseTest):
+    # A placeholder object that represents the user account undergoing testing.
+    user = object()
+
+    # Constants for group SID attributes.
+    default_attrs = (security.SE_GROUP_MANDATORY |
+                     security.SE_GROUP_ENABLED_BY_DEFAULT |
+                     security.SE_GROUP_ENABLED)
+    resource_attrs = default_attrs | security.SE_GROUP_RESOURCE
+
+    asserted_identity = security.SID_AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY
+
+    def setUp(self):
+        super().setUp()
+        self.do_asn1_print = global_asn1_print
+        self.do_hexdump = global_hexdump
+
+    @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')
+            if FILTER and not re.search(FILTER, name):
+                continue
+            name = re.sub(r'\W+', '_', name)
+
+            cls.generate_dynamic_test('test_group', name,
+                                      dict(case))
+
+    # Enable or disable resource SID compression on the krbtgt
+    # account. Depending on how the KDC chooses to handle SID compression, this
+    # may or may not have any real effect.
+    def set_krbtgt_sid_compression(self, compression):
+        krbtgt_creds = self.get_krbtgt_creds()
+        krbtgt_dn = krbtgt_creds.get_dn()
+
+        samdb = self.get_samdb()
+
+        # Get the current supported encryption types of the krbtgt account.
+        res = samdb.search(krbtgt_dn,
+                           scope=ldb.SCOPE_BASE,
+                           attrs=['msDS-SupportedEncryptionTypes'])
+        orig_msg = res[0]
+        krbtgt_enctypes = orig_msg.get(
+            'msDS-SupportedEncryptionTypes', idx=0)
+        if krbtgt_enctypes is None:
+            # Setting the enctypes isn't likely to accomplish anything.
+            return
+
+        krbtgt_enctypes = int(krbtgt_enctypes)
+
+        # Enable or disable the compression bit.
+        if compression:
+            set_krbtgt_enctypes = krbtgt_enctypes | (
+                security.KERB_ENCTYPE_RESOURCE_SID_COMPRESSION_DISABLED)
+        else:
+            set_krbtgt_enctypes = krbtgt_enctypes & ~(
+                security.KERB_ENCTYPE_RESOURCE_SID_COMPRESSION_DISABLED)
+
+        if krbtgt_enctypes == set_krbtgt_enctypes:
+            # Nothing to do.
+            return
+
+        msg = ldb.Message(krbtgt_dn)
+        msg['msDS-SupportedEncryptionTypes'] = ldb.MessageElement(
+            str(set_krbtgt_enctypes),
+            ldb.FLAG_MOD_REPLACE,
+            'msDS-SupportedEncryptionTypes')
+
+        # Clean up the change afterwards.
+        diff = samdb.msg_diff(msg, orig_msg)
+        self.addCleanup(samdb.modify, diff)
+
+        samdb.modify(msg)
+
+        # Make sure the value remains as we set it.
+        res = samdb.search(krbtgt_dn,
+                           scope=ldb.SCOPE_BASE,
+                           attrs=['msDS-SupportedEncryptionTypes'])
+        new_krbtgt_enctypes = res[0].get(
+            'msDS-SupportedEncryptionTypes', idx=0)
+        self.assertIsNotNone(new_krbtgt_enctypes)
+        new_krbtgt_enctypes = int(new_krbtgt_enctypes)
+        self.assertEqual(set_krbtgt_enctypes, new_krbtgt_enctypes,
+                         'failed to set krbtgt supported enctypes')
+
+    # Get a ticket with the SIDs in the PAC replaced with ones we specify. This
+    # is useful for creating arbitrary tickets that can be used to perform a
+    # TGS-REQ.
+    def ticket_with_sids(self, ticket, new_sids, domain_sid):
+        krbtgt_creds = self.get_krbtgt_creds()
+        krbtgt_key = self.TicketDecryptionKey_from_creds(krbtgt_creds)
+
+        checksum_keys = {
+            krb5pac.PAC_TYPE_KDC_CHECKSUM: krbtgt_key
+        }
+
+        modify_pac_fn = partial(self.set_pac_sids,
+                                new_sids=new_sids,
+                                domain_sid=domain_sid)
+
+        return self.modified_ticket(ticket,
+                                    modify_pac_fn=modify_pac_fn,
+                                    checksum_keys=checksum_keys)
+
+    # Replace the SIDs in a PAC with 'new_sids'.
+    def set_pac_sids(self, pac, new_sids, domain_sid):
+        base_sids = []
+        extra_sids = []
+        resource_sids = []
+
+        resource_domain = None
+
+        # Filter our SIDs into three arrays depending on their ultimate
+        # location in the PAC.
+        for sid, sid_type, attrs in new_sids:
+            if sid_type is self.SidType.BASE_SID:
+                domain, rid = sid.rsplit('-', 1)
+                self.assertEqual(domain_sid, domain,
+                                 'base SIDs must be in our domain')
+
+                base_sid = samr.RidWithAttribute()
+                base_sid.rid = int(rid)
+                base_sid.attributes = attrs
+
+                base_sids.append(base_sid)
+            elif sid_type is self.SidType.EXTRA_SID:
+                extra_sid = netlogon.netr_SidAttr()
+                extra_sid.sid = security.dom_sid(sid)
+                extra_sid.attributes = attrs
+
+                extra_sids.append(extra_sid)
+            elif sid_type is self.SidType.RESOURCE_SID:
+                domain, rid = sid.rsplit('-', 1)
+                if resource_domain is None:
+                    resource_domain = domain
+                else:
+                    self.assertEqual(resource_domain, domain,
+                                     'resource SIDs must share the same '
+                                     'domain')
+
+                resource_sid = samr.RidWithAttribute()
+                resource_sid.rid = int(rid)
+                resource_sid.attributes = attrs
+
+                resource_sids.append(resource_sid)
+            else:
+                self.fail(f'invalid SID type {sid_type}')
+
+        pac_buffers = pac.buffers
+        for pac_buffer in pac_buffers:
+            # Find the LOGON_INFO PAC buffer.
+            if pac_buffer.type == krb5pac.PAC_TYPE_LOGON_INFO:
+                logon_info = pac_buffer.info.info
+
+                # Add Extra SIDs and set the EXTRA_SIDS flag as needed.
+                logon_info.info3.sidcount = len(extra_sids)
+                if extra_sids:
+                    logon_info.info3.sids = extra_sids
+                    logon_info.info3.base.user_flags |= (
+                        netlogon.NETLOGON_EXTRA_SIDS)
+                else:
+                    logon_info.info3.sids = None
+                    logon_info.info3.base.user_flags &= ~(
+                        netlogon.NETLOGON_EXTRA_SIDS)
+
+                # Add Base SIDs.
+                logon_info.info3.base.groups.count = len(base_sids)
+                if base_sids:
+                    logon_info.info3.base.groups.rids = base_sids
+                else:
+                    logon_info.info3.base.groups.rids = None
+
+                # Add Resource SIDs and set the RESOURCE_GROUPS flag as needed.
+                logon_info.resource_groups.groups.count = len(resource_sids)
+                if resource_sids:
+                    resource_domain = security.dom_sid(resource_domain)
+                    logon_info.resource_groups.domain_sid = resource_domain
+                    logon_info.resource_groups.groups.rids = resource_sids
+                    logon_info.info3.base.user_flags |= (
+                        netlogon.NETLOGON_RESOURCE_GROUPS)
+                else:
+                    logon_info.resource_groups.domain_sid = None
+                    logon_info.resource_groups.groups.rids = None
+                    logon_info.info3.base.user_flags &= ~(
+                        netlogon.NETLOGON_RESOURCE_GROUPS)
+
+                break
+        else:
+            self.fail('no LOGON_INFO PAC buffer')
+
+        pac.buffers = pac_buffers
+
+        return pac
+
+    # A list of test cases.
+    cases = [
+        # AS-REQ tests.
+        {
+            'test': 'universal; as-req to krbtgt',
+            'groups': {
+                # A Universal group containing the user.
+                'foo': (GroupType.UNIVERSAL, {user}),
+            },
+            # Make an AS-REQ to the krbtgt with the user's account.
+            'as:to_krbtgt': True,
+            'as:expected': {
+                # Ignoring the user ID, or base RID, expect the PAC to contain
+                # precisely the following SIDS in any order:
+                ('foo', SidType.BASE_SID, default_attrs),
+                (asserted_identity, SidType.EXTRA_SID, default_attrs),
+                (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
+                (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
+            },
+        },
+        {
+            'test': 'universal; as-req to service',
+            'groups': {
+                'foo': (GroupType.UNIVERSAL, {user}),
+            },
+            # The same again, but this time perform the AS-REQ to a service.
+            'as:to_krbtgt': False,
+            'as:expected': {
+                ('foo', SidType.BASE_SID, default_attrs),
+                (asserted_identity, SidType.EXTRA_SID, default_attrs),
+                (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
+                (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
+            },
+        },
+        {
+            'test': 'global; as-req to krbtgt',
+            'groups': {
+                # The behaviour should be the same with a Global group.
+                'foo': (GroupType.GLOBAL, {user}),
+            },
+            'as:to_krbtgt': True,
+            'as:expected': {
+                ('foo', SidType.BASE_SID, default_attrs),
+                (asserted_identity, SidType.EXTRA_SID, default_attrs),
+                (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
+                (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
+            },
+        },
+        {
+            'test': 'global; as-req to service',
+            'groups': {
+                'foo': (GroupType.GLOBAL, {user}),
+            },
+            'as:to_krbtgt': False,
+            'as:expected': {
+                ('foo', SidType.BASE_SID, default_attrs),
+                (asserted_identity, SidType.EXTRA_SID, default_attrs),
+                (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
+                (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
+            },
+        },
+        {
+            'test': 'domain-local; as-req to krbtgt',
+            'groups': {
+                # A Domain-local group containing the user.
+                'foo': (GroupType.DOMAIN_LOCAL, {user}),
+            },
+            'as:to_krbtgt': True,
+            'as:expected': {
+                # A TGT will not contain domain-local groups the user belongs
+                # to.
+                (asserted_identity, SidType.EXTRA_SID, default_attrs),
+                (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
+                (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
+            },
+        },
+        {
+            'test': 'domain-local; compression; as-req to service',
+            'groups': {
+                'foo': (GroupType.DOMAIN_LOCAL, {user}),
+            },
+            'as:to_krbtgt': False,
+            'as:expected': {
+                # However, a service ticket will include domain-local
+                # groups. The account supports SID compression, so they are
+                # added as resource SIDs.
+                ('foo', SidType.RESOURCE_SID, resource_attrs),
+                (asserted_identity, SidType.EXTRA_SID, default_attrs),
+                (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
+                (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
+            },
+        },
+        {
+            'test': 'domain-local; no compression; as-req to service',
+            'groups': {
+                'foo': (GroupType.DOMAIN_LOCAL, {user}),
+            },
+            'as:to_krbtgt': False,
+            # This time, the target account disclaims support for SID
+            # compression.
+            'as:compression': False,
+            'as:expected': {
+                # The SIDs in the PAC are the same, except the group SID is
+                # placed in Extra SIDs, not Resource SIDs.
+                ('foo', SidType.EXTRA_SID, resource_attrs),
+                (asserted_identity, SidType.EXTRA_SID, default_attrs),
+                (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
+                (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
+            },
+        },
+        {
+            'test': 'nested domain-local; as-req to krbtgt',
+            'groups': {
+                # A Universal group containing a Domain-local group containing
+                # the user.
+                'universal': (GroupType.UNIVERSAL, {'dom-local'}),
+                'dom-local': (GroupType.DOMAIN_LOCAL, {user}),
+            },
+            # It is not possible in Windows for a Universal group to contain a
+            # Domain-local group without exploiting bugs. This flag provides a
+            # convenient means by which these tests can be skipped.
+            'configuration_invalid': True,
+            'as:to_krbtgt': True,
+            'as:expected': {
+                # While Windows would exclude the universal group from the PAC,
+                # expecting its inclusion is more sensible on the whole.
+                ('universal', SidType.BASE_SID, default_attrs),
+                (asserted_identity, SidType.EXTRA_SID, default_attrs),
+                (security.DOMAIN_RID_USERS, SidType.BASE_SID, default_attrs),
+                (security.SID_CLAIMS_VALID, SidType.EXTRA_SID, default_attrs),
+            },
+        },
+        {
+            'test': 'nested domain-local; compression; as-req to service',
+            'groups': {
+                'universal': (GroupType.UNIVERSAL, {'dom-local'}),
+                'dom-local': (GroupType.DOMAIN_LOCAL, {user}),
+            },
+            'configuration_invalid': True,
+            'as:to_krbtgt': False,
+            'as:expected': {
+                # A service ticket is expected to include both SIDs.


-- 
Samba Shared Repository



More information about the samba-cvs mailing list