The branch, master has been updated via dadd3223882 tests/krb5: Add claims tests via 8b8a268084b tests/krb5: Allow specifying sname for getting service ticket via 6170d46cdd7 tests/krb5: Check claims buffers via fa90633b810 tests/krb5: Add xpress (de)compression functions via 20082340433 tests/krb5: Add function for creating claims via 88c9e2af205 krb5pac.idl: Add definitions for claims PAC buffers via e53455497c9 claims.idl: Add claim type definitions from 761ce8cfe41 s4:kdc: Set kerberos debug class for kdc service
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit dadd32238822c6f2ee10cd55442c88e2034fb11a Author: Joseph Sutton <josephsut...@catalyst.net.nz> Date: Fri Mar 4 16:23:32 2022 +1300 tests/krb5: Add claims tests Based on tests originally written by Stefan Metzmacher <me...@samba.org> Signed-off-by: Joseph Sutton <josephsut...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> Autobuild-User(master): Andrew Bartlett <abart...@samba.org> Autobuild-Date(master): Fri Sep 9 01:11:05 UTC 2022 on sn-devel-184 commit 8b8a268084b494e61a8e41e0ee11916474cc3bbd Author: Joseph Sutton <josephsut...@catalyst.net.nz> Date: Mon Mar 7 17:07:03 2022 +1300 tests/krb5: Allow specifying sname for getting service ticket Signed-off-by: Joseph Sutton <josephsut...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 6170d46cdd77da1ed2ae6f19b893fad74cd21196 Author: Joseph Sutton <josephsut...@catalyst.net.nz> Date: Fri Mar 4 16:22:07 2022 +1300 tests/krb5: Check claims buffers Signed-off-by: Joseph Sutton <josephsut...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit fa90633b8109696c923e4559a17b82761f4dc486 Author: Joseph Sutton <josephsut...@catalyst.net.nz> Date: Fri Mar 4 16:21:19 2022 +1300 tests/krb5: Add xpress (de)compression functions Signed-off-by: Joseph Sutton <josephsut...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 200823404335cb781b18e5be25934a2625018dd1 Author: Joseph Sutton <josephsut...@catalyst.net.nz> Date: Fri Mar 4 16:20:18 2022 +1300 tests/krb5: Add function for creating claims Signed-off-by: Joseph Sutton <josephsut...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 88c9e2af205cc8327d4977b9ca0ea626b6a3c1e1 Author: Joseph Sutton <josephsut...@catalyst.net.nz> Date: Fri Mar 4 16:17:40 2022 +1300 krb5pac.idl: Add definitions for claims PAC buffers The PAC device info definition comes from [MS-PAC] 2.12. Signed-off-by: Joseph Sutton <josephsut...@catalyst.net.nz> Signed-off-by: Andrew Bartlett <abart...@samba.org> Reviewed-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> commit e53455497c90be9665905fa878efb40872efa09b Author: Joseph Sutton <josephsut...@catalyst.net.nz> Date: Fri Sep 9 11:02:01 2022 +1200 claims.idl: Add claim type definitions Signed-off-by: Joseph Sutton <josephsut...@catalyst.net.nz> Signed-off-by: Andrew Bartlett <abart...@samba.org> Reviewed-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> ----------------------------------------------------------------------- Summary of changes: librpc/idl/IDL_LICENSE.txt | 76 ++ librpc/idl/claims.idl | 118 +++ librpc/idl/krb5pac.idl | 23 + librpc/idl/wscript_build | 1 + librpc/wscript_build | 8 +- python/samba/tests/krb5/claims_tests.py | 1319 ++++++++++++++++++++++++++++++ python/samba/tests/krb5/kdc_base_test.py | 196 ++++- python/samba/tests/krb5/kdc_tgs_tests.py | 6 +- python/samba/tests/krb5/raw_testcase.py | 329 +++++++- python/samba/tests/krb5/s4u_tests.py | 4 +- python/samba/tests/krb5/xpress.py | 128 +++ python/samba/tests/usage.py | 1 + selftest/knownfail_heimdal_kdc | 88 ++ selftest/knownfail_mit_kdc | 89 ++ selftest/knownfail_mit_kdc_1_20 | 4 + source4/librpc/wscript_build | 7 + source4/selftest/tests.py | 4 + 17 files changed, 2363 insertions(+), 38 deletions(-) create mode 100644 librpc/idl/claims.idl create mode 100755 python/samba/tests/krb5/claims_tests.py create mode 100644 python/samba/tests/krb5/xpress.py Changeset truncated at 500 lines: diff --git a/librpc/idl/IDL_LICENSE.txt b/librpc/idl/IDL_LICENSE.txt index 01ae670b69b..a2d87ecb044 100644 --- a/librpc/idl/IDL_LICENSE.txt +++ b/librpc/idl/IDL_LICENSE.txt @@ -7,3 +7,79 @@ under the following license: This work 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. + + +The following relates to IDL obtained from Open Specifications Documentation + + Intellectual Property Rights Notice for Open Specifications Documentation + + * Technical Documentation. Microsoft publishes Open Specifications + documentation (“this documentation”) for protocols, file formats, + data portability, computer languages, and standards + support. Additionally, overview documents cover inter-protocol + relationships and interactions. + + * Copyrights. This documentation is covered by Microsoft + copyrights. Regardless of any other terms that are contained in + the terms of use for the Microsoft website that hosts this + documentation, you can make copies of it in order to develop + implementations of the technologies that are described in this + documentation and can distribute portions of it in your + implementations that use these technologies or in your + documentation as necessary to properly document the + implementation. You can also distribute in your implementation, + with or without modification, any schemas, IDLs, or code samples + that are included in the documentation. This permission also + applies to any documents that are referenced in the Open + Specifications documentation. + + * No Trade Secrets. Microsoft does not claim any trade secret rights + in this documentation. + + * Patents. Microsoft has patents that might cover your + implementations of the technologies described in the Open + Specifications documentation. Neither this notice nor Microsoft's + delivery of this documentation grants any licenses under those + patents or any other Microsoft patents. However, a given Open + Specifications document might be covered by the Microsoft Open + Specifications Promise or the Microsoft Community Promise. If you + would prefer a written license, or if the technologies described + in this documentation are not covered by the Open Specifications + Promise or Community Promise, as applicable, patent licenses are + available by contacting i...@microsoft.com. + + * License Programs. To see all of the protocols in scope under a + specific license program and the associated patents, visit the + Patent Map. + + * Trademarks. The names of companies and products contained in this + documentation might be covered by trademarks or similar + intellectual property rights. This notice does not grant any + licenses under those rights. For a list of Microsoft trademarks, + visit www.microsoft.com/trademarks. + + * Fictitious Names. The example companies, organizations, products, + domain names, email addresses, logos, people, places, and events + that are depicted in this documentation are fictitious. No + association with any real company, organization, product, domain + name, email address, logo, person, place, or event is intended or + should be inferred. + + Reservation of Rights. All other rights are reserved, and this notice + does not grant any rights other than as specifically described above, + whether by implication, estoppel, or otherwise. + + Tools. The Open Specifications documentation does not require the use + of Microsoft programming tools or programming environments in order + for you to develop an implementation. If you have access to Microsoft + programming tools and environments, you are free to take advantage of + them. Certain Open Specifications documents are intended for use in + conjunction with publicly available standards specifications and + network programming art and, as such, assume that the reader either + is familiar with the aforementioned material or has immediate access + to it. + + Support. For questions and support, please contact doch...@microsoft.com + + + The above is the IPR notice from MS-KILE diff --git a/librpc/idl/claims.idl b/librpc/idl/claims.idl new file mode 100644 index 00000000000..ed84cd772c1 --- /dev/null +++ b/librpc/idl/claims.idl @@ -0,0 +1,118 @@ +/* + claims + + claim: An assertion about a security principal + + From MS-ADTS: + + For ease of implementation, the full IDL for the data types used for + claims is provided + + The below was intially obtained from MS-ADTS which is + Copyright © 2022 Microsoft Corporation as permitted + by the Open Specifications terms reproduced in IDL_LICENCE.txt +*/ + +#include "idl_types.h" + +[ + uuid("bba9cb76-eb0c-462c-aa1b-5d8c34415701"), + version(1.0), + pointer_default(unique), + helpstring("Active Directory Claims") +] +interface claims +{ +#define wchar_t uint16 +#define CLAIM_ID [string, charset(UTF16)] wchar_t * + + typedef enum { + CLAIM_TYPE_INT64 = 1, + CLAIM_TYPE_UINT64 = 2, + CLAIM_TYPE_STRING = 3, + CLAIM_TYPE_BOOLEAN = 6 + } CLAIM_TYPE; + + typedef enum { + CLAIMS_SOURCE_TYPE_AD = 1, + CLAIMS_SOURCE_TYPE_CERTIFICATE = 2 + } CLAIMS_SOURCE_TYPE; + + typedef enum { + CLAIMS_COMPRESSION_FORMAT_NONE = 0, + CLAIMS_COMPRESSION_FORMAT_LZNT1 = 2, + CLAIMS_COMPRESSION_FORMAT_XPRESS = 3, + CLAIMS_COMPRESSION_FORMAT_XPRESS_HUFF = 4 + } CLAIMS_COMPRESSION_FORMAT; + + typedef struct { + [range(1, 10*1024*1024)] uint32 value_count; + [size_is(value_count)] dlong *values; + } CLAIM_INT64; + + typedef struct { + [range(1, 10*1024*1024)] uint32 value_count; + [size_is(value_count)] hyper *values; + } CLAIM_UINT64; + + typedef struct { + [range(1, 10*1024*1024)] uint32 value_count; + [size_is(value_count), string, charset(UTF16)] wchar_t **values; + } CLAIM_STRING; + + typedef [switch_type(CLAIM_TYPE),nodiscriminant,flag(NDR_ALIGN8)] union { + [case(CLAIM_TYPE_INT64)] CLAIM_INT64 claim_int64; + [case(CLAIM_TYPE_UINT64)] CLAIM_UINT64 claim_uint64; + [case(CLAIM_TYPE_STRING)] CLAIM_STRING claim_string; + [case(CLAIM_TYPE_BOOLEAN)] CLAIM_UINT64 claim_boolean; + [default]; + } CLAIM_ENTRY_VALUES; + + typedef struct { + CLAIM_ID id; + CLAIM_TYPE type; + [switch_is(type)] CLAIM_ENTRY_VALUES values; + } CLAIM_ENTRY; + + typedef struct { + CLAIMS_SOURCE_TYPE claims_source_type; + uint32 claims_count; + [size_is(claims_count)] CLAIM_ENTRY *claim_entries; + } CLAIMS_ARRAY; + + typedef struct { + CLAIMS_SET_METADATA *metadata; + } CLAIMS_SET_METADATA_CTR; + + typedef struct { + CLAIMS_SET *claims; + } CLAIMS_SET_CTR; + + /* Public structures. */ + + typedef [public] struct { + uint32 claims_array_count; + [size_is(claims_array_count)] CLAIMS_ARRAY *claims_arrays; + uint16 reserved_type; + uint32 reserved_field_size; + [size_is(reserved_field_size)] uint8 *reserved_field; + } CLAIMS_SET; + + typedef [public] struct { + [subcontext(0xFFFFFC01)] CLAIMS_SET_CTR claims; + } CLAIMS_SET_NDR; + + typedef [public] struct { + [subcontext(0xFFFFFC01)] CLAIMS_SET_METADATA_CTR claims; + } CLAIMS_SET_METADATA_NDR; + + typedef [public] struct { + uint32 claims_set_size; + [size_is(claims_set_size)] uint8 *claims_set; + CLAIMS_COMPRESSION_FORMAT compression_format; + uint32 uncompressed_claims_set_size; + uint16 reserved_type; + uint32 reserved_field_size; + [size_is(reserved_field_size)] uint8 *reserved_field; + } CLAIMS_SET_METADATA; +} diff --git a/librpc/idl/krb5pac.idl b/librpc/idl/krb5pac.idl index bbe4a253e3a..d2f8414d69e 100644 --- a/librpc/idl/krb5pac.idl +++ b/librpc/idl/krb5pac.idl @@ -1,5 +1,10 @@ /* krb5 PAC + + Portions obtained from MS-KILE which is Copyright © 2021 Microsoft + Corporation as permitted by the Open Specifications terms + reproduced in IDL_LICENCE.txt + */ #include "idl_types.h" @@ -133,6 +138,21 @@ interface krb5pac PAC_CONSTRAINED_DELEGATION *info; } PAC_CONSTRAINED_DELEGATION_CTR; + typedef struct { + uint32 rid; + uint32 primary_gid; + dom_sid2 *domain_sid; + samr_RidWithAttributeArray groups; + uint32 sid_count; + [size_is(sid_count)] netr_SidAttr *sids; + uint32 domain_group_count; + [size_is(domain_group_count)] PAC_DOMAIN_GROUP_MEMBERSHIP *domain_groups; + } PAC_DEVICE_INFO; + + typedef struct { + PAC_DEVICE_INFO *info; + } PAC_DEVICE_INFO_CTR; + typedef [public,v1_enum] enum { PAC_TYPE_LOGON_INFO = 1, PAC_TYPE_CREDENTIAL_INFO = 2, @@ -165,6 +185,9 @@ interface krb5pac [case(PAC_TYPE_TICKET_CHECKSUM)] PAC_SIGNATURE_DATA ticket_checksum; [case(PAC_TYPE_ATTRIBUTES_INFO)] PAC_ATTRIBUTES_INFO attributes_info; [case(PAC_TYPE_REQUESTER_SID)] PAC_REQUESTER_SID requester_sid; + [case(PAC_TYPE_CLIENT_CLAIMS_INFO)][subcontext(0)] DATA_BLOB_REM client_claims_info; + [case(PAC_TYPE_DEVICE_INFO)][subcontext(0xFFFFFC01)] PAC_DEVICE_INFO_CTR device_info; + [case(PAC_TYPE_DEVICE_CLAIMS_INFO)][subcontext(0)] DATA_BLOB_REM device_claims_info; /* 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 diff --git a/librpc/idl/wscript_build b/librpc/idl/wscript_build index 1e53eec7dc0..e05e4795921 100644 --- a/librpc/idl/wscript_build +++ b/librpc/idl/wscript_build @@ -141,6 +141,7 @@ bld.SAMBA_PIDL_LIST('PIDL', bld.SAMBA_PIDL_LIST('PIDL', ''' auth.idl + claims.idl dcerpc.idl dfsblobs.idl dns.idl diff --git a/librpc/wscript_build b/librpc/wscript_build index cf9085c0884..698ccddd093 100644 --- a/librpc/wscript_build +++ b/librpc/wscript_build @@ -372,7 +372,7 @@ bld.SAMBA_SUBSYSTEM('NDR_KRB5PAC', bld.SAMBA_LIBRARY('ndr-krb5pac', source='ndr/ndr_krb5pac.c gen_ndr/ndr_krb5pac.c', - public_deps='ndr ndr-standard NDR_SECURITY', + public_deps='ndr ndr-standard NDR_SECURITY NDR_CLAIMS', public_headers='gen_ndr/krb5pac.h gen_ndr/ndr_krb5pac.h ndr/ndr_krb5pac.h', header_path=[ ('gen_ndr*', 'gen_ndr'), ('ndr*', 'ndr')], pc_files='ndr_krb5pac.pc', @@ -384,6 +384,10 @@ bld.SAMBA_SUBSYSTEM('NDR_KRB5CCACHE', deps='ndr NDR_COMPRESSION NDR_SECURITY ndr-standard asn1util' ) +bld.SAMBA_SUBSYSTEM('NDR_CLAIMS', + source='gen_ndr/ndr_claims.c', + deps='ndr') + bld.SAMBA_LIBRARY('ndr-standard', source='', vnum='0.0.1', @@ -394,7 +398,7 @@ bld.SAMBA_LIBRARY('ndr-standard', NDR_ECHO security NDR_DNS NDR_DNSP NDR_ATSVC NDR_SPOOLSS NDR_DSSETUP NDR_SERVER_ID NDR_NOTIFY''', public_deps='ndr', - public_headers='gen_ndr/samr.h gen_ndr/ndr_samr.h gen_ndr/lsa.h gen_ndr/netlogon.h gen_ndr/atsvc.h gen_ndr/ndr_atsvc.h gen_ndr/ndr_svcctl.h gen_ndr/svcctl.h', + public_headers='gen_ndr/samr.h gen_ndr/ndr_samr.h gen_ndr/lsa.h gen_ndr/netlogon.h gen_ndr/atsvc.h gen_ndr/ndr_atsvc.h gen_ndr/ndr_svcctl.h gen_ndr/svcctl.h gen_ndr/claims.h', header_path='gen_ndr' ) diff --git a/python/samba/tests/krb5/claims_tests.py b/python/samba/tests/krb5/claims_tests.py new file mode 100755 index 00000000000..717f773327c --- /dev/null +++ b/python/samba/tests/krb5/claims_tests.py @@ -0,0 +1,1319 @@ +#!/usr/bin/env python3 +# Unix SMB/CIFS implementation. +# Copyright (C) Stefan Metzmacher 2020 +# Copyright (C) Catalyst.Net Ltd 2022 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + +import os +import re +import sys + +import ldb + +from samba.dcerpc import claims, krb5pac, security + +from samba.tests import DynamicTestCase, env_get_var_value +from samba.tests.krb5 import kcrypto +from samba.tests.krb5.kcrypto import Enctype +from samba.tests.krb5.kdc_base_test import KDCBaseTest +from samba.tests.krb5.raw_testcase import Krb5EncryptionKey +from samba.tests.krb5.rfc4120_constants import ( + AES256_CTS_HMAC_SHA1_96, + ARCFOUR_HMAC_MD5, + KRB_TGS_REP, + NT_PRINCIPAL, + NT_SRV_INST, +) +import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 + +sys.path.insert(0, 'bin/python') +os.environ['PYTHONUNBUFFERED'] = '1' + +global_asn1_print = False +global_hexdump = False + + +class UnorderedList(list): + def __eq__(self, other): + if isinstance(other, UnorderedList): + return sorted(self) == sorted(other) + else: + return False + + +@DynamicTestCase +class ClaimsTests(KDCBaseTest): + @classmethod + def setUpClass(cls): + super().setUpClass() + + cls._search_iterator = None + + def setUp(self): + super().setUp() + self.do_asn1_print = global_asn1_print + self.do_hexdump = global_hexdump + + def get_sample_dn(self): + if self._search_iterator is None: + samdb = self.get_samdb() + type(self)._search_iterator = samdb.search_iterator() + + return str(next(self._search_iterator).dn) + + def get_binary_dn(self): + return 'B:8:01010101:' + self.get_sample_dn() + + def remove_client_claims(self, ticket): + def modify_pac_fn(pac): + pac_buffers = pac.buffers + for pac_buffer in pac_buffers: + if pac_buffer.type == krb5pac.PAC_TYPE_CLIENT_CLAIMS_INFO: + pac.num_buffers -= 1 + pac_buffers.remove(pac_buffer) + + break + else: + self.fail('expected client claims in PAC') + + pac.buffers = pac_buffers + + return pac + + return self.modified_ticket( + ticket, + modify_pac_fn=modify_pac_fn, + checksum_keys=self.get_krbtgt_checksum_key()) + + def test_delegation_claims(self): + self.run_delegation_test(remove_claims=False) + + def test_delegation_claims_remove_claims(self): + self.run_delegation_test(remove_claims=True) + + def run_delegation_test(self, remove_claims): + service_creds = self.get_service_creds() + service_spn = service_creds.get_spn() + + user_name = self.get_new_username() + mach_name = self.get_new_username() + + samdb = self.get_samdb() + user_creds, user_dn = self.create_account( + samdb, + user_name, + self.AccountType.USER, + additional_details={ + 'middleName': 'user_old', + }) + mach_creds, mach_dn = self.create_account( + samdb, + mach_name, + self.AccountType.COMPUTER, + spn=f'host/{mach_name}', + additional_details={ + 'middleName': 'mach_old', + 'msDS-AllowedToDelegateTo': service_spn, + }) + + claim_id = self.get_new_username() + self.create_claim(claim_id, + enabled=True, + attribute='middleName', + single_valued=True, + source_type='AD', + for_classes=['user', 'computer'], + value_type=claims.CLAIM_TYPE_STRING) + + options = 'forwardable' + expected_flags = krb5_asn1.TicketFlags(options) + + expected_claims_user = { + claim_id: { + 'source_type': claims.CLAIMS_SOURCE_TYPE_AD, + 'type': claims.CLAIM_TYPE_STRING, + 'values': ['user_old'], + }, + } + expected_claims_mac = { + claim_id: { + 'source_type': claims.CLAIMS_SOURCE_TYPE_AD, + 'type': claims.CLAIM_TYPE_STRING, + 'values': ['mach_old'], + }, + } + + user_tgt = self.get_tgt(user_creds, + kdc_options=options, + expect_pac=True, + expected_flags=expected_flags, + expect_client_claims=True, + expected_client_claims=expected_claims_user) + user_ticket = self.get_service_ticket( + user_tgt, + mach_creds, + kdc_options=options, + expect_pac=True, + expected_flags=expected_flags, + expect_client_claims=True, + expected_client_claims=expected_claims_user) + + mach_tgt = self.get_tgt(mach_creds, + expect_pac=True, + expect_client_claims=True, + expected_client_claims=expected_claims_mac) + + if remove_claims: + user_ticket = self.remove_client_claims(user_ticket) + mach_tgt = self.remove_client_claims(mach_tgt) + + # Change the value of the attributes used for the claim. + msg = ldb.Message(ldb.Dn(samdb, user_dn)) + msg['middleName'] = ldb.MessageElement('user_new', + ldb.FLAG_MOD_REPLACE, + 'middleName') + samdb.modify(msg) + + # Change the value of the attributes used for the claim. + msg = ldb.Message(ldb.Dn(samdb, mach_dn)) + msg['middleName'] = ldb.MessageElement('mach_new', + ldb.FLAG_MOD_REPLACE, + 'middleName') -- Samba Shared Repository