The branch, master has been updated via 9ad03f51a34 s4:kdc: Add asserted identity SID to identify whether S4U2Self has occurred via 9b03e31fba7 s4:dsdb:tests: Also pass tests if asserted identity is present via a14acd0c07d s4:selftest: Do not print the env twice via e6a2c3c38f2 s4:torture: let remote_pac test for asserted identity sids via 5902e87ed32 python:tests: Add krb5 tests for asserted identity via d6b6702e843 python:tests: Reorder variables via e03665fb8cd python:tests: Add support for unexpected groups in krb5 tests via 61b22319155 python:tests: Add support for expected groups in krb5 tests via fc8a29435ef python:tests: Allow to print krb5 encryption keys as string via 4b684c325b0 python:tests: Add support to print krb5 keys as string via 887f0cf243a s4:kdc: Fix S4U2Proxy in RODC case to return an error via 461dc44e740 s4:kdc: pass down SAMBA_KDC_FLAG_PROTOCOL_TRANSITION to samba_kdc_update_pac() via 2a79a5eef8f s4:mit-samba: Pass flags to mit_samba_get_pac() via c29d5fcbea3 s4:mit-samba: Pass flags to ks_get_pac() via a5c8077a858 python:tests: Check code error code in test_s4u2self_rodc_revealed via f8c3b68fe53 python:tests: Fix standalone run of kdc_tgs_tests via dbbb5ca169e s4:kdc: Set debug class for pac-glue via 21d1a9509a6 librpc:idl: Add comments to assert identity string in security.idl via 685006c8309 selftest: Use selftest's TMPDIR to store the krb5 ccache in pam_winbind_setcred test via db7e296f9ca selftest: Use selftest's TMPDIR to store the krb5 ccache in pam_winbind tests via a6d6ae3cfcd s3:winbind: Remove no longer used domain's private_data pointer via 3cb256439e9 s3:winbind: Do not use domain's private data to store the ADS_STRUCT via 91395e660a2 s3:winbind: Simplify open_cached_internal_pipe_conn() via e1f29b0970f s3:winbind: Do not use domain's private data to store the SAMR pipes from 7880537674c s3:winbind: Fix uninitialized validation_level variable
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 9ad03f51a34359c9b0d513dd8c3c17b635469c8f Author: Andreas Schneider <a...@samba.org> Date: Mon Oct 11 14:47:25 2021 +0200 s4:kdc: Add asserted identity SID to identify whether S4U2Self has occurred Because the KDC does not limit protocol transition (S4U2Self), two new well-known SIDs are available to give this control to the resource administrator. These SIDs identify whether protocol transition (S4U2Self) has occurred, and can be used with standard access control lists to grant or limit access as needed. See https://docs.microsoft.com/en-us/windows-server/security/kerberos/kerberos-constrained-delegation-overview Pair-Programmed-With: Stefan Metzmacher <me...@samba.org> Signed-off-by: Andreas Schneider <a...@samba.org> Signed-off-by: Stefan Metzmacher <me...@samba.org> Autobuild-User(master): Andreas Schneider <a...@cryptomilk.org> Autobuild-Date(master): Wed Apr 13 13:54:27 UTC 2022 on sn-devel-184 commit 9b03e31fba7aa726f3c481f18f9e9e5b4c96c381 Author: Andreas Schneider <a...@samba.org> Date: Mon Jan 24 13:04:23 2022 +0100 s4:dsdb:tests: Also pass tests if asserted identity is present We should make sure that we use NTLMSSP or Kerberos consistently for the tests and don't mix them. We're also much stricter and symmetric_difference() to check if the sets are actually the same. Pair-Programmed-With: Stefan Metzmacher <me...@samba.org> Signed-off-by: Andreas Schneider <a...@samba.org> Signed-off-by: Stefan Metzmacher <me...@samba.org> commit a14acd0c07d3e496b2a60503941683b0f501581f Author: Andreas Schneider <a...@samba.org> Date: Tue Feb 22 11:39:21 2022 +0100 s4:selftest: Do not print the env twice This makes it easier to write knownfail rules Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit e6a2c3c38f2aef3a79da2fc154d1f19ec5efb2b0 Author: Andreas Schneider <a...@samba.org> Date: Mon Jan 24 13:03:36 2022 +0100 s4:torture: let remote_pac test for asserted identity sids Pair-Programmed-With: Stefan Metzmacher <me...@samba.org> Signed-off-by: Andreas Schneider <a...@samba.org> Signed-off-by: Stefan Metzmacher <me...@samba.org> commit 5902e87ed3270d30a308d6914fdb3d04965a07d7 Author: Andreas Schneider <a...@samba.org> Date: Mon Nov 29 16:17:23 2021 +0100 python:tests: Add krb5 tests for asserted identity Pair-Programmed-With: Stefan Metzmacher <me...@samba.org> Signed-off-by: Stefan Metzmacher <me...@samba.org> Signed-off-by: Andreas Schneider <a...@samba.org> commit d6b6702e84360e2388a37ae92b569f21c59354f2 Author: Stefan Metzmacher <me...@samba.org> Date: Mon Feb 14 15:15:24 2022 +0100 python:tests: Reorder variables Those will be needed earlier in the next commit. Pair-Programmed-With: Andreas Schneider <a...@samba.org> Signed-off-by: Andreas Schneider <a...@samba.org> Signed-off-by: Stefan Metzmacher <me...@samba.org> commit e03665fb8cd3edac37c7346d160ddfdad2f6074f Author: Andreas Schneider <a...@samba.org> Date: Fri Jan 21 10:19:20 2022 +0100 python:tests: Add support for unexpected groups in krb5 tests Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 61b223191550b327e8229a1eb6ff0bccf70206b8 Author: Andreas Schneider <a...@samba.org> Date: Fri Jan 21 11:20:22 2022 +0100 python:tests: Add support for expected groups in krb5 tests Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit fc8a29435ef72d32839943dad884b5a562d97d8e Author: Stefan Metzmacher <me...@samba.org> Date: Fri Feb 11 15:47:22 2022 +0100 python:tests: Allow to print krb5 encryption keys as string Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 4b684c325b02f9d0d23e5e77177383b646cb1d78 Author: Stefan Metzmacher <me...@samba.org> Date: Fri Feb 11 15:46:53 2022 +0100 python:tests: Add support to print krb5 keys as string Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 887f0cf243a3d4bc3e87654794c3bc8ec6857aac Author: Andreas Schneider <a...@samba.org> Date: Wed Mar 23 16:34:25 2022 +0100 s4:kdc: Fix S4U2Proxy in RODC case to return an error Tested also against Windows Server 2022. Details: https://lists.samba.org/archive/cifs-protocol/2022-April/003673.html Pair-Programmed-With: Stefan Metzmacher <me...@samba.org> Signed-off-by: Andreas Schneider <a...@samba.org> Signed-off-by: Stefan Metzmacher <me...@samba.org> commit 461dc44e740aacad41bb0df0552560d1eb3c6ea8 Author: Andreas Schneider <a...@samba.org> Date: Mon Oct 11 14:47:25 2021 +0200 s4:kdc: pass down SAMBA_KDC_FLAG_PROTOCOL_TRANSITION to samba_kdc_update_pac() This gives samba_kdc_update_pac() a chance to detect S4U2Self. Pair-Programmed-With: Stefan Metzmacher <me...@samba.org> Signed-off-by: Andreas Schneider <a...@samba.org> Signed-off-by: Stefan Metzmacher <me...@samba.org> commit 2a79a5eef8ff103f9a5c42f1d14a7d4a84df93d7 Author: Andreas Schneider <a...@samba.org> Date: Mon Oct 11 13:33:33 2021 +0200 s4:mit-samba: Pass flags to mit_samba_get_pac() Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit c29d5fcbea335d0382a3d42da36e7aeed817a71b Author: Andreas Schneider <a...@samba.org> Date: Mon Oct 11 13:31:49 2021 +0200 s4:mit-samba: Pass flags to ks_get_pac() Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit a5c8077a858275a5545bb9dffa72fe5817d915da Author: Andreas Schneider <a...@samba.org> Date: Wed Mar 23 17:01:24 2022 +0100 python:tests: Check code error code in test_s4u2self_rodc_revealed Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit f8c3b68fe5380c1bac3962dfb1e8313d248b396d Author: Stefan Metzmacher <me...@samba.org> Date: Thu Mar 17 16:36:14 2022 +0100 python:tests: Fix standalone run of kdc_tgs_tests Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit dbbb5ca169ee412cfe1e26e5b98e2a07aeedbbc9 Author: Andreas Schneider <a...@samba.org> Date: Wed Mar 23 17:25:09 2022 +0100 s4:kdc: Set debug class for pac-glue Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 21d1a9509a65e9db5d651d73d4927ba9120adaac Author: Stefan Metzmacher <me...@samba.org> Date: Fri Feb 11 13:19:50 2022 +0100 librpc:idl: Add comments to assert identity string in security.idl Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 685006c8309ae0740d37cef5854acb995b7fdd3a Author: Samuel Cabrero <scabr...@samba.org> Date: Tue Apr 12 16:56:25 2022 +0200 selftest: Use selftest's TMPDIR to store the krb5 ccache in pam_winbind_setcred test Using /tmp directly can lead to errors if multiple autobuilds are running at the same time. Using tempfile.gettempdir() will look for $TMPDIR environment variable. Signed-off-by: Samuel Cabrero <scabr...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit db7e296f9caf52d82f33fbeb511d8889abd60a7a Author: Samuel Cabrero <scabr...@samba.org> Date: Wed Apr 13 13:20:27 2022 +0200 selftest: Use selftest's TMPDIR to store the krb5 ccache in pam_winbind tests Using /tmp directly can lead to errors if multiple autobuilds are running at the same time. Using tempfile.gettempdir() will look for $TMPDIR environment variable. Signed-off-by: Samuel Cabrero <scabr...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit a6d6ae3cfcd64a85f82ec5b12253ca0e237d95bb Author: Samuel Cabrero <scabr...@samba.org> Date: Wed Apr 13 11:34:18 2022 +0200 s3:winbind: Remove no longer used domain's private_data pointer BUG: https://bugzilla.samba.org/show_bug.cgi?id=15046 Signed-off-by: Samuel Cabrero <scabr...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 3cb256439e9ceece26c2de82293c43486543e0cb Author: Samuel Cabrero <scabr...@samba.org> Date: Wed Apr 13 11:31:45 2022 +0200 s3:winbind: Do not use domain's private data to store the ADS_STRUCT The ADS_STRUCT is not allocated using talloc and there are many places casting this pointer directly so use a typed pointer. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15046 Signed-off-by: Samuel Cabrero <scabr...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 91395e660a2b1b69bf74ca0b77aee416e2ac1db3 Author: Samuel Cabrero <scabr...@samba.org> Date: Wed Apr 13 11:15:35 2022 +0200 s3:winbind: Simplify open_cached_internal_pipe_conn() BUG: https://bugzilla.samba.org/show_bug.cgi?id=15046 Signed-off-by: Samuel Cabrero <scabr...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit e1f29b0970f4cac52a9cd517be6862cf69a1433a Author: Samuel Cabrero <scabr...@samba.org> Date: Wed Apr 13 11:01:00 2022 +0200 s3:winbind: Do not use domain's private data to store the SAMR pipes The domain's private_data pointer is also used to store a ADS_STRUCT, which is not allocated using talloc and there are many places casting this pointer directly. The recently added samba.tests.pam_winbind_setcred was randomly failing and after debugging it the problem was that kerberos authentication was failing because the time_offset passed to kerberos_return_pac() was wrong. This time_offset was retrieved from ads->auth.time_offset, where the ads pointer was directly casted from domain->private_data but private_data was pointing to a winbind_internal_pipes struct. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15046 Signed-off-by: Samuel Cabrero <scabr...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> ----------------------------------------------------------------------- Summary of changes: librpc/idl/security.idl | 11 +++ python/samba/tests/krb5/kcrypto.py | 5 +- python/samba/tests/krb5/kdc_tgs_tests.py | 9 +- python/samba/tests/krb5/raw_testcase.py | 45 +++++++++- python/samba/tests/krb5/s4u_tests.py | 148 ++++++++++++++++++++++++++----- selftest/tests.py | 6 +- source3/winbindd/winbindd.h | 10 ++- source3/winbindd/winbindd_ads.c | 10 +-- source3/winbindd/winbindd_ndr.c | 7 +- source3/winbindd/winbindd_pam.c | 6 +- source3/winbindd/winbindd_samr.c | 27 ++---- source4/dsdb/tests/python/token_group.py | 113 +++++++++++++++++++---- source4/kdc/mit-kdb/kdb_samba_policies.c | 5 ++ source4/kdc/mit_samba.c | 10 +++ source4/kdc/mit_samba.h | 1 + source4/kdc/pac-glue.c | 75 ++++++++++++++++ source4/kdc/pac-glue.h | 7 ++ source4/kdc/wdc-samba4.c | 63 ++++++++++++- source4/selftest/tests.py | 4 +- source4/torture/rpc/remote_pac.c | 62 ++++++++++++- 20 files changed, 538 insertions(+), 86 deletions(-) Changeset truncated at 500 lines: diff --git a/librpc/idl/security.idl b/librpc/idl/security.idl index 6b867595a28..b8604741164 100644 --- a/librpc/idl/security.idl +++ b/librpc/idl/security.idl @@ -298,7 +298,18 @@ interface security const string SID_NT_TRUSTED_INSTALLER = "S-1-5-80-956008885-3418522649-1831038044-1853292631-2271478464"; + /* + * This is added during the AS-REQ/AS-REP exchange after + * pre-authentication was successful. + */ const string SID_AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY = "S-1-18-1"; + /* + * This is added during S4U2Self PAC creation. + * + * It won't replace a possible + * SID_AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY + * during S4U2Proxy. + */ const string SID_SERVICE_ASSERTED_IDENTITY = "S-1-18-2"; const string SID_COMPOUNDED_AUTHENTICATION = "S-1-5-21-0-0-0-496"; diff --git a/python/samba/tests/krb5/kcrypto.py b/python/samba/tests/krb5/kcrypto.py index 4bf38d3c36b..79df0b58a3e 100755 --- a/python/samba/tests/krb5/kcrypto.py +++ b/python/samba/tests/krb5/kcrypto.py @@ -51,7 +51,7 @@ os.environ["PYTHONUNBUFFERED"] = "1" from math import gcd from functools import reduce from struct import pack, unpack -from binascii import crc32 +from binascii import crc32, b2a_hex from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives import hmac from cryptography.hazmat.primitives.ciphers import algorithms as ciphers @@ -616,6 +616,9 @@ class Key(object): self.enctype = enctype self.contents = contents + def __str__(self): + return "enctype=%d contents=%s" % (self.enctype, + b2a_hex(self.contents).decode('ascii')) def seedsize(enctype): e = _get_enctype_profile(enctype) diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py index 21044f6d094..1f16d05e2db 100755 --- a/python/samba/tests/krb5/kdc_tgs_tests.py +++ b/python/samba/tests/krb5/kdc_tgs_tests.py @@ -20,15 +20,15 @@ import sys import os -import ldb +sys.path.insert(0, "bin/python") +os.environ["PYTHONUNBUFFERED"] = "1" +import ldb from samba import dsdb from samba.dcerpc import krb5pac, security -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 @@ -1039,7 +1039,8 @@ class KdcTgsTests(KDCBaseTest): creds = self._get_creds(replication_allowed=True, revealed_to_rodc=True) tgt = self._get_tgt(creds, from_rodc=True) - self._s4u2self(tgt, creds, expected_error=0) + self._s4u2self(tgt, creds, + expected_error=KDC_ERR_C_PRINCIPAL_UNKNOWN) def test_user2user_rodc_revealed(self): creds = self._get_creds(replication_allowed=True, diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py index 74d111d386b..7f9d9d17640 100644 --- a/python/samba/tests/krb5/raw_testcase.py +++ b/python/samba/tests/krb5/raw_testcase.py @@ -231,6 +231,10 @@ class Krb5EncryptionKey: self.ctype = EncTypeChecksum[self.etype] self.kvno = kvno + def __str__(self): + return "etype=%d ctype=%d kvno=%d key=%s" % ( + self.etype, self.ctype, self.kvno, self.key) + def encrypt(self, usage, plaintext): ciphertext = kcrypto.encrypt(self.key, usage, plaintext) return ciphertext @@ -2045,6 +2049,8 @@ class RawKerberosTest(TestCaseInTempDir): expected_srealm=None, expected_sname=None, expected_account_name=None, + expected_groups=None, + unexpected_groups=None, expected_upn_name=None, expected_sid=None, expected_supported_etypes=None, @@ -2105,6 +2111,8 @@ class RawKerberosTest(TestCaseInTempDir): 'expected_srealm': expected_srealm, 'expected_sname': expected_sname, 'expected_account_name': expected_account_name, + 'expected_groups': expected_groups, + 'unexpected_groups': unexpected_groups, 'expected_upn_name': expected_upn_name, 'expected_sid': expected_sid, 'expected_supported_etypes': expected_supported_etypes, @@ -2161,6 +2169,8 @@ class RawKerberosTest(TestCaseInTempDir): expected_srealm=None, expected_sname=None, expected_account_name=None, + expected_groups=None, + unexpected_groups=None, expected_upn_name=None, expected_sid=None, expected_supported_etypes=None, @@ -2222,6 +2232,8 @@ class RawKerberosTest(TestCaseInTempDir): 'expected_srealm': expected_srealm, 'expected_sname': expected_sname, 'expected_account_name': expected_account_name, + 'expected_groups': expected_groups, + 'unexpected_groups': unexpected_groups, 'expected_upn_name': expected_upn_name, 'expected_sid': expected_sid, 'expected_supported_etypes': expected_supported_etypes, @@ -2796,6 +2808,8 @@ class RawKerberosTest(TestCaseInTempDir): require_strict=require_strict) expected_account_name = kdc_exchange_dict['expected_account_name'] + expected_groups = kdc_exchange_dict['expected_groups'] + unexpected_groups = kdc_exchange_dict['unexpected_groups'] expected_sid = kdc_exchange_dict['expected_sid'] expect_upn_dns_info_ex = kdc_exchange_dict['expect_upn_dns_info_ex'] @@ -2828,7 +2842,8 @@ class RawKerberosTest(TestCaseInTempDir): self.assertEqual(account_name, pac_buffer.info.account_name) elif pac_buffer.type == krb5pac.PAC_TYPE_LOGON_INFO: - logon_info = pac_buffer.info.info.info3.base + info3 = pac_buffer.info.info.info3 + logon_info = info3.base if expected_account_name is not None: self.assertEqual(expected_account_name, @@ -2838,6 +2853,30 @@ class RawKerberosTest(TestCaseInTempDir): expected_rid = int(expected_sid.rsplit('-', 1)[1]) self.assertEqual(expected_rid, logon_info.rid) + if expected_groups is not None: + self.assertIsNotNone(info3.sids) + got_sids = {str(sid_attr.sid) for sid_attr in info3.sids} + self.assertEqual(info3.sidcount, + len(got_sids), + 'Found duplicate SIDs') + + match_count = 0 + for g in expected_groups: + for sid_attr in info3.sids: + if g == str(sid_attr.sid): + match_count += 1 + self.assertEqual(match_count, len(expected_groups)) + + if unexpected_groups is not None: + match_count = 0 + + for g in unexpected_groups: + self.assertIsNotNone(info3.sids) + for sid_attr in info3.sids: + if g == str(sid_attr.sid): + match_count += 1 + self.assertEqual(match_count, 0) + elif pac_buffer.type == krb5pac.PAC_TYPE_UPN_DNS_INFO: upn_dns_info = pac_buffer.info upn_dns_info_ex = upn_dns_info.ex @@ -3939,6 +3978,8 @@ class RawKerberosTest(TestCaseInTempDir): kdc_options, renew_time=None, expected_account_name=None, + expected_groups=None, + unexpected_groups=None, expected_upn_name=None, expected_sid=None, expected_flags=None, @@ -3979,6 +4020,8 @@ class RawKerberosTest(TestCaseInTempDir): expected_srealm=expected_srealm, expected_sname=expected_sname, expected_account_name=expected_account_name, + expected_groups=expected_groups, + unexpected_groups=unexpected_groups, expected_upn_name=expected_upn_name, expected_sid=expected_sid, expected_supported_etypes=expected_supported_etypes, diff --git a/python/samba/tests/krb5/s4u_tests.py b/python/samba/tests/krb5/s4u_tests.py index 49dd89cd764..76e8bbe990e 100755 --- a/python/samba/tests/krb5/s4u_tests.py +++ b/python/samba/tests/krb5/s4u_tests.py @@ -24,7 +24,7 @@ sys.path.insert(0, "bin/python") os.environ["PYTHONUNBUFFERED"] = "1" from samba import ntstatus -from samba.dcerpc import krb5pac, lsa +from samba.dcerpc import krb5pac, lsa, security from samba.tests import env_get_var_value from samba.tests.krb5.kcrypto import Cksumtype, Enctype @@ -283,6 +283,8 @@ class S4UKerberosTests(KDCBaseTest): ARCFOUR_HMAC_MD5)) expect_edata = kdc_dict.pop('expect_edata', None) + expected_groups = kdc_dict.pop('expected_groups', None) + unexpected_groups = kdc_dict.pop('unexpected_groups', None) def generate_s4u2self_padata(_kdc_exchange_dict, _callback_dict, @@ -301,6 +303,7 @@ class S4UKerberosTests(KDCBaseTest): expected_srealm=realm, expected_sname=service_sname, expected_account_name=client_name, + unexpected_groups=unexpected_groups, expected_sid=sid, expected_flags=expected_flags, unexpected_flags=unexpected_flags, @@ -529,7 +532,21 @@ class S4UKerberosTests(KDCBaseTest): 'expected_flags': 'forwardable' }) + # Do an S4U2Self an check that the service asserted identity is part of + # the sids. + def test_s4u2self_asserted_identity(self): + self._run_s4u2self_test( + { + 'client_opts': { + 'not_delegated': False + }, + 'expected_groups': [security.SID_SERVICE_ASSERTED_IDENTITY], + 'unexpected_groups': [security.SID_AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY] + }) + def _run_delegation_test(self, kdc_dict): + s4u2self = kdc_dict.pop('s4u2self', False) + client_opts = kdc_dict.pop('client_opts', None) client_creds = self.get_cached_creds( account_type=self.AccountType.USER, @@ -570,19 +587,88 @@ class S4UKerberosTests(KDCBaseTest): account_type=self.AccountType.COMPUTER, opts=service1_opts) + service1_tgt = self.get_tgt(service1_creds) + + 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() + service1_service = 'host' + service1_sname = self.PrincipalName_create( + name_type=NT_PRINCIPAL, names=[service1_service, + service1_name]) + service1_decryption_key = self.TicketDecryptionKey_from_creds( + service1_creds) + + expect_pac = kdc_dict.pop('expect_pac', True) + + expected_groups = kdc_dict.pop('expected_groups', None) + unexpected_groups = kdc_dict.pop('unexpected_groups', None) + 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) + etypes = kdc_dict.pop('etypes', (AES256_CTS_HMAC_SHA1_96, + ARCFOUR_HMAC_MD5)) - service1_tgt = self.get_tgt(service1_creds) + if s4u2self: + def generate_s4u2self_padata(_kdc_exchange_dict, + _callback_dict, + req_body): + pa_s4u = self.PA_S4U2Self_create( + name=client_cname, + realm=client_realm, + tgt_session_key=service1_tgt.session_key, + ctype=None) + + return [pa_s4u], req_body + + s4u2self_expected_flags = krb5_asn1.TicketFlags('forwardable') + s4u2self_unexpected_flags = krb5_asn1.TicketFlags('0') + + s4u2self_kdc_options = krb5_asn1.KDCOptions('forwardable') + + s4u2self_authenticator_subkey = self.RandomKey(Enctype.AES256) + s4u2self_kdc_exchange_dict = self.tgs_exchange_dict( + expected_crealm=client_realm, + expected_cname=client_cname, + expected_srealm=service1_realm, + expected_sname=service1_sname, + expected_account_name=client_username, + expected_groups=expected_groups, + unexpected_groups=unexpected_groups, + expected_sid=sid, + expected_flags=s4u2self_expected_flags, + unexpected_flags=s4u2self_unexpected_flags, + ticket_decryption_key=service1_decryption_key, + generate_padata_fn=generate_s4u2self_padata, + check_rep_fn=self.generic_check_kdc_rep, + check_kdc_private_fn=self.generic_check_kdc_private, + tgt=service1_tgt, + authenticator_subkey=s4u2self_authenticator_subkey, + kdc_options=str(s4u2self_kdc_options), + expect_claims=False, + expect_edata=False) + + self._generic_kdc_exchange(s4u2self_kdc_exchange_dict, + cname=None, + realm=service1_realm, + sname=service1_sname, + etypes=etypes) + + client_service_tkt = s4u2self_kdc_exchange_dict['rep_ticket_creds'] + else: + 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) modify_client_tkt_fn = kdc_dict.pop('modify_client_tkt_fn', None) if modify_client_tkt_fn is not None: @@ -598,14 +684,6 @@ class S4UKerberosTests(KDCBaseTest): 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' @@ -635,9 +713,6 @@ class S4UKerberosTests(KDCBaseTest): 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( @@ -646,14 +721,14 @@ 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, expected_srealm=service2_realm, expected_sname=service2_sname, expected_account_name=client_username, + expected_groups=expected_groups, + unexpected_groups=unexpected_groups, expected_sid=sid, expected_supported_etypes=service2_etypes, ticket_decryption_key=service2_decryption_key, @@ -699,6 +774,33 @@ class S4UKerberosTests(KDCBaseTest): 'allow_delegation': True }) + def test_constrained_delegation_authentication_asserted_identity(self): + # Test constrained delegation and check asserted identity is the + # authenticaten authority. Note that we should always find this + # SID for all the requests. Just S4U2Self will have a different SID. + self._run_delegation_test( + { + 'expected_error_mode': 0, + 'allow_delegation': True, + 'expected_groups': [security.SID_AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY], + 'unexpected_groups': [security.SID_SERVICE_ASSERTED_IDENTITY] + }) + + def test_constrained_delegation_service_asserted_identity(self): + # Test constrained delegation and check asserted identity is the + # service sid is there. This is a S4U2Proxy + S4U2Self test. + self._run_delegation_test( + { + 'expected_error_mode': 0, + 'allow_delegation': True, + 's4u2self': True, + 'service1_opts': { + 'trusted_to_auth_for_delegation': True, + }, + 'expected_groups': [security.SID_SERVICE_ASSERTED_IDENTITY], + 'unexpected_groups': [security.SID_AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY] + }) + def test_constrained_delegation_no_auth_data_required(self): # Test constrained delegation. self._run_delegation_test( diff --git a/selftest/tests.py b/selftest/tests.py index 19b07dfec27..3ea6d97cc24 100644 --- a/selftest/tests.py +++ b/selftest/tests.py @@ -18,7 +18,7 @@ # three separated by newlines. All other lines in the output are considered # comments. -import os +import os, tempfile from selftesthelpers import bindir, srcdir, python from selftesthelpers import planpythontestsuite, samba4srcdir from selftesthelpers import plantestsuite, bbdir @@ -235,7 +235,7 @@ if with_pam: options = [ { "description": "krb5", - "pam_options": "krb5_auth krb5_ccache_type=FILE", + "pam_options": "krb5_auth krb5_ccache_type=FILE:%s/krb5cc_pam_test_%%u" % (tempfile.gettempdir()), }, { "description": "default", @@ -383,7 +383,7 @@ if with_pam: pam_options]) description = "krb5" - pam_options = "'krb5_auth krb5_ccache_type=FILE:/tmp/krb5cc_pam_test_%u'" + pam_options = "'krb5_auth krb5_ccache_type=FILE:%s/krb5cc_pam_test_setcred_%%u'" % (tempfile.gettempdir()) plantestsuite("samba.tests.pam_winbind_setcred(domain+%s)" % description, "ad_dc:local", [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind_setcred.sh"), valgrindify(python), pam_wrapper_so_path, diff --git a/source3/winbindd/winbindd.h b/source3/winbindd/winbindd.h index dac4a1fa927..fe286a9a686 100644 --- a/source3/winbindd/winbindd.h +++ b/source3/winbindd/winbindd.h @@ -43,6 +43,9 @@ #define WB_REPLACE_CHAR '_' +struct winbind_internal_pipes; +struct ads_struct; + struct winbindd_cli_state { struct winbindd_cli_state *prev, *next; /* Linked list pointers */ int sock; /* Open socket from client */ @@ -153,9 +156,10 @@ struct winbindd_domain { */ struct winbindd_methods *backend; - /* Private data for the backends (used for connection cache) */ - - void *private_data; + struct { + struct winbind_internal_pipes *samr_pipes; + struct ads_struct *ads_conn; + } backend_data; /* A working DC */ char *dcname; diff --git a/source3/winbindd/winbindd_ads.c b/source3/winbindd/winbindd_ads.c index 6f01ef6e334..d350f160223 100644 --- a/source3/winbindd/winbindd_ads.c +++ b/source3/winbindd/winbindd_ads.c @@ -269,10 +269,10 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain) } DEBUG(10,("ads_cached_connection\n")); - ads_cached_connection_reuse((ADS_STRUCT **)&domain->private_data); + ads_cached_connection_reuse(&domain->backend_data.ads_conn); - if (domain->private_data) { - return (ADS_STRUCT *)domain->private_data; + if (domain->backend_data.ads_conn != NULL) { + return domain->backend_data.ads_conn; } -- Samba Shared Repository