The Samba-Bugzilla – Attachment 16873 Details for
Bug 14881
Backport bronze bit fixes, tests, and selftest improvements
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
patch from master backported to 4.14 (v4)
bronze-bit-samba-4.14-v4.patch (text/plain), 719.34 KB, created by
Andrew Bartlett
on 2021-10-26 08:48:26 UTC
(
hide
)
Description:
patch from master backported to 4.14 (v4)
Filename:
MIME Type:
Creator:
Andrew Bartlett
Created:
2021-10-26 08:48:26 UTC
Size:
719.34 KB
patch
obsolete
>From 18db9ec01e9d9cc27e1da98208041c6ef985ddc3 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 1 Sep 2021 15:39:19 +1200 >Subject: [PATCH 001/159] krb5pac.idl: Add ticket checksum PAC buffer type > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >(cherry picked from commit ff2f38fae79220e16765e17671972f9a55eb7cce) >--- > librpc/idl/krb5pac.idl | 4 +++- > 1 file changed, 3 insertions(+), 1 deletion(-) > >diff --git a/librpc/idl/krb5pac.idl b/librpc/idl/krb5pac.idl >index fb360c1257f..3239d7656b6 100644 >--- a/librpc/idl/krb5pac.idl >+++ b/librpc/idl/krb5pac.idl >@@ -112,7 +112,8 @@ interface krb5pac > PAC_TYPE_KDC_CHECKSUM = 7, > PAC_TYPE_LOGON_NAME = 10, > PAC_TYPE_CONSTRAINED_DELEGATION = 11, >- PAC_TYPE_UPN_DNS_INFO = 12 >+ PAC_TYPE_UPN_DNS_INFO = 12, >+ PAC_TYPE_TICKET_CHECKSUM = 16 > } PAC_TYPE; > > typedef struct { >@@ -128,6 +129,7 @@ interface krb5pac > [case(PAC_TYPE_CONSTRAINED_DELEGATION)][subcontext(0xFFFFFC01)] > PAC_CONSTRAINED_DELEGATION_CTR constrained_delegation; > [case(PAC_TYPE_UPN_DNS_INFO)] PAC_UPN_DNS_INFO upn_dns_info; >+ [case(PAC_TYPE_TICKET_CHECKSUM)] PAC_SIGNATURE_DATA ticket_checksum; > /* when new PAC info types are added they are supposed to be done > in such a way that they are backwards compatible with existing > servers. This makes it safe to just use a [default] for >-- >2.25.1 > > >From 4cc7d0d6b4a60fb45856c01e75b01de14ad9d033 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 1 Sep 2021 15:40:59 +1200 >Subject: [PATCH 002/159] security.idl: Add well-known SIDs for FAST > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >(cherry picked from commit 0092b4a3ed58b2c256d4dd9117cce927a3edde12) >--- > librpc/idl/security.idl | 3 +++ > 1 file changed, 3 insertions(+) > >diff --git a/librpc/idl/security.idl b/librpc/idl/security.idl >index 06bf7449a70..3df96dedbdd 100644 >--- a/librpc/idl/security.idl >+++ b/librpc/idl/security.idl >@@ -295,6 +295,9 @@ interface security > const string SID_AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY = "S-1-18-1"; > const string SID_SERVICE_ASSERTED_IDENTITY = "S-1-18-2"; > >+ const string SID_COMPOUNDED_AUTHENTICATION = "S-1-5-21-0-0-0-496"; >+ const string SID_CLAIMS_VALID = "S-1-5-21-0-0-0-497"; >+ > /* > * http://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx > */ >-- >2.25.1 > > >From 8a0332df8b03133391b99db5285f661e756df6f9 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 1 Sep 2021 15:46:42 +1200 >Subject: [PATCH 003/159] tests/krb5: Calculate expected salt if not given > explicitly > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >(cherry picked from commit c6badf818e9db44461979a931c74fc5ab6e80132) >--- > python/samba/tests/krb5/as_req_tests.py | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/as_req_tests.py b/python/samba/tests/krb5/as_req_tests.py >index 82ff3f4845c..09160bf6814 100755 >--- a/python/samba/tests/krb5/as_req_tests.py >+++ b/python/samba/tests/krb5/as_req_tests.py >@@ -74,7 +74,7 @@ class AsReqKerberosTests(KDCBaseTest): > expected_cname = cname > expected_srealm = realm > expected_sname = sname >- expected_salt = client_creds.get_forced_salt() >+ expected_salt = client_creds.get_salt() > > if any(etype in client_as_etypes and etype in initial_etypes > for etype in (kcrypto.Enctype.AES256, >@@ -142,7 +142,7 @@ class AsReqKerberosTests(KDCBaseTest): > expected_cname = cname > expected_srealm = realm > expected_sname = sname >- expected_salt = client_creds.get_forced_salt() >+ expected_salt = client_creds.get_salt() > > till = self.get_KerberosTime(offset=36000) > >-- >2.25.1 > > >From 483bce295e23421b29248a10b4f058375a67ce8f Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 1 Sep 2021 15:50:26 +1200 >Subject: [PATCH 004/159] tests/krb5: Add methods to obtain the length of > checksum types > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >(cherry picked from commit 9924dd976183ea62b08f116f8b8bacc698bb9b95) >--- > python/samba/tests/krb5/kcrypto.py | 26 ++++++++++++++++++++++++++ > 1 file changed, 26 insertions(+) > >diff --git a/python/samba/tests/krb5/kcrypto.py b/python/samba/tests/krb5/kcrypto.py >index ce7b00bda4c..4a4a12a66d4 100755 >--- a/python/samba/tests/krb5/kcrypto.py >+++ b/python/samba/tests/krb5/kcrypto.py >@@ -478,6 +478,7 @@ class _ChecksumProfile(object): > # define: > # * checksum > # * verify (if verification is not just checksum-and-compare) >+ # * checksum_len > @classmethod > def verify(cls, key, keyusage, text, cksum): > expected = cls.checksum(key, keyusage, text) >@@ -504,6 +505,10 @@ class _SimplifiedChecksum(_ChecksumProfile): > raise ValueError('Wrong key type for checksum') > super(_SimplifiedChecksum, cls).verify(key, keyusage, text, cksum) > >+ @classmethod >+ def checksum_len(cls): >+ return cls.macsize >+ > > class _SHA1AES128(_SimplifiedChecksum): > macsize = 12 >@@ -533,6 +538,10 @@ class _HMACMD5(_ChecksumProfile): > raise ValueError('Wrong key type for checksum') > super(_HMACMD5, cls).verify(key, keyusage, text, cksum) > >+ @classmethod >+ def checksum_len(cls): >+ return hashes.MD5.digest_size >+ > > class _MD5(_ChecksumProfile): > @classmethod >@@ -540,6 +549,10 @@ class _MD5(_ChecksumProfile): > # This is unkeyed! > return SIMPLE_HASH(text, hashes.MD5) > >+ @classmethod >+ def checksum_len(cls): >+ return hashes.MD5.digest_size >+ > > class _SHA1(_ChecksumProfile): > @classmethod >@@ -547,6 +560,10 @@ class _SHA1(_ChecksumProfile): > # This is unkeyed! > return SIMPLE_HASH(text, hashes.SHA1) > >+ @classmethod >+ def checksum_len(cls): >+ return hashes.SHA1.digest_size >+ > > class _CRC32(_ChecksumProfile): > @classmethod >@@ -555,6 +572,10 @@ class _CRC32(_ChecksumProfile): > cksum = (~crc32(text, 0xffffffff)) & 0xffffffff > return pack('<I', cksum) > >+ @classmethod >+ def checksum_len(cls): >+ return 4 >+ > > _enctype_table = { > Enctype.DES3: _DES3CBC, >@@ -643,6 +664,11 @@ def verify_checksum(cksumtype, key, keyusage, text, cksum): > c.verify(key, keyusage, text, cksum) > > >+def checksum_len(cksumtype): >+ c = _get_checksum_profile(cksumtype) >+ return c.checksum_len() >+ >+ > def prfplus(key, pepper, ln): > # Produce ln bytes of output using the RFC 6113 PRF+ function. > out = b'' >-- >2.25.1 > > >From 0a5c985894b01ba65f61aa29b6d7319b509b19b2 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 1 Sep 2021 15:57:26 +1200 >Subject: [PATCH 005/159] tests/krb5: Use signed integers to represent key > version numbers in ASN.1 > >As specified in 'MS-KILE 3.1.5.8: Key Version Numbers', Windows uses >signed 32-bit integers to represent key version numbers. This makes a >difference for an RODC with a msDS-SecondaryKrbTgtNumber greater than >32767, where the kvno should be encoded in four bytes rather than five. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >(cherry picked from commit 448b661bf8815a05f534926d8ee8d6f57d123c2c) >--- > python/samba/tests/krb5/raw_testcase.py | 2 +- > python/samba/tests/krb5/rfc4120.asn1 | 2 +- > python/samba/tests/krb5/rfc4120_pyasn1.py | 2 +- > 3 files changed, 3 insertions(+), 3 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 6db17f2a118..c5ee5eb6083 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -995,7 +995,7 @@ class RawKerberosTest(TestCaseInTempDir): > def EncryptedData_create(self, key, usage, plaintext): > # EncryptedData ::= SEQUENCE { > # etype [0] Int32 -- EncryptionType --, >- # kvno [1] UInt32 OPTIONAL, >+ # kvno [1] Int32 OPTIONAL, > # cipher [2] OCTET STRING -- ciphertext > # } > ciphertext = key.encrypt(usage, plaintext) >diff --git a/python/samba/tests/krb5/rfc4120.asn1 b/python/samba/tests/krb5/rfc4120.asn1 >index f47c1d00202..a37011ae932 100644 >--- a/python/samba/tests/krb5/rfc4120.asn1 >+++ b/python/samba/tests/krb5/rfc4120.asn1 >@@ -124,7 +124,7 @@ KerberosFlags ::= BIT STRING (SIZE (1..32)) > > EncryptedData ::= SEQUENCE { > etype [0] EncryptionType, --Int32 EncryptionType -- >- kvno [1] UInt32 OPTIONAL, >+ kvno [1] Int32 OPTIONAL, > cipher [2] OCTET STRING -- ciphertext > } > >diff --git a/python/samba/tests/krb5/rfc4120_pyasn1.py b/python/samba/tests/krb5/rfc4120_pyasn1.py >index 39ec8ed7982..a9e4bcbb18f 100644 >--- a/python/samba/tests/krb5/rfc4120_pyasn1.py >+++ b/python/samba/tests/krb5/rfc4120_pyasn1.py >@@ -120,7 +120,7 @@ class EncryptedData(univ.Sequence): > > EncryptedData.componentType = namedtype.NamedTypes( > namedtype.NamedType('etype', EncryptionType().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), >- namedtype.OptionalNamedType('kvno', UInt32().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), >+ namedtype.OptionalNamedType('kvno', Int32().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), > namedtype.NamedType('cipher', univ.OctetString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))) > ) > >-- >2.25.1 > > >From 276c0e66d8c55ea0dffcc431e4ef1c12d74ae15f Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 1 Sep 2021 16:05:39 +1200 >Subject: [PATCH 006/159] tests/krb5: Add KDCOptions flag for constrained > delegation > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >(cherry picked from commit 08086c43987abecc588ebd32ec846ff7e27a83b6) >--- > python/samba/tests/krb5/rfc4120.asn1 | 1 + > python/samba/tests/krb5/rfc4120_pyasn1.py | 1 + > 2 files changed, 2 insertions(+) > >diff --git a/python/samba/tests/krb5/rfc4120.asn1 b/python/samba/tests/krb5/rfc4120.asn1 >index a37011ae932..e0831e1f86f 100644 >--- a/python/samba/tests/krb5/rfc4120.asn1 >+++ b/python/samba/tests/krb5/rfc4120.asn1 >@@ -632,6 +632,7 @@ KDCOptionsValues ::= BIT STRING { -- KerberosFlags > opt-hardware-auth(11), > unused12(12), > unused13(13), >+ cname-in-addl-tkt(14), > -- Canonicalize is used by RFC 6806 > canonicalize(15), > -- 26 was unused in 1510 >diff --git a/python/samba/tests/krb5/rfc4120_pyasn1.py b/python/samba/tests/krb5/rfc4120_pyasn1.py >index a9e4bcbb18f..348dd8c63fb 100644 >--- a/python/samba/tests/krb5/rfc4120_pyasn1.py >+++ b/python/samba/tests/krb5/rfc4120_pyasn1.py >@@ -649,6 +649,7 @@ KDCOptionsValues.namedValues = namedval.NamedValues( > ('opt-hardware-auth', 11), > ('unused12', 12), > ('unused13', 13), >+ ('cname-in-addl-tkt', 14), > ('canonicalize', 15), > ('disable-transited-check', 26), > ('renewable-ok', 27), >-- >2.25.1 > > >From cc383a5a9f397fca600e558946b5a53472fb87a7 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 1 Sep 2021 16:21:55 +1200 >Subject: [PATCH 007/159] tests/krb5: Use more compact dict lookup > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >(cherry picked from commit 3fd73b65a3db405db5a0a82cca6c808763d4f437) >--- > python/samba/tests/krb5/raw_testcase.py | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index c5ee5eb6083..0ec0f65c6d6 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -305,7 +305,7 @@ class KerberosCredentials(Credentials): > > def get_forced_key(self, etype): > etype = int(etype) >- return self.forced_keys.get(etype, None) >+ return self.forced_keys.get(etype) > > def set_forced_salt(self, salt): > self.forced_salt = bytes(salt) >@@ -830,7 +830,7 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertIsNotNone(value) > > def getElementValue(self, obj, elem): >- return obj.get(elem, None) >+ return obj.get(elem) > > def assertElementMissing(self, obj, elem): > v = self.getElementValue(obj, elem) >@@ -942,7 +942,7 @@ class RawKerberosTest(TestCaseInTempDir): > def PasswordKey_from_etype_info2(self, creds, etype_info2, kvno=None): > e = etype_info2['etype'] > >- salt = etype_info2.get('salt', None) >+ salt = etype_info2.get('salt') > > if e == kcrypto.Enctype.RC4: > nthash = creds.get_nt_hash() >-- >2.25.1 > > >From 843eb59248f22dc84449f4a782462cb6574dc844 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 1 Sep 2021 16:31:56 +1200 >Subject: [PATCH 008/159] tests/krb5: Replace expected_cname_private with > expected_anon parameter > >This is used in the case where the KDC returns 'WELLKNOWN/ANONYMOUS' as >the cname, and makes the reply checking logic easier to follow. This >also removes the need to fetch the client credentials in the test >methods. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >(cherry picked from commit bf55786fcd9a96daa9002661d6f5d9b3502ed8a7) >--- > python/samba/tests/krb5/fast_tests.py | 33 +++++------------------- > python/samba/tests/krb5/raw_testcase.py | 34 ++++++++++++------------- > 2 files changed, 24 insertions(+), 43 deletions(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index 2d4b69f8590..b371ab617aa 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -49,7 +49,6 @@ from samba.tests.krb5.rfc4120_constants import ( > KU_TICKET, > NT_PRINCIPAL, > NT_SRV_INST, >- NT_WELLKNOWN, > PADATA_FX_COOKIE, > PADATA_FX_FAST, > PADATA_PAC_OPTIONS >@@ -985,14 +984,6 @@ class FAST_Tests(KDCBaseTest): > ]) > > def test_fast_hide_client_names(self): >- user_creds = self.get_client_creds() >- user_name = user_creds.get_username() >- user_cname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >- names=[user_name]) >- >- expected_cname = self.PrincipalName_create( >- name_type=NT_WELLKNOWN, names=['WELLKNOWN', 'ANONYMOUS']) >- > self._run_test_sequence([ > { > 'rep_type': KRB_AS_REP, >@@ -1001,7 +992,7 @@ class FAST_Tests(KDCBaseTest): > 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, > 'gen_armor_tgt_fn': self.get_mach_tgt, > 'fast_options': '01', # hide client names >- 'expected_cname': expected_cname >+ 'expected_anon': True > }, > { > 'rep_type': KRB_AS_REP, >@@ -1011,20 +1002,11 @@ class FAST_Tests(KDCBaseTest): > 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, > 'gen_armor_tgt_fn': self.get_mach_tgt, > 'fast_options': '01', # hide client names >- 'expected_cname': expected_cname, >- 'expected_cname_private': user_cname >+ 'expected_anon': True > } > ]) > > def test_fast_tgs_hide_client_names(self): >- user_creds = self.get_client_creds() >- user_name = user_creds.get_username() >- user_cname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >- names=[user_name]) >- >- expected_cname = self.PrincipalName_create( >- name_type=NT_WELLKNOWN, names=['WELLKNOWN', 'ANONYMOUS']) >- > self._run_test_sequence([ > { > 'rep_type': KRB_TGS_REP, >@@ -1033,8 +1015,7 @@ class FAST_Tests(KDCBaseTest): > 'gen_tgt_fn': self.get_user_tgt, > 'fast_armor': None, > 'fast_options': '01', # hide client names >- 'expected_cname': expected_cname, >- 'expected_cname_private': user_cname >+ 'expected_anon': True > } > ]) > >@@ -1216,8 +1197,8 @@ class FAST_Tests(KDCBaseTest): > srealm = target_realm > > expected_cname = kdc_dict.pop('expected_cname', client_cname) >- expected_cname_private = kdc_dict.pop('expected_cname_private', >- None) >+ expected_anon = kdc_dict.pop('expected_anon', >+ False) > expected_crealm = kdc_dict.pop('expected_crealm', client_realm) > expected_sname = kdc_dict.pop('expected_sname', sname) > expected_srealm = kdc_dict.pop('expected_srealm', srealm) >@@ -1341,7 +1322,7 @@ class FAST_Tests(KDCBaseTest): > kdc_exchange_dict = self.as_exchange_dict( > expected_crealm=expected_crealm, > expected_cname=expected_cname, >- expected_cname_private=expected_cname_private, >+ expected_anon=expected_anon, > expected_srealm=expected_srealm, > expected_sname=expected_sname, > ticket_decryption_key=krbtgt_decryption_key, >@@ -1370,7 +1351,7 @@ class FAST_Tests(KDCBaseTest): > kdc_exchange_dict = self.tgs_exchange_dict( > expected_crealm=expected_crealm, > expected_cname=expected_cname, >- expected_cname_private=expected_cname_private, >+ expected_anon=expected_anon, > expected_srealm=expected_srealm, > expected_sname=expected_sname, > ticket_decryption_key=target_decryption_key, >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 0ec0f65c6d6..e4dbb10d135 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1721,7 +1721,7 @@ class RawKerberosTest(TestCaseInTempDir): > def as_exchange_dict(self, > expected_crealm=None, > expected_cname=None, >- expected_cname_private=None, >+ expected_anon=False, > expected_srealm=None, > expected_sname=None, > ticket_decryption_key=None, >@@ -1759,6 +1759,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'rep_encpart_asn1Spec': krb5_asn1.EncASRepPart, > 'expected_crealm': expected_crealm, > 'expected_cname': expected_cname, >+ 'expected_anon': expected_anon, > 'expected_srealm': expected_srealm, > 'expected_sname': expected_sname, > 'ticket_decryption_key': ticket_decryption_key, >@@ -1784,10 +1785,6 @@ class RawKerberosTest(TestCaseInTempDir): > 'inner_req': inner_req, > 'outer_req': outer_req > } >- if expected_cname_private is not None: >- kdc_exchange_dict['expected_cname_private'] = ( >- expected_cname_private) >- > if callback_dict is None: > callback_dict = {} > >@@ -1796,7 +1793,7 @@ class RawKerberosTest(TestCaseInTempDir): > def tgs_exchange_dict(self, > expected_crealm=None, > expected_cname=None, >- expected_cname_private=None, >+ expected_anon=False, > expected_srealm=None, > expected_sname=None, > ticket_decryption_key=None, >@@ -1834,6 +1831,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'rep_encpart_asn1Spec': krb5_asn1.EncTGSRepPart, > 'expected_crealm': expected_crealm, > 'expected_cname': expected_cname, >+ 'expected_anon': expected_anon, > 'expected_srealm': expected_srealm, > 'expected_sname': expected_sname, > 'ticket_decryption_key': ticket_decryption_key, >@@ -1859,10 +1857,6 @@ class RawKerberosTest(TestCaseInTempDir): > 'inner_req': inner_req, > 'outer_req': outer_req > } >- if expected_cname_private is not None: >- kdc_exchange_dict['expected_cname_private'] = ( >- expected_cname_private) >- > if callback_dict is None: > callback_dict = {} > >@@ -1874,7 +1868,7 @@ class RawKerberosTest(TestCaseInTempDir): > rep): > > expected_crealm = kdc_exchange_dict['expected_crealm'] >- expected_cname = kdc_exchange_dict['expected_cname'] >+ expected_anon = kdc_exchange_dict['expected_anon'] > expected_srealm = kdc_exchange_dict['expected_srealm'] > expected_sname = kdc_exchange_dict['expected_sname'] > ticket_decryption_key = kdc_exchange_dict['ticket_decryption_key'] >@@ -1888,6 +1882,12 @@ class RawKerberosTest(TestCaseInTempDir): > padata = self.getElementValue(rep, 'padata') > if self.strict_checking: > self.assertElementEqualUTF8(rep, 'crealm', expected_crealm) >+ if expected_anon: >+ expected_cname = self.PrincipalName_create( >+ name_type=NT_WELLKNOWN, >+ names=['WELLKNOWN', 'ANONYMOUS']) >+ else: >+ expected_cname = kdc_exchange_dict['expected_cname'] > self.assertElementEqualPrincipal(rep, 'cname', expected_cname) > self.assertElementPresent(rep, 'ticket') > ticket = self.getElementValue(rep, 'ticket') >@@ -2042,14 +2042,11 @@ class RawKerberosTest(TestCaseInTempDir): > and kdc_options[canon_pos] == '1') > > expected_crealm = kdc_exchange_dict['expected_crealm'] >+ expected_cname = kdc_exchange_dict['expected_cname'] > expected_srealm = kdc_exchange_dict['expected_srealm'] > expected_sname = kdc_exchange_dict['expected_sname'] > ticket_decryption_key = kdc_exchange_dict['ticket_decryption_key'] > >- try: >- expected_cname = kdc_exchange_dict['expected_cname_private'] >- except KeyError: >- expected_cname = kdc_exchange_dict['expected_cname'] > > ticket = self.getElementValue(rep, 'ticket') > >@@ -2182,7 +2179,7 @@ class RawKerberosTest(TestCaseInTempDir): > > rep_msg_type = kdc_exchange_dict['rep_msg_type'] > >- expected_cname = kdc_exchange_dict['expected_cname'] >+ expected_anon = kdc_exchange_dict['expected_anon'] > expected_srealm = kdc_exchange_dict['expected_srealm'] > expected_sname = kdc_exchange_dict['expected_sname'] > expected_error_mode = kdc_exchange_dict['expected_error_mode'] >@@ -2203,7 +2200,10 @@ class RawKerberosTest(TestCaseInTempDir): > # error-code checked above > if self.strict_checking: > self.assertElementMissing(rep, 'crealm') >- if expected_cname['name-type'] == NT_WELLKNOWN and not inner: >+ if expected_anon and not inner: >+ expected_cname = self.PrincipalName_create( >+ name_type=NT_WELLKNOWN, >+ names=['WELLKNOWN', 'ANONYMOUS']) > self.assertElementEqualPrincipal(rep, 'cname', expected_cname) > else: > self.assertElementMissing(rep, 'cname') >-- >2.25.1 > > >From 444186e5bdde33e6ff5b152155a145f6f6338a63 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 1 Sep 2021 16:34:02 +1200 >Subject: [PATCH 009/159] tests/krb5: Allow specifying an OU to create accounts > in > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >(cherry picked from commit 7aae0e9b100b8cb7d1da78b8cb9a4a5c20acffbd) >--- > python/samba/tests/krb5/kdc_base_test.py | 8 ++++++-- > 1 file changed, 6 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index f5c1eba9151..efe11da8468 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -151,12 +151,16 @@ class KDCBaseTest(RawKerberosTest): > return default_enctypes > > def create_account(self, ldb, name, machine_account=False, >- spn=None, upn=None, additional_details=None): >+ spn=None, upn=None, additional_details=None, >+ ou=None): > '''Create an account for testing. > The dn of the created account is added to self.accounts, > which is used by tearDownClass to clean up the created accounts. > ''' >- dn = "cn=%s,%s" % (name, ldb.domain_dn()) >+ if ou is None: >+ ou = ldb.domain_dn() >+ >+ dn = "CN=%s,%s" % (name, ou) > > # remove the account if it exists, this will happen if a previous test > # run failed >-- >2.25.1 > > >From 46f262687a155e5b2b2f42ae288dcfff63e761c0 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 1 Sep 2021 16:34:46 +1200 >Subject: [PATCH 010/159] tests/krb5: Allow specifying additional User Account > Control flags for account > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >(cherry picked from commit 9aa900857441ea7e1c2d6c60bfa1ddeb142bf3e3) >--- > python/samba/tests/krb5/kdc_base_test.py | 8 ++++---- > 1 file changed, 4 insertions(+), 4 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index efe11da8468..bd5bacfaca1 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -152,7 +152,7 @@ class KDCBaseTest(RawKerberosTest): > > def create_account(self, ldb, name, machine_account=False, > spn=None, upn=None, additional_details=None, >- ou=None): >+ ou=None, account_control=0): > '''Create an account for testing. > The dn of the created account is added to self.accounts, > which is used by tearDownClass to clean up the created accounts. >@@ -168,11 +168,11 @@ class KDCBaseTest(RawKerberosTest): > if machine_account: > object_class = "computer" > account_name = "%s$" % name >- account_control = str(UF_WORKSTATION_TRUST_ACCOUNT) >+ account_control |= UF_WORKSTATION_TRUST_ACCOUNT > else: > object_class = "user" > account_name = name >- account_control = str(UF_NORMAL_ACCOUNT) >+ account_control |= UF_NORMAL_ACCOUNT > > password = generate_random_password(32, 32) > utf16pw = ('"%s"' % password).encode('utf-16-le') >@@ -181,7 +181,7 @@ class KDCBaseTest(RawKerberosTest): > "dn": dn, > "objectclass": object_class, > "sAMAccountName": account_name, >- "userAccountControl": account_control, >+ "userAccountControl": str(account_control), > "unicodePwd": utf16pw} > if spn is not None: > details["servicePrincipalName"] = spn >-- >2.25.1 > > >From da495982e68c6d19f1639e4ca1d81ea971e772dd Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 1 Sep 2021 16:35:58 +1200 >Subject: [PATCH 011/159] tests/krb5: Keep track of account DN in credentials > object > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >(cherry picked from commit 9973b51e48a5d5f3e33c6e0da46e6231a42bd77a) >--- > python/samba/tests/krb5/kdc_base_test.py | 2 ++ > python/samba/tests/krb5/raw_testcase.py | 8 ++++++++ > 2 files changed, 10 insertions(+) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index bd5bacfaca1..b52452358cc 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -201,6 +201,7 @@ class KDCBaseTest(RawKerberosTest): > creds.set_workstation(name) > else: > creds.set_workstation('') >+ creds.set_dn(dn) > # > # Save the account name so it can be deleted in tearDownClass > self.accounts.add(dn) >@@ -441,6 +442,7 @@ class KDCBaseTest(RawKerberosTest): > > kvno = int(res[0]['msDS-KeyVersionNumber'][0]) > creds.set_kvno(kvno) >+ creds.set_dn(dn) > > keys = self.get_keys(samdb, dn) > self.creds_set_keys(creds, keys) >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index e4dbb10d135..e62fad3d187 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -261,6 +261,8 @@ class KerberosCredentials(Credentials): > > self.forced_salt = None > >+ self.dn = None >+ > def set_as_supported_enctypes(self, value): > self.as_supported_enctypes = int(value) > >@@ -327,6 +329,12 @@ class KerberosCredentials(Credentials): > > return salt_string.encode('utf-8') > >+ def set_dn(self, dn): >+ self.dn = dn >+ >+ def get_dn(self): >+ return self.dn >+ > > class KerberosTicketCreds: > def __init__(self, ticket, session_key, >-- >2.25.1 > > >From 5339251295dca480aa214e0f71ffc5b76e22f808 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 2 Sep 2021 14:27:00 +1200 >Subject: [PATCH 012/159] tests/krb5: Move padata generation methods to base > class > >This allows them to be used directly from RawKerberosTest. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >(cherry picked from commit 1f23b16ef3a900a1bda01bf2a5a3a3847e2e79d1) >--- > python/samba/tests/krb5/fast_tests.py | 14 -------------- > python/samba/tests/krb5/raw_testcase.py | 13 +++++++++++++ > 2 files changed, 13 insertions(+), 14 deletions(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index b371ab617aa..4fc297c1e34 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -51,7 +51,6 @@ from samba.tests.krb5.rfc4120_constants import ( > NT_SRV_INST, > PADATA_FX_COOKIE, > PADATA_FX_FAST, >- PADATA_PAC_OPTIONS > ) > import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 > import samba.tests.krb5.kcrypto as kcrypto >@@ -1466,19 +1465,6 @@ class FAST_Tests(KDCBaseTest): > > return self.PA_DATA_create(PADATA_FX_COOKIE, cookie) > >- def get_pa_pac_request(self, request_pac=True): >- pac_request = self.KERB_PA_PAC_REQUEST_create(request_pac) >- >- return pac_request >- >- def get_pa_pac_options(self, options): >- pac_options = self.PA_PAC_OPTIONS_create(options) >- pac_options = self.der_encode(pac_options, >- asn1Spec=krb5_asn1.PA_PAC_OPTIONS()) >- pac_options = self.PA_DATA_create(PADATA_PAC_OPTIONS, pac_options) >- >- return pac_options >- > def check_kdc_fast_support(self): > # Check that the KDC supports FAST > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index e62fad3d187..b724baf5cf8 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1151,6 +1151,19 @@ class RawKerberosTest(TestCaseInTempDir): > pa_data = self.PA_DATA_create(PADATA_PAC_REQUEST, pa_pac) > return pa_data > >+ def get_pa_pac_request(self, request_pac=True): >+ pac_request = self.KERB_PA_PAC_REQUEST_create(request_pac) >+ >+ return pac_request >+ >+ def get_pa_pac_options(self, options): >+ pac_options = self.PA_PAC_OPTIONS_create(options) >+ pac_options = self.der_encode(pac_options, >+ asn1Spec=krb5_asn1.PA_PAC_OPTIONS()) >+ pac_options = self.PA_DATA_create(PADATA_PAC_OPTIONS, pac_options) >+ >+ return pac_options >+ > def KDC_REQ_BODY_create(self, > kdc_options, > cname, >-- >2.25.1 > > >From eee7c3bdf141545903b07b02be2081ef7ee73003 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 2 Sep 2021 14:36:42 +1200 >Subject: [PATCH 013/159] tests/krb5: add options to kdc_exchange_dict to > specify including PAC-REQUEST or PAC-OPTIONS > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >(cherry picked from commit c0db1ba54d238d4b2da8895215d8314b068ce09c) >--- > python/samba/tests/krb5/raw_testcase.py | 40 +++++++++++++++++++++---- > 1 file changed, 34 insertions(+), 6 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index b724baf5cf8..58f246606d7 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1574,6 +1574,9 @@ class RawKerberosTest(TestCaseInTempDir): > expected_error_mode = kdc_exchange_dict['expected_error_mode'] > kdc_options = kdc_exchange_dict['kdc_options'] > >+ pac_request = kdc_exchange_dict['pac_request'] >+ pac_options = kdc_exchange_dict['pac_options'] >+ > # Parameters specific to the inner request body > inner_req = kdc_exchange_dict['inner_req'] > >@@ -1619,6 +1622,14 @@ class RawKerberosTest(TestCaseInTempDir): > else: > del req_body[key] > >+ additional_padata = [] >+ if pac_request is not None: >+ pa_pac_request = self.KERB_PA_PAC_REQUEST_create(pac_request) >+ additional_padata.append(pa_pac_request) >+ if pac_options is not None: >+ pa_pac_options = self.get_pa_pac_options(pac_options) >+ additional_padata.append(pa_pac_options) >+ > if req_msg_type == KRB_AS_REQ: > tgs_req = None > tgs_req_padata = None >@@ -1637,6 +1648,8 @@ class RawKerberosTest(TestCaseInTempDir): > fast_padata, req_body = generate_fast_padata_fn(kdc_exchange_dict, > callback_dict, > req_body) >+ >+ fast_padata += additional_padata > else: > fast_padata = [] > >@@ -1701,6 +1714,9 @@ class RawKerberosTest(TestCaseInTempDir): > if outer_padata is not None: > padata += outer_padata > >+ if fast is None: >+ padata += additional_padata >+ > if not padata: > padata = None > >@@ -1766,7 +1782,9 @@ class RawKerberosTest(TestCaseInTempDir): > auth_data=None, > kdc_options='', > inner_req=None, >- outer_req=None): >+ outer_req=None, >+ pac_request=None, >+ pac_options=None): > if expected_error_mode == 0: > expected_error_mode = () > elif not isinstance(expected_error_mode, collections.abc.Container): >@@ -1804,7 +1822,9 @@ class RawKerberosTest(TestCaseInTempDir): > 'auth_data': auth_data, > 'kdc_options': kdc_options, > 'inner_req': inner_req, >- 'outer_req': outer_req >+ 'outer_req': outer_req, >+ 'pac_request': pac_request, >+ 'pac_options': pac_options > } > if callback_dict is None: > callback_dict = {} >@@ -1838,7 +1858,9 @@ class RawKerberosTest(TestCaseInTempDir): > body_checksum_type=None, > kdc_options='', > inner_req=None, >- outer_req=None): >+ outer_req=None, >+ pac_request=None, >+ pac_options=None): > if expected_error_mode == 0: > expected_error_mode = () > elif not isinstance(expected_error_mode, collections.abc.Container): >@@ -1876,7 +1898,9 @@ class RawKerberosTest(TestCaseInTempDir): > 'authenticator_subkey': authenticator_subkey, > 'kdc_options': kdc_options, > 'inner_req': inner_req, >- 'outer_req': outer_req >+ 'outer_req': outer_req, >+ 'pac_request': pac_request, >+ 'pac_options': pac_options > } > if callback_dict is None: > callback_dict = {} >@@ -2820,7 +2844,9 @@ class RawKerberosTest(TestCaseInTempDir): > padata, > kdc_options, > preauth_key=None, >- ticket_decryption_key=None): >+ ticket_decryption_key=None, >+ pac_request=None, >+ pac_options=None): > > def _generate_padata_copy(_kdc_exchange_dict, > _callback_dict, >@@ -2860,7 +2886,9 @@ class RawKerberosTest(TestCaseInTempDir): > expected_error_mode=expected_error_mode, > client_as_etypes=client_as_etypes, > expected_salt=expected_salt, >- kdc_options=str(kdc_options)) >+ kdc_options=str(kdc_options), >+ pac_request=pac_request, >+ pac_options=pac_options) > > rep = self._generic_kdc_exchange(kdc_exchange_dict, > cname=cname, >-- >2.25.1 > > >From 90f60857146959239b955d74ada78c9dd6e9859b Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 2 Sep 2021 14:37:27 +1200 >Subject: [PATCH 014/159] tests/krb5: Don't create PAC request manually in > as_req_tests > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >(cherry picked from commit bc21ba2592093c765751ed3e8083dcd3512997f8) >--- > python/samba/tests/krb5/as_req_tests.py | 35 ++++++++----------------- > 1 file changed, 11 insertions(+), 24 deletions(-) > >diff --git a/python/samba/tests/krb5/as_req_tests.py b/python/samba/tests/krb5/as_req_tests.py >index 09160bf6814..35f88a0c920 100755 >--- a/python/samba/tests/krb5/as_req_tests.py >+++ b/python/samba/tests/krb5/as_req_tests.py >@@ -56,7 +56,7 @@ class AsReqKerberosTests(KDCBaseTest): > > def _test_as_req_nopreauth(self, > initial_etypes, >- initial_padata=None, >+ pac=None, > initial_kdc_options=None): > client_creds = self.get_client_creds() > client_account = client_creds.get_username() >@@ -84,27 +84,19 @@ class AsReqKerberosTests(KDCBaseTest): > else: > expected_error_mode = KDC_ERR_ETYPE_NOSUPP > >- def _generate_padata_copy(_kdc_exchange_dict, >- _callback_dict, >- req_body): >- return initial_padata, req_body >- >- generate_padata_fn = (_generate_padata_copy >- if initial_padata is not None >- else None) >- > kdc_exchange_dict = self.as_exchange_dict( > expected_crealm=expected_crealm, > expected_cname=expected_cname, > expected_srealm=expected_srealm, > expected_sname=expected_sname, >- generate_padata_fn=generate_padata_fn, >+ generate_padata_fn=None, > check_error_fn=self.generic_check_kdc_error, > check_rep_fn=None, > expected_error_mode=expected_error_mode, > client_as_etypes=client_as_etypes, > expected_salt=expected_salt, >- kdc_options=str(initial_kdc_options)) >+ kdc_options=str(initial_kdc_options), >+ pac_request=pac) > > self._generic_kdc_exchange(kdc_exchange_dict, > cname=cname, >@@ -114,13 +106,8 @@ class AsReqKerberosTests(KDCBaseTest): > > def _test_as_req_no_preauth_with_args(self, etype_idx, pac): > name, etypes = self.etype_test_permutation_by_idx(etype_idx) >- if pac is None: >- padata = None >- else: >- pa_pac = self.KERB_PA_PAC_REQUEST_create(pac) >- padata = [pa_pac] > self._test_as_req_nopreauth( >- initial_padata=padata, >+ pac=pac, > initial_etypes=etypes, > initial_kdc_options=krb5_asn1.KDCOptions('forwardable')) > >@@ -146,8 +133,6 @@ class AsReqKerberosTests(KDCBaseTest): > > till = self.get_KerberosTime(offset=36000) > >- pa_pac = self.KERB_PA_PAC_REQUEST_create(True) >- initial_padata = [pa_pac] > initial_etypes = client_as_etypes > initial_kdc_options = krb5_asn1.KDCOptions('forwardable') > initial_error_mode = KDC_ERR_PREAUTH_REQUIRED >@@ -164,8 +149,9 @@ class AsReqKerberosTests(KDCBaseTest): > expected_sname, > expected_salt, > initial_etypes, >- initial_padata, >- initial_kdc_options) >+ None, >+ initial_kdc_options, >+ pac_request=True) > etype_info2 = kdc_exchange_dict['preauth_etype_info2'] > self.assertIsNotNone(etype_info2) > >@@ -183,7 +169,7 @@ class AsReqKerberosTests(KDCBaseTest): > > pa_ts = self.PA_DATA_create(PADATA_ENC_TIMESTAMP, pa_ts) > >- preauth_padata = [pa_ts, pa_pac] >+ preauth_padata = [pa_ts] > preauth_etypes = client_as_etypes > preauth_kdc_options = krb5_asn1.KDCOptions('forwardable') > preauth_error_mode = 0 # AS-REP >@@ -207,7 +193,8 @@ class AsReqKerberosTests(KDCBaseTest): > preauth_padata, > preauth_kdc_options, > preauth_key=preauth_key, >- ticket_decryption_key=krbtgt_decryption_key) >+ ticket_decryption_key=krbtgt_decryption_key, >+ pac_request=True) > self.assertIsNotNone(as_rep) > > if __name__ == "__main__": >-- >2.25.1 > > >From ee83e0aaf89b8d4ee039ec7ab7efce63d37e7f10 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 2 Sep 2021 14:38:33 +1200 >Subject: [PATCH 015/159] tests/krb5: Don't create PAC request or options > manually in fast_tests > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >(cherry picked from commit 7556a4dfa64650939aef14a2fc4d10b9ed3d29f7) >--- > python/samba/tests/krb5/fast_tests.py | 22 +++++++++------------- > 1 file changed, 9 insertions(+), 13 deletions(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index 4fc297c1e34..e10db90a57e 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -1093,8 +1093,6 @@ class FAST_Tests(KDCBaseTest): > 'canonicalize,' > 'renewable-ok')) > >- pac_request = self.get_pa_pac_request() >- > client_creds = self.get_client_creds() > target_creds = self.get_service_creds() > krbtgt_creds = self.get_krbtgt_creds() >@@ -1250,7 +1248,7 @@ class FAST_Tests(KDCBaseTest): > _callback_dict, > req_body, > padata): >- return padata, req_body >+ return list(padata), req_body > > def _check_padata_preauth_key(_kdc_exchange_dict, > _callback_dict, >@@ -1260,15 +1258,9 @@ class FAST_Tests(KDCBaseTest): > return preauth_key, as_rep_usage > > pac_options = kdc_dict.pop('pac_options', '1') # claims support >- pac_options = self.get_pa_pac_options(pac_options) > > kdc_options = kdc_dict.pop('kdc_options', kdc_options_default) > >- if rep_type == KRB_AS_REP: >- padata = [pac_request, pac_options] >- else: >- padata = [pac_options] >- > gen_padata_fn = kdc_dict.pop('gen_padata_fn', None) > if gen_padata_fn is not None: > self.assertEqual(KRB_AS_REP, rep_type) >@@ -1278,10 +1270,10 @@ class FAST_Tests(KDCBaseTest): > client_creds, > preauth_etype_info2[0], > client_creds.get_kvno()) >- gen_padata = gen_padata_fn(preauth_key, armor_key) >- padata.insert(0, gen_padata) >+ padata = [gen_padata_fn(preauth_key, armor_key)] > else: > preauth_key = None >+ padata = [] > > if rep_type == KRB_AS_REP: > check_padata_fn = _check_padata_preauth_key >@@ -1345,7 +1337,9 @@ class FAST_Tests(KDCBaseTest): > armor_subkey=armor_subkey, > kdc_options=kdc_options, > inner_req=inner_req, >- outer_req=outer_req) >+ outer_req=outer_req, >+ pac_request=True, >+ pac_options=pac_options) > else: # KRB_TGS_REP > kdc_exchange_dict = self.tgs_exchange_dict( > expected_crealm=expected_crealm, >@@ -1374,7 +1368,9 @@ class FAST_Tests(KDCBaseTest): > body_checksum_type=None, > kdc_options=kdc_options, > inner_req=inner_req, >- outer_req=outer_req) >+ outer_req=outer_req, >+ pac_request=None, >+ pac_options=pac_options) > > repeat = kdc_dict.pop('repeat', 1) > for _ in range(repeat): >-- >2.25.1 > > >From 4c30e01f209217eebcb76c292392abfd752ed8b5 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 1 Sep 2021 17:46:02 +1200 >Subject: [PATCH 016/159] tests/krb5: Remove magic constants > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >(cherry picked from commit 571265257f335ba7f6f1b46daa0d657b8a8dff2b) >--- > python/samba/tests/krb5/fast_tests.py | 2 +- > python/samba/tests/krb5/kdc_base_test.py | 2 +- > 2 files changed, 2 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index e10db90a57e..29a666aad5e 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -1466,7 +1466,7 @@ class FAST_Tests(KDCBaseTest): > > samdb = self.get_samdb() > >- krbtgt_rid = 502 >+ krbtgt_rid = security.DOMAIN_RID_KRBTGT > krbtgt_sid = '%s-%d' % (samdb.get_domain_sid(), krbtgt_rid) > > res = samdb.search(base='<SID=%s>' % krbtgt_sid, >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index b52452358cc..ac43b2eae1a 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -425,7 +425,7 @@ class KDCBaseTest(RawKerberosTest): > def download_krbtgt_creds(): > samdb = self.get_samdb() > >- krbtgt_rid = 502 >+ krbtgt_rid = security.DOMAIN_RID_KRBTGT > krbtgt_sid = '%s-%d' % (samdb.get_domain_sid(), krbtgt_rid) > > res = samdb.search(base='<SID=%s>' % krbtgt_sid, >-- >2.25.1 > > >From 29195cc25efabd6f0785646eb289588fd7322809 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 1 Sep 2021 19:13:11 +1200 >Subject: [PATCH 017/159] tests/krb5: Allow specifying ticket flags expected to > be set or reset > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >(cherry picked from commit 85ddfc1afcf21797dab15431a5f375444c4d316e) >--- > python/samba/tests/krb5/fast_tests.py | 11 +++++++ > python/samba/tests/krb5/raw_testcase.py | 40 +++++++++++++++++++++++-- > 2 files changed, 49 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index 29a666aad5e..687f7532a64 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -1309,6 +1309,13 @@ class FAST_Tests(KDCBaseTest): > inner_req = kdc_dict.pop('inner_req', None) > outer_req = kdc_dict.pop('outer_req', None) > >+ expected_flags = kdc_dict.pop('expected_flags', None) >+ if expected_flags is not None: >+ expected_flags = krb5_asn1.KDCOptions(expected_flags) >+ unexpected_flags = kdc_dict.pop('unexpected_flags', None) >+ if unexpected_flags is not None: >+ unexpected_flags = krb5_asn1.KDCOptions(unexpected_flags) >+ > if rep_type == KRB_AS_REP: > kdc_exchange_dict = self.as_exchange_dict( > expected_crealm=expected_crealm, >@@ -1316,6 +1323,8 @@ class FAST_Tests(KDCBaseTest): > expected_anon=expected_anon, > expected_srealm=expected_srealm, > expected_sname=expected_sname, >+ expected_flags=expected_flags, >+ unexpected_flags=unexpected_flags, > ticket_decryption_key=krbtgt_decryption_key, > generate_fast_fn=generate_fast_fn, > generate_fast_armor_fn=generate_fast_armor_fn, >@@ -1347,6 +1356,8 @@ class FAST_Tests(KDCBaseTest): > expected_anon=expected_anon, > expected_srealm=expected_srealm, > expected_sname=expected_sname, >+ expected_flags=expected_flags, >+ unexpected_flags=unexpected_flags, > ticket_decryption_key=target_decryption_key, > generate_fast_fn=generate_fast_fn, > generate_fast_armor_fn=generate_fast_armor_fn, >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 58f246606d7..268f6ccc6bb 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -896,6 +896,24 @@ class RawKerberosTest(TestCaseInTempDir): > else: > self.assertIsNone(v) > >+ def assertElementFlags(self, obj, elem, expected, unexpected): >+ v = self.getElementValue(obj, elem) >+ self.assertIsNotNone(v) >+ if expected is not None: >+ self.assertIsInstance(expected, krb5_asn1.KDCOptions) >+ for i, flag in enumerate(expected): >+ if flag == 1: >+ self.assertEqual('1', v[i], >+ f"'{expected.namedValues[i]}' " >+ f"expected in {v}") >+ if unexpected is not None: >+ self.assertIsInstance(unexpected, krb5_asn1.KDCOptions) >+ for i, flag in enumerate(unexpected): >+ if flag == 1: >+ self.assertEqual('0', v[i], >+ f"'{unexpected.namedValues[i]}' " >+ f"unexpected in {v}") >+ > def get_KerberosTimeWithUsec(self, epoch=None, offset=None): > if epoch is None: > epoch = time.time() >@@ -1761,6 +1779,8 @@ class RawKerberosTest(TestCaseInTempDir): > expected_anon=False, > expected_srealm=None, > expected_sname=None, >+ expected_flags=None, >+ unexpected_flags=None, > ticket_decryption_key=None, > generate_fast_fn=None, > generate_fast_armor_fn=None, >@@ -1801,6 +1821,8 @@ class RawKerberosTest(TestCaseInTempDir): > 'expected_anon': expected_anon, > 'expected_srealm': expected_srealm, > 'expected_sname': expected_sname, >+ 'expected_flags': expected_flags, >+ 'unexpected_flags': unexpected_flags, > 'ticket_decryption_key': ticket_decryption_key, > 'generate_fast_fn': generate_fast_fn, > 'generate_fast_armor_fn': generate_fast_armor_fn, >@@ -1837,6 +1859,8 @@ class RawKerberosTest(TestCaseInTempDir): > expected_anon=False, > expected_srealm=None, > expected_sname=None, >+ expected_flags=None, >+ unexpected_flags=None, > ticket_decryption_key=None, > generate_fast_fn=None, > generate_fast_armor_fn=None, >@@ -1877,6 +1901,8 @@ class RawKerberosTest(TestCaseInTempDir): > 'expected_anon': expected_anon, > 'expected_srealm': expected_srealm, > 'expected_sname': expected_sname, >+ 'expected_flags': expected_flags, >+ 'unexpected_flags': unexpected_flags, > 'ticket_decryption_key': ticket_decryption_key, > 'generate_fast_fn': generate_fast_fn, > 'generate_fast_armor_fn': generate_fast_armor_fn, >@@ -2092,6 +2118,8 @@ class RawKerberosTest(TestCaseInTempDir): > expected_sname = kdc_exchange_dict['expected_sname'] > ticket_decryption_key = kdc_exchange_dict['ticket_decryption_key'] > >+ expected_flags = kdc_exchange_dict.get('expected_flags') >+ unexpected_flags = kdc_exchange_dict.get('unexpected_flags') > > ticket = self.getElementValue(rep, 'ticket') > >@@ -2101,7 +2129,9 @@ class RawKerberosTest(TestCaseInTempDir): > > ticket_session_key = None > if ticket_private is not None: >- self.assertElementPresent(ticket_private, 'flags') >+ self.assertElementFlags(ticket_private, 'flags', >+ expected_flags, >+ unexpected_flags) > self.assertElementPresent(ticket_private, 'key') > ticket_key = self.getElementValue(ticket_private, 'key') > self.assertIsNotNone(ticket_key) >@@ -2137,7 +2167,9 @@ class RawKerberosTest(TestCaseInTempDir): > kdc_exchange_dict['nonce']) > # TODO self.assertElementPresent(encpart_private, > # 'key-expiration') >- self.assertElementPresent(encpart_private, 'flags') >+ self.assertElementFlags(ticket_private, 'flags', >+ expected_flags, >+ unexpected_flags) > self.assertElementPresent(encpart_private, 'authtime') > if self.strict_checking: > self.assertElementPresent(encpart_private, 'starttime') >@@ -2843,6 +2875,8 @@ class RawKerberosTest(TestCaseInTempDir): > etypes, > padata, > kdc_options, >+ expected_flags=None, >+ unexpected_flags=None, > preauth_key=None, > ticket_decryption_key=None, > pac_request=None, >@@ -2886,6 +2920,8 @@ class RawKerberosTest(TestCaseInTempDir): > expected_error_mode=expected_error_mode, > client_as_etypes=client_as_etypes, > expected_salt=expected_salt, >+ expected_flags=expected_flags, >+ unexpected_flags=unexpected_flags, > kdc_options=str(kdc_options), > pac_request=pac_request, > pac_options=pac_options) >-- >2.25.1 > > >From 70ebb403298a643c6f1021ddc5b0917d57d323f9 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 1 Sep 2021 19:15:17 +1200 >Subject: [PATCH 018/159] tests/krb5: Make time assertion less strict > >This assertion could fail if there was a time difference between the KDC >and the client. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >(cherry picked from commit 1974b872fb5a7da052305d01e2f1efc8d0637078) >--- > python/samba/tests/krb5/raw_testcase.py | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 268f6ccc6bb..5ae8fe4ba41 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2559,7 +2559,7 @@ class RawKerberosTest(TestCaseInTempDir): > current_time = time.time() > > self.assertLess(current_time - 300, rep_time) >- self.assertLess(rep_time, current_time) >+ self.assertLess(rep_time, current_time + 300) > > if all(etype not in client_as_etypes or etype not in proposed_etypes > for etype in (kcrypto.Enctype.AES256, >-- >2.25.1 > > >From 53e49e6e85cc0d30cc1a6b76cebaec3100f76d92 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 1 Sep 2021 19:34:20 +1200 >Subject: [PATCH 019/159] tests/krb5: Allow Kerberos requests to be sent to DC > or RODC > >If run inside the 'rodc' testing environment, 'DC_SERVER' and 'SERVER' >refer to the hostnames of the DC and RODC respectively, and this commit >allows either one of them to be used as the KDC for Kerberos exchanges. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >(cherry picked from commit 0afb548a0a3221730c4a81d51bc31e99ec90e334) >--- > python/samba/tests/krb5/kdc_base_test.py | 2 +- > python/samba/tests/krb5/raw_testcase.py | 39 +++++++++++++++--------- > 2 files changed, 26 insertions(+), 15 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index ac43b2eae1a..0755040a87a 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -116,7 +116,7 @@ class KDCBaseTest(RawKerberosTest): > lp = self.get_lp() > > session = system_session() >- type(self)._ldb = SamDB(url="ldap://%s" % self.host, >+ type(self)._ldb = SamDB(url="ldap://%s" % self.dc_host, > session_info=session, > credentials=creds, > lp=lp) >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 5ae8fe4ba41..c03600f765b 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -418,6 +418,7 @@ class RawKerberosTest(TestCaseInTempDir): > super().setUpClass() > > cls.host = samba.tests.env_get_var_value('SERVER') >+ cls.dc_host = samba.tests.env_get_var_value('DC_SERVER') > > # A dictionary containing credentials that have already been > # obtained. >@@ -452,10 +453,10 @@ class RawKerberosTest(TestCaseInTempDir): > if self.do_hexdump: > sys.stderr.write("disconnect[%s]\n" % reason) > >- def _connect_tcp(self): >+ def _connect_tcp(self, host): > tcp_port = 88 > try: >- self.a = socket.getaddrinfo(self.host, tcp_port, socket.AF_UNSPEC, >+ self.a = socket.getaddrinfo(host, tcp_port, socket.AF_UNSPEC, > socket.SOCK_STREAM, socket.SOL_TCP, > 0) > self.s = socket.socket(self.a[0][0], self.a[0][1], self.a[0][2]) >@@ -468,11 +469,11 @@ class RawKerberosTest(TestCaseInTempDir): > self.s.close() > raise > >- def connect(self): >+ def connect(self, host): > self.assertNotConnected() >- self._connect_tcp() >+ self._connect_tcp(host) > if self.do_hexdump: >- sys.stderr.write("connected[%s]\n" % self.host) >+ sys.stderr.write("connected[%s]\n" % host) > > def env_get_var(self, varname, prefix, > fallback_default=True, >@@ -819,8 +820,10 @@ class RawKerberosTest(TestCaseInTempDir): > req, > asn1_print=None, > hexdump=None, >- timeout=None): >- self.connect() >+ timeout=None, >+ to_rodc=False): >+ host = self.host if to_rodc else self.dc_host >+ self.connect(host) > try: > self.send_pdu(req, asn1_print=asn1_print, hexdump=hexdump) > rep = self.recv_pdu( >@@ -1747,7 +1750,9 @@ class RawKerberosTest(TestCaseInTempDir): > req_body=req_body, > asn1Spec=req_asn1Spec()) > >- rep = self.send_recv_transaction(req_decoded) >+ to_rodc = kdc_exchange_dict['to_rodc'] >+ >+ rep = self.send_recv_transaction(req_decoded, to_rodc=to_rodc) > self.assertIsNotNone(rep) > > msg_type = self.getElementValue(rep, 'msg-type') >@@ -1804,7 +1809,8 @@ class RawKerberosTest(TestCaseInTempDir): > inner_req=None, > outer_req=None, > pac_request=None, >- pac_options=None): >+ pac_options=None, >+ to_rodc=False): > if expected_error_mode == 0: > expected_error_mode = () > elif not isinstance(expected_error_mode, collections.abc.Container): >@@ -1846,7 +1852,8 @@ class RawKerberosTest(TestCaseInTempDir): > 'inner_req': inner_req, > 'outer_req': outer_req, > 'pac_request': pac_request, >- 'pac_options': pac_options >+ 'pac_options': pac_options, >+ 'to_rodc': to_rodc > } > if callback_dict is None: > callback_dict = {} >@@ -1884,7 +1891,8 @@ class RawKerberosTest(TestCaseInTempDir): > inner_req=None, > outer_req=None, > pac_request=None, >- pac_options=None): >+ pac_options=None, >+ to_rodc=False): > if expected_error_mode == 0: > expected_error_mode = () > elif not isinstance(expected_error_mode, collections.abc.Container): >@@ -1926,7 +1934,8 @@ class RawKerberosTest(TestCaseInTempDir): > 'inner_req': inner_req, > 'outer_req': outer_req, > 'pac_request': pac_request, >- 'pac_options': pac_options >+ 'pac_options': pac_options, >+ 'to_rodc': to_rodc > } > if callback_dict is None: > callback_dict = {} >@@ -2880,7 +2889,8 @@ class RawKerberosTest(TestCaseInTempDir): > preauth_key=None, > ticket_decryption_key=None, > pac_request=None, >- pac_options=None): >+ pac_options=None, >+ to_rodc=False): > > def _generate_padata_copy(_kdc_exchange_dict, > _callback_dict, >@@ -2924,7 +2934,8 @@ class RawKerberosTest(TestCaseInTempDir): > unexpected_flags=unexpected_flags, > kdc_options=str(kdc_options), > pac_request=pac_request, >- pac_options=pac_options) >+ pac_options=pac_options, >+ to_rodc=to_rodc) > > rep = self._generic_kdc_exchange(kdc_exchange_dict, > cname=cname, >-- >2.25.1 > > >From d6b448797748810b0aa92f9aa515798e10c16efe Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 1 Sep 2021 19:43:41 +1200 >Subject: [PATCH 020/159] tests/krb5: Check for presence of 'renew-till' > element > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >(cherry picked from commit 9cba5f9a1b098e49315e2e3d4c0b626884c04a64) >--- > python/samba/tests/krb5/raw_testcase.py | 15 +++++++++++++-- > 1 file changed, 13 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index c03600f765b..45ce3c092ad 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2120,6 +2120,9 @@ class RawKerberosTest(TestCaseInTempDir): > canon_pos = len(tuple(krb5_asn1.KDCOptions('canonicalize'))) - 1 > canonicalize = (canon_pos < len(kdc_options) > and kdc_options[canon_pos] == '1') >+ renewable_pos = len(tuple(krb5_asn1.KDCOptions('renewable'))) - 1 >+ renewable = (renewable_pos < len(kdc_options) >+ and kdc_options[renewable_pos] == '1') > > expected_crealm = kdc_exchange_dict['expected_crealm'] > expected_cname = kdc_exchange_dict['expected_cname'] >@@ -2158,7 +2161,11 @@ class RawKerberosTest(TestCaseInTempDir): > if self.strict_checking: > self.assertElementPresent(ticket_private, 'starttime') > self.assertElementPresent(ticket_private, 'endtime') >- # TODO self.assertElementPresent(ticket_private, 'renew-till') >+ if renewable: >+ if self.strict_checking: >+ self.assertElementPresent(ticket_private, 'renew-till') >+ else: >+ self.assertElementMissing(ticket_private, 'renew-till') > # TODO self.assertElementMissing(ticket_private, 'caddr') > self.assertElementPresent(ticket_private, 'authorization-data') > >@@ -2183,7 +2190,11 @@ class RawKerberosTest(TestCaseInTempDir): > if self.strict_checking: > self.assertElementPresent(encpart_private, 'starttime') > self.assertElementPresent(encpart_private, 'endtime') >- # TODO self.assertElementPresent(encpart_private, 'renew-till') >+ if renewable: >+ if self.strict_checking: >+ self.assertElementPresent(encpart_private, 'renew-till') >+ else: >+ self.assertElementMissing(encpart_private, 'renew-till') > self.assertElementEqualUTF8(encpart_private, 'srealm', > expected_srealm) > self.assertElementEqualPrincipal(encpart_private, 'sname', >-- >2.25.1 > > >From 0c1e737653c3ac5b7abfc9c88e130873bc3a1a0d Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 1 Sep 2021 19:45:57 +1200 >Subject: [PATCH 021/159] tests/krb5: Check 'caddr' element > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >(cherry picked from commit d3106a8d35225e826d548d3bea0d42edc3998c38) >--- > python/samba/tests/krb5/raw_testcase.py | 6 ++++-- > 1 file changed, 4 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 45ce3c092ad..9e47897dd76 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2166,7 +2166,8 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertElementPresent(ticket_private, 'renew-till') > else: > self.assertElementMissing(ticket_private, 'renew-till') >- # TODO self.assertElementMissing(ticket_private, 'caddr') >+ if self.strict_checking: >+ self.assertElementEqual(ticket_private, 'caddr', []) > self.assertElementPresent(ticket_private, 'authorization-data') > > encpart_session_key = None >@@ -2199,7 +2200,8 @@ class RawKerberosTest(TestCaseInTempDir): > expected_srealm) > self.assertElementEqualPrincipal(encpart_private, 'sname', > expected_sname) >- # TODO self.assertElementMissing(encpart_private, 'caddr') >+ if self.strict_checking: >+ self.assertElementEqual(encpart_private, 'caddr', []) > > sent_claims = self.sent_claims(kdc_exchange_dict) > >-- >2.25.1 > > >From 0304cd5f99642af533e95d946b2a0169fd88cb09 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 1 Sep 2021 19:47:27 +1200 >Subject: [PATCH 022/159] tests/krb5: Check for presence of 'key-expiration' > element > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >(cherry picked from commit c3b746290278f7b5c1dea676e3fa28b9f15bcf94) >--- > python/samba/tests/krb5/raw_testcase.py | 11 +++++++++-- > 1 file changed, 9 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 9e47897dd76..e754794e48b 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2130,6 +2130,8 @@ class RawKerberosTest(TestCaseInTempDir): > expected_sname = kdc_exchange_dict['expected_sname'] > ticket_decryption_key = kdc_exchange_dict['ticket_decryption_key'] > >+ rep_msg_type = kdc_exchange_dict['rep_msg_type'] >+ > expected_flags = kdc_exchange_dict.get('expected_flags') > unexpected_flags = kdc_exchange_dict.get('unexpected_flags') > >@@ -2182,8 +2184,13 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertElementPresent(encpart_private, 'last-req') > self.assertElementEqual(encpart_private, 'nonce', > kdc_exchange_dict['nonce']) >- # TODO self.assertElementPresent(encpart_private, >- # 'key-expiration') >+ if rep_msg_type == KRB_AS_REP: >+ if self.strict_checking: >+ self.assertElementPresent(encpart_private, >+ 'key-expiration') >+ else: >+ self.assertElementMissing(encpart_private, >+ 'key-expiration') > self.assertElementFlags(ticket_private, 'flags', > expected_flags, > unexpected_flags) >-- >2.25.1 > > >From b2ffb6ad1edea869eab5d3c7c35e62ebeb4aaf4d Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 3 Sep 2021 09:18:32 +1200 >Subject: [PATCH 023/159] tests/krb5: Create testing accounts in appropriate > containers > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Isaac Boukris <iboukris@samba.org> > >Autobuild-User(master): Andrew Bartlett <abartlet@samba.org> >Autobuild-Date(master): Tue Sep 14 00:01:44 UTC 2021 on sn-devel-184 > >(cherry picked from commit 01378a52a1cf0b6855492673455013d5719be45b) >--- > python/samba/tests/krb5/kdc_base_test.py | 7 ++++++- > 1 file changed, 6 insertions(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 0755040a87a..49a3227c26e 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -34,6 +34,8 @@ from samba.drs_utils import drsuapi_connect > from samba.dsdb import ( > DS_DOMAIN_FUNCTION_2000, > DS_DOMAIN_FUNCTION_2008, >+ DS_GUID_COMPUTERS_CONTAINER, >+ DS_GUID_USERS_CONTAINER, > UF_WORKSTATION_TRUST_ACCOUNT, > UF_NORMAL_ACCOUNT > ) >@@ -158,7 +160,10 @@ class KDCBaseTest(RawKerberosTest): > which is used by tearDownClass to clean up the created accounts. > ''' > if ou is None: >- ou = ldb.domain_dn() >+ guid = (DS_GUID_COMPUTERS_CONTAINER if machine_account >+ else DS_GUID_USERS_CONTAINER) >+ >+ ou = ldb.get_wellknown_dn(ldb.get_default_basedn(), guid) > > dn = "CN=%s,%s" % (name, ou) > >-- >2.25.1 > > >From 122984afff61b2850ff0679383912ee01e960a3d Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 1 Sep 2021 19:26:43 +1200 >Subject: [PATCH 024/159] tests/krb5: Allow specifying status code to be > checked > >This allows us to check the status code that may be sent in an error >reply to a TGS-REQ message. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >(cherry picked from commit 4ba5e82ae53410ec9a0bc7d47b181a88c15d9387) >--- > python/samba/tests/krb5/raw_testcase.py | 9 +++++++++ > 1 file changed, 9 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index e754794e48b..f65811243ba 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1798,6 +1798,7 @@ class RawKerberosTest(TestCaseInTempDir): > check_kdc_private_fn=None, > callback_dict=None, > expected_error_mode=0, >+ expected_status=None, > client_as_etypes=None, > expected_salt=None, > authenticator_subkey=None, >@@ -1841,6 +1842,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'check_kdc_private_fn': check_kdc_private_fn, > 'callback_dict': callback_dict, > 'expected_error_mode': expected_error_mode, >+ 'expected_status': expected_status, > 'client_as_etypes': client_as_etypes, > 'expected_salt': expected_salt, > 'authenticator_subkey': authenticator_subkey, >@@ -1879,6 +1881,7 @@ class RawKerberosTest(TestCaseInTempDir): > check_padata_fn=None, > check_kdc_private_fn=None, > expected_error_mode=0, >+ expected_status=None, > callback_dict=None, > tgt=None, > armor_key=None, >@@ -1923,6 +1926,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'check_kdc_private_fn': check_kdc_private_fn, > 'callback_dict': callback_dict, > 'expected_error_mode': expected_error_mode, >+ 'expected_status': expected_status, > 'tgt': tgt, > 'body_checksum_type': body_checksum_type, > 'armor_key': armor_key, >@@ -2540,7 +2544,12 @@ class RawKerberosTest(TestCaseInTempDir): > status = int.from_bytes(pw_salt[:4], 'little') > flags = int.from_bytes(pw_salt[8:], 'little') > >+ expected_status = kdc_exchange_dict['expected_status'] >+ self.assertEqual(expected_status, status) >+ > self.assertEqual(3, flags) >+ else: >+ self.assertIsNone(kdc_exchange_dict.get('expected_status')) > > if enc_challenge is not None: > if not sent_enc_challenge: >-- >2.25.1 > > >From c0a8f10d1d501993980b69c617db2e2f96021a7a Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 3 Sep 2021 09:40:02 +1200 >Subject: [PATCH 025/159] tests/krb5: Get expected cname from TGT for TGS-REQ > messages > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >(cherry picked from commit a5186f92803009c81eca2957e1bf2eb0ff7b6dff) >--- > python/samba/tests/krb5/fast_tests.py | 15 +++++++-------- > 1 file changed, 7 insertions(+), 8 deletions(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index 687f7532a64..e1ba4628994 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -179,18 +179,12 @@ class FAST_Tests(KDCBaseTest): > ]) > > def test_simple_tgs_wrong_principal(self): >- mach_creds = self.get_mach_creds() >- mach_name = mach_creds.get_username() >- expected_cname = self.PrincipalName_create( >- name_type=NT_PRINCIPAL, names=[mach_name]) >- > self._run_test_sequence([ > { > 'rep_type': KRB_TGS_REP, > 'expected_error_mode': 0, > 'use_fast': False, >- 'gen_tgt_fn': self.get_mach_tgt, >- 'expected_cname': expected_cname >+ 'gen_tgt_fn': self.get_mach_tgt > } > ]) > >@@ -1193,7 +1187,12 @@ class FAST_Tests(KDCBaseTest): > else: # KRB_TGS_REP > srealm = target_realm > >- expected_cname = kdc_dict.pop('expected_cname', client_cname) >+ if rep_type == KRB_TGS_REP: >+ tgt_cname = tgt.cname >+ else: >+ tgt_cname = client_cname >+ >+ expected_cname = kdc_dict.pop('expected_cname', tgt_cname) > expected_anon = kdc_dict.pop('expected_anon', > False) > expected_crealm = kdc_dict.pop('expected_crealm', client_realm) >-- >2.25.1 > > >From d879c0475b619c74dc608b8332999e3b3f6682cd Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 3 Sep 2021 09:55:10 +1200 >Subject: [PATCH 026/159] tests/krb5: Get encpart decryption key from > kdc_exchange_dict > >Instead of using check_padata_fn to get the encpart decryption key, we >can get the key from the AS-REQ preauth phase or from the TGT, depending >on whether the message is an AS-REQ or a TGS-REQ. This allows removal of >check_padata_fn and some duplicated code. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >(cherry picked from commit 0e99382d73f44eed7e19e83e430938d587e762d0) >--- > python/samba/tests/krb5/fast_tests.py | 18 +--- > python/samba/tests/krb5/raw_testcase.py | 122 ++++++++++-------------- > 2 files changed, 54 insertions(+), 86 deletions(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index e1ba4628994..12235cd439e 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -45,7 +45,6 @@ from samba.tests.krb5.rfc4120_constants import ( > KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTIONS, > KRB_AS_REP, > KRB_TGS_REP, >- KU_AS_REP_ENC_PART, > KU_TICKET, > NT_PRINCIPAL, > NT_SRV_INST, >@@ -1114,8 +1113,6 @@ class FAST_Tests(KDCBaseTest): > fast_cookie = None > preauth_etype_info2 = None > >- preauth_key = None >- > for kdc_dict in test_sequence: > rep_type = kdc_dict.pop('rep_type') > self.assertIn(rep_type, (KRB_AS_REP, KRB_TGS_REP)) >@@ -1249,13 +1246,6 @@ class FAST_Tests(KDCBaseTest): > padata): > return list(padata), req_body > >- def _check_padata_preauth_key(_kdc_exchange_dict, >- _callback_dict, >- _rep, >- _padata): >- as_rep_usage = KU_AS_REP_ENC_PART >- return preauth_key, as_rep_usage >- > pac_options = kdc_dict.pop('pac_options', '1') # claims support > > kdc_options = kdc_dict.pop('kdc_options', kdc_options_default) >@@ -1274,11 +1264,6 @@ class FAST_Tests(KDCBaseTest): > preauth_key = None > padata = [] > >- if rep_type == KRB_AS_REP: >- check_padata_fn = _check_padata_preauth_key >- else: >- check_padata_fn = self.check_simple_tgs_padata >- > if use_fast: > inner_padata = padata > outer_padata = [] >@@ -1332,13 +1317,13 @@ class FAST_Tests(KDCBaseTest): > generate_padata_fn=generate_padata_fn, > check_error_fn=check_error_fn, > check_rep_fn=check_rep_fn, >- check_padata_fn=check_padata_fn, > check_kdc_private_fn=self.generic_check_kdc_private, > callback_dict={}, > expected_error_mode=expected_error_mode, > client_as_etypes=etypes, > expected_salt=expected_salt, > authenticator_subkey=authenticator_subkey, >+ preauth_key=preauth_key, > auth_data=auth_data, > armor_key=armor_key, > armor_tgt=armor_tgt, >@@ -1365,7 +1350,6 @@ class FAST_Tests(KDCBaseTest): > generate_padata_fn=generate_padata_fn, > check_error_fn=check_error_fn, > check_rep_fn=check_rep_fn, >- check_padata_fn=check_padata_fn, > check_kdc_private_fn=self.generic_check_kdc_private, > expected_error_mode=expected_error_mode, > callback_dict={}, >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index f65811243ba..164d06b9788 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1794,7 +1794,6 @@ class RawKerberosTest(TestCaseInTempDir): > generate_padata_fn=None, > check_error_fn=None, > check_rep_fn=None, >- check_padata_fn=None, > check_kdc_private_fn=None, > callback_dict=None, > expected_error_mode=0, >@@ -1802,6 +1801,7 @@ class RawKerberosTest(TestCaseInTempDir): > client_as_etypes=None, > expected_salt=None, > authenticator_subkey=None, >+ preauth_key=None, > armor_key=None, > armor_tgt=None, > armor_subkey=None, >@@ -1838,7 +1838,6 @@ class RawKerberosTest(TestCaseInTempDir): > 'generate_padata_fn': generate_padata_fn, > 'check_error_fn': check_error_fn, > 'check_rep_fn': check_rep_fn, >- 'check_padata_fn': check_padata_fn, > 'check_kdc_private_fn': check_kdc_private_fn, > 'callback_dict': callback_dict, > 'expected_error_mode': expected_error_mode, >@@ -1846,6 +1845,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'client_as_etypes': client_as_etypes, > 'expected_salt': expected_salt, > 'authenticator_subkey': authenticator_subkey, >+ 'preauth_key': preauth_key, > 'armor_key': armor_key, > 'armor_tgt': armor_tgt, > 'armor_subkey': armor_subkey, >@@ -1878,7 +1878,6 @@ class RawKerberosTest(TestCaseInTempDir): > generate_padata_fn=None, > check_error_fn=None, > check_rep_fn=None, >- check_padata_fn=None, > check_kdc_private_fn=None, > expected_error_mode=0, > expected_status=None, >@@ -1922,7 +1921,6 @@ class RawKerberosTest(TestCaseInTempDir): > 'generate_padata_fn': generate_padata_fn, > 'check_error_fn': check_error_fn, > 'check_rep_fn': check_rep_fn, >- 'check_padata_fn': check_padata_fn, > 'check_kdc_private_fn': check_kdc_private_fn, > 'callback_dict': callback_dict, > 'expected_error_mode': expected_error_mode, >@@ -1956,7 +1954,6 @@ class RawKerberosTest(TestCaseInTempDir): > expected_srealm = kdc_exchange_dict['expected_srealm'] > expected_sname = kdc_exchange_dict['expected_sname'] > ticket_decryption_key = kdc_exchange_dict['ticket_decryption_key'] >- check_padata_fn = kdc_exchange_dict['check_padata_fn'] > check_kdc_private_fn = kdc_exchange_dict['check_kdc_private_fn'] > rep_encpart_asn1Spec = kdc_exchange_dict['rep_encpart_asn1Spec'] > msg_type = kdc_exchange_dict['rep_msg_type'] >@@ -2004,41 +2001,37 @@ class RawKerberosTest(TestCaseInTempDir): > > ticket_checksum = None > >- encpart_decryption_key = None >- self.assertIsNotNone(check_padata_fn) >- if check_padata_fn is not None: >- # See if we can get the decryption key from the preauth phase >- encpart_decryption_key, encpart_decryption_usage = ( >- check_padata_fn(kdc_exchange_dict, callback_dict, >- rep, padata)) >- >- if armor_key is not None: >- pa_dict = self.get_pa_dict(padata) >- >- if PADATA_FX_FAST in pa_dict: >- fx_fast_data = pa_dict[PADATA_FX_FAST] >- fast_response = self.check_fx_fast_data(kdc_exchange_dict, >- fx_fast_data, >- armor_key, >- finished=True) >- >- if 'strengthen-key' in fast_response: >- strengthen_key = self.EncryptionKey_import( >- fast_response['strengthen-key']) >- encpart_decryption_key = ( >- self.generate_strengthen_reply_key( >- strengthen_key, >- encpart_decryption_key)) >- >- fast_finished = fast_response.get('finished', None) >- if fast_finished is not None: >- ticket_checksum = fast_finished['ticket-checksum'] >- >- self.check_rep_padata(kdc_exchange_dict, >- callback_dict, >- rep, >- fast_response['padata'], >- error_code=0) >+ # Get the decryption key for the encrypted part >+ encpart_decryption_key, encpart_decryption_usage = ( >+ self.get_preauth_key(kdc_exchange_dict)) >+ >+ if armor_key is not None: >+ pa_dict = self.get_pa_dict(padata) >+ >+ if PADATA_FX_FAST in pa_dict: >+ fx_fast_data = pa_dict[PADATA_FX_FAST] >+ fast_response = self.check_fx_fast_data(kdc_exchange_dict, >+ fx_fast_data, >+ armor_key, >+ finished=True) >+ >+ if 'strengthen-key' in fast_response: >+ strengthen_key = self.EncryptionKey_import( >+ fast_response['strengthen-key']) >+ encpart_decryption_key = ( >+ self.generate_strengthen_reply_key( >+ strengthen_key, >+ encpart_decryption_key)) >+ >+ fast_finished = fast_response.get('finished') >+ if fast_finished is not None: >+ ticket_checksum = fast_finished['ticket-checksum'] >+ >+ self.check_rep_padata(kdc_exchange_dict, >+ callback_dict, >+ rep, >+ fast_response['padata'], >+ error_code=0) > > ticket_private = None > self.assertIsNotNone(ticket_decryption_key) >@@ -2558,13 +2551,7 @@ class RawKerberosTest(TestCaseInTempDir): > armor_key = kdc_exchange_dict['armor_key'] > self.assertIsNotNone(armor_key) > >- check_padata_fn = kdc_exchange_dict['check_padata_fn'] >- padata = self.getElementValue(rep, 'padata') >- self.assertIsNotNone(check_padata_fn) >- preauth_key, _ = check_padata_fn(kdc_exchange_dict, >- callback_dict, >- rep, >- padata) >+ preauth_key, _ = self.get_preauth_key(kdc_exchange_dict) > > kdc_challenge_key = self.generate_kdc_challenge_key( > armor_key, preauth_key) >@@ -2790,21 +2777,25 @@ class RawKerberosTest(TestCaseInTempDir): > > return padata, req_body > >- def check_simple_tgs_padata(self, >- kdc_exchange_dict, >- callback_dict, >- rep, >- padata): >- tgt = kdc_exchange_dict['tgt'] >- authenticator_subkey = kdc_exchange_dict['authenticator_subkey'] >- if authenticator_subkey is not None: >- subkey = authenticator_subkey >- subkey_usage = KU_TGS_REP_ENC_PART_SUB_KEY >- else: >- subkey = tgt.session_key >- subkey_usage = KU_TGS_REP_ENC_PART_SESSION >+ def get_preauth_key(self, kdc_exchange_dict): >+ msg_type = kdc_exchange_dict['rep_msg_type'] >+ >+ if msg_type == KRB_AS_REP: >+ key = kdc_exchange_dict['preauth_key'] >+ usage = KU_AS_REP_ENC_PART >+ else: # KRB_TGS_REP >+ authenticator_subkey = kdc_exchange_dict['authenticator_subkey'] >+ if authenticator_subkey is not None: >+ key = authenticator_subkey >+ usage = KU_TGS_REP_ENC_PART_SUB_KEY >+ else: >+ tgt = kdc_exchange_dict['tgt'] >+ key = tgt.session_key >+ usage = KU_TGS_REP_ENC_PART_SESSION >+ >+ self.assertIsNotNone(key) > >- return subkey, subkey_usage >+ return key, usage > > def generate_armor_key(self, subkey, session_key): > armor_key = kcrypto.cf2(subkey.key, >@@ -2926,13 +2917,6 @@ class RawKerberosTest(TestCaseInTempDir): > req_body): > return padata, req_body > >- def _check_padata_preauth_key(_kdc_exchange_dict, >- _callback_dict, >- rep, >- padata): >- as_rep_usage = KU_AS_REP_ENC_PART >- return preauth_key, as_rep_usage >- > if not expected_error_mode: > check_error_fn = None > check_rep_fn = self.generic_check_kdc_rep >@@ -2954,13 +2938,13 @@ class RawKerberosTest(TestCaseInTempDir): > generate_padata_fn=generate_padata_fn, > check_error_fn=check_error_fn, > check_rep_fn=check_rep_fn, >- check_padata_fn=_check_padata_preauth_key, > check_kdc_private_fn=self.generic_check_kdc_private, > expected_error_mode=expected_error_mode, > client_as_etypes=client_as_etypes, > expected_salt=expected_salt, > expected_flags=expected_flags, > unexpected_flags=unexpected_flags, >+ preauth_key=preauth_key, > kdc_options=str(kdc_options), > pac_request=pac_request, > pac_options=pac_options, >-- >2.25.1 > > >From 05d955bb9ee0436d6e13c938fabaccfa979b7d73 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 3 Sep 2021 15:36:24 +1200 >Subject: [PATCH 027/159] tests/krb5: Add get_cached_creds() method to create > persistent accounts for testing > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >(cherry picked from commit c9fd8ffd8927ef42fd555e690f966f65aa01332e) >--- > python/samba/tests/krb5/fast_tests.py | 2 +- > python/samba/tests/krb5/kdc_base_test.py | 191 +++++++++++++++-------- > 2 files changed, 125 insertions(+), 68 deletions(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index 12235cd439e..106b9b1fb78 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -1108,7 +1108,7 @@ class FAST_Tests(KDCBaseTest): > target_sname = self.PrincipalName_create( > name_type=NT_SRV_INST, names=[target_service, target_username]) > target_decryption_key = self.TicketDecryptionKey_from_creds( >- target_creds, etype=kcrypto.Enctype.RC4) >+ target_creds) > > fast_cookie = None > preauth_etype_info2 = None >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 49a3227c26e..b2b9d87c3af 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -22,6 +22,7 @@ from datetime import datetime, timezone > import tempfile > import binascii > import collections >+import secrets > > from collections import namedtuple > import ldb >@@ -37,7 +38,10 @@ from samba.dsdb import ( > DS_GUID_COMPUTERS_CONTAINER, > DS_GUID_USERS_CONTAINER, > UF_WORKSTATION_TRUST_ACCOUNT, >- UF_NORMAL_ACCOUNT >+ UF_NO_AUTH_DATA_REQUIRED, >+ UF_NORMAL_ACCOUNT, >+ UF_NOT_DELEGATED, >+ UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION > ) > from samba.ndr import ndr_pack, ndr_unpack > from samba import net >@@ -88,9 +92,17 @@ class KDCBaseTest(RawKerberosTest): > > cls._functional_level = None > >+ # An identifier to ensure created accounts have unique names. Windows >+ # caches accounts based on usernames, so account names being different >+ # across test runs avoids previous test runs affecting the results. >+ cls.account_base = f'krb5_{secrets.token_hex(5)}_' >+ cls.account_id = 0 >+ > # A set containing DNs of accounts created as part of testing. > cls.accounts = set() > >+ cls.account_cache = {} >+ > @classmethod > def tearDownClass(cls): > # Clean up any accounts created by create_account. This is >@@ -322,24 +334,113 @@ class KDCBaseTest(RawKerberosTest): > creds.set_tgs_supported_enctypes(supported_enctypes) > creds.set_ap_supported_enctypes(supported_enctypes) > >- def get_client_creds(self, >- allow_missing_password=False, >- allow_missing_keys=True): >- def create_client_account(): >- samdb = self.get_samdb() >+ def get_cached_creds(self, *, >+ machine_account, >+ opts=None): >+ if opts is None: >+ opts = {} >+ >+ opts_default = { >+ 'no_auth_data_required': False, >+ 'supported_enctypes': None, >+ 'not_delegated': False, >+ 'allowed_to_delegate_to': None, >+ 'trusted_to_auth_for_delegation': False, >+ 'fast_support': False >+ } >+ >+ account_opts = { >+ 'machine_account': machine_account, >+ **opts_default, >+ **opts >+ } >+ >+ cache_key = tuple(sorted(account_opts.items())) >+ >+ creds = self.account_cache.get(cache_key) >+ if creds is None: >+ creds = self.create_account_opts(**account_opts) >+ self.account_cache[cache_key] = creds >+ >+ return creds >+ >+ def create_account_opts(self, *, >+ machine_account, >+ no_auth_data_required, >+ supported_enctypes, >+ not_delegated, >+ allowed_to_delegate_to, >+ trusted_to_auth_for_delegation, >+ fast_support): >+ if machine_account: >+ self.assertFalse(not_delegated) >+ else: >+ self.assertIsNone(allowed_to_delegate_to) >+ self.assertFalse(trusted_to_auth_for_delegation) > >- creds, dn = self.create_account(samdb, 'kdctestclient') >+ samdb = self.get_samdb() > >- res = samdb.search(base=dn, >- scope=ldb.SCOPE_BASE, >- attrs=['msDS-KeyVersionNumber']) >- kvno = int(res[0]['msDS-KeyVersionNumber'][0]) >- creds.set_kvno(kvno) >+ user_name = self.account_base + str(self.account_id) >+ type(self).account_id += 1 > >- keys = self.get_keys(samdb, dn) >- self.creds_set_keys(creds, keys) >+ user_account_control = 0 >+ if trusted_to_auth_for_delegation: >+ user_account_control |= UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION >+ if not_delegated: >+ user_account_control |= UF_NOT_DELEGATED >+ if no_auth_data_required: >+ user_account_control |= UF_NO_AUTH_DATA_REQUIRED > >- return creds >+ details = {} >+ >+ enctypes = supported_enctypes >+ if fast_support: >+ fast_bits = (security.KERB_ENCTYPE_FAST_SUPPORTED | >+ security.KERB_ENCTYPE_COMPOUND_IDENTITY_SUPPORTED | >+ security.KERB_ENCTYPE_CLAIMS_SUPPORTED) >+ enctypes = (enctypes or 0) | fast_bits >+ >+ if enctypes is not None: >+ details['msDS-SupportedEncryptionTypes'] = str(enctypes) >+ >+ if allowed_to_delegate_to: >+ details['msDS-AllowedToDelegateTo'] = allowed_to_delegate_to >+ >+ if machine_account: >+ spn = 'host/' + user_name >+ else: >+ spn = None >+ >+ creds, dn = self.create_account(samdb, user_name, >+ machine_account=machine_account, >+ spn=spn, >+ additional_details=details, >+ account_control=user_account_control) >+ >+ res = samdb.search(base=dn, >+ scope=ldb.SCOPE_BASE, >+ attrs=['msDS-KeyVersionNumber']) >+ kvno = int(res[0]['msDS-KeyVersionNumber'][0]) >+ creds.set_kvno(kvno) >+ >+ keys = self.get_keys(samdb, dn) >+ self.creds_set_keys(creds, keys) >+ >+ if machine_account: >+ if supported_enctypes is not None: >+ tgs_enctypes = supported_enctypes >+ else: >+ tgs_enctypes = security.KERB_ENCTYPE_RC4_HMAC_MD5 >+ >+ creds.set_tgs_supported_enctypes(tgs_enctypes) >+ >+ return creds >+ >+ def get_client_creds(self, >+ allow_missing_password=False, >+ allow_missing_keys=True): >+ def create_client_account(): >+ return self.get_cached_creds(machine_account=False) > > c = self._get_krb5_creds(prefix='CLIENT', > allow_missing_password=allow_missing_password, >@@ -351,32 +452,8 @@ class KDCBaseTest(RawKerberosTest): > allow_missing_password=False, > allow_missing_keys=True): > def create_mach_account(): >- samdb = self.get_samdb() >- >- mach_name = 'kdctestmac' >- details = { >- 'msDS-SupportedEncryptionTypes': str( >- security.KERB_ENCTYPE_FAST_SUPPORTED | >- security.KERB_ENCTYPE_COMPOUND_IDENTITY_SUPPORTED | >- security.KERB_ENCTYPE_CLAIMS_SUPPORTED >- ) >- } >- >- creds, dn = self.create_account(samdb, mach_name, >- machine_account=True, >- spn='host/' + mach_name, >- additional_details=details) >- >- res = samdb.search(base=dn, >- scope=ldb.SCOPE_BASE, >- attrs=['msDS-KeyVersionNumber']) >- kvno = int(res[0]['msDS-KeyVersionNumber'][0]) >- creds.set_kvno(kvno) >- >- keys = self.get_keys(samdb, dn) >- self.creds_set_keys(creds, keys) >- >- return creds >+ return self.get_cached_creds(machine_account=True, >+ opts={'fast_support': True}) > > c = self._get_krb5_creds(prefix='MAC', > allow_missing_password=allow_missing_password, >@@ -388,32 +465,12 @@ class KDCBaseTest(RawKerberosTest): > allow_missing_password=False, > allow_missing_keys=True): > def create_service_account(): >- samdb = self.get_samdb() >- >- mach_name = 'kdctestservice' >- details = { >- 'msDS-SupportedEncryptionTypes': str( >- security.KERB_ENCTYPE_FAST_SUPPORTED | >- security.KERB_ENCTYPE_COMPOUND_IDENTITY_SUPPORTED | >- security.KERB_ENCTYPE_CLAIMS_SUPPORTED >- ) >- } >- >- creds, dn = self.create_account(samdb, mach_name, >- machine_account=True, >- spn='host/' + mach_name, >- additional_details=details) >- >- res = samdb.search(base=dn, >- scope=ldb.SCOPE_BASE, >- attrs=['msDS-KeyVersionNumber']) >- kvno = int(res[0]['msDS-KeyVersionNumber'][0]) >- creds.set_kvno(kvno) >- >- keys = self.get_keys(samdb, dn) >- self.creds_set_keys(creds, keys) >- >- return creds >+ return self.get_cached_creds( >+ machine_account=True, >+ opts={ >+ 'trusted_to_auth_for_delegation': True, >+ 'fast_support': True >+ }) > > c = self._get_krb5_creds(prefix='SERVICE', > allow_missing_password=allow_missing_password, >-- >2.25.1 > > >From 35de4c24218d712e28b80525eed300e41144051a Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 8 Sep 2021 11:28:52 +1200 >Subject: [PATCH 028/159] tests/krb5: Generate padata for FAST tests > >This gives us access to parameters of kdc_exchange_dict and enables us >to simplify the logic. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >(cherry picked from commit 943079fd94fec66cdc2ba4ea1b2beb2971473004) >--- > python/samba/tests/krb5/fast_tests.py | 101 ++++++++++++++++---------- > 1 file changed, 61 insertions(+), 40 deletions(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index 106b9b1fb78..8024b92f445 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -1017,19 +1017,6 @@ class FAST_Tests(KDCBaseTest): > # challenge is only considered a replay if the ciphertext is identical > # to a previous challenge. Windows does not perform this check. > >- class GenerateEncChallengePadataReplay: >- def __init__(replay): >- replay._padata = None >- >- def __call__(replay, key, armor_key): >- if replay._padata is None: >- client_challenge_key = ( >- self.generate_client_challenge_key(armor_key, key)) >- replay._padata = self.get_challenge_pa_data( >- client_challenge_key) >- >- return replay._padata >- > self._run_test_sequence([ > { > 'rep_type': KRB_AS_REP, >@@ -1042,28 +1029,72 @@ class FAST_Tests(KDCBaseTest): > 'rep_type': KRB_AS_REP, > 'expected_error_mode': 0, > 'use_fast': True, >- 'gen_padata_fn': GenerateEncChallengePadataReplay(), >+ 'gen_padata_fn': self.generate_enc_challenge_padata_replay, > 'fast_armor': FX_FAST_ARMOR_AP_REQUEST, > 'gen_armor_tgt_fn': self.get_mach_tgt, > 'repeat': 2 > } > ]) > >- def generate_enc_timestamp_padata(self, key, _armor_key): >- return self.get_enc_timestamp_pa_data_from_key(key) >+ def generate_enc_timestamp_padata(self, >+ kdc_exchange_dict, >+ callback_dict, >+ req_body): >+ key = kdc_exchange_dict['preauth_key'] >+ >+ padata = self.get_enc_timestamp_pa_data_from_key(key) >+ return [padata], req_body >+ >+ def generate_enc_challenge_padata(self, >+ kdc_exchange_dict, >+ callback_dict, >+ req_body, >+ skew=0): >+ armor_key = kdc_exchange_dict['armor_key'] >+ key = kdc_exchange_dict['preauth_key'] > >- def generate_enc_challenge_padata(self, key, armor_key, skew=0): > client_challenge_key = ( > self.generate_client_challenge_key(armor_key, key)) >- return self.get_challenge_pa_data(client_challenge_key, skew=skew) >+ padata = self.get_challenge_pa_data(client_challenge_key, skew=skew) >+ return [padata], req_body >+ >+ def generate_enc_challenge_padata_wrong_key_kdc(self, >+ kdc_exchange_dict, >+ callback_dict, >+ req_body): >+ armor_key = kdc_exchange_dict['armor_key'] >+ key = kdc_exchange_dict['preauth_key'] > >- def generate_enc_challenge_padata_wrong_key_kdc(self, key, armor_key): > kdc_challenge_key = ( > self.generate_kdc_challenge_key(armor_key, key)) >- return self.get_challenge_pa_data(kdc_challenge_key) >+ padata = self.get_challenge_pa_data(kdc_challenge_key) >+ return [padata], req_body > >- def generate_enc_challenge_padata_wrong_key(self, key, _armor_key): >- return self.get_challenge_pa_data(key) >+ def generate_enc_challenge_padata_wrong_key(self, >+ kdc_exchange_dict, >+ callback_dict, >+ req_body): >+ key = kdc_exchange_dict['preauth_key'] >+ >+ padata = self.get_challenge_pa_data(key) >+ return [padata], req_body >+ >+ def generate_enc_challenge_padata_replay(self, >+ kdc_exchange_dict, >+ callback_dict, >+ req_body): >+ padata = callback_dict.get('replay_padata') >+ >+ if padata is None: >+ armor_key = kdc_exchange_dict['armor_key'] >+ key = kdc_exchange_dict['preauth_key'] >+ >+ client_challenge_key = ( >+ self.generate_client_challenge_key(armor_key, key)) >+ padata = self.get_challenge_pa_data(client_challenge_key) >+ callback_dict['replay_padata'] = padata >+ >+ return [padata], req_body > > def generate_empty_fast(self, > _kdc_exchange_dict, >@@ -1251,35 +1282,25 @@ class FAST_Tests(KDCBaseTest): > kdc_options = kdc_dict.pop('kdc_options', kdc_options_default) > > gen_padata_fn = kdc_dict.pop('gen_padata_fn', None) >- if gen_padata_fn is not None: >- self.assertEqual(KRB_AS_REP, rep_type) >+ >+ if rep_type == KRB_AS_REP and gen_padata_fn is not None: > self.assertIsNotNone(preauth_etype_info2) > > preauth_key = self.PasswordKey_from_etype_info2( > client_creds, > preauth_etype_info2[0], > client_creds.get_kvno()) >- padata = [gen_padata_fn(preauth_key, armor_key)] > else: > preauth_key = None >- padata = [] > > if use_fast: >- inner_padata = padata >- outer_padata = [] >+ generate_fast_padata_fn = gen_padata_fn >+ generate_padata_fn = (functools.partial(_generate_padata_copy, >+ padata=[fast_cookie]) >+ if fast_cookie is not None else None) > else: >- inner_padata = [] >- outer_padata = padata >- >- if use_fast and fast_cookie is not None: >- outer_padata.append(fast_cookie) >- >- generate_fast_padata_fn = (functools.partial(_generate_padata_copy, >- padata=inner_padata) >- if inner_padata else None) >- generate_padata_fn = (functools.partial(_generate_padata_copy, >- padata=outer_padata) >- if outer_padata else None) >+ generate_fast_padata_fn = None >+ generate_padata_fn = gen_padata_fn > > gen_authdata_fn = kdc_dict.pop('gen_authdata_fn', None) > if gen_authdata_fn is not None: >-- >2.25.1 > > >From 6af2bc3f3b813317061ab3f59027307d9d94ec9b Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 13 Sep 2021 21:14:18 +1200 >Subject: [PATCH 029/159] tests/krb5: Sign-extend kvno from 32-bit integer > >This helps to avoid problems with RODC kvnos that have the high bit set. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >(cherry picked from commit 7bc52cecb442c4bcbd39372a8b98bb033e4d1540) >--- > python/samba/tests/krb5/raw_testcase.py | 3 +++ > 1 file changed, 3 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 164d06b9788..cca38fb9480 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -294,6 +294,9 @@ class KerberosCredentials(Credentials): > return self._get_krb5_etypes(self.ap_supported_enctypes) > > def set_kvno(self, kvno): >+ # Sign-extend from 32 bits. >+ if kvno & 1 << 31: >+ kvno |= -1 << 31 > self.kvno = kvno > > def get_kvno(self): >-- >2.25.1 > > >From b7ee0e8ac7d4ff80fb5123bb68840bd4eb788837 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 13 Sep 2021 20:20:23 +1200 >Subject: [PATCH 030/159] tests/krb5: Add method to get RODC krbtgt credentials > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >(cherry picked from commit a5bf7aad54b7053417a24ae0918ee42ceed7bf21) >--- > python/samba/tests/krb5/kdc_base_test.py | 74 ++++++++++++++++++++++++ > 1 file changed, 74 insertions(+) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index b2b9d87c3af..fd2e4d08cd3 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -89,6 +89,7 @@ class KDCBaseTest(RawKerberosTest): > cls._lp = None > > cls._ldb = None >+ cls._rodc_ldb = None > > cls._functional_level = None > >@@ -137,6 +138,30 @@ class KDCBaseTest(RawKerberosTest): > > return self._ldb > >+ def get_rodc_samdb(self): >+ if self._rodc_ldb is None: >+ creds = self.get_admin_creds() >+ lp = self.get_lp() >+ >+ session = system_session() >+ type(self)._rodc_ldb = SamDB(url="ldap://%s" % self.host, >+ session_info=session, >+ credentials=creds, >+ lp=lp, >+ am_rodc=True) >+ >+ return self._rodc_ldb >+ >+ def get_server_dn(self, samdb): >+ server = samdb.get_serverName() >+ >+ res = samdb.search(base=server, >+ scope=ldb.SCOPE_BASE, >+ attrs=['serverReference']) >+ dn = ldb.Dn(samdb, res[0]['serverReference'][0].decode('utf8')) >+ >+ return dn >+ > def get_domain_functional_level(self, ldb): > if self._functional_level is None: > res = ldb.search(base='', >@@ -478,6 +503,55 @@ class KDCBaseTest(RawKerberosTest): > fallback_creds_fn=create_service_account) > return c > >+ def get_rodc_krbtgt_creds(self, >+ require_keys=True, >+ require_strongest_key=False): >+ if require_strongest_key: >+ self.assertTrue(require_keys) >+ >+ def download_rodc_krbtgt_creds(): >+ samdb = self.get_samdb() >+ rodc_samdb = self.get_rodc_samdb() >+ >+ rodc_dn = self.get_server_dn(rodc_samdb) >+ >+ res = samdb.search(rodc_dn, >+ scope=ldb.SCOPE_BASE, >+ attrs=['msDS-KrbTgtLink']) >+ krbtgt_dn = res[0]['msDS-KrbTgtLink'][0] >+ >+ res = samdb.search(krbtgt_dn, >+ scope=ldb.SCOPE_BASE, >+ attrs=['sAMAccountName', >+ 'msDS-KeyVersionNumber', >+ 'msDS-SecondaryKrbTgtNumber']) >+ krbtgt_dn = res[0].dn >+ username = str(res[0]['sAMAccountName']) >+ >+ creds = KerberosCredentials() >+ creds.set_domain(self.env_get_var('DOMAIN', 'RODC_KRBTGT')) >+ creds.set_realm(self.env_get_var('REALM', 'RODC_KRBTGT')) >+ creds.set_username(username) >+ >+ kvno = int(res[0]['msDS-KeyVersionNumber'][0]) >+ krbtgt_number = int(res[0]['msDS-SecondaryKrbTgtNumber'][0]) >+ >+ rodc_kvno = krbtgt_number << 16 | kvno >+ creds.set_kvno(rodc_kvno) >+ creds.set_dn(krbtgt_dn) >+ >+ keys = self.get_keys(samdb, krbtgt_dn) >+ self.creds_set_keys(creds, keys) >+ >+ return creds >+ >+ c = self._get_krb5_creds(prefix='RODC_KRBTGT', >+ allow_missing_password=True, >+ allow_missing_keys=not require_keys, >+ require_strongest_key=require_strongest_key, >+ fallback_creds_fn=download_rodc_krbtgt_creds) >+ return c >+ > def get_krbtgt_creds(self, > require_keys=True, > require_strongest_key=False): >-- >2.25.1 > > >From c483640978f3ac4e279fc992b73443715107dc23 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 13 Sep 2021 20:58:01 +1200 >Subject: [PATCH 031/159] tests/krb5: Add get_secrets() method to get the > secret attributes of a DN > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >(cherry picked from commit af633992e31e839cdd7f77740c1f25d129be2f79) >--- > python/samba/tests/krb5/kdc_base_test.py | 26 +++++++++++++++++++----- > 1 file changed, 21 insertions(+), 5 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index fd2e4d08cd3..3681d26bb83 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -250,7 +250,9 @@ class KDCBaseTest(RawKerberosTest): > > return (creds, dn) > >- def get_keys(self, samdb, dn): >+ def get_secrets(self, samdb, dn, >+ destination_dsa_guid, >+ source_dsa_invocation_id): > admin_creds = self.get_admin_creds() > > dns_hostname = samdb.host_dns_name() >@@ -258,15 +260,13 @@ class KDCBaseTest(RawKerberosTest): > self.get_lp(), > admin_creds) > >- destination_dsa_guid = misc.GUID(samdb.get_ntds_GUID()) >- > req = drsuapi.DsGetNCChangesRequest8() > > req.destination_dsa_guid = destination_dsa_guid >- req.source_dsa_invocation_id = misc.GUID() >+ req.source_dsa_invocation_id = source_dsa_invocation_id > > naming_context = drsuapi.DsReplicaObjectIdentifier() >- naming_context.dn = str(dn) >+ naming_context.dn = dn > > req.naming_context = naming_context > >@@ -299,9 +299,25 @@ class KDCBaseTest(RawKerberosTest): > req.mapping_ctr.mappings = None > > _, ctr = bind.DsGetNCChanges(handle, 8, req) >+ >+ self.assertEqual(1, ctr.object_count) >+ > identifier = ctr.first_object.object.identifier > attributes = ctr.first_object.object.attribute_ctr.attributes > >+ self.assertEqual(dn, identifier.dn) >+ >+ return bind, identifier, attributes >+ >+ def get_keys(self, samdb, dn): >+ admin_creds = self.get_admin_creds() >+ >+ bind, identifier, attributes = self.get_secrets( >+ samdb, >+ str(dn), >+ destination_dsa_guid=misc.GUID(samdb.get_ntds_GUID()), >+ source_dsa_invocation_id=misc.GUID()) >+ > rid = identifier.sid.split()[1] > > net_ctx = net.Net(admin_creds) >-- >2.25.1 > > >From 1c661363a1e420446532f2c36a7bc4bda36711b2 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 13 Sep 2021 22:13:24 +1200 >Subject: [PATCH 032/159] tests/krb5: Allow replicating accounts to the RODC > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >(cherry picked from commit 3cc9e77f38f6698aa01abca4285a520c7c0cd2ac) >--- > python/samba/tests/krb5/kdc_base_test.py | 141 ++++++++++++++++++++++- > 1 file changed, 139 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 3681d26bb83..56102cfc4ea 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -31,8 +31,9 @@ from samba import generate_random_password > from samba.auth import system_session > from samba.credentials import Credentials, SPECIFIED, MUST_USE_KERBEROS > from samba.dcerpc import drsblobs, drsuapi, misc, krb5pac, krb5ccache, security >-from samba.drs_utils import drsuapi_connect >+from samba.drs_utils import drs_Replicate, drsuapi_connect > from samba.dsdb import ( >+ DSDB_SYNTAX_BINARY_DN, > DS_DOMAIN_FUNCTION_2000, > DS_DOMAIN_FUNCTION_2008, > DS_GUID_COMPUTERS_CONTAINER, >@@ -45,7 +46,7 @@ from samba.dsdb import ( > ) > from samba.ndr import ndr_pack, ndr_unpack > from samba import net >-from samba.samdb import SamDB >+from samba.samdb import SamDB, dsdb_Dn > > from samba.tests import delete_force > import samba.tests.krb5.kcrypto as kcrypto >@@ -104,12 +105,20 @@ class KDCBaseTest(RawKerberosTest): > > cls.account_cache = {} > >+ cls.ldb_cleanups = [] >+ > @classmethod > def tearDownClass(cls): > # Clean up any accounts created by create_account. This is > # done in tearDownClass() rather than tearDown(), so that > # accounts need only be created once for permutation tests. > if cls._ldb is not None: >+ for cleanup in reversed(cls.ldb_cleanups): >+ try: >+ cls._ldb.modify(cleanup) >+ except ldb.LdbError: >+ pass >+ > for dn in cls.accounts: > delete_force(cls._ldb, dn) > super().tearDownClass() >@@ -250,6 +259,76 @@ class KDCBaseTest(RawKerberosTest): > > return (creds, dn) > >+ def replicate_account_to_rodc(self, dn): >+ samdb = self.get_samdb() >+ rodc_samdb = self.get_rodc_samdb() >+ >+ repl_val = f'{samdb.get_dsServiceName()}:{dn}:SECRETS_ONLY' >+ >+ msg = ldb.Message() >+ msg.dn = ldb.Dn(rodc_samdb, '') >+ msg['replicateSingleObject'] = ldb.MessageElement( >+ repl_val, >+ ldb.FLAG_MOD_REPLACE, >+ 'replicateSingleObject') >+ >+ try: >+ # Try replication using the replicateSingleObject rootDSE >+ # operation. >+ rodc_samdb.modify(msg) >+ except ldb.LdbError as err: >+ enum, estr = err.args >+ self.assertEqual(enum, ldb.ERR_UNWILLING_TO_PERFORM) >+ self.assertIn('rootdse_modify: unknown attribute to change!', >+ estr) >+ >+ # If that method wasn't supported, we may be in the rodc:local test >+ # environment, where we can try replicating to the local database. >+ >+ lp = self.get_lp() >+ >+ rodc_creds = Credentials() >+ rodc_creds.guess(lp) >+ rodc_creds.set_machine_account(lp) >+ >+ local_samdb = SamDB(url=None, session_info=system_session(), >+ credentials=rodc_creds, lp=lp) >+ >+ destination_dsa_guid = misc.GUID(local_samdb.get_ntds_GUID()) >+ >+ repl = drs_Replicate(f'ncacn_ip_tcp:{self.dc_host}[seal]', >+ lp, rodc_creds, >+ local_samdb, destination_dsa_guid) >+ >+ source_dsa_invocation_id = misc.GUID(samdb.invocation_id) >+ >+ repl.replicate(dn, >+ source_dsa_invocation_id, >+ destination_dsa_guid, >+ exop=drsuapi.DRSUAPI_EXOP_REPL_SECRET, >+ rodc=True) >+ >+ def check_revealed(self, dn, rodc_dn, revealed=True): >+ samdb = self.get_samdb() >+ >+ res = samdb.search(base=rodc_dn, >+ scope=ldb.SCOPE_BASE, >+ attrs=['msDS-RevealedUsers']) >+ >+ revealed_users = res[0].get('msDS-RevealedUsers') >+ if revealed_users is None: >+ self.assertFalse(revealed) >+ return >+ >+ revealed_dns = set(str(dsdb_Dn(samdb, str(user), >+ syntax_oid=DSDB_SYNTAX_BINARY_DN).dn) >+ for user in revealed_users) >+ >+ if revealed: >+ self.assertIn(str(dn), revealed_dns) >+ else: >+ self.assertNotIn(str(dn), revealed_dns) >+ > def get_secrets(self, samdb, dn, > destination_dsa_guid, > source_dsa_invocation_id): >@@ -375,6 +454,29 @@ class KDCBaseTest(RawKerberosTest): > creds.set_tgs_supported_enctypes(supported_enctypes) > creds.set_ap_supported_enctypes(supported_enctypes) > >+ def add_to_group(self, account_dn, group_dn, group_attr): >+ samdb = self.get_samdb() >+ >+ res = samdb.search(base=group_dn, >+ scope=ldb.SCOPE_BASE, >+ attrs=[group_attr]) >+ orig_msg = res[0] >+ >+ members = list(orig_msg[group_attr]) >+ members.append(account_dn) >+ >+ msg = ldb.Message() >+ msg.dn = group_dn >+ msg[group_attr] = ldb.MessageElement(members, >+ ldb.FLAG_MOD_REPLACE, >+ group_attr) >+ >+ cleanup = samdb.msg_diff(msg, orig_msg) >+ self.ldb_cleanups.append(cleanup) >+ samdb.modify(msg) >+ >+ return cleanup >+ > def get_cached_creds(self, *, > machine_account, > opts=None): >@@ -382,6 +484,9 @@ class KDCBaseTest(RawKerberosTest): > opts = {} > > opts_default = { >+ 'allowed_replication': False, >+ 'denied_replication': False, >+ 'revealed_to_rodc': False, > 'no_auth_data_required': False, > 'supported_enctypes': None, > 'not_delegated': False, >@@ -407,6 +512,9 @@ class KDCBaseTest(RawKerberosTest): > > def create_account_opts(self, *, > machine_account, >+ allowed_replication, >+ denied_replication, >+ revealed_to_rodc, > no_auth_data_required, > supported_enctypes, > not_delegated, >@@ -420,6 +528,9 @@ class KDCBaseTest(RawKerberosTest): > self.assertFalse(trusted_to_auth_for_delegation) > > samdb = self.get_samdb() >+ rodc_samdb = self.get_rodc_samdb() >+ >+ rodc_dn = self.get_server_dn(rodc_samdb) > > user_name = self.account_base + str(self.account_id) > type(self).account_id += 1 >@@ -475,6 +586,32 @@ class KDCBaseTest(RawKerberosTest): > > creds.set_tgs_supported_enctypes(tgs_enctypes) > >+ # Handle secret replication to the RODC. >+ >+ if allowed_replication or revealed_to_rodc: >+ # Allow replicating this account's secrets if requested, or allow >+ # it only temporarily if we're about to replicate them. >+ allowed_cleanup = self.add_to_group( >+ dn, rodc_dn, >+ 'msDS-RevealOnDemandGroup') >+ >+ if revealed_to_rodc: >+ # Replicate this account's secrets to the RODC. >+ self.replicate_account_to_rodc(dn) >+ >+ if not allowed_replication: >+ # If we don't want replicating secrets to be allowed for this >+ # account, disable it again. >+ samdb.modify(allowed_cleanup) >+ >+ self.check_revealed(dn, >+ rodc_dn, >+ revealed=revealed_to_rodc) >+ >+ if denied_replication: >+ # Deny replicating this account's secrets to the RODC. >+ self.add_to_group(dn, rodc_dn, 'msDS-NeverRevealGroup') >+ > return creds > > def get_client_creds(self, >-- >2.25.1 > > >From 2b3303852047c0d25fffa56c17a97f275ced2f92 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 13 Sep 2021 21:24:05 +1200 >Subject: [PATCH 033/159] tests/krb5: Create RODC account for testing > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >(cherry picked from commit ef5666bc51ca80e1acdadd525a9c61762756c8e3) >--- > python/samba/tests/krb5/kdc_base_test.py | 114 +++++++++++++++++++++++ > 1 file changed, 114 insertions(+) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 56102cfc4ea..892d3aaf41f 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -42,8 +42,10 @@ from samba.dsdb import ( > UF_NO_AUTH_DATA_REQUIRED, > UF_NORMAL_ACCOUNT, > UF_NOT_DELEGATED, >+ UF_PARTIAL_SECRETS_ACCOUNT, > UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION > ) >+from samba.join import DCJoinContext > from samba.ndr import ndr_pack, ndr_unpack > from samba import net > from samba.samdb import SamDB, dsdb_Dn >@@ -105,6 +107,8 @@ class KDCBaseTest(RawKerberosTest): > > cls.account_cache = {} > >+ cls._rodc_ctx = None >+ > cls.ldb_cleanups = [] > > @classmethod >@@ -121,6 +125,10 @@ class KDCBaseTest(RawKerberosTest): > > for dn in cls.accounts: > delete_force(cls._ldb, dn) >+ >+ if cls._rodc_ctx is not None: >+ cls._rodc_ctx.cleanup_old_join(force=True) >+ > super().tearDownClass() > > def setUp(self): >@@ -171,6 +179,25 @@ class KDCBaseTest(RawKerberosTest): > > return dn > >+ def get_mock_rodc_ctx(self): >+ if self._rodc_ctx is None: >+ admin_creds = self.get_admin_creds() >+ lp = self.get_lp() >+ >+ rodc_name = 'KRB5RODC' >+ site_name = 'Default-First-Site-Name' >+ >+ type(self)._rodc_ctx = DCJoinContext(server=self.dc_host, >+ creds=admin_creds, >+ lp=lp, >+ site=site_name, >+ netbios_name=rodc_name, >+ targetdir=None, >+ domain=None) >+ self.create_rodc(self._rodc_ctx) >+ >+ return self._rodc_ctx >+ > def get_domain_functional_level(self, ldb): > if self._functional_level is None: > res = ldb.search(base='', >@@ -259,6 +286,49 @@ class KDCBaseTest(RawKerberosTest): > > return (creds, dn) > >+ def create_rodc(self, ctx): >+ ctx.nc_list = [ctx.base_dn, ctx.config_dn, ctx.schema_dn] >+ ctx.full_nc_list = [ctx.base_dn, ctx.config_dn, ctx.schema_dn] >+ ctx.krbtgt_dn = f'CN=krbtgt_{ctx.myname},CN=Users,{ctx.base_dn}' >+ >+ ctx.never_reveal_sid = [f'<SID={ctx.domsid}-{security.DOMAIN_RID_RODC_DENY}>', >+ f'<SID={security.SID_BUILTIN_ADMINISTRATORS}>', >+ f'<SID={security.SID_BUILTIN_SERVER_OPERATORS}>', >+ f'<SID={security.SID_BUILTIN_BACKUP_OPERATORS}>', >+ f'<SID={security.SID_BUILTIN_ACCOUNT_OPERATORS}>'] >+ ctx.reveal_sid = f'<SID={ctx.domsid}-{security.DOMAIN_RID_RODC_ALLOW}>' >+ >+ mysid = ctx.get_mysid() >+ admin_dn = f'<SID={mysid}>' >+ ctx.managedby = admin_dn >+ >+ ctx.userAccountControl = (UF_WORKSTATION_TRUST_ACCOUNT | >+ UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION | >+ UF_PARTIAL_SECRETS_ACCOUNT) >+ >+ ctx.connection_dn = f'CN=RODC Connection (FRS),{ctx.ntds_dn}' >+ ctx.secure_channel_type = misc.SEC_CHAN_RODC >+ ctx.RODC = True >+ ctx.replica_flags = (drsuapi.DRSUAPI_DRS_INIT_SYNC | >+ drsuapi.DRSUAPI_DRS_PER_SYNC | >+ drsuapi.DRSUAPI_DRS_GET_ANC | >+ drsuapi.DRSUAPI_DRS_NEVER_SYNCED | >+ drsuapi.DRSUAPI_DRS_SPECIAL_SECRET_PROCESSING) >+ ctx.domain_replica_flags = ctx.replica_flags | drsuapi.DRSUAPI_DRS_CRITICAL_ONLY >+ >+ ctx.build_nc_lists() >+ >+ ctx.cleanup_old_join() >+ >+ try: >+ ctx.join_add_objects() >+ except Exception: >+ # cleanup the failed join (checking we still have a live LDB >+ # connection to the remote DC first) >+ ctx.refresh_ldb_connection() >+ ctx.cleanup_old_join() >+ raise >+ > def replicate_account_to_rodc(self, dn): > samdb = self.get_samdb() > rodc_samdb = self.get_rodc_samdb() >@@ -705,6 +775,50 @@ class KDCBaseTest(RawKerberosTest): > fallback_creds_fn=download_rodc_krbtgt_creds) > return c > >+ def get_mock_rodc_krbtgt_creds(self, >+ require_keys=True, >+ require_strongest_key=False): >+ if require_strongest_key: >+ self.assertTrue(require_keys) >+ >+ def create_rodc_krbtgt_account(): >+ samdb = self.get_samdb() >+ >+ rodc_ctx = self.get_mock_rodc_ctx() >+ >+ krbtgt_dn = rodc_ctx.new_krbtgt_dn >+ >+ res = samdb.search(base=ldb.Dn(samdb, krbtgt_dn), >+ scope=ldb.SCOPE_BASE, >+ attrs=['msDS-KeyVersionNumber', >+ 'msDS-SecondaryKrbTgtNumber']) >+ dn = res[0].dn >+ username = str(rodc_ctx.krbtgt_name) >+ >+ creds = KerberosCredentials() >+ creds.set_domain(self.env_get_var('DOMAIN', 'RODC_KRBTGT')) >+ creds.set_realm(self.env_get_var('REALM', 'RODC_KRBTGT')) >+ creds.set_username(username) >+ >+ kvno = int(res[0]['msDS-KeyVersionNumber'][0]) >+ krbtgt_number = int(res[0]['msDS-SecondaryKrbTgtNumber'][0]) >+ >+ rodc_kvno = krbtgt_number << 16 | kvno >+ creds.set_kvno(rodc_kvno) >+ creds.set_dn(dn) >+ >+ keys = self.get_keys(samdb, dn) >+ self.creds_set_keys(creds, keys) >+ >+ return creds >+ >+ c = self._get_krb5_creds(prefix='MOCK_RODC_KRBTGT', >+ allow_missing_password=True, >+ allow_missing_keys=not require_keys, >+ require_strongest_key=require_strongest_key, >+ fallback_creds_fn=create_rodc_krbtgt_account) >+ return c >+ > def get_krbtgt_creds(self, > require_keys=True, > require_strongest_key=False): >-- >2.25.1 > > >From b2501d3432e05fa182b359fb25188acfc382cc45 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 13 Sep 2021 21:24:31 +1200 >Subject: [PATCH 034/159] tests/krb5: Allow replicating accounts to the created > RODC > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >(cherry picked from commit 35292bd32225b39ad7a03c3aa53027458f0671eb) >--- > python/samba/tests/krb5/kdc_base_test.py | 50 ++++++++++++++++++++++++ > 1 file changed, 50 insertions(+) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 892d3aaf41f..0e138352b06 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -378,6 +378,16 @@ class KDCBaseTest(RawKerberosTest): > exop=drsuapi.DRSUAPI_EXOP_REPL_SECRET, > rodc=True) > >+ def reveal_account_to_mock_rodc(self, dn): >+ samdb = self.get_samdb() >+ rodc_ctx = self.get_mock_rodc_ctx() >+ >+ self.get_secrets( >+ samdb, >+ dn, >+ destination_dsa_guid=rodc_ctx.ntds_guid, >+ source_dsa_invocation_id=misc.GUID(samdb.invocation_id)) >+ > def check_revealed(self, dn, rodc_dn, revealed=True): > samdb = self.get_samdb() > >@@ -555,8 +565,11 @@ class KDCBaseTest(RawKerberosTest): > > opts_default = { > 'allowed_replication': False, >+ 'allowed_replication_mock': False, > 'denied_replication': False, >+ 'denied_replication_mock': False, > 'revealed_to_rodc': False, >+ 'revealed_to_mock_rodc': False, > 'no_auth_data_required': False, > 'supported_enctypes': None, > 'not_delegated': False, >@@ -583,8 +596,11 @@ class KDCBaseTest(RawKerberosTest): > def create_account_opts(self, *, > machine_account, > allowed_replication, >+ allowed_replication_mock, > denied_replication, >+ denied_replication_mock, > revealed_to_rodc, >+ revealed_to_mock_rodc, > no_auth_data_required, > supported_enctypes, > not_delegated, >@@ -682,6 +698,40 @@ class KDCBaseTest(RawKerberosTest): > # Deny replicating this account's secrets to the RODC. > self.add_to_group(dn, rodc_dn, 'msDS-NeverRevealGroup') > >+ # Handle secret replication to the mock RODC. >+ >+ if allowed_replication_mock or revealed_to_mock_rodc: >+ # Allow replicating this account's secrets if requested, or allow >+ # it only temporarily if we want to add the account to the mock >+ # RODC's msDS-RevealedUsers. >+ rodc_ctx = self.get_mock_rodc_ctx() >+ mock_rodc_dn = ldb.Dn(samdb, rodc_ctx.acct_dn) >+ >+ allowed_mock_cleanup = self.add_to_group( >+ dn, mock_rodc_dn, >+ 'msDS-RevealOnDemandGroup') >+ >+ if revealed_to_mock_rodc: >+ # Request replicating this account's secrets to the mock RODC, >+ # which updates msDS-RevealedUsers. >+ self.reveal_account_to_mock_rodc(dn) >+ >+ if not allowed_replication_mock: >+ # If we don't want replicating secrets to be allowed for this >+ # account, disable it again. >+ samdb.modify(allowed_mock_cleanup) >+ >+ self.check_revealed(dn, >+ mock_rodc_dn, >+ revealed=revealed_to_mock_rodc) >+ >+ if denied_replication_mock: >+ # Deny replicating this account's secrets to the mock RODC. >+ rodc_ctx = self.get_mock_rodc_ctx() >+ mock_rodc_dn = ldb.Dn(samdb, rodc_ctx.acct_dn) >+ >+ self.add_to_group(dn, mock_rodc_dn, 'msDS-NeverRevealGroup') >+ > return creds > > def get_client_creds(self, >-- >2.25.1 > > >From e7cfbcd7b436fab27b1163239e593ad064b05f4d Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 1 Sep 2021 15:42:28 +1200 >Subject: [PATCH 035/159] python: Don't leak file handles > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Noel Power <npower@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit cde38d36b98f1d40e7b58cd4c4b4bedfab76c390) >--- > python/samba/__init__.py | 12 +++++++----- > python/samba/ms_schema.py | 6 +++--- > python/samba/schema.py | 9 +++++++-- > 3 files changed, 17 insertions(+), 10 deletions(-) > >diff --git a/python/samba/__init__.py b/python/samba/__init__.py >index fa047a813e2..b4d141e95c1 100644 >--- a/python/samba/__init__.py >+++ b/python/samba/__init__.py >@@ -217,7 +217,8 @@ class Ldb(_Ldb): > > :param ldif_path: Path to LDIF file. > """ >- self.add_ldif(open(ldif_path, 'r').read()) >+ with open(ldif_path, 'r') as ldif_file: >+ self.add_ldif(ldif_file.read()) > > def add_ldif(self, ldif, controls=None): > """Add data based on a LDIF string. >@@ -279,10 +280,11 @@ def read_and_sub_file(file_name, subst_vars): > :param file_name: File to be read (typically from setup directory) > param subst_vars: Optional variables to subsitute in the file. > """ >- data = open(file_name, 'r', encoding="utf-8").read() >- if subst_vars is not None: >- data = substitute_var(data, subst_vars) >- check_all_substituted(data) >+ with open(file_name, 'r', encoding="utf-8") as data_file: >+ data = data_file.read() >+ if subst_vars is not None: >+ data = substitute_var(data, subst_vars) >+ check_all_substituted(data) > return data > > >diff --git a/python/samba/ms_schema.py b/python/samba/ms_schema.py >index 4b5c4a5df83..b26bbfd4fbd 100644 >--- a/python/samba/ms_schema.py >+++ b/python/samba/ms_schema.py >@@ -295,9 +295,9 @@ def __parse_schema_file(filename, objectClass): > out = [] > > from io import open >- f = open(filename, "r", encoding='latin-1') >- for entry in __read_raw_entries(f): >- out.append(__write_ldif_one(__transform_entry(entry, objectClass))) >+ with open(filename, "r", encoding='latin-1') as f: >+ for entry in __read_raw_entries(f): >+ out.append(__write_ldif_one(__transform_entry(entry, objectClass))) > > return "\n\n".join(out) > >diff --git a/python/samba/schema.py b/python/samba/schema.py >index 54fc9fc3125..a3adc162fa3 100644 >--- a/python/samba/schema.py >+++ b/python/samba/schema.py >@@ -110,8 +110,13 @@ class Schema(object): > setup_path('ad-schema/%s' % Schema.base_schemas[base_schema][0]), > setup_path('ad-schema/%s' % Schema.base_schemas[base_schema][1])) > >+ def read_file(file): >+ with open(file, 'rb') as data_file: >+ return data_file.read() >+ > if files is not None: >- self.schema_data = "".join(get_string(open(file, 'rb').read()) for file in files) >+ self.schema_data = "".join(get_string(read_file(file)) >+ for file in files) > > self.schema_data = substitute_var(self.schema_data, > {"SCHEMADN": schemadn}) >@@ -130,7 +135,7 @@ class Schema(object): > if override_prefixmap is not None: > self.prefixmap_data = override_prefixmap > else: >- self.prefixmap_data = open(setup_path("prefixMap.txt"), 'rb').read() >+ self.prefixmap_data = read_file(setup_path("prefixMap.txt")) > > if additional_prefixmap is not None: > self.prefixmap_data += "".join("%s\n" % map for map in additional_prefixmap) >-- >2.25.1 > > >From b46b3d2a746546d22182b7b2682b76ff2d252e1c Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 10 Sep 2021 14:02:22 +1200 >Subject: [PATCH 036/159] python/join: Check for correct msDS-KrbTgtLink > attribute > >Previously, the wrong case was used when checking for this attribute, >which meant krbtgt accounts were not being cleaned up. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Noel Power <npower@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 21a7717359082feaddfdf42788648c3d7574c28e) >--- > python/samba/join.py | 7 ++++--- > 1 file changed, 4 insertions(+), 3 deletions(-) > >diff --git a/python/samba/join.py b/python/samba/join.py >index 59de000a401..79030cdfd29 100644 >--- a/python/samba/join.py >+++ b/python/samba/join.py >@@ -257,8 +257,9 @@ class DCJoinContext(object): > > ctx.del_noerror(res[0].dn, recursive=True) > >- if "msDS-Krbtgtlink" in res[0]: >- ctx.new_krbtgt_dn = res[0]["msDS-Krbtgtlink"][0] >+ krbtgt_dn = res[0].get('msDS-KrbTgtLink', idx=0) >+ if krbtgt_dn is not None: >+ ctx.new_krbtgt_dn = krbtgt_dn > ctx.del_noerror(ctx.new_krbtgt_dn) > > res = ctx.samdb.search(base=ctx.samdb.get_default_basedn(), >@@ -337,7 +338,7 @@ class DCJoinContext(object): > attrs=["msDS-krbTgtLink", "userAccountControl", "serverReferenceBL", "rIDSetReferences"]) > if len(res) == 0: > raise Exception("Could not find domain member account '%s' to promote to a DC, use 'samba-tool domain join' instead'" % ctx.samname) >- if "msDS-krbTgtLink" in res[0] or "serverReferenceBL" in res[0] or "rIDSetReferences" in res[0]: >+ if "msDS-KrbTgtLink" in res[0] or "serverReferenceBL" in res[0] or "rIDSetReferences" in res[0]: > raise Exception("Account '%s' appears to be an active DC, use 'samba-tool domain join' if you must re-create this account" % ctx.samname) > if (int(res[0]["userAccountControl"][0]) & (samba.dsdb.UF_WORKSTATION_TRUST_ACCOUNT | > samba.dsdb.UF_SERVER_TRUST_ACCOUNT) == 0): >-- >2.25.1 > > >From d5b152d8338bde63e0b72f07b5afda698d23b3f1 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 15 Sep 2021 20:56:28 +1200 >Subject: [PATCH 037/159] tests/krb5: Add helper method for modifying PACs > >This method can remove or replace a PAC in an authorization-data >container, while additionally returning the original PAC. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit a281ae09bcf35277c830c4112567c72233fd66b8) >--- > python/samba/tests/krb5/raw_testcase.py | 45 +++++++++++++++++++++++++ > 1 file changed, 45 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index cca38fb9480..b7df1ac0879 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -42,6 +42,8 @@ from samba.tests import TestCaseInTempDir > > import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 > from samba.tests.krb5.rfc4120_constants import ( >+ AD_IF_RELEVANT, >+ AD_WIN2K_PAC, > FX_FAST_ARMOR_AP_REQUEST, > KDC_ERR_GENERIC, > KDC_ERR_PREAUTH_FAILED, >@@ -2848,6 +2850,49 @@ class RawKerberosTest(TestCaseInTempDir): > ticket_blob) > self.assertEqual(expected_checksum, checksum) > >+ def replace_pac(self, auth_data, new_pac, expect_pac=True): >+ if new_pac is not None: >+ self.assertElementEqual(new_pac, 'ad-type', AD_WIN2K_PAC) >+ self.assertElementPresent(new_pac, 'ad-data') >+ >+ new_auth_data = [] >+ >+ ad_relevant = None >+ old_pac = None >+ >+ for authdata_elem in auth_data: >+ if authdata_elem['ad-type'] == AD_IF_RELEVANT: >+ ad_relevant = self.der_decode( >+ authdata_elem['ad-data'], >+ asn1Spec=krb5_asn1.AD_IF_RELEVANT()) >+ >+ relevant_elems = [] >+ for relevant_elem in ad_relevant: >+ if relevant_elem['ad-type'] == AD_WIN2K_PAC: >+ self.assertIsNone(old_pac, 'Multiple PACs detected') >+ old_pac = relevant_elem['ad-data'] >+ >+ if new_pac is not None: >+ relevant_elems.append(new_pac) >+ else: >+ relevant_elems.append(relevant_elem) >+ if expect_pac: >+ self.assertIsNotNone(old_pac, 'Expected PAC') >+ >+ ad_relevant = self.der_encode( >+ relevant_elems, >+ asn1Spec=krb5_asn1.AD_IF_RELEVANT()) >+ >+ authdata_elem = self.AuthorizationData_create(AD_IF_RELEVANT, >+ ad_relevant) >+ >+ new_auth_data.append(authdata_elem) >+ >+ if expect_pac: >+ self.assertIsNotNone(ad_relevant, 'Expected AD-RELEVANT') >+ >+ return new_auth_data, old_pac >+ > def get_outer_pa_dict(self, kdc_exchange_dict): > return self.get_pa_dict(kdc_exchange_dict['req_padata']) > >-- >2.25.1 > > >From 9c34b4fb80d119e60b89469f2865c0bb588da8f8 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 16 Sep 2021 11:22:28 +1200 >Subject: [PATCH 038/159] tests/krb5: Check correct flags element > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 0061fa2c2a26d990ed2e47441bca8797fc9be356) >--- > python/samba/tests/krb5/raw_testcase.py | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index b7df1ac0879..632f69794e6 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2193,7 +2193,7 @@ class RawKerberosTest(TestCaseInTempDir): > else: > self.assertElementMissing(encpart_private, > 'key-expiration') >- self.assertElementFlags(ticket_private, 'flags', >+ self.assertElementFlags(encpart_private, 'flags', > expected_flags, > unexpected_flags) > self.assertElementPresent(encpart_private, 'authtime') >-- >2.25.1 > > >From 104dda583f2d9fa563e9baba140fe1324015a9f0 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 16 Sep 2021 11:13:09 +1200 >Subject: [PATCH 039/159] tests/krb5: Refactor tgs_req() to use > _generic_kdc_exchange > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 2a4d53dc12aa785f696e53ae3376f67375ce455f) >--- > python/samba/tests/krb5/kdc_base_test.py | 78 +++++++++++++----------- > python/samba/tests/krb5/kdc_tgs_tests.py | 3 +- > python/samba/tests/krb5/raw_testcase.py | 1 - > source4/selftest/tests.py | 18 ++++-- > 4 files changed, 58 insertions(+), 42 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 0e138352b06..6a370d3036e 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -52,7 +52,11 @@ from samba.samdb import SamDB, dsdb_Dn > > from samba.tests import delete_force > import samba.tests.krb5.kcrypto as kcrypto >-from samba.tests.krb5.raw_testcase import KerberosCredentials, RawKerberosTest >+from samba.tests.krb5.raw_testcase import ( >+ KerberosCredentials, >+ KerberosTicketCreds, >+ RawKerberosTest >+) > import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 > from samba.tests.krb5.rfc4120_constants import ( > AD_IF_RELEVANT, >@@ -66,7 +70,6 @@ from samba.tests.krb5.rfc4120_constants import ( > KU_AS_REP_ENC_PART, > KU_ENC_CHALLENGE_CLIENT, > KU_PA_ENC_TIMESTAMP, >- KU_TGS_REP_ENC_PART_SUB_KEY, > KU_TICKET, > NT_PRINCIPAL, > NT_SRV_HST, >@@ -1063,49 +1066,56 @@ class KDCBaseTest(RawKerberosTest): > else: > self.assertEqual(rep['error-code'], expected, "rep = {%s}" % rep) > >- def tgs_req(self, cname, sname, realm, ticket, key, etypes): >+ def tgs_req(self, cname, sname, realm, ticket, key, etypes, >+ expected_error_mode=0): > '''Send a TGS-REQ, returns the response and the decrypted and > decoded enc-part > ''' > > kdc_options = "0" >- till = self.get_KerberosTime(offset=36000) >- padata = [] > > subkey = self.RandomKey(key.etype) > > (ctime, cusec) = self.get_KerberosTimeWithUsec() > >- req = self.TGS_REQ_create(padata=padata, >- cusec=cusec, >- ctime=ctime, >- ticket=ticket, >- kdc_options=str(kdc_options), >- cname=cname, >- realm=realm, >- sname=sname, >- from_time=None, >- till_time=till, >- renew_time=None, >- nonce=0x7ffffffe, >- etypes=etypes, >- addresses=None, >- EncAuthorizationData=None, >- EncAuthorizationData_key=None, >- additional_tickets=None, >- ticket_session_key=key, >- authenticator_subkey=subkey) >- rep = self.send_recv_transaction(req) >- self.assertIsNotNone(rep) >+ tgt = KerberosTicketCreds(ticket, >+ key, >+ crealm=realm, >+ cname=cname) > >- msg_type = rep['msg-type'] >- enc_part = None >- if msg_type == KRB_TGS_REP: >- enc_part = subkey.decrypt( >- KU_TGS_REP_ENC_PART_SUB_KEY, rep['enc-part']['cipher']) >- enc_part = self.der_decode( >- enc_part, asn1Spec=krb5_asn1.EncTGSRepPart()) >- return (rep, enc_part) >+ if not expected_error_mode: >+ check_error_fn = None >+ check_rep_fn = self.generic_check_kdc_rep >+ else: >+ check_error_fn = self.generic_check_kdc_error >+ check_rep_fn = None >+ >+ kdc_exchange_dict = self.tgs_exchange_dict( >+ expected_crealm=realm, >+ expected_cname=cname, >+ expected_srealm=realm, >+ expected_sname=sname, >+ expected_error_mode=expected_error_mode, >+ check_error_fn=check_error_fn, >+ check_rep_fn=check_rep_fn, >+ check_kdc_private_fn=self.generic_check_kdc_private, >+ tgt=tgt, >+ authenticator_subkey=subkey, >+ kdc_options=str(kdc_options)) >+ >+ rep = self._generic_kdc_exchange(kdc_exchange_dict, >+ cname=None, >+ realm=realm, >+ sname=sname, >+ etypes=etypes) >+ >+ if expected_error_mode: >+ enc_part = None >+ else: >+ ticket_creds = kdc_exchange_dict['rep_ticket_creds'] >+ enc_part = ticket_creds.encpart_private >+ >+ return rep, enc_part > > # Named tuple to contain values of interest when the PAC is decoded. > PacData = namedtuple( >diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py >index 97f9dd41339..dad9e6b88df 100755 >--- a/python/samba/tests/krb5/kdc_tgs_tests.py >+++ b/python/samba/tests/krb5/kdc_tgs_tests.py >@@ -84,7 +84,8 @@ class KdcTgsTests(KDCBaseTest): > name_type=NT_PRINCIPAL, > names=["host", samdb.host_dns_name()]) > >- (rep, enc_part) = self.tgs_req(cname, sname, realm, ticket, key, etype) >+ (rep, enc_part) = self.tgs_req(cname, sname, realm, ticket, key, etype, >+ expected_error_mode=KDC_ERR_BADMATCH) > > self.assertIsNone( > enc_part, >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 632f69794e6..7eba62b4022 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2039,7 +2039,6 @@ class RawKerberosTest(TestCaseInTempDir): > error_code=0) > > ticket_private = None >- self.assertIsNotNone(ticket_decryption_key) > if ticket_decryption_key is not None: > self.assertElementEqual(ticket_encpart, 'etype', > ticket_decryption_key.etype) >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index a3f9478059f..c83136d6421 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -822,22 +822,26 @@ planoldpythontestsuite("fl2008r2dc:local", "samba.tests.krb5.xrealm_tests") > planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.test_ccache", > environ={ > 'ADMIN_USERNAME': '$USERNAME', >- 'ADMIN_PASSWORD': '$PASSWORD' >+ 'ADMIN_PASSWORD': '$PASSWORD', >+ 'STRICT_CHECKING': '0' > }) > planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.test_ldap", > environ={ > 'ADMIN_USERNAME': '$USERNAME', >- 'ADMIN_PASSWORD': '$PASSWORD' >+ 'ADMIN_PASSWORD': '$PASSWORD', >+ 'STRICT_CHECKING': '0' > }) > planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.test_rpc", > environ={ > 'ADMIN_USERNAME': '$USERNAME', >- 'ADMIN_PASSWORD': '$PASSWORD' >+ 'ADMIN_PASSWORD': '$PASSWORD', >+ 'STRICT_CHECKING': '0' > }) > planoldpythontestsuite("ad_dc_smb1", "samba.tests.krb5.test_smb", > environ={ > 'ADMIN_USERNAME': '$USERNAME', >- 'ADMIN_PASSWORD': '$PASSWORD' >+ 'ADMIN_PASSWORD': '$PASSWORD', >+ 'STRICT_CHECKING': '0' > }) > > for env in ["ad_dc", smbv1_disabled_testenv]: >@@ -1427,7 +1431,8 @@ planpythontestsuite( > "samba.tests.krb5.kdc_tgs_tests", > environ={ > 'ADMIN_USERNAME': '$USERNAME', >- 'ADMIN_PASSWORD': '$PASSWORD' >+ 'ADMIN_PASSWORD': '$PASSWORD', >+ 'STRICT_CHECKING': '0' > }) > planpythontestsuite( > "ad_dc", >@@ -1442,7 +1447,8 @@ planpythontestsuite( > "samba.tests.krb5.ms_kile_client_principal_lookup_tests", > environ={ > 'ADMIN_USERNAME': '$USERNAME', >- 'ADMIN_PASSWORD': '$PASSWORD' >+ 'ADMIN_PASSWORD': '$PASSWORD', >+ 'STRICT_CHECKING': '0' > }) > > for env in [ >-- >2.25.1 > > >From 97e219b21b6605574fcf6f3dfebe089dd9fbd605 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 16 Sep 2021 11:16:27 +1200 >Subject: [PATCH 040/159] tests/krb5: Allow tgs_req() to send additional padata > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 1f0654b8facf3b9b2288d2569a573ff3a5ca4a82) >--- > python/samba/tests/krb5/kdc_base_test.py | 9 ++++++++- > 1 file changed, 8 insertions(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 6a370d3036e..57ef1bceb49 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -1067,7 +1067,7 @@ class KDCBaseTest(RawKerberosTest): > self.assertEqual(rep['error-code'], expected, "rep = {%s}" % rep) > > def tgs_req(self, cname, sname, realm, ticket, key, etypes, >- expected_error_mode=0): >+ expected_error_mode=0, padata=None): > '''Send a TGS-REQ, returns the response and the decrypted and > decoded enc-part > ''' >@@ -1090,6 +1090,12 @@ class KDCBaseTest(RawKerberosTest): > check_error_fn = self.generic_check_kdc_error > check_rep_fn = None > >+ def generate_padata(_kdc_exchange_dict, >+ _callback_dict, >+ req_body): >+ >+ return padata, req_body >+ > kdc_exchange_dict = self.tgs_exchange_dict( > expected_crealm=realm, > expected_cname=cname, >@@ -1099,6 +1105,7 @@ class KDCBaseTest(RawKerberosTest): > check_error_fn=check_error_fn, > check_rep_fn=check_rep_fn, > check_kdc_private_fn=self.generic_check_kdc_private, >+ generate_padata_fn=generate_padata if padata is not None else None, > tgt=tgt, > authenticator_subkey=subkey, > kdc_options=str(kdc_options)) >-- >2.25.1 > > >From 2de8b9db68bb7547f0977733f521787b54af642e Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 16 Sep 2021 11:18:12 +1200 >Subject: [PATCH 041/159] tests/krb5: Allow tgs_req() to specify different > kdc-options > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 1a3426da54463c3e454c1b76c3df4e96882e6aa9) >--- > python/samba/tests/krb5/kdc_base_test.py | 4 +--- > 1 file changed, 1 insertion(+), 3 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 57ef1bceb49..c448f127c0c 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -1067,13 +1067,11 @@ class KDCBaseTest(RawKerberosTest): > self.assertEqual(rep['error-code'], expected, "rep = {%s}" % rep) > > def tgs_req(self, cname, sname, realm, ticket, key, etypes, >- expected_error_mode=0, padata=None): >+ expected_error_mode=0, padata=None, kdc_options=0): > '''Send a TGS-REQ, returns the response and the decrypted and > decoded enc-part > ''' > >- kdc_options = "0" >- > subkey = self.RandomKey(key.etype) > > (ctime, cusec) = self.get_KerberosTimeWithUsec() >-- >2.25.1 > > >From 573d1ebcec88ffa428908217deb660e61a4235ac Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 16 Sep 2021 11:25:01 +1200 >Subject: [PATCH 042/159] tests/krb5: Allow tgs_req() to send requests to the > RODC > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 6403a09d94ab54f89d6e50601ae6b19ab7e6aae7) >--- > python/samba/tests/krb5/kdc_base_test.py | 6 ++++-- > 1 file changed, 4 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index c448f127c0c..5ef08eb32fe 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -1067,7 +1067,8 @@ class KDCBaseTest(RawKerberosTest): > self.assertEqual(rep['error-code'], expected, "rep = {%s}" % rep) > > def tgs_req(self, cname, sname, realm, ticket, key, etypes, >- expected_error_mode=0, padata=None, kdc_options=0): >+ expected_error_mode=0, padata=None, kdc_options=0, >+ to_rodc=False): > '''Send a TGS-REQ, returns the response and the decrypted and > decoded enc-part > ''' >@@ -1106,7 +1107,8 @@ class KDCBaseTest(RawKerberosTest): > generate_padata_fn=generate_padata if padata is not None else None, > tgt=tgt, > authenticator_subkey=subkey, >- kdc_options=str(kdc_options)) >+ kdc_options=str(kdc_options), >+ to_rodc=to_rodc) > > rep = self._generic_kdc_exchange(kdc_exchange_dict, > cname=None, >-- >2.25.1 > > >From ca126cef2eb5e06265a9e557a6dd381b0b2ee2b2 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 16 Sep 2021 11:52:46 +1200 >Subject: [PATCH 043/159] tests/krb5: Allow as_req() to specify different > kdc-options > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit a5e62d681d81a422bac7bd89dc27ef2314d77457) >--- > python/samba/tests/krb5/kdc_base_test.py | 3 +-- > 1 file changed, 1 insertion(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 5ef08eb32fe..ae62c9d5fc6 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -913,12 +913,11 @@ class KDCBaseTest(RawKerberosTest): > fallback_creds_fn=download_krbtgt_creds) > return c > >- def as_req(self, cname, sname, realm, etypes, padata=None): >+ def as_req(self, cname, sname, realm, etypes, padata=None, kdc_options=0): > '''Send a Kerberos AS_REQ, returns the undecoded response > ''' > > till = self.get_KerberosTime(offset=36000) >- kdc_options = 0 > > req = self.AS_REQ_create(padata=padata, > kdc_options=str(kdc_options), >-- >2.25.1 > > >From 258f0190aa80d74942d9d3dc5e55e4636782342d Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 16 Sep 2021 12:06:51 +1200 >Subject: [PATCH 044/159] tests/krb5: Use PAC buffer type constants from > krb5pac.idl > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 3504e99dc5bcc206ca2964012b7fdca541555416) >--- > python/samba/tests/krb5/kdc_base_test.py | 13 +++---------- > 1 file changed, 3 insertions(+), 10 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index ae62c9d5fc6..2cebd9ef0cf 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -1127,13 +1127,6 @@ class KDCBaseTest(RawKerberosTest): > PacData = namedtuple( > "PacData", > "account_name account_sid logon_name upn domain_name") >- PAC_LOGON_INFO = 1 >- PAC_CREDENTIAL_INFO = 2 >- PAC_SRV_CHECKSUM = 6 >- PAC_KDC_CHECKSUM = 7 >- PAC_LOGON_NAME = 10 >- PAC_CONSTRAINED_DELEGATION = 11 >- PAC_UPN_DNS_INFO = 12 > > def get_pac_data(self, authorization_data): > '''Decode the PAC element contained in the authorization-data element >@@ -1154,15 +1147,15 @@ class KDCBaseTest(RawKerberosTest): > for ad in (x for x in buf if x['ad-type'] == AD_WIN2K_PAC): > pb = ndr_unpack(krb5pac.PAC_DATA, ad['ad-data']) > for pac in pb.buffers: >- if pac.type == self.PAC_LOGON_INFO: >+ if pac.type == krb5pac.PAC_TYPE_LOGON_INFO: > account_name = ( > pac.info.info.info3.base.account_name) > user_sid = ( > str(pac.info.info.info3.base.domain_sid) > + "-" + str(pac.info.info.info3.base.rid)) >- elif pac.type == self.PAC_LOGON_NAME: >+ elif pac.type == krb5pac.PAC_TYPE_LOGON_NAME: > logon_name = pac.info.account_name >- elif pac.type == self.PAC_UPN_DNS_INFO: >+ elif pac.type == krb5pac.PAC_TYPE_UPN_DNS_INFO: > upn = pac.info.upn_name > domain_name = pac.info.dns_domain_name > >-- >2.25.1 > > >From 6b53053e55f1e74f2c5b18b7b933503735e6c158 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 16 Sep 2021 12:13:51 +1200 >Subject: [PATCH 045/159] tests/krb5: Don't manually create PAC request and > options in fast_tests > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit c226029655ca361560d93298a6729a021f2f6b75) >--- > python/samba/tests/krb5/fast_tests.py | 17 +++++++++-------- > python/samba/tests/krb5/raw_testcase.py | 5 ----- > 2 files changed, 9 insertions(+), 13 deletions(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index 8024b92f445..dedf7a57a4b 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -1553,10 +1553,7 @@ class FAST_Tests(KDCBaseTest): > 'canonicalize,' > 'renewable-ok')) > >- pac_request = self.get_pa_pac_request() >- pac_options = self.get_pa_pac_options('1') # supports claims >- >- padata = [pac_request, pac_options] >+ pac_options = '1' # supports claims > > rep, kdc_exchange_dict = self._test_as_exchange( > cname=cname, >@@ -1571,10 +1568,12 @@ class FAST_Tests(KDCBaseTest): > expected_sname=sname, > expected_salt=salt, > etypes=etype, >- padata=padata, >+ padata=None, > kdc_options=kdc_options, > preauth_key=None, >- ticket_decryption_key=ticket_decryption_key) >+ ticket_decryption_key=ticket_decryption_key, >+ pac_request=True, >+ pac_options=pac_options) > self.check_pre_authentication(rep) > > etype_info2 = kdc_exchange_dict['preauth_etype_info2'] >@@ -1585,7 +1584,7 @@ class FAST_Tests(KDCBaseTest): > > ts_enc_padata = self.get_enc_timestamp_pa_data(creds, rep) > >- padata = [ts_enc_padata, pac_request, pac_options] >+ padata = [ts_enc_padata] > > expected_realm = realm.upper() > >@@ -1608,7 +1607,9 @@ class FAST_Tests(KDCBaseTest): > padata=padata, > kdc_options=kdc_options, > preauth_key=preauth_key, >- ticket_decryption_key=ticket_decryption_key) >+ ticket_decryption_key=ticket_decryption_key, >+ pac_request=True, >+ pac_options=pac_options) > self.check_as_reply(rep) > > tgt = rep['ticket'] >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 7eba62b4022..39821240941 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1177,11 +1177,6 @@ class RawKerberosTest(TestCaseInTempDir): > pa_data = self.PA_DATA_create(PADATA_PAC_REQUEST, pa_pac) > return pa_data > >- def get_pa_pac_request(self, request_pac=True): >- pac_request = self.KERB_PA_PAC_REQUEST_create(request_pac) >- >- return pac_request >- > def get_pa_pac_options(self, options): > pac_options = self.PA_PAC_OPTIONS_create(options) > pac_options = self.der_encode(pac_options, >-- >2.25.1 > > >From 850595df3b4b3368a1541614ff5f879424b83fef Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 16 Sep 2021 12:19:28 +1200 >Subject: [PATCH 046/159] tests/krb5: Set DN of created accounts to ldb.Dn type > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 7645dfa5bedee7ef3f7debbf0fa7600bd1c4bd79) >--- > python/samba/tests/krb5/kdc_base_test.py | 14 +++++++------- > 1 file changed, 7 insertions(+), 7 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 2cebd9ef0cf..e510ccbe46e 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -228,7 +228,7 @@ class KDCBaseTest(RawKerberosTest): > > return default_enctypes > >- def create_account(self, ldb, name, machine_account=False, >+ def create_account(self, samdb, name, machine_account=False, > spn=None, upn=None, additional_details=None, > ou=None, account_control=0): > '''Create an account for testing. >@@ -239,13 +239,13 @@ class KDCBaseTest(RawKerberosTest): > guid = (DS_GUID_COMPUTERS_CONTAINER if machine_account > else DS_GUID_USERS_CONTAINER) > >- ou = ldb.get_wellknown_dn(ldb.get_default_basedn(), guid) >+ ou = samdb.get_wellknown_dn(samdb.get_default_basedn(), guid) > > dn = "CN=%s,%s" % (name, ou) > > # remove the account if it exists, this will happen if a previous test > # run failed >- delete_force(ldb, dn) >+ delete_force(samdb, dn) > if machine_account: > object_class = "computer" > account_name = "%s$" % name >@@ -270,19 +270,19 @@ class KDCBaseTest(RawKerberosTest): > details["userPrincipalName"] = upn > if additional_details is not None: > details.update(additional_details) >- ldb.add(details) >+ samdb.add(details) > > creds = KerberosCredentials() > creds.guess(self.get_lp()) >- creds.set_realm(ldb.domain_dns_name().upper()) >- creds.set_domain(ldb.domain_netbios_name().upper()) >+ creds.set_realm(samdb.domain_dns_name().upper()) >+ creds.set_domain(samdb.domain_netbios_name().upper()) > creds.set_password(password) > creds.set_username(account_name) > if machine_account: > creds.set_workstation(name) > else: > creds.set_workstation('') >- creds.set_dn(dn) >+ creds.set_dn(ldb.Dn(samdb, dn)) > # > # Save the account name so it can be deleted in tearDownClass > self.accounts.add(dn) >-- >2.25.1 > > >From db5bd19429b5d2ee5520d9fa82f1872b418cc4aa Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 16 Sep 2021 12:38:38 +1200 >Subject: [PATCH 047/159] tests/krb5: Allow get_service_ticket() to get tickets > from the RODC > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 5d3a135c2326edc9ca8f56bea24d2f52320f4fd6) >--- > python/samba/tests/krb5/fast_tests.py | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index dedf7a57a4b..74fe11c5a90 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -1497,7 +1497,7 @@ class FAST_Tests(KDCBaseTest): > self.assertTrue( > security.KERB_ENCTYPE_CLAIMS_SUPPORTED & krbtgt_etypes) > >- def get_service_ticket(self, tgt, target_creds, service='host'): >+ def get_service_ticket(self, tgt, target_creds, service='host', to_rodc=False): > etype = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) > > key = tgt.session_key >@@ -1510,7 +1510,7 @@ class FAST_Tests(KDCBaseTest): > sname = self.PrincipalName_create(name_type=NT_PRINCIPAL, > names=[service, target_name]) > >- rep, enc_part = self.tgs_req(cname, sname, realm, ticket, key, etype) >+ rep, enc_part = self.tgs_req(cname, sname, realm, ticket, key, etype, to_rodc=to_rodc) > > service_ticket = rep['ticket'] > >-- >2.25.1 > > >From 350c5205d829e99a2f0165f207ee81dbbaa83919 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 16 Sep 2021 12:41:46 +1200 >Subject: [PATCH 048/159] tests/krb5: Allow get_tgt() to get tickets from the > RODC > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 2d69805b1e3a8022f1418605e5f29ae0bbaa4a06) >--- > python/samba/tests/krb5/fast_tests.py | 13 +++++++++---- > 1 file changed, 9 insertions(+), 4 deletions(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index 74fe11c5a90..9109a63d704 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -1530,7 +1530,7 @@ class FAST_Tests(KDCBaseTest): > > return service_ticket_creds > >- def get_tgt(self, creds): >+ def get_tgt(self, creds, to_rodc=False): > user_name = creds.get_username() > realm = creds.get_realm() > >@@ -1544,7 +1544,10 @@ class FAST_Tests(KDCBaseTest): > > till = self.get_KerberosTime(offset=36000) > >- krbtgt_creds = self.get_krbtgt_creds() >+ if to_rodc: >+ krbtgt_creds = self.get_rodc_krbtgt_creds() >+ else: >+ krbtgt_creds = self.get_krbtgt_creds() > ticket_decryption_key = ( > self.TicketDecryptionKey_from_creds(krbtgt_creds)) > >@@ -1573,7 +1576,8 @@ class FAST_Tests(KDCBaseTest): > preauth_key=None, > ticket_decryption_key=ticket_decryption_key, > pac_request=True, >- pac_options=pac_options) >+ pac_options=pac_options, >+ to_rodc=to_rodc) > self.check_pre_authentication(rep) > > etype_info2 = kdc_exchange_dict['preauth_etype_info2'] >@@ -1609,7 +1613,8 @@ class FAST_Tests(KDCBaseTest): > preauth_key=preauth_key, > ticket_decryption_key=ticket_decryption_key, > pac_request=True, >- pac_options=pac_options) >+ pac_options=pac_options, >+ to_rodc=to_rodc) > self.check_as_reply(rep) > > tgt = rep['ticket'] >-- >2.25.1 > > >From f3f789c6e405f05fe0040d82f16c4f287e2f24c9 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 16 Sep 2021 13:14:06 +1200 >Subject: [PATCH 049/159] tests/krb5: Allow get_tgt() to specify different > kdc-options > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 4ecfa82e71b0dd5b71aa97973033c5c72257a0c3) >--- > python/samba/tests/krb5/fast_tests.py | 8 +++++--- > 1 file changed, 5 insertions(+), 3 deletions(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index 9109a63d704..826c3536fb9 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -1530,7 +1530,7 @@ class FAST_Tests(KDCBaseTest): > > return service_ticket_creds > >- def get_tgt(self, creds, to_rodc=False): >+ def get_tgt(self, creds, to_rodc=False, kdc_options=None): > user_name = creds.get_username() > realm = creds.get_realm() > >@@ -1551,10 +1551,12 @@ class FAST_Tests(KDCBaseTest): > ticket_decryption_key = ( > self.TicketDecryptionKey_from_creds(krbtgt_creds)) > >- kdc_options = str(krb5_asn1.KDCOptions('forwardable,' >+ if kdc_options is None: >+ kdc_options = krb5_asn1.KDCOptions('forwardable,' > 'renewable,' > 'canonicalize,' >- 'renewable-ok')) >+ 'renewable-ok') >+ kdc_options = str(kdc_options) > > pac_options = '1' # supports claims > >-- >2.25.1 > > >From e21c3148371e716c7a037e4462303eabb381f38c Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 16 Sep 2021 13:14:45 +1200 >Subject: [PATCH 050/159] tests/krb5: Allow get_tgt() to specify expected and > unexpected flags > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 035a8f198555ad1eedf8e2e6c565fbbbe4fbe7ce) >--- > python/samba/tests/krb5/fast_tests.py | 5 ++++- > 1 file changed, 4 insertions(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index 826c3536fb9..fd96c2b9c1a 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -1530,7 +1530,8 @@ class FAST_Tests(KDCBaseTest): > > return service_ticket_creds > >- def get_tgt(self, creds, to_rodc=False, kdc_options=None): >+ def get_tgt(self, creds, to_rodc=False, kdc_options=None, >+ expected_flags=None, unexpected_flags=None): > user_name = creds.get_username() > realm = creds.get_realm() > >@@ -1572,6 +1573,8 @@ class FAST_Tests(KDCBaseTest): > expected_srealm=realm, > expected_sname=sname, > expected_salt=salt, >+ expected_flags=expected_flags, >+ unexpected_flags=unexpected_flags, > etypes=etype, > padata=None, > kdc_options=kdc_options, >-- >2.25.1 > > >From 704227295c3d1bef68fa30aa11cd4cde8434c916 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 16 Sep 2021 13:24:46 +1200 >Subject: [PATCH 051/159] tests/krb5: Move get_tgt() and get_service_ticket() > to kdc_base_test > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 59c1043be25b92db75ab5676601cb15426ef37a3) >--- > python/samba/tests/krb5/fast_tests.py | 141 ---------------------- > python/samba/tests/krb5/kdc_base_test.py | 144 +++++++++++++++++++++++ > 2 files changed, 144 insertions(+), 141 deletions(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index fd96c2b9c1a..a74dc2a3cd0 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -1497,147 +1497,6 @@ class FAST_Tests(KDCBaseTest): > self.assertTrue( > security.KERB_ENCTYPE_CLAIMS_SUPPORTED & krbtgt_etypes) > >- def get_service_ticket(self, tgt, target_creds, service='host', to_rodc=False): >- etype = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) >- >- key = tgt.session_key >- ticket = tgt.ticket >- >- cname = tgt.cname >- realm = tgt.crealm >- >- target_name = target_creds.get_username()[:-1] >- sname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >- names=[service, target_name]) >- >- rep, enc_part = self.tgs_req(cname, sname, realm, ticket, key, etype, to_rodc=to_rodc) >- >- service_ticket = rep['ticket'] >- >- ticket_etype = service_ticket['enc-part']['etype'] >- target_key = self.TicketDecryptionKey_from_creds(target_creds, >- etype=ticket_etype) >- >- session_key = self.EncryptionKey_import(enc_part['key']) >- >- service_ticket_creds = KerberosTicketCreds(service_ticket, >- session_key, >- crealm=realm, >- cname=cname, >- srealm=realm, >- sname=sname, >- decryption_key=target_key) >- >- return service_ticket_creds >- >- def get_tgt(self, creds, to_rodc=False, kdc_options=None, >- expected_flags=None, unexpected_flags=None): >- user_name = creds.get_username() >- realm = creds.get_realm() >- >- salt = creds.get_salt() >- >- etype = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) >- cname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >- names=[user_name]) >- sname = self.PrincipalName_create(name_type=NT_SRV_INST, >- names=['krbtgt', realm]) >- >- till = self.get_KerberosTime(offset=36000) >- >- if to_rodc: >- krbtgt_creds = self.get_rodc_krbtgt_creds() >- else: >- krbtgt_creds = self.get_krbtgt_creds() >- ticket_decryption_key = ( >- self.TicketDecryptionKey_from_creds(krbtgt_creds)) >- >- if kdc_options is None: >- kdc_options = krb5_asn1.KDCOptions('forwardable,' >- 'renewable,' >- 'canonicalize,' >- 'renewable-ok') >- kdc_options = str(kdc_options) >- >- pac_options = '1' # supports claims >- >- rep, kdc_exchange_dict = self._test_as_exchange( >- cname=cname, >- realm=realm, >- sname=sname, >- till=till, >- client_as_etypes=etype, >- expected_error_mode=KDC_ERR_PREAUTH_REQUIRED, >- expected_crealm=realm, >- expected_cname=cname, >- expected_srealm=realm, >- expected_sname=sname, >- expected_salt=salt, >- expected_flags=expected_flags, >- unexpected_flags=unexpected_flags, >- etypes=etype, >- padata=None, >- kdc_options=kdc_options, >- preauth_key=None, >- ticket_decryption_key=ticket_decryption_key, >- pac_request=True, >- pac_options=pac_options, >- to_rodc=to_rodc) >- self.check_pre_authentication(rep) >- >- etype_info2 = kdc_exchange_dict['preauth_etype_info2'] >- >- preauth_key = self.PasswordKey_from_etype_info2(creds, >- etype_info2[0], >- creds.get_kvno()) >- >- ts_enc_padata = self.get_enc_timestamp_pa_data(creds, rep) >- >- padata = [ts_enc_padata] >- >- expected_realm = realm.upper() >- >- expected_sname = self.PrincipalName_create( >- name_type=NT_SRV_INST, names=['krbtgt', realm.upper()]) >- >- rep, kdc_exchange_dict = self._test_as_exchange( >- cname=cname, >- realm=realm, >- sname=sname, >- till=till, >- client_as_etypes=etype, >- expected_error_mode=0, >- expected_crealm=expected_realm, >- expected_cname=cname, >- expected_srealm=expected_realm, >- expected_sname=expected_sname, >- expected_salt=salt, >- etypes=etype, >- padata=padata, >- kdc_options=kdc_options, >- preauth_key=preauth_key, >- ticket_decryption_key=ticket_decryption_key, >- pac_request=True, >- pac_options=pac_options, >- to_rodc=to_rodc) >- self.check_as_reply(rep) >- >- tgt = rep['ticket'] >- >- enc_part = self.get_as_rep_enc_data(preauth_key, rep) >- session_key = self.EncryptionKey_import(enc_part['key']) >- >- ticket_creds = KerberosTicketCreds( >- tgt, >- session_key, >- crealm=realm, >- cname=cname, >- srealm=realm, >- sname=sname, >- decryption_key=ticket_decryption_key) >- >- return ticket_creds, enc_part >- > def get_mach_tgt(self): > if self.mach_tgt is None: > mach_creds = self.get_mach_creds() >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index e510ccbe46e..fbcc89a9b31 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -73,6 +73,7 @@ from samba.tests.krb5.rfc4120_constants import ( > KU_TICKET, > NT_PRINCIPAL, > NT_SRV_HST, >+ NT_SRV_INST, > PADATA_ENCRYPTED_CHALLENGE, > PADATA_ENC_TIMESTAMP, > PADATA_ETYPE_INFO2, >@@ -1123,6 +1124,149 @@ class KDCBaseTest(RawKerberosTest): > > return rep, enc_part > >+ def get_service_ticket(self, tgt, target_creds, service='host', >+ to_rodc=False): >+ etype = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) >+ >+ key = tgt.session_key >+ ticket = tgt.ticket >+ >+ cname = tgt.cname >+ realm = tgt.crealm >+ >+ target_name = target_creds.get_username()[:-1] >+ sname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >+ names=[service, target_name]) >+ >+ rep, enc_part = self.tgs_req(cname, sname, realm, ticket, key, etype, >+ to_rodc=to_rodc) >+ >+ service_ticket = rep['ticket'] >+ >+ ticket_etype = service_ticket['enc-part']['etype'] >+ target_key = self.TicketDecryptionKey_from_creds(target_creds, >+ etype=ticket_etype) >+ >+ session_key = self.EncryptionKey_import(enc_part['key']) >+ >+ service_ticket_creds = KerberosTicketCreds(service_ticket, >+ session_key, >+ crealm=realm, >+ cname=cname, >+ srealm=realm, >+ sname=sname, >+ decryption_key=target_key) >+ >+ return service_ticket_creds >+ >+ def get_tgt(self, creds, to_rodc=False, kdc_options=None, >+ expected_flags=None, unexpected_flags=None): >+ user_name = creds.get_username() >+ realm = creds.get_realm() >+ >+ salt = creds.get_salt() >+ >+ etype = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) >+ cname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >+ names=[user_name]) >+ sname = self.PrincipalName_create(name_type=NT_SRV_INST, >+ names=['krbtgt', realm]) >+ >+ till = self.get_KerberosTime(offset=36000) >+ >+ if to_rodc: >+ krbtgt_creds = self.get_rodc_krbtgt_creds() >+ else: >+ krbtgt_creds = self.get_krbtgt_creds() >+ ticket_decryption_key = ( >+ self.TicketDecryptionKey_from_creds(krbtgt_creds)) >+ >+ if kdc_options is None: >+ kdc_options = krb5_asn1.KDCOptions('forwardable,' >+ 'renewable,' >+ 'canonicalize,' >+ 'renewable-ok') >+ kdc_options = str(kdc_options) >+ >+ pac_options = '1' # supports claims >+ >+ rep, kdc_exchange_dict = self._test_as_exchange( >+ cname=cname, >+ realm=realm, >+ sname=sname, >+ till=till, >+ client_as_etypes=etype, >+ expected_error_mode=KDC_ERR_PREAUTH_REQUIRED, >+ expected_crealm=realm, >+ expected_cname=cname, >+ expected_srealm=realm, >+ expected_sname=sname, >+ expected_salt=salt, >+ expected_flags=expected_flags, >+ unexpected_flags=unexpected_flags, >+ etypes=etype, >+ padata=None, >+ kdc_options=kdc_options, >+ preauth_key=None, >+ ticket_decryption_key=ticket_decryption_key, >+ pac_request=True, >+ pac_options=pac_options, >+ to_rodc=to_rodc) >+ self.check_pre_authentication(rep) >+ >+ etype_info2 = kdc_exchange_dict['preauth_etype_info2'] >+ >+ preauth_key = self.PasswordKey_from_etype_info2(creds, >+ etype_info2[0], >+ creds.get_kvno()) >+ >+ ts_enc_padata = self.get_enc_timestamp_pa_data(creds, rep) >+ >+ padata = [ts_enc_padata] >+ >+ expected_realm = realm.upper() >+ >+ expected_sname = self.PrincipalName_create( >+ name_type=NT_SRV_INST, names=['krbtgt', realm.upper()]) >+ >+ rep, kdc_exchange_dict = self._test_as_exchange( >+ cname=cname, >+ realm=realm, >+ sname=sname, >+ till=till, >+ client_as_etypes=etype, >+ expected_error_mode=0, >+ expected_crealm=expected_realm, >+ expected_cname=cname, >+ expected_srealm=expected_realm, >+ expected_sname=expected_sname, >+ expected_salt=salt, >+ etypes=etype, >+ padata=padata, >+ kdc_options=kdc_options, >+ preauth_key=preauth_key, >+ ticket_decryption_key=ticket_decryption_key, >+ pac_request=True, >+ pac_options=pac_options, >+ to_rodc=to_rodc) >+ self.check_as_reply(rep) >+ >+ tgt = rep['ticket'] >+ >+ enc_part = self.get_as_rep_enc_data(preauth_key, rep) >+ session_key = self.EncryptionKey_import(enc_part['key']) >+ >+ ticket_creds = KerberosTicketCreds( >+ tgt, >+ session_key, >+ crealm=realm, >+ cname=cname, >+ srealm=realm, >+ sname=sname, >+ decryption_key=ticket_decryption_key) >+ >+ return ticket_creds, enc_part >+ > # Named tuple to contain values of interest when the PAC is decoded. > PacData = namedtuple( > "PacData", >-- >2.25.1 > > >From f3f2412ba224b85c8b4dcf70b79052c5dcc44616 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 21 Sep 2021 11:51:05 +1200 >Subject: [PATCH 052/159] tests/krb5: Return encpart from get_tgt() as part of > KerberosTicketCreds > >The encpart is already contained in ticket_creds, so it no longer needs >to be returned as a separate value. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 6193f7433b15579aa32b26a146287923c9d3844d) >--- > python/samba/tests/krb5/fast_tests.py | 8 ++------ > python/samba/tests/krb5/kdc_base_test.py | 16 ++-------------- > 2 files changed, 4 insertions(+), 20 deletions(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index a74dc2a3cd0..42e75e7513c 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -67,11 +67,9 @@ class FAST_Tests(KDCBaseTest): > super().setUpClass() > > cls.user_tgt = None >- cls.user_enc_part = None > cls.user_service_ticket = None > > cls.mach_tgt = None >- cls.mach_enc_part = None > cls.mach_service_ticket = None > > def setUp(self): >@@ -1500,16 +1498,14 @@ class FAST_Tests(KDCBaseTest): > def get_mach_tgt(self): > if self.mach_tgt is None: > mach_creds = self.get_mach_creds() >- type(self).mach_tgt, type(self).mach_enc_part = ( >- self.get_tgt(mach_creds)) >+ type(self).mach_tgt = self.get_tgt(mach_creds) > > return self.mach_tgt > > def get_user_tgt(self): > if self.user_tgt is None: > user_creds = self.get_client_creds() >- type(self).user_tgt, type(self).user_enc_part = ( >- self.get_tgt(user_creds)) >+ type(self).user_tgt = self.get_tgt(user_creds) > > return self.user_tgt > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index fbcc89a9b31..28d34210fce 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -1251,21 +1251,9 @@ class KDCBaseTest(RawKerberosTest): > to_rodc=to_rodc) > self.check_as_reply(rep) > >- tgt = rep['ticket'] >+ ticket_creds = kdc_exchange_dict['rep_ticket_creds'] > >- enc_part = self.get_as_rep_enc_data(preauth_key, rep) >- session_key = self.EncryptionKey_import(enc_part['key']) >- >- ticket_creds = KerberosTicketCreds( >- tgt, >- session_key, >- crealm=realm, >- cname=cname, >- srealm=realm, >- sname=sname, >- decryption_key=ticket_decryption_key) >- >- return ticket_creds, enc_part >+ return ticket_creds > > # Named tuple to contain values of interest when the PAC is decoded. > PacData = namedtuple( >-- >2.25.1 > > >From d2183a56f2dc8105d8be68352b37f31da1bd9896 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 21 Sep 2021 11:51:20 +1200 >Subject: [PATCH 053/159] tests/krb5: Cache obtained tickets > >Now tickets obtained with get_tgt() and get_service_ticket() make use of >a cache so they can be reused, unless the 'fresh' parameter is specified >as true. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 419e4061ced466ec7e5e23f815823b540ef4751c) >--- > python/samba/tests/krb5/kdc_base_test.py | 29 ++++++++++++++++++++++-- > 1 file changed, 27 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 28d34210fce..59175c7bb2f 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -110,6 +110,7 @@ class KDCBaseTest(RawKerberosTest): > cls.accounts = set() > > cls.account_cache = {} >+ cls.tkt_cache = {} > > cls._rodc_ctx = None > >@@ -1125,7 +1126,17 @@ class KDCBaseTest(RawKerberosTest): > return rep, enc_part > > def get_service_ticket(self, tgt, target_creds, service='host', >- to_rodc=False): >+ to_rodc=False, fresh=False): >+ user_name = tgt.cname['name-string'][0] >+ target_name = target_creds.get_username() >+ cache_key = (user_name, target_name, service, to_rodc) >+ >+ if not fresh: >+ ticket = self.tkt_cache.get(cache_key) >+ >+ if ticket is not None: >+ return ticket >+ > etype = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) > > key = tgt.session_key >@@ -1157,11 +1168,23 @@ class KDCBaseTest(RawKerberosTest): > sname=sname, > decryption_key=target_key) > >+ self.tkt_cache[cache_key] = service_ticket_creds >+ > return service_ticket_creds > > def get_tgt(self, creds, to_rodc=False, kdc_options=None, >- expected_flags=None, unexpected_flags=None): >+ expected_flags=None, unexpected_flags=None, >+ fresh=False): > user_name = creds.get_username() >+ cache_key = (user_name, to_rodc, kdc_options, >+ expected_flags, unexpected_flags) >+ >+ if not fresh: >+ tgt = self.tkt_cache.get(cache_key) >+ >+ if tgt is not None: >+ return tgt >+ > realm = creds.get_realm() > > salt = creds.get_salt() >@@ -1253,6 +1276,8 @@ class KDCBaseTest(RawKerberosTest): > > ticket_creds = kdc_exchange_dict['rep_ticket_creds'] > >+ self.tkt_cache[cache_key] = ticket_creds >+ > return ticket_creds > > # Named tuple to contain values of interest when the PAC is decoded. >-- >2.25.1 > > >From 263f23c7dee40d95f9e87f24c6f48778c9376023 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 16 Sep 2021 16:54:57 +1200 >Subject: [PATCH 054/159] tests/krb5: Add methods for creating zeroed checksums > and verifying checksums > >Creating a zeroed checksum is needed for signing a PAC. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit a562882b15125902c5d89f094b8c9b1150f5d010) >--- > python/samba/tests/krb5/raw_testcase.py | 17 +++++++++++++++++ > 1 file changed, 17 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 39821240941..be49f16b1f7 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -232,12 +232,29 @@ class Krb5EncryptionKey: > plaintext = kcrypto.decrypt(self.key, usage, ciphertext) > return plaintext > >+ def make_zeroed_checksum(self, ctype=None): >+ if ctype is None: >+ ctype = self.ctype >+ >+ checksum_len = kcrypto.checksum_len(ctype) >+ return bytes(checksum_len) >+ > def make_checksum(self, usage, plaintext, ctype=None): > if ctype is None: > ctype = self.ctype > cksum = kcrypto.make_checksum(ctype, self.key, usage, plaintext) > return cksum > >+ def verify_checksum(self, usage, plaintext, ctype, cksum): >+ if self.ctype != ctype: >+ raise AssertionError(f'{self.ctype} != {ctype}') >+ >+ kcrypto.verify_checksum(ctype, >+ self.key, >+ usage, >+ plaintext, >+ cksum) >+ > def export_obj(self): > EncryptionKey_obj = { > 'keytype': self.etype, >-- >2.25.1 > > >From 60d3828fdc85c47259dc70b30bcd894bd39fc34c Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 16 Sep 2021 17:20:22 +1200 >Subject: [PATCH 055/159] tests/krb5: Add RodcPacEncryptionKey type allowing > for RODC PAC signatures > >Signatures created by an RODC have an RODCIdentifier appended to them >identifying the RODC's krbtgt account. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Isaac Boukris <iboukris@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >Autobuild-User(master): Andrew Bartlett <abartlet@samba.org> >Autobuild-Date(master): Tue Sep 21 23:55:39 UTC 2021 on sn-devel-184 > >(cherry picked from commit ec95b3042bf2649c0600cafb12818c27242b5098) >--- > python/samba/tests/krb5/raw_testcase.py | 45 +++++++++++++++++++++++-- > 1 file changed, 42 insertions(+), 3 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index be49f16b1f7..e213b5eef9b 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -263,6 +263,45 @@ class Krb5EncryptionKey: > return EncryptionKey_obj > > >+class RodcPacEncryptionKey(Krb5EncryptionKey): >+ def __init__(self, key, kvno, rodc_id=None): >+ super().__init__(key, kvno) >+ >+ if rodc_id is None: >+ kvno = self.kvno >+ if kvno is not None: >+ kvno >>= 16 >+ kvno &= (1 << 16) - 1 >+ >+ rodc_id = kvno or None >+ >+ if rodc_id is not None: >+ self.rodc_id = rodc_id.to_bytes(2, byteorder='little') >+ else: >+ self.rodc_id = b'' >+ >+ def make_zeroed_checksum(self, ctype=None): >+ checksum = super().make_zeroed_checksum(ctype) >+ return checksum + bytes(len(self.rodc_id)) >+ >+ def make_checksum(self, usage, plaintext, ctype=None): >+ checksum = super().make_checksum(usage, plaintext, ctype) >+ return checksum + self.rodc_id >+ >+ def verify_checksum(self, usage, plaintext, ctype, cksum): >+ if self.rodc_id: >+ cksum, cksum_rodc_id = cksum[:-2], cksum[-2:] >+ >+ if self.rodc_id != cksum_rodc_id: >+ raise AssertionError(f'{self.rodc_id.hex()} != ' >+ f'{cksum_rodc_id.hex()}') >+ >+ super().verify_checksum(usage, >+ plaintext, >+ ctype, >+ cksum) >+ >+ > class KerberosCredentials(Credentials): > def __init__(self): > super(KerberosCredentials, self).__init__() >@@ -325,7 +364,7 @@ class KerberosCredentials(Credentials): > etype = int(etype) > contents = binascii.a2b_hex(hexkey) > key = kcrypto.Key(etype, contents) >- self.forced_keys[etype] = Krb5EncryptionKey(key, self.kvno) >+ self.forced_keys[etype] = RodcPacEncryptionKey(key, self.kvno) > > def get_forced_key(self, etype): > etype = int(etype) >@@ -982,13 +1021,13 @@ class RawKerberosTest(TestCaseInTempDir): > > def SessionKey_create(self, etype, contents, kvno=None): > key = kcrypto.Key(etype, contents) >- return Krb5EncryptionKey(key, kvno) >+ return RodcPacEncryptionKey(key, kvno) > > def PasswordKey_create(self, etype=None, pwd=None, salt=None, kvno=None): > self.assertIsNotNone(pwd) > self.assertIsNotNone(salt) > key = kcrypto.string_to_key(etype, pwd, salt) >- return Krb5EncryptionKey(key, kvno) >+ return RodcPacEncryptionKey(key, kvno) > > def PasswordKey_from_etype_info2(self, creds, etype_info2, kvno=None): > e = etype_info2['etype'] >-- >2.25.1 > > >From 777027a9de37d085c130a6c704783a0686a17985 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 17 Sep 2021 14:56:51 +1200 >Subject: [PATCH 056/159] tests/krb5: Add method to verify ticket PAC checksums > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 12b5e72a35d632516980f6c051a5d83f913079e7) >--- > python/samba/tests/krb5/raw_testcase.py | 118 +++++++++++++++++++++++- > 1 file changed, 117 insertions(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index e213b5eef9b..265789cdb26 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -34,8 +34,9 @@ from pyasn1.codec.native.encoder import encode as pyasn1_native_encode > from pyasn1.codec.ber.encoder import BitStringEncoder > > from samba.credentials import Credentials >-from samba.dcerpc import security >+from samba.dcerpc import krb5pac, security > from samba.gensec import FEATURE_SEAL >+from samba.ndr import ndr_pack, ndr_unpack > > import samba.tests > from samba.tests import TestCaseInTempDir >@@ -418,6 +419,10 @@ class KerberosTicketCreds: > class RawKerberosTest(TestCaseInTempDir): > """A raw Kerberos Test case.""" > >+ pac_checksum_types = {krb5pac.PAC_TYPE_SRV_CHECKSUM, >+ krb5pac.PAC_TYPE_KDC_CHECKSUM, >+ krb5pac.PAC_TYPE_TICKET_CHECKSUM} >+ > etypes_to_test = ( > {"value": -1111, "name": "dummy", }, > {"value": kcrypto.Enctype.AES256, "name": "aes128", }, >@@ -2900,6 +2905,114 @@ class RawKerberosTest(TestCaseInTempDir): > ticket_blob) > self.assertEqual(expected_checksum, checksum) > >+ def verify_ticket(self, ticket, krbtgt_key, expect_pac=True): >+ # Check if the ticket is a TGT. >+ sname = ticket.ticket['sname'] >+ is_tgt = sname['name-string'][0] == b'krbtgt' >+ >+ # Decrypt the ticket. >+ >+ key = ticket.decryption_key >+ enc_part = ticket.ticket['enc-part'] >+ >+ self.assertElementEqual(enc_part, 'etype', key.etype) >+ self.assertElementKVNO(enc_part, 'kvno', key.kvno) >+ >+ enc_part = key.decrypt(KU_TICKET, enc_part['cipher']) >+ enc_part = self.der_decode( >+ enc_part, asn1Spec=krb5_asn1.EncTicketPart()) >+ >+ # Fetch the authorization data from the ticket. >+ auth_data = enc_part.get('authorization-data') >+ if expect_pac: >+ self.assertIsNotNone(auth_data) >+ elif auth_data is None: >+ return >+ >+ # Get a copy of the authdata with an empty PAC, and the existing PAC >+ # (if present). >+ empty_pac = self.get_empty_pac() >+ auth_data, pac_data = self.replace_pac(auth_data, >+ empty_pac, >+ expect_pac=expect_pac) >+ if not expect_pac: >+ return >+ >+ # Unpack the PAC as both PAC_DATA and PAC_DATA_RAW types. We use the >+ # raw type to create a new PAC with zeroed signatures for >+ # verification. This is because on Windows, the resource_groups field >+ # is added to PAC_LOGON_INFO after the info3 field has been created, >+ # which results in a different ordering of pointer values than Samba >+ # (see commit 0e201ecdc53). Using the raw type avoids changing >+ # PAC_LOGON_INFO, so verification against Windows can work. We still >+ # need the PAC_DATA type to retrieve the actual checksums, because the >+ # signatures in the raw type may contain padding bytes. >+ pac = ndr_unpack(krb5pac.PAC_DATA, >+ pac_data) >+ raw_pac = ndr_unpack(krb5pac.PAC_DATA_RAW, >+ pac_data) >+ >+ checksums = {} >+ >+ for pac_buffer, raw_pac_buffer in zip(pac.buffers, raw_pac.buffers): >+ buffer_type = pac_buffer.type >+ if buffer_type in self.pac_checksum_types: >+ self.assertNotIn(buffer_type, checksums, >+ f'Duplicate checksum type {buffer_type}') >+ >+ # Fetch the checksum and the checksum type from the PAC buffer. >+ checksum = pac_buffer.info.signature >+ ctype = pac_buffer.info.type >+ if ctype & 1 << 31: >+ ctype |= -1 << 31 >+ >+ checksums[buffer_type] = checksum, ctype >+ >+ if buffer_type != krb5pac.PAC_TYPE_TICKET_CHECKSUM: >+ # Zero the checksum field so that we can later verify the >+ # checksums. The ticket checksum field is not zeroed. >+ >+ signature = ndr_unpack( >+ krb5pac.PAC_SIGNATURE_DATA, >+ raw_pac_buffer.info.remaining) >+ signature.signature = bytes(len(checksum)) >+ raw_pac_buffer.info.remaining = ndr_pack( >+ signature) >+ >+ # Re-encode the PAC. >+ pac_data = ndr_pack(raw_pac) >+ >+ # Verify the signatures. >+ >+ server_checksum, server_ctype = checksums[ >+ krb5pac.PAC_TYPE_SRV_CHECKSUM] >+ Krb5EncryptionKey.verify_checksum(key, >+ KU_NON_KERB_CKSUM_SALT, >+ pac_data, >+ server_ctype, >+ server_checksum) >+ >+ kdc_checksum, kdc_ctype = checksums[ >+ krb5pac.PAC_TYPE_KDC_CHECKSUM] >+ krbtgt_key.verify_checksum(KU_NON_KERB_CKSUM_SALT, >+ server_checksum, >+ kdc_ctype, >+ kdc_checksum) >+ >+ if is_tgt: >+ self.assertNotIn(krb5pac.PAC_TYPE_TICKET_CHECKSUM, checksums) >+ else: >+ ticket_checksum, ticket_ctype = checksums[ >+ krb5pac.PAC_TYPE_TICKET_CHECKSUM] >+ enc_part['authorization-data'] = auth_data >+ enc_part = self.der_encode(enc_part, >+ asn1Spec=krb5_asn1.EncTicketPart()) >+ >+ krbtgt_key.verify_checksum(KU_NON_KERB_CKSUM_SALT, >+ enc_part, >+ ticket_ctype, >+ ticket_checksum) >+ > def replace_pac(self, auth_data, new_pac, expect_pac=True): > if new_pac is not None: > self.assertElementEqual(new_pac, 'ad-type', AD_WIN2K_PAC) >@@ -2943,6 +3056,9 @@ class RawKerberosTest(TestCaseInTempDir): > > return new_auth_data, old_pac > >+ def get_empty_pac(self): >+ return self.AuthorizationData_create(AD_WIN2K_PAC, bytes(1)) >+ > def get_outer_pa_dict(self, kdc_exchange_dict): > return self.get_pa_dict(kdc_exchange_dict['req_padata']) > >-- >2.25.1 > > >From df8bff002b2a5410e10b364b0d28cff83fd4369e Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 17 Sep 2021 15:26:12 +1200 >Subject: [PATCH 057/159] tests/krb5: Add method for modifying a ticket and > creating PAC checksums > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 1fcde7cb6ce50e0a08097841e92476f320560664) >--- > python/samba/tests/krb5/raw_testcase.py | 234 ++++++++++++++++++++++++ > 1 file changed, 234 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 265789cdb26..4ac7698ffab 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -3013,6 +3013,240 @@ class RawKerberosTest(TestCaseInTempDir): > ticket_ctype, > ticket_checksum) > >+ def modified_ticket(self, >+ ticket, *, >+ new_ticket_key=None, >+ modify_fn=None, >+ modify_pac_fn=None, >+ exclude_pac=False, >+ update_pac_checksums=True, >+ checksum_keys=None, >+ include_checksums=None): >+ if checksum_keys is None: >+ # A dict containing a key for each checksum type to be created in >+ # the PAC. >+ checksum_keys = {} >+ >+ if include_checksums is None: >+ # A dict containing a value for each checksum type; True if the >+ # checksum type is to be included in the PAC, False if it is to be >+ # excluded, or None/not present if the checksum is to be included >+ # based on its presence in the original PAC. >+ include_checksums = {} >+ >+ # Check that the values passed in by the caller make sense. >+ >+ self.assertLessEqual(checksum_keys.keys(), self.pac_checksum_types) >+ self.assertLessEqual(include_checksums.keys(), self.pac_checksum_types) >+ >+ if exclude_pac: >+ self.assertIsNone(modify_pac_fn) >+ >+ update_pac_checksums = False >+ >+ if not update_pac_checksums: >+ self.assertFalse(checksum_keys) >+ self.assertFalse(include_checksums) >+ >+ expect_pac = update_pac_checksums or modify_pac_fn is not None >+ >+ key = ticket.decryption_key >+ >+ if new_ticket_key is None: >+ # Use the same key to re-encrypt the ticket. >+ new_ticket_key = key >+ >+ if krb5pac.PAC_TYPE_SRV_CHECKSUM not in checksum_keys: >+ # If the server signature key is not present, fall back to the key >+ # used to encrypt the ticket. >+ checksum_keys[krb5pac.PAC_TYPE_SRV_CHECKSUM] = new_ticket_key >+ >+ if krb5pac.PAC_TYPE_TICKET_CHECKSUM not in checksum_keys: >+ # If the ticket signature key is not present, fall back to the key >+ # used for the KDC signature. >+ kdc_checksum_key = checksum_keys.get(krb5pac.PAC_TYPE_KDC_CHECKSUM) >+ if kdc_checksum_key is not None: >+ checksum_keys[krb5pac.PAC_TYPE_TICKET_CHECKSUM] = ( >+ kdc_checksum_key) >+ >+ # Decrypt the ticket. >+ >+ enc_part = ticket.ticket['enc-part'] >+ >+ self.assertElementEqual(enc_part, 'etype', key.etype) >+ self.assertElementKVNO(enc_part, 'kvno', key.kvno) >+ >+ enc_part = key.decrypt(KU_TICKET, enc_part['cipher']) >+ enc_part = self.der_decode( >+ enc_part, asn1Spec=krb5_asn1.EncTicketPart()) >+ >+ # Modify the ticket here. >+ if modify_fn is not None: >+ enc_part = modify_fn(enc_part) >+ >+ auth_data = enc_part.get('authorization-data') >+ if expect_pac: >+ self.assertIsNotNone(auth_data) >+ if auth_data is not None: >+ new_pac = None >+ if not exclude_pac: >+ # Get a copy of the authdata with an empty PAC, and the >+ # existing PAC (if present). >+ empty_pac = self.get_empty_pac() >+ empty_pac_auth_data, pac_data = self.replace_pac(auth_data, >+ empty_pac) >+ >+ if expect_pac: >+ self.assertIsNotNone(pac_data) >+ if pac_data is not None: >+ pac = ndr_unpack(krb5pac.PAC_DATA, pac_data) >+ >+ # Modify the PAC here. >+ if modify_pac_fn is not None: >+ pac = modify_pac_fn(pac) >+ >+ if update_pac_checksums: >+ # Get the enc-part with an empty PAC, which is needed >+ # to create a ticket signature. >+ enc_part_to_sign = enc_part.copy() >+ enc_part_to_sign['authorization-data'] = ( >+ empty_pac_auth_data) >+ enc_part_to_sign = self.der_encode( >+ enc_part_to_sign, >+ asn1Spec=krb5_asn1.EncTicketPart()) >+ >+ self.update_pac_checksums(pac, >+ checksum_keys, >+ include_checksums, >+ enc_part_to_sign) >+ >+ # Re-encode the PAC. >+ pac_data = ndr_pack(pac) >+ new_pac = self.AuthorizationData_create(AD_WIN2K_PAC, >+ pac_data) >+ >+ # Replace the PAC in the authorization data and re-add it to the >+ # ticket enc-part. >+ auth_data, _ = self.replace_pac(auth_data, new_pac) >+ enc_part['authorization-data'] = auth_data >+ >+ # Re-encrypt the ticket enc-part with the new key. >+ enc_part_new = self.der_encode(enc_part, >+ asn1Spec=krb5_asn1.EncTicketPart()) >+ enc_part_new = self.EncryptedData_create(new_ticket_key, >+ KU_TICKET, >+ enc_part_new) >+ >+ # Create a copy of the ticket with the new enc-part. >+ new_ticket = ticket.ticket.copy() >+ new_ticket['enc-part'] = enc_part_new >+ >+ new_ticket_creds = KerberosTicketCreds( >+ new_ticket, >+ session_key=ticket.session_key, >+ crealm=ticket.crealm, >+ cname=ticket.cname, >+ srealm=ticket.srealm, >+ sname=ticket.sname, >+ decryption_key=new_ticket_key, >+ ticket_private=enc_part, >+ encpart_private=ticket.encpart_private) >+ >+ return new_ticket_creds >+ >+ def update_pac_checksums(self, >+ pac, >+ checksum_keys, >+ include_checksums, >+ enc_part=None): >+ pac_buffers = pac.buffers >+ checksum_buffers = {} >+ >+ # Find the relevant PAC checksum buffers. >+ for pac_buffer in pac_buffers: >+ buffer_type = pac_buffer.type >+ if buffer_type in self.pac_checksum_types: >+ self.assertNotIn(buffer_type, checksum_buffers, >+ f'Duplicate checksum type {buffer_type}') >+ >+ checksum_buffers[buffer_type] = pac_buffer >+ >+ # Create any additional buffers that were requested but not >+ # present. Conversely, remove any buffers that were requested to be >+ # removed. >+ for buffer_type in self.pac_checksum_types: >+ if buffer_type in checksum_buffers: >+ if include_checksums.get(buffer_type) is False: >+ checksum_buffer = checksum_buffers.pop(buffer_type) >+ >+ pac.num_buffers -= 1 >+ pac_buffers.remove(checksum_buffer) >+ >+ elif include_checksums.get(buffer_type) is True: >+ info = krb5pac.PAC_SIGNATURE_DATA() >+ >+ checksum_buffer = krb5pac.PAC_BUFFER() >+ checksum_buffer.type = buffer_type >+ checksum_buffer.info = info >+ >+ pac_buffers.append(checksum_buffer) >+ pac.num_buffers += 1 >+ >+ checksum_buffers[buffer_type] = checksum_buffer >+ >+ # Fill the relevant checksum buffers. >+ for buffer_type, checksum_buffer in checksum_buffers.items(): >+ checksum_key = checksum_keys[buffer_type] >+ ctype = checksum_key.ctype & ((1 << 32) - 1) >+ >+ if buffer_type == krb5pac.PAC_TYPE_TICKET_CHECKSUM: >+ self.assertIsNotNone(enc_part) >+ >+ signature = checksum_key.make_checksum( >+ KU_NON_KERB_CKSUM_SALT, >+ enc_part) >+ >+ elif buffer_type == krb5pac.PAC_TYPE_SRV_CHECKSUM: >+ signature = Krb5EncryptionKey.make_zeroed_checksum( >+ checksum_key) >+ >+ else: >+ signature = checksum_key.make_zeroed_checksum() >+ >+ checksum_buffer.info.signature = signature >+ checksum_buffer.info.type = ctype >+ >+ # Add the new checksum buffers to the PAC. >+ pac.buffers = pac_buffers >+ >+ # Calculate the server and KDC checksums and insert them into the PAC. >+ >+ server_checksum_buffer = checksum_buffers.get( >+ krb5pac.PAC_TYPE_SRV_CHECKSUM) >+ if server_checksum_buffer is not None: >+ server_checksum_key = checksum_keys[krb5pac.PAC_TYPE_SRV_CHECKSUM] >+ >+ pac_data = ndr_pack(pac) >+ server_checksum = Krb5EncryptionKey.make_checksum( >+ server_checksum_key, >+ KU_NON_KERB_CKSUM_SALT, >+ pac_data) >+ >+ server_checksum_buffer.info.signature = server_checksum >+ >+ kdc_checksum_buffer = checksum_buffers.get( >+ krb5pac.PAC_TYPE_KDC_CHECKSUM) >+ if kdc_checksum_buffer is not None: >+ self.assertIsNotNone(server_checksum_buffer) >+ >+ kdc_checksum_key = checksum_keys[krb5pac.PAC_TYPE_KDC_CHECKSUM] >+ >+ kdc_checksum = kdc_checksum_key.make_checksum( >+ KU_NON_KERB_CKSUM_SALT, >+ server_checksum) >+ >+ kdc_checksum_buffer.info.signature = kdc_checksum >+ > def replace_pac(self, auth_data, new_pac, expect_pac=True): > if new_pac is not None: > self.assertElementEqual(new_pac, 'ad-type', AD_WIN2K_PAC) >-- >2.25.1 > > >From b9c7fd9b557ebc86e13abcd5ba86291523b2d481 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 21 Sep 2021 13:33:16 +1200 >Subject: [PATCH 058/159] tests/krb5: Simplify adding authdata to ticket by > using modified_ticket() > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 4c67a53cdca206a118e82b356db0faf0ddc011ab) >--- > python/samba/tests/krb5/fast_tests.py | 49 +++++-------------------- > python/samba/tests/krb5/raw_testcase.py | 8 ++++ > 2 files changed, 18 insertions(+), 39 deletions(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index 42e75e7513c..d8ccfaee325 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -25,10 +25,7 @@ import collections > import ldb > > from samba.dcerpc import security >-from samba.tests.krb5.raw_testcase import ( >- KerberosTicketCreds, >- Krb5EncryptionKey >-) >+from samba.tests.krb5.raw_testcase import Krb5EncryptionKey > from samba.tests.krb5.kdc_base_test import KDCBaseTest > from samba.tests.krb5.rfc4120_constants import ( > AD_FX_FAST_ARMOR, >@@ -45,7 +42,6 @@ from samba.tests.krb5.rfc4120_constants import ( > KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTIONS, > KRB_AS_REP, > KRB_TGS_REP, >- KU_TICKET, > NT_PRINCIPAL, > NT_SRV_INST, > PADATA_FX_COOKIE, >@@ -1428,44 +1424,19 @@ class FAST_Tests(KDCBaseTest): > def gen_tgt_fast_armor_auth_data(self): > user_tgt = self.get_user_tgt() > >- ticket_decryption_key = user_tgt.decryption_key >+ auth_data = self.generate_fast_armor_auth_data() >+ >+ def modify_fn(enc_part): >+ enc_part['authorization-data'].append(auth_data) > >- tgt_encpart = self.getElementValue(user_tgt.ticket, 'enc-part') >- self.assertElementEqual(tgt_encpart, 'etype', >- ticket_decryption_key.etype) >- self.assertElementKVNO(tgt_encpart, 'kvno', >- ticket_decryption_key.kvno) >- tgt_cipher = self.getElementValue(tgt_encpart, 'cipher') >- tgt_decpart = ticket_decryption_key.decrypt(KU_TICKET, tgt_cipher) >- tgt_private = self.der_decode(tgt_decpart, >- asn1Spec=krb5_asn1.EncTicketPart()) >+ return enc_part > >- auth_data = self.generate_fast_armor_auth_data() >- tgt_private['authorization-data'].append(auth_data) >- >- # Re-encrypt the user TGT. >- tgt_private_new = self.der_encode( >- tgt_private, >- asn1Spec=krb5_asn1.EncTicketPart()) >- tgt_encpart = self.EncryptedData_create(ticket_decryption_key, >- KU_TICKET, >- tgt_private_new) >- user_ticket = user_tgt.ticket.copy() >- user_ticket['enc-part'] = tgt_encpart >- >- user_tgt = KerberosTicketCreds( >- user_ticket, >- session_key=user_tgt.session_key, >- crealm=user_tgt.crealm, >- cname=user_tgt.cname, >- srealm=user_tgt.srealm, >- sname=user_tgt.sname, >- decryption_key=user_tgt.decryption_key, >- ticket_private=tgt_private, >- encpart_private=user_tgt.encpart_private) >+ checksum_keys = self.get_krbtgt_checksum_key() > > # Use our modifed TGT to replace the one in the request. >- return user_tgt >+ return self.modified_ticket(user_tgt, >+ modify_fn=modify_fn, >+ checksum_keys=checksum_keys) > > def create_fast_cookie(self, cookie): > self.assertIsNotNone(cookie) >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 4ac7698ffab..57013caafb1 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -3290,6 +3290,14 @@ class RawKerberosTest(TestCaseInTempDir): > > return new_auth_data, old_pac > >+ def get_krbtgt_checksum_key(self): >+ krbtgt_creds = self.get_krbtgt_creds() >+ krbtgt_key = self.TicketDecryptionKey_from_creds(krbtgt_creds) >+ >+ return { >+ krb5pac.PAC_TYPE_KDC_CHECKSUM: krbtgt_key >+ } >+ > def get_empty_pac(self): > return self.AuthorizationData_create(AD_WIN2K_PAC, bytes(1)) > >-- >2.25.1 > > >From b0611da0bef97c0fc136c336b51bf3f24f588dd0 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 21 Sep 2021 17:01:12 +1200 >Subject: [PATCH 059/159] tests/krb5: Make get_default_enctypes() return a set > of enctype constants > >This is often more convenient than a bitfield. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 7cedd383bcc1b5652ea65817b464d6e0485c7b8b) >--- > python/samba/tests/krb5/kdc_base_test.py | 13 ++++--------- > 1 file changed, 4 insertions(+), 9 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 59175c7bb2f..3d2d20cb65b 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -222,11 +222,11 @@ class KDCBaseTest(RawKerberosTest): > functional_level = self.get_domain_functional_level(samdb) > > # RC4 should always be supported >- default_enctypes = security.KERB_ENCTYPE_RC4_HMAC_MD5 >+ default_enctypes = {kcrypto.Enctype.RC4} > if functional_level >= DS_DOMAIN_FUNCTION_2008: > # AES is only supported at functional level 2008 or higher >- default_enctypes |= security.KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96 >- default_enctypes |= security.KERB_ENCTYPE_AES128_CTS_HMAC_SHA1_96 >+ default_enctypes.add(kcrypto.Enctype.AES256) >+ default_enctypes.add(kcrypto.Enctype.AES128) > > return default_enctypes > >@@ -513,12 +513,7 @@ class KDCBaseTest(RawKerberosTest): > > default_enctypes = self.get_default_enctypes() > >- if default_enctypes & security.KERB_ENCTYPE_RC4_HMAC_MD5: >- self.assertIn(kcrypto.Enctype.RC4, keys) >- if default_enctypes & security.KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96: >- self.assertIn(kcrypto.Enctype.AES256, keys) >- if default_enctypes & security.KERB_ENCTYPE_AES128_CTS_HMAC_SHA1_96: >- self.assertIn(kcrypto.Enctype.AES128, keys) >+ self.assertCountEqual(default_enctypes, keys) > > return keys > >-- >2.25.1 > > >From ca354e5eb13ecf62f546511364d7b2801b1ec4e8 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 21 Sep 2021 21:01:46 +1200 >Subject: [PATCH 060/159] tests/krb5: Add methods to convert between enctypes > and bitfields > >These methods are useful for converting a collection of encryption types >into msDS-SupportedEncryptionTypes bit flags, and vice versa. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 432eba9e09849e74f4c0f2d7826d45cbd2b7ce42) >--- > python/samba/tests/krb5/kdc_base_test.py | 6 +-- > python/samba/tests/krb5/raw_testcase.py | 51 +++++++++++++++++++----- > 2 files changed, 43 insertions(+), 14 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 3d2d20cb65b..10ad9e6961f 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -633,10 +633,8 @@ class KDCBaseTest(RawKerberosTest): > > enctypes = supported_enctypes > if fast_support: >- fast_bits = (security.KERB_ENCTYPE_FAST_SUPPORTED | >- security.KERB_ENCTYPE_COMPOUND_IDENTITY_SUPPORTED | >- security.KERB_ENCTYPE_CLAIMS_SUPPORTED) >- enctypes = (enctypes or 0) | fast_bits >+ enctypes = enctypes or 0 >+ enctypes |= KerberosCredentials.fast_supported_bits > > if enctypes is not None: > details['msDS-SupportedEncryptionTypes'] = str(enctypes) >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 57013caafb1..57579126f8a 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -304,6 +304,11 @@ class RodcPacEncryptionKey(Krb5EncryptionKey): > > > class KerberosCredentials(Credentials): >+ >+ fast_supported_bits = (security.KERB_ENCTYPE_FAST_SUPPORTED | >+ security.KERB_ENCTYPE_COMPOUND_IDENTITY_SUPPORTED | >+ security.KERB_ENCTYPE_CLAIMS_SUPPORTED) >+ > def __init__(self): > super(KerberosCredentials, self).__init__() > all_enc_types = 0 >@@ -331,26 +336,52 @@ class KerberosCredentials(Credentials): > def set_ap_supported_enctypes(self, value): > self.ap_supported_enctypes = int(value) > >- def _get_krb5_etypes(self, supported_enctypes): >+ etype_map = collections.OrderedDict([ >+ (kcrypto.Enctype.AES256, >+ security.KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96), >+ (kcrypto.Enctype.AES128, >+ security.KERB_ENCTYPE_AES128_CTS_HMAC_SHA1_96), >+ (kcrypto.Enctype.RC4, >+ security.KERB_ENCTYPE_RC4_HMAC_MD5), >+ (kcrypto.Enctype.DES_MD5, >+ security.KERB_ENCTYPE_DES_CBC_MD5), >+ (kcrypto.Enctype.DES_CRC, >+ security.KERB_ENCTYPE_DES_CBC_CRC) >+ ]) >+ >+ @classmethod >+ def etypes_to_bits(self, etypes): >+ bits = 0 >+ for etype in etypes: >+ bit = self.etype_map[etype] >+ if bits & bit: >+ raise ValueError(f'Got duplicate etype: {etype}') >+ bits |= bit >+ >+ return bits >+ >+ @classmethod >+ def bits_to_etypes(self, bits): > etypes = () >+ for etype, bit in self.etype_map.items(): >+ if bit & bits: >+ bits &= ~bit >+ etypes += (etype,) > >- if supported_enctypes & security.KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96: >- etypes += (kcrypto.Enctype.AES256,) >- if supported_enctypes & security.KERB_ENCTYPE_AES128_CTS_HMAC_SHA1_96: >- etypes += (kcrypto.Enctype.AES128,) >- if supported_enctypes & security.KERB_ENCTYPE_RC4_HMAC_MD5: >- etypes += (kcrypto.Enctype.RC4,) >+ bits &= ~self.fast_supported_bits >+ if bits != 0: >+ raise ValueError(f'Unsupported etype bits: {bits}') > > return etypes > > def get_as_krb5_etypes(self): >- return self._get_krb5_etypes(self.as_supported_enctypes) >+ return self.bits_to_etypes(self.as_supported_enctypes) > > def get_tgs_krb5_etypes(self): >- return self._get_krb5_etypes(self.tgs_supported_enctypes) >+ return self.bits_to_etypes(self.tgs_supported_enctypes) > > def get_ap_krb5_etypes(self): >- return self._get_krb5_etypes(self.ap_supported_enctypes) >+ return self.bits_to_etypes(self.ap_supported_enctypes) > > def set_kvno(self, kvno): > # Sign-extend from 32 bits. >-- >2.25.1 > > >From 0db318a9a266d0ae36aa522127801b5e1eac3b98 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 21 Sep 2021 17:10:49 +1200 >Subject: [PATCH 061/159] tests/krb5: Get supported enctypes for credentials > from database > >Look up the account's msDS-SupportedEncryptionTypes attribute to get the >encryption types that it supports. Move the fallback to RC4 to when the >ticket decryption key is obtained. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit b6eaf2cf44fb66d8f302d4cab050827a67de3ea4) >--- > python/samba/tests/krb5/as_req_tests.py | 4 +- > python/samba/tests/krb5/kdc_base_test.py | 52 +++++++++++++++++------- > python/samba/tests/krb5/raw_testcase.py | 5 ++- > 3 files changed, 43 insertions(+), 18 deletions(-) > >diff --git a/python/samba/tests/krb5/as_req_tests.py b/python/samba/tests/krb5/as_req_tests.py >index 35f88a0c920..8d9b90fee69 100755 >--- a/python/samba/tests/krb5/as_req_tests.py >+++ b/python/samba/tests/krb5/as_req_tests.py >@@ -60,7 +60,7 @@ class AsReqKerberosTests(KDCBaseTest): > initial_kdc_options=None): > client_creds = self.get_client_creds() > client_account = client_creds.get_username() >- client_as_etypes = client_creds.get_as_krb5_etypes() >+ client_as_etypes = self.get_default_enctypes() > krbtgt_creds = self.get_krbtgt_creds(require_keys=False) > krbtgt_account = krbtgt_creds.get_username() > realm = krbtgt_creds.get_realm() >@@ -114,7 +114,7 @@ class AsReqKerberosTests(KDCBaseTest): > def test_as_req_enc_timestamp(self): > client_creds = self.get_client_creds() > client_account = client_creds.get_username() >- client_as_etypes = client_creds.get_as_krb5_etypes() >+ client_as_etypes = self.get_default_enctypes() > client_kvno = client_creds.get_kvno() > krbtgt_creds = self.get_krbtgt_creds(require_strongest_key=True) > krbtgt_account = krbtgt_creds.get_username() >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 10ad9e6961f..cdaeaf9f3e1 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -289,6 +289,8 @@ class KDCBaseTest(RawKerberosTest): > # Save the account name so it can be deleted in tearDownClass > self.accounts.add(dn) > >+ self.creds_set_enctypes(creds) >+ > return (creds, dn) > > def create_rodc(self, ctx): >@@ -522,13 +524,28 @@ class KDCBaseTest(RawKerberosTest): > for enctype, key in keys.items(): > creds.set_forced_key(enctype, key) > >- supported_enctypes = 0 >- if kcrypto.Enctype.AES256 in keys: >- supported_enctypes |= security.KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96 >- if kcrypto.Enctype.AES128 in keys: >- supported_enctypes |= security.KERB_ENCTYPE_AES128_CTS_HMAC_SHA1_96 >- if kcrypto.Enctype.RC4 in keys: >- supported_enctypes |= security.KERB_ENCTYPE_RC4_HMAC_MD5 >+ def creds_set_enctypes(self, creds): >+ samdb = self.get_samdb() >+ >+ res = samdb.search(creds.get_dn(), >+ scope=ldb.SCOPE_BASE, >+ attrs=['msDS-SupportedEncryptionTypes']) >+ supported_enctypes = res[0].get('msDS-SupportedEncryptionTypes', idx=0) >+ >+ if supported_enctypes is None: >+ supported_enctypes = 0 >+ >+ creds.set_as_supported_enctypes(supported_enctypes) >+ creds.set_tgs_supported_enctypes(supported_enctypes) >+ creds.set_ap_supported_enctypes(supported_enctypes) >+ >+ def creds_set_default_enctypes(self, creds, fast_support=False): >+ default_enctypes = self.get_default_enctypes() >+ supported_enctypes = KerberosCredentials.etypes_to_bits( >+ default_enctypes) >+ >+ if fast_support: >+ supported_enctypes |= KerberosCredentials.fast_supported_bits > > creds.set_as_supported_enctypes(supported_enctypes) > creds.set_tgs_supported_enctypes(supported_enctypes) >@@ -662,14 +679,6 @@ class KDCBaseTest(RawKerberosTest): > keys = self.get_keys(samdb, dn) > self.creds_set_keys(creds, keys) > >- if machine_account: >- if supported_enctypes is not None: >- tgs_enctypes = supported_enctypes >- else: >- tgs_enctypes = security.KERB_ENCTYPE_RC4_HMAC_MD5 >- >- creds.set_tgs_supported_enctypes(tgs_enctypes) >- > # Handle secret replication to the RODC. > > if allowed_replication or revealed_to_rodc: >@@ -814,6 +823,11 @@ class KDCBaseTest(RawKerberosTest): > keys = self.get_keys(samdb, krbtgt_dn) > self.creds_set_keys(creds, keys) > >+ # The RODC krbtgt account should support the default enctypes, >+ # although it might not have the msDS-SupportedEncryptionTypes >+ # attribute. >+ self.creds_set_default_enctypes(creds) >+ > return creds > > c = self._get_krb5_creds(prefix='RODC_KRBTGT', >@@ -858,6 +872,8 @@ class KDCBaseTest(RawKerberosTest): > keys = self.get_keys(samdb, dn) > self.creds_set_keys(creds, keys) > >+ self.creds_set_enctypes(creds) >+ > return creds > > c = self._get_krb5_creds(prefix='MOCK_RODC_KRBTGT', >@@ -898,6 +914,12 @@ class KDCBaseTest(RawKerberosTest): > keys = self.get_keys(samdb, dn) > self.creds_set_keys(creds, keys) > >+ # The krbtgt account should support the default enctypes, although >+ # it might not (on Samba) have the msDS-SupportedEncryptionTypes >+ # attribute. >+ self.creds_set_default_enctypes(creds, >+ fast_support=self.kdc_fast_support) >+ > return creds > > c = self._get_krb5_creds(prefix='KRBTGT', >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 57579126f8a..8d7778602f5 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1082,7 +1082,10 @@ class RawKerberosTest(TestCaseInTempDir): > > if etype is None: > etypes = creds.get_tgs_krb5_etypes() >- etype = etypes[0] >+ if etypes: >+ etype = etypes[0] >+ else: >+ etype = kcrypto.Enctype.RC4 > > forced_key = creds.get_forced_key(etype) > if forced_key is not None: >-- >2.25.1 > > >From 02a069a23c8e27b19cf6494fa1570e9f62cb9393 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 21 Sep 2021 17:11:28 +1200 >Subject: [PATCH 062/159] tests/krb5: Correctly check PA-SUPPORTED-ENCTYPES > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 14cd933a9d6af08deb680c9f688b166138d45ed9) >--- > python/samba/tests/krb5/fast_tests.py | 4 ++++ > python/samba/tests/krb5/kdc_base_test.py | 3 +++ > python/samba/tests/krb5/raw_testcase.py | 24 +++++++++++++++--------- > 3 files changed, 22 insertions(+), 9 deletions(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index d8ccfaee325..431b48f00d6 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -1126,6 +1126,7 @@ class FAST_Tests(KDCBaseTest): > name_type=NT_SRV_INST, names=[krbtgt_username, krbtgt_realm]) > krbtgt_decryption_key = self.TicketDecryptionKey_from_creds( > krbtgt_creds) >+ krbtgt_etypes = krbtgt_creds.tgs_supported_enctypes > > target_username = target_creds.get_username()[:-1] > target_realm = target_creds.get_realm() >@@ -1134,6 +1135,7 @@ class FAST_Tests(KDCBaseTest): > name_type=NT_SRV_INST, names=[target_service, target_username]) > target_decryption_key = self.TicketDecryptionKey_from_creds( > target_creds) >+ target_etypes = target_creds.tgs_supported_enctypes > > fast_cookie = None > preauth_etype_info2 = None >@@ -1322,6 +1324,7 @@ class FAST_Tests(KDCBaseTest): > expected_anon=expected_anon, > expected_srealm=expected_srealm, > expected_sname=expected_sname, >+ expected_supported_etypes=krbtgt_etypes, > expected_flags=expected_flags, > unexpected_flags=unexpected_flags, > ticket_decryption_key=krbtgt_decryption_key, >@@ -1355,6 +1358,7 @@ class FAST_Tests(KDCBaseTest): > expected_anon=expected_anon, > expected_srealm=expected_srealm, > expected_sname=expected_sname, >+ expected_supported_etypes=target_etypes, > expected_flags=expected_flags, > unexpected_flags=unexpected_flags, > ticket_decryption_key=target_decryption_key, >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index cdaeaf9f3e1..646859e85b3 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -1267,6 +1267,8 @@ class KDCBaseTest(RawKerberosTest): > expected_sname = self.PrincipalName_create( > name_type=NT_SRV_INST, names=['krbtgt', realm.upper()]) > >+ expected_etypes = krbtgt_creds.tgs_supported_enctypes >+ > rep, kdc_exchange_dict = self._test_as_exchange( > cname=cname, > realm=realm, >@@ -1279,6 +1281,7 @@ class KDCBaseTest(RawKerberosTest): > expected_srealm=expected_realm, > expected_sname=expected_sname, > expected_salt=salt, >+ expected_supported_etypes=expected_etypes, > etypes=etype, > padata=padata, > kdc_options=kdc_options, >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 8d7778602f5..c6bc3e553ad 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1879,6 +1879,7 @@ class RawKerberosTest(TestCaseInTempDir): > expected_anon=False, > expected_srealm=None, > expected_sname=None, >+ expected_supported_etypes=None, > expected_flags=None, > unexpected_flags=None, > ticket_decryption_key=None, >@@ -1923,6 +1924,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'expected_anon': expected_anon, > 'expected_srealm': expected_srealm, > 'expected_sname': expected_sname, >+ 'expected_supported_etypes': expected_supported_etypes, > 'expected_flags': expected_flags, > 'unexpected_flags': unexpected_flags, > 'ticket_decryption_key': ticket_decryption_key, >@@ -1963,6 +1965,7 @@ class RawKerberosTest(TestCaseInTempDir): > expected_anon=False, > expected_srealm=None, > expected_sname=None, >+ expected_supported_etypes=None, > expected_flags=None, > unexpected_flags=None, > ticket_decryption_key=None, >@@ -2006,6 +2009,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'expected_anon': expected_anon, > 'expected_srealm': expected_srealm, > 'expected_sname': expected_sname, >+ 'expected_supported_etypes': expected_supported_etypes, > 'expected_flags': expected_flags, > 'unexpected_flags': unexpected_flags, > 'ticket_decryption_key': ticket_decryption_key, >@@ -2312,19 +2316,19 @@ class RawKerberosTest(TestCaseInTempDir): > if canonicalize: > self.assertIn(PADATA_SUPPORTED_ETYPES, enc_pa_dict) > >+ expected_supported_etypes = kdc_exchange_dict[ >+ 'expected_supported_etypes'] >+ expected_supported_etypes |= ( >+ security.KERB_ENCTYPE_DES_CBC_CRC | >+ security.KERB_ENCTYPE_DES_CBC_MD5 | >+ security.KERB_ENCTYPE_RC4_HMAC_MD5) >+ > (supported_etypes,) = struct.unpack( > '<L', > enc_pa_dict[PADATA_SUPPORTED_ETYPES]) > >- self.assertTrue( >- security.KERB_ENCTYPE_FAST_SUPPORTED >- & supported_etypes) >- self.assertTrue( >- security.KERB_ENCTYPE_COMPOUND_IDENTITY_SUPPORTED >- & supported_etypes) >- self.assertTrue( >- security.KERB_ENCTYPE_CLAIMS_SUPPORTED >- & supported_etypes) >+ self.assertEqual(supported_etypes, >+ expected_supported_etypes) > else: > self.assertNotIn(PADATA_SUPPORTED_ETYPES, enc_pa_dict) > >@@ -3396,6 +3400,7 @@ class RawKerberosTest(TestCaseInTempDir): > kdc_options, > expected_flags=None, > unexpected_flags=None, >+ expected_supported_etypes=None, > preauth_key=None, > ticket_decryption_key=None, > pac_request=None, >@@ -3424,6 +3429,7 @@ class RawKerberosTest(TestCaseInTempDir): > expected_cname=expected_cname, > expected_srealm=expected_srealm, > expected_sname=expected_sname, >+ expected_supported_etypes=expected_supported_etypes, > ticket_decryption_key=ticket_decryption_key, > generate_padata_fn=generate_padata_fn, > check_error_fn=check_error_fn, >-- >2.25.1 > > >From 5b930c8489a0f5e939edb3f56f01f65c1c94e87b Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 20 Sep 2021 13:54:39 +1200 >Subject: [PATCH 063/159] tests/krb5: Set key version number for all accounts > created with create_account() > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 054ec1a8cc4ae42918c7c06ef9c66c8a81242655) >--- > python/samba/tests/krb5/kdc_base_test.py | 12 ++++++------ > 1 file changed, 6 insertions(+), 6 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 646859e85b3..91034a10e15 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -291,6 +291,12 @@ class KDCBaseTest(RawKerberosTest): > > self.creds_set_enctypes(creds) > >+ res = samdb.search(base=dn, >+ scope=ldb.SCOPE_BASE, >+ attrs=['msDS-KeyVersionNumber']) >+ kvno = int(res[0]['msDS-KeyVersionNumber'][0]) >+ creds.set_kvno(kvno) >+ > return (creds, dn) > > def create_rodc(self, ctx): >@@ -670,12 +676,6 @@ class KDCBaseTest(RawKerberosTest): > additional_details=details, > account_control=user_account_control) > >- res = samdb.search(base=dn, >- scope=ldb.SCOPE_BASE, >- attrs=['msDS-KeyVersionNumber']) >- kvno = int(res[0]['msDS-KeyVersionNumber'][0]) >- creds.set_kvno(kvno) >- > keys = self.get_keys(samdb, dn) > self.creds_set_keys(creds, keys) > >-- >2.25.1 > > >From ff741b747f0ba820ce604d9db39ecca3feecec6b Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 20 Sep 2021 13:59:24 +1200 >Subject: [PATCH 064/159] tests/krb5: Allow tgs_req() to check the returned > ticket enc-part > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 38b4b334caf1b32f1479db3ada48b2028946f5e6) >--- > python/samba/tests/krb5/kdc_base_test.py | 9 ++++++++- > 1 file changed, 8 insertions(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 91034a10e15..914112fdfc7 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -1084,7 +1084,7 @@ class KDCBaseTest(RawKerberosTest): > > def tgs_req(self, cname, sname, realm, ticket, key, etypes, > expected_error_mode=0, padata=None, kdc_options=0, >- to_rodc=False): >+ to_rodc=False, service_creds=None): > '''Send a TGS-REQ, returns the response and the decrypted and > decoded enc-part > ''' >@@ -1098,6 +1098,12 @@ class KDCBaseTest(RawKerberosTest): > crealm=realm, > cname=cname) > >+ if service_creds is not None: >+ decryption_key = self.TicketDecryptionKey_from_creds( >+ service_creds) >+ else: >+ decryption_key = None >+ > if not expected_error_mode: > check_error_fn = None > check_rep_fn = self.generic_check_kdc_rep >@@ -1120,6 +1126,7 @@ class KDCBaseTest(RawKerberosTest): > check_error_fn=check_error_fn, > check_rep_fn=check_rep_fn, > check_kdc_private_fn=self.generic_check_kdc_private, >+ ticket_decryption_key=decryption_key, > generate_padata_fn=generate_padata if padata is not None else None, > tgt=tgt, > authenticator_subkey=subkey, >-- >2.25.1 > > >From c2e6297f7af59ff2695ca9e9c1a0bc7de040335f Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 20 Sep 2021 13:58:09 +1200 >Subject: [PATCH 065/159] tests/krb5: Add method to get DC credentials > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 9d01043042f1caac98a23cf4d9aa9a02a31a9239) >--- > python/samba/tests/krb5/kdc_base_test.py | 42 ++++++++++++++++++++++++ > 1 file changed, 42 insertions(+) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 914112fdfc7..5de9907d02b 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -930,6 +930,48 @@ class KDCBaseTest(RawKerberosTest): > fallback_creds_fn=download_krbtgt_creds) > return c > >+ def get_dc_creds(self, >+ require_keys=True, >+ require_strongest_key=False): >+ if require_strongest_key: >+ self.assertTrue(require_keys) >+ >+ def download_dc_creds(): >+ samdb = self.get_samdb() >+ >+ dc_rid = 1000 >+ dc_sid = '%s-%d' % (samdb.get_domain_sid(), dc_rid) >+ >+ res = samdb.search(base='<SID=%s>' % dc_sid, >+ scope=ldb.SCOPE_BASE, >+ attrs=['sAMAccountName', >+ 'msDS-KeyVersionNumber']) >+ dn = res[0].dn >+ username = str(res[0]['sAMAccountName']) >+ >+ creds = KerberosCredentials() >+ creds.set_domain(self.env_get_var('DOMAIN', 'DC')) >+ creds.set_realm(self.env_get_var('REALM', 'DC')) >+ creds.set_username(username) >+ >+ kvno = int(res[0]['msDS-KeyVersionNumber'][0]) >+ creds.set_kvno(kvno) >+ creds.set_dn(dn) >+ >+ keys = self.get_keys(samdb, dn) >+ self.creds_set_keys(creds, keys) >+ >+ self.creds_set_enctypes(creds) >+ >+ return creds >+ >+ c = self._get_krb5_creds(prefix='DC', >+ allow_missing_password=True, >+ allow_missing_keys=not require_keys, >+ require_strongest_key=require_strongest_key, >+ fallback_creds_fn=download_dc_creds) >+ return c >+ > def as_req(self, cname, sname, realm, etypes, padata=None, kdc_options=0): > '''Send a Kerberos AS_REQ, returns the undecoded response > ''' >-- >2.25.1 > > >From 48ee3563f0f0a207f54ac94cb46722bc93c5b862 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 20 Sep 2021 14:08:16 +1200 >Subject: [PATCH 066/159] tests/krb5: Fix checking for presence of > authorization data > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit f9284d8517edd9ffd96f0c24166a16366f97de8f) >--- > python/samba/tests/krb5/kdc_base_test.py | 3 ++- > .../ms_kile_client_principal_lookup_tests.py | 6 ++++-- > python/samba/tests/krb5/raw_testcase.py | 16 +++++++++++++--- > 3 files changed, 19 insertions(+), 6 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 5de9907d02b..b4d3739aa11 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -1126,7 +1126,7 @@ class KDCBaseTest(RawKerberosTest): > > def tgs_req(self, cname, sname, realm, ticket, key, etypes, > expected_error_mode=0, padata=None, kdc_options=0, >- to_rodc=False, service_creds=None): >+ to_rodc=False, service_creds=None, expect_pac=True): > '''Send a TGS-REQ, returns the response and the decrypted and > decoded enc-part > ''' >@@ -1173,6 +1173,7 @@ class KDCBaseTest(RawKerberosTest): > tgt=tgt, > authenticator_subkey=subkey, > kdc_options=str(kdc_options), >+ expect_pac=expect_pac, > to_rodc=to_rodc) > > rep = self._generic_kdc_exchange(kdc_exchange_dict, >diff --git a/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py b/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >index 99c842701ea..64ebe15ad70 100755 >--- a/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >+++ b/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >@@ -321,7 +321,8 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > names=[mc.get_username()]) > > (rep, enc_part) = self.tgs_req( >- cname, sname, uc.get_realm(), ticket, key, etype) >+ cname, sname, uc.get_realm(), ticket, key, etype, >+ expect_pac=False) > self.check_tgs_reply(rep) > > # Check the contents of the service ticket >@@ -695,7 +696,8 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > names=[mc.get_username()]) > > (rep, enc_part) = self.tgs_req( >- cname, sname, uc.get_realm(), ticket, key, etype) >+ cname, sname, uc.get_realm(), ticket, key, etype, >+ expect_pac=False) > self.check_tgs_reply(rep) > > # Check the contents of the service ticket >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index c6bc3e553ad..b531e33041d 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -944,12 +944,15 @@ class RawKerberosTest(TestCaseInTempDir): > v = self.getElementValue(obj, elem) > self.assertIsNone(v) > >- def assertElementPresent(self, obj, elem): >+ def assertElementPresent(self, obj, elem, expect_empty=False): > v = self.getElementValue(obj, elem) > self.assertIsNotNone(v) > if self.strict_checking: > if isinstance(v, collections.abc.Container): >- self.assertNotEqual(0, len(v)) >+ if expect_empty: >+ self.assertEqual(0, len(v)) >+ else: >+ self.assertNotEqual(0, len(v)) > > def assertElementEqual(self, obj, elem, value): > v = self.getElementValue(obj, elem) >@@ -1907,6 +1910,7 @@ class RawKerberosTest(TestCaseInTempDir): > outer_req=None, > pac_request=None, > pac_options=None, >+ expect_pac=True, > to_rodc=False): > if expected_error_mode == 0: > expected_error_mode = () >@@ -1952,6 +1956,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'outer_req': outer_req, > 'pac_request': pac_request, > 'pac_options': pac_options, >+ 'expect_pac': expect_pac, > 'to_rodc': to_rodc > } > if callback_dict is None: >@@ -1992,6 +1997,7 @@ class RawKerberosTest(TestCaseInTempDir): > outer_req=None, > pac_request=None, > pac_options=None, >+ expect_pac=True, > to_rodc=False): > if expected_error_mode == 0: > expected_error_mode = () >@@ -2036,6 +2042,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'outer_req': outer_req, > 'pac_request': pac_request, > 'pac_options': pac_options, >+ 'expect_pac': expect_pac, > 'to_rodc': to_rodc > } > if callback_dict is None: >@@ -2236,6 +2243,8 @@ class RawKerberosTest(TestCaseInTempDir): > armor_key = kdc_exchange_dict['armor_key'] > self.verify_ticket_checksum(ticket, ticket_checksum, armor_key) > >+ expect_pac = kdc_exchange_dict['expect_pac'] >+ > ticket_session_key = None > if ticket_private is not None: > self.assertElementFlags(ticket_private, 'flags', >@@ -2265,7 +2274,8 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertElementMissing(ticket_private, 'renew-till') > if self.strict_checking: > self.assertElementEqual(ticket_private, 'caddr', []) >- self.assertElementPresent(ticket_private, 'authorization-data') >+ self.assertElementPresent(ticket_private, 'authorization-data', >+ expect_empty=not expect_pac) > > encpart_session_key = None > if encpart_private is not None: >-- >2.25.1 > > >From 3bcb528107d81553a47665dbebee0a445e279f6a Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 22 Sep 2021 11:41:45 +1200 >Subject: [PATCH 067/159] tests/krb5: Provide ticket enc-part key to tgs_req() > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit f2f1f3a1e9269f0e7b93006bba2368a6ffbecc7c) >--- > python/samba/tests/krb5/kdc_base_test.py | 3 +- > python/samba/tests/krb5/kdc_tgs_tests.py | 6 ++-- > .../ms_kile_client_principal_lookup_tests.py | 28 ++++++++++++------- > 3 files changed, 24 insertions(+), 13 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index b4d3739aa11..b71ae66bf54 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -1215,7 +1215,8 @@ class KDCBaseTest(RawKerberosTest): > names=[service, target_name]) > > rep, enc_part = self.tgs_req(cname, sname, realm, ticket, key, etype, >- to_rodc=to_rodc) >+ to_rodc=to_rodc, >+ service_creds=target_creds) > > service_ticket = rep['ticket'] > >diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py >index dad9e6b88df..0904233b01f 100755 >--- a/python/samba/tests/krb5/kdc_tgs_tests.py >+++ b/python/samba/tests/krb5/kdc_tgs_tests.py >@@ -132,7 +132,8 @@ class KdcTgsTests(KDCBaseTest): > names=["ldap", samdb.host_dns_name()]) > > (rep, _) = self.tgs_req( >- cname, sname, uc.get_realm(), ticket, key, etype) >+ cname, sname, uc.get_realm(), ticket, key, etype, >+ service_creds=self.get_dc_creds()) > > self.check_tgs_reply(rep) > >@@ -175,7 +176,8 @@ class KdcTgsTests(KDCBaseTest): > names=[mc.get_username()]) > > (rep, enc_part) = self.tgs_req( >- cname, sname, uc.get_realm(), ticket, key, etype) >+ cname, sname, uc.get_realm(), ticket, key, etype, >+ service_creds=mc) > self.check_tgs_reply(rep) > > # Check the contents of the service ticket >diff --git a/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py b/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >index 64ebe15ad70..ce796f63ac2 100755 >--- a/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >+++ b/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >@@ -126,7 +126,8 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > names=[mc.get_username()]) > > (rep, enc_part) = self.tgs_req( >- cname, sname, uc.get_realm(), ticket, key, etype) >+ cname, sname, uc.get_realm(), ticket, key, etype, >+ service_creds=mc) > self.check_tgs_reply(rep) > > # Check the contents of the pac, and the ticket >@@ -185,7 +186,8 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > names=[mc.get_username()]) > > (rep, enc_part) = self.tgs_req( >- cname, sname, mc.get_realm(), ticket, key, etype) >+ cname, sname, mc.get_realm(), ticket, key, etype, >+ service_creds=mc) > self.check_tgs_reply(rep) > > # Check the contents of the pac, and the ticket >@@ -247,7 +249,8 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > names=[mc.get_username()]) > > (rep, enc_part) = self.tgs_req( >- cname, sname, uc.get_realm(), ticket, key, etype) >+ cname, sname, uc.get_realm(), ticket, key, etype, >+ service_creds=mc) > self.check_tgs_reply(rep) > > # Check the contents of the service ticket >@@ -322,7 +325,7 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > > (rep, enc_part) = self.tgs_req( > cname, sname, uc.get_realm(), ticket, key, etype, >- expect_pac=False) >+ service_creds=mc, expect_pac=False) > self.check_tgs_reply(rep) > > # Check the contents of the service ticket >@@ -390,7 +393,8 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > names=[mc.get_username()]) > > (rep, enc_part) = self.tgs_req( >- cname, sname, uc.get_realm(), ticket, key, etype) >+ cname, sname, uc.get_realm(), ticket, key, etype, >+ service_creds=mc) > self.check_tgs_reply(rep) > > # Check the contents of the pac, and the ticket >@@ -492,7 +496,8 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > names=[mc.get_username()]) > > (rep, enc_part) = self.tgs_req( >- cname, sname, uc.get_realm(), ticket, key, etype) >+ cname, sname, uc.get_realm(), ticket, key, etype, >+ service_creds=mc) > self.check_tgs_reply(rep) > > # Check the contents of the pac, and the ticket >@@ -555,7 +560,8 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > names=[mc.get_username()]) > > (rep, enc_part) = self.tgs_req( >- cname, sname, uc.get_realm(), ticket, key, etype) >+ cname, sname, uc.get_realm(), ticket, key, etype, >+ service_creds=mc) > self.check_tgs_reply(rep) > > # Check the contents of the pac, and the ticket >@@ -619,7 +625,8 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > names=[mc.get_username()]) > > (rep, enc_part) = self.tgs_req( >- cname, sname, uc.get_realm(), ticket, key, etype) >+ cname, sname, uc.get_realm(), ticket, key, etype, >+ service_creds=mc) > self.check_tgs_reply(rep) > > # Check the contents of the pac, and the ticket >@@ -697,7 +704,7 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > > (rep, enc_part) = self.tgs_req( > cname, sname, uc.get_realm(), ticket, key, etype, >- expect_pac=False) >+ service_creds=mc, expect_pac=False) > self.check_tgs_reply(rep) > > # Check the contents of the service ticket >@@ -767,7 +774,8 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > names=[mc.get_username()]) > > (rep, enc_part) = self.tgs_req( >- cname, sname, uc.get_realm(), ticket, key, etype) >+ cname, sname, uc.get_realm(), ticket, key, etype, >+ service_creds=mc) > self.check_tgs_reply(rep) > > # Check the contents of the pac, and the ticket >-- >2.25.1 > > >From c92389393c4efeca93dd6eab757fac40762daa26 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 20 Sep 2021 14:05:58 +1200 >Subject: [PATCH 068/159] tests/krb5: Simplify account creation > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 394e8db261b10d130c5e5730989bf68f9bf4f85f) >--- > .../ms_kile_client_principal_lookup_tests.py | 16 ++++------------ > 1 file changed, 4 insertions(+), 12 deletions(-) > >diff --git a/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py b/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >index ce796f63ac2..501bc4892f4 100755 >--- a/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >+++ b/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >@@ -282,15 +282,11 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > samdb = self.get_samdb() > user_name = "mskileusr" > alt_name = "mskilealtsec" >- (uc, dn) = self.create_account(samdb, user_name) >+ (uc, dn) = self.create_account(samdb, user_name, >+ account_control=UF_DONT_REQUIRE_PREAUTH) > realm = uc.get_realm().lower() > alt_sec = "Kerberos:%s@%s" % (alt_name, realm) > self.add_attribute(samdb, dn, "altSecurityIdentities", alt_sec) >- self.modify_attribute( >- samdb, >- dn, >- "userAccountControl", >- str(UF_NORMAL_ACCOUNT | UF_DONT_REQUIRE_PREAUTH)) > > mach_name = "mskilemac" > (mc, _) = self.create_account(samdb, mach_name, machine_account=True) >@@ -660,15 +656,11 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > samdb = self.get_samdb() > user_name = "mskileusr" > alt_name = "mskilealtsec" >- (uc, dn) = self.create_account(samdb, user_name) >+ (uc, dn) = self.create_account(samdb, user_name, >+ account_control=UF_DONT_REQUIRE_PREAUTH) > realm = uc.get_realm().lower() > alt_sec = "Kerberos:%s@%s" % (alt_name, realm) > self.add_attribute(samdb, dn, "altSecurityIdentities", alt_sec) >- self.modify_attribute( >- samdb, >- dn, >- "userAccountControl", >- str(UF_NORMAL_ACCOUNT | UF_DONT_REQUIRE_PREAUTH)) > ename = alt_name + "@" + realm > > mach_name = "mskilemac" >-- >2.25.1 > > >From bfc9eaf664dfad9e8c65d85e7c0bce433e612f70 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 21 Sep 2021 13:54:47 +1200 >Subject: [PATCH 069/159] tests/krb5: Add get_rodc_krbtgt_creds() to > RawKerberosTest > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 1458cd9065de34c42bd5ec63feb2f66c25103982) >--- > python/samba/tests/krb5/raw_testcase.py | 11 +++++++++++ > 1 file changed, 11 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index b531e33041d..59882e44173 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -750,6 +750,17 @@ class RawKerberosTest(TestCaseInTempDir): > c.set_gensec_features(c.get_gensec_features() | FEATURE_SEAL) > return c > >+ def get_rodc_krbtgt_creds(self, >+ require_keys=True, >+ require_strongest_key=False): >+ if require_strongest_key: >+ self.assertTrue(require_keys) >+ c = self._get_krb5_creds(prefix='RODC_KRBTGT', >+ allow_missing_password=True, >+ allow_missing_keys=not require_keys, >+ require_strongest_key=require_strongest_key) >+ return c >+ > def get_krbtgt_creds(self, > require_keys=True, > require_strongest_key=False): >-- >2.25.1 > > >From c45c7e70f87f550a37e7ca3367192f538076615e Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 20 Sep 2021 14:10:07 +1200 >Subject: [PATCH 070/159] tests/krb5: Verify checksums of tickets obtained from > the KDC > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit ea7b550a500d9e458498d37688b67dafd3d9509d) >--- > python/samba/tests/krb5/raw_testcase.py | 34 +++++++++++++++++-------- > 1 file changed, 24 insertions(+), 10 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 59882e44173..985792887ca 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2254,6 +2254,13 @@ class RawKerberosTest(TestCaseInTempDir): > armor_key = kdc_exchange_dict['armor_key'] > self.verify_ticket_checksum(ticket, ticket_checksum, armor_key) > >+ to_rodc = kdc_exchange_dict['to_rodc'] >+ if to_rodc: >+ krbtgt_creds = self.get_rodc_krbtgt_creds() >+ else: >+ krbtgt_creds = self.get_krbtgt_creds() >+ krbtgt_key = self.TicketDecryptionKey_from_creds(krbtgt_creds) >+ > expect_pac = kdc_exchange_dict['expect_pac'] > > ticket_session_key = None >@@ -2386,6 +2393,9 @@ class RawKerberosTest(TestCaseInTempDir): > ticket_private=ticket_private, > encpart_private=encpart_private) > >+ if ticket_decryption_key is not None: >+ self.verify_ticket(ticket_creds, krbtgt_key, expect_pac=expect_pac) >+ > kdc_exchange_dict['rep_ticket_creds'] = ticket_creds > > def check_pac_options_claims_support(self, pac_options): >@@ -3061,16 +3071,20 @@ class RawKerberosTest(TestCaseInTempDir): > if is_tgt: > self.assertNotIn(krb5pac.PAC_TYPE_TICKET_CHECKSUM, checksums) > else: >- ticket_checksum, ticket_ctype = checksums[ >- krb5pac.PAC_TYPE_TICKET_CHECKSUM] >- enc_part['authorization-data'] = auth_data >- enc_part = self.der_encode(enc_part, >- asn1Spec=krb5_asn1.EncTicketPart()) >- >- krbtgt_key.verify_checksum(KU_NON_KERB_CKSUM_SALT, >- enc_part, >- ticket_ctype, >- ticket_checksum) >+ ticket_checksum, ticket_ctype = checksums.get( >+ krb5pac.PAC_TYPE_TICKET_CHECKSUM, >+ (None, None)) >+ if self.strict_checking: >+ self.assertIsNotNone(ticket_checksum) >+ if ticket_checksum is not None: >+ enc_part['authorization-data'] = auth_data >+ enc_part = self.der_encode(enc_part, >+ asn1Spec=krb5_asn1.EncTicketPart()) >+ >+ krbtgt_key.verify_checksum(KU_NON_KERB_CKSUM_SALT, >+ enc_part, >+ ticket_ctype, >+ ticket_checksum) > > def modified_ticket(self, > ticket, *, >-- >2.25.1 > > >From b6be56df17bd52837ff30beef4a5ffd2f5007d08 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 20 Sep 2021 15:06:18 +1200 >Subject: [PATCH 071/159] tests/krb5: Add method to determine if principal is > krbtgt > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit c0b81f0dd54d0d71b5d0f5a870b505e82d0e85b8) >--- > python/samba/tests/krb5/raw_testcase.py | 6 +++++- > 1 file changed, 5 insertions(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 985792887ca..cadf2b50dc9 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2977,7 +2977,7 @@ class RawKerberosTest(TestCaseInTempDir): > def verify_ticket(self, ticket, krbtgt_key, expect_pac=True): > # Check if the ticket is a TGT. > sname = ticket.ticket['sname'] >- is_tgt = sname['name-string'][0] == b'krbtgt' >+ is_tgt = self.is_tgs(sname) > > # Decrypt the ticket. > >@@ -3371,6 +3371,10 @@ class RawKerberosTest(TestCaseInTempDir): > krb5pac.PAC_TYPE_KDC_CHECKSUM: krbtgt_key > } > >+ def is_tgs(self, principal): >+ name = principal['name-string'][0] >+ return name in ('krbtgt', b'krbtgt') >+ > def get_empty_pac(self): > return self.AuthorizationData_create(AD_WIN2K_PAC, bytes(1)) > >-- >2.25.1 > > >From 1e4a94b0a01ae4ae973f54df5d8bc769022e5ff9 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 20 Sep 2021 15:10:35 +1200 >Subject: [PATCH 072/159] tests/krb5: Add classes for testing invalid checksums > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >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 Sep 23 19:28:44 UTC 2021 on sn-devel-184 > >(cherry picked from commit 5b331443d0698256ee7fcc040a1ab8137efe925d) >--- > python/samba/tests/krb5/raw_testcase.py | 23 +++++++++++++++++++++++ > 1 file changed, 23 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index cadf2b50dc9..579d52b3e92 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -303,6 +303,29 @@ class RodcPacEncryptionKey(Krb5EncryptionKey): > cksum) > > >+class ZeroedChecksumKey(Krb5EncryptionKey): >+ def make_checksum(self, usage, plaintext, ctype=None): >+ return self.make_zeroed_checksum(ctype) >+ >+ >+class WrongLengthChecksumKey(Krb5EncryptionKey): >+ def __init__(self, key, kvno, length): >+ super().__init__(key, kvno) >+ >+ self._length = length >+ >+ def make_checksum(self, usage, plaintext, ctype=None): >+ checksum = super().make_checksum(usage, plaintext, ctype) >+ >+ diff = self._length - len(checksum) >+ if diff > 0: >+ checksum += bytes(diff) >+ elif diff < 0: >+ checksum = checksum[:self._length] >+ >+ return checksum >+ >+ > class KerberosCredentials(Credentials): > > fast_supported_bits = (security.KERB_ENCTYPE_FAST_SUPPORTED | >-- >2.25.1 > > >From 24a7c75fad0cd035f9b6a24924ecdd1c2d54b1a9 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 11:16:24 +1300 >Subject: [PATCH 073/159] tests/krb5: Rename method parameter > >For class methods, the name given to the first parameter is generally 'cls' >rather than 'self'. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit d501ddca3b7b9c39c0b3eccf19176e3122cf5b9d) >--- > python/samba/tests/krb5/raw_testcase.py | 10 +++++----- > 1 file changed, 5 insertions(+), 5 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 579d52b3e92..11c0e308e3d 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -373,10 +373,10 @@ class KerberosCredentials(Credentials): > ]) > > @classmethod >- def etypes_to_bits(self, etypes): >+ def etypes_to_bits(cls, etypes): > bits = 0 > for etype in etypes: >- bit = self.etype_map[etype] >+ bit = cls.etype_map[etype] > if bits & bit: > raise ValueError(f'Got duplicate etype: {etype}') > bits |= bit >@@ -384,14 +384,14 @@ class KerberosCredentials(Credentials): > return bits > > @classmethod >- def bits_to_etypes(self, bits): >+ def bits_to_etypes(cls, bits): > etypes = () >- for etype, bit in self.etype_map.items(): >+ for etype, bit in cls.etype_map.items(): > if bit & bits: > bits &= ~bit > etypes += (etype,) > >- bits &= ~self.fast_supported_bits >+ bits &= ~cls.fast_supported_bits > if bits != 0: > raise ValueError(f'Unsupported etype bits: {bits}') > >-- >2.25.1 > > >From 3f3790532c21320b1ad97315e4ad3889e2b5e63c Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 11:16:51 +1300 >Subject: [PATCH 074/159] tests/krb5: Remove unused parameter > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 8e4b21590836dab02c1864f6ac12b3879c4bd69c) >--- > python/samba/tests/krb5/raw_testcase.py | 3 --- > 1 file changed, 3 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 11c0e308e3d..1119c9926d7 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2169,7 +2169,6 @@ class RawKerberosTest(TestCaseInTempDir): > > self.check_rep_padata(kdc_exchange_dict, > callback_dict, >- rep, > fast_response['padata'], > error_code=0) > >@@ -2509,7 +2508,6 @@ class RawKerberosTest(TestCaseInTempDir): > > etype_info2 = self.check_rep_padata(kdc_exchange_dict, > callback_dict, >- rep, > rep_padata, > error_code) > >@@ -2520,7 +2518,6 @@ class RawKerberosTest(TestCaseInTempDir): > def check_rep_padata(self, > kdc_exchange_dict, > callback_dict, >- rep, > rep_padata, > error_code): > rep_msg_type = kdc_exchange_dict['rep_msg_type'] >-- >2.25.1 > > >From 03dcc80bc140e8448eab66a918245a2f09adc22b Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 11:23:17 +1300 >Subject: [PATCH 075/159] tests/krb5: Allow for missing msDS-KeyVersionNumber > attribute > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit ce433ff868d3cdf8e8a6e4995d89d6e036335fb6) >--- > python/samba/tests/krb5/kdc_base_test.py | 6 ++++-- > 1 file changed, 4 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index b71ae66bf54..bb92bbd65e5 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -294,8 +294,10 @@ class KDCBaseTest(RawKerberosTest): > res = samdb.search(base=dn, > scope=ldb.SCOPE_BASE, > attrs=['msDS-KeyVersionNumber']) >- kvno = int(res[0]['msDS-KeyVersionNumber'][0]) >- creds.set_kvno(kvno) >+ kvno = res[0].get('msDS-KeyVersionNumber', idx=0) >+ if kvno is not None: >+ self.assertEqual(int(kvno), 1) >+ creds.set_kvno(1) > > return (creds, dn) > >-- >2.25.1 > > >From b7fe1b336aef2bed6aaf4d2e1600bf8aca90d9ca Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 30 Sep 2021 10:51:01 +1300 >Subject: [PATCH 076/159] tests/krb5: Fix sending PA-PAC-OPTIONS and > PA-PAC-REQUEST > >These padata were not being sent if other FAST padata was not specified. > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 6f1282e8d34073d8499ce919908b39645b017cb8) >--- > python/samba/tests/krb5/raw_testcase.py | 3 +-- > 1 file changed, 1 insertion(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 1119c9926d7..ceff1b6220e 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1801,8 +1801,6 @@ class RawKerberosTest(TestCaseInTempDir): > fast_padata, req_body = generate_fast_padata_fn(kdc_exchange_dict, > callback_dict, > req_body) >- >- fast_padata += additional_padata > else: > fast_padata = [] > >@@ -1847,6 +1845,7 @@ class RawKerberosTest(TestCaseInTempDir): > KU_FAST_REQ_CHKSUM, > checksum_blob) > >+ fast_padata += additional_padata > fast = generate_fast_fn(kdc_exchange_dict, > callback_dict, > inner_req_body, >-- >2.25.1 > > >From 449eff09565ecf5acafbcec4f693e8dff0061721 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 30 Sep 2021 10:54:33 +1300 >Subject: [PATCH 077/159] tests/krb5: Fix PA-PAC-OPTIONS checking > >Make the check work correctly if bits other than the claims bit are >specified. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 1fd00135fa4dff4331d86b228ccc01f834476997) >--- > python/samba/tests/krb5/raw_testcase.py | 44 +++++++++++++------------ > 1 file changed, 23 insertions(+), 21 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index ceff1b6220e..0217674ed2d 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2354,10 +2354,10 @@ class RawKerberosTest(TestCaseInTempDir): > if self.strict_checking: > self.assertElementEqual(encpart_private, 'caddr', []) > >- sent_claims = self.sent_claims(kdc_exchange_dict) >+ sent_pac_options = self.get_sent_pac_options(kdc_exchange_dict) > > if self.strict_checking: >- if sent_claims or canonicalize: >+ if canonicalize or '1' in sent_pac_options: > self.assertElementPresent(encpart_private, > 'encrypted-pa-data') > enc_pa_dict = self.get_pa_dict( >@@ -2381,12 +2381,15 @@ class RawKerberosTest(TestCaseInTempDir): > else: > self.assertNotIn(PADATA_SUPPORTED_ETYPES, enc_pa_dict) > >- # ClaimsCompIdFASTSupported registry key >- if sent_claims: >+ if '1' in sent_pac_options: > self.assertIn(PADATA_PAC_OPTIONS, enc_pa_dict) > >- self.check_pac_options_claims_support( >- enc_pa_dict[PADATA_PAC_OPTIONS]) >+ pac_options = self.der_decode( >+ enc_pa_dict[PADATA_PAC_OPTIONS], >+ asn1Spec=krb5_asn1.PA_PAC_OPTIONS()) >+ >+ self.assertElementEqual(pac_options, 'options', >+ sent_pac_options) > else: > self.assertNotIn(PADATA_PAC_OPTIONS, enc_pa_dict) > else: >@@ -2419,11 +2422,6 @@ class RawKerberosTest(TestCaseInTempDir): > > kdc_exchange_dict['rep_ticket_creds'] = ticket_creds > >- def check_pac_options_claims_support(self, pac_options): >- pac_options = self.der_decode(pac_options, >- asn1Spec=krb5_asn1.PA_PAC_OPTIONS()) >- self.assertEqual('1', pac_options['options'][0]) # claims bit >- > def generic_check_kdc_error(self, > kdc_exchange_dict, > callback_dict, >@@ -2565,8 +2563,9 @@ class RawKerberosTest(TestCaseInTempDir): > if not sent_fast and error_code != 0: > expected_patypes += (PADATA_PW_SALT,) > else: >- sent_claims = self.sent_claims(kdc_exchange_dict) >- if sent_claims and error_code not in (0, KDC_ERR_GENERIC): >+ sent_pac_options = self.get_sent_pac_options(kdc_exchange_dict) >+ if ('1' in sent_pac_options >+ and error_code not in (0, KDC_ERR_GENERIC)): > expected_patypes += (PADATA_PAC_OPTIONS,) > elif error_code != KDC_ERR_GENERIC: > if expect_etype_info: >@@ -2656,8 +2655,9 @@ class RawKerberosTest(TestCaseInTempDir): > continue > if patype == PADATA_PAC_OPTIONS: > self.assertIsNone(pac_options) >- pac_options = pavalue >- self.assertIsNotNone(pac_options) >+ pac_options = self.der_decode( >+ pavalue, >+ asn1Spec=krb5_asn1.PA_PAC_OPTIONS()) > continue > if patype == PADATA_PW_SALT: > self.assertIsNone(pw_salt) >@@ -2677,7 +2677,7 @@ class RawKerberosTest(TestCaseInTempDir): > inner=True) > > if pac_options is not None: >- self.check_pac_options_claims_support(pac_options) >+ self.assertElementEqual(pac_options, 'options', sent_pac_options) > > if pw_salt is not None: > self.assertEqual(12, len(pw_salt)) >@@ -3418,19 +3418,21 @@ class RawKerberosTest(TestCaseInTempDir): > > return PADATA_ENCRYPTED_CHALLENGE in fast_pa_dict > >- def sent_claims(self, kdc_exchange_dict): >+ def get_sent_pac_options(self, kdc_exchange_dict): > fast_pa_dict = self.get_fast_pa_dict(kdc_exchange_dict) > > if PADATA_PAC_OPTIONS not in fast_pa_dict: >- return False >+ return '' > > pac_options = self.der_decode(fast_pa_dict[PADATA_PAC_OPTIONS], > asn1Spec=krb5_asn1.PA_PAC_OPTIONS()) > pac_options = pac_options['options'] >- claims_pos = len(tuple(krb5_asn1.PACOptionFlags('claims'))) - 1 > >- return (claims_pos < len(pac_options) >- and pac_options[claims_pos] == '1') >+ # Mask out unsupported bits. >+ pac_options, remaining = pac_options[:4], pac_options[4:] >+ pac_options += '0' * len(remaining) >+ >+ return pac_options > > def get_krbtgt_sname(self): > krbtgt_creds = self.get_krbtgt_creds() >-- >2.25.1 > > >From ed24c8a037a1318e79725899b874d3bfd4c7a00e Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 11:47:39 +1300 >Subject: [PATCH 078/159] tests/krb5: Rename allowed_to_delegate_to parameter > for clarity > >This helps to distinguish resourced-based and non-resource-based >constrained delegation. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 31817c383c2014224b1397fde610624663313246) >--- > python/samba/tests/krb5/kdc_base_test.py | 10 +++++----- > 1 file changed, 5 insertions(+), 5 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index bb92bbd65e5..e6639270f69 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -598,7 +598,7 @@ class KDCBaseTest(RawKerberosTest): > 'no_auth_data_required': False, > 'supported_enctypes': None, > 'not_delegated': False, >- 'allowed_to_delegate_to': None, >+ 'delegation_to_spn': None, > 'trusted_to_auth_for_delegation': False, > 'fast_support': False > } >@@ -629,13 +629,13 @@ class KDCBaseTest(RawKerberosTest): > no_auth_data_required, > supported_enctypes, > not_delegated, >- allowed_to_delegate_to, >+ delegation_to_spn, > trusted_to_auth_for_delegation, > fast_support): > if machine_account: > self.assertFalse(not_delegated) > else: >- self.assertIsNone(allowed_to_delegate_to) >+ self.assertIsNone(delegation_to_spn) > self.assertFalse(trusted_to_auth_for_delegation) > > samdb = self.get_samdb() >@@ -664,8 +664,8 @@ class KDCBaseTest(RawKerberosTest): > if enctypes is not None: > details['msDS-SupportedEncryptionTypes'] = str(enctypes) > >- if allowed_to_delegate_to: >- details['msDS-AllowedToDelegateTo'] = allowed_to_delegate_to >+ if delegation_to_spn: >+ details['msDS-AllowedToDelegateTo'] = delegation_to_spn > > if machine_account: > spn = 'host/' + user_name >-- >2.25.1 > > >From 8ded8a753e36903865243b651b2bf973ad59e8a3 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 11:50:36 +1300 >Subject: [PATCH 079/159] tests/krb5: Allow created accounts to use > resource-based constrained delegation > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit bba8cb8dce19e47a7b813efd9a7527e38856435e) >--- > python/samba/tests/krb5/kdc_base_test.py | 33 ++++++++++++++++++++++++ > 1 file changed, 33 insertions(+) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index e6639270f69..918e04a1dbe 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -301,6 +301,30 @@ class KDCBaseTest(RawKerberosTest): > > return (creds, dn) > >+ def get_security_descriptor(self, dn): >+ samdb = self.get_samdb() >+ >+ sid = self.get_objectSid(samdb, dn) >+ >+ owner_sid = security.dom_sid(security.SID_BUILTIN_ADMINISTRATORS) >+ >+ ace = security.ace() >+ ace.access_mask = security.SEC_ADS_GENERIC_ALL >+ >+ ace.trustee = security.dom_sid(sid) >+ >+ dacl = security.acl() >+ dacl.revision = security.SECURITY_ACL_REVISION_ADS >+ dacl.aces = [ace] >+ dacl.num_aces = 1 >+ >+ security_desc = security.descriptor() >+ security_desc.type |= security.SEC_DESC_DACL_PRESENT >+ security_desc.owner_sid = owner_sid >+ security_desc.dacl = dacl >+ >+ return ndr_pack(security_desc) >+ > def create_rodc(self, ctx): > ctx.nc_list = [ctx.base_dn, ctx.config_dn, ctx.schema_dn] > ctx.full_nc_list = [ctx.base_dn, ctx.config_dn, ctx.schema_dn] >@@ -599,6 +623,7 @@ class KDCBaseTest(RawKerberosTest): > 'supported_enctypes': None, > 'not_delegated': False, > 'delegation_to_spn': None, >+ 'delegation_from_dn': None, > 'trusted_to_auth_for_delegation': False, > 'fast_support': False > } >@@ -630,12 +655,14 @@ class KDCBaseTest(RawKerberosTest): > supported_enctypes, > not_delegated, > delegation_to_spn, >+ delegation_from_dn, > trusted_to_auth_for_delegation, > fast_support): > if machine_account: > self.assertFalse(not_delegated) > else: > self.assertIsNone(delegation_to_spn) >+ self.assertIsNone(delegation_from_dn) > self.assertFalse(trusted_to_auth_for_delegation) > > samdb = self.get_samdb() >@@ -667,6 +694,12 @@ class KDCBaseTest(RawKerberosTest): > if delegation_to_spn: > details['msDS-AllowedToDelegateTo'] = delegation_to_spn > >+ if delegation_from_dn: >+ security_descriptor = self.get_security_descriptor( >+ delegation_from_dn) >+ details['msDS-AllowedToActOnBehalfOfOtherIdentity'] = ( >+ security_descriptor) >+ > if machine_account: > spn = 'host/' + user_name > else: >-- >2.25.1 > > >From cfcae3fb28d19a69a5f3b900e06be7e2680d82c5 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 11:52:17 +1300 >Subject: [PATCH 080/159] tests/krb5: Add assertion to make failures clearer > >These failures may occur if tests are not run against an RODC. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit cda50b5c505072989abf84c209e16ff4efe2e628) >--- > python/samba/tests/krb5/kdc_base_test.py | 1 + > 1 file changed, 1 insertion(+) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 918e04a1dbe..25433ba1069 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -590,6 +590,7 @@ class KDCBaseTest(RawKerberosTest): > scope=ldb.SCOPE_BASE, > attrs=[group_attr]) > orig_msg = res[0] >+ self.assertIn(group_attr, orig_msg) > > members = list(orig_msg[group_attr]) > members.append(account_dn) >-- >2.25.1 > > >From 187bf45097ef77545d0a8a2abb72740041dac0cf Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 11:54:49 +1300 >Subject: [PATCH 081/159] tests/krb5: Introduce helper method for creating > invalid length checksums > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 9d142dc3a452b0f06efc66f422402ee6e553ee7c) >--- > python/samba/tests/krb5/raw_testcase.py | 13 ++++++++----- > 1 file changed, 8 insertions(+), 5 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 0217674ed2d..6107442409f 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -314,17 +314,20 @@ class WrongLengthChecksumKey(Krb5EncryptionKey): > > self._length = length > >- def make_checksum(self, usage, plaintext, ctype=None): >- checksum = super().make_checksum(usage, plaintext, ctype) >- >- diff = self._length - len(checksum) >+ @classmethod >+ def _adjust_to_length(cls, checksum, length): >+ diff = length - len(checksum) > if diff > 0: > checksum += bytes(diff) > elif diff < 0: >- checksum = checksum[:self._length] >+ checksum = checksum[:length] > > return checksum > >+ def make_checksum(self, usage, plaintext, ctype=None): >+ checksum = super().make_checksum(usage, plaintext, ctype) >+ return self._adjust_to_length(checksum, self._length) >+ > > class KerberosCredentials(Credentials): > >-- >2.25.1 > > >From b600c6624e44d26ce92f87921ae7a43822ef3e51 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 11:56:21 +1300 >Subject: [PATCH 082/159] tests/krb5: Fix method for creating invalid length > zeroed checksum > >Previously the base class method was being used. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit ae09219c3a1c6d47817f51baf3784e8986c7478d) >--- > python/samba/tests/krb5/raw_testcase.py | 3 +++ > 1 file changed, 3 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 6107442409f..a3f17e4dc4a 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -324,6 +324,9 @@ class WrongLengthChecksumKey(Krb5EncryptionKey): > > return checksum > >+ def make_zeroed_checksum(self, ctype=None): >+ return bytes(self._length) >+ > def make_checksum(self, usage, plaintext, ctype=None): > checksum = super().make_checksum(usage, plaintext, ctype) > return self._adjust_to_length(checksum, self._length) >-- >2.25.1 > > >From b48ae2b2d29876b895452f54f0507507e4bdde5d Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 11:59:42 +1300 >Subject: [PATCH 083/159] tests/krb5: Fix checksum generation and verification > >The KDC and server checksums may be generated using the same key, but >only the KDC checksum should have an RODCIdentifier. To fix this, >instead of overriding the existing methods, add additional ones for >RODC-specific signatures, so that both types of signatures can be >generated or verified. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit a927cecafdd5ad6dc5189fa98cb42684c9c3b033) >--- > python/samba/tests/krb5/raw_testcase.py | 57 ++++++++++++++----------- > 1 file changed, 32 insertions(+), 25 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index a3f17e4dc4a..aefbdd6d761 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -281,15 +281,15 @@ class RodcPacEncryptionKey(Krb5EncryptionKey): > else: > self.rodc_id = b'' > >- def make_zeroed_checksum(self, ctype=None): >+ def make_rodc_zeroed_checksum(self, ctype=None): > checksum = super().make_zeroed_checksum(ctype) > return checksum + bytes(len(self.rodc_id)) > >- def make_checksum(self, usage, plaintext, ctype=None): >+ def make_rodc_checksum(self, usage, plaintext, ctype=None): > checksum = super().make_checksum(usage, plaintext, ctype) > return checksum + self.rodc_id > >- def verify_checksum(self, usage, plaintext, ctype, cksum): >+ def verify_rodc_checksum(self, usage, plaintext, ctype, cksum): > if self.rodc_id: > cksum, cksum_rodc_id = cksum[:-2], cksum[-2:] > >@@ -303,12 +303,15 @@ class RodcPacEncryptionKey(Krb5EncryptionKey): > cksum) > > >-class ZeroedChecksumKey(Krb5EncryptionKey): >+class ZeroedChecksumKey(RodcPacEncryptionKey): > def make_checksum(self, usage, plaintext, ctype=None): > return self.make_zeroed_checksum(ctype) > >+ def make_rodc_checksum(self, usage, plaintext, ctype=None): >+ return self.make_rodc_zeroed_checksum(ctype) > >-class WrongLengthChecksumKey(Krb5EncryptionKey): >+ >+class WrongLengthChecksumKey(RodcPacEncryptionKey): > def __init__(self, key, kvno, length): > super().__init__(key, kvno) > >@@ -331,6 +334,13 @@ class WrongLengthChecksumKey(Krb5EncryptionKey): > checksum = super().make_checksum(usage, plaintext, ctype) > return self._adjust_to_length(checksum, self._length) > >+ def make_rodc_zeroed_checksum(self, ctype=None): >+ return bytes(self._length) >+ >+ def make_rodc_checksum(self, usage, plaintext, ctype=None): >+ checksum = super().make_rodc_checksum(usage, plaintext, ctype) >+ return self._adjust_to_length(checksum, self._length) >+ > > class KerberosCredentials(Credentials): > >@@ -3080,18 +3090,17 @@ class RawKerberosTest(TestCaseInTempDir): > > server_checksum, server_ctype = checksums[ > krb5pac.PAC_TYPE_SRV_CHECKSUM] >- Krb5EncryptionKey.verify_checksum(key, >- KU_NON_KERB_CKSUM_SALT, >- pac_data, >- server_ctype, >- server_checksum) >+ key.verify_checksum(KU_NON_KERB_CKSUM_SALT, >+ pac_data, >+ server_ctype, >+ server_checksum) > > kdc_checksum, kdc_ctype = checksums[ > krb5pac.PAC_TYPE_KDC_CHECKSUM] >- krbtgt_key.verify_checksum(KU_NON_KERB_CKSUM_SALT, >- server_checksum, >- kdc_ctype, >- kdc_checksum) >+ krbtgt_key.verify_rodc_checksum(KU_NON_KERB_CKSUM_SALT, >+ server_checksum, >+ kdc_ctype, >+ kdc_checksum) > > if is_tgt: > self.assertNotIn(krb5pac.PAC_TYPE_TICKET_CHECKSUM, checksums) >@@ -3106,10 +3115,10 @@ class RawKerberosTest(TestCaseInTempDir): > enc_part = self.der_encode(enc_part, > asn1Spec=krb5_asn1.EncTicketPart()) > >- krbtgt_key.verify_checksum(KU_NON_KERB_CKSUM_SALT, >- enc_part, >- ticket_ctype, >- ticket_checksum) >+ krbtgt_key.verify_rodc_checksum(KU_NON_KERB_CKSUM_SALT, >+ enc_part, >+ ticket_ctype, >+ ticket_checksum) > > def modified_ticket(self, > ticket, *, >@@ -3300,16 +3309,15 @@ class RawKerberosTest(TestCaseInTempDir): > if buffer_type == krb5pac.PAC_TYPE_TICKET_CHECKSUM: > self.assertIsNotNone(enc_part) > >- signature = checksum_key.make_checksum( >+ signature = checksum_key.make_rodc_checksum( > KU_NON_KERB_CKSUM_SALT, > enc_part) > > elif buffer_type == krb5pac.PAC_TYPE_SRV_CHECKSUM: >- signature = Krb5EncryptionKey.make_zeroed_checksum( >- checksum_key) >+ signature = checksum_key.make_zeroed_checksum() > > else: >- signature = checksum_key.make_zeroed_checksum() >+ signature = checksum_key.make_rodc_zeroed_checksum() > > checksum_buffer.info.signature = signature > checksum_buffer.info.type = ctype >@@ -3325,8 +3333,7 @@ class RawKerberosTest(TestCaseInTempDir): > server_checksum_key = checksum_keys[krb5pac.PAC_TYPE_SRV_CHECKSUM] > > pac_data = ndr_pack(pac) >- server_checksum = Krb5EncryptionKey.make_checksum( >- server_checksum_key, >+ server_checksum = server_checksum_key.make_checksum( > KU_NON_KERB_CKSUM_SALT, > pac_data) > >@@ -3339,7 +3346,7 @@ class RawKerberosTest(TestCaseInTempDir): > > kdc_checksum_key = checksum_keys[krb5pac.PAC_TYPE_KDC_CHECKSUM] > >- kdc_checksum = kdc_checksum_key.make_checksum( >+ kdc_checksum = kdc_checksum_key.make_rodc_checksum( > KU_NON_KERB_CKSUM_SALT, > server_checksum) > >-- >2.25.1 > > >From 89689b0e0a1c8c53e6f9b35b25b48bab26cb6bfe Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 12:03:33 +1300 >Subject: [PATCH 084/159] tests/krb5: Allow excluding the PAC server checksum > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit dcf45a151a198f7165cd332a26db78a5d8e8f8c5) >--- > python/samba/tests/krb5/raw_testcase.py | 5 ++++- > 1 file changed, 4 insertions(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index aefbdd6d761..4c1aedbca0f 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -3342,7 +3342,10 @@ class RawKerberosTest(TestCaseInTempDir): > kdc_checksum_buffer = checksum_buffers.get( > krb5pac.PAC_TYPE_KDC_CHECKSUM) > if kdc_checksum_buffer is not None: >- self.assertIsNotNone(server_checksum_buffer) >+ if server_checksum_buffer is None: >+ # There's no server signature to make the checksum over, so >+ # just make the checksum over an empty bytes object. >+ server_checksum = bytes() > > kdc_checksum_key = checksum_keys[krb5pac.PAC_TYPE_KDC_CHECKSUM] > >-- >2.25.1 > > >From 17c871fd4dce01e549fe031d14ededb08c50c825 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 12:06:03 +1300 >Subject: [PATCH 085/159] tests/krb5: Fix handling authdata with missing PAC > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit a4bc712ee02f32c2d04dfc2d99d58931344e5ceb) >--- > python/samba/tests/krb5/raw_testcase.py | 11 ++++++----- > 1 file changed, 6 insertions(+), 5 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 4c1aedbca0f..b9895e547c4 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -3200,11 +3200,11 @@ class RawKerberosTest(TestCaseInTempDir): > # Get a copy of the authdata with an empty PAC, and the > # existing PAC (if present). > empty_pac = self.get_empty_pac() >- empty_pac_auth_data, pac_data = self.replace_pac(auth_data, >- empty_pac) >+ empty_pac_auth_data, pac_data = self.replace_pac( >+ auth_data, >+ empty_pac, >+ expect_pac=expect_pac) > >- if expect_pac: >- self.assertIsNotNone(pac_data) > if pac_data is not None: > pac = ndr_unpack(krb5pac.PAC_DATA, pac_data) > >@@ -3234,7 +3234,8 @@ class RawKerberosTest(TestCaseInTempDir): > > # Replace the PAC in the authorization data and re-add it to the > # ticket enc-part. >- auth_data, _ = self.replace_pac(auth_data, new_pac) >+ auth_data, _ = self.replace_pac(auth_data, new_pac, >+ expect_pac=expect_pac) > enc_part['authorization-data'] = auth_data > > # Re-encrypt the ticket enc-part with the new key. >-- >2.25.1 > > >From 4b35dbe572ada81ce7d4e3d41a70e24b376bb093 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 12:16:58 +1300 >Subject: [PATCH 086/159] tests/krb5: Fix status code checking > >The type used to encode the status code is actually KERB-ERROR-DATA, >rather than PA-DATA. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 012b6fcd1976c6570e9b92c133d8c21e543e5a4f) >--- > python/samba/tests/krb5/raw_testcase.py | 89 +++++++++----------- > python/samba/tests/krb5/rfc4120_constants.py | 6 ++ > 2 files changed, 48 insertions(+), 47 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index b9895e547c4..db7db28cac5 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -49,6 +49,7 @@ from samba.tests.krb5.rfc4120_constants import ( > KDC_ERR_GENERIC, > KDC_ERR_PREAUTH_FAILED, > KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTIONS, >+ KERB_ERR_TYPE_EXTENDED, > KRB_AP_REQ, > KRB_AS_REP, > KRB_AS_REQ, >@@ -85,7 +86,6 @@ from samba.tests.krb5.rfc4120_constants import ( > PADATA_PAC_REQUEST, > PADATA_PK_AS_REQ, > PADATA_PK_AS_REP_19, >- PADATA_PW_SALT, > PADATA_SUPPORTED_ETYPES > ) > import samba.tests.krb5.kcrypto as kcrypto >@@ -2497,34 +2497,51 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertIsNotNone(edata) > if edata is not None: > if rep_msg_type == KRB_TGS_REP and not sent_fast: >- rep_padata = [self.der_decode(edata, >- asn1Spec=krb5_asn1.PA_DATA())] >+ error_data = self.der_decode( >+ edata, >+ asn1Spec=krb5_asn1.KERB_ERROR_DATA()) >+ self.assertEqual(KERB_ERR_TYPE_EXTENDED, >+ error_data['data-type']) >+ >+ extended_error = error_data['data-value'] >+ >+ self.assertEqual(12, len(extended_error)) >+ >+ status = int.from_bytes(extended_error[:4], 'little') >+ flags = int.from_bytes(extended_error[8:], 'little') >+ >+ expected_status = kdc_exchange_dict['expected_status'] >+ self.assertEqual(expected_status, status) >+ >+ self.assertEqual(3, flags) > else: >+ self.assertIsNone(kdc_exchange_dict['expected_status']) >+ > rep_padata = self.der_decode(edata, > asn1Spec=krb5_asn1.METHOD_DATA()) >- self.assertGreater(len(rep_padata), 0) >+ self.assertGreater(len(rep_padata), 0) > >- if sent_fast: >- self.assertEqual(1, len(rep_padata)) >- rep_pa_dict = self.get_pa_dict(rep_padata) >- self.assertIn(PADATA_FX_FAST, rep_pa_dict) >+ if sent_fast: >+ self.assertEqual(1, len(rep_padata)) >+ rep_pa_dict = self.get_pa_dict(rep_padata) >+ self.assertIn(PADATA_FX_FAST, rep_pa_dict) > >- armor_key = kdc_exchange_dict['armor_key'] >- self.assertIsNotNone(armor_key) >- fast_response = self.check_fx_fast_data( >- kdc_exchange_dict, >- rep_pa_dict[PADATA_FX_FAST], >- armor_key, >- expect_strengthen_key=False) >+ armor_key = kdc_exchange_dict['armor_key'] >+ self.assertIsNotNone(armor_key) >+ fast_response = self.check_fx_fast_data( >+ kdc_exchange_dict, >+ rep_pa_dict[PADATA_FX_FAST], >+ armor_key, >+ expect_strengthen_key=False) > >- rep_padata = fast_response['padata'] >+ rep_padata = fast_response['padata'] > >- etype_info2 = self.check_rep_padata(kdc_exchange_dict, >- callback_dict, >- rep_padata, >- error_code) >+ etype_info2 = self.check_rep_padata(kdc_exchange_dict, >+ callback_dict, >+ rep_padata, >+ error_code) > >- kdc_exchange_dict['preauth_etype_info2'] = etype_info2 >+ kdc_exchange_dict['preauth_etype_info2'] = etype_info2 > > return rep > >@@ -2576,13 +2593,10 @@ class RawKerberosTest(TestCaseInTempDir): > expected_patypes += (PADATA_FX_COOKIE,) > > if rep_msg_type == KRB_TGS_REP: >- if not sent_fast and error_code != 0: >- expected_patypes += (PADATA_PW_SALT,) >- else: >- sent_pac_options = self.get_sent_pac_options(kdc_exchange_dict) >- if ('1' in sent_pac_options >- and error_code not in (0, KDC_ERR_GENERIC)): >- expected_patypes += (PADATA_PAC_OPTIONS,) >+ sent_pac_options = self.get_sent_pac_options(kdc_exchange_dict) >+ if ('1' in sent_pac_options >+ and error_code not in (0, KDC_ERR_GENERIC)): >+ expected_patypes += (PADATA_PAC_OPTIONS,) > elif error_code != KDC_ERR_GENERIC: > if expect_etype_info: > self.assertGreater(len(expect_etype_info2), 0) >@@ -2621,7 +2635,6 @@ class RawKerberosTest(TestCaseInTempDir): > fast_error = None > fx_fast = None > pac_options = None >- pw_salt = None > for pa in rep_padata: > patype = self.getElementValue(pa, 'padata-type') > pavalue = self.getElementValue(pa, 'padata-value') >@@ -2675,11 +2688,6 @@ class RawKerberosTest(TestCaseInTempDir): > pavalue, > asn1Spec=krb5_asn1.PA_PAC_OPTIONS()) > continue >- if patype == PADATA_PW_SALT: >- self.assertIsNone(pw_salt) >- pw_salt = pavalue >- self.assertIsNotNone(pw_salt) >- continue > > if fast_cookie is not None: > kdc_exchange_dict['fast_cookie'] = fast_cookie >@@ -2695,19 +2703,6 @@ class RawKerberosTest(TestCaseInTempDir): > if pac_options is not None: > self.assertElementEqual(pac_options, 'options', sent_pac_options) > >- if pw_salt is not None: >- self.assertEqual(12, len(pw_salt)) >- >- status = int.from_bytes(pw_salt[:4], 'little') >- flags = int.from_bytes(pw_salt[8:], 'little') >- >- expected_status = kdc_exchange_dict['expected_status'] >- self.assertEqual(expected_status, status) >- >- self.assertEqual(3, flags) >- else: >- self.assertIsNone(kdc_exchange_dict.get('expected_status')) >- > if enc_challenge is not None: > if not sent_enc_challenge: > self.assertEqual(len(enc_challenge), 0) >diff --git a/python/samba/tests/krb5/rfc4120_constants.py b/python/samba/tests/krb5/rfc4120_constants.py >index ac2bac4d91e..76f2b75d94e 100644 >--- a/python/samba/tests/krb5/rfc4120_constants.py >+++ b/python/samba/tests/krb5/rfc4120_constants.py >@@ -78,6 +78,12 @@ KDC_ERR_SKEW = 37 > KDC_ERR_GENERIC = 60 > KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTIONS = 93 > >+# Extended error types >+KERB_AP_ERR_TYPE_SKEW_RECOVERY = int( >+ krb5_asn1.KerbErrorDataTypeValues('kERB-AP-ERR-TYPE-SKEW-RECOVERY')) >+KERB_ERR_TYPE_EXTENDED = int( >+ krb5_asn1.KerbErrorDataTypeValues('kERB-ERR-TYPE-EXTENDED')) >+ > # Name types > NT_UNKNOWN = int(krb5_asn1.NameTypeValues('kRB5-NT-UNKNOWN')) > NT_PRINCIPAL = int(krb5_asn1.NameTypeValues('kRB5-NT-PRINCIPAL')) >-- >2.25.1 > > >From f728d5f850e64e167d32af19bc51a20939a883b5 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 13:01:30 +1300 >Subject: [PATCH 087/159] tests/krb5: Make expected_sname checking more > explicit > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >[abartlet@samba.org backported from commit 8f6d369d709614e2f5c0684882c62f0476bcafa2 > as Samba 4.14 as the test which crashes older MIT KDC versions is > omitted] >--- > python/samba/tests/krb5/fast_tests.py | 39 ++++++++++--------------- > python/samba/tests/krb5/raw_testcase.py | 6 +--- > 2 files changed, 17 insertions(+), 28 deletions(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index 431b48f00d6..5180eb57563 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -99,11 +99,7 @@ class FAST_Tests(KDCBaseTest): > ]) > > def test_simple_no_sname(self): >- krbtgt_creds = self.get_krbtgt_creds() >- krbtgt_username = krbtgt_creds.get_username() >- krbtgt_realm = krbtgt_creds.get_realm() >- expected_sname = self.PrincipalName_create( >- name_type=NT_SRV_INST, names=[krbtgt_username, krbtgt_realm]) >+ expected_sname = self.get_krbtgt_sname() > > self._run_test_sequence([ > { >@@ -116,11 +112,7 @@ class FAST_Tests(KDCBaseTest): > ]) > > def test_simple_tgs_no_sname(self): >- krbtgt_creds = self.get_krbtgt_creds() >- krbtgt_username = krbtgt_creds.get_username() >- krbtgt_realm = krbtgt_creds.get_realm() >- expected_sname = self.PrincipalName_create( >- name_type=NT_SRV_INST, names=[krbtgt_username, krbtgt_realm]) >+ expected_sname = self.get_krbtgt_sname() > > self._run_test_sequence([ > { >@@ -134,11 +126,7 @@ class FAST_Tests(KDCBaseTest): > ]) > > def test_fast_no_sname(self): >- krbtgt_creds = self.get_krbtgt_creds() >- krbtgt_username = krbtgt_creds.get_username() >- krbtgt_realm = krbtgt_creds.get_realm() >- expected_sname = self.PrincipalName_create( >- name_type=NT_SRV_INST, names=[krbtgt_username, krbtgt_realm]) >+ expected_sname = self.get_krbtgt_sname() > > self._run_test_sequence([ > { >@@ -153,11 +141,7 @@ class FAST_Tests(KDCBaseTest): > ]) > > def test_fast_tgs_no_sname(self): >- krbtgt_creds = self.get_krbtgt_creds() >- krbtgt_username = krbtgt_creds.get_username() >- krbtgt_realm = krbtgt_creds.get_realm() >- expected_sname = self.PrincipalName_create( >- name_type=NT_SRV_INST, names=[krbtgt_username, krbtgt_realm]) >+ expected_sname = self.get_krbtgt_sname() > > self._run_test_sequence([ > { >@@ -830,6 +814,8 @@ class FAST_Tests(KDCBaseTest): > ]) > > def test_fast_ad_fx_fast_armor(self): >+ expected_sname = self.get_krbtgt_sname() >+ > # If the authenticator or TGT authentication data contains the > # AD-fx-fast-armor authdata type, the KDC must reject the request > # (RFC6113 5.4.1.1). >@@ -849,7 +835,8 @@ class FAST_Tests(KDCBaseTest): > 'use_fast': True, > 'gen_authdata_fn': self.generate_fast_armor_auth_data, > 'gen_tgt_fn': self.get_user_tgt, >- 'fast_armor': None >+ 'fast_armor': None, >+ 'expected_sname': expected_sname > } > ]) > >@@ -877,6 +864,8 @@ class FAST_Tests(KDCBaseTest): > ]) > > def test_fast_ad_fx_fast_armor_ticket(self): >+ expected_sname = self.get_krbtgt_sname() >+ > # If the authenticator or TGT authentication data contains the > # AD-fx-fast-armor authdata type, the KDC must reject the request > # (RFC6113 5.4.2). >@@ -896,7 +885,8 @@ class FAST_Tests(KDCBaseTest): > 'expected_error_mode': KDC_ERR_GENERIC, > 'use_fast': True, > 'gen_tgt_fn': self.gen_tgt_fast_armor_auth_data, >- 'fast_armor': None >+ 'fast_armor': None, >+ 'expected_sname': expected_sname > } > ]) > >@@ -956,6 +946,8 @@ class FAST_Tests(KDCBaseTest): > ]) > > def test_fast_tgs_no_subkey(self): >+ expected_sname = self.get_krbtgt_sname() >+ > # Show that omitting the subkey in the TGS-REQ authenticator fails > # (RFC6113 5.4.2). > self._run_test_sequence([ >@@ -965,7 +957,8 @@ class FAST_Tests(KDCBaseTest): > 'use_fast': True, > 'gen_tgt_fn': self.get_user_tgt, > 'fast_armor': None, >- 'include_subkey': False >+ 'include_subkey': False, >+ 'expected_sname': expected_sname > } > ]) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index db7db28cac5..f6aeb00dc8f 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2475,11 +2475,7 @@ class RawKerberosTest(TestCaseInTempDir): > else: > self.assertElementMissing(rep, 'cname') > self.assertElementEqualUTF8(rep, 'realm', expected_srealm) >- if sent_fast and error_code == KDC_ERR_GENERIC: >- self.assertElementEqualPrincipal(rep, 'sname', >- self.get_krbtgt_sname()) >- else: >- self.assertElementEqualPrincipal(rep, 'sname', expected_sname) >+ self.assertElementEqualPrincipal(rep, 'sname', expected_sname) > self.assertElementMissing(rep, 'e-text') > if (error_code == KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTIONS > or (rep_msg_type == KRB_TGS_REP >-- >2.25.1 > > >From 4fa468343eccc5e1922b46c950f5be37d471a78c Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 13:03:49 +1300 >Subject: [PATCH 088/159] tests/krb5: Fix assertElementFlags() > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 788b3a29eea62f9f38ca8865c7cb7860bdc94bec) >--- > python/samba/tests/krb5/fast_tests.py | 4 ++-- > python/samba/tests/krb5/raw_testcase.py | 4 ++-- > 2 files changed, 4 insertions(+), 4 deletions(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index 5180eb57563..cf9b9d718bb 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -1305,10 +1305,10 @@ class FAST_Tests(KDCBaseTest): > > expected_flags = kdc_dict.pop('expected_flags', None) > if expected_flags is not None: >- expected_flags = krb5_asn1.KDCOptions(expected_flags) >+ expected_flags = krb5_asn1.TicketFlags(expected_flags) > unexpected_flags = kdc_dict.pop('unexpected_flags', None) > if unexpected_flags is not None: >- unexpected_flags = krb5_asn1.KDCOptions(unexpected_flags) >+ unexpected_flags = krb5_asn1.TicketFlags(unexpected_flags) > > if rep_type == KRB_AS_REP: > kdc_exchange_dict = self.as_exchange_dict( >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index f6aeb00dc8f..a24faf1d060 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1053,14 +1053,14 @@ class RawKerberosTest(TestCaseInTempDir): > v = self.getElementValue(obj, elem) > self.assertIsNotNone(v) > if expected is not None: >- self.assertIsInstance(expected, krb5_asn1.KDCOptions) >+ self.assertIsInstance(expected, krb5_asn1.TicketFlags) > for i, flag in enumerate(expected): > if flag == 1: > self.assertEqual('1', v[i], > f"'{expected.namedValues[i]}' " > f"expected in {v}") > if unexpected is not None: >- self.assertIsInstance(unexpected, krb5_asn1.KDCOptions) >+ self.assertIsInstance(unexpected, krb5_asn1.TicketFlags) > for i, flag in enumerate(unexpected): > if flag == 1: > self.assertEqual('0', v[i], >-- >2.25.1 > > >From d5032e29092b4cf71970724b1a93b9d2f8469c9f Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 14:02:37 +1300 >Subject: [PATCH 089/159] tests/krb5: Remove unneeded parameters from ticket > cache key > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 7fba83c6c6309a525742c38e904d3e473db99ef1) >--- > python/samba/tests/krb5/kdc_base_test.py | 3 +-- > 1 file changed, 1 insertion(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 25433ba1069..7ddaa53b541 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -1278,8 +1278,7 @@ class KDCBaseTest(RawKerberosTest): > expected_flags=None, unexpected_flags=None, > fresh=False): > user_name = creds.get_username() >- cache_key = (user_name, to_rodc, kdc_options, >- expected_flags, unexpected_flags) >+ cache_key = (user_name, to_rodc, kdc_options) > > if not fresh: > tgt = self.tkt_cache.get(cache_key) >-- >2.25.1 > > >From dcead4d28de155d89258648e37aff31d7b8c5ef6 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 15:48:58 +1300 >Subject: [PATCH 090/159] tests/krb5: Fix checking for presence of error data > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit ab92dc16d20b0996b8c46714652c15019c795095) >--- > python/samba/tests/krb5/fast_tests.py | 39 +++++++++++++++++------- > python/samba/tests/krb5/kdc_base_test.py | 4 ++- > python/samba/tests/krb5/kdc_tgs_tests.py | 3 +- > python/samba/tests/krb5/raw_testcase.py | 27 ++++++++-------- > 4 files changed, 48 insertions(+), 25 deletions(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index cf9b9d718bb..28fe0686335 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -107,7 +107,8 @@ class FAST_Tests(KDCBaseTest): > 'expected_error_mode': (KDC_ERR_GENERIC, KDC_ERR_S_PRINCIPAL_UNKNOWN), > 'use_fast': False, > 'sname': None, >- 'expected_sname': expected_sname >+ 'expected_sname': expected_sname, >+ 'expect_edata': False > } > ]) > >@@ -121,7 +122,8 @@ class FAST_Tests(KDCBaseTest): > 'use_fast': False, > 'gen_tgt_fn': self.get_user_tgt, > 'sname': None, >- 'expected_sname': expected_sname >+ 'expected_sname': expected_sname, >+ 'expect_edata': False > } > ]) > >@@ -172,6 +174,7 @@ class FAST_Tests(KDCBaseTest): > 'expected_error_mode': KDC_ERR_NOT_US, > 'use_fast': False, > 'gen_tgt_fn': self.get_user_service_ticket, >+ 'expect_edata': False > } > ]) > >@@ -182,6 +185,7 @@ class FAST_Tests(KDCBaseTest): > 'expected_error_mode': KDC_ERR_NOT_US, > 'use_fast': False, > 'gen_tgt_fn': self.get_mach_service_ticket, >+ 'expect_edata': False > } > ]) > >@@ -294,7 +298,8 @@ class FAST_Tests(KDCBaseTest): > 'expected_error_mode': KDC_ERR_ETYPE_NOSUPP, > 'use_fast': False, > 'gen_tgt_fn': self.get_mach_tgt, >- 'etypes': () >+ 'etypes': (), >+ 'expect_edata': False > } > ]) > >@@ -342,7 +347,8 @@ class FAST_Tests(KDCBaseTest): > 'use_fast': True, > 'gen_fast_fn': self.generate_empty_fast, > 'fast_armor': None, >- 'gen_armor_tgt_fn': self.get_mach_tgt >+ 'gen_armor_tgt_fn': self.get_mach_tgt, >+ 'expect_edata': False > } > ]) > >@@ -365,7 +371,8 @@ class FAST_Tests(KDCBaseTest): > 'expected_error_mode': KDC_ERR_GENERIC, > 'use_fast': True, > 'fast_armor': None, # no armor, >- 'gen_armor_tgt_fn': self.get_mach_tgt >+ 'gen_armor_tgt_fn': self.get_mach_tgt, >+ 'expect_edata': False > } > ]) > >@@ -809,7 +816,8 @@ class FAST_Tests(KDCBaseTest): > # should be KRB_APP_ERR_MODIFIED > 'use_fast': False, > 'gen_authdata_fn': self.generate_fast_used_auth_data, >- 'gen_tgt_fn': self.get_user_tgt >+ 'gen_tgt_fn': self.get_user_tgt, >+ 'expect_edata': False > } > ]) > >@@ -836,7 +844,8 @@ class FAST_Tests(KDCBaseTest): > 'gen_authdata_fn': self.generate_fast_armor_auth_data, > 'gen_tgt_fn': self.get_user_tgt, > 'fast_armor': None, >- 'expected_sname': expected_sname >+ 'expected_sname': expected_sname, >+ 'expect_edata': False > } > ]) > >@@ -886,7 +895,8 @@ class FAST_Tests(KDCBaseTest): > 'use_fast': True, > 'gen_tgt_fn': self.gen_tgt_fast_armor_auth_data, > 'fast_armor': None, >- 'expected_sname': expected_sname >+ 'expected_sname': expected_sname, >+ 'expect_edata': False > } > ]) > >@@ -958,7 +968,8 @@ class FAST_Tests(KDCBaseTest): > 'gen_tgt_fn': self.get_user_tgt, > 'fast_armor': None, > 'include_subkey': False, >- 'expected_sname': expected_sname >+ 'expected_sname': expected_sname, >+ 'expect_edata': False > } > ]) > >@@ -1209,6 +1220,10 @@ class FAST_Tests(KDCBaseTest): > else: > tgt_cname = client_cname > >+ expect_edata = kdc_dict.pop('expect_edata', None) >+ if expect_edata is not None: >+ self.assertTrue(expected_error_mode) >+ > expected_cname = kdc_dict.pop('expected_cname', tgt_cname) > expected_anon = kdc_dict.pop('expected_anon', > False) >@@ -1343,7 +1358,8 @@ class FAST_Tests(KDCBaseTest): > inner_req=inner_req, > outer_req=outer_req, > pac_request=True, >- pac_options=pac_options) >+ pac_options=pac_options, >+ expect_edata=expect_edata) > else: # KRB_TGS_REP > kdc_exchange_dict = self.tgs_exchange_dict( > expected_crealm=expected_crealm, >@@ -1376,7 +1392,8 @@ class FAST_Tests(KDCBaseTest): > inner_req=inner_req, > outer_req=outer_req, > pac_request=None, >- pac_options=pac_options) >+ pac_options=pac_options, >+ expect_edata=expect_edata) > > repeat = kdc_dict.pop('repeat', 1) > for _ in range(repeat): >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 7ddaa53b541..d25fc0b42b2 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -1162,7 +1162,8 @@ class KDCBaseTest(RawKerberosTest): > > def tgs_req(self, cname, sname, realm, ticket, key, etypes, > expected_error_mode=0, padata=None, kdc_options=0, >- to_rodc=False, service_creds=None, expect_pac=True): >+ to_rodc=False, service_creds=None, expect_pac=True, >+ expect_edata=None): > '''Send a TGS-REQ, returns the response and the decrypted and > decoded enc-part > ''' >@@ -1209,6 +1210,7 @@ class KDCBaseTest(RawKerberosTest): > tgt=tgt, > authenticator_subkey=subkey, > kdc_options=str(kdc_options), >+ expect_edata=expect_edata, > expect_pac=expect_pac, > to_rodc=to_rodc) > >diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py >index 0904233b01f..2b55ba8a376 100755 >--- a/python/samba/tests/krb5/kdc_tgs_tests.py >+++ b/python/samba/tests/krb5/kdc_tgs_tests.py >@@ -85,7 +85,8 @@ class KdcTgsTests(KDCBaseTest): > names=["host", samdb.host_dns_name()]) > > (rep, enc_part) = self.tgs_req(cname, sname, realm, ticket, key, etype, >- expected_error_mode=KDC_ERR_BADMATCH) >+ expected_error_mode=KDC_ERR_BADMATCH, >+ expect_edata=False) > > self.assertIsNone( > enc_part, >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index a24faf1d060..1a3aedbd436 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1959,6 +1959,7 @@ class RawKerberosTest(TestCaseInTempDir): > outer_req=None, > pac_request=None, > pac_options=None, >+ expect_edata=None, > expect_pac=True, > to_rodc=False): > if expected_error_mode == 0: >@@ -2005,6 +2006,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'outer_req': outer_req, > 'pac_request': pac_request, > 'pac_options': pac_options, >+ 'expect_edata': expect_edata, > 'expect_pac': expect_pac, > 'to_rodc': to_rodc > } >@@ -2046,6 +2048,7 @@ class RawKerberosTest(TestCaseInTempDir): > outer_req=None, > pac_request=None, > pac_options=None, >+ expect_edata=None, > expect_pac=True, > to_rodc=False): > if expected_error_mode == 0: >@@ -2091,6 +2094,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'outer_req': outer_req, > 'pac_request': pac_request, > 'pac_options': pac_options, >+ 'expect_edata': expect_edata, > 'expect_pac': expect_pac, > 'to_rodc': to_rodc > } >@@ -2477,20 +2481,20 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertElementEqualUTF8(rep, 'realm', expected_srealm) > self.assertElementEqualPrincipal(rep, 'sname', expected_sname) > self.assertElementMissing(rep, 'e-text') >- if (error_code == KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTIONS >- or (rep_msg_type == KRB_TGS_REP >- and not sent_fast) >- or (sent_fast and fast_armor_type is not None >- and fast_armor_type != FX_FAST_ARMOR_AP_REQUEST) >- or inner): >+ expected_status = kdc_exchange_dict['expected_status'] >+ expect_edata = kdc_exchange_dict['expect_edata'] >+ if expect_edata is None: >+ expect_edata = (error_code != KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTIONS >+ and (not sent_fast or fast_armor_type is None >+ or fast_armor_type == FX_FAST_ARMOR_AP_REQUEST) >+ and not inner) >+ if not expect_edata: >+ self.assertIsNone(expected_status) > self.assertElementMissing(rep, 'e-data') > return rep > edata = self.getElementValue(rep, 'e-data') > if self.strict_checking: >- if error_code != KDC_ERR_GENERIC: >- # Predicting whether an ERR_GENERIC error contains e-data is >- # more complicated. >- self.assertIsNotNone(edata) >+ self.assertIsNotNone(edata) > if edata is not None: > if rep_msg_type == KRB_TGS_REP and not sent_fast: > error_data = self.der_decode( >@@ -2506,12 +2510,11 @@ class RawKerberosTest(TestCaseInTempDir): > status = int.from_bytes(extended_error[:4], 'little') > flags = int.from_bytes(extended_error[8:], 'little') > >- expected_status = kdc_exchange_dict['expected_status'] > self.assertEqual(expected_status, status) > > self.assertEqual(3, flags) > else: >- self.assertIsNone(kdc_exchange_dict['expected_status']) >+ self.assertIsNone(expected_status) > > rep_padata = self.der_decode(edata, > asn1Spec=krb5_asn1.METHOD_DATA()) >-- >2.25.1 > > >From 99e76997a919ae23dc1364ddf31d36d4e8806aa9 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 16:10:07 +1300 >Subject: [PATCH 091/159] tests/krb5: Add expect_claims parameter to > kdc_exchange_dict > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 7cfc225b549108739bd86e222f2f35eb96af4ea3) >--- > python/samba/tests/krb5/raw_testcase.py | 4 ++++ > 1 file changed, 4 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 1a3aedbd436..0415f1ff6e6 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1961,6 +1961,7 @@ class RawKerberosTest(TestCaseInTempDir): > pac_options=None, > expect_edata=None, > expect_pac=True, >+ expect_claims=True, > to_rodc=False): > if expected_error_mode == 0: > expected_error_mode = () >@@ -2008,6 +2009,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'pac_options': pac_options, > 'expect_edata': expect_edata, > 'expect_pac': expect_pac, >+ 'expect_claims': expect_claims, > 'to_rodc': to_rodc > } > if callback_dict is None: >@@ -2050,6 +2052,7 @@ class RawKerberosTest(TestCaseInTempDir): > pac_options=None, > expect_edata=None, > expect_pac=True, >+ expect_claims=True, > to_rodc=False): > if expected_error_mode == 0: > expected_error_mode = () >@@ -2096,6 +2099,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'pac_options': pac_options, > 'expect_edata': expect_edata, > 'expect_pac': expect_pac, >+ 'expect_claims': expect_claims, > 'to_rodc': to_rodc > } > if callback_dict is None: >-- >2.25.1 > > >From 3774c166a456fa23ba37fa59108ec976cfe9d4dd Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 16:15:26 +1300 >Subject: [PATCH 092/159] tests/krb5: Check buffer types in PAC with > STRICT_CHECKING=1 > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit aa2e583fdea4fd93e4e71c54630e32a1035d1e2a) >--- > librpc/idl/krb5pac.idl | 3 ++ > python/samba/tests/krb5/raw_testcase.py | 52 +++++++++++++++++++++++++ > 2 files changed, 55 insertions(+) > >diff --git a/librpc/idl/krb5pac.idl b/librpc/idl/krb5pac.idl >index 3239d7656b6..515150ab9cd 100644 >--- a/librpc/idl/krb5pac.idl >+++ b/librpc/idl/krb5pac.idl >@@ -113,6 +113,9 @@ interface krb5pac > PAC_TYPE_LOGON_NAME = 10, > PAC_TYPE_CONSTRAINED_DELEGATION = 11, > PAC_TYPE_UPN_DNS_INFO = 12, >+ PAC_TYPE_CLIENT_CLAIMS_INFO = 13, >+ PAC_TYPE_DEVICE_INFO = 14, >+ PAC_TYPE_DEVICE_CLAIMS_INFO = 15, > PAC_TYPE_TICKET_CHECKSUM = 16 > } PAC_TYPE; > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 0415f1ff6e6..320de0a4dbe 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2340,6 +2340,13 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertElementPresent(ticket_private, 'authorization-data', > expect_empty=not expect_pac) > >+ if expect_pac: >+ authorization_data = self.getElementValue(ticket_private, >+ 'authorization-data') >+ pac_data = self.get_pac(authorization_data) >+ >+ self.check_pac_buffers(pac_data, kdc_exchange_dict) >+ > encpart_session_key = None > if encpart_private is not None: > self.assertElementPresent(encpart_private, 'key') >@@ -2446,6 +2453,47 @@ class RawKerberosTest(TestCaseInTempDir): > > kdc_exchange_dict['rep_ticket_creds'] = ticket_creds > >+ def check_pac_buffers(self, pac_data, kdc_exchange_dict): >+ pac = ndr_unpack(krb5pac.PAC_DATA, pac_data) >+ >+ rep_msg_type = kdc_exchange_dict['rep_msg_type'] >+ armor_tgt = kdc_exchange_dict['armor_tgt'] >+ >+ expected_sname = kdc_exchange_dict['expected_sname'] >+ expect_claims = kdc_exchange_dict['expect_claims'] >+ >+ expected_types = [krb5pac.PAC_TYPE_LOGON_INFO, >+ krb5pac.PAC_TYPE_SRV_CHECKSUM, >+ krb5pac.PAC_TYPE_KDC_CHECKSUM, >+ krb5pac.PAC_TYPE_LOGON_NAME, >+ krb5pac.PAC_TYPE_UPN_DNS_INFO] >+ >+ kdc_options = kdc_exchange_dict['kdc_options'] >+ pos = len(tuple(krb5_asn1.KDCOptions('cname-in-addl-tkt'))) - 1 >+ constrained_delegation = (pos < len(kdc_options) >+ and kdc_options[pos] == '1') >+ if constrained_delegation: >+ expected_types.append(krb5pac.PAC_TYPE_CONSTRAINED_DELEGATION) >+ >+ if self.kdc_fast_support: >+ if expect_claims: >+ expected_types.append(krb5pac.PAC_TYPE_CLIENT_CLAIMS_INFO) >+ >+ if (rep_msg_type == KRB_TGS_REP >+ and armor_tgt is not None): >+ expected_types.append(krb5pac.PAC_TYPE_DEVICE_INFO) >+ expected_types.append(krb5pac.PAC_TYPE_DEVICE_CLAIMS_INFO) >+ >+ if not self.is_tgs(expected_sname): >+ expected_types.append(krb5pac.PAC_TYPE_TICKET_CHECKSUM) >+ >+ if self.strict_checking: >+ buffer_types = [pac_buffer.type >+ for pac_buffer in pac.buffers] >+ self.assertCountEqual(expected_types, buffer_types, >+ f'expected: {expected_types} ' >+ f'got: {buffer_types}') >+ > def generic_check_kdc_error(self, > kdc_exchange_dict, > callback_dict, >@@ -3397,6 +3445,10 @@ class RawKerberosTest(TestCaseInTempDir): > > return new_auth_data, old_pac > >+ def get_pac(self, auth_data, expect_pac=True): >+ _, pac = self.replace_pac(auth_data, None, expect_pac) >+ return pac >+ > def get_krbtgt_checksum_key(self): > krbtgt_creds = self.get_krbtgt_creds() > krbtgt_key = self.TicketDecryptionKey_from_creds(krbtgt_creds) >-- >2.25.1 > > >From 019e365fe5d4a69500e64359d4829ff4708beaa1 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 16:26:54 +1300 >Subject: [PATCH 093/159] tests/krb5: Check constrained delegation PAC buffer > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 0e232fa1c9e5760ae6b9a99b5e7aa5513b84aa8b) >--- > python/samba/tests/krb5/raw_testcase.py | 21 +++++++++++++++++++++ > 1 file changed, 21 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 320de0a4dbe..8144bd37b2f 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2053,6 +2053,8 @@ class RawKerberosTest(TestCaseInTempDir): > expect_edata=None, > expect_pac=True, > expect_claims=True, >+ expected_proxy_target=None, >+ expected_transited_services=None, > to_rodc=False): > if expected_error_mode == 0: > expected_error_mode = () >@@ -2100,6 +2102,8 @@ class RawKerberosTest(TestCaseInTempDir): > 'expect_edata': expect_edata, > 'expect_pac': expect_pac, > 'expect_claims': expect_claims, >+ 'expected_proxy_target': expected_proxy_target, >+ 'expected_transited_services': expected_transited_services, > 'to_rodc': to_rodc > } > if callback_dict is None: >@@ -2494,6 +2498,23 @@ class RawKerberosTest(TestCaseInTempDir): > f'expected: {expected_types} ' > f'got: {buffer_types}') > >+ for pac_buffer in pac.buffers: >+ if pac_buffer.type == krb5pac.PAC_TYPE_CONSTRAINED_DELEGATION: >+ expected_proxy_target = kdc_exchange_dict[ >+ 'expected_proxy_target'] >+ expected_transited_services = kdc_exchange_dict[ >+ 'expected_transited_services'] >+ >+ delegation_info = pac_buffer.info.info >+ >+ self.assertEqual(expected_proxy_target, >+ str(delegation_info.proxy_target)) >+ >+ transited_services = list(map( >+ str, delegation_info.transited_services)) >+ self.assertEqual(expected_transited_services, >+ transited_services) >+ > def generic_check_kdc_error(self, > kdc_exchange_dict, > callback_dict, >-- >2.25.1 > > >From eb50a9636daf468800028e88d9ce635d7fb359c2 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 16:41:23 +1300 >Subject: [PATCH 094/159] tests/krb5: Save account SPN > >This is useful for testing delegation. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit bb58b4b58c66a6ada79e886dd0c44401e1c5878c) >--- > python/samba/tests/krb5/kdc_base_test.py | 1 + > python/samba/tests/krb5/raw_testcase.py | 7 +++++++ > 2 files changed, 8 insertions(+) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index d25fc0b42b2..70ab14786da 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -285,6 +285,7 @@ class KDCBaseTest(RawKerberosTest): > else: > creds.set_workstation('') > creds.set_dn(ldb.Dn(samdb, dn)) >+ creds.set_spn(spn) > # > # Save the account name so it can be deleted in tearDownClass > self.accounts.add(dn) >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 8144bd37b2f..c34ffb848e1 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -365,6 +365,7 @@ class KerberosCredentials(Credentials): > self.forced_salt = None > > self.dn = None >+ self.spn = None > > def set_as_supported_enctypes(self, value): > self.as_supported_enctypes = int(value) >@@ -467,6 +468,12 @@ class KerberosCredentials(Credentials): > def get_dn(self): > return self.dn > >+ def set_spn(self, spn): >+ self.spn = spn >+ >+ def get_spn(self): >+ return self.spn >+ > > class KerberosTicketCreds: > def __init__(self, ticket, session_key, >-- >2.25.1 > > >From 8d9e3dda85005b1907646fd8fe672cd8cc63d881 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 16:48:50 +1300 >Subject: [PATCH 095/159] tests/krb5: Allow specifying options and expected > flags when obtaining a ticket > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 34020766bb7094d1ab5d4fc4c0ee89ccb81f39f1) >--- > python/samba/tests/krb5/kdc_base_test.py | 31 +++++++++++++++++------- > 1 file changed, 22 insertions(+), 9 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 70ab14786da..34a23b3b876 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -1164,7 +1164,7 @@ class KDCBaseTest(RawKerberosTest): > def tgs_req(self, cname, sname, realm, ticket, key, etypes, > expected_error_mode=0, padata=None, kdc_options=0, > to_rodc=False, service_creds=None, expect_pac=True, >- expect_edata=None): >+ expect_edata=None, expected_flags=None, unexpected_flags=None): > '''Send a TGS-REQ, returns the response and the decrypted and > decoded enc-part > ''' >@@ -1203,6 +1203,8 @@ class KDCBaseTest(RawKerberosTest): > expected_srealm=realm, > expected_sname=sname, > expected_error_mode=expected_error_mode, >+ expected_flags=expected_flags, >+ unexpected_flags=unexpected_flags, > check_error_fn=check_error_fn, > check_rep_fn=check_rep_fn, > check_kdc_private_fn=self.generic_check_kdc_private, >@@ -1230,10 +1232,12 @@ class KDCBaseTest(RawKerberosTest): > return rep, enc_part > > def get_service_ticket(self, tgt, target_creds, service='host', >- to_rodc=False, fresh=False): >+ to_rodc=False, kdc_options=None, >+ expected_flags=None, unexpected_flags=None, >+ fresh=False): > user_name = tgt.cname['name-string'][0] > target_name = target_creds.get_username() >- cache_key = (user_name, target_name, service, to_rodc) >+ cache_key = (user_name, target_name, service, to_rodc, kdc_options) > > if not fresh: > ticket = self.tkt_cache.get(cache_key) >@@ -1243,6 +1247,10 @@ class KDCBaseTest(RawKerberosTest): > > etype = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) > >+ if kdc_options is None: >+ kdc_options = '0' >+ kdc_options = krb5_asn1.KDCOptions(kdc_options) >+ > key = tgt.session_key > ticket = tgt.ticket > >@@ -1255,7 +1263,10 @@ class KDCBaseTest(RawKerberosTest): > > rep, enc_part = self.tgs_req(cname, sname, realm, ticket, key, etype, > to_rodc=to_rodc, >- service_creds=target_creds) >+ service_creds=target_creds, >+ kdc_options=kdc_options, >+ expected_flags=expected_flags, >+ unexpected_flags=unexpected_flags) > > service_ticket = rep['ticket'] > >@@ -1309,11 +1320,11 @@ class KDCBaseTest(RawKerberosTest): > self.TicketDecryptionKey_from_creds(krbtgt_creds)) > > if kdc_options is None: >- kdc_options = krb5_asn1.KDCOptions('forwardable,' >- 'renewable,' >- 'canonicalize,' >- 'renewable-ok') >- kdc_options = str(kdc_options) >+ kdc_options = ('forwardable,' >+ 'renewable,' >+ 'canonicalize,' >+ 'renewable-ok') >+ kdc_options = krb5_asn1.KDCOptions(kdc_options) > > pac_options = '1' # supports claims > >@@ -1370,6 +1381,8 @@ class KDCBaseTest(RawKerberosTest): > expected_srealm=expected_realm, > expected_sname=expected_sname, > expected_salt=salt, >+ expected_flags=expected_flags, >+ unexpected_flags=unexpected_flags, > expected_supported_etypes=expected_etypes, > etypes=etype, > padata=padata, >-- >2.25.1 > > >From f65355ea5afe33fe8f4c4abaa20d365898c97d79 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 16:52:01 +1300 >Subject: [PATCH 096/159] tests/krb5: Supply supported account enctypes in > tgs_req() > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 248249dc0acac89d1495c3572cbd2cbe8bdca362) >--- > python/samba/tests/krb5/kdc_base_test.py | 3 +++ > 1 file changed, 3 insertions(+) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 34a23b3b876..93951586cc7 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -1181,8 +1181,10 @@ class KDCBaseTest(RawKerberosTest): > if service_creds is not None: > decryption_key = self.TicketDecryptionKey_from_creds( > service_creds) >+ expected_supported_etypes = service_creds.tgs_supported_enctypes > else: > decryption_key = None >+ expected_supported_etypes = None > > if not expected_error_mode: > check_error_fn = None >@@ -1205,6 +1207,7 @@ class KDCBaseTest(RawKerberosTest): > expected_error_mode=expected_error_mode, > expected_flags=expected_flags, > unexpected_flags=unexpected_flags, >+ expected_supported_etypes=expected_supported_etypes, > check_error_fn=check_error_fn, > check_rep_fn=check_rep_fn, > check_kdc_private_fn=self.generic_check_kdc_private, >-- >2.25.1 > > >From 14d6e9c192db81e3b3878517b7e17f67f7ed5cf9 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 30 Sep 2021 16:53:35 +1300 >Subject: [PATCH 097/159] tests/krb5: Add parameter to enforce presence of > ticket checksums > >This allows existing tests to pass before this functionality is >implemented. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit ef24fe982d750a42be81808379b0254d8488c559) >--- > python/samba/tests/krb5/raw_testcase.py | 20 +++++++++++++++++--- > 1 file changed, 17 insertions(+), 3 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index c34ffb848e1..72a39b23b0e 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1942,6 +1942,7 @@ class RawKerberosTest(TestCaseInTempDir): > expected_flags=None, > unexpected_flags=None, > ticket_decryption_key=None, >+ expect_ticket_checksum=None, > generate_fast_fn=None, > generate_fast_armor_fn=None, > generate_fast_padata_fn=None, >@@ -1990,6 +1991,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'expected_flags': expected_flags, > 'unexpected_flags': unexpected_flags, > 'ticket_decryption_key': ticket_decryption_key, >+ 'expect_ticket_checksum': expect_ticket_checksum, > 'generate_fast_fn': generate_fast_fn, > 'generate_fast_armor_fn': generate_fast_armor_fn, > 'generate_fast_padata_fn': generate_fast_padata_fn, >@@ -2034,6 +2036,7 @@ class RawKerberosTest(TestCaseInTempDir): > expected_flags=None, > unexpected_flags=None, > ticket_decryption_key=None, >+ expect_ticket_checksum=None, > generate_fast_fn=None, > generate_fast_armor_fn=None, > generate_fast_padata_fn=None, >@@ -2083,6 +2086,7 @@ class RawKerberosTest(TestCaseInTempDir): > 'expected_flags': expected_flags, > 'unexpected_flags': unexpected_flags, > 'ticket_decryption_key': ticket_decryption_key, >+ 'expect_ticket_checksum': expect_ticket_checksum, > 'generate_fast_fn': generate_fast_fn, > 'generate_fast_armor_fn': generate_fast_armor_fn, > 'generate_fast_padata_fn': generate_fast_padata_fn, >@@ -2459,8 +2463,15 @@ class RawKerberosTest(TestCaseInTempDir): > ticket_private=ticket_private, > encpart_private=encpart_private) > >+ # TODO: This parameter should be removed when all service tickets are >+ # issued with ticket checksums. >+ expect_ticket_checksum = kdc_exchange_dict['expect_ticket_checksum'] >+ if expect_ticket_checksum: >+ self.assertIsNotNone(ticket_decryption_key) >+ > if ticket_decryption_key is not None: >- self.verify_ticket(ticket_creds, krbtgt_key, expect_pac=expect_pac) >+ self.verify_ticket(ticket_creds, krbtgt_key, expect_pac=expect_pac, >+ expect_ticket_checksum=expect_ticket_checksum) > > kdc_exchange_dict['rep_ticket_creds'] = ticket_creds > >@@ -3083,7 +3094,8 @@ class RawKerberosTest(TestCaseInTempDir): > ticket_blob) > self.assertEqual(expected_checksum, checksum) > >- def verify_ticket(self, ticket, krbtgt_key, expect_pac=True): >+ def verify_ticket(self, ticket, krbtgt_key, expect_pac=True, >+ expect_ticket_checksum=True): > # Check if the ticket is a TGT. > sname = ticket.ticket['sname'] > is_tgt = self.is_tgs(sname) >@@ -3182,8 +3194,10 @@ class RawKerberosTest(TestCaseInTempDir): > ticket_checksum, ticket_ctype = checksums.get( > krb5pac.PAC_TYPE_TICKET_CHECKSUM, > (None, None)) >- if self.strict_checking: >+ if expect_ticket_checksum: > self.assertIsNotNone(ticket_checksum) >+ elif expect_ticket_checksum is False: >+ self.assertIsNone(ticket_checksum) > if ticket_checksum is not None: > enc_part['authorization-data'] = auth_data > enc_part = self.der_encode(enc_part, >-- >2.25.1 > > >From 9a12c7506a5a1786221ecd3689df2238e27bd9b1 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 14 Oct 2021 16:43:05 +1300 >Subject: [PATCH 098/159] tests/krb5: Add compatability tests for ticket > checksums > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >[abartlet@samba.org: Backported from ec4b264bdf9ab64a728212580b344fbf35c3c673 > to Samba 4.14 due to conflicts in > knownfail as the test which crashes older MIT KDC versions is > omitted] >--- > .../samba/tests/krb5/compatability_tests.py | 44 ++++++++++++++++++- > selftest/knownfail_heimdal_kdc | 6 ++- > source4/selftest/tests.py | 7 ++- > 3 files changed, 53 insertions(+), 4 deletions(-) > >diff --git a/python/samba/tests/krb5/compatability_tests.py b/python/samba/tests/krb5/compatability_tests.py >index cd67549212a..0da72796894 100755 >--- a/python/samba/tests/krb5/compatability_tests.py >+++ b/python/samba/tests/krb5/compatability_tests.py >@@ -23,7 +23,7 @@ import os > sys.path.insert(0, "bin/python") > os.environ["PYTHONUNBUFFERED"] = "1" > >-from samba.tests.krb5.raw_testcase import RawKerberosTest >+from samba.tests.krb5.kdc_base_test import KDCBaseTest > import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 > from samba.tests.krb5.rfc4120_constants import ( > AES128_CTS_HMAC_SHA1_96, >@@ -50,7 +50,7 @@ MIT_ENC_AS_REP_PART_TYPE_TAG = 0x7A > ENC_PA_REP_FLAG = 0x00010000 > > >-class SimpleKerberosTests(RawKerberosTest): >+class SimpleKerberosTests(KDCBaseTest): > > def setUp(self): > super(SimpleKerberosTests, self).setUp() >@@ -120,6 +120,46 @@ class SimpleKerberosTests(RawKerberosTest): > self.fail( > "(Heimdal) Salt populated for ARCFOUR_HMAC_MD5 encryption") > >+ def test_heimdal_ticket_signature(self): >+ # Ensure that a DC correctly issues tickets signed with its krbtgt key. >+ user_creds = self.get_client_creds() >+ target_creds = self.get_service_creds() >+ >+ krbtgt_creds = self.get_krbtgt_creds() >+ key = self.TicketDecryptionKey_from_creds(krbtgt_creds) >+ >+ # Get a TGT from the DC. >+ tgt = self.get_tgt(user_creds) >+ >+ # Ensure the PAC contains the expected checksums. >+ self.verify_ticket(tgt, key) >+ >+ # Get a service ticket from the DC. >+ service_ticket = self.get_service_ticket(tgt, target_creds) >+ >+ # Ensure the PAC contains the expected checksums. >+ self.verify_ticket(service_ticket, key, expect_ticket_checksum=True) >+ >+ def test_mit_ticket_signature(self): >+ # Ensure that a DC does not issue tickets signed with its krbtgt key. >+ user_creds = self.get_client_creds() >+ target_creds = self.get_service_creds() >+ >+ krbtgt_creds = self.get_krbtgt_creds() >+ key = self.TicketDecryptionKey_from_creds(krbtgt_creds) >+ >+ # Get a TGT from the DC. >+ tgt = self.get_tgt(user_creds) >+ >+ # Ensure the PAC contains the expected checksums. >+ self.verify_ticket(tgt, key) >+ >+ # Get a service ticket from the DC. >+ service_ticket = self.get_service_ticket(tgt, target_creds) >+ >+ # Ensure the PAC does not contain the expected checksums. >+ self.verify_ticket(service_ticket, key, expect_ticket_checksum=False) >+ > def as_pre_auth_req(self, creds, etypes): > user = creds.get_username() > realm = creds.get_realm() >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 80b8224f015..6eb667f8969 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -1,7 +1,7 @@ > # > # We expect all the MIT specific compatability tests to fail on heimdal > # kerberos >-^samba.tests.krb5.compatability_tests.samba.tests.krb5.compatability_tests.SimpleKerberosTests.test_mit_ >+^samba.tests.krb5.compatability_tests.samba.tests.krb5.compatability_tests.SimpleKerberosTests.test_mit_(?!ticket_signature) > # > # Heimdal currently fails the following MS-KILE client principal lookup > # tests >@@ -121,3 +121,7 @@ > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_outer_no_sname.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_outer_no_sname.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_no_sname.ad_dc >+# >+# Heimdal currently does not generate ticket signatures >+# >+^samba.tests.krb5.compatability_tests.samba.tests.krb5.compatability_tests.SimpleKerberosTests.test_heimdal_ticket_signature >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index c83136d6421..92e5b8f5946 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -1424,7 +1424,12 @@ planpythontestsuite("ad_dc", "samba.tests.krb5.as_canonicalization_tests", > 'ADMIN_USERNAME': '$USERNAME', > 'ADMIN_PASSWORD': '$PASSWORD' > }) >-planpythontestsuite("ad_dc", "samba.tests.krb5.compatability_tests") >+planpythontestsuite("ad_dc", "samba.tests.krb5.compatability_tests", >+ environ={ >+ 'ADMIN_USERNAME': '$USERNAME', >+ 'ADMIN_PASSWORD': '$PASSWORD', >+ 'STRICT_CHECKING': '0', >+ }) > planpythontestsuite("ad_dc", "samba.tests.krb5.kdc_tests") > planpythontestsuite( > "ad_dc", >-- >2.25.1 > > >From 769d8128d0d5e27d38cbe0ee40ec0cf7c9dacab3 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 11 Oct 2021 14:37:03 +1300 >Subject: [PATCH 099/159] tests/krb5: Use correct principal name type > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 687c8f94c68af9f1e44771dfd7219eeb41382bba) >--- > python/samba/tests/krb5/fast_tests.py | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/fast_tests.py b/python/samba/tests/krb5/fast_tests.py >index 28fe0686335..1cdfd5e20c4 100755 >--- a/python/samba/tests/krb5/fast_tests.py >+++ b/python/samba/tests/krb5/fast_tests.py >@@ -43,6 +43,7 @@ from samba.tests.krb5.rfc4120_constants import ( > KRB_AS_REP, > KRB_TGS_REP, > NT_PRINCIPAL, >+ NT_SRV_HST, > NT_SRV_INST, > PADATA_FX_COOKIE, > PADATA_FX_FAST, >@@ -1136,7 +1137,7 @@ class FAST_Tests(KDCBaseTest): > target_realm = target_creds.get_realm() > target_service = 'host' > target_sname = self.PrincipalName_create( >- name_type=NT_SRV_INST, names=[target_service, target_username]) >+ name_type=NT_SRV_HST, names=[target_service, target_username]) > target_decryption_key = self.TicketDecryptionKey_from_creds( > target_creds) > target_etypes = target_creds.tgs_supported_enctypes >-- >2.25.1 > > >From 412d8e5fa508902501ee6186ed85a39e127a4dae Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 11 Oct 2021 14:39:26 +1300 >Subject: [PATCH 100/159] tests/krb5: Clarify checksum type assertion message > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit ee2b7e2c77f021984ec583fa0c4c756979197b0f) >--- > python/samba/tests/krb5/raw_testcase.py | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 72a39b23b0e..e52eb5ae5b9 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -248,7 +248,8 @@ class Krb5EncryptionKey: > > def verify_checksum(self, usage, plaintext, ctype, cksum): > if self.ctype != ctype: >- raise AssertionError(f'{self.ctype} != {ctype}') >+ raise AssertionError(f'key checksum type ({self.ctype}) != ' >+ f'checksum type ({ctype})') > > kcrypto.verify_checksum(ctype, > self.key, >-- >2.25.1 > > >From 8705741160642842574b2bfb9448dfd5dcfb296d Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 11 Oct 2021 16:15:43 +1300 >Subject: [PATCH 101/159] tests/krb5: Fix padata checking at functional level > 2003 > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 72265227e9c2037b63cdfb01a456a86ac8932f59) >--- > python/samba/tests/krb5/raw_testcase.py | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index e52eb5ae5b9..bb9d414da5b 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2661,11 +2661,10 @@ class RawKerberosTest(TestCaseInTempDir): > if kcrypto.Enctype.RC4 in proposed_etypes: > expect_etype_info = True > for etype in proposed_etypes: >- if etype in (kcrypto.Enctype.AES256, kcrypto.Enctype.AES128): >- expect_etype_info = False > if etype not in client_as_etypes: > continue > if etype in (kcrypto.Enctype.AES256, kcrypto.Enctype.AES128): >+ expect_etype_info = False > if etype > expected_aes_type: > expected_aes_type = etype > if etype in (kcrypto.Enctype.RC4,) and error_code != 0: >@@ -2865,7 +2864,8 @@ class RawKerberosTest(TestCaseInTempDir): > else: > self.assertIsNone(etype_info2) > if expect_etype_info: >- self.assertIsNotNone(etype_info) >+ if self.strict_checking: >+ self.assertIsNotNone(etype_info) > else: > if self.strict_checking: > self.assertIsNone(etype_info) >-- >2.25.1 > > >From a3dd1a980c2fd17a333bd70c75694692bd71d771 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 12 Oct 2021 11:34:59 +1300 >Subject: [PATCH 102/159] tests/krb5: Add environment variable to specify KDC > FAST support > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >[abartlet@samba.org backportd from commit 238f52bad811688624e9fd4b1595266e2149094a > because tests.py changed in more recent releases with new tests nearby] >--- > python/samba/tests/krb5/raw_testcase.py | 6 +++- > source4/selftest/tests.py | 37 +++++++++++++++++-------- > 2 files changed, 31 insertions(+), 12 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index bb9d414da5b..fbddb7f83b1 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -568,7 +568,11 @@ class RawKerberosTest(TestCaseInTempDir): > # obtained. > cls.creds_dict = {} > >- cls.kdc_fast_support = False >+ kdc_fast_support = samba.tests.env_get_var_value('FAST_SUPPORT', >+ allow_missing=True) >+ if kdc_fast_support is None: >+ kdc_fast_support = '0' >+ cls.kdc_fast_support = bool(int(kdc_fast_support)) > > def setUp(self): > super().setUp() >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index 92e5b8f5946..c34d25d81d5 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -809,39 +809,47 @@ planoldpythontestsuite("nt4_dc", "samba.tests.netbios", extra_args=['-U"$USERNAM > planoldpythontestsuite("ad_dc:local", "samba.tests.gpo", extra_args=['-U"$USERNAME%$PASSWORD"']) > planoldpythontestsuite("ad_dc:local", "samba.tests.dckeytab", extra_args=['-U"$USERNAME%$PASSWORD"']) > >+have_fast_support = int('SAMBA_USES_MITKDC' in config_hash) > planoldpythontestsuite("none", "samba.tests.krb5.kcrypto") > planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.simple_tests", >- environ={'SERVICE_USERNAME':'$SERVER'}) >+ environ={'SERVICE_USERNAME':'$SERVER', >+ 'FAST_SUPPORT': have_fast_support}) > planoldpythontestsuite("ad_dc_default:local", "samba.tests.krb5.s4u_tests", > environ={'SERVICE_USERNAME':'srv_account', > 'SERVICE_PASSWORD':'$PASSWORD', >- 'FOR_USER':'$USERNAME'}) >+ 'FOR_USER':'$USERNAME', >+ 'FAST_SUPPORT': have_fast_support}) > >-planoldpythontestsuite("fl2008r2dc:local", "samba.tests.krb5.xrealm_tests") >+planoldpythontestsuite("fl2008r2dc:local", "samba.tests.krb5.xrealm_tests", >+ environ={'FAST_SUPPORT': have_fast_support}) > > planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.test_ccache", > environ={ > 'ADMIN_USERNAME': '$USERNAME', > 'ADMIN_PASSWORD': '$PASSWORD', >- 'STRICT_CHECKING': '0' >+ 'STRICT_CHECKING': '0', >+ 'FAST_SUPPORT': have_fast_support > }) > planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.test_ldap", > environ={ > 'ADMIN_USERNAME': '$USERNAME', > 'ADMIN_PASSWORD': '$PASSWORD', >- 'STRICT_CHECKING': '0' >+ 'STRICT_CHECKING': '0', >+ 'FAST_SUPPORT': have_fast_support > }) > planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.test_rpc", > environ={ > 'ADMIN_USERNAME': '$USERNAME', > 'ADMIN_PASSWORD': '$PASSWORD', >- 'STRICT_CHECKING': '0' >+ 'STRICT_CHECKING': '0', >+ 'FAST_SUPPORT': have_fast_support > }) > planoldpythontestsuite("ad_dc_smb1", "samba.tests.krb5.test_smb", > environ={ > 'ADMIN_USERNAME': '$USERNAME', > 'ADMIN_PASSWORD': '$PASSWORD', >- 'STRICT_CHECKING': '0' >+ 'STRICT_CHECKING': '0', >+ 'FAST_SUPPORT': have_fast_support > }) > > for env in ["ad_dc", smbv1_disabled_testenv]: >@@ -1402,6 +1410,7 @@ for env in ["fl2008r2dc", "fl2003dc"]: > 'ADMIN_USERNAME': '$USERNAME', > 'ADMIN_PASSWORD': '$PASSWORD', > 'STRICT_CHECKING': '0', >+ 'FAST_SUPPORT': have_fast_support > }) > > >@@ -1422,22 +1431,26 @@ for env in ["rodc", "promoted_dc", "fl2000dc", "fl2008r2dc"]: > planpythontestsuite("ad_dc", "samba.tests.krb5.as_canonicalization_tests", > environ={ > 'ADMIN_USERNAME': '$USERNAME', >- 'ADMIN_PASSWORD': '$PASSWORD' >+ 'ADMIN_PASSWORD': '$PASSWORD', >+ 'FAST_SUPPORT': have_fast_support > }) > planpythontestsuite("ad_dc", "samba.tests.krb5.compatability_tests", > environ={ > 'ADMIN_USERNAME': '$USERNAME', > 'ADMIN_PASSWORD': '$PASSWORD', > 'STRICT_CHECKING': '0', >+ 'FAST_SUPPORT': have_fast_support, > }) >-planpythontestsuite("ad_dc", "samba.tests.krb5.kdc_tests") >+planpythontestsuite("ad_dc", "samba.tests.krb5.kdc_tests", >+ environ={'FAST_SUPPORT': have_fast_support}) > planpythontestsuite( > "ad_dc", > "samba.tests.krb5.kdc_tgs_tests", > environ={ > 'ADMIN_USERNAME': '$USERNAME', > 'ADMIN_PASSWORD': '$PASSWORD', >- 'STRICT_CHECKING': '0' >+ 'STRICT_CHECKING': '0', >+ 'FAST_SUPPORT': have_fast_support > }) > planpythontestsuite( > "ad_dc", >@@ -1446,6 +1459,7 @@ planpythontestsuite( > 'ADMIN_USERNAME': '$USERNAME', > 'ADMIN_PASSWORD': '$PASSWORD', > 'STRICT_CHECKING': '0', >+ 'FAST_SUPPORT': have_fast_support > }) > planpythontestsuite( > "ad_dc", >@@ -1453,7 +1467,8 @@ planpythontestsuite( > environ={ > 'ADMIN_USERNAME': '$USERNAME', > 'ADMIN_PASSWORD': '$PASSWORD', >- 'STRICT_CHECKING': '0' >+ 'STRICT_CHECKING': '0', >+ 'FAST_SUPPORT': have_fast_support > }) > > for env in [ >-- >2.25.1 > > >From 8f79f3027f70b05fabf93912a5995989900ead89 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 11 Oct 2021 14:45:45 +1300 >Subject: [PATCH 103/159] tests/krb5: Check padata types when STRICT_CHECKING=0 > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >[abartlet@samba.org backported from commit bd22dcd9cc4dfda827f892224eb2da4a16564176 > to Samba 4.14 due to conflicts in > knownfail as the test which crashes older MIT KDC versions is > omitted] >--- > python/samba/tests/krb5/raw_testcase.py | 25 +++++++++++++++++++++---- > selftest/knownfail_mit_kdc | 9 +++++++++ > 2 files changed, 30 insertions(+), 4 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index fbddb7f83b1..dbcff787f70 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1079,6 +1079,20 @@ class RawKerberosTest(TestCaseInTempDir): > f"'{unexpected.namedValues[i]}' " > f"unexpected in {v}") > >+ def assertSequenceElementsEqual(self, expected, got, *, >+ require_strict=None): >+ if self.strict_checking: >+ self.assertEqual(expected, got) >+ else: >+ fail_msg = f'expected: {expected} got: {got}' >+ >+ if require_strict is not None: >+ fail_msg += f' (ignoring: {require_strict})' >+ expected = (x for x in expected if x not in require_strict) >+ got = (x for x in got if x not in require_strict) >+ >+ self.assertCountEqual(expected, got, fail_msg) >+ > def get_KerberosTimeWithUsec(self, epoch=None, offset=None): > if epoch is None: > epoch = time.time() >@@ -2714,10 +2728,13 @@ class RawKerberosTest(TestCaseInTempDir): > expected_patypes += (PADATA_FX_FAST,) > expected_patypes += (PADATA_FX_COOKIE,) > >- if self.strict_checking: >- for i, patype in enumerate(expected_patypes): >- self.assertElementEqual(rep_padata[i], 'padata-type', patype) >- self.assertEqual(len(rep_padata), len(expected_patypes)) >+ got_patypes = tuple(pa['padata-type'] for pa in rep_padata) >+ self.assertSequenceElementsEqual(expected_patypes, got_patypes, >+ require_strict={PADATA_FX_COOKIE, >+ PADATA_FX_FAST, >+ PADATA_PAC_OPTIONS, >+ PADATA_PK_AS_REP_19, >+ PADATA_PK_AS_REQ}) > > etype_info2 = None > etype_info = None >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >index f167c2bf856..4e0b20c5c80 100644 >--- a/selftest/knownfail_mit_kdc >+++ b/selftest/knownfail_mit_kdc >@@ -290,6 +290,11 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_nt_principal_step_4_b > ^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_nt_principal_step_4_c > ^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_nt_principal_step_6_c >+# >+# MIT currently fails some as_req_no_preauth tests. >+# >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth.*aes.*rc4.*fl2003dc >+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth.*rc4.*aes.*fl2003dc > # Differences in our KDC compared to windows > # > ^samba4.krb5.kdc .*.as-req-pac-request # We should reply to a request for a PAC over UDP with KRB5KRB_ERR_RESPONSE_TOO_BIG unconditionally >@@ -304,6 +309,9 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_authdata_fast_not_used.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_enc_timestamp.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_encrypted_challenge_clock_skew.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_encrypted_challenge_no_fast.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_encrypted_challenge_wrong_key.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_encrypted_challenge_wrong_key_kdc.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_invalid_tgt.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_invalid_tgt_mach.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_armor.ad_dc >@@ -318,5 +326,6 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_outer_no_sname.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_no_sname.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_no_sname.ad_dc >+^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_fast_no_etypes.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_no_sname.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_tgs_no_sname.ad_dc >-- >2.25.1 > > >From 0c1029c251f84b38df00c2deac9c4cd7f08dcb90 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 11 Oct 2021 14:48:03 +1300 >Subject: [PATCH 104/159] tests/krb5: Check logon name in PAC > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit e7c39cc44f2e16aecb01c0afc195911a474ef0b9) >--- > python/samba/tests/krb5/raw_testcase.py | 6 ++++++ > 1 file changed, 6 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index dbcff787f70..b0cd2bfdf0f 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2552,6 +2552,12 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertEqual(expected_transited_services, > transited_services) > >+ elif pac_buffer.type == krb5pac.PAC_TYPE_LOGON_NAME: >+ expected_cname = kdc_exchange_dict['expected_cname'] >+ account_name = expected_cname['name-string'][0] >+ >+ self.assertEqual(account_name, pac_buffer.info.account_name) >+ > def generic_check_kdc_error(self, > kdc_exchange_dict, > callback_dict, >-- >2.25.1 > > >From cf67ceda11f03a39ba81f60e0c7a26c30c5ea546 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 11 Oct 2021 14:49:34 +1300 >Subject: [PATCH 105/159] tests/krb5: Simplify padata checking > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit cf3ca6ac4567d7c7954ea4ecc8cc9dd5effcc094) >--- > python/samba/tests/krb5/raw_testcase.py | 169 ++++++------------------ > 1 file changed, 41 insertions(+), 128 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index b0cd2bfdf0f..b51ad499192 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2742,73 +2742,32 @@ class RawKerberosTest(TestCaseInTempDir): > PADATA_PK_AS_REP_19, > PADATA_PK_AS_REQ}) > >- etype_info2 = None >- etype_info = None >- enc_timestamp = None >- enc_challenge = None >- pk_as_req = None >- pk_as_rep19 = None >- fast_cookie = None >- fast_error = None >- fx_fast = None >- pac_options = None >- for pa in rep_padata: >- patype = self.getElementValue(pa, 'padata-type') >- pavalue = self.getElementValue(pa, 'padata-value') >- if patype == PADATA_ETYPE_INFO2: >- self.assertIsNone(etype_info2) >- etype_info2 = self.der_decode(pavalue, >- asn1Spec=krb5_asn1.ETYPE_INFO2()) >- continue >- if patype == PADATA_ETYPE_INFO: >- self.assertIsNone(etype_info) >- etype_info = self.der_decode(pavalue, >- asn1Spec=krb5_asn1.ETYPE_INFO()) >- continue >- if patype == PADATA_ENC_TIMESTAMP: >- self.assertIsNone(enc_timestamp) >- enc_timestamp = pavalue >- self.assertEqual(len(enc_timestamp), 0) >- continue >- if patype == PADATA_ENCRYPTED_CHALLENGE: >- self.assertIsNone(enc_challenge) >- enc_challenge = pavalue >- continue >- if patype == PADATA_PK_AS_REQ: >- self.assertIsNone(pk_as_req) >- pk_as_req = pavalue >- self.assertEqual(len(pk_as_req), 0) >- continue >- if patype == PADATA_PK_AS_REP_19: >- self.assertIsNone(pk_as_rep19) >- pk_as_rep19 = pavalue >- self.assertEqual(len(pk_as_rep19), 0) >- continue >- if patype == PADATA_FX_COOKIE: >- self.assertIsNone(fast_cookie) >- fast_cookie = pavalue >- self.assertIsNotNone(fast_cookie) >- continue >- if patype == PADATA_FX_ERROR: >- self.assertIsNone(fast_error) >- fast_error = pavalue >- self.assertIsNotNone(fast_error) >- continue >- if patype == PADATA_FX_FAST: >- self.assertIsNone(fx_fast) >- fx_fast = pavalue >- self.assertEqual(len(fx_fast), 0) >- continue >- if patype == PADATA_PAC_OPTIONS: >- self.assertIsNone(pac_options) >- pac_options = self.der_decode( >- pavalue, >- asn1Spec=krb5_asn1.PA_PAC_OPTIONS()) >- continue >+ if not expected_patypes: >+ return None >+ >+ pa_dict = self.get_pa_dict(rep_padata) >+ >+ enc_timestamp = pa_dict.get(PADATA_ENC_TIMESTAMP) >+ if enc_timestamp is not None: >+ self.assertEqual(len(enc_timestamp), 0) >+ >+ pk_as_req = pa_dict.get(PADATA_PK_AS_REQ) >+ if pk_as_req is not None: >+ self.assertEqual(len(pk_as_req), 0) >+ >+ pk_as_rep19 = pa_dict.get(PADATA_PK_AS_REP_19) >+ if pk_as_rep19 is not None: >+ self.assertEqual(len(pk_as_rep19), 0) > >+ fx_fast = pa_dict.get(PADATA_FX_FAST) >+ if fx_fast is not None: >+ self.assertEqual(len(fx_fast), 0) >+ >+ fast_cookie = pa_dict.get(PADATA_FX_COOKIE) > if fast_cookie is not None: > kdc_exchange_dict['fast_cookie'] = fast_cookie > >+ fast_error = pa_dict.get(PADATA_FX_ERROR) > if fast_error is not None: > fast_error = self.der_decode(fast_error, > asn1Spec=krb5_asn1.KRB_ERROR()) >@@ -2817,9 +2776,14 @@ class RawKerberosTest(TestCaseInTempDir): > fast_error, > inner=True) > >+ pac_options = pa_dict.get(PADATA_PAC_OPTIONS) > if pac_options is not None: >+ pac_options = self.der_decode( >+ pac_options, >+ asn1Spec=krb5_asn1.PA_PAC_OPTIONS()) > self.assertElementEqual(pac_options, 'options', sent_pac_options) > >+ enc_challenge = pa_dict.get(PADATA_ENCRYPTED_CHALLENGE) > if enc_challenge is not None: > if not sent_enc_challenge: > self.assertEqual(len(enc_challenge), 0) >@@ -2862,52 +2826,21 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertLess(current_time - 300, rep_time) > self.assertLess(rep_time, current_time + 300) > >- if all(etype not in client_as_etypes or etype not in proposed_etypes >- for etype in (kcrypto.Enctype.AES256, >- kcrypto.Enctype.AES128, >- kcrypto.Enctype.RC4)): >- self.assertIsNone(etype_info2) >- self.assertIsNone(etype_info) >- if rep_msg_type == KRB_AS_REP: >- if self.strict_checking: >- if sent_fast: >- self.assertIsNotNone(enc_challenge) >- self.assertIsNone(enc_timestamp) >- else: >- self.assertIsNotNone(enc_timestamp) >- self.assertIsNone(enc_challenge) >- self.assertIsNotNone(pk_as_req) >- self.assertIsNotNone(pk_as_rep19) >- else: >- self.assertIsNone(enc_timestamp) >- self.assertIsNone(enc_challenge) >- self.assertIsNone(pk_as_req) >- self.assertIsNone(pk_as_rep19) >- return None >- >- if error_code != KDC_ERR_GENERIC: >- if self.strict_checking: >- self.assertIsNotNone(etype_info2) >- else: >- self.assertIsNone(etype_info2) >- if expect_etype_info: >- if self.strict_checking: >- self.assertIsNotNone(etype_info) >- else: >- if self.strict_checking: >- self.assertIsNone(etype_info) >- if unexpect_etype_info: >- self.assertIsNone(etype_info) >- >- if error_code != KDC_ERR_GENERIC and self.strict_checking: >+ etype_info2 = pa_dict.get(PADATA_ETYPE_INFO2) >+ if etype_info2 is not None: >+ etype_info2 = self.der_decode(etype_info2, >+ asn1Spec=krb5_asn1.ETYPE_INFO2()) > self.assertGreaterEqual(len(etype_info2), 1) >- self.assertEqual(len(etype_info2), len(expect_etype_info2)) >+ if self.strict_checking: >+ self.assertEqual(len(etype_info2), len(expect_etype_info2)) > for i in range(0, len(etype_info2)): > e = self.getElementValue(etype_info2[i], 'etype') >- self.assertEqual(e, expect_etype_info2[i]) >+ if self.strict_checking: >+ self.assertEqual(e, expect_etype_info2[i]) > salt = self.getElementValue(etype_info2[i], 'salt') > if e == kcrypto.Enctype.RC4: >- self.assertIsNone(salt) >+ if self.strict_checking: >+ self.assertIsNone(salt) > else: > self.assertIsNotNone(salt) > expected_salt = kdc_exchange_dict['expected_salt'] >@@ -2916,7 +2849,11 @@ class RawKerberosTest(TestCaseInTempDir): > s2kparams = self.getElementValue(etype_info2[i], 's2kparams') > if self.strict_checking: > self.assertIsNone(s2kparams) >+ >+ etype_info = pa_dict.get(PADATA_ETYPE_INFO) > if etype_info is not None: >+ etype_info = self.der_decode(etype_info, >+ asn1Spec=krb5_asn1.ETYPE_INFO()) > self.assertEqual(len(etype_info), 1) > e = self.getElementValue(etype_info[0], 'etype') > self.assertEqual(e, kcrypto.Enctype.RC4) >@@ -2926,30 +2863,6 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertIsNotNone(salt) > self.assertEqual(len(salt), 0) > >- if error_code not in (KDC_ERR_PREAUTH_FAILED, >- KDC_ERR_GENERIC): >- if sent_fast: >- self.assertIsNotNone(enc_challenge) >- if self.strict_checking: >- self.assertIsNone(enc_timestamp) >- else: >- self.assertIsNotNone(enc_timestamp) >- if self.strict_checking: >- self.assertIsNone(enc_challenge) >- if not sent_enc_challenge: >- if self.strict_checking: >- self.assertIsNotNone(pk_as_req) >- self.assertIsNotNone(pk_as_rep19) >- else: >- self.assertIsNone(pk_as_req) >- self.assertIsNone(pk_as_rep19) >- else: >- if self.strict_checking: >- self.assertIsNone(enc_timestamp) >- self.assertIsNone(enc_challenge) >- self.assertIsNone(pk_as_req) >- self.assertIsNone(pk_as_rep19) >- > return etype_info2 > > def generate_simple_fast(self, >-- >2.25.1 > > >From aad8ebb75d50afcffb9d9f230e75f3b8a17dc348 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 8 Oct 2021 11:48:41 +1300 >Subject: [PATCH 106/159] tests/krb5: Disable debugging output for tests > >This reduces the time spent running the tests in a testenv. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit dfd613661eec4b81e162f2d86a8fa9266c2fdc03) >--- > python/samba/tests/krb5/as_canonicalization_tests.py | 4 ++-- > python/samba/tests/krb5/as_req_tests.py | 4 ++-- > python/samba/tests/krb5/compatability_tests.py | 4 ++-- > python/samba/tests/krb5/kdc_tests.py | 4 ++-- > python/samba/tests/krb5/kdc_tgs_tests.py | 4 ++-- > python/samba/tests/krb5/s4u_tests.py | 4 ++-- > python/samba/tests/krb5/simple_tests.py | 4 ++-- > python/samba/tests/krb5/test_ccache.py | 4 ++-- > python/samba/tests/krb5/test_ldap.py | 4 ++-- > python/samba/tests/krb5/test_rpc.py | 4 ++-- > python/samba/tests/krb5/test_smb.py | 4 ++-- > python/samba/tests/krb5/xrealm_tests.py | 4 ++-- > 12 files changed, 24 insertions(+), 24 deletions(-) > >diff --git a/python/samba/tests/krb5/as_canonicalization_tests.py b/python/samba/tests/krb5/as_canonicalization_tests.py >index 29d8cf418f5..9538d0ae3cf 100755 >--- a/python/samba/tests/krb5/as_canonicalization_tests.py >+++ b/python/samba/tests/krb5/as_canonicalization_tests.py >@@ -427,8 +427,8 @@ class KerberosASCanonicalizationTests(KDCBaseTest): > > > if __name__ == "__main__": >- global_asn1_print = True >- global_hexdump = True >+ global_asn1_print = False >+ global_hexdump = False > import unittest > > unittest.main() >diff --git a/python/samba/tests/krb5/as_req_tests.py b/python/samba/tests/krb5/as_req_tests.py >index 8d9b90fee69..7d7baaebf24 100755 >--- a/python/samba/tests/krb5/as_req_tests.py >+++ b/python/samba/tests/krb5/as_req_tests.py >@@ -198,8 +198,8 @@ class AsReqKerberosTests(KDCBaseTest): > self.assertIsNotNone(as_rep) > > if __name__ == "__main__": >- global_asn1_print = True >- global_hexdump = True >+ global_asn1_print = False >+ global_hexdump = False > import unittest > unittest.main() > >diff --git a/python/samba/tests/krb5/compatability_tests.py b/python/samba/tests/krb5/compatability_tests.py >index 0da72796894..ed2dc565b6d 100755 >--- a/python/samba/tests/krb5/compatability_tests.py >+++ b/python/samba/tests/krb5/compatability_tests.py >@@ -261,7 +261,7 @@ class SimpleKerberosTests(KDCBaseTest): > > > if __name__ == "__main__": >- global_asn1_print = True >- global_hexdump = True >+ global_asn1_print = False >+ global_hexdump = False > import unittest > unittest.main() >diff --git a/python/samba/tests/krb5/kdc_tests.py b/python/samba/tests/krb5/kdc_tests.py >index 928f3c25c0f..b7c8566a1ec 100755 >--- a/python/samba/tests/krb5/kdc_tests.py >+++ b/python/samba/tests/krb5/kdc_tests.py >@@ -222,7 +222,7 @@ class KdcTests(RawKerberosTest): > > > if __name__ == "__main__": >- global_asn1_print = True >- global_hexdump = True >+ global_asn1_print = False >+ global_hexdump = False > import unittest > unittest.main() >diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py >index 2b55ba8a376..3075cc6b0a9 100755 >--- a/python/samba/tests/krb5/kdc_tgs_tests.py >+++ b/python/samba/tests/krb5/kdc_tgs_tests.py >@@ -211,7 +211,7 @@ class KdcTgsTests(KDCBaseTest): > > > if __name__ == "__main__": >- global_asn1_print = True >- global_hexdump = True >+ global_asn1_print = False >+ global_hexdump = False > import unittest > unittest.main() >diff --git a/python/samba/tests/krb5/s4u_tests.py b/python/samba/tests/krb5/s4u_tests.py >index 57575f0595d..bbddef4d6e0 100755 >--- a/python/samba/tests/krb5/s4u_tests.py >+++ b/python/samba/tests/krb5/s4u_tests.py >@@ -197,7 +197,7 @@ class S4UKerberosTests(RawKerberosTest): > > > if __name__ == "__main__": >- global_asn1_print = True >- global_hexdump = True >+ global_asn1_print = False >+ global_hexdump = False > import unittest > unittest.main() >diff --git a/python/samba/tests/krb5/simple_tests.py b/python/samba/tests/krb5/simple_tests.py >index 795d753b4f7..3cd3b17bb31 100755 >--- a/python/samba/tests/krb5/simple_tests.py >+++ b/python/samba/tests/krb5/simple_tests.py >@@ -179,7 +179,7 @@ class SimpleKerberosTests(RawKerberosTest): > > > if __name__ == "__main__": >- global_asn1_print = True >- global_hexdump = True >+ global_asn1_print = False >+ global_hexdump = False > import unittest > unittest.main() >diff --git a/python/samba/tests/krb5/test_ccache.py b/python/samba/tests/krb5/test_ccache.py >index feb7a7bd9be..c44ea02d504 100755 >--- a/python/samba/tests/krb5/test_ccache.py >+++ b/python/samba/tests/krb5/test_ccache.py >@@ -129,7 +129,7 @@ class CcacheTests(KDCBaseTest): > > > if __name__ == "__main__": >- global_asn1_print = True >- global_hexdump = True >+ global_asn1_print = False >+ global_hexdump = False > import unittest > unittest.main() >diff --git a/python/samba/tests/krb5/test_ldap.py b/python/samba/tests/krb5/test_ldap.py >index d304fb9d71e..95b2d24221a 100755 >--- a/python/samba/tests/krb5/test_ldap.py >+++ b/python/samba/tests/krb5/test_ldap.py >@@ -90,7 +90,7 @@ class LdapTests(KDCBaseTest): > > > if __name__ == "__main__": >- global_asn1_print = True >- global_hexdump = True >+ global_asn1_print = False >+ global_hexdump = False > import unittest > unittest.main() >diff --git a/python/samba/tests/krb5/test_rpc.py b/python/samba/tests/krb5/test_rpc.py >index 324b57f2847..40ac6df7a35 100755 >--- a/python/samba/tests/krb5/test_rpc.py >+++ b/python/samba/tests/krb5/test_rpc.py >@@ -73,7 +73,7 @@ class RpcTests(KDCBaseTest): > > > if __name__ == "__main__": >- global_asn1_print = True >- global_hexdump = True >+ global_asn1_print = False >+ global_hexdump = False > import unittest > unittest.main() >diff --git a/python/samba/tests/krb5/test_smb.py b/python/samba/tests/krb5/test_smb.py >index 45d4fe5e0c1..eebc9a9d4fe 100755 >--- a/python/samba/tests/krb5/test_smb.py >+++ b/python/samba/tests/krb5/test_smb.py >@@ -104,7 +104,7 @@ class SmbTests(KDCBaseTest): > > > if __name__ == "__main__": >- global_asn1_print = True >- global_hexdump = True >+ global_asn1_print = False >+ global_hexdump = False > import unittest > unittest.main() >diff --git a/python/samba/tests/krb5/xrealm_tests.py b/python/samba/tests/krb5/xrealm_tests.py >index 073cb755b46..73a6b3cf52d 100755 >--- a/python/samba/tests/krb5/xrealm_tests.py >+++ b/python/samba/tests/krb5/xrealm_tests.py >@@ -181,7 +181,7 @@ class XrealmKerberosTests(RawKerberosTest): > > > if __name__ == "__main__": >- global_asn1_print = True >- global_hexdump = True >+ global_asn1_print = False >+ global_hexdump = False > import unittest > unittest.main() >-- >2.25.1 > > >From abd72ee3e8722120932b83787c739ccb6a453756 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 5 Oct 2021 19:47:22 +1300 >Subject: [PATCH 107/159] tests/krb5: Provide clearer assertion messages for > test failures > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 5233f002000f196875af488b4f4d1df26fca90de) >--- > python/samba/tests/krb5/raw_testcase.py | 7 ++++++- > 1 file changed, 6 insertions(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index b51ad499192..188a54451d3 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -1942,7 +1942,12 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertIsNone(check_error_fn) > self.assertEqual(0, len(expected_error_mode)) > self.assertIsNotNone(expected_msg_type) >- self.assertEqual(msg_type, expected_msg_type) >+ if msg_type == KRB_ERROR: >+ error_code = self.getElementValue(rep, 'error-code') >+ fail_msg = f'Got unexpected error: {error_code}' >+ else: >+ fail_msg = f'Expected to fail with error: {expected_error_mode}' >+ self.assertEqual(msg_type, expected_msg_type, fail_msg) > > if msg_type == KRB_ERROR: > return check_error_fn(kdc_exchange_dict, >-- >2.25.1 > > >From 1b7e89b8bd2f529502fafe808906aa3f0a9d49de Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 5 Oct 2021 16:32:01 +1300 >Subject: [PATCH 108/159] tests/krb5: Fix sha1 checksum type > >Previously, sha1 signatures were being designated as rsa-md5-des3 >signatures. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit ebe729786806c69e95b26ffc410e887e203accb8) >--- > python/samba/tests/krb5/kcrypto.py | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/kcrypto.py b/python/samba/tests/krb5/kcrypto.py >index 4a4a12a66d4..4bf38d3c36b 100755 >--- a/python/samba/tests/krb5/kcrypto.py >+++ b/python/samba/tests/krb5/kcrypto.py >@@ -81,8 +81,8 @@ class Cksumtype(object): > MD4_DES = 3 > MD5 = 7 > MD5_DES = 8 >- SHA1 = 9 > SHA1_DES3 = 12 >+ SHA1 = 14 > SHA1_AES128 = 15 > SHA1_AES256 = 16 > HMAC_MD5 = -138 >-- >2.25.1 > > >From f0da7ee3311f5733f5fd8917e1be1fd0b4a09098 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 13 Oct 2021 12:26:22 +1300 >Subject: [PATCH 109/159] selftest/dbcheck: Fix up RODC one-way links > >Test accounts were replicated to the RODC and then deleted, causing >state links to remain in the database. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 40e5db4aabcd32834ee524857b77d36921f6bdfe) >--- > testprogs/blackbox/dbcheck.sh | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/testprogs/blackbox/dbcheck.sh b/testprogs/blackbox/dbcheck.sh >index caf89ca402b..e2ba987e2de 100755 >--- a/testprogs/blackbox/dbcheck.sh >+++ b/testprogs/blackbox/dbcheck.sh >@@ -19,7 +19,7 @@ dbcheck() { > > # This list of attributes can be freely extended > dbcheck_fix_one_way_links() { >- $PYTHON $BINDIR/samba-tool dbcheck --quiet --fix --yes fix_all_old_dn_string_component_mismatch --attrs="lastKnownParent defaultObjectCategory fromServer rIDSetReferences" --cross-ncs $ARGS >+ $PYTHON $BINDIR/samba-tool dbcheck --quiet --fix --yes fix_all_old_dn_string_component_mismatch --attrs="lastKnownParent defaultObjectCategory fromServer rIDSetReferences msDS-RevealOnDemandGroup msDS-NeverRevealGroup" --cross-ncs $ARGS > } > > # This list of attributes can be freely extended >-- >2.25.1 > > >From cb9464dc9c9b33f0646d86cdaeca1d41f2a94a8e Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 14 Oct 2021 16:58:15 +1300 >Subject: [PATCH 110/159] tests/krb5: Add TKT_SIG_SUPPORT environment variable > >This lets us indicate that service tickets should be issued with ticket >checksums in the PAC. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >[abartlet@samba.org backported from commit ae2c57fb0332f94ac44d0886c5edbed707ef52fe > due to changes in other tests nearby in tests.py] >--- > python/samba/tests/krb5/raw_testcase.py | 6 ++++ > source4/selftest/tests.py | 41 +++++++++++++++++-------- > 2 files changed, 34 insertions(+), 13 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 188a54451d3..1f7c51c07a5 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -574,6 +574,12 @@ class RawKerberosTest(TestCaseInTempDir): > kdc_fast_support = '0' > cls.kdc_fast_support = bool(int(kdc_fast_support)) > >+ tkt_sig_support = samba.tests.env_get_var_value('TKT_SIG_SUPPORT', >+ allow_missing=True) >+ if tkt_sig_support is None: >+ tkt_sig_support = '0' >+ cls.tkt_sig_support = bool(int(tkt_sig_support)) >+ > def setUp(self): > super().setUp() > self.do_asn1_print = False >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index c34d25d81d5..f7b34baba8a 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -810,46 +810,54 @@ planoldpythontestsuite("ad_dc:local", "samba.tests.gpo", extra_args=['-U"$USERNA > planoldpythontestsuite("ad_dc:local", "samba.tests.dckeytab", extra_args=['-U"$USERNAME%$PASSWORD"']) > > have_fast_support = int('SAMBA_USES_MITKDC' in config_hash) >+tkt_sig_support = 0 > planoldpythontestsuite("none", "samba.tests.krb5.kcrypto") > planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.simple_tests", > environ={'SERVICE_USERNAME':'$SERVER', >- 'FAST_SUPPORT': have_fast_support}) >+ 'FAST_SUPPORT': have_fast_support, >+ 'TKT_SIG_SUPPORT': tkt_sig_support}) > planoldpythontestsuite("ad_dc_default:local", "samba.tests.krb5.s4u_tests", > environ={'SERVICE_USERNAME':'srv_account', > 'SERVICE_PASSWORD':'$PASSWORD', > 'FOR_USER':'$USERNAME', >- 'FAST_SUPPORT': have_fast_support}) >+ 'FAST_SUPPORT': have_fast_support, >+ 'TKT_SIG_SUPPORT': tkt_sig_support}) > > planoldpythontestsuite("fl2008r2dc:local", "samba.tests.krb5.xrealm_tests", >- environ={'FAST_SUPPORT': have_fast_support}) >+ environ={'FAST_SUPPORT': have_fast_support, >+ 'TKT_SIG_SUPPORT': tkt_sig_support}) > > planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.test_ccache", > environ={ > 'ADMIN_USERNAME': '$USERNAME', > 'ADMIN_PASSWORD': '$PASSWORD', > 'STRICT_CHECKING': '0', >- 'FAST_SUPPORT': have_fast_support >+ 'FAST_SUPPORT': have_fast_support, >+ 'TKT_SIG_SUPPORT': tkt_sig_support > }) > planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.test_ldap", > environ={ > 'ADMIN_USERNAME': '$USERNAME', > 'ADMIN_PASSWORD': '$PASSWORD', > 'STRICT_CHECKING': '0', >- 'FAST_SUPPORT': have_fast_support >+ 'FAST_SUPPORT': have_fast_support, >+ 'TKT_SIG_SUPPORT': tkt_sig_support > }) > planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.test_rpc", > environ={ > 'ADMIN_USERNAME': '$USERNAME', > 'ADMIN_PASSWORD': '$PASSWORD', > 'STRICT_CHECKING': '0', >- 'FAST_SUPPORT': have_fast_support >+ 'FAST_SUPPORT': have_fast_support, >+ 'TKT_SIG_SUPPORT': tkt_sig_support > }) > planoldpythontestsuite("ad_dc_smb1", "samba.tests.krb5.test_smb", > environ={ > 'ADMIN_USERNAME': '$USERNAME', > 'ADMIN_PASSWORD': '$PASSWORD', > 'STRICT_CHECKING': '0', >- 'FAST_SUPPORT': have_fast_support >+ 'FAST_SUPPORT': have_fast_support, >+ 'TKT_SIG_SUPPORT': tkt_sig_support > }) > > for env in ["ad_dc", smbv1_disabled_testenv]: >@@ -1410,7 +1418,8 @@ for env in ["fl2008r2dc", "fl2003dc"]: > 'ADMIN_USERNAME': '$USERNAME', > 'ADMIN_PASSWORD': '$PASSWORD', > 'STRICT_CHECKING': '0', >- 'FAST_SUPPORT': have_fast_support >+ 'FAST_SUPPORT': have_fast_support, >+ 'TKT_SIG_SUPPORT': tkt_sig_support > }) > > >@@ -1432,7 +1441,8 @@ planpythontestsuite("ad_dc", "samba.tests.krb5.as_canonicalization_tests", > environ={ > 'ADMIN_USERNAME': '$USERNAME', > 'ADMIN_PASSWORD': '$PASSWORD', >- 'FAST_SUPPORT': have_fast_support >+ 'FAST_SUPPORT': have_fast_support, >+ 'TKT_SIG_SUPPORT': tkt_sig_support > }) > planpythontestsuite("ad_dc", "samba.tests.krb5.compatability_tests", > environ={ >@@ -1440,9 +1450,11 @@ planpythontestsuite("ad_dc", "samba.tests.krb5.compatability_tests", > 'ADMIN_PASSWORD': '$PASSWORD', > 'STRICT_CHECKING': '0', > 'FAST_SUPPORT': have_fast_support, >+ 'TKT_SIG_SUPPORT': tkt_sig_support > }) > planpythontestsuite("ad_dc", "samba.tests.krb5.kdc_tests", >- environ={'FAST_SUPPORT': have_fast_support}) >+ environ={'FAST_SUPPORT': have_fast_support, >+ 'TKT_SIG_SUPPORT': tkt_sig_support}) > planpythontestsuite( > "ad_dc", > "samba.tests.krb5.kdc_tgs_tests", >@@ -1450,7 +1462,8 @@ planpythontestsuite( > 'ADMIN_USERNAME': '$USERNAME', > 'ADMIN_PASSWORD': '$PASSWORD', > 'STRICT_CHECKING': '0', >- 'FAST_SUPPORT': have_fast_support >+ 'FAST_SUPPORT': have_fast_support, >+ 'TKT_SIG_SUPPORT': tkt_sig_support > }) > planpythontestsuite( > "ad_dc", >@@ -1459,7 +1472,8 @@ planpythontestsuite( > 'ADMIN_USERNAME': '$USERNAME', > 'ADMIN_PASSWORD': '$PASSWORD', > 'STRICT_CHECKING': '0', >- 'FAST_SUPPORT': have_fast_support >+ 'FAST_SUPPORT': have_fast_support, >+ 'TKT_SIG_SUPPORT': tkt_sig_support > }) > planpythontestsuite( > "ad_dc", >@@ -1468,7 +1482,8 @@ planpythontestsuite( > 'ADMIN_USERNAME': '$USERNAME', > 'ADMIN_PASSWORD': '$PASSWORD', > 'STRICT_CHECKING': '0', >- 'FAST_SUPPORT': have_fast_support >+ 'FAST_SUPPORT': have_fast_support, >+ 'TKT_SIG_SUPPORT': tkt_sig_support > }) > > for env in [ >-- >2.25.1 > > >From a5d6475107c0e9a6cff5ca87bd822d820a35417b Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Tue, 5 Oct 2021 15:39:11 +1300 >Subject: [PATCH 111/159] tests/krb5: Require ticket checksums if decryption > key is available > >We perform this check conditionally, because MIT doesn't currently add >ticket checksums. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit bf63221722903665e7b20991021fb5cdf4e4327e) >--- > python/samba/tests/krb5/raw_testcase.py | 5 ++--- > 1 file changed, 2 insertions(+), 3 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 1f7c51c07a5..2e289c90ce7 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2493,15 +2493,14 @@ class RawKerberosTest(TestCaseInTempDir): > ticket_private=ticket_private, > encpart_private=encpart_private) > >- # TODO: This parameter should be removed when all service tickets are >- # issued with ticket checksums. > expect_ticket_checksum = kdc_exchange_dict['expect_ticket_checksum'] > if expect_ticket_checksum: > self.assertIsNotNone(ticket_decryption_key) > > if ticket_decryption_key is not None: > self.verify_ticket(ticket_creds, krbtgt_key, expect_pac=expect_pac, >- expect_ticket_checksum=expect_ticket_checksum) >+ expect_ticket_checksum=expect_ticket_checksum >+ or self.tkt_sig_support) > > kdc_exchange_dict['rep_ticket_creds'] = ticket_creds > >-- >2.25.1 > > >From ac073b7891d5e8cc9735a9391c61245f8c4d676e Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 6 Oct 2021 16:35:47 +1300 >Subject: [PATCH 112/159] tests/krb5: Verify tickets obtained with > get_service_ticket() > >We only require the ticket checksum with Heimdal, because MIT currently >doesn't add it. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit d86eee2fd0fb72e52d878ceba0c476ca58abe6cf) >--- > python/samba/tests/krb5/kdc_base_test.py | 8 ++++++++ > 1 file changed, 8 insertions(+) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 93951586cc7..8a5e12bbed4 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -1287,6 +1287,14 @@ class KDCBaseTest(RawKerberosTest): > sname=sname, > decryption_key=target_key) > >+ if to_rodc: >+ krbtgt_creds = self.get_rodc_krbtgt_creds() >+ else: >+ krbtgt_creds = self.get_krbtgt_creds() >+ krbtgt_key = self.TicketDecryptionKey_from_creds(krbtgt_creds) >+ self.verify_ticket(service_ticket_creds, krbtgt_key, >+ expect_ticket_checksum=self.tkt_sig_support) >+ > self.tkt_cache[cache_key] = service_ticket_creds > > return service_ticket_creds >-- >2.25.1 > > >From b9eb9ece461a010e5f8d1fdc807223eda920a13b Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Thu, 30 Sep 2021 15:03:04 +1300 >Subject: [PATCH 113/159] tests/krb5: Add constrained delegation tests > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 56ccdba54e0c7cf3409d8430ea1012e5d3d9b092) >--- > python/samba/tests/krb5/rfc4120_constants.py | 5 + > python/samba/tests/krb5/rodc_tests.py | 73 ++ > python/samba/tests/krb5/s4u_tests.py | 958 ++++++++++++++++++- > python/samba/tests/usage.py | 1 + > selftest/knownfail_heimdal_kdc | 29 + > source4/selftest/tests.py | 11 +- > 6 files changed, 1070 insertions(+), 7 deletions(-) > create mode 100755 python/samba/tests/krb5/rodc_tests.py > >diff --git a/python/samba/tests/krb5/rfc4120_constants.py b/python/samba/tests/krb5/rfc4120_constants.py >index 76f2b75d94e..39bb2db8e32 100644 >--- a/python/samba/tests/krb5/rfc4120_constants.py >+++ b/python/samba/tests/krb5/rfc4120_constants.py >@@ -69,12 +69,17 @@ PADATA_SUPPORTED_ETYPES = int( > KDC_ERR_C_PRINCIPAL_UNKNOWN = 6 > KDC_ERR_S_PRINCIPAL_UNKNOWN = 7 > KDC_ERR_POLICY = 12 >+KDC_ERR_BADOPTION = 13 > KDC_ERR_ETYPE_NOSUPP = 14 >+KDC_ERR_SUMTYPE_NOSUPP = 15 > KDC_ERR_PREAUTH_FAILED = 24 > KDC_ERR_PREAUTH_REQUIRED = 25 >+KDC_ERR_BAD_INTEGRITY = 31 > KDC_ERR_NOT_US = 35 > KDC_ERR_BADMATCH = 36 > KDC_ERR_SKEW = 37 >+KDC_ERR_MODIFIED = 41 >+KDC_ERR_INAPP_CKSUM = 50 > KDC_ERR_GENERIC = 60 > KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTIONS = 93 > >diff --git a/python/samba/tests/krb5/rodc_tests.py b/python/samba/tests/krb5/rodc_tests.py >new file mode 100755 >index 00000000000..4579f9eb552 >--- /dev/null >+++ b/python/samba/tests/krb5/rodc_tests.py >@@ -0,0 +1,73 @@ >+#!/usr/bin/env python3 >+# Unix SMB/CIFS implementation. >+# Copyright (C) Stefan Metzmacher 2020 >+# >+# 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 >+ >+from samba.tests.krb5.kdc_base_test import KDCBaseTest >+ >+sys.path.insert(0, "bin/python") >+os.environ["PYTHONUNBUFFERED"] = "1" >+ >+global_asn1_print = False >+global_hexdump = False >+ >+ >+class RodcKerberosTests(KDCBaseTest): >+ >+ def setUp(self): >+ super().setUp() >+ self.do_asn1_print = global_asn1_print >+ self.do_hexdump = global_hexdump >+ >+ # Ensure that an RODC correctly issues tickets signed with its krbtgt key >+ # and including the RODCIdentifier. >+ def test_rodc_ticket_signature(self): >+ user_creds = self.get_cached_creds( >+ machine_account=False, >+ opts={ >+ 'revealed_to_rodc': True >+ }) >+ target_creds = self.get_cached_creds( >+ machine_account=True, >+ opts={ >+ 'revealed_to_rodc': True >+ }) >+ >+ krbtgt_creds = self.get_rodc_krbtgt_creds() >+ rodc_key = self.TicketDecryptionKey_from_creds(krbtgt_creds) >+ >+ # Get a TGT from the RODC. >+ tgt = self.get_tgt(user_creds, to_rodc=True) >+ >+ # Ensure the PAC contains the expected checksums. >+ self.verify_ticket(tgt, rodc_key) >+ >+ # Get a service ticket from the RODC. >+ service_ticket = self.get_service_ticket(tgt, target_creds, >+ to_rodc=True) >+ >+ # Ensure the PAC contains the expected checksums. >+ self.verify_ticket(service_ticket, rodc_key) >+ >+ >+if __name__ == "__main__": >+ global_asn1_print = False >+ global_hexdump = False >+ import unittest >+ unittest.main() >diff --git a/python/samba/tests/krb5/s4u_tests.py b/python/samba/tests/krb5/s4u_tests.py >index bbddef4d6e0..9a25256081a 100755 >--- a/python/samba/tests/krb5/s4u_tests.py >+++ b/python/samba/tests/krb5/s4u_tests.py >@@ -18,17 +18,34 @@ > > import sys > import os >+import functools > > sys.path.insert(0, "bin/python") > os.environ["PYTHONUNBUFFERED"] = "1" > >+from samba import ntstatus >+from samba.dcerpc import krb5pac, lsa >+ > from samba.tests import env_get_var_value >-from samba.tests.krb5.kcrypto import Cksumtype >-from samba.tests.krb5.raw_testcase import RawKerberosTest >+from samba.tests.krb5.kcrypto import Cksumtype, Enctype >+from samba.tests.krb5.kdc_base_test import KDCBaseTest >+from samba.tests.krb5.raw_testcase import ( >+ RodcPacEncryptionKey, >+ ZeroedChecksumKey >+) > from samba.tests.krb5.rfc4120_constants import ( >+ AES256_CTS_HMAC_SHA1_96, >+ ARCFOUR_HMAC_MD5, >+ KDC_ERR_BADOPTION, >+ KDC_ERR_BAD_INTEGRITY, >+ KDC_ERR_GENERIC, >+ KDC_ERR_INAPP_CKSUM, >+ KDC_ERR_MODIFIED, >+ KDC_ERR_SUMTYPE_NOSUPP, > KU_PA_ENC_TIMESTAMP, > KU_AS_REP_ENC_PART, > KU_TGS_REP_ENC_PART_SUB_KEY, >+ NT_PRINCIPAL > ) > import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 > >@@ -36,7 +53,7 @@ global_asn1_print = False > global_hexdump = False > > >-class S4UKerberosTests(RawKerberosTest): >+class S4UKerberosTests(KDCBaseTest): > > def setUp(self): > super(S4UKerberosTests, self).setUp() >@@ -119,8 +136,14 @@ class S4UKerberosTests(RawKerberosTest): > self.assertEqual(msg_type, 11) > > enc_part2 = key.decrypt(KU_AS_REP_ENC_PART, rep['enc-part']['cipher']) >- enc_part2 = self.der_decode( >- enc_part2, asn1Spec=krb5_asn1.EncASRepPart()) >+ # MIT KDC encodes both EncASRepPart and EncTGSRepPart with >+ # application tag 26 >+ try: >+ enc_part2 = self.der_decode( >+ enc_part2, asn1Spec=krb5_asn1.EncASRepPart()) >+ except Exception: >+ enc_part2 = self.der_decode( >+ enc_part2, asn1Spec=krb5_asn1.EncTGSRepPart()) > > # S4U2Self Request > sname = cname >@@ -195,6 +218,931 @@ class S4UKerberosTests(RawKerberosTest): > msg_type = self._test_s4u2self(pa_s4u2self_ctype=Cksumtype.CRC32) > self.assertEqual(msg_type, 30) > >+ def _run_s4u2self_test(self, kdc_dict): >+ client_opts = kdc_dict.pop('client_opts', None) >+ client_creds = self.get_cached_creds(machine_account=False, >+ opts=client_opts) >+ >+ service_opts = kdc_dict.pop('service_opts', None) >+ service_creds = self.get_cached_creds(machine_account=True, >+ opts=service_opts) >+ >+ service_tgt = self.get_tgt(service_creds) >+ modify_service_tgt_fn = kdc_dict.pop('modify_service_tgt_fn', None) >+ if modify_service_tgt_fn is not None: >+ service_tgt = modify_service_tgt_fn(service_tgt) >+ >+ client_name = client_creds.get_username() >+ client_cname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >+ names=[client_name]) >+ >+ service_name = service_creds.get_username()[:-1] >+ service_sname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >+ names=['host', service_name]) >+ >+ realm = client_creds.get_realm() >+ >+ expected_flags = kdc_dict.pop('expected_flags', None) >+ if expected_flags is not None: >+ expected_flags = krb5_asn1.TicketFlags(expected_flags) >+ >+ unexpected_flags = kdc_dict.pop('unexpected_flags', None) >+ if unexpected_flags is not None: >+ unexpected_flags = krb5_asn1.TicketFlags(unexpected_flags) >+ >+ kdc_options = kdc_dict.pop('kdc_options', '0') >+ kdc_options = krb5_asn1.KDCOptions(kdc_options) >+ >+ service_decryption_key = self.TicketDecryptionKey_from_creds( >+ service_creds) >+ >+ authenticator_subkey = self.RandomKey(Enctype.AES256) >+ >+ etypes = kdc_dict.pop('etypes', (AES256_CTS_HMAC_SHA1_96, >+ ARCFOUR_HMAC_MD5)) >+ >+ def generate_s4u2self_padata(_kdc_exchange_dict, >+ _callback_dict, >+ req_body): >+ pa_s4u = self.PA_S4U2Self_create( >+ name=client_cname, >+ realm=realm, >+ tgt_session_key=service_tgt.session_key, >+ ctype=None) >+ >+ return [pa_s4u], req_body >+ >+ kdc_exchange_dict = self.tgs_exchange_dict( >+ expected_crealm=realm, >+ expected_cname=client_cname, >+ expected_srealm=realm, >+ expected_sname=service_sname, >+ expected_flags=expected_flags, >+ unexpected_flags=unexpected_flags, >+ ticket_decryption_key=service_decryption_key, >+ expect_ticket_checksum=True, >+ generate_padata_fn=generate_s4u2self_padata, >+ check_rep_fn=self.generic_check_kdc_rep, >+ check_kdc_private_fn=self.generic_check_kdc_private, >+ expected_error_mode=0, >+ tgt=service_tgt, >+ authenticator_subkey=authenticator_subkey, >+ kdc_options=str(kdc_options), >+ expect_claims=False) >+ >+ self._generic_kdc_exchange(kdc_exchange_dict, >+ cname=None, >+ realm=realm, >+ sname=service_sname, >+ etypes=etypes) >+ >+ # Ensure we used all the parameters given to us. >+ self.assertEqual({}, kdc_dict) >+ >+ # Test performing an S4U2Self operation with a forwardable ticket. The >+ # resulting ticket should have the 'forwardable' flag set. >+ def test_s4u2self_forwardable(self): >+ self._run_s4u2self_test( >+ { >+ 'client_opts': { >+ 'not_delegated': False >+ }, >+ 'kdc_options': 'forwardable', >+ 'modify_service_tgt_fn': functools.partial( >+ self.set_ticket_forwardable, flag=True), >+ 'expected_flags': 'forwardable' >+ }) >+ >+ # Test performing an S4U2Self operation without requesting a forwardable >+ # ticket. The resulting ticket should not have the 'forwardable' flag set. >+ def test_s4u2self_without_forwardable(self): >+ self._run_s4u2self_test( >+ { >+ 'client_opts': { >+ 'not_delegated': False >+ }, >+ 'modify_service_tgt_fn': functools.partial( >+ self.set_ticket_forwardable, flag=True), >+ 'unexpected_flags': 'forwardable' >+ }) >+ >+ # Do an S4U2Self with a non-forwardable TGT. The 'forwardable' flag should >+ # not be set on the ticket. >+ def test_s4u2self_not_forwardable(self): >+ self._run_s4u2self_test( >+ { >+ 'client_opts': { >+ 'not_delegated': False >+ }, >+ 'kdc_options': 'forwardable', >+ 'modify_service_tgt_fn': functools.partial( >+ self.set_ticket_forwardable, flag=False), >+ 'unexpected_flags': 'forwardable' >+ }) >+ >+ # Do an S4U2Self with the not_delegated flag set on the client. The >+ # 'forwardable' flag should not be set on the ticket. >+ def test_s4u2self_client_not_delegated(self): >+ self._run_s4u2self_test( >+ { >+ 'client_opts': { >+ 'not_delegated': True >+ }, >+ 'kdc_options': 'forwardable', >+ 'modify_service_tgt_fn': functools.partial( >+ self.set_ticket_forwardable, flag=True), >+ 'unexpected_flags': 'forwardable' >+ }) >+ >+ # Do an S4U2Self with a service not trusted to authenticate for delegation, >+ # but having an empty msDS-AllowedToDelegateTo attribute. The 'forwardable' >+ # flag should be set on the ticket. >+ def test_s4u2self_not_trusted_empty_allowed(self): >+ self._run_s4u2self_test( >+ { >+ 'client_opts': { >+ 'not_delegated': False >+ }, >+ 'service_opts': { >+ 'trusted_to_auth_for_delegation': False, >+ 'delegation_to_spn': () >+ }, >+ 'kdc_options': 'forwardable', >+ 'modify_service_tgt_fn': functools.partial( >+ self.set_ticket_forwardable, flag=True), >+ 'expected_flags': 'forwardable' >+ }) >+ >+ # Do an S4U2Self with a service not trusted to authenticate for delegation >+ # and having a non-empty msDS-AllowedToDelegateTo attribute. The >+ # 'forwardable' flag should not be set on the ticket. >+ def test_s4u2self_not_trusted_nonempty_allowed(self): >+ self._run_s4u2self_test( >+ { >+ 'client_opts': { >+ 'not_delegated': False >+ }, >+ 'service_opts': { >+ 'trusted_to_auth_for_delegation': False, >+ 'delegation_to_spn': ('test',) >+ }, >+ 'kdc_options': 'forwardable', >+ 'modify_service_tgt_fn': functools.partial( >+ self.set_ticket_forwardable, flag=True), >+ 'unexpected_flags': 'forwardable' >+ }) >+ >+ # Do an S4U2Self with a service trusted to authenticate for delegation and >+ # having an empty msDS-AllowedToDelegateTo attribute. The 'forwardable' >+ # flag should be set on the ticket. >+ def test_s4u2self_trusted_empty_allowed(self): >+ self._run_s4u2self_test( >+ { >+ 'client_opts': { >+ 'not_delegated': False >+ }, >+ 'service_opts': { >+ 'trusted_to_auth_for_delegation': True, >+ 'delegation_to_spn': () >+ }, >+ 'kdc_options': 'forwardable', >+ 'modify_service_tgt_fn': functools.partial( >+ self.set_ticket_forwardable, flag=True), >+ 'expected_flags': 'forwardable' >+ }) >+ >+ # Do an S4U2Self with a service trusted to authenticate for delegation and >+ # having a non-empty msDS-AllowedToDelegateTo attribute. The 'forwardable' >+ # flag should be set on the ticket. >+ def test_s4u2self_trusted_nonempty_allowed(self): >+ self._run_s4u2self_test( >+ { >+ 'client_opts': { >+ 'not_delegated': False >+ }, >+ 'service_opts': { >+ 'trusted_to_auth_for_delegation': True, >+ 'delegation_to_spn': ('test',) >+ }, >+ 'kdc_options': 'forwardable', >+ 'modify_service_tgt_fn': functools.partial( >+ self.set_ticket_forwardable, flag=True), >+ 'expected_flags': 'forwardable' >+ }) >+ >+ def _run_delegation_test(self, kdc_dict): >+ client_opts = kdc_dict.pop('client_opts', None) >+ client_creds = self.get_cached_creds(machine_account=False, >+ opts=client_opts) >+ >+ service1_opts = kdc_dict.pop('service1_opts', {}) >+ service2_opts = kdc_dict.pop('service2_opts', {}) >+ >+ allow_delegation = kdc_dict.pop('allow_delegation', False) >+ allow_rbcd = kdc_dict.pop('allow_rbcd', False) >+ self.assertFalse(allow_delegation and allow_rbcd) >+ >+ if allow_rbcd: >+ service1_creds = self.get_cached_creds(machine_account=True, >+ opts=service1_opts) >+ >+ self.assertNotIn('delegation_from_dn', service2_opts) >+ service2_opts['delegation_from_dn'] = str(service1_creds.get_dn()) >+ >+ service2_creds = self.get_cached_creds(machine_account=True, >+ opts=service2_opts) >+ else: >+ service2_creds = self.get_cached_creds(machine_account=True, >+ opts=service2_opts) >+ >+ if allow_delegation: >+ self.assertNotIn('delegation_to_spn', service1_opts) >+ service1_opts['delegation_to_spn'] = service2_creds.get_spn() >+ >+ service1_creds = self.get_cached_creds(machine_account=True, >+ opts=service1_opts) >+ >+ client_tkt_options = kdc_dict.pop('client_tkt_options', 'forwardable') >+ expected_flags = krb5_asn1.TicketFlags(client_tkt_options) >+ >+ client_tgt = self.get_tgt(client_creds, >+ kdc_options=client_tkt_options, >+ expected_flags=expected_flags) >+ client_service_tkt = self.get_service_ticket( >+ client_tgt, >+ service1_creds, >+ kdc_options=client_tkt_options, >+ expected_flags=expected_flags) >+ >+ service1_tgt = self.get_tgt(service1_creds) >+ >+ modify_client_tkt_fn = kdc_dict.pop('modify_client_tkt_fn', None) >+ if modify_client_tkt_fn is not None: >+ client_service_tkt = modify_client_tkt_fn(client_service_tkt) >+ >+ additional_tickets = [client_service_tkt.ticket] >+ >+ modify_service_tgt_fn = kdc_dict.pop('modify_service_tgt_fn', None) >+ if modify_service_tgt_fn is not None: >+ service1_tgt = modify_service_tgt_fn(service1_tgt) >+ >+ kdc_options = kdc_dict.pop('kdc_options', None) >+ if kdc_options is None: >+ kdc_options = str(krb5_asn1.KDCOptions('cname-in-addl-tkt')) >+ >+ client_username = client_creds.get_username() >+ client_realm = client_creds.get_realm() >+ client_cname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >+ names=[client_username]) >+ >+ service1_name = service1_creds.get_username()[:-1] >+ service1_realm = service1_creds.get_realm() >+ >+ service2_name = service2_creds.get_username()[:-1] >+ service2_realm = service2_creds.get_realm() >+ service2_service = 'host' >+ service2_sname = self.PrincipalName_create( >+ name_type=NT_PRINCIPAL, names=[service2_service, >+ service2_name]) >+ service2_decryption_key = self.TicketDecryptionKey_from_creds( >+ service2_creds) >+ service2_etypes = service2_creds.tgs_supported_enctypes >+ >+ expected_error_mode = kdc_dict.pop('expected_error_mode') >+ expected_status = kdc_dict.pop('expected_status', None) >+ if expected_error_mode: >+ check_error_fn = self.generic_check_kdc_error >+ check_rep_fn = None >+ else: >+ check_error_fn = None >+ check_rep_fn = self.generic_check_kdc_rep >+ >+ self.assertIsNone(expected_status) >+ >+ expect_edata = kdc_dict.pop('expect_edata', None) >+ if expect_edata is not None: >+ self.assertTrue(expected_error_mode) >+ >+ pac_options = kdc_dict.pop('pac_options', None) >+ >+ authenticator_subkey = self.RandomKey(Enctype.AES256) >+ >+ etypes = kdc_dict.pop('etypes', (AES256_CTS_HMAC_SHA1_96, >+ ARCFOUR_HMAC_MD5)) >+ >+ expected_proxy_target = service2_creds.get_spn() >+ >+ expected_transited_services = kdc_dict.pop( >+ 'expected_transited_services', []) >+ >+ transited_service = f'host/{service1_name}@{service1_realm}' >+ expected_transited_services.append(transited_service) >+ >+ kdc_exchange_dict = self.tgs_exchange_dict( >+ expected_crealm=client_realm, >+ expected_cname=client_cname, >+ expected_srealm=service2_realm, >+ expected_sname=service2_sname, >+ expected_supported_etypes=service2_etypes, >+ ticket_decryption_key=service2_decryption_key, >+ check_error_fn=check_error_fn, >+ check_rep_fn=check_rep_fn, >+ check_kdc_private_fn=self.generic_check_kdc_private, >+ expected_error_mode=expected_error_mode, >+ expected_status=expected_status, >+ callback_dict={}, >+ tgt=service1_tgt, >+ authenticator_subkey=authenticator_subkey, >+ kdc_options=kdc_options, >+ pac_options=pac_options, >+ expect_edata=expect_edata, >+ expected_proxy_target=expected_proxy_target, >+ expected_transited_services=expected_transited_services) >+ >+ self._generic_kdc_exchange(kdc_exchange_dict, >+ cname=None, >+ realm=service2_realm, >+ sname=service2_sname, >+ etypes=etypes, >+ additional_tickets=additional_tickets) >+ >+ # Ensure we used all the parameters given to us. >+ self.assertEqual({}, kdc_dict) >+ >+ def test_constrained_delegation(self): >+ # Test constrained delegation. >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': 0, >+ 'allow_delegation': True >+ }) >+ >+ def test_constrained_delegation_existing_delegation_info(self): >+ # Test constrained delegation with an existing S4U_DELEGATION_INFO >+ # structure in the PAC. >+ >+ services = ['service1', 'service2', 'service3'] >+ >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': 0, >+ 'allow_delegation': True, >+ 'modify_client_tkt_fn': functools.partial( >+ self.add_delegation_info, services=services), >+ 'expected_transited_services': services >+ }) >+ >+ def test_constrained_delegation_not_allowed(self): >+ # Test constrained delegation when the delegating service does not >+ # allow it. >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': KDC_ERR_BADOPTION, >+ 'expected_status': ntstatus.NT_STATUS_NOT_SUPPORTED, >+ 'allow_delegation': False >+ }) >+ >+ def test_constrained_delegation_no_client_pac(self): >+ # Test constrained delegation when the client service ticket does not >+ # contain a PAC. >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': (KDC_ERR_BADOPTION, >+ KDC_ERR_MODIFIED), >+ 'allow_delegation': True, >+ 'modify_client_tkt_fn': self.remove_ticket_pac, >+ 'expect_edata': False >+ }) >+ >+ def test_constrained_delegation_no_service_pac(self): >+ # Test constrained delegation when the service TGT does not contain a >+ # PAC. >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': 0, >+ 'allow_delegation': True, >+ 'modify_service_tgt_fn': self.remove_ticket_pac >+ }) >+ >+ def test_constrained_delegation_non_forwardable(self): >+ # Test constrained delegation with a non-forwardable ticket. >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': KDC_ERR_BADOPTION, >+ 'expected_status': ntstatus.NT_STATUS_ACCOUNT_RESTRICTION, >+ 'allow_delegation': True, >+ 'modify_client_tkt_fn': functools.partial( >+ self.set_ticket_forwardable, flag=False) >+ }) >+ >+ def test_constrained_delegation_pac_options_rbcd(self): >+ # Test constrained delegation, but with the RBCD bit set in the PAC >+ # options. >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': 0, >+ 'pac_options': '0001', # supports RBCD >+ 'allow_delegation': True >+ }) >+ >+ def test_rbcd_existing_delegation_info(self): >+ # Test constrained delegation with an existing S4U_DELEGATION_INFO >+ # structure in the PAC. >+ >+ services = ['service1', 'service2', 'service3'] >+ >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': 0, >+ 'allow_rbcd': True, >+ 'pac_options': '0001', # supports RBCD >+ 'modify_client_tkt_fn': functools.partial( >+ self.add_delegation_info, services=services), >+ 'expected_transited_services': services >+ }) >+ >+ def test_rbcd_not_allowed(self): >+ # Test resource-based constrained delegation when the target service >+ # does not allow it. >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': KDC_ERR_BADOPTION, >+ 'expected_status': ntstatus.NT_STATUS_NOT_FOUND, >+ 'allow_rbcd': False, >+ 'pac_options': '0001' # supports RBCD >+ }) >+ >+ def test_rbcd_no_client_pac_a(self): >+ # Test constrained delegation when the client service ticket does not >+ # contain a PAC, and an empty msDS-AllowedToDelegateTo attribute. >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': KDC_ERR_MODIFIED, >+ 'expected_status': ntstatus.NT_STATUS_NOT_SUPPORTED, >+ 'allow_rbcd': True, >+ 'pac_options': '0001', # supports RBCD >+ 'modify_client_tkt_fn': self.remove_ticket_pac >+ }) >+ >+ def test_rbcd_no_client_pac_b(self): >+ # Test constrained delegation when the client service ticket does not >+ # contain a PAC, and a non-empty msDS-AllowedToDelegateTo attribute. >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': KDC_ERR_MODIFIED, >+ 'expected_status': ntstatus.NT_STATUS_NO_MATCH, >+ 'allow_rbcd': True, >+ 'pac_options': '0001', # supports RBCD >+ 'modify_client_tkt_fn': self.remove_ticket_pac, >+ 'service1_opts': { >+ 'delegation_to_spn': ('host/test') >+ } >+ }) >+ >+ def test_rbcd_no_service_pac(self): >+ # Test constrained delegation when the service TGT does not contain a >+ # PAC. >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': KDC_ERR_BADOPTION, >+ 'expected_status': >+ ntstatus.NT_STATUS_NOT_FOUND, >+ 'allow_rbcd': True, >+ 'pac_options': '0001', # supports RBCD >+ 'modify_service_tgt_fn': self.remove_ticket_pac >+ }) >+ >+ def test_rbcd_non_forwardable(self): >+ # Test resource-based constrained delegation with a non-forwardable >+ # ticket. >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': KDC_ERR_BADOPTION, >+ 'expected_status': ntstatus.NT_STATUS_ACCOUNT_RESTRICTION, >+ 'allow_rbcd': True, >+ 'pac_options': '0001', # supports RBCD >+ 'modify_client_tkt_fn': functools.partial( >+ self.set_ticket_forwardable, flag=False) >+ }) >+ >+ def test_rbcd_no_pac_options_a(self): >+ # Test resource-based constrained delegation without the RBCD bit set >+ # in the PAC options, and an empty msDS-AllowedToDelegateTo attribute. >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': KDC_ERR_BADOPTION, >+ 'expected_status': ntstatus.NT_STATUS_NOT_SUPPORTED, >+ 'allow_rbcd': True, >+ 'pac_options': '1' # does not support RBCD >+ }) >+ >+ def test_rbcd_no_pac_options_b(self): >+ # Test resource-based constrained delegation without the RBCD bit set >+ # in the PAC options, and a non-empty msDS-AllowedToDelegateTo >+ # attribute. >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': KDC_ERR_BADOPTION, >+ 'expected_status': ntstatus.NT_STATUS_NO_MATCH, >+ 'allow_rbcd': True, >+ 'pac_options': '1', # does not support RBCD >+ 'service1_opts': { >+ 'delegation_to_spn': ('host/test') >+ } >+ }) >+ >+ def test_bronze_bit_constrained_delegation_old_checksum(self): >+ # Attempt to modify the ticket without updating the PAC checksums. >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': (KDC_ERR_MODIFIED, >+ KDC_ERR_BAD_INTEGRITY), >+ 'allow_delegation': True, >+ 'client_tkt_options': '0', # non-forwardable ticket >+ 'modify_client_tkt_fn': functools.partial( >+ self.set_ticket_forwardable, >+ flag=True, update_pac_checksums=False), >+ 'expect_edata': False >+ }) >+ >+ def test_bronze_bit_rbcd_old_checksum(self): >+ # Attempt to modify the ticket without updating the PAC checksums. >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': KDC_ERR_MODIFIED, >+ 'expected_status': ntstatus.NT_STATUS_NOT_SUPPORTED, >+ 'allow_rbcd': True, >+ 'pac_options': '0001', # supports RBCD >+ 'client_tkt_options': '0', # non-forwardable ticket >+ 'modify_client_tkt_fn': functools.partial( >+ self.set_ticket_forwardable, >+ flag=True, update_pac_checksums=False) >+ }) >+ >+ def test_constrained_delegation_missing_client_checksum(self): >+ # Present a user ticket without the required checksums. >+ for checksum in self.pac_checksum_types: >+ with self.subTest(checksum=checksum): >+ if checksum == krb5pac.PAC_TYPE_TICKET_CHECKSUM: >+ expected_error_mode = (KDC_ERR_BADOPTION, >+ KDC_ERR_MODIFIED) >+ else: >+ expected_error_mode = KDC_ERR_GENERIC >+ >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': expected_error_mode, >+ 'allow_delegation': True, >+ 'modify_client_tkt_fn': functools.partial( >+ self.remove_pac_checksum, checksum=checksum), >+ 'expect_edata': False >+ }) >+ >+ def test_constrained_delegation_missing_service_checksum(self): >+ # Present the service's ticket without the required checksums. >+ for checksum in filter(lambda x: x != krb5pac.PAC_TYPE_TICKET_CHECKSUM, >+ self.pac_checksum_types): >+ with self.subTest(checksum=checksum): >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': KDC_ERR_GENERIC, >+ 'expected_status': >+ ntstatus.NT_STATUS_INSUFFICIENT_RESOURCES, >+ 'allow_delegation': True, >+ 'modify_service_tgt_fn': functools.partial( >+ self.remove_pac_checksum, checksum=checksum) >+ }) >+ >+ def test_rbcd_missing_client_checksum(self): >+ # Present a user ticket without the required checksums. >+ for checksum in self.pac_checksum_types: >+ with self.subTest(checksum=checksum): >+ if checksum == krb5pac.PAC_TYPE_TICKET_CHECKSUM: >+ expected_error_mode = KDC_ERR_MODIFIED >+ else: >+ expected_error_mode = KDC_ERR_GENERIC >+ >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': expected_error_mode, >+ 'expected_status': >+ ntstatus.NT_STATUS_NOT_SUPPORTED, >+ 'allow_rbcd': True, >+ 'pac_options': '0001', # supports RBCD >+ 'modify_client_tkt_fn': functools.partial( >+ self.remove_pac_checksum, checksum=checksum) >+ }) >+ >+ def test_rbcd_missing_service_checksum(self): >+ # Present the service's ticket without the required checksums. >+ for checksum in filter(lambda x: x != krb5pac.PAC_TYPE_TICKET_CHECKSUM, >+ self.pac_checksum_types): >+ with self.subTest(checksum=checksum): >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': KDC_ERR_GENERIC, >+ 'expected_status': >+ ntstatus.NT_STATUS_INSUFFICIENT_RESOURCES, >+ 'allow_rbcd': True, >+ 'pac_options': '0001', # supports RBCD >+ 'modify_service_tgt_fn': functools.partial( >+ self.remove_pac_checksum, checksum=checksum) >+ }) >+ >+ def test_constrained_delegation_zeroed_client_checksum(self): >+ # Present a user ticket with invalid checksums. >+ for checksum in self.pac_checksum_types: >+ with self.subTest(checksum=checksum): >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': (KDC_ERR_MODIFIED, >+ KDC_ERR_BAD_INTEGRITY), >+ 'allow_delegation': True, >+ 'modify_client_tkt_fn': functools.partial( >+ self.zeroed_pac_checksum, checksum=checksum), >+ 'expect_edata': False >+ }) >+ >+ def test_constrained_delegation_zeroed_service_checksum(self): >+ # Present the service's ticket with invalid checksums. >+ for checksum in self.pac_checksum_types: >+ with self.subTest(checksum=checksum): >+ if checksum == krb5pac.PAC_TYPE_SRV_CHECKSUM: >+ expected_error_mode = (KDC_ERR_MODIFIED, >+ KDC_ERR_BAD_INTEGRITY) >+ expected_status = ntstatus.NT_STATUS_WRONG_PASSWORD >+ else: >+ expected_error_mode = 0 >+ expected_status = None >+ >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': expected_error_mode, >+ 'expected_status': expected_status, >+ 'allow_delegation': True, >+ 'modify_service_tgt_fn': functools.partial( >+ self.zeroed_pac_checksum, checksum=checksum) >+ }) >+ >+ def test_rbcd_zeroed_client_checksum(self): >+ # Present a user ticket with invalid checksums. >+ for checksum in self.pac_checksum_types: >+ with self.subTest(checksum=checksum): >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': KDC_ERR_MODIFIED, >+ 'expected_status': >+ ntstatus.NT_STATUS_NOT_SUPPORTED, >+ 'allow_rbcd': True, >+ 'pac_options': '0001', # supports RBCD >+ 'modify_client_tkt_fn': functools.partial( >+ self.zeroed_pac_checksum, checksum=checksum) >+ }) >+ >+ def test_rbcd_zeroed_service_checksum(self): >+ # Present the service's ticket with invalid checksums. >+ for checksum in self.pac_checksum_types: >+ with self.subTest(checksum=checksum): >+ if checksum == krb5pac.PAC_TYPE_SRV_CHECKSUM: >+ expected_error_mode = (KDC_ERR_MODIFIED, >+ KDC_ERR_BAD_INTEGRITY) >+ expected_status = ntstatus.NT_STATUS_WRONG_PASSWORD >+ else: >+ expected_error_mode = 0 >+ expected_status = None >+ >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': expected_error_mode, >+ 'expected_status': expected_status, >+ 'allow_rbcd': True, >+ 'pac_options': '0001', # supports RBCD >+ 'modify_service_tgt_fn': functools.partial( >+ self.zeroed_pac_checksum, checksum=checksum) >+ }) >+ >+ unkeyed_ctypes = {Cksumtype.MD5, Cksumtype.SHA1, Cksumtype.CRC32} >+ >+ def test_constrained_delegation_unkeyed_client_checksum(self): >+ # Present a user ticket with invalid checksums. >+ for checksum in self.pac_checksum_types: >+ for ctype in self.unkeyed_ctypes: >+ with self.subTest(checksum=checksum, ctype=ctype): >+ if (checksum == krb5pac.PAC_TYPE_SRV_CHECKSUM >+ and ctype == Cksumtype.SHA1): >+ expected_error_mode = (KDC_ERR_SUMTYPE_NOSUPP, >+ KDC_ERR_INAPP_CKSUM) >+ else: >+ expected_error_mode = (KDC_ERR_GENERIC, >+ KDC_ERR_INAPP_CKSUM) >+ >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': expected_error_mode, >+ 'allow_delegation': True, >+ 'modify_client_tkt_fn': functools.partial( >+ self.unkeyed_pac_checksum, >+ checksum=checksum, ctype=ctype), >+ 'expect_edata': False >+ }) >+ >+ def test_constrained_delegation_unkeyed_service_checksum(self): >+ # Present the service's ticket with invalid checksums. >+ for checksum in self.pac_checksum_types: >+ for ctype in self.unkeyed_ctypes: >+ with self.subTest(checksum=checksum, ctype=ctype): >+ if checksum == krb5pac.PAC_TYPE_SRV_CHECKSUM: >+ if ctype == Cksumtype.SHA1: >+ expected_error_mode = (KDC_ERR_SUMTYPE_NOSUPP, >+ KDC_ERR_INAPP_CKSUM) >+ expected_status = ntstatus.NT_STATUS_LOGON_FAILURE >+ else: >+ expected_error_mode = (KDC_ERR_GENERIC, >+ KDC_ERR_INAPP_CKSUM) >+ expected_status = ( >+ ntstatus.NT_STATUS_INSUFFICIENT_RESOURCES) >+ else: >+ expected_error_mode = 0 >+ expected_status = None >+ >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': expected_error_mode, >+ 'expected_status': expected_status, >+ 'allow_delegation': True, >+ 'modify_service_tgt_fn': functools.partial( >+ self.unkeyed_pac_checksum, >+ checksum=checksum, ctype=ctype) >+ }) >+ >+ def test_rbcd_unkeyed_client_checksum(self): >+ # Present a user ticket with invalid checksums. >+ for checksum in self.pac_checksum_types: >+ for ctype in self.unkeyed_ctypes: >+ with self.subTest(checksum=checksum, ctype=ctype): >+ if (checksum == krb5pac.PAC_TYPE_SRV_CHECKSUM >+ and ctype == Cksumtype.SHA1): >+ expected_error_mode = KDC_ERR_SUMTYPE_NOSUPP >+ else: >+ expected_error_mode = KDC_ERR_GENERIC >+ >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': expected_error_mode, >+ 'expected_status': >+ ntstatus.NT_STATUS_NOT_SUPPORTED, >+ 'allow_rbcd': True, >+ 'pac_options': '0001', # supports RBCD >+ 'modify_client_tkt_fn': functools.partial( >+ self.unkeyed_pac_checksum, >+ checksum=checksum, ctype=ctype) >+ }) >+ >+ def test_rbcd_unkeyed_service_checksum(self): >+ # Present the service's ticket with invalid checksums. >+ for checksum in self.pac_checksum_types: >+ for ctype in self.unkeyed_ctypes: >+ with self.subTest(checksum=checksum, ctype=ctype): >+ if checksum == krb5pac.PAC_TYPE_SRV_CHECKSUM: >+ if ctype == Cksumtype.SHA1: >+ expected_error_mode = (KDC_ERR_SUMTYPE_NOSUPP, >+ KDC_ERR_BAD_INTEGRITY) >+ expected_status = ntstatus.NT_STATUS_LOGON_FAILURE >+ else: >+ expected_error_mode = KDC_ERR_GENERIC >+ expected_status = ( >+ ntstatus.NT_STATUS_INSUFFICIENT_RESOURCES) >+ else: >+ expected_error_mode = 0 >+ expected_status = None >+ >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': expected_error_mode, >+ 'expected_status': expected_status, >+ 'allow_rbcd': True, >+ 'pac_options': '0001', # supports RBCD >+ 'modify_service_tgt_fn': functools.partial( >+ self.unkeyed_pac_checksum, >+ checksum=checksum, ctype=ctype) >+ }) >+ >+ def remove_pac_checksum(self, ticket, checksum): >+ checksum_keys = self.get_krbtgt_checksum_key() >+ >+ return self.modified_ticket(ticket, >+ checksum_keys=checksum_keys, >+ include_checksums={checksum: False}) >+ >+ def zeroed_pac_checksum(self, ticket, checksum): >+ krbtgt_creds = self.get_krbtgt_creds() >+ krbtgt_key = self.TicketDecryptionKey_from_creds(krbtgt_creds) >+ >+ server_key = ticket.decryption_key >+ >+ checksum_keys = { >+ krb5pac.PAC_TYPE_SRV_CHECKSUM: server_key, >+ krb5pac.PAC_TYPE_KDC_CHECKSUM: krbtgt_key, >+ krb5pac.PAC_TYPE_TICKET_CHECKSUM: krbtgt_key, >+ } >+ >+ if checksum == krb5pac.PAC_TYPE_SRV_CHECKSUM: >+ zeroed_key = server_key >+ else: >+ zeroed_key = krbtgt_key >+ >+ checksum_keys[checksum] = ZeroedChecksumKey(zeroed_key.key, >+ zeroed_key.kvno) >+ >+ return self.modified_ticket(ticket, >+ checksum_keys=checksum_keys, >+ include_checksums={checksum: True}) >+ >+ def unkeyed_pac_checksum(self, ticket, checksum, ctype): >+ krbtgt_creds = self.get_krbtgt_creds() >+ krbtgt_key = self.TicketDecryptionKey_from_creds(krbtgt_creds) >+ >+ server_key = ticket.decryption_key >+ >+ checksum_keys = { >+ krb5pac.PAC_TYPE_SRV_CHECKSUM: server_key, >+ krb5pac.PAC_TYPE_KDC_CHECKSUM: krbtgt_key, >+ krb5pac.PAC_TYPE_TICKET_CHECKSUM: krbtgt_key, >+ } >+ >+ # Make a copy of the existing key and change the ctype. >+ key = checksum_keys[checksum] >+ new_key = RodcPacEncryptionKey(key.key, key.kvno) >+ new_key.ctype = ctype >+ checksum_keys[checksum] = new_key >+ >+ return self.modified_ticket(ticket, >+ checksum_keys=checksum_keys, >+ include_checksums={checksum: True}) >+ >+ def add_delegation_info(self, ticket, services=None): >+ def modify_pac_fn(pac): >+ pac_buffers = pac.buffers >+ self.assertNotIn(krb5pac.PAC_TYPE_CONSTRAINED_DELEGATION, >+ (buffer.type for buffer in pac_buffers)) >+ >+ transited_services = list(map(lsa.String, services)) >+ >+ delegation = krb5pac.PAC_CONSTRAINED_DELEGATION() >+ delegation.proxy_target = lsa.String('test_proxy_target') >+ delegation.transited_services = transited_services >+ delegation.num_transited_services = len(transited_services) >+ >+ info = krb5pac.PAC_CONSTRAINED_DELEGATION_CTR() >+ info.info = delegation >+ >+ pac_buffer = krb5pac.PAC_BUFFER() >+ pac_buffer.type = krb5pac.PAC_TYPE_CONSTRAINED_DELEGATION >+ pac_buffer.info = info >+ >+ pac_buffers.append(pac_buffer) >+ >+ pac.buffers = pac_buffers >+ pac.num_buffers += 1 >+ >+ return pac >+ >+ checksum_keys = self.get_krbtgt_checksum_key() >+ >+ return self.modified_ticket(ticket, >+ checksum_keys=checksum_keys, >+ modify_pac_fn=modify_pac_fn) >+ >+ def set_ticket_forwardable(self, ticket, flag, update_pac_checksums=True): >+ flag = '1' if flag else '0' >+ >+ def modify_fn(enc_part): >+ # Reset the forwardable flag >+ forwardable_pos = (len(tuple(krb5_asn1.TicketFlags('forwardable'))) >+ - 1) >+ >+ flags = enc_part['flags'] >+ self.assertLessEqual(forwardable_pos, len(flags)) >+ enc_part['flags'] = (flags[:forwardable_pos] + >+ flag + >+ flags[forwardable_pos+1:]) >+ >+ return enc_part >+ >+ if update_pac_checksums: >+ checksum_keys = self.get_krbtgt_checksum_key() >+ else: >+ checksum_keys = None >+ >+ return self.modified_ticket(ticket, >+ modify_fn=modify_fn, >+ checksum_keys=checksum_keys, >+ update_pac_checksums=update_pac_checksums) >+ >+ def remove_ticket_pac(self, ticket): >+ return self.modified_ticket(ticket, >+ exclude_pac=True) >+ > > if __name__ == "__main__": > global_asn1_print = False >diff --git a/python/samba/tests/usage.py b/python/samba/tests/usage.py >index 7cdf25b48ae..0a9aac1f2cc 100644 >--- a/python/samba/tests/usage.py >+++ b/python/samba/tests/usage.py >@@ -103,6 +103,7 @@ EXCLUDE_USAGE = { > 'python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py', > 'python/samba/tests/krb5/as_req_tests.py', > 'python/samba/tests/krb5/fast_tests.py', >+ 'python/samba/tests/krb5/rodc_tests.py', > } > > EXCLUDE_HELP = { >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 6eb667f8969..0b8e83f1f3f 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -125,3 +125,32 @@ > # Heimdal currently does not generate ticket signatures > # > ^samba.tests.krb5.compatability_tests.samba.tests.krb5.compatability_tests.SimpleKerberosTests.test_heimdal_ticket_signature >+# >+# S4U tests >+# >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_bronze_bit_rbcd_old_checksum >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_missing_client_checksum >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_unkeyed_client_checksum >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_unkeyed_service_checksum >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_zeroed_client_checksum >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_zeroed_service_checksum >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_existing_delegation_info >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_missing_client_checksum >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_no_client_pac_a >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_no_client_pac_b >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_unkeyed_client_checksum >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_unkeyed_service_checksum >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_zeroed_client_checksum >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_zeroed_service_checksum >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_client_not_delegated >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_forwardable >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_not_forwardable >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_not_trusted_empty_allowed >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_not_trusted_nonempty_allowed >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_trusted_empty_allowed >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_trusted_nonempty_allowed >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_without_forwardable >+# >+# RODC tests >+# >+^samba.tests.krb5.rodc_tests.samba.tests.krb5.rodc_tests.RodcKerberosTests.test_rodc_ticket_signature >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index f7b34baba8a..5d3c4ac4bfd 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -817,9 +817,16 @@ planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.simple_tests", > 'FAST_SUPPORT': have_fast_support, > 'TKT_SIG_SUPPORT': tkt_sig_support}) > planoldpythontestsuite("ad_dc_default:local", "samba.tests.krb5.s4u_tests", >- environ={'SERVICE_USERNAME':'srv_account', >- 'SERVICE_PASSWORD':'$PASSWORD', >+ environ={'ADMIN_USERNAME':'$USERNAME', >+ 'ADMIN_PASSWORD':'$PASSWORD', > 'FOR_USER':'$USERNAME', >+ 'STRICT_CHECKING':'0', >+ 'FAST_SUPPORT': have_fast_support, >+ 'TKT_SIG_SUPPORT': tkt_sig_support}) >+planoldpythontestsuite("rodc:local", "samba.tests.krb5.rodc_tests", >+ environ={'ADMIN_USERNAME':'$USERNAME', >+ 'ADMIN_PASSWORD':'$PASSWORD', >+ 'STRICT_CHECKING':'0', > 'FAST_SUPPORT': have_fast_support, > 'TKT_SIG_SUPPORT': tkt_sig_support}) > >-- >2.25.1 > > >From 047ec6f821db6e7b6e5c4a4bbcb5a4633ce10ced Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 29 Sep 2021 12:07:40 +1300 >Subject: [PATCH 114/159] tests/krb5: Don't include empty AD-IF-RELEVANT > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 1a08399cd8169a525cc9e7aed99da84ef20e5b9c) >--- > python/samba/tests/krb5/raw_testcase.py | 19 ++++++++++++------- > 1 file changed, 12 insertions(+), 7 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 2e289c90ce7..e008223eb23 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -3424,14 +3424,19 @@ class RawKerberosTest(TestCaseInTempDir): > if expect_pac: > self.assertIsNotNone(old_pac, 'Expected PAC') > >- ad_relevant = self.der_encode( >- relevant_elems, >- asn1Spec=krb5_asn1.AD_IF_RELEVANT()) >- >- authdata_elem = self.AuthorizationData_create(AD_IF_RELEVANT, >- ad_relevant) >+ if relevant_elems: >+ ad_relevant = self.der_encode( >+ relevant_elems, >+ asn1Spec=krb5_asn1.AD_IF_RELEVANT()) >+ >+ authdata_elem = self.AuthorizationData_create( >+ AD_IF_RELEVANT, >+ ad_relevant) >+ else: >+ authdata_elem = None > >- new_auth_data.append(authdata_elem) >+ if authdata_elem is not None: >+ new_auth_data.append(authdata_elem) > > if expect_pac: > self.assertIsNotNone(ad_relevant, 'Expected AD-RELEVANT') >-- >2.25.1 > > >From 0e3b3865b18de203feb14e8d26a393f341daebfd Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 8 Oct 2021 15:41:35 +1300 >Subject: [PATCH 115/159] tests/krb5: Allow bypassing cache when creating > accounts > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 3948701f1d0f3ccd06f6dad56ca72833d66b1d84) >--- > python/samba/tests/krb5/kdc_base_test.py | 13 +++++++++---- > 1 file changed, 9 insertions(+), 4 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 8a5e12bbed4..87160f675ae 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -610,7 +610,8 @@ class KDCBaseTest(RawKerberosTest): > > def get_cached_creds(self, *, > machine_account, >- opts=None): >+ opts=None, >+ use_cache=True): > if opts is None: > opts = {} > >@@ -638,9 +639,13 @@ class KDCBaseTest(RawKerberosTest): > > cache_key = tuple(sorted(account_opts.items())) > >- creds = self.account_cache.get(cache_key) >- if creds is None: >- creds = self.create_account_opts(**account_opts) >+ if use_cache: >+ creds = self.account_cache.get(cache_key) >+ if creds is not None: >+ return creds >+ >+ creds = self.create_account_opts(**account_opts) >+ if use_cache: > self.account_cache[cache_key] = creds > > return creds >-- >2.25.1 > > >From a89be86247243c3514b31ff4f221dc5b6cd10072 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 8 Oct 2021 15:40:39 +1300 >Subject: [PATCH 116/159] tests/krb5: Fix duplicate account creation > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 3dede18c5a1801023a60cc55b99022b033428350) >--- > .../krb5/ms_kile_client_principal_lookup_tests.py | 13 +++++-------- > 1 file changed, 5 insertions(+), 8 deletions(-) > >diff --git a/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py b/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >index 501bc4892f4..2ee3d4a2a83 100755 >--- a/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >+++ b/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >@@ -150,18 +150,15 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > # Create a machine account for the test. > # > samdb = self.get_samdb() >- user_name = "mskilemac" >- (mc, dn) = self.create_account(samdb, user_name, machine_account=True) >- realm = mc.get_realm().lower() >- > mach_name = "mskilemac" >- (mc, _) = self.create_account(samdb, mach_name, machine_account=True) >+ (mc, dn) = self.create_account(samdb, mach_name, machine_account=True) >+ realm = mc.get_realm().lower() > > # Do the initial AS-REQ, should get a pre-authentication required > # response > etype = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) > cname = self.PrincipalName_create( >- name_type=NT_PRINCIPAL, names=[user_name]) >+ name_type=NT_PRINCIPAL, names=[mach_name]) > sname = self.PrincipalName_create( > name_type=NT_SRV_INST, names=["krbtgt", realm]) > >@@ -180,7 +177,7 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > key = self.EncryptionKey_import(enc_part2['key']) > cname = self.PrincipalName_create( > name_type=NT_PRINCIPAL, >- names=[user_name]) >+ names=[mach_name]) > sname = self.PrincipalName_create( > name_type=NT_PRINCIPAL, > names=[mc.get_username()]) >@@ -197,7 +194,7 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > # check the crealm and cname > cname = enc_part['cname'] > self.assertEqual(NT_PRINCIPAL, cname['name-type']) >- self.assertEqual(user_name.encode('UTF8'), cname['name-string'][0]) >+ self.assertEqual(mach_name.encode('UTF8'), cname['name-string'][0]) > self.assertEqual(realm.upper().encode('UTF8'), enc_part['crealm']) > > def test_nt_principal_step_3(self): >-- >2.25.1 > > >From 188fd1dfab906767fc0c041f030715cc3316ec18 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 8 Oct 2021 16:06:58 +1300 >Subject: [PATCH 117/159] s4:kdc: Simplify samba_kdc_update_pac_blob() to take > ldb_context as parameter > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 7149eeaceb426470b1b8181749d2d081c2fb83a4) >--- > source4/kdc/mit_samba.c | 7 +------ > source4/kdc/pac-glue.c | 5 ++--- > source4/kdc/pac-glue.h | 3 +-- > source4/kdc/wdc-samba4.c | 2 +- > 4 files changed, 5 insertions(+), 12 deletions(-) > >diff --git a/source4/kdc/mit_samba.c b/source4/kdc/mit_samba.c >index 54dcd545ea1..2936fe2d18a 100644 >--- a/source4/kdc/mit_samba.c >+++ b/source4/kdc/mit_samba.c >@@ -482,7 +482,6 @@ krb5_error_code mit_samba_reget_pac(struct mit_samba_context *ctx, > DATA_BLOB *deleg_blob = NULL; > struct samba_kdc_entry *client_skdc_entry = NULL; > struct samba_kdc_entry *krbtgt_skdc_entry = NULL; >- struct samba_kdc_entry *server_skdc_entry = NULL; > bool is_in_db = false; > bool is_untrusted = false; > size_t num_types = 0; >@@ -513,9 +512,6 @@ krb5_error_code mit_samba_reget_pac(struct mit_samba_context *ctx, > if (server == NULL) { > return EINVAL; > } >- server_skdc_entry = >- talloc_get_type_abort(server->e_data, >- struct samba_kdc_entry); > > if (krbtgt == NULL) { > return EINVAL; >@@ -575,8 +571,7 @@ krb5_error_code mit_samba_reget_pac(struct mit_samba_context *ctx, > > nt_status = samba_kdc_update_pac_blob(tmp_ctx, > context, >- krbtgt_skdc_entry, >- server_skdc_entry, >+ krbtgt_skdc_entry->kdc_db_ctx->samdb, > *pac, > pac_blob, > pac_srv_sig, >diff --git a/source4/kdc/pac-glue.c b/source4/kdc/pac-glue.c >index 04fbc5cf487..88bcb734fc5 100644 >--- a/source4/kdc/pac-glue.c >+++ b/source4/kdc/pac-glue.c >@@ -747,8 +747,7 @@ NTSTATUS samba_kdc_get_pac_blob(TALLOC_CTX *mem_ctx, > > NTSTATUS samba_kdc_update_pac_blob(TALLOC_CTX *mem_ctx, > krb5_context context, >- struct samba_kdc_entry *krbtgt, >- struct samba_kdc_entry *server, >+ struct ldb_context *samdb, > const krb5_pac pac, DATA_BLOB *pac_blob, > struct PAC_SIGNATURE_DATA *pac_srv_sig, > struct PAC_SIGNATURE_DATA *pac_kdc_sig) >@@ -768,7 +767,7 @@ NTSTATUS samba_kdc_update_pac_blob(TALLOC_CTX *mem_ctx, > * as the token might be generated by a trusted domain. > */ > nt_status = authsam_update_user_info_dc(mem_ctx, >- krbtgt->kdc_db_ctx->samdb, >+ samdb, > user_info_dc); > if (!NT_STATUS_IS_OK(nt_status)) { > return nt_status; >diff --git a/source4/kdc/pac-glue.h b/source4/kdc/pac-glue.h >index 2eb7fd3b755..7b51b0389f5 100644 >--- a/source4/kdc/pac-glue.h >+++ b/source4/kdc/pac-glue.h >@@ -51,8 +51,7 @@ NTSTATUS samba_kdc_get_pac_blob(TALLOC_CTX *mem_ctx, > > NTSTATUS samba_kdc_update_pac_blob(TALLOC_CTX *mem_ctx, > krb5_context context, >- struct samba_kdc_entry *krbtgt, >- struct samba_kdc_entry *server, >+ struct ldb_context *samdb, > const krb5_pac pac, DATA_BLOB *pac_blob, > struct PAC_SIGNATURE_DATA *pac_srv_sig, > struct PAC_SIGNATURE_DATA *pac_kdc_sig); >diff --git a/source4/kdc/wdc-samba4.c b/source4/kdc/wdc-samba4.c >index a7d8de1f417..68c8a8aa572 100644 >--- a/source4/kdc/wdc-samba4.c >+++ b/source4/kdc/wdc-samba4.c >@@ -186,7 +186,7 @@ static krb5_error_code samba_wdc_reget_pac(void *priv, krb5_context context, > } > > nt_status = samba_kdc_update_pac_blob(mem_ctx, context, >- krbtgt_skdc_entry, p, >+ krbtgt_skdc_entry->kdc_db_ctx->samdb, > *pac, pac_blob, > pac_srv_sig, pac_kdc_sig); > if (!NT_STATUS_IS_OK(nt_status)) { >-- >2.25.1 > > >From 8fe10cec1fbef992a6a82c01f56ae0b243d82ba5 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 6 Oct 2021 16:40:21 +1300 >Subject: [PATCH 118/159] s4:kdc: Fix debugging messages > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit c14c61748b5a2d2a4f4de00615c476fcf381309e) >--- > source4/kdc/wdc-samba4.c | 48 ++++++++++++++++++++-------------------- > 1 file changed, 24 insertions(+), 24 deletions(-) > >diff --git a/source4/kdc/wdc-samba4.c b/source4/kdc/wdc-samba4.c >index 68c8a8aa572..037db40ce46 100644 >--- a/source4/kdc/wdc-samba4.c >+++ b/source4/kdc/wdc-samba4.c >@@ -238,10 +238,10 @@ static krb5_error_code samba_wdc_reget_pac(void *priv, krb5_context context, > switch (types[i]) { > case PAC_TYPE_LOGON_INFO: > if (logon_info_idx != -1) { >- DEBUG(1, ("logon type[%d] twice [%d] and [%d]: \n", >- (int)types[i], >- (int)logon_info_idx, >- (int)i)); >+ DEBUG(1, ("logon info type[%"PRIu32"] twice [%zd] and [%zu]: \n", >+ types[i], >+ logon_info_idx, >+ i)); > SAFE_FREE(types); > talloc_free(mem_ctx); > return EINVAL; >@@ -250,10 +250,10 @@ static krb5_error_code samba_wdc_reget_pac(void *priv, krb5_context context, > break; > case PAC_TYPE_CONSTRAINED_DELEGATION: > if (delegation_idx != -1) { >- DEBUG(1, ("logon type[%d] twice [%d] and [%d]: \n", >- (int)types[i], >- (int)logon_info_idx, >- (int)i)); >+ DEBUG(1, ("constrained delegation type[%"PRIu32"] twice [%zd] and [%zu]: \n", >+ types[i], >+ delegation_idx, >+ i)); > SAFE_FREE(types); > talloc_free(mem_ctx); > return EINVAL; >@@ -262,10 +262,10 @@ static krb5_error_code samba_wdc_reget_pac(void *priv, krb5_context context, > break; > case PAC_TYPE_LOGON_NAME: > if (logon_name_idx != -1) { >- DEBUG(1, ("logon type[%d] twice [%d] and [%d]: \n", >- (int)types[i], >- (int)logon_info_idx, >- (int)i)); >+ DEBUG(1, ("logon name type[%"PRIu32"] twice [%zd] and [%zu]: \n", >+ types[i], >+ logon_name_idx, >+ i)); > SAFE_FREE(types); > talloc_free(mem_ctx); > return EINVAL; >@@ -274,10 +274,10 @@ static krb5_error_code samba_wdc_reget_pac(void *priv, krb5_context context, > break; > case PAC_TYPE_UPN_DNS_INFO: > if (upn_dns_info_idx != -1) { >- DEBUG(1, ("logon type[%d] twice [%d] and [%d]: \n", >- (int)types[i], >- (int)logon_info_idx, >- (int)i)); >+ DEBUG(1, ("upn dns info type[%"PRIu32"] twice [%zd] and [%zu]: \n", >+ types[i], >+ upn_dns_info_idx, >+ i)); > SAFE_FREE(types); > talloc_free(mem_ctx); > return EINVAL; >@@ -286,10 +286,10 @@ static krb5_error_code samba_wdc_reget_pac(void *priv, krb5_context context, > break; > case PAC_TYPE_SRV_CHECKSUM: > if (srv_checksum_idx != -1) { >- DEBUG(1, ("logon type[%d] twice [%d] and [%d]: \n", >- (int)types[i], >- (int)logon_info_idx, >- (int)i)); >+ DEBUG(1, ("server checksum type[%"PRIu32"] twice [%zd] and [%zu]: \n", >+ types[i], >+ srv_checksum_idx, >+ i)); > SAFE_FREE(types); > talloc_free(mem_ctx); > return EINVAL; >@@ -298,10 +298,10 @@ static krb5_error_code samba_wdc_reget_pac(void *priv, krb5_context context, > break; > case PAC_TYPE_KDC_CHECKSUM: > if (kdc_checksum_idx != -1) { >- DEBUG(1, ("logon type[%d] twice [%d] and [%d]: \n", >- (int)types[i], >- (int)logon_info_idx, >- (int)i)); >+ DEBUG(1, ("kdc checksum type[%"PRIu32"] twice [%zd] and [%zu]: \n", >+ types[i], >+ kdc_checksum_idx, >+ i)); > SAFE_FREE(types); > talloc_free(mem_ctx); > return EINVAL; >-- >2.25.1 > > >From 78e08e37b2362ea16670a8f036f162c05eb49c0b Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 8 Oct 2021 15:42:29 +1300 >Subject: [PATCH 119/159] s4/torture: Expect ticket checksum PAC buffer > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >[abartlet@samba.org backported from commit d5002c34ce1ffef795dc83af3175ca0e04d17dfd > due to missing tests in Samba 4.14 that crashed the MIT KDC] >--- > selftest/knownfail_heimdal_kdc | 41 ++++++++++++++++++++++++++++++++ > selftest/knownfail_mit_kdc | 41 ++++++++++++++++++++++++++++++++ > source4/torture/rpc/remote_pac.c | 14 +++++++++-- > 3 files changed, 94 insertions(+), 2 deletions(-) > >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 0b8e83f1f3f..31572067ad4 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -154,3 +154,44 @@ > # RODC tests > # > ^samba.tests.krb5.rodc_tests.samba.tests.krb5.rodc_tests.RodcKerberosTests.test_rodc_ticket_signature >+# >+# PAC tests >+# >+^netr-bdc-arcfour.verify-sig-arcfour >+^netr-bdc-arcfour.verify-sig-arcfour >+^samba4.blackbox.pkinit_pac.STEP1 remote.pac verification.ad_dc:local >+^samba4.blackbox.pkinit_pac.STEP1 remote.pac verification.ad_dc_ntvfs:local >+^samba4.blackbox.pkinit_pac.netr-bdc-aes.verify-sig-aes.ad_dc:local >+^samba4.blackbox.pkinit_pac.netr-bdc-aes.verify-sig-aes.ad_dc_ntvfs:local >+^samba4.blackbox.pkinit_pac.netr-mem-aes.s4u2proxy-aes.ad_dc:local >+^samba4.blackbox.pkinit_pac.netr-mem-aes.s4u2proxy-aes.ad_dc_ntvfs:local >+^samba4.blackbox.pkinit_pac.netr-mem-aes.verify-sig-aes.ad_dc:local >+^samba4.blackbox.pkinit_pac.netr-mem-aes.verify-sig-aes.ad_dc_ntvfs:local >+^samba4.blackbox.pkinit_pac.netr-mem-arcfour.s4u2proxy-arcfour.ad_dc:local >+^samba4.blackbox.pkinit_pac.netr-mem-arcfour.s4u2proxy-arcfour.ad_dc_ntvfs:local >+^samba4.blackbox.pkinit_pac.netr-mem-arcfour.verify-sig-arcfour.ad_dc:local >+^samba4.blackbox.pkinit_pac.netr-mem-arcfour.verify-sig-arcfour.ad_dc_ntvfs:local >+^samba4.rpc.pac on ncacn_np.netr-bdc-aes.verify-sig-aes.fl2000dc >+^samba4.rpc.pac on ncacn_np.netr-bdc-aes.verify-sig-aes.fl2003dc >+^samba4.rpc.pac on ncacn_np.netr-bdc-aes.verify-sig-aes.fl2008dc >+^samba4.rpc.pac on ncacn_np.netr-bdc-aes.verify-sig-aes.fl2008r2dc >+^samba4.rpc.pac on ncacn_np.netr-bdc-arcfour.verify-sig-arcfour.fl2000dc >+^samba4.rpc.pac on ncacn_np.netr-bdc-arcfour.verify-sig-arcfour.fl2003dc >+^samba4.rpc.pac on ncacn_np.netr-bdc-arcfour.verify-sig-arcfour.fl2008dc >+^samba4.rpc.pac on ncacn_np.netr-bdc-arcfour.verify-sig-arcfour.fl2008r2dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.s4u2proxy-aes.fl2000dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.s4u2proxy-aes.fl2003dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.s4u2proxy-aes.fl2008dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.s4u2proxy-aes.fl2008r2dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.verify-sig-aes.fl2000dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.verify-sig-aes.fl2003dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.verify-sig-aes.fl2008dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.verify-sig-aes.fl2008r2dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.s4u2proxy-arcfour.fl2000dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.s4u2proxy-arcfour.fl2003dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.s4u2proxy-arcfour.fl2008dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.s4u2proxy-arcfour.fl2008r2dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2000dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2003dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2008dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2008r2dc >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >index 4e0b20c5c80..09efbc7b590 100644 >--- a/selftest/knownfail_mit_kdc >+++ b/selftest/knownfail_mit_kdc >@@ -329,3 +329,44 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_fast_no_etypes.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_no_sname.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_tgs_no_sname.ad_dc >+# >+# PAC tests >+# >+^netr-bdc-arcfour.verify-sig-arcfour >+^netr-bdc-arcfour.verify-sig-arcfour >+^samba4.blackbox.pkinit_pac.STEP1 remote.pac verification.ad_dc:local >+^samba4.blackbox.pkinit_pac.STEP1 remote.pac verification.ad_dc_ntvfs:local >+^samba4.blackbox.pkinit_pac.netr-bdc-aes.verify-sig-aes.ad_dc:local >+^samba4.blackbox.pkinit_pac.netr-bdc-aes.verify-sig-aes.ad_dc_ntvfs:local >+^samba4.blackbox.pkinit_pac.netr-mem-aes.s4u2proxy-aes.ad_dc:local >+^samba4.blackbox.pkinit_pac.netr-mem-aes.s4u2proxy-aes.ad_dc_ntvfs:local >+^samba4.blackbox.pkinit_pac.netr-mem-aes.verify-sig-aes.ad_dc:local >+^samba4.blackbox.pkinit_pac.netr-mem-aes.verify-sig-aes.ad_dc_ntvfs:local >+^samba4.blackbox.pkinit_pac.netr-mem-arcfour.s4u2proxy-arcfour.ad_dc:local >+^samba4.blackbox.pkinit_pac.netr-mem-arcfour.s4u2proxy-arcfour.ad_dc_ntvfs:local >+^samba4.blackbox.pkinit_pac.netr-mem-arcfour.verify-sig-arcfour.ad_dc:local >+^samba4.blackbox.pkinit_pac.netr-mem-arcfour.verify-sig-arcfour.ad_dc_ntvfs:local >+^samba4.rpc.pac on ncacn_np.netr-bdc-aes.verify-sig-aes.fl2000dc >+^samba4.rpc.pac on ncacn_np.netr-bdc-aes.verify-sig-aes.fl2003dc >+^samba4.rpc.pac on ncacn_np.netr-bdc-aes.verify-sig-aes.fl2008dc >+^samba4.rpc.pac on ncacn_np.netr-bdc-aes.verify-sig-aes.fl2008r2dc >+^samba4.rpc.pac on ncacn_np.netr-bdc-arcfour.verify-sig-arcfour.fl2000dc >+^samba4.rpc.pac on ncacn_np.netr-bdc-arcfour.verify-sig-arcfour.fl2003dc >+^samba4.rpc.pac on ncacn_np.netr-bdc-arcfour.verify-sig-arcfour.fl2008dc >+^samba4.rpc.pac on ncacn_np.netr-bdc-arcfour.verify-sig-arcfour.fl2008r2dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.s4u2proxy-aes.fl2000dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.s4u2proxy-aes.fl2003dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.s4u2proxy-aes.fl2008dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.s4u2proxy-aes.fl2008r2dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.verify-sig-aes.fl2000dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.verify-sig-aes.fl2003dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.verify-sig-aes.fl2008dc >+^samba4.rpc.pac on ncacn_np.netr-mem-aes.verify-sig-aes.fl2008r2dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.s4u2proxy-arcfour.fl2000dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.s4u2proxy-arcfour.fl2003dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.s4u2proxy-arcfour.fl2008dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.s4u2proxy-arcfour.fl2008r2dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2000dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2003dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2008dc >+^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2008r2dc >diff --git a/source4/torture/rpc/remote_pac.c b/source4/torture/rpc/remote_pac.c >index c74746123fe..14c23f674f1 100644 >--- a/source4/torture/rpc/remote_pac.c >+++ b/source4/torture/rpc/remote_pac.c >@@ -266,7 +266,7 @@ static bool test_PACVerify(struct torture_context *tctx, > (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA); > torture_assert(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), "ndr_pull_struct_blob of PAC_DATA structure failed"); > >- num_pac_buffers = 4; >+ num_pac_buffers = 5; > if (expect_pac_upn_dns_info) { > num_pac_buffers += 1; > } >@@ -317,6 +317,12 @@ static bool test_PACVerify(struct torture_context *tctx, > pac_buf->info != NULL, > "PAC_TYPE_KDC_CHECKSUM info"); > >+ pac_buf = get_pac_buffer(&pac_data_struct, PAC_TYPE_TICKET_CHECKSUM); >+ torture_assert_not_null(tctx, pac_buf, "PAC_TYPE_TICKET_CHECKSUM"); >+ torture_assert(tctx, >+ pac_buf->info != NULL, >+ "PAC_TYPE_TICKET_CHECKSUM info"); >+ > ok = netlogon_validate_pac(tctx, p, server_creds, secure_channel_type, test_machine_name, > negotiate_flags, pac_data, session_info); > >@@ -1076,7 +1082,7 @@ static bool test_S4U2Proxy(struct torture_context *tctx, > (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA); > torture_assert(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), "ndr_pull_struct_blob of PAC_DATA structure failed"); > >- num_pac_buffers = 6; >+ num_pac_buffers = 7; > > torture_assert_int_equal(tctx, pac_data_struct.version, 0, "version"); > torture_assert_int_equal(tctx, pac_data_struct.num_buffers, num_pac_buffers, "num_buffers"); >@@ -1101,6 +1107,10 @@ static bool test_S4U2Proxy(struct torture_context *tctx, > torture_assert_not_null(tctx, pac_buf, "PAC_TYPE_KDC_CHECKSUM"); > torture_assert_not_null(tctx, pac_buf->info, "PAC_TYPE_KDC_CHECKSUM info"); > >+ pac_buf = get_pac_buffer(&pac_data_struct, PAC_TYPE_TICKET_CHECKSUM); >+ torture_assert_not_null(tctx, pac_buf, "PAC_TYPE_TICKET_CHECKSUM"); >+ torture_assert_not_null(tctx, pac_buf->info, "PAC_TYPE_TICKET_CHECKSUM info"); >+ > pac_buf = get_pac_buffer(&pac_data_struct, PAC_TYPE_CONSTRAINED_DELEGATION); > torture_assert_not_null(tctx, pac_buf, "PAC_TYPE_CONSTRAINED_DELEGATION"); > torture_assert_not_null(tctx, pac_buf->info, "PAC_TYPE_CONSTRAINED_DELEGATION info"); >-- >2.25.1 > > >From fc145c34b1a90b6c84f6d93d6cc85dcd93397d6d Mon Sep 17 00:00:00 2001 >From: Isaac Boukris <iboukris@gmail.com> >Date: Mon, 28 Dec 2020 22:07:10 +0200 >Subject: [PATCH 120/159] kdc: remove KRB5SignedPath, to be replaced with PAC > >KRB5SignedPath was a Heimdal-specific authorization data element used to >protect the authenticity of evidence tickets when used in constrained >delegation (without a Windows PAC). > >Remove this, to be replaced with the Windows PAC which itself now supports >signing the entire ticket in the TGS key. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >[jsutton@samba.org Backported from Heimdal commit > bb1d8f2a8c2545bccdf2c9179ce9259bf1050086 > - Removed tests > - Removed auditing hook (only present in Heimdal master) > - Added knownfails >] > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit ccabc7f16cca5b0dcb46233e934e708167f1071b) >--- > selftest/knownfail_heimdal_kdc | 6 + > source4/heimdal/kdc/kerberos5.c | 12 -- > source4/heimdal/kdc/krb5tgs.c | 297 ----------------------------- > source4/heimdal/lib/asn1/krb5.asn1 | 21 -- > 4 files changed, 6 insertions(+), 330 deletions(-) > >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 31572067ad4..f0263133eee 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -130,6 +130,7 @@ > # > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_bronze_bit_rbcd_old_checksum > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_missing_client_checksum >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_no_service_pac > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_unkeyed_client_checksum > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_unkeyed_service_checksum > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_zeroed_client_checksum >@@ -195,3 +196,8 @@ > ^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2003dc > ^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2008dc > ^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2008r2dc >+# >+# The lack of KRB5SignedPath means we no longer return >+# KRB5KRB_ERR_RESPONSE_TOO_BIG in this specific case >+# >+^samba4.krb5.kdc with machine account.as-req-pac-request.fl2000dc:local >diff --git a/source4/heimdal/kdc/kerberos5.c b/source4/heimdal/kdc/kerberos5.c >index 0fa336e871c..a400b21a652 100644 >--- a/source4/heimdal/kdc/kerberos5.c >+++ b/source4/heimdal/kdc/kerberos5.c >@@ -1744,18 +1744,6 @@ _kdc_as_rep(krb5_context context, > _kdc_log_timestamp(context, config, "AS-REQ", et.authtime, et.starttime, > et.endtime, et.renew_till); > >- /* do this as the last thing since this signs the EncTicketPart */ >- ret = _kdc_add_KRB5SignedPath(context, >- config, >- server, >- setype, >- client->entry.principal, >- NULL, >- NULL, >- &et); >- if (ret) >- goto out; >- > log_as_req(context, config, reply_key->keytype, setype, b); > > ret = _kdc_encode_reply(context, config, >diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c >index d143eb739eb..c6bab82f517 100644 >--- a/source4/heimdal/kdc/krb5tgs.c >+++ b/source4/heimdal/kdc/krb5tgs.c >@@ -47,230 +47,6 @@ get_krbtgt_realm(const PrincipalName *p) > return NULL; > } > >-/* >- * The KDC might add a signed path to the ticket authorization data >- * field. This is to avoid server impersonating clients and the >- * request constrained delegation. >- * >- * This is done by storing a KRB5_AUTHDATA_IF_RELEVANT with a single >- * entry of type KRB5SignedPath. >- */ >- >-static krb5_error_code >-find_KRB5SignedPath(krb5_context context, >- const AuthorizationData *ad, >- krb5_data *data) >-{ >- AuthorizationData child; >- krb5_error_code ret; >- int pos; >- >- if (ad == NULL || ad->len == 0) >- return KRB5KDC_ERR_PADATA_TYPE_NOSUPP; >- >- pos = ad->len - 1; >- >- if (ad->val[pos].ad_type != KRB5_AUTHDATA_IF_RELEVANT) >- return KRB5KDC_ERR_PADATA_TYPE_NOSUPP; >- >- ret = decode_AuthorizationData(ad->val[pos].ad_data.data, >- ad->val[pos].ad_data.length, >- &child, >- NULL); >- if (ret) { >- krb5_set_error_message(context, ret, "Failed to decode " >- "IF_RELEVANT with %d", ret); >- return ret; >- } >- >- if (child.len != 1) { >- free_AuthorizationData(&child); >- return KRB5KDC_ERR_PADATA_TYPE_NOSUPP; >- } >- >- if (child.val[0].ad_type != KRB5_AUTHDATA_SIGNTICKET) { >- free_AuthorizationData(&child); >- return KRB5KDC_ERR_PADATA_TYPE_NOSUPP; >- } >- >- if (data) >- ret = der_copy_octet_string(&child.val[0].ad_data, data); >- free_AuthorizationData(&child); >- return ret; >-} >- >-krb5_error_code >-_kdc_add_KRB5SignedPath(krb5_context context, >- krb5_kdc_configuration *config, >- hdb_entry_ex *krbtgt, >- krb5_enctype enctype, >- krb5_principal client, >- krb5_const_principal server, >- krb5_principals principals, >- EncTicketPart *tkt) >-{ >- krb5_error_code ret; >- KRB5SignedPath sp; >- krb5_data data; >- krb5_crypto crypto = NULL; >- size_t size = 0; >- >- if (server && principals) { >- ret = add_Principals(principals, server); >- if (ret) >- return ret; >- } >- >- { >- KRB5SignedPathData spd; >- >- spd.client = client; >- spd.authtime = tkt->authtime; >- spd.delegated = principals; >- spd.method_data = NULL; >- >- ASN1_MALLOC_ENCODE(KRB5SignedPathData, data.data, data.length, >- &spd, &size, ret); >- if (ret) >- return ret; >- if (data.length != size) >- krb5_abortx(context, "internal asn.1 encoder error"); >- } >- >- { >- Key *key; >- ret = hdb_enctype2key(context, &krbtgt->entry, enctype, &key); >- if (ret == 0) >- ret = krb5_crypto_init(context, &key->key, 0, &crypto); >- if (ret) { >- free(data.data); >- return ret; >- } >- } >- >- /* >- * Fill in KRB5SignedPath >- */ >- >- sp.etype = enctype; >- sp.delegated = principals; >- sp.method_data = NULL; >- >- ret = krb5_create_checksum(context, crypto, KRB5_KU_KRB5SIGNEDPATH, 0, >- data.data, data.length, &sp.cksum); >- krb5_crypto_destroy(context, crypto); >- free(data.data); >- if (ret) >- return ret; >- >- ASN1_MALLOC_ENCODE(KRB5SignedPath, data.data, data.length, &sp, &size, ret); >- free_Checksum(&sp.cksum); >- if (ret) >- return ret; >- if (data.length != size) >- krb5_abortx(context, "internal asn.1 encoder error"); >- >- >- /* >- * Add IF-RELEVANT(KRB5SignedPath) to the last slot in >- * authorization data field. >- */ >- >- ret = _kdc_tkt_add_if_relevant_ad(context, tkt, >- KRB5_AUTHDATA_SIGNTICKET, &data); >- krb5_data_free(&data); >- >- return ret; >-} >- >-static krb5_error_code >-check_KRB5SignedPath(krb5_context context, >- krb5_kdc_configuration *config, >- hdb_entry_ex *krbtgt, >- krb5_principal cp, >- EncTicketPart *tkt, >- krb5_principals *delegated, >- int *signedpath) >-{ >- krb5_error_code ret; >- krb5_data data; >- krb5_crypto crypto = NULL; >- >- if (delegated) >- *delegated = NULL; >- >- ret = find_KRB5SignedPath(context, tkt->authorization_data, &data); >- if (ret == 0) { >- KRB5SignedPathData spd; >- KRB5SignedPath sp; >- size_t size = 0; >- >- ret = decode_KRB5SignedPath(data.data, data.length, &sp, NULL); >- krb5_data_free(&data); >- if (ret) >- return ret; >- >- spd.client = cp; >- spd.authtime = tkt->authtime; >- spd.delegated = sp.delegated; >- spd.method_data = sp.method_data; >- >- ASN1_MALLOC_ENCODE(KRB5SignedPathData, data.data, data.length, >- &spd, &size, ret); >- if (ret) { >- free_KRB5SignedPath(&sp); >- return ret; >- } >- if (data.length != size) >- krb5_abortx(context, "internal asn.1 encoder error"); >- >- { >- Key *key; >- ret = hdb_enctype2key(context, &krbtgt->entry, sp.etype, &key); >- if (ret == 0) >- ret = krb5_crypto_init(context, &key->key, 0, &crypto); >- if (ret) { >- free(data.data); >- free_KRB5SignedPath(&sp); >- return ret; >- } >- } >- ret = krb5_verify_checksum(context, crypto, KRB5_KU_KRB5SIGNEDPATH, >- data.data, data.length, >- &sp.cksum); >- krb5_crypto_destroy(context, crypto); >- free(data.data); >- if (ret) { >- free_KRB5SignedPath(&sp); >- kdc_log(context, config, 5, >- "KRB5SignedPath not signed correctly, not marking as signed"); >- return 0; >- } >- >- if (delegated && sp.delegated) { >- >- *delegated = malloc(sizeof(*sp.delegated)); >- if (*delegated == NULL) { >- free_KRB5SignedPath(&sp); >- return ENOMEM; >- } >- >- ret = copy_Principals(*delegated, sp.delegated); >- if (ret) { >- free_KRB5SignedPath(&sp); >- free(*delegated); >- *delegated = NULL; >- return ret; >- } >- } >- free_KRB5SignedPath(&sp); >- >- *signedpath = 1; >- } >- >- return 0; >-} >- > /* > * > */ >@@ -738,7 +514,6 @@ tgs_make_reply(krb5_context context, > krb5_principal client_principal, > hdb_entry_ex *krbtgt, > krb5_enctype krbtgt_etype, >- krb5_principals spp, > const krb5_data *rspac, > const METHOD_DATA *enc_pa_data, > const char **e_text, >@@ -903,20 +678,6 @@ tgs_make_reply(krb5_context context, > goto out; > } > } >- >- /* Filter out type KRB5SignedPath */ >- ret = find_KRB5SignedPath(context, et.authorization_data, NULL); >- if (ret == 0) { >- if (et.authorization_data->len == 1) { >- free_AuthorizationData(et.authorization_data); >- free(et.authorization_data); >- et.authorization_data = NULL; >- } else { >- AuthorizationData *ad = et.authorization_data; >- free_AuthorizationDataElement(&ad->val[ad->len - 1]); >- ad->len--; >- } >- } > } > > ret = krb5_copy_keyblock_contents(context, sessionkey, &et.key); >@@ -945,24 +706,6 @@ tgs_make_reply(krb5_context context, > _kdc_log_timestamp(context, config, "TGS-REQ", et.authtime, et.starttime, > et.endtime, et.renew_till); > >- /* Don't sign cross realm tickets, they can't be checked anyway */ >- { >- char *r = get_krbtgt_realm(&ek.sname); >- >- if (r == NULL || strcmp(r, ek.srealm) == 0) { >- ret = _kdc_add_KRB5SignedPath(context, >- config, >- krbtgt, >- krbtgt_etype, >- client_principal, >- NULL, >- spp, >- &et); >- if (ret) >- goto out; >- } >- } >- > if (enc_pa_data->len) { > rep.padata = calloc(1, sizeof(*rep.padata)); > if (rep.padata == NULL) { >@@ -1517,7 +1260,6 @@ tgs_build_reply(krb5_context context, > HDB *clientdb, *s4u2self_impersonated_clientdb; > krb5_realm ref_realm = NULL; > EncTicketPart *tgt = &ticket->ticket; >- krb5_principals spp = NULL; > const EncryptionKey *ekey; > krb5_keyblock sessionkey; > krb5_kvno kvno; >@@ -1891,23 +1633,6 @@ server_lookup: > goto out; > } > >- /* also check the krbtgt for signature */ >- ret = check_KRB5SignedPath(context, >- config, >- krbtgt, >- cp, >- tgt, >- &spp, >- &signedpath); >- if (ret) { >- const char *msg = krb5_get_error_message(context, ret); >- kdc_log(context, config, 0, >- "KRB5SignedPath check failed for %s (%s) from %s with %s", >- spn, cpn, from, msg); >- krb5_free_error_message(context, msg); >- goto out; >- } >- > /* > * Process request > */ >@@ -2200,27 +1925,6 @@ server_lookup: > goto out; > } > >- /* >- * Check that the KDC issued the user's ticket. >- */ >- ret = check_KRB5SignedPath(context, >- config, >- krbtgt, >- cp, >- &adtkt, >- NULL, >- &ad_signedpath); >- if (ret) { >- const char *msg = krb5_get_error_message(context, ret); >- kdc_log(context, config, 0, >- "KRB5SignedPath check from service %s failed " >- "for delegation to %s for client %s (%s)" >- "from %s failed with %s", >- spn, tpn, dpn, cpn, from, msg); >- krb5_free_error_message(context, msg); >- goto out; >- } >- > if (!ad_signedpath) { > ret = KRB5KDC_ERR_BADOPTION; > kdc_log(context, config, 0, >@@ -2318,7 +2022,6 @@ server_lookup: > cp, > krbtgt_out, > krbtgt_etype, >- spp, > &rspac, > &enc_pa_data, > e_text, >diff --git a/source4/heimdal/lib/asn1/krb5.asn1 b/source4/heimdal/lib/asn1/krb5.asn1 >index c2f40c0ecd6..155d51d4ac8 100644 >--- a/source4/heimdal/lib/asn1/krb5.asn1 >+++ b/source4/heimdal/lib/asn1/krb5.asn1 >@@ -43,9 +43,6 @@ EXPORTS > KRB-PRIV, > KRB-SAFE, > KRB-SAFE-BODY, >- KRB5SignedPath, >- KRB5SignedPathData, >- KRB5SignedPathPrincipals, > KerberosString, > KerberosTime, > KrbCredInfo, >@@ -713,24 +710,6 @@ PA-S4U2Self ::= SEQUENCE { > auth[3] GeneralString > } > >--- never encoded on the wire, just used to checksum over >-KRB5SignedPathData ::= SEQUENCE { >- client[0] Principal OPTIONAL, >- authtime[1] KerberosTime, >- delegated[2] Principals OPTIONAL, >- method_data[3] METHOD-DATA OPTIONAL >-} >- >-KRB5SignedPath ::= SEQUENCE { >- -- DERcoded KRB5SignedPathData >- -- krbtgt key (etype), KeyUsage = XXX >- etype[0] ENCTYPE, >- cksum[1] Checksum, >- -- srvs delegated though >- delegated[2] Principals OPTIONAL, >- method_data[3] METHOD-DATA OPTIONAL >-} >- > AD-LoginAlias ::= SEQUENCE { -- ad-type number TBD -- > login-alias [0] PrincipalName, > checksum [1] Checksum >-- >2.25.1 > > >From a361e0b98725e61c6ed57793d37bc416ab9ac4bb Mon Sep 17 00:00:00 2001 >From: Isaac Boukris <iboukris@gmail.com> >Date: Fri, 13 Aug 2021 12:44:37 +0300 >Subject: [PATCH 121/159] kdc: sign ticket using Windows PAC > >Split Windows PAC signing and verification logic, as the signing has to be when >the ticket is ready. > >Create sign and verify the PAC KDC signature if the plugin did not, allowing >for S4U2Proxy to work, instead of KRB5SignedPath. > >Use the header key to verify PAC server signature, as the same key used to >encrypt/decrypt the ticket should be used for PAC server signature, like U2U >tickets are signed witht the tgt session-key and not with the longterm key, >and so krbtgt should be no different and the header key should be used. > >Lookup the delegated client in DB instead of passing the delegator DB entry. > >Add PAC ticket-signatures and related functions. > >Note: due to the change from KRB5SignedPath to PAC, S4U2Proxy requests >against new KDC will not work if the evidence ticket was acquired from >an old KDC, and vide versa. > >Closes: #767 > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >[jsutton@samba.org Backported from Heimdal commit > 2ffaba9401d19c718764d4bd24180960290238e9 > - Removed tests > - Adapted to Samba's version of Heimdal > - Addressed build failures with -O3 > - Added knownfails >] > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >[abartlet@samba.org backported from commit d7b03394a9012960d71489e775d40d10fd6f5232 > due to conflicts in knownfail due to missing tests that crash the > MIT KDC] >--- > selftest/knownfail_heimdal_kdc | 54 +-- > source4/heimdal/kdc/kerberos5.c | 69 +--- > source4/heimdal/kdc/krb5tgs.c | 354 +++++++++--------- > source4/heimdal/kdc/windc.c | 15 +- > source4/heimdal/kdc/windc_plugin.h | 5 +- > source4/heimdal/lib/krb5/authdata.c | 124 +++++++ > source4/heimdal/lib/krb5/pac.c | 376 ++++++++++++++++++-- > source4/heimdal/lib/krb5/version-script.map | 5 + > source4/heimdal_build/wscript_build | 2 +- > source4/selftest/tests.py | 2 +- > 10 files changed, 687 insertions(+), 319 deletions(-) > create mode 100644 source4/heimdal/lib/krb5/authdata.c > >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index f0263133eee..4ec682c01d0 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -1,7 +1,7 @@ > # > # We expect all the MIT specific compatability tests to fail on heimdal > # kerberos >-^samba.tests.krb5.compatability_tests.samba.tests.krb5.compatability_tests.SimpleKerberosTests.test_mit_(?!ticket_signature) >+^samba.tests.krb5.compatability_tests.samba.tests.krb5.compatability_tests.SimpleKerberosTests.test_mit_ > # > # Heimdal currently fails the following MS-KILE client principal lookup > # tests >@@ -122,14 +122,9 @@ > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_outer_no_sname.ad_dc > ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_no_sname.ad_dc > # >-# Heimdal currently does not generate ticket signatures >-# >-^samba.tests.krb5.compatability_tests.samba.tests.krb5.compatability_tests.SimpleKerberosTests.test_heimdal_ticket_signature >-# > # S4U tests > # > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_bronze_bit_rbcd_old_checksum >-^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_missing_client_checksum > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_no_service_pac > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_unkeyed_client_checksum > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_unkeyed_service_checksum >@@ -143,60 +138,13 @@ > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_unkeyed_service_checksum > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_zeroed_client_checksum > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_zeroed_service_checksum >-^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_client_not_delegated > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_forwardable >-^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_not_forwardable > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_not_trusted_empty_allowed >-^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_not_trusted_nonempty_allowed >-^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_trusted_empty_allowed >-^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_trusted_nonempty_allowed >-^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_without_forwardable > # > # RODC tests > # > ^samba.tests.krb5.rodc_tests.samba.tests.krb5.rodc_tests.RodcKerberosTests.test_rodc_ticket_signature > # >-# PAC tests >-# >-^netr-bdc-arcfour.verify-sig-arcfour >-^netr-bdc-arcfour.verify-sig-arcfour >-^samba4.blackbox.pkinit_pac.STEP1 remote.pac verification.ad_dc:local >-^samba4.blackbox.pkinit_pac.STEP1 remote.pac verification.ad_dc_ntvfs:local >-^samba4.blackbox.pkinit_pac.netr-bdc-aes.verify-sig-aes.ad_dc:local >-^samba4.blackbox.pkinit_pac.netr-bdc-aes.verify-sig-aes.ad_dc_ntvfs:local >-^samba4.blackbox.pkinit_pac.netr-mem-aes.s4u2proxy-aes.ad_dc:local >-^samba4.blackbox.pkinit_pac.netr-mem-aes.s4u2proxy-aes.ad_dc_ntvfs:local >-^samba4.blackbox.pkinit_pac.netr-mem-aes.verify-sig-aes.ad_dc:local >-^samba4.blackbox.pkinit_pac.netr-mem-aes.verify-sig-aes.ad_dc_ntvfs:local >-^samba4.blackbox.pkinit_pac.netr-mem-arcfour.s4u2proxy-arcfour.ad_dc:local >-^samba4.blackbox.pkinit_pac.netr-mem-arcfour.s4u2proxy-arcfour.ad_dc_ntvfs:local >-^samba4.blackbox.pkinit_pac.netr-mem-arcfour.verify-sig-arcfour.ad_dc:local >-^samba4.blackbox.pkinit_pac.netr-mem-arcfour.verify-sig-arcfour.ad_dc_ntvfs:local >-^samba4.rpc.pac on ncacn_np.netr-bdc-aes.verify-sig-aes.fl2000dc >-^samba4.rpc.pac on ncacn_np.netr-bdc-aes.verify-sig-aes.fl2003dc >-^samba4.rpc.pac on ncacn_np.netr-bdc-aes.verify-sig-aes.fl2008dc >-^samba4.rpc.pac on ncacn_np.netr-bdc-aes.verify-sig-aes.fl2008r2dc >-^samba4.rpc.pac on ncacn_np.netr-bdc-arcfour.verify-sig-arcfour.fl2000dc >-^samba4.rpc.pac on ncacn_np.netr-bdc-arcfour.verify-sig-arcfour.fl2003dc >-^samba4.rpc.pac on ncacn_np.netr-bdc-arcfour.verify-sig-arcfour.fl2008dc >-^samba4.rpc.pac on ncacn_np.netr-bdc-arcfour.verify-sig-arcfour.fl2008r2dc >-^samba4.rpc.pac on ncacn_np.netr-mem-aes.s4u2proxy-aes.fl2000dc >-^samba4.rpc.pac on ncacn_np.netr-mem-aes.s4u2proxy-aes.fl2003dc >-^samba4.rpc.pac on ncacn_np.netr-mem-aes.s4u2proxy-aes.fl2008dc >-^samba4.rpc.pac on ncacn_np.netr-mem-aes.s4u2proxy-aes.fl2008r2dc >-^samba4.rpc.pac on ncacn_np.netr-mem-aes.verify-sig-aes.fl2000dc >-^samba4.rpc.pac on ncacn_np.netr-mem-aes.verify-sig-aes.fl2003dc >-^samba4.rpc.pac on ncacn_np.netr-mem-aes.verify-sig-aes.fl2008dc >-^samba4.rpc.pac on ncacn_np.netr-mem-aes.verify-sig-aes.fl2008r2dc >-^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.s4u2proxy-arcfour.fl2000dc >-^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.s4u2proxy-arcfour.fl2003dc >-^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.s4u2proxy-arcfour.fl2008dc >-^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.s4u2proxy-arcfour.fl2008r2dc >-^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2000dc >-^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2003dc >-^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2008dc >-^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2008r2dc >-# > # The lack of KRB5SignedPath means we no longer return > # KRB5KRB_ERR_RESPONSE_TOO_BIG in this specific case > # >diff --git a/source4/heimdal/kdc/kerberos5.c b/source4/heimdal/kdc/kerberos5.c >index a400b21a652..7b17d2539ce 100644 >--- a/source4/heimdal/kdc/kerberos5.c >+++ b/source4/heimdal/kdc/kerberos5.c >@@ -1712,6 +1712,7 @@ _kdc_as_rep(krb5_context context, > if (send_pac_p(context, req)) { > krb5_pac p = NULL; > krb5_data data; >+ uint16_t rodc_id; > > ret = _kdc_pac_generate(context, client, pk_reply_key, &p); > if (ret) { >@@ -1720,10 +1721,13 @@ _kdc_as_rep(krb5_context context, > goto out; > } > if (p != NULL) { >+ rodc_id = server->entry.kvno >> 16; >+ > ret = _krb5_pac_sign(context, p, et.authtime, > client->entry.principal, > &skey->key, /* Server key */ > &skey->key, /* FIXME: should be krbtgt key */ >+ rodc_id, > &data); > krb5_pac_free(context, p); > if (ret) { >@@ -1732,9 +1736,7 @@ _kdc_as_rep(krb5_context context, > goto out; > } > >- ret = _kdc_tkt_add_if_relevant_ad(context, &et, >- KRB5_AUTHDATA_WIN2K_PAC, >- &data); >+ ret = _kdc_tkt_insert_pac(context, &et, &data); > krb5_data_free(&data); > if (ret) > goto out; >@@ -1888,64 +1890,3 @@ prepare_enc_data(krb5_context context, > > return TRUE; > } >- >-/* >- * Add the AuthorizationData `data´ of `type´ to the last element in >- * the sequence of authorization_data in `tkt´ wrapped in an IF_RELEVANT >- */ >- >-krb5_error_code >-_kdc_tkt_add_if_relevant_ad(krb5_context context, >- EncTicketPart *tkt, >- int type, >- const krb5_data *data) >-{ >- krb5_error_code ret; >- size_t size = 0; >- >- if (tkt->authorization_data == NULL) { >- tkt->authorization_data = calloc(1, sizeof(*tkt->authorization_data)); >- if (tkt->authorization_data == NULL) { >- krb5_set_error_message(context, ENOMEM, "out of memory"); >- return ENOMEM; >- } >- } >- >- /* add the entry to the last element */ >- { >- AuthorizationData ad = { 0, NULL }; >- AuthorizationDataElement ade; >- >- ade.ad_type = type; >- ade.ad_data = *data; >- >- ret = add_AuthorizationData(&ad, &ade); >- if (ret) { >- krb5_set_error_message(context, ret, "add AuthorizationData failed"); >- return ret; >- } >- >- ade.ad_type = KRB5_AUTHDATA_IF_RELEVANT; >- >- ASN1_MALLOC_ENCODE(AuthorizationData, >- ade.ad_data.data, ade.ad_data.length, >- &ad, &size, ret); >- free_AuthorizationData(&ad); >- if (ret) { >- krb5_set_error_message(context, ret, "ASN.1 encode of " >- "AuthorizationData failed"); >- return ret; >- } >- if (ade.ad_data.length != size) >- krb5_abortx(context, "internal asn.1 encoder error"); >- >- ret = add_AuthorizationData(tkt->authorization_data, &ade); >- der_free_octet_string(&ade.ad_data); >- if (ret) { >- krb5_set_error_message(context, ret, "add AuthorizationData failed"); >- return ret; >- } >- } >- >- return 0; >-} >diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c >index c6bab82f517..3b35b828402 100644 >--- a/source4/heimdal/kdc/krb5tgs.c >+++ b/source4/heimdal/kdc/krb5tgs.c >@@ -59,85 +59,64 @@ check_PAC(krb5_context context, > hdb_entry_ex *client, > hdb_entry_ex *server, > hdb_entry_ex *krbtgt, >+ hdb_entry_ex *ticket_server, > const EncryptionKey *server_check_key, >- const EncryptionKey *server_sign_key, >- const EncryptionKey *krbtgt_sign_key, >+ const EncryptionKey *krbtgt_check_key, > EncTicketPart *tkt, >- krb5_data *rspac, >- int *signedpath) >+ krb5_boolean *kdc_issued, >+ krb5_pac *ppac) > { >- AuthorizationData *ad = tkt->authorization_data; >- unsigned i, j; >+ krb5_pac pac = NULL; > krb5_error_code ret; >+ krb5_boolean signedticket; > >- if (ad == NULL || ad->len == 0) >- return 0; >- >- for (i = 0; i < ad->len; i++) { >- AuthorizationData child; >- >- if (ad->val[i].ad_type != KRB5_AUTHDATA_IF_RELEVANT) >- continue; >- >- ret = decode_AuthorizationData(ad->val[i].ad_data.data, >- ad->val[i].ad_data.length, >- &child, >- NULL); >- if (ret) { >- krb5_set_error_message(context, ret, "Failed to decode " >- "IF_RELEVANT with %d", ret); >- return ret; >- } >- for (j = 0; j < child.len; j++) { >- >- if (child.val[j].ad_type == KRB5_AUTHDATA_WIN2K_PAC) { >- int signed_pac = 0; >- krb5_pac pac; >- >- /* Found PAC */ >- ret = krb5_pac_parse(context, >- child.val[j].ad_data.data, >- child.val[j].ad_data.length, >- &pac); >- free_AuthorizationData(&child); >- if (ret) >- return ret; >+ *kdc_issued = FALSE; >+ *ppac = NULL; > >- ret = krb5_pac_verify(context, pac, tkt->authtime, >- client_principal, >- server_check_key, NULL); >- if (ret) { >- krb5_pac_free(context, pac); >- return ret; >- } >+ ret = _krb5_kdc_pac_ticket_parse(context, tkt, &signedticket, &pac); >+ if (ret || pac == NULL) >+ return ret; > >- ret = _kdc_pac_verify(context, client_principal, >- delegated_proxy_principal, >- client, server, krbtgt, &pac, &signed_pac); >- if (ret) { >- krb5_pac_free(context, pac); >- return ret; >- } >+ /* Verify the server signature. */ >+ ret = krb5_pac_verify(context, pac, tkt->authtime, client_principal, >+ server_check_key, NULL); >+ if (ret) { >+ krb5_pac_free(context, pac); >+ return ret; >+ } > >- /* >- * Only re-sign PAC if we could verify it with the PAC >- * function. The no-verify case happens when we get in >- * a PAC from cross realm from a Windows domain and >- * that there is no PAC verification function. >- */ >- if (signed_pac) { >- *signedpath = 1; >- ret = _krb5_pac_sign(context, pac, tkt->authtime, >- client_principal, >- server_sign_key, krbtgt_sign_key, rspac); >- } >+ /* Verify the KDC signatures. */ >+ ret = _kdc_pac_verify(context, client_principal, delegated_proxy_principal, >+ client, server, krbtgt, &pac); >+ if (ret == KRB5_PLUGIN_NO_HANDLE) { >+ /* >+ * We can't verify the KDC signatures if the ticket was issued by >+ * another realm's KDC. >+ */ >+ if (krb5_realm_compare(context, server->entry.principal, >+ ticket_server->entry.principal)) { >+ ret = krb5_pac_verify(context, pac, 0, NULL, NULL, >+ krbtgt_check_key); >+ if (ret) { > krb5_pac_free(context, pac); >- > return ret; > } > } >- free_AuthorizationData(&child); >+ /* Discard the PAC if the plugin didn't handle it */ >+ krb5_pac_free(context, pac); >+ ret = krb5_pac_init(context, &pac); >+ if (ret) >+ return ret; >+ } else if (ret) { >+ krb5_pac_free(context, pac); >+ return ret; > } >+ >+ *kdc_issued = signedticket || >+ krb5_principal_is_krbtgt(context, >+ ticket_server->entry.principal); >+ *ppac = pac; >+ > return 0; > } > >@@ -499,11 +478,12 @@ static krb5_error_code > tgs_make_reply(krb5_context context, > krb5_kdc_configuration *config, > KDC_REQ_BODY *b, >- krb5_const_principal tgt_name, >+ krb5_principal tgt_name, > const EncTicketPart *tgt, > const krb5_keyblock *replykey, > int rk_is_subkey, > const EncryptionKey *serverkey, >+ const EncryptionKey *krbtgtkey, > const krb5_keyblock *sessionkey, > krb5_kvno kvno, > AuthorizationData *auth_data, >@@ -513,8 +493,9 @@ tgs_make_reply(krb5_context context, > hdb_entry_ex *client, > krb5_principal client_principal, > hdb_entry_ex *krbtgt, >- krb5_enctype krbtgt_etype, >- const krb5_data *rspac, >+ krb5_pac mspac, >+ uint16_t rodc_id, >+ krb5_boolean add_ticket_sig, > const METHOD_DATA *enc_pa_data, > const char **e_text, > krb5_data *reply) >@@ -647,17 +628,6 @@ tgs_make_reply(krb5_context context, > if (!server->entry.flags.proxiable) > et.flags.proxiable = 0; > >- if(rspac->length) { >- /* >- * No not need to filter out the any PAC from the >- * auth_data since it's signed by the KDC. >- */ >- ret = _kdc_tkt_add_if_relevant_ad(context, &et, >- KRB5_AUTHDATA_WIN2K_PAC, rspac); >- if (ret) >- goto out; >- } >- > if (auth_data) { > unsigned int i = 0; > >@@ -724,6 +694,11 @@ tgs_make_reply(krb5_context context, > is_weak = 1; > } > >+ /* The PAC should be the last change to the ticket. */ >+ ret = _krb5_kdc_pac_sign_ticket(context, mspac, tgt_name, serverkey, >+ krbtgtkey, rodc_id, add_ticket_sig, &et); >+ if (ret) >+ goto out; > > /* It is somewhat unclear where the etype in the following > encryption should come from. What we have is a session >@@ -910,6 +885,7 @@ tgs_parse_request(krb5_context context, > int **cusec, > AuthorizationData **auth_data, > krb5_keyblock **replykey, >+ Key **header_key, > int *rk_is_subkey) > { > static char failed[] = "<unparse_name failed>"; >@@ -1047,6 +1023,8 @@ tgs_parse_request(krb5_context context, > goto out; > } > >+ *header_key = tkey; >+ > { > krb5_authenticator auth; > >@@ -1236,6 +1214,57 @@ eout: > return ENOMEM; > } > >+static krb5_error_code >+db_fetch_client(krb5_context context, >+ krb5_kdc_configuration *config, >+ int flags, >+ krb5_principal cp, >+ const char *cpn, >+ const char *krbtgt_realm, >+ HDB **clientdb, >+ hdb_entry_ex **client_out) >+{ >+ krb5_error_code ret; >+ hdb_entry_ex *client = NULL; >+ >+ *client_out = NULL; >+ >+ ret = _kdc_db_fetch(context, config, cp, HDB_F_GET_CLIENT | flags, >+ NULL, clientdb, &client); >+ if (ret == HDB_ERR_NOT_FOUND_HERE) { >+ /* >+ * This is OK, we are just trying to find out if they have >+ * been disabled or deleted in the meantime; missing secrets >+ * are OK. >+ */ >+ } else if (ret) { >+ /* >+ * If the client belongs to the same realm as our TGS, it >+ * should exist in the local database. >+ */ >+ const char *msg; >+ >+ if (strcmp(krb5_principal_get_realm(context, cp), krbtgt_realm) == 0) { >+ if (ret == HDB_ERR_NOENTRY) >+ ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN; >+ kdc_log(context, config, 4, "Client no longer in database: %s", cpn); >+ return ret; >+ } >+ >+ msg = krb5_get_error_message(context, ret); >+ kdc_log(context, config, 4, "Client not found in database: %s", msg); >+ krb5_free_error_message(context, msg); >+ } else if (client->entry.flags.invalid || !client->entry.flags.client) { >+ kdc_log(context, config, 4, "Client has invalid bit set"); >+ _kdc_free_ent(context, client); >+ return KRB5KDC_ERR_POLICY; >+ } >+ >+ *client_out = client; >+ >+ return 0; >+} >+ > static krb5_error_code > tgs_build_reply(krb5_context context, > krb5_kdc_configuration *config, >@@ -1243,6 +1272,7 @@ tgs_build_reply(krb5_context context, > KDC_REQ_BODY *b, > hdb_entry_ex *krbtgt, > krb5_enctype krbtgt_etype, >+ Key *tkey_check, > const krb5_keyblock *replykey, > int rk_is_subkey, > krb5_ticket *ticket, >@@ -1263,7 +1293,9 @@ tgs_build_reply(krb5_context context, > const EncryptionKey *ekey; > krb5_keyblock sessionkey; > krb5_kvno kvno; >- krb5_data rspac; >+ krb5_pac mspac = NULL; >+ uint16_t rodc_id; >+ krb5_boolean add_ticket_sig = FALSE; > > hdb_entry_ex *krbtgt_out = NULL; > >@@ -1274,15 +1306,13 @@ tgs_build_reply(krb5_context context, > int nloop = 0; > EncTicketPart adtkt; > char opt_str[128]; >- int signedpath = 0; >+ krb5_boolean kdc_issued = FALSE; > >- Key *tkey_check; > Key *tkey_sign; > int flags = HDB_F_FOR_TGS_REQ; > > memset(&sessionkey, 0, sizeof(sessionkey)); > memset(&adtkt, 0, sizeof(adtkt)); >- krb5_data_zero(&rspac); > memset(&enc_pa_data, 0, sizeof(enc_pa_data)); > > s = b->sname; >@@ -1517,18 +1547,6 @@ server_lookup: > * backward. > */ > >- /* >- * Validate authoriation data >- */ >- >- ret = hdb_enctype2key(context, &krbtgt->entry, >- krbtgt_etype, &tkey_check); >- if(ret) { >- kdc_log(context, config, 0, >- "Failed to find key for krbtgt PAC check"); >- goto out; >- } >- > /* Now refetch the primary krbtgt, and get the current kvno (the > * sign check may have been on an old kvno, and the server may > * have been an incoming trust) */ >@@ -1589,41 +1607,14 @@ server_lookup: > goto out; > } > >- ret = _kdc_db_fetch(context, config, cp, HDB_F_GET_CLIENT | flags, >- NULL, &clientdb, &client); >- if(ret == HDB_ERR_NOT_FOUND_HERE) { >- /* This is OK, we are just trying to find out if they have >- * been disabled or deleted in the meantime, missing secrets >- * is OK */ >- } else if(ret){ >- const char *krbtgt_realm, *msg; >- >- /* >- * If the client belongs to the same realm as our krbtgt, it >- * should exist in the local database. >- * >- */ >- >- krbtgt_realm = krb5_principal_get_realm(context, krbtgt_out->entry.principal); >- >- if(strcmp(krb5_principal_get_realm(context, cp), krbtgt_realm) == 0) { >- if (ret == HDB_ERR_NOENTRY) >- ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN; >- kdc_log(context, config, 1, "Client no longer in database: %s", >- cpn); >- goto out; >- } >- >- msg = krb5_get_error_message(context, ret); >- kdc_log(context, config, 1, "Client not found in database: %s", msg); >- krb5_free_error_message(context, msg); >- } >+ ret = db_fetch_client(context, config, flags, cp, cpn, >+ krb5_principal_get_realm(context, krbtgt_out->entry.principal), >+ &clientdb, &client); >+ if (ret) >+ goto out; > >- ret = check_PAC(context, config, cp, NULL, >- client, server, krbtgt, >- &tkey_check->key, >- ekey, &tkey_sign->key, >- tgt, &rspac, &signedpath); >+ ret = check_PAC(context, config, cp, NULL, client, server, krbtgt, krbtgt, >+ &tkey_check->key, &tkey_check->key, tgt, &kdc_issued, &mspac); > if (ret) { > const char *msg = krb5_get_error_message(context, ret); > kdc_log(context, config, 0, >@@ -1760,27 +1751,15 @@ server_lookup: > goto out; > > /* If we were about to put a PAC into the ticket, we better fix it to be the right PAC */ >- if(rspac.data) { >- krb5_pac p = NULL; >- krb5_data_free(&rspac); >- ret = _kdc_pac_generate(context, s4u2self_impersonated_client, NULL, &p); >+ if (mspac) { >+ krb5_pac_free(context, mspac); >+ mspac = NULL; >+ ret = _kdc_pac_generate(context, s4u2self_impersonated_client, NULL, &mspac); > if (ret) { > kdc_log(context, config, 0, "PAC generation failed for -- %s", > tpn); > goto out; > } >- if (p != NULL) { >- ret = _krb5_pac_sign(context, p, ticket->ticket.authtime, >- s4u2self_impersonated_client->entry.principal, >- ekey, &tkey_sign->key, >- &rspac); >- krb5_pac_free(context, p); >- if (ret) { >- kdc_log(context, config, 0, "PAC signing failed for -- %s", >- tpn); >- goto out; >- } >- } > } > > /* >@@ -1823,22 +1802,25 @@ server_lookup: > && b->additional_tickets->len != 0 > && b->kdc_options.enc_tkt_in_skey == 0) > { >- int ad_signedpath = 0; >+ hdb_entry_ex *adclient = NULL; >+ krb5_boolean ad_kdc_issued = FALSE; > Key *clientkey; > Ticket *t; > > /* >- * Require that the KDC have issued the service's krbtgt (not >- * self-issued ticket with kimpersonate(1). >+ * We require that the service's krbtgt has a PAC. > */ >- if (!signedpath) { >+ if (mspac == NULL) { > ret = KRB5KDC_ERR_BADOPTION; > kdc_log(context, config, 0, >- "Constrained delegation done on service ticket %s/%s", >+ "Constrained delegation without PAC %s/%s", > cpn, spn); > goto out; > } > >+ krb5_pac_free(context, mspac); >+ mspac = NULL; >+ > t = &b->additional_tickets->val[0]; > > ret = hdb_enctype2key(context, &client->entry, >@@ -1902,19 +1884,32 @@ server_lookup: > goto out; > } > >- krb5_data_free(&rspac); >+ /* Try lookup the delegated client in DB */ >+ ret = db_fetch_client(context, config, flags, tp, tpn, >+ krb5_principal_get_realm(context, krbtgt_out->entry.principal), >+ NULL, &adclient); >+ if (ret) >+ goto out; >+ >+ if (adclient != NULL) { >+ ret = kdc_check_flags(context, config, >+ adclient, tpn, >+ server, spn, >+ FALSE); >+ if (ret) { >+ _kdc_free_ent(context, adclient); >+ goto out; >+ } >+ } > > /* >- * generate the PAC for the user. >- * > * TODO: pass in t->sname and t->realm and build > * a S4U_DELEGATION_INFO blob to the PAC. > */ >- ret = check_PAC(context, config, tp, dp, >- client, server, krbtgt, >- &clientkey->key, >- ekey, &tkey_sign->key, >- &adtkt, &rspac, &ad_signedpath); >+ ret = check_PAC(context, config, tp, dp, adclient, server, krbtgt, client, >+ &clientkey->key, &tkey_check->key, &adtkt, &ad_kdc_issued, &mspac); >+ if (adclient) >+ _kdc_free_ent(context, adclient); > if (ret) { > const char *msg = krb5_get_error_message(context, ret); > kdc_log(context, config, 0, >@@ -1925,13 +1920,12 @@ server_lookup: > goto out; > } > >- if (!ad_signedpath) { >+ if (mspac == NULL || !ad_kdc_issued) { > ret = KRB5KDC_ERR_BADOPTION; > kdc_log(context, config, 0, >- "Ticket not signed with PAC nor SignedPath service %s failed " >- "for delegation to %s for client %s (%s)" >- "from %s", >- spn, tpn, dpn, cpn, from); >+ "Ticket not signed with PAC; service %s failed for " >+ "for delegation to %s for client %s (%s) from %s; (%s).", >+ spn, tpn, dpn, cpn, from, mspac ? "Ticket unsigned" : "No PAC"); > goto out; > } > >@@ -2000,6 +1994,25 @@ server_lookup: > } > } > >+ /* >+ * Only add ticket signature if the requested server is not krbtgt, and >+ * either the header server is krbtgt or, in the case of renewal/validation >+ * if it was signed with PAC ticket signature and we verified it. >+ * Currently Heimdal only allows renewal of krbtgt anyway but that might >+ * change one day (see issue #763) so make sure to check for it. >+ */ >+ >+ if (kdc_issued && >+ !krb5_principal_is_krbtgt(context, server->entry.principal)) >+ add_ticket_sig = TRUE; >+ >+ /* >+ * Active-Directory implementations use the high part of the kvno as the >+ * read-only-dc identifier, we need to embed it in the PAC KDC signatures. >+ */ >+ >+ rodc_id = krbtgt_out->entry.kvno >> 16; >+ > /* > * > */ >@@ -2012,6 +2025,7 @@ server_lookup: > replykey, > rk_is_subkey, > ekey, >+ &tkey_sign->key, > &sessionkey, > kvno, > *auth_data, >@@ -2021,8 +2035,9 @@ server_lookup: > client, > cp, > krbtgt_out, >- krbtgt_etype, >- &rspac, >+ mspac, >+ rodc_id, >+ add_ticket_sig, > &enc_pa_data, > e_text, > reply); >@@ -2035,7 +2050,6 @@ out: > if (dpn) > free(dpn); > >- krb5_data_free(&rspac); > krb5_free_keyblock_contents(context, &sessionkey); > if(krbtgt_out) > _kdc_free_ent(context, krbtgt_out); >@@ -2060,6 +2074,9 @@ out: > > free_EncTicketPart(&adtkt); > >+ if (mspac) >+ krb5_pac_free(context, mspac); >+ > return ret; > } > >@@ -2080,6 +2097,7 @@ _kdc_tgs_rep(krb5_context context, > krb5_error_code ret; > int i = 0; > const PA_DATA *tgs_req; >+ Key *header_key = NULL; > > hdb_entry_ex *krbtgt = NULL; > krb5_ticket *ticket = NULL; >@@ -2117,6 +2135,7 @@ _kdc_tgs_rep(krb5_context context, > &csec, &cusec, > &auth_data, > &replykey, >+ &header_key, > &rk_is_subkey); > if (ret == HDB_ERR_NOT_FOUND_HERE) { > /* kdc_log() is called in tgs_parse_request() */ >@@ -2134,6 +2153,7 @@ _kdc_tgs_rep(krb5_context context, > &req->req_body, > krbtgt, > krbtgt_etype, >+ header_key, > replykey, > rk_is_subkey, > ticket, >diff --git a/source4/heimdal/kdc/windc.c b/source4/heimdal/kdc/windc.c >index fb1c8a6a993..43dc89e2bc0 100644 >--- a/source4/heimdal/kdc/windc.c >+++ b/source4/heimdal/kdc/windc.c >@@ -77,8 +77,14 @@ _kdc_pac_generate(krb5_context context, > krb5_pac *pac) > { > *pac = NULL; >- if (windcft == NULL) >+ if (krb5_config_get_bool_default(context, NULL, FALSE, "realms", >+ client->entry.principal->realm, >+ "disable_pac", NULL)) > return 0; >+ if (windcft == NULL) { >+ return krb5_pac_init(context, pac); >+ } >+ > if (windcft->pac_pk_generate != NULL && pk_reply_key != NULL) > return (windcft->pac_pk_generate)(windcctx, context, > client, pk_reply_key, pac); >@@ -92,20 +98,17 @@ _kdc_pac_verify(krb5_context context, > hdb_entry_ex *client, > hdb_entry_ex *server, > hdb_entry_ex *krbtgt, >- krb5_pac *pac, >- int *verified) >+ krb5_pac *pac) > { > krb5_error_code ret; > > if (windcft == NULL) >- return 0; >+ return KRB5_PLUGIN_NO_HANDLE; > > ret = windcft->pac_verify(windcctx, context, > client_principal, > delegated_proxy_principal, > client, server, krbtgt, pac); >- if (ret == 0) >- *verified = 1; > return ret; > } > >diff --git a/source4/heimdal/kdc/windc_plugin.h b/source4/heimdal/kdc/windc_plugin.h >index bf90826cb06..dda258da3d1 100644 >--- a/source4/heimdal/kdc/windc_plugin.h >+++ b/source4/heimdal/kdc/windc_plugin.h >@@ -43,8 +43,9 @@ > * krb5_pac_init and fill in the PAC structure for the principal using > * krb5_pac_add_buffer. > * >- * The PAC verify function should verify all components in the PAC >- * using krb5_pac_get_types and krb5_pac_get_buffer for all types. >+ * The PAC verify function should verify the PAC KDC signatures by fetching >+ * the right KDC key and calling krb5_pac_verify() with that KDC key. >+ * Optionally, update the PAC buffers upon success. > * > * Check client access function check if the client is authorized. > */ >diff --git a/source4/heimdal/lib/krb5/authdata.c b/source4/heimdal/lib/krb5/authdata.c >new file mode 100644 >index 00000000000..ac426618f6e >--- /dev/null >+++ b/source4/heimdal/lib/krb5/authdata.c >@@ -0,0 +1,124 @@ >+/* >+ * Copyright (c) 1997-2021 Kungliga Tekniska Högskolan >+ * (Royal Institute of Technology, Stockholm, Sweden). >+ * Copyright (c) 2021 Isaac Boukris >+ * All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * 3. Neither the name of the Institute nor the names of its contributors >+ * may be used to endorse or promote products derived from this software >+ * without specific prior written permission. >+ * >+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND >+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE >+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE >+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL >+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS >+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) >+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT >+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY >+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF >+ * SUCH DAMAGE. >+ */ >+ >+#include "krb5_locl.h" >+ >+/* >+ * Add the AuthorizationData `data´ of `type´ to the last element in >+ * the sequence of authorization_data in `tkt´ wrapped in an IF_RELEVANT >+ */ >+ >+KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL >+_kdc_tkt_add_if_relevant_ad(krb5_context context, >+ EncTicketPart *tkt, >+ int type, >+ const krb5_data *data) >+{ >+ krb5_error_code ret; >+ size_t size = 0; >+ >+ if (tkt->authorization_data == NULL) { >+ tkt->authorization_data = calloc(1, sizeof(*tkt->authorization_data)); >+ if (tkt->authorization_data == NULL) { >+ return krb5_enomem(context); >+ } >+ } >+ >+ /* add the entry to the last element */ >+ { >+ AuthorizationData ad = { 0, NULL }; >+ AuthorizationDataElement ade; >+ >+ ade.ad_type = type; >+ ade.ad_data = *data; >+ >+ ret = add_AuthorizationData(&ad, &ade); >+ if (ret) { >+ krb5_set_error_message(context, ret, "add AuthorizationData failed"); >+ return ret; >+ } >+ >+ ade.ad_type = KRB5_AUTHDATA_IF_RELEVANT; >+ >+ ASN1_MALLOC_ENCODE(AuthorizationData, >+ ade.ad_data.data, ade.ad_data.length, >+ &ad, &size, ret); >+ free_AuthorizationData(&ad); >+ if (ret) { >+ krb5_set_error_message(context, ret, "ASN.1 encode of " >+ "AuthorizationData failed"); >+ return ret; >+ } >+ if (ade.ad_data.length != size) >+ krb5_abortx(context, "internal asn.1 encoder error"); >+ >+ ret = add_AuthorizationData(tkt->authorization_data, &ade); >+ der_free_octet_string(&ade.ad_data); >+ if (ret) { >+ krb5_set_error_message(context, ret, "add AuthorizationData failed"); >+ return ret; >+ } >+ } >+ >+ return 0; >+} >+ >+/* >+ * Insert a PAC wrapped in AD-IF-RELEVANT container as the first AD element, >+ * as some clients such as Windows may fail to parse it otherwise. >+ */ >+ >+KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL >+_kdc_tkt_insert_pac(krb5_context context, >+ EncTicketPart *tkt, >+ const krb5_data *data) >+{ >+ AuthorizationDataElement ade; >+ unsigned int i; >+ krb5_error_code ret; >+ >+ ret = _kdc_tkt_add_if_relevant_ad(context, tkt, KRB5_AUTHDATA_WIN2K_PAC, >+ data); >+ if (ret) >+ return ret; >+ >+ heim_assert(tkt->authorization_data->len != 0, "No authorization_data!"); >+ ade = tkt->authorization_data->val[tkt->authorization_data->len - 1]; >+ for (i = 0; i < tkt->authorization_data->len - 1; i++) { >+ tkt->authorization_data->val[i + 1] = tkt->authorization_data->val[i]; >+ } >+ tkt->authorization_data->val[0] = ade; >+ >+ return 0; >+} >diff --git a/source4/heimdal/lib/krb5/pac.c b/source4/heimdal/lib/krb5/pac.c >index 26aae107b32..eec1e84c7bd 100644 >--- a/source4/heimdal/lib/krb5/pac.c >+++ b/source4/heimdal/lib/krb5/pac.c >@@ -53,6 +53,8 @@ struct krb5_pac_data { > struct PAC_INFO_BUFFER *server_checksum; > struct PAC_INFO_BUFFER *privsvr_checksum; > struct PAC_INFO_BUFFER *logon_name; >+ struct PAC_INFO_BUFFER *ticket_checksum; >+ krb5_data ticket_sign_data; > }; > > #define PAC_ALIGNMENT 8 >@@ -64,6 +66,7 @@ struct krb5_pac_data { > #define PAC_PRIVSVR_CHECKSUM 7 > #define PAC_LOGON_NAME 10 > #define PAC_CONSTRAINED_DELEGATION 11 >+#define PAC_TICKET_CHECKSUM 16 > > #define CHECK(r,f,l) \ > do { \ >@@ -142,13 +145,13 @@ krb5_pac_parse(krb5_context context, const void *ptr, size_t len, > CHECK(ret, krb5_ret_uint32(sp, &tmp2), out); > if (tmp < 1) { > ret = EINVAL; /* Too few buffers */ >- krb5_set_error_message(context, ret, N_("PAC have too few buffer", "")); >+ krb5_set_error_message(context, ret, N_("PAC has too few buffers", "")); > goto out; > } > if (tmp2 != 0) { > ret = EINVAL; /* Wrong version */ > krb5_set_error_message(context, ret, >- N_("PAC have wrong version %d", ""), >+ N_("PAC has wrong version %d", ""), > (int)tmp2); > goto out; > } >@@ -191,7 +194,7 @@ krb5_pac_parse(krb5_context context, const void *ptr, size_t len, > if (p->pac->buffers[i].offset_lo > len) { > ret = EINVAL; > krb5_set_error_message(context, ret, >- N_("PAC offset off end", "")); >+ N_("PAC offset overflow", "")); > goto out; > } > if (p->pac->buffers[i].offset_lo < header_end) { >@@ -204,7 +207,7 @@ krb5_pac_parse(krb5_context context, const void *ptr, size_t len, > } > if (p->pac->buffers[i].buffersize > len - p->pac->buffers[i].offset_lo){ > ret = EINVAL; >- krb5_set_error_message(context, ret, N_("PAC length off end", "")); >+ krb5_set_error_message(context, ret, N_("PAC length overflow", "")); > goto out; > } > >@@ -213,7 +216,7 @@ krb5_pac_parse(krb5_context context, const void *ptr, size_t len, > if (p->server_checksum) { > ret = EINVAL; > krb5_set_error_message(context, ret, >- N_("PAC have two server checksums", "")); >+ N_("PAC has multiple server checksums", "")); > goto out; > } > p->server_checksum = &p->pac->buffers[i]; >@@ -221,7 +224,7 @@ krb5_pac_parse(krb5_context context, const void *ptr, size_t len, > if (p->privsvr_checksum) { > ret = EINVAL; > krb5_set_error_message(context, ret, >- N_("PAC have two KDC checksums", "")); >+ N_("PAC has multiple KDC checksums", "")); > goto out; > } > p->privsvr_checksum = &p->pac->buffers[i]; >@@ -229,10 +232,18 @@ krb5_pac_parse(krb5_context context, const void *ptr, size_t len, > if (p->logon_name) { > ret = EINVAL; > krb5_set_error_message(context, ret, >- N_("PAC have two logon names", "")); >+ N_("PAC has multiple logon names", "")); > goto out; > } > p->logon_name = &p->pac->buffers[i]; >+ } else if (p->pac->buffers[i].type == PAC_TICKET_CHECKSUM) { >+ if (p->ticket_checksum) { >+ ret = EINVAL; >+ krb5_set_error_message(context, ret, >+ N_("PAC has multiple ticket checksums", "")); >+ goto out; >+ } >+ p->ticket_checksum = &p->pac->buffers[i]; > } > } > >@@ -425,6 +436,7 @@ KRB5_LIB_FUNCTION void KRB5_LIB_CALL > krb5_pac_free(krb5_context context, krb5_pac pac) > { > krb5_data_free(&pac->data); >+ krb5_data_free(&pac->ticket_sign_data); > free(pac->pac); > free(pac); > } >@@ -444,6 +456,7 @@ verify_checksum(krb5_context context, > uint32_t type; > krb5_error_code ret; > Checksum cksum; >+ size_t cksumsize; > > memset(&cksum, 0, sizeof(cksum)); > >@@ -456,8 +469,17 @@ verify_checksum(krb5_context context, > > CHECK(ret, krb5_ret_uint32(sp, &type), out); > cksum.cksumtype = type; >- cksum.checksum.length = >- sig->buffersize - krb5_storage_seek(sp, 0, SEEK_CUR); >+ >+ ret = krb5_checksumsize(context, type, &cksumsize); >+ if (ret) >+ goto out; >+ >+ /* Allow for RODCIdentifier trailer, see MS-PAC 2.8 */ >+ if (cksumsize > (sig->buffersize - krb5_storage_seek(sp, 0, SEEK_CUR))) { >+ ret = EINVAL; >+ goto out; >+ } >+ cksum.checksum.length = cksumsize; > cksum.checksum.data = malloc(cksum.checksum.length); > if (cksum.checksum.data == NULL) { > ret = krb5_enomem(context); >@@ -804,7 +826,6 @@ out: > return ret; > } > >- > /** > * Verify the PAC. > * >@@ -844,18 +865,22 @@ krb5_pac_verify(krb5_context context, > return EINVAL; > } > >- ret = verify_logonname(context, >- pac->logon_name, >- &pac->data, >- authtime, >- principal); >- if (ret) >- return ret; >+ if (principal != NULL) { >+ ret = verify_logonname(context, pac->logon_name, &pac->data, authtime, >+ principal); >+ if (ret) >+ return ret; >+ } >+ >+ if (pac->server_checksum->buffersize < 4 || >+ pac->privsvr_checksum->buffersize < 4) >+ return EINVAL; > > /* > * in the service case, clean out data option of the privsvr and > * server checksum before checking the checksum. > */ >+ if (server != NULL) > { > krb5_data *copy; > >@@ -897,6 +922,20 @@ krb5_pac_verify(krb5_context context, > privsvr); > if (ret) > return ret; >+ >+ if (pac->ticket_sign_data.length != 0) { >+ if (pac->ticket_checksum == NULL) { >+ krb5_set_error_message(context, EINVAL, >+ "PAC missing ticket checksum"); >+ return EINVAL; >+ } >+ >+ ret = verify_checksum(context, pac->ticket_checksum, &pac->data, >+ pac->ticket_sign_data.data, >+ pac->ticket_sign_data.length, privsvr); >+ if (ret) >+ return ret; >+ } > } > > return 0; >@@ -965,13 +1004,14 @@ _krb5_pac_sign(krb5_context context, > krb5_principal principal, > const krb5_keyblock *server_key, > const krb5_keyblock *priv_key, >+ uint16_t rodc_id, > krb5_data *data) > { > krb5_error_code ret; > krb5_storage *sp = NULL, *spdata = NULL; > uint32_t end; > size_t server_size, priv_size; >- uint32_t server_offset = 0, priv_offset = 0; >+ uint32_t server_offset = 0, priv_offset = 0, ticket_offset = 0; > uint32_t server_cksumtype = 0, priv_cksumtype = 0; > int num = 0; > size_t i; >@@ -985,9 +1025,9 @@ _krb5_pac_sign(krb5_context context, > p->server_checksum = &p->pac->buffers[i]; > } > if (p->server_checksum != &p->pac->buffers[i]) { >- ret = EINVAL; >+ ret = KRB5KDC_ERR_BADOPTION; > krb5_set_error_message(context, ret, >- N_("PAC have two server checksums", "")); >+ N_("PAC has multiple server checksums", "")); > goto out; > } > } else if (p->pac->buffers[i].type == PAC_PRIVSVR_CHECKSUM) { >@@ -995,9 +1035,9 @@ _krb5_pac_sign(krb5_context context, > p->privsvr_checksum = &p->pac->buffers[i]; > } > if (p->privsvr_checksum != &p->pac->buffers[i]) { >- ret = EINVAL; >+ ret = KRB5KDC_ERR_BADOPTION; > krb5_set_error_message(context, ret, >- N_("PAC have two KDC checksums", "")); >+ N_("PAC has multiple KDC checksums", "")); > goto out; > } > } else if (p->pac->buffers[i].type == PAC_LOGON_NAME) { >@@ -1005,9 +1045,19 @@ _krb5_pac_sign(krb5_context context, > p->logon_name = &p->pac->buffers[i]; > } > if (p->logon_name != &p->pac->buffers[i]) { >- ret = EINVAL; >+ ret = KRB5KDC_ERR_BADOPTION; >+ krb5_set_error_message(context, ret, >+ N_("PAC has multiple logon names", "")); >+ goto out; >+ } >+ } else if (p->pac->buffers[i].type == PAC_TICKET_CHECKSUM) { >+ if (p->ticket_checksum == NULL) { >+ p->ticket_checksum = &p->pac->buffers[i]; >+ } >+ if (p->ticket_checksum != &p->pac->buffers[i]) { >+ ret = KRB5KDC_ERR_BADOPTION; > krb5_set_error_message(context, ret, >- N_("PAC have two logon names", "")); >+ N_("PAC has multiple ticket checksums", "")); > goto out; > } > } >@@ -1019,6 +1069,8 @@ _krb5_pac_sign(krb5_context context, > num++; > if (p->privsvr_checksum == NULL) > num++; >+ if (p->ticket_sign_data.length != 0 && p->ticket_checksum == NULL) >+ num++; > > if (num) { > void *ptr; >@@ -1044,6 +1096,11 @@ _krb5_pac_sign(krb5_context context, > memset(p->privsvr_checksum, 0, sizeof(*p->privsvr_checksum)); > p->privsvr_checksum->type = PAC_PRIVSVR_CHECKSUM; > } >+ if (p->ticket_sign_data.length != 0 && p->ticket_checksum == NULL) { >+ p->ticket_checksum = &p->pac->buffers[p->pac->numbuffers++]; >+ memset(p->ticket_checksum, 0, sizeof(*p->privsvr_checksum)); >+ p->ticket_checksum->type = PAC_TICKET_CHECKSUM; >+ } > } > > /* Calculate LOGON NAME */ >@@ -1055,6 +1112,7 @@ _krb5_pac_sign(krb5_context context, > ret = pac_checksum(context, server_key, &server_cksumtype, &server_size); > if (ret) > goto out; >+ > ret = pac_checksum(context, priv_key, &priv_cksumtype, &priv_size); > if (ret) > goto out; >@@ -1095,10 +1153,24 @@ _krb5_pac_sign(krb5_context context, > priv_offset = end + 4; > CHECK(ret, krb5_store_uint32(spdata, priv_cksumtype), out); > CHECK(ret, fill_zeros(context, spdata, priv_size), out); >+ if (rodc_id != 0) { >+ len += sizeof(rodc_id); >+ CHECK(ret, fill_zeros(context, spdata, sizeof(rodc_id)), out); >+ } >+ } else if (p->ticket_sign_data.length != 0 && >+ p->pac->buffers[i].type == PAC_TICKET_CHECKSUM) { >+ len = priv_size + 4; >+ ticket_offset = end + 4; >+ CHECK(ret, krb5_store_uint32(spdata, priv_cksumtype), out); >+ CHECK(ret, fill_zeros(context, spdata, priv_size), out); >+ if (rodc_id != 0) { >+ len += sizeof(rodc_id); >+ CHECK(ret, krb5_store_uint16(spdata, rodc_id), out); >+ } > } else if (p->pac->buffers[i].type == PAC_LOGON_NAME) { > len = krb5_storage_write(spdata, logon.data, logon.length); > if (logon.length != len) { >- ret = EINVAL; >+ ret = KRB5KDC_ERR_BADOPTION; > goto out; > } > } else { >@@ -1156,6 +1228,16 @@ _krb5_pac_sign(krb5_context context, > } > > /* sign */ >+ if (p->ticket_sign_data.length) { >+ ret = create_checksum(context, priv_key, priv_cksumtype, >+ p->ticket_sign_data.data, >+ p->ticket_sign_data.length, >+ (char *)d.data + ticket_offset, priv_size); >+ if (ret) { >+ krb5_data_free(&d); >+ goto out; >+ } >+ } > ret = create_checksum(context, server_key, server_cksumtype, > d.data, d.length, > (char *)d.data + server_offset, server_size); >@@ -1171,6 +1253,32 @@ _krb5_pac_sign(krb5_context context, > goto out; > } > >+ if (rodc_id != 0) { >+ krb5_data rd; >+ krb5_storage *rs = krb5_storage_emem(); >+ if (rs == NULL) { >+ krb5_data_free(&d); >+ ret = krb5_enomem(context); >+ goto out; >+ } >+ krb5_storage_set_flags(rs, KRB5_STORAGE_BYTEORDER_LE); >+ ret = krb5_store_uint16(rs, rodc_id); >+ if (ret) { >+ krb5_storage_free(rs); >+ krb5_data_free(&d); >+ goto out; >+ } >+ ret = krb5_storage_to_data(rs, &rd); >+ krb5_storage_free(rs); >+ if (ret) { >+ krb5_data_free(&d); >+ goto out; >+ } >+ heim_assert(rd.length == sizeof(rodc_id), "invalid length"); >+ memcpy((char *)d.data + priv_offset + priv_size, rd.data, rd.length); >+ krb5_data_free(&rd); >+ } >+ > /* done */ > *data = d; > >@@ -1187,3 +1295,221 @@ out: > krb5_storage_free(spdata); > return ret; > } >+ >+KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL >+_krb5_pac_get_kdc_checksum_info(krb5_context context, >+ krb5_pac pac, >+ krb5_cksumtype *cstype, >+ uint16_t *rodc_id) >+{ >+ krb5_error_code ret; >+ krb5_storage *sp = NULL; >+ const struct PAC_INFO_BUFFER *sig; >+ size_t cksumsize, prefix; >+ uint32_t type = 0; >+ >+ *cstype = 0; >+ *rodc_id = 0; >+ >+ sig = pac->privsvr_checksum; >+ if (sig == NULL) { >+ krb5_set_error_message(context, KRB5KDC_ERR_BADOPTION, >+ "PAC missing kdc checksum"); >+ return KRB5KDC_ERR_BADOPTION; >+ } >+ >+ sp = krb5_storage_from_mem((char *)pac->data.data + sig->offset_lo, >+ sig->buffersize); >+ if (sp == NULL) >+ return krb5_enomem(context); >+ >+ krb5_storage_set_flags(sp, KRB5_STORAGE_BYTEORDER_LE); >+ >+ ret = krb5_ret_uint32(sp, &type); >+ if (ret) >+ goto out; >+ >+ ret = krb5_checksumsize(context, type, &cksumsize); >+ if (ret) >+ goto out; >+ >+ prefix = krb5_storage_seek(sp, 0, SEEK_CUR); >+ >+ if ((sig->buffersize - prefix) >= cksumsize + 2) { >+ krb5_storage_seek(sp, cksumsize, SEEK_CUR); >+ ret = krb5_ret_uint16(sp, rodc_id); >+ if (ret) >+ goto out; >+ } >+ >+ *cstype = type; >+ >+out: >+ krb5_storage_free(sp); >+ >+ return ret; >+} >+ >+static unsigned char single_zero = '\0'; >+static krb5_data single_zero_pac = { 1, &single_zero }; >+ >+KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL >+_krb5_kdc_pac_ticket_parse(krb5_context context, >+ EncTicketPart *tkt, >+ krb5_boolean *signedticket, >+ krb5_pac *ppac) >+{ >+ AuthorizationData *ad = tkt->authorization_data; >+ krb5_boolean pac_found = FALSE; >+ krb5_pac pac = NULL; >+ unsigned i, j; >+ size_t len = 0; >+ krb5_error_code ret; >+ >+ *signedticket = FALSE; >+ *ppac = NULL; >+ >+ if (ad == NULL || ad->len == 0) >+ return 0; >+ >+ for (i = 0; i < ad->len; i++) { >+ AuthorizationData child; >+ >+ if (ad->val[i].ad_type == KRB5_AUTHDATA_WIN2K_PAC) >+ return KRB5KDC_ERR_BADOPTION; >+ >+ if (ad->val[i].ad_type != KRB5_AUTHDATA_IF_RELEVANT) >+ continue; >+ >+ ret = decode_AuthorizationData(ad->val[i].ad_data.data, >+ ad->val[i].ad_data.length, >+ &child, >+ NULL); >+ if (ret) { >+ krb5_set_error_message(context, ret, "Failed to decode " >+ "AD-IF-RELEVANT with %d", ret); >+ return ret; >+ } >+ >+ for (j = 0; j < child.len; j++) { >+ if (child.val[j].ad_type == KRB5_AUTHDATA_WIN2K_PAC) { >+ krb5_data adifr_data = ad->val[i].ad_data; >+ krb5_data pac_data = child.val[j].ad_data; >+ krb5_data recoded_adifr; >+ >+ if (pac_found) { >+ free_AuthorizationData(&child); >+ return KRB5KDC_ERR_BADOPTION; >+ } >+ pac_found = TRUE; >+ >+ ret = krb5_pac_parse(context, >+ pac_data.data, >+ pac_data.length, >+ &pac); >+ if (ret) { >+ free_AuthorizationData(&child); >+ return ret; >+ } >+ >+ if (pac->ticket_checksum == NULL) { >+ free_AuthorizationData(&child); >+ *ppac = pac; >+ continue; >+ } >+ >+ /* >+ * Encode the ticket with the PAC replaced with a single zero >+ * byte, to be used as input data to the ticket signature. >+ */ >+ >+ child.val[j].ad_data = single_zero_pac; >+ >+ ASN1_MALLOC_ENCODE(AuthorizationData, recoded_adifr.data, >+ recoded_adifr.length, &child, &len, ret); >+ if (recoded_adifr.length != len) >+ krb5_abortx(context, "Internal error in ASN.1 encoder"); >+ >+ child.val[j].ad_data = pac_data; >+ free_AuthorizationData(&child); >+ >+ if (ret) { >+ krb5_pac_free(context, pac); >+ return ret; >+ } >+ >+ ad->val[i].ad_data = recoded_adifr; >+ >+ ASN1_MALLOC_ENCODE(EncTicketPart, >+ pac->ticket_sign_data.data, >+ pac->ticket_sign_data.length, tkt, &len, >+ ret); >+ if(pac->ticket_sign_data.length != len) >+ krb5_abortx(context, "Internal error in ASN.1 encoder"); >+ >+ ad->val[i].ad_data = adifr_data; >+ krb5_data_free(&recoded_adifr); >+ >+ if (ret) { >+ krb5_pac_free(context, pac); >+ return ret; >+ } >+ >+ *signedticket = TRUE; >+ *ppac = pac; >+ } >+ } >+ free_AuthorizationData(&child); >+ } >+ return 0; >+} >+ >+KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL >+_krb5_kdc_pac_sign_ticket(krb5_context context, >+ const krb5_pac pac, >+ krb5_principal client, >+ const krb5_keyblock *server_key, >+ const krb5_keyblock *kdc_key, >+ uint16_t rodc_id, >+ krb5_boolean add_ticket_sig, >+ EncTicketPart *tkt) >+{ >+ krb5_error_code ret; >+ krb5_data tkt_data; >+ krb5_data rspac; >+ >+ krb5_data_zero(&rspac); >+ krb5_data_zero(&tkt_data); >+ >+ krb5_data_free(&pac->ticket_sign_data); >+ >+ if (add_ticket_sig) { >+ size_t len = 0; >+ >+ ret = _kdc_tkt_insert_pac(context, tkt, &single_zero_pac); >+ if (ret) >+ return ret; >+ >+ ASN1_MALLOC_ENCODE(EncTicketPart, tkt_data.data, tkt_data.length, >+ tkt, &len, ret); >+ if(tkt_data.length != len) >+ krb5_abortx(context, "Internal error in ASN.1 encoder"); >+ if (ret) >+ return ret; >+ >+ ret = remove_AuthorizationData(tkt->authorization_data, 0); >+ if (ret) { >+ krb5_data_free(&tkt_data); >+ return ret; >+ } >+ >+ pac->ticket_sign_data = tkt_data; >+ } >+ >+ ret = _krb5_pac_sign(context, pac, tkt->authtime, client, server_key, >+ kdc_key, rodc_id, &rspac); >+ if (ret) >+ return ret; >+ >+ return _kdc_tkt_insert_pac(context, tkt, &rspac); >+} >diff --git a/source4/heimdal/lib/krb5/version-script.map b/source4/heimdal/lib/krb5/version-script.map >index b95ba92f4f6..e04e02aace9 100644 >--- a/source4/heimdal/lib/krb5/version-script.map >+++ b/source4/heimdal/lib/krb5/version-script.map >@@ -751,6 +751,11 @@ HEIMDAL_KRB5_2.0 { > _krb5_get_host_realm_int; > _krb5_get_int; > _krb5_pac_sign; >+ _krb5_kdc_pac_sign_ticket; >+ _krb5_kdc_pac_ticket_parse; >+ _krb5_pac_get_kdc_checksum_info; >+ _kdc_tkt_insert_pac; >+ _kdc_tkt_add_if_relevant_ad; > _krb5_parse_moduli; > _krb5_pk_kdf; > _krb5_pk_load_id; >diff --git a/source4/heimdal_build/wscript_build b/source4/heimdal_build/wscript_build >index 09c525c2957..39e3f5d56e8 100644 >--- a/source4/heimdal_build/wscript_build >+++ b/source4/heimdal_build/wscript_build >@@ -617,7 +617,7 @@ if not bld.CONFIG_SET("USING_SYSTEM_KRB5"): > KRB5_SOURCE = [os.path.join('lib/krb5/', x) for x in to_list( > '''acache.c add_et_list.c > addr_families.c appdefault.c >- asn1_glue.c auth_context.c >+ asn1_glue.c auth_context.c authdata.c > build_ap_req.c build_auth.c cache.c > changepw.c codec.c config_file.c > constants.c convert_creds.c >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index 5d3c4ac4bfd..c2a6256029f 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -810,7 +810,7 @@ planoldpythontestsuite("ad_dc:local", "samba.tests.gpo", extra_args=['-U"$USERNA > planoldpythontestsuite("ad_dc:local", "samba.tests.dckeytab", extra_args=['-U"$USERNAME%$PASSWORD"']) > > have_fast_support = int('SAMBA_USES_MITKDC' in config_hash) >-tkt_sig_support = 0 >+tkt_sig_support = int('SAMBA4_USES_HEIMDAL' in config_hash) > planoldpythontestsuite("none", "samba.tests.krb5.kcrypto") > planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.simple_tests", > environ={'SERVICE_USERNAME':'$SERVER', >-- >2.25.1 > > >From 9b1039f655a43c4ffdf26c17ea6cde1d682989ac Mon Sep 17 00:00:00 2001 >From: Isaac Boukris <iboukris@gmail.com> >Date: Sun, 19 Sep 2021 15:04:14 +0300 >Subject: [PATCH 122/159] krb5: allow NULL parameter to krb5_pac_free() > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >[jsutton@samba.org Cherry-picked from Heimdal commit >b295167208a96e68515902138f6ce93972892ec5] > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 2d09de5c41e729bccc2d7949d8a3568a95e80e76) >--- > source4/heimdal/kdc/krb5tgs.c | 3 +-- > source4/heimdal/lib/krb5/pac.c | 2 ++ > 2 files changed, 3 insertions(+), 2 deletions(-) > >diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c >index 3b35b828402..d0483a3903b 100644 >--- a/source4/heimdal/kdc/krb5tgs.c >+++ b/source4/heimdal/kdc/krb5tgs.c >@@ -2074,8 +2074,7 @@ out: > > free_EncTicketPart(&adtkt); > >- if (mspac) >- krb5_pac_free(context, mspac); >+ krb5_pac_free(context, mspac); > > return ret; > } >diff --git a/source4/heimdal/lib/krb5/pac.c b/source4/heimdal/lib/krb5/pac.c >index eec1e84c7bd..18f385fac1f 100644 >--- a/source4/heimdal/lib/krb5/pac.c >+++ b/source4/heimdal/lib/krb5/pac.c >@@ -435,6 +435,8 @@ krb5_pac_get_types(krb5_context context, > KRB5_LIB_FUNCTION void KRB5_LIB_CALL > krb5_pac_free(krb5_context context, krb5_pac pac) > { >+ if (pac == NULL) >+ return; > krb5_data_free(&pac->data); > krb5_data_free(&pac->ticket_sign_data); > free(pac->pac); >-- >2.25.1 > > >From f2369e24b15cf721a5900b1b5eacac8b44663860 Mon Sep 17 00:00:00 2001 >From: Isaac Boukris <iboukris@gmail.com> >Date: Sun, 19 Sep 2021 15:16:58 +0300 >Subject: [PATCH 123/159] krb5: rework PAC validation loop > >Avoid allocating the PAC on error. > >Closes: #836 > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >[jsutton@samba.org Cherry-picked from Heimdal commit >6df8be5091363a1c9a9165465ab8292f817bec81] > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 2773379603a5a625c5d1c6e62f29c442942ff570) >--- > source4/heimdal/lib/krb5/pac.c | 132 +++++++++++++++++---------------- > 1 file changed, 69 insertions(+), 63 deletions(-) > >diff --git a/source4/heimdal/lib/krb5/pac.c b/source4/heimdal/lib/krb5/pac.c >index 18f385fac1f..922a8710eda 100644 >--- a/source4/heimdal/lib/krb5/pac.c >+++ b/source4/heimdal/lib/krb5/pac.c >@@ -1362,11 +1362,10 @@ _krb5_kdc_pac_ticket_parse(krb5_context context, > krb5_pac *ppac) > { > AuthorizationData *ad = tkt->authorization_data; >- krb5_boolean pac_found = FALSE; > krb5_pac pac = NULL; > unsigned i, j; > size_t len = 0; >- krb5_error_code ret; >+ krb5_error_code ret = 0; > > *signedticket = FALSE; > *ppac = NULL; >@@ -1377,8 +1376,10 @@ _krb5_kdc_pac_ticket_parse(krb5_context context, > for (i = 0; i < ad->len; i++) { > AuthorizationData child; > >- if (ad->val[i].ad_type == KRB5_AUTHDATA_WIN2K_PAC) >- return KRB5KDC_ERR_BADOPTION; >+ if (ad->val[i].ad_type == KRB5_AUTHDATA_WIN2K_PAC) { >+ ret = KRB5KDC_ERR_BADOPTION; >+ goto out; >+ } > > if (ad->val[i].ad_type != KRB5_AUTHDATA_IF_RELEVANT) > continue; >@@ -1390,79 +1391,84 @@ _krb5_kdc_pac_ticket_parse(krb5_context context, > if (ret) { > krb5_set_error_message(context, ret, "Failed to decode " > "AD-IF-RELEVANT with %d", ret); >- return ret; >+ goto out; > } > > for (j = 0; j < child.len; j++) { >- if (child.val[j].ad_type == KRB5_AUTHDATA_WIN2K_PAC) { >- krb5_data adifr_data = ad->val[i].ad_data; >- krb5_data pac_data = child.val[j].ad_data; >- krb5_data recoded_adifr; >- >- if (pac_found) { >- free_AuthorizationData(&child); >- return KRB5KDC_ERR_BADOPTION; >- } >- pac_found = TRUE; >- >- ret = krb5_pac_parse(context, >- pac_data.data, >- pac_data.length, >- &pac); >- if (ret) { >- free_AuthorizationData(&child); >- return ret; >- } >- >- if (pac->ticket_checksum == NULL) { >- free_AuthorizationData(&child); >- *ppac = pac; >- continue; >- } >- >- /* >- * Encode the ticket with the PAC replaced with a single zero >- * byte, to be used as input data to the ticket signature. >- */ >- >- child.val[j].ad_data = single_zero_pac; >- >- ASN1_MALLOC_ENCODE(AuthorizationData, recoded_adifr.data, >- recoded_adifr.length, &child, &len, ret); >- if (recoded_adifr.length != len) >- krb5_abortx(context, "Internal error in ASN.1 encoder"); >- >- child.val[j].ad_data = pac_data; >+ krb5_data adifr_data = ad->val[i].ad_data; >+ krb5_data pac_data = child.val[j].ad_data; >+ krb5_data recoded_adifr; >+ >+ if (child.val[j].ad_type != KRB5_AUTHDATA_WIN2K_PAC) >+ continue; >+ >+ if (pac != NULL) { >+ free_AuthorizationData(&child); >+ ret = KRB5KDC_ERR_BADOPTION; >+ goto out; >+ } >+ >+ ret = krb5_pac_parse(context, >+ pac_data.data, >+ pac_data.length, >+ &pac); >+ if (ret) { > free_AuthorizationData(&child); >+ goto out; >+ } > >- if (ret) { >- krb5_pac_free(context, pac); >- return ret; >- } >+ if (pac->ticket_checksum == NULL) >+ continue; > >- ad->val[i].ad_data = recoded_adifr; >+ /* >+ * Encode the ticket with the PAC replaced with a single zero >+ * byte, to be used as input data to the ticket signature. >+ */ > >- ASN1_MALLOC_ENCODE(EncTicketPart, >- pac->ticket_sign_data.data, >- pac->ticket_sign_data.length, tkt, &len, >- ret); >- if(pac->ticket_sign_data.length != len) >- krb5_abortx(context, "Internal error in ASN.1 encoder"); >+ child.val[j].ad_data = single_zero_pac; > >- ad->val[i].ad_data = adifr_data; >- krb5_data_free(&recoded_adifr); >+ ASN1_MALLOC_ENCODE(AuthorizationData, recoded_adifr.data, >+ recoded_adifr.length, &child, &len, ret); >+ if (recoded_adifr.length != len) >+ krb5_abortx(context, "Internal error in ASN.1 encoder"); > >- if (ret) { >- krb5_pac_free(context, pac); >- return ret; >- } >+ child.val[j].ad_data = pac_data; > >- *signedticket = TRUE; >- *ppac = pac; >+ if (ret) { >+ free_AuthorizationData(&child); >+ goto out; > } >+ >+ ad->val[i].ad_data = recoded_adifr; >+ >+ ASN1_MALLOC_ENCODE(EncTicketPart, >+ pac->ticket_sign_data.data, >+ pac->ticket_sign_data.length, tkt, &len, >+ ret); >+ if (pac->ticket_sign_data.length != len) >+ krb5_abortx(context, "Internal error in ASN.1 encoder"); >+ >+ ad->val[i].ad_data = adifr_data; >+ krb5_data_free(&recoded_adifr); >+ >+ if (ret) { >+ free_AuthorizationData(&child); >+ goto out; >+ } >+ >+ *signedticket = TRUE; > } > free_AuthorizationData(&child); > } >+ >+out: >+ if (ret) { >+ krb5_pac_free(context, pac); >+ return ret; >+ } >+ >+ *ppac = pac; >+ > return 0; > } > >-- >2.25.1 > > >From 70f3343ab81fdd32835e9fcf3007f97d09db4a36 Mon Sep 17 00:00:00 2001 >From: Luke Howard <lukeh@padl.com> >Date: Fri, 17 Sep 2021 13:57:57 +1000 >Subject: [PATCH 124/159] krb5: return KRB5KRB_AP_ERR_INAPP_CKSUM if PAC > checksum fails > >Return KRB5KRB_AP_ERR_INAPP_CKSUM instead of EINVAL when verifying a PAC, if >the checksum is absent or unkeyed. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >[jsutton@samba.org Cherry-picked from Heimdal commit >c4b99b48c4b18f30d504b427bc1961d7a71f631e] > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit d6a472e953545ec3858ca969c1a4191e4f27ba63) >--- > source4/heimdal/lib/krb5/pac.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > >diff --git a/source4/heimdal/lib/krb5/pac.c b/source4/heimdal/lib/krb5/pac.c >index 922a8710eda..3e45125d35e 100644 >--- a/source4/heimdal/lib/krb5/pac.c >+++ b/source4/heimdal/lib/krb5/pac.c >@@ -489,13 +489,13 @@ verify_checksum(krb5_context context, > } > ret = krb5_storage_read(sp, cksum.checksum.data, cksum.checksum.length); > if (ret != (int)cksum.checksum.length) { >- ret = EINVAL; >+ ret = KRB5KRB_AP_ERR_INAPP_CKSUM; > krb5_set_error_message(context, ret, "PAC checksum missing checksum"); > goto out; > } > > if (!krb5_checksum_is_keyed(context, cksum.cksumtype)) { >- ret = EINVAL; >+ ret = KRB5KRB_AP_ERR_INAPP_CKSUM; > krb5_set_error_message(context, ret, "Checksum type %d not keyed", > cksum.cksumtype); > goto out; >-- >2.25.1 > > >From 4f95c4f4a38b14b8405978cb0e9cc4efc943ab77 Mon Sep 17 00:00:00 2001 >From: Luke Howard <lukeh@padl.com> >Date: Sun, 6 Jan 2019 17:54:58 +1100 >Subject: [PATCH 125/159] kdc: only set HDB_F_GET_KRBTGT when requesting TGS > principal > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >[jsutton@samba.org Backported from Heimdal commit > f1dd2b818aa0866960945edea02a6bc782ed697c > - Removed change to _kdc_find_etype() use_strongest_session_key > parameter since Samba's Heimdal version uses different logic >] > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit db30b71f79864a20b38a1f812a5df833f3a92de8) >--- > source4/heimdal/kdc/kerberos5.c | 5 ++++- > 1 file changed, 4 insertions(+), 1 deletion(-) > >diff --git a/source4/heimdal/kdc/kerberos5.c b/source4/heimdal/kdc/kerberos5.c >index 7b17d2539ce..d1fd201113b 100644 >--- a/source4/heimdal/kdc/kerberos5.c >+++ b/source4/heimdal/kdc/kerberos5.c >@@ -983,6 +983,7 @@ _kdc_as_rep(krb5_context context, > pk_client_params *pkp = NULL; > #endif > const EncryptionKey *pk_reply_key = NULL; >+ krb5_boolean is_tgs; > > memset(&rep, 0, sizeof(rep)); > memset(&session_key, 0, sizeof(session_key)); >@@ -1033,6 +1034,8 @@ _kdc_as_rep(krb5_context context, > kdc_log(context, config, 0, "AS-REQ %s from %s for %s", > client_name, from, server_name); > >+ is_tgs = krb5_principal_is_krbtgt(context, server_princ); >+ > /* > * > */ >@@ -1101,7 +1104,7 @@ _kdc_as_rep(krb5_context context, > goto out; > } > ret = _kdc_db_fetch(context, config, server_princ, >- HDB_F_GET_SERVER|HDB_F_GET_KRBTGT | flags, >+ HDB_F_GET_SERVER | flags | (is_tgs ? HDB_F_GET_KRBTGT : 0), > NULL, NULL, &server); > if(ret == HDB_ERR_NOT_FOUND_HERE) { > kdc_log(context, config, 5, "target %s does not have secrets at this KDC, need to proxy", server_name); >-- >2.25.1 > > >From f88673a09de41ac8cc0002327b0b09c499f75e54 Mon Sep 17 00:00:00 2001 >From: Luke Howard <lukeh@padl.com> >Date: Thu, 23 Sep 2021 14:39:35 +1000 >Subject: [PATCH 126/159] kdc: use ticket client name when signing PAC > >The principal in the PAC_LOGON_NAME buffer is expected to match the client name >in the ticket. Previously we were setting this to the canonical client name, >which would have broken PAC validation if the client did not request name >canonicalization > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >[jsutton@samba.org Backported from Heimdal commit > 3b0856cab2b25624deb1f6e0e67637ba96a647ac > - Renamed variable to avoid shadowing existing variable >] > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 75d1a7cd14b134506061ed64ddb9b99856231d2c) >--- > source4/heimdal/kdc/kerberos5.c | 12 +++++++++++- > 1 file changed, 11 insertions(+), 1 deletion(-) > >diff --git a/source4/heimdal/kdc/kerberos5.c b/source4/heimdal/kdc/kerberos5.c >index d1fd201113b..6dc945b134a 100644 >--- a/source4/heimdal/kdc/kerberos5.c >+++ b/source4/heimdal/kdc/kerberos5.c >@@ -1716,6 +1716,7 @@ _kdc_as_rep(krb5_context context, > krb5_pac p = NULL; > krb5_data data; > uint16_t rodc_id; >+ krb5_principal client_pac; > > ret = _kdc_pac_generate(context, client, pk_reply_key, &p); > if (ret) { >@@ -1726,12 +1727,21 @@ _kdc_as_rep(krb5_context context, > if (p != NULL) { > rodc_id = server->entry.kvno >> 16; > >+ /* libkrb5 expects ticket and PAC client names to match */ >+ ret = _krb5_principalname2krb5_principal(context, &client_pac, >+ et.cname, et.crealm); >+ if (ret) { >+ krb5_pac_free(context, p); >+ goto out; >+ } >+ > ret = _krb5_pac_sign(context, p, et.authtime, >- client->entry.principal, >+ client_pac, > &skey->key, /* Server key */ > &skey->key, /* FIXME: should be krbtgt key */ > rodc_id, > &data); >+ krb5_free_principal(context, client_pac); > krb5_pac_free(context, p); > if (ret) { > kdc_log(context, config, 0, "PAC signing failed for -- %s", >-- >2.25.1 > > >From 28bf8d7af88a475ce590b90697f5bdc3e48eefa0 Mon Sep 17 00:00:00 2001 >From: Luke Howard <lukeh@padl.com> >Date: Thu, 23 Sep 2021 17:51:51 +1000 >Subject: [PATCH 127/159] kdc: correctly generate PAC TGS signature > >When generating an AS-REQ, the TGS signature was incorrectly generated using >the server key, which would fail to validate if the server was not also the >TGS. Fix this. > >Patch from Isaac Bourkis <iboukris@gmail.com>. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >[jsutton@samba.org Backported from Heimdal commit > e7863e2af922809dad25a2e948e98c408944d551 > - Samba's Heimdal version does not have the generate_pac() helper > function. > - Samba's Heimdal version does not use the 'r' context variable. >] > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 91e684f5dcb48b76e6a322c15acb53cbce5c275a) >--- > source4/heimdal/kdc/kerberos5.c | 49 ++++++++++++++++++++++++++++++++- > 1 file changed, 48 insertions(+), 1 deletion(-) > >diff --git a/source4/heimdal/kdc/kerberos5.c b/source4/heimdal/kdc/kerberos5.c >index 6dc945b134a..a131f1af08e 100644 >--- a/source4/heimdal/kdc/kerberos5.c >+++ b/source4/heimdal/kdc/kerberos5.c >@@ -948,6 +948,33 @@ _kdc_is_anonymous(krb5_context context, krb5_principal principal) > return 1; > } > >+static krb5_error_code >+get_local_tgs(krb5_context context, >+ krb5_kdc_configuration *config, >+ krb5_const_realm realm, >+ hdb_entry_ex **krbtgt) >+{ >+ krb5_error_code ret; >+ krb5_principal tgs_name; >+ >+ *krbtgt = NULL; >+ >+ ret = krb5_make_principal(context, >+ &tgs_name, >+ realm, >+ KRB5_TGS_NAME, >+ realm, >+ NULL); >+ if (ret) >+ return ret; >+ >+ ret = _kdc_db_fetch(context, config, tgs_name, >+ HDB_F_GET_KRBTGT, NULL, NULL, krbtgt); >+ krb5_free_principal(context, tgs_name); >+ >+ return ret; >+} >+ > /* > * > */ >@@ -984,6 +1011,8 @@ _kdc_as_rep(krb5_context context, > #endif > const EncryptionKey *pk_reply_key = NULL; > krb5_boolean is_tgs; >+ hdb_entry_ex *krbtgt = NULL; >+ Key *krbtgt_key = NULL; > > memset(&rep, 0, sizeof(rep)); > memset(&session_key, 0, sizeof(session_key)); >@@ -1466,6 +1495,22 @@ _kdc_as_rep(krb5_context context, > if(ret) > goto out; > >+ /* If server is not krbtgt, fetch local krbtgt key for signing authdata */ >+ if (is_tgs) { >+ krbtgt_key = skey; >+ } else { >+ ret = get_local_tgs(context, config, server_princ->realm, >+ &krbtgt); >+ if (ret) >+ goto out; >+ >+ ret = _kdc_get_preferred_key(context, config, krbtgt, >+ server_princ->realm, >+ NULL, &krbtgt_key); >+ if (ret) >+ goto out; >+ } >+ > if(f.renew || f.validate || f.proxy || f.forwarded || f.enc_tkt_in_skey > || (f.request_anonymous && !config->allow_anonymous)) { > ret = KRB5KDC_ERR_BADOPTION; >@@ -1738,7 +1783,7 @@ _kdc_as_rep(krb5_context context, > ret = _krb5_pac_sign(context, p, et.authtime, > client_pac, > &skey->key, /* Server key */ >- &skey->key, /* FIXME: should be krbtgt key */ >+ &krbtgt_key->key, /* TGS key */ > rodc_id, > &data); > krb5_free_principal(context, client_pac); >@@ -1807,6 +1852,8 @@ out: > _kdc_free_ent(context, client); > if(server) > _kdc_free_ent(context, server); >+ if (krbtgt) >+ _kdc_free_ent(context, krbtgt); > return ret; > } > >-- >2.25.1 > > >From 6ff1595ebea528dc06648d3e534036a8c7a8514c Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 11 Aug 2021 13:27:11 +1200 >Subject: [PATCH 128/159] s4/heimdal/lib/krb5/pac.c: Align PAC buffers to match > Windows > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 28a5a586c8e9cd155d676dcfcb81a2587ace99d1) >--- > selftest/knownfail_heimdal_kdc | 1 + > source4/heimdal/lib/krb5/pac.c | 14 +++++++++++++- > 2 files changed, 14 insertions(+), 1 deletion(-) > >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 4ec682c01d0..20eea7f2d7e 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -124,6 +124,7 @@ > # > # S4U tests > # >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_bronze_bit_constrained_delegation_old_checksum > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_bronze_bit_rbcd_old_checksum > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_no_service_pac > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_unkeyed_client_checksum >diff --git a/source4/heimdal/lib/krb5/pac.c b/source4/heimdal/lib/krb5/pac.c >index 3e45125d35e..6535a9bdcc4 100644 >--- a/source4/heimdal/lib/krb5/pac.c >+++ b/source4/heimdal/lib/krb5/pac.c >@@ -62,10 +62,12 @@ struct krb5_pac_data { > #define PACTYPE_SIZE 8 > #define PAC_INFO_BUFFER_SIZE 16 > >+#define PAC_LOGON_INFO 1 > #define PAC_SERVER_CHECKSUM 6 > #define PAC_PRIVSVR_CHECKSUM 7 > #define PAC_LOGON_NAME 10 > #define PAC_CONSTRAINED_DELEGATION 11 >+#define PAC_UPN_DNS_INFO 12 > #define PAC_TICKET_CHECKSUM 16 > > #define CHECK(r,f,l) \ >@@ -1184,7 +1186,17 @@ _krb5_pac_sign(krb5_context context, > ret = krb5_enomem(context); > goto out; > } >- /* XXX if not aligned, fill_zeros */ >+ >+ if (p->pac->buffers[i].type == PAC_LOGON_INFO >+ || p->pac->buffers[i].type == PAC_UPN_DNS_INFO) >+ { >+ uint32_t rounded = (len + PAC_ALIGNMENT - 1) / PAC_ALIGNMENT >+ * PAC_ALIGNMENT; >+ uint32_t remaining = rounded - len; >+ CHECK(ret, fill_zeros(context, spdata, remaining), out); >+ >+ len = rounded; >+ } > } > > /* write header */ >-- >2.25.1 > > >From 984fbbd3ac9ca6688a4a0e33c5fe26c58bca8ea2 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 8 Oct 2021 15:43:41 +1300 >Subject: [PATCH 129/159] heimdal: Make _krb5_pac_get_kdc_checksum_info() into > a global function > >This lets us call it from Samba. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 3bdce12789af1e7a7aba56691f184625a432410d) >--- > source4/heimdal/lib/krb5/pac.c | 8 ++++---- > source4/heimdal/lib/krb5/version-script.map | 2 +- > 2 files changed, 5 insertions(+), 5 deletions(-) > >diff --git a/source4/heimdal/lib/krb5/pac.c b/source4/heimdal/lib/krb5/pac.c >index 6535a9bdcc4..f6d38178a88 100644 >--- a/source4/heimdal/lib/krb5/pac.c >+++ b/source4/heimdal/lib/krb5/pac.c >@@ -1311,10 +1311,10 @@ out: > } > > KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL >-_krb5_pac_get_kdc_checksum_info(krb5_context context, >- krb5_pac pac, >- krb5_cksumtype *cstype, >- uint16_t *rodc_id) >+krb5_pac_get_kdc_checksum_info(krb5_context context, >+ krb5_pac pac, >+ krb5_cksumtype *cstype, >+ uint16_t *rodc_id) > { > krb5_error_code ret; > krb5_storage *sp = NULL; >diff --git a/source4/heimdal/lib/krb5/version-script.map b/source4/heimdal/lib/krb5/version-script.map >index e04e02aace9..2359001e9da 100644 >--- a/source4/heimdal/lib/krb5/version-script.map >+++ b/source4/heimdal/lib/krb5/version-script.map >@@ -470,6 +470,7 @@ HEIMDAL_KRB5_2.0 { > krb5_pac_add_buffer; > krb5_pac_free; > krb5_pac_get_buffer; >+ krb5_pac_get_kdc_checksum_info; > krb5_pac_get_types; > krb5_pac_init; > krb5_pac_parse; >@@ -753,7 +754,6 @@ HEIMDAL_KRB5_2.0 { > _krb5_pac_sign; > _krb5_kdc_pac_sign_ticket; > _krb5_kdc_pac_ticket_parse; >- _krb5_pac_get_kdc_checksum_info; > _kdc_tkt_insert_pac; > _kdc_tkt_add_if_relevant_ad; > _krb5_parse_moduli; >-- >2.25.1 > > >From 961b5be62ef8e303f04eaca5c1e0667842060b93 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 8 Oct 2021 16:08:39 +1300 >Subject: [PATCH 130/159] s4:kdc: Check ticket signature > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 02fa69c6c73c01d82807be4370e838f3e7c66f35) >--- > selftest/knownfail_heimdal_kdc | 9 -- > source4/kdc/wdc-samba4.c | 270 ++++++++++++++++++++++++++------- > 2 files changed, 215 insertions(+), 64 deletions(-) > >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 20eea7f2d7e..683dbacb979 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -124,13 +124,8 @@ > # > # S4U tests > # >-^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_bronze_bit_constrained_delegation_old_checksum > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_bronze_bit_rbcd_old_checksum > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_no_service_pac >-^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_unkeyed_client_checksum >-^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_unkeyed_service_checksum >-^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_zeroed_client_checksum >-^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_zeroed_service_checksum > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_existing_delegation_info > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_missing_client_checksum > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_no_client_pac_a >@@ -142,10 +137,6 @@ > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_forwardable > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_not_trusted_empty_allowed > # >-# RODC tests >-# >-^samba.tests.krb5.rodc_tests.samba.tests.krb5.rodc_tests.RodcKerberosTests.test_rodc_ticket_signature >-# > # The lack of KRB5SignedPath means we no longer return > # KRB5KRB_ERR_RESPONSE_TOO_BIG in this specific case > # >diff --git a/source4/kdc/wdc-samba4.c b/source4/kdc/wdc-samba4.c >index 037db40ce46..589df8a651d 100644 >--- a/source4/kdc/wdc-samba4.c >+++ b/source4/kdc/wdc-samba4.c >@@ -23,7 +23,10 @@ > > #include "includes.h" > #include "kdc/kdc-glue.h" >+#include "kdc/db-glue.h" > #include "kdc/pac-glue.h" >+#include "sdb.h" >+#include "sdb_hdb.h" > > /* > * Given the right private pointer from hdb_samba4, >@@ -94,15 +97,13 @@ static krb5_error_code samba_wdc_get_pac_compat(void *priv, krb5_context context > return samba_wdc_get_pac(priv, context, client, NULL, pac); > } > >-/* Resign (and reform, including possibly new groups) a PAC */ >- >-static krb5_error_code samba_wdc_reget_pac(void *priv, krb5_context context, >- const krb5_principal client_principal, >- const krb5_principal delegated_proxy_principal, >- struct hdb_entry_ex *client, >- struct hdb_entry_ex *server, >- struct hdb_entry_ex *krbtgt, >- krb5_pac *pac) >+static krb5_error_code samba_wdc_reget_pac2(krb5_context context, >+ const krb5_principal delegated_proxy_principal, >+ struct hdb_entry_ex *client, >+ struct hdb_entry_ex *server, >+ struct hdb_entry_ex *krbtgt, >+ krb5_pac *pac, >+ krb5_cksumtype ctype) > { > struct samba_kdc_entry *p = > talloc_get_type_abort(server->ctx, >@@ -110,15 +111,13 @@ static krb5_error_code samba_wdc_reget_pac(void *priv, krb5_context context, > struct samba_kdc_entry *krbtgt_skdc_entry = > talloc_get_type_abort(krbtgt->ctx, > struct samba_kdc_entry); >- TALLOC_CTX *mem_ctx = talloc_named(p, 0, "samba_kdc_reget_pac context"); >+ TALLOC_CTX *mem_ctx = talloc_named(p, 0, "samba_kdc_reget_pac2 context"); > krb5_pac new_pac = NULL; > DATA_BLOB *pac_blob = NULL; > DATA_BLOB *upn_blob = NULL; > DATA_BLOB *deleg_blob = NULL; > krb5_error_code ret; > NTSTATUS nt_status; >- struct PAC_SIGNATURE_DATA *pac_srv_sig; >- struct PAC_SIGNATURE_DATA *pac_kdc_sig; > bool is_in_db, is_untrusted; > size_t num_types = 0; > uint32_t *types = NULL; >@@ -130,6 +129,7 @@ static krb5_error_code samba_wdc_reget_pac(void *priv, krb5_context context, > ssize_t upn_dns_info_idx = -1; > ssize_t srv_checksum_idx = -1; > ssize_t kdc_checksum_idx = -1; >+ ssize_t tkt_checksum_idx = -1; > > if (!mem_ctx) { > return ENOMEM; >@@ -150,6 +150,71 @@ static krb5_error_code samba_wdc_reget_pac(void *priv, krb5_context context, > return ret; > } > >+ if (delegated_proxy_principal != NULL) { >+ krb5_enctype etype; >+ Key *key = NULL; >+ >+ if (!is_in_db) { >+ /* >+ * The RODC-issued PAC was signed by a KDC entry that we >+ * don't have a key for. The server signature is not >+ * trustworthy, since it could have been created by the >+ * server we got the ticket from. We must not proceed as >+ * otherwise the ticket signature is unchecked. >+ */ >+ talloc_free(mem_ctx); >+ return HDB_ERR_NOT_FOUND_HERE; >+ } >+ >+ /* Fetch the correct key depending on the checksum type. */ >+ if (ctype == CKSUMTYPE_HMAC_MD5) { >+ etype = ENCTYPE_ARCFOUR_HMAC; >+ } else { >+ ret = krb5_cksumtype_to_enctype(context, >+ ctype, >+ &etype); >+ if (ret != 0) { >+ talloc_free(mem_ctx); >+ return ret; >+ } >+ } >+ ret = hdb_enctype2key(context, &krbtgt->entry, etype, &key); >+ if (ret != 0) { >+ return ret; >+ } >+ >+ /* Check the KDC and ticket signatures. */ >+ ret = krb5_pac_verify(context, >+ *pac, >+ 0, >+ NULL, >+ NULL, >+ &key->key); >+ if (ret != 0) { >+ DEBUG(1, ("PAC KDC signature failed to verify\n")); >+ talloc_free(mem_ctx); >+ return ret; >+ } >+ >+ deleg_blob = talloc_zero(mem_ctx, DATA_BLOB); >+ if (!deleg_blob) { >+ talloc_free(mem_ctx); >+ return ENOMEM; >+ } >+ >+ nt_status = samba_kdc_update_delegation_info_blob(mem_ctx, >+ context, *pac, >+ server->entry.principal, >+ delegated_proxy_principal, >+ deleg_blob); >+ if (!NT_STATUS_IS_OK(nt_status)) { >+ DEBUG(0, ("Building PAC failed: %s\n", >+ nt_errstr(nt_status))); >+ talloc_free(mem_ctx); >+ return EINVAL; >+ } >+ } >+ > if (is_untrusted) { > struct samba_kdc_entry *client_skdc_entry = NULL; > >@@ -173,52 +238,10 @@ static krb5_error_code samba_wdc_reget_pac(void *priv, krb5_context context, > return ENOMEM; > } > >- pac_srv_sig = talloc_zero(mem_ctx, struct PAC_SIGNATURE_DATA); >- if (!pac_srv_sig) { >- talloc_free(mem_ctx); >- return ENOMEM; >- } >- >- pac_kdc_sig = talloc_zero(mem_ctx, struct PAC_SIGNATURE_DATA); >- if (!pac_kdc_sig) { >- talloc_free(mem_ctx); >- return ENOMEM; >- } >- > nt_status = samba_kdc_update_pac_blob(mem_ctx, context, > krbtgt_skdc_entry->kdc_db_ctx->samdb, > *pac, pac_blob, >- pac_srv_sig, pac_kdc_sig); >- if (!NT_STATUS_IS_OK(nt_status)) { >- DEBUG(0, ("Building PAC failed: %s\n", >- nt_errstr(nt_status))); >- talloc_free(mem_ctx); >- return EINVAL; >- } >- >- if (is_in_db) { >- /* Now check the KDC signature, fetching the correct key based on the enc type */ >- ret = kdc_check_pac(context, pac_srv_sig->signature, pac_kdc_sig, krbtgt); >- if (ret != 0) { >- DEBUG(1, ("PAC KDC signature failed to verify\n")); >- talloc_free(mem_ctx); >- return ret; >- } >- } >- } >- >- if (delegated_proxy_principal) { >- deleg_blob = talloc_zero(mem_ctx, DATA_BLOB); >- if (!deleg_blob) { >- talloc_free(mem_ctx); >- return ENOMEM; >- } >- >- nt_status = samba_kdc_update_delegation_info_blob(mem_ctx, >- context, *pac, >- server->entry.principal, >- delegated_proxy_principal, >- deleg_blob); >+ NULL, NULL); > if (!NT_STATUS_IS_OK(nt_status)) { > DEBUG(0, ("Building PAC failed: %s\n", > nt_errstr(nt_status))); >@@ -308,6 +331,18 @@ static krb5_error_code samba_wdc_reget_pac(void *priv, krb5_context context, > } > kdc_checksum_idx = i; > break; >+ case PAC_TYPE_TICKET_CHECKSUM: >+ if (tkt_checksum_idx != -1) { >+ DEBUG(1, ("ticket checksum type[%"PRIu32"] twice [%zd] and [%zu]: \n", >+ types[i], >+ tkt_checksum_idx, >+ i)); >+ SAFE_FREE(types); >+ talloc_free(mem_ctx); >+ return EINVAL; >+ } >+ tkt_checksum_idx = i; >+ break; > default: > continue; > } >@@ -471,6 +506,131 @@ static krb5_error_code samba_wdc_reget_pac(void *priv, krb5_context context, > return ret; > } > >+/* Resign (and reform, including possibly new groups) a PAC */ >+ >+static krb5_error_code samba_wdc_reget_pac(void *priv, krb5_context context, >+ const krb5_principal client_principal, >+ const krb5_principal delegated_proxy_principal, >+ struct hdb_entry_ex *client, >+ struct hdb_entry_ex *server, >+ struct hdb_entry_ex *krbtgt, >+ krb5_pac *pac) >+{ >+ struct samba_kdc_entry *krbtgt_skdc_entry = >+ talloc_get_type_abort(krbtgt->ctx, >+ struct samba_kdc_entry); >+ krb5_error_code ret; >+ krb5_cksumtype ctype = CKSUMTYPE_NONE; >+ struct hdb_entry_ex signing_krbtgt_hdb; >+ >+ if (delegated_proxy_principal) { >+ uint16_t rodc_id; >+ unsigned int my_krbtgt_number; >+ >+ /* >+ * We're using delegated_proxy_principal for the moment to >+ * indicate cases where the ticket was encrypted with the server >+ * key, and not a krbtgt key. This cannot be trusted, so we need >+ * to find a krbtgt key that signs the PAC in order to trust the >+ * ticket. >+ * >+ * The krbtgt passed in to this function refers to the krbtgt >+ * used to decrypt the ticket of the server requesting >+ * S4U2Proxy. >+ * >+ * When we implement service ticket renewal, we need to check >+ * the PAC, and this will need to be updated. >+ */ >+ ret = krb5_pac_get_kdc_checksum_info(context, >+ *pac, >+ &ctype, >+ &rodc_id); >+ if (ret != 0) { >+ DEBUG(1, ("Failed to get PAC checksum info\n")); >+ return ret; >+ } >+ >+ /* >+ * We need to check the KDC and ticket signatures, fetching the >+ * correct key based on the enctype. >+ */ >+ >+ my_krbtgt_number = krbtgt_skdc_entry->kdc_db_ctx->my_krbtgt_number; >+ >+ if (my_krbtgt_number != 0) { >+ /* >+ * If we are an RODC, and we are not the KDC that signed >+ * the evidence ticket, then we need to proxy the >+ * request. >+ */ >+ if (rodc_id != my_krbtgt_number) { >+ return HDB_ERR_NOT_FOUND_HERE; >+ } >+ } else { >+ /* >+ * If we are a DC, the ticket may have been signed by a >+ * different KDC than the one that issued the header >+ * ticket. >+ */ >+ if (rodc_id != krbtgt->entry.kvno >> 16) { >+ struct sdb_entry_ex signing_krbtgt_sdb; >+ >+ /* >+ * If we didn't sign the ticket, then return an >+ * error. >+ */ >+ if (rodc_id != 0) { >+ return KRB5KRB_AP_ERR_MODIFIED; >+ } >+ >+ /* >+ * Fetch our key from the database. To support >+ * key rollover, we're going to need to try >+ * multiple keys by trial and error. For now, >+ * krbtgt keys aren't assumed to change. >+ */ >+ ret = samba_kdc_fetch(context, >+ krbtgt_skdc_entry->kdc_db_ctx, >+ krbtgt->entry.principal, >+ SDB_F_GET_KRBTGT | SDB_F_CANON, >+ 0, >+ &signing_krbtgt_sdb); >+ if (ret != 0) { >+ return ret; >+ } >+ >+ ret = sdb_entry_ex_to_hdb_entry_ex(context, >+ &signing_krbtgt_sdb, >+ &signing_krbtgt_hdb); >+ sdb_free_entry(&signing_krbtgt_sdb); >+ if (ret != 0) { >+ return ret; >+ } >+ >+ /* >+ * Replace the krbtgt entry with our own entry >+ * for further processing. >+ */ >+ krbtgt = &signing_krbtgt_hdb; >+ } >+ } >+ } >+ >+ ret = samba_wdc_reget_pac2(context, >+ delegated_proxy_principal, >+ client, >+ server, >+ krbtgt, >+ pac, >+ ctype); >+ >+ if (krbtgt == &signing_krbtgt_hdb) { >+ hdb_free_entry(context, &signing_krbtgt_hdb); >+ } >+ >+ return ret; >+} >+ > static char *get_netbios_name(TALLOC_CTX *mem_ctx, HostAddresses *addrs) > { > char *nb_name = NULL; >-- >2.25.1 > > >From 346c257baf22cb5914cc57b1834504dbe3860337 Mon Sep 17 00:00:00 2001 >From: Nicolas Williams <nico@twosigma.com> >Date: Sun, 10 Oct 2021 21:55:59 -0500 >Subject: [PATCH 131/159] krb5: Fix PAC signature leak affecting KDC > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >[jsutton@samba.org Cherry-picked from Heimdal commit > 54581d2d52443a9a07ed5980df331f660b397dcf] > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit f6adfefbbb41b9100736134d0f975f1ec0c33c42) >--- > source4/heimdal/lib/krb5/pac.c | 136 +++++++++++++++------------------ > 1 file changed, 61 insertions(+), 75 deletions(-) > >diff --git a/source4/heimdal/lib/krb5/pac.c b/source4/heimdal/lib/krb5/pac.c >index f6d38178a88..05bcc523080 100644 >--- a/source4/heimdal/lib/krb5/pac.c >+++ b/source4/heimdal/lib/krb5/pac.c >@@ -1018,9 +1018,10 @@ _krb5_pac_sign(krb5_context context, > uint32_t server_offset = 0, priv_offset = 0, ticket_offset = 0; > uint32_t server_cksumtype = 0, priv_cksumtype = 0; > int num = 0; >- size_t i; >+ size_t i, sz; > krb5_data logon, d; > >+ krb5_data_zero(&d); > krb5_data_zero(&logon); > > for (i = 0; i < p->pac->numbuffers; i++) { >@@ -1080,8 +1081,10 @@ _krb5_pac_sign(krb5_context context, > void *ptr; > > ptr = realloc(p->pac, sizeof(*p->pac) + (sizeof(p->pac->buffers[0]) * (p->pac->numbuffers + num - 1))); >- if (ptr == NULL) >- return krb5_enomem(context); >+ if (ptr == NULL) { >+ ret = krb5_enomem(context); >+ goto out; >+ } > > p->pac = ptr; > >@@ -1109,30 +1112,33 @@ _krb5_pac_sign(krb5_context context, > > /* Calculate LOGON NAME */ > ret = build_logon_name(context, authtime, principal, &logon); >- if (ret) >- goto out; > > /* Set lengths for checksum */ >- ret = pac_checksum(context, server_key, &server_cksumtype, &server_size); >- if (ret) >- goto out; >+ if (ret == 0) >+ ret = pac_checksum(context, server_key, &server_cksumtype, &server_size); > >- ret = pac_checksum(context, priv_key, &priv_cksumtype, &priv_size); >- if (ret) >- goto out; >+ if (ret == 0) >+ ret = pac_checksum(context, priv_key, &priv_cksumtype, &priv_size); > > /* Encode PAC */ >- sp = krb5_storage_emem(); >- if (sp == NULL) >- return krb5_enomem(context); >- >- krb5_storage_set_flags(sp, KRB5_STORAGE_BYTEORDER_LE); >+ if (ret == 0) { >+ sp = krb5_storage_emem(); >+ if (sp == NULL) >+ ret = krb5_enomem(context); >+ } > >- spdata = krb5_storage_emem(); >- if (spdata == NULL) { >- krb5_storage_free(sp); >- return krb5_enomem(context); >+ if (ret == 0) { >+ krb5_storage_set_flags(sp, KRB5_STORAGE_BYTEORDER_LE); >+ spdata = krb5_storage_emem(); >+ if (spdata == NULL) { >+ krb5_storage_free(sp); >+ ret = krb5_enomem(context); >+ } > } >+ >+ if (ret) >+ goto out; >+ > krb5_storage_set_flags(spdata, KRB5_STORAGE_BYTEORDER_LE); > > CHECK(ret, krb5_store_uint32(sp, p->pac->numbuffers), out); >@@ -1222,77 +1228,56 @@ _krb5_pac_sign(krb5_context context, > /* assert (server_offset != 0 && priv_offset != 0); */ > > /* export PAC */ >- ret = krb5_storage_to_data(spdata, &d); >- if (ret) { >- krb5_set_error_message(context, ret, N_("malloc: out of memory", "")); >- goto out; >- } >- ret = krb5_storage_write(sp, d.data, d.length); >- if (ret != (int)d.length) { >- krb5_data_free(&d); >- ret = krb5_enomem(context); >- goto out; >+ if (ret == 0) >+ ret = krb5_storage_to_data(spdata, &d); >+ if (ret == 0) { >+ sz = krb5_storage_write(sp, d.data, d.length); >+ if (sz != d.length) { >+ krb5_data_free(&d); >+ ret = krb5_enomem(context); >+ goto out; >+ } > } > krb5_data_free(&d); > >- ret = krb5_storage_to_data(sp, &d); >- if (ret) { >- ret = krb5_enomem(context); >- goto out; >- } >+ if (ret == 0) >+ ret = krb5_storage_to_data(sp, &d); > > /* sign */ >- if (p->ticket_sign_data.length) { >+ if (ret == 0 && p->ticket_sign_data.length) > ret = create_checksum(context, priv_key, priv_cksumtype, > p->ticket_sign_data.data, > p->ticket_sign_data.length, > (char *)d.data + ticket_offset, priv_size); >- if (ret) { >- krb5_data_free(&d); >- goto out; >- } >- } >- ret = create_checksum(context, server_key, server_cksumtype, >- d.data, d.length, >- (char *)d.data + server_offset, server_size); >- if (ret) { >- krb5_data_free(&d); >- goto out; >- } >- ret = create_checksum(context, priv_key, priv_cksumtype, >- (char *)d.data + server_offset, server_size, >- (char *)d.data + priv_offset, priv_size); >- if (ret) { >- krb5_data_free(&d); >- goto out; >- } >- >- if (rodc_id != 0) { >+ if (ret == 0) >+ ret = create_checksum(context, server_key, server_cksumtype, >+ d.data, d.length, >+ (char *)d.data + server_offset, server_size); >+ if (ret == 0) >+ ret = create_checksum(context, priv_key, priv_cksumtype, >+ (char *)d.data + server_offset, server_size, >+ (char *)d.data + priv_offset, priv_size); >+ if (ret == 0 && rodc_id != 0) { > krb5_data rd; > krb5_storage *rs = krb5_storage_emem(); >- if (rs == NULL) { >- krb5_data_free(&d); >+ if (rs == NULL) > ret = krb5_enomem(context); >- goto out; >- } > krb5_storage_set_flags(rs, KRB5_STORAGE_BYTEORDER_LE); >- ret = krb5_store_uint16(rs, rodc_id); >- if (ret) { >- krb5_storage_free(rs); >- krb5_data_free(&d); >- goto out; >- } >- ret = krb5_storage_to_data(rs, &rd); >+ if (ret == 0) >+ ret = krb5_store_uint16(rs, rodc_id); >+ if (ret == 0) >+ ret = krb5_storage_to_data(rs, &rd); > krb5_storage_free(rs); >- if (ret) { >- krb5_data_free(&d); >+ if (ret) > goto out; >- } > heim_assert(rd.length == sizeof(rodc_id), "invalid length"); > memcpy((char *)d.data + priv_offset + priv_size, rd.data, rd.length); > krb5_data_free(&rd); > } > >+ if (ret) >+ goto out; >+ > /* done */ > *data = d; > >@@ -1302,6 +1287,7 @@ _krb5_pac_sign(krb5_context context, > > return 0; > out: >+ krb5_data_free(&d); > krb5_data_free(&logon); > if (sp) > krb5_storage_free(sp); >@@ -1528,8 +1514,8 @@ _krb5_kdc_pac_sign_ticket(krb5_context context, > > ret = _krb5_pac_sign(context, pac, tkt->authtime, client, server_key, > kdc_key, rodc_id, &rspac); >- if (ret) >- return ret; >- >- return _kdc_tkt_insert_pac(context, tkt, &rspac); >+ if (ret == 0) >+ ret = _kdc_tkt_insert_pac(context, tkt, &rspac); >+ krb5_data_free(&rspac); >+ return ret; > } >-- >2.25.1 > > >From 74ad7812b7f2728e1c18761cd10a9af4009fef07 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Fri, 15 Oct 2021 13:09:20 +1300 >Subject: [PATCH 132/159] selftest/dbcheck: Fix up RODC one-way links (use > correct dbcheck rule) > >The previous commit was correct on intention, but it was not noticed >as there is a race, that the incorrect rule was appended to. > >These links are removed by remove_plausible_deleted_DN_links not >fix_all_old_dn_string_component_mismatch > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz> > >Autobuild-User(master): Andrew Bartlett <abartlet@samba.org> >Autobuild-Date(master): Fri Oct 15 10:00:47 UTC 2021 on sn-devel-184 > >(cherry picked from commit a7ad665e65f0701eb75cac5bc10a366ccd9689f4) >--- > testprogs/blackbox/dbcheck.sh | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > >diff --git a/testprogs/blackbox/dbcheck.sh b/testprogs/blackbox/dbcheck.sh >index e2ba987e2de..5462441005e 100755 >--- a/testprogs/blackbox/dbcheck.sh >+++ b/testprogs/blackbox/dbcheck.sh >@@ -19,12 +19,12 @@ dbcheck() { > > # This list of attributes can be freely extended > dbcheck_fix_one_way_links() { >- $PYTHON $BINDIR/samba-tool dbcheck --quiet --fix --yes fix_all_old_dn_string_component_mismatch --attrs="lastKnownParent defaultObjectCategory fromServer rIDSetReferences msDS-RevealOnDemandGroup msDS-NeverRevealGroup" --cross-ncs $ARGS >+ $PYTHON $BINDIR/samba-tool dbcheck --quiet --fix --yes fix_all_old_dn_string_component_mismatch --attrs="lastKnownParent defaultObjectCategory fromServer rIDSetReferences" --cross-ncs $ARGS > } > > # This list of attributes can be freely extended > dbcheck_fix_stale_links() { >- $PYTHON $BINDIR/samba-tool dbcheck --quiet --fix --yes remove_plausible_deleted_DN_links --attrs="member msDS-NC-Replica-Locations msDS-NC-RO-Replica-Locations" --cross-ncs $ARGS >+ $PYTHON $BINDIR/samba-tool dbcheck --quiet --fix --yes remove_plausible_deleted_DN_links --attrs="member msDS-NC-Replica-Locations msDS-NC-RO-Replica-Locations msDS-RevealOnDemandGroup msDS-NeverRevealGroup" --cross-ncs $ARGS > } > > # This list of attributes can be freely extended >-- >2.25.1 > > >From 817542e52c98e040a30d4880614a2477fceb02a8 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 15 Oct 2021 12:12:30 +1300 >Subject: [PATCH 133/159] heimdal:kdc: Fix ticket signing without a PAC > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit d23d8e859357b0fac4d1f4a49f1dce6cf60d6216) >--- > source4/heimdal/kdc/krb5tgs.c | 6 ++++-- > 1 file changed, 4 insertions(+), 2 deletions(-) > >diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c >index d0483a3903b..2de3b099199 100644 >--- a/source4/heimdal/kdc/krb5tgs.c >+++ b/source4/heimdal/kdc/krb5tgs.c >@@ -695,10 +695,12 @@ tgs_make_reply(krb5_context context, > } > > /* The PAC should be the last change to the ticket. */ >- ret = _krb5_kdc_pac_sign_ticket(context, mspac, tgt_name, serverkey, >- krbtgtkey, rodc_id, add_ticket_sig, &et); >+ if (mspac != NULL) { >+ ret = _krb5_kdc_pac_sign_ticket(context, mspac, tgt_name, serverkey, >+ krbtgtkey, rodc_id, add_ticket_sig, &et); > if (ret) > goto out; >+ } > > /* It is somewhat unclear where the etype in the following > encryption should come from. What we have is a session >-- >2.25.1 > > >From a9f8834e0060062ee0aca79078175a260acb55e4 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 15 Oct 2021 14:26:40 +1300 >Subject: [PATCH 134/159] tests/krb5: Allow get_tgt() to request including or > omitting a PAC > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit e086c6193f6da6fcb5d0bcada2199e9bc7ad25f5) >--- > python/samba/tests/krb5/kdc_base_test.py | 9 +++++---- > 1 file changed, 5 insertions(+), 4 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 87160f675ae..1fc15315b0b 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -1306,9 +1306,9 @@ class KDCBaseTest(RawKerberosTest): > > def get_tgt(self, creds, to_rodc=False, kdc_options=None, > expected_flags=None, unexpected_flags=None, >- fresh=False): >+ pac_request=True, expect_pac=True, fresh=False): > user_name = creds.get_username() >- cache_key = (user_name, to_rodc, kdc_options) >+ cache_key = (user_name, to_rodc, kdc_options, pac_request) > > if not fresh: > tgt = self.tkt_cache.get(cache_key) >@@ -1363,7 +1363,7 @@ class KDCBaseTest(RawKerberosTest): > kdc_options=kdc_options, > preauth_key=None, > ticket_decryption_key=ticket_decryption_key, >- pac_request=True, >+ pac_request=pac_request, > pac_options=pac_options, > to_rodc=to_rodc) > self.check_pre_authentication(rep) >@@ -1405,8 +1405,9 @@ class KDCBaseTest(RawKerberosTest): > kdc_options=kdc_options, > preauth_key=preauth_key, > ticket_decryption_key=ticket_decryption_key, >- pac_request=True, >+ pac_request=pac_request, > pac_options=pac_options, >+ expect_pac=expect_pac, > to_rodc=to_rodc) > self.check_as_reply(rep) > >-- >2.25.1 > > >From 29bf1fae40bed74bbf346c540e6e598e59eca07a Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 15 Oct 2021 14:27:15 +1300 >Subject: [PATCH 135/159] tests/krb5: Allow specifying whether to expect a PAC > with _test_as_exchange() > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 0dc69c1327f72384628a869a00482f6528b8671b) >--- > python/samba/tests/krb5/raw_testcase.py | 2 ++ > 1 file changed, 2 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index e008223eb23..29dc5f397b6 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -3530,6 +3530,7 @@ class RawKerberosTest(TestCaseInTempDir): > ticket_decryption_key=None, > pac_request=None, > pac_options=None, >+ expect_pac=True, > to_rodc=False): > > def _generate_padata_copy(_kdc_exchange_dict, >@@ -3569,6 +3570,7 @@ class RawKerberosTest(TestCaseInTempDir): > kdc_options=str(kdc_options), > pac_request=pac_request, > pac_options=pac_options, >+ expect_pac=expect_pac, > to_rodc=to_rodc) > > rep = self._generic_kdc_exchange(kdc_exchange_dict, >-- >2.25.1 > > >From a1fceb1072fbb19fe6ad5c38b1d6ea38a7b85b6b Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 15 Oct 2021 14:27:25 +1300 >Subject: [PATCH 136/159] tests/krb5: Add method to get the PAC from a ticket > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 288355896a2b6f460c42559ec46ff980ab57782e) >--- > python/samba/tests/krb5/raw_testcase.py | 9 +++++++++ > 1 file changed, 9 insertions(+) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 29dc5f397b6..0790ac13f99 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -3447,6 +3447,15 @@ class RawKerberosTest(TestCaseInTempDir): > _, pac = self.replace_pac(auth_data, None, expect_pac) > return pac > >+ def get_ticket_pac(self, ticket, expect_pac=True): >+ auth_data = ticket.ticket_private.get('authorization-data') >+ if expect_pac: >+ self.assertIsNotNone(auth_data) >+ elif auth_data is None: >+ return None >+ >+ return self.get_pac(auth_data, expect_pac=expect_pac) >+ > def get_krbtgt_checksum_key(self): > krbtgt_creds = self.get_krbtgt_creds() > krbtgt_key = self.TicketDecryptionKey_from_creds(krbtgt_creds) >-- >2.25.1 > > >From c9a315f4d9e8bc930e21d3cbbf6c6aa535ff0f59 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 15 Oct 2021 14:29:26 +1300 >Subject: [PATCH 137/159] tests/krb5: Add tests for requesting a service ticket > without a PAC > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642 > >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): Sun Oct 17 23:40:33 UTC 2021 on sn-devel-184 > >[abartlet@samba.org backported from commit 9d3a691920205f8a9dc05d0e173e25e6a335f139 > as the MIT KDC 1.16 seen on the reference Ubuntu 18.04 does not fail > test_remove_pac] >--- > python/samba/tests/krb5/kdc_tgs_tests.py | 120 +++++++++++++++++++++++ > selftest/knownfail_heimdal_kdc | 5 + > selftest/knownfail_mit_kdc | 4 + > 3 files changed, 129 insertions(+) > >diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py >index 3075cc6b0a9..9d846a2c3ad 100755 >--- a/python/samba/tests/krb5/kdc_tgs_tests.py >+++ b/python/samba/tests/krb5/kdc_tgs_tests.py >@@ -23,15 +23,18 @@ import os > sys.path.insert(0, "bin/python") > os.environ["PYTHONUNBUFFERED"] = "1" > >+import samba.tests.krb5.kcrypto as kcrypto > from samba.tests.krb5.kdc_base_test import KDCBaseTest > from samba.tests.krb5.rfc4120_constants import ( > AES256_CTS_HMAC_SHA1_96, > ARCFOUR_HMAC_MD5, > KRB_ERROR, >+ KRB_TGS_REP, > KDC_ERR_BADMATCH, > NT_PRINCIPAL, > NT_SRV_INST, > ) >+import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 > > global_asn1_print = False > global_hexdump = False >@@ -209,6 +212,123 @@ class KdcTgsTests(KDCBaseTest): > pac_data.account_sid, > "rep = {%s},%s" % (rep, pac_data)) > >+ def _make_tgs_request(self, client_creds, service_creds, tgt, >+ expect_pac=True): >+ client_account = client_creds.get_username() >+ cname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >+ names=[client_account]) >+ >+ service_account = service_creds.get_username() >+ sname = self.PrincipalName_create(name_type=NT_PRINCIPAL, >+ names=[service_account]) >+ >+ realm = service_creds.get_realm() >+ >+ expected_crealm = realm >+ expected_cname = cname >+ expected_srealm = realm >+ expected_sname = sname >+ >+ expected_supported_etypes = service_creds.tgs_supported_enctypes >+ >+ etypes = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) >+ >+ kdc_options = str(krb5_asn1.KDCOptions('canonicalize')) >+ >+ target_decryption_key = self.TicketDecryptionKey_from_creds( >+ service_creds) >+ >+ authenticator_subkey = self.RandomKey(kcrypto.Enctype.AES256) >+ >+ kdc_exchange_dict = self.tgs_exchange_dict( >+ expected_crealm=expected_crealm, >+ expected_cname=expected_cname, >+ expected_srealm=expected_srealm, >+ expected_sname=expected_sname, >+ expected_supported_etypes=expected_supported_etypes, >+ ticket_decryption_key=target_decryption_key, >+ check_rep_fn=self.generic_check_kdc_rep, >+ check_kdc_private_fn=self.generic_check_kdc_private, >+ expected_error_mode=0, >+ tgt=tgt, >+ authenticator_subkey=authenticator_subkey, >+ kdc_options=kdc_options, >+ expect_pac=expect_pac) >+ >+ rep = self._generic_kdc_exchange(kdc_exchange_dict, >+ cname=cname, >+ realm=realm, >+ sname=sname, >+ etypes=etypes) >+ self.check_reply(rep, KRB_TGS_REP) >+ >+ return kdc_exchange_dict['rep_ticket_creds'] >+ >+ def test_request_no_pac(self): >+ client_creds = self.get_client_creds() >+ service_creds = self.get_service_creds() >+ >+ tgt = self.get_tgt(client_creds, pac_request=False, >+ expect_pac=False) >+ >+ pac = self.get_ticket_pac(tgt, expect_pac=False) >+ self.assertIsNone(pac) >+ >+ ticket = self._make_tgs_request(client_creds, service_creds, tgt, >+ expect_pac=False) >+ >+ pac = self.get_ticket_pac(ticket, expect_pac=False) >+ self.assertIsNone(pac) >+ >+ def test_client_no_auth_data_required(self): >+ client_creds = self.get_cached_creds( >+ machine_account=False, >+ opts={'no_auth_data_required': True}) >+ service_creds = self.get_service_creds() >+ >+ tgt = self.get_tgt(client_creds) >+ >+ pac = self.get_ticket_pac(tgt) >+ self.assertIsNotNone(pac) >+ >+ ticket = self._make_tgs_request(client_creds, service_creds, tgt) >+ >+ pac = self.get_ticket_pac(ticket) >+ self.assertIsNotNone(pac) >+ >+ def test_service_no_auth_data_required(self): >+ client_creds = self.get_client_creds() >+ service_creds = self.get_cached_creds( >+ machine_account=True, >+ opts={'no_auth_data_required': True}) >+ >+ tgt = self.get_tgt(client_creds) >+ >+ pac = self.get_ticket_pac(tgt) >+ self.assertIsNotNone(pac) >+ >+ ticket = self._make_tgs_request(client_creds, service_creds, tgt, >+ expect_pac=False) >+ >+ pac = self.get_ticket_pac(ticket, expect_pac=False) >+ self.assertIsNone(pac) >+ >+ def test_remove_pac(self): >+ client_creds = self.get_client_creds() >+ service_creds = self.get_service_creds() >+ >+ tgt = self.modified_ticket(self.get_tgt(client_creds), >+ exclude_pac=True) >+ >+ pac = self.get_ticket_pac(tgt, expect_pac=False) >+ self.assertIsNone(pac) >+ >+ ticket = self._make_tgs_request(client_creds, service_creds, tgt, >+ expect_pac=False) >+ >+ pac = self.get_ticket_pac(ticket, expect_pac=False) >+ self.assertIsNone(pac) >+ > > if __name__ == "__main__": > global_asn1_print = False >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 683dbacb979..32cfa2afa88 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -141,3 +141,8 @@ > # KRB5KRB_ERR_RESPONSE_TOO_BIG in this specific case > # > ^samba4.krb5.kdc with machine account.as-req-pac-request.fl2000dc:local >+# >+# TGS tests >+# >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_client_no_auth_data_required >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_service_no_auth_data_required >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >index 09efbc7b590..00f652db14a 100644 >--- a/selftest/knownfail_mit_kdc >+++ b/selftest/knownfail_mit_kdc >@@ -276,6 +276,10 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_ldap_service_ticket\(ad_dc\) > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_get_ticket_for_host_service_of_machine_account\(ad_dc\) > # >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_client_no_auth_data_required\(ad_dc\) >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_request_no_pac\(ad_dc\) >+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_service_no_auth_data_required\(ad_dc\) >+# > # MIT currently fails the following MS-KILE tests. > # > ^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_enterprise_principal_step_1_3 >-- >2.25.1 > > >From 5d6c76872f9c88a1b2d5a155a2bb1f887c3280fd Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Mon, 18 Oct 2021 15:21:50 +1300 >Subject: [PATCH 138/159] kdc: Remove UF_NO_AUTH_DATA_REQUIRED from client > principals > >Tests against Windows 2019 show that UF_NO_AUTH_DATA_REQUIRED >applies to services only, not to clients. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14871 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >[abartlet@samba.org backported from commit 92e8ce18a79e88c9b961dc20e39436c4cf653013 > as there was a knownfail conflict with the test_remove_pac case > which succeeds on this branch] >--- > selftest/knownfail_heimdal_kdc | 1 - > selftest/knownfail_mit_kdc | 1 - > source4/kdc/mit_samba.c | 7 ------- > source4/kdc/pac-glue.c | 5 ----- > 4 files changed, 14 deletions(-) > >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 32cfa2afa88..4d058bad3da 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -144,5 +144,4 @@ > # > # TGS tests > # >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_client_no_auth_data_required > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_service_no_auth_data_required >diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc >index 00f652db14a..0f845fb9b1c 100644 >--- a/selftest/knownfail_mit_kdc >+++ b/selftest/knownfail_mit_kdc >@@ -276,7 +276,6 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_ldap_service_ticket\(ad_dc\) > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_get_ticket_for_host_service_of_machine_account\(ad_dc\) > # >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_client_no_auth_data_required\(ad_dc\) > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_request_no_pac\(ad_dc\) > ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_service_no_auth_data_required\(ad_dc\) > # >diff --git a/source4/kdc/mit_samba.c b/source4/kdc/mit_samba.c >index 2936fe2d18a..689e14e1c38 100644 >--- a/source4/kdc/mit_samba.c >+++ b/source4/kdc/mit_samba.c >@@ -495,18 +495,11 @@ krb5_error_code mit_samba_reget_pac(struct mit_samba_context *ctx, > ssize_t srv_checksum_idx = -1; > ssize_t kdc_checksum_idx = -1; > krb5_pac new_pac = NULL; >- bool ok; > > if (client != NULL) { > client_skdc_entry = > talloc_get_type_abort(client->e_data, > struct samba_kdc_entry); >- >- /* The user account may be set not to want the PAC */ >- ok = samba_princ_needs_pac(client_skdc_entry); >- if (!ok) { >- return EINVAL; >- } > } > > if (server == NULL) { >diff --git a/source4/kdc/pac-glue.c b/source4/kdc/pac-glue.c >index 88bcb734fc5..688103d8477 100644 >--- a/source4/kdc/pac-glue.c >+++ b/source4/kdc/pac-glue.c >@@ -651,11 +651,6 @@ NTSTATUS samba_kdc_get_pac_blobs(TALLOC_CTX *mem_ctx, > } > *_upn_info_blob = NULL; > >- /* The user account may be set not to want the PAC */ >- if ( ! samba_princ_needs_pac(p)) { >- return NT_STATUS_OK; >- } >- > logon_blob = talloc_zero(mem_ctx, DATA_BLOB); > if (logon_blob == NULL) { > return NT_STATUS_NO_MEMORY; >-- >2.25.1 > > >From e267790f12f68b06f43dbed936b05ff19c255747 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Mon, 18 Oct 2021 16:00:45 +1300 >Subject: [PATCH 139/159] kdc: Correctly strip PAC, rather than error on > UF_NO_AUTH_DATA_REQUIRED for servers > >UF_NO_AUTH_DATA_REQUIRED on a server/service account should cause >the PAC to be stripped not to given an error if the PAC was still >present. > >Tested against Windows 2019 > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14871 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit 031a8287642e3c4b9d0b7c6b51f3b1d79b227542) >--- > selftest/knownfail_heimdal_kdc | 4 ---- > source4/kdc/wdc-samba4.c | 38 +++++++++++++++++++++++----------- > 2 files changed, 26 insertions(+), 16 deletions(-) > >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 4d058bad3da..683dbacb979 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -141,7 +141,3 @@ > # KRB5KRB_ERR_RESPONSE_TOO_BIG in this specific case > # > ^samba4.krb5.kdc with machine account.as-req-pac-request.fl2000dc:local >-# >-# TGS tests >-# >-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_service_no_auth_data_required >diff --git a/source4/kdc/wdc-samba4.c b/source4/kdc/wdc-samba4.c >index 589df8a651d..ac9d7d51733 100644 >--- a/source4/kdc/wdc-samba4.c >+++ b/source4/kdc/wdc-samba4.c >@@ -105,13 +105,15 @@ static krb5_error_code samba_wdc_reget_pac2(krb5_context context, > krb5_pac *pac, > krb5_cksumtype ctype) > { >- struct samba_kdc_entry *p = >+ struct samba_kdc_entry *server_skdc_entry = > talloc_get_type_abort(server->ctx, > struct samba_kdc_entry); > struct samba_kdc_entry *krbtgt_skdc_entry = > talloc_get_type_abort(krbtgt->ctx, > struct samba_kdc_entry); >- TALLOC_CTX *mem_ctx = talloc_named(p, 0, "samba_kdc_reget_pac2 context"); >+ TALLOC_CTX *mem_ctx = talloc_named(server_skdc_entry, >+ 0, >+ "samba_kdc_reget_pac2 context"); > krb5_pac new_pac = NULL; > DATA_BLOB *pac_blob = NULL; > DATA_BLOB *upn_blob = NULL; >@@ -135,12 +137,6 @@ static krb5_error_code samba_wdc_reget_pac2(krb5_context context, > return ENOMEM; > } > >- /* The user account may be set not to want the PAC */ >- if (!samba_princ_needs_pac(p)) { >- talloc_free(mem_ctx); >- return EINVAL; >- } >- > /* If the krbtgt was generated by an RODC, and we are not that > * RODC, then we need to regenerate the PAC - we can't trust > * it */ >@@ -373,12 +369,28 @@ static krb5_error_code samba_wdc_reget_pac2(krb5_context context, > return EINVAL; > } > >- /* Build an updated PAC */ >+ /* >+ * The server account may be set not to want the PAC. >+ * >+ * While this is wasteful if the above cacluations were done >+ * and now thrown away, this is cleaner as we do any ticket >+ * signature checking etc always. >+ * >+ * UF_NO_AUTH_DATA_REQUIRED is the rare case and most of the >+ * time (eg not accepting a ticket from the RODC) we do not >+ * need to re-generate anything anyway. >+ */ >+ if (!samba_princ_needs_pac(server_skdc_entry)) { >+ ret = 0; >+ new_pac = NULL; >+ goto out; >+ } >+ >+ /* Otherwise build an updated PAC */ > ret = krb5_pac_init(context, &new_pac); > if (ret != 0) { >- SAFE_FREE(types); >- talloc_free(mem_ctx); >- return ret; >+ new_pac = NULL; >+ goto out; > } > > for (i = 0;;) { >@@ -496,6 +508,8 @@ static krb5_error_code samba_wdc_reget_pac2(krb5_context context, > } > } > >+out: >+ > SAFE_FREE(types); > > /* We now replace the pac */ >-- >2.25.1 > > >From 1bc8229f351134ce0de2d595e51ebad35b5f25c3 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 18 Oct 2021 16:05:19 +1300 >Subject: [PATCH 140/159] tests/krb5: Ensure PAC is not present if expect_pac > is false > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14871 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit cc3d27596b9e8a8a46e8ba9c3c1a445477d458cf) >--- > python/samba/tests/krb5/raw_testcase.py | 14 +++++++------- > 1 file changed, 7 insertions(+), 7 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 0790ac13f99..0b9fe8e7a04 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -2385,13 +2385,6 @@ class RawKerberosTest(TestCaseInTempDir): > self.assertElementPresent(ticket_private, 'authorization-data', > expect_empty=not expect_pac) > >- if expect_pac: >- authorization_data = self.getElementValue(ticket_private, >- 'authorization-data') >- pac_data = self.get_pac(authorization_data) >- >- self.check_pac_buffers(pac_data, kdc_exchange_dict) >- > encpart_session_key = None > if encpart_private is not None: > self.assertElementPresent(encpart_private, 'key') >@@ -2493,6 +2486,13 @@ class RawKerberosTest(TestCaseInTempDir): > ticket_private=ticket_private, > encpart_private=encpart_private) > >+ if ticket_private is not None: >+ pac_data = self.get_ticket_pac(ticket_creds, expect_pac=expect_pac) >+ if expect_pac: >+ self.check_pac_buffers(pac_data, kdc_exchange_dict) >+ else: >+ self.assertIsNone(pac_data) >+ > expect_ticket_checksum = kdc_exchange_dict['expect_ticket_checksum'] > if expect_ticket_checksum: > self.assertIsNotNone(ticket_decryption_key) >-- >2.25.1 > > >From 74399f732e8fbe0a954cfc73c9faffd4059919b6 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 18 Oct 2021 16:07:11 +1300 >Subject: [PATCH 141/159] tests/krb5: Add tests for constrained delegation to > NO_AUTH_DATA_REQUIRED service > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14871 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Stefan Metzmacher <metze@samba.org> > >Autobuild-User(master): Stefan Metzmacher <metze@samba.org> >Autobuild-Date(master): Wed Oct 20 09:22:43 UTC 2021 on sn-devel-184 > >(cherry picked from commit 83a654a4efd39a6e792a6d49e0ecf586e9bc53ef) >--- > python/samba/tests/krb5/s4u_tests.py | 107 ++++++++++++++++++++++++++- > selftest/knownfail_heimdal_kdc | 8 +- > 2 files changed, 113 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/s4u_tests.py b/python/samba/tests/krb5/s4u_tests.py >index 9a25256081a..bbb7135b55b 100755 >--- a/python/samba/tests/krb5/s4u_tests.py >+++ b/python/samba/tests/krb5/s4u_tests.py >@@ -538,6 +538,8 @@ class S4UKerberosTests(KDCBaseTest): > transited_service = f'host/{service1_name}@{service1_realm}' > expected_transited_services.append(transited_service) > >+ expect_pac = kdc_dict.pop('expect_pac', True) >+ > kdc_exchange_dict = self.tgs_exchange_dict( > expected_crealm=client_realm, > expected_cname=client_cname, >@@ -557,7 +559,8 @@ class S4UKerberosTests(KDCBaseTest): > pac_options=pac_options, > expect_edata=expect_edata, > expected_proxy_target=expected_proxy_target, >- expected_transited_services=expected_transited_services) >+ expected_transited_services=expected_transited_services, >+ expect_pac=expect_pac) > > self._generic_kdc_exchange(kdc_exchange_dict, > cname=None, >@@ -577,6 +580,18 @@ class S4UKerberosTests(KDCBaseTest): > 'allow_delegation': True > }) > >+ def test_constrained_delegation_no_auth_data_required(self): >+ # Test constrained delegation. >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': 0, >+ 'allow_delegation': True, >+ 'service2_opts': { >+ 'no_auth_data_required': True >+ }, >+ 'expect_pac': False >+ }) >+ > def test_constrained_delegation_existing_delegation_info(self): > # Test constrained delegation with an existing S4U_DELEGATION_INFO > # structure in the PAC. >@@ -624,6 +639,35 @@ class S4UKerberosTests(KDCBaseTest): > 'modify_service_tgt_fn': self.remove_ticket_pac > }) > >+ def test_constrained_delegation_no_client_pac_no_auth_data_required(self): >+ # Test constrained delegation when the client service ticket does not >+ # contain a PAC. >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': (KDC_ERR_BADOPTION, >+ KDC_ERR_MODIFIED), >+ 'allow_delegation': True, >+ 'modify_client_tkt_fn': self.remove_ticket_pac, >+ 'expect_edata': False, >+ 'service2_opts': { >+ 'no_auth_data_required': True >+ } >+ }) >+ >+ def test_constrained_delegation_no_service_pac_no_auth_data_required(self): >+ # Test constrained delegation when the service TGT does not contain a >+ # PAC. >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': (KDC_ERR_BADOPTION, >+ KDC_ERR_MODIFIED), >+ 'allow_delegation': True, >+ 'modify_service_tgt_fn': self.remove_ticket_pac, >+ 'service2_opts': { >+ 'no_auth_data_required': True >+ } >+ }) >+ > def test_constrained_delegation_non_forwardable(self): > # Test constrained delegation with a non-forwardable ticket. > self._run_delegation_test( >@@ -645,6 +689,18 @@ class S4UKerberosTests(KDCBaseTest): > 'allow_delegation': True > }) > >+ def test_rbcd_no_auth_data_required(self): >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': 0, >+ 'allow_rbcd': True, >+ 'pac_options': '0001', # supports RBCD >+ 'service2_opts': { >+ 'no_auth_data_required': True >+ }, >+ 'expect_pac': False >+ }) >+ > def test_rbcd_existing_delegation_info(self): > # Test constrained delegation with an existing S4U_DELEGATION_INFO > # structure in the PAC. >@@ -712,6 +768,55 @@ class S4UKerberosTests(KDCBaseTest): > 'modify_service_tgt_fn': self.remove_ticket_pac > }) > >+ def test_rbcd_no_client_pac_no_auth_data_required_a(self): >+ # Test constrained delegation when the client service ticket does not >+ # contain a PAC, and an empty msDS-AllowedToDelegateTo attribute. >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': KDC_ERR_MODIFIED, >+ 'expected_status': ntstatus.NT_STATUS_NOT_SUPPORTED, >+ 'allow_rbcd': True, >+ 'pac_options': '0001', # supports RBCD >+ 'modify_client_tkt_fn': self.remove_ticket_pac, >+ 'service2_opts': { >+ 'no_auth_data_required': True >+ } >+ }) >+ >+ def test_rbcd_no_client_pac_no_auth_data_required_b(self): >+ # Test constrained delegation when the client service ticket does not >+ # contain a PAC, and a non-empty msDS-AllowedToDelegateTo attribute. >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': KDC_ERR_MODIFIED, >+ 'expected_status': ntstatus.NT_STATUS_NO_MATCH, >+ 'allow_rbcd': True, >+ 'pac_options': '0001', # supports RBCD >+ 'modify_client_tkt_fn': self.remove_ticket_pac, >+ 'service1_opts': { >+ 'delegation_to_spn': ('host/test') >+ }, >+ 'service2_opts': { >+ 'no_auth_data_required': True >+ } >+ }) >+ >+ def test_rbcd_no_service_pac_no_auth_data_required(self): >+ # Test constrained delegation when the service TGT does not contain a >+ # PAC. >+ self._run_delegation_test( >+ { >+ 'expected_error_mode': KDC_ERR_BADOPTION, >+ 'expected_status': >+ ntstatus.NT_STATUS_NOT_FOUND, >+ 'allow_rbcd': True, >+ 'pac_options': '0001', # supports RBCD >+ 'modify_service_tgt_fn': self.remove_ticket_pac, >+ 'service2_opts': { >+ 'no_auth_data_required': True >+ } >+ }) >+ > def test_rbcd_non_forwardable(self): > # Test resource-based constrained delegation with a non-forwardable > # ticket. >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index 683dbacb979..b1d7a1ebe8f 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -125,7 +125,7 @@ > # S4U tests > # > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_bronze_bit_rbcd_old_checksum >-^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_no_service_pac >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_no_service_pac\(.*\)$ > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_existing_delegation_info > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_missing_client_checksum > ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_no_client_pac_a >@@ -141,3 +141,9 @@ > # KRB5KRB_ERR_RESPONSE_TOO_BIG in this specific case > # > ^samba4.krb5.kdc with machine account.as-req-pac-request.fl2000dc:local >+# >+# >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_no_auth_data_required >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_no_auth_data_required >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_no_client_pac_no_auth_data_required_a >+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_no_client_pac_no_auth_data_required_b >-- >2.25.1 > > >From 129cda090d18e445c0439c04640fcb55b6c7f83b Mon Sep 17 00:00:00 2001 >From: Viktor Dukhovni <viktor@twosigma.com> >Date: Wed, 10 Aug 2016 23:31:14 +0000 >Subject: [PATCH 142/159] HEIMDAL:kdc: Fix transit path validation > CVE-2017-6594 > >Commit f469fc6 (2010-10-02) inadvertently caused the previous hop realm >to not be added to the transit path of issued tickets. This may, in >some cases, enable bypass of capath policy in Heimdal versions 1.5 >through 7.2. > >Note, this may break sites that rely on the bug. With the bug some >incomplete [capaths] worked, that should not have. These may now break >authentication in some cross-realm configurations. > >(similar to heimdal commit b1e699103f08d6a0ca46a122193c9da65f6cf837) > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=12998 > >Reviewed-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >Autobuild-User(master): Stefan Metzmacher <metze@samba.org> >Autobuild-Date(master): Wed Oct 20 10:58:37 UTC 2021 on sn-devel-184 > >(cherry picked from commit 7e961f3f7a815960ae25377d5b7515184d439690) >--- > source4/heimdal/kdc/krb5tgs.c | 13 ++++++++++--- > 1 file changed, 10 insertions(+), 3 deletions(-) > >diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c >index 2de3b099199..7e9379db64a 100644 >--- a/source4/heimdal/kdc/krb5tgs.c >+++ b/source4/heimdal/kdc/krb5tgs.c >@@ -409,8 +409,12 @@ fix_transited_encoding(krb5_context context, > "Decoding transited encoding"); > return ret; > } >+ >+ /* >+ * If the realm of the presented tgt is neither the client nor the server >+ * realm, it is a transit realm and must be added to transited set. >+ */ > if(strcmp(client_realm, tgt_realm) && strcmp(server_realm, tgt_realm)) { >- /* not us, so add the previous realm to transited set */ > if (num_realms + 1 > UINT_MAX/sizeof(*realms)) { > ret = ERANGE; > goto free_realms; >@@ -492,6 +496,7 @@ tgs_make_reply(krb5_context context, > const char *server_name, > hdb_entry_ex *client, > krb5_principal client_principal, >+ const char *tgt_realm, > hdb_entry_ex *krbtgt, > krb5_pac mspac, > uint16_t rodc_id, >@@ -553,7 +558,7 @@ tgs_make_reply(krb5_context context, > &tgt->transited, &et, > krb5_principal_get_realm(context, client_principal), > krb5_principal_get_realm(context, server->entry.principal), >- krb5_principal_get_realm(context, krbtgt->entry.principal)); >+ tgt_realm); > if(ret) > goto out; > >@@ -1292,13 +1297,14 @@ tgs_build_reply(krb5_context context, > HDB *clientdb, *s4u2self_impersonated_clientdb; > krb5_realm ref_realm = NULL; > EncTicketPart *tgt = &ticket->ticket; >+ const char *tgt_realm = /* Realm of TGT issuer */ >+ krb5_principal_get_realm(context, krbtgt->entry.principal); > const EncryptionKey *ekey; > krb5_keyblock sessionkey; > krb5_kvno kvno; > krb5_pac mspac = NULL; > uint16_t rodc_id; > krb5_boolean add_ticket_sig = FALSE; >- > hdb_entry_ex *krbtgt_out = NULL; > > METHOD_DATA enc_pa_data; >@@ -2036,6 +2042,7 @@ server_lookup: > spn, > client, > cp, >+ tgt_realm, > krbtgt_out, > mspac, > rodc_id, >-- >2.25.1 > > >From e56c69399a75cf7c600f156d6ba446f42aa953ea Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Wed, 8 Sep 2021 17:01:26 +1200 >Subject: [PATCH 143/159] pytest/rodc_rwdc: try to avoid race. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14868 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit a169e013e66bab15e594ce49b805edebfcd503cf) >--- > source4/dsdb/tests/python/rodc_rwdc.py | 4 ++++ > 1 file changed, 4 insertions(+) > >diff --git a/source4/dsdb/tests/python/rodc_rwdc.py b/source4/dsdb/tests/python/rodc_rwdc.py >index a09d16a0163..b9ea18e5b68 100644 >--- a/source4/dsdb/tests/python/rodc_rwdc.py >+++ b/source4/dsdb/tests/python/rodc_rwdc.py >@@ -251,6 +251,10 @@ class RodcRwdcCachedTests(password_lockout_base.BasePasswordTestCase): > res = ldb_system.search(userdn, attrs=['unicodePwd']) > self.assertTrue('unicodePwd' in res[0]) > >+ # force replication here to flush any pending preloads (this >+ # was a racy test). >+ self.force_replication() >+ > newpass = userpass + '!' > > # Forcing replication should blank out password (when changed) >-- >2.25.1 > > >From d4932bb024a1e8ffa18887c1b3ea5ecab49f16cd Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 20 Sep 2021 16:27:40 +1200 >Subject: [PATCH 144/159] selftest: Increase account lockout windows to make > test more realiable > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14868 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit 6292f0597f208d7953382341380921cf0fd0a8a8) >--- > source4/dsdb/tests/python/rodc_rwdc.py | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > >diff --git a/source4/dsdb/tests/python/rodc_rwdc.py b/source4/dsdb/tests/python/rodc_rwdc.py >index b9ea18e5b68..0340042e19d 100644 >--- a/source4/dsdb/tests/python/rodc_rwdc.py >+++ b/source4/dsdb/tests/python/rodc_rwdc.py >@@ -289,14 +289,14 @@ class RodcRwdcCachedTests(password_lockout_base.BasePasswordTestCase): > m = ldb.Message() > m.dn = ldb.Dn(self.ldb, self.base_dn) > >- self.account_lockout_duration = 10 >+ self.account_lockout_duration = 15 > account_lockout_duration_ticks = -int(self.account_lockout_duration * (1e7)) > > m["lockoutDuration"] = ldb.MessageElement(str(account_lockout_duration_ticks), > ldb.FLAG_MOD_REPLACE, > "lockoutDuration") > >- self.lockout_observation_window = 10 >+ self.lockout_observation_window = 15 > lockout_observation_window_ticks = -int(self.lockout_observation_window * (1e7)) > > m["lockOutObservationWindow"] = ldb.MessageElement(str(lockout_observation_window_ticks), >-- >2.25.1 > > >From cff629e6d0c73b7bd382f634964bfc2384f9b569 Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Fri, 6 Aug 2021 11:08:10 +1200 >Subject: [PATCH 145/159] pytest: dynamic tests optionally add __doc__ > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14869 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit aacb18f920349e13b562c7c97901a0be7b273137) >--- > python/samba/tests/__init__.py | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > >diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py >index a5a8acdcc41..c75f9c1ebe7 100644 >--- a/python/samba/tests/__init__.py >+++ b/python/samba/tests/__init__.py >@@ -69,7 +69,7 @@ class TestCase(unittest.TestCase): > """A Samba test case.""" > > @classmethod >- def generate_dynamic_test(cls, fnname, suffix, *args): >+ def generate_dynamic_test(cls, fnname, suffix, *args, doc=None): > """ > fnname is something like "test_dynamic_sum" > suffix is something like "1plus2" >@@ -82,6 +82,7 @@ class TestCase(unittest.TestCase): > """ > def fn(self): > getattr(self, "_%s_with_args" % fnname)(*args) >+ fn.__doc__ = doc > setattr(cls, "%s_%s" % (fnname, suffix), fn) > > @classmethod >-- >2.25.1 > > >From 857cc25e85dc2a0fa3d5b64fe667d0cc3170e4e8 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Fri, 8 Oct 2021 15:40:09 +1300 >Subject: [PATCH 146/159] selftest: krb5 account creation: clarify account type > as an enum > >This makes the code clearer with a symbolic constant rather >than a True/False boolean. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14869 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit 49306f74eb29a2192019fab9260f9d242f9d5fd9) >--- > .../tests/krb5/as_canonicalization_tests.py | 7 ++- > python/samba/tests/krb5/kdc_base_test.py | 63 ++++++++++++------- > python/samba/tests/krb5/kdc_tgs_tests.py | 7 ++- > .../ms_kile_client_principal_lookup_tests.py | 36 +++++++---- > python/samba/tests/krb5/rodc_tests.py | 4 +- > python/samba/tests/krb5/s4u_tests.py | 35 ++++++----- > python/samba/tests/krb5/test_ccache.py | 11 ++-- > 7 files changed, 100 insertions(+), 63 deletions(-) > >diff --git a/python/samba/tests/krb5/as_canonicalization_tests.py b/python/samba/tests/krb5/as_canonicalization_tests.py >index 9538d0ae3cf..674fcb37101 100755 >--- a/python/samba/tests/krb5/as_canonicalization_tests.py >+++ b/python/samba/tests/krb5/as_canonicalization_tests.py >@@ -171,9 +171,10 @@ class KerberosASCanonicalizationTests(KDCBaseTest): > def machine_account_creds(self): > if self.machine_creds is None: > samdb = self.get_samdb() >- self.machine_creds, _ = self.create_account(samdb, >- MACHINE_NAME, >- machine_account=True) >+ self.machine_creds, _ = self.create_account( >+ samdb, >+ MACHINE_NAME, >+ account_type=self.AccountType.COMPUTER) > self.machine_creds.set_secure_channel_type(SEC_CHAN_WKSTA) > self.machine_creds.set_kerberos_state(DONT_USE_KERBEROS) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 1fc15315b0b..7cd3c5255f2 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -23,6 +23,7 @@ import tempfile > import binascii > import collections > import secrets >+from enum import Enum, auto > > from collections import namedtuple > import ldb >@@ -90,6 +91,10 @@ class KDCBaseTest(RawKerberosTest): > """ Base class for KDC tests. > """ > >+ class AccountType(Enum): >+ USER = auto() >+ COMPUTER = auto() >+ > @classmethod > def setUpClass(cls): > super().setUpClass() >@@ -230,7 +235,7 @@ class KDCBaseTest(RawKerberosTest): > > return default_enctypes > >- def create_account(self, samdb, name, machine_account=False, >+ def create_account(self, samdb, name, account_type=AccountType.USER, > spn=None, upn=None, additional_details=None, > ou=None, account_control=0): > '''Create an account for testing. >@@ -238,8 +243,10 @@ class KDCBaseTest(RawKerberosTest): > which is used by tearDownClass to clean up the created accounts. > ''' > if ou is None: >- guid = (DS_GUID_COMPUTERS_CONTAINER if machine_account >- else DS_GUID_USERS_CONTAINER) >+ if account_type is account_type.COMPUTER: >+ guid = DS_GUID_COMPUTERS_CONTAINER >+ else: >+ guid = DS_GUID_USERS_CONTAINER > > ou = samdb.get_wellknown_dn(samdb.get_default_basedn(), guid) > >@@ -248,14 +255,17 @@ class KDCBaseTest(RawKerberosTest): > # remove the account if it exists, this will happen if a previous test > # run failed > delete_force(samdb, dn) >- if machine_account: >- object_class = "computer" >- account_name = "%s$" % name >- account_control |= UF_WORKSTATION_TRUST_ACCOUNT >- else: >+ if account_type is self.AccountType.USER: > object_class = "user" > account_name = name > account_control |= UF_NORMAL_ACCOUNT >+ else: >+ object_class = "computer" >+ account_name = "%s$" % name >+ if account_type is self.AccountType.COMPUTER: >+ account_control |= UF_WORKSTATION_TRUST_ACCOUNT >+ else: >+ self.fail() > > password = generate_random_password(32, 32) > utf16pw = ('"%s"' % password).encode('utf-16-le') >@@ -267,6 +277,10 @@ class KDCBaseTest(RawKerberosTest): > "userAccountControl": str(account_control), > "unicodePwd": utf16pw} > if spn is not None: >+ if isinstance(spn, str): >+ spn = spn.format(account=account_name) >+ else: >+ spn = tuple(s.format(account=account_name) for s in spn) > details["servicePrincipalName"] = spn > if upn is not None: > details["userPrincipalName"] = upn >@@ -280,10 +294,10 @@ class KDCBaseTest(RawKerberosTest): > creds.set_domain(samdb.domain_netbios_name().upper()) > creds.set_password(password) > creds.set_username(account_name) >- if machine_account: >- creds.set_workstation(name) >- else: >+ if account_type is self.AccountType.USER: > creds.set_workstation('') >+ else: >+ creds.set_workstation(name) > creds.set_dn(ldb.Dn(samdb, dn)) > creds.set_spn(spn) > # >@@ -609,13 +623,14 @@ class KDCBaseTest(RawKerberosTest): > return cleanup > > def get_cached_creds(self, *, >- machine_account, >+ account_type, > opts=None, > use_cache=True): > if opts is None: > opts = {} > > opts_default = { >+ 'spn': None, > 'allowed_replication': False, > 'allowed_replication_mock': False, > 'denied_replication': False, >@@ -632,7 +647,7 @@ class KDCBaseTest(RawKerberosTest): > } > > account_opts = { >- 'machine_account': machine_account, >+ 'account_type': account_type, > **opts_default, > **opts > } >@@ -651,7 +666,8 @@ class KDCBaseTest(RawKerberosTest): > return creds > > def create_account_opts(self, *, >- machine_account, >+ account_type, >+ spn, > allowed_replication, > allowed_replication_mock, > denied_replication, >@@ -665,12 +681,13 @@ class KDCBaseTest(RawKerberosTest): > delegation_from_dn, > trusted_to_auth_for_delegation, > fast_support): >- if machine_account: >- self.assertFalse(not_delegated) >- else: >+ if account_type is self.AccountType.USER: >+ self.assertIsNone(spn) > self.assertIsNone(delegation_to_spn) > self.assertIsNone(delegation_from_dn) > self.assertFalse(trusted_to_auth_for_delegation) >+ else: >+ self.assertFalse(not_delegated) > > samdb = self.get_samdb() > rodc_samdb = self.get_rodc_samdb() >@@ -707,13 +724,11 @@ class KDCBaseTest(RawKerberosTest): > details['msDS-AllowedToActOnBehalfOfOtherIdentity'] = ( > security_descriptor) > >- if machine_account: >+ if spn is None and account_type is not self.AccountType.USER: > spn = 'host/' + user_name >- else: >- spn = None > > creds, dn = self.create_account(samdb, user_name, >- machine_account=machine_account, >+ account_type=account_type, > spn=spn, > additional_details=details, > account_control=user_account_control) >@@ -787,7 +802,7 @@ class KDCBaseTest(RawKerberosTest): > allow_missing_password=False, > allow_missing_keys=True): > def create_client_account(): >- return self.get_cached_creds(machine_account=False) >+ return self.get_cached_creds(account_type=self.AccountType.USER) > > c = self._get_krb5_creds(prefix='CLIENT', > allow_missing_password=allow_missing_password, >@@ -799,7 +814,7 @@ class KDCBaseTest(RawKerberosTest): > allow_missing_password=False, > allow_missing_keys=True): > def create_mach_account(): >- return self.get_cached_creds(machine_account=True, >+ return self.get_cached_creds(account_type=self.AccountType.COMPUTER, > opts={'fast_support': True}) > > c = self._get_krb5_creds(prefix='MAC', >@@ -813,7 +828,7 @@ class KDCBaseTest(RawKerberosTest): > allow_missing_keys=True): > def create_service_account(): > return self.get_cached_creds( >- machine_account=True, >+ account_type=self.AccountType.COMPUTER, > opts={ > 'trusted_to_auth_for_delegation': True, > 'fast_support': True >diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py >index 9d846a2c3ad..f36704f998c 100755 >--- a/python/samba/tests/krb5/kdc_tgs_tests.py >+++ b/python/samba/tests/krb5/kdc_tgs_tests.py >@@ -148,7 +148,8 @@ class KdcTgsTests(KDCBaseTest): > samdb = self.get_samdb() > user_name = "tsttktusr" > (uc, dn) = self.create_account(samdb, user_name) >- (mc, _) = self.create_account(samdb, "tsttktmac", machine_account=True) >+ (mc, _) = self.create_account(samdb, "tsttktmac", >+ account_type=self.AccountType.COMPUTER) > realm = uc.get_realm().lower() > > # Do the initial AS-REQ, should get a pre-authentication required >@@ -282,7 +283,7 @@ class KdcTgsTests(KDCBaseTest): > > def test_client_no_auth_data_required(self): > client_creds = self.get_cached_creds( >- machine_account=False, >+ account_type=self.AccountType.USER, > opts={'no_auth_data_required': True}) > service_creds = self.get_service_creds() > >@@ -299,7 +300,7 @@ class KdcTgsTests(KDCBaseTest): > def test_service_no_auth_data_required(self): > client_creds = self.get_client_creds() > service_creds = self.get_cached_creds( >- machine_account=True, >+ account_type=self.AccountType.COMPUTER, > opts={'no_auth_data_required': True}) > > tgt = self.get_tgt(client_creds) >diff --git a/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py b/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >index 2ee3d4a2a83..0aa3309b814 100755 >--- a/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >+++ b/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py >@@ -95,7 +95,8 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > realm = uc.get_realm().lower() > > mach_name = "mskilemac" >- (mc, _) = self.create_account(samdb, mach_name, machine_account=True) >+ (mc, _) = self.create_account(samdb, mach_name, >+ account_type=self.AccountType.COMPUTER) > > # Do the initial AS-REQ, should get a pre-authentication required > # response >@@ -151,7 +152,8 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > # > samdb = self.get_samdb() > mach_name = "mskilemac" >- (mc, dn) = self.create_account(samdb, mach_name, machine_account=True) >+ (mc, dn) = self.create_account(samdb, mach_name, >+ account_type=self.AccountType.COMPUTER) > realm = mc.get_realm().lower() > > # Do the initial AS-REQ, should get a pre-authentication required >@@ -215,7 +217,8 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > realm = uc.get_realm().lower() > > mach_name = "mskilemac" >- (mc, _) = self.create_account(samdb, mach_name, machine_account=True) >+ (mc, _) = self.create_account(samdb, mach_name, >+ account_type=self.AccountType.COMPUTER) > > # Do the initial AS-REQ, should get a pre-authentication required > # response >@@ -286,7 +289,8 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > self.add_attribute(samdb, dn, "altSecurityIdentities", alt_sec) > > mach_name = "mskilemac" >- (mc, _) = self.create_account(samdb, mach_name, machine_account=True) >+ (mc, _) = self.create_account(samdb, mach_name, >+ account_type=self.AccountType.COMPUTER) > > # Do the initial AS-REQ, as we've set UF_DONT_REQUIRE_PREAUTH > # we should get a valid AS-RESP >@@ -351,7 +355,8 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > self.add_attribute(samdb, dn, "altSecurityIdentities", alt_sec) > > mach_name = "mskilemac" >- (mc, _) = self.create_account(samdb, mach_name, machine_account=True) >+ (mc, _) = self.create_account(samdb, mach_name, >+ account_type=self.AccountType.COMPUTER) > > # Do the initial AS-REQ, should get a pre-authentication required > # response >@@ -420,7 +425,8 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > self.add_attribute(samdb, dn, "altSecurityIdentities", alt_sec) > > mach_name = "mskilemac" >- (mc, _) = self.create_account(samdb, mach_name, machine_account=True) >+ (mc, _) = self.create_account(samdb, mach_name, >+ account_type=self.AccountType.COMPUTER) > > # Do the initial AS-REQ, should get a pre-authentication required > # response >@@ -459,7 +465,8 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > realm = uc.get_realm().lower() > > mach_name = "mskilemac" >- (mc, _) = self.create_account(samdb, mach_name, machine_account=True) >+ (mc, _) = self.create_account(samdb, mach_name, >+ account_type=self.AccountType.COMPUTER) > > # Do the initial AS-REQ, should get a pre-authentication required > # response >@@ -523,7 +530,8 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > ename = user_name + "@" + realm > > mach_name = "mskilemac" >- (mc, _) = self.create_account(samdb, mach_name, machine_account=True) >+ (mc, _) = self.create_account(samdb, mach_name, >+ account_type=self.AccountType.COMPUTER) > > # Do the initial AS-REQ, should get a pre-authentication required > # response >@@ -586,7 +594,8 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > realm = uc.get_realm().lower() > > mach_name = "mskilemac" >- (mc, dn) = self.create_account(samdb, mach_name, machine_account=True) >+ (mc, dn) = self.create_account(samdb, mach_name, >+ account_type=self.AccountType.COMPUTER) > ename = mach_name + "@" + realm > uname = mach_name + "$@" + realm > >@@ -661,7 +670,8 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > ename = alt_name + "@" + realm > > mach_name = "mskilemac" >- (mc, _) = self.create_account(samdb, mach_name, machine_account=True) >+ (mc, _) = self.create_account(samdb, mach_name, >+ account_type=self.AccountType.COMPUTER) > > # Do the initial AS-REQ, as we've set UF_DONT_REQUIRE_PREAUTH > # we should get a valid AS-RESP >@@ -728,7 +738,8 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > uname = user_name + "@" + realm > > mach_name = "mskilemac" >- (mc, _) = self.create_account(samdb, mach_name, machine_account=True) >+ (mc, _) = self.create_account(samdb, mach_name, >+ account_type=self.AccountType.COMPUTER) > > # Do the initial AS-REQ, should get a pre-authentication required > # response >@@ -798,7 +809,8 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): > ename = alt_name + "@" + realm > > mach_name = "mskilemac" >- (mc, _) = self.create_account(samdb, mach_name, machine_account=True) >+ (mc, _) = self.create_account(samdb, mach_name, >+ account_type=self.AccountType.COMPUTER) > > # Do the initial AS-REQ, should get a pre-authentication required > # response >diff --git a/python/samba/tests/krb5/rodc_tests.py b/python/samba/tests/krb5/rodc_tests.py >index 4579f9eb552..302ae865cf1 100755 >--- a/python/samba/tests/krb5/rodc_tests.py >+++ b/python/samba/tests/krb5/rodc_tests.py >@@ -39,12 +39,12 @@ class RodcKerberosTests(KDCBaseTest): > # and including the RODCIdentifier. > def test_rodc_ticket_signature(self): > user_creds = self.get_cached_creds( >- machine_account=False, >+ account_type=self.AccountType.USER, > opts={ > 'revealed_to_rodc': True > }) > target_creds = self.get_cached_creds( >- machine_account=True, >+ account_type=self.AccountType.COMPUTER, > opts={ > 'revealed_to_rodc': True > }) >diff --git a/python/samba/tests/krb5/s4u_tests.py b/python/samba/tests/krb5/s4u_tests.py >index bbb7135b55b..ea629d29706 100755 >--- a/python/samba/tests/krb5/s4u_tests.py >+++ b/python/samba/tests/krb5/s4u_tests.py >@@ -220,12 +220,14 @@ class S4UKerberosTests(KDCBaseTest): > > def _run_s4u2self_test(self, kdc_dict): > client_opts = kdc_dict.pop('client_opts', None) >- client_creds = self.get_cached_creds(machine_account=False, >- opts=client_opts) >+ client_creds = self.get_cached_creds( >+ account_type=self.AccountType.USER, >+ opts=client_opts) > > service_opts = kdc_dict.pop('service_opts', None) >- service_creds = self.get_cached_creds(machine_account=True, >- opts=service_opts) >+ service_creds = self.get_cached_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts=service_opts) > > service_tgt = self.get_tgt(service_creds) > modify_service_tgt_fn = kdc_dict.pop('modify_service_tgt_fn', None) >@@ -432,8 +434,9 @@ class S4UKerberosTests(KDCBaseTest): > > def _run_delegation_test(self, kdc_dict): > client_opts = kdc_dict.pop('client_opts', None) >- client_creds = self.get_cached_creds(machine_account=False, >- opts=client_opts) >+ client_creds = self.get_cached_creds( >+ account_type=self.AccountType.USER, >+ opts=client_opts) > > service1_opts = kdc_dict.pop('service1_opts', {}) > service2_opts = kdc_dict.pop('service2_opts', {}) >@@ -443,24 +446,28 @@ class S4UKerberosTests(KDCBaseTest): > self.assertFalse(allow_delegation and allow_rbcd) > > if allow_rbcd: >- service1_creds = self.get_cached_creds(machine_account=True, >- opts=service1_opts) >+ service1_creds = self.get_cached_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts=service1_opts) > > self.assertNotIn('delegation_from_dn', service2_opts) > service2_opts['delegation_from_dn'] = str(service1_creds.get_dn()) > >- service2_creds = self.get_cached_creds(machine_account=True, >- opts=service2_opts) >+ service2_creds = self.get_cached_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts=service2_opts) > else: >- service2_creds = self.get_cached_creds(machine_account=True, >- opts=service2_opts) >+ service2_creds = self.get_cached_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts=service2_opts) > > if allow_delegation: > self.assertNotIn('delegation_to_spn', service1_opts) > service1_opts['delegation_to_spn'] = service2_creds.get_spn() > >- service1_creds = self.get_cached_creds(machine_account=True, >- opts=service1_opts) >+ service1_creds = self.get_cached_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts=service1_opts) > > client_tkt_options = kdc_dict.pop('client_tkt_options', 'forwardable') > expected_flags = krb5_asn1.TicketFlags(client_tkt_options) >diff --git a/python/samba/tests/krb5/test_ccache.py b/python/samba/tests/krb5/test_ccache.py >index c44ea02d504..6a2b78398ac 100755 >--- a/python/samba/tests/krb5/test_ccache.py >+++ b/python/samba/tests/krb5/test_ccache.py >@@ -55,11 +55,12 @@ class CcacheTests(KDCBaseTest): > (user_credentials, _) = self.create_account(samdb, user_name) > > # Create the machine account. >- (mach_credentials, _) = self.create_account(samdb, >- mach_name, >- machine_account=True, >- spn="%s/%s" % (service, >- mach_name)) >+ (mach_credentials, _) = self.create_account( >+ samdb, >+ mach_name, >+ account_type=self.AccountType.COMPUTER, >+ spn="%s/%s" % (service, >+ mach_name)) > > # Talk to the KDC to obtain the service ticket, which gets placed into > # the cache. The machine account name has to match the name in the >-- >2.25.1 > > >From 57fc1c28b7f085e474746336726ea2731c614fc3 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Mon, 18 Oct 2021 20:44:54 +1300 >Subject: [PATCH 147/159] selftest: Remove duplicate setup of $base_dn and > $ldbmodify > >These are already set up to the same values above for the full >DC and correct values for the (strange) s4member environment. > >By not setting $base_dn again we avoid an error once we start >checking for them. > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit 2c0658d408f17af2abc223b0cb18d8d33e0ecd1a) >--- > selftest/target/Samba4.pm | 4 ---- > 1 file changed, 4 deletions(-) > >diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm >index f58190706b1..09cedcb05f1 100755 >--- a/selftest/target/Samba4.pm >+++ b/selftest/target/Samba4.pm >@@ -1108,10 +1108,6 @@ servicePrincipalName: http/testupnspn.$ctx->{dnsname} > } > > # Change the userPrincipalName for jane >- $ldbmodify = ${cmd_env}; >- $ldbmodify .= Samba::bindir_path($self, "ldbmodify"); >- $ldbmodify .= " --configfile=$ctx->{smb_conf}"; >- $base_dn = "DC=".join(",DC=", split(/\./, $ctx->{realm})); > $user_dn = "cn=jane,cn=users,$base_dn"; > > open(LDIF, "|$ldbmodify -H $ctx->{privatedir}/sam.ldb"); >-- >2.25.1 > > >From 3f41beb4caf20d8d6a68c042968e07e940c6461e Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Mon, 18 Oct 2021 11:55:14 +1300 >Subject: [PATCH 148/159] selftest: Improve error handling and perl style when > setting up users in Samba4.pm > >This catches errors and avoids using global varibles (the old >style file handles are global). > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14869 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit 459200caba04fd83ed650b9cdfe5b158cf9a149f) >--- > selftest/target/Samba4.pm | 72 ++++++++++++++++++++++++++++----------- > 1 file changed, 53 insertions(+), 19 deletions(-) > >diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm >index 09cedcb05f1..615e8b240b4 100755 >--- a/selftest/target/Samba4.pm >+++ b/selftest/target/Samba4.pm >@@ -239,12 +239,19 @@ sub wait_for_start($$) > > sub write_ldb_file($$$) > { >- my ($self, $file, $ldif) = @_; >+ my ($self, $file, $ldif_in) = @_; > > my $ldbadd = Samba::bindir_path($self, "ldbadd"); >- open(LDIF, "|$ldbadd -H $file >/dev/null"); >- print LDIF $ldif; >- return(close(LDIF)); >+ open(my $ldif, "|$ldbadd -H $file > /dev/null") >+ or die "Failed to run $ldbadd: $!"; >+ print $ldif $ldif_in; >+ close($ldif); >+ >+ unless ($? == 0) { >+ warn("$ldbadd failed: $?"); >+ return undef; >+ } >+ return 1; > } > > sub add_wins_config($$) >@@ -946,6 +953,8 @@ sub provision_raw_step2($$$) > { > my ($self, $ctx, $ret) = @_; > >+ my $ldif; >+ > my $provision_cmd = join(" ", @{$ctx->{provision_options}}); > unless (system($provision_cmd) == 0) { > warn("Unable to provision: \n$provision_cmd\n"); >@@ -991,17 +1000,23 @@ sub provision_raw_step2($$$) > > my $user_dn = "cn=$testallowed_account,cn=users,$base_dn"; > $testallowed_account = "testallowed account"; >- open(LDIF, "|$ldbmodify -H $ctx->{privatedir}/sam.ldb"); >- print LDIF "dn: $user_dn >+ open($ldif, "|$ldbmodify -H $ctx->{privatedir}/sam.ldb") >+ or die "Failed to run $ldbmodify: $!"; >+ print $ldif "dn: $user_dn > changetype: modify > replace: samAccountName > samAccountName: $testallowed_account > - > "; >- close(LDIF); >+ close($ldif); >+ unless ($? == 0) { >+ warn("$ldbmodify failed: $?"); >+ return undef; >+ } > >- open(LDIF, "|$ldbmodify -H $ctx->{privatedir}/sam.ldb"); >- print LDIF "dn: $user_dn >+ open($ldif, "|$ldbmodify -H $ctx->{privatedir}/sam.ldb") >+ or die "Failed to run $ldbmodify: $!"; >+ print $ldif "dn: $user_dn > changetype: modify > replace: userPrincipalName > userPrincipalName: testallowed upn\@$ctx->{realm} >@@ -1009,7 +1024,11 @@ replace: servicePrincipalName > servicePrincipalName: host/testallowed > - > "; >- close(LDIF); >+ close($ldif); >+ unless ($? == 0) { >+ warn("$ldbmodify failed: $?"); >+ return undef; >+ } > > $samba_tool_cmd = ${cmd_env}; > $samba_tool_cmd .= Samba::bindir_path($self, "samba-tool") >@@ -1020,14 +1039,19 @@ servicePrincipalName: host/testallowed > } > > $user_dn = "cn=testdenied,cn=users,$base_dn"; >- open(LDIF, "|$ldbmodify -H $ctx->{privatedir}/sam.ldb"); >- print LDIF "dn: $user_dn >+ open($ldif, "|$ldbmodify -H $ctx->{privatedir}/sam.ldb") >+ or die "Failed to run $ldbmodify: $!"; >+ print $ldif "dn: $user_dn > changetype: modify > replace: userPrincipalName > userPrincipalName: testdenied_upn\@$ctx->{realm}.upn > - > "; >- close(LDIF); >+ close($ldif); >+ unless ($? == 0) { >+ warn("$ldbmodify failed: $?"); >+ return undef; >+ } > > $samba_tool_cmd = ${cmd_env}; > $samba_tool_cmd .= Samba::bindir_path($self, "samba-tool") >@@ -1038,8 +1062,9 @@ userPrincipalName: testdenied_upn\@$ctx->{realm}.upn > } > > $user_dn = "cn=testupnspn,cn=users,$base_dn"; >- open(LDIF, "|$ldbmodify -H $ctx->{privatedir}/sam.ldb"); >- print LDIF "dn: $user_dn >+ open($ldif, "|$ldbmodify -H $ctx->{privatedir}/sam.ldb") >+ or die "Failed to run $ldbmodify: $!"; >+ print $ldif "dn: $user_dn > changetype: modify > replace: userPrincipalName > userPrincipalName: http/testupnspn.$ctx->{dnsname}\@$ctx->{realm} >@@ -1047,7 +1072,11 @@ replace: servicePrincipalName > servicePrincipalName: http/testupnspn.$ctx->{dnsname} > - > "; >- close(LDIF); >+ close($ldif); >+ unless ($? == 0) { >+ warn("$ldbmodify failed: $?"); >+ return undef; >+ } > > $samba_tool_cmd = ${cmd_env}; > $samba_tool_cmd .= Samba::bindir_path($self, "samba-tool") >@@ -1110,14 +1139,19 @@ servicePrincipalName: http/testupnspn.$ctx->{dnsname} > # Change the userPrincipalName for jane > $user_dn = "cn=jane,cn=users,$base_dn"; > >- open(LDIF, "|$ldbmodify -H $ctx->{privatedir}/sam.ldb"); >- print LDIF "dn: $user_dn >+ open($ldif, "|$ldbmodify -H $ctx->{privatedir}/sam.ldb") >+ or die "Failed to run $ldbmodify: $!"; >+ print $ldif "dn: $user_dn > changetype: modify > replace: userPrincipalName > userPrincipalName: jane.doe\@$ctx->{realm} > - > "; >- close(LDIF); >+ close($ldif); >+ unless ($? == 0) { >+ warn("$ldbmodify failed: $?"); >+ return undef; >+ } > > return $ret; > } >-- >2.25.1 > > >From c9a2867559b86bc191c9ffa1ec2f62d9ce1bb2c1 Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Mon, 4 Oct 2021 13:02:35 +0200 >Subject: [PATCH 149/159] waf: Allow building with MIT KRB5 >= 1.20 >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >gssrpc/xdr.h:105:1: error: function declaration isnât a prototype >[-Werror=strict-prototypes] > 105 | typedef bool_t (*xdrproc_t)(); > | ^~~~~~~ > >This can't be fixed, as the protoype is variadic. It can take up to three >arguments. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14870 > >Signed-off-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit 5d8e794551b5df835f07e2bd8348fef746144601) >--- > source4/kdc/wscript_build | 1 + > 1 file changed, 1 insertion(+) > >diff --git a/source4/kdc/wscript_build b/source4/kdc/wscript_build >index c1f9a478582..0edca94e75f 100644 >--- a/source4/kdc/wscript_build >+++ b/source4/kdc/wscript_build >@@ -29,6 +29,7 @@ if bld.CONFIG_SET('SAMBA4_USES_HEIMDAL'): > if bld.CONFIG_GET('SAMBA_USES_MITKDC'): > bld.SAMBA_MODULE('service_kdc', > source='kdc-service-mit.c', >+ cflags_end='-Wno-strict-prototypes', > subsystem='service', > init_function='server_service_mitkdc_init', > deps=''' >-- >2.25.1 > > >From f8996cac697c8ca6fec3c9cd091bc2a0234a0e0d Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 8 Oct 2021 18:04:55 +0200 >Subject: [PATCH 150/159] selftest/Samba3: remove unused close(USERMAP); calls > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14869 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >[abartlet@samba.org backported from commit d998f7f8df215866ab32e05be772e24fc0b2131c > as offline login tests are not in Samba 4.14] >--- > selftest/target/Samba3.pm | 4 ---- > 1 file changed, 4 deletions(-) > >diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm >index 4afcc47b82b..f781fe7bf57 100755 >--- a/selftest/target/Samba3.pm >+++ b/selftest/target/Samba3.pm >@@ -771,7 +771,6 @@ sub provision_ad_member > > mkdir($_, 0777) foreach(@dirs); > >- close(USERMAP); > $ret->{DOMAIN} = $dcvars->{DOMAIN}; > $ret->{REALM} = $dcvars->{REALM}; > $ret->{DOMSID} = $dcvars->{DOMSID}; >@@ -920,7 +919,6 @@ sub setup_ad_member_rfc2307 > > $ret or return undef; > >- close(USERMAP); > $ret->{DOMAIN} = $dcvars->{DOMAIN}; > $ret->{REALM} = $dcvars->{REALM}; > $ret->{DOMSID} = $dcvars->{DOMSID}; >@@ -1018,7 +1016,6 @@ sub setup_ad_member_idmap_rid > > $ret or return undef; > >- close(USERMAP); > $ret->{DOMAIN} = $dcvars->{DOMAIN}; > $ret->{REALM} = $dcvars->{REALM}; > $ret->{DOMSID} = $dcvars->{DOMSID}; >@@ -1118,7 +1115,6 @@ sub setup_ad_member_idmap_ad > > $ret or return undef; > >- close(USERMAP); > $ret->{DOMAIN} = $dcvars->{DOMAIN}; > $ret->{REALM} = $dcvars->{REALM}; > $ret->{DOMSID} = $dcvars->{DOMSID}; >-- >2.25.1 > > >From 9e0743838d916db097afa0f3859cee2d4f0a73d0 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 5 Oct 2021 16:42:00 +0200 >Subject: [PATCH 151/159] selftest/Samba3: replace (winbindd => "yes", > skip_wait => 1) with (winbindd => "offline") > >This is much more flexible and concentrates the logic in a single place. > >We'll use winbindd => "offline" in other places soon. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14870 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 4dc3c68c9a28f71888e3d6dd3b1f0bcdb8fa45de) >--- > selftest/target/Samba3.pm | 12 ++++++++---- > 1 file changed, 8 insertions(+), 4 deletions(-) > >diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm >index f781fe7bf57..4ec95e237a7 100755 >--- a/selftest/target/Samba3.pm >+++ b/selftest/target/Samba3.pm >@@ -827,7 +827,7 @@ sub provision_ad_member > nmbd => "yes", > winbindd => "yes", > smbd => "yes")) { >- return undef; >+ return undef; > } > > $ret->{DC_SERVER} = $dcvars->{SERVER}; >@@ -1909,7 +1909,7 @@ sub check_or_start($$) { > LOG_FILE => $env_vars->{WINBINDD_TEST_LOG}, > PCAP_FILE => "env-$ENV{ENVNAME}-winbindd", > }; >- if ($winbindd ne "yes") { >+ if ($winbindd ne "yes" and $winbindd ne "offline") { > $daemon_ctx->{SKIP_DAEMON} = 1; > } > >@@ -3131,13 +3131,17 @@ sub wait_for_start($$$$$) > } > } > >- if ($winbindd eq "yes") { >+ if ($winbindd eq "yes" or $winbindd eq "offline") { > print "checking for winbindd\n"; > my $count = 0; > $cmd = "SELFTEST_WINBINDD_SOCKET_DIR='$envvars->{SELFTEST_WINBINDD_SOCKET_DIR}' "; > $cmd .= "NSS_WRAPPER_PASSWD='$envvars->{NSS_WRAPPER_PASSWD}' "; > $cmd .= "NSS_WRAPPER_GROUP='$envvars->{NSS_WRAPPER_GROUP}' "; >- $cmd .= Samba::bindir_path($self, "wbinfo") . " --ping-dc"; >+ if ($winbindd eq "yes") { >+ $cmd .= Samba::bindir_path($self, "wbinfo") . " --ping-dc"; >+ } elsif ($winbindd eq "offline") { >+ $cmd .= Samba::bindir_path($self, "wbinfo") . " --ping"; >+ } > > do { > $ret = system($cmd); >-- >2.25.1 > > >From 375d839ea9b41daab455e69f3188fabb9e639539 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 20 Oct 2021 12:39:05 +1300 >Subject: [PATCH 152/159] tests/krb5: Decrease length of test account prefix > >This allows us more room to test with different account names. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14874 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit a5a6296e57cab2b53617d997c37b4e92d4124cc7) >--- > python/samba/tests/krb5/kdc_base_test.py | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 7cd3c5255f2..8f453b464fd 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -108,7 +108,7 @@ class KDCBaseTest(RawKerberosTest): > # An identifier to ensure created accounts have unique names. Windows > # caches accounts based on usernames, so account names being different > # across test runs avoids previous test runs affecting the results. >- cls.account_base = f'krb5_{secrets.token_hex(5)}_' >+ cls.account_base = f'{secrets.token_hex(4)}_' > cls.account_id = 0 > > # A set containing DNs of accounts created as part of testing. >-- >2.25.1 > > >From 15e2ff11a41abe6dc748d714793b4454eab068c2 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 20 Oct 2021 12:41:39 +1300 >Subject: [PATCH 153/159] tests/krb5: Allow specifying prefix or suffix for > test account names > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14874 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit 7e39994ed341883ac4c8c257220c19dbf70c7bc5) >--- > python/samba/tests/krb5/kdc_base_test.py | 8 ++++++++ > 1 file changed, 8 insertions(+) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 8f453b464fd..d8f3969d228 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -630,6 +630,8 @@ class KDCBaseTest(RawKerberosTest): > opts = {} > > opts_default = { >+ 'name_prefix': None, >+ 'name_suffix': None, > 'spn': None, > 'allowed_replication': False, > 'allowed_replication_mock': False, >@@ -667,6 +669,8 @@ class KDCBaseTest(RawKerberosTest): > > def create_account_opts(self, *, > account_type, >+ name_prefix, >+ name_suffix, > spn, > allowed_replication, > allowed_replication_mock, >@@ -696,6 +700,10 @@ class KDCBaseTest(RawKerberosTest): > > user_name = self.account_base + str(self.account_id) > type(self).account_id += 1 >+ if name_prefix is not None: >+ user_name = name_prefix + user_name >+ if name_suffix is not None: >+ user_name += name_suffix > > user_account_control = 0 > if trusted_to_auth_for_delegation: >-- >2.25.1 > > >From 2c973282a36e4cf90e522c012b7d80cc2e425c66 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 20 Oct 2021 12:44:19 +1300 >Subject: [PATCH 154/159] tests/krb5: Allow creating machine accounts without a > trailing dollar > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14874 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit f4785ccfefe7c89f84ad847ca3c12f604172b321) >--- > python/samba/tests/krb5/kdc_base_test.py | 12 ++++++++---- > 1 file changed, 8 insertions(+), 4 deletions(-) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index d8f3969d228..35f168a3c83 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -237,7 +237,7 @@ class KDCBaseTest(RawKerberosTest): > > def create_account(self, samdb, name, account_type=AccountType.USER, > spn=None, upn=None, additional_details=None, >- ou=None, account_control=0): >+ ou=None, account_control=0, add_dollar=True): > '''Create an account for testing. > The dn of the created account is added to self.accounts, > which is used by tearDownClass to clean up the created accounts. >@@ -255,13 +255,14 @@ class KDCBaseTest(RawKerberosTest): > # remove the account if it exists, this will happen if a previous test > # run failed > delete_force(samdb, dn) >+ account_name = name > if account_type is self.AccountType.USER: > object_class = "user" >- account_name = name > account_control |= UF_NORMAL_ACCOUNT > else: > object_class = "computer" >- account_name = "%s$" % name >+ if add_dollar: >+ account_name += '$' > if account_type is self.AccountType.COMPUTER: > account_control |= UF_WORKSTATION_TRUST_ACCOUNT > else: >@@ -632,6 +633,7 @@ class KDCBaseTest(RawKerberosTest): > opts_default = { > 'name_prefix': None, > 'name_suffix': None, >+ 'add_dollar': True, > 'spn': None, > 'allowed_replication': False, > 'allowed_replication_mock': False, >@@ -671,6 +673,7 @@ class KDCBaseTest(RawKerberosTest): > account_type, > name_prefix, > name_suffix, >+ add_dollar, > spn, > allowed_replication, > allowed_replication_mock, >@@ -739,7 +742,8 @@ class KDCBaseTest(RawKerberosTest): > account_type=account_type, > spn=spn, > additional_details=details, >- account_control=user_account_control) >+ account_control=user_account_control, >+ add_dollar=add_dollar) > > keys = self.get_keys(samdb, dn) > self.creds_set_keys(creds, keys) >-- >2.25.1 > > >From c76c96c6a86d4fc5c71e0ba90bea7686591f2dbb Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 20 Oct 2021 12:45:08 +1300 >Subject: [PATCH 155/159] tests/krb5: Allow specifying the UPN for test > accounts > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14874 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit 889476d1754f8ce2a41557ed3bf5242c1293584e) >--- > python/samba/tests/krb5/kdc_base_test.py | 4 ++++ > python/samba/tests/krb5/raw_testcase.py | 7 +++++++ > 2 files changed, 11 insertions(+) > >diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py >index 35f168a3c83..b24c6376ab0 100644 >--- a/python/samba/tests/krb5/kdc_base_test.py >+++ b/python/samba/tests/krb5/kdc_base_test.py >@@ -300,6 +300,7 @@ class KDCBaseTest(RawKerberosTest): > else: > creds.set_workstation(name) > creds.set_dn(ldb.Dn(samdb, dn)) >+ creds.set_upn(upn) > creds.set_spn(spn) > # > # Save the account name so it can be deleted in tearDownClass >@@ -634,6 +635,7 @@ class KDCBaseTest(RawKerberosTest): > 'name_prefix': None, > 'name_suffix': None, > 'add_dollar': True, >+ 'upn': None, > 'spn': None, > 'allowed_replication': False, > 'allowed_replication_mock': False, >@@ -674,6 +676,7 @@ class KDCBaseTest(RawKerberosTest): > name_prefix, > name_suffix, > add_dollar, >+ upn, > spn, > allowed_replication, > allowed_replication_mock, >@@ -740,6 +743,7 @@ class KDCBaseTest(RawKerberosTest): > > creds, dn = self.create_account(samdb, user_name, > account_type=account_type, >+ upn=upn, > spn=spn, > additional_details=details, > account_control=user_account_control, >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 0b9fe8e7a04..619a8d006b2 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -366,6 +366,7 @@ class KerberosCredentials(Credentials): > self.forced_salt = None > > self.dn = None >+ self.upn = None > self.spn = None > > def set_as_supported_enctypes(self, value): >@@ -475,6 +476,12 @@ class KerberosCredentials(Credentials): > def get_spn(self): > return self.spn > >+ def set_upn(self, upn): >+ self.upn = upn >+ >+ def get_upn(self): >+ return self.upn >+ > > class KerberosTicketCreds: > def __init__(self, ticket, session_key, >-- >2.25.1 > > >From be929d18194586d3a265beda79e483a9e83f81be Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 20 Oct 2021 12:45:47 +1300 >Subject: [PATCH 156/159] tests/krb5: Fix account salt calculation to match > Windows > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14874 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit 25bdf4c994e4fdb74abbacb1e22237f3f2cc37fe) >--- > python/samba/tests/krb5/raw_testcase.py | 13 +++++++++++-- > 1 file changed, 11 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py >index 619a8d006b2..f352615db1f 100644 >--- a/python/samba/tests/krb5/raw_testcase.py >+++ b/python/samba/tests/krb5/raw_testcase.py >@@ -454,13 +454,22 @@ class KerberosCredentials(Credentials): > if self.forced_salt is not None: > return self.forced_salt > >+ upn = self.get_upn() >+ if upn is not None: >+ salt_name = upn.rsplit('@', 1)[0].replace('/', '') >+ else: >+ salt_name = self.get_username() >+ > if self.get_workstation(): >+ salt_name = self.get_username().lower() >+ if salt_name[-1] == '$': >+ salt_name = salt_name[:-1] > salt_string = '%shost%s.%s' % ( > self.get_realm().upper(), >- self.get_username().lower().rsplit('$', 1)[0], >+ salt_name, > self.get_realm().lower()) > else: >- salt_string = self.get_realm().upper() + self.get_username() >+ salt_string = self.get_realm().upper() + salt_name > > return salt_string.encode('utf-8') > >-- >2.25.1 > > >From cbd629432c8ca3f7aaa04ee76892d077cd7be131 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Wed, 20 Oct 2021 12:46:36 +1300 >Subject: [PATCH 157/159] tests/krb5: Add tests for account salt calculation > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14874 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >[abartlet@samba.org backported from commit 46039baa81377df10e5b134e4bb064ed246795e4 > as the no_preauth side of the testsuite shows differences in enctypes > in Samba 4.14. The change is only in salt calculation so this is > not vital] >--- > python/samba/tests/krb5/as_req_tests.py | 10 + > python/samba/tests/krb5/salt_tests.py | 327 ++++++++++++++++++++++++ > python/samba/tests/usage.py | 1 + > selftest/knownfail.d/kdc-salt | 12 + > selftest/knownfail_heimdal_kdc | 108 ++++++++ > source4/selftest/tests.py | 8 + > 6 files changed, 466 insertions(+) > create mode 100755 python/samba/tests/krb5/salt_tests.py > create mode 100644 selftest/knownfail.d/kdc-salt > >diff --git a/python/samba/tests/krb5/as_req_tests.py b/python/samba/tests/krb5/as_req_tests.py >index 7d7baaebf24..08081928363 100755 >--- a/python/samba/tests/krb5/as_req_tests.py >+++ b/python/samba/tests/krb5/as_req_tests.py >@@ -113,6 +113,13 @@ class AsReqKerberosTests(KDCBaseTest): > > def test_as_req_enc_timestamp(self): > client_creds = self.get_client_creds() >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_as_req_enc_timestamp_mac(self): >+ client_creds = self.get_mach_creds() >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def _run_as_req_enc_timestamp(self, client_creds): > client_account = client_creds.get_username() > client_as_etypes = self.get_default_enctypes() > client_kvno = client_creds.get_kvno() >@@ -197,6 +204,9 @@ class AsReqKerberosTests(KDCBaseTest): > pac_request=True) > self.assertIsNotNone(as_rep) > >+ return etype_info2 >+ >+ > if __name__ == "__main__": > global_asn1_print = False > global_hexdump = False >diff --git a/python/samba/tests/krb5/salt_tests.py b/python/samba/tests/krb5/salt_tests.py >new file mode 100755 >index 00000000000..ecbf618e40e >--- /dev/null >+++ b/python/samba/tests/krb5/salt_tests.py >@@ -0,0 +1,327 @@ >+#!/usr/bin/env python3 >+# Unix SMB/CIFS implementation. >+# Copyright (C) Stefan Metzmacher 2020 >+# >+# 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 >+ >+import ldb >+ >+from samba.tests.krb5.as_req_tests import AsReqKerberosTests >+import samba.tests.krb5.kcrypto as kcrypto >+ >+sys.path.insert(0, "bin/python") >+os.environ["PYTHONUNBUFFERED"] = "1" >+ >+global_asn1_print = False >+global_hexdump = False >+ >+ >+class SaltTests(AsReqKerberosTests): >+ >+ def setUp(self): >+ super().setUp() >+ self.do_asn1_print = global_asn1_print >+ self.do_hexdump = global_hexdump >+ >+ def _get_creds(self, *, >+ account_type, >+ opts=None): >+ try: >+ return self.get_cached_creds( >+ account_type=account_type, >+ opts=opts) >+ except ldb.LdbError: >+ self.fail() >+ >+ def _run_salt_test(self, client_creds): >+ expected_salt = self.get_salt(client_creds) >+ self.assertIsNotNone(expected_salt) >+ >+ etype_info2 = self._run_as_req_enc_timestamp(client_creds) >+ >+ self.assertEqual(etype_info2[0]['etype'], kcrypto.Enctype.AES256) >+ self.assertEqual(etype_info2[0]['salt'], expected_salt) >+ >+ def test_salt_at_user(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.USER, >+ opts={'name_suffix': 'foo@bar'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_at_mac(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'name_suffix': 'foo@bar'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_at_case_user(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.USER, >+ opts={'name_suffix': 'Foo@bar'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_at_case_mac(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'name_suffix': 'Foo@bar'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_double_at_user(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.USER, >+ opts={'name_suffix': 'foo@@bar'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_double_at_mac(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'name_suffix': 'foo@@bar'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_at_start_user(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.USER, >+ opts={'name_prefix': '@foo'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_at_start_mac(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'name_prefix': '@foo'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_at_end_user(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.USER, >+ opts={'name_suffix': 'foo@'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_at_end_mac(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'name_suffix': 'foo@'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_at_end_no_dollar_mac(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'name_suffix': 'foo@', >+ 'add_dollar': False}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_no_dollar_mac(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'add_dollar': False}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_dollar_mid_mac(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'name_suffix': 'foo$bar', >+ 'add_dollar': False}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_dollar_user(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.USER, >+ opts={'name_suffix': 'foo$bar'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_dollar_mac(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'name_suffix': 'foo$bar'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_dollar_end_user(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.USER, >+ opts={'name_suffix': 'foo$'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_dollar_end_mac(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'name_suffix': 'foo$'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_user(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.USER, >+ opts={'upn': 'foo0'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_mac(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'upn': 'foo1'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_host_user(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.USER, >+ opts={'upn': 'host/foo2'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_host_mac(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'upn': 'host/foo3'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_realm_user(self): >+ realm = self.get_samdb().domain_dns_name() >+ client_creds = self._get_creds( >+ account_type=self.AccountType.USER, >+ opts={'upn': 'foo4@' + realm}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_realm_mac(self): >+ realm = self.get_samdb().domain_dns_name() >+ client_creds = self._get_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'upn': 'foo5@' + realm}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_host_realm_user(self): >+ realm = self.get_samdb().domain_dns_name() >+ client_creds = self._get_creds( >+ account_type=self.AccountType.USER, >+ opts={'upn': 'host/foo6@' + realm}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_host_realm_mac(self): >+ realm = self.get_samdb().domain_dns_name() >+ client_creds = self._get_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'upn': 'host/foo7@' + realm}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_dollar_realm_user(self): >+ realm = self.get_samdb().domain_dns_name() >+ client_creds = self._get_creds( >+ account_type=self.AccountType.USER, >+ opts={'upn': 'foo8$@' + realm}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_dollar_realm_mac(self): >+ realm = self.get_samdb().domain_dns_name() >+ client_creds = self._get_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'upn': 'foo9$@' + realm}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_host_dollar_realm_user(self): >+ realm = self.get_samdb().domain_dns_name() >+ client_creds = self._get_creds( >+ account_type=self.AccountType.USER, >+ opts={'upn': 'host/foo10$@' + realm}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_host_dollar_realm_mac(self): >+ realm = self.get_samdb().domain_dns_name() >+ client_creds = self._get_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'upn': 'host/foo11$@' + realm}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_other_realm_user(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.USER, >+ opts={'upn': 'foo12@other.realm'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_other_realm_mac(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'upn': 'foo13@other.realm'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_host_other_realm_user(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.USER, >+ opts={'upn': 'host/foo14@other.realm'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_host_other_realm_mac(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'upn': 'host/foo15@other.realm'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_case_user(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.USER, >+ opts={'upn': 'Foo16'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_case_mac(self): >+ client_creds = self._get_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'upn': 'Foo17'}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_dollar_mid_realm_user(self): >+ realm = self.get_samdb().domain_dns_name() >+ client_creds = self._get_creds( >+ account_type=self.AccountType.USER, >+ opts={'upn': 'foo$18@' + realm}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_dollar_mid_realm_mac(self): >+ realm = self.get_samdb().domain_dns_name() >+ client_creds = self._get_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'upn': 'foo$19@' + realm}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_host_dollar_mid_realm_user(self): >+ realm = self.get_samdb().domain_dns_name() >+ client_creds = self._get_creds( >+ account_type=self.AccountType.USER, >+ opts={'upn': 'host/foo$20@' + realm}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_host_dollar_mid_realm_mac(self): >+ realm = self.get_samdb().domain_dns_name() >+ client_creds = self._get_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'upn': 'host/foo$21@' + realm}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_at_realm_user(self): >+ realm = self.get_samdb().domain_dns_name() >+ client_creds = self._get_creds( >+ account_type=self.AccountType.USER, >+ opts={'upn': 'foo22@bar@' + realm}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ def test_salt_upn_at_realm_mac(self): >+ realm = self.get_samdb().domain_dns_name() >+ client_creds = self._get_creds( >+ account_type=self.AccountType.COMPUTER, >+ opts={'upn': 'foo23@bar@' + realm}) >+ self._run_as_req_enc_timestamp(client_creds) >+ >+ >+if __name__ == "__main__": >+ global_asn1_print = False >+ global_hexdump = False >+ import unittest >+ unittest.main() >diff --git a/python/samba/tests/usage.py b/python/samba/tests/usage.py >index 0a9aac1f2cc..af118242a1b 100644 >--- a/python/samba/tests/usage.py >+++ b/python/samba/tests/usage.py >@@ -104,6 +104,7 @@ EXCLUDE_USAGE = { > 'python/samba/tests/krb5/as_req_tests.py', > 'python/samba/tests/krb5/fast_tests.py', > 'python/samba/tests/krb5/rodc_tests.py', >+ 'python/samba/tests/krb5/salt_tests.py', > } > > EXCLUDE_HELP = { >diff --git a/selftest/knownfail.d/kdc-salt b/selftest/knownfail.d/kdc-salt >new file mode 100644 >index 00000000000..1a4ecd44624 >--- /dev/null >+++ b/selftest/knownfail.d/kdc-salt >@@ -0,0 +1,12 @@ >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_at_case_mac >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_at_case_user >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_at_end_mac >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_at_end_no_dollar_mac >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_at_end_user >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_at_mac >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_at_start_mac >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_at_start_user >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_at_user >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_double_at_mac >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_double_at_user >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_upn_at_realm_user >diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc >index b1d7a1ebe8f..b39b11c3c53 100644 >--- a/selftest/knownfail_heimdal_kdc >+++ b/selftest/knownfail_heimdal_kdc >@@ -71,6 +71,114 @@ > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_False.fl2008r2dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_None.fl2008r2dc > ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_dummy_rc4_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_dummy_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_dummy_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_dummy_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_dummy_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_dummy_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_dummy_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_dummy_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_dummy_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_dummy_rc4_aes128_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_dummy_rc4_aes128_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_dummy_rc4_aes128_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_dummy_rc4_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_dummy_rc4_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_dummy_rc4_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_dummy_rc4_aes256_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_dummy_rc4_aes256_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_dummy_rc4_aes256_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_dummy_rc4_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_dummy_rc4_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_dummy_rc4_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes128_aes256_dummy_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes128_aes256_dummy_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes128_aes256_dummy_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes128_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes128_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes128_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes128_dummy_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes128_dummy_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes128_dummy_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes128_dummy_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes128_dummy_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes128_dummy_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes256_aes128_dummy_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes256_aes128_dummy_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes256_aes128_dummy_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes256_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes256_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes256_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes256_dummy_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes256_dummy_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes256_dummy_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes256_dummy_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes256_dummy_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes256_dummy_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_dummy_aes128_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_dummy_aes128_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_dummy_aes128_aes256_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_dummy_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_dummy_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_dummy_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_dummy_aes256_aes128_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_dummy_aes256_aes128_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_dummy_aes256_aes128_pac_True.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_False.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_None.fl2008r2dc >+^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_as_req_no_preauth_rc4_dummy_aes256_pac_True.fl2008r2dc > # > # FAST tests > # >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index c2a6256029f..c2175486aae 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -1429,6 +1429,14 @@ for env in ["fl2008r2dc", "fl2003dc"]: > 'TKT_SIG_SUPPORT': tkt_sig_support > }) > >+planoldpythontestsuite('fl2008r2dc', 'samba.tests.krb5.salt_tests', >+ environ={ >+ 'ADMIN_USERNAME': '$USERNAME', >+ 'ADMIN_PASSWORD': '$PASSWORD', >+ 'STRICT_CHECKING': '0', >+ 'FAST_SUPPORT': have_fast_support, >+ 'TKT_SIG_SUPPORT': tkt_sig_support >+ }) > > for env in ["rodc", "promoted_dc", "fl2000dc", "fl2008r2dc"]: > if env == "rodc": >-- >2.25.1 > > >From 50645a4cca649beb88273b5c4937924236d8c90b Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Tue, 19 Oct 2021 16:01:36 +1300 >Subject: [PATCH 158/159] dsdb: Allow special chars like "@" in samAccountName > when generating the salt > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14874 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> > >Autobuild-User(master): Stefan Metzmacher <metze@samba.org> >Autobuild-Date(master): Wed Oct 20 12:54:54 UTC 2021 on sn-devel-184 > >(cherry picked from commit 5eeb441b771a1ffe1ba1c69b72e8795f525a58ed) >--- > auth/credentials/credentials_krb5.c | 12 +- > lib/krb5_wrap/krb5_samba.c | 192 +++++++++++++++--- > lib/krb5_wrap/krb5_samba.h | 13 +- > selftest/knownfail.d/kdc-salt | 11 - > source3/passdb/machine_account_secrets.c | 10 +- > .../dsdb/samdb/ldb_modules/password_hash.c | 23 ++- > 6 files changed, 195 insertions(+), 66 deletions(-) > >diff --git a/auth/credentials/credentials_krb5.c b/auth/credentials/credentials_krb5.c >index d7b1c430841..2338d9f114b 100644 >--- a/auth/credentials/credentials_krb5.c >+++ b/auth/credentials/credentials_krb5.c >@@ -1200,12 +1200,12 @@ _PUBLIC_ int cli_credentials_get_keytab(struct cli_credentials *cred, > break; > } > >- ret = smb_krb5_salt_principal(realm, >- username, /* sAMAccountName */ >- upn, /* userPrincipalName */ >- uac_flags, >- mem_ctx, >- &salt_principal); >+ ret = smb_krb5_salt_principal_str(realm, >+ username, /* sAMAccountName */ >+ upn, /* userPrincipalName */ >+ uac_flags, >+ mem_ctx, >+ &salt_principal); > if (ret) { > talloc_free(mem_ctx); > return ret; >diff --git a/lib/krb5_wrap/krb5_samba.c b/lib/krb5_wrap/krb5_samba.c >index 20ce86c708d..63a6e951f80 100644 >--- a/lib/krb5_wrap/krb5_samba.c >+++ b/lib/krb5_wrap/krb5_samba.c >@@ -456,19 +456,20 @@ int smb_krb5_get_pw_salt(krb5_context context, > * > * @see smb_krb5_salt_principal2data > */ >-int smb_krb5_salt_principal(const char *realm, >+int smb_krb5_salt_principal(krb5_context krb5_ctx, >+ const char *realm, > const char *sAMAccountName, > const char *userPrincipalName, > uint32_t uac_flags, >- TALLOC_CTX *mem_ctx, >- char **_salt_principal) >+ krb5_principal *salt_princ) > { > TALLOC_CTX *frame = talloc_stackframe(); > char *upper_realm = NULL; > const char *principal = NULL; > int principal_len = 0; >+ krb5_error_code krb5_ret; > >- *_salt_principal = NULL; >+ *salt_princ = NULL; > > if (sAMAccountName == NULL) { > TALLOC_FREE(frame); >@@ -512,7 +513,6 @@ int smb_krb5_salt_principal(const char *realm, > */ > if (uac_flags & UF_TRUST_ACCOUNT_MASK) { > int computer_len = 0; >- char *tmp = NULL; > > computer_len = strlen(sAMAccountName); > if (sAMAccountName[computer_len-1] == '$') { >@@ -520,60 +520,186 @@ int smb_krb5_salt_principal(const char *realm, > } > > if (uac_flags & UF_INTERDOMAIN_TRUST_ACCOUNT) { >- principal = talloc_asprintf(frame, "krbtgt/%*.*s", >- computer_len, computer_len, >- sAMAccountName); >- if (principal == NULL) { >+ const char *krbtgt = "krbtgt"; >+ krb5_ret = krb5_build_principal_ext(krb5_ctx, >+ salt_princ, >+ strlen(upper_realm), >+ upper_realm, >+ strlen(krbtgt), >+ krbtgt, >+ computer_len, >+ sAMAccountName, >+ 0); >+ if (krb5_ret != 0) { > TALLOC_FREE(frame); >- return ENOMEM; >+ return krb5_ret; > } > } else { >- >- tmp = talloc_asprintf(frame, "host/%*.*s.%s", >- computer_len, computer_len, >- sAMAccountName, realm); >+ const char *host = "host"; >+ char *tmp = NULL; >+ char *tmp_lower = NULL; >+ >+ tmp = talloc_asprintf(frame, "%*.*s.%s", >+ computer_len, >+ computer_len, >+ sAMAccountName, >+ realm); > if (tmp == NULL) { > TALLOC_FREE(frame); > return ENOMEM; > } > >- principal = strlower_talloc(frame, tmp); >- TALLOC_FREE(tmp); >- if (principal == NULL) { >+ tmp_lower = strlower_talloc(frame, tmp); >+ if (tmp_lower == NULL) { > TALLOC_FREE(frame); > return ENOMEM; > } >- } > >- principal_len = strlen(principal); >+ krb5_ret = krb5_build_principal_ext(krb5_ctx, >+ salt_princ, >+ strlen(upper_realm), >+ upper_realm, >+ strlen(host), >+ host, >+ strlen(tmp_lower), >+ tmp_lower, >+ 0); >+ if (krb5_ret != 0) { >+ TALLOC_FREE(frame); >+ return krb5_ret; >+ } >+ } > > } else if (userPrincipalName != NULL) { >- char *p; >+ /* >+ * We parse the name not only to allow an easy >+ * replacement of the realm (no matter the realm in >+ * the UPN, the salt comes from the upper-case real >+ * realm, but also to correctly provide a salt when >+ * the UPN is host/foo.bar >+ * >+ * This can fail for a UPN of the form foo@bar@REALM >+ * (which is accepted by windows) however. >+ */ >+ krb5_ret = krb5_parse_name(krb5_ctx, >+ userPrincipalName, >+ salt_princ); > >- principal = userPrincipalName; >- p = strchr(principal, '@'); >- if (p != NULL) { >- principal_len = PTR_DIFF(p, principal); >- } else { >- principal_len = strlen(principal); >+ if (krb5_ret != 0) { >+ TALLOC_FREE(frame); >+ return krb5_ret; >+ } >+ >+ /* >+ * No matter what realm (including none) in the UPN, >+ * the realm is replaced with our upper-case realm >+ */ >+ smb_krb5_principal_set_realm(krb5_ctx, >+ *salt_princ, >+ upper_realm); >+ if (krb5_ret != 0) { >+ krb5_free_principal(krb5_ctx, *salt_princ); >+ TALLOC_FREE(frame); >+ return krb5_ret; > } > } else { > principal = sAMAccountName; > principal_len = strlen(principal); >- } > >- *_salt_principal = talloc_asprintf(mem_ctx, "%*.*s@%s", >- principal_len, principal_len, >- principal, upper_realm); >- if (*_salt_principal == NULL) { >- TALLOC_FREE(frame); >- return ENOMEM; >+ krb5_ret = krb5_build_principal_ext(krb5_ctx, >+ salt_princ, >+ strlen(upper_realm), >+ upper_realm, >+ principal_len, >+ principal, >+ 0); >+ if (krb5_ret != 0) { >+ TALLOC_FREE(frame); >+ return krb5_ret; >+ } > } > > TALLOC_FREE(frame); > return 0; > } > >+/** >+ * @brief This constructs the salt principal used by active directory >+ * >+ * Most Kerberos encryption types require a salt in order to >+ * calculate the long term private key for user/computer object >+ * based on a password. >+ * >+ * The returned _salt_principal is a string in forms like this: >+ * - host/somehost.example.com@EXAMPLE.COM >+ * - SomeAccount@EXAMPLE.COM >+ * - SomePrincipal@EXAMPLE.COM >+ * >+ * This is not the form that's used as salt, it's just >+ * the human readable form. It needs to be converted by >+ * smb_krb5_salt_principal2data(). >+ * >+ * @param[in] realm The realm the user/computer is added too. >+ * >+ * @param[in] sAMAccountName The sAMAccountName attribute of the object. >+ * >+ * @param[in] userPrincipalName The userPrincipalName attribute of the object >+ * or NULL is not available. >+ * >+ * @param[in] uac_flags UF_ACCOUNT_TYPE_MASKed userAccountControl field >+ * >+ * @param[in] mem_ctx The TALLOC_CTX to allocate _salt_principal. >+ * >+ * @param[out] _salt_principal The resulting principal as string. >+ * >+ * @retval 0 Success; otherwise - Kerberos error codes >+ * >+ * @see smb_krb5_salt_principal2data >+ */ >+int smb_krb5_salt_principal_str(const char *realm, >+ const char *sAMAccountName, >+ const char *userPrincipalName, >+ uint32_t uac_flags, >+ TALLOC_CTX *mem_ctx, >+ char **_salt_principal_str) >+{ >+ krb5_principal salt_principal = NULL; >+ char *salt_principal_malloc; >+ krb5_context krb5_ctx; >+ krb5_error_code krb5_ret >+ = smb_krb5_init_context_common(&krb5_ctx); >+ if (krb5_ret != 0) { >+ DBG_ERR("kerberos init context failed (%s)\n", >+ error_message(krb5_ret)); >+ return krb5_ret; >+ } >+ >+ krb5_ret = smb_krb5_salt_principal(krb5_ctx, >+ realm, >+ sAMAccountName, >+ userPrincipalName, >+ uac_flags, >+ &salt_principal); >+ >+ krb5_ret = krb5_unparse_name(krb5_ctx, salt_principal, >+ &salt_principal_malloc); >+ if (krb5_ret != 0) { >+ krb5_free_principal(krb5_ctx, salt_principal); >+ DBG_ERR("kerberos unparse of salt principal failed (%s)\n", >+ error_message(krb5_ret)); >+ return krb5_ret; >+ } >+ krb5_free_principal(krb5_ctx, salt_principal); >+ *_salt_principal_str >+ = talloc_strdup(mem_ctx, salt_principal_malloc); >+ krb5_free_unparsed_name(krb5_ctx, salt_principal_malloc); >+ >+ if (*_salt_principal_str == NULL) { >+ return ENOMEM; >+ } >+ return 0; >+} >+ > /** > * @brief Converts the salt principal string into the salt data blob > * >diff --git a/lib/krb5_wrap/krb5_samba.h b/lib/krb5_wrap/krb5_samba.h >index ca9a893e4f7..56a2a975278 100644 >--- a/lib/krb5_wrap/krb5_samba.h >+++ b/lib/krb5_wrap/krb5_samba.h >@@ -350,12 +350,19 @@ krb5_error_code ms_suptypes_to_ietf_enctypes(TALLOC_CTX *mem_ctx, > int smb_krb5_get_pw_salt(krb5_context context, > krb5_const_principal host_princ, > krb5_data *psalt); >-int smb_krb5_salt_principal(const char *realm, >+int smb_krb5_salt_principal(krb5_context krb5_ctx, >+ const char *realm, > const char *sAMAccountName, > const char *userPrincipalName, > uint32_t uac_flags, >- TALLOC_CTX *mem_ctx, >- char **_salt_principal); >+ krb5_principal *salt_princ); >+ >+int smb_krb5_salt_principal_str(const char *realm, >+ const char *sAMAccountName, >+ const char *userPrincipalName, >+ uint32_t uac_flags, >+ TALLOC_CTX *mem_ctx, >+ char **_salt_principal); > int smb_krb5_salt_principal2data(krb5_context context, > const char *salt_principal, > TALLOC_CTX *mem_ctx, >diff --git a/selftest/knownfail.d/kdc-salt b/selftest/knownfail.d/kdc-salt >index 1a4ecd44624..a671e4d93eb 100644 >--- a/selftest/knownfail.d/kdc-salt >+++ b/selftest/knownfail.d/kdc-salt >@@ -1,12 +1 @@ >-^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_at_case_mac >-^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_at_case_user >-^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_at_end_mac >-^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_at_end_no_dollar_mac >-^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_at_end_user >-^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_at_mac >-^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_at_start_mac >-^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_at_start_user >-^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_at_user >-^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_double_at_mac >-^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_double_at_user > ^samba.tests.krb5.salt_tests.samba.tests.krb5.salt_tests.SaltTests.test_salt_upn_at_realm_user >diff --git a/source3/passdb/machine_account_secrets.c b/source3/passdb/machine_account_secrets.c >index d81f79c705b..1964eb5a448 100644 >--- a/source3/passdb/machine_account_secrets.c >+++ b/source3/passdb/machine_account_secrets.c >@@ -1574,11 +1574,11 @@ NTSTATUS secrets_store_JoinCtx(const struct libnet_JoinCtx *r) > if (info->salt_principal == NULL && r->out.domain_is_ad) { > char *p = NULL; > >- ret = smb_krb5_salt_principal(info->domain_info.dns_domain.string, >- info->account_name, >- NULL /* userPrincipalName */, >- UF_WORKSTATION_TRUST_ACCOUNT, >- info, &p); >+ ret = smb_krb5_salt_principal_str(info->domain_info.dns_domain.string, >+ info->account_name, >+ NULL /* userPrincipalName */, >+ UF_WORKSTATION_TRUST_ACCOUNT, >+ info, &p); > if (ret != 0) { > status = krb5_to_nt_status(ret); > DBG_ERR("smb_krb5_salt_principal() failed " >diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c >index 5bdd23c13e9..9f38a31c8dd 100644 >--- a/source4/dsdb/samdb/ldb_modules/password_hash.c >+++ b/source4/dsdb/samdb/ldb_modules/password_hash.c >@@ -688,8 +688,8 @@ static int setup_kerberos_keys(struct setup_password_fields_io *io) > { > struct ldb_context *ldb; > krb5_error_code krb5_ret; >- char *salt_principal = NULL; >- char *salt_data = NULL; >+ krb5_principal salt_principal = NULL; >+ krb5_data salt_data; > krb5_data salt; > krb5_keyblock key; > krb5_data cleartext_data; >@@ -700,11 +700,11 @@ static int setup_kerberos_keys(struct setup_password_fields_io *io) > cleartext_data.length = io->n.cleartext_utf8->length; > > uac_flags = io->u.userAccountControl & UF_ACCOUNT_TYPE_MASK; >- krb5_ret = smb_krb5_salt_principal(io->ac->status->domain_data.realm, >+ krb5_ret = smb_krb5_salt_principal(io->smb_krb5_context->krb5_context, >+ io->ac->status->domain_data.realm, > io->u.sAMAccountName, > io->u.user_principal_name, > uac_flags, >- io->ac, > &salt_principal); > if (krb5_ret) { > ldb_asprintf_errstring(ldb, >@@ -718,8 +718,10 @@ static int setup_kerberos_keys(struct setup_password_fields_io *io) > /* > * create salt from salt_principal > */ >- krb5_ret = smb_krb5_salt_principal2data(io->smb_krb5_context->krb5_context, >- salt_principal, io->ac, &salt_data); >+ krb5_ret = smb_krb5_get_pw_salt(io->smb_krb5_context->krb5_context, >+ salt_principal, &salt_data); >+ >+ krb5_free_principal(io->smb_krb5_context->krb5_context, salt_principal); > if (krb5_ret) { > ldb_asprintf_errstring(ldb, > "setup_kerberos_keys: " >@@ -728,12 +730,17 @@ static int setup_kerberos_keys(struct setup_password_fields_io *io) > krb5_ret, io->ac)); > return LDB_ERR_OPERATIONS_ERROR; > } >- io->g.salt = salt_data; > > /* now use the talloced copy of the salt */ >- salt.data = discard_const(io->g.salt); >+ salt.data = talloc_strndup(io->ac, >+ (char *)salt_data.data, >+ salt_data.length); >+ io->g.salt = salt.data; > salt.length = strlen(io->g.salt); > >+ smb_krb5_free_data_contents(io->smb_krb5_context->krb5_context, >+ &salt_data); >+ > /* > * create ENCTYPE_AES256_CTS_HMAC_SHA1_96 key out of > * the salt and the cleartext password >-- >2.25.1 > > >From 3138758c0a55d97b56586fc0b6240d916483f61e Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Fri, 22 Oct 2021 10:50:36 +1300 >Subject: [PATCH 159/159] lib/krb5_wrap: Fix missing error check in new salt > code > >CID 1492905: Control flow issues (DEADCODE) > >This was a regression in 5eeb441b771a1ffe1ba1c69b72e8795f525a58ed. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14874 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> > >Autobuild-User(master): Andrew Bartlett <abartlet@samba.org> >Autobuild-Date(master): Sat Oct 23 08:07:13 UTC 2021 on sn-devel-184 > >(cherry picked from commit 5094d986b7686f057195dcb10764295b88967019) >--- > lib/krb5_wrap/krb5_samba.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > >diff --git a/lib/krb5_wrap/krb5_samba.c b/lib/krb5_wrap/krb5_samba.c >index 63a6e951f80..fff5b4e2a22 100644 >--- a/lib/krb5_wrap/krb5_samba.c >+++ b/lib/krb5_wrap/krb5_samba.c >@@ -594,9 +594,9 @@ int smb_krb5_salt_principal(krb5_context krb5_ctx, > * No matter what realm (including none) in the UPN, > * the realm is replaced with our upper-case realm > */ >- smb_krb5_principal_set_realm(krb5_ctx, >- *salt_princ, >- upper_realm); >+ krb5_ret = smb_krb5_principal_set_realm(krb5_ctx, >+ *salt_princ, >+ upper_realm); > if (krb5_ret != 0) { > krb5_free_principal(krb5_ctx, *salt_princ); > TALLOC_FREE(frame); >-- >2.25.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Flags:
abartlet
:
ci-passed+
Actions:
View
Attachments on
bug 14881
:
16864
|
16865
|
16868
|
16869
|
16870
|
16871
|
16873
|
16874
|
16875
|
16876
|
16877
|
16879
|
16881
|
16882
|
16883