diff --git a/0001-CVE-2022-32743-s4-acl-Add-tests-for-validated-dNSHos.patch b/0001-CVE-2022-32743-s4-acl-Add-tests-for-validated-dNSHos.patch deleted file mode 100644 index 2fc183646add976a3ab04a4d2fe74096986d1220..0000000000000000000000000000000000000000 --- a/0001-CVE-2022-32743-s4-acl-Add-tests-for-validated-dNSHos.patch +++ /dev/null @@ -1,815 +0,0 @@ -From d277700710dc118f61065ed9e16e08e76820b66a Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Wed, 1 Jun 2022 16:07:17 +1200 -Subject: [PATCH 01/15] CVE-2022-32743 s4-acl: Add tests for validated - dNSHostName write - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14833 - -Signed-off-by: Joseph Sutton -Reviewed-by: Douglas Bagnall ---- - selftest/knownfail.d/validated-dns-host-name | 15 + - source4/dsdb/tests/python/acl.py | 757 +++++++++++++++++++++++++++ - 2 files changed, 772 insertions(+) - create mode 100644 selftest/knownfail.d/validated-dns-host-name - -diff --git a/selftest/knownfail.d/validated-dns-host-name b/selftest/knownfail.d/validated-dns-host-name -new file mode 100644 -index 0000000..ee51f44 ---- /dev/null -+++ b/selftest/knownfail.d/validated-dns-host-name -@@ -0,0 +1,15 @@ -+^samba4.ldap.acl.python.*__main__.AclModifyTests.test_modify_dns_host_name\( -+^samba4.ldap.acl.python.*__main__.AclModifyTests.test_modify_dns_host_name_account_no_dollar\( -+^samba4.ldap.acl.python.*__main__.AclModifyTests.test_modify_dns_host_name_allowed_suffixes\( -+^samba4.ldap.acl.python.*__main__.AclModifyTests.test_modify_dns_host_name_case\( -+^samba4.ldap.acl.python.*__main__.AclModifyTests.test_modify_dns_host_name_dollar\( -+^samba4.ldap.acl.python.*__main__.AclModifyTests.test_modify_dns_host_name_empty_string\( -+^samba4.ldap.acl.python.*__main__.AclModifyTests.test_modify_dns_host_name_invalid\( -+^samba4.ldap.acl.python.*__main__.AclModifyTests.test_modify_dns_host_name_no_suffix\( -+^samba4.ldap.acl.python.*__main__.AclModifyTests.test_modify_dns_host_name_no_value\( -+^samba4.ldap.acl.python.*__main__.AclModifyTests.test_modify_dns_host_name_spn\( -+^samba4.ldap.acl.python.*__main__.AclModifyTests.test_modify_dns_host_name_spn_matching_account_name_new\( -+^samba4.ldap.acl.python.*__main__.AclModifyTests.test_modify_dns_host_name_spn_matching_account_name_original\( -+^samba4.ldap.acl.python.*__main__.AclModifyTests.test_modify_dns_host_name_wrong_prefix\( -+^samba4.ldap.acl.python.*__main__.AclModifyTests.test_modify_dns_host_name_wrong_suffix\( -+^samba4.ldap.acl.python.*__main__.AclModifyTests.test_modify_spn_matching_dns_host_name_invalid\( -diff --git a/source4/dsdb/tests/python/acl.py b/source4/dsdb/tests/python/acl.py -index 0061d0c..6751934 100755 ---- a/source4/dsdb/tests/python/acl.py -+++ b/source4/dsdb/tests/python/acl.py -@@ -300,6 +300,7 @@ class AclModifyTests(AclTests): - delete_force(self.ldb_admin, "CN=test_modify_group1,CN=Users," + self.base_dn) - delete_force(self.ldb_admin, "CN=test_modify_group2,CN=Users," + self.base_dn) - delete_force(self.ldb_admin, "CN=test_modify_group3,CN=Users," + self.base_dn) -+ delete_force(self.ldb_admin, "CN=test_mod_hostname,OU=test_modify_ou1," + self.base_dn) - delete_force(self.ldb_admin, "OU=test_modify_ou1," + self.base_dn) - delete_force(self.ldb_admin, self.get_user_dn(self.user_with_wp)) - delete_force(self.ldb_admin, self.get_user_dn(self.user_with_sm)) -@@ -651,6 +652,762 @@ Member: CN=test_modify_user2,CN=Users,""" + self.base_dn - else: - self.fail() - -+ def test_modify_dns_host_name(self): -+ '''Test modifying dNSHostName with validated write''' -+ -+ ou_dn = f'OU=test_modify_ou1,{self.base_dn}' -+ -+ account_name = 'test_mod_hostname' -+ dn = f'CN={account_name},{ou_dn}' -+ -+ self.ldb_admin.create_ou(ou_dn) -+ -+ # Grant Validated Write. -+ mod = (f'(OA;CI;SW;{security.GUID_DRS_DNS_HOST_NAME};;' -+ f'{self.user_sid})') -+ self.sd_utils.dacl_add_ace(ou_dn, mod) -+ -+ # Create the account. -+ self.ldb_admin.add({ -+ 'dn': dn, -+ 'objectClass': 'computer', -+ 'sAMAccountName': f'{account_name}$', -+ }) -+ -+ host_name = f'{account_name}.{self.ldb_user.domain_dns_name()}' -+ -+ m = Message(Dn(self.ldb_user, dn)) -+ m['dNSHostName'] = MessageElement(host_name, -+ FLAG_MOD_REPLACE, -+ 'dNSHostName') -+ try: -+ self.ldb_user.modify(m) -+ except LdbError: -+ self.fail() -+ -+ def test_modify_dns_host_name_no_validated_write(self): -+ '''Test modifying dNSHostName without validated write''' -+ -+ ou_dn = f'OU=test_modify_ou1,{self.base_dn}' -+ -+ account_name = 'test_mod_hostname' -+ dn = f'CN={account_name},{ou_dn}' -+ -+ self.ldb_admin.create_ou(ou_dn) -+ -+ # Create the account. -+ self.ldb_admin.add({ -+ 'dn': dn, -+ 'objectClass': 'computer', -+ 'sAMAccountName': f'{account_name}$', -+ }) -+ -+ host_name = f'{account_name}.{self.ldb_user.domain_dns_name()}' -+ -+ m = Message(Dn(self.ldb_user, dn)) -+ m['dNSHostName'] = MessageElement(host_name, -+ FLAG_MOD_REPLACE, -+ 'dNSHostName') -+ try: -+ self.ldb_user.modify(m) -+ except LdbError as err: -+ num, estr = err.args -+ self.assertEqual(ERR_INSUFFICIENT_ACCESS_RIGHTS, num) -+ else: -+ self.fail() -+ -+ def test_modify_dns_host_name_invalid(self): -+ '''Test modifying dNSHostName to an invalid value''' -+ -+ ou_dn = f'OU=test_modify_ou1,{self.base_dn}' -+ -+ account_name = 'test_mod_hostname' -+ dn = f'CN={account_name},{ou_dn}' -+ -+ self.ldb_admin.create_ou(ou_dn) -+ -+ # Grant Validated Write. -+ mod = (f'(OA;CI;SW;{security.GUID_DRS_DNS_HOST_NAME};;' -+ f'{self.user_sid})') -+ self.sd_utils.dacl_add_ace(ou_dn, mod) -+ -+ # Create the account. -+ self.ldb_admin.add({ -+ 'dn': dn, -+ 'objectClass': 'computer', -+ 'sAMAccountName': f'{account_name}$', -+ }) -+ -+ host_name = 'invalid' -+ -+ m = Message(Dn(self.ldb_user, dn)) -+ m['dNSHostName'] = MessageElement(host_name, -+ FLAG_MOD_REPLACE, -+ 'dNSHostName') -+ try: -+ self.ldb_user.modify(m) -+ except LdbError as err: -+ num, estr = err.args -+ self.assertEqual(ERR_CONSTRAINT_VIOLATION, num) -+ else: -+ self.fail() -+ -+ def test_modify_dns_host_name_invalid_wp(self): -+ '''Test modifying dNSHostName to an invalid value when we have WP''' -+ -+ ou_dn = f'OU=test_modify_ou1,{self.base_dn}' -+ -+ account_name = 'test_mod_hostname' -+ dn = f'CN={account_name},{ou_dn}' -+ -+ self.ldb_admin.create_ou(ou_dn) -+ -+ # Grant Write Property. -+ mod = (f'(OA;CI;WP;{security.GUID_DRS_DNS_HOST_NAME};;' -+ f'{self.user_sid})') -+ self.sd_utils.dacl_add_ace(ou_dn, mod) -+ -+ # Create the account. -+ self.ldb_admin.add({ -+ 'dn': dn, -+ 'objectClass': 'computer', -+ 'sAMAccountName': f'{account_name}$', -+ }) -+ -+ host_name = 'invalid' -+ -+ m = Message(Dn(self.ldb_user, dn)) -+ m['dNSHostName'] = MessageElement(host_name, -+ FLAG_MOD_REPLACE, -+ 'dNSHostName') -+ try: -+ self.ldb_user.modify(m) -+ except LdbError: -+ self.fail() -+ -+ def test_modify_dns_host_name_invalid_non_computer(self): -+ '''Test modifying dNSHostName to an invalid value on a non-computer''' -+ -+ ou_dn = f'OU=test_modify_ou1,{self.base_dn}' -+ -+ account_name = 'test_mod_hostname' -+ dn = f'CN={account_name},{ou_dn}' -+ -+ self.ldb_admin.create_ou(ou_dn) -+ -+ # Grant Validated Write. -+ mod = (f'(OA;CI;SW;{security.GUID_DRS_DNS_HOST_NAME};;' -+ f'{self.user_sid})') -+ self.sd_utils.dacl_add_ace(ou_dn, mod) -+ -+ # Create the account. -+ self.ldb_admin.add({ -+ 'dn': dn, -+ 'objectClass': 'user', -+ 'sAMAccountName': f'{account_name}', -+ }) -+ -+ host_name = 'invalid' -+ -+ m = Message(Dn(self.ldb_user, dn)) -+ m['dNSHostName'] = MessageElement(host_name, -+ FLAG_MOD_REPLACE, -+ 'dNSHostName') -+ try: -+ self.ldb_user.modify(m) -+ except LdbError as err: -+ num, estr = err.args -+ self.assertEqual(ERR_INSUFFICIENT_ACCESS_RIGHTS, num) -+ else: -+ self.fail() -+ -+ def test_modify_dns_host_name_no_value(self): -+ '''Test modifying dNSHostName with validated write with no value''' -+ -+ ou_dn = f'OU=test_modify_ou1,{self.base_dn}' -+ -+ account_name = 'test_mod_hostname' -+ dn = f'CN={account_name},{ou_dn}' -+ -+ self.ldb_admin.create_ou(ou_dn) -+ -+ # Grant Validated Write. -+ mod = (f'(OA;CI;SW;{security.GUID_DRS_DNS_HOST_NAME};;' -+ f'{self.user_sid})') -+ self.sd_utils.dacl_add_ace(ou_dn, mod) -+ -+ # Create the account. -+ self.ldb_admin.add({ -+ 'dn': dn, -+ 'objectClass': 'computer', -+ 'sAMAccountName': f'{account_name}$', -+ }) -+ -+ m = Message(Dn(self.ldb_user, dn)) -+ m['dNSHostName'] = MessageElement([], -+ FLAG_MOD_REPLACE, -+ 'dNSHostName') -+ try: -+ self.ldb_user.modify(m) -+ except LdbError as err: -+ num, estr = err.args -+ self.assertEqual(ERR_OPERATIONS_ERROR, num) -+ else: -+ # Windows accepts this. -+ pass -+ -+ def test_modify_dns_host_name_empty_string(self): -+ '''Test modifying dNSHostName with validated write of an empty string''' -+ -+ ou_dn = f'OU=test_modify_ou1,{self.base_dn}' -+ -+ account_name = 'test_mod_hostname' -+ dn = f'CN={account_name},{ou_dn}' -+ -+ self.ldb_admin.create_ou(ou_dn) -+ -+ # Grant Validated Write. -+ mod = (f'(OA;CI;SW;{security.GUID_DRS_DNS_HOST_NAME};;' -+ f'{self.user_sid})') -+ self.sd_utils.dacl_add_ace(ou_dn, mod) -+ -+ # Create the account. -+ self.ldb_admin.add({ -+ 'dn': dn, -+ 'objectClass': 'computer', -+ 'sAMAccountName': f'{account_name}$', -+ }) -+ -+ m = Message(Dn(self.ldb_user, dn)) -+ m['dNSHostName'] = MessageElement('\0', -+ FLAG_MOD_REPLACE, -+ 'dNSHostName') -+ try: -+ self.ldb_user.modify(m) -+ except LdbError as err: -+ num, estr = err.args -+ self.assertEqual(ERR_CONSTRAINT_VIOLATION, num) -+ else: -+ self.fail() -+ -+ def test_modify_dns_host_name_dollar(self): -+ '''Test modifying dNSHostName with validated write of a value including a dollar''' -+ -+ ou_dn = f'OU=test_modify_ou1,{self.base_dn}' -+ -+ account_name = 'test_mod_hostname' -+ dn = f'CN={account_name},{ou_dn}' -+ -+ self.ldb_admin.create_ou(ou_dn) -+ -+ # Grant Validated Write. -+ mod = (f'(OA;CI;SW;{security.GUID_DRS_DNS_HOST_NAME};;' -+ f'{self.user_sid})') -+ self.sd_utils.dacl_add_ace(ou_dn, mod) -+ -+ # Create the account. -+ self.ldb_admin.add({ -+ 'dn': dn, -+ 'objectClass': 'computer', -+ 'sAMAccountName': f'{account_name}$', -+ }) -+ -+ host_name = f'{account_name}$.{self.ldb_user.domain_dns_name()}' -+ -+ m = Message(Dn(self.ldb_user, dn)) -+ m['dNSHostName'] = MessageElement(host_name, -+ FLAG_MOD_REPLACE, -+ 'dNSHostName') -+ try: -+ self.ldb_user.modify(m) -+ except LdbError as err: -+ num, estr = err.args -+ self.assertEqual(ERR_CONSTRAINT_VIOLATION, num) -+ else: -+ self.fail() -+ -+ def test_modify_dns_host_name_account_no_dollar(self): -+ '''Test modifying dNSHostName with validated write with no dollar in sAMAccountName''' -+ -+ ou_dn = f'OU=test_modify_ou1,{self.base_dn}' -+ -+ account_name = 'test_mod_hostname' -+ dn = f'CN={account_name},{ou_dn}' -+ -+ self.ldb_admin.create_ou(ou_dn) -+ -+ # Grant Validated Write. -+ mod = (f'(OA;CI;SW;{security.GUID_DRS_DNS_HOST_NAME};;' -+ f'{self.user_sid})') -+ self.sd_utils.dacl_add_ace(ou_dn, mod) -+ -+ # Create the account. -+ self.ldb_admin.add({ -+ 'dn': dn, -+ 'objectClass': 'computer', -+ 'sAMAccountName': f'{account_name}', -+ }) -+ -+ host_name = f'{account_name}.{self.ldb_user.domain_dns_name()}' -+ -+ m = Message(Dn(self.ldb_user, dn)) -+ m['dNSHostName'] = MessageElement(host_name, -+ FLAG_MOD_REPLACE, -+ 'dNSHostName') -+ try: -+ self.ldb_user.modify(m) -+ except LdbError: -+ self.fail() -+ -+ def test_modify_dns_host_name_no_suffix(self): -+ '''Test modifying dNSHostName with validated write of a value missing the suffix''' -+ -+ ou_dn = f'OU=test_modify_ou1,{self.base_dn}' -+ -+ account_name = 'test_mod_hostname' -+ dn = f'CN={account_name},{ou_dn}' -+ -+ self.ldb_admin.create_ou(ou_dn) -+ -+ # Grant Validated Write. -+ mod = (f'(OA;CI;SW;{security.GUID_DRS_DNS_HOST_NAME};;' -+ f'{self.user_sid})') -+ self.sd_utils.dacl_add_ace(ou_dn, mod) -+ -+ # Create the account. -+ self.ldb_admin.add({ -+ 'dn': dn, -+ 'objectClass': 'computer', -+ 'sAMAccountName': f'{account_name}$', -+ }) -+ -+ host_name = f'{account_name}' -+ -+ m = Message(Dn(self.ldb_user, dn)) -+ m['dNSHostName'] = MessageElement(host_name, -+ FLAG_MOD_REPLACE, -+ 'dNSHostName') -+ try: -+ self.ldb_user.modify(m) -+ except LdbError as err: -+ num, estr = err.args -+ self.assertEqual(ERR_CONSTRAINT_VIOLATION, num) -+ else: -+ self.fail() -+ -+ def test_modify_dns_host_name_wrong_prefix(self): -+ '''Test modifying dNSHostName with validated write of a value with the wrong prefix''' -+ -+ ou_dn = f'OU=test_modify_ou1,{self.base_dn}' -+ -+ account_name = 'test_mod_hostname' -+ dn = f'CN={account_name},{ou_dn}' -+ -+ self.ldb_admin.create_ou(ou_dn) -+ -+ # Grant Validated Write. -+ mod = (f'(OA;CI;SW;{security.GUID_DRS_DNS_HOST_NAME};;' -+ f'{self.user_sid})') -+ self.sd_utils.dacl_add_ace(ou_dn, mod) -+ -+ # Create the account. -+ self.ldb_admin.add({ -+ 'dn': dn, -+ 'objectClass': 'computer', -+ 'sAMAccountName': f'{account_name}$', -+ }) -+ -+ host_name = f'invalid.{self.ldb_user.domain_dns_name()}' -+ -+ m = Message(Dn(self.ldb_user, dn)) -+ m['dNSHostName'] = MessageElement(host_name, -+ FLAG_MOD_REPLACE, -+ 'dNSHostName') -+ try: -+ self.ldb_user.modify(m) -+ except LdbError as err: -+ num, estr = err.args -+ self.assertEqual(ERR_CONSTRAINT_VIOLATION, num) -+ else: -+ self.fail() -+ -+ def test_modify_dns_host_name_wrong_suffix(self): -+ '''Test modifying dNSHostName with validated write of a value with the wrong suffix''' -+ -+ ou_dn = f'OU=test_modify_ou1,{self.base_dn}' -+ -+ account_name = 'test_mod_hostname' -+ dn = f'CN={account_name},{ou_dn}' -+ -+ self.ldb_admin.create_ou(ou_dn) -+ -+ # Grant Validated Write. -+ mod = (f'(OA;CI;SW;{security.GUID_DRS_DNS_HOST_NAME};;' -+ f'{self.user_sid})') -+ self.sd_utils.dacl_add_ace(ou_dn, mod) -+ -+ # Create the account. -+ self.ldb_admin.add({ -+ 'dn': dn, -+ 'objectClass': 'computer', -+ 'sAMAccountName': f'{account_name}$', -+ }) -+ -+ host_name = f'{account_name}.invalid.example.com' -+ -+ m = Message(Dn(self.ldb_user, dn)) -+ m['dNSHostName'] = MessageElement(host_name, -+ FLAG_MOD_REPLACE, -+ 'dNSHostName') -+ try: -+ self.ldb_user.modify(m) -+ except LdbError as err: -+ num, estr = err.args -+ self.assertEqual(ERR_CONSTRAINT_VIOLATION, num) -+ else: -+ self.fail() -+ -+ def test_modify_dns_host_name_case(self): -+ '''Test modifying dNSHostName with validated write of a value with irregular case''' -+ -+ ou_dn = f'OU=test_modify_ou1,{self.base_dn}' -+ -+ account_name = 'test_mod_hostname' -+ dn = f'CN={account_name},{ou_dn}' -+ -+ self.ldb_admin.create_ou(ou_dn) -+ -+ # Grant Validated Write. -+ mod = (f'(OA;CI;SW;{security.GUID_DRS_DNS_HOST_NAME};;' -+ f'{self.user_sid})') -+ self.sd_utils.dacl_add_ace(ou_dn, mod) -+ -+ # Create the account. -+ self.ldb_admin.add({ -+ 'dn': dn, -+ 'objectClass': 'computer', -+ 'sAMAccountName': f'{account_name}$', -+ }) -+ -+ host_name = f'{account_name}.{self.ldb_user.domain_dns_name()}' -+ host_name = host_name.capitalize() -+ -+ m = Message(Dn(self.ldb_user, dn)) -+ m['dNSHostName'] = MessageElement(host_name, -+ FLAG_MOD_REPLACE, -+ 'dNSHostName') -+ try: -+ self.ldb_user.modify(m) -+ except LdbError: -+ self.fail() -+ -+ def test_modify_dns_host_name_allowed_suffixes(self): -+ '''Test modifying dNSHostName with validated write and an allowed suffix''' -+ -+ allowed_suffix = 'suffix.that.is.allowed' -+ -+ # Add the allowed suffix. -+ -+ res = self.ldb_admin.search(self.base_dn, -+ scope=SCOPE_BASE, -+ attrs=['msDS-AllowedDNSSuffixes']) -+ self.assertEqual(1, len(res)) -+ old_allowed_suffixes = res[0].get('msDS-AllowedDNSSuffixes') -+ -+ def modify_allowed_suffixes(suffixes): -+ if suffixes is None: -+ suffixes = [] -+ flag = FLAG_MOD_DELETE -+ else: -+ flag = FLAG_MOD_REPLACE -+ -+ m = Message(Dn(self.ldb_admin, self.base_dn)) -+ m['msDS-AllowedDNSSuffixes'] = MessageElement( -+ suffixes, -+ flag, -+ 'msDS-AllowedDNSSuffixes') -+ self.ldb_admin.modify(m) -+ -+ self.addCleanup(modify_allowed_suffixes, old_allowed_suffixes) -+ -+ if old_allowed_suffixes is None: -+ allowed_suffixes = [] -+ else: -+ allowed_suffixes = list(old_allowed_suffixes) -+ -+ if (allowed_suffix not in allowed_suffixes and -+ allowed_suffix.encode('utf-8') not in allowed_suffixes): -+ allowed_suffixes.append(allowed_suffix) -+ -+ modify_allowed_suffixes(allowed_suffixes) -+ -+ # Create the account and run the test. -+ -+ ou_dn = f'OU=test_modify_ou1,{self.base_dn}' -+ -+ account_name = 'test_mod_hostname' -+ dn = f'CN={account_name},{ou_dn}' -+ -+ self.ldb_admin.create_ou(ou_dn) -+ -+ # Grant Validated Write. -+ mod = (f'(OA;CI;SW;{security.GUID_DRS_DNS_HOST_NAME};;' -+ f'{self.user_sid})') -+ self.sd_utils.dacl_add_ace(ou_dn, mod) -+ -+ # Create the account. -+ self.ldb_admin.add({ -+ 'dn': dn, -+ 'objectClass': 'computer', -+ 'sAMAccountName': f'{account_name}$', -+ }) -+ -+ host_name = f'{account_name}.{allowed_suffix}' -+ -+ m = Message(Dn(self.ldb_user, dn)) -+ m['dNSHostName'] = MessageElement(host_name, -+ FLAG_MOD_REPLACE, -+ 'dNSHostName') -+ try: -+ self.ldb_user.modify(m) -+ except LdbError: -+ self.fail() -+ -+ def test_modify_dns_host_name_spn(self): -+ '''Test modifying dNSHostName and SPN with validated write''' -+ -+ ou_dn = f'OU=test_modify_ou1,{self.base_dn}' -+ -+ account_name = 'test_mod_hostname' -+ dn = f'CN={account_name},{ou_dn}' -+ -+ self.ldb_admin.create_ou(ou_dn) -+ -+ # Grant Validated Write. -+ mod = (f'(OA;CI;SW;{security.GUID_DRS_DNS_HOST_NAME};;' -+ f'{self.user_sid})') -+ self.sd_utils.dacl_add_ace(ou_dn, mod) -+ mod = (f'(OA;CI;SW;{security.GUID_DRS_VALIDATE_SPN};;' -+ f'{self.user_sid})') -+ self.sd_utils.dacl_add_ace(ou_dn, mod) -+ -+ # Create the account. -+ self.ldb_admin.add({ -+ 'dn': dn, -+ 'objectClass': 'computer', -+ 'sAMAccountName': f'{account_name}$', -+ }) -+ -+ host_name = f'{account_name}.{self.ldb_user.domain_dns_name()}' -+ spn = f'host/{host_name}' -+ -+ m = Message(Dn(self.ldb_user, dn)) -+ m['0'] = MessageElement(host_name, -+ FLAG_MOD_REPLACE, -+ 'dNSHostName') -+ m['1'] = MessageElement(spn, -+ FLAG_MOD_ADD, -+ 'servicePrincipalName') -+ try: -+ self.ldb_user.modify(m) -+ except LdbError: -+ self.fail() -+ -+ def test_modify_spn_matching_dns_host_name_invalid(self): -+ '''Test modifying SPN with validated write, matching a valid dNSHostName ''' -+ -+ ou_dn = f'OU=test_modify_ou1,{self.base_dn}' -+ -+ account_name = 'test_mod_hostname' -+ dn = f'CN={account_name},{ou_dn}' -+ -+ self.ldb_admin.create_ou(ou_dn) -+ -+ # Grant Write Property. -+ mod = (f'(OA;CI;WP;{security.GUID_DRS_DNS_HOST_NAME};;' -+ f'{self.user_sid})') -+ self.sd_utils.dacl_add_ace(ou_dn, mod) -+ # Grant Validated Write. -+ mod = (f'(OA;CI;SW;{security.GUID_DRS_VALIDATE_SPN};;' -+ f'{self.user_sid})') -+ self.sd_utils.dacl_add_ace(ou_dn, mod) -+ -+ # Create the account. -+ self.ldb_admin.add({ -+ 'dn': dn, -+ 'objectClass': 'computer', -+ 'sAMAccountName': f'{account_name}$', -+ }) -+ -+ invalid_host_name = 'invalid' -+ -+ host_name = f'{account_name}.{self.ldb_user.domain_dns_name()}' -+ spn = f'host/{host_name}' -+ -+ m = Message(Dn(self.ldb_user, dn)) -+ m['0'] = MessageElement(invalid_host_name, -+ FLAG_MOD_REPLACE, -+ 'dNSHostName') -+ m['1'] = MessageElement(spn, -+ FLAG_MOD_ADD, -+ 'servicePrincipalName') -+ m['2'] = MessageElement(host_name, -+ FLAG_MOD_REPLACE, -+ 'dNSHostName') -+ try: -+ self.ldb_user.modify(m) -+ except LdbError: -+ self.fail() -+ -+ def test_modify_spn_matching_dns_host_name_original(self): -+ '''Test modifying SPN with validated write, matching the original dNSHostName ''' -+ -+ ou_dn = f'OU=test_modify_ou1,{self.base_dn}' -+ -+ account_name = 'test_mod_hostname' -+ dn = f'CN={account_name},{ou_dn}' -+ -+ self.ldb_admin.create_ou(ou_dn) -+ -+ # Grant Validated Write. -+ mod = (f'(OA;CI;SW;{security.GUID_DRS_DNS_HOST_NAME};;' -+ f'{self.user_sid})') -+ self.sd_utils.dacl_add_ace(ou_dn, mod) -+ mod = (f'(OA;CI;SW;{security.GUID_DRS_VALIDATE_SPN};;' -+ f'{self.user_sid})') -+ self.sd_utils.dacl_add_ace(ou_dn, mod) -+ -+ original_host_name = 'invalid_host_name' -+ original_spn = 'host/{original_host_name}' -+ -+ # Create the account. -+ self.ldb_admin.add({ -+ 'dn': dn, -+ 'objectClass': 'computer', -+ 'sAMAccountName': f'{account_name}$', -+ 'dNSHostName': original_host_name, -+ }) -+ -+ host_name = f'{account_name}.{self.ldb_user.domain_dns_name()}' -+ -+ m = Message(Dn(self.ldb_user, dn)) -+ m['0'] = MessageElement(original_spn, -+ FLAG_MOD_ADD, -+ 'servicePrincipalName') -+ m['1'] = MessageElement(host_name, -+ FLAG_MOD_REPLACE, -+ 'dNSHostName') -+ try: -+ self.ldb_user.modify(m) -+ except LdbError as err: -+ num, estr = err.args -+ self.assertEqual(ERR_CONSTRAINT_VIOLATION, num) -+ else: -+ self.fail() -+ -+ def test_modify_dns_host_name_spn_matching_account_name_original(self): -+ '''Test modifying dNSHostName and SPN with validated write, matching the original sAMAccountName''' -+ -+ ou_dn = f'OU=test_modify_ou1,{self.base_dn}' -+ -+ account_name = 'test_mod_hostname' -+ dn = f'CN={account_name},{ou_dn}' -+ -+ self.ldb_admin.create_ou(ou_dn) -+ -+ sam_account_name = '3e0abfd0-126a-11d0-a060-00aa006c33ed' -+ -+ # Grant Write Property. -+ mod = (f'(OA;CI;WP;{sam_account_name};;' -+ f'{self.user_sid})') -+ self.sd_utils.dacl_add_ace(ou_dn, mod) -+ # Grant Validated Write. -+ mod = (f'(OA;CI;SW;{security.GUID_DRS_DNS_HOST_NAME};;' -+ f'{self.user_sid})') -+ self.sd_utils.dacl_add_ace(ou_dn, mod) -+ mod = (f'(OA;CI;SW;{security.GUID_DRS_VALIDATE_SPN};;' -+ f'{self.user_sid})') -+ self.sd_utils.dacl_add_ace(ou_dn, mod) -+ -+ # Create the account. -+ self.ldb_admin.add({ -+ 'dn': dn, -+ 'objectClass': 'computer', -+ 'sAMAccountName': f'{account_name}$', -+ }) -+ -+ new_account_name = 'test_mod_hostname2' -+ host_name = f'{account_name}.{self.ldb_user.domain_dns_name()}' -+ spn = f'host/{host_name}' -+ -+ m = Message(Dn(self.ldb_user, dn)) -+ m['0'] = MessageElement(host_name, -+ FLAG_MOD_REPLACE, -+ 'dNSHostName') -+ m['1'] = MessageElement(spn, -+ FLAG_MOD_ADD, -+ 'servicePrincipalName') -+ m['2'] = MessageElement(f'{new_account_name}$', -+ FLAG_MOD_REPLACE, -+ 'sAMAccountName') -+ try: -+ self.ldb_user.modify(m) -+ except LdbError as err: -+ num, estr = err.args -+ self.assertEqual(ERR_CONSTRAINT_VIOLATION, num) -+ else: -+ self.fail() -+ -+ def test_modify_dns_host_name_spn_matching_account_name_new(self): -+ '''Test modifying dNSHostName and SPN with validated write, matching the new sAMAccountName''' -+ -+ ou_dn = f'OU=test_modify_ou1,{self.base_dn}' -+ -+ account_name = 'test_mod_hostname' -+ dn = f'CN={account_name},{ou_dn}' -+ -+ self.ldb_admin.create_ou(ou_dn) -+ -+ sam_account_name = '3e0abfd0-126a-11d0-a060-00aa006c33ed' -+ -+ # Grant Write Property. -+ mod = (f'(OA;CI;WP;{sam_account_name};;' -+ f'{self.user_sid})') -+ self.sd_utils.dacl_add_ace(ou_dn, mod) -+ # Grant Validated Write. -+ mod = (f'(OA;CI;SW;{security.GUID_DRS_DNS_HOST_NAME};;' -+ f'{self.user_sid})') -+ self.sd_utils.dacl_add_ace(ou_dn, mod) -+ mod = (f'(OA;CI;SW;{security.GUID_DRS_VALIDATE_SPN};;' -+ f'{self.user_sid})') -+ self.sd_utils.dacl_add_ace(ou_dn, mod) -+ -+ # Create the account. -+ self.ldb_admin.add({ -+ 'dn': dn, -+ 'objectClass': 'computer', -+ 'sAMAccountName': f'{account_name}$', -+ }) -+ -+ new_account_name = 'test_mod_hostname2' -+ new_host_name = f'{new_account_name}.{self.ldb_user.domain_dns_name()}' -+ new_spn = f'host/{new_host_name}' -+ -+ m = Message(Dn(self.ldb_user, dn)) -+ m['0'] = MessageElement(new_spn, -+ FLAG_MOD_ADD, -+ 'servicePrincipalName') -+ m['1'] = MessageElement(new_host_name, -+ FLAG_MOD_REPLACE, -+ 'dNSHostName') -+ m['2'] = MessageElement(f'{new_account_name}$', -+ FLAG_MOD_REPLACE, -+ 'sAMAccountName') -+ try: -+ self.ldb_user.modify(m) -+ except LdbError: -+ self.fail() -+ - # enable these when we have search implemented - - --- -1.8.3.1 - diff --git a/0002-CVE-2022-32743-tests-py_credentials-Add-tests-for-se.patch b/0002-CVE-2022-32743-tests-py_credentials-Add-tests-for-se.patch deleted file mode 100644 index 8d7bb2f4e2dd3333c9edcc99e7c811206a25018e..0000000000000000000000000000000000000000 --- a/0002-CVE-2022-32743-tests-py_credentials-Add-tests-for-se.patch +++ /dev/null @@ -1,346 +0,0 @@ -From b41691d0e546795bda994d94091b8e0a03ab96d6 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Tue, 7 Jun 2022 17:35:35 +1200 -Subject: [PATCH 02/15] CVE-2022-32743 tests/py_credentials: Add tests for - setting dNSHostName with LogonGetDomainInfo() - -Test that the value is properly validated, and that it can be set -regardless of rights on the account. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14833 - -Signed-off-by: Joseph Sutton -Reviewed-by: Douglas Bagnall ---- - python/samba/tests/py_credentials.py | 281 +++++++++++++++++++++++++++- - selftest/knownfail.d/netlogon-dns-host-name | 2 + - 2 files changed, 281 insertions(+), 2 deletions(-) - create mode 100644 selftest/knownfail.d/netlogon-dns-host-name - -diff --git a/python/samba/tests/py_credentials.py b/python/samba/tests/py_credentials.py -index ecb8271..0c442b8 100644 ---- a/python/samba/tests/py_credentials.py -+++ b/python/samba/tests/py_credentials.py -@@ -18,6 +18,8 @@ - from samba.tests import TestCase, delete_force - import os - -+import ldb -+ - import samba - from samba.auth import system_session - from samba.credentials import ( -@@ -25,7 +27,7 @@ from samba.credentials import ( - CLI_CRED_NTLMv2_AUTH, - CLI_CRED_NTLM_AUTH, - DONT_USE_KERBEROS) --from samba.dcerpc import netlogon, ntlmssp, srvsvc -+from samba.dcerpc import lsa, netlogon, ntlmssp, security, srvsvc - from samba.dcerpc.netlogon import ( - netr_Authenticator, - netr_WorkstationInformation, -@@ -36,10 +38,11 @@ from samba.dsdb import ( - UF_WORKSTATION_TRUST_ACCOUNT, - UF_PASSWD_NOTREQD, - UF_NORMAL_ACCOUNT) --from samba.ndr import ndr_pack -+from samba.ndr import ndr_pack, ndr_unpack - from samba.samdb import SamDB - from samba import NTSTATUSError, ntstatus - from samba.common import get_string -+from samba.sd_utils import SDUtils - - import ctypes - -@@ -105,6 +108,280 @@ class PyCredentialsTests(TestCase): - (authenticator, subsequent) = self.get_authenticator(c) - self.do_NetrLogonGetDomainInfo(c, authenticator, subsequent) - -+ # Test using LogonGetDomainInfo to update dNSHostName to an allowed value. -+ def test_set_dns_hostname_valid(self): -+ c = self.get_netlogon_connection() -+ authenticator, subsequent = self.get_authenticator(c) -+ -+ domain_hostname = self.ldb.domain_dns_name() -+ -+ new_dns_hostname = f'{self.machine_name}.{domain_hostname}' -+ new_dns_hostname = new_dns_hostname.encode('utf-8') -+ -+ query = netr_WorkstationInformation() -+ query.os_name = lsa.String('some OS') -+ query.dns_hostname = new_dns_hostname -+ -+ c.netr_LogonGetDomainInfo( -+ server_name=self.server, -+ computer_name=self.user_creds.get_workstation(), -+ credential=authenticator, -+ return_authenticator=subsequent, -+ level=1, -+ query=query) -+ -+ # Check the result. -+ -+ res = self.ldb.search(self.machine_dn, -+ scope=ldb.SCOPE_BASE, -+ attrs=['dNSHostName']) -+ self.assertEqual(1, len(res)) -+ -+ got_dns_hostname = res[0].get('dNSHostName', idx=0) -+ self.assertEqual(new_dns_hostname, got_dns_hostname) -+ -+ # Test using LogonGetDomainInfo to update dNSHostName to an allowed value, -+ # when we are denied the right to do so. -+ def test_set_dns_hostname_valid_denied(self): -+ c = self.get_netlogon_connection() -+ authenticator, subsequent = self.get_authenticator(c) -+ -+ res = self.ldb.search(self.machine_dn, -+ scope=ldb.SCOPE_BASE, -+ attrs=['objectSid']) -+ self.assertEqual(1, len(res)) -+ -+ machine_sid = ndr_unpack(security.dom_sid, -+ res[0].get('objectSid', idx=0)) -+ -+ sd_utils = SDUtils(self.ldb) -+ -+ # Deny Validated Write and Write Property. -+ mod = (f'(OD;;SWWP;{security.GUID_DRS_DNS_HOST_NAME};;' -+ f'{machine_sid})') -+ sd_utils.dacl_add_ace(self.machine_dn, mod) -+ -+ domain_hostname = self.ldb.domain_dns_name() -+ -+ new_dns_hostname = f'{self.machine_name}.{domain_hostname}' -+ new_dns_hostname = new_dns_hostname.encode('utf-8') -+ -+ query = netr_WorkstationInformation() -+ query.os_name = lsa.String('some OS') -+ query.dns_hostname = new_dns_hostname -+ -+ c.netr_LogonGetDomainInfo( -+ server_name=self.server, -+ computer_name=self.user_creds.get_workstation(), -+ credential=authenticator, -+ return_authenticator=subsequent, -+ level=1, -+ query=query) -+ -+ # Check the result. -+ -+ res = self.ldb.search(self.machine_dn, -+ scope=ldb.SCOPE_BASE, -+ attrs=['dNSHostName']) -+ self.assertEqual(1, len(res)) -+ -+ got_dns_hostname = res[0].get('dNSHostName', idx=0) -+ self.assertEqual(new_dns_hostname, got_dns_hostname) -+ -+ # Ensure we can't use LogonGetDomainInfo to update dNSHostName to an -+ # invalid value, even with Validated Write. -+ def test_set_dns_hostname_invalid_validated_write(self): -+ c = self.get_netlogon_connection() -+ authenticator, subsequent = self.get_authenticator(c) -+ -+ res = self.ldb.search(self.machine_dn, -+ scope=ldb.SCOPE_BASE, -+ attrs=['objectSid']) -+ self.assertEqual(1, len(res)) -+ -+ machine_sid = ndr_unpack(security.dom_sid, -+ res[0].get('objectSid', idx=0)) -+ -+ sd_utils = SDUtils(self.ldb) -+ -+ # Grant Validated Write. -+ mod = (f'(OA;;SW;{security.GUID_DRS_DNS_HOST_NAME};;' -+ f'{machine_sid})') -+ sd_utils.dacl_add_ace(self.machine_dn, mod) -+ -+ new_dns_hostname = b'invalid' -+ -+ query = netr_WorkstationInformation() -+ query.os_name = lsa.String('some OS') -+ query.dns_hostname = new_dns_hostname -+ -+ c.netr_LogonGetDomainInfo( -+ server_name=self.server, -+ computer_name=self.user_creds.get_workstation(), -+ credential=authenticator, -+ return_authenticator=subsequent, -+ level=1, -+ query=query) -+ -+ # Check the result. -+ -+ res = self.ldb.search(self.machine_dn, -+ scope=ldb.SCOPE_BASE, -+ attrs=['dNSHostName']) -+ self.assertEqual(1, len(res)) -+ -+ got_dns_hostname = res[0].get('dNSHostName', idx=0) -+ self.assertIsNone(got_dns_hostname) -+ -+ # Ensure we can't use LogonGetDomainInfo to update dNSHostName to an -+ # invalid value, even with Write Property. -+ def test_set_dns_hostname_invalid_write_property(self): -+ c = self.get_netlogon_connection() -+ authenticator, subsequent = self.get_authenticator(c) -+ -+ res = self.ldb.search(self.machine_dn, -+ scope=ldb.SCOPE_BASE, -+ attrs=['objectSid']) -+ self.assertEqual(1, len(res)) -+ -+ machine_sid = ndr_unpack(security.dom_sid, -+ res[0].get('objectSid', idx=0)) -+ -+ sd_utils = SDUtils(self.ldb) -+ -+ # Grant Write Property. -+ mod = (f'(OA;;WP;{security.GUID_DRS_DNS_HOST_NAME};;' -+ f'{machine_sid})') -+ sd_utils.dacl_add_ace(self.machine_dn, mod) -+ -+ new_dns_hostname = b'invalid' -+ -+ query = netr_WorkstationInformation() -+ query.os_name = lsa.String('some OS') -+ query.dns_hostname = new_dns_hostname -+ -+ c.netr_LogonGetDomainInfo( -+ server_name=self.server, -+ computer_name=self.user_creds.get_workstation(), -+ credential=authenticator, -+ return_authenticator=subsequent, -+ level=1, -+ query=query) -+ -+ # Check the result. -+ -+ res = self.ldb.search(self.machine_dn, -+ scope=ldb.SCOPE_BASE, -+ attrs=['dNSHostName']) -+ self.assertEqual(1, len(res)) -+ -+ got_dns_hostname = res[0].get('dNSHostName', idx=0) -+ self.assertIsNone(got_dns_hostname) -+ -+ # Show we can't use LogonGetDomainInfo to set the dNSHostName to just the -+ # machine name. -+ def test_set_dns_hostname_to_machine_name(self): -+ c = self.get_netlogon_connection() -+ authenticator, subsequent = self.get_authenticator(c) -+ -+ new_dns_hostname = self.machine_name.encode('utf-8') -+ -+ query = netr_WorkstationInformation() -+ query.os_name = lsa.String('some OS') -+ query.dns_hostname = new_dns_hostname -+ -+ c.netr_LogonGetDomainInfo( -+ server_name=self.server, -+ computer_name=self.user_creds.get_workstation(), -+ credential=authenticator, -+ return_authenticator=subsequent, -+ level=1, -+ query=query) -+ -+ # Check the result. -+ -+ res = self.ldb.search(self.machine_dn, -+ scope=ldb.SCOPE_BASE, -+ attrs=['dNSHostName']) -+ self.assertEqual(1, len(res)) -+ -+ got_dns_hostname = res[0].get('dNSHostName', idx=0) -+ self.assertIsNone(got_dns_hostname) -+ -+ # Show we can't use LogonGetDomainInfo to set dNSHostName with an invalid -+ # suffix. -+ def test_set_dns_hostname_invalid_suffix(self): -+ c = self.get_netlogon_connection() -+ authenticator, subsequent = self.get_authenticator(c) -+ -+ domain_hostname = self.ldb.domain_dns_name() -+ -+ new_dns_hostname = f'{self.machine_name}.foo.{domain_hostname}' -+ new_dns_hostname = new_dns_hostname.encode('utf-8') -+ -+ query = netr_WorkstationInformation() -+ query.os_name = lsa.String('some OS') -+ query.dns_hostname = new_dns_hostname -+ -+ c.netr_LogonGetDomainInfo( -+ server_name=self.server, -+ computer_name=self.user_creds.get_workstation(), -+ credential=authenticator, -+ return_authenticator=subsequent, -+ level=1, -+ query=query) -+ -+ # Check the result. -+ -+ res = self.ldb.search(self.machine_dn, -+ scope=ldb.SCOPE_BASE, -+ attrs=['dNSHostName']) -+ self.assertEqual(1, len(res)) -+ -+ got_dns_hostname = res[0].get('dNSHostName', idx=0) -+ self.assertIsNone(got_dns_hostname) -+ -+ # Test that setting the HANDLES_SPN_UPDATE flag inhibits the dNSHostName -+ # update, but other attributes are still updated. -+ def test_set_dns_hostname_with_flag(self): -+ c = self.get_netlogon_connection() -+ authenticator, subsequent = self.get_authenticator(c) -+ -+ domain_hostname = self.ldb.domain_dns_name() -+ -+ new_dns_hostname = f'{self.machine_name}.{domain_hostname}' -+ new_dns_hostname = new_dns_hostname.encode('utf-8') -+ -+ operating_system = 'some OS' -+ -+ query = netr_WorkstationInformation() -+ query.os_name = lsa.String(operating_system) -+ -+ query.dns_hostname = new_dns_hostname -+ query.workstation_flags = netlogon.NETR_WS_FLAG_HANDLES_SPN_UPDATE -+ -+ c.netr_LogonGetDomainInfo( -+ server_name=self.server, -+ computer_name=self.user_creds.get_workstation(), -+ credential=authenticator, -+ return_authenticator=subsequent, -+ level=1, -+ query=query) -+ -+ # Check the result. -+ -+ res = self.ldb.search(self.machine_dn, -+ scope=ldb.SCOPE_BASE, -+ attrs=['dNSHostName', -+ 'operatingSystem']) -+ self.assertEqual(1, len(res)) -+ -+ got_dns_hostname = res[0].get('dNSHostName', idx=0) -+ self.assertIsNone(got_dns_hostname) -+ -+ got_os = res[0].get('operatingSystem', idx=0) -+ self.assertEqual(operating_system.encode('utf-8'), got_os) -+ - def test_SamLogonEx(self): - c = self.get_netlogon_connection() - -diff --git a/selftest/knownfail.d/netlogon-dns-host-name b/selftest/knownfail.d/netlogon-dns-host-name -new file mode 100644 -index 0000000..2d0a0ec ---- /dev/null -+++ b/selftest/knownfail.d/netlogon-dns-host-name -@@ -0,0 +1,2 @@ -+^samba.tests.py_credentials.samba.tests.py_credentials.PyCredentialsTests.test_set_dns_hostname_invalid_suffix\( -+^samba.tests.py_credentials.samba.tests.py_credentials.PyCredentialsTests.test_set_dns_hostname_with_flag\( --- -1.8.3.1 - diff --git a/0003-CVE-2022-32743-s4-torture-rpc-Fix-tests-to-match-Win.patch b/0003-CVE-2022-32743-s4-torture-rpc-Fix-tests-to-match-Win.patch deleted file mode 100644 index a85579891220ddbab0bbd64c070a352950259d00..0000000000000000000000000000000000000000 --- a/0003-CVE-2022-32743-s4-torture-rpc-Fix-tests-to-match-Win.patch +++ /dev/null @@ -1,65 +0,0 @@ -From e38b75a50f79c1d1ea2d7d4489896ca5aa16d9d9 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Tue, 14 Jun 2022 17:19:00 +1200 -Subject: [PATCH 03/15] CVE-2022-32743 s4:torture/rpc: Fix tests to match - Windows - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14833 - -Signed-off-by: Joseph Sutton -Reviewed-by: Douglas Bagnall ---- - selftest/knownfail.d/netlogon-dns-host-name | 9 +++++++++ - source4/torture/rpc/netlogon.c | 12 +++++++----- - 2 files changed, 16 insertions(+), 5 deletions(-) - -diff --git a/selftest/knownfail.d/netlogon-dns-host-name b/selftest/knownfail.d/netlogon-dns-host-name -index 2d0a0ec..0164a7c 100644 ---- a/selftest/knownfail.d/netlogon-dns-host-name -+++ b/selftest/knownfail.d/netlogon-dns-host-name -@@ -1,2 +1,11 @@ - ^samba.tests.py_credentials.samba.tests.py_credentials.PyCredentialsTests.test_set_dns_hostname_invalid_suffix\( - ^samba.tests.py_credentials.samba.tests.py_credentials.PyCredentialsTests.test_set_dns_hostname_with_flag\( -+^samba4.rpc.netlogon on ncacn_ip_tcp with bigendian.netlogon.GetDomainInfo\( -+^samba4.rpc.netlogon on ncacn_ip_tcp with seal,padcheck.netlogon.GetDomainInfo\( -+^samba4.rpc.netlogon on ncacn_ip_tcp with validate.netlogon.GetDomainInfo\( -+^samba4.rpc.netlogon on ncacn_np with bigendian.netlogon.GetDomainInfo\( -+^samba4.rpc.netlogon on ncacn_np with seal,padcheck.netlogon.GetDomainInfo\( -+^samba4.rpc.netlogon on ncacn_np with validate.netlogon.GetDomainInfo\( -+^samba4.rpc.netlogon with bigendian.netlogon.GetDomainInfo\( -+^samba4.rpc.netlogon with seal,padcheck.netlogon.GetDomainInfo\( -+^samba4.rpc.netlogon with validate.netlogon.GetDomainInfo\( -diff --git a/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c -index 11f950d..59d7feb 100644 ---- a/source4/torture/rpc/netlogon.c -+++ b/source4/torture/rpc/netlogon.c -@@ -5251,9 +5251,9 @@ static bool test_GetDomainInfo(struct torture_context *tctx, - torture_assert(tctx, - ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL, - "'operatingSystemServicePack' shouldn't stick!"); -- torture_assert(tctx, -- ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL) == NULL, -- "'operatingSystemVersion' shouldn't stick!"); -+ torture_assert_str_equal(tctx, -+ ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL), -+ version_str, "'operatingSystemVersion' wrong!"); - - /* The DNS host name shouldn't have been updated by the server */ - -@@ -5387,9 +5387,11 @@ static bool test_GetDomainInfo(struct torture_context *tctx, - - torture_assert(tctx, odiT->domainname.string != NULL, - "trust_list domainname should be valid"); -- if (texT->trust_type == LSA_TRUST_TYPE_DOWNLEVEL) { -+ if (texT->trust_type == LSA_TRUST_TYPE_DOWNLEVEL || -+ texT->trust_type == LSA_TRUST_TYPE_MIT) -+ { - torture_assert(tctx, odiT->dns_domainname.string == NULL, -- "trust_list dns_domainname should be NULL for downlevel"); -+ "trust_list dns_domainname should be NULL for downlevel or MIT"); - } else { - torture_assert(tctx, odiT->dns_domainname.string != NULL, - "trust_list dns_domainname should be valid for uplevel"); --- -1.8.3.1 - diff --git a/0004-CVE-2022-32743-s4-dsdb-util-Add-dsdb_msg_get_single_.patch b/0004-CVE-2022-32743-s4-dsdb-util-Add-dsdb_msg_get_single_.patch deleted file mode 100644 index 0379186addc198f7c316053b1829eabf6770c34d..0000000000000000000000000000000000000000 --- a/0004-CVE-2022-32743-s4-dsdb-util-Add-dsdb_msg_get_single_.patch +++ /dev/null @@ -1,140 +0,0 @@ -From 49ac07e786df58b914ee85e2db773c0ba8d4e171 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Tue, 7 Jun 2022 17:36:56 +1200 -Subject: [PATCH 04/15] CVE-2022-32743 s4/dsdb/util: Add - dsdb_msg_get_single_value() - -This function simulates an add or modify operation for an ldb message to -determine the final value of a particular single-valued attribute. This -is useful when validating attributes that should stay in sync with other -attributes, such as servicePrincipalName and dNSHostName. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14833 - -Signed-off-by: Joseph Sutton -Reviewed-by: Douglas Bagnall ---- - source4/dsdb/samdb/ldb_modules/util.c | 107 ++++++++++++++++++++++++++++++++++ - 1 file changed, 107 insertions(+) - -diff --git a/source4/dsdb/samdb/ldb_modules/util.c b/source4/dsdb/samdb/ldb_modules/util.c -index e7fe8f8..42aa9a2 100644 ---- a/source4/dsdb/samdb/ldb_modules/util.c -+++ b/source4/dsdb/samdb/ldb_modules/util.c -@@ -1568,6 +1568,113 @@ int dsdb_get_expected_new_values(TALLOC_CTX *mem_ctx, - return LDB_SUCCESS; - } - -+ -+/* -+ * Get the value of a single-valued attribute from an ADDed message. 'val' will only live as -+ * long as 'msg' and 'original_val' do, and must not be freed. -+ */ -+int dsdb_msg_add_get_single_value(const struct ldb_message *msg, -+ const char *attr_name, -+ const struct ldb_val **val) -+{ -+ const struct ldb_message_element *el = NULL; -+ -+ /* -+ * The ldb_msg_normalize() call in ldb_request() ensures that -+ * there is at most one message element for each -+ * attribute. Thus, we don't need a loop to deal with an -+ * LDB_ADD. -+ */ -+ el = ldb_msg_find_element(msg, attr_name); -+ if (el == NULL) { -+ *val = NULL; -+ return LDB_SUCCESS; -+ } -+ if (el->num_values != 1) { -+ return LDB_ERR_CONSTRAINT_VIOLATION; -+ } -+ -+ *val = &el->values[0]; -+ return LDB_SUCCESS; -+} -+ -+/* -+ * Get the value of a single-valued attribute after processing a -+ * message. 'operation' is either LDB_ADD or LDB_MODIFY. 'val' will only live as -+ * long as 'msg' and 'original_val' do, and must not be freed. -+ */ -+int dsdb_msg_get_single_value(const struct ldb_message *msg, -+ const char *attr_name, -+ const struct ldb_val *original_val, -+ const struct ldb_val **val, -+ enum ldb_request_type operation) -+{ -+ unsigned idx; -+ -+ *val = NULL; -+ -+ if (operation == LDB_ADD) { -+ if (original_val != NULL) { -+ /* This is an error on the caller's part. */ -+ return LDB_ERR_CONSTRAINT_VIOLATION; -+ } -+ return dsdb_msg_add_get_single_value(msg, attr_name, val); -+ } -+ -+ SMB_ASSERT(operation == LDB_MODIFY); -+ -+ *val = original_val; -+ -+ for (idx = 0; idx < msg->num_elements; ++idx) { -+ const struct ldb_message_element *el = &msg->elements[idx]; -+ -+ if (ldb_attr_cmp(el->name, attr_name) != 0) { -+ continue; -+ } -+ -+ switch (el->flags & LDB_FLAG_MOD_MASK) { -+ case LDB_FLAG_MOD_ADD: -+ if (el->num_values != 1) { -+ return LDB_ERR_CONSTRAINT_VIOLATION; -+ } -+ if (*val != NULL) { -+ return LDB_ERR_CONSTRAINT_VIOLATION; -+ } -+ -+ *val = &el->values[0]; -+ -+ break; -+ -+ case LDB_FLAG_MOD_REPLACE: -+ if (el->num_values > 1) { -+ return LDB_ERR_CONSTRAINT_VIOLATION; -+ } -+ -+ *val = el->num_values ? &el->values[0] : NULL; -+ -+ break; -+ -+ case LDB_FLAG_MOD_DELETE: -+ if (el->num_values > 1) { -+ return LDB_ERR_CONSTRAINT_VIOLATION; -+ } -+ -+ /* -+ * If a value was specified for the delete, we don't -+ * bother checking it matches the value we currently -+ * have. Any mismatch will be caught later (e.g. in -+ * ldb_kv_modify_internal). -+ */ -+ -+ *val = NULL; -+ -+ break; -+ } -+ } -+ -+ return LDB_SUCCESS; -+} -+ - /* - * This function determines the (last) structural or 88 object class of a passed - * "objectClass" attribute - per MS-ADTS 3.1.1.1.4 this is the last value. --- -1.8.3.1 - diff --git a/0005-CVE-2022-32743-s4-dsdb-util-Add-function-to-check-fo.patch b/0005-CVE-2022-32743-s4-dsdb-util-Add-function-to-check-fo.patch deleted file mode 100644 index 6e42c0871de99838652b03a435e7932b2d62dee6..0000000000000000000000000000000000000000 --- a/0005-CVE-2022-32743-s4-dsdb-util-Add-function-to-check-fo.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 0d888f0c902ebd98cfb82d50ab8b8b3928341ee2 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Tue, 14 Jun 2022 14:16:10 +1200 -Subject: [PATCH 05/15] CVE-2022-32743 s4/dsdb/util: Add function to check for - a subclass relationship - -We need to be able to determine whether an object is a subclass of a -specific objectclass such as 'computer'. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14833 - -Signed-off-by: Joseph Sutton -Reviewed-by: Douglas Bagnall ---- - source4/dsdb/samdb/ldb_modules/util.c | 38 +++++++++++++++++++++++++++++++++++ - 1 file changed, 38 insertions(+) - -diff --git a/source4/dsdb/samdb/ldb_modules/util.c b/source4/dsdb/samdb/ldb_modules/util.c -index 42aa9a2..9e00aed 100644 ---- a/source4/dsdb/samdb/ldb_modules/util.c -+++ b/source4/dsdb/samdb/ldb_modules/util.c -@@ -1718,6 +1718,44 @@ const struct dsdb_class *dsdb_get_structural_oc_from_msg(const struct dsdb_schem - return dsdb_get_last_structural_class(schema, oc_el); - } - -+/* -+ Get the parent class of an objectclass, or NULL if none exists. -+ */ -+const struct dsdb_class *dsdb_get_parent_class(const struct dsdb_schema *schema, -+ const struct dsdb_class *objectclass) -+{ -+ if (ldb_attr_cmp(objectclass->lDAPDisplayName, "top") == 0) { -+ return NULL; -+ } -+ -+ if (objectclass->subClassOf == NULL) { -+ return NULL; -+ } -+ -+ return dsdb_class_by_lDAPDisplayName(schema, objectclass->subClassOf); -+} -+ -+/* -+ Return true if 'struct_objectclass' is a subclass of 'other_objectclass'. The -+ two objectclasses must originate from the same schema, to allow for -+ pointer-based identity comparison. -+ */ -+bool dsdb_is_subclass_of(const struct dsdb_schema *schema, -+ const struct dsdb_class *struct_objectclass, -+ const struct dsdb_class *other_objectclass) -+{ -+ while (struct_objectclass != NULL) { -+ /* Pointer comparison can be used due to the same schema str. */ -+ if (struct_objectclass == other_objectclass) { -+ return true; -+ } -+ -+ struct_objectclass = dsdb_get_parent_class(schema, struct_objectclass); -+ } -+ -+ return false; -+} -+ - /* Fix the DN so that the relative attribute names are in upper case so that the DN: - cn=Adminstrator,cn=users,dc=samba,dc=example,dc=com becomes - CN=Adminstrator,CN=users,DC=samba,DC=example,DC=com --- -1.8.3.1 - diff --git a/0006-CVE-2022-32743-dsdb-Implement-validated-dNSHostName-.patch b/0006-CVE-2022-32743-dsdb-Implement-validated-dNSHostName-.patch deleted file mode 100644 index 7774a2b5fdaa60140513165ac5f56e865045e1a7..0000000000000000000000000000000000000000 --- a/0006-CVE-2022-32743-dsdb-Implement-validated-dNSHostName-.patch +++ /dev/null @@ -1,339 +0,0 @@ -From b95431ab2303eb258e37e88d8841f2fb79fc4af5 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Wed, 1 Jun 2022 16:08:42 +1200 -Subject: [PATCH 06/15] CVE-2022-32743 dsdb: Implement validated dNSHostName - write - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14833 - -Signed-off-by: Joseph Sutton -Reviewed-by: Douglas Bagnall ---- - selftest/knownfail.d/validated-dns-host-name | 12 -- - source4/dsdb/samdb/ldb_modules/acl.c | 283 +++++++++++++++++++++++++++ - 2 files changed, 283 insertions(+), 12 deletions(-) - -diff --git a/selftest/knownfail.d/validated-dns-host-name b/selftest/knownfail.d/validated-dns-host-name -index ee51f44..4b61658 100644 ---- a/selftest/knownfail.d/validated-dns-host-name -+++ b/selftest/knownfail.d/validated-dns-host-name -@@ -1,15 +1,3 @@ --^samba4.ldap.acl.python.*__main__.AclModifyTests.test_modify_dns_host_name\( --^samba4.ldap.acl.python.*__main__.AclModifyTests.test_modify_dns_host_name_account_no_dollar\( --^samba4.ldap.acl.python.*__main__.AclModifyTests.test_modify_dns_host_name_allowed_suffixes\( --^samba4.ldap.acl.python.*__main__.AclModifyTests.test_modify_dns_host_name_case\( --^samba4.ldap.acl.python.*__main__.AclModifyTests.test_modify_dns_host_name_dollar\( --^samba4.ldap.acl.python.*__main__.AclModifyTests.test_modify_dns_host_name_empty_string\( --^samba4.ldap.acl.python.*__main__.AclModifyTests.test_modify_dns_host_name_invalid\( --^samba4.ldap.acl.python.*__main__.AclModifyTests.test_modify_dns_host_name_no_suffix\( --^samba4.ldap.acl.python.*__main__.AclModifyTests.test_modify_dns_host_name_no_value\( - ^samba4.ldap.acl.python.*__main__.AclModifyTests.test_modify_dns_host_name_spn\( - ^samba4.ldap.acl.python.*__main__.AclModifyTests.test_modify_dns_host_name_spn_matching_account_name_new\( --^samba4.ldap.acl.python.*__main__.AclModifyTests.test_modify_dns_host_name_spn_matching_account_name_original\( --^samba4.ldap.acl.python.*__main__.AclModifyTests.test_modify_dns_host_name_wrong_prefix\( --^samba4.ldap.acl.python.*__main__.AclModifyTests.test_modify_dns_host_name_wrong_suffix\( - ^samba4.ldap.acl.python.*__main__.AclModifyTests.test_modify_spn_matching_dns_host_name_invalid\( -diff --git a/source4/dsdb/samdb/ldb_modules/acl.c b/source4/dsdb/samdb/ldb_modules/acl.c -index 1fc6dbf..50802ae 100644 ---- a/source4/dsdb/samdb/ldb_modules/acl.c -+++ b/source4/dsdb/samdb/ldb_modules/acl.c -@@ -802,6 +802,277 @@ static int acl_check_spn(TALLOC_CTX *mem_ctx, - return LDB_SUCCESS; - } - -+static int acl_check_dns_host_name(TALLOC_CTX *mem_ctx, -+ struct ldb_module *module, -+ struct ldb_request *req, -+ const struct ldb_message_element *el, -+ struct security_descriptor *sd, -+ struct dom_sid *sid, -+ const struct dsdb_attribute *attr, -+ const struct dsdb_class *objectclass) -+{ -+ int ret; -+ unsigned i; -+ TALLOC_CTX *tmp_ctx = NULL; -+ struct ldb_context *ldb = ldb_module_get_ctx(module); -+ const struct dsdb_schema *schema = NULL; -+ const struct ldb_message_element *allowed_suffixes = NULL; -+ struct ldb_result *nc_res = NULL; -+ struct ldb_dn *nc_root = NULL; -+ const char *nc_dns_name = NULL; -+ const char *dnsHostName_str = NULL; -+ size_t dns_host_name_len; -+ size_t account_name_len; -+ const struct ldb_message *msg = NULL; -+ const struct ldb_message *search_res = NULL; -+ const struct ldb_val *samAccountName = NULL; -+ const struct ldb_val *dnsHostName = NULL; -+ const struct dsdb_class *computer_objectclass = NULL; -+ bool is_subclass; -+ -+ static const char *nc_attrs[] = { -+ "msDS-AllowedDNSSuffixes", -+ NULL -+ }; -+ -+ if (el->num_values == 0) { -+ return LDB_SUCCESS; -+ } -+ dnsHostName = &el->values[0]; -+ -+ tmp_ctx = talloc_new(mem_ctx); -+ if (tmp_ctx == NULL) { -+ return ldb_oom(ldb); -+ } -+ -+ /* if we have wp, we can do whatever we like */ -+ ret = acl_check_access_on_attribute(module, -+ tmp_ctx, -+ sd, -+ sid, -+ SEC_ADS_WRITE_PROP, -+ attr, objectclass); -+ if (ret == LDB_SUCCESS) { -+ talloc_free(tmp_ctx); -+ return LDB_SUCCESS; -+ } -+ -+ ret = acl_check_extended_right(tmp_ctx, -+ module, -+ req, -+ objectclass, -+ sd, -+ acl_user_token(module), -+ GUID_DRS_DNS_HOST_NAME, -+ SEC_ADS_SELF_WRITE, -+ sid); -+ -+ if (ret != LDB_SUCCESS) { -+ dsdb_acl_debug(sd, acl_user_token(module), -+ req->op.mod.message->dn, -+ true, -+ 10); -+ talloc_free(tmp_ctx); -+ return ret; -+ } -+ -+ /* -+ * If we have "validated write dnshostname", allow delete of -+ * any existing value (this keeps constrained delete to the -+ * same rules as unconstrained) -+ */ -+ if (req->operation == LDB_MODIFY) { -+ struct ldb_result *acl_res = NULL; -+ -+ static const char *acl_attrs[] = { -+ "sAMAccountName", -+ NULL -+ }; -+ -+ msg = req->op.mod.message; -+ -+ /* -+ * If not add or replace (eg delete), -+ * return success -+ */ -+ if ((el->flags -+ & (LDB_FLAG_MOD_ADD|LDB_FLAG_MOD_REPLACE)) == 0) -+ { -+ talloc_free(tmp_ctx); -+ return LDB_SUCCESS; -+ } -+ -+ ret = dsdb_module_search_dn(module, tmp_ctx, -+ &acl_res, msg->dn, -+ acl_attrs, -+ DSDB_FLAG_NEXT_MODULE | -+ DSDB_FLAG_AS_SYSTEM | -+ DSDB_SEARCH_SHOW_RECYCLED, -+ req); -+ if (ret != LDB_SUCCESS) { -+ talloc_free(tmp_ctx); -+ return ret; -+ } -+ -+ search_res = acl_res->msgs[0]; -+ } else if (req->operation == LDB_ADD) { -+ msg = req->op.add.message; -+ search_res = msg; -+ } else { -+ talloc_free(tmp_ctx); -+ return LDB_ERR_OPERATIONS_ERROR; -+ } -+ -+ /* Check if the account has objectclass 'computer' or 'server'. */ -+ -+ schema = dsdb_get_schema(ldb, req); -+ if (schema == NULL) { -+ talloc_free(tmp_ctx); -+ return ldb_operr(ldb); -+ } -+ -+ computer_objectclass = dsdb_class_by_lDAPDisplayName(schema, "computer"); -+ if (computer_objectclass == NULL) { -+ talloc_free(tmp_ctx); -+ return ldb_operr(ldb); -+ } -+ -+ is_subclass = dsdb_is_subclass_of(schema, objectclass, computer_objectclass); -+ if (!is_subclass) { -+ /* The account is not a computer -- check if it's a server. */ -+ -+ const struct dsdb_class *server_objectclass = NULL; -+ -+ server_objectclass = dsdb_class_by_lDAPDisplayName(schema, "server"); -+ if (server_objectclass == NULL) { -+ talloc_free(tmp_ctx); -+ return ldb_operr(ldb); -+ } -+ -+ is_subclass = dsdb_is_subclass_of(schema, objectclass, server_objectclass); -+ if (!is_subclass) { -+ /* Not a computer or server, so no need to validate. */ -+ talloc_free(tmp_ctx); -+ return LDB_SUCCESS; -+ } -+ } -+ -+ samAccountName = ldb_msg_find_ldb_val(search_res, "sAMAccountName"); -+ -+ ret = dsdb_msg_get_single_value(msg, -+ "sAMAccountName", -+ samAccountName, -+ &samAccountName, -+ req->operation); -+ if (ret != LDB_SUCCESS) { -+ talloc_free(tmp_ctx); -+ return ret; -+ } -+ -+ account_name_len = samAccountName->length; -+ if (account_name_len && samAccountName->data[account_name_len - 1] == '$') { -+ /* Account for the '$' character. */ -+ --account_name_len; -+ } -+ -+ dnsHostName_str = (const char *)dnsHostName->data; -+ dns_host_name_len = dnsHostName->length; -+ -+ /* Check that sAMAccountName matches the new dNSHostName. */ -+ -+ if (dns_host_name_len < account_name_len) { -+ goto fail; -+ } -+ if (strncasecmp(dnsHostName_str, -+ (const char *)samAccountName->data, -+ account_name_len) != 0) -+ { -+ goto fail; -+ } -+ -+ dnsHostName_str += account_name_len; -+ dns_host_name_len -= account_name_len; -+ -+ /* Check the '.' character */ -+ -+ if (dns_host_name_len == 0 || *dnsHostName_str != '.') { -+ goto fail; -+ } -+ -+ ++dnsHostName_str; -+ --dns_host_name_len; -+ -+ /* Now we check the suffix. */ -+ -+ ret = dsdb_find_nc_root(ldb, -+ tmp_ctx, -+ search_res->dn, -+ &nc_root); -+ if (ret != LDB_SUCCESS) { -+ talloc_free(tmp_ctx); -+ return ret; -+ } -+ -+ nc_dns_name = samdb_dn_to_dns_domain(tmp_ctx, nc_root); -+ if (nc_dns_name == NULL) { -+ talloc_free(tmp_ctx); -+ return ldb_operr(ldb); -+ } -+ -+ if (strlen(nc_dns_name) == dns_host_name_len && -+ strncasecmp(dnsHostName_str, -+ nc_dns_name, -+ dns_host_name_len) == 0) -+ { -+ /* It matches -- success. */ -+ talloc_free(tmp_ctx); -+ return LDB_SUCCESS; -+ } -+ -+ /* We didn't get a match, so now try msDS-AllowedDNSSuffixes. */ -+ -+ ret = dsdb_module_search_dn(module, tmp_ctx, -+ &nc_res, nc_root, -+ nc_attrs, -+ DSDB_FLAG_NEXT_MODULE | -+ DSDB_FLAG_AS_SYSTEM | -+ DSDB_SEARCH_SHOW_RECYCLED, -+ req); -+ if (ret != LDB_SUCCESS) { -+ talloc_free(tmp_ctx); -+ return ret; -+ } -+ -+ allowed_suffixes = ldb_msg_find_element(nc_res->msgs[0], -+ "msDS-AllowedDNSSuffixes"); -+ if (allowed_suffixes == NULL) { -+ goto fail; -+ } -+ -+ for (i = 0; i < allowed_suffixes->num_values; ++i) { -+ const struct ldb_val *suffix = &allowed_suffixes->values[i]; -+ -+ if (suffix->length == dns_host_name_len && -+ strncasecmp(dnsHostName_str, -+ (const char *)suffix->data, -+ dns_host_name_len) == 0) -+ { -+ /* It matches -- success. */ -+ talloc_free(tmp_ctx); -+ return LDB_SUCCESS; -+ } -+ } -+ -+fail: -+ ldb_debug_set(ldb, LDB_DEBUG_WARNING, -+ "acl: hostname validation failed for " -+ "hostname[%.*s] account[%.*s]\n", -+ (int)dnsHostName->length, dnsHostName->data, -+ (int)samAccountName->length, samAccountName->data); -+ talloc_free(tmp_ctx); -+ return LDB_ERR_CONSTRAINT_VIOLATION; -+} -+ - static int acl_add(struct ldb_module *module, struct ldb_request *req) - { - int ret; -@@ -1536,6 +1807,18 @@ static int acl_modify(struct ldb_module *module, struct ldb_request *req) - if (ret != LDB_SUCCESS) { - goto fail; - } -+ } else if (ldb_attr_cmp("dnsHostName", el->name) == 0) { -+ ret = acl_check_dns_host_name(tmp_ctx, -+ module, -+ req, -+ el, -+ sd, -+ sid, -+ attr, -+ objectclass); -+ if (ret != LDB_SUCCESS) { -+ goto fail; -+ } - } else if (is_undelete != NULL && (ldb_attr_cmp("isDeleted", el->name) == 0)) { - /* - * in case of undelete op permissions on --- -1.8.3.1 - diff --git a/0007-CVE-2022-32743-dsdb-common-Add-FORCE_ALLOW_VALIDATED.patch b/0007-CVE-2022-32743-dsdb-common-Add-FORCE_ALLOW_VALIDATED.patch deleted file mode 100644 index d9e6bc3596106a3cfe961caae12d70d2b6ea4170..0000000000000000000000000000000000000000 --- a/0007-CVE-2022-32743-dsdb-common-Add-FORCE_ALLOW_VALIDATED.patch +++ /dev/null @@ -1,67 +0,0 @@ -From c2ab1f4696fa3f52918a126d0b37993a07f68bcb Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Tue, 7 Jun 2022 17:36:43 +1200 -Subject: [PATCH 07/15] CVE-2022-32743 dsdb/common: Add - FORCE_ALLOW_VALIDATED_DNS_HOSTNAME_SPN_WRITE control - -Passing this control will grant the right to set validated values for -dNSHostName and servicePrincipalName, and non-validated values for other -attributes. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14833 - -Signed-off-by: Joseph Sutton -Reviewed-by: Douglas Bagnall ---- - source4/dsdb/common/util.c | 7 +++++++ - source4/dsdb/samdb/ldb_modules/util.h | 1 + - source4/dsdb/samdb/samdb.h | 6 ++++++ - 3 files changed, 14 insertions(+) - -diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c -index 1129175..88b0555 100644 ---- a/source4/dsdb/common/util.c -+++ b/source4/dsdb/common/util.c -@@ -4546,6 +4546,13 @@ int dsdb_request_add_controls(struct ldb_request *req, uint32_t dsdb_flags) - } - } - -+ if (dsdb_flags & DSDB_FLAG_FORCE_ALLOW_VALIDATED_DNS_HOSTNAME_SPN_WRITE) { -+ ret = ldb_request_add_control(req, DSDB_CONTROL_FORCE_ALLOW_VALIDATED_DNS_HOSTNAME_SPN_WRITE_OID, true, NULL); -+ if (ret != LDB_SUCCESS) { -+ return ret; -+ } -+ } -+ - return LDB_SUCCESS; - } - -diff --git a/source4/dsdb/samdb/ldb_modules/util.h b/source4/dsdb/samdb/ldb_modules/util.h -index 5ecf0ee..937767a 100644 ---- a/source4/dsdb/samdb/ldb_modules/util.h -+++ b/source4/dsdb/samdb/ldb_modules/util.h -@@ -39,3 +39,4 @@ struct netlogon_samlogon_response; - #define DSDB_FLAG_TOP_MODULE 0x00800000 - #define DSDB_FLAG_TRUSTED 0x01000000 - #define DSDB_FLAG_REPLICATED_UPDATE 0x02000000 -+#define DSDB_FLAG_FORCE_ALLOW_VALIDATED_DNS_HOSTNAME_SPN_WRITE 0x04000000 -diff --git a/source4/dsdb/samdb/samdb.h b/source4/dsdb/samdb/samdb.h -index 286c97f..3db7704 100644 ---- a/source4/dsdb/samdb/samdb.h -+++ b/source4/dsdb/samdb/samdb.h -@@ -226,6 +226,12 @@ struct dsdb_control_transaction_identifier { - struct GUID transaction_guid; - }; - -+/* -+ * passed when we want to allow validated writes to dNSHostName and -+ * servicePrincipalName. -+ */ -+#define DSDB_CONTROL_FORCE_ALLOW_VALIDATED_DNS_HOSTNAME_SPN_WRITE_OID "1.3.6.1.4.1.7165.4.3.35" -+ - #define DSDB_EXTENDED_REPLICATED_OBJECTS_OID "1.3.6.1.4.1.7165.4.4.1" - struct dsdb_extended_replicated_object { - struct ldb_message *msg; --- -1.8.3.1 - diff --git a/0008-CVE-2022-32743-dsdb-modules-acl-Handle-FORCE_ALLOW_V.patch b/0008-CVE-2022-32743-dsdb-modules-acl-Handle-FORCE_ALLOW_V.patch deleted file mode 100644 index 583dbbc3bf6992f04ecb9f898521f3ae0d14ea51..0000000000000000000000000000000000000000 --- a/0008-CVE-2022-32743-dsdb-modules-acl-Handle-FORCE_ALLOW_V.patch +++ /dev/null @@ -1,240 +0,0 @@ -From f9831259b9f6a49b9e1a7be75198d60374cdef2f Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Tue, 7 Jun 2022 17:39:07 +1200 -Subject: [PATCH 08/15] CVE-2022-32743 dsdb/modules/acl: Handle - FORCE_ALLOW_VALIDATED_DNS_HOSTNAME_SPN_WRITE control - -When this control is specified, we'll assume we have Validated Write on -dNSHostName and servicePrincipalName, and Write Property on other -attributes. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14833 - -Signed-off-by: Joseph Sutton -Reviewed-by: Douglas Bagnall ---- - source4/dsdb/samdb/ldb_modules/acl.c | 148 +++++++++++++++++++++-------------- - 1 file changed, 91 insertions(+), 57 deletions(-) - -diff --git a/source4/dsdb/samdb/ldb_modules/acl.c b/source4/dsdb/samdb/ldb_modules/acl.c -index 50802ae..a26d0ba 100644 ---- a/source4/dsdb/samdb/ldb_modules/acl.c -+++ b/source4/dsdb/samdb/ldb_modules/acl.c -@@ -667,7 +667,8 @@ static int acl_check_spn(TALLOC_CTX *mem_ctx, - struct security_descriptor *sd, - struct dom_sid *sid, - const struct dsdb_attribute *attr, -- const struct dsdb_class *objectclass) -+ const struct dsdb_class *objectclass, -+ const struct ldb_control *implicit_validated_write_control) - { - int ret; - unsigned int i; -@@ -694,34 +695,44 @@ static int acl_check_spn(TALLOC_CTX *mem_ctx, - NULL - }; - -- /* if we have wp, we can do whatever we like */ -- if (acl_check_access_on_attribute(module, -- tmp_ctx, -- sd, -- sid, -- SEC_ADS_WRITE_PROP, -- attr, objectclass) == LDB_SUCCESS) { -- talloc_free(tmp_ctx); -- return LDB_SUCCESS; -- } -+ if (implicit_validated_write_control != NULL) { -+ /* -+ * The validated write control dispenses with ACL -+ * checks. We act as if we have an implicit Self Write -+ * privilege, but, assuming we don't have Write -+ * Property, still proceed with further validation -+ * checks. -+ */ -+ } else { -+ /* if we have wp, we can do whatever we like */ -+ if (acl_check_access_on_attribute(module, -+ tmp_ctx, -+ sd, -+ sid, -+ SEC_ADS_WRITE_PROP, -+ attr, objectclass) == LDB_SUCCESS) { -+ talloc_free(tmp_ctx); -+ return LDB_SUCCESS; -+ } - -- ret = acl_check_extended_right(tmp_ctx, -- module, -- req, -- objectclass, -- sd, -- acl_user_token(module), -- GUID_DRS_VALIDATE_SPN, -- SEC_ADS_SELF_WRITE, -- sid); -+ ret = acl_check_extended_right(tmp_ctx, -+ module, -+ req, -+ objectclass, -+ sd, -+ acl_user_token(module), -+ GUID_DRS_VALIDATE_SPN, -+ SEC_ADS_SELF_WRITE, -+ sid); - -- if (ret != LDB_SUCCESS) { -- dsdb_acl_debug(sd, acl_user_token(module), -- req->op.mod.message->dn, -- true, -- 10); -- talloc_free(tmp_ctx); -- return ret; -+ if (ret != LDB_SUCCESS) { -+ dsdb_acl_debug(sd, acl_user_token(module), -+ req->op.mod.message->dn, -+ true, -+ 10); -+ talloc_free(tmp_ctx); -+ return ret; -+ } - } - - /* -@@ -809,7 +820,8 @@ static int acl_check_dns_host_name(TALLOC_CTX *mem_ctx, - struct security_descriptor *sd, - struct dom_sid *sid, - const struct dsdb_attribute *attr, -- const struct dsdb_class *objectclass) -+ const struct dsdb_class *objectclass, -+ const struct ldb_control *implicit_validated_write_control) - { - int ret; - unsigned i; -@@ -845,35 +857,45 @@ static int acl_check_dns_host_name(TALLOC_CTX *mem_ctx, - return ldb_oom(ldb); - } - -- /* if we have wp, we can do whatever we like */ -- ret = acl_check_access_on_attribute(module, -- tmp_ctx, -- sd, -- sid, -- SEC_ADS_WRITE_PROP, -- attr, objectclass); -- if (ret == LDB_SUCCESS) { -- talloc_free(tmp_ctx); -- return LDB_SUCCESS; -- } -+ if (implicit_validated_write_control != NULL) { -+ /* -+ * The validated write control dispenses with ACL -+ * checks. We act as if we have an implicit Self Write -+ * privilege, but, assuming we don't have Write -+ * Property, still proceed with further validation -+ * checks. -+ */ -+ } else { -+ /* if we have wp, we can do whatever we like */ -+ ret = acl_check_access_on_attribute(module, -+ tmp_ctx, -+ sd, -+ sid, -+ SEC_ADS_WRITE_PROP, -+ attr, objectclass); -+ if (ret == LDB_SUCCESS) { -+ talloc_free(tmp_ctx); -+ return LDB_SUCCESS; -+ } - -- ret = acl_check_extended_right(tmp_ctx, -- module, -- req, -- objectclass, -- sd, -- acl_user_token(module), -- GUID_DRS_DNS_HOST_NAME, -- SEC_ADS_SELF_WRITE, -- sid); -+ ret = acl_check_extended_right(tmp_ctx, -+ module, -+ req, -+ objectclass, -+ sd, -+ acl_user_token(module), -+ GUID_DRS_DNS_HOST_NAME, -+ SEC_ADS_SELF_WRITE, -+ sid); - -- if (ret != LDB_SUCCESS) { -- dsdb_acl_debug(sd, acl_user_token(module), -- req->op.mod.message->dn, -- true, -- 10); -- talloc_free(tmp_ctx); -- return ret; -+ if (ret != LDB_SUCCESS) { -+ dsdb_acl_debug(sd, acl_user_token(module), -+ req->op.mod.message->dn, -+ true, -+ 10); -+ talloc_free(tmp_ctx); -+ return ret; -+ } - } - - /* -@@ -1621,6 +1643,7 @@ static int acl_modify(struct ldb_module *module, struct ldb_request *req) - struct dom_sid *sid = NULL; - struct ldb_control *as_system; - struct ldb_control *is_undelete; -+ struct ldb_control *implicit_validated_write_control = NULL; - bool userPassword; - bool password_rights_checked = false; - TALLOC_CTX *tmp_ctx; -@@ -1647,6 +1670,12 @@ static int acl_modify(struct ldb_module *module, struct ldb_request *req) - - is_undelete = ldb_request_get_control(req, DSDB_CONTROL_RESTORE_TOMBSTONE_OID); - -+ implicit_validated_write_control = ldb_request_get_control( -+ req, DSDB_CONTROL_FORCE_ALLOW_VALIDATED_DNS_HOSTNAME_SPN_WRITE_OID); -+ if (implicit_validated_write_control != NULL) { -+ implicit_validated_write_control->critical = 0; -+ } -+ - /* Don't print this debug statement if elements[0].name is going to be NULL */ - if (msg->num_elements > 0) { - DEBUG(10, ("ldb:acl_modify: %s\n", msg->elements[0].name)); -@@ -1803,7 +1832,8 @@ static int acl_modify(struct ldb_module *module, struct ldb_request *req) - sd, - sid, - attr, -- objectclass); -+ objectclass, -+ implicit_validated_write_control); - if (ret != LDB_SUCCESS) { - goto fail; - } -@@ -1815,7 +1845,8 @@ static int acl_modify(struct ldb_module *module, struct ldb_request *req) - sd, - sid, - attr, -- objectclass); -+ objectclass, -+ implicit_validated_write_control); - if (ret != LDB_SUCCESS) { - goto fail; - } -@@ -1827,6 +1858,9 @@ static int acl_modify(struct ldb_module *module, struct ldb_request *req) - * tombstone_reanimate module - */ - continue; -+ } else if (implicit_validated_write_control != NULL) { -+ /* Allow the update. */ -+ continue; - } else { - ret = acl_check_access_on_attribute(module, - tmp_ctx, --- -1.8.3.1 - diff --git a/0009-CVE-2022-32743-s4-rpc_server-netlogon-Remove-dNSHost.patch b/0009-CVE-2022-32743-s4-rpc_server-netlogon-Remove-dNSHost.patch deleted file mode 100644 index d6005f6dbd7d5c6dfd5455254d678dad9ee3a5f2..0000000000000000000000000000000000000000 --- a/0009-CVE-2022-32743-s4-rpc_server-netlogon-Remove-dNSHost.patch +++ /dev/null @@ -1,82 +0,0 @@ -From d07641fc5a7d2fa323e6d6fe3223da3a6d682405 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Thu, 2 Jun 2022 17:11:08 +1200 -Subject: [PATCH 09/15] CVE-2022-32743 s4:rpc_server/netlogon: Remove - dNSHostName prefix check - -This check is not exhaustive (it does not check the suffix of the -dNSHostName), and should be covered by a validated write check in -acl_modify(). - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14833 - -Signed-off-by: Joseph Sutton -Reviewed-by: Douglas Bagnall ---- - selftest/knownfail.d/netlogon-dns-host-name | 5 +++++ - source4/rpc_server/netlogon/dcerpc_netlogon.c | 21 ++------------------- - 2 files changed, 7 insertions(+), 19 deletions(-) - -diff --git a/selftest/knownfail.d/netlogon-dns-host-name b/selftest/knownfail.d/netlogon-dns-host-name -index 0164a7c..d6a8aa2 100644 ---- a/selftest/knownfail.d/netlogon-dns-host-name -+++ b/selftest/knownfail.d/netlogon-dns-host-name -@@ -1,4 +1,6 @@ - ^samba.tests.py_credentials.samba.tests.py_credentials.PyCredentialsTests.test_set_dns_hostname_invalid_suffix\( -+^samba.tests.py_credentials.samba.tests.py_credentials.PyCredentialsTests.test_set_dns_hostname_invalid_validated_write\( -+^samba.tests.py_credentials.samba.tests.py_credentials.PyCredentialsTests.test_set_dns_hostname_invalid_write_property\( - ^samba.tests.py_credentials.samba.tests.py_credentials.PyCredentialsTests.test_set_dns_hostname_with_flag\( - ^samba4.rpc.netlogon on ncacn_ip_tcp with bigendian.netlogon.GetDomainInfo\( - ^samba4.rpc.netlogon on ncacn_ip_tcp with seal,padcheck.netlogon.GetDomainInfo\( -@@ -6,6 +8,9 @@ - ^samba4.rpc.netlogon on ncacn_np with bigendian.netlogon.GetDomainInfo\( - ^samba4.rpc.netlogon on ncacn_np with seal,padcheck.netlogon.GetDomainInfo\( - ^samba4.rpc.netlogon on ncacn_np with validate.netlogon.GetDomainInfo\( -+^samba4.rpc.netlogon on ncalrpc with bigendian.netlogon.GetDomainInfo\( -+^samba4.rpc.netlogon on ncalrpc with seal,padcheck.netlogon.GetDomainInfo\( -+^samba4.rpc.netlogon on ncalrpc with validate.netlogon.GetDomainInfo\( - ^samba4.rpc.netlogon with bigendian.netlogon.GetDomainInfo\( - ^samba4.rpc.netlogon with seal,padcheck.netlogon.GetDomainInfo\( - ^samba4.rpc.netlogon with validate.netlogon.GetDomainInfo\( -diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c -index eab57da..2d5fc8b 100644 ---- a/source4/rpc_server/netlogon/dcerpc_netlogon.c -+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c -@@ -2413,7 +2413,7 @@ static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_cal - }; - const char * const attrs2[] = { "sAMAccountName", "dNSHostName", - "msDS-SupportedEncryptionTypes", NULL }; -- const char *sam_account_name, *old_dns_hostname, *prefix1, *prefix2; -+ const char *sam_account_name, *old_dns_hostname; - struct ldb_context *sam_ctx; - const struct GUID *our_domain_guid = NULL; - struct lsa_TrustDomainInfoInfoEx *our_tdo = NULL; -@@ -2483,24 +2483,7 @@ static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_cal - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - -- /* -- * Checks that the sam account name without a possible "$" -- * matches as prefix with the DNS hostname in the workstation -- * info structure. -- */ -- prefix1 = talloc_strndup(mem_ctx, sam_account_name, -- strcspn(sam_account_name, "$")); -- NT_STATUS_HAVE_NO_MEMORY(prefix1); -- if (r->in.query->workstation_info->dns_hostname != NULL) { -- prefix2 = talloc_strndup(mem_ctx, -- r->in.query->workstation_info->dns_hostname, -- strcspn(r->in.query->workstation_info->dns_hostname, ".")); -- NT_STATUS_HAVE_NO_MEMORY(prefix2); -- -- if (strcasecmp(prefix1, prefix2) != 0) { -- update_dns_hostname = false; -- } -- } else { -+ if (r->in.query->workstation_info->dns_hostname == NULL) { - update_dns_hostname = false; - } - --- -1.8.3.1 - diff --git a/0010-CVE-2022-32743-s4-rpc_server-netlogon-Always-observe.patch b/0010-CVE-2022-32743-s4-rpc_server-netlogon-Always-observe.patch deleted file mode 100644 index be6b1f03c8b269f43d8135e058c1972b7104d9f3..0000000000000000000000000000000000000000 --- a/0010-CVE-2022-32743-s4-rpc_server-netlogon-Always-observe.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 02c2a8c7b01d6412393423813b710c88b20fb97f Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Tue, 7 Jun 2022 17:25:28 +1200 -Subject: [PATCH 10/15] CVE-2022-32743 s4:rpc_server/netlogon: Always observe - NETR_WS_FLAG_HANDLES_SPN_UPDATE flag - -Even when there is no old DNS hostname present. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14833 - -Signed-off-by: Joseph Sutton -Reviewed-by: Douglas Bagnall ---- - selftest/knownfail.d/netlogon-dns-host-name | 1 - - source4/rpc_server/netlogon/dcerpc_netlogon.c | 7 ++----- - 2 files changed, 2 insertions(+), 6 deletions(-) - -diff --git a/selftest/knownfail.d/netlogon-dns-host-name b/selftest/knownfail.d/netlogon-dns-host-name -index d6a8aa2..30c157f 100644 ---- a/selftest/knownfail.d/netlogon-dns-host-name -+++ b/selftest/knownfail.d/netlogon-dns-host-name -@@ -1,7 +1,6 @@ - ^samba.tests.py_credentials.samba.tests.py_credentials.PyCredentialsTests.test_set_dns_hostname_invalid_suffix\( - ^samba.tests.py_credentials.samba.tests.py_credentials.PyCredentialsTests.test_set_dns_hostname_invalid_validated_write\( - ^samba.tests.py_credentials.samba.tests.py_credentials.PyCredentialsTests.test_set_dns_hostname_invalid_write_property\( --^samba.tests.py_credentials.samba.tests.py_credentials.PyCredentialsTests.test_set_dns_hostname_with_flag\( - ^samba4.rpc.netlogon on ncacn_ip_tcp with bigendian.netlogon.GetDomainInfo\( - ^samba4.rpc.netlogon on ncacn_ip_tcp with seal,padcheck.netlogon.GetDomainInfo\( - ^samba4.rpc.netlogon on ncacn_ip_tcp with validate.netlogon.GetDomainInfo\( -diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c -index 2d5fc8b..efba013 100644 ---- a/source4/rpc_server/netlogon/dcerpc_netlogon.c -+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c -@@ -2495,13 +2495,10 @@ static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_cal - /* - * Updates the DNS hostname when the client wishes that the - * server should handle this for him -- * ("NETR_WS_FLAG_HANDLES_SPN_UPDATE" not set). And this is -- * obviously only checked when we do already have a -- * "dNSHostName". -+ * ("NETR_WS_FLAG_HANDLES_SPN_UPDATE" not set). - * See MS-NRPC section 3.5.4.3.9 - */ -- if ((old_dns_hostname != NULL) && -- (r->in.query->workstation_info->workstation_flags -+ if ((r->in.query->workstation_info->workstation_flags - & NETR_WS_FLAG_HANDLES_SPN_UPDATE) != 0) { - update_dns_hostname = false; - } --- -1.8.3.1 - diff --git a/0011-CVE-2022-32743-s4-rpc_server-netlogon-Connect-to-sam.patch b/0011-CVE-2022-32743-s4-rpc_server-netlogon-Connect-to-sam.patch deleted file mode 100644 index 59505bc9839d8028c19733741204aedc18d300d1..0000000000000000000000000000000000000000 --- a/0011-CVE-2022-32743-s4-rpc_server-netlogon-Connect-to-sam.patch +++ /dev/null @@ -1,71 +0,0 @@ -From f545142380151a626848dbae9ee746167f3299fa Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Tue, 7 Jun 2022 17:29:02 +1200 -Subject: [PATCH 11/15] CVE-2022-32743 s4:rpc_server/netlogon: Connect to samdb - as a user, rather than as system - -This allows us to perform validation on a client-specified dNSHostName -value, to ensure that it matches the sAMAccountName. - -We might not have any rights to modify the account, so pass the control -FORCE_ALLOW_VALIDATED_DNS_HOSTNAME_SPN_WRITE which allows us to perform -a validated write to dNSHostName and servicePrincipalName (and -unvalidated writes to other attributes, such as operatingSystem). - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14833 - -Signed-off-by: Joseph Sutton -Reviewed-by: Douglas Bagnall ---- - selftest/knownfail.d/netlogon-dns-host-name | 17 ++--------------- - source4/rpc_server/netlogon/dcerpc_netlogon.c | 5 +++-- - 2 files changed, 5 insertions(+), 17 deletions(-) - -diff --git a/selftest/knownfail.d/netlogon-dns-host-name b/selftest/knownfail.d/netlogon-dns-host-name -index 30c157f..3eca0cd 100644 ---- a/selftest/knownfail.d/netlogon-dns-host-name -+++ b/selftest/knownfail.d/netlogon-dns-host-name -@@ -1,15 +1,2 @@ --^samba.tests.py_credentials.samba.tests.py_credentials.PyCredentialsTests.test_set_dns_hostname_invalid_suffix\( --^samba.tests.py_credentials.samba.tests.py_credentials.PyCredentialsTests.test_set_dns_hostname_invalid_validated_write\( --^samba.tests.py_credentials.samba.tests.py_credentials.PyCredentialsTests.test_set_dns_hostname_invalid_write_property\( --^samba4.rpc.netlogon on ncacn_ip_tcp with bigendian.netlogon.GetDomainInfo\( --^samba4.rpc.netlogon on ncacn_ip_tcp with seal,padcheck.netlogon.GetDomainInfo\( --^samba4.rpc.netlogon on ncacn_ip_tcp with validate.netlogon.GetDomainInfo\( --^samba4.rpc.netlogon on ncacn_np with bigendian.netlogon.GetDomainInfo\( --^samba4.rpc.netlogon on ncacn_np with seal,padcheck.netlogon.GetDomainInfo\( --^samba4.rpc.netlogon on ncacn_np with validate.netlogon.GetDomainInfo\( --^samba4.rpc.netlogon on ncalrpc with bigendian.netlogon.GetDomainInfo\( --^samba4.rpc.netlogon on ncalrpc with seal,padcheck.netlogon.GetDomainInfo\( --^samba4.rpc.netlogon on ncalrpc with validate.netlogon.GetDomainInfo\( --^samba4.rpc.netlogon with bigendian.netlogon.GetDomainInfo\( --^samba4.rpc.netlogon with seal,padcheck.netlogon.GetDomainInfo\( --^samba4.rpc.netlogon with validate.netlogon.GetDomainInfo\( -+^samba.tests.py_credentials.samba.tests.py_credentials.PyCredentialsTests.test_set_dns_hostname_valid\( -+^samba.tests.py_credentials.samba.tests.py_credentials.PyCredentialsTests.test_set_dns_hostname_valid_denied\( -diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c -index efba013..15cd27b 100644 ---- a/source4/rpc_server/netlogon/dcerpc_netlogon.c -+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c -@@ -2450,7 +2450,8 @@ static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_cal - } - NT_STATUS_NOT_OK_RETURN(status); - -- sam_ctx = dcesrv_samdb_connect_as_system(mem_ctx, dce_call); -+ /* We want to avoid connecting as system. */ -+ sam_ctx = dcesrv_samdb_connect_as_user(mem_ctx, dce_call); - if (sam_ctx == NULL) { - return NT_STATUS_INVALID_SYSTEM_SERVICE; - } -@@ -2607,7 +2608,7 @@ static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_cal - } - } - -- if (dsdb_replace(sam_ctx, new_msg, 0) != LDB_SUCCESS) { -+ if (dsdb_replace(sam_ctx, new_msg, DSDB_FLAG_FORCE_ALLOW_VALIDATED_DNS_HOSTNAME_SPN_WRITE) != LDB_SUCCESS) { - DEBUG(3,("Impossible to update samdb: %s\n", - ldb_errstring(sam_ctx))); - } --- -1.8.3.1 - diff --git a/0012-CVE-2022-32743-dsdb-modules-acl-Account-for-sAMAccou.patch b/0012-CVE-2022-32743-dsdb-modules-acl-Account-for-sAMAccou.patch deleted file mode 100644 index 056319f52cadc80adf345af01921a9f82a0a4660..0000000000000000000000000000000000000000 --- a/0012-CVE-2022-32743-dsdb-modules-acl-Account-for-sAMAccou.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 7638abd38a13f9d2b5c769eb12c70eacf49b3806 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Tue, 7 Jun 2022 17:37:34 +1200 -Subject: [PATCH 12/15] CVE-2022-32743 dsdb/modules/acl: Account for - sAMAccountName without $ - -If we have an account without a trailing $, we should ensure the -servicePrincipalName matches the entire sAMAccountName. We should not -allow a match against the sAMAccountName prefix of length -strlen(samAccountName) - 1, as that could conflict with a different -account. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14833 - -Signed-off-by: Joseph Sutton -Reviewed-by: Douglas Bagnall ---- - source4/dsdb/samdb/ldb_modules/acl.c | 12 ++++++++++-- - 1 file changed, 10 insertions(+), 2 deletions(-) - -diff --git a/source4/dsdb/samdb/ldb_modules/acl.c b/source4/dsdb/samdb/ldb_modules/acl.c -index a26d0ba..82f6ec3 100644 ---- a/source4/dsdb/samdb/ldb_modules/acl.c -+++ b/source4/dsdb/samdb/ldb_modules/acl.c -@@ -543,6 +543,7 @@ static int acl_validate_spn_value(TALLOC_CTX *mem_ctx, - char *instanceName; - char *serviceType; - char *serviceName; -+ size_t account_name_len; - const char *forest_name = samdb_forest_name(ldb, mem_ctx); - const char *base_domain = samdb_default_domain_name(ldb, mem_ctx); - struct loadparm_context *lp_ctx = talloc_get_type(ldb_get_opaque(ldb, "loadparm"), -@@ -616,11 +617,18 @@ static int acl_validate_spn_value(TALLOC_CTX *mem_ctx, - } - } - } -+ -+ account_name_len = strlen(samAccountName); -+ if (account_name_len && samAccountName[account_name_len - 1] == '$') { -+ /* Account for the '$' character. */ -+ --account_name_len; -+ } -+ - /* instanceName can be samAccountName without $ or dnsHostName - * or "ntds_guid._msdcs.forest_domain for DC objects */ -- if (strlen(instanceName) == (strlen(samAccountName) - 1) -+ if (strlen(instanceName) == account_name_len - && strncasecmp(instanceName, samAccountName, -- strlen(samAccountName) - 1) == 0) { -+ account_name_len) == 0) { - goto success; - } - if ((dnsHostName != NULL) && --- -1.8.3.1 - diff --git a/0013-CVE-2022-32743-dsdb-modules-acl-Allow-simultaneous-s.patch b/0013-CVE-2022-32743-dsdb-modules-acl-Allow-simultaneous-s.patch deleted file mode 100644 index 7a79af13242e1a6835a7ba6e4744cf34b90b87b8..0000000000000000000000000000000000000000 --- a/0013-CVE-2022-32743-dsdb-modules-acl-Allow-simultaneous-s.patch +++ /dev/null @@ -1,217 +0,0 @@ -From e1c52ac05a9ff505d2e5eac2f1ece4e95844ee71 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Tue, 7 Jun 2022 17:38:55 +1200 -Subject: [PATCH 13/15] CVE-2022-32743 dsdb/modules/acl: Allow simultaneous - sAMAccountName, dNSHostName, and servicePrincipalName change - -If the message changes the sAMAccountName, we'll check dNSHostName and -servicePrincipalName values against the new value of sAMAccountName, -rather than the account's current value. Similarly, if the message -changes the dNSHostName, we'll check servicePrincipalName values against -the new dNSHostName. This allows setting more than one of these -attributes simultaneously with validated write rights. - -We now pass 'struct ldb_val' to acl_validate_spn_value() instead of -simple strings. Previously, we were relying on the data inside 'struct -ldb_val' having a terminating zero byte, even though this is not -guaranteed. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14833 - -Signed-off-by: Joseph Sutton -Reviewed-by: Douglas Bagnall ---- - selftest/knownfail.d/netlogon-dns-host-name | 2 - - selftest/knownfail.d/validated-dns-host-name | 3 - - source4/dsdb/samdb/ldb_modules/acl.c | 85 +++++++++++++++++++++------- - 3 files changed, 65 insertions(+), 25 deletions(-) - delete mode 100644 selftest/knownfail.d/netlogon-dns-host-name - delete mode 100644 selftest/knownfail.d/validated-dns-host-name - -diff --git a/selftest/knownfail.d/netlogon-dns-host-name b/selftest/knownfail.d/netlogon-dns-host-name -deleted file mode 100644 -index 3eca0cd..0000000 ---- a/selftest/knownfail.d/netlogon-dns-host-name -+++ /dev/null -@@ -1,2 +0,0 @@ --^samba.tests.py_credentials.samba.tests.py_credentials.PyCredentialsTests.test_set_dns_hostname_valid\( --^samba.tests.py_credentials.samba.tests.py_credentials.PyCredentialsTests.test_set_dns_hostname_valid_denied\( -diff --git a/selftest/knownfail.d/validated-dns-host-name b/selftest/knownfail.d/validated-dns-host-name -deleted file mode 100644 -index 4b61658..0000000 ---- a/selftest/knownfail.d/validated-dns-host-name -+++ /dev/null -@@ -1,3 +0,0 @@ --^samba4.ldap.acl.python.*__main__.AclModifyTests.test_modify_dns_host_name_spn\( --^samba4.ldap.acl.python.*__main__.AclModifyTests.test_modify_dns_host_name_spn_matching_account_name_new\( --^samba4.ldap.acl.python.*__main__.AclModifyTests.test_modify_spn_matching_dns_host_name_invalid\( -diff --git a/source4/dsdb/samdb/ldb_modules/acl.c b/source4/dsdb/samdb/ldb_modules/acl.c -index 82f6ec3..4098ae2 100644 ---- a/source4/dsdb/samdb/ldb_modules/acl.c -+++ b/source4/dsdb/samdb/ldb_modules/acl.c -@@ -529,10 +529,10 @@ static int acl_sDRightsEffective(struct ldb_module *module, - - static int acl_validate_spn_value(TALLOC_CTX *mem_ctx, - struct ldb_context *ldb, -- const char *spn_value, -+ const struct ldb_val *spn_value, - uint32_t userAccountControl, -- const char *samAccountName, -- const char *dnsHostName, -+ const struct ldb_val *samAccountName, -+ const struct ldb_val *dnsHostName, - const char *netbios_name, - const char *ntds_guid) - { -@@ -543,6 +543,7 @@ static int acl_validate_spn_value(TALLOC_CTX *mem_ctx, - char *instanceName; - char *serviceType; - char *serviceName; -+ const char *spn_value_str = NULL; - size_t account_name_len; - const char *forest_name = samdb_forest_name(ldb, mem_ctx); - const char *base_domain = samdb_default_domain_name(ldb, mem_ctx); -@@ -551,7 +552,18 @@ static int acl_validate_spn_value(TALLOC_CTX *mem_ctx, - bool is_dc = (userAccountControl & UF_SERVER_TRUST_ACCOUNT) || - (userAccountControl & UF_PARTIAL_SECRETS_ACCOUNT); - -- if (strcasecmp_m(spn_value, samAccountName) == 0) { -+ spn_value_str = talloc_strndup(mem_ctx, -+ (const char *)spn_value->data, -+ spn_value->length); -+ if (spn_value_str == NULL) { -+ return ldb_oom(ldb); -+ } -+ -+ if (spn_value->length == samAccountName->length && -+ strncasecmp((const char *)spn_value->data, -+ (const char *)samAccountName->data, -+ spn_value->length) == 0) -+ { - /* MacOS X sets this value, and setting an SPN of your - * own samAccountName is both pointless and safe */ - return LDB_SUCCESS; -@@ -565,7 +577,7 @@ static int acl_validate_spn_value(TALLOC_CTX *mem_ctx, - "Could not initialize kerberos context."); - } - -- ret = krb5_parse_name(krb_ctx, spn_value, &principal); -+ ret = krb5_parse_name(krb_ctx, spn_value_str, &principal); - if (ret) { - krb5_free_context(krb_ctx); - return LDB_ERR_CONSTRAINT_VIOLATION; -@@ -618,8 +630,10 @@ static int acl_validate_spn_value(TALLOC_CTX *mem_ctx, - } - } - -- account_name_len = strlen(samAccountName); -- if (account_name_len && samAccountName[account_name_len - 1] == '$') { -+ account_name_len = samAccountName->length; -+ if (account_name_len && -+ samAccountName->data[account_name_len - 1] == '$') -+ { - /* Account for the '$' character. */ - --account_name_len; - } -@@ -627,12 +641,18 @@ static int acl_validate_spn_value(TALLOC_CTX *mem_ctx, - /* instanceName can be samAccountName without $ or dnsHostName - * or "ntds_guid._msdcs.forest_domain for DC objects */ - if (strlen(instanceName) == account_name_len -- && strncasecmp(instanceName, samAccountName, -- account_name_len) == 0) { -+ && strncasecmp(instanceName, -+ (const char *)samAccountName->data, -+ account_name_len) == 0) -+ { - goto success; - } - if ((dnsHostName != NULL) && -- (strcasecmp(instanceName, dnsHostName) == 0)) { -+ strlen(instanceName) == dnsHostName->length && -+ (strncasecmp(instanceName, -+ (const char *)dnsHostName->data, -+ dnsHostName->length) == 0)) -+ { - goto success; - } - if (is_dc) { -@@ -650,10 +670,13 @@ fail: - krb5_free_context(krb_ctx); - ldb_debug_set(ldb, LDB_DEBUG_WARNING, - "acl: spn validation failed for " -- "spn[%s] uac[0x%x] account[%s] hostname[%s] " -+ "spn[%.*s] uac[0x%x] account[%.*s] hostname[%.*s] " - "nbname[%s] ntds[%s] forest[%s] domain[%s]\n", -- spn_value, (unsigned)userAccountControl, -- samAccountName, dnsHostName, -+ (int)spn_value->length, spn_value->data, -+ (unsigned)userAccountControl, -+ (int)samAccountName->length, samAccountName->data, -+ dnsHostName != NULL ? (int)dnsHostName->length : 0, -+ dnsHostName != NULL ? (const char *)dnsHostName->data : "", - netbios_name, ntds_guid, - forest_name, base_domain); - return LDB_ERR_CONSTRAINT_VIOLATION; -@@ -686,9 +709,9 @@ static int acl_check_spn(TALLOC_CTX *mem_ctx, - struct ldb_result *netbios_res; - struct ldb_dn *partitions_dn = samdb_partitions_dn(ldb, tmp_ctx); - uint32_t userAccountControl; -- const char *samAccountName; -- const char *dnsHostName; - const char *netbios_name; -+ const struct ldb_val *dns_host_name_val = NULL; -+ const struct ldb_val *sam_account_name_val = NULL; - struct GUID ntds; - char *ntds_guid = NULL; - -@@ -773,9 +796,31 @@ static int acl_check_spn(TALLOC_CTX *mem_ctx, - return ret; - } - -+ dns_host_name_val = ldb_msg_find_ldb_val(acl_res->msgs[0], "dNSHostName"); -+ -+ ret = dsdb_msg_get_single_value(req->op.mod.message, -+ "dNSHostName", -+ dns_host_name_val, -+ &dns_host_name_val, -+ req->operation); -+ if (ret != LDB_SUCCESS) { -+ talloc_free(tmp_ctx); -+ return ret; -+ } -+ - userAccountControl = ldb_msg_find_attr_as_uint(acl_res->msgs[0], "userAccountControl", 0); -- dnsHostName = ldb_msg_find_attr_as_string(acl_res->msgs[0], "dnsHostName", NULL); -- samAccountName = ldb_msg_find_attr_as_string(acl_res->msgs[0], "samAccountName", NULL); -+ -+ sam_account_name_val = ldb_msg_find_ldb_val(acl_res->msgs[0], "sAMAccountName"); -+ -+ ret = dsdb_msg_get_single_value(req->op.mod.message, -+ "sAMAccountName", -+ sam_account_name_val, -+ &sam_account_name_val, -+ req->operation); -+ if (ret != LDB_SUCCESS) { -+ talloc_free(tmp_ctx); -+ return ret; -+ } - - ret = dsdb_module_search(module, tmp_ctx, - &netbios_res, partitions_dn, -@@ -806,10 +851,10 @@ static int acl_check_spn(TALLOC_CTX *mem_ctx, - for (i=0; i < el->num_values; i++) { - ret = acl_validate_spn_value(tmp_ctx, - ldb, -- (char *)el->values[i].data, -+ &el->values[i], - userAccountControl, -- samAccountName, -- dnsHostName, -+ sam_account_name_val, -+ dns_host_name_val, - netbios_name, - ntds_guid); - if (ret != LDB_SUCCESS) { --- -1.8.3.1 - diff --git a/0014-CVE-2022-32743-s4-rpc_server-common-Add-dcesrv_samdb.patch b/0014-CVE-2022-32743-s4-rpc_server-common-Add-dcesrv_samdb.patch deleted file mode 100644 index 300b077857e2f01c06f0a8c5664e6935410ed64a..0000000000000000000000000000000000000000 --- a/0014-CVE-2022-32743-s4-rpc_server-common-Add-dcesrv_samdb.patch +++ /dev/null @@ -1,159 +0,0 @@ -From 6b76bc7339addb14884c2d6ddb20c559c7fbe07d Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Thu, 9 Jun 2022 19:32:30 +1200 -Subject: [PATCH 14/15] CVE-2022-32743 s4:rpc_server/common: Add - dcesrv_samdb_connect_session_info() - -This function allows us to connect to samdb as a particular user by -passing in that user's session info. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14833 - -Signed-off-by: Joseph Sutton -Reviewed-by: Douglas Bagnall ---- - source4/rpc_server/common/common.h | 1 + - source4/rpc_server/common/server_info.c | 65 ++++++++++++++++++++------------- - 2 files changed, 40 insertions(+), 26 deletions(-) - -diff --git a/source4/rpc_server/common/common.h b/source4/rpc_server/common/common.h -index 7d2f8c5..b57ddf2 100644 ---- a/source4/rpc_server/common/common.h -+++ b/source4/rpc_server/common/common.h -@@ -30,6 +30,7 @@ struct dcesrv_context; - struct dcesrv_call_state; - struct ndr_interface_table; - struct ncacn_packet; -+struct auth_session_info; - - struct dcerpc_server_info { - const char *domain_name; -diff --git a/source4/rpc_server/common/server_info.c b/source4/rpc_server/common/server_info.c -index a2af376..34228c3 100644 ---- a/source4/rpc_server/common/server_info.c -+++ b/source4/rpc_server/common/server_info.c -@@ -190,48 +190,44 @@ bool dcesrv_common_validate_share_name(TALLOC_CTX *mem_ctx, const char *share_na - return true; - } - --static struct ldb_context *dcesrv_samdb_connect_common( -+/* -+ * call_session_info is session info for samdb. call_audit_session_info is for -+ * auditing and may be NULL. -+ */ -+struct ldb_context *dcesrv_samdb_connect_session_info( - TALLOC_CTX *mem_ctx, - struct dcesrv_call_state *dce_call, -- bool as_system) -+ const struct auth_session_info *call_session_info, -+ const struct auth_session_info *call_audit_session_info) - { - struct ldb_context *samdb = NULL; -- struct auth_session_info *system_session_info = NULL; -- const struct auth_session_info *call_session_info = -- dcesrv_call_session_info(dce_call); - struct auth_session_info *user_session_info = NULL; -- struct auth_session_info *ldb_session_info = NULL; - struct auth_session_info *audit_session_info = NULL; - struct tsocket_address *remote_address = NULL; - -- if (as_system) { -- system_session_info = system_session(dce_call->conn->dce_ctx->lp_ctx); -- if (system_session_info == NULL) { -- return NULL; -- } -- } -- - user_session_info = copy_session_info(mem_ctx, call_session_info); - if (user_session_info == NULL) { - return NULL; - } - -+ if (call_audit_session_info != NULL) { -+ audit_session_info = copy_session_info(mem_ctx, call_audit_session_info); -+ if (audit_session_info == NULL) { -+ talloc_free(user_session_info); -+ return NULL; -+ } -+ } -+ - if (dce_call->conn->remote_address != NULL) { - remote_address = tsocket_address_copy(dce_call->conn->remote_address, - user_session_info); - if (remote_address == NULL) { -+ TALLOC_FREE(audit_session_info); -+ talloc_free(user_session_info); - return NULL; - } - } - -- if (system_session_info != NULL) { -- ldb_session_info = system_session_info; -- audit_session_info = user_session_info; -- } else { -- ldb_session_info = user_session_info; -- audit_session_info = NULL; -- } -- - /* - * We need to make sure every argument - * stays arround for the lifetime of 'samdb', -@@ -253,10 +249,11 @@ static struct ldb_context *dcesrv_samdb_connect_common( - mem_ctx, - dce_call->event_ctx, - dce_call->conn->dce_ctx->lp_ctx, -- ldb_session_info, -+ user_session_info, - remote_address, - 0); - if (samdb == NULL) { -+ TALLOC_FREE(audit_session_info); - talloc_free(user_session_info); - return NULL; - } -@@ -265,6 +262,8 @@ static struct ldb_context *dcesrv_samdb_connect_common( - if (audit_session_info != NULL) { - int ret; - -+ talloc_steal(samdb, audit_session_info); -+ - ret = ldb_set_opaque(samdb, - DSDB_NETWORK_SESSION_INFO, - audit_session_info); -@@ -288,8 +287,18 @@ struct ldb_context *dcesrv_samdb_connect_as_system( - TALLOC_CTX *mem_ctx, - struct dcesrv_call_state *dce_call) - { -- return dcesrv_samdb_connect_common(mem_ctx, dce_call, -- true /* as_system */); -+ const struct auth_session_info *system_session_info = NULL; -+ const struct auth_session_info *call_session_info = NULL; -+ -+ system_session_info = system_session(dce_call->conn->dce_ctx->lp_ctx); -+ if (system_session_info == NULL) { -+ return NULL; -+ } -+ -+ call_session_info = dcesrv_call_session_info(dce_call); -+ -+ return dcesrv_samdb_connect_session_info(mem_ctx, dce_call, -+ system_session_info, call_session_info); - } - - /* -@@ -301,6 +310,10 @@ struct ldb_context *dcesrv_samdb_connect_as_user( - TALLOC_CTX *mem_ctx, - struct dcesrv_call_state *dce_call) - { -- return dcesrv_samdb_connect_common(mem_ctx, dce_call, -- false /* not as_system */); -+ const struct auth_session_info *call_session_info = NULL; -+ -+ call_session_info = dcesrv_call_session_info(dce_call); -+ -+ return dcesrv_samdb_connect_session_info(mem_ctx, dce_call, -+ call_session_info, NULL); - } --- -1.8.3.1 - diff --git a/0015-CVE-2022-32743-s4-rpc_server-netlogon-Reconnect-to-s.patch b/0015-CVE-2022-32743-s4-rpc_server-netlogon-Reconnect-to-s.patch deleted file mode 100644 index 22ff1b2bcaf0ed4309cc14fe1d3ec45479fa1eca..0000000000000000000000000000000000000000 --- a/0015-CVE-2022-32743-s4-rpc_server-netlogon-Reconnect-to-s.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 15c86028a861139cee4560fe093c965ffc30eb13 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Thu, 9 Jun 2022 19:46:07 +1200 -Subject: [PATCH 15/15] CVE-2022-32743 s4:rpc_server/netlogon: Reconnect to - samdb as workstation account - -This ensures that the database update can be attributed to the -workstation account, rather than to the anonymous SID, in the audit -logs. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14833 - -Signed-off-by: Joseph Sutton -Reviewed-by: Douglas Bagnall - -Autobuild-User(master): Douglas Bagnall -Autobuild-Date(master): Thu Jul 28 23:41:27 UTC 2022 on sn-devel-184 ---- - source4/rpc_server/netlogon/dcerpc_netlogon.c | 28 +++++++++++++++++++++++++++ - 1 file changed, 28 insertions(+) - -diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c -index 15cd27b..12ad780 100644 ---- a/source4/rpc_server/netlogon/dcerpc_netlogon.c -+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c -@@ -2422,6 +2422,7 @@ static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_cal - struct ldb_dn *workstation_dn; - struct netr_DomainInformation *domain_info; - struct netr_LsaPolicyInformation *lsa_policy_info; -+ struct auth_session_info *workstation_session_info = NULL; - uint32_t default_supported_enc_types = 0xFFFFFFFF; - bool update_dns_hostname = true; - int ret, i; -@@ -2468,6 +2469,33 @@ static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_cal - dom_sid_string(mem_ctx, creds->sid)); - NT_STATUS_HAVE_NO_MEMORY(workstation_dn); - -+ /* Get the workstation's session info from the database. */ -+ status = authsam_get_session_info_principal(mem_ctx, -+ dce_call->conn->dce_ctx->lp_ctx, -+ sam_ctx, -+ NULL, /* principal */ -+ workstation_dn, -+ 0, /* session_info_flags */ -+ &workstation_session_info); -+ if (!NT_STATUS_IS_OK(status)) { -+ return status; -+ } -+ -+ /* -+ * Reconnect to samdb as the workstation, now that we have its -+ * session info. We do this so the database update can be -+ * attributed to the workstation account in the audit logs -- -+ * otherwise it might be incorrectly attributed to -+ * SID_NT_ANONYMOUS. -+ */ -+ sam_ctx = dcesrv_samdb_connect_session_info(mem_ctx, -+ dce_call, -+ workstation_session_info, -+ workstation_session_info); -+ if (sam_ctx == NULL) { -+ return NT_STATUS_INVALID_SYSTEM_SERVICE; -+ } -+ - /* Lookup for attributes in workstation object */ - ret = gendb_search_dn(sam_ctx, mem_ctx, workstation_dn, &res1, - attrs2); --- -1.8.3.1 - diff --git a/backport-0001-CVE-2021-44142.patch b/backport-0001-CVE-2021-44142.patch deleted file mode 100644 index 1e9e5cd1b95e1d2597497937f56ecadaa7fc7565..0000000000000000000000000000000000000000 --- a/backport-0001-CVE-2021-44142.patch +++ /dev/null @@ -1,31 +0,0 @@ -From eee61be9b5867b63b73b0b1fea03f44a4e1235b7 Mon Sep 17 00:00:00 2001 -From: Ralph Boehme -Date: Thu, 13 Jan 2022 16:48:01 +0100 -Subject: [PATCH 03/99] CVE-2021-44142: libadouble: add defines for icon - lengths - -From https://www.ietf.org/rfc/rfc1740.txt - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14914 - -Signed-off-by: Ralph Boehme -Reviewed-by: Jeremy Allison ---- - source3/lib/adouble.h | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/source3/lib/adouble.h b/source3/lib/adouble.h -index 8b14d0ab871..de44f3f5fdc 100644 ---- a/source3/lib/adouble.h -+++ b/source3/lib/adouble.h -@@ -101,6 +101,8 @@ typedef enum {ADOUBLE_META, ADOUBLE_RSRC} adouble_type_t; - #define ADEDLEN_MACFILEI 4 - #define ADEDLEN_PRODOSFILEI 8 - #define ADEDLEN_MSDOSFILEI 2 -+#define ADEDLEN_ICONBW 128 -+#define ADEDLEN_ICONCOL 1024 - #define ADEDLEN_DID 4 - #define ADEDLEN_PRIVDEV 8 - #define ADEDLEN_PRIVINO 8 --- -2.25.1 diff --git a/backport-0001-CVE-2022-0336.patch b/backport-0001-CVE-2022-0336.patch deleted file mode 100644 index 39c54958ffc33ed4a89d637ef972b656bc20d0ad..0000000000000000000000000000000000000000 --- a/backport-0001-CVE-2022-0336.patch +++ /dev/null @@ -1,52 +0,0 @@ -From d392b10c55bbcedda01fdd87fe6035fa3a6986b3 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Tue, 18 Jan 2022 11:56:38 +1300 -Subject: [PATCH 01/99] CVE-2022-0336: pytest: Add a test for an SPN conflict - with a re-added SPN - -This test currently fails, as re-adding an SPN means that later checks -do not run. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14950 - -Signed-off-by: Joseph Sutton -Reviewed-by: Douglas Bagnall ---- - python/samba/tests/ldap_spn.py | 7 +++++++ - selftest/knownfail.d/ldap_spn | 1 + - 2 files changed, 8 insertions(+) - -diff --git a/python/samba/tests/ldap_spn.py b/python/samba/tests/ldap_spn.py -index 8a398ffaa49..6ebdf8f9a32 100644 ---- a/python/samba/tests/ldap_spn.py -+++ b/python/samba/tests/ldap_spn.py -@@ -268,6 +268,8 @@ class LdapSpnTestBase(TestCase): - for k in ('dNSHostName', 'servicePrincipalName'): - if isinstance(m.get(k), str): - m[k] = m[k].format(dnsname=f"x.{REALM}") -+ elif isinstance(m.get(k), list): -+ m[k] = [x.format(dnsname=f"x.{REALM}") for x in m[k]] - - msg = ldb.Message.from_dict(samdb, m, op) - -@@ -727,6 +729,11 @@ class LdapSpnSambaOnlyTest(LdapSpnTestBase): - ('user:C', 'host/{dnsname}', '*', ok), - ('user:D', 'www/{dnsname}', 'D', denied), - ), -+ ("add a conflict, along with a re-added SPN", -+ ('A', 'cifs/{dnsname}', '*', ok), -+ ('B', 'cifs/heeble.example.net', 'B', ok), -+ ('B', ['cifs/heeble.example.net', 'host/{dnsname}'], 'B', constraint), -+ ), - - ("changing dNSHostName after host", - ('A', {'dNSHostName': '{dnsname}'}, '*', ok), -diff --git a/selftest/knownfail.d/ldap_spn b/selftest/knownfail.d/ldap_spn -index 63f9fe02ef7..16dafa91b66 100644 ---- a/selftest/knownfail.d/ldap_spn -+++ b/selftest/knownfail.d/ldap_spn -@@ -1 +1,2 @@ - samba.tests.ldap_spn.+LdapSpnTest.test_spn_dodgy_spns -+samba.tests.ldap_spn.+LdapSpnSambaOnlyTest.test_spn_add_a_conflict_along_with_a_re_added_SPN --- -2.25.1 diff --git a/backport-0001-CVE-2022-1615-util-genrand-don-t-ignore-errors-in-random-number-ge.patch b/backport-0001-CVE-2022-1615-util-genrand-don-t-ignore-errors-in-random-number-ge.patch deleted file mode 100644 index fd5ded77f3d3ca2e29c89b6cc49e640b12f164f2..0000000000000000000000000000000000000000 --- a/backport-0001-CVE-2022-1615-util-genrand-don-t-ignore-errors-in-random-number-ge.patch +++ /dev/null @@ -1,94 +0,0 @@ -From 9849e7440e30853c61a80ce1f11b7b244ed766fe Mon Sep 17 00:00:00 2001 -From: Douglas Bagnall -Date: Mon, 5 Aug 2019 00:10:53 +1200 -Subject: [PATCH] util/genrand: don't ignore errors in random number generation - -In this case it is probably better to crash out. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15103 - -Signed-off-by: Douglas Bagnall -Reviewed-by: Andreas Schneider ---- - lib/util/genrand.c | 29 ++++++++++++++++++++++++++--- - lib/util/wscript_build | 2 +- - 2 files changed, 27 insertions(+), 4 deletions(-) - -diff --git a/lib/util/genrand.c b/lib/util/genrand.c -index 18ffa0d..fd6f457 100644 ---- a/lib/util/genrand.c -+++ b/lib/util/genrand.c -@@ -20,6 +20,7 @@ - */ - - #include "replace.h" -+#include "lib/util/fault.h" - #include "lib/util/genrand.h" - - #include -@@ -31,10 +32,26 @@ - * https://nikmav.blogspot.com/2017/03/improving-by-simplifying-gnutls-prng.html - */ - -+ -+_NORETURN_ static void genrand_panic(int err, -+ const char *location, -+ const char *func) -+{ -+ char buf[200]; -+ snprintf(buf, sizeof(buf), -+ "%s:%s: GnuTLS could not generate a random buffer: %s [%d]\n", -+ location, func, gnutls_strerror_name(err), err); -+ smb_panic(buf); -+} -+ -+ - _PUBLIC_ void generate_random_buffer(uint8_t *out, int len) - { - /* Random number generator for temporary keys. */ -- gnutls_rnd(GNUTLS_RND_RANDOM, out, len); -+ int ret = gnutls_rnd(GNUTLS_RND_RANDOM, out, len); -+ if (ret != 0) { -+ genrand_panic(ret, __location__, __func__); -+ } - } - - _PUBLIC_ void generate_secret_buffer(uint8_t *out, int len) -@@ -48,7 +65,10 @@ _PUBLIC_ void generate_secret_buffer(uint8_t *out, int len) - * the limit for a re-seed. For its re-seed it mixes mixes data obtained - * from the OS random device with the previous key. - */ -- gnutls_rnd(GNUTLS_RND_KEY, out, len); -+ int ret = gnutls_rnd(GNUTLS_RND_KEY, out, len); -+ if (ret != 0) { -+ genrand_panic(ret, __location__, __func__); -+ } - } - - _PUBLIC_ void generate_nonce_buffer(uint8_t *out, int len) -@@ -60,5 +80,8 @@ _PUBLIC_ void generate_nonce_buffer(uint8_t *out, int len) - * bytes (typically few megabytes), or after few hours of operation - * without reaching the limit has passed. - */ -- gnutls_rnd(GNUTLS_RND_NONCE, out, len); -+ int ret = gnutls_rnd(GNUTLS_RND_NONCE, out, len); -+ if (ret != 0) { -+ genrand_panic(ret, __location__, __func__); -+ } - } -diff --git a/lib/util/wscript_build b/lib/util/wscript_build -index df235c1..d26aa4e 100644 ---- a/lib/util/wscript_build -+++ b/lib/util/wscript_build -@@ -143,7 +143,7 @@ bld.SAMBA_LIBRARY('msghdr', - - bld.SAMBA_LIBRARY('genrand', - source='genrand.c', -- deps='replace gnutls', -+ deps='replace gnutls smb-panic', - local_include=False, - private_library=True) - --- -1.8.3.1 - diff --git a/backport-0001-CVE-2022-3437.patch b/backport-0001-CVE-2022-3437.patch deleted file mode 100644 index af5c103318ae8a7058e2ca8b133ed1f2f450979e..0000000000000000000000000000000000000000 --- a/backport-0001-CVE-2022-3437.patch +++ /dev/null @@ -1,39 +0,0 @@ -From fe1204d9da2c6f761c4dc4421f67057b10eaf430 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Wed, 12 Oct 2022 13:56:08 +1300 -Subject: [PATCH 05/15] CVE-2022-3437 source4/heimdal: Remove __func__ - compatibility workaround - -As described by the C standard, __func__ is a variable, not a macro. -Hence this #ifndef check does not work as intended, and only serves to -unconditionally disable __func__. A nonoperating __func__ prevents -cmocka operating correctly, so remove this definition. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15134 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett - -Conflict: NA -Reference: https://download.samba.org/pub/samba/patches/security/samba-4.15.11-security-2022-10-25.patch ---- - source4/heimdal/lib/krb5/krb5_locl.h | 4 ---- - 1 file changed, 4 deletions(-) - -diff --git a/source4/heimdal/lib/krb5/krb5_locl.h b/source4/heimdal/lib/krb5/krb5_locl.h -index 49c614d5efe..d3360c556ce 100644 ---- a/source4/heimdal/lib/krb5/krb5_locl.h -+++ b/source4/heimdal/lib/krb5/krb5_locl.h -@@ -188,10 +188,6 @@ struct _krb5_krb_auth_data; - #define ALLOC(X, N) (X) = calloc((N), sizeof(*(X))) - #define ALLOC_SEQ(X, N) do { (X)->len = (N); ALLOC((X)->val, (N)); } while(0) - --#ifndef __func__ --#define __func__ "unknown-function" --#endif -- - #define krb5_einval(context, argnum) _krb5_einval((context), __func__, (argnum)) - - #ifndef PATH_SEP --- -2.25.1 diff --git a/backport-0002-CVE-2021-44142.patch b/backport-0002-CVE-2021-44142.patch deleted file mode 100644 index 5ce8fec077a35fdd55f2db7f81d0974213ea62d9..0000000000000000000000000000000000000000 --- a/backport-0002-CVE-2021-44142.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 22b4091924977f6437b59627f33a8e6f02b41011 Mon Sep 17 00:00:00 2001 -From: Ralph Boehme -Date: Sat, 20 Nov 2021 16:36:42 +0100 -Subject: [PATCH 04/99] CVE-2021-44142: smbd: add Netatalk xattr used by - vfs_fruit to the list of private Samba xattrs - -This is an internal xattr that should not be user visible. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14914 - -Signed-off-by: Ralph Boehme -Reviewed-by: Jeremy Allison ---- - source3/smbd/trans2.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c -index a86ac3228e3..4f6d92955cf 100644 ---- a/source3/smbd/trans2.c -+++ b/source3/smbd/trans2.c -@@ -46,6 +46,7 @@ - #include "libcli/smb/smb2_posix.h" - #include "lib/util/string_wrappers.h" - #include "source3/lib/substitute.h" -+#include "source3/lib/adouble.h" - - #define DIR_ENTRY_SAFETY_MARGIN 4096 - -@@ -203,6 +204,7 @@ bool samba_private_attr_name(const char *unix_ea_name) - SAMBA_XATTR_DOS_ATTRIB, - SAMBA_XATTR_MARKER, - XATTR_NTACL_NAME, -+ AFPINFO_EA_NETATALK, - NULL - }; - --- -2.25.1 diff --git a/backport-0002-CVE-2022-0336.patch b/backport-0002-CVE-2022-0336.patch deleted file mode 100644 index 57943e86a5991c8c9233910f4b3e618bd59199a1..0000000000000000000000000000000000000000 --- a/backport-0002-CVE-2022-0336.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 7a516257ea310fa045bdf14e677eaa97f2a83c33 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Tue, 18 Jan 2022 12:02:45 +1300 -Subject: [PATCH 02/99] CVE-2022-0336: s4/dsdb/samldb: Don't return early when - an SPN is re-added to an object - -If an added SPN already exists on an object, we still want to check the -rest of the element values for conflicts. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14950 - -Signed-off-by: Joseph Sutton -Reviewed-by: Douglas Bagnall ---- - selftest/knownfail.d/ldap_spn | 1 - - source4/dsdb/samdb/ldb_modules/samldb.c | 3 +-- - 2 files changed, 1 insertion(+), 3 deletions(-) - -diff --git a/selftest/knownfail.d/ldap_spn b/selftest/knownfail.d/ldap_spn -index 16dafa91b66..63f9fe02ef7 100644 ---- a/selftest/knownfail.d/ldap_spn -+++ b/selftest/knownfail.d/ldap_spn -@@ -1,2 +1 @@ - samba.tests.ldap_spn.+LdapSpnTest.test_spn_dodgy_spns --samba.tests.ldap_spn.+LdapSpnSambaOnlyTest.test_spn_add_a_conflict_along_with_a_re_added_SPN -diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c -index db3883eb527..24971d521aa 100644 ---- a/source4/dsdb/samdb/ldb_modules/samldb.c -+++ b/source4/dsdb/samdb/ldb_modules/samldb.c -@@ -4006,8 +4006,7 @@ static int samldb_spn_uniqueness_check(struct samldb_ctx *ac, - ac->msg->dn); - if (ret == LDB_ERR_COMPARE_TRUE) { - DBG_INFO("SPN %s re-added to the same object\n", spn); -- talloc_free(tmp_ctx); -- return LDB_SUCCESS; -+ continue; - } - if (ret != LDB_SUCCESS) { - DBG_ERR("SPN %s failed direct uniqueness check\n", spn); --- -2.25.1 diff --git a/backport-0002-CVE-2022-1615-py-uptodateness-more-details-in-missing-dn-report.patch b/backport-0002-CVE-2022-1615-py-uptodateness-more-details-in-missing-dn-report.patch deleted file mode 100644 index ff42ca71cd4deaf2474bb7d038244a0f38b554f3..0000000000000000000000000000000000000000 --- a/backport-0002-CVE-2022-1615-py-uptodateness-more-details-in-missing-dn-report.patch +++ /dev/null @@ -1,34 +0,0 @@ -From ffa84f2e5d335626b5f7311af8d2a7056b3e5c6f Mon Sep 17 00:00:00 2001 -From: Douglas Bagnall -Date: Mon, 11 Jul 2022 12:06:54 +1200 -Subject: [PATCH] py/uptodateness: more details in missing dn report - -This does not fix bug 15127, but it improves reporting. - -https://bugzilla.samba.org/show_bug.cgi?id=15127 - -Signed-off-by: Douglas Bagnall -Reviewed-by: Andreas Schneider - -Autobuild-User(master): Andreas Schneider -Autobuild-Date(master): Thu Jul 28 06:18:43 UTC 2022 on sn-devel-184 ---- - python/samba/uptodateness.py | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/python/samba/uptodateness.py b/python/samba/uptodateness.py -index db1ba53..49c984a 100644 ---- a/python/samba/uptodateness.py -+++ b/python/samba/uptodateness.py -@@ -147,7 +147,7 @@ def get_utdv_distances(utdv_edges, dsas): - dist = peak - utdv_edges[dn2][dn1] - d[dn2] = dist - else: -- print("Missing dn %s from UTD vector" % dn1, -+ print(f"Missing dn {dn1} from UTD vector for dsa {dn2}", - file=sys.stderr) - else: - print("missing dn %s from UTD vector list" % dn2, --- -1.8.3.1 - diff --git a/backport-0002-CVE-2022-3437.patch b/backport-0002-CVE-2022-3437.patch deleted file mode 100644 index 2c2a2e744dc98fb5995bc068fda3d6103d4110aa..0000000000000000000000000000000000000000 --- a/backport-0002-CVE-2022-3437.patch +++ /dev/null @@ -1,58 +0,0 @@ -From a49a3ac8e082921c2793a073b5991c4693f167ab Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Wed, 12 Oct 2022 13:55:51 +1300 -Subject: [PATCH 06/15] CVE-2022-3437 source4/heimdal_build: Add - gssapi-subsystem subsystem - -This allows us to access (and so test) functions internal to GSSAPI by -depending on this subsystem. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15134 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett - -[jsutton@samba.org Adapted to older wscript_build file] - -Conflict: NA -Reference: https://download.samba.org/pub/samba/patches/security/samba-4.15.11-security-2022-10-25.patch ---- - source4/heimdal_build/wscript_build | 14 ++++++++++---- - 1 file changed, 10 insertions(+), 4 deletions(-) - -diff --git a/source4/heimdal_build/wscript_build b/source4/heimdal_build/wscript_build -index e91c8ab2eeb..41152192798 100644 ---- a/source4/heimdal_build/wscript_build -+++ b/source4/heimdal_build/wscript_build -@@ -571,8 +571,8 @@ if not bld.CONFIG_SET("USING_SYSTEM_GSSAPI"): - HEIMDAL_AUTOPROTO_PRIVATE('lib/gssapi/krb5/gsskrb5-private.h', - HEIMDAL_GSSAPI_KRB5_SOURCE) - -- HEIMDAL_LIBRARY('gssapi', -- HEIMDAL_GSSAPI_SPNEGO_SOURCE + HEIMDAL_GSSAPI_KRB5_SOURCE + ''' -+ HEIMDAL_SUBSYSTEM('gssapi-subsystem', -+ HEIMDAL_GSSAPI_SPNEGO_SOURCE + HEIMDAL_GSSAPI_KRB5_SOURCE + ''' - lib/gssapi/mech/context.c lib/gssapi/mech/gss_krb5.c lib/gssapi/mech/gss_mech_switch.c - lib/gssapi/mech/gss_process_context_token.c lib/gssapi/mech/gss_buffer_set.c - lib/gssapi/mech/gss_aeap.c lib/gssapi/mech/gss_add_cred.c lib/gssapi/mech/gss_cred.c -@@ -597,10 +597,16 @@ if not bld.CONFIG_SET("USING_SYSTEM_GSSAPI"): - lib/gssapi/mech/gss_set_cred_option.c lib/gssapi/mech/gss_pseudo_random.c ../heimdal_build/gssapi-glue.c''', - includes='../heimdal/lib/gssapi ../heimdal/lib/gssapi/gssapi ../heimdal/lib/gssapi/spnego ../heimdal/lib/gssapi/krb5 ../heimdal/lib/gssapi/mech', - deps='hcrypto asn1 HEIMDAL_SPNEGO_ASN1 HEIMDAL_GSSAPI_ASN1 roken krb5 com_err wind heimbase', -- vnum='2.0.0', -- version_script='lib/gssapi/version-script.map', - ) - -+ HEIMDAL_LIBRARY('gssapi', -+ '', -+ includes='../heimdal/lib/gssapi ../heimdal/lib/gssapi/gssapi ../heimdal/lib/gssapi/spnego ../heimdal/lib/gssapi/krb5 ../heimdal/lib/gssapi/mech', -+ deps='gssapi-subsystem', -+ vnum='2.0.0', -+ version_script='lib/gssapi/version-script.map', -+ ) -+ - if not bld.CONFIG_SET("USING_SYSTEM_KRB5"): - # expand_path.c needs some of the install paths - HEIMDAL_SUBSYSTEM('HEIMDAL_CONFIG', --- -2.25.1 diff --git a/backport-0003-CVE-2021-44142.patch b/backport-0003-CVE-2021-44142.patch deleted file mode 100644 index 316275ff6da93cc24fb85d4d12c4b0f2695ac2ec..0000000000000000000000000000000000000000 --- a/backport-0003-CVE-2021-44142.patch +++ /dev/null @@ -1,67 +0,0 @@ -From b4c0b4620f12055207adb0519c8d91c3021f354a Mon Sep 17 00:00:00 2001 -From: Ralph Boehme -Date: Fri, 26 Nov 2021 07:19:32 +0100 -Subject: [PATCH 05/99] CVE-2021-44142: libadouble: harden ad_unpack_xattrs() - -This ensures ad_unpack_xattrs() is only called for an ad_type of ADOUBLE_RSRC, -which is used for parsing ._ AppleDouble sidecar files, and the buffer -ad->ad_data is AD_XATTR_MAX_HDR_SIZE bytes large which is a prerequisite for all -buffer out-of-bounds access checks in ad_unpack_xattrs(). - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14914 - -Signed-off-by: Ralph Boehme -Reviewed-by: Jeremy Allison ---- - source3/lib/adouble.c | 21 ++++++++++++++++++--- - 1 file changed, 18 insertions(+), 3 deletions(-) - -diff --git a/source3/lib/adouble.c b/source3/lib/adouble.c -index f809a445081..6cbe8a5aeda 100644 ---- a/source3/lib/adouble.c -+++ b/source3/lib/adouble.c -@@ -707,14 +707,27 @@ static bool ad_pack(struct vfs_handle_struct *handle, - static bool ad_unpack_xattrs(struct adouble *ad) - { - struct ad_xattr_header *h = &ad->adx_header; -+ size_t bufsize = talloc_get_size(ad->ad_data); - const char *p = ad->ad_data; - uint32_t hoff; - uint32_t i; - -+ if (ad->ad_type != ADOUBLE_RSRC) { -+ return false; -+ } -+ - if (ad_getentrylen(ad, ADEID_FINDERI) <= ADEDLEN_FINDERI) { - return true; - } - -+ /* -+ * Ensure the buffer ad->ad_data was allocated by ad_alloc() for an -+ * ADOUBLE_RSRC type (._ AppleDouble file on-disk). -+ */ -+ if (bufsize != AD_XATTR_MAX_HDR_SIZE) { -+ return false; -+ } -+ - /* 2 bytes padding */ - hoff = ad_getentryoff(ad, ADEID_FINDERI) + ADEDLEN_FINDERI + 2; - -@@ -964,9 +977,11 @@ static bool ad_unpack(struct adouble *ad, const size_t nentries, - ad->ad_eid[eid].ade_len = len; - } - -- ok = ad_unpack_xattrs(ad); -- if (!ok) { -- return false; -+ if (ad->ad_type == ADOUBLE_RSRC) { -+ ok = ad_unpack_xattrs(ad); -+ if (!ok) { -+ return false; -+ } - } - - return true; --- -2.25.1 diff --git a/backport-0003-CVE-2022-3437.patch b/backport-0003-CVE-2022-3437.patch deleted file mode 100644 index ccc5abd698e6910245520d3c1cb2c10874bef314..0000000000000000000000000000000000000000 --- a/backport-0003-CVE-2022-3437.patch +++ /dev/null @@ -1,1351 +0,0 @@ -From 310bffc085514f9ceba5b3501ddef15807c53809 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Wed, 12 Oct 2022 13:55:39 +1300 -Subject: [PATCH 07/15] CVE-2022-3437 s4/auth/tests: Add unit tests for - unwrap_des3() - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15134 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett -[jsutton@samba.org Adapted to lack of 'samba.unittests.auth.sam' test, - renamed 'third_party' to 'source4' in paths, defined - HEIMDAL_NORETURN_ATTRIBUTE and HEIMDAL_PRINTF_ATTRIBUTE to fix compiler - error] - -Conflict: NA -Reference: https://download.samba.org/pub/samba/patches/security/samba-4.15.11-security-2022-10-25.patch ---- - selftest/knownfail.d/heimdal-des-overflow | 9 + - selftest/tests.py | 5 + - source4/auth/tests/heimdal_unwrap_des.c | 1247 +++++++++++++++++++++ - source4/auth/wscript_build | 21 + - 4 files changed, 1282 insertions(+) - create mode 100644 selftest/knownfail.d/heimdal-des-overflow - create mode 100644 source4/auth/tests/heimdal_unwrap_des.c - -diff --git a/selftest/knownfail.d/heimdal-des-overflow b/selftest/knownfail.d/heimdal-des-overflow -new file mode 100644 -index 00000000000..23acbb43d31 ---- /dev/null -+++ b/selftest/knownfail.d/heimdal-des-overflow -@@ -0,0 +1,9 @@ -+^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_dce_style_missing_payload.none -+^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_dce_style_with_seal_missing_payload.none -+^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_missing_8_bytes.none -+^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_missing_payload.none -+^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_truncated_header_0.none -+^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_truncated_header_1.none -+^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_with_padding_truncated_0.none -+^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_with_padding_truncated_1.none -+^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_with_seal_missing_payload.none -diff --git a/selftest/tests.py b/selftest/tests.py -index c87b41c1a66..1331a6841e0 100644 ---- a/selftest/tests.py -+++ b/selftest/tests.py -@@ -47,6 +47,8 @@ with_pam = ("WITH_PAM" in config_hash) - with_elasticsearch_backend = ("HAVE_SPOTLIGHT_BACKEND_ES" in config_hash) - pam_wrapper_so_path = config_hash.get("LIBPAM_WRAPPER_SO_PATH") - pam_set_items_so_path = config_hash.get("PAM_SET_ITEMS_SO_PATH") -+have_heimdal_support = "SAMBA4_USES_HEIMDAL" in config_hash -+using_system_gssapi = "USING_SYSTEM_GSSAPI" in config_hash - - planpythontestsuite("none", "samba.tests.source") - if have_man_pages_support: -@@ -429,6 +431,9 @@ plantestsuite("samba.unittests.test_registry_regfio", "none", - [os.path.join(bindir(), "default/source3/test_registry_regfio")]) - plantestsuite("samba.unittests.test_oLschema2ldif", "none", - [os.path.join(bindir(), "default/source4/utils/oLschema2ldif/test_oLschema2ldif")]) -+if have_heimdal_support and not using_system_gssapi: -+ plantestsuite("samba.unittests.auth.heimdal_gensec_unwrap_des", "none", -+ [valgrindify(os.path.join(bindir(), "test_heimdal_gensec_unwrap_des"))]) - if with_elasticsearch_backend: - plantestsuite("samba.unittests.mdsparser_es", "none", - [os.path.join(bindir(), "default/source3/test_mdsparser_es")] + [configuration]) -diff --git a/source4/auth/tests/heimdal_unwrap_des.c b/source4/auth/tests/heimdal_unwrap_des.c -new file mode 100644 -index 00000000000..dc31e9d0ad1 ---- /dev/null -+++ b/source4/auth/tests/heimdal_unwrap_des.c -@@ -0,0 +1,1247 @@ -+/* -+ * Unit tests for source4/heimdal/lib/gssapi/krb5/unwrap.c -+ * -+ * 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 . -+ * -+ */ -+ -+/* -+ * from cmocka.c: -+ * These headers or their equivalents should be included prior to -+ * including -+ * this header file. -+ * -+ * #include -+ * #include -+ * #include -+ * -+ * This allows test applications to use custom definitions of C standard -+ * library functions and types. -+ * -+ */ -+ -+#include -+#include -+#include -+ -+#include -+ -+#include "includes.h" -+#include "replace.h" -+ -+#define HEIMDAL_NORETURN_ATTRIBUTE _NORETURN_ -+#define HEIMDAL_PRINTF_ATTRIBUTE(x) FORMAT_ATTRIBUTE(x) -+ -+#include "../../../source4/heimdal/lib/gssapi/gssapi/gssapi.h" -+#include "gsskrb5_locl.h" -+ -+/****************************************************************************** -+ * Helper functions -+ ******************************************************************************/ -+ -+const uint8_t *valid_range_begin; -+const uint8_t *valid_range_end; -+const uint8_t *invalid_range_end; -+ -+/* -+ * 'array_len' is the size of the passed in array. 'buffer_len' is the size to -+ * report in the resulting buffer. -+ */ -+static const gss_buffer_desc get_input_buffer(TALLOC_CTX *mem_ctx, -+ const uint8_t array[], -+ const size_t array_len, -+ const size_t buffer_len) -+{ -+ gss_buffer_desc buf; -+ -+ /* Add some padding to catch invalid memory accesses. */ -+ const size_t padding = 0x100; -+ const size_t padded_len = array_len + padding; -+ -+ uint8_t *data = talloc_size(mem_ctx, padded_len); -+ assert_non_null(data); -+ -+ memcpy(data, array, array_len); -+ memset(data + array_len, 0, padding); -+ -+ assert_in_range(buffer_len, 0, array_len); -+ -+ buf.value = data; -+ buf.length = buffer_len; -+ -+ valid_range_begin = buf.value; -+ valid_range_end = valid_range_begin + buf.length; -+ invalid_range_end = valid_range_begin + padded_len; -+ -+ return buf; -+} -+ -+static void assert_mem_in_valid_range(const uint8_t *ptr, const size_t len) -+{ -+ /* Ensure we've set up the range pointers properly. */ -+ assert_non_null(valid_range_begin); -+ assert_non_null(valid_range_end); -+ assert_non_null(invalid_range_end); -+ -+ /* -+ * Ensure the length isn't excessively large (a symptom of integer -+ * underflow). -+ */ -+ assert_in_range(len, 0, 0x1000); -+ -+ /* Ensure the memory is in our valid range. */ -+ assert_in_range(ptr, valid_range_begin, valid_range_end); -+ assert_in_range(ptr + len, valid_range_begin, valid_range_end); -+} -+ -+/* -+ * This function takes a pointer to volatile to allow it to be called from the -+ * ct_memcmp() wrapper. -+ */ -+static void assert_mem_outside_invalid_range(const volatile uint8_t *ptr, -+ const size_t len) -+{ -+ const LargestIntegralType _valid_range_end -+ = cast_ptr_to_largest_integral_type(valid_range_end); -+ const LargestIntegralType _invalid_range_end -+ = cast_ptr_to_largest_integral_type(invalid_range_end); -+ const LargestIntegralType _ptr = cast_ptr_to_largest_integral_type(ptr); -+ const LargestIntegralType _len = cast_to_largest_integral_type(len); -+ -+ /* Ensure we've set up the range pointers properly. */ -+ assert_non_null(valid_range_begin); -+ assert_non_null(valid_range_end); -+ assert_non_null(invalid_range_end); -+ -+ /* -+ * Ensure the length isn't excessively large (a symptom of integer -+ * underflow). -+ */ -+ assert_in_range(len, 0, 0x1000); -+ -+ /* Ensure the memory is outside the invalid range. */ -+ if (_ptr < _invalid_range_end && _ptr + _len > _valid_range_end) { -+ fail(); -+ } -+} -+ -+/***************************************************************************** -+ * wrapped functions -+ *****************************************************************************/ -+ -+krb5_keyblock dummy_key; -+ -+krb5_error_code __wrap_krb5_auth_con_getlocalsubkey(krb5_context context, -+ krb5_auth_context auth_context, -+ krb5_keyblock **keyblock); -+krb5_error_code __wrap_krb5_auth_con_getlocalsubkey(krb5_context context, -+ krb5_auth_context auth_context, -+ krb5_keyblock **keyblock) -+{ -+ *keyblock = &dummy_key; -+ return 0; -+} -+ -+void __wrap_krb5_free_keyblock(krb5_context context, -+ krb5_keyblock *keyblock); -+void __wrap_krb5_free_keyblock(krb5_context context, -+ krb5_keyblock *keyblock) -+{ -+ assert_ptr_equal(&dummy_key, keyblock); -+} -+ -+struct krb5_crypto_data dummy_crypto; -+ -+krb5_error_code __wrap_krb5_crypto_init(krb5_context context, -+ const krb5_keyblock *key, -+ krb5_enctype etype, -+ krb5_crypto *crypto); -+krb5_error_code __wrap_krb5_crypto_init(krb5_context context, -+ const krb5_keyblock *key, -+ krb5_enctype etype, -+ krb5_crypto *crypto) -+{ -+ static const LargestIntegralType etypes[] = {ETYPE_DES3_CBC_NONE, 0}; -+ -+ assert_ptr_equal(&dummy_key, key); -+ assert_in_set(etype, etypes, ARRAY_SIZE(etypes)); -+ -+ *crypto = &dummy_crypto; -+ -+ return 0; -+} -+ -+krb5_error_code __wrap_krb5_decrypt(krb5_context context, -+ krb5_crypto crypto, -+ unsigned usage, -+ void *data, -+ size_t len, -+ krb5_data *result); -+krb5_error_code __wrap_krb5_decrypt(krb5_context context, -+ krb5_crypto crypto, -+ unsigned usage, -+ void *data, -+ size_t len, -+ krb5_data *result) -+{ -+ assert_ptr_equal(&dummy_crypto, crypto); -+ assert_int_equal(KRB5_KU_USAGE_SEAL, usage); -+ -+ assert_mem_in_valid_range(data, len); -+ -+ check_expected(len); -+ check_expected_ptr(data); -+ -+ result->data = malloc(len); -+ assert_non_null(result->data); -+ result->length = len; -+ -+ memcpy(result->data, data, len); -+ -+ return 0; -+} -+ -+krb5_error_code __wrap_krb5_decrypt_ivec(krb5_context context, -+ krb5_crypto crypto, -+ unsigned usage, -+ void *data, -+ size_t len, -+ krb5_data *result, -+ void *ivec); -+krb5_error_code __wrap_krb5_decrypt_ivec(krb5_context context, -+ krb5_crypto crypto, -+ unsigned usage, -+ void *data, -+ size_t len, -+ krb5_data *result, -+ void *ivec) -+{ -+ assert_ptr_equal(&dummy_crypto, crypto); -+ assert_int_equal(KRB5_KU_USAGE_SEQ, usage); -+ -+ assert_mem_in_valid_range(data, len); -+ -+ assert_int_equal(8, len); -+ check_expected_ptr(data); -+ check_expected_ptr(ivec); -+ -+ result->data = malloc(len); -+ assert_non_null(result->data); -+ result->length = len; -+ -+ memcpy(result->data, data, len); -+ -+ return 0; -+} -+ -+krb5_error_code __wrap_krb5_verify_checksum(krb5_context context, -+ krb5_crypto crypto, -+ krb5_key_usage usage, -+ void *data, -+ size_t len, -+ Checksum *cksum); -+krb5_error_code __wrap_krb5_verify_checksum(krb5_context context, -+ krb5_crypto crypto, -+ krb5_key_usage usage, -+ void *data, -+ size_t len, -+ Checksum *cksum) -+{ -+ assert_ptr_equal(&dummy_crypto, crypto); -+ assert_int_equal(KRB5_KU_USAGE_SIGN, usage); -+ -+ assert_mem_in_valid_range(data, len); -+ -+ check_expected(len); -+ check_expected_ptr(data); -+ -+ assert_non_null(cksum); -+ assert_int_equal(CKSUMTYPE_HMAC_SHA1_DES3, cksum->cksumtype); -+ assert_int_equal(20, cksum->checksum.length); -+ check_expected_ptr(cksum->checksum.data); -+ -+ return 0; -+} -+ -+krb5_error_code __wrap_krb5_crypto_destroy(krb5_context context, -+ krb5_crypto crypto); -+krb5_error_code __wrap_krb5_crypto_destroy(krb5_context context, -+ krb5_crypto crypto) -+{ -+ assert_ptr_equal(&dummy_crypto, crypto); -+ -+ return 0; -+} -+ -+ -+int __wrap_der_get_length(const unsigned char *p, -+ size_t len, -+ size_t *val, -+ size_t *size); -+int __real_der_get_length(const unsigned char *p, -+ size_t len, -+ size_t *val, -+ size_t *size); -+int __wrap_der_get_length(const unsigned char *p, -+ size_t len, -+ size_t *val, -+ size_t *size) -+{ -+ assert_mem_in_valid_range(p, len); -+ -+ return __real_der_get_length(p, len, val, size); -+} -+ -+int __wrap_ct_memcmp(const volatile void * volatile p1, -+ const volatile void * volatile p2, -+ size_t len); -+int __real_ct_memcmp(const volatile void * volatile p1, -+ const volatile void * volatile p2, -+ size_t len); -+int __wrap_ct_memcmp(const volatile void * volatile p1, -+ const volatile void * volatile p2, -+ size_t len) -+{ -+ assert_mem_outside_invalid_range(p1, len); -+ assert_mem_outside_invalid_range(p2, len); -+ -+ return __real_ct_memcmp(p1, p2, len); -+} -+ -+void *__wrap_malloc(size_t size); -+void *__real_malloc(size_t size); -+void *__wrap_malloc(size_t size) -+{ -+ /* -+ * Ensure the length isn't excessively large (a symptom of integer -+ * underflow). -+ */ -+ assert_in_range(size, 0, 0x10000); -+ -+ return __real_malloc(size); -+} -+ -+/***************************************************************************** -+ * Mock implementations -+ *****************************************************************************/ -+ -+/* -+ * Set the globals used by the mocked functions to a known and consistent state -+ * -+ */ -+static void init_mock_results(TALLOC_CTX *mem_ctx) -+{ -+ dummy_key.keytype = KRB5_ENCTYPE_DES3_CBC_MD5; -+ dummy_key.keyvalue.data = NULL; -+ dummy_key.keyvalue.length = 0; -+ -+ dummy_crypto = (struct krb5_crypto_data) {0}; -+ -+ valid_range_begin = NULL; -+ valid_range_end = NULL; -+ invalid_range_end = NULL; -+} -+ -+/***************************************************************************** -+ * Unit test set up and tear down -+ *****************************************************************************/ -+ -+struct context { -+ gss_ctx_id_t context_handle; -+}; -+ -+static int setup(void **state) { -+ struct context *ctx = NULL; -+ krb5_context context = NULL; -+ OM_uint32 major_status; -+ OM_uint32 minor_status; -+ krb5_error_code code; -+ -+ ctx = talloc_zero(NULL, struct context); -+ assert_non_null(ctx); -+ -+ init_mock_results(ctx); -+ -+ code = _gsskrb5_init(&context); -+ assert_int_equal(0, code); -+ -+ major_status = _gsskrb5_create_ctx(&minor_status, -+ &ctx->context_handle, -+ context, -+ GSS_C_NO_CHANNEL_BINDINGS, -+ ACCEPTOR_START); -+ assert_int_equal(GSS_S_COMPLETE, major_status); -+ -+ *state = ctx; -+ return 0; -+} -+ -+static int teardown(void **state) { -+ struct context *ctx = *state; -+ OM_uint32 major_status; -+ OM_uint32 minor_status; -+ -+ major_status = _gsskrb5_delete_sec_context(&minor_status, -+ &ctx->context_handle, -+ GSS_C_NO_BUFFER); -+ assert_int_equal(GSS_S_COMPLETE, major_status); -+ -+ TALLOC_FREE(ctx); -+ return 0; -+} -+ -+/***************************************************************************** -+ * _gsskrb5_unwrap unit tests -+ *****************************************************************************/ -+ -+static void test_unwrap_dce_style_missing_payload(void **state) { -+ struct context *ctx = *state; -+ OM_uint32 major_status; -+ OM_uint32 minor_status; -+ gsskrb5_ctx gss_ctx; -+ gss_buffer_desc input = {0}; -+ gss_buffer_desc output = {0}; -+ int conf_state; -+ gss_qop_t qop_state; -+ -+ /* See RFC 1964 for token format. */ -+ static const uint8_t data[] = { -+ 0x60, /* ASN.1 Application tag */ -+ 0x37, /* total length */ -+ 0x06, /* OBJECT IDENTIFIER */ -+ 0x09, /* mech length */ -+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02, /* GSS KRB5 mech */ -+ 0x02, 0x01, /* TOK_ID */ -+ 0x04, 0x00, /* SGN_ALG (HMAC SHA1 DES3-KD) */ -+ 0xff, 0xff, /* SEAL_ALG (none) */ -+ 0xff, 0xff, /* Filler */ -+ 0xa0, 0xa1, 0xa2, 0xa3, /* encrypted sequence number */ -+ 0x00, 0x00, 0x00, 0x00, /* sequence number direction (remote) */ -+ /* checksum */ -+ 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, -+ 0xa9, 0xaa, 0xab, 0xac, 0xad, -+ 0xae, 0xaf, 0xb0, 0xb1, 0xb2, -+ 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, -+ }; -+ -+ input = get_input_buffer(ctx, data, sizeof(data), 22); -+ -+ gss_ctx = (gsskrb5_ctx) ctx->context_handle; -+ gss_ctx->flags |= GSS_C_DCE_STYLE; -+ -+ major_status = _gsskrb5_unwrap(&minor_status, -+ ctx->context_handle, -+ &input, -+ &output, -+ &conf_state, -+ &qop_state); -+ assert_int_equal(GSS_S_BAD_MECH, major_status); -+} -+ -+static void test_unwrap_dce_style_valid(void **state) { -+ struct context *ctx = *state; -+ OM_uint32 major_status; -+ OM_uint32 minor_status; -+ gsskrb5_ctx gss_ctx; -+ gss_buffer_desc input = {0}; -+ gss_buffer_desc output = {0}; -+ int conf_state; -+ gss_qop_t qop_state; -+ -+ /* See RFC 1964 for token format. */ -+ static const uint8_t data[] = { -+ 0x60, /* ASN.1 Application tag */ -+ 0x37, /* total length */ -+ 0x06, /* OBJECT IDENTIFIER */ -+ 0x09, /* mech length */ -+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02, /* GSS KRB5 mech */ -+ 0x02, 0x01, /* TOK_ID */ -+ 0x04, 0x00, /* SGN_ALG (HMAC SHA1 DES3-KD) */ -+ 0xff, 0xff, /* SEAL_ALG (none) */ -+ 0xff, 0xff, /* Filler */ -+ 0xa0, 0xa1, 0xa2, 0xa3, /* encrypted sequence number */ -+ 0x00, 0x00, 0x00, 0x00, /* sequence number direction (remote) */ -+ /* checksum */ -+ 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, -+ 0xa9, 0xaa, 0xab, 0xac, 0xad, -+ 0xae, 0xaf, 0xb0, 0xb1, 0xb2, -+ 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, -+ /* unused */ -+ 0xb8, 0xb9, 0xba, 0xbb, -+ 0xbc, 0xbd, 0xbe, -+ 0x00, /* padding byte */ -+ }; -+ -+ input = get_input_buffer(ctx, data, sizeof(data), 57); -+ -+ gss_ctx = (gsskrb5_ctx) ctx->context_handle; -+ gss_ctx->flags |= GSS_C_DCE_STYLE; -+ -+ expect_value(__wrap_krb5_decrypt_ivec, data, (uint8_t *)input.value + 21); -+ expect_memory(__wrap_krb5_decrypt_ivec, ivec, -+ (uint8_t *)input.value + 29, DES_CBLOCK_LEN); -+ -+ expect_value(__wrap_krb5_verify_checksum, len, 16); -+ expect_value(__wrap_krb5_verify_checksum, data, (uint8_t *)input.value + 41); -+ expect_memory(__wrap_krb5_verify_checksum, cksum->checksum.data, -+ (uint8_t *)input.value + 29, 20); -+ -+ major_status = _gsskrb5_unwrap(&minor_status, -+ ctx->context_handle, -+ &input, -+ &output, -+ &conf_state, -+ &qop_state); -+ assert_int_equal(GSS_S_COMPLETE, major_status); -+ -+ assert_int_equal(0, conf_state); -+ assert_int_equal(GSS_C_QOP_DEFAULT, qop_state); -+ -+ assert_int_equal(output.length, 0); -+ -+ major_status = gss_release_buffer(&minor_status, &output); -+ assert_int_equal(GSS_S_COMPLETE, major_status); -+} -+ -+static void test_unwrap_dce_style_with_seal_missing_payload(void **state) { -+ struct context *ctx = *state; -+ OM_uint32 major_status; -+ OM_uint32 minor_status; -+ gsskrb5_ctx gss_ctx; -+ gss_buffer_desc input = {0}; -+ gss_buffer_desc output = {0}; -+ int conf_state; -+ gss_qop_t qop_state; -+ -+ /* See RFC 1964 for token format. */ -+ static const uint8_t data[] = { -+ 0x60, /* ASN.1 Application tag */ -+ 0x37, /* total length */ -+ 0x06, /* OBJECT IDENTIFIER */ -+ 0x09, /* mech length */ -+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02, /* GSS KRB5 mech */ -+ 0x02, 0x01, /* TOK_ID */ -+ 0x04, 0x00, /* SGN_ALG (HMAC SHA1 DES3-KD) */ -+ 0x02, 0x00, /* SEAL_ALG (DES3-KD) */ -+ 0xff, 0xff, /* Filler */ -+ 0xa0, 0xa1, 0xa2, 0xa3, /* encrypted sequence number */ -+ 0x00, 0x00, 0x00, 0x00, /* sequence number direction (remote) */ -+ /* checksum */ -+ 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, -+ 0xa9, 0xaa, 0xab, 0xac, 0xad, -+ 0xae, 0xaf, 0xb0, 0xb1, 0xb2, -+ 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, -+ }; -+ -+ input = get_input_buffer(ctx, data, sizeof(data), 22); -+ -+ gss_ctx = (gsskrb5_ctx) ctx->context_handle; -+ gss_ctx->flags |= GSS_C_DCE_STYLE; -+ -+ major_status = _gsskrb5_unwrap(&minor_status, -+ ctx->context_handle, -+ &input, -+ &output, -+ &conf_state, -+ &qop_state); -+ assert_int_equal(GSS_S_BAD_MECH, major_status); -+} -+ -+static void test_unwrap_dce_style_with_seal_valid(void **state) { -+ struct context *ctx = *state; -+ OM_uint32 major_status; -+ OM_uint32 minor_status; -+ gsskrb5_ctx gss_ctx; -+ gss_buffer_desc input = {0}; -+ gss_buffer_desc output = {0}; -+ int conf_state; -+ gss_qop_t qop_state; -+ -+ /* See RFC 1964 for token format. */ -+ static const uint8_t data[] = { -+ 0x60, /* ASN.1 Application tag */ -+ 0x37, /* total length */ -+ 0x06, /* OBJECT IDENTIFIER */ -+ 0x09, /* mech length */ -+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02, /* GSS KRB5 mech */ -+ 0x02, 0x01, /* TOK_ID */ -+ 0x04, 0x00, /* SGN_ALG (HMAC SHA1 DES3-KD) */ -+ 0x02, 0x00, /* SEAL_ALG (DES3-KD) */ -+ 0xff, 0xff, /* Filler */ -+ 0xa0, 0xa1, 0xa2, 0xa3, /* encrypted sequence number */ -+ 0x00, 0x00, 0x00, 0x00, /* sequence number direction (remote) */ -+ /* checksum */ -+ 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, -+ 0xa9, 0xaa, 0xab, 0xac, 0xad, -+ 0xae, 0xaf, 0xb0, 0xb1, 0xb2, -+ 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, -+ /* unused */ -+ 0xb8, 0xb9, 0xba, 0xbb, -+ 0xbc, 0xbd, 0xbe, -+ 0x00, /* padding byte */ -+ }; -+ -+ input = get_input_buffer(ctx, data, sizeof(data), 57); -+ -+ gss_ctx = (gsskrb5_ctx) ctx->context_handle; -+ gss_ctx->flags |= GSS_C_DCE_STYLE; -+ -+ expect_value(__wrap_krb5_decrypt, len, 8); -+ expect_value(__wrap_krb5_decrypt, data, (uint8_t *)input.value + 49); -+ -+ expect_value(__wrap_krb5_decrypt_ivec, data, (uint8_t *)input.value + 21); -+ expect_memory(__wrap_krb5_decrypt_ivec, ivec, -+ (uint8_t *)input.value + 29, DES_CBLOCK_LEN); -+ -+ expect_value(__wrap_krb5_verify_checksum, len, 16); -+ expect_value(__wrap_krb5_verify_checksum, data, (uint8_t *)input.value + 41); -+ expect_memory(__wrap_krb5_verify_checksum, cksum->checksum.data, -+ (uint8_t *)input.value + 29, 20); -+ -+ major_status = _gsskrb5_unwrap(&minor_status, -+ ctx->context_handle, -+ &input, -+ &output, -+ &conf_state, -+ &qop_state); -+ assert_int_equal(GSS_S_COMPLETE, major_status); -+ -+ assert_int_equal(1, conf_state); -+ assert_int_equal(GSS_C_QOP_DEFAULT, qop_state); -+ -+ assert_int_equal(output.length, 0); -+ -+ major_status = gss_release_buffer(&minor_status, &output); -+ assert_int_equal(GSS_S_COMPLETE, major_status); -+} -+ -+static void test_unwrap_missing_8_bytes(void **state) { -+ struct context *ctx = *state; -+ OM_uint32 major_status; -+ OM_uint32 minor_status; -+ gss_buffer_desc input = {0}; -+ gss_buffer_desc output = {0}; -+ int conf_state; -+ gss_qop_t qop_state; -+ -+ /* See RFC 1964 for token format. */ -+ static const uint8_t data[] = { -+ 0x60, /* ASN.1 Application tag */ -+ 0x2f, /* total length */ -+ 0x06, /* OBJECT IDENTIFIER */ -+ 0x09, /* mech length */ -+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02, /* GSS KRB5 mech */ -+ 0x02, 0x01, /* TOK_ID */ -+ 0x04, 0x00, /* SGN_ALG (HMAC SHA1 DES3-KD) */ -+ 0xff, 0xff, /* SEAL_ALG (none) */ -+ 0xff, 0xff, /* Filler */ -+ 0xa0, 0xa1, 0xa2, 0xa3, /* encrypted sequence number */ -+ 0x00, 0x00, 0x00, 0x00, /* sequence number direction (remote) */ -+ /* checksum */ -+ 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, -+ 0xa9, 0xaa, 0xab, 0xac, 0xad, -+ 0xae, 0xaf, 0xb0, 0xb1, 0xb2, -+ 0xb3, 0xb4, 0xb5, 0xb6, 0x00, /* padding byte */ -+ }; -+ -+ input = get_input_buffer(ctx, data, sizeof(data), 49); -+ -+ /* -+ * A fixed unwrap_des3() should fail before these wrappers are called, -+ * but we want the wrappers to have access to any required values in the -+ * event that they are called. Specifying WILL_RETURN_ONCE avoids a test -+ * failure if these values remain unused. -+ */ -+ expect_value_count(__wrap_krb5_decrypt_ivec, data, -+ (uint8_t *)input.value + 21, -+ WILL_RETURN_ONCE); -+ expect_memory_count(__wrap_krb5_decrypt_ivec, ivec, -+ (uint8_t *)input.value + 29, DES_CBLOCK_LEN, -+ WILL_RETURN_ONCE); -+ -+ expect_value_count(__wrap_krb5_verify_checksum, len, 8, WILL_RETURN_ONCE); -+ expect_value_count(__wrap_krb5_verify_checksum, data, -+ (uint8_t *)input.value + 41, -+ WILL_RETURN_ONCE); -+ expect_memory_count(__wrap_krb5_verify_checksum, cksum->checksum.data, -+ (uint8_t *)input.value + 29, 20, -+ WILL_RETURN_ONCE); -+ -+ major_status = _gsskrb5_unwrap(&minor_status, -+ ctx->context_handle, -+ &input, -+ &output, -+ &conf_state, -+ &qop_state); -+ assert_int_equal(GSS_S_BAD_MECH, major_status); -+} -+ -+static void test_unwrap_missing_payload(void **state) { -+ struct context *ctx = *state; -+ OM_uint32 major_status; -+ OM_uint32 minor_status; -+ gss_buffer_desc input = {0}; -+ gss_buffer_desc output = {0}; -+ int conf_state; -+ gss_qop_t qop_state; -+ -+ /* See RFC 1964 for token format. */ -+ static const uint8_t data[] = { -+ 0x60, /* ASN.1 Application tag */ -+ 0x14, /* total length */ -+ 0x06, /* OBJECT IDENTIFIER */ -+ 0x09, /* mech length */ -+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02, /* GSS KRB5 mech */ -+ 0x02, 0x01, /* TOK_ID */ -+ 0x04, 0x00, /* SGN_ALG (HMAC SHA1 DES3-KD) */ -+ 0xff, 0xff, /* SEAL_ALG (none) */ -+ 0xff, 0xff, /* Filler */ -+ 0x00, 0xa1, 0xa2, 0xa3, /* padding byte / encrypted sequence number */ -+ 0x00, 0x00, 0x00, 0x00, /* sequence number direction (remote) */ -+ /* checksum */ -+ 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, -+ 0xa9, 0xaa, 0xab, 0xac, 0xad, -+ 0xae, 0xaf, 0xb0, 0xb1, 0xb2, -+ 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, -+ }; -+ -+ input = get_input_buffer(ctx, data, sizeof(data), 22); -+ -+ major_status = _gsskrb5_unwrap(&minor_status, -+ ctx->context_handle, -+ &input, -+ &output, -+ &conf_state, -+ &qop_state); -+ assert_int_equal(GSS_S_BAD_MECH, major_status); -+} -+ -+static void test_unwrap_truncated_header_0(void **state) { -+ struct context *ctx = *state; -+ OM_uint32 major_status; -+ OM_uint32 minor_status; -+ gss_buffer_desc input = {0}; -+ gss_buffer_desc output = {0}; -+ int conf_state; -+ gss_qop_t qop_state; -+ -+ /* See RFC 1964 for token format. */ -+ static const uint8_t data[] = { -+ 0x60, /* ASN.1 Application tag */ -+ 0x00, /* total length */ -+ 0x06, /* OBJECT IDENTIFIER */ -+ }; -+ -+ input = get_input_buffer(ctx, data, sizeof(data), 2); -+ -+ major_status = _gsskrb5_unwrap(&minor_status, -+ ctx->context_handle, -+ &input, -+ &output, -+ &conf_state, -+ &qop_state); -+ assert_int_equal(GSS_S_DEFECTIVE_TOKEN, major_status); -+} -+ -+static void test_unwrap_truncated_header_1(void **state) { -+ struct context *ctx = *state; -+ OM_uint32 major_status; -+ OM_uint32 minor_status; -+ gss_buffer_desc input = {0}; -+ gss_buffer_desc output = {0}; -+ int conf_state; -+ gss_qop_t qop_state; -+ -+ /* See RFC 1964 for token format. */ -+ static const uint8_t data[] = { -+ 0x60, /* ASN.1 Application tag */ -+ 0x02, /* total length */ -+ 0x06, /* OBJECT IDENTIFIER */ -+ 0x09, /* mech length */ -+ 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, /* GSS KRB5 mech */ -+ }; -+ -+ input = get_input_buffer(ctx, data, sizeof(data), 4); -+ -+ major_status = _gsskrb5_unwrap(&minor_status, -+ ctx->context_handle, -+ &input, -+ &output, -+ &conf_state, -+ &qop_state); -+ assert_int_equal(GSS_S_BAD_MECH, major_status); -+} -+ -+static void test_unwrap_valid(void **state) { -+ struct context *ctx = *state; -+ OM_uint32 major_status; -+ OM_uint32 minor_status; -+ gss_buffer_desc input = {0}; -+ gss_buffer_desc output = {0}; -+ int conf_state; -+ gss_qop_t qop_state; -+ -+ /* See RFC 1964 for token format. */ -+ static const uint8_t data[] = { -+ 0x60, /* ASN.1 Application tag */ -+ 0x37, /* total length */ -+ 0x06, /* OBJECT IDENTIFIER */ -+ 0x09, /* mech length */ -+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02, /* GSS KRB5 mech */ -+ 0x02, 0x01, /* TOK_ID */ -+ 0x04, 0x00, /* SGN_ALG (HMAC SHA1 DES3-KD) */ -+ 0xff, 0xff, /* SEAL_ALG (none) */ -+ 0xff, 0xff, /* Filler */ -+ 0xa0, 0xa1, 0xa2, 0xa3, /* encrypted sequence number */ -+ 0x00, 0x00, 0x00, 0x00, /* sequence number direction (remote) */ -+ /* checksum */ -+ 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, -+ 0xa9, 0xaa, 0xab, 0xac, 0xad, -+ 0xae, 0xaf, 0xb0, 0xb1, 0xb2, -+ 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, -+ /* unused */ -+ 0xb8, 0xb9, 0xba, 0xbb, -+ 0xbc, 0xbd, 0xbe, -+ 0x00, /* padding byte */ -+ }; -+ -+ input = get_input_buffer(ctx, data, sizeof(data), 57); -+ -+ expect_value(__wrap_krb5_decrypt_ivec, data, (uint8_t *)input.value + 21); -+ expect_memory(__wrap_krb5_decrypt_ivec, ivec, -+ (uint8_t *)input.value + 29, DES_CBLOCK_LEN); -+ -+ expect_value(__wrap_krb5_verify_checksum, len, 16); -+ expect_value(__wrap_krb5_verify_checksum, data, (uint8_t *)input.value + 41); -+ expect_memory(__wrap_krb5_verify_checksum, cksum->checksum.data, -+ (uint8_t *)input.value + 29, 20); -+ -+ major_status = _gsskrb5_unwrap(&minor_status, -+ ctx->context_handle, -+ &input, -+ &output, -+ &conf_state, -+ &qop_state); -+ assert_int_equal(GSS_S_COMPLETE, major_status); -+ -+ assert_int_equal(0, conf_state); -+ assert_int_equal(GSS_C_QOP_DEFAULT, qop_state); -+ -+ assert_int_equal(output.length, 0); -+ -+ major_status = gss_release_buffer(&minor_status, &output); -+ assert_int_equal(GSS_S_COMPLETE, major_status); -+} -+ -+static void test_unwrap_with_padding_truncated_0(void **state) { -+ struct context *ctx = *state; -+ OM_uint32 major_status; -+ OM_uint32 minor_status; -+ gss_buffer_desc input = {0}; -+ gss_buffer_desc output = {0}; -+ int conf_state; -+ gss_qop_t qop_state; -+ -+ /* See RFC 1964 for token format. */ -+ static const uint8_t data[] = { -+ 0x60, /* ASN.1 Application tag */ -+ 0x37, /* total length */ -+ 0x06, /* OBJECT IDENTIFIER */ -+ 0x09, /* mech length */ -+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02, /* GSS KRB5 mech */ -+ 0x02, 0x01, /* TOK_ID */ -+ 0x04, 0x00, /* SGN_ALG (HMAC SHA1 DES3-KD) */ -+ 0xff, 0xff, /* SEAL_ALG (none) */ -+ 0xff, 0xff, /* Filler */ -+ 0xa0, 0xa1, 0xa2, 0xa3, /* encrypted sequence number */ -+ 0x00, 0x00, 0x00, 0x00, /* sequence number direction (remote) */ -+ /* checksum */ -+ 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, -+ 0xa9, 0xaa, 0xab, 0xac, 0xad, -+ 0xae, 0xaf, 0xb0, 0xb1, 0xb2, -+ 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, -+ /* unused */ -+ 0xb8, 0xb9, 0xba, 0xbb, -+ 0x04, 0x04, 0x04, 0x04, /* padding bytes */ -+ }; -+ -+ input = get_input_buffer(ctx, data, sizeof(data), 57); -+ -+ /* -+ * A fixed unwrap_des3() should fail before these wrappers are called, -+ * but we want the wrappers to have access to any required values in the -+ * event that they are called. Specifying WILL_RETURN_ONCE avoids a test -+ * failure if these values remain unused. -+ */ -+ expect_value_count(__wrap_krb5_decrypt_ivec, data, -+ (uint8_t *)input.value + 21, -+ WILL_RETURN_ONCE); -+ expect_memory_count(__wrap_krb5_decrypt_ivec, ivec, -+ (uint8_t *)input.value + 29, DES_CBLOCK_LEN, -+ WILL_RETURN_ONCE); -+ -+ expect_value_count(__wrap_krb5_verify_checksum, len, 16, WILL_RETURN_ONCE); -+ expect_value_count(__wrap_krb5_verify_checksum, data, -+ (uint8_t *)input.value + 41, -+ WILL_RETURN_ONCE); -+ expect_memory_count(__wrap_krb5_verify_checksum, cksum->checksum.data, -+ (uint8_t *)input.value + 29, 20, -+ WILL_RETURN_ONCE); -+ -+ major_status = _gsskrb5_unwrap(&minor_status, -+ ctx->context_handle, -+ &input, -+ &output, -+ &conf_state, -+ &qop_state); -+ assert_int_equal(GSS_S_BAD_MECH, major_status); -+} -+ -+static void test_unwrap_with_padding_truncated_1(void **state) { -+ struct context *ctx = *state; -+ OM_uint32 major_status; -+ OM_uint32 minor_status; -+ gss_buffer_desc input = {0}; -+ gss_buffer_desc output = {0}; -+ int conf_state; -+ gss_qop_t qop_state; -+ -+ /* See RFC 1964 for token format. */ -+ static const uint8_t data[] = { -+ 0x60, /* ASN.1 Application tag */ -+ 0x37, /* total length */ -+ 0x06, /* OBJECT IDENTIFIER */ -+ 0x09, /* mech length */ -+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02, /* GSS KRB5 mech */ -+ 0x02, 0x01, /* TOK_ID */ -+ 0x04, 0x00, /* SGN_ALG (HMAC SHA1 DES3-KD) */ -+ 0xff, 0xff, /* SEAL_ALG (none) */ -+ 0xff, 0xff, /* Filler */ -+ 0x00, 0xa1, 0xa2, 0xa3, /* padding byte / encrypted sequence number */ -+ 0x00, 0x00, 0x00, 0x00, /* sequence number direction (remote) */ -+ /* checksum */ -+ 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, -+ 0xa9, 0xaa, 0xab, 0xac, 0xad, -+ 0xae, 0xaf, 0xb0, 0xb1, 0xb2, -+ 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, -+ /* padding bytes */ -+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, -+ }; -+ -+ input = get_input_buffer(ctx, data, sizeof(data), 57); -+ -+ /* -+ * A fixed unwrap_des3() should fail before these wrappers are called, -+ * but we want the wrappers to have access to any required values in the -+ * event that they are called. Specifying WILL_RETURN_ONCE avoids a test -+ * failure if these values remain unused. -+ */ -+ expect_value_count(__wrap_krb5_decrypt_ivec, data, -+ (uint8_t *)input.value + 21, -+ WILL_RETURN_ONCE); -+ expect_memory_count(__wrap_krb5_decrypt_ivec, ivec, -+ (uint8_t *)input.value + 29, DES_CBLOCK_LEN, -+ WILL_RETURN_ONCE); -+ -+ expect_value_count(__wrap_krb5_verify_checksum, len, 16, WILL_RETURN_ONCE); -+ expect_value_count(__wrap_krb5_verify_checksum, data, -+ (uint8_t *)input.value + 41, -+ WILL_RETURN_ONCE); -+ expect_memory_count(__wrap_krb5_verify_checksum, cksum->checksum.data, -+ (uint8_t *)input.value + 29, 20, -+ WILL_RETURN_ONCE); -+ -+ major_status = _gsskrb5_unwrap(&minor_status, -+ ctx->context_handle, -+ &input, -+ &output, -+ &conf_state, -+ &qop_state); -+ assert_int_equal(GSS_S_BAD_MECH, major_status); -+} -+ -+static void test_unwrap_with_padding_valid(void **state) { -+ struct context *ctx = *state; -+ OM_uint32 major_status; -+ OM_uint32 minor_status; -+ gss_buffer_desc input = {0}; -+ gss_buffer_desc output = {0}; -+ int conf_state; -+ gss_qop_t qop_state; -+ -+ /* See RFC 1964 for token format. */ -+ static const uint8_t data[] = { -+ 0x60, /* ASN.1 Application tag */ -+ 0x3f, /* total length */ -+ 0x06, /* OBJECT IDENTIFIER */ -+ 0x09, /* mech length */ -+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02, /* GSS KRB5 mech */ -+ 0x02, 0x01, /* TOK_ID */ -+ 0x04, 0x00, /* SGN_ALG (HMAC SHA1 DES3-KD) */ -+ 0xff, 0xff, /* SEAL_ALG (none) */ -+ 0xff, 0xff, /* Filler */ -+ 0xa0, 0xa1, 0xa2, 0xa3, /* encrypted sequence number */ -+ 0x00, 0x00, 0x00, 0x00, /* sequence number direction (remote) */ -+ /* checksum */ -+ 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, -+ 0xa9, 0xaa, 0xab, 0xac, 0xad, -+ 0xae, 0xaf, 0xb0, 0xb1, 0xb2, -+ 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, -+ /* unused */ -+ 0xb8, 0xb9, 0xba, 0xbb, -+ 0xbc, 0xbd, 0xbe, 0xbf, -+ /* padding bytes */ -+ 0x08, 0x08, 0x08, 0x08, -+ 0x08, 0x08, 0x08, 0x08, -+ }; -+ -+ input = get_input_buffer(ctx, data, sizeof(data), 65); -+ -+ expect_value(__wrap_krb5_decrypt_ivec, data, (uint8_t *)input.value + 21); -+ expect_memory(__wrap_krb5_decrypt_ivec, ivec, -+ (uint8_t *)input.value + 29, DES_CBLOCK_LEN); -+ -+ expect_value(__wrap_krb5_verify_checksum, len, 24); -+ expect_value(__wrap_krb5_verify_checksum, data, (uint8_t *)input.value + 41); -+ expect_memory(__wrap_krb5_verify_checksum, cksum->checksum.data, -+ (uint8_t *)input.value + 29, 20); -+ -+ major_status = _gsskrb5_unwrap(&minor_status, -+ ctx->context_handle, -+ &input, -+ &output, -+ &conf_state, -+ &qop_state); -+ assert_int_equal(GSS_S_COMPLETE, major_status); -+ -+ assert_int_equal(0, conf_state); -+ assert_int_equal(GSS_C_QOP_DEFAULT, qop_state); -+ -+ assert_int_equal(output.length, 0); -+ -+ major_status = gss_release_buffer(&minor_status, &output); -+ assert_int_equal(GSS_S_COMPLETE, major_status); -+} -+ -+static void test_unwrap_with_seal_empty_token_valid(void **state) { -+ struct context *ctx = *state; -+ OM_uint32 major_status; -+ OM_uint32 minor_status; -+ gss_buffer_desc input = {0}; -+ gss_buffer_desc output = {0}; -+ int conf_state; -+ gss_qop_t qop_state; -+ -+ /* See RFC 1964 for token format. */ -+ static const uint8_t data[] = { -+ 0x60, /* ASN.1 Application tag */ -+ 0x37, /* total length */ -+ 0x06, /* OBJECT IDENTIFIER */ -+ 0x09, /* mech length */ -+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02, /* GSS KRB5 mech */ -+ 0x02, 0x01, /* TOK_ID */ -+ 0x04, 0x00, /* SGN_ALG (HMAC SHA1 DES3-KD) */ -+ 0x02, 0x00, /* SEAL_ALG (DES3-KD) */ -+ 0xff, 0xff, /* Filler */ -+ 0xa0, 0xa1, 0xa2, 0xa3, /* encrypted sequence number */ -+ 0x00, 0x00, 0x00, 0x00, /* sequence number direction (remote) */ -+ /* checksum */ -+ 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, -+ 0xa9, 0xaa, 0xab, 0xac, 0xad, -+ 0xae, 0xaf, 0xb0, 0xb1, 0xb2, -+ 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, -+ /* unused */ -+ 0xb8, 0xb9, 0xba, 0xbb, -+ 0xbc, 0xbd, 0xbe, -+ 0x00, /* padding byte */ -+ }; -+ -+ input = get_input_buffer(ctx, data, sizeof(data), 57); -+ -+ expect_value(__wrap_krb5_decrypt, len, 8); -+ expect_value(__wrap_krb5_decrypt, data, (uint8_t *)input.value + 49); -+ -+ expect_value(__wrap_krb5_decrypt_ivec, data, (uint8_t *)input.value + 21); -+ expect_memory(__wrap_krb5_decrypt_ivec, ivec, -+ (uint8_t *)input.value + 29, DES_CBLOCK_LEN); -+ -+ expect_value(__wrap_krb5_verify_checksum, len, 16); -+ expect_value(__wrap_krb5_verify_checksum, data, (uint8_t *)input.value + 41); -+ expect_memory(__wrap_krb5_verify_checksum, cksum->checksum.data, -+ (uint8_t *)input.value + 29, 20); -+ -+ major_status = _gsskrb5_unwrap(&minor_status, -+ ctx->context_handle, -+ &input, -+ &output, -+ &conf_state, -+ &qop_state); -+ assert_int_equal(GSS_S_COMPLETE, major_status); -+ -+ assert_int_equal(1, conf_state); -+ assert_int_equal(GSS_C_QOP_DEFAULT, qop_state); -+ -+ assert_int_equal(output.length, 0); -+ -+ major_status = gss_release_buffer(&minor_status, &output); -+ assert_int_equal(GSS_S_COMPLETE, major_status); -+} -+ -+static void test_unwrap_with_seal_missing_payload(void **state) { -+ struct context *ctx = *state; -+ OM_uint32 major_status; -+ OM_uint32 minor_status; -+ gss_buffer_desc input = {0}; -+ gss_buffer_desc output = {0}; -+ int conf_state; -+ gss_qop_t qop_state; -+ -+ /* See RFC 1964 for token format. */ -+ static const uint8_t data[] = { -+ 0x60, /* ASN.1 Application tag */ -+ 0x14, /* total length */ -+ 0x06, /* OBJECT IDENTIFIER */ -+ 0x09, /* mech length */ -+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02, /* GSS KRB5 mech */ -+ 0x02, 0x01, /* TOK_ID */ -+ 0x04, 0x00, /* SGN_ALG (HMAC SHA1 DES3-KD) */ -+ 0x02, 0x00, /* SEAL_ALG (DES3-KD) */ -+ 0xff, 0xff, /* Filler */ -+ 0xa0, 0xa1, 0xa2, 0xa3, /* encrypted sequence number */ -+ 0x00, 0x00, 0x00, 0x00, /* sequence number direction (remote) */ -+ /* checksum */ -+ 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, -+ 0xa9, 0xaa, 0xab, 0xac, 0xad, -+ 0xae, 0xaf, 0xb0, 0xb1, 0xb2, -+ 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, -+ }; -+ -+ input = get_input_buffer(ctx, data, sizeof(data), 22); -+ -+ major_status = _gsskrb5_unwrap(&minor_status, -+ ctx->context_handle, -+ &input, -+ &output, -+ &conf_state, -+ &qop_state); -+ assert_int_equal(GSS_S_BAD_MECH, major_status); -+} -+ -+static void test_unwrap_with_seal_valid(void **state) { -+ struct context *ctx = *state; -+ OM_uint32 major_status; -+ OM_uint32 minor_status; -+ gss_buffer_desc input = {0}; -+ gss_buffer_desc output = {0}; -+ int conf_state; -+ gss_qop_t qop_state; -+ -+ /* See RFC 1964 for token format. */ -+ static const uint8_t data[] = { -+ 0x60, /* ASN.1 Application tag */ -+ 0x3e, /* total length */ -+ 0x06, /* OBJECT IDENTIFIER */ -+ 0x09, /* mech length */ -+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02, /* GSS KRB5 mech */ -+ 0x02, 0x01, /* TOK_ID */ -+ 0x04, 0x00, /* SGN_ALG (HMAC SHA1 DES3-KD) */ -+ 0x02, 0x00, /* SEAL_ALG (DES3-KD) */ -+ 0xff, 0xff, /* Filler */ -+ 0xa0, 0xa1, 0xa2, 0xa3, /* encrypted sequence number */ -+ 0x00, 0x00, 0x00, 0x00, /* sequence number direction (remote) */ -+ /* checksum */ -+ 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, -+ 0xa9, 0xaa, 0xab, 0xac, 0xad, -+ 0xae, 0xaf, 0xb0, 0xb1, 0xb2, -+ 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, -+ /* unused */ -+ 0xb8, 0xb9, 0xba, 0xbb, -+ 0xbc, 0xbd, 0xbe, 0xbf, -+ 0xc0, 0xc1, 0xc2, 0xc3, -+ 0xc4, 0xc5, -+ 0x00, /* padding byte */ -+ }; -+ -+ input = get_input_buffer(ctx, data, sizeof(data), 64); -+ -+ expect_value(__wrap_krb5_decrypt, len, 15); -+ expect_value(__wrap_krb5_decrypt, data, (uint8_t *)input.value + 49); -+ -+ expect_value(__wrap_krb5_decrypt_ivec, data, (uint8_t *)input.value + 21); -+ expect_memory(__wrap_krb5_decrypt_ivec, ivec, -+ (uint8_t *)input.value + 29, DES_CBLOCK_LEN); -+ -+ expect_value(__wrap_krb5_verify_checksum, len, 23); -+ expect_value(__wrap_krb5_verify_checksum, data, (uint8_t *)input.value + 41); -+ expect_memory(__wrap_krb5_verify_checksum, cksum->checksum.data, -+ (uint8_t *)input.value + 29, 20); -+ -+ major_status = _gsskrb5_unwrap(&minor_status, -+ ctx->context_handle, -+ &input, -+ &output, -+ &conf_state, -+ &qop_state); -+ assert_int_equal(GSS_S_COMPLETE, major_status); -+ -+ assert_int_equal(1, conf_state); -+ assert_int_equal(GSS_C_QOP_DEFAULT, qop_state); -+ -+ assert_int_equal(output.length, 7); -+ assert_memory_equal((uint8_t *)input.value + 57, output.value, output.length); -+ -+ major_status = gss_release_buffer(&minor_status, &output); -+ assert_int_equal(GSS_S_COMPLETE, major_status); -+} -+ -+int main(int argc, const char **argv) -+{ -+ static const struct CMUnitTest tests[] = { -+ cmocka_unit_test_setup_teardown( -+ test_unwrap_dce_style_missing_payload, setup, teardown), -+ cmocka_unit_test_setup_teardown( -+ test_unwrap_dce_style_valid, setup, teardown), -+ cmocka_unit_test_setup_teardown( -+ test_unwrap_dce_style_with_seal_missing_payload, setup, teardown), -+ cmocka_unit_test_setup_teardown( -+ test_unwrap_dce_style_with_seal_valid, setup, teardown), -+ cmocka_unit_test_setup_teardown( -+ test_unwrap_missing_8_bytes, setup, teardown), -+ cmocka_unit_test_setup_teardown( -+ test_unwrap_missing_payload, setup, teardown), -+ cmocka_unit_test_setup_teardown( -+ test_unwrap_truncated_header_0, setup, teardown), -+ cmocka_unit_test_setup_teardown( -+ test_unwrap_truncated_header_1, setup, teardown), -+ cmocka_unit_test_setup_teardown( -+ test_unwrap_valid, setup, teardown), -+ cmocka_unit_test_setup_teardown( -+ test_unwrap_with_padding_truncated_0, setup, teardown), -+ cmocka_unit_test_setup_teardown( -+ test_unwrap_with_padding_truncated_1, setup, teardown), -+ cmocka_unit_test_setup_teardown( -+ test_unwrap_with_padding_valid, setup, teardown), -+ cmocka_unit_test_setup_teardown( -+ test_unwrap_with_seal_empty_token_valid, setup, teardown), -+ cmocka_unit_test_setup_teardown( -+ test_unwrap_with_seal_missing_payload, setup, teardown), -+ cmocka_unit_test_setup_teardown( -+ test_unwrap_with_seal_valid, setup, teardown), -+ }; -+ -+ cmocka_set_message_output(CM_OUTPUT_SUBUNIT); -+ return cmocka_run_group_tests(tests, NULL, NULL); -+} -diff --git a/source4/auth/wscript_build b/source4/auth/wscript_build -index 381a7b19bf0..01b2f280609 100644 ---- a/source4/auth/wscript_build -+++ b/source4/auth/wscript_build -@@ -49,6 +49,27 @@ bld.SAMBA_BINARY('test_kerberos', - for_selftest=True - ) - -+bld.SAMBA_BINARY('test_heimdal_gensec_unwrap_des', -+ source='tests/heimdal_unwrap_des.c', -+ deps='cmocka talloc gssapi-subsystem', -+ local_include=False, -+ for_selftest=True, -+ enabled=(bld.CONFIG_SET('SAMBA4_USES_HEIMDAL') and -+ not bld.CONFIG_SET('USING_SYSTEM_GSSAPI')), -+ ldflags=''' -+ -Wl,--wrap,ct_memcmp -+ -Wl,--wrap,der_get_length -+ -Wl,--wrap,krb5_auth_con_getlocalsubkey -+ -Wl,--wrap,krb5_crypto_destroy -+ -Wl,--wrap,krb5_crypto_init -+ -Wl,--wrap,krb5_decrypt -+ -Wl,--wrap,krb5_decrypt_ivec -+ -Wl,--wrap,krb5_free_keyblock -+ -Wl,--wrap,krb5_verify_checksum -+ -Wl,--wrap,malloc -+ ''' -+) -+ - pytalloc_util = bld.pyembed_libname('pytalloc-util') - pyparam_util = bld.pyembed_libname('pyparam_util') - pyldb_util = bld.pyembed_libname('pyldb-util') --- -2.25.1 diff --git a/backport-0004-CVE-2021-44142.patch b/backport-0004-CVE-2021-44142.patch deleted file mode 100644 index 9c5c36b32159656037285a7293eee2d39443040f..0000000000000000000000000000000000000000 --- a/backport-0004-CVE-2021-44142.patch +++ /dev/null @@ -1,451 +0,0 @@ -From 4533a7b4319cd95815d2dcd5fe5075539fb850e5 Mon Sep 17 00:00:00 2001 -From: Ralph Boehme -Date: Thu, 25 Nov 2021 15:04:03 +0100 -Subject: [PATCH 06/99] CVE-2021-44142: libadouble: add basic cmocka tests - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14914 - -Signed-off-by: Ralph Boehme -Reviewed-by: Jeremy Allison -[slow@samba.org: conflict due to missing test in selftest/tests.py] ---- - selftest/knownfail.d/samba.unittests.adouble | 3 + - selftest/tests.py | 2 + - source3/lib/test_adouble.c | 389 +++++++++++++++++++ - source3/wscript_build | 5 + - 4 files changed, 399 insertions(+) - create mode 100644 selftest/knownfail.d/samba.unittests.adouble - create mode 100644 source3/lib/test_adouble.c - -diff --git a/selftest/knownfail.d/samba.unittests.adouble b/selftest/knownfail.d/samba.unittests.adouble -new file mode 100644 -index 00000000000..8b0314f2fae ---- /dev/null -+++ b/selftest/knownfail.d/samba.unittests.adouble -@@ -0,0 +1,3 @@ -+^samba.unittests.adouble.parse_abouble_finderinfo2\(none\) -+^samba.unittests.adouble.parse_abouble_finderinfo3\(none\) -+^samba.unittests.adouble.parse_abouble_date2\(none\) -diff --git a/selftest/tests.py b/selftest/tests.py -index e7338985caf..c87b41c1a66 100644 ---- a/selftest/tests.py -+++ b/selftest/tests.py -@@ -434,3 +434,5 @@ if with_elasticsearch_backend: - [os.path.join(bindir(), "default/source3/test_mdsparser_es")] + [configuration]) - plantestsuite("samba.unittests.credentials", "none", - [os.path.join(bindir(), "default/auth/credentials/test_creds")]) -+plantestsuite("samba.unittests.adouble", "none", -+ [os.path.join(bindir(), "test_adouble")]) -diff --git a/source3/lib/test_adouble.c b/source3/lib/test_adouble.c -new file mode 100644 -index 00000000000..615c22469c9 ---- /dev/null -+++ b/source3/lib/test_adouble.c -@@ -0,0 +1,389 @@ -+/* -+ * Unix SMB/CIFS implementation. -+ * -+ * Copyright (C) 2021 Ralph Boehme -+ * -+ * 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 . -+ */ -+ -+#include "adouble.c" -+#include -+ -+static int setup_talloc_context(void **state) -+{ -+ TALLOC_CTX *frame = talloc_stackframe(); -+ -+ *state = frame; -+ return 0; -+} -+ -+static int teardown_talloc_context(void **state) -+{ -+ TALLOC_CTX *frame = *state; -+ -+ TALLOC_FREE(frame); -+ return 0; -+} -+ -+/* -+ * Basic and sane buffer. -+ */ -+static uint8_t ad_basic[] = { -+ 0x00, 0x05, 0x16, 0x07, /* Magic */ -+ 0x00, 0x02, 0x00, 0x00, /* Version */ -+ 0x00, 0x00, 0x00, 0x00, /* Filler */ -+ 0x00, 0x00, 0x00, 0x00, /* Filler */ -+ 0x00, 0x00, 0x00, 0x00, /* Filler */ -+ 0x00, 0x00, 0x00, 0x00, /* Filler */ -+ 0x00, 0x02, /* Count */ -+ /* adentry 1: FinderInfo */ -+ 0x00, 0x00, 0x00, 0x09, /* eid: FinderInfo */ -+ 0x00, 0x00, 0x00, 0x32, /* offset */ -+ 0x00, 0x00, 0x00, 0x20, /* length */ -+ /* adentry 2: Resourcefork */ -+ 0x00, 0x00, 0x00, 0x02, /* eid: Resourcefork */ -+ 0x00, 0x00, 0x00, 0x52, /* offset */ -+ 0xff, 0xff, 0xff, 0x00, /* length */ -+ /* FinderInfo data: 32 bytes */ -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+}; -+ -+/* -+ * An empty FinderInfo entry. -+ */ -+static uint8_t ad_finderinfo1[] = { -+ 0x00, 0x05, 0x16, 0x07, /* Magic */ -+ 0x00, 0x02, 0x00, 0x00, /* Version */ -+ 0x00, 0x00, 0x00, 0x00, /* Filler */ -+ 0x00, 0x00, 0x00, 0x00, /* Filler */ -+ 0x00, 0x00, 0x00, 0x00, /* Filler */ -+ 0x00, 0x00, 0x00, 0x00, /* Filler */ -+ 0x00, 0x02, /* Count */ -+ /* adentry 1: FinderInfo */ -+ 0x00, 0x00, 0x00, 0x09, /* eid: FinderInfo */ -+ 0x00, 0x00, 0x00, 0x52, /* off: points at end of buffer */ -+ 0x00, 0x00, 0x00, 0x00, /* len: 0, so off+len don't exceed bufferlen */ -+ /* adentry 2: Resourcefork */ -+ 0x00, 0x00, 0x00, 0x02, /* eid: Resourcefork */ -+ 0x00, 0x00, 0x00, 0x52, /* offset */ -+ 0xff, 0xff, 0xff, 0x00, /* length */ -+ /* FinderInfo data: 32 bytes */ -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+}; -+ -+/* -+ * A dangerous FinderInfo with correct length exceeding buffer by one byte. -+ */ -+static uint8_t ad_finderinfo2[] = { -+ 0x00, 0x05, 0x16, 0x07, /* Magic */ -+ 0x00, 0x02, 0x00, 0x00, /* Version */ -+ 0x00, 0x00, 0x00, 0x00, /* Filler */ -+ 0x00, 0x00, 0x00, 0x00, /* Filler */ -+ 0x00, 0x00, 0x00, 0x00, /* Filler */ -+ 0x00, 0x00, 0x00, 0x00, /* Filler */ -+ 0x00, 0x02, /* Count */ -+ /* adentry 1: FinderInfo */ -+ 0x00, 0x00, 0x00, 0x09, /* eid: FinderInfo */ -+ 0x00, 0x00, 0x00, 0x33, /* off: points at beginng of data + 1 */ -+ 0x00, 0x00, 0x00, 0x20, /* len: 32, so off+len exceeds bufferlen by 1 */ -+ /* adentry 2: Resourcefork */ -+ 0x00, 0x00, 0x00, 0x02, /* eid: Resourcefork */ -+ 0x00, 0x00, 0x00, 0x52, /* offset */ -+ 0xff, 0xff, 0xff, 0x00, /* length */ -+ /* FinderInfo data: 32 bytes */ -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+}; -+ -+static uint8_t ad_finderinfo3[] = { -+ 0x00, 0x05, 0x16, 0x07, /* Magic */ -+ 0x00, 0x02, 0x00, 0x00, /* Version */ -+ 0x00, 0x00, 0x00, 0x00, /* Filler */ -+ 0x00, 0x00, 0x00, 0x00, /* Filler */ -+ 0x00, 0x00, 0x00, 0x00, /* Filler */ -+ 0x00, 0x00, 0x00, 0x00, /* Filler */ -+ 0x00, 0x02, /* Count */ -+ /* adentry 1: FinderInfo */ -+ 0x00, 0x00, 0x00, 0x09, /* eid: FinderInfo */ -+ 0x00, 0x00, 0x00, 0x33, /* off: points at beginng of data + 1 */ -+ 0x00, 0x00, 0x00, 0x1f, /* len: 31, so off+len don't exceed buf */ -+ /* adentry 2: Resourcefork */ -+ 0x00, 0x00, 0x00, 0x02, /* eid: Resourcefork */ -+ 0x00, 0x00, 0x00, 0x52, /* offset */ -+ 0xff, 0xff, 0xff, 0x00, /* length */ -+ /* FinderInfo data: 32 bytes */ -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+}; -+ -+/* -+ * A dangerous name entry. -+ */ -+static uint8_t ad_name[] = { -+ 0x00, 0x05, 0x16, 0x07, /* Magic */ -+ 0x00, 0x02, 0x00, 0x00, /* Version */ -+ 0x00, 0x00, 0x00, 0x00, /* Filler */ -+ 0x00, 0x00, 0x00, 0x00, /* Filler */ -+ 0x00, 0x00, 0x00, 0x00, /* Filler */ -+ 0x00, 0x00, 0x00, 0x00, /* Filler */ -+ 0x00, 0x02, /* Count */ -+ /* adentry 1: FinderInfo */ -+ 0x00, 0x00, 0x00, 0x09, /* eid: FinderInfo */ -+ 0x00, 0x00, 0x00, 0x32, /* offset */ -+ 0x00, 0x00, 0x00, 0x20, /* length */ -+ /* adentry 2: Name */ -+ 0x00, 0x00, 0x00, 0x03, /* eid: Name */ -+ 0x00, 0x00, 0x00, 0x52, /* off: points at end of buffer */ -+ 0x00, 0x00, 0x00, 0x01, /* len: 1, so off+len exceeds bufferlen */ -+ /* FinderInfo data: 32 bytes */ -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+}; -+ -+/* -+ * A empty ADEID_FILEDATESI entry. -+ */ -+static uint8_t ad_date1[] = { -+ 0x00, 0x05, 0x16, 0x07, /* Magic */ -+ 0x00, 0x02, 0x00, 0x00, /* Version */ -+ 0x00, 0x00, 0x00, 0x00, /* Filler */ -+ 0x00, 0x00, 0x00, 0x00, /* Filler */ -+ 0x00, 0x00, 0x00, 0x00, /* Filler */ -+ 0x00, 0x00, 0x00, 0x00, /* Filler */ -+ 0x00, 0x02, /* Count */ -+ /* adentry 1: FinderInfo */ -+ 0x00, 0x00, 0x00, 0x09, /* eid: FinderInfo */ -+ 0x00, 0x00, 0x00, 0x32, /* offset */ -+ 0x00, 0x00, 0x00, 0x20, /* length */ -+ /* adentry 2: Dates */ -+ 0x00, 0x00, 0x00, 0x08, /* eid: dates */ -+ 0x00, 0x00, 0x00, 0x52, /* off: end of buffer */ -+ 0x00, 0x00, 0x00, 0x00, /* len: 0, empty entry, valid */ -+ /* FinderInfo data: 32 bytes */ -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+}; -+ -+/* -+ * A dangerous ADEID_FILEDATESI entry, invalid length. -+ */ -+static uint8_t ad_date2[] = { -+ 0x00, 0x05, 0x16, 0x07, /* Magic */ -+ 0x00, 0x02, 0x00, 0x00, /* Version */ -+ 0x00, 0x00, 0x00, 0x00, /* Filler */ -+ 0x00, 0x00, 0x00, 0x00, /* Filler */ -+ 0x00, 0x00, 0x00, 0x00, /* Filler */ -+ 0x00, 0x00, 0x00, 0x00, /* Filler */ -+ 0x00, 0x02, /* Count */ -+ /* adentry 1: FinderInfo */ -+ 0x00, 0x00, 0x00, 0x09, /* eid: FinderInfo */ -+ 0x00, 0x00, 0x00, 0x32, /* offset */ -+ 0x00, 0x00, 0x00, 0x20, /* length */ -+ /* adentry 2: Dates */ -+ 0x00, 0x00, 0x00, 0x08, /* eid: dates */ -+ 0x00, 0x00, 0x00, 0x43, /* off: FinderInfo buf but one byte short */ -+ 0x00, 0x00, 0x00, 0x0f, /* len: 15, so off+len don't exceed bufferlen */ -+ /* FinderInfo data: 32 bytes */ -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+}; -+ -+static struct adouble *parse_adouble(TALLOC_CTX *mem_ctx, -+ uint8_t *adbuf, -+ size_t adsize, -+ off_t filesize) -+{ -+ struct adouble *ad = NULL; -+ bool ok; -+ -+ ad = talloc_zero(mem_ctx, struct adouble); -+ ad->ad_data = talloc_zero_size(ad, adsize); -+ assert_non_null(ad); -+ -+ memcpy(ad->ad_data, adbuf, adsize); -+ -+ ok = ad_unpack(ad, 2, filesize); -+ if (!ok) { -+ return NULL; -+ } -+ -+ return ad; -+} -+ -+static void parse_abouble_basic(void **state) -+{ -+ TALLOC_CTX *frame = *state; -+ struct adouble *ad = NULL; -+ char *p = NULL; -+ -+ ad = parse_adouble(frame, ad_basic, sizeof(ad_basic), 0xffffff52); -+ assert_non_null(ad); -+ -+ p = ad_get_entry(ad, ADEID_FINDERI); -+ assert_non_null(p); -+ -+ return; -+} -+ -+static void parse_abouble_finderinfo1(void **state) -+{ -+ TALLOC_CTX *frame = *state; -+ struct adouble *ad = NULL; -+ char *p = NULL; -+ -+ ad = parse_adouble(frame, -+ ad_finderinfo1, -+ sizeof(ad_finderinfo1), -+ 0xffffff52); -+ assert_non_null(ad); -+ -+ p = ad_get_entry(ad, ADEID_FINDERI); -+ assert_null(p); -+ -+ return; -+} -+ -+static void parse_abouble_finderinfo2(void **state) -+{ -+ TALLOC_CTX *frame = *state; -+ struct adouble *ad = NULL; -+ -+ ad = parse_adouble(frame, -+ ad_finderinfo2, -+ sizeof(ad_finderinfo2), -+ 0xffffff52); -+ assert_null(ad); -+ -+ return; -+} -+ -+static void parse_abouble_finderinfo3(void **state) -+{ -+ TALLOC_CTX *frame = *state; -+ struct adouble *ad = NULL; -+ -+ ad = parse_adouble(frame, -+ ad_finderinfo3, -+ sizeof(ad_finderinfo3), -+ 0xffffff52); -+ assert_null(ad); -+ -+ return; -+} -+ -+static void parse_abouble_name(void **state) -+{ -+ TALLOC_CTX *frame = *state; -+ struct adouble *ad = NULL; -+ -+ ad = parse_adouble(frame, ad_name, sizeof(ad_name), 0x52); -+ assert_null(ad); -+ -+ return; -+} -+ -+static void parse_abouble_date1(void **state) -+{ -+ TALLOC_CTX *frame = *state; -+ struct adouble *ad = NULL; -+ char *p = NULL; -+ -+ ad = parse_adouble(frame, ad_date1, sizeof(ad_date1), 0x52); -+ assert_non_null(ad); -+ -+ p = ad_get_entry(ad, ADEID_FILEDATESI); -+ assert_null(p); -+ -+ return; -+} -+ -+static void parse_abouble_date2(void **state) -+{ -+ TALLOC_CTX *frame = *state; -+ struct adouble *ad = NULL; -+ -+ ad = parse_adouble(frame, ad_date2, sizeof(ad_date2), 0x52); -+ assert_null(ad); -+ -+ return; -+} -+ -+int main(int argc, char *argv[]) -+{ -+ int rc; -+ const struct CMUnitTest tests[] = { -+ cmocka_unit_test(parse_abouble_basic), -+ cmocka_unit_test(parse_abouble_finderinfo1), -+ cmocka_unit_test(parse_abouble_finderinfo2), -+ cmocka_unit_test(parse_abouble_finderinfo3), -+ cmocka_unit_test(parse_abouble_name), -+ cmocka_unit_test(parse_abouble_date1), -+ cmocka_unit_test(parse_abouble_date2), -+ }; -+ -+ if (argc == 2) { -+ cmocka_set_test_filter(argv[1]); -+ } -+ cmocka_set_message_output(CM_OUTPUT_SUBUNIT); -+ -+ rc = cmocka_run_group_tests(tests, -+ setup_talloc_context, -+ teardown_talloc_context); -+ -+ return rc; -+} -diff --git a/source3/wscript_build b/source3/wscript_build -index 69febb53750..9df9bdd35b7 100644 ---- a/source3/wscript_build -+++ b/source3/wscript_build -@@ -1085,6 +1085,11 @@ bld.SAMBA3_SUBSYSTEM('ADOUBLE', - source='lib/adouble.c', - deps='STRING_REPLACE') - -+bld.SAMBA3_BINARY('test_adouble', -+ source='lib/test_adouble.c', -+ deps='smbd_base STRING_REPLACE cmocka', -+ for_selftest=True) -+ - bld.SAMBA3_SUBSYSTEM('STRING_REPLACE', - source='lib/string_replace.c') - --- -2.25.1 diff --git a/backport-0004-CVE-2022-3437.patch b/backport-0004-CVE-2022-3437.patch deleted file mode 100644 index f91795b0f26023acb8e4f7688181bd8848b20dcf..0000000000000000000000000000000000000000 --- a/backport-0004-CVE-2022-3437.patch +++ /dev/null @@ -1,81 +0,0 @@ -From c22914f845b3eba1c9ad444333f3d044352b7e2c Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Wed, 12 Oct 2022 13:57:13 +1300 -Subject: [PATCH 08/15] CVE-2022-3437 source4/heimdal: Use constant-time - memcmp() for arcfour unwrap - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15134 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett - -[jsutton@samba.org Adapted to small differences in comparisons, and - removed erroneous duplicate code in conflicting region] - -Conflict: NA -Reference: https://download.samba.org/pub/samba/patches/security/samba-4.15.11-security-2022-10-25.patch ---- - source4/heimdal/lib/gssapi/krb5/arcfour.c | 24 +++++++---------------- - 1 file changed, 7 insertions(+), 17 deletions(-) - -diff --git a/source4/heimdal/lib/gssapi/krb5/arcfour.c b/source4/heimdal/lib/gssapi/krb5/arcfour.c -index a61f7686e95..c6b317ff683 100644 ---- a/source4/heimdal/lib/gssapi/krb5/arcfour.c -+++ b/source4/heimdal/lib/gssapi/krb5/arcfour.c -@@ -385,9 +385,9 @@ _gssapi_verify_mic_arcfour(OM_uint32 * minor_status, - _gsskrb5_decode_be_om_uint32(SND_SEQ, &seq_number); - - if (context_handle->more_flags & LOCAL) -- cmp = memcmp(&SND_SEQ[4], "\xff\xff\xff\xff", 4); -+ cmp = ct_memcmp(&SND_SEQ[4], "\xff\xff\xff\xff", 4); - else -- cmp = memcmp(&SND_SEQ[4], "\x00\x00\x00\x00", 4); -+ cmp = ct_memcmp(&SND_SEQ[4], "\x00\x00\x00\x00", 4); - - memset(SND_SEQ, 0, sizeof(SND_SEQ)); - if (cmp != 0) { -@@ -656,9 +656,9 @@ OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status, - _gsskrb5_decode_be_om_uint32(SND_SEQ, &seq_number); - - if (context_handle->more_flags & LOCAL) -- cmp = memcmp(&SND_SEQ[4], "\xff\xff\xff\xff", 4); -+ cmp = ct_memcmp(&SND_SEQ[4], "\xff\xff\xff\xff", 4); - else -- cmp = memcmp(&SND_SEQ[4], "\x00\x00\x00\x00", 4); -+ cmp = ct_memcmp(&SND_SEQ[4], "\x00\x00\x00\x00", 4); - - if (cmp != 0) { - *minor_status = 0; -@@ -1266,19 +1266,9 @@ _gssapi_unwrap_iov_arcfour(OM_uint32 *minor_status, - _gsskrb5_decode_be_om_uint32(snd_seq, &seq_number); - - if (ctx->more_flags & LOCAL) { -- cmp = memcmp(&snd_seq[4], "\xff\xff\xff\xff", 4); -+ cmp = ct_memcmp(&snd_seq[4], "\xff\xff\xff\xff", 4); - } else { -- cmp = memcmp(&snd_seq[4], "\x00\x00\x00\x00", 4); -- } -- if (cmp != 0) { -- *minor_status = 0; -- return GSS_S_BAD_MIC; -- } -- -- if (ctx->more_flags & LOCAL) { -- cmp = memcmp(&snd_seq[4], "\xff\xff\xff\xff", 4); -- } else { -- cmp = memcmp(&snd_seq[4], "\x00\x00\x00\x00", 4); -+ cmp = ct_memcmp(&snd_seq[4], "\x00\x00\x00\x00", 4); - } - if (cmp != 0) { - *minor_status = 0; -@@ -1353,7 +1343,7 @@ _gssapi_unwrap_iov_arcfour(OM_uint32 *minor_status, - return GSS_S_FAILURE; - } - -- cmp = memcmp(cksum_data, p0 + 16, 8); /* SGN_CKSUM */ -+ cmp = ct_memcmp(cksum_data, p0 + 16, 8); /* SGN_CKSUM */ - if (cmp != 0) { - *minor_status = 0; - return GSS_S_BAD_MIC; --- -2.25.1 diff --git a/backport-0005-CVE-2021-44142.patch b/backport-0005-CVE-2021-44142.patch deleted file mode 100644 index bb490fcd5b844a75bc436654870c3ad3489035fe..0000000000000000000000000000000000000000 --- a/backport-0005-CVE-2021-44142.patch +++ /dev/null @@ -1,169 +0,0 @@ - -From 0e2b3fb982d1f53d111e10d9197ed2ec2e13712c Mon Sep 17 00:00:00 2001 -From: Ralph Boehme -Date: Thu, 13 Jan 2022 17:03:02 +0100 -Subject: [PATCH 07/99] CVE-2021-44142: libadouble: harden parsing code - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14914 - -Signed-off-by: Ralph Boehme -Reviewed-by: Jeremy Allison ---- - selftest/knownfail.d/samba.unittests.adouble | 3 - - source3/lib/adouble.c | 115 ++++++++++++++++--- - 2 files changed, 101 insertions(+), 17 deletions(-) - delete mode 100644 selftest/knownfail.d/samba.unittests.adouble - -diff --git a/selftest/knownfail.d/samba.unittests.adouble b/selftest/knownfail.d/samba.unittests.adouble -deleted file mode 100644 -index 8b0314f2fae..00000000000 ---- a/selftest/knownfail.d/samba.unittests.adouble -+++ /dev/null -@@ -1,3 +0,0 @@ --^samba.unittests.adouble.parse_abouble_finderinfo2\(none\) --^samba.unittests.adouble.parse_abouble_finderinfo3\(none\) --^samba.unittests.adouble.parse_abouble_date2\(none\) -diff --git a/source3/lib/adouble.c b/source3/lib/adouble.c -index 6cbe8a5aeda..37fb686f17b 100644 ---- a/source3/lib/adouble.c -+++ b/source3/lib/adouble.c -@@ -269,6 +269,95 @@ size_t ad_setentryoff(struct adouble *ad, int eid, size_t off) - return ad->ad_eid[eid].ade_off = off; - } - -+/* -+ * All entries besides FinderInfo and resource fork must fit into the -+ * buffer. FinderInfo is special as it may be larger then the default 32 bytes -+ * if it contains marshalled xattrs, which we will fixup that in -+ * ad_convert(). The first 32 bytes however must also be part of the buffer. -+ * -+ * The resource fork is never accessed directly by the ad_data buf. -+ */ -+static bool ad_entry_check_size(uint32_t eid, -+ size_t bufsize, -+ uint32_t off, -+ uint32_t got_len) -+{ -+ struct { -+ off_t expected_len; -+ bool fixed_size; -+ bool minimum_size; -+ } ad_checks[] = { -+ [ADEID_DFORK] = {-1, false, false}, /* not applicable */ -+ [ADEID_RFORK] = {-1, false, false}, /* no limit */ -+ [ADEID_NAME] = {ADEDLEN_NAME, false, false}, -+ [ADEID_COMMENT] = {ADEDLEN_COMMENT, false, false}, -+ [ADEID_ICONBW] = {ADEDLEN_ICONBW, true, false}, -+ [ADEID_ICONCOL] = {ADEDLEN_ICONCOL, false, false}, -+ [ADEID_FILEI] = {ADEDLEN_FILEI, true, false}, -+ [ADEID_FILEDATESI] = {ADEDLEN_FILEDATESI, true, false}, -+ [ADEID_FINDERI] = {ADEDLEN_FINDERI, false, true}, -+ [ADEID_MACFILEI] = {ADEDLEN_MACFILEI, true, false}, -+ [ADEID_PRODOSFILEI] = {ADEDLEN_PRODOSFILEI, true, false}, -+ [ADEID_MSDOSFILEI] = {ADEDLEN_MSDOSFILEI, true, false}, -+ [ADEID_SHORTNAME] = {ADEDLEN_SHORTNAME, false, false}, -+ [ADEID_AFPFILEI] = {ADEDLEN_AFPFILEI, true, false}, -+ [ADEID_DID] = {ADEDLEN_DID, true, false}, -+ [ADEID_PRIVDEV] = {ADEDLEN_PRIVDEV, true, false}, -+ [ADEID_PRIVINO] = {ADEDLEN_PRIVINO, true, false}, -+ [ADEID_PRIVSYN] = {ADEDLEN_PRIVSYN, true, false}, -+ [ADEID_PRIVID] = {ADEDLEN_PRIVID, true, false}, -+ }; -+ -+ if (eid >= ADEID_MAX) { -+ return false; -+ } -+ if (got_len == 0) { -+ /* Entry present, but empty, allow */ -+ return true; -+ } -+ if (ad_checks[eid].expected_len == 0) { -+ /* -+ * Shouldn't happen: implicitly initialized to zero because -+ * explicit initializer missing. -+ */ -+ return false; -+ } -+ if (ad_checks[eid].expected_len == -1) { -+ /* Unused or no limit */ -+ return true; -+ } -+ if (ad_checks[eid].fixed_size) { -+ if (ad_checks[eid].expected_len != got_len) { -+ /* Wrong size fo fixed size entry. */ -+ return false; -+ } -+ } else { -+ if (ad_checks[eid].minimum_size) { -+ if (got_len < ad_checks[eid].expected_len) { -+ /* -+ * Too small for variable sized entry with -+ * minimum size. -+ */ -+ return false; -+ } -+ } else { -+ if (got_len > ad_checks[eid].expected_len) { -+ /* Too big for variable sized entry. */ -+ return false; -+ } -+ } -+ } -+ if (off + got_len < off) { -+ /* wrap around */ -+ return false; -+ } -+ if (off + got_len > bufsize) { -+ /* overflow */ -+ return false; -+ } -+ return true; -+} -+ - /** - * Return a pointer to an AppleDouble entry - * -@@ -276,8 +365,15 @@ size_t ad_setentryoff(struct adouble *ad, int eid, size_t off) - **/ - char *ad_get_entry(const struct adouble *ad, int eid) - { -+ size_t bufsize = talloc_get_size(ad->ad_data); - off_t off = ad_getentryoff(ad, eid); - size_t len = ad_getentrylen(ad, eid); -+ bool valid; -+ -+ valid = ad_entry_check_size(eid, bufsize, off, len); -+ if (!valid) { -+ return NULL; -+ } - - if (off == 0 || len == 0) { - return NULL; -@@ -914,20 +1010,11 @@ static bool ad_unpack(struct adouble *ad, const size_t nentries, - return false; - } - -- /* -- * All entries besides FinderInfo and resource fork -- * must fit into the buffer. FinderInfo is special as -- * it may be larger then the default 32 bytes (if it -- * contains marshalled xattrs), but we will fixup that -- * in ad_convert(). And the resource fork is never -- * accessed directly by the ad_data buf (also see -- * comment above) anyway. -- */ -- if ((eid != ADEID_RFORK) && -- (eid != ADEID_FINDERI) && -- ((off + len) > bufsize)) { -- DEBUG(1, ("bogus eid %d: off: %" PRIu32 ", len: %" PRIu32 "\n", -- eid, off, len)); -+ ok = ad_entry_check_size(eid, bufsize, off, len); -+ if (!ok) { -+ DBG_ERR("bogus eid [%"PRIu32"] bufsize [%zu] " -+ "off [%"PRIu32"] len [%"PRIu32"]\n", -+ eid, bufsize, off, len); - return false; - } - --- -2.25.1 diff --git a/backport-0005-CVE-2022-3437.patch b/backport-0005-CVE-2022-3437.patch deleted file mode 100644 index c5f3ba6f550907f110f04b8f6af8d5e0705628b7..0000000000000000000000000000000000000000 --- a/backport-0005-CVE-2022-3437.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 5f6dbf2ab29bcd30c701cab3daecf5a6a53a44cd Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Wed, 12 Oct 2022 13:57:55 +1300 -Subject: [PATCH 09/15] CVE-2022-3437 source4/heimdal: Use constant-time - memcmp() in unwrap_des3() - -The surrounding checks all use ct_memcmp(), so this one was presumably -meant to as well. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15134 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett - -Conflict: NA -Reference: https://download.samba.org/pub/samba/patches/security/samba-4.15.11-security-2022-10-25.patch ---- - source4/heimdal/lib/gssapi/krb5/unwrap.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/source4/heimdal/lib/gssapi/krb5/unwrap.c b/source4/heimdal/lib/gssapi/krb5/unwrap.c -index b3da35ee9e2..7111a7944fe 100644 ---- a/source4/heimdal/lib/gssapi/krb5/unwrap.c -+++ b/source4/heimdal/lib/gssapi/krb5/unwrap.c -@@ -227,7 +227,7 @@ unwrap_des3 - if (ret) - return ret; - -- if (memcmp (p, "\x04\x00", 2) != 0) /* HMAC SHA1 DES3_KD */ -+ if (ct_memcmp (p, "\x04\x00", 2) != 0) /* HMAC SHA1 DES3_KD */ - return GSS_S_BAD_SIG; - p += 2; - if (ct_memcmp (p, "\x02\x00", 2) == 0) { --- -2.25.1 diff --git a/backport-0006-CVE-2022-3437.patch b/backport-0006-CVE-2022-3437.patch deleted file mode 100644 index 4af5b9c73de9e54397364a17d75eeca805f8f979..0000000000000000000000000000000000000000 --- a/backport-0006-CVE-2022-3437.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 9f6f1e01aca4f00a5d23127803c81939253e0577 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Wed, 12 Oct 2022 13:57:42 +1300 -Subject: [PATCH 10/15] CVE-2022-3437 source4/heimdal: Don't pass NULL pointers - to memcpy() in DES unwrap - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15134 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett - -Conflict: NA -Reference: https://download.samba.org/pub/samba/patches/security/samba-4.15.11-security-2022-10-25.patch ---- - source4/heimdal/lib/gssapi/krb5/unwrap.c | 14 ++++++++------ - 1 file changed, 8 insertions(+), 6 deletions(-) - -diff --git a/source4/heimdal/lib/gssapi/krb5/unwrap.c b/source4/heimdal/lib/gssapi/krb5/unwrap.c -index 7111a7944fe..9639091cb3a 100644 ---- a/source4/heimdal/lib/gssapi/krb5/unwrap.c -+++ b/source4/heimdal/lib/gssapi/krb5/unwrap.c -@@ -180,9 +180,10 @@ unwrap_des - output_message_buffer->value = malloc(output_message_buffer->length); - if(output_message_buffer->length != 0 && output_message_buffer->value == NULL) - return GSS_S_FAILURE; -- memcpy (output_message_buffer->value, -- p + 24, -- output_message_buffer->length); -+ if (output_message_buffer->value != NULL) -+ memcpy (output_message_buffer->value, -+ p + 24, -+ output_message_buffer->length); - return GSS_S_COMPLETE; - } - #endif -@@ -374,9 +375,10 @@ unwrap_des3 - output_message_buffer->value = malloc(output_message_buffer->length); - if(output_message_buffer->length != 0 && output_message_buffer->value == NULL) - return GSS_S_FAILURE; -- memcpy (output_message_buffer->value, -- p + 36, -- output_message_buffer->length); -+ if (output_message_buffer->value != NULL) -+ memcpy (output_message_buffer->value, -+ p + 36, -+ output_message_buffer->length); - return GSS_S_COMPLETE; - } - --- -2.25.1 diff --git a/backport-0007-CVE-2022-3437.patch b/backport-0007-CVE-2022-3437.patch deleted file mode 100644 index ae786f85a3fb174a761e2532bf5663d298c3cd78..0000000000000000000000000000000000000000 --- a/backport-0007-CVE-2022-3437.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 5a62eb5734d50fe556934aefa3bac5698372f00e Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Mon, 15 Aug 2022 16:53:45 +1200 -Subject: [PATCH 11/15] CVE-2022-3437 source4/heimdal: Avoid undefined - behaviour in _gssapi_verify_pad() - -By decrementing 'pad' only when we know it's safe, we ensure we can't -stray backwards past the start of a buffer, which would be undefined -behaviour. - -In the previous version of the loop, 'i' is the number of bytes left to -check, and 'pad' is the current byte we're checking. 'pad' was -decremented at the end of each loop iteration. If 'i' was 1 (so we -checked the final byte), 'pad' could potentially be pointing to the -first byte of the input buffer, and the decrement would put it one -byte behind the buffer. - -That would be undefined behaviour. - -The patch changes it so that 'pad' is the byte we previously checked, -which allows us to ensure that we only decrement it when we know we -have a byte to check. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15134 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett - -Conflict: NA -Reference: https://download.samba.org/pub/samba/patches/security/samba-4.15.11-security-2022-10-25.patch ---- - source4/heimdal/lib/gssapi/krb5/decapsulate.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/source4/heimdal/lib/gssapi/krb5/decapsulate.c b/source4/heimdal/lib/gssapi/krb5/decapsulate.c -index 86085f56950..4e3fcd659e9 100644 ---- a/source4/heimdal/lib/gssapi/krb5/decapsulate.c -+++ b/source4/heimdal/lib/gssapi/krb5/decapsulate.c -@@ -193,13 +193,13 @@ _gssapi_verify_pad(gss_buffer_t wrapped_token, - if (wrapped_token->length < 1) - return GSS_S_BAD_MECH; - -- pad = (u_char *)wrapped_token->value + wrapped_token->length - 1; -- padlength = *pad; -+ pad = (u_char *)wrapped_token->value + wrapped_token->length; -+ padlength = pad[-1]; - - if (padlength > datalen) - return GSS_S_BAD_MECH; - -- for (i = padlength; i > 0 && *pad == padlength; i--, pad--) -+ for (i = padlength; i > 0 && *--pad == padlength; i--) - ; - if (i != 0) - return GSS_S_BAD_MIC; --- -2.25.1 diff --git a/backport-0008-CVE-2022-3437.patch b/backport-0008-CVE-2022-3437.patch deleted file mode 100644 index 9e7161bc88d21b9f2345fee4a4f4686a0971896d..0000000000000000000000000000000000000000 --- a/backport-0008-CVE-2022-3437.patch +++ /dev/null @@ -1,50 +0,0 @@ -From ebac8bf0478e19849f83af6d44b73d7ab3afd25b Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Mon, 15 Aug 2022 16:53:55 +1200 -Subject: [PATCH 12/15] CVE-2022-3437 source4/heimdal: Check the result of - _gsskrb5_get_mech() - -We should make sure that the result of 'total_len - mech_len' won't -overflow, and that we don't memcmp() past the end of the buffer. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15134 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett - -Conflict: NA -Reference: https://download.samba.org/pub/samba/patches/security/samba-4.15.11-security-2022-10-25.patch ---- - selftest/knownfail.d/heimdal-des-overflow | 1 - - source4/heimdal/lib/gssapi/krb5/decapsulate.c | 4 ++++ - 2 files changed, 4 insertions(+), 1 deletion(-) - -diff --git a/selftest/knownfail.d/heimdal-des-overflow b/selftest/knownfail.d/heimdal-des-overflow -index 23acbb43d31..68b304530db 100644 ---- a/selftest/knownfail.d/heimdal-des-overflow -+++ b/selftest/knownfail.d/heimdal-des-overflow -@@ -3,7 +3,6 @@ - ^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_missing_8_bytes.none - ^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_missing_payload.none - ^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_truncated_header_0.none --^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_truncated_header_1.none - ^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_with_padding_truncated_0.none - ^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_with_padding_truncated_1.none - ^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_with_seal_missing_payload.none -diff --git a/source4/heimdal/lib/gssapi/krb5/decapsulate.c b/source4/heimdal/lib/gssapi/krb5/decapsulate.c -index 4e3fcd659e9..031a621eabc 100644 ---- a/source4/heimdal/lib/gssapi/krb5/decapsulate.c -+++ b/source4/heimdal/lib/gssapi/krb5/decapsulate.c -@@ -80,6 +80,10 @@ _gssapi_verify_mech_header(u_char **str, - - if (mech_len != mech->length) - return GSS_S_BAD_MECH; -+ if (mech_len > total_len) -+ return GSS_S_BAD_MECH; -+ if (p - *str > total_len - mech_len) -+ return GSS_S_BAD_MECH; - if (ct_memcmp(p, - mech->elements, - mech->length) != 0) --- -2.25.1 diff --git a/backport-0009-CVE-2022-3437.patch b/backport-0009-CVE-2022-3437.patch deleted file mode 100644 index afbd04478d1e2736a2ebdaf6443f477ad85d4a7f..0000000000000000000000000000000000000000 --- a/backport-0009-CVE-2022-3437.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 1aca34515515f2cb00fbf5ad8b9212b319f01836 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Mon, 15 Aug 2022 16:54:23 +1200 -Subject: [PATCH 13/15] CVE-2022-3437 source4/heimdal: Check buffer length - against overflow for DES{,3} unwrap - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15134 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett - -Conflict: NA -Reference: https://download.samba.org/pub/samba/patches/security/samba-4.15.11-security-2022-10-25.patch ---- - selftest/knownfail.d/heimdal-des-overflow | 5 ----- - source4/heimdal/lib/gssapi/krb5/unwrap.c | 14 ++++++++++++++ - 2 files changed, 14 insertions(+), 5 deletions(-) - -diff --git a/selftest/knownfail.d/heimdal-des-overflow b/selftest/knownfail.d/heimdal-des-overflow -index 68b304530db..94a49bbee7f 100644 ---- a/selftest/knownfail.d/heimdal-des-overflow -+++ b/selftest/knownfail.d/heimdal-des-overflow -@@ -1,8 +1,3 @@ --^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_dce_style_missing_payload.none --^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_dce_style_with_seal_missing_payload.none --^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_missing_8_bytes.none --^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_missing_payload.none - ^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_truncated_header_0.none - ^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_with_padding_truncated_0.none - ^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_with_padding_truncated_1.none --^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_with_seal_missing_payload.none -diff --git a/source4/heimdal/lib/gssapi/krb5/unwrap.c b/source4/heimdal/lib/gssapi/krb5/unwrap.c -index 9639091cb3a..70d26a75ccf 100644 ---- a/source4/heimdal/lib/gssapi/krb5/unwrap.c -+++ b/source4/heimdal/lib/gssapi/krb5/unwrap.c -@@ -64,6 +64,8 @@ unwrap_des - - if (IS_DCE_STYLE(context_handle)) { - token_len = 22 + 8 + 15; /* 45 */ -+ if (input_message_buffer->length < token_len) -+ return GSS_S_BAD_MECH; - } else { - token_len = input_message_buffer->length; - } -@@ -76,6 +78,11 @@ unwrap_des - if (ret) - return ret; - -+ len = (p - (u_char *)input_message_buffer->value) -+ + 22 + 8; -+ if (input_message_buffer->length < len) -+ return GSS_S_BAD_MECH; -+ - if (memcmp (p, "\x00\x00", 2) != 0) - return GSS_S_BAD_SIG; - p += 2; -@@ -216,6 +223,8 @@ unwrap_des3 - - if (IS_DCE_STYLE(context_handle)) { - token_len = 34 + 8 + 15; /* 57 */ -+ if (input_message_buffer->length < token_len) -+ return GSS_S_BAD_MECH; - } else { - token_len = input_message_buffer->length; - } -@@ -228,6 +237,11 @@ unwrap_des3 - if (ret) - return ret; - -+ len = (p - (u_char *)input_message_buffer->value) -+ + 34 + 8; -+ if (input_message_buffer->length < len) -+ return GSS_S_BAD_MECH; -+ - if (ct_memcmp (p, "\x04\x00", 2) != 0) /* HMAC SHA1 DES3_KD */ - return GSS_S_BAD_SIG; - p += 2; --- -2.25.1 diff --git a/backport-0010-CVE-2022-3437.patch b/backport-0010-CVE-2022-3437.patch deleted file mode 100644 index f13cb9ef9b6295ed22f8a8c8fefddc0d12527243..0000000000000000000000000000000000000000 --- a/backport-0010-CVE-2022-3437.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 77e0f2febaaf4d6e5e42f8e73a1f8f3c0e4a2985 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Mon, 10 Oct 2022 20:33:09 +1300 -Subject: [PATCH 14/15] CVE-2022-3437 source4/heimdal: Check for overflow in - _gsskrb5_get_mech() - -If len_len is equal to total_len - 1 (i.e. the input consists only of a -0x60 byte and a length), the expression 'total_len - 1 - len_len - 1', -used as the 'len' parameter to der_get_length(), will overflow to -SIZE_MAX. Then der_get_length() will proceed to read, unconstrained, -whatever data follows in memory. Add a check to ensure that doesn't -happen. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15134 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett - -Conflict: NA -Reference: https://download.samba.org/pub/samba/patches/security/samba-4.15.11-security-2022-10-25.patch ---- - selftest/knownfail.d/heimdal-des-overflow | 1 - - source4/heimdal/lib/gssapi/krb5/decapsulate.c | 2 ++ - 2 files changed, 2 insertions(+), 1 deletion(-) - -diff --git a/selftest/knownfail.d/heimdal-des-overflow b/selftest/knownfail.d/heimdal-des-overflow -index 94a49bbee7f..a7416dc61d9 100644 ---- a/selftest/knownfail.d/heimdal-des-overflow -+++ b/selftest/knownfail.d/heimdal-des-overflow -@@ -1,3 +1,2 @@ --^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_truncated_header_0.none - ^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_with_padding_truncated_0.none - ^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_with_padding_truncated_1.none -diff --git a/source4/heimdal/lib/gssapi/krb5/decapsulate.c b/source4/heimdal/lib/gssapi/krb5/decapsulate.c -index 031a621eabc..d7b75a64222 100644 ---- a/source4/heimdal/lib/gssapi/krb5/decapsulate.c -+++ b/source4/heimdal/lib/gssapi/krb5/decapsulate.c -@@ -54,6 +54,8 @@ _gsskrb5_get_mech (const u_char *ptr, - e = der_get_length (p, total_len - 1, &len, &len_len); - if (e || 1 + len_len + len != total_len) - return -1; -+ if (total_len < 1 + len_len + 1) -+ return -1; - p += len_len; - if (*p++ != 0x06) - return -1; --- -2.25.1 diff --git a/backport-0011-CVE-2022-3437.patch b/backport-0011-CVE-2022-3437.patch deleted file mode 100644 index ce643fe4877a7d385c3fe00916fbab075d821574..0000000000000000000000000000000000000000 --- a/backport-0011-CVE-2022-3437.patch +++ /dev/null @@ -1,58 +0,0 @@ -From e9db03736007721e37c4fba847ce4aa0c4520924 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Wed, 12 Oct 2022 13:57:33 +1300 -Subject: [PATCH 15/15] CVE-2022-3437 source4/heimdal: Pass correct length to - _gssapi_verify_pad() - -We later subtract 8 when calculating the length of the output message -buffer. If padlength is excessively high, this calculation can underflow -and result in a very large positive value. - -Now we properly constrain the value of padlength so underflow shouldn't -be possible. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15134 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett - -Conflict: NA -Reference: https://download.samba.org/pub/samba/patches/security/samba-4.15.11-security-2022-10-25.patch ---- - selftest/knownfail.d/heimdal-des-overflow | 2 -- - source4/heimdal/lib/gssapi/krb5/unwrap.c | 4 ++-- - 2 files changed, 2 insertions(+), 4 deletions(-) - delete mode 100644 selftest/knownfail.d/heimdal-des-overflow - -diff --git a/selftest/knownfail.d/heimdal-des-overflow b/selftest/knownfail.d/heimdal-des-overflow -deleted file mode 100644 -index a7416dc61d9..00000000000 ---- a/selftest/knownfail.d/heimdal-des-overflow -+++ /dev/null -@@ -1,2 +0,0 @@ --^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_with_padding_truncated_0.none --^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_with_padding_truncated_1.none -diff --git a/source4/heimdal/lib/gssapi/krb5/unwrap.c b/source4/heimdal/lib/gssapi/krb5/unwrap.c -index 70d26a75ccf..ed8f7d78ffa 100644 ---- a/source4/heimdal/lib/gssapi/krb5/unwrap.c -+++ b/source4/heimdal/lib/gssapi/krb5/unwrap.c -@@ -124,7 +124,7 @@ unwrap_des - } else { - /* check pad */ - ret = _gssapi_verify_pad(input_message_buffer, -- input_message_buffer->length - len, -+ input_message_buffer->length - len - 8, - &padlength); - if (ret) - return ret; -@@ -289,7 +289,7 @@ unwrap_des3 - } else { - /* check pad */ - ret = _gssapi_verify_pad(input_message_buffer, -- input_message_buffer->length - len, -+ input_message_buffer->length - len - 8, - &padlength); - if (ret) - return ret; --- -2.25.1 diff --git a/backport-CVE-2021-44141.patch b/backport-CVE-2021-44141.patch deleted file mode 100644 index e2b339fe0b5ea18679b98a1ead295e62d1d90ce2..0000000000000000000000000000000000000000 --- a/backport-CVE-2021-44141.patch +++ /dev/null @@ -1,8695 +0,0 @@ -From 550ece56400dc7391296943cf93ce0a4e54f9843 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Thu, 2 Dec 2021 12:05:51 -0800 -Subject: [PATCH 08/99] CVE-2021-44141: s4: libcli: Add smbcli_unlink_wcard(). - -We will use this in place of smbcli_unlink() when we -know we are using a wildcard pattern. If can be used -to generally replace smbcli_unlink() as it calls down -to smbcli_unlink() is no wildcard is detected. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison -Reviewed-by: Ralph Boehme ---- - source4/libcli/clifile.c | 96 ++++++++++++++++++++++++++++++++++++++++ - source4/libcli/libcli.h | 5 +++ - 2 files changed, 101 insertions(+) - -diff --git a/source4/libcli/clifile.c b/source4/libcli/clifile.c -index 19288247c44..f013a5653bb 100644 ---- a/source4/libcli/clifile.c -+++ b/source4/libcli/clifile.c -@@ -23,6 +23,7 @@ - #include "system/filesys.h" - #include "libcli/raw/libcliraw.h" - #include "libcli/libcli.h" -+#include "system/dir.h" - - /**************************************************************************** - Hard/Symlink a file (UNIX extensions). -@@ -148,6 +149,101 @@ NTSTATUS smbcli_unlink(struct smbcli_tree *tree, const char *fname) - return smb_raw_unlink(tree, &parms); - } - -+struct wcard_delete_state { -+ struct smbcli_tree *tree; -+ NTSTATUS status; -+ char *error_name; /* To help debugging. */ -+}; -+ -+static void del_fn(struct clilist_file_info *finfo, -+ const char *pattern, -+ void *priv) -+{ -+ NTSTATUS status; -+ union smb_unlink parms; -+ char *filename = NULL; -+ char *dirname = NULL; -+ char *p = NULL; -+ struct wcard_delete_state *state = (struct wcard_delete_state *)priv; -+ -+ if (ISDOT(finfo->name) || ISDOTDOT(finfo->name)) { -+ return; -+ } -+ dirname = talloc_strdup(state, pattern); -+ if (dirname == NULL) { -+ TALLOC_FREE(state->error_name); -+ state->status = NT_STATUS_NO_MEMORY; -+ return; -+ } -+ p = strrchr_m(dirname, '\\'); -+ if (p != NULL) { -+ /* Remove the terminating '\' */ -+ *p = '\0'; -+ } -+ if (dirname[0] != '\0') { -+ filename = talloc_asprintf(dirname, -+ "%s\\%s", -+ dirname, -+ finfo->name); -+ } else { -+ filename = talloc_asprintf(dirname, -+ "%s", -+ finfo->name); -+ } -+ if (filename == NULL) { -+ TALLOC_FREE(dirname); -+ TALLOC_FREE(state->error_name); -+ state->status = NT_STATUS_NO_MEMORY; -+ return; -+ } -+ parms.unlink.in.pattern = filename; -+ parms.unlink.in.attrib = FILE_ATTRIBUTE_SYSTEM | -+ FILE_ATTRIBUTE_HIDDEN; -+ status = smb_raw_unlink(state->tree, &parms); -+ if (NT_STATUS_IS_OK(state->status)) { -+ state->status = status; -+ if (!NT_STATUS_IS_OK(status)) { -+ /* -+ * Save off the name we failed to -+ * delete to help debugging. -+ */ -+ state->error_name = talloc_move(state, &filename); -+ } -+ } -+ TALLOC_FREE(dirname); -+} -+ -+/**************************************************************************** -+ Delete a file, possibly with a wildcard pattern. -+****************************************************************************/ -+NTSTATUS smbcli_unlink_wcard(struct smbcli_tree *tree, const char *pattern) -+{ -+ NTSTATUS status; -+ int ret; -+ struct wcard_delete_state *state = NULL; -+ -+ if (strchr(pattern, '*') == NULL) { -+ /* No wildcard, just call smbcli_unlink(). */ -+ return smbcli_unlink(tree, pattern); -+ } -+ state = talloc_zero(tree, struct wcard_delete_state); -+ if (state == NULL) { -+ return NT_STATUS_NO_MEMORY; -+ } -+ state->tree = tree; -+ ret = smbcli_list(tree, -+ pattern, -+ FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN, -+ del_fn, -+ state); -+ status = state->status; -+ TALLOC_FREE(state); -+ if (ret < 0) { -+ return NT_STATUS_UNSUCCESSFUL; -+ } -+ return status; -+} -+ - /**************************************************************************** - Create a directory. - ****************************************************************************/ -diff --git a/source4/libcli/libcli.h b/source4/libcli/libcli.h -index 652a9f5d182..9d2a3240483 100644 ---- a/source4/libcli/libcli.h -+++ b/source4/libcli/libcli.h -@@ -158,6 +158,11 @@ NTSTATUS smbcli_rename(struct smbcli_tree *tree, const char *fname_src, - ****************************************************************************/ - NTSTATUS smbcli_unlink(struct smbcli_tree *tree, const char *fname); - -+/**************************************************************************** -+ Delete a wildcard pattern of files. -+****************************************************************************/ -+NTSTATUS smbcli_unlink_wcard(struct smbcli_tree *tree, const char *fname); -+ - /**************************************************************************** - Create a directory. - ****************************************************************************/ --- -2.25.1 - - -From cf661f306afaf66feeea11bb2d9e7f7e3c988914 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Thu, 2 Dec 2021 12:10:14 -0800 -Subject: [PATCH 09/99] CVE-2021-44141: s4: libcli: In smbcli_deltree() use - smbcli_unlink_wcard() in place of smbcli_unlink(). - -We know we have a wildcard mask here. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison -Reviewed-by: Ralph Boehme ---- - source4/libcli/clideltree.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/source4/libcli/clideltree.c b/source4/libcli/clideltree.c -index 01b33313213..3e4f9fb834f 100644 ---- a/source4/libcli/clideltree.c -+++ b/source4/libcli/clideltree.c -@@ -119,7 +119,7 @@ int smbcli_deltree(struct smbcli_tree *tree, const char *dname) - if (asprintf(&mask, "%s\\*", dname) < 0) { - return -1; - } -- smbcli_unlink(dstate.tree, mask); -+ smbcli_unlink_wcard(dstate.tree, mask); - smbcli_list(dstate.tree, mask, - FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM, - delete_fn, &dstate); --- -2.25.1 - - -From a0fd6cd62f3d773371fa5f460306a562e524e6eb Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Thu, 2 Dec 2021 12:08:49 -0800 -Subject: [PATCH 10/99] CVE-2021-44141: s4: torture: In raw.notify test use - smbcli_unlink_wcard() in place of smbcli_unlink(). - -We know we have a wildcard mask here. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison -Reviewed-by: Ralph Boehme ---- - source4/torture/raw/notify.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/source4/torture/raw/notify.c b/source4/torture/raw/notify.c -index 881ad6b71cc..f3c38068780 100644 ---- a/source4/torture/raw/notify.c -+++ b/source4/torture/raw/notify.c -@@ -254,7 +254,7 @@ static bool test_notify_dir(struct torture_context *tctx, - - torture_comment(tctx, "Testing notify on wildcard unlink for %d files\n", count-1); - /* (2nd unlink) do a wildcard unlink */ -- status = smbcli_unlink(cli2->tree, BASEDIR_CN1_DIR "\\test*.txt"); -+ status = smbcli_unlink_wcard(cli2->tree, BASEDIR_CN1_DIR "\\test*.txt"); - torture_assert_ntstatus_ok_goto(tctx, status, ret, done, - "smb_raw_changenotify_recv"); - --- -2.25.1 - - -From 6f9580493e250a00d100a3f96253d00bd4294b55 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Wed, 1 Dec 2021 17:52:37 -0800 -Subject: [PATCH 11/99] CVE-2021-44141: s4: torture: Use smbcli_unlink_wcard() - to remove wildcards in base.chkpath test. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison -Reviewed-by: Ralph Boehme ---- - source4/torture/basic/base.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/source4/torture/basic/base.c b/source4/torture/basic/base.c -index e91fef1d6c2..232ba9c5cb3 100644 ---- a/source4/torture/basic/base.c -+++ b/source4/torture/basic/base.c -@@ -1461,7 +1461,7 @@ static bool torture_chkpath_test(struct torture_context *tctx, - - /* cleanup from an old run */ - smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2"); -- smbcli_unlink(cli->tree, "\\chkpath.dir\\*"); -+ smbcli_unlink_wcard(cli->tree, "\\chkpath.dir\\*"); - smbcli_rmdir(cli->tree, "\\chkpath.dir"); - - if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir"))) { -@@ -1516,7 +1516,7 @@ static bool torture_chkpath_test(struct torture_context *tctx, - } - - smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2"); -- smbcli_unlink(cli->tree, "\\chkpath.dir\\*"); -+ smbcli_unlink_wcard(cli->tree, "\\chkpath.dir\\*"); - smbcli_rmdir(cli->tree, "\\chkpath.dir"); - - return ret; --- -2.25.1 - - -From 745d08fe10a824ef1fe1fcf57fadfd6c8b6ae216 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Wed, 1 Dec 2021 17:58:58 -0800 -Subject: [PATCH 12/99] CVE-2021-44141: s4: torture: Use smbcli_unlink_wcard() - to cleanup in base.mangle test. - -Avoid using smbcli_unlink() calls with wildcard names. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison -Reviewed-by: Ralph Boehme ---- - source4/torture/basic/mangle_test.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/source4/torture/basic/mangle_test.c b/source4/torture/basic/mangle_test.c -index 0c3ccd54bf9..9bd3cf55dfb 100644 ---- a/source4/torture/basic/mangle_test.c -+++ b/source4/torture/basic/mangle_test.c -@@ -195,7 +195,7 @@ bool torture_mangle(struct torture_context *torture, - } - } - -- smbcli_unlink(cli->tree, "\\mangle_test\\*"); -+ smbcli_unlink_wcard(cli->tree, "\\mangle_test\\*"); - if (NT_STATUS_IS_ERR(smbcli_rmdir(cli->tree, "\\mangle_test"))) { - printf("ERROR: Failed to remove directory\n"); - return false; --- -2.25.1 - - -From ee3a5f2ee00cbd78446cff2e815f6cf3600e17a8 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Wed, 1 Dec 2021 18:03:57 -0800 -Subject: [PATCH 13/99] CVE-2021-44141: s4: torture: Use smbcli_unlink_wcard() - in base.casetable test. - -Avoid smbcli_unlink() calls with a wildcard path. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison -Reviewed-by: Ralph Boehme ---- - source4/torture/basic/utable.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/source4/torture/basic/utable.c b/source4/torture/basic/utable.c -index da2fe2e0b37..a3ddf1a7621 100644 ---- a/source4/torture/basic/utable.c -+++ b/source4/torture/basic/utable.c -@@ -195,7 +195,7 @@ bool torture_casetable(struct torture_context *tctx, - smbcli_close(cli->tree, fnum); - } - -- smbcli_unlink(cli->tree, "\\utable\\*"); -+ smbcli_unlink_wcard(cli->tree, "\\utable\\*"); - smbcli_rmdir(cli->tree, "\\utable"); - - return true; --- -2.25.1 - - -From 2cfbfd3e0a6fd012944cad4e0fe7fe2a8688b7cc Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Wed, 1 Dec 2021 18:08:32 -0800 -Subject: [PATCH 14/99] CVE-2021-44141: s4: torture: Use smbcli_unlink_wcard() - to setup and cleanup in masktest. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison -Reviewed-by: Ralph Boehme ---- - source4/torture/masktest.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/source4/torture/masktest.c b/source4/torture/masktest.c -index 5b2457a92e9..e311769a43d 100644 ---- a/source4/torture/masktest.c -+++ b/source4/torture/masktest.c -@@ -225,7 +225,7 @@ static void test_mask(int argc, char *argv[], - - smbcli_mkdir(cli->tree, "\\masktest"); - -- smbcli_unlink(cli->tree, "\\masktest\\*"); -+ smbcli_unlink_wcard(cli->tree, "\\masktest\\*"); - - if (argc >= 2) { - while (argc >= 2) { --- -2.25.1 - - -From db095ee5f039dc079200f1791c62c168ec57f2aa Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Thu, 2 Dec 2021 14:23:10 -0800 -Subject: [PATCH 15/99] CVE-2021-44141: s4: libcli: smbcli_unlink() is no - longer used with wildcard patterns. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison -Reviewed-by: Ralph Boehme ---- - source4/libcli/clifile.c | 6 +----- - 1 file changed, 1 insertion(+), 5 deletions(-) - -diff --git a/source4/libcli/clifile.c b/source4/libcli/clifile.c -index f013a5653bb..c6a5cd5a5e7 100644 ---- a/source4/libcli/clifile.c -+++ b/source4/libcli/clifile.c -@@ -140,11 +140,7 @@ NTSTATUS smbcli_unlink(struct smbcli_tree *tree, const char *fname) - union smb_unlink parms; - - parms.unlink.in.pattern = fname; -- if (strchr(fname, '*')) { -- parms.unlink.in.attrib = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN; -- } else { -- parms.unlink.in.attrib = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY; -- } -+ parms.unlink.in.attrib = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY; - - return smb_raw_unlink(tree, &parms); - } --- -2.25.1 - - -From 57fbf7564c7a0bea68ec80f774deb2fba22f3afb Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Thu, 2 Dec 2021 13:47:07 -0800 -Subject: [PATCH 16/99] CVE-2021-44141: s3: torture: Add torture_deltree() for - setup and teardown. - -Not yet used. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison -Reviewed-by: Ralph Boehme ---- - source3/torture/proto.h | 1 + - source3/torture/torture.c | 127 ++++++++++++++++++++++++++++++++++++++ - 2 files changed, 128 insertions(+) - -diff --git a/source3/torture/proto.h b/source3/torture/proto.h -index 65fa17523d8..d4db60f9dde 100644 ---- a/source3/torture/proto.h -+++ b/source3/torture/proto.h -@@ -74,6 +74,7 @@ bool torture_ioctl_test(int dummy); - bool torture_chkpath_test(int dummy); - NTSTATUS torture_setup_unix_extensions(struct cli_state *cli); - void torture_conn_set_sockopt(struct cli_state *cli); -+void torture_deltree(struct cli_state *cli, const char *dname); - - /* The following definitions come from torture/utable.c */ - -diff --git a/source3/torture/torture.c b/source3/torture/torture.c -index 4a886614ae1..a995b54df9c 100644 ---- a/source3/torture/torture.c -+++ b/source3/torture/torture.c -@@ -458,6 +458,133 @@ void torture_conn_set_sockopt(struct cli_state *cli) - smbXcli_conn_set_sockopt(cli->conn, sockops); - } - -+static NTSTATUS torture_delete_fn(struct file_info *finfo, -+ const char *pattern, -+ void *state) -+{ -+ NTSTATUS status; -+ char *filename = NULL; -+ char *dirname = NULL; -+ char *p = NULL; -+ TALLOC_CTX *frame = talloc_stackframe(); -+ struct cli_state *cli = (struct cli_state *)state; -+ -+ if (ISDOT(finfo->name) || ISDOTDOT(finfo->name)) { -+ TALLOC_FREE(frame); -+ return NT_STATUS_OK; -+ } -+ -+ dirname = talloc_strdup(frame, pattern); -+ if (dirname == NULL) { -+ TALLOC_FREE(frame); -+ return NT_STATUS_NO_MEMORY; -+ } -+ p = strrchr_m(dirname, '\\'); -+ if (p != NULL) { -+ /* Remove the terminating '\' */ -+ *p = '\0'; -+ } -+ if (dirname[0] != '\0') { -+ filename = talloc_asprintf(frame, -+ "%s\\%s", -+ dirname, -+ finfo->name); -+ } else { -+ filename = talloc_asprintf(frame, -+ "%s", -+ finfo->name); -+ } -+ if (filename == NULL) { -+ TALLOC_FREE(frame); -+ return NT_STATUS_NO_MEMORY; -+ } -+ if (finfo->attr & FILE_ATTRIBUTE_DIRECTORY) { -+ char *subdirname = talloc_asprintf(frame, -+ "%s\\*", -+ filename); -+ if (subdirname == NULL) { -+ TALLOC_FREE(frame); -+ return NT_STATUS_NO_MEMORY; -+ } -+ status = cli_list(cli, -+ subdirname, -+ FILE_ATTRIBUTE_DIRECTORY | -+ FILE_ATTRIBUTE_HIDDEN | -+ FILE_ATTRIBUTE_SYSTEM, -+ torture_delete_fn, -+ cli); -+ if (NT_STATUS_IS_OK(status)) { -+ printf("torture_delete_fn: cli_list " -+ "of %s failed (%s)\n", -+ subdirname, -+ nt_errstr(status)); -+ TALLOC_FREE(frame); -+ return status; -+ } -+ status = cli_rmdir(cli, filename); -+ } else { -+ status = cli_unlink(cli, -+ filename, -+ FILE_ATTRIBUTE_SYSTEM | -+ FILE_ATTRIBUTE_HIDDEN); -+ } -+ if (!NT_STATUS_IS_OK(status)) { -+ if (finfo->attr & FILE_ATTRIBUTE_DIRECTORY) { -+ printf("torture_delete_fn: cli_rmdir" -+ " of %s failed (%s)\n", -+ filename, -+ nt_errstr(status)); -+ } else { -+ printf("torture_delete_fn: cli_unlink" -+ " of %s failed (%s)\n", -+ filename, -+ nt_errstr(status)); -+ } -+ } -+ TALLOC_FREE(frame); -+ return status; -+} -+ -+void torture_deltree(struct cli_state *cli, const char *dname) -+{ -+ char *mask = NULL; -+ NTSTATUS status; -+ -+ /* It might be a file */ -+ (void)cli_unlink(cli, -+ dname, -+ FILE_ATTRIBUTE_SYSTEM | -+ FILE_ATTRIBUTE_HIDDEN); -+ -+ mask = talloc_asprintf(cli, -+ "%s\\*", -+ dname); -+ if (mask == NULL) { -+ printf("torture_deltree: talloc_asprintf failed\n"); -+ return; -+ } -+ -+ status = cli_list(cli, -+ mask, -+ FILE_ATTRIBUTE_DIRECTORY | -+ FILE_ATTRIBUTE_HIDDEN| -+ FILE_ATTRIBUTE_SYSTEM, -+ torture_delete_fn, -+ cli); -+ if (!NT_STATUS_IS_OK(status)) { -+ printf("torture_deltree: cli_list of %s failed (%s)\n", -+ mask, -+ nt_errstr(status)); -+ } -+ TALLOC_FREE(mask); -+ status = cli_rmdir(cli, dname); -+ if (!NT_STATUS_IS_OK(status)) { -+ printf("torture_deltree: cli_rmdir of %s failed (%s)\n", -+ dname, -+ nt_errstr(status)); -+ } -+} -+ - /* check if the server produced the expected dos or nt error code */ - static bool check_both_error(int line, NTSTATUS status, - uint8_t eclass, uint32_t ecode, NTSTATUS nterr) --- -2.25.1 - - -From 74fe15a05ad913112c4a76431b9e280e17ab2ee4 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Wed, 1 Dec 2021 12:51:54 -0800 -Subject: [PATCH 17/99] CVE-2021-44141: s3: torture: In - run_smb1_wild_mangle_unlink_test() use torture_deltree() for setup and - cleanup. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison -Reviewed-by: Ralph Boehme ---- - source3/torture/torture.c | 10 ++-------- - 1 file changed, 2 insertions(+), 8 deletions(-) - -diff --git a/source3/torture/torture.c b/source3/torture/torture.c -index a995b54df9c..cb11524446a 100644 ---- a/source3/torture/torture.c -+++ b/source3/torture/torture.c -@@ -12814,10 +12814,7 @@ static bool run_smb1_wild_mangle_unlink_test(int dummy) - } - - /* Start fresh. */ -- cli_unlink(cli, -- star_name, -- FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); -- cli_rmdir(cli, dname); -+ torture_deltree(cli, dname); - - /* - * Create two files - 'a' and '*'. -@@ -12927,10 +12924,7 @@ static bool run_smb1_wild_mangle_unlink_test(int dummy) - TALLOC_FREE(mangled_name); - - if (cli != NULL) { -- cli_unlink(cli, -- star_name, -- FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); -- cli_rmdir(cli, dname); -+ torture_deltree(cli, dname); - torture_close_connection(cli); - } - --- -2.25.1 - - -From 919b3c8d3fb9c5248a79ff01e096353cab3fd9f0 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Wed, 1 Dec 2021 13:51:12 -0800 -Subject: [PATCH 18/99] CVE-2021-44141: s3: torture: In - run_smb1_wild_mangle_rename_test() use torture_deltree() for setup and - cleanup. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison -Reviewed-by: Ralph Boehme ---- - source3/torture/torture.c | 10 ++-------- - 1 file changed, 2 insertions(+), 8 deletions(-) - -diff --git a/source3/torture/torture.c b/source3/torture/torture.c -index cb11524446a..5b5b5287d55 100644 ---- a/source3/torture/torture.c -+++ b/source3/torture/torture.c -@@ -12972,10 +12972,7 @@ static bool run_smb1_wild_mangle_rename_test(int dummy) - smbXcli_conn_set_sockopt(cli->conn, sockops); - - /* Ensure we start from fresh. */ -- cli_unlink(cli, -- wild_name, -- FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); -- cli_posix_rmdir(cli_posix, dname); -+ torture_deltree(cli, dname); - - /* - * Create two files - 'foo' and 'fo*'. -@@ -13094,13 +13091,10 @@ static bool run_smb1_wild_mangle_rename_test(int dummy) - TALLOC_FREE(windows_rename_src); - - if (cli != NULL) { -- cli_unlink(cli, -- wild_name, -- FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); -+ torture_deltree(cli, dname); - torture_close_connection(cli); - } - -- cli_posix_rmdir(cli_posix, dname); - torture_close_connection(cli_posix); - - return correct; --- -2.25.1 - - -From 04304b9f92cb6b17fa368ed039f84f3a75cf9016 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Thu, 2 Dec 2021 14:13:41 -0800 -Subject: [PATCH 19/99] CVE-2021-44141: s3: torture: In torture_utable(), use - torture_deltree() for setup. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison -Reviewed-by: Ralph Boehme ---- - source3/torture/utable.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/source3/torture/utable.c b/source3/torture/utable.c -index a912c4cb3b0..01f6b2e51e9 100644 ---- a/source3/torture/utable.c -+++ b/source3/torture/utable.c -@@ -43,8 +43,8 @@ bool torture_utable(int dummy) - - memset(valid, 0, sizeof(valid)); - -+ torture_deltree(cli, "\\utable"); - cli_mkdir(cli, "\\utable"); -- cli_unlink(cli, "\\utable\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); - - for (c=1; c < 0x10000; c++) { - size_t size = 0; --- -2.25.1 - - -From 18ac36f7aed4e46f2c029d67c0e97ce4c32e9bbe Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Thu, 2 Dec 2021 14:14:53 -0800 -Subject: [PATCH 20/99] CVE-2021-44141: s3: torture: In torture_casetable(), - use torture_deltree() for setup and cleanup. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison -Reviewed-by: Ralph Boehme ---- - source3/torture/utable.c | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - -diff --git a/source3/torture/utable.c b/source3/torture/utable.c -index 01f6b2e51e9..059cae9edd1 100644 ---- a/source3/torture/utable.c -+++ b/source3/torture/utable.c -@@ -146,8 +146,7 @@ bool torture_casetable(int dummy) - - memset(equiv, 0, sizeof(equiv)); - -- cli_unlink(cli, "\\utable\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); -- cli_rmdir(cli, "\\utable"); -+ torture_deltree(cli, "\\utable"); - if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\utable"))) { - printf("Failed to create utable directory!\n"); - return False; -@@ -205,8 +204,7 @@ bool torture_casetable(int dummy) - cli_close(cli, fnum); - } - -- cli_unlink(cli, "\\utable\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); -- cli_rmdir(cli, "\\utable"); -+ torture_deltree(cli, "\\utable"); - - return True; - } --- -2.25.1 - - -From ff64b0f32d0f0b41926badff7aab53c32759bc94 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Thu, 2 Dec 2021 14:16:38 -0800 -Subject: [PATCH 21/99] CVE-2021-44141: s3: torture: In torture_chkpath_test(), - use torture_deltree() for setup and cleanup. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison -Reviewed-by: Ralph Boehme ---- - source3/torture/torture.c | 8 ++------ - 1 file changed, 2 insertions(+), 6 deletions(-) - -diff --git a/source3/torture/torture.c b/source3/torture/torture.c -index 5b5b5287d55..e4343cf3050 100644 ---- a/source3/torture/torture.c -+++ b/source3/torture/torture.c -@@ -9933,9 +9933,7 @@ bool torture_chkpath_test(int dummy) - printf("starting chkpath test\n"); - - /* cleanup from an old run */ -- cli_rmdir(cli, "\\chkpath.dir\\dir2"); -- cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); -- cli_rmdir(cli, "\\chkpath.dir"); -+ torture_deltree(cli, "\\chkpath.dir"); - - status = cli_mkdir(cli, "\\chkpath.dir"); - if (!NT_STATUS_IS_OK(status)) { -@@ -9996,9 +9994,7 @@ bool torture_chkpath_test(int dummy) - ret = False; - } - -- cli_rmdir(cli, "\\chkpath.dir\\dir2"); -- cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); -- cli_rmdir(cli, "\\chkpath.dir"); -+ torture_deltree(cli, "\\chkpath.dir"); - - if (!torture_close_connection(cli)) { - return False; --- -2.25.1 - - -From 8349c57f76fcd53810620fc79d6b892ed2141ae6 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Thu, 2 Dec 2021 14:18:56 -0800 -Subject: [PATCH 22/99] CVE-2021-44141: s3: torture: In run_streamerror(), use - torture_deltree() for setup. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison -Reviewed-by: Ralph Boehme ---- - source3/torture/torture.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/source3/torture/torture.c b/source3/torture/torture.c -index e4343cf3050..9ad0f2120e5 100644 ---- a/source3/torture/torture.c -+++ b/source3/torture/torture.c -@@ -12464,8 +12464,7 @@ static bool run_streamerror(int dummy) - return false; - } - -- cli_unlink(cli, "\\testdir_streamerror\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); -- cli_rmdir(cli, dname); -+ torture_deltree(cli, dname); - - status = cli_mkdir(cli, dname); - if (!NT_STATUS_IS_OK(status)) { --- -2.25.1 - - -From cf109e26b7ae918833cb4610dbcba8dc9f7c5bc0 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Thu, 2 Dec 2021 14:20:07 -0800 -Subject: [PATCH 23/99] CVE-2021-44141: s3: torture: In test_mask(), use - torture_deltree() for setup. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison -Reviewed-by: Ralph Boehme ---- - source3/torture/masktest.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/source3/torture/masktest.c b/source3/torture/masktest.c -index ebd156167cd..d7485cfb5eb 100644 ---- a/source3/torture/masktest.c -+++ b/source3/torture/masktest.c -@@ -355,10 +355,9 @@ static void test_mask(int argc, char *argv[], - int fc_len = strlen(filechars); - TALLOC_CTX *ctx = talloc_tos(); - -+ torture_deltree(cli, "\\masktest"); - cli_mkdir(cli, "\\masktest"); - -- cli_unlink(cli, "\\masktest\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); -- - if (argc >= 2) { - while (argc >= 2) { - mask = talloc_asprintf(ctx, --- -2.25.1 - - -From c249f1d09d60fb637a118c0ade7714cc3fcb1866 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Thu, 2 Dec 2021 14:21:47 -0800 -Subject: [PATCH 24/99] CVE-2021-44141: s3: torture: In torture_mangle(), use - torture_deltree() for setup and cleanup. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison -Reviewed-by: Ralph Boehme ---- - source3/torture/mangle_test.c | 9 ++------- - 1 file changed, 2 insertions(+), 7 deletions(-) - -diff --git a/source3/torture/mangle_test.c b/source3/torture/mangle_test.c -index 5832a92cdda..92754b9eeb6 100644 ---- a/source3/torture/mangle_test.c -+++ b/source3/torture/mangle_test.c -@@ -188,8 +188,7 @@ bool torture_mangle(int dummy) - return False; - } - -- cli_unlink(cli, "\\mangle_test\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); -- cli_rmdir(cli, "\\mangle_test"); -+ torture_deltree(cli, "\\mangle_test"); - - if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\mangle_test"))) { - printf("ERROR: Failed to make directory\n"); -@@ -212,11 +211,7 @@ bool torture_mangle(int dummy) - } - } - -- cli_unlink(cli, "\\mangle_test\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); -- if (!NT_STATUS_IS_OK(cli_rmdir(cli, "\\mangle_test"))) { -- printf("ERROR: Failed to remove directory\n"); -- return False; -- } -+ torture_deltree(cli, "\\mangle_test"); - - printf("\nTotal collisions %u/%u - %.2f%% (%u failures)\n", - collisions, total, (100.0*collisions) / total, failures); --- -2.25.1 - - -From 6c40cda03e7011fe6ad7df2170a11bcfcce38e40 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Thu, 2 Dec 2021 14:10:41 -0800 -Subject: [PATCH 25/99] CVE-2021-44141: s3: torture: In - run_smb1_wild_mangle_unlink_test() use a valid pathname for rename target. - -The server will not be supporting wildcard rename soon. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison -Reviewed-by: Ralph Boehme ---- - source3/torture/torture.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/source3/torture/torture.c b/source3/torture/torture.c -index 9ad0f2120e5..b80a1113a5f 100644 ---- a/source3/torture/torture.c -+++ b/source3/torture/torture.c -@@ -12941,7 +12941,7 @@ static bool run_smb1_wild_mangle_rename_test(int dummy) - const char *foostar_name = "smb1_wild_mangle_rename/fo*"; - const char *wild_name = "smb1_wild_mangle_rename/*"; - char *windows_rename_src = NULL; -- const char *windows_rename_dst = "smb1_wild_mangle_rename\\ba*"; -+ const char *windows_rename_dst = "smb1_wild_mangle_rename\\bar"; - char *mangled_name = NULL; - NTSTATUS status; - --- -2.25.1 - - -From b39ba559c078b371a3b212a4c26e589fae811417 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Wed, 1 Dec 2021 12:05:20 -0800 -Subject: [PATCH 26/99] CVE-2021-44141: s4: torture: Remove the wildcard unlink - test code. - -This is pre WindowXP SMB1 functionality, and we -need to remove this from the server in order to -move towards SMB2-only, so the test must go. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison -Reviewed-by: Ralph Boehme ---- - source4/torture/raw/unlink.c | 72 ------------------------------------ - 1 file changed, 72 deletions(-) - -diff --git a/source4/torture/raw/unlink.c b/source4/torture/raw/unlink.c -index 4f198fa2759..53059aa576a 100644 ---- a/source4/torture/raw/unlink.c -+++ b/source4/torture/raw/unlink.c -@@ -112,78 +112,6 @@ static bool test_unlink(struct torture_context *tctx, struct smbcli_state *cli) - status = smb_raw_unlink(cli->tree, &io); - CHECK_STATUS(status, NT_STATUS_FILE_IS_A_DIRECTORY); - -- printf("Trying wildcards\n"); -- smbcli_close(cli->tree, smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE)); -- io.unlink.in.pattern = BASEDIR "\\t*.t"; -- io.unlink.in.attrib = 0; -- status = smb_raw_unlink(cli->tree, &io); -- CHECK_STATUS(status, NT_STATUS_NO_SUCH_FILE); -- -- io.unlink.in.pattern = BASEDIR "\\z*"; -- io.unlink.in.attrib = 0; -- status = smb_raw_unlink(cli->tree, &io); -- CHECK_STATUS(status, NT_STATUS_NO_SUCH_FILE); -- -- io.unlink.in.pattern = BASEDIR "\\z*"; -- io.unlink.in.attrib = FILE_ATTRIBUTE_DIRECTORY; -- status = smb_raw_unlink(cli->tree, &io); -- -- if (torture_setting_bool(tctx, "samba3", false)) { -- /* -- * In Samba3 we gave up upon getting the error codes in -- * wildcard unlink correct. Trying gentest showed that this is -- * irregular beyond our capabilities. So for -- * FILE_ATTRIBUTE_DIRECTORY we always return NAME_INVALID. -- * Tried by jra and vl. If others feel like solving this -- * puzzle, please tell us :-) -- */ -- CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID); -- } -- else { -- CHECK_STATUS(status, NT_STATUS_NO_SUCH_FILE); -- } -- -- io.unlink.in.pattern = BASEDIR "\\*"; -- io.unlink.in.attrib = FILE_ATTRIBUTE_DIRECTORY; -- status = smb_raw_unlink(cli->tree, &io); -- CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID); -- -- io.unlink.in.pattern = BASEDIR "\\?"; -- io.unlink.in.attrib = FILE_ATTRIBUTE_DIRECTORY; -- status = smb_raw_unlink(cli->tree, &io); -- CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID); -- -- io.unlink.in.pattern = BASEDIR "\\t*"; -- io.unlink.in.attrib = FILE_ATTRIBUTE_DIRECTORY; -- status = smb_raw_unlink(cli->tree, &io); -- if (torture_setting_bool(tctx, "samba3", false)) { -- CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID); -- } -- else { -- CHECK_STATUS(status, NT_STATUS_OK); -- } -- -- smbcli_close(cli->tree, smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE)); -- -- io.unlink.in.pattern = BASEDIR "\\*.dat"; -- io.unlink.in.attrib = FILE_ATTRIBUTE_DIRECTORY; -- status = smb_raw_unlink(cli->tree, &io); -- if (torture_setting_bool(tctx, "samba3", false)) { -- CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID); -- } -- else { -- CHECK_STATUS(status, NT_STATUS_NO_SUCH_FILE); -- } -- -- io.unlink.in.pattern = BASEDIR "\\*.tx?"; -- io.unlink.in.attrib = 0; -- status = smb_raw_unlink(cli->tree, &io); -- CHECK_STATUS(status, NT_STATUS_OK); -- -- status = smb_raw_unlink(cli->tree, &io); -- CHECK_STATUS(status, NT_STATUS_NO_SUCH_FILE); -- -- - done: - smb_raw_exit(cli->session); - smbcli_deltree(cli->tree, BASEDIR); --- -2.25.1 - - -From 05d2d29964ef5ef0e519b9621002138423d99bf9 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Wed, 1 Dec 2021 13:22:39 -0800 -Subject: [PATCH 27/99] CVE-2021-44141: s4: torture: Remove the wildcard rename - test code. - -This is pre WindowXP SMB1 functionality, and we -need to remove this from the server in order to -move towards SMB2-only, so the test must go. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison -Reviewed-by: Ralph Boehme ---- - source4/torture/raw/rename.c | 33 --------------------------------- - 1 file changed, 33 deletions(-) - -diff --git a/source4/torture/raw/rename.c b/source4/torture/raw/rename.c -index 63e13c0546f..5f48c055984 100644 ---- a/source4/torture/raw/rename.c -+++ b/source4/torture/raw/rename.c -@@ -146,39 +146,6 @@ static bool test_mv(struct torture_context *tctx, - status = smb_raw_rename(cli->tree, &io); - CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND); - -- -- torture_comment(tctx, "trying wildcard rename\n"); -- io.rename.in.pattern1 = BASEDIR "\\*.txt"; -- io.rename.in.pattern2 = fname1; -- -- status = smb_raw_rename(cli->tree, &io); -- CHECK_STATUS(status, NT_STATUS_OK); -- -- torture_comment(tctx, "and again\n"); -- status = smb_raw_rename(cli->tree, &io); -- CHECK_STATUS(status, NT_STATUS_OK); -- -- torture_comment(tctx, "Trying extension change\n"); -- io.rename.in.pattern1 = BASEDIR "\\*.txt"; -- io.rename.in.pattern2 = BASEDIR "\\*.bak"; -- status = smb_raw_rename(cli->tree, &io); -- CHECK_STATUS(status, NT_STATUS_OK); -- -- status = smb_raw_rename(cli->tree, &io); -- CHECK_STATUS(status, NT_STATUS_NO_SUCH_FILE); -- -- torture_comment(tctx, "Checking attrib handling\n"); -- torture_set_file_attribute(cli->tree, BASEDIR "\\test1.bak", FILE_ATTRIBUTE_HIDDEN); -- io.rename.in.pattern1 = BASEDIR "\\test1.bak"; -- io.rename.in.pattern2 = BASEDIR "\\*.txt"; -- io.rename.in.attrib = 0; -- status = smb_raw_rename(cli->tree, &io); -- CHECK_STATUS(status, NT_STATUS_NO_SUCH_FILE); -- -- io.rename.in.attrib = FILE_ATTRIBUTE_HIDDEN; -- status = smb_raw_rename(cli->tree, &io); -- CHECK_STATUS(status, NT_STATUS_OK); -- - done: - smbcli_close(cli->tree, fnum); - smb_raw_exit(cli->session); --- -2.25.1 - - -From 80d8a557dda29441f4091ec76bed86d23fd3f223 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Wed, 1 Dec 2021 12:18:35 -0800 -Subject: [PATCH 28/99] CVE-2021-44141: s3: torture: Remove the wildcard unlink - test code. - -This is pre WindowXP SMB1 functionality, and we -need to remove this from the server in order to -move towards SMB2-only, so the test must go. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison -Reviewed-by: Ralph Boehme ---- - selftest/todo_smb2_tests_to_port.list | 2 - - source3/selftest/tests.py | 2 +- - source3/torture/torture.c | 69 --------------------------- - 3 files changed, 1 insertion(+), 72 deletions(-) - -diff --git a/selftest/todo_smb2_tests_to_port.list b/selftest/todo_smb2_tests_to_port.list -index a9d7b8b48c5..dc1df963918 100644 ---- a/selftest/todo_smb2_tests_to_port.list -+++ b/selftest/todo_smb2_tests_to_port.list -@@ -242,7 +242,6 @@ samba3.smbtorture_s3.crypt_client.TRANS2(nt4_dc_smb1) - samba3.smbtorture_s3.crypt_client.UID-REGRESSION-TEST(nt4_dc_smb1) - samba3.smbtorture_s3.crypt_client.UNLINK(nt4_dc_smb1) - samba3.smbtorture_s3.crypt_client.W2K(nt4_dc_smb1) --samba3.smbtorture_s3.crypt_client.WILDDELETE(nt4_dc_smb1) - samba3.smbtorture_s3.crypt_client.XCOPY(nt4_dc_smb1) - samba3.smbtorture_s3.crypt.POSIX-ACL-OPLOCK(nt4_dc_smb1) - samba3.smbtorture_s3.crypt.POSIX-ACL-SHAREROOT(nt4_dc_smb1) -@@ -327,7 +326,6 @@ samba3.smbtorture_s3.plain.TRANS2(fileserver_smb1) - samba3.smbtorture_s3.plain.UID-REGRESSION-TEST(fileserver_smb1) - samba3.smbtorture_s3.plain.UNLINK(fileserver_smb1) - samba3.smbtorture_s3.plain.W2K(fileserver_smb1) --samba3.smbtorture_s3.plain.WILDDELETE(fileserver_smb1) - samba3.smbtorture_s3.plain.WINDOWS-BAD-SYMLINK(nt4_dc_smb1) - samba3.smbtorture_s3.plain.XCOPY(fileserver_smb1) - samba3.smbtorture_s3.vfs_aio_fork(fileserver_smb1).RW1(fileserver_smb1) -diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py -index 0654d8b0495..4751e4437aa 100755 ---- a/source3/selftest/tests.py -+++ b/source3/selftest/tests.py -@@ -113,7 +113,7 @@ fileserver_tests = [ - "UNLINK", "BROWSE", "ATTR", "TRANS2", "TORTURE", - "OPLOCK1", "OPLOCK2", "OPLOCK4", "STREAMERROR", - "DIR", "DIR1", "DIR-CREATETIME", "TCON", "TCONDEV", "RW1", "RW2", "RW3", "LARGE_READX", "RW-SIGNING", -- "OPEN", "XCOPY", "RENAME", "DELETE", "DELETE-LN", "WILDDELETE", "PROPERTIES", "W2K", -+ "OPEN", "XCOPY", "RENAME", "DELETE", "DELETE-LN", "PROPERTIES", "W2K", - "TCON2", "IOCTL", "CHKPATH", "FDSESS", "CHAIN1", "CHAIN2", "OWNER-RIGHTS", - "CHAIN3", "PIDHIGH", "CLI_SPLICE", - "UID-REGRESSION-TEST", "SHORTNAME-TEST", -diff --git a/source3/torture/torture.c b/source3/torture/torture.c -index b80a1113a5f..0d3b01326b1 100644 ---- a/source3/torture/torture.c -+++ b/source3/torture/torture.c -@@ -6121,71 +6121,6 @@ static bool run_delete_print_test(int dummy) - return correct; - } - --/* -- Test wildcard delete. -- */ --static bool run_wild_deletetest(int dummy) --{ -- struct cli_state *cli = NULL; -- const char *dname = "\\WTEST"; -- const char *fname = "\\WTEST\\A"; -- const char *wunlink_name = "\\WTEST\\*"; -- uint16_t fnum1 = (uint16_t)-1; -- bool correct = false; -- NTSTATUS status; -- -- printf("starting wildcard delete test\n"); -- -- if (!torture_open_connection(&cli, 0)) { -- return false; -- } -- -- smbXcli_conn_set_sockopt(cli->conn, sockops); -- -- cli_unlink(cli, fname, 0); -- cli_rmdir(cli, dname); -- status = cli_mkdir(cli, dname); -- if (!NT_STATUS_IS_OK(status)) { -- printf("mkdir of %s failed %s!\n", dname, nt_errstr(status)); -- goto fail; -- } -- status = cli_openx(cli, fname, O_CREAT|O_RDONLY, DENY_NONE, &fnum1); -- if (!NT_STATUS_IS_OK(status)) { -- printf("open of %s failed %s!\n", fname, nt_errstr(status)); -- goto fail; -- } -- status = cli_close(cli, fnum1); -- fnum1 = -1; -- -- /* -- * Note the unlink attribute-type of zero. This should -- * map into FILE_ATTRIBUTE_NORMAL at the server even -- * on a wildcard delete. -- */ -- -- status = cli_unlink(cli, wunlink_name, 0); -- if (!NT_STATUS_IS_OK(status)) { -- printf("unlink of %s failed %s!\n", -- wunlink_name, nt_errstr(status)); -- goto fail; -- } -- -- printf("finished wildcard delete test\n"); -- -- correct = true; -- -- fail: -- -- if (fnum1 != (uint16_t)-1) cli_close(cli, fnum1); -- cli_unlink(cli, fname, 0); -- cli_rmdir(cli, dname); -- -- if (cli && !torture_close_connection(cli)) { -- correct = false; -- } -- return correct; --} -- - static bool run_deletetest_ln(int dummy) - { - struct cli_state *cli; -@@ -15148,10 +15083,6 @@ static struct { - .name = "DELETE-PRINT", - .fn = run_delete_print_test, - }, -- { -- .name = "WILDDELETE", -- .fn = run_wild_deletetest, -- }, - { - .name = "DELETE-LN", - .fn = run_deletetest_ln, --- -2.25.1 - - -From d57802650f48391ef906283963c86e31466702c4 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Wed, 1 Dec 2021 12:24:07 -0800 -Subject: [PATCH 29/99] CVE-2021-44141: s3: smbd: Remove support for SMBcopy - SMB_COM_COPY (0x29) - -It's not used in our client code or tested. - -From MS-CIFS. - -This command was introduced in the LAN Manager 1.0 dialect -It was rendered obsolete in the NT LAN Manager dialect. -This command was used to perform server-side file copies, but -is no longer used. Clients SHOULD -NOT send requests using this command code. -Servers receiving requests with this command code -SHOULD return STATUS_NOT_IMPLEMENTED (ERRDOS/ERRbadfunc). - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison -Reviewed-by: Ralph Boehme ---- - source3/smbd/reply.c | 416 ++----------------------------------------- - 1 file changed, 11 insertions(+), 405 deletions(-) - -diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c -index f85d1122a07..faef4b23a3c 100644 ---- a/source3/smbd/reply.c -+++ b/source3/smbd/reply.c -@@ -8766,416 +8766,22 @@ NTSTATUS copy_file(TALLOC_CTX *ctx, - - /**************************************************************************** - Reply to a file copy. -+ -+ From MS-CIFS. -+ -+ This command was introduced in the LAN Manager 1.0 dialect -+ It was rendered obsolete in the NT LAN Manager dialect. -+ This command was used to perform server-side file copies, but -+ is no longer used. Clients SHOULD -+ NOT send requests using this command code. -+ Servers receiving requests with this command code -+ SHOULD return STATUS_NOT_IMPLEMENTED (ERRDOS/ERRbadfunc). - ****************************************************************************/ - - void reply_copy(struct smb_request *req) - { -- connection_struct *conn = req->conn; -- struct smb_filename *smb_fname_src = NULL; -- struct smb_filename *smb_fname_src_dir = NULL; -- struct smb_filename *smb_fname_dst = NULL; -- char *fname_src = NULL; -- char *fname_dst = NULL; -- char *fname_src_mask = NULL; -- char *fname_src_dir = NULL; -- const char *p; -- int count=0; -- int error = ERRnoaccess; -- int tid2; -- int ofun; -- int flags; -- bool target_is_directory=False; -- bool source_has_wild = False; -- bool dest_has_wild = False; -- NTSTATUS status; -- uint32_t ucf_flags_src = UCF_ALWAYS_ALLOW_WCARD_LCOMP | -- ucf_flags_from_smb_request(req); -- uint32_t ucf_flags_dst = UCF_ALWAYS_ALLOW_WCARD_LCOMP | -- ucf_flags_from_smb_request(req); -- TALLOC_CTX *ctx = talloc_tos(); -- - START_PROFILE(SMBcopy); -- -- if (req->wct < 3) { -- reply_nterror(req, NT_STATUS_INVALID_PARAMETER); -- goto out; -- } -- -- tid2 = SVAL(req->vwv+0, 0); -- ofun = SVAL(req->vwv+1, 0); -- flags = SVAL(req->vwv+2, 0); -- -- p = (const char *)req->buf; -- p += srvstr_get_path_req(ctx, req, &fname_src, p, STR_TERMINATE, -- &status); -- if (!NT_STATUS_IS_OK(status)) { -- reply_nterror(req, status); -- goto out; -- } -- p += srvstr_get_path_req(ctx, req, &fname_dst, p, STR_TERMINATE, -- &status); -- if (!NT_STATUS_IS_OK(status)) { -- reply_nterror(req, status); -- goto out; -- } -- -- DEBUG(3,("reply_copy : %s -> %s\n", fname_src, fname_dst)); -- -- if (tid2 != conn->cnum) { -- /* can't currently handle inter share copies XXXX */ -- DEBUG(3,("Rejecting inter-share copy\n")); -- reply_nterror(req, NT_STATUS_BAD_DEVICE_TYPE); -- goto out; -- } -- -- status = filename_convert(ctx, conn, -- fname_src, -- ucf_flags_src, -- 0, -- &smb_fname_src); -- if (!NT_STATUS_IS_OK(status)) { -- if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { -- reply_botherror(req, NT_STATUS_PATH_NOT_COVERED, -- ERRSRV, ERRbadpath); -- goto out; -- } -- reply_nterror(req, status); -- goto out; -- } -- -- status = filename_convert(ctx, conn, -- fname_dst, -- ucf_flags_dst, -- 0, -- &smb_fname_dst); -- if (!NT_STATUS_IS_OK(status)) { -- if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { -- reply_botherror(req, NT_STATUS_PATH_NOT_COVERED, -- ERRSRV, ERRbadpath); -- goto out; -- } -- reply_nterror(req, status); -- goto out; -- } -- -- target_is_directory = VALID_STAT_OF_DIR(smb_fname_dst->st); -- -- if ((flags&1) && target_is_directory) { -- reply_nterror(req, NT_STATUS_NO_SUCH_FILE); -- goto out; -- } -- -- if ((flags&2) && !target_is_directory) { -- reply_nterror(req, NT_STATUS_OBJECT_PATH_NOT_FOUND); -- goto out; -- } -- -- if ((flags&(1<<5)) && VALID_STAT_OF_DIR(smb_fname_src->st)) { -- /* wants a tree copy! XXXX */ -- DEBUG(3,("Rejecting tree copy\n")); -- reply_nterror(req, NT_STATUS_INVALID_PARAMETER); -- goto out; -- } -- -- /* Split up the directory from the filename/mask. */ -- status = split_fname_dir_mask(ctx, smb_fname_src->base_name, -- &fname_src_dir, &fname_src_mask); -- if (!NT_STATUS_IS_OK(status)) { -- reply_nterror(req, NT_STATUS_NO_MEMORY); -- goto out; -- } -- -- if (!req->posix_pathnames) { -- char *orig_src_lcomp = NULL; -- char *orig_dst_lcomp = NULL; -- /* -- * Check the wildcard mask *before* -- * unmangling. As mangling is done -- * for names that can't be returned -- * to Windows the unmangled name may -- * contain Windows wildcard characters. -- */ -- orig_src_lcomp = get_original_lcomp(ctx, -- conn, -- fname_src, -- ucf_flags_src); -- if (orig_src_lcomp == NULL) { -- reply_nterror(req, NT_STATUS_NO_MEMORY); -- goto out; -- } -- orig_dst_lcomp = get_original_lcomp(ctx, -- conn, -- fname_dst, -- ucf_flags_dst); -- if (orig_dst_lcomp == NULL) { -- reply_nterror(req, NT_STATUS_NO_MEMORY); -- goto out; -- } -- source_has_wild = ms_has_wild(orig_src_lcomp); -- dest_has_wild = ms_has_wild(orig_dst_lcomp); -- TALLOC_FREE(orig_src_lcomp); -- TALLOC_FREE(orig_dst_lcomp); -- } -- -- /* -- * We should only check the mangled cache -- * here if unix_convert failed. This means -- * that the path in 'mask' doesn't exist -- * on the file system and so we need to look -- * for a possible mangle. This patch from -- * Tine Smukavec . -- */ -- if (!VALID_STAT(smb_fname_src->st) && -- mangle_is_mangled(fname_src_mask, conn->params)) { -- char *new_mask = NULL; -- mangle_lookup_name_from_8_3(ctx, fname_src_mask, -- &new_mask, conn->params); -- -- /* Use demangled name if one was successfully found. */ -- if (new_mask) { -- TALLOC_FREE(fname_src_mask); -- fname_src_mask = new_mask; -- } -- } -- -- if (!source_has_wild) { -- -- /* -- * Only one file needs to be copied. Append the mask back onto -- * the directory. -- */ -- TALLOC_FREE(smb_fname_src->base_name); -- if (ISDOT(fname_src_dir)) { -- /* Ensure we use canonical names on open. */ -- smb_fname_src->base_name = talloc_asprintf(smb_fname_src, -- "%s", -- fname_src_mask); -- } else { -- smb_fname_src->base_name = talloc_asprintf(smb_fname_src, -- "%s/%s", -- fname_src_dir, -- fname_src_mask); -- } -- if (!smb_fname_src->base_name) { -- reply_nterror(req, NT_STATUS_NO_MEMORY); -- goto out; -- } -- -- if (dest_has_wild) { -- char *fname_dst_mod = NULL; -- if (!resolve_wildcards(smb_fname_dst, -- smb_fname_src->base_name, -- smb_fname_dst->base_name, -- &fname_dst_mod)) { -- reply_nterror(req, NT_STATUS_NO_MEMORY); -- goto out; -- } -- TALLOC_FREE(smb_fname_dst->base_name); -- smb_fname_dst->base_name = fname_dst_mod; -- } -- -- status = check_name(conn, smb_fname_src); -- if (!NT_STATUS_IS_OK(status)) { -- reply_nterror(req, status); -- goto out; -- } -- -- status = check_name(conn, smb_fname_dst); -- if (!NT_STATUS_IS_OK(status)) { -- reply_nterror(req, status); -- goto out; -- } -- -- status = copy_file(ctx, conn, smb_fname_src, smb_fname_dst, -- ofun, count, target_is_directory); -- -- if(!NT_STATUS_IS_OK(status)) { -- reply_nterror(req, status); -- goto out; -- } else { -- count++; -- } -- } else { -- struct smb_Dir *dir_hnd = NULL; -- const char *dname = NULL; -- char *talloced = NULL; -- long offset = 0; -- -- /* -- * There is a wildcard that requires us to actually read the -- * src dir and copy each file matching the mask to the dst. -- * Right now streams won't be copied, but this could -- * presumably be added with a nested loop for reach dir entry. -- */ -- SMB_ASSERT(!smb_fname_src->stream_name); -- SMB_ASSERT(!smb_fname_dst->stream_name); -- -- smb_fname_src->stream_name = NULL; -- smb_fname_dst->stream_name = NULL; -- -- if (strequal(fname_src_mask,"????????.???")) { -- TALLOC_FREE(fname_src_mask); -- fname_src_mask = talloc_strdup(ctx, "*"); -- if (!fname_src_mask) { -- reply_nterror(req, NT_STATUS_NO_MEMORY); -- goto out; -- } -- } -- -- smb_fname_src_dir = synthetic_smb_fname(talloc_tos(), -- fname_src_dir, -- NULL, -- NULL, -- smb_fname_src->twrp, -- smb_fname_src->flags); -- if (smb_fname_src_dir == NULL) { -- reply_nterror(req, NT_STATUS_NO_MEMORY); -- goto out; -- } -- -- status = check_name(conn, smb_fname_src_dir); -- if (!NT_STATUS_IS_OK(status)) { -- reply_nterror(req, status); -- goto out; -- } -- -- dir_hnd = OpenDir(ctx, -- conn, -- smb_fname_src_dir, -- fname_src_mask, -- 0); -- if (dir_hnd == NULL) { -- status = map_nt_error_from_unix(errno); -- reply_nterror(req, status); -- goto out; -- } -- -- error = ERRbadfile; -- -- /* Iterate over the src dir copying each entry to the dst. */ -- while ((dname = ReadDirName(dir_hnd, &offset, -- &smb_fname_src->st, &talloced))) { -- char *destname = NULL; -- -- if (ISDOT(dname) || ISDOTDOT(dname)) { -- TALLOC_FREE(talloced); -- continue; -- } -- -- if (IS_VETO_PATH(conn, dname)) { -- TALLOC_FREE(talloced); -- continue; -- } -- -- if(!mask_match(dname, fname_src_mask, -- conn->case_sensitive)) { -- TALLOC_FREE(talloced); -- continue; -- } -- -- error = ERRnoaccess; -- -- /* Get the src smb_fname struct setup. */ -- TALLOC_FREE(smb_fname_src->base_name); -- if (ISDOT(fname_src_dir)) { -- /* Ensure we use canonical names on open. */ -- smb_fname_src->base_name = -- talloc_asprintf(smb_fname_src, "%s", -- dname); -- } else { -- smb_fname_src->base_name = -- talloc_asprintf(smb_fname_src, "%s/%s", -- fname_src_dir, dname); -- } -- -- if (!smb_fname_src->base_name) { -- TALLOC_FREE(dir_hnd); -- TALLOC_FREE(talloced); -- reply_nterror(req, NT_STATUS_NO_MEMORY); -- goto out; -- } -- -- if (!resolve_wildcards(ctx, smb_fname_src->base_name, -- smb_fname_dst->base_name, -- &destname)) { -- TALLOC_FREE(talloced); -- continue; -- } -- if (!destname) { -- TALLOC_FREE(dir_hnd); -- TALLOC_FREE(talloced); -- reply_nterror(req, NT_STATUS_NO_MEMORY); -- goto out; -- } -- -- TALLOC_FREE(smb_fname_dst->base_name); -- smb_fname_dst->base_name = destname; -- -- ZERO_STRUCT(smb_fname_src->st); -- vfs_stat(conn, smb_fname_src); -- -- status = openat_pathref_fsp(conn->cwd_fsp, -- smb_fname_src); -- if (!NT_STATUS_IS_OK(status)) { -- DBG_INFO("openat_pathref_fsp [%s] failed: %s\n", -- smb_fname_str_dbg(smb_fname_src), -- nt_errstr(status)); -- break; -- } -- -- if (!is_visible_fsp(smb_fname_src->fsp)) { -- TALLOC_FREE(talloced); -- continue; -- } -- -- status = check_name(conn, smb_fname_src); -- if (!NT_STATUS_IS_OK(status)) { -- TALLOC_FREE(dir_hnd); -- TALLOC_FREE(talloced); -- reply_nterror(req, status); -- goto out; -- } -- -- status = check_name(conn, smb_fname_dst); -- if (!NT_STATUS_IS_OK(status)) { -- TALLOC_FREE(dir_hnd); -- TALLOC_FREE(talloced); -- reply_nterror(req, status); -- goto out; -- } -- -- DEBUG(3,("reply_copy : doing copy on %s -> %s\n", -- smb_fname_src->base_name, -- smb_fname_dst->base_name)); -- -- status = copy_file(ctx, conn, smb_fname_src, -- smb_fname_dst, ofun, count, -- target_is_directory); -- if (NT_STATUS_IS_OK(status)) { -- count++; -- } -- -- TALLOC_FREE(talloced); -- } -- TALLOC_FREE(dir_hnd); -- } -- -- if (count == 0) { -- reply_nterror(req, dos_to_ntstatus(ERRDOS, error)); -- goto out; -- } -- -- reply_outbuf(req, 1, 0); -- SSVAL(req->outbuf,smb_vwv0,count); -- out: -- TALLOC_FREE(smb_fname_src); -- TALLOC_FREE(smb_fname_src_dir); -- TALLOC_FREE(smb_fname_dst); -- TALLOC_FREE(fname_src); -- TALLOC_FREE(fname_dst); -- TALLOC_FREE(fname_src_mask); -- TALLOC_FREE(fname_src_dir); -- -+ reply_nterror(req, NT_STATUS_NOT_IMPLEMENTED); - END_PROFILE(SMBcopy); - return; - } --- -2.25.1 - - -From 79ae11f3cb464ffe381c62451ad38125f1872156 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Wed, 1 Dec 2021 12:31:44 -0800 -Subject: [PATCH 30/99] CVE-2021-44141: s3: smbd: In reply_unlink() remove the - possibility of receiving a wildcard name. - -This was the only user of "has_wild=true" passed to -unlink_internals(). - -Next commit will remove this functionality from unlink_internals(). - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison -Reviewed-by: Ralph Boehme ---- - source3/smbd/reply.c | 19 ++----------------- - 1 file changed, 2 insertions(+), 17 deletions(-) - -diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c -index faef4b23a3c..dd8c536ffac 100644 ---- a/source3/smbd/reply.c -+++ b/source3/smbd/reply.c -@@ -3537,10 +3537,8 @@ void reply_unlink(struct smb_request *req) - struct smb_filename *smb_fname = NULL; - uint32_t dirtype; - NTSTATUS status; -- uint32_t ucf_flags = UCF_ALWAYS_ALLOW_WCARD_LCOMP | -- ucf_flags_from_smb_request(req); -+ uint32_t ucf_flags = ucf_flags_from_smb_request(req); - TALLOC_CTX *ctx = talloc_tos(); -- bool has_wild = false; - - START_PROFILE(SMBunlink); - -@@ -3573,22 +3571,9 @@ void reply_unlink(struct smb_request *req) - goto out; - } - -- if (!req->posix_pathnames) { -- char *lcomp = get_original_lcomp(ctx, -- conn, -- name, -- ucf_flags); -- if (lcomp == NULL) { -- reply_nterror(req, NT_STATUS_NO_MEMORY); -- goto out; -- } -- has_wild = ms_has_wild(lcomp); -- TALLOC_FREE(lcomp); -- } -- - DEBUG(3,("reply_unlink : %s\n", smb_fname_str_dbg(smb_fname))); - -- status = unlink_internals(conn, req, dirtype, smb_fname, has_wild); -+ status = unlink_internals(conn, req, dirtype, smb_fname, false); - if (!NT_STATUS_IS_OK(status)) { - if (open_was_deferred(req->xconn, req->mid)) { - /* We have re-scheduled this call. */ --- -2.25.1 - - -From e4c3d31854fa1969d946bd6a7cfcf25db5d21d7b Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Wed, 1 Dec 2021 12:53:29 -0800 -Subject: [PATCH 31/99] CVE-2021-44141: s3: smbd: Change unlink_internals() to - ignore has_wild parameter. - -It's always passed as false now so we can remove the (horrible) -enumeration code for unlink. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison -Reviewed-by: Ralph Boehme ---- - source3/smbd/reply.c | 226 +++++-------------------------------------- - 1 file changed, 26 insertions(+), 200 deletions(-) - -diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c -index dd8c536ffac..abdf5f01fd8 100644 ---- a/source3/smbd/reply.c -+++ b/source3/smbd/reply.c -@@ -3283,11 +3283,9 @@ NTSTATUS unlink_internals(connection_struct *conn, - { - char *fname_dir = NULL; - char *fname_mask = NULL; -- int count=0; - NTSTATUS status = NT_STATUS_OK; - struct smb_filename *smb_fname_dir = NULL; - TALLOC_CTX *ctx = talloc_tos(); -- int ret; - - /* Split up the directory from the filename/mask. */ - status = split_fname_dir_mask(ctx, smb_fname->base_name, -@@ -3316,209 +3314,37 @@ NTSTATUS unlink_internals(connection_struct *conn, - } - } - -- if (!has_wild) { -- -- /* -- * Only one file needs to be unlinked. Append the mask back -- * onto the directory. -- */ -- TALLOC_FREE(smb_fname->base_name); -- if (ISDOT(fname_dir)) { -- /* Ensure we use canonical names on open. */ -- smb_fname->base_name = talloc_asprintf(smb_fname, -- "%s", -- fname_mask); -- } else { -- smb_fname->base_name = talloc_asprintf(smb_fname, -- "%s/%s", -- fname_dir, -- fname_mask); -- } -- if (!smb_fname->base_name) { -- status = NT_STATUS_NO_MEMORY; -- goto out; -- } -- if (dirtype == 0) { -- dirtype = FILE_ATTRIBUTE_NORMAL; -- } -- -- status = check_name(conn, smb_fname); -- if (!NT_STATUS_IS_OK(status)) { -- goto out; -- } -- -- status = do_unlink(conn, req, smb_fname, dirtype); -- if (!NT_STATUS_IS_OK(status)) { -- goto out; -- } -- -- count++; -+ /* -+ * Only one file needs to be unlinked. Append the mask back -+ * onto the directory. -+ */ -+ TALLOC_FREE(smb_fname->base_name); -+ if (ISDOT(fname_dir)) { -+ /* Ensure we use canonical names on open. */ -+ smb_fname->base_name = talloc_asprintf(smb_fname, -+ "%s", -+ fname_mask); - } else { -- struct smb_Dir *dir_hnd = NULL; -- long offset = 0; -- const char *dname = NULL; -- char *talloced = NULL; -- -- if ((dirtype & SAMBA_ATTRIBUTES_MASK) == FILE_ATTRIBUTE_DIRECTORY) { -- status = NT_STATUS_OBJECT_NAME_INVALID; -- goto out; -- } -- if (dirtype == 0) { -- dirtype = FILE_ATTRIBUTE_NORMAL; -- } -- -- if (strequal(fname_mask,"????????.???")) { -- TALLOC_FREE(fname_mask); -- fname_mask = talloc_strdup(ctx, "*"); -- if (!fname_mask) { -- status = NT_STATUS_NO_MEMORY; -- goto out; -- } -- } -- -- smb_fname_dir = synthetic_smb_fname(talloc_tos(), -- fname_dir, -- NULL, -- NULL, -- smb_fname->twrp, -- smb_fname->flags); -- if (smb_fname_dir == NULL) { -- status = NT_STATUS_NO_MEMORY; -- goto out; -- } -- -- status = check_name(conn, smb_fname_dir); -- if (!NT_STATUS_IS_OK(status)) { -- goto out; -- } -- -- dir_hnd = OpenDir(talloc_tos(), conn, smb_fname_dir, fname_mask, -- dirtype); -- if (dir_hnd == NULL) { -- status = map_nt_error_from_unix(errno); -- goto out; -- } -- -- /* XXXX the CIFS spec says that if bit0 of the flags2 field is set then -- the pattern matches against the long name, otherwise the short name -- We don't implement this yet XXXX -- */ -- -- status = NT_STATUS_NO_SUCH_FILE; -- -- while ((dname = ReadDirName(dir_hnd, &offset, -- &smb_fname->st, &talloced))) { -- TALLOC_CTX *frame = talloc_stackframe(); -- char *p = NULL; -- struct smb_filename *f = NULL; -- -- /* Quick check for "." and ".." */ -- if (ISDOT(dname) || ISDOTDOT(dname)) { -- TALLOC_FREE(frame); -- TALLOC_FREE(talloced); -- continue; -- } -- -- if (IS_VETO_PATH(conn, dname)) { -- TALLOC_FREE(frame); -- TALLOC_FREE(talloced); -- continue; -- } -- -- if(!mask_match(dname, fname_mask, -- conn->case_sensitive)) { -- TALLOC_FREE(frame); -- TALLOC_FREE(talloced); -- continue; -- } -- -- if (ISDOT(fname_dir)) { -- /* Ensure we use canonical names on open. */ -- p = talloc_asprintf(smb_fname, "%s", dname); -- } else { -- p = talloc_asprintf(smb_fname, "%s/%s", -- fname_dir, dname); -- } -- if (p == NULL) { -- TALLOC_FREE(dir_hnd); -- status = NT_STATUS_NO_MEMORY; -- TALLOC_FREE(frame); -- TALLOC_FREE(talloced); -- goto out; -- } -- f = synthetic_smb_fname(frame, -- p, -- NULL, -- &smb_fname->st, -- smb_fname->twrp, -- smb_fname->flags); -- if (f == NULL) { -- TALLOC_FREE(dir_hnd); -- status = NT_STATUS_NO_MEMORY; -- TALLOC_FREE(frame); -- TALLOC_FREE(talloced); -- goto out; -- } -- -- ret = vfs_stat(conn, f); -- if (ret != 0) { -- status = map_nt_error_from_unix(errno); -- TALLOC_FREE(dir_hnd); -- TALLOC_FREE(frame); -- TALLOC_FREE(talloced); -- goto out; -- } -- -- status = openat_pathref_fsp(conn->cwd_fsp, f); -- if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) && -- (f->flags & SMB_FILENAME_POSIX_PATH) && -- S_ISLNK(f->st.st_ex_mode)) -- { -- status = NT_STATUS_OK; -- } -- if (!NT_STATUS_IS_OK(status)) { -- TALLOC_FREE(dir_hnd); -- TALLOC_FREE(frame); -- TALLOC_FREE(talloced); -- goto out; -- } -- -- if (!is_visible_fsp(f->fsp)) { -- TALLOC_FREE(frame); -- TALLOC_FREE(talloced); -- continue; -- } -- -- status = check_name(conn, f); -- if (!NT_STATUS_IS_OK(status)) { -- TALLOC_FREE(dir_hnd); -- TALLOC_FREE(frame); -- TALLOC_FREE(talloced); -- goto out; -- } -- -- status = do_unlink(conn, req, f, dirtype); -- if (!NT_STATUS_IS_OK(status)) { -- TALLOC_FREE(dir_hnd); -- TALLOC_FREE(frame); -- TALLOC_FREE(talloced); -- goto out; -- } -- -- count++; -- DBG_DEBUG("successful unlink [%s]\n", -- smb_fname_str_dbg(f)); -- -- TALLOC_FREE(frame); -- TALLOC_FREE(talloced); -- } -- TALLOC_FREE(dir_hnd); -+ smb_fname->base_name = talloc_asprintf(smb_fname, -+ "%s/%s", -+ fname_dir, -+ fname_mask); -+ } -+ if (!smb_fname->base_name) { -+ status = NT_STATUS_NO_MEMORY; -+ goto out; -+ } -+ if (dirtype == 0) { -+ dirtype = FILE_ATTRIBUTE_NORMAL; - } - -- if (count == 0 && NT_STATUS_IS_OK(status) && errno != 0) { -- status = map_nt_error_from_unix(errno); -+ status = check_name(conn, smb_fname); -+ if (!NT_STATUS_IS_OK(status)) { -+ goto out; - } - -+ status = do_unlink(conn, req, smb_fname, dirtype); -+ - out: - TALLOC_FREE(smb_fname_dir); - TALLOC_FREE(fname_dir); --- -2.25.1 - - -From 945c9264243c811346d28ce0aeb740bdbe1083dc Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Wed, 1 Dec 2021 13:03:03 -0800 -Subject: [PATCH 32/99] CVE-2021-44141: s3: smbd: Remove 'bool has_wild' - parameter from unlink_internals(). - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison -Reviewed-by: Ralph Boehme ---- - source3/printing/nt_printing.c | 2 +- - source3/smbd/proto.h | 3 +-- - source3/smbd/reply.c | 5 ++--- - source3/smbd/trans2.c | 3 +-- - 4 files changed, 5 insertions(+), 8 deletions(-) - -diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c -index b172ed92c6e..a47afda4a84 100644 ---- a/source3/printing/nt_printing.c -+++ b/source3/printing/nt_printing.c -@@ -2042,7 +2042,7 @@ static NTSTATUS driver_unlink_internals(connection_struct *conn, - goto err_out; - } - -- status = unlink_internals(conn, NULL, 0, smb_fname, false); -+ status = unlink_internals(conn, NULL, 0, smb_fname); - err_out: - talloc_free(tmp_ctx); - return status; -diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h -index bf7401f5191..9454d44968b 100644 ---- a/source3/smbd/proto.h -+++ b/source3/smbd/proto.h -@@ -995,8 +995,7 @@ void reply_ctemp(struct smb_request *req); - NTSTATUS unlink_internals(connection_struct *conn, - struct smb_request *req, - uint32_t dirtype, -- struct smb_filename *smb_fname, -- bool has_wcard); -+ struct smb_filename *smb_fname); - void reply_unlink(struct smb_request *req); - ssize_t fake_sendfile(struct smbXsrv_connection *xconn, files_struct *fsp, - off_t startpos, size_t nread); -diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c -index abdf5f01fd8..e996b809243 100644 ---- a/source3/smbd/reply.c -+++ b/source3/smbd/reply.c -@@ -3278,8 +3278,7 @@ static NTSTATUS do_unlink(connection_struct *conn, - NTSTATUS unlink_internals(connection_struct *conn, - struct smb_request *req, - uint32_t dirtype, -- struct smb_filename *smb_fname, -- bool has_wild) -+ struct smb_filename *smb_fname) - { - char *fname_dir = NULL; - char *fname_mask = NULL; -@@ -3399,7 +3398,7 @@ void reply_unlink(struct smb_request *req) - - DEBUG(3,("reply_unlink : %s\n", smb_fname_str_dbg(smb_fname))); - -- status = unlink_internals(conn, req, dirtype, smb_fname, false); -+ status = unlink_internals(conn, req, dirtype, smb_fname); - if (!NT_STATUS_IS_OK(status)) { - if (open_was_deferred(req->xconn, req->mid)) { - /* We have re-scheduled this call. */ -diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c -index 4f6d92955cf..c455b68725e 100644 ---- a/source3/smbd/trans2.c -+++ b/source3/smbd/trans2.c -@@ -6514,8 +6514,7 @@ NTSTATUS hardlink_internals(TALLOC_CTX *ctx, - status = unlink_internals(conn, - req, - FILE_ATTRIBUTE_NORMAL, -- smb_fname_new, -- false); -+ smb_fname_new); - if (!NT_STATUS_IS_OK(status)) { - goto out; - } --- -2.25.1 - - -From 410126c7fb939c3bebee318376602e5084a93e12 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Wed, 1 Dec 2021 13:56:31 -0800 -Subject: [PATCH 33/99] CVE-2021-44141: s3: smbd: Remove - UCF_ALWAYS_ALLOW_WCARD_LCOMP flag from pathname processing in reply_mv(). - -We are no longer supporting wildcard rename via SMBmv (0x7) -as WindowsXP SMB1 and above do not use it. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison -Reviewed-by: Ralph Boehme ---- - source3/smbd/reply.c | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - -diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c -index e996b809243..0bc3db4c9ca 100644 ---- a/source3/smbd/reply.c -+++ b/source3/smbd/reply.c -@@ -8242,10 +8242,8 @@ void reply_mv(struct smb_request *req) - const char *src_original_lcomp = NULL; - struct smb_filename *smb_fname_dst = NULL; - const char *dst_original_lcomp = NULL; -- uint32_t src_ucf_flags = ucf_flags_from_smb_request(req) | -- (!req->posix_pathnames ? UCF_ALWAYS_ALLOW_WCARD_LCOMP : 0); -- uint32_t dst_ucf_flags = ucf_flags_from_smb_request(req) | -- (!req->posix_pathnames ? UCF_ALWAYS_ALLOW_WCARD_LCOMP : 0); -+ uint32_t src_ucf_flags = ucf_flags_from_smb_request(req); -+ uint32_t dst_ucf_flags = ucf_flags_from_smb_request(req); - bool stream_rename = false; - - START_PROFILE(SMBmv); --- -2.25.1 - - -From 7b0eba7ff03aa79400c4dbac224122209c8e8995 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Wed, 1 Dec 2021 16:07:07 -0800 -Subject: [PATCH 34/99] CVE-2021-44141: s3: smbd: In - smb_file_rename_information() (SMB_FILE_RENAME_INFORMATION info level) - prevent destination wildcards. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison -Reviewed-by: Ralph Boehme ---- - source3/smbd/trans2.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c -index c455b68725e..1eac9b0d2db 100644 ---- a/source3/smbd/trans2.c -+++ b/source3/smbd/trans2.c -@@ -7438,8 +7438,7 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn, - * the newname instead. - */ - char *base_name = NULL; -- uint32_t ucf_flags = UCF_ALWAYS_ALLOW_WCARD_LCOMP| -- ucf_flags_from_smb_request(req); -+ uint32_t ucf_flags = ucf_flags_from_smb_request(req); - - /* newname must *not* be a stream name. */ - if (newname[0] == ':') { --- -2.25.1 - - -From 07b47529426d4623270c2541b840bf71cfca9d59 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Wed, 1 Dec 2021 16:08:13 -0800 -Subject: [PATCH 35/99] CVE-2021-44141: s3: smbd: In SMBntrename (0xa5) prevent - wildcards in destination name. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison -Reviewed-by: Ralph Boehme ---- - source3/smbd/nttrans.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c -index ffff822e221..5e6163f0433 100644 ---- a/source3/smbd/nttrans.c -+++ b/source3/smbd/nttrans.c -@@ -1771,6 +1771,11 @@ void reply_ntrename(struct smb_request *req) - goto out; - } - -+ if (!req->posix_pathnames && ms_has_wild(newname)) { -+ reply_nterror(req, NT_STATUS_OBJECT_PATH_SYNTAX_BAD); -+ goto out; -+ } -+ - if (!req->posix_pathnames) { - /* The newname must begin with a ':' if the - oldname contains a ':'. */ --- -2.25.1 - - -From 9d0c2fd42fc77de7a9748ef2ecd7d284b5105e37 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Wed, 1 Dec 2021 16:12:46 -0800 -Subject: [PATCH 36/99] CVE-2021-44141: s3: smbd: In reply_ntrename() remove - the UCF_ALWAYS_ALLOW_WCARD_LCOMP flag for destination lookups. - -We know the destination will never be a wildcard. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison -Reviewed-by: Ralph Boehme ---- - source3/smbd/nttrans.c | 8 -------- - 1 file changed, 8 deletions(-) - -diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c -index 5e6163f0433..e25a59a7cb9 100644 ---- a/source3/smbd/nttrans.c -+++ b/source3/smbd/nttrans.c -@@ -1788,14 +1788,6 @@ void reply_ntrename(struct smb_request *req) - } - } - -- /* -- * If this is a rename operation, allow wildcards and save the -- * destination's last component. -- */ -- if (rename_type == RENAME_FLAG_RENAME) { -- ucf_flags_dst |= UCF_ALWAYS_ALLOW_WCARD_LCOMP; -- } -- - /* rename_internals() calls unix_convert(), so don't call it here. */ - status = filename_convert(ctx, conn, - oldname, --- -2.25.1 - - -From c7678425514417b524800e65098bc8608849c457 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Wed, 1 Dec 2021 16:14:57 -0800 -Subject: [PATCH 37/99] CVE-2021-44141: s3: smbd: In reply_ntrename(), never - set dest_has_wcard. - -It can never be true. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison -Reviewed-by: Ralph Boehme ---- - source3/smbd/nttrans.c | 4 ---- - 1 file changed, 4 deletions(-) - -diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c -index e25a59a7cb9..f5cb82024c8 100644 ---- a/source3/smbd/nttrans.c -+++ b/source3/smbd/nttrans.c -@@ -1816,10 +1816,6 @@ void reply_ntrename(struct smb_request *req) - goto out; - } - -- if (!req->posix_pathnames) { -- dest_has_wcard = ms_has_wild(dst_original_lcomp); -- } -- - status = filename_convert(ctx, conn, - newname, - ucf_flags_dst, --- -2.25.1 - - -From 992864a49f099052c452eb5e1da733f39294d94a Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Wed, 1 Dec 2021 16:17:51 -0800 -Subject: [PATCH 38/99] CVE-2021-44141: s3: smbd: In reply_ntrename() remove - 'bool dest_has_wcard' and all uses. - -It's always false now. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison -Reviewed-by: Ralph Boehme ---- - source3/smbd/nttrans.c | 32 ++++++++++++-------------------- - 1 file changed, 12 insertions(+), 20 deletions(-) - -diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c -index f5cb82024c8..b0f55ade267 100644 ---- a/source3/smbd/nttrans.c -+++ b/source3/smbd/nttrans.c -@@ -1732,7 +1732,6 @@ void reply_ntrename(struct smb_request *req) - const char *dst_original_lcomp = NULL; - const char *p; - NTSTATUS status; -- bool dest_has_wcard = False; - uint32_t attrs; - uint32_t ucf_flags_src = ucf_flags_from_smb_request(req); - uint32_t ucf_flags_dst = ucf_flags_from_smb_request(req); -@@ -1862,27 +1861,20 @@ void reply_ntrename(struct smb_request *req) - DELETE_ACCESS); - break; - case RENAME_FLAG_HARD_LINK: -- if (dest_has_wcard) { -- /* No wildcards. */ -- status = NT_STATUS_OBJECT_PATH_SYNTAX_BAD; -- } else { -- status = hardlink_internals(ctx, conn, -- req, -- false, -- smb_fname_old, -- smb_fname_new); -- } -+ status = hardlink_internals(ctx, -+ conn, -+ req, -+ false, -+ smb_fname_old, -+ smb_fname_new); - break; - case RENAME_FLAG_COPY: -- if (dest_has_wcard) { -- /* No wildcards. */ -- status = NT_STATUS_OBJECT_PATH_SYNTAX_BAD; -- } else { -- status = copy_internals(ctx, conn, req, -- smb_fname_old, -- smb_fname_new, -- attrs); -- } -+ status = copy_internals(ctx, -+ conn, -+ req, -+ smb_fname_old, -+ smb_fname_new, -+ attrs); - break; - case RENAME_FLAG_MOVE_CLUSTER_INFORMATION: - status = NT_STATUS_INVALID_PARAMETER; --- -2.25.1 - - -From 848b891d978d928dc3199f7f1e146bfc0b7ab988 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Wed, 1 Dec 2021 16:25:03 -0800 -Subject: [PATCH 39/99] CVE-2021-44141: s3: smbd: Prepare to remove wildcard - matching from rename_internals(). - -src_has_wild and dest_has_wild can never be true. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison -Reviewed-by: Ralph Boehme ---- - source3/smbd/reply.c | 14 -------------- - 1 file changed, 14 deletions(-) - -diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c -index 0bc3db4c9ca..3eaadb33861 100644 ---- a/source3/smbd/reply.c -+++ b/source3/smbd/reply.c -@@ -7860,20 +7860,6 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx, - goto out; - } - -- if (!(smb_fname_src->flags & SMB_FILENAME_POSIX_PATH)) { -- /* -- * Check the wildcard mask *before* -- * unmangling. As mangling is done -- * for names that can't be returned -- * to Windows the unmangled name may -- * contain Windows wildcard characters. -- */ -- if (src_original_lcomp != NULL) { -- src_has_wild = ms_has_wild(src_original_lcomp); -- } -- dest_has_wild = ms_has_wild(dst_original_lcomp); -- } -- - /* - * We should only check the mangled cache - * here if unix_convert failed. This means --- -2.25.1 - - -From ece00d51a7b28ec96c0a173ca40feb61aaf5dbe3 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Wed, 1 Dec 2021 16:26:28 -0800 -Subject: [PATCH 40/99] CVE-2021-44141: s3: smbd: Remove dest_has_wild and all - associated code from rename_internals() - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison -Reviewed-by: Ralph Boehme ---- - source3/smbd/reply.c | 19 ------------------- - 1 file changed, 19 deletions(-) - -diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c -index 3eaadb33861..21f40cf123e 100644 ---- a/source3/smbd/reply.c -+++ b/source3/smbd/reply.c -@@ -7841,7 +7841,6 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx, - struct smb2_create_blobs *posx = NULL; - int rc; - bool src_has_wild = false; -- bool dest_has_wild = false; - - /* - * Split the old name into directory and last component -@@ -7923,24 +7922,6 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx, - smb_fname_str_dbg(smb_fname_dst), - dst_original_lcomp)); - -- /* The dest name still may have wildcards. */ -- if (dest_has_wild) { -- char *fname_dst_mod = NULL; -- if (!resolve_wildcards(smb_fname_dst, -- smb_fname_src->base_name, -- smb_fname_dst->base_name, -- &fname_dst_mod)) { -- DEBUG(6, ("rename_internals: resolve_wildcards " -- "%s %s failed\n", -- smb_fname_src->base_name, -- smb_fname_dst->base_name)); -- status = NT_STATUS_NO_MEMORY; -- goto out; -- } -- TALLOC_FREE(smb_fname_dst->base_name); -- smb_fname_dst->base_name = fname_dst_mod; -- } -- - ZERO_STRUCT(smb_fname_src->st); - - rc = vfs_stat(conn, smb_fname_src); --- -2.25.1 - - -From cafca2b7a0eca282d24d8f3571bc14ef725f30e4 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Wed, 1 Dec 2021 16:29:43 -0800 -Subject: [PATCH 41/99] CVE-2021-44141: s3: smbd: Remove all wildcard code from - rename_internals(). - -We no longer use resolve_wildcards() so comment it out -for later removal. Keep the '{ ... }' block around the -singleton rename for now, to keep the diff small. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison -Reviewed-by: Ralph Boehme ---- - source3/smbd/reply.c | 201 +------------------------------------------ - 1 file changed, 4 insertions(+), 197 deletions(-) - -diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c -index 21f40cf123e..a0e61546323 100644 ---- a/source3/smbd/reply.c -+++ b/source3/smbd/reply.c -@@ -7059,6 +7059,7 @@ void reply_rmdir(struct smb_request *req) - return; - } - -+#if 0 - /******************************************************************* - Resolve wildcards in a filename rename. - ********************************************************************/ -@@ -7185,6 +7186,7 @@ static bool resolve_wildcards(TALLOC_CTX *ctx, - - return True; - } -+#endif - - /**************************************************************************** - Ensure open files have their names updated. Updated to notify other smbd's -@@ -7831,24 +7833,18 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx, - char *fname_src_dir = NULL; - struct smb_filename *smb_fname_src_dir = NULL; - char *fname_src_mask = NULL; -- int count=0; - NTSTATUS status = NT_STATUS_OK; -- struct smb_Dir *dir_hnd = NULL; -- const char *dname = NULL; - char *talloced = NULL; -- long offset = 0; - int create_options = 0; - struct smb2_create_blobs *posx = NULL; - int rc; -- bool src_has_wild = false; - - /* - * Split the old name into directory and last component - * strings. Note that unix_convert may have stripped off a - * leading ./ from both name and newname if the rename is - * at the root of the share. We need to make sure either both -- * name and newname contain a / character or neither of them do -- * as this is checked in resolve_wildcards(). -+ * name and newname contain a / character or neither of them do. - */ - - /* Split up the directory from the filename/mask. */ -@@ -7888,7 +7884,7 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx, - } - } - -- if (!src_has_wild) { -+ { - files_struct *fsp; - - /* -@@ -7992,195 +7988,6 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx, - nt_errstr(status), smb_fname_str_dbg(smb_fname_src), - smb_fname_str_dbg(smb_fname_dst))); - -- goto out; -- } -- -- /* -- * Wildcards - process each file that matches. -- */ -- if (strequal(fname_src_mask, "????????.???")) { -- TALLOC_FREE(fname_src_mask); -- fname_src_mask = talloc_strdup(ctx, "*"); -- if (!fname_src_mask) { -- status = NT_STATUS_NO_MEMORY; -- goto out; -- } -- } -- -- smb_fname_src_dir = synthetic_smb_fname(talloc_tos(), -- fname_src_dir, -- NULL, -- NULL, -- smb_fname_src->twrp, -- smb_fname_src->flags); -- if (smb_fname_src_dir == NULL) { -- status = NT_STATUS_NO_MEMORY; -- goto out; -- } -- -- status = check_name(conn, smb_fname_src_dir); -- if (!NT_STATUS_IS_OK(status)) { -- goto out; -- } -- -- dir_hnd = OpenDir(talloc_tos(), conn, smb_fname_src_dir, fname_src_mask, -- attrs); -- if (dir_hnd == NULL) { -- status = map_nt_error_from_unix(errno); -- goto out; -- } -- -- status = NT_STATUS_NO_SUCH_FILE; -- /* -- * Was status = NT_STATUS_OBJECT_NAME_NOT_FOUND; -- * - gentest fix. JRA -- */ -- -- while ((dname = ReadDirName(dir_hnd, &offset, &smb_fname_src->st, -- &talloced))) { -- files_struct *fsp = NULL; -- char *destname = NULL; -- bool sysdir_entry = False; -- -- /* Quick check for "." and ".." */ -- if (ISDOT(dname) || ISDOTDOT(dname)) { -- if (attrs & FILE_ATTRIBUTE_DIRECTORY) { -- sysdir_entry = True; -- } else { -- TALLOC_FREE(talloced); -- continue; -- } -- } -- -- if(!mask_match(dname, fname_src_mask, conn->case_sensitive)) { -- TALLOC_FREE(talloced); -- continue; -- } -- -- if (sysdir_entry) { -- status = NT_STATUS_OBJECT_NAME_INVALID; -- break; -- } -- -- TALLOC_FREE(smb_fname_src->base_name); -- if (ISDOT(fname_src_dir)) { -- /* Ensure we use canonical names on open. */ -- smb_fname_src->base_name = talloc_asprintf(smb_fname_src, -- "%s", -- dname); -- } else { -- smb_fname_src->base_name = talloc_asprintf(smb_fname_src, -- "%s/%s", -- fname_src_dir, -- dname); -- } -- if (!smb_fname_src->base_name) { -- status = NT_STATUS_NO_MEMORY; -- goto out; -- } -- -- if (!resolve_wildcards(ctx, smb_fname_src->base_name, -- smb_fname_dst->base_name, -- &destname)) { -- DEBUG(6, ("resolve_wildcards %s %s failed\n", -- smb_fname_src->base_name, destname)); -- TALLOC_FREE(talloced); -- continue; -- } -- if (!destname) { -- status = NT_STATUS_NO_MEMORY; -- goto out; -- } -- -- TALLOC_FREE(smb_fname_dst->base_name); -- smb_fname_dst->base_name = destname; -- -- ZERO_STRUCT(smb_fname_src->st); -- vfs_stat(conn, smb_fname_src); -- -- status = openat_pathref_fsp(conn->cwd_fsp, smb_fname_src); -- if (!NT_STATUS_IS_OK(status)) { -- DBG_INFO("openat_pathref_fsp [%s] failed: %s\n", -- smb_fname_str_dbg(smb_fname_src), -- nt_errstr(status)); -- break; -- } -- -- if (!is_visible_fsp(smb_fname_src->fsp)) { -- TALLOC_FREE(talloced); -- continue; -- } -- -- create_options = 0; -- -- if (S_ISDIR(smb_fname_src->st.st_ex_mode)) { -- create_options |= FILE_DIRECTORY_FILE; -- } -- -- status = SMB_VFS_CREATE_FILE( -- conn, /* conn */ -- req, /* req */ -- smb_fname_src, /* fname */ -- access_mask, /* access_mask */ -- (FILE_SHARE_READ | /* share_access */ -- FILE_SHARE_WRITE), -- FILE_OPEN, /* create_disposition*/ -- create_options, /* create_options */ -- 0, /* file_attributes */ -- 0, /* oplock_request */ -- NULL, /* lease */ -- 0, /* allocation_size */ -- 0, /* private_flags */ -- NULL, /* sd */ -- NULL, /* ea_list */ -- &fsp, /* result */ -- NULL, /* pinfo */ -- posx, /* in_context_blobs */ -- NULL); /* out_context_blobs */ -- -- if (!NT_STATUS_IS_OK(status)) { -- DEBUG(3,("rename_internals: SMB_VFS_CREATE_FILE " -- "returned %s rename %s -> %s\n", -- nt_errstr(status), -- smb_fname_str_dbg(smb_fname_src), -- smb_fname_str_dbg(smb_fname_dst))); -- break; -- } -- -- dst_original_lcomp = talloc_strdup(smb_fname_dst, dname); -- if (dst_original_lcomp == NULL) { -- status = NT_STATUS_NO_MEMORY; -- goto out; -- } -- -- status = rename_internals_fsp(conn, -- fsp, -- smb_fname_dst, -- dst_original_lcomp, -- attrs, -- replace_if_exists); -- -- close_file(req, fsp, NORMAL_CLOSE); -- -- if (!NT_STATUS_IS_OK(status)) { -- DEBUG(3, ("rename_internals_fsp returned %s for " -- "rename %s -> %s\n", nt_errstr(status), -- smb_fname_str_dbg(smb_fname_src), -- smb_fname_str_dbg(smb_fname_dst))); -- break; -- } -- -- count++; -- -- DEBUG(3,("rename_internals: doing rename on %s -> " -- "%s\n", smb_fname_str_dbg(smb_fname_src), -- smb_fname_str_dbg(smb_fname_src))); -- TALLOC_FREE(talloced); -- } -- TALLOC_FREE(dir_hnd); -- -- if (count == 0 && NT_STATUS_IS_OK(status) && errno != 0) { -- status = map_nt_error_from_unix(errno); - } - - out: --- -2.25.1 - - -From be70e606c61cd2da8f27718f5a227728494793e3 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Wed, 1 Dec 2021 16:31:36 -0800 -Subject: [PATCH 42/99] CVE-2021-44141: s3: smbd: Remove the commented out - resolve_wildcards(). - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison -Reviewed-by: Ralph Boehme ---- - source3/smbd/reply.c | 129 ------------------------------------------- - 1 file changed, 129 deletions(-) - -diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c -index a0e61546323..aec0892c81a 100644 ---- a/source3/smbd/reply.c -+++ b/source3/smbd/reply.c -@@ -7059,135 +7059,6 @@ void reply_rmdir(struct smb_request *req) - return; - } - --#if 0 --/******************************************************************* -- Resolve wildcards in a filename rename. --********************************************************************/ -- --static bool resolve_wildcards(TALLOC_CTX *ctx, -- const char *name1, -- const char *name2, -- char **pp_newname) --{ -- char *name2_copy = NULL; -- char *root1 = NULL; -- char *root2 = NULL; -- char *ext1 = NULL; -- char *ext2 = NULL; -- char *p,*p2, *pname1, *pname2; -- -- name2_copy = talloc_strdup(ctx, name2); -- if (!name2_copy) { -- return False; -- } -- -- pname1 = strrchr_m(name1,'/'); -- pname2 = strrchr_m(name2_copy,'/'); -- -- if (!pname1 || !pname2) { -- return False; -- } -- -- /* Truncate the copy of name2 at the last '/' */ -- *pname2 = '\0'; -- -- /* Now go past the '/' */ -- pname1++; -- pname2++; -- -- root1 = talloc_strdup(ctx, pname1); -- root2 = talloc_strdup(ctx, pname2); -- -- if (!root1 || !root2) { -- return False; -- } -- -- p = strrchr_m(root1,'.'); -- if (p) { -- *p = 0; -- ext1 = talloc_strdup(ctx, p+1); -- } else { -- ext1 = talloc_strdup(ctx, ""); -- } -- p = strrchr_m(root2,'.'); -- if (p) { -- *p = 0; -- ext2 = talloc_strdup(ctx, p+1); -- } else { -- ext2 = talloc_strdup(ctx, ""); -- } -- -- if (!ext1 || !ext2) { -- return False; -- } -- -- p = root1; -- p2 = root2; -- while (*p2) { -- if (*p2 == '?') { -- /* Hmmm. Should this be mb-aware ? */ -- *p2 = *p; -- p2++; -- } else if (*p2 == '*') { -- *p2 = '\0'; -- root2 = talloc_asprintf(ctx, "%s%s", -- root2, -- p); -- if (!root2) { -- return False; -- } -- break; -- } else { -- p2++; -- } -- if (*p) { -- p++; -- } -- } -- -- p = ext1; -- p2 = ext2; -- while (*p2) { -- if (*p2 == '?') { -- /* Hmmm. Should this be mb-aware ? */ -- *p2 = *p; -- p2++; -- } else if (*p2 == '*') { -- *p2 = '\0'; -- ext2 = talloc_asprintf(ctx, "%s%s", -- ext2, -- p); -- if (!ext2) { -- return False; -- } -- break; -- } else { -- p2++; -- } -- if (*p) { -- p++; -- } -- } -- -- if (*ext2) { -- *pp_newname = talloc_asprintf(ctx, "%s/%s.%s", -- name2_copy, -- root2, -- ext2); -- } else { -- *pp_newname = talloc_asprintf(ctx, "%s/%s", -- name2_copy, -- root2); -- } -- -- if (!*pp_newname) { -- return False; -- } -- -- return True; --} --#endif -- - /**************************************************************************** - Ensure open files have their names updated. Updated to notify other smbd's - asynchronously. --- -2.25.1 - - -From cf2de328ea36011d9f4594bac84fce0b8db0889e Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Wed, 1 Dec 2021 16:35:54 -0800 -Subject: [PATCH 43/99] CVE-2021-44141: s3: smbd: Inside rename_internals() - remove '{ ... }' block around singleton rename code. - -Best viewed with 'git show -b' - -As we're touching the DEBUG() code, change it to modern DBG_NOTICE(). - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison -Reviewed-by: Ralph Boehme ---- - source3/smbd/reply.c | 132 +++++++++++++++++++++---------------------- - 1 file changed, 64 insertions(+), 68 deletions(-) - -diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c -index aec0892c81a..e9814037b1e 100644 ---- a/source3/smbd/reply.c -+++ b/source3/smbd/reply.c -@@ -7708,6 +7708,7 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx, - char *talloced = NULL; - int create_options = 0; - struct smb2_create_blobs *posx = NULL; -+ struct files_struct *fsp = NULL; - int rc; - - /* -@@ -7755,70 +7756,67 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx, - } - } - -- { -- files_struct *fsp; -+ /* -+ * Only one file needs to be renamed. Append the mask back -+ * onto the directory. -+ */ -+ TALLOC_FREE(smb_fname_src->base_name); -+ if (ISDOT(fname_src_dir)) { -+ /* Ensure we use canonical names on open. */ -+ smb_fname_src->base_name = talloc_asprintf(smb_fname_src, -+ "%s", -+ fname_src_mask); -+ } else { -+ smb_fname_src->base_name = talloc_asprintf(smb_fname_src, -+ "%s/%s", -+ fname_src_dir, -+ fname_src_mask); -+ } -+ if (!smb_fname_src->base_name) { -+ status = NT_STATUS_NO_MEMORY; -+ goto out; -+ } - -- /* -- * Only one file needs to be renamed. Append the mask back -- * onto the directory. -- */ -- TALLOC_FREE(smb_fname_src->base_name); -- if (ISDOT(fname_src_dir)) { -- /* Ensure we use canonical names on open. */ -- smb_fname_src->base_name = talloc_asprintf(smb_fname_src, -- "%s", -- fname_src_mask); -- } else { -- smb_fname_src->base_name = talloc_asprintf(smb_fname_src, -- "%s/%s", -- fname_src_dir, -- fname_src_mask); -- } -- if (!smb_fname_src->base_name) { -- status = NT_STATUS_NO_MEMORY; -- goto out; -- } -+ DBG_NOTICE("case_sensitive = %d, " -+ "case_preserve = %d, short case preserve = %d, " -+ "directory = %s, newname = %s, " -+ "last_component_dest = %s\n", -+ conn->case_sensitive, conn->case_preserve, -+ conn->short_case_preserve, -+ smb_fname_str_dbg(smb_fname_src), -+ smb_fname_str_dbg(smb_fname_dst), -+ dst_original_lcomp); - -- DEBUG(3, ("rename_internals: case_sensitive = %d, " -- "case_preserve = %d, short case preserve = %d, " -- "directory = %s, newname = %s, " -- "last_component_dest = %s\n", -- conn->case_sensitive, conn->case_preserve, -- conn->short_case_preserve, -- smb_fname_str_dbg(smb_fname_src), -- smb_fname_str_dbg(smb_fname_dst), -- dst_original_lcomp)); -+ ZERO_STRUCT(smb_fname_src->st); - -- ZERO_STRUCT(smb_fname_src->st); -+ rc = vfs_stat(conn, smb_fname_src); -+ if (rc == -1) { -+ status = map_nt_error_from_unix_common(errno); -+ goto out; -+ } - -- rc = vfs_stat(conn, smb_fname_src); -- if (rc == -1) { -- status = map_nt_error_from_unix_common(errno); -+ status = openat_pathref_fsp(conn->cwd_fsp, smb_fname_src); -+ if (!NT_STATUS_IS_OK(status)) { -+ if (!NT_STATUS_EQUAL(status, -+ NT_STATUS_OBJECT_NAME_NOT_FOUND)) { - goto out; - } -- -- status = openat_pathref_fsp(conn->cwd_fsp, smb_fname_src); -- if (!NT_STATUS_IS_OK(status)) { -- if (!NT_STATUS_EQUAL(status, -- NT_STATUS_OBJECT_NAME_NOT_FOUND)) { -- goto out; -- } -- /* -- * Possible symlink src. -- */ -- if (!(smb_fname_src->flags & SMB_FILENAME_POSIX_PATH)) { -- goto out; -- } -- if (!S_ISLNK(smb_fname_src->st.st_ex_mode)) { -- goto out; -- } -+ /* -+ * Possible symlink src. -+ */ -+ if (!(smb_fname_src->flags & SMB_FILENAME_POSIX_PATH)) { -+ goto out; - } -- -- if (S_ISDIR(smb_fname_src->st.st_ex_mode)) { -- create_options |= FILE_DIRECTORY_FILE; -+ if (!S_ISLNK(smb_fname_src->st.st_ex_mode)) { -+ goto out; - } -+ } - -- status = SMB_VFS_CREATE_FILE( -+ if (S_ISDIR(smb_fname_src->st.st_ex_mode)) { -+ create_options |= FILE_DIRECTORY_FILE; -+ } -+ -+ status = SMB_VFS_CREATE_FILE( - conn, /* conn */ - req, /* req */ - smb_fname_src, /* fname */ -@@ -7839,27 +7837,25 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx, - posx, /* in_context_blobs */ - NULL); /* out_context_blobs */ - -- if (!NT_STATUS_IS_OK(status)) { -- DEBUG(3, ("Could not open rename source %s: %s\n", -- smb_fname_str_dbg(smb_fname_src), -- nt_errstr(status))); -- goto out; -- } -+ if (!NT_STATUS_IS_OK(status)) { -+ DBG_NOTICE("Could not open rename source %s: %s\n", -+ smb_fname_str_dbg(smb_fname_src), -+ nt_errstr(status)); -+ goto out; -+ } - -- status = rename_internals_fsp(conn, -+ status = rename_internals_fsp(conn, - fsp, - smb_fname_dst, - dst_original_lcomp, - attrs, - replace_if_exists); - -- close_file(req, fsp, NORMAL_CLOSE); -+ close_file(req, fsp, NORMAL_CLOSE); - -- DEBUG(3, ("rename_internals: Error %s rename %s -> %s\n", -- nt_errstr(status), smb_fname_str_dbg(smb_fname_src), -- smb_fname_str_dbg(smb_fname_dst))); -- -- } -+ DBG_NOTICE("Error %s rename %s -> %s\n", -+ nt_errstr(status), smb_fname_str_dbg(smb_fname_src), -+ smb_fname_str_dbg(smb_fname_dst)); - - out: - TALLOC_FREE(posx); --- -2.25.1 - - -From fc80b553dc6c6a17fa496e1347174ffb802c3ffb Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Wed, 1 Dec 2021 16:39:42 -0800 -Subject: [PATCH 44/99] CVE-2021-44141: s3: smbd: Remove 'const char - *src_original_lcomp' parameter from rename_internals(). - -No longer used. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison -Reviewed-by: Ralph Boehme ---- - source3/smbd/nttrans.c | 1 - - source3/smbd/proto.h | 1 - - source3/smbd/reply.c | 2 -- - source3/smbd/trans2.c | 1 - - 4 files changed, 5 deletions(-) - -diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c -index b0f55ade267..2b742411071 100644 ---- a/source3/smbd/nttrans.c -+++ b/source3/smbd/nttrans.c -@@ -1853,7 +1853,6 @@ void reply_ntrename(struct smb_request *req) - conn, - req, - smb_fname_old, -- NULL, - smb_fname_new, - dst_original_lcomp, - attrs, -diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h -index 9454d44968b..fa26d58bfde 100644 ---- a/source3/smbd/proto.h -+++ b/source3/smbd/proto.h -@@ -1041,7 +1041,6 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx, - connection_struct *conn, - struct smb_request *req, - struct smb_filename *smb_fname_src, -- const char *src_original_lcomp, - struct smb_filename *smb_fname_dst, - const char *dst_original_lcomp, - uint32_t attrs, -diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c -index e9814037b1e..8fc943375b4 100644 ---- a/source3/smbd/reply.c -+++ b/source3/smbd/reply.c -@@ -7694,7 +7694,6 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx, - connection_struct *conn, - struct smb_request *req, - struct smb_filename *smb_fname_src, -- const char *src_original_lcomp, - struct smb_filename *smb_fname_dst, - const char *dst_original_lcomp, - uint32_t attrs, -@@ -7996,7 +7995,6 @@ void reply_mv(struct smb_request *req) - conn, - req, - smb_fname_src, -- src_original_lcomp, - smb_fname_dst, - dst_original_lcomp, - attrs, -diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c -index 1eac9b0d2db..2b2643b6325 100644 ---- a/source3/smbd/trans2.c -+++ b/source3/smbd/trans2.c -@@ -7527,7 +7527,6 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn, - conn, - req, - smb_fname_src, -- NULL, - smb_fname_dst, - dst_original_lcomp, - 0, --- -2.25.1 - - -From 8c1a9ccb546e7677dc05e98bd6aa77681e0d7510 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Wed, 1 Dec 2021 16:40:55 -0800 -Subject: [PATCH 45/99] CVE-2021-44141: s3: smbd: Remove 'const char - *src_original_lcomp' from reply_mv(). - -No longer used. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison -Reviewed-by: Ralph Boehme ---- - source3/smbd/reply.c | 11 ----------- - 1 file changed, 11 deletions(-) - -diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c -index 8fc943375b4..079c8da7e3c 100644 ---- a/source3/smbd/reply.c -+++ b/source3/smbd/reply.c -@@ -7879,7 +7879,6 @@ void reply_mv(struct smb_request *req) - NTSTATUS status; - TALLOC_CTX *ctx = talloc_tos(); - struct smb_filename *smb_fname_src = NULL; -- const char *src_original_lcomp = NULL; - struct smb_filename *smb_fname_dst = NULL; - const char *dst_original_lcomp = NULL; - uint32_t src_ucf_flags = ucf_flags_from_smb_request(req); -@@ -7939,16 +7938,6 @@ void reply_mv(struct smb_request *req) - goto out; - } - -- /* Get the last component of the source for rename_internals(). */ -- src_original_lcomp = get_original_lcomp(ctx, -- conn, -- name, -- dst_ucf_flags); -- if (src_original_lcomp == NULL) { -- reply_nterror(req, NT_STATUS_NO_MEMORY); -- goto out; -- } -- - status = filename_convert(ctx, - conn, - newname, --- -2.25.1 - - -From 9907c8af089a6263349566f002747d84edf926d3 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Thu, 9 Dec 2021 16:08:07 -0800 -Subject: [PATCH 46/99] CVE-2021-44141: s3: smbd: Move setting of dirtype if - FILE_ATTRIBUTE_NORMAL to do_unlink(). - -Now we don't use wildcards when calling in unlink_internals() -the logic inside it serves no purpose and can be replaced with -a direct call to do_unlink() (which we will rename to unlink_internals()). - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - source3/smbd/reply.c | 7 ++++--- - 1 file changed, 4 insertions(+), 3 deletions(-) - -diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c -index 079c8da7e3c..b709dc65c47 100644 ---- a/source3/smbd/reply.c -+++ b/source3/smbd/reply.c -@@ -3142,6 +3142,10 @@ static NTSTATUS do_unlink(connection_struct *conn, - int ret; - struct smb2_create_blobs *posx = NULL; - -+ if (dirtype == 0) { -+ dirtype = FILE_ATTRIBUTE_NORMAL; -+ } -+ - DEBUG(10,("do_unlink: %s, dirtype = %d\n", - smb_fname_str_dbg(smb_fname), - dirtype)); -@@ -3333,9 +3337,6 @@ NTSTATUS unlink_internals(connection_struct *conn, - status = NT_STATUS_NO_MEMORY; - goto out; - } -- if (dirtype == 0) { -- dirtype = FILE_ATTRIBUTE_NORMAL; -- } - - status = check_name(conn, smb_fname); - if (!NT_STATUS_IS_OK(status)) { --- -2.25.1 - - -From 9fb1d11b2edafe0b2e8fb8cfbe34e1da046b3d97 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Thu, 9 Dec 2021 16:11:20 -0800 -Subject: [PATCH 47/99] CVE-2021-44141: s3: smbd: Move to modern debug calls - inside do_unlink(). - -We will be changing its name next. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - source3/smbd/reply.c | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - -diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c -index b709dc65c47..71d7454e58f 100644 ---- a/source3/smbd/reply.c -+++ b/source3/smbd/reply.c -@@ -3146,9 +3146,9 @@ static NTSTATUS do_unlink(connection_struct *conn, - dirtype = FILE_ATTRIBUTE_NORMAL; - } - -- DEBUG(10,("do_unlink: %s, dirtype = %d\n", -+ DBG_DEBUG("%s, dirtype = %d\n", - smb_fname_str_dbg(smb_fname), -- dirtype)); -+ dirtype); - - if (!CAN_WRITE(conn)) { - return NT_STATUS_MEDIA_WRITE_PROTECTED; -@@ -3248,17 +3248,17 @@ static NTSTATUS do_unlink(connection_struct *conn, - TALLOC_FREE(posx); - - if (!NT_STATUS_IS_OK(status)) { -- DEBUG(10, ("SMB_VFS_CREATEFILE failed: %s\n", -- nt_errstr(status))); -+ DBG_DEBUG("SMB_VFS_CREATEFILE failed: %s\n", -+ nt_errstr(status)); - return status; - } - - status = can_set_delete_on_close(fsp, fattr); - if (!NT_STATUS_IS_OK(status)) { -- DEBUG(10, ("do_unlink can_set_delete_on_close for file %s - " -+ DBG_DEBUG("can_set_delete_on_close for file %s - " - "(%s)\n", - smb_fname_str_dbg(smb_fname), -- nt_errstr(status))); -+ nt_errstr(status)); - close_file(req, fsp, NORMAL_CLOSE); - return status; - } --- -2.25.1 - - -From a88596028eac6facd644afa7eb5bf9ed34915c30 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Thu, 9 Dec 2021 16:14:40 -0800 -Subject: [PATCH 48/99] CVE-2021-44141: s3: smbd: Comment out the old - unlink_internals(). Rename do_unlink() -> unlink_internals(). - -One parameter needs changing position. The logic inside unlink_internals() -is no longer needed if it doesn't accept wildcards. filename_convert() -already handles mangled names just fine, so we don't need this logic. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - source3/smbd/reply.c | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - -diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c -index 71d7454e58f..01de8f0c03f 100644 ---- a/source3/smbd/reply.c -+++ b/source3/smbd/reply.c -@@ -3130,10 +3130,10 @@ static NTSTATUS can_rename(connection_struct *conn, files_struct *fsp, - * unlink a file with all relevant access checks - *******************************************************************/ - --static NTSTATUS do_unlink(connection_struct *conn, -+NTSTATUS unlink_internals(connection_struct *conn, - struct smb_request *req, -- struct smb_filename *smb_fname, -- uint32_t dirtype) -+ uint32_t dirtype, -+ struct smb_filename *smb_fname) - { - uint32_t fattr; - files_struct *fsp; -@@ -3274,6 +3274,7 @@ static NTSTATUS do_unlink(connection_struct *conn, - return close_file(req, fsp, NORMAL_CLOSE); - } - -+#if 0 - /**************************************************************************** - The guts of the unlink command, split out so it may be called by the NT SMB - code. -@@ -3351,6 +3352,7 @@ NTSTATUS unlink_internals(connection_struct *conn, - TALLOC_FREE(fname_mask); - return status; - } -+#endif - - /**************************************************************************** - Reply to a unlink --- -2.25.1 - - -From fad0039acabd43eaf6853af60e5d245a2691a664 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Thu, 9 Dec 2021 16:16:52 -0800 -Subject: [PATCH 49/99] CVE-2021-44141: s3: smbd: Remove the old - unlink_internals() implementation. - -No longer used. filename_convert() already handles mangled -names just fine, so we don't need this logic. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - source3/smbd/reply.c | 80 -------------------------------------------- - 1 file changed, 80 deletions(-) - -diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c -index 01de8f0c03f..26049b2b62b 100644 ---- a/source3/smbd/reply.c -+++ b/source3/smbd/reply.c -@@ -3274,86 +3274,6 @@ NTSTATUS unlink_internals(connection_struct *conn, - return close_file(req, fsp, NORMAL_CLOSE); - } - --#if 0 --/**************************************************************************** -- The guts of the unlink command, split out so it may be called by the NT SMB -- code. --****************************************************************************/ -- --NTSTATUS unlink_internals(connection_struct *conn, -- struct smb_request *req, -- uint32_t dirtype, -- struct smb_filename *smb_fname) --{ -- char *fname_dir = NULL; -- char *fname_mask = NULL; -- NTSTATUS status = NT_STATUS_OK; -- struct smb_filename *smb_fname_dir = NULL; -- TALLOC_CTX *ctx = talloc_tos(); -- -- /* Split up the directory from the filename/mask. */ -- status = split_fname_dir_mask(ctx, smb_fname->base_name, -- &fname_dir, &fname_mask); -- if (!NT_STATUS_IS_OK(status)) { -- goto out; -- } -- -- /* -- * We should only check the mangled cache -- * here if unix_convert failed. This means -- * that the path in 'mask' doesn't exist -- * on the file system and so we need to look -- * for a possible mangle. This patch from -- * Tine Smukavec . -- */ -- -- if (!VALID_STAT(smb_fname->st) && -- mangle_is_mangled(fname_mask, conn->params)) { -- char *new_mask = NULL; -- mangle_lookup_name_from_8_3(ctx, fname_mask, -- &new_mask, conn->params); -- if (new_mask) { -- TALLOC_FREE(fname_mask); -- fname_mask = new_mask; -- } -- } -- -- /* -- * Only one file needs to be unlinked. Append the mask back -- * onto the directory. -- */ -- TALLOC_FREE(smb_fname->base_name); -- if (ISDOT(fname_dir)) { -- /* Ensure we use canonical names on open. */ -- smb_fname->base_name = talloc_asprintf(smb_fname, -- "%s", -- fname_mask); -- } else { -- smb_fname->base_name = talloc_asprintf(smb_fname, -- "%s/%s", -- fname_dir, -- fname_mask); -- } -- if (!smb_fname->base_name) { -- status = NT_STATUS_NO_MEMORY; -- goto out; -- } -- -- status = check_name(conn, smb_fname); -- if (!NT_STATUS_IS_OK(status)) { -- goto out; -- } -- -- status = do_unlink(conn, req, smb_fname, dirtype); -- -- out: -- TALLOC_FREE(smb_fname_dir); -- TALLOC_FREE(fname_dir); -- TALLOC_FREE(fname_mask); -- return status; --} --#endif -- - /**************************************************************************** - Reply to a unlink - ****************************************************************************/ --- -2.25.1 - - -From 26ecf18b426eb3f2db9d60f02ece2af5e6fa057e Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Thu, 9 Dec 2021 16:35:17 -0800 -Subject: [PATCH 50/99] CVE-2021-44141: s3: smbd: Handling - SMB_FILE_RENAME_INFORMATION, the destination name is a single component. - -No errors should be allowed from filename_convert(). - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - source3/smbd/trans2.c | 19 +------------------ - 1 file changed, 1 insertion(+), 18 deletions(-) - -diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c -index 2b2643b6325..95a7cc63970 100644 ---- a/source3/smbd/trans2.c -+++ b/source3/smbd/trans2.c -@@ -7477,25 +7477,8 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn, - 0, - &smb_fname_dst); - -- /* If an error we expect this to be -- * NT_STATUS_OBJECT_PATH_NOT_FOUND */ -- - if (!NT_STATUS_IS_OK(status)) { -- if(!NT_STATUS_EQUAL(NT_STATUS_OBJECT_PATH_NOT_FOUND, -- status)) { -- goto out; -- } -- /* Create an smb_fname to call rename_internals_fsp() */ -- smb_fname_dst = synthetic_smb_fname(ctx, -- base_name, -- NULL, -- NULL, -- smb_fname_src->twrp, -- smb_fname_src->flags); -- if (smb_fname_dst == NULL) { -- status = NT_STATUS_NO_MEMORY; -- goto out; -- } -+ goto out; - } - dst_original_lcomp = get_original_lcomp(smb_fname_dst, - conn, --- -2.25.1 - - -From 838985e439df0c1b741516ff141da02ecbf5656f Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Thu, 9 Dec 2021 16:45:13 -0800 -Subject: [PATCH 51/99] CVE-2021-44141: s3: smbd: In rename_internals_fsp(), - remove unneeded call to check_name(). - -All callers have gone through filename_convert(), which has -already called check_name() on the destination. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - source3/smbd/reply.c | 5 ----- - 1 file changed, 5 deletions(-) - -diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c -index 26049b2b62b..b9f1bd6b9c2 100644 ---- a/source3/smbd/reply.c -+++ b/source3/smbd/reply.c -@@ -7185,11 +7185,6 @@ NTSTATUS rename_internals_fsp(connection_struct *conn, - bool dst_exists, old_is_stream, new_is_stream; - int ret; - -- status = check_name(conn, smb_fname_dst_in); -- if (!NT_STATUS_IS_OK(status)) { -- return status; -- } -- - status = parent_dirname_compatible_open(conn, smb_fname_dst_in); - if (!NT_STATUS_IS_OK(status)) { - return status; --- -2.25.1 - - -From 43a9866c46b9a82af34693e5c17c0c627169cb76 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Thu, 9 Dec 2021 16:47:13 -0800 -Subject: [PATCH 52/99] CVE-2021-44141: s3: smbd: check_name() is now static to - filename.c - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - source3/smbd/filename.c | 2 +- - source3/smbd/proto.h | 2 -- - 2 files changed, 1 insertion(+), 3 deletions(-) - -diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c -index 11022dca703..44f9aebf068 100644 ---- a/source3/smbd/filename.c -+++ b/source3/smbd/filename.c -@@ -1430,7 +1430,7 @@ static NTSTATUS check_veto_path(connection_struct *conn, - a valid one for the user to access. - ****************************************************************************/ - --NTSTATUS check_name(connection_struct *conn, -+static NTSTATUS check_name(connection_struct *conn, - const struct smb_filename *smb_fname) - { - NTSTATUS status = check_veto_path(conn, smb_fname); -diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h -index fa26d58bfde..e6a0d6c3d51 100644 ---- a/source3/smbd/proto.h -+++ b/source3/smbd/proto.h -@@ -358,8 +358,6 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, - NTTIME twrp, - struct smb_filename **smb_fname, - uint32_t ucf_flags); --NTSTATUS check_name(connection_struct *conn, -- const struct smb_filename *smb_fname); - NTSTATUS canonicalize_snapshot_path(struct smb_filename *smb_fname, - uint32_t ucf_flags, - NTTIME twrp); --- -2.25.1 - - -From 68ee550a0dd41e31fd6ffdd1aeda8adb3595a8cf Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Thu, 9 Dec 2021 16:49:46 -0800 -Subject: [PATCH 53/99] CVE-2021-44141: s3: smbd: In rename_internals(), remove - the name spliting and re-combining code. - -filename_convert() handles mangled names just fine, so we don't -need to split the last component and check for mangle. - -Now we don't take wildcard names this is not needed. This was the -last caller of split_fname_dir_mask(), so ifdef it out. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - source3/smbd/reply.c | 67 ++------------------------------------------ - 1 file changed, 2 insertions(+), 65 deletions(-) - -diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c -index b9f1bd6b9c2..7b0eb18d744 100644 ---- a/source3/smbd/reply.c -+++ b/source3/smbd/reply.c -@@ -1624,6 +1624,7 @@ void reply_dskattr(struct smb_request *req) - return; - } - -+#if 0 - /* - * Utility function to split the filename from the directory. - */ -@@ -1655,6 +1656,7 @@ static NTSTATUS split_fname_dir_mask(TALLOC_CTX *ctx, const char *fname_in, - *fname_mask_out = fname_mask; - return NT_STATUS_OK; - } -+#endif - - /**************************************************************************** - Make a dir struct. -@@ -7618,52 +7620,12 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx, - bool replace_if_exists, - uint32_t access_mask) - { -- char *fname_src_dir = NULL; -- struct smb_filename *smb_fname_src_dir = NULL; -- char *fname_src_mask = NULL; - NTSTATUS status = NT_STATUS_OK; -- char *talloced = NULL; - int create_options = 0; - struct smb2_create_blobs *posx = NULL; - struct files_struct *fsp = NULL; - int rc; - -- /* -- * Split the old name into directory and last component -- * strings. Note that unix_convert may have stripped off a -- * leading ./ from both name and newname if the rename is -- * at the root of the share. We need to make sure either both -- * name and newname contain a / character or neither of them do. -- */ -- -- /* Split up the directory from the filename/mask. */ -- status = split_fname_dir_mask(ctx, smb_fname_src->base_name, -- &fname_src_dir, &fname_src_mask); -- if (!NT_STATUS_IS_OK(status)) { -- status = NT_STATUS_NO_MEMORY; -- goto out; -- } -- -- /* -- * We should only check the mangled cache -- * here if unix_convert failed. This means -- * that the path in 'mask' doesn't exist -- * on the file system and so we need to look -- * for a possible mangle. This patch from -- * Tine Smukavec . -- */ -- -- if (!VALID_STAT(smb_fname_src->st) && -- mangle_is_mangled(fname_src_mask, conn->params)) { -- char *new_mask = NULL; -- mangle_lookup_name_from_8_3(ctx, fname_src_mask, &new_mask, -- conn->params); -- if (new_mask) { -- TALLOC_FREE(fname_src_mask); -- fname_src_mask = new_mask; -- } -- } -- - if (smb_fname_src->flags & SMB_FILENAME_POSIX_PATH) { - status = make_smb2_posix_create_ctx(talloc_tos(), &posx, 0777); - if (!NT_STATUS_IS_OK(status)) { -@@ -7673,27 +7635,6 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx, - } - } - -- /* -- * Only one file needs to be renamed. Append the mask back -- * onto the directory. -- */ -- TALLOC_FREE(smb_fname_src->base_name); -- if (ISDOT(fname_src_dir)) { -- /* Ensure we use canonical names on open. */ -- smb_fname_src->base_name = talloc_asprintf(smb_fname_src, -- "%s", -- fname_src_mask); -- } else { -- smb_fname_src->base_name = talloc_asprintf(smb_fname_src, -- "%s/%s", -- fname_src_dir, -- fname_src_mask); -- } -- if (!smb_fname_src->base_name) { -- status = NT_STATUS_NO_MEMORY; -- goto out; -- } -- - DBG_NOTICE("case_sensitive = %d, " - "case_preserve = %d, short case preserve = %d, " - "directory = %s, newname = %s, " -@@ -7776,10 +7717,6 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx, - - out: - TALLOC_FREE(posx); -- TALLOC_FREE(talloced); -- TALLOC_FREE(smb_fname_src_dir); -- TALLOC_FREE(fname_src_dir); -- TALLOC_FREE(fname_src_mask); - return status; - } - --- -2.25.1 - - -From 0163d21c31ad978182adba73bae8f0ee48c69e53 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Thu, 9 Dec 2021 16:51:45 -0800 -Subject: [PATCH 54/99] CVE-2021-44141: s3: smbd: Remove - split_fname_dir_mask(). - -No longer used. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - source3/smbd/reply.c | 34 ---------------------------------- - 1 file changed, 34 deletions(-) - -diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c -index 7b0eb18d744..d2048856cff 100644 ---- a/source3/smbd/reply.c -+++ b/source3/smbd/reply.c -@@ -1624,40 +1624,6 @@ void reply_dskattr(struct smb_request *req) - return; - } - --#if 0 --/* -- * Utility function to split the filename from the directory. -- */ --static NTSTATUS split_fname_dir_mask(TALLOC_CTX *ctx, const char *fname_in, -- char **fname_dir_out, -- char **fname_mask_out) --{ -- const char *p = NULL; -- char *fname_dir = NULL; -- char *fname_mask = NULL; -- -- p = strrchr_m(fname_in, '/'); -- if (!p) { -- fname_dir = talloc_strdup(ctx, "."); -- fname_mask = talloc_strdup(ctx, fname_in); -- } else { -- fname_dir = talloc_strndup(ctx, fname_in, -- PTR_DIFF(p, fname_in)); -- fname_mask = talloc_strdup(ctx, p+1); -- } -- -- if (!fname_dir || !fname_mask) { -- TALLOC_FREE(fname_dir); -- TALLOC_FREE(fname_mask); -- return NT_STATUS_NO_MEMORY; -- } -- -- *fname_dir_out = fname_dir; -- *fname_mask_out = fname_mask; -- return NT_STATUS_OK; --} --#endif -- - /**************************************************************************** - Make a dir struct. - ****************************************************************************/ --- -2.25.1 - - -From 1c1c7ed99466ace89eb61d4783903b8b8a718e27 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Thu, 2 Dec 2021 17:51:42 -0800 -Subject: [PATCH 55/99] CVE-2021-44141: s3: smbd: In call_trans2findfirst() we - don't need filename_convert_with_privilege() anymore. - -It was extra-paranoid code now not needed as the new VFS -version of filename_convert() does the same job. - -There are now no remaining callers of filename_convert_with_privilege(). - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - source3/smbd/trans2.c | 11 ++--------- - 1 file changed, 2 insertions(+), 9 deletions(-) - -diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c -index 95a7cc63970..4612221dbfe 100644 ---- a/source3/smbd/trans2.c -+++ b/source3/smbd/trans2.c -@@ -2757,19 +2757,12 @@ close_if_end = %d requires_resume_key = %d backup_priv = %d level = 0x%x, max_da - if (backup_priv) { - become_root(); - as_root = true; -- ntstatus = filename_convert_with_privilege(talloc_tos(), -- conn, -- req, -- directory, -- ucf_flags, -- &smb_dname); -- } else { -- ntstatus = filename_convert(talloc_tos(), conn, -+ } -+ ntstatus = filename_convert(talloc_tos(), conn, - directory, - ucf_flags, - 0, - &smb_dname); -- } - - if (!NT_STATUS_IS_OK(ntstatus)) { - if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_PATH_NOT_COVERED)) { --- -2.25.1 - - -From 46ec23c244bc001a5bb1105a2d1e23ebfdd78ca4 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Thu, 2 Dec 2021 17:55:26 -0800 -Subject: [PATCH 56/99] CVE-2021-44141: s3: smbd: Remove - filename_convert_with_privilege(). No longer used. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - source3/smbd/filename.c | 21 --------------------- - source3/smbd/proto.h | 6 ------ - 2 files changed, 27 deletions(-) - -diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c -index 44f9aebf068..3d0f350c3dc 100644 ---- a/source3/smbd/filename.c -+++ b/source3/smbd/filename.c -@@ -2078,27 +2078,6 @@ NTSTATUS filename_convert(TALLOC_CTX *ctx, - pp_smb_fname); - } - --/* -- * Go through all the steps to validate a filename. -- * root (privileged) version. -- */ -- --NTSTATUS filename_convert_with_privilege(TALLOC_CTX *ctx, -- connection_struct *conn, -- struct smb_request *smbreq, -- const char *name_in, -- uint32_t ucf_flags, -- struct smb_filename **pp_smb_fname) --{ -- return filename_convert_internal(ctx, -- conn, -- smbreq, -- name_in, -- ucf_flags, -- 0, -- pp_smb_fname); --} -- - /* - * Build the full path from a dirfsp and dirfsp relative name - */ -diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h -index e6a0d6c3d51..58b32c6908b 100644 ---- a/source3/smbd/proto.h -+++ b/source3/smbd/proto.h -@@ -382,12 +382,6 @@ NTSTATUS filename_convert(TALLOC_CTX *mem_ctx, - uint32_t ucf_flags, - NTTIME twrp, - struct smb_filename **pp_smb_fname); --NTSTATUS filename_convert_with_privilege(TALLOC_CTX *mem_ctx, -- connection_struct *conn, -- struct smb_request *smbreq, -- const char *name_in, -- uint32_t ucf_flags, -- struct smb_filename **pp_smb_fname); - - /* The following definitions come from smbd/files.c */ - --- -2.25.1 - - -From 733e66aa31da219f7bc54cd380451d380d6ca3a1 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Fri, 3 Dec 2021 10:10:45 -0800 -Subject: [PATCH 57/99] CVE-2021-44141: s3: smbd: In - filename_convert_internal(), remove call to check_name_with_privilege(). - -We now always pass NULL as struct smb_request *smbreq, -so this code path can never be taken. - -Comment out check_name_with_privilege() as it's now -no longer used. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - source3/smbd/filename.c | 7 +++---- - 1 file changed, 3 insertions(+), 4 deletions(-) - -diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c -index 3d0f350c3dc..882f41ec400 100644 ---- a/source3/smbd/filename.c -+++ b/source3/smbd/filename.c -@@ -1452,6 +1452,7 @@ static NTSTATUS check_name(connection_struct *conn, - return NT_STATUS_OK; - } - -+#if 0 - /**************************************************************************** - Must be called as root. Creates the struct privilege_paths - attached to the struct smb_request if this call is successful. -@@ -1470,6 +1471,7 @@ static NTSTATUS check_name_with_privilege(connection_struct *conn, - smb_fname, - smbreq); - } -+#endif - - /**************************************************************************** - Check if two filenames are equal. -@@ -1999,11 +2001,8 @@ static NTSTATUS filename_convert_internal(TALLOC_CTX *ctx, - TALLOC_FREE(smb_fname); - return status; - } -- } else if (!smbreq) { -- status = check_name(conn, smb_fname); - } else { -- status = check_name_with_privilege(conn, smbreq, -- smb_fname); -+ status = check_name(conn, smb_fname); - } - if (!NT_STATUS_IS_OK(status)) { - DEBUG(3,("filename_convert_internal: check_name failed " --- -2.25.1 - - -From 3f60b452049e4c10cec414a7da8709f2ceb3f929 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Fri, 3 Dec 2021 10:13:13 -0800 -Subject: [PATCH 58/99] CVE-2021-44141: s3: smbd: Remove unused - check_name_with_privilege(). - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - source3/smbd/filename.c | 21 --------------------- - 1 file changed, 21 deletions(-) - -diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c -index 882f41ec400..297f48496e8 100644 ---- a/source3/smbd/filename.c -+++ b/source3/smbd/filename.c -@@ -1452,27 +1452,6 @@ static NTSTATUS check_name(connection_struct *conn, - return NT_STATUS_OK; - } - --#if 0 --/**************************************************************************** -- Must be called as root. Creates the struct privilege_paths -- attached to the struct smb_request if this call is successful. --****************************************************************************/ -- --static NTSTATUS check_name_with_privilege(connection_struct *conn, -- struct smb_request *smbreq, -- const struct smb_filename *smb_fname) --{ -- NTSTATUS status = check_veto_path(conn, smb_fname); -- -- if (!NT_STATUS_IS_OK(status)) { -- return status; -- } -- return check_reduced_name_with_privilege(conn, -- smb_fname, -- smbreq); --} --#endif -- - /**************************************************************************** - Check if two filenames are equal. - This needs to be careful about whether we are case sensitive. --- -2.25.1 - - -From 51c024a1b029c0ca66594336d5474b8cc64c4452 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Fri, 3 Dec 2021 10:14:03 -0800 -Subject: [PATCH 59/99] CVE-2021-44141: s3: smbd: Remove now unused - check_reduced_name_with_privilege(). - -We now only have one function that does this check (check_reduced_name()), -used everywhere. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - source3/smbd/proto.h | 3 - - source3/smbd/vfs.c | 173 ------------------------------------------- - 2 files changed, 176 deletions(-) - -diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h -index 58b32c6908b..5e7bc392b87 100644 ---- a/source3/smbd/proto.h -+++ b/source3/smbd/proto.h -@@ -1300,9 +1300,6 @@ struct smb_filename *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn); - NTSTATUS check_reduced_name(connection_struct *conn, - const struct smb_filename *cwd_fname, - const struct smb_filename *smb_fname); --NTSTATUS check_reduced_name_with_privilege(connection_struct *conn, -- const struct smb_filename *smb_fname, -- struct smb_request *smbreq); - int vfs_stat(struct connection_struct *conn, - struct smb_filename *smb_fname); - int vfs_stat_smb_basename(struct connection_struct *conn, -diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c -index 34831385e09..d8b7b1283fb 100644 ---- a/source3/smbd/vfs.c -+++ b/source3/smbd/vfs.c -@@ -1122,179 +1122,6 @@ struct smb_filename *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn) - return result; - } - --/******************************************************************* -- Reduce a file name, removing .. elements and checking that -- it is below dir in the hierarchy. This uses realpath. -- This function must run as root, and will return names -- and valid stat structs that can be checked on open. --********************************************************************/ -- --NTSTATUS check_reduced_name_with_privilege(connection_struct *conn, -- const struct smb_filename *smb_fname, -- struct smb_request *smbreq) --{ -- NTSTATUS status; -- TALLOC_CTX *ctx = talloc_tos(); -- const char *conn_rootdir; -- size_t rootdir_len; -- char *resolved_name = NULL; -- struct smb_filename *resolved_fname = NULL; -- struct smb_filename *saved_dir_fname = NULL; -- struct smb_filename *smb_fname_cwd = NULL; -- int ret; -- struct smb_filename *parent_name = NULL; -- struct smb_filename *file_name = NULL; -- -- DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n", -- smb_fname->base_name, -- conn->connectpath)); -- -- status = SMB_VFS_PARENT_PATHNAME(conn, -- ctx, -- smb_fname, -- &parent_name, -- &file_name); -- if (!NT_STATUS_IS_OK(status)) { -- goto err; -- } -- -- if (SMB_VFS_STAT(conn, parent_name) != 0) { -- status = map_nt_error_from_unix(errno); -- goto err; -- } -- /* Remember where we were. */ -- saved_dir_fname = vfs_GetWd(ctx, conn); -- if (!saved_dir_fname) { -- status = map_nt_error_from_unix(errno); -- goto err; -- } -- -- if (vfs_ChDir(conn, parent_name) == -1) { -- status = map_nt_error_from_unix(errno); -- goto err; -- } -- -- smb_fname_cwd = synthetic_smb_fname(talloc_tos(), -- ".", -- NULL, -- NULL, -- parent_name->twrp, -- 0); -- if (smb_fname_cwd == NULL) { -- status = NT_STATUS_NO_MEMORY; -- goto err; -- } -- -- /* Get the absolute path of the parent directory. */ -- resolved_fname = SMB_VFS_REALPATH(conn, ctx, smb_fname_cwd); -- if (resolved_fname == NULL) { -- status = map_nt_error_from_unix(errno); -- goto err; -- } -- resolved_name = resolved_fname->base_name; -- -- if (*resolved_name != '/') { -- DEBUG(0,("check_reduced_name_with_privilege: realpath " -- "doesn't return absolute paths !\n")); -- status = NT_STATUS_OBJECT_NAME_INVALID; -- goto err; -- } -- -- DBG_DEBUG("realpath [%s] -> [%s]\n", -- smb_fname_str_dbg(parent_name), -- resolved_name); -- -- /* Now check the stat value is the same. */ -- if (SMB_VFS_LSTAT(conn, smb_fname_cwd) != 0) { -- status = map_nt_error_from_unix(errno); -- goto err; -- } -- -- /* Ensure we're pointing at the same place. */ -- if (!check_same_stat(&smb_fname_cwd->st, &parent_name->st)) { -- DBG_ERR("device/inode/uid/gid on directory %s changed. " -- "Denying access !\n", -- smb_fname_str_dbg(parent_name)); -- status = NT_STATUS_ACCESS_DENIED; -- goto err; -- } -- -- /* Ensure we're below the connect path. */ -- -- conn_rootdir = SMB_VFS_CONNECTPATH(conn, smb_fname); -- if (conn_rootdir == NULL) { -- DEBUG(2, ("check_reduced_name_with_privilege: Could not get " -- "conn_rootdir\n")); -- status = NT_STATUS_ACCESS_DENIED; -- goto err; -- } -- -- rootdir_len = strlen(conn_rootdir); -- -- /* -- * In the case of rootdir_len == 1, we know that conn_rootdir is -- * "/", and we also know that resolved_name starts with a slash. -- * So, in this corner case, resolved_name is automatically a -- * sub-directory of the conn_rootdir. Thus we can skip the string -- * comparison and the next character checks (which are even -- * wrong in this case). -- */ -- if (rootdir_len != 1) { -- bool matched; -- -- matched = (strncmp(conn_rootdir, resolved_name, -- rootdir_len) == 0); -- -- if (!matched || (resolved_name[rootdir_len] != '/' && -- resolved_name[rootdir_len] != '\0')) { -- DBG_WARNING("%s is a symlink outside the " -- "share path\n", -- smb_fname_str_dbg(parent_name)); -- DEBUGADD(1, ("conn_rootdir =%s\n", conn_rootdir)); -- DEBUGADD(1, ("resolved_name=%s\n", resolved_name)); -- status = NT_STATUS_ACCESS_DENIED; -- goto err; -- } -- } -- -- /* Now ensure that the last component either doesn't -- exist, or is *NOT* a symlink. */ -- -- ret = SMB_VFS_LSTAT(conn, file_name); -- if (ret == -1) { -- /* Errno must be ENOENT for this be ok. */ -- if (errno != ENOENT) { -- status = map_nt_error_from_unix(errno); -- DBG_WARNING("LSTAT on %s failed with %s\n", -- smb_fname_str_dbg(file_name), -- nt_errstr(status)); -- goto err; -- } -- } -- -- if (VALID_STAT(file_name->st) && -- S_ISLNK(file_name->st.st_ex_mode)) -- { -- DBG_WARNING("Last component %s is a symlink. Denying" -- "access.\n", -- smb_fname_str_dbg(file_name)); -- status = NT_STATUS_ACCESS_DENIED; -- goto err; -- } -- -- status = NT_STATUS_OK; -- -- err: -- -- if (saved_dir_fname != NULL) { -- vfs_ChDir(conn, saved_dir_fname); -- TALLOC_FREE(saved_dir_fname); -- } -- TALLOC_FREE(resolved_fname); -- TALLOC_FREE(parent_name); -- return status; --} -- - /******************************************************************* - Reduce a file name, removing .. elements and checking that - it is below dir in the hierarchy. This uses realpath. --- -2.25.1 - - -From f8ecb37606ef65a53fbf45c7a4305454de1e53af Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Fri, 3 Dec 2021 10:19:38 -0800 -Subject: [PATCH 60/99] CVE-2021-44141: s3: smbd: filename_convert() is now a - one-to-one wrapper around filename_convert_internal(). - -Remove filename_convert() and rename filename_convert_internal() -> filename_convert(). -Move the old DEBUG(..) statements to DBG_XXX() so they don't print the wrong name. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - source3/smbd/filename.c | 46 +++++++++++------------------------------ - 1 file changed, 12 insertions(+), 34 deletions(-) - -diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c -index 297f48496e8..2c4fa5506ff 100644 ---- a/source3/smbd/filename.c -+++ b/source3/smbd/filename.c -@@ -1913,13 +1913,12 @@ char *get_original_lcomp(TALLOC_CTX *ctx, - * @return NT_STATUS_OK if all operations completed successfully, appropriate - * error otherwise. - */ --static NTSTATUS filename_convert_internal(TALLOC_CTX *ctx, -- connection_struct *conn, -- struct smb_request *smbreq, -- const char *name_in, -- uint32_t ucf_flags, -- NTTIME twrp, -- struct smb_filename **_smb_fname) -+NTSTATUS filename_convert(TALLOC_CTX *ctx, -+ connection_struct *conn, -+ const char *name_in, -+ uint32_t ucf_flags, -+ NTTIME twrp, -+ struct smb_filename **_smb_fname) - { - struct smb_filename *smb_fname = NULL; - bool has_wild; -@@ -1935,10 +1934,10 @@ static NTSTATUS filename_convert_internal(TALLOC_CTX *ctx, - !conn->sconn->using_smb2, - &fname); - if (!NT_STATUS_IS_OK(status)) { -- DEBUG(10,("filename_convert_internal: dfs_redirect " -+ DBG_DEBUG("dfs_redirect " - "failed for name %s with %s\n", - name_in, -- nt_errstr(status) )); -+ nt_errstr(status)); - return status; - } - name_in = fname; -@@ -1964,10 +1963,10 @@ static NTSTATUS filename_convert_internal(TALLOC_CTX *ctx, - - status = unix_convert(ctx, conn, name_in, twrp, &smb_fname, ucf_flags); - if (!NT_STATUS_IS_OK(status)) { -- DEBUG(10,("filename_convert_internal: unix_convert failed " -+ DBG_DEBUG("unix_convert failed " - "for name %s with %s\n", - name_in, -- nt_errstr(status) )); -+ nt_errstr(status)); - return status; - } - -@@ -1984,10 +1983,10 @@ static NTSTATUS filename_convert_internal(TALLOC_CTX *ctx, - status = check_name(conn, smb_fname); - } - if (!NT_STATUS_IS_OK(status)) { -- DEBUG(3,("filename_convert_internal: check_name failed " -+ DBG_NOTICE("check_name failed " - "for name %s with %s\n", - smb_fname_str_dbg(smb_fname), -- nt_errstr(status) )); -+ nt_errstr(status)); - TALLOC_FREE(smb_fname); - return status; - } -@@ -2035,27 +2034,6 @@ static NTSTATUS filename_convert_internal(TALLOC_CTX *ctx, - return status; - } - --/* -- * Go through all the steps to validate a filename. -- * Non-root version. -- */ -- --NTSTATUS filename_convert(TALLOC_CTX *ctx, -- connection_struct *conn, -- const char *name_in, -- uint32_t ucf_flags, -- NTTIME twrp, -- struct smb_filename **pp_smb_fname) --{ -- return filename_convert_internal(ctx, -- conn, -- NULL, -- name_in, -- ucf_flags, -- twrp, -- pp_smb_fname); --} -- - /* - * Build the full path from a dirfsp and dirfsp relative name - */ --- -2.25.1 - - -From 3490db2a38981b10ad165d9815ff026ad1b8513d Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Fri, 3 Dec 2021 16:00:26 -0800 -Subject: [PATCH 61/99] CVE-2021-44141: s3: smbd: In dfs_path_lookup(). If we - have a DFS path including a @GMT-token, don't throw away the twrp value when - parsing the path. - -Not yet used. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - source3/smbd/msdfs.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c -index fd002e98071..86ca79a994b 100644 ---- a/source3/smbd/msdfs.c -+++ b/source3/smbd/msdfs.c -@@ -697,6 +697,7 @@ static NTSTATUS dfs_path_lookup(TALLOC_CTX *ctx, - const struct dfs_path *pdp, /* Parsed out - server+share+extrapath. */ - uint32_t ucf_flags, -+ NTTIME *_twrp, - int *consumedcntp, - struct referral **ppreflist, - size_t *preferral_count) -@@ -867,6 +868,10 @@ static NTSTATUS dfs_path_lookup(TALLOC_CTX *ctx, - } - } - -+ if ((ucf_flags & UCF_GMT_PATHNAME) && _twrp != NULL) { -+ *_twrp = smb_fname->twrp; -+ } -+ - status = NT_STATUS_OK; - out: - -@@ -965,6 +970,7 @@ NTSTATUS dfs_redirect(TALLOC_CTX *ctx, - path_in, - pdp, - ucf_flags, -+ NULL, /* twrp. */ - NULL, /* int *consumedcntp */ - NULL, /* struct referral **ppreflist */ - NULL); /* size_t *preferral_count */ -@@ -1189,6 +1195,7 @@ NTSTATUS get_referred_path(TALLOC_CTX *ctx, - dfs_path, - pdp, - 0, /* ucf_flags */ -+ NULL, - consumedcntp, - &jucn->referral_list, - &jucn->referral_count); --- -2.25.1 - - -From 5c55cd93e5bd1481e88edd4fa0c76f4679bdfcc6 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Fri, 3 Dec 2021 16:14:08 -0800 -Subject: [PATCH 62/99] CVE-2021-44141: s3: smbd: Allow dfs_redirect() to - return a TWRP token it got from a parsed pathname. - -This one is subtle. If an SMB1 request has both a DFS path and a @GMT token, -the unix_convert() inside the DFS path processing will remove the @GMT -token, not allowing the subsequent unix_convert() inside filename_convert() -to see it. By returning it from dfs_redirect() we can ensure it's correctly -added to the smb_filename returned from filename_convert(). - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - source3/smbd/filename.c | 11 +++++++++-- - source3/smbd/msdfs.c | 3 ++- - source3/smbd/proto.h | 1 + - 3 files changed, 12 insertions(+), 3 deletions(-) - -diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c -index 2c4fa5506ff..bcbe9f70015 100644 ---- a/source3/smbd/filename.c -+++ b/source3/smbd/filename.c -@@ -1824,6 +1824,7 @@ char *get_original_lcomp(TALLOC_CTX *ctx, - char *last_slash = NULL; - char *orig_lcomp; - char *fname = NULL; -+ NTTIME twrp = 0; - NTSTATUS status; - - if (ucf_flags & UCF_DFS_PATHNAME) { -@@ -1832,6 +1833,7 @@ char *get_original_lcomp(TALLOC_CTX *ctx, - filename_in, - ucf_flags, - !conn->sconn->using_smb2, -+ &twrp, - &fname); - if (!NT_STATUS_IS_OK(status)) { - DBG_DEBUG("dfs_redirect " -@@ -1860,7 +1862,7 @@ char *get_original_lcomp(TALLOC_CTX *ctx, - filename_in, - NULL, - NULL, -- 0, -+ twrp, - 0); - if (smb_fname == NULL) { - TALLOC_FREE(fname); -@@ -1868,7 +1870,7 @@ char *get_original_lcomp(TALLOC_CTX *ctx, - } - status = canonicalize_snapshot_path(smb_fname, - ucf_flags, -- 0); -+ twrp); - if (!NT_STATUS_IS_OK(status)) { - TALLOC_FREE(fname); - TALLOC_FREE(smb_fname); -@@ -1928,10 +1930,12 @@ NTSTATUS filename_convert(TALLOC_CTX *ctx, - - if (ucf_flags & UCF_DFS_PATHNAME) { - char *fname = NULL; -+ NTTIME dfs_twrp = 0; - status = dfs_redirect(ctx, conn, - name_in, - ucf_flags, - !conn->sconn->using_smb2, -+ &dfs_twrp, - &fname); - if (!NT_STATUS_IS_OK(status)) { - DBG_DEBUG("dfs_redirect " -@@ -1942,6 +1946,9 @@ NTSTATUS filename_convert(TALLOC_CTX *ctx, - } - name_in = fname; - ucf_flags &= ~UCF_DFS_PATHNAME; -+ if (twrp == 0 && dfs_twrp != 0) { -+ twrp = dfs_twrp; -+ } - } - - if (is_fake_file_path(name_in)) { -diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c -index 86ca79a994b..07636592016 100644 ---- a/source3/smbd/msdfs.c -+++ b/source3/smbd/msdfs.c -@@ -901,6 +901,7 @@ NTSTATUS dfs_redirect(TALLOC_CTX *ctx, - const char *path_in, - uint32_t ucf_flags, - bool allow_broken_path, -+ NTTIME *_twrp, - char **pp_path_out) - { - const struct loadparm_substitution *lp_sub = -@@ -970,7 +971,7 @@ NTSTATUS dfs_redirect(TALLOC_CTX *ctx, - path_in, - pdp, - ucf_flags, -- NULL, /* twrp. */ -+ _twrp, /* twrp. */ - NULL, /* int *consumedcntp */ - NULL, /* struct referral **ppreflist */ - NULL); /* size_t *preferral_count */ -diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h -index 5e7bc392b87..c1db119633e 100644 ---- a/source3/smbd/proto.h -+++ b/source3/smbd/proto.h -@@ -567,6 +567,7 @@ NTSTATUS dfs_redirect(TALLOC_CTX *ctx, - const char *name_in, - uint32_t ucf_flags, - bool allow_broken_path, -+ NTTIME *twrp, - char **pp_name_out); - struct connection_struct; - struct smb_filename; --- -2.25.1 - - -From e6d9ef3b1e8e19c1b02a3320a619464b1c319a51 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Fri, 3 Dec 2021 10:35:09 -0800 -Subject: [PATCH 63/99] CVE-2021-44141: s3: smbd: Add - filename_convert_smb1_search_path() - deals with SMB1 search pathnames. - -SMB1search and trans2 findfirst are unique in that -they are the only passed in pathnames that can contain -a terminal wildcard component. - -Deal with these two special cases with this new function -that strips off the terminal wildcard and returns as -the mask, and pass the non-wildcard parent directory -component through the standard filename_convert(). - -Uses new helper function strip_gmt_from_raw_dfs(). - -When SMB1search and trans2 findfirst have been -converted to use this function, we can strip all -wildcard handling out of filename_convert() as -we now know it will only ever be given valid -pathnames. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - source3/smbd/filename.c | 240 ++++++++++++++++++++++++++++++++++++++++ - source3/smbd/proto.h | 6 + - 2 files changed, 246 insertions(+) - -diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c -index bcbe9f70015..ab2a418a3a0 100644 ---- a/source3/smbd/filename.c -+++ b/source3/smbd/filename.c -@@ -2041,6 +2041,246 @@ NTSTATUS filename_convert(TALLOC_CTX *ctx, - return status; - } - -+/* -+ * Strip a @GMT component from an SMB1-DFS path. Could be anywhere -+ * in the path. -+ */ -+ -+static char *strip_gmt_from_raw_dfs(TALLOC_CTX *ctx, -+ const char *name_in, -+ bool posix_pathnames, -+ NTTIME *_twrp) -+{ -+ NTSTATUS status; -+ struct smb_filename *smb_fname = NULL; -+ char *name_out = NULL; -+ -+ smb_fname = synthetic_smb_fname(ctx, -+ name_in, -+ NULL, -+ NULL, -+ 0, -+ 0); -+ if (smb_fname == NULL) { -+ return NULL; -+ } -+ if (!posix_pathnames) { -+ /* -+ * Raw DFS names are still '\\' separated. -+ * canonicalize_snapshot_path() only works -+ * on '/' separated paths. Convert. -+ */ -+ string_replace(smb_fname->base_name, '\\', '/'); -+ } -+ status = canonicalize_snapshot_path(smb_fname, -+ UCF_GMT_PATHNAME, -+ 0); -+ if (!NT_STATUS_IS_OK(status)) { -+ TALLOC_FREE(smb_fname); -+ return NULL; -+ } -+ if (!posix_pathnames) { -+ /* Replace as raw DFS names. */ -+ string_replace(smb_fname->base_name, '/', '\\'); -+ } -+ name_out = talloc_strdup(ctx, smb_fname->base_name); -+ *_twrp = smb_fname->twrp; -+ TALLOC_FREE(smb_fname); -+ return name_out; -+} -+ -+/* -+ * Deal with the SMB1 semantics of sending a pathname with a -+ * wildcard as the terminal component for a SMB1search or -+ * trans2 findfirst. -+ */ -+ -+NTSTATUS filename_convert_smb1_search_path(TALLOC_CTX *ctx, -+ connection_struct *conn, -+ const char *name_in, -+ uint32_t ucf_flags, -+ struct smb_filename **_smb_fname_out, -+ char **_mask_out) -+{ -+ NTSTATUS status; -+ char *p = NULL; -+ char *mask = NULL; -+ struct smb_filename *smb_fname = NULL; -+ bool posix_pathnames = (ucf_flags & UCF_POSIX_PATHNAMES); -+ NTTIME twrp = 0; -+ TALLOC_CTX *frame = talloc_stackframe(); -+ -+ *_smb_fname_out = NULL; -+ *_mask_out = NULL; -+ -+ DBG_DEBUG("name_in: %s\n", name_in); -+ -+ if (ucf_flags & UCF_DFS_PATHNAME) { -+ /* -+ * We've been given a raw DFS pathname. -+ * In Windows mode this is separated by '\\' -+ * characters. -+ * -+ * We need to remove the last component -+ * which must be a wildcard before passing -+ * to dfs_redirect(). But the last component -+ * may also be a @GMT- token so we have to -+ * remove that first. -+ */ -+ char path_sep = posix_pathnames ? '/' : '\\'; -+ char *fname = NULL; -+ char *name_in_copy = NULL; -+ char *last_component = NULL; -+ -+ /* Work on a copy of name_in. */ -+ if (ucf_flags & UCF_GMT_PATHNAME) { -+ name_in_copy = strip_gmt_from_raw_dfs(frame, -+ name_in, -+ posix_pathnames, -+ &twrp); -+ ucf_flags &= ~UCF_GMT_PATHNAME; -+ } else { -+ name_in_copy = talloc_strdup(frame, name_in); -+ } -+ if (name_in_copy == NULL) { -+ TALLOC_FREE(frame); -+ return NT_STATUS_NO_MEMORY; -+ } -+ -+ /* -+ * Now we know that the last component is the -+ * wildcard. Copy it and truncate to remove it. -+ */ -+ p = strrchr_m(name_in_copy, path_sep); -+ if (p == NULL) { -+ last_component = talloc_strdup(frame, name_in_copy); -+ name_in_copy[0] = '\0'; -+ } else { -+ last_component = talloc_strdup(frame, p+1); -+ *p = '\0'; -+ } -+ if (last_component == NULL) { -+ TALLOC_FREE(frame); -+ return NT_STATUS_NO_MEMORY; -+ } -+ -+ DBG_DEBUG("name_in_copy: %s\n", name_in); -+ -+ /* -+ * Now we can call dfs_redirect() -+ * on the name without wildcard. -+ */ -+ status = dfs_redirect(frame, -+ conn, -+ name_in_copy, -+ ucf_flags, -+ !conn->sconn->using_smb2, -+ NULL, -+ &fname); -+ if (!NT_STATUS_IS_OK(status)) { -+ DBG_DEBUG("dfs_redirect " -+ "failed for name %s with %s\n", -+ name_in_copy, -+ nt_errstr(status)); -+ TALLOC_FREE(frame); -+ return status; -+ } -+ /* Add the last component back. */ -+ if (fname[0] == '\0') { -+ name_in = talloc_strdup(frame, last_component); -+ } else { -+ name_in = talloc_asprintf(frame, -+ "%s%c%s", -+ fname, -+ path_sep, -+ last_component); -+ } -+ if (name_in == NULL) { -+ TALLOC_FREE(frame); -+ return NT_STATUS_NO_MEMORY; -+ } -+ ucf_flags &= ~UCF_DFS_PATHNAME; -+ -+ DBG_DEBUG("After DFS redirect name_in: %s\n", name_in); -+ } -+ -+ smb_fname = synthetic_smb_fname(frame, -+ name_in, -+ NULL, -+ NULL, -+ twrp, -+ posix_pathnames ? -+ SMB_FILENAME_POSIX_PATH : 0); -+ if (smb_fname == NULL) { -+ TALLOC_FREE(frame); -+ return NT_STATUS_NO_MEMORY; -+ } -+ -+ /* Canonicalize any @GMT- paths. */ -+ status = canonicalize_snapshot_path(smb_fname, ucf_flags, twrp); -+ if (!NT_STATUS_IS_OK(status)) { -+ TALLOC_FREE(frame); -+ return status; -+ } -+ -+ /* Get the original lcomp. */ -+ mask = get_original_lcomp(frame, -+ conn, -+ name_in, -+ ucf_flags); -+ if (mask == NULL) { -+ TALLOC_FREE(frame); -+ return NT_STATUS_NO_MEMORY; -+ } -+ -+ if (mask[0] == '\0') { -+ /* Windows and OS/2 systems treat search on the root as * */ -+ TALLOC_FREE(mask); -+ mask = talloc_strdup(frame, "*"); -+ if (mask == NULL) { -+ TALLOC_FREE(frame); -+ return NT_STATUS_NO_MEMORY; -+ } -+ } -+ -+ DBG_DEBUG("mask = %s\n", mask); -+ -+ /* -+ * Remove the terminal component so -+ * filename_convert never sees the mask. -+ */ -+ p = strrchr_m(smb_fname->base_name,'/'); -+ if (p == NULL) { -+ /* filename_convert handles a '\0' base_name. */ -+ smb_fname->base_name[0] = '\0'; -+ } else { -+ *p = '\0'; -+ } -+ -+ DBG_DEBUG("For filename_convert: smb_fname = %s\n", -+ smb_fname_str_dbg(smb_fname)); -+ -+ /* Convert the parent directory path. */ -+ status = filename_convert(frame, -+ conn, -+ smb_fname->base_name, -+ ucf_flags, -+ smb_fname->twrp, -+ &smb_fname); -+ -+ if (NT_STATUS_IS_OK(status)) { -+ *_smb_fname_out = talloc_move(ctx, &smb_fname); -+ *_mask_out = talloc_move(ctx, &mask); -+ } else { -+ DBG_DEBUG("filename_convert error for %s: %s\n", -+ smb_fname_str_dbg(smb_fname), -+ nt_errstr(status)); -+ } -+ -+ TALLOC_FREE(frame); -+ return status; -+} -+ - /* - * Build the full path from a dirfsp and dirfsp relative name - */ -diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h -index c1db119633e..46d3f2e5156 100644 ---- a/source3/smbd/proto.h -+++ b/source3/smbd/proto.h -@@ -382,6 +382,12 @@ NTSTATUS filename_convert(TALLOC_CTX *mem_ctx, - uint32_t ucf_flags, - NTTIME twrp, - struct smb_filename **pp_smb_fname); -+NTSTATUS filename_convert_smb1_search_path(TALLOC_CTX *ctx, -+ connection_struct *conn, -+ const char *name_in, -+ uint32_t ucf_flags, -+ struct smb_filename **_smb_fname_out, -+ char **_mask_out); - - /* The following definitions come from smbd/files.c */ - --- -2.25.1 - - -From 0f1436ed031b702ab5853b6a21e476a1c47b243c Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Fri, 3 Dec 2021 11:22:03 -0800 -Subject: [PATCH 64/99] CVE-2021-44141: s3: smbd: Convert reply_search() to use - filename_convert_smb1_search_path(). - -Cleans up this code path nicely ! - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - source3/smbd/reply.c | 71 ++++++++++---------------------------------- - 1 file changed, 16 insertions(+), 55 deletions(-) - -diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c -index d2048856cff..cc95bfa3af0 100644 ---- a/source3/smbd/reply.c -+++ b/source3/smbd/reply.c -@@ -1747,15 +1747,17 @@ void reply_search(struct smb_request *req) - /* dirtype &= ~FILE_ATTRIBUTE_DIRECTORY; */ - - if (status_len == 0) { -- int ret; -+ const char *dirpath; - struct smb_filename *smb_dname = NULL; -- uint32_t ucf_flags = UCF_ALWAYS_ALLOW_WCARD_LCOMP | -- ucf_flags_from_smb_request(req); -- nt_status = filename_convert(ctx, conn, -- path, -- ucf_flags, -- 0, -- &smb_fname); -+ uint32_t ucf_flags = ucf_flags_from_smb_request(req); -+ -+ nt_status = filename_convert_smb1_search_path(ctx, -+ conn, -+ path, -+ ucf_flags, -+ &smb_dname, -+ &mask); -+ - if (!NT_STATUS_IS_OK(nt_status)) { - if (NT_STATUS_EQUAL(nt_status,NT_STATUS_PATH_NOT_COVERED)) { - reply_botherror(req, NT_STATUS_PATH_NOT_COVERED, -@@ -1766,56 +1768,9 @@ void reply_search(struct smb_request *req) - goto out; - } - -- directory = smb_fname->base_name; -- -- p = strrchr_m(directory,'/'); -- if ((p != NULL) && (*directory != '/')) { -- mask = talloc_strdup(ctx, p + 1); -- directory = talloc_strndup(ctx, directory, -- PTR_DIFF(p, directory)); -- } else { -- mask = talloc_strdup(ctx, directory); -- directory = talloc_strdup(ctx,"."); -- } -- -- if (!directory) { -- reply_nterror(req, NT_STATUS_NO_MEMORY); -- goto out; -- } -- - memset((char *)status,'\0',21); - SCVAL(status,0,(dirtype & 0x1F)); - -- smb_dname = synthetic_smb_fname(talloc_tos(), -- directory, -- NULL, -- NULL, -- smb_fname->twrp, -- smb_fname->flags); -- if (smb_dname == NULL) { -- reply_nterror(req, NT_STATUS_NO_MEMORY); -- goto out; -- } -- -- /* -- * As we've cut off the last component from -- * smb_fname we need to re-stat smb_dname -- * so FILE_OPEN disposition knows the directory -- * exists. -- */ -- ret = vfs_stat(conn, smb_dname); -- if (ret == -1) { -- nt_status = map_nt_error_from_unix(errno); -- reply_nterror(req, nt_status); -- goto out; -- } -- -- nt_status = openat_pathref_fsp(conn->cwd_fsp, smb_dname); -- if (!NT_STATUS_IS_OK(nt_status)) { -- reply_nterror(req, nt_status); -- goto out; -- } -- - /* - * Open an fsp on this directory for the dptr. - */ -@@ -1872,6 +1827,12 @@ void reply_search(struct smb_request *req) - } - - dptr_num = dptr_dnum(fsp->dptr); -+ dirpath = dptr_path(sconn, dptr_num); -+ directory = talloc_strdup(ctx, dirpath); -+ if (!directory) { -+ reply_nterror(req, NT_STATUS_NO_MEMORY); -+ goto out; -+ } - - } else { - int status_dirtype; --- -2.25.1 - - -From 12b44645fb92de451cf82de12b46a43fdc1c2cc1 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Fri, 3 Dec 2021 11:28:40 -0800 -Subject: [PATCH 65/99] CVE-2021-44141: s3: smbd: Fix call_trans2findfirst() to - use filename_convert_smb1_search_path(). - -filename_convert() no longer has to handle wildcards. -UCF_ALWAYS_ALLOW_WCARD_LCOMP is now unused. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - source3/smbd/trans2.c | 99 ++++--------------------------------------- - 1 file changed, 8 insertions(+), 91 deletions(-) - -diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c -index 4612221dbfe..3ba7011b989 100644 ---- a/source3/smbd/trans2.c -+++ b/source3/smbd/trans2.c -@@ -2665,14 +2665,12 @@ static void call_trans2findfirst(connection_struct *conn, - NTSTATUS ntstatus = NT_STATUS_OK; - bool ask_sharemode = lp_smbd_search_ask_sharemode(SNUM(conn)); - struct smbd_server_connection *sconn = req->sconn; -- uint32_t ucf_flags = UCF_ALWAYS_ALLOW_WCARD_LCOMP | -- ucf_flags_from_smb_request(req); -+ uint32_t ucf_flags = ucf_flags_from_smb_request(req); - bool backup_priv = false; - bool as_root = false; - files_struct *fsp = NULL; - const struct loadparm_substitution *lp_sub = - loadparm_s3_global_substitution(); -- int ret; - - if (total_params < 13) { - reply_nterror(req, NT_STATUS_INVALID_PARAMETER); -@@ -2758,11 +2756,12 @@ close_if_end = %d requires_resume_key = %d backup_priv = %d level = 0x%x, max_da - become_root(); - as_root = true; - } -- ntstatus = filename_convert(talloc_tos(), conn, -- directory, -- ucf_flags, -- 0, -- &smb_dname); -+ ntstatus = filename_convert_smb1_search_path(talloc_tos(), -+ conn, -+ directory, -+ ucf_flags, -+ &smb_dname, -+ &mask); - - if (!NT_STATUS_IS_OK(ntstatus)) { - if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_PATH_NOT_COVERED)) { -@@ -2774,72 +2773,9 @@ close_if_end = %d requires_resume_key = %d backup_priv = %d level = 0x%x, max_da - goto out; - } - -- /* -- * The above call to filename_convert() is on the path from the client -- * including the search mask. Until the code that chops of the search -- * mask from the path below is moved before the call to -- * filename_convert(), we close a possible pathref fsp to ensure -- * SMB_VFS_CREATE_FILE() below will internally open a pathref fsp on the -- * correct path. -- */ -- if (smb_dname->fsp != NULL) { -- ntstatus = fd_close(smb_dname->fsp); -- if (!NT_STATUS_IS_OK(ntstatus)) { -- reply_nterror(req, ntstatus); -- goto out; -- } -- /* -- * The pathref fsp link destructor will set smb_dname->fsp to -- * NULL. Turning this into an assert to give a hint at readers -- * of the code trying to understand the mechanics. -- */ -- file_free(req, smb_dname->fsp); -- SMB_ASSERT(smb_dname->fsp == NULL); -- } -- -- mask = get_original_lcomp(talloc_tos(), -- conn, -- directory, -- ucf_flags); -- if (mask == NULL) { -- reply_nterror(req, NT_STATUS_NO_MEMORY); -- goto out; -- } -- -+ TALLOC_FREE(directory); - directory = smb_dname->base_name; - -- p = strrchr_m(directory,'/'); -- if(p == NULL) { -- /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */ -- if((directory[0] == '.') && (directory[1] == '\0')) { -- mask = talloc_strdup(talloc_tos(),"*"); -- if (!mask) { -- reply_nterror(req, NT_STATUS_NO_MEMORY); -- goto out; -- } -- } -- } else { -- *p = 0; -- } -- -- if (p == NULL || p == directory) { -- struct smb_filename *old_name = smb_dname; -- -- /* Ensure we don't have a directory name of "". */ -- smb_dname = synthetic_smb_fname(talloc_tos(), -- ".", -- NULL, -- &old_name->st, -- old_name->twrp, -- old_name->flags); -- TALLOC_FREE(old_name); -- if (smb_dname == NULL) { -- reply_nterror(req, NT_STATUS_NO_MEMORY); -- goto out; -- } -- directory = smb_dname->base_name; -- } -- - DEBUG(5,("dir=%s, mask = %s\n",directory, mask)); - - if (info_level == SMB_FIND_EA_LIST) { -@@ -2897,25 +2833,6 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd - } - params = *pparams; - -- /* -- * As we've cut off the last component from -- * smb_fname we need to re-stat smb_dname -- * so FILE_OPEN disposition knows the directory -- * exists. -- */ -- ret = vfs_stat(conn, smb_dname); -- if (ret == -1) { -- ntstatus = map_nt_error_from_unix(errno); -- reply_nterror(req, ntstatus); -- goto out; -- } -- -- ntstatus = openat_pathref_fsp(conn->cwd_fsp, smb_dname); -- if (!NT_STATUS_IS_OK(ntstatus)) { -- reply_nterror(req, ntstatus); -- goto out; -- } -- - /* - * Open an fsp on this directory for the dptr. - */ --- -2.25.1 - - -From fc8e6669edb9e20fbc3a4f06dccccbb7ec676f70 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Fri, 3 Dec 2021 11:31:40 -0800 -Subject: [PATCH 66/99] CVE-2021-44141: s3: smbd: dfs_path_lookup() no longer - deals with wildcards. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - source3/smbd/msdfs.c | 13 ------------- - 1 file changed, 13 deletions(-) - -diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c -index 07636592016..6a3abd2f6eb 100644 ---- a/source3/smbd/msdfs.c -+++ b/source3/smbd/msdfs.c -@@ -680,10 +680,6 @@ bool is_msdfs_link(struct files_struct *dirfsp, - Used by other functions to decide if a dfs path is remote, - and to get the list of referred locations for that remote path. - -- search_flag: For findfirsts, dfs links themselves are not -- redirected, but paths beyond the links are. For normal smb calls, -- even dfs links need to be redirected. -- - consumedcntp: how much of the dfs path is being redirected. the client - should try the remaining path on the redirected server. - -@@ -755,15 +751,6 @@ static NTSTATUS dfs_path_lookup(TALLOC_CTX *ctx, - TALLOC_FREE(parent_fname); - - if (NT_STATUS_IS_OK(status)) { -- /* XX_ALLOW_WCARD_XXX is called from search functions.*/ -- if (ucf_flags & UCF_ALWAYS_ALLOW_WCARD_LCOMP) { -- DBG_INFO("(FindFirst) No redirection " -- "for dfs link %s.\n", -- dfspath); -- status = NT_STATUS_OK; -- goto out; -- } -- - DBG_INFO("%s resolves to a valid dfs link\n", - dfspath); - --- -2.25.1 - - -From d91d4a17443ab833bd210c10ac68b3992cb97370 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Fri, 3 Dec 2021 11:42:23 -0800 -Subject: [PATCH 67/99] CVE-2021-44141: s3: smbd: Remove 'bool - search_wcard_flag' from parse_dfs_path(). - -Never set. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - source3/smbd/msdfs.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c -index 6a3abd2f6eb..1feeec6fff2 100644 ---- a/source3/smbd/msdfs.c -+++ b/source3/smbd/msdfs.c -@@ -894,14 +894,13 @@ NTSTATUS dfs_redirect(TALLOC_CTX *ctx, - const struct loadparm_substitution *lp_sub = - loadparm_s3_global_substitution(); - NTSTATUS status; -- bool search_wcard_flag = (ucf_flags & UCF_ALWAYS_ALLOW_WCARD_LCOMP); - struct dfs_path *pdp = talloc(ctx, struct dfs_path); - - if (!pdp) { - return NT_STATUS_NO_MEMORY; - } - -- status = parse_dfs_path(conn, path_in, search_wcard_flag, -+ status = parse_dfs_path(conn, path_in, false, - allow_broken_path, pdp); - if (!NT_STATUS_IS_OK(status)) { - TALLOC_FREE(pdp); --- -2.25.1 - - -From 6f2c67d9993925e45245c7c3f1aa947d72cd2573 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Fri, 3 Dec 2021 11:48:23 -0800 -Subject: [PATCH 68/99] CVE-2021-44141: s3: smbd: parse_dfs_path() can ignore - wildcards. - -If one is passed to filename_convert(), it will error out there -with NT_STATUS_OBJECT_NAME_INVALID. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - source3/smbd/msdfs.c | 6 ------ - 1 file changed, 6 deletions(-) - -diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c -index 1feeec6fff2..c003b442baa 100644 ---- a/source3/smbd/msdfs.c -+++ b/source3/smbd/msdfs.c -@@ -215,12 +215,6 @@ static NTSTATUS parse_dfs_path(connection_struct *conn, - if (pdp->posix_path) { - status = check_path_syntax_posix(pdp->reqpath); - } else { -- if (!allow_wcards) { -- bool has_wcard = ms_has_wild(pdp->reqpath); -- if (has_wcard) { -- return NT_STATUS_INVALID_PARAMETER; -- } -- } - status = check_path_syntax(pdp->reqpath); - } - --- -2.25.1 - - -From b73be0c7a7c86943416cb83de387341ebfb169fd Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Fri, 3 Dec 2021 11:30:42 -0800 -Subject: [PATCH 69/99] CVE-2021-44141: s3: smbd: filename_convert() no longer - deals with wildcards. - -These are already errored out with NT_STATUS_OBJECT_NAME_INVALID -in the unix_convert() code. - -Remove the check. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - source3/smbd/filename.c | 9 --------- - 1 file changed, 9 deletions(-) - -diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c -index ab2a418a3a0..dca5de31be6 100644 ---- a/source3/smbd/filename.c -+++ b/source3/smbd/filename.c -@@ -1923,7 +1923,6 @@ NTSTATUS filename_convert(TALLOC_CTX *ctx, - struct smb_filename **_smb_fname) - { - struct smb_filename *smb_fname = NULL; -- bool has_wild; - NTSTATUS status; - - *_smb_fname = NULL; -@@ -1998,14 +1997,6 @@ NTSTATUS filename_convert(TALLOC_CTX *ctx, - return status; - } - -- has_wild = ms_has_wild(name_in); -- if (has_wild) { -- DBG_DEBUG("[%s] contains wildcard, skipping pathref fsp\n", -- name_in); -- *_smb_fname = smb_fname; -- return NT_STATUS_OK; -- } -- - if (!VALID_STAT(smb_fname->st)) { - DBG_DEBUG("[%s] does not exist, skipping pathref fsp\n", - smb_fname_str_dbg(smb_fname)); --- -2.25.1 - - -From 5e42ab3f6a09ec469ef882dca24f1372711646a0 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Fri, 3 Dec 2021 11:33:42 -0800 -Subject: [PATCH 70/99] CVE-2021-44141: s3: smbd: Inside 'struct uc_state', - remove allow_wcard_last_component. - -This is never allowed. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - source3/smbd/filename.c | 8 +++----- - 1 file changed, 3 insertions(+), 5 deletions(-) - -diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c -index dca5de31be6..dc2a5a33824 100644 ---- a/source3/smbd/filename.c -+++ b/source3/smbd/filename.c -@@ -524,7 +524,6 @@ struct uc_state { - bool component_was_mangled; - bool name_has_wildcard; - bool posix_pathnames; -- bool allow_wcard_last_component; - bool done; - }; - -@@ -870,7 +869,7 @@ static NTSTATUS unix_convert_step(struct uc_state *state) - return NT_STATUS_OBJECT_NAME_INVALID; - } - return determine_path_error(state->end+1, -- state->allow_wcard_last_component, -+ false, - state->posix_pathnames); - } - -@@ -962,7 +961,6 @@ NTSTATUS unix_convert(TALLOC_CTX *mem_ctx, - .orig_path = orig_path, - .ucf_flags = ucf_flags, - .posix_pathnames = (ucf_flags & UCF_POSIX_PATHNAMES), -- .allow_wcard_last_component = (ucf_flags & UCF_ALWAYS_ALLOW_WCARD_LCOMP), - }; - - *smb_fname_out = NULL; -@@ -1038,7 +1036,7 @@ NTSTATUS unix_convert(TALLOC_CTX *mem_ctx, - status = NT_STATUS_OBJECT_NAME_INVALID; - } else { - status =determine_path_error(&state->orig_path[2], -- state->allow_wcard_last_component, -+ false, - state->posix_pathnames); - } - goto err; -@@ -1163,7 +1161,7 @@ NTSTATUS unix_convert(TALLOC_CTX *mem_ctx, - if (!state->posix_pathnames) { - /* POSIX pathnames have no wildcards. */ - state->name_has_wildcard = ms_has_wild(state->smb_fname->base_name); -- if (state->name_has_wildcard && !state->allow_wcard_last_component) { -+ if (state->name_has_wildcard) { - /* Wildcard not valid anywhere. */ - status = NT_STATUS_OBJECT_NAME_INVALID; - goto fail; --- -2.25.1 - - -From b0fc0efbac5b1c4144769ec5a2855f4276b9c7a2 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Fri, 3 Dec 2021 12:37:15 -0800 -Subject: [PATCH 71/99] CVE-2021-44141: s3: smbd: We no longer need - determine_path_error(). - -Now we don't have to consider wildcards just -return NT_STATUS_OBJECT_PATH_NOT_FOUND for -the cases we used to call it. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - source3/smbd/filename.c | 47 ++--------------------------------------- - 1 file changed, 2 insertions(+), 45 deletions(-) - -diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c -index dc2a5a33824..09bf859bd2d 100644 ---- a/source3/smbd/filename.c -+++ b/source3/smbd/filename.c -@@ -90,45 +90,6 @@ static bool mangled_equal(const char *name1, - return strequal(name1, mname); - } - --/**************************************************************************** -- Cope with the differing wildcard and non-wildcard error cases. --****************************************************************************/ -- --static NTSTATUS determine_path_error(const char *name, -- bool allow_wcard_last_component, -- bool posix_pathnames) --{ -- const char *p; -- bool name_has_wild = false; -- -- if (!allow_wcard_last_component) { -- /* Error code within a pathname. */ -- return NT_STATUS_OBJECT_PATH_NOT_FOUND; -- } -- -- /* We're terminating here so we -- * can be a little slower and get -- * the error code right. Windows -- * treats the last part of the pathname -- * separately I think, so if the last -- * component is a wildcard then we treat -- * this ./ as "end of component" */ -- -- p = strchr(name, '/'); -- -- if (!posix_pathnames) { -- name_has_wild = ms_has_wild(name); -- } -- -- if (!p && (name_has_wild || ISDOT(name))) { -- /* Error code at the end of a pathname. */ -- return NT_STATUS_OBJECT_NAME_INVALID; -- } else { -- /* Error code within a pathname. */ -- return NT_STATUS_OBJECT_PATH_NOT_FOUND; -- } --} -- - static NTSTATUS check_for_dot_component(const struct smb_filename *smb_fname) - { - /* Ensure we catch all names with in "/." -@@ -868,9 +829,7 @@ static NTSTATUS unix_convert_step(struct uc_state *state) - /* Error code at the end of a pathname. */ - return NT_STATUS_OBJECT_NAME_INVALID; - } -- return determine_path_error(state->end+1, -- false, -- state->posix_pathnames); -+ return NT_STATUS_OBJECT_PATH_NOT_FOUND; - } - - /* The name cannot have a wildcard if it's not -@@ -1035,9 +994,7 @@ NTSTATUS unix_convert(TALLOC_CTX *mem_ctx, - if (state->orig_path[1] == '\0' || state->orig_path[2] == '\0') { - status = NT_STATUS_OBJECT_NAME_INVALID; - } else { -- status =determine_path_error(&state->orig_path[2], -- false, -- state->posix_pathnames); -+ status = NT_STATUS_OBJECT_PATH_NOT_FOUND; - } - goto err; - } --- -2.25.1 - - -From d52dd78e9d8cecbc9e913c0b91f345cafe755dbd Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Fri, 3 Dec 2021 12:40:43 -0800 -Subject: [PATCH 72/99] CVE-2021-44141: s3: smbd: UCF_ALWAYS_ALLOW_WCARD_LCOMP - 0x00000002 is no longer used. - -Hurrah ! - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - source3/smbd/filename.c | 3 --- - source3/smbd/smbd.h | 2 +- - 2 files changed, 1 insertion(+), 4 deletions(-) - -diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c -index 09bf859bd2d..73a2f116915 100644 ---- a/source3/smbd/filename.c -+++ b/source3/smbd/filename.c -@@ -459,9 +459,6 @@ Note NT_STATUS_OK doesn't mean the name exists or is valid, just that we - didn't get any fatal errors that should immediately terminate the calling SMB - processing whilst resolving. - --If UCF_ALWAYS_ALLOW_WCARD_LCOMP is passed in, then a MS wildcard --should be allowed in the last component of the path only. -- - If the orig_path was a stream, smb_filename->base_name will point to the base - filename, and smb_filename->stream_name will point to the stream name. If - orig_path was not a stream, then smb_filename->stream_name will be NULL. -diff --git a/source3/smbd/smbd.h b/source3/smbd/smbd.h -index 84fcf033a71..88bff2830d9 100644 ---- a/source3/smbd/smbd.h -+++ b/source3/smbd/smbd.h -@@ -61,7 +61,7 @@ struct trans_state { - * unix_convert_flags - */ - /* UCF_SAVE_LCOMP 0x00000001 is no longer used. */ --#define UCF_ALWAYS_ALLOW_WCARD_LCOMP 0x00000002 -+/* UCF_ALWAYS_ALLOW_WCARD_LCOMP 0x00000002 is no longer used. */ - /* UCF_COND_ALLOW_WCARD_LCOMP 0x00000004 is no longer used. */ - #define UCF_POSIX_PATHNAMES 0x00000008 - /* #define UCF_UNIX_NAME_LOOKUP 0x00000010 is no longer used. */ --- -2.25.1 - - -From 3471f03816f8133f501288c8e468c36cdad8ae65 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Fri, 3 Dec 2021 12:53:36 -0800 -Subject: [PATCH 73/99] CVE-2021-44141: s3: smbd: Inside unix_convert(), never - set state->name_is_wildcard. - -We error out immediately if it's set anyway. -Preparing to remove 'state->name_is_wildcard' structure element. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - source3/smbd/filename.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c -index 73a2f116915..2095c23aaf4 100644 ---- a/source3/smbd/filename.c -+++ b/source3/smbd/filename.c -@@ -1114,8 +1114,8 @@ NTSTATUS unix_convert(TALLOC_CTX *mem_ctx, - - if (!state->posix_pathnames) { - /* POSIX pathnames have no wildcards. */ -- state->name_has_wildcard = ms_has_wild(state->smb_fname->base_name); -- if (state->name_has_wildcard) { -+ bool name_has_wildcard = ms_has_wild(state->smb_fname->base_name); -+ if (name_has_wildcard) { - /* Wildcard not valid anywhere. */ - status = NT_STATUS_OBJECT_NAME_INVALID; - goto fail; --- -2.25.1 - - -From 36f480c7c8ea88238a040415f677ad0a57fec60c Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Fri, 3 Dec 2021 12:55:41 -0800 -Subject: [PATCH 74/99] CVE-2021-44141: s3: smbd: In unix_convert(), remove all - references to state->name_has_wildcard. - -It is never set. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - source3/smbd/filename.c | 25 ++----------------------- - 1 file changed, 2 insertions(+), 23 deletions(-) - -diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c -index 2095c23aaf4..01c0d9d7dbd 100644 ---- a/source3/smbd/filename.c -+++ b/source3/smbd/filename.c -@@ -1125,7 +1125,7 @@ NTSTATUS unix_convert(TALLOC_CTX *mem_ctx, - DBG_DEBUG("Begin: name [%s] dirpath [%s] name [%s]\n", - state->smb_fname->base_name, state->dirpath, state->name); - -- if (!state->name_has_wildcard) { -+ { - int parent_stat_errno = 0; - - /* -@@ -1239,27 +1239,6 @@ NTSTATUS unix_convert(TALLOC_CTX *mem_ctx, - goto done; - } - } -- } else { -- /* -- * We have a wildcard in the pathname. -- * -- * Optimization for common case where the wildcard -- * is in the last component and the client already -- * sent the correct case. -- * NOTE : check_parent_exists() doesn't preserve errno. -- */ -- int saved_errno = errno; -- status = check_parent_exists(state->mem_ctx, -- state->conn, -- state->posix_pathnames, -- state->smb_fname, -- &state->dirpath, -- &state->name, -- NULL); -- errno = saved_errno; -- if (!NT_STATUS_IS_OK(status)) { -- goto fail; -- } - } - - /* -@@ -1299,7 +1278,7 @@ NTSTATUS unix_convert(TALLOC_CTX *mem_ctx, - * components as this can change the size. - */ - -- if(!state->component_was_mangled && !state->name_has_wildcard) { -+ if(!state->component_was_mangled) { - stat_cache_add(state->orig_path, - state->smb_fname->base_name, - state->smb_fname->twrp, --- -2.25.1 - - -From 104499b56ded1960c0fa7f2dfd49eea4d0f76172 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Fri, 3 Dec 2021 12:59:50 -0800 -Subject: [PATCH 75/99] CVE-2021-44141: s3: smbd: In unix_convert() remove the - now unneeded block indentation. - -We removed the 'if (state->name_has_wildcard) {' clause, so -the block no longer needs indenting. - -Best seen with git show -b. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - source3/smbd/filename.c | 193 ++++++++++++++++++++-------------------- - 1 file changed, 95 insertions(+), 98 deletions(-) - -diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c -index 01c0d9d7dbd..c8b3f1f5955 100644 ---- a/source3/smbd/filename.c -+++ b/source3/smbd/filename.c -@@ -910,6 +910,7 @@ NTSTATUS unix_convert(TALLOC_CTX *mem_ctx, - struct uc_state *state = &uc_state; - NTSTATUS status; - int ret = -1; -+ int parent_stat_errno = 0; - - *state = (struct uc_state) { - .mem_ctx = mem_ctx, -@@ -1125,119 +1126,115 @@ NTSTATUS unix_convert(TALLOC_CTX *mem_ctx, - DBG_DEBUG("Begin: name [%s] dirpath [%s] name [%s]\n", - state->smb_fname->base_name, state->dirpath, state->name); - -- { -- int parent_stat_errno = 0; -+ /* -+ * stat the name - if it exists then we can add the stream back (if -+ * there was one) and be done! -+ */ - -- /* -- * stat the name - if it exists then we can add the stream back (if -- * there was one) and be done! -- */ -+ ret = vfs_stat(state->conn, state->smb_fname); -+ if (ret == 0) { -+ status = check_for_dot_component(state->smb_fname); -+ if (!NT_STATUS_IS_OK(status)) { -+ goto fail; -+ } -+ /* Add the path (not including the stream) to the cache. */ -+ stat_cache_add(state->orig_path, -+ state->smb_fname->base_name, -+ state->smb_fname->twrp, -+ state->conn->case_sensitive); -+ DBG_DEBUG("Conversion of base_name finished " -+ "[%s] -> [%s]\n", -+ state->orig_path, state->smb_fname->base_name); -+ goto done; -+ } - -- ret = vfs_stat(state->conn, state->smb_fname); -- if (ret == 0) { -- status = check_for_dot_component(state->smb_fname); -- if (!NT_STATUS_IS_OK(status)) { -- goto fail; -- } -- /* Add the path (not including the stream) to the cache. */ -- stat_cache_add(state->orig_path, -- state->smb_fname->base_name, -- state->smb_fname->twrp, -- state->conn->case_sensitive); -- DBG_DEBUG("Conversion of base_name finished " -- "[%s] -> [%s]\n", -- state->orig_path, state->smb_fname->base_name); -- goto done; -+ /* Stat failed - ensure we don't use it. */ -+ SET_STAT_INVALID(state->smb_fname->st); -+ -+ /* -+ * Note: we must continue processing a path if we get EACCES -+ * from stat. With NFS4 permissions the file might be lacking -+ * READ_ATTR, but if the parent has LIST permissions we can -+ * resolve the path in the path traversal loop down below. -+ */ -+ -+ if (errno == ENOENT) { -+ /* Optimization when creating a new file - only -+ the last component doesn't exist. -+ NOTE : check_parent_exists() doesn't preserve errno. -+ */ -+ int saved_errno = errno; -+ status = check_parent_exists(state->mem_ctx, -+ state->conn, -+ state->posix_pathnames, -+ state->smb_fname, -+ &state->dirpath, -+ &state->name, -+ &parent_stat_errno); -+ errno = saved_errno; -+ if (!NT_STATUS_IS_OK(status)) { -+ goto fail; - } -+ } - -- /* Stat failed - ensure we don't use it. */ -- SET_STAT_INVALID(state->smb_fname->st); -+ /* -+ * A special case - if we don't have any wildcards or mangling chars and are case -+ * sensitive or the underlying filesystem is case insensitive then searching -+ * won't help. -+ */ - -- /* -- * Note: we must continue processing a path if we get EACCES -- * from stat. With NFS4 permissions the file might be lacking -- * READ_ATTR, but if the parent has LIST permissions we can -- * resolve the path in the path traversal loop down below. -- */ -+ if ((state->conn->case_sensitive || !(state->conn->fs_capabilities & -+ FILE_CASE_SENSITIVE_SEARCH)) && -+ !mangle_is_mangled(state->smb_fname->base_name, state->conn->params)) { - -- if (errno == ENOENT) { -- /* Optimization when creating a new file - only -- the last component doesn't exist. -- NOTE : check_parent_exists() doesn't preserve errno. -- */ -- int saved_errno = errno; -- status = check_parent_exists(state->mem_ctx, -- state->conn, -- state->posix_pathnames, -- state->smb_fname, -- &state->dirpath, -- &state->name, -- &parent_stat_errno); -- errno = saved_errno; -- if (!NT_STATUS_IS_OK(status)) { -- goto fail; -- } -+ status = check_for_dot_component(state->smb_fname); -+ if (!NT_STATUS_IS_OK(status)) { -+ goto fail; - } - - /* -- * A special case - if we don't have any wildcards or mangling chars and are case -- * sensitive or the underlying filesystem is case insensitive then searching -- * won't help. -+ * The stat failed. Could be ok as it could be -+ * a new file. - */ - -- if ((state->conn->case_sensitive || !(state->conn->fs_capabilities & -- FILE_CASE_SENSITIVE_SEARCH)) && -- !mangle_is_mangled(state->smb_fname->base_name, state->conn->params)) { -- -- status = check_for_dot_component(state->smb_fname); -- if (!NT_STATUS_IS_OK(status)) { -- goto fail; -- } -- -+ if (errno == ENOTDIR || errno == ELOOP) { -+ status = NT_STATUS_OBJECT_PATH_NOT_FOUND; -+ goto fail; -+ } else if (errno == ENOENT) { - /* -- * The stat failed. Could be ok as it could be -- * a new file. -- */ -- -- if (errno == ENOTDIR || errno == ELOOP) { -+ * Was it a missing last component ? -+ * or a missing intermediate component ? -+ * -+ * Optimization. -+ * -+ * For this code path we can guarantee that -+ * we have gone through check_parent_exists() -+ * and it returned NT_STATUS_OK. -+ * -+ * Either there was no parent component (".") -+ * parent_stat_errno == 0 and we have a missing -+ * last component here. -+ * -+ * OR check_parent_exists() called STAT/LSTAT -+ * and if it failed parent_stat_errno has been -+ * set telling us if the parent existed or not. -+ * -+ * Either way we can avoid another STAT/LSTAT -+ * system call on the parent here. -+ */ -+ if (parent_stat_errno == ENOTDIR || -+ parent_stat_errno == ENOENT || -+ parent_stat_errno == ELOOP) { - status = NT_STATUS_OBJECT_PATH_NOT_FOUND; - goto fail; -- } else if (errno == ENOENT) { -- /* -- * Was it a missing last component ? -- * or a missing intermediate component ? -- * -- * Optimization. -- * -- * For this code path we can guarantee that -- * we have gone through check_parent_exists() -- * and it returned NT_STATUS_OK. -- * -- * Either there was no parent component (".") -- * parent_stat_errno == 0 and we have a missing -- * last component here. -- * -- * OR check_parent_exists() called STAT/LSTAT -- * and if it failed parent_stat_errno has been -- * set telling us if the parent existed or not. -- * -- * Either way we can avoid another STAT/LSTAT -- * system call on the parent here. -- */ -- if (parent_stat_errno == ENOTDIR || -- parent_stat_errno == ENOENT || -- parent_stat_errno == ELOOP) { -- status = NT_STATUS_OBJECT_PATH_NOT_FOUND; -- goto fail; -- } -- -- /* -- * Missing last component is ok - new file. -- * Also deal with permission denied elsewhere. -- * Just drop out to done. -- */ -- goto done; - } -+ -+ /* -+ * Missing last component is ok - new file. -+ * Also deal with permission denied elsewhere. -+ * Just drop out to done. -+ */ -+ goto done; - } - } - --- -2.25.1 - - -From e94d2bcbdc6d4899be71b74a2daf39e65474558c Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Fri, 3 Dec 2021 13:03:47 -0800 -Subject: [PATCH 76/99] CVE-2021-44141: s3: smbd: In unix_convert_step() remove - all use of 'state->name_was_wildcard' - -We know it is never true. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - source3/smbd/filename.c | 23 ++--------------------- - 1 file changed, 2 insertions(+), 21 deletions(-) - -diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c -index c8b3f1f5955..c582d24ec6b 100644 ---- a/source3/smbd/filename.c -+++ b/source3/smbd/filename.c -@@ -829,25 +829,6 @@ static NTSTATUS unix_convert_step(struct uc_state *state) - return NT_STATUS_OBJECT_PATH_NOT_FOUND; - } - -- /* The name cannot have a wildcard if it's not -- the last component. */ -- -- if (!state->posix_pathnames) { -- state->name_has_wildcard = ms_has_wild(state->name); -- } -- -- /* Wildcards never valid within a pathname. */ -- if (state->name_has_wildcard && state->end != NULL) { -- return NT_STATUS_OBJECT_NAME_INVALID; -- } -- -- /* Skip the stat call if it's a wildcard end. */ -- if (state->name_has_wildcard) { -- DBG_DEBUG("Wildcard [%s]\n", state->name); -- state->done = true; -- return NT_STATUS_OK; -- } -- - status = unix_convert_step_stat(state); - if (!NT_STATUS_IS_OK(status)) { - return status; -@@ -880,9 +861,9 @@ static NTSTATUS unix_convert_step(struct uc_state *state) - - /* - * Cache the dirpath thus far. Don't cache a name with mangled -- * or wildcard components as this can change the size. -+ * components as this can change the size. - */ -- if(!state->component_was_mangled && !state->name_has_wildcard) { -+ if(!state->component_was_mangled) { - stat_cache_add(state->orig_path, - state->dirpath, - state->smb_fname->twrp, --- -2.25.1 - - -From f77e56e2d1baff6f0ff78e10d6bbba49d106edd9 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Fri, 3 Dec 2021 13:05:55 -0800 -Subject: [PATCH 77/99] CVE-2021-44141: s3: smbd: In unix_convert_step_stat() - remove use of state->name_was_wildcard. - -It can never be true. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - source3/smbd/filename.c | 8 ++------ - 1 file changed, 2 insertions(+), 6 deletions(-) - -diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c -index c582d24ec6b..8f7da13f034 100644 ---- a/source3/smbd/filename.c -+++ b/source3/smbd/filename.c -@@ -662,8 +662,8 @@ static NTSTATUS unix_convert_step_stat(struct uc_state *state) - if (state->posix_pathnames) { - /* - * For posix_pathnames, we're done. -- * Don't blunder into the name_has_wildcard OR -- * get_real_filename() codepaths as they may -+ * Don't blunder into the -+ * get_real_filename() codepath as they may - * be doing case insensitive lookups. So when - * creating a new POSIX directory Foo they might - * match on name foo. -@@ -712,10 +712,6 @@ static NTSTATUS unix_convert_step_stat(struct uc_state *state) - * Try to find this part of the path in the directory. - */ - -- if (state->name_has_wildcard) { -- return unix_convert_step_search_fail(state); -- } -- - dname = (struct smb_filename) { - .base_name = state->dirpath, - .twrp = state->smb_fname->twrp, --- -2.25.1 - - -From f8698b1f797ddf2c6e418e683e6c68392ad3ef9e Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Fri, 3 Dec 2021 13:06:27 -0800 -Subject: [PATCH 78/99] CVE-2021-44141: s3: smbd: Remove 'struct uc_state' - name_has_wildcard element. - -It is never set or looked at. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - source3/smbd/filename.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c -index 8f7da13f034..0d82085870c 100644 ---- a/source3/smbd/filename.c -+++ b/source3/smbd/filename.c -@@ -480,7 +480,6 @@ struct uc_state { - char *dirpath; - char *stream; - bool component_was_mangled; -- bool name_has_wildcard; - bool posix_pathnames; - bool done; - }; --- -2.25.1 - - -From 10242faa0785ca277d584274c151467e78e787bf Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Fri, 19 Nov 2021 12:54:47 -0800 -Subject: [PATCH 79/99] CVE-2021-44141: s4: torture: Fix - raw.search:test_one_file() to use torture_result() instead of printf. - -I think this test pre-dates torture_result. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - source4/torture/raw/search.c | 60 ++++++++++++++++++++++++------------ - 1 file changed, 41 insertions(+), 19 deletions(-) - -diff --git a/source4/torture/raw/search.c b/source4/torture/raw/search.c -index 14af01bffad..07285893f40 100644 ---- a/source4/torture/raw/search.c -+++ b/source4/torture/raw/search.c -@@ -316,7 +316,11 @@ static bool test_one_file(struct torture_context *tctx, - - fnum = create_complex_file(cli, tctx, fname); - if (fnum == -1) { -- printf("ERROR: open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree)); -+ torture_result(tctx, -+ TORTURE_FAIL, -+ __location__"ERROR: open of %s failed (%s)\n", -+ fname, -+ smbcli_errstr(cli->tree)); - ret = false; - goto done; - } -@@ -343,9 +347,11 @@ static bool test_one_file(struct torture_context *tctx, - } - - if (!NT_STATUS_IS_OK(levels[i].status)) { -- printf("search level %s(%d) failed - %s\n", -- levels[i].name, (int)levels[i].level, -- nt_errstr(levels[i].status)); -+ torture_result(tctx, -+ TORTURE_FAIL, -+ __location__"search level %s(%d) failed - %s\n", -+ levels[i].name, (int)levels[i].level, -+ nt_errstr(levels[i].status)); - ret = false; - continue; - } -@@ -363,7 +369,9 @@ static bool test_one_file(struct torture_context *tctx, - expected_status = STATUS_NO_MORE_FILES; - } - if (!NT_STATUS_EQUAL(status, expected_status)) { -- printf("search level %s(%d) should fail with %s - %s\n", -+ torture_result(tctx, -+ TORTURE_FAIL, -+ __location__"search level %s(%d) should fail with %s - %s\n", - levels[i].name, (int)levels[i].level, - nt_errstr(expected_status), - nt_errstr(status)); -@@ -400,8 +408,10 @@ static bool test_one_file(struct torture_context *tctx, - s = find(name); \ - if (s) { \ - if ((s->sname1.field1) != (v.sname2.out.field2)) { \ -- printf("(%s) %s/%s [0x%x] != %s/%s [0x%x]\n", \ -- __location__, \ -+ torture_result(tctx,\ -+ TORTURE_FAIL,\ -+ "(%s) %s/%s [0x%x] != %s/%s [0x%x]\n", \ -+ __location__, \ - #sname1, #field1, (int)s->sname1.field1, \ - #sname2, #field2, (int)v.sname2.out.field2); \ - ret = false; \ -@@ -412,8 +422,10 @@ static bool test_one_file(struct torture_context *tctx, - s = find(name); \ - if (s) { \ - if (s->sname1.field1 != (~1 & nt_time_to_unix(v.sname2.out.field2))) { \ -- printf("(%s) %s/%s [%s] != %s/%s [%s]\n", \ -- __location__, \ -+ torture_result(tctx,\ -+ TORTURE_FAIL,\ -+ "(%s) %s/%s [%s] != %s/%s [%s]\n", \ -+ __location__, \ - #sname1, #field1, timestring(tctx, s->sname1.field1), \ - #sname2, #field2, nt_time_string(tctx, v.sname2.out.field2)); \ - ret = false; \ -@@ -424,8 +436,10 @@ static bool test_one_file(struct torture_context *tctx, - s = find(name); \ - if (s) { \ - if (s->sname1.field1 != v.sname2.out.field2) { \ -- printf("(%s) %s/%s [%s] != %s/%s [%s]\n", \ -- __location__, \ -+ torture_result(tctx,\ -+ TORTURE_FAIL,\ -+ "(%s) %s/%s [%s] != %s/%s [%s]\n", \ -+ __location__, \ - #sname1, #field1, nt_time_string(tctx, s->sname1.field1), \ - #sname2, #field2, nt_time_string(tctx, v.sname2.out.field2)); \ - ret = false; \ -@@ -436,8 +450,10 @@ static bool test_one_file(struct torture_context *tctx, - s = find(name); \ - if (s) { \ - if (!s->sname1.field1 || strcmp(s->sname1.field1, v.sname2.out.field2.s)) { \ -- printf("(%s) %s/%s [%s] != %s/%s [%s]\n", \ -- __location__, \ -+ torture_result(tctx,\ -+ TORTURE_FAIL,\ -+ "(%s) %s/%s [%s] != %s/%s [%s]\n", \ -+ __location__, \ - #sname1, #field1, s->sname1.field1, \ - #sname2, #field2, v.sname2.out.field2.s); \ - ret = false; \ -@@ -450,8 +466,10 @@ static bool test_one_file(struct torture_context *tctx, - if (!s->sname1.field1.s || \ - strcmp(s->sname1.field1.s, v.sname2.out.field2.s) || \ - wire_bad_flags(&s->sname1.field1, flags, cli->transport)) { \ -- printf("(%s) %s/%s [%s] != %s/%s [%s]\n", \ -- __location__, \ -+ torture_result(tctx,\ -+ TORTURE_FAIL,\ -+ "(%s) %s/%s [%s] != %s/%s [%s]\n", \ -+ __location__, \ - #sname1, #field1, s->sname1.field1.s, \ - #sname2, #field2, v.sname2.out.field2.s); \ - ret = false; \ -@@ -464,8 +482,10 @@ static bool test_one_file(struct torture_context *tctx, - if (!s->sname1.field1.s || \ - strcmp(s->sname1.field1.s, fname) || \ - wire_bad_flags(&s->sname1.field1, flags, cli->transport)) { \ -- printf("(%s) %s/%s [%s] != %s\n", \ -- __location__, \ -+ torture_result(tctx,\ -+ TORTURE_FAIL,\ -+ "(%s) %s/%s [%s] != %s\n", \ -+ __location__, \ - #sname1, #field1, s->sname1.field1.s, \ - fname); \ - ret = false; \ -@@ -477,8 +497,10 @@ static bool test_one_file(struct torture_context *tctx, - if (s) { \ - if (!s->sname1.field1 || \ - strcmp(s->sname1.field1, fname)) { \ -- printf("(%s) %s/%s [%s] != %s\n", \ -- __location__, \ -+ torture_result(tctx,\ -+ TORTURE_FAIL,\ -+ "(%s) %s/%s [%s] != %s\n", \ -+ __location__, \ - #sname1, #field1, s->sname1.field1, \ - fname); \ - ret = false; \ --- -2.25.1 - - -From 738c7080e78553b9f6eeef778522a1df9a88f977 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Fri, 19 Nov 2021 14:18:47 -0800 -Subject: [PATCH 80/99] CVE-2021-44141: s4: torture: In - raw.search:test_one_file() remove the leading '\\' in the test filenames. - -We'll soon be using this under SMB1+POSIX and neither Windows or POSIX -need a leading '\\' (and SMB1+POSIX sees the '\\' as part of the name). - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - source4/torture/raw/search.c | 22 +++++++++++----------- - 1 file changed, 11 insertions(+), 11 deletions(-) - -diff --git a/source4/torture/raw/search.c b/source4/torture/raw/search.c -index 07285893f40..9b140928689 100644 ---- a/source4/torture/raw/search.c -+++ b/source4/torture/raw/search.c -@@ -305,8 +305,8 @@ static bool test_one_file(struct torture_context *tctx, - { - bool ret = true; - int fnum; -- const char *fname = "\\torture_search.txt"; -- const char *fname2 = "\\torture_search-NOTEXIST.txt"; -+ const char *fname = "torture_search.txt"; -+ const char *fname2 = "torture_search-NOTEXIST.txt"; - NTSTATUS status; - int i; - union smb_fileinfo all_info, alt_info, name_info, internal_info; -@@ -581,20 +581,20 @@ static bool test_one_file(struct torture_context *tctx, - short_name, alt_info, alt_name_info, fname, STR_UNICODE); - } - -- CHECK_NAME("STANDARD", standard, name, fname+1, 0); -- CHECK_NAME("EA_SIZE", ea_size, name, fname+1, 0); -- CHECK_NAME("DIRECTORY_INFO", directory_info, name, fname+1, STR_TERMINATE_ASCII); -- CHECK_NAME("FULL_DIRECTORY_INFO", full_directory_info, name, fname+1, STR_TERMINATE_ASCII); -+ CHECK_NAME("STANDARD", standard, name, fname, 0); -+ CHECK_NAME("EA_SIZE", ea_size, name, fname, 0); -+ CHECK_NAME("DIRECTORY_INFO", directory_info, name, fname, STR_TERMINATE_ASCII); -+ CHECK_NAME("FULL_DIRECTORY_INFO", full_directory_info, name, fname, STR_TERMINATE_ASCII); - - if (name_info_supported) { -- CHECK_NAME("NAME_INFO", name_info, name, fname+1, -+ CHECK_NAME("NAME_INFO", name_info, name, fname, - STR_TERMINATE_ASCII); - } - -- CHECK_NAME("BOTH_DIRECTORY_INFO", both_directory_info, name, fname+1, STR_TERMINATE_ASCII); -- CHECK_NAME("ID_FULL_DIRECTORY_INFO", id_full_directory_info, name, fname+1, STR_TERMINATE_ASCII); -- CHECK_NAME("ID_BOTH_DIRECTORY_INFO", id_both_directory_info, name, fname+1, STR_TERMINATE_ASCII); -- CHECK_UNIX_NAME("UNIX_INFO", unix_info, name, fname+1, STR_TERMINATE_ASCII); -+ CHECK_NAME("BOTH_DIRECTORY_INFO", both_directory_info, name, fname, STR_TERMINATE_ASCII); -+ CHECK_NAME("ID_FULL_DIRECTORY_INFO", id_full_directory_info, name, fname, STR_TERMINATE_ASCII); -+ CHECK_NAME("ID_BOTH_DIRECTORY_INFO", id_both_directory_info, name, fname, STR_TERMINATE_ASCII); -+ CHECK_UNIX_NAME("UNIX_INFO", unix_info, name, fname, STR_TERMINATE_ASCII); - - if (internal_info_supported) { - CHECK_VAL("ID_FULL_DIRECTORY_INFO", id_full_directory_info, --- -2.25.1 - - -From 4fc4bd4f20cdfcf1df63f76f2f9940808b286c72 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Thu, 18 Nov 2021 11:48:42 -0800 -Subject: [PATCH 81/99] CVE-2021-44141: s3: smbd: Tighten up info level checks - for SMB1+POSIX to make sure POSIX was negotiated first. - -Add knownfail file - - knownfail.d/posix_infolevel_fails - -for tests that don't currently negotiate -SMB1+POSIX before using SMB1+POSIX calls. - -These are: - -samba3.smbtorture_s3.plain.POSIX-BLOCKING-LOCK.smbtorture\(nt4_dc_smb1\) -samba3.blackbox.acl_xattr.NT1.nt_affects_posix.* -samba3.blackbox.acl_xattr.NT1.nt_affects_chown.* -samba3.blackbox.acl_xattr.NT1.nt_affects_chgrp.* -samba3.blackbox.inherit_owner.*.NT1.*verify.*unix\ owner.* -samba3.unix.info2.info2\(nt4_dc_smb1\) -samba3.unix.info2.info2\(ad_dc_smb1\) -samba3.raw.search.one\ file\ search.* - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - selftest/knownfail.d/posix_infolevel_fails | 8 +++ - source3/smbd/trans2.c | 60 +++++++++++++++++++--- - 2 files changed, 62 insertions(+), 6 deletions(-) - create mode 100644 selftest/knownfail.d/posix_infolevel_fails - -diff --git a/selftest/knownfail.d/posix_infolevel_fails b/selftest/knownfail.d/posix_infolevel_fails -new file mode 100644 -index 00000000000..78a6781684c ---- /dev/null -+++ b/selftest/knownfail.d/posix_infolevel_fails -@@ -0,0 +1,8 @@ -+^samba3.smbtorture_s3.plain.POSIX-BLOCKING-LOCK.smbtorture\(nt4_dc_smb1\) -+^samba3.blackbox.acl_xattr.NT1.nt_affects_posix.* -+^samba3.blackbox.acl_xattr.NT1.nt_affects_chown.* -+^samba3.blackbox.acl_xattr.NT1.nt_affects_chgrp.* -+^samba3.blackbox.inherit_owner.*.NT1.*verify.*unix\ owner.* -+^samba3.unix.info2.info2\(nt4_dc_smb1\) -+^samba3.unix.info2.info2\(ad_dc_smb1\) -+^samba3.raw.search.one\ file\ search.* -diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c -index 3ba7011b989..33ba9da9f83 100644 ---- a/source3/smbd/trans2.c -+++ b/source3/smbd/trans2.c -@@ -2717,6 +2717,10 @@ close_if_end = %d requires_resume_key = %d backup_priv = %d level = 0x%x, max_da - reply_nterror(req, NT_STATUS_INVALID_LEVEL); - goto out; - } -+ if (!req->posix_pathnames) { -+ reply_nterror(req, NT_STATUS_INVALID_LEVEL); -+ goto out; -+ } - break; - default: - reply_nterror(req, NT_STATUS_INVALID_LEVEL); -@@ -3183,6 +3187,10 @@ resume_key = %d resume name = %s continue=%d level = %d\n", - reply_nterror(req, NT_STATUS_INVALID_LEVEL); - return; - } -+ if (!req->posix_pathnames) { -+ reply_nterror(req, NT_STATUS_INVALID_LEVEL); -+ return; -+ } - break; - default: - reply_nterror(req, NT_STATUS_INVALID_LEVEL); -@@ -5144,8 +5152,13 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, - uint32_t access_mask = 0; - size_t len = 0; - -- if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) { -- return NT_STATUS_INVALID_LEVEL; -+ if (INFO_LEVEL_IS_UNIX(info_level)) { -+ if (!lp_unix_extensions()) { -+ return NT_STATUS_INVALID_LEVEL; -+ } -+ if (!req->posix_pathnames) { -+ return NT_STATUS_INVALID_LEVEL; -+ } - } - - DEBUG(5,("smbd_do_qfilepathinfo: %s (%s) level=%d max_data=%u\n", -@@ -5958,9 +5971,15 @@ static void call_trans2qfilepathinfo(connection_struct *conn, - - DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level)); - -- if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) { -- reply_nterror(req, NT_STATUS_INVALID_LEVEL); -- return; -+ if (INFO_LEVEL_IS_UNIX(info_level)) { -+ if (!lp_unix_extensions()) { -+ reply_nterror(req, NT_STATUS_INVALID_LEVEL); -+ return; -+ } -+ if (!req->posix_pathnames) { -+ reply_nterror(req, NT_STATUS_INVALID_LEVEL); -+ return; -+ } - } - - /* Initial check for valid fsp ptr. */ -@@ -6053,6 +6072,10 @@ static void call_trans2qfilepathinfo(connection_struct *conn, - reply_nterror(req, NT_STATUS_INVALID_LEVEL); - return; - } -+ if (!req->posix_pathnames) { -+ reply_nterror(req, NT_STATUS_INVALID_LEVEL); -+ return; -+ } - } - - if (req->posix_pathnames) { -@@ -9061,7 +9084,9 @@ NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn, - if (!lp_unix_extensions()) { - return NT_STATUS_INVALID_LEVEL; - } -- -+ if (!req->posix_pathnames) { -+ return NT_STATUS_INVALID_LEVEL; -+ } - status = smbd_do_posix_setfilepathinfo(conn, - req, - req, -@@ -9282,6 +9307,17 @@ static void call_trans2setfilepathinfo(connection_struct *conn, - } - info_level = SVAL(params,2); - -+ if (INFO_LEVEL_IS_UNIX(info_level)) { -+ if (!lp_unix_extensions()) { -+ reply_nterror(req, NT_STATUS_INVALID_LEVEL); -+ return; -+ } -+ if (!req->posix_pathnames) { -+ reply_nterror(req, NT_STATUS_INVALID_LEVEL); -+ return; -+ } -+ } -+ - smb_fname = fsp->fsp_name; - - if (fsp_get_pathref_fd(fsp) == -1) { -@@ -9360,6 +9396,18 @@ static void call_trans2setfilepathinfo(connection_struct *conn, - } - - info_level = SVAL(params,0); -+ -+ if (INFO_LEVEL_IS_UNIX(info_level)) { -+ if (!lp_unix_extensions()) { -+ reply_nterror(req, NT_STATUS_INVALID_LEVEL); -+ return; -+ } -+ if (!req->posix_pathnames) { -+ reply_nterror(req, NT_STATUS_INVALID_LEVEL); -+ return; -+ } -+ } -+ - if (req->posix_pathnames) { - srvstr_get_path_posix(req, - params, --- -2.25.1 - - -From c032a254bb5b703f510c42880ea5416982df9577 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Sat, 20 Nov 2021 20:17:11 -0800 -Subject: [PATCH 82/99] CVE-2021-44141: s3: smbclient: Give a message if we try - and use any POSIX command without negotiating POSIX first. - -Ensure we only use a POSIX command if POSIX is set up. -Issue the message: Command "posix" must be issued before the "XXXX" command can be used. -After the parameter parsing has been done. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - source3/client/client.c | 79 +++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 79 insertions(+) - -diff --git a/source3/client/client.c b/source3/client/client.c -index a8e11044b39..5ad6ee7b844 100644 ---- a/source3/client/client.c -+++ b/source3/client/client.c -@@ -2839,6 +2839,11 @@ static int cmd_posix_open(void) - d_printf("posix_open 0\n"); - return 1; - } -+ if (CLI_DIRSEP_CHAR != '/') { -+ d_printf("Command \"posix\" must be issued before " -+ "the \"posix_open\" command can be used.\n"); -+ return 1; -+ } - mode = (mode_t)strtol(buf, (char **)NULL, 8); - - status = cli_resolve_path(ctx, "", -@@ -2900,6 +2905,11 @@ static int cmd_posix_mkdir(void) - d_printf("posix_mkdir 0\n"); - return 1; - } -+ if (CLI_DIRSEP_CHAR != '/') { -+ d_printf("Command \"posix\" must be issued before " -+ "the \"posix_mkdir\" command can be used.\n"); -+ return 1; -+ } - mode = (mode_t)strtol(buf, (char **)NULL, 8); - - status = cli_resolve_path(ctx, "", -@@ -2934,6 +2944,11 @@ static int cmd_posix_unlink(void) - d_printf("posix_unlink \n"); - return 1; - } -+ if (CLI_DIRSEP_CHAR != '/') { -+ d_printf("Command \"posix\" must be issued before " -+ "the \"posix_unlink\" command can be used.\n"); -+ return 1; -+ } - mask = talloc_asprintf(ctx, - "%s%s", - client_get_cur_dir(), -@@ -2979,6 +2994,11 @@ static int cmd_posix_rmdir(void) - d_printf("posix_rmdir \n"); - return 1; - } -+ if (CLI_DIRSEP_CHAR != '/') { -+ d_printf("Command \"posix\" must be issued before " -+ "the \"posix_rmdir\" command can be used.\n"); -+ return 1; -+ } - mask = talloc_asprintf(ctx, - "%s%s", - client_get_cur_dir(), -@@ -3178,6 +3198,12 @@ static int cmd_lock(void) - return 1; - } - -+ if (CLI_DIRSEP_CHAR != '/') { -+ d_printf("Command \"posix\" must be issued before " -+ "the \"lock\" command can be used.\n"); -+ return 1; -+ } -+ - len = (uint64_t)strtol(buf, (char **)NULL, 16); - - status = cli_posix_lock(cli, fnum, start, len, true, lock_type); -@@ -3214,6 +3240,12 @@ static int cmd_unlock(void) - return 1; - } - -+ if (CLI_DIRSEP_CHAR != '/') { -+ d_printf("Command \"posix\" must be issued before " -+ "the \"unlock\" command can be used.\n"); -+ return 1; -+ } -+ - len = (uint64_t)strtol(buf, (char **)NULL, 16); - - status = cli_posix_unlock(cli, fnum, start, len); -@@ -3237,6 +3269,12 @@ static int cmd_posix_whoami(void) - bool guest = false; - uint32_t i; - -+ if (CLI_DIRSEP_CHAR != '/') { -+ d_printf("Command \"posix\" must be issued before " -+ "the \"posix_whoami\" command can be used.\n"); -+ return 1; -+ } -+ - status = cli_posix_whoami(cli, - ctx, - &uid, -@@ -3374,6 +3412,12 @@ static int cmd_link(void) - return 1; - } - -+ if (CLI_DIRSEP_CHAR != '/') { -+ d_printf("Command \"posix\" must be issued before " -+ "the \"link\" command can be used.\n"); -+ return 1; -+ } -+ - status = cli_posix_hardlink(targetcli, targetname, newname); - if (!NT_STATUS_IS_OK(status)) { - d_printf("%s linking files (%s -> %s)\n", -@@ -3427,6 +3471,12 @@ static int cmd_readlink(void) - return 1; - } - -+ if (CLI_DIRSEP_CHAR != '/') { -+ d_printf("Command \"posix\" must be issued before " -+ "the \"readlink\" command can be used.\n"); -+ return 1; -+ } -+ - status = cli_posix_readlink(targetcli, name, talloc_tos(), &linkname); - if (!NT_STATUS_IS_OK(status)) { - d_printf("%s readlink on file %s\n", -@@ -3466,6 +3516,11 @@ static int cmd_symlink(void) - link_target = buf; - - if (SERVER_HAS_UNIX_CIFS(cli)) { -+ if (CLI_DIRSEP_CHAR != '/') { -+ d_printf("Command \"posix\" must be issued before " -+ "the \"symlink\" command can be used.\n"); -+ return 1; -+ } - newname = talloc_asprintf(ctx, "%s%s", client_get_cur_dir(), - buf2); - if (!newname) { -@@ -3549,6 +3604,12 @@ static int cmd_chmod(void) - return 1; - } - -+ if (CLI_DIRSEP_CHAR != '/') { -+ d_printf("Command \"posix\" must be issued before " -+ "the \"chmod\" command can be used.\n"); -+ return 1; -+ } -+ - status = cli_posix_chmod(targetcli, targetname, mode); - if (!NT_STATUS_IS_OK(status)) { - d_printf("%s chmod file %s 0%o\n", -@@ -3713,6 +3774,12 @@ static int cmd_getfacl(void) - return 1; - } - -+ if (CLI_DIRSEP_CHAR != '/') { -+ d_printf("Command \"posix\" must be issued before " -+ "the \"getfacl\" command can be used.\n"); -+ return 1; -+ } -+ - status = cli_unix_extensions_version(targetcli, &major, &minor, - &caplow, &caphigh); - if (!NT_STATUS_IS_OK(status)) { -@@ -4012,6 +4079,12 @@ static int cmd_stat(void) - return 1; - } - -+ if (CLI_DIRSEP_CHAR != '/') { -+ d_printf("Command \"posix\" must be issued before " -+ "the \"stat\" command can be used.\n"); -+ return 1; -+ } -+ - status = cli_posix_stat(targetcli, targetname, &sbuf); - if (!NT_STATUS_IS_OK(status)) { - d_printf("%s stat file %s\n", -@@ -4126,6 +4199,12 @@ static int cmd_chown(void) - return 1; - } - -+ if (CLI_DIRSEP_CHAR != '/') { -+ d_printf("Command \"posix\" must be issued before " -+ "the \"chown\" command can be used.\n"); -+ return 1; -+ } -+ - status = cli_posix_chown(targetcli, targetname, uid, gid); - if (!NT_STATUS_IS_OK(status)) { - d_printf("%s chown file %s uid=%d, gid=%d\n", --- -2.25.1 - - -From bfcf165b29b30dd1f8037ab0f9a9e03731d2642f Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Fri, 19 Nov 2021 14:44:05 -0800 -Subject: [PATCH 83/99] CVE-2021-44141: s4: torture: In - raw.search:test_one_file() add a second connection. - -Change from torture_suite_add_1smb_test() to torture_suite_add_2smb_test(). - -Not yet used. We will need this to do SMB1+POSIX search calls on -a connection on which we have negotiated SMB1+POSIX. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - source4/torture/raw/search.c | 7 ++++--- - 1 file changed, 4 insertions(+), 3 deletions(-) - -diff --git a/source4/torture/raw/search.c b/source4/torture/raw/search.c -index 9b140928689..f6ad569dd4b 100644 ---- a/source4/torture/raw/search.c -+++ b/source4/torture/raw/search.c -@@ -300,8 +300,9 @@ static union smb_search_data *find(const char *name) - /* - basic testing of all RAW_SEARCH_* calls using a single file - */ --static bool test_one_file(struct torture_context *tctx, -- struct smbcli_state *cli) -+static bool test_one_file(struct torture_context *tctx, -+ struct smbcli_state *cli, -+ struct smbcli_state *cli_unix) - { - bool ret = true; - int fnum; -@@ -1571,7 +1572,7 @@ struct torture_suite *torture_raw_search(TALLOC_CTX *mem_ctx) - { - struct torture_suite *suite = torture_suite_create(mem_ctx, "search"); - -- torture_suite_add_1smb_test(suite, "one file search", test_one_file); -+ torture_suite_add_2smb_test(suite, "one file search", test_one_file); - torture_suite_add_1smb_test(suite, "many files", test_many_files); - torture_suite_add_1smb_test(suite, "sorted", test_sorted); - torture_suite_add_1smb_test(suite, "modify search", test_modify_search); --- -2.25.1 - - -From 08c40af638154fa009e6b6f526a357b10ba7e3ba Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Fri, 19 Nov 2021 14:48:20 -0800 -Subject: [PATCH 84/99] CVE-2021-44141: s4: torture: raw.search: Add - setup_smb1_posix(). Call it on the second connection in test_one_file(). - -Not yet used. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - source4/torture/raw/search.c | 59 ++++++++++++++++++++++++++++++++++++ - 1 file changed, 59 insertions(+) - -diff --git a/source4/torture/raw/search.c b/source4/torture/raw/search.c -index f6ad569dd4b..3f7de80ad0f 100644 ---- a/source4/torture/raw/search.c -+++ b/source4/torture/raw/search.c -@@ -297,6 +297,55 @@ static union smb_search_data *find(const char *name) - return NULL; - } - -+/* -+ * Negotiate SMB1+POSIX. -+ */ -+ -+static NTSTATUS setup_smb1_posix(struct torture_context *tctx, -+ struct smbcli_state *cli_unix) -+{ -+ struct smb_trans2 tp; -+ uint16_t setup; -+ uint8_t data[12]; -+ uint8_t params[4]; -+ uint32_t cap = cli_unix->transport->negotiate.capabilities; -+ -+ if ((cap & CAP_UNIX) == 0) { -+ /* -+ * Server doesn't support SMB1+POSIX. -+ * The caller will skip the UNIX info -+ * level anyway. -+ */ -+ torture_comment(tctx, -+ "Server doesn't support SMB1+POSIX\n"); -+ return NT_STATUS_OK; -+ } -+ -+ /* Setup POSIX on this connection. */ -+ SSVAL(data, 0, CIFS_UNIX_MAJOR_VERSION); -+ SSVAL(data, 2, CIFS_UNIX_MINOR_VERSION); -+ SBVAL(data,4,((uint64_t)( -+ CIFS_UNIX_POSIX_ACLS_CAP| -+ CIFS_UNIX_POSIX_PATHNAMES_CAP| -+ CIFS_UNIX_FCNTL_LOCKS_CAP| -+ CIFS_UNIX_EXTATTR_CAP| -+ CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP))); -+ setup = TRANSACT2_SETFSINFO; -+ tp.in.max_setup = 0; -+ tp.in.flags = 0; -+ tp.in.timeout = 0; -+ tp.in.setup_count = 1; -+ tp.in.max_param = 0; -+ tp.in.max_data = 0; -+ tp.in.setup = &setup; -+ tp.in.trans_name = NULL; -+ SSVAL(params, 0, 0); -+ SSVAL(params, 2, SMB_SET_CIFS_UNIX_INFO); -+ tp.in.params = data_blob_talloc(tctx, params, 4); -+ tp.in.data = data_blob_talloc(tctx, data, 12); -+ return smb_raw_trans2(cli_unix->tree, tctx, &tp); -+} -+ - /* - basic testing of all RAW_SEARCH_* calls using a single file - */ -@@ -315,6 +364,16 @@ static bool test_one_file(struct torture_context *tctx, - internal_info_supported; - union smb_search_data *s; - -+ status = setup_smb1_posix(tctx, cli_unix); -+ if (!NT_STATUS_IS_OK(status)) { -+ torture_result(tctx, -+ TORTURE_FAIL, -+ __location__"setup_smb1_posix() failed (%s)\n", -+ nt_errstr(status)); -+ ret = false; -+ goto done; -+ } -+ - fnum = create_complex_file(cli, tctx, fname); - if (fnum == -1) { - torture_result(tctx, --- -2.25.1 - - -From a7b6aa7d1f20dfb565605d662404d3988c83e5c8 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Fri, 19 Nov 2021 14:51:39 -0800 -Subject: [PATCH 85/99] CVE-2021-44141: s4: torture: Fix - raw.search:test_one_file() by using the SMB1+POSIX connection for POSIX info - levels. - -Remove the following entry in knownfail.d/posix_infolevel_fails. - - ^samba3.raw.search.one\ file\ search.* - -from knownfail.d/posix_infolevel_fails - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - selftest/knownfail.d/posix_infolevel_fails | 1 - - source4/torture/raw/search.c | 13 +++++++++++-- - 2 files changed, 11 insertions(+), 3 deletions(-) - -diff --git a/selftest/knownfail.d/posix_infolevel_fails b/selftest/knownfail.d/posix_infolevel_fails -index 78a6781684c..4ce4a9cec91 100644 ---- a/selftest/knownfail.d/posix_infolevel_fails -+++ b/selftest/knownfail.d/posix_infolevel_fails -@@ -5,4 +5,3 @@ - ^samba3.blackbox.inherit_owner.*.NT1.*verify.*unix\ owner.* - ^samba3.unix.info2.info2\(nt4_dc_smb1\) - ^samba3.unix.info2.info2\(ad_dc_smb1\) --^samba3.raw.search.one\ file\ search.* -diff --git a/source4/torture/raw/search.c b/source4/torture/raw/search.c -index 3f7de80ad0f..575bbd03fb7 100644 ---- a/source4/torture/raw/search.c -+++ b/source4/torture/raw/search.c -@@ -389,10 +389,19 @@ static bool test_one_file(struct torture_context *tctx, - for (i=0;itransport->negotiate.capabilities; -+ struct smbcli_state *cli_search = cli; - - torture_comment(tctx, "Testing %s\n", levels[i].name); - -- levels[i].status = torture_single_search(cli, tctx, fname, -+ if (levels[i].data_level == RAW_SEARCH_DATA_UNIX_INFO) { -+ /* -+ * For an SMB1+POSIX info level, use the cli_unix -+ * connection. -+ */ -+ cli_search = cli_unix; -+ } -+ -+ levels[i].status = torture_single_search(cli_search, tctx, fname, - levels[i].level, - levels[i].data_level, - 0, -@@ -416,7 +425,7 @@ static bool test_one_file(struct torture_context *tctx, - continue; - } - -- status = torture_single_search(cli, tctx, fname2, -+ status = torture_single_search(cli_search, tctx, fname2, - levels[i].level, - levels[i].data_level, - 0, --- -2.25.1 - - -From 300abd383ea7fc0b1b8c59d5a8c90201f216dcd6 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Fri, 19 Nov 2021 12:15:06 -0800 -Subject: [PATCH 86/99] CVE-2021-44141: s4: torture: Fix unix.info2 test to - actually negotiate SMB1+POSIX before using POSIX calls. - -Cope with the minor difference in wildcard search return when -we're actually using SMB1+POSIX on the server (SMB1+POSIX treats -all directory search paths as wildcards). - -Remove the following entries in knownfail.d/posix_infolevel_fails. - - samba3.unix.info2.info2\(nt4_dc_smb1\) - samba3.unix.info2.info2\(ad_dc_smb1\) - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - selftest/knownfail.d/posix_infolevel_fails | 2 -- - source4/torture/unix/unix_info2.c | 42 ++++++++++++++++++++-- - 2 files changed, 40 insertions(+), 4 deletions(-) - -diff --git a/selftest/knownfail.d/posix_infolevel_fails b/selftest/knownfail.d/posix_infolevel_fails -index 4ce4a9cec91..3bfff110771 100644 ---- a/selftest/knownfail.d/posix_infolevel_fails -+++ b/selftest/knownfail.d/posix_infolevel_fails -@@ -3,5 +3,3 @@ - ^samba3.blackbox.acl_xattr.NT1.nt_affects_chown.* - ^samba3.blackbox.acl_xattr.NT1.nt_affects_chgrp.* - ^samba3.blackbox.inherit_owner.*.NT1.*verify.*unix\ owner.* --^samba3.unix.info2.info2\(nt4_dc_smb1\) --^samba3.unix.info2.info2\(ad_dc_smb1\) -diff --git a/source4/torture/unix/unix_info2.c b/source4/torture/unix/unix_info2.c -index 6b275435551..2098b225e7f 100644 ---- a/source4/torture/unix/unix_info2.c -+++ b/source4/torture/unix/unix_info2.c -@@ -19,6 +19,7 @@ - - #include "includes.h" - #include "libcli/libcli.h" -+#include "libcli/raw/raw_proto.h" - #include "torture/util.h" - #include "torture/unix/proto.h" - #include "lib/cmdline/cmdline.h" -@@ -53,6 +54,10 @@ static struct smbcli_state *connect_to_server(struct torture_context *tctx) - const char *share = torture_setting_string(tctx, "share", NULL); - struct smbcli_options options; - struct smbcli_session_options session_options; -+ struct smb_trans2 tp; -+ uint16_t setup; -+ uint8_t data[12]; -+ uint8_t params[4]; - - lpcfg_smbcli_options(tctx->lp_ctx, &options); - lpcfg_smbcli_session_options(tctx->lp_ctx, &session_options); -@@ -72,6 +77,33 @@ static struct smbcli_state *connect_to_server(struct torture_context *tctx) - return NULL; - } - -+ /* Setup POSIX on the server. */ -+ SSVAL(data, 0, CIFS_UNIX_MAJOR_VERSION); -+ SSVAL(data, 2, CIFS_UNIX_MINOR_VERSION); -+ SBVAL(data,4,((uint64_t)( -+ CIFS_UNIX_POSIX_ACLS_CAP| -+ CIFS_UNIX_POSIX_PATHNAMES_CAP| -+ CIFS_UNIX_FCNTL_LOCKS_CAP| -+ CIFS_UNIX_EXTATTR_CAP| -+ CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP))); -+ setup = TRANSACT2_SETFSINFO; -+ tp.in.max_setup = 0; -+ tp.in.flags = 0; -+ tp.in.timeout = 0; -+ tp.in.setup_count = 1; -+ tp.in.max_param = 0; -+ tp.in.max_data = 0; -+ tp.in.setup = &setup; -+ tp.in.trans_name = NULL; -+ SSVAL(params, 0, 0); -+ SSVAL(params, 2, SMB_SET_CIFS_UNIX_INFO); -+ tp.in.params = data_blob_talloc(tctx, params, 4); -+ tp.in.data = data_blob_talloc(tctx, data, 12); -+ -+ status = smb_raw_trans2(cli->tree, tctx, &tp); -+ torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OK, -+ "doing SMB_SET_CIFS_UNIX_INFO"); -+ - return cli; - } - -@@ -245,8 +277,14 @@ static bool find_single_info2(void *mem_ctx, - - torture_assert_int_equal(torture, search.t2ffirst.out.count, 1, - "expected exactly one result"); -- torture_assert_int_equal(torture, search.t2ffirst.out.end_of_search, 1, -- "expected end_of_search to be true"); -+ /* -+ * In smbd directory listings using POSIX extensions -+ * always treat the search pathname as a wildcard, -+ * so don't expect end_of_search to be set here. Wildcard -+ * searches always need a findnext to end the search. -+ */ -+ torture_assert_int_equal(torture, search.t2ffirst.out.end_of_search, 0, -+ "expected end_of_search to be false"); - - return check_unix_info2(torture, info2); - } --- -2.25.1 - - -From a180e5726d598192e99ac4a26a2a3752bf7ac7c7 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Fri, 19 Nov 2021 12:12:36 -0800 -Subject: [PATCH 87/99] CVE-2021-44141: s3: tests: Fix the - samba3.blackbox.inherit_owner test to actually negotiate SMB1+POSIX before - using POSIX calls. - -Remove the following entry in knownfail.d/posix_infolevel_fails. - - samba3.blackbox.inherit_owner.*.NT1.*verify.*unix\ owner.* - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - selftest/knownfail.d/posix_infolevel_fails | 1 - - source3/script/tests/test_inherit_owner.sh | 2 +- - 2 files changed, 1 insertion(+), 2 deletions(-) - -diff --git a/selftest/knownfail.d/posix_infolevel_fails b/selftest/knownfail.d/posix_infolevel_fails -index 3bfff110771..a865a2055b2 100644 ---- a/selftest/knownfail.d/posix_infolevel_fails -+++ b/selftest/knownfail.d/posix_infolevel_fails -@@ -2,4 +2,3 @@ - ^samba3.blackbox.acl_xattr.NT1.nt_affects_posix.* - ^samba3.blackbox.acl_xattr.NT1.nt_affects_chown.* - ^samba3.blackbox.acl_xattr.NT1.nt_affects_chgrp.* --^samba3.blackbox.inherit_owner.*.NT1.*verify.*unix\ owner.* -diff --git a/source3/script/tests/test_inherit_owner.sh b/source3/script/tests/test_inherit_owner.sh -index 7e1333787aa..9783235883c 100755 ---- a/source3/script/tests/test_inherit_owner.sh -+++ b/source3/script/tests/test_inherit_owner.sh -@@ -79,7 +79,7 @@ unix_owner_id_is() { - local fname=$2 - local expected_id=$3 - local actual_id -- actual_id=$($SMBCLIENT //$SERVER/$share -U $USERNAME%$PASSWORD -c "getfacl $fname" 2>/dev/null | sed -rn 's/^# owner: (.*)/\1/p') -+ actual_id=$($SMBCLIENT //$SERVER/$share -U $USERNAME%$PASSWORD -c "posix; getfacl $fname" 2>/dev/null | sed -rn 's/^# owner: (.*)/\1/p') - if ! test "x$actual_id" = "x$expected_id" ; then - echo "Actual uid of $share/$fname is [$actual_id] expected [$expected_id]" - exit 1 --- -2.25.1 - - -From c7aa173d2a44b3cf254b3739c7aedc2d5c8c0d58 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Fri, 19 Nov 2021 00:05:35 -0800 -Subject: [PATCH 88/99] CVE-2021-44141: s3: tests: Fix the - samba3.blackbox.acl_xattr test to actually negotiate SMB1+POSIX before using - POSIX calls. - -Remove the following entries in knownfail.d/posix_infolevel_fails. - - samba3.blackbox.acl_xattr.NT1.nt_affects_posix.* - samba3.blackbox.acl_xattr.NT1.nt_affects_chown.* - samba3.blackbox.acl_xattr.NT1.nt_affects_chgrp.* - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - selftest/knownfail.d/posix_infolevel_fails | 3 --- - source3/script/tests/test_acl_xattr.sh | 12 ++++++------ - 2 files changed, 6 insertions(+), 9 deletions(-) - -diff --git a/selftest/knownfail.d/posix_infolevel_fails b/selftest/knownfail.d/posix_infolevel_fails -index a865a2055b2..bf8a884cb16 100644 ---- a/selftest/knownfail.d/posix_infolevel_fails -+++ b/selftest/knownfail.d/posix_infolevel_fails -@@ -1,4 +1 @@ - ^samba3.smbtorture_s3.plain.POSIX-BLOCKING-LOCK.smbtorture\(nt4_dc_smb1\) --^samba3.blackbox.acl_xattr.NT1.nt_affects_posix.* --^samba3.blackbox.acl_xattr.NT1.nt_affects_chown.* --^samba3.blackbox.acl_xattr.NT1.nt_affects_chgrp.* -diff --git a/source3/script/tests/test_acl_xattr.sh b/source3/script/tests/test_acl_xattr.sh -index f134ff79c91..8abd7476244 100755 ---- a/source3/script/tests/test_acl_xattr.sh -+++ b/source3/script/tests/test_acl_xattr.sh -@@ -55,9 +55,9 @@ nt_affects_posix() { - local b4 - local af - local fname="$share.$$" -- b4=$($SMBCLIENT //$SERVER/$share -U $USERNAME%$PASSWORD -c "getfacl $fname" 2>/dev/null) || exit 1 -+ b4=$($SMBCLIENT //$SERVER/$share -U $USERNAME%$PASSWORD -c "posix; getfacl $fname" 2>/dev/null) || exit 1 - $SMBCACLS //$SERVER/$share $fname -U $USERNAME%$PASSWORD -a "ACL:$SERVER\force_user:ALLOWED/0x0/READ" 2>/dev/null || exit 1 -- af=$($SMBCLIENT //$SERVER/$share -U $USERNAME%$PASSWORD -c "getfacl $fname" 2>/dev/null) || exit 1 -+ af=$($SMBCLIENT //$SERVER/$share -U $USERNAME%$PASSWORD -c "posix; getfacl $fname" 2>/dev/null) || exit 1 - echo "before: $b4" - echo "after: $af" - echo "${b4}" | grep -q "^# owner:" || exit 1 -@@ -90,12 +90,12 @@ nt_affects_chown() { - #basic sanity... - test "$b4_expected != $af_expected" || exit 1 - -- b4_actual=$($SMBCLIENT //$SERVER/$share -U $USERNAME%$PASSWORD -c "getfacl $fname" 2>/dev/null) || exit 1 -+ b4_actual=$($SMBCLIENT //$SERVER/$share -U $USERNAME%$PASSWORD -c "posix; getfacl $fname" 2>/dev/null) || exit 1 - echo "${b4_actual}" | grep -q "^# owner:" || exit 1 - b4_actual=$(echo "$b4_actual" | sed -rn 's/^# owner: (.*)/\1/p') - $SMBCACLS //$SERVER/$share $fname -U $USERNAME%$PASSWORD -a "ACL:$SERVER\force_user:ALLOWED/0x0/FULL" || exit 1 - $SMBCACLS //$SERVER/$share $fname -U force_user%$PASSWORD -C force_user 2>/dev/null || exit 1 -- af_actual=$($SMBCLIENT //$SERVER/$share -U $USERNAME%$PASSWORD -c "getfacl $fname" 2>/dev/null) || exit 1 -+ af_actual=$($SMBCLIENT //$SERVER/$share -U $USERNAME%$PASSWORD -c "posix; getfacl $fname" 2>/dev/null) || exit 1 - echo "${af_actual}" | grep -q "^# owner:" || exit 1 - af_actual=$(echo "$af_actual" | sed -rn 's/^# owner: (.*)/\1/p') - echo "before: $b4_actual" -@@ -124,11 +124,11 @@ nt_affects_chgrp() { - #basic sanity... - test "$b4_expected" != "$af_expected" || exit 1 - -- b4_actual=$($SMBCLIENT //$SERVER/$share -U $USERNAME%$PASSWORD -c "getfacl $fname" 2>/dev/null) || exit 1 -+ b4_actual=$($SMBCLIENT //$SERVER/$share -U $USERNAME%$PASSWORD -c "posix; getfacl $fname" 2>/dev/null) || exit 1 - echo "${b4_actual}" | grep -q "^# group:" || exit 1 - b4_actual=$(echo "$b4_actual" | sed -rn 's/^# group: (.*)/\1/p') - $SMBCACLS //$SERVER/$share $fname -U $USERNAME%$PASSWORD -G domadmins 2>/dev/null || exit 1 -- af_actual=$($SMBCLIENT //$SERVER/$share -U $USERNAME%$PASSWORD -c "getfacl $fname" 2>/dev/null) || exit 1 -+ af_actual=$($SMBCLIENT //$SERVER/$share -U $USERNAME%$PASSWORD -c "posix; getfacl $fname" 2>/dev/null) || exit 1 - echo "${af_actual}" | grep -q "^# group:" || exit 1 - af_actual=$(echo "$af_actual" | sed -rn 's/^# group: (.*)/\1/p') - echo "before: $b4_actual" --- -2.25.1 - - -From 3e0d40f5481f2343fa93e204f2c432e1a2335c98 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Thu, 18 Nov 2021 12:16:44 -0800 -Subject: [PATCH 89/99] CVE-2021-44141: s3: smbtorture3: Fix - POSIX-BLOCKING-LOCK to actually negotiate SMB1+POSIX before using POSIX - calls. - -This must be done before doing POSIX calls on a connection. - -Remove the final entry in knownfail.d/posix_infolevel_fails - - samba3.smbtorture_s3.plain.POSIX-BLOCKING-LOCK.smbtorture\(nt4_dc_smb1\) - -And remove the file knownfail.d/posix_infolevel_fails itself. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - selftest/knownfail.d/posix_infolevel_fails | 1 - - source3/torture/torture.c | 5 +++++ - 2 files changed, 5 insertions(+), 1 deletion(-) - delete mode 100644 selftest/knownfail.d/posix_infolevel_fails - -diff --git a/selftest/knownfail.d/posix_infolevel_fails b/selftest/knownfail.d/posix_infolevel_fails -deleted file mode 100644 -index bf8a884cb16..00000000000 ---- a/selftest/knownfail.d/posix_infolevel_fails -+++ /dev/null -@@ -1 +0,0 @@ --^samba3.smbtorture_s3.plain.POSIX-BLOCKING-LOCK.smbtorture\(nt4_dc_smb1\) -diff --git a/source3/torture/torture.c b/source3/torture/torture.c -index 0d3b01326b1..e3d26ddb261 100644 ---- a/source3/torture/torture.c -+++ b/source3/torture/torture.c -@@ -8929,6 +8929,11 @@ static bool run_posix_blocking_lock(int dummy) - return false; - } - -+ status = torture_setup_unix_extensions(cli2); -+ if (!NT_STATUS_IS_OK(status)) { -+ return false; -+ } -+ - cli_setatr(cli1, fname, 0, 0); - cli_posix_unlink(cli1, fname); - --- -2.25.1 - - -From 9e90f31639a71ba4c8099c9da4ad25102a36873b Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Tue, 7 Dec 2021 12:28:54 -0800 -Subject: [PATCH 90/99] CVE-2021-44141: s3: torture: Add - samba3.blackbox.test_symlink_traversal.SMB2. - -Add to knownfail.d/symlink_traversal - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - selftest/knownfail.d/symlink_traversal | 1 + - .../tests/test_symlink_traversal_smb2.sh | 263 ++++++++++++++++++ - source3/selftest/tests.py | 6 + - 3 files changed, 270 insertions(+) - create mode 100644 selftest/knownfail.d/symlink_traversal - create mode 100755 source3/script/tests/test_symlink_traversal_smb2.sh - -diff --git a/selftest/knownfail.d/symlink_traversal b/selftest/knownfail.d/symlink_traversal -new file mode 100644 -index 00000000000..a8ac4bbae1f ---- /dev/null -+++ b/selftest/knownfail.d/symlink_traversal -@@ -0,0 +1 @@ -+^samba3.blackbox.test_symlink_traversal.SMB2.symlink_traversal_SMB2\(fileserver\) -diff --git a/source3/script/tests/test_symlink_traversal_smb2.sh b/source3/script/tests/test_symlink_traversal_smb2.sh -new file mode 100755 -index 00000000000..7e1de6dde1a ---- /dev/null -+++ b/source3/script/tests/test_symlink_traversal_smb2.sh -@@ -0,0 +1,263 @@ -+#!/bin/sh -+ -+if [ $# -lt 7 ]; then -+cat < "$tmpfile" < -Date: Tue, 7 Dec 2021 12:32:19 -0800 -Subject: [PATCH 91/99] CVE-2021-44141: s3: torture: Add - samba3.blackbox.test_symlink_traversal.SMB1. - -Add to knownfail.d/symlink_traversal. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - selftest/knownfail.d/symlink_traversal | 1 + - .../tests/test_symlink_traversal_smb1.sh | 263 ++++++++++++++++++ - source3/selftest/tests.py | 4 + - 3 files changed, 268 insertions(+) - create mode 100755 source3/script/tests/test_symlink_traversal_smb1.sh - -diff --git a/selftest/knownfail.d/symlink_traversal b/selftest/knownfail.d/symlink_traversal -index a8ac4bbae1f..2a51ff3f91d 100644 ---- a/selftest/knownfail.d/symlink_traversal -+++ b/selftest/knownfail.d/symlink_traversal -@@ -1 +1,2 @@ - ^samba3.blackbox.test_symlink_traversal.SMB2.symlink_traversal_SMB2\(fileserver\) -+^samba3.blackbox.test_symlink_traversal.SMB1.symlink_traversal_SMB1\(fileserver_smb1_done\) -diff --git a/source3/script/tests/test_symlink_traversal_smb1.sh b/source3/script/tests/test_symlink_traversal_smb1.sh -new file mode 100755 -index 00000000000..1deaaccbb54 ---- /dev/null -+++ b/source3/script/tests/test_symlink_traversal_smb1.sh -@@ -0,0 +1,263 @@ -+#!/bin/sh -+ -+if [ $# -lt 7 ]; then -+cat < "$tmpfile" < -Date: Tue, 7 Dec 2021 12:34:38 -0800 -Subject: [PATCH 92/99] CVE-2021-44141: s3: torture: Add - samba3.blackbox.test_symlink_traversal.SMB1.posix - -Add to knownfail.d/symlink_traversal. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - selftest/knownfail.d/symlink_traversal | 1 + - .../test_symlink_traversal_smb1_posix.sh | 270 ++++++++++++++++++ - source3/selftest/tests.py | 5 + - 3 files changed, 276 insertions(+) - create mode 100755 source3/script/tests/test_symlink_traversal_smb1_posix.sh - -diff --git a/selftest/knownfail.d/symlink_traversal b/selftest/knownfail.d/symlink_traversal -index 2a51ff3f91d..25a4da8f250 100644 ---- a/selftest/knownfail.d/symlink_traversal -+++ b/selftest/knownfail.d/symlink_traversal -@@ -1,2 +1,3 @@ - ^samba3.blackbox.test_symlink_traversal.SMB2.symlink_traversal_SMB2\(fileserver\) - ^samba3.blackbox.test_symlink_traversal.SMB1.symlink_traversal_SMB1\(fileserver_smb1_done\) -+^samba3.blackbox.test_symlink_traversal.SMB1.posix.symlink_traversal_SMB1_posix\(fileserver_smb1_done\) -diff --git a/source3/script/tests/test_symlink_traversal_smb1_posix.sh b/source3/script/tests/test_symlink_traversal_smb1_posix.sh -new file mode 100755 -index 00000000000..6241434dcf6 ---- /dev/null -+++ b/source3/script/tests/test_symlink_traversal_smb1_posix.sh -@@ -0,0 +1,270 @@ -+#!/bin/sh -+ -+if [ $# -lt 7 ]; then -+cat < "$tmpfile" < -Date: Tue, 7 Dec 2021 12:56:51 -0800 -Subject: [PATCH 93/99] CVE-2021-44141: s3: torture: In test_smbclient_s3, - change the error codes expected for test_widelinks() and test_nosymlinks() - from ACCESS_DENIED to NT_STATUS_OBJECT_NAME_NOT_FOUND. - -For SMB1/2/3 (minus posix) we need to treat bad symlinks -as though they don't exist. - -Add to knwownfail.d/symlink_traversal - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - selftest/knownfail.d/symlink_traversal | 2 ++ - selftest/target/Samba3.pm | 2 +- - source3/script/tests/test_smbclient_s3.sh | 10 +++++----- - 3 files changed, 8 insertions(+), 6 deletions(-) - -diff --git a/selftest/knownfail.d/symlink_traversal b/selftest/knownfail.d/symlink_traversal -index 25a4da8f250..840ab38b0f9 100644 ---- a/selftest/knownfail.d/symlink_traversal -+++ b/selftest/knownfail.d/symlink_traversal -@@ -1,3 +1,5 @@ - ^samba3.blackbox.test_symlink_traversal.SMB2.symlink_traversal_SMB2\(fileserver\) - ^samba3.blackbox.test_symlink_traversal.SMB1.symlink_traversal_SMB1\(fileserver_smb1_done\) - ^samba3.blackbox.test_symlink_traversal.SMB1.posix.symlink_traversal_SMB1_posix\(fileserver_smb1_done\) -+^samba3.blackbox.smbclient_s3.*.Ensure\ widelinks\ are\ restricted\(.*\) -+^samba3.blackbox.smbclient_s3.*.follow\ symlinks\ \=\ no\(.*\) -diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm -index 84903b87d3e..b901fd2677a 100755 ---- a/selftest/target/Samba3.pm -+++ b/selftest/target/Samba3.pm -@@ -2496,7 +2496,7 @@ sub provision($$) - create_file_chmod("$widelinks_target", 0666) or return undef; - - ## -- ## This link should get ACCESS_DENIED -+ ## This link should get an error - ## - symlink "$widelinks_target", "$widelinks_shrdir/source"; - ## -diff --git a/source3/script/tests/test_smbclient_s3.sh b/source3/script/tests/test_smbclient_s3.sh -index 89a17656159..e250d4dd106 100755 ---- a/source3/script/tests/test_smbclient_s3.sh -+++ b/source3/script/tests/test_smbclient_s3.sh -@@ -1044,12 +1044,12 @@ EOF - return 1 - fi - --# This should fail with NT_STATUS_ACCESS_DENIED -- echo "$out" | grep 'NT_STATUS_ACCESS_DENIED' -+# This should fail with NT_STATUS_OBJECT_NAME_NOT_FOUND -+ echo "$out" | grep 'NT_STATUS_OBJECT_NAME_NOT_FOUND' - ret=$? - if [ $ret != 0 ] ; then - echo "$out" -- echo "failed - should get NT_STATUS_ACCESS_DENIED listing \\widelinks_share\\source" -+ echo "failed - should get NT_STATUS_OBJECT_NAME_NOT_FOUND listing \\widelinks_share\\source" - return 1 - fi - } -@@ -1168,11 +1168,11 @@ EOF - return 1 - fi - -- echo "$out" | grep 'NT_STATUS_ACCESS_DENIED' -+ echo "$out" | grep 'NT_STATUS_OBJECT_NAME_NOT_FOUND' - ret=$? - if [ $ret -ne 0 ] ; then - echo "$out" -- echo "failed - should get NT_STATUS_ACCESS_DENIED getting \\nosymlinks\\source" -+ echo "failed - should get NT_STATUS_OBJECT_NAME_NOT_FOUND getting \\nosymlinks\\source" - return 1 - fi - --- -2.25.1 - - -From dbeef6bc732f05da5b35274cb0782a914e7392d7 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Tue, 7 Dec 2021 17:56:35 -0800 -Subject: [PATCH 94/99] CVE-2021-44141: s3: torture: Change expected error - return for samba3.smbtorture_s3.plain.POSIX.smbtorture. - -Trying to open a symlink as a terminal component should return -NT_STATUS_OBJECT_NAME_NOT_FOUND, not NT_STATUS_OBJECT_PATH_NOT_FOUND. - -Mark as knownfail.d/simple_posix_open until we fix the server. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - selftest/knownfail.d/simple_posix_open | 1 + - source3/torture/torture.c | 4 ++-- - 2 files changed, 3 insertions(+), 2 deletions(-) - create mode 100644 selftest/knownfail.d/simple_posix_open - -diff --git a/selftest/knownfail.d/simple_posix_open b/selftest/knownfail.d/simple_posix_open -new file mode 100644 -index 00000000000..5fcbdbdc2c6 ---- /dev/null -+++ b/selftest/knownfail.d/simple_posix_open -@@ -0,0 +1 @@ -+^samba3.smbtorture_s3.plain.POSIX.smbtorture\(.*\) -diff --git a/source3/torture/torture.c b/source3/torture/torture.c -index e3d26ddb261..c5da3836eac 100644 ---- a/source3/torture/torture.c -+++ b/source3/torture/torture.c -@@ -7984,9 +7984,9 @@ static bool run_simple_posix_open_test(int dummy) - goto out; - } else { - if (!check_both_error(__LINE__, status, ERRDOS, ERRbadpath, -- NT_STATUS_OBJECT_PATH_NOT_FOUND)) { -+ NT_STATUS_OBJECT_NAME_NOT_FOUND)) { - printf("POSIX open of %s should have failed " -- "with NT_STATUS_OBJECT_PATH_NOT_FOUND, " -+ "with NT_STATUS_OBJECT_NAME_NOT_FOUND, " - "failed with %s instead.\n", - sname, nt_errstr(status)); - goto out; --- -2.25.1 - - -From b97f4a6519f64cbcea2b6baa33d853faf4bc24cb Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Tue, 7 Dec 2021 11:44:09 -0800 -Subject: [PATCH 95/99] CVE-2021-44141: s3: smbd: For SMB1+POSIX clients trying - to open a symlink, always return NT_STATUS_OBJECT_NAME_NOT_FOUND. - -Matches the error return from openat_pathref_fsp(). - -NT_STATUS_OBJECT_PATH_NOT_FOUND is for a bad component in a path, not -a bad terminal symlink. - -Remove knownfail.d/simple_posix_open, we now pass. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - selftest/knownfail.d/simple_posix_open | 1 - - source3/smbd/open.c | 13 ++++++------- - 2 files changed, 6 insertions(+), 8 deletions(-) - delete mode 100644 selftest/knownfail.d/simple_posix_open - -diff --git a/selftest/knownfail.d/simple_posix_open b/selftest/knownfail.d/simple_posix_open -deleted file mode 100644 -index 5fcbdbdc2c6..00000000000 ---- a/selftest/knownfail.d/simple_posix_open -+++ /dev/null -@@ -1 +0,0 @@ --^samba3.smbtorture_s3.plain.POSIX.smbtorture\(.*\) -diff --git a/source3/smbd/open.c b/source3/smbd/open.c -index 5ed2c035318..5d2e2a1abf2 100644 ---- a/source3/smbd/open.c -+++ b/source3/smbd/open.c -@@ -1447,12 +1447,10 @@ static NTSTATUS open_file(files_struct *fsp, - * POSIX client that hit a symlink. We don't want to - * return NT_STATUS_STOPPED_ON_SYMLINK to avoid handling - * this special error code in all callers, so we map -- * this to NT_STATUS_OBJECT_PATH_NOT_FOUND. Historically -- * the lower level functions returned status code mapped -- * from errno by map_nt_error_from_unix() where ELOOP is -- * mapped to NT_STATUS_OBJECT_PATH_NOT_FOUND. -+ * this to NT_STATUS_OBJECT_NAME_NOT_FOUND to match -+ * openat_pathref_fsp(). - */ -- status = NT_STATUS_OBJECT_PATH_NOT_FOUND; -+ status = NT_STATUS_OBJECT_NAME_NOT_FOUND; - } - if (!NT_STATUS_IS_OK(status)) { - DEBUG(3,("Error opening file %s (%s) (local_flags=%d) " -@@ -1535,9 +1533,10 @@ static NTSTATUS open_file(files_struct *fsp, - { - /* - * Don't allow stat opens on symlinks directly unless -- * it's a POSIX open. -+ * it's a POSIX open. Match the return code from -+ * openat_pathref_fsp(). - */ -- return NT_STATUS_OBJECT_PATH_NOT_FOUND; -+ return NT_STATUS_OBJECT_NAME_NOT_FOUND; - } - - if (!fsp->fsp_flags.is_pathref) { --- -2.25.1 - - -From 66774e97e200d686be9c54739dc67ff0ed56af6f Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Tue, 7 Dec 2021 14:33:17 -0800 -Subject: [PATCH 96/99] CVE-2021-44141: s3: smbd: Inside check_reduced_name() - ensure we return the correct error codes when failing symlinks. - -NT_STATUS_OBJECT_PATH_NOT_FOUND for a path component failure. -NT_STATUS_OBJECT_NAME_NOT_FOUND for a terminal component failure. - -Remove: - - samba3.blackbox.test_symlink_traversal.SMB1.posix - samba3.blackbox.smbclient_s3.*.Ensure\ widelinks\ are\ restricted\(.*\) - samba3.blackbox.smbclient_s3.*.follow\ symlinks\ \=\ no\(.*\) - -in knownfail.d/symlink_traversal as we now pass these. Only one more fix -remaining to get rid of knownfail.d/symlink_traversal completely. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - selftest/knownfail.d/symlink_traversal | 3 --- - source3/smbd/vfs.c | 18 ++++++++++++++++-- - 2 files changed, 16 insertions(+), 5 deletions(-) - -diff --git a/selftest/knownfail.d/symlink_traversal b/selftest/knownfail.d/symlink_traversal -index 840ab38b0f9..2a51ff3f91d 100644 ---- a/selftest/knownfail.d/symlink_traversal -+++ b/selftest/knownfail.d/symlink_traversal -@@ -1,5 +1,2 @@ - ^samba3.blackbox.test_symlink_traversal.SMB2.symlink_traversal_SMB2\(fileserver\) - ^samba3.blackbox.test_symlink_traversal.SMB1.symlink_traversal_SMB1\(fileserver_smb1_done\) --^samba3.blackbox.test_symlink_traversal.SMB1.posix.symlink_traversal_SMB1_posix\(fileserver_smb1_done\) --^samba3.blackbox.smbclient_s3.*.Ensure\ widelinks\ are\ restricted\(.*\) --^samba3.blackbox.smbclient_s3.*.follow\ symlinks\ \=\ no\(.*\) -diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c -index d8b7b1283fb..a6022902c1d 100644 ---- a/source3/smbd/vfs.c -+++ b/source3/smbd/vfs.c -@@ -1146,6 +1146,7 @@ NTSTATUS check_reduced_name(connection_struct *conn, - bool allow_symlinks = true; - const char *conn_rootdir; - size_t rootdir_len; -+ bool parent_dir_checked = false; - - DBG_DEBUG("check_reduced_name [%s] [%s]\n", fname, conn->connectpath); - -@@ -1207,6 +1208,7 @@ NTSTATUS check_reduced_name(connection_struct *conn, - if (resolved_name == NULL) { - return NT_STATUS_NO_MEMORY; - } -+ parent_dir_checked = true; - } else { - resolved_name = resolved_fname->base_name; - } -@@ -1256,7 +1258,13 @@ NTSTATUS check_reduced_name(connection_struct *conn, - conn_rootdir, - resolved_name); - TALLOC_FREE(resolved_fname); -- return NT_STATUS_ACCESS_DENIED; -+ if (parent_dir_checked) { -+ /* Part of a component path. */ -+ return NT_STATUS_OBJECT_PATH_NOT_FOUND; -+ } else { -+ /* End of a path. */ -+ return NT_STATUS_OBJECT_NAME_NOT_FOUND; -+ } - } - } - -@@ -1311,7 +1319,13 @@ NTSTATUS check_reduced_name(connection_struct *conn, - p); - TALLOC_FREE(resolved_fname); - TALLOC_FREE(new_fname); -- return NT_STATUS_ACCESS_DENIED; -+ if (parent_dir_checked) { -+ /* Part of a component path. */ -+ return NT_STATUS_OBJECT_PATH_NOT_FOUND; -+ } else { -+ /* End of a path. */ -+ return NT_STATUS_OBJECT_NAME_NOT_FOUND; -+ } - } - } - --- -2.25.1 - - -From 9371ace08e603c745be14d6131b7a7713b36e782 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Tue, 7 Dec 2021 14:39:42 -0800 -Subject: [PATCH 97/99] CVE-2021-44141: s3: smbd: Fix a subtle bug in the error - returns from filename_convert(). - -If filename_convert() fails to convert the path, we never call -check_name(). This means we can return an incorrect error code -(NT_STATUS_ACCESS_DENIED) if we ran into a symlink that points -outside the share to a non-readable directory. We need to make -sure in this case we always call check_name(). - -Remove knownfail.d/symlink_traversal. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - selftest/knownfail.d/symlink_traversal | 2 -- - source3/smbd/filename.c | 36 ++++++++++++++++++++++++++ - 2 files changed, 36 insertions(+), 2 deletions(-) - delete mode 100644 selftest/knownfail.d/symlink_traversal - -diff --git a/selftest/knownfail.d/symlink_traversal b/selftest/knownfail.d/symlink_traversal -deleted file mode 100644 -index 2a51ff3f91d..00000000000 ---- a/selftest/knownfail.d/symlink_traversal -+++ /dev/null -@@ -1,2 +0,0 @@ --^samba3.blackbox.test_symlink_traversal.SMB2.symlink_traversal_SMB2\(fileserver\) --^samba3.blackbox.test_symlink_traversal.SMB1.symlink_traversal_SMB1\(fileserver_smb1_done\) -diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c -index 0d82085870c..56ebdd9f370 100644 ---- a/source3/smbd/filename.c -+++ b/source3/smbd/filename.c -@@ -30,6 +30,9 @@ - #include "smbd/smbd.h" - #include "smbd/globals.h" - -+static NTSTATUS check_name(connection_struct *conn, -+ const struct smb_filename *smb_fname); -+ - uint32_t ucf_flags_from_smb_request(struct smb_request *req) - { - uint32_t ucf_flags = 0; -@@ -529,6 +532,39 @@ static NTSTATUS unix_convert_step_search_fail(struct uc_state *state) - - if (errno == EACCES) { - if ((state->ucf_flags & UCF_PREP_CREATEFILE) == 0) { -+ /* -+ * Could be a symlink pointing to -+ * a directory outside the share -+ * to which we don't have access. -+ * If so, we need to know that here -+ * so we can return the correct error code. -+ * check_name() is never called if we -+ * error out of filename_convert(). -+ */ -+ int ret; -+ NTSTATUS status; -+ struct smb_filename dname = (struct smb_filename) { -+ .base_name = state->dirpath, -+ .twrp = state->smb_fname->twrp, -+ }; -+ -+ /* handle null paths */ -+ if ((dname.base_name == NULL) || -+ (dname.base_name[0] == '\0')) { -+ return NT_STATUS_ACCESS_DENIED; -+ } -+ ret = SMB_VFS_LSTAT(state->conn, &dname); -+ if (ret != 0) { -+ return NT_STATUS_ACCESS_DENIED; -+ } -+ if (!S_ISLNK(dname.st.st_ex_mode)) { -+ return NT_STATUS_ACCESS_DENIED; -+ } -+ status = check_name(state->conn, &dname); -+ if (!NT_STATUS_IS_OK(status)) { -+ /* We know this is an intermediate path. */ -+ return NT_STATUS_OBJECT_PATH_NOT_FOUND; -+ } - return NT_STATUS_ACCESS_DENIED; - } else { - /* --- -2.25.1 - - -From d46ffccc0780b9ef6b5a49e3e17b665345bd4362 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Tue, 7 Dec 2021 22:15:46 -0800 -Subject: [PATCH 98/99] CVE-2021-44141: s3: torture: Add a test - samba3.blackbox.test_symlink_rename.SMB1.posix that shows we still leak - target info across a SMB1+POSIX rename. - -Add a knownfail.d/posix_sylink_rename - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - selftest/knownfail.d/posix_sylink_rename | 1 + - .../tests/test_symlink_rename_smb1_posix.sh | 186 ++++++++++++++++++ - source3/selftest/tests.py | 5 + - 3 files changed, 192 insertions(+) - create mode 100644 selftest/knownfail.d/posix_sylink_rename - create mode 100755 source3/script/tests/test_symlink_rename_smb1_posix.sh - -diff --git a/selftest/knownfail.d/posix_sylink_rename b/selftest/knownfail.d/posix_sylink_rename -new file mode 100644 -index 00000000000..9c3cc0a41ba ---- /dev/null -+++ b/selftest/knownfail.d/posix_sylink_rename -@@ -0,0 +1 @@ -+^samba3.blackbox.test_symlink_rename.SMB1.posix.symlink_rename_SMB1_posix\(fileserver_smb1_done\) -diff --git a/source3/script/tests/test_symlink_rename_smb1_posix.sh b/source3/script/tests/test_symlink_rename_smb1_posix.sh -new file mode 100755 -index 00000000000..7d2e0037b8d ---- /dev/null -+++ b/source3/script/tests/test_symlink_rename_smb1_posix.sh -@@ -0,0 +1,186 @@ -+#!/bin/sh -+ -+if [ $# -lt 7 ]; then -+cat < "$tmpfile" < -Date: Tue, 7 Dec 2021 22:19:29 -0800 -Subject: [PATCH 99/99] CVE-2021-44141: s3: smbd: Inside - rename_internals_fsp(), we must use vfs_stat() for existence, not - SMB_VFS_STAT(). - -We need to take SMB1+POSIX into account here and do an LSTAT if it's -a POSIX name. - -Remove knownfail.d/posix_sylink_rename - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 - -Signed-off-by: Jeremy Allison ---- - selftest/knownfail.d/posix_sylink_rename | 1 - - source3/smbd/reply.c | 2 +- - 2 files changed, 1 insertion(+), 2 deletions(-) - delete mode 100644 selftest/knownfail.d/posix_sylink_rename - -diff --git a/selftest/knownfail.d/posix_sylink_rename b/selftest/knownfail.d/posix_sylink_rename -deleted file mode 100644 -index 9c3cc0a41ba..00000000000 ---- a/selftest/knownfail.d/posix_sylink_rename -+++ /dev/null -@@ -1 +0,0 @@ --^samba3.blackbox.test_symlink_rename.SMB1.posix.symlink_rename_SMB1_posix\(fileserver_smb1_done\) -diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c -index cc95bfa3af0..69278a1da87 100644 ---- a/source3/smbd/reply.c -+++ b/source3/smbd/reply.c -@@ -7266,7 +7266,7 @@ NTSTATUS rename_internals_fsp(connection_struct *conn, - goto out; - } - -- dst_exists = SMB_VFS_STAT(conn, smb_fname_dst) == 0; -+ dst_exists = vfs_stat(conn, smb_fname_dst) == 0; - - if(!replace_if_exists && dst_exists) { - DEBUG(3, ("rename_internals_fsp: dest exists doing rename " --- -2.25.1 - diff --git a/backport-CVE-2022-2031-CVE-2022-32744.patch b/backport-CVE-2022-2031-CVE-2022-32744.patch deleted file mode 100644 index fcb80a5bfaf9a94e793bdb1794f6961c01d00f0c..0000000000000000000000000000000000000000 --- a/backport-CVE-2022-2031-CVE-2022-32744.patch +++ /dev/null @@ -1,11383 +0,0 @@ -From c8ef1ef980a1281ec7edd1788dad9e22889d995a Mon Sep 17 00:00:00 2001 -From: Isaac Boukris -Date: Sat, 19 Sep 2020 14:16:20 +0200 -Subject: [PATCH 19/99] s4:mit-kdb: Force canonicalization for looking up - principals - -See also -https://github.com/krb5/krb5/commit/ac8865a22138ab0c657208c41be8fd6bc7968148 - -Pair-Programmed-With: Andreas Schneider -Signed-off-by: Isaac Boukris -Signed-off-by: Andreas Schneider -Reviewed-by: Alexander Bokovoy - -Autobuild-User(master): Andreas Schneider -Autobuild-Date(master): Mon Nov 29 09:32:26 UTC 2021 on sn-devel-184 - -(cherry picked from commit 90febd2a33b88af49af595fe0e995d6ba0f33a1b) ---- - selftest/knownfail_mit_kdc | 14 -------------- - source4/heimdal/lib/hdb/hdb.h | 1 + - source4/kdc/db-glue.c | 7 ++++++- - source4/kdc/mit_samba.c | 8 ++++++++ - source4/kdc/sdb.h | 1 + - 5 files changed, 16 insertions(+), 15 deletions(-) - -diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc -index cc7b501c6bf..c046a46a4f3 100644 ---- a/selftest/knownfail_mit_kdc -+++ b/selftest/knownfail_mit_kdc -@@ -379,8 +379,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_renew_rodc_revealed - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_sid_mismatch_existing - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_sid_mismatch_nonexisting --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_authdata_no_pac --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_no_pac - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_req - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_allowed_denied - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_denied -@@ -408,8 +406,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_user2user_authdata_no_pac - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_no_pac - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_no_sname --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_other_sname --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_req - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_allowed_denied - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_denied - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_no_krbtgt_link -@@ -422,10 +418,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_user2user_sid_mismatch_existing - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_sid_mismatch_nonexisting - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_tgt_cname_host --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_tgt_correct_cname --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_tgt_correct_realm --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_tgt_other_cname --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_tgt_wrong_realm - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_wrong_sname - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_wrong_sname_krbtgt - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_wrong_srealm -@@ -471,12 +463,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_tgs_rodc_pac_request_false - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_pac_request_none - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_pac_request_true --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_pac_request_false --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_pac_request_none --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_pac_request_true --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_user_pac_request_false --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_user_pac_request_none --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_user_pac_request_true - # - # PAC requester SID tests - # -diff --git a/source4/heimdal/lib/hdb/hdb.h b/source4/heimdal/lib/hdb/hdb.h -index 5ef9d9565f3..dafaffc6c2d 100644 ---- a/source4/heimdal/lib/hdb/hdb.h -+++ b/source4/heimdal/lib/hdb/hdb.h -@@ -63,6 +63,7 @@ enum hdb_lockop{ HDB_RLOCK, HDB_WLOCK }; - #define HDB_F_ALL_KVNOS 2048 /* we want all the keys, live or not */ - #define HDB_F_FOR_AS_REQ 4096 /* fetch is for a AS REQ */ - #define HDB_F_FOR_TGS_REQ 8192 /* fetch is for a TGS REQ */ -+#define HDB_F_FORCE_CANON 16384 /* force canonicalition */ - - /* hdb_capability_flags */ - #define HDB_CAP_F_HANDLE_ENTERPRISE_PRINCIPAL 1 -diff --git a/source4/kdc/db-glue.c b/source4/kdc/db-glue.c -index 3a7e2176653..ac47fe78373 100644 ---- a/source4/kdc/db-glue.c -+++ b/source4/kdc/db-glue.c -@@ -957,11 +957,16 @@ static krb5_error_code samba_kdc_message2entry(krb5_context context, - krb5_clear_error_message(context); - goto out; - } -- } else if ((flags & SDB_F_CANON) && (flags & SDB_F_FOR_AS_REQ)) { -+ } else if ((flags & SDB_F_FORCE_CANON) || -+ ((flags & SDB_F_CANON) && (flags & SDB_F_FOR_AS_REQ))) { - /* - * SDB_F_CANON maps from the canonicalize flag in the - * packet, and has a different meaning between AS-REQ - * and TGS-REQ. We only change the principal in the AS-REQ case -+ * -+ * The SDB_F_FORCE_CANON if for new MIT KDC code that wants -+ * the canonical name in all lookups, and takes care to -+ * canonicalize only when appropriate. - */ - ret = smb_krb5_make_principal(context, &entry_ex->entry.principal, lpcfg_realm(lp_ctx), samAccountName, NULL); - if (ret) { -diff --git a/source4/kdc/mit_samba.c b/source4/kdc/mit_samba.c -index 4239332f0d9..53c137de2fd 100644 ---- a/source4/kdc/mit_samba.c -+++ b/source4/kdc/mit_samba.c -@@ -221,6 +221,14 @@ int mit_samba_get_principal(struct mit_samba_context *ctx, - return ENOMEM; - } - -+#if KRB5_KDB_API_VERSION >= 10 -+ /* -+ * The MIT KDC code that wants the canonical name in all lookups, and -+ * takes care to canonicalize only when appropriate. -+ */ -+ sflags |= SDB_F_FORCE_CANON; -+#endif -+ - if (kflags & KRB5_KDB_FLAG_CANONICALIZE) { - sflags |= SDB_F_CANON; - } -diff --git a/source4/kdc/sdb.h b/source4/kdc/sdb.h -index c929acccce6..a9115ec23d7 100644 ---- a/source4/kdc/sdb.h -+++ b/source4/kdc/sdb.h -@@ -116,6 +116,7 @@ struct sdb_entry_ex { - #define SDB_F_KVNO_SPECIFIED 128 /* we want a particular KVNO */ - #define SDB_F_FOR_AS_REQ 4096 /* fetch is for a AS REQ */ - #define SDB_F_FOR_TGS_REQ 8192 /* fetch is for a TGS REQ */ -+#define SDB_F_FORCE_CANON 16384 /* force canonicalition */ - - void sdb_free_entry(struct sdb_entry_ex *e); - void free_sdb_entry(struct sdb_entry *s); --- -2.25.1 - - -From f40a974045a34c40f378dd9d96a4d401c3bb9a72 Mon Sep 17 00:00:00 2001 -From: Andreas Schneider -Date: Tue, 21 Dec 2021 12:17:11 +0100 -Subject: [PATCH 20/99] s4:kdc: Also cannoicalize krbtgt principals when - enforcing canonicalization - -Signed-off-by: Andreas Schneider -Reviewed-by: Stefan Metzmacher -(cherry picked from commit f1ec950aeb47283a504018bafa21f54c3282e70c) ---- - source4/kdc/db-glue.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/source4/kdc/db-glue.c b/source4/kdc/db-glue.c -index ac47fe78373..d017741e30a 100644 ---- a/source4/kdc/db-glue.c -+++ b/source4/kdc/db-glue.c -@@ -920,7 +920,7 @@ static krb5_error_code samba_kdc_message2entry(krb5_context context, - if (ent_type == SAMBA_KDC_ENT_TYPE_KRBTGT) { - p->is_krbtgt = true; - -- if (flags & (SDB_F_CANON)) { -+ if (flags & (SDB_F_CANON|SDB_F_FORCE_CANON)) { - /* - * When requested to do so, ensure that the - * both realm values in the principal are set --- -2.25.1 - - -From 8373345853a59265a9e6d2a826983aa8a4b7a4ea Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Wed, 24 Nov 2021 11:30:38 +1300 -Subject: [PATCH 21/99] selftest: Check received LDB error code when - STRICT_CHECKING=0 - -We were instead only checking the expected error. - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett -(cherry picked from commit ad4d6fb01fd8083e68f07c427af8932574810cdc) ---- - source4/dsdb/tests/python/priv_attrs.py | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/source4/dsdb/tests/python/priv_attrs.py b/source4/dsdb/tests/python/priv_attrs.py -index aa35dcc1317..4dfdfb9cbb8 100644 ---- a/source4/dsdb/tests/python/priv_attrs.py -+++ b/source4/dsdb/tests/python/priv_attrs.py -@@ -167,7 +167,7 @@ class PrivAttrsTests(samba.tests.TestCase): - creds_tmp.set_kerberos_state(DONT_USE_KERBEROS) # kinit is too expensive to use in a tight loop - return creds_tmp - -- def assertGotLdbError(self, got, wanted): -+ def assertGotLdbError(self, wanted, got): - if not self.strict_checking: - self.assertNotEqual(got, ldb.SUCCESS) - else: --- -2.25.1 - - -From bc1e71396ad41c37f5fa2101cb5e5e44dc221364 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Wed, 24 Nov 2021 11:53:18 +1300 -Subject: [PATCH 22/99] tests/krb5: Remove unused variable - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett -(cherry picked from commit 57b1b76154d699b9d70ad04fa5e94c4b30f0e4bf) ---- - python/samba/tests/krb5/raw_testcase.py | 2 -- - 1 file changed, 2 deletions(-) - -diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py -index 42f2e94f5aa..36a6134e6c9 100644 ---- a/python/samba/tests/krb5/raw_testcase.py -+++ b/python/samba/tests/krb5/raw_testcase.py -@@ -2855,7 +2855,6 @@ class RawKerberosTest(TestCaseInTempDir): - - expect_etype_info2 = () - expect_etype_info = False -- unexpect_etype_info = True - expected_aes_type = 0 - expected_rc4_type = 0 - if kcrypto.Enctype.RC4 in proposed_etypes: -@@ -2868,7 +2867,6 @@ class RawKerberosTest(TestCaseInTempDir): - if etype > expected_aes_type: - expected_aes_type = etype - if etype in (kcrypto.Enctype.RC4,) and error_code != 0: -- unexpect_etype_info = False - if etype > expected_rc4_type: - expected_rc4_type = etype - --- -2.25.1 - - -From 3059417db81edb174da640eb78d4dd6dab5f3120 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Wed, 24 Nov 2021 11:34:11 +1300 -Subject: [PATCH 23/99] tests/krb5: Deduplicate AS-REQ tests - -salt_tests was running the tests defined in the base class as well as -its own tests. - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett -(cherry picked from commit f0b222e3ecf72c8562bc97bedd9f3a92980b60d5) ---- - python/samba/tests/krb5/as_req_tests.py | 163 ++++++++++++------------ - python/samba/tests/krb5/salt_tests.py | 4 +- - 2 files changed, 85 insertions(+), 82 deletions(-) - -diff --git a/python/samba/tests/krb5/as_req_tests.py b/python/samba/tests/krb5/as_req_tests.py -index 08081928363..315720f85d6 100755 ---- a/python/samba/tests/krb5/as_req_tests.py -+++ b/python/samba/tests/krb5/as_req_tests.py -@@ -38,87 +38,8 @@ from samba.tests.krb5.rfc4120_constants import ( - global_asn1_print = False - global_hexdump = False - --@DynamicTestCase --class AsReqKerberosTests(KDCBaseTest): -- -- @classmethod -- def setUpDynamicTestCases(cls): -- for (name, idx) in cls.etype_test_permutation_name_idx(): -- for pac in [None, True, False]: -- tname = "%s_pac_%s" % (name, pac) -- targs = (idx, pac) -- cls.generate_dynamic_test("test_as_req_no_preauth", tname, *targs) -- -- def setUp(self): -- super(AsReqKerberosTests, self).setUp() -- self.do_asn1_print = global_asn1_print -- self.do_hexdump = global_hexdump -- -- def _test_as_req_nopreauth(self, -- initial_etypes, -- pac=None, -- initial_kdc_options=None): -- client_creds = self.get_client_creds() -- client_account = client_creds.get_username() -- 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() -- -- cname = self.PrincipalName_create(name_type=NT_PRINCIPAL, -- names=[client_account]) -- sname = self.PrincipalName_create(name_type=NT_SRV_INST, -- names=[krbtgt_account, realm]) -- -- expected_crealm = realm -- expected_cname = cname -- expected_srealm = realm -- expected_sname = sname -- expected_salt = client_creds.get_salt() -- -- if any(etype in client_as_etypes and etype in initial_etypes -- for etype in (kcrypto.Enctype.AES256, -- kcrypto.Enctype.AES128, -- kcrypto.Enctype.RC4)): -- expected_error_mode = KDC_ERR_PREAUTH_REQUIRED -- else: -- expected_error_mode = KDC_ERR_ETYPE_NOSUPP -- -- 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=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), -- pac_request=pac) -- -- self._generic_kdc_exchange(kdc_exchange_dict, -- cname=cname, -- realm=realm, -- sname=sname, -- etypes=initial_etypes) -- -- def _test_as_req_no_preauth_with_args(self, etype_idx, pac): -- name, etypes = self.etype_test_permutation_by_idx(etype_idx) -- self._test_as_req_nopreauth( -- pac=pac, -- initial_etypes=etypes, -- initial_kdc_options=krb5_asn1.KDCOptions('forwardable')) -- -- 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) - -+class AsReqBaseTest(KDCBaseTest): - def _run_as_req_enc_timestamp(self, client_creds): - client_account = client_creds.get_username() - client_as_etypes = self.get_default_enctypes() -@@ -207,6 +128,88 @@ class AsReqKerberosTests(KDCBaseTest): - return etype_info2 - - -+@DynamicTestCase -+class AsReqKerberosTests(AsReqBaseTest): -+ -+ @classmethod -+ def setUpDynamicTestCases(cls): -+ for (name, idx) in cls.etype_test_permutation_name_idx(): -+ for pac in [None, True, False]: -+ tname = "%s_pac_%s" % (name, pac) -+ targs = (idx, pac) -+ cls.generate_dynamic_test("test_as_req_no_preauth", tname, *targs) -+ -+ def setUp(self): -+ super(AsReqKerberosTests, self).setUp() -+ self.do_asn1_print = global_asn1_print -+ self.do_hexdump = global_hexdump -+ -+ def _test_as_req_nopreauth(self, -+ initial_etypes, -+ pac=None, -+ initial_kdc_options=None): -+ client_creds = self.get_client_creds() -+ client_account = client_creds.get_username() -+ 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() -+ -+ cname = self.PrincipalName_create(name_type=NT_PRINCIPAL, -+ names=[client_account]) -+ sname = self.PrincipalName_create(name_type=NT_SRV_INST, -+ names=[krbtgt_account, realm]) -+ -+ expected_crealm = realm -+ expected_cname = cname -+ expected_srealm = realm -+ expected_sname = sname -+ expected_salt = client_creds.get_salt() -+ -+ if any(etype in client_as_etypes and etype in initial_etypes -+ for etype in (kcrypto.Enctype.AES256, -+ kcrypto.Enctype.AES128, -+ kcrypto.Enctype.RC4)): -+ expected_error_mode = KDC_ERR_PREAUTH_REQUIRED -+ else: -+ expected_error_mode = KDC_ERR_ETYPE_NOSUPP -+ -+ 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=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), -+ pac_request=pac) -+ -+ self._generic_kdc_exchange(kdc_exchange_dict, -+ cname=cname, -+ realm=realm, -+ sname=sname, -+ etypes=initial_etypes) -+ -+ def _test_as_req_no_preauth_with_args(self, etype_idx, pac): -+ name, etypes = self.etype_test_permutation_by_idx(etype_idx) -+ self._test_as_req_nopreauth( -+ pac=pac, -+ initial_etypes=etypes, -+ initial_kdc_options=krb5_asn1.KDCOptions('forwardable')) -+ -+ 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) -+ -+ - 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 -index ecbf618e40e..db777f8b7bc 100755 ---- a/python/samba/tests/krb5/salt_tests.py -+++ b/python/samba/tests/krb5/salt_tests.py -@@ -21,7 +21,7 @@ import os - - import ldb - --from samba.tests.krb5.as_req_tests import AsReqKerberosTests -+from samba.tests.krb5.as_req_tests import AsReqBaseTest - import samba.tests.krb5.kcrypto as kcrypto - - sys.path.insert(0, "bin/python") -@@ -31,7 +31,7 @@ global_asn1_print = False - global_hexdump = False - - --class SaltTests(AsReqKerberosTests): -+class SaltTests(AsReqBaseTest): - - def setUp(self): - super().setUp() --- -2.25.1 - - -From 083a777e3d2b18d2e59ee4e04a4387c8db7ec185 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Wed, 24 Nov 2021 16:02:00 +1300 -Subject: [PATCH 24/99] tests/krb5: Run test_rpc against member server - -We were instead always running against the DC. - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett -(cherry picked from commit 167bd2070483004cd0b9a96ffb40ea73c6ddf579) ---- - python/samba/tests/krb5/test_rpc.py | 9 ++++----- - 1 file changed, 4 insertions(+), 5 deletions(-) - -diff --git a/python/samba/tests/krb5/test_rpc.py b/python/samba/tests/krb5/test_rpc.py -index 03c125f518a..2d483986e83 100755 ---- a/python/samba/tests/krb5/test_rpc.py -+++ b/python/samba/tests/krb5/test_rpc.py -@@ -58,7 +58,7 @@ class RpcTests(KDCBaseTest): - - samdb = self.get_samdb() - -- mach_name = samdb.host_dns_name() -+ mach_name = self.host - service = "cifs" - - # Create the user account. -@@ -67,7 +67,7 @@ class RpcTests(KDCBaseTest): - use_cache=False) - user_name = user_credentials.get_username() - -- mach_credentials = self.get_dc_creds() -+ mach_credentials = self.get_server_creds() - - # 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 -@@ -114,8 +114,7 @@ class RpcTests(KDCBaseTest): - self.assertEqual(user_name, account_name.string) - - def test_rpc_anonymous(self): -- samdb = self.get_samdb() -- mach_name = samdb.host_dns_name() -+ mach_name = self.host - - anon_creds = credentials.Credentials() - anon_creds.set_anonymous() -@@ -125,7 +124,7 @@ class RpcTests(KDCBaseTest): - - (account_name, _) = conn.GetUserName(None, None, None) - -- self.assertEqual('ANONYMOUS LOGON', account_name.string) -+ self.assertEqual('ANONYMOUS LOGON', account_name.string.upper()) - - - if __name__ == "__main__": --- -2.25.1 - - -From b797f39871100c8d33900af72608d2dc6ec9f435 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Wed, 24 Nov 2021 11:37:35 +1300 -Subject: [PATCH 25/99] tests/krb5: Allow PasswordKey_create() to use s2kparams - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett -(cherry picked from commit a560c2e9ad8abb824d1805c86c656943745f81eb) ---- - python/samba/tests/krb5/raw_testcase.py | 9 ++++++--- - 1 file changed, 6 insertions(+), 3 deletions(-) - -diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py -index 36a6134e6c9..da3f69c79c6 100644 ---- a/python/samba/tests/krb5/raw_testcase.py -+++ b/python/samba/tests/krb5/raw_testcase.py -@@ -1167,10 +1167,11 @@ class RawKerberosTest(TestCaseInTempDir): - key = kcrypto.Key(etype, contents) - return RodcPacEncryptionKey(key, kvno) - -- def PasswordKey_create(self, etype=None, pwd=None, salt=None, kvno=None): -+ def PasswordKey_create(self, etype=None, pwd=None, salt=None, kvno=None, -+ params=None): - self.assertIsNotNone(pwd) - self.assertIsNotNone(salt) -- key = kcrypto.string_to_key(etype, pwd, salt) -+ key = kcrypto.string_to_key(etype, pwd, salt, params=params) - return RodcPacEncryptionKey(key, kvno) - - def PasswordKey_from_etype_info2(self, creds, etype_info2, kvno=None): -@@ -1182,9 +1183,11 @@ class RawKerberosTest(TestCaseInTempDir): - nthash = creds.get_nt_hash() - return self.SessionKey_create(etype=e, contents=nthash, kvno=kvno) - -+ params = etype_info2.get('s2kparams') -+ - password = creds.get_password() - return self.PasswordKey_create( -- etype=e, pwd=password, salt=salt, kvno=kvno) -+ etype=e, pwd=password, salt=salt, kvno=kvno, params=params) - - def TicketDecryptionKey_from_creds(self, creds, etype=None): - --- -2.25.1 - - -From 9fbb213304ecebac5b7620b8f183a5baddeb287d Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Wed, 24 Nov 2021 11:40:35 +1300 -Subject: [PATCH 26/99] tests/krb5: Split out methods to create renewable or - invalid tickets - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett -(cherry picked from commit e930274aa43810d6485c3c8a7c82958ecb409630) ---- - python/samba/tests/krb5/kdc_tgs_tests.py | 68 +++++++++++++----------- - 1 file changed, 36 insertions(+), 32 deletions(-) - -diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py -index abac5a47a56..0578969ba69 100755 ---- a/python/samba/tests/krb5/kdc_tgs_tests.py -+++ b/python/samba/tests/krb5/kdc_tgs_tests.py -@@ -1786,6 +1786,40 @@ class KdcTgsTests(KDCBaseTest): - - self._run_tgs(tgt, expected_error=KDC_ERR_C_PRINCIPAL_UNKNOWN) - -+ def _modify_renewable(self, enc_part): -+ # Set the renewable flag. -+ renewable_flag = krb5_asn1.TicketFlags('renewable') -+ pos = len(tuple(renewable_flag)) - 1 -+ -+ flags = enc_part['flags'] -+ self.assertLessEqual(pos, len(flags)) -+ -+ new_flags = flags[:pos] + '1' + flags[pos + 1:] -+ enc_part['flags'] = new_flags -+ -+ # Set the renew-till time to be in the future. -+ renew_till = self.get_KerberosTime(offset=100 * 60 * 60) -+ enc_part['renew-till'] = renew_till -+ -+ return enc_part -+ -+ def _modify_invalid(self, enc_part): -+ # Set the invalid flag. -+ invalid_flag = krb5_asn1.TicketFlags('invalid') -+ pos = len(tuple(invalid_flag)) - 1 -+ -+ flags = enc_part['flags'] -+ self.assertLessEqual(pos, len(flags)) -+ -+ new_flags = flags[:pos] + '1' + flags[pos + 1:] -+ enc_part['flags'] = new_flags -+ -+ # Set the ticket start time to be in the past. -+ past_time = self.get_KerberosTime(offset=-100 * 60 * 60) -+ enc_part['starttime'] = past_time -+ -+ return enc_part -+ - def _get_tgt(self, - client_creds, - renewable=False, -@@ -1880,39 +1914,9 @@ class KdcTgsTests(KDCBaseTest): - } - - if renewable: -- def flags_modify_fn(enc_part): -- # Set the renewable flag. -- renewable_flag = krb5_asn1.TicketFlags('renewable') -- pos = len(tuple(renewable_flag)) - 1 -- -- flags = enc_part['flags'] -- self.assertLessEqual(pos, len(flags)) -- -- new_flags = flags[:pos] + '1' + flags[pos + 1:] -- enc_part['flags'] = new_flags -- -- # Set the renew-till time to be in the future. -- renew_till = self.get_KerberosTime(offset=100 * 60 * 60) -- enc_part['renew-till'] = renew_till -- -- return enc_part -+ flags_modify_fn = self._modify_renewable - elif invalid: -- def flags_modify_fn(enc_part): -- # Set the invalid flag. -- invalid_flag = krb5_asn1.TicketFlags('invalid') -- pos = len(tuple(invalid_flag)) - 1 -- -- flags = enc_part['flags'] -- self.assertLessEqual(pos, len(flags)) -- -- new_flags = flags[:pos] + '1' + flags[pos + 1:] -- enc_part['flags'] = new_flags -- -- # Set the ticket start time to be in the past. -- past_time = self.get_KerberosTime(offset=-100 * 60 * 60) -- enc_part['starttime'] = past_time -- -- return enc_part -+ flags_modify_fn = self._modify_invalid - else: - flags_modify_fn = None - --- -2.25.1 - - -From 9d8786faa9fa6ca1182ec2b382882361a588f54d Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Wed, 24 Nov 2021 11:52:31 +1300 -Subject: [PATCH 27/99] tests/krb5: Adjust error codes to better match Windows - with PacRequestorEnforcement=2 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett -(cherry picked from commit d95705172bcf6fe24817800a4c0009e9cc8be595) ---- - python/samba/tests/krb5/alias_tests.py | 7 +- - python/samba/tests/krb5/kdc_tgs_tests.py | 130 ++++++++---------- - .../ms_kile_client_principal_lookup_tests.py | 39 ++---- - python/samba/tests/krb5/s4u_tests.py | 57 ++++---- - python/samba/tests/krb5/test_rpc.py | 8 +- - selftest/knownfail_heimdal_kdc | 64 +++++++++ - selftest/knownfail_mit_kdc | 11 ++ - 7 files changed, 183 insertions(+), 133 deletions(-) - -diff --git a/python/samba/tests/krb5/alias_tests.py b/python/samba/tests/krb5/alias_tests.py -index 60213845a44..1f63775c189 100755 ---- a/python/samba/tests/krb5/alias_tests.py -+++ b/python/samba/tests/krb5/alias_tests.py -@@ -28,7 +28,7 @@ from samba.tests.krb5.kdc_base_test import KDCBaseTest - from samba.tests.krb5.rfc4120_constants import ( - AES256_CTS_HMAC_SHA1_96, - ARCFOUR_HMAC_MD5, -- KDC_ERR_CLIENT_NAME_MISMATCH, -+ KDC_ERR_TGT_REVOKED, - NT_PRINCIPAL, - ) - -@@ -168,7 +168,7 @@ class AliasTests(KDCBaseTest): - ctype=None) - return [padata], req_body - -- expected_error_mode = KDC_ERR_CLIENT_NAME_MISMATCH -+ expected_error_mode = KDC_ERR_TGT_REVOKED - - # Make a request using S4U2Self. The request should fail. - kdc_exchange_dict = self.tgs_exchange_dict( -@@ -184,7 +184,8 @@ class AliasTests(KDCBaseTest): - tgt=tgt, - authenticator_subkey=authenticator_subkey, - kdc_options='0', -- expect_pac=True) -+ expect_pac=True, -+ expect_edata=False) - - rep = self._generic_kdc_exchange(kdc_exchange_dict, - cname=None, -diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py -index 0578969ba69..7ea15f0fbab 100755 ---- a/python/samba/tests/krb5/kdc_tgs_tests.py -+++ b/python/samba/tests/krb5/kdc_tgs_tests.py -@@ -23,7 +23,7 @@ import os - import ldb - - --from samba import dsdb, ntstatus -+from samba import dsdb - - from samba.dcerpc import krb5pac, security - -@@ -38,8 +38,6 @@ from samba.tests.krb5.rfc4120_constants import ( - KRB_ERROR, - KRB_TGS_REP, - KDC_ERR_BADMATCH, -- KDC_ERR_BADOPTION, -- KDC_ERR_CLIENT_NAME_MISMATCH, - KDC_ERR_GENERIC, - KDC_ERR_MODIFIED, - KDC_ERR_POLICY, -@@ -262,7 +260,7 @@ class KdcTgsTests(KDCBaseTest): - authenticator_subkey = self.RandomKey(kcrypto.Enctype.AES256) - - if expect_error: -- expected_error_mode = KDC_ERR_BADOPTION -+ expected_error_mode = KDC_ERR_TGT_REVOKED - check_error_fn = self.generic_check_kdc_error - check_rep_fn = None - else: -@@ -288,7 +286,8 @@ class KdcTgsTests(KDCBaseTest): - authenticator_subkey=authenticator_subkey, - kdc_options=kdc_options, - pac_request=pac_request, -- expect_pac=expect_pac) -+ expect_pac=expect_pac, -+ expect_edata=False) - - rep = self._generic_kdc_exchange(kdc_exchange_dict, - cname=cname, -@@ -516,8 +515,7 @@ class KdcTgsTests(KDCBaseTest): - creds = self._get_creds() - tgt = self._get_tgt(creds, remove_requester_sid=True) - -- self._run_tgs(tgt, expected_error=0, expect_pac=True, -- expect_requester_sid=False) # Note: not expected -+ self._run_tgs(tgt, expected_error=KDC_ERR_TGT_REVOKED) - - def test_tgs_req_no_pac_attrs(self): - creds = self._get_creds() -@@ -531,11 +529,7 @@ class KdcTgsTests(KDCBaseTest): - revealed_to_rodc=True) - tgt = self._get_tgt(creds, from_rodc=True, remove_requester_sid=True) - -- samdb = self.get_samdb() -- sid = self.get_objectSid(samdb, creds.get_dn()) -- -- self._run_tgs(tgt, expected_error=0, expect_pac=True, -- expect_requester_sid=True, expected_sid=sid) -+ self._run_tgs(tgt, expected_error=KDC_ERR_TGT_REVOKED) - - def test_tgs_req_from_rodc_no_pac_attrs(self): - creds = self._get_creds(replication_allowed=True, -@@ -548,101 +542,99 @@ class KdcTgsTests(KDCBaseTest): - def test_tgs_no_pac(self): - creds = self._get_creds() - tgt = self._get_tgt(creds, remove_pac=True) -- self._run_tgs(tgt, expected_error=KDC_ERR_BADOPTION) -+ self._run_tgs(tgt, expected_error=KDC_ERR_TGT_REVOKED) - - def test_renew_no_pac(self): - creds = self._get_creds() - tgt = self._get_tgt(creds, renewable=True, remove_pac=True) -- self._renew_tgt(tgt, expected_error=KDC_ERR_BADOPTION) -+ self._renew_tgt(tgt, expected_error=KDC_ERR_TGT_REVOKED) - - def test_validate_no_pac(self): - creds = self._get_creds() - tgt = self._get_tgt(creds, invalid=True, remove_pac=True) -- self._validate_tgt(tgt, expected_error=KDC_ERR_BADOPTION) -+ self._validate_tgt(tgt, expected_error=KDC_ERR_TGT_REVOKED) - - def test_s4u2self_no_pac(self): - creds = self._get_creds() - tgt = self._get_tgt(creds, remove_pac=True) - self._s4u2self(tgt, creds, -- expected_error=(KDC_ERR_GENERIC, KDC_ERR_BADOPTION), -- expected_status=ntstatus.NT_STATUS_INVALID_PARAMETER, -- expect_edata=True) -+ expected_error=KDC_ERR_TGT_REVOKED, -+ expect_edata=False) - - def test_user2user_no_pac(self): - creds = self._get_creds() - tgt = self._get_tgt(creds, remove_pac=True) -- self._user2user(tgt, creds, expected_error=KDC_ERR_BADOPTION) -+ self._user2user(tgt, creds, expected_error=KDC_ERR_TGT_REVOKED) - - # Test making a request with authdata and without a PAC. - def test_tgs_authdata_no_pac(self): - creds = self._get_creds() - tgt = self._get_tgt(creds, remove_pac=True, allow_empty_authdata=True) -- self._run_tgs(tgt, expected_error=KDC_ERR_BADOPTION) -+ self._run_tgs(tgt, expected_error=KDC_ERR_TGT_REVOKED) - - def test_renew_authdata_no_pac(self): - creds = self._get_creds() - tgt = self._get_tgt(creds, renewable=True, remove_pac=True, - allow_empty_authdata=True) -- self._renew_tgt(tgt, expected_error=KDC_ERR_BADOPTION) -+ self._renew_tgt(tgt, expected_error=KDC_ERR_TGT_REVOKED) - - def test_validate_authdata_no_pac(self): - creds = self._get_creds() - tgt = self._get_tgt(creds, invalid=True, remove_pac=True, - allow_empty_authdata=True) -- self._validate_tgt(tgt, expected_error=KDC_ERR_BADOPTION) -+ self._validate_tgt(tgt, expected_error=KDC_ERR_TGT_REVOKED) - - def test_s4u2self_authdata_no_pac(self): - creds = self._get_creds() - tgt = self._get_tgt(creds, remove_pac=True, allow_empty_authdata=True) - self._s4u2self(tgt, creds, -- expected_error=(KDC_ERR_GENERIC, KDC_ERR_BADOPTION), -- expected_status=ntstatus.NT_STATUS_INVALID_PARAMETER, -- expect_edata=True) -+ expected_error=KDC_ERR_TGT_REVOKED, -+ expect_edata=False) - - def test_user2user_authdata_no_pac(self): - creds = self._get_creds() - tgt = self._get_tgt(creds, remove_pac=True, allow_empty_authdata=True) -- self._user2user(tgt, creds, expected_error=KDC_ERR_BADOPTION) -+ self._user2user(tgt, creds, expected_error=KDC_ERR_TGT_REVOKED) - - # Test changing the SID in the PAC to that of another account. - def test_tgs_sid_mismatch_existing(self): - creds = self._get_creds() - existing_rid = self._get_existing_rid() - tgt = self._get_tgt(creds, new_rid=existing_rid) -- self._run_tgs(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) -+ self._run_tgs(tgt, expected_error=KDC_ERR_TGT_REVOKED) - - def test_renew_sid_mismatch_existing(self): - creds = self._get_creds() - existing_rid = self._get_existing_rid() - tgt = self._get_tgt(creds, renewable=True, new_rid=existing_rid) -- self._renew_tgt(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) -+ self._renew_tgt(tgt, expected_error=KDC_ERR_TGT_REVOKED) - - def test_validate_sid_mismatch_existing(self): - creds = self._get_creds() - existing_rid = self._get_existing_rid() - tgt = self._get_tgt(creds, invalid=True, new_rid=existing_rid) -- self._validate_tgt(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) -+ self._validate_tgt(tgt, expected_error=KDC_ERR_TGT_REVOKED) - - def test_s4u2self_sid_mismatch_existing(self): - creds = self._get_creds() - existing_rid = self._get_existing_rid() - tgt = self._get_tgt(creds, new_rid=existing_rid) - self._s4u2self(tgt, creds, -- expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) -+ expected_error=KDC_ERR_TGT_REVOKED) - - def test_user2user_sid_mismatch_existing(self): - creds = self._get_creds() - existing_rid = self._get_existing_rid() - tgt = self._get_tgt(creds, new_rid=existing_rid) - self._user2user(tgt, creds, -- expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) -+ expected_error=KDC_ERR_TGT_REVOKED) - - def test_requester_sid_mismatch_existing(self): - creds = self._get_creds() - existing_rid = self._get_existing_rid() - tgt = self._get_tgt(creds, new_rid=existing_rid, - can_modify_logon_info=False) -- self._run_tgs(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) -+ self._run_tgs(tgt, expected_error=KDC_ERR_TGT_REVOKED) - - def test_logon_info_sid_mismatch_existing(self): - creds = self._get_creds() -@@ -656,49 +648,49 @@ class KdcTgsTests(KDCBaseTest): - existing_rid = self._get_existing_rid() - tgt = self._get_tgt(creds, new_rid=existing_rid, - remove_requester_sid=True) -- self._run_tgs(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) -+ self._run_tgs(tgt, expected_error=KDC_ERR_TGT_REVOKED) - - # Test changing the SID in the PAC to a non-existent one. - def test_tgs_sid_mismatch_nonexisting(self): - creds = self._get_creds() - nonexistent_rid = self._get_non_existent_rid() - tgt = self._get_tgt(creds, new_rid=nonexistent_rid) -- self._run_tgs(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) -+ self._run_tgs(tgt, expected_error=KDC_ERR_TGT_REVOKED) - - def test_renew_sid_mismatch_nonexisting(self): - creds = self._get_creds() - nonexistent_rid = self._get_non_existent_rid() - tgt = self._get_tgt(creds, renewable=True, - new_rid=nonexistent_rid) -- self._renew_tgt(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) -+ self._renew_tgt(tgt, expected_error=KDC_ERR_TGT_REVOKED) - - def test_validate_sid_mismatch_nonexisting(self): - creds = self._get_creds() - nonexistent_rid = self._get_non_existent_rid() - tgt = self._get_tgt(creds, invalid=True, - new_rid=nonexistent_rid) -- self._validate_tgt(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) -+ self._validate_tgt(tgt, expected_error=KDC_ERR_TGT_REVOKED) - - def test_s4u2self_sid_mismatch_nonexisting(self): - creds = self._get_creds() - nonexistent_rid = self._get_non_existent_rid() - tgt = self._get_tgt(creds, new_rid=nonexistent_rid) - self._s4u2self(tgt, creds, -- expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) -+ expected_error=KDC_ERR_TGT_REVOKED) - - def test_user2user_sid_mismatch_nonexisting(self): - creds = self._get_creds() - nonexistent_rid = self._get_non_existent_rid() - tgt = self._get_tgt(creds, new_rid=nonexistent_rid) - self._user2user(tgt, creds, -- expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) -+ expected_error=KDC_ERR_TGT_REVOKED) - - def test_requester_sid_mismatch_nonexisting(self): - creds = self._get_creds() - nonexistent_rid = self._get_non_existent_rid() - tgt = self._get_tgt(creds, new_rid=nonexistent_rid, - can_modify_logon_info=False) -- self._run_tgs(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) -+ self._run_tgs(tgt, expected_error=KDC_ERR_TGT_REVOKED) - - def test_logon_info_sid_mismatch_nonexisting(self): - creds = self._get_creds() -@@ -712,7 +704,7 @@ class KdcTgsTests(KDCBaseTest): - nonexistent_rid = self._get_non_existent_rid() - tgt = self._get_tgt(creds, new_rid=nonexistent_rid, - remove_requester_sid=True) -- self._run_tgs(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) -+ self._run_tgs(tgt, expected_error=KDC_ERR_TGT_REVOKED) - - # Test with an RODC-issued ticket where the client is revealed to the RODC. - def test_tgs_rodc_revealed(self): -@@ -753,7 +745,7 @@ class KdcTgsTests(KDCBaseTest): - existing_rid = self._get_existing_rid(replication_allowed=True, - revealed_to_rodc=True) - tgt = self._get_tgt(creds, from_rodc=True, new_rid=existing_rid) -- self._run_tgs(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) -+ self._run_tgs(tgt, expected_error=KDC_ERR_TGT_REVOKED) - - def test_renew_rodc_sid_mismatch_existing(self): - creds = self._get_creds(replication_allowed=True, -@@ -762,7 +754,7 @@ class KdcTgsTests(KDCBaseTest): - revealed_to_rodc=True) - tgt = self._get_tgt(creds, renewable=True, from_rodc=True, - new_rid=existing_rid) -- self._renew_tgt(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) -+ self._renew_tgt(tgt, expected_error=KDC_ERR_TGT_REVOKED) - - def test_validate_rodc_sid_mismatch_existing(self): - creds = self._get_creds(replication_allowed=True, -@@ -771,7 +763,7 @@ class KdcTgsTests(KDCBaseTest): - revealed_to_rodc=True) - tgt = self._get_tgt(creds, invalid=True, from_rodc=True, - new_rid=existing_rid) -- self._validate_tgt(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) -+ self._validate_tgt(tgt, expected_error=KDC_ERR_TGT_REVOKED) - - def test_s4u2self_rodc_sid_mismatch_existing(self): - creds = self._get_creds(replication_allowed=True, -@@ -779,7 +771,7 @@ class KdcTgsTests(KDCBaseTest): - existing_rid = self._get_existing_rid(replication_allowed=True, - revealed_to_rodc=True) - tgt = self._get_tgt(creds, from_rodc=True, new_rid=existing_rid) -- self._s4u2self(tgt, creds, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) -+ self._s4u2self(tgt, creds, expected_error=KDC_ERR_TGT_REVOKED) - - def test_user2user_rodc_sid_mismatch_existing(self): - creds = self._get_creds(replication_allowed=True, -@@ -788,7 +780,7 @@ class KdcTgsTests(KDCBaseTest): - revealed_to_rodc=True) - tgt = self._get_tgt(creds, from_rodc=True, new_rid=existing_rid) - self._user2user(tgt, creds, -- expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) -+ expected_error=KDC_ERR_TGT_REVOKED) - - def test_tgs_rodc_requester_sid_mismatch_existing(self): - creds = self._get_creds(replication_allowed=True, -@@ -797,7 +789,7 @@ class KdcTgsTests(KDCBaseTest): - revealed_to_rodc=True) - tgt = self._get_tgt(creds, from_rodc=True, new_rid=existing_rid, - can_modify_logon_info=False) -- self._run_tgs(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) -+ self._run_tgs(tgt, expected_error=KDC_ERR_TGT_REVOKED) - - def test_tgs_rodc_logon_info_sid_mismatch_existing(self): - creds = self._get_creds(replication_allowed=True, -@@ -815,7 +807,7 @@ class KdcTgsTests(KDCBaseTest): - revealed_to_rodc=True) - tgt = self._get_tgt(creds, from_rodc=True, new_rid=existing_rid, - remove_requester_sid=True) -- self._run_tgs(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) -+ self._run_tgs(tgt, expected_error=KDC_ERR_TGT_REVOKED) - - # Test with an RODC-issued ticket where the SID in the PAC is changed to a - # non-existent one. -@@ -824,7 +816,7 @@ class KdcTgsTests(KDCBaseTest): - revealed_to_rodc=True) - nonexistent_rid = self._get_non_existent_rid() - tgt = self._get_tgt(creds, from_rodc=True, new_rid=nonexistent_rid) -- self._run_tgs(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) -+ self._run_tgs(tgt, expected_error=KDC_ERR_TGT_REVOKED) - - def test_renew_rodc_sid_mismatch_nonexisting(self): - creds = self._get_creds(replication_allowed=True, -@@ -832,7 +824,7 @@ class KdcTgsTests(KDCBaseTest): - nonexistent_rid = self._get_non_existent_rid() - tgt = self._get_tgt(creds, renewable=True, from_rodc=True, - new_rid=nonexistent_rid) -- self._renew_tgt(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) -+ self._renew_tgt(tgt, expected_error=KDC_ERR_TGT_REVOKED) - - def test_validate_rodc_sid_mismatch_nonexisting(self): - creds = self._get_creds(replication_allowed=True, -@@ -840,14 +832,14 @@ class KdcTgsTests(KDCBaseTest): - nonexistent_rid = self._get_non_existent_rid() - tgt = self._get_tgt(creds, invalid=True, from_rodc=True, - new_rid=nonexistent_rid) -- self._validate_tgt(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) -+ self._validate_tgt(tgt, expected_error=KDC_ERR_TGT_REVOKED) - - def test_s4u2self_rodc_sid_mismatch_nonexisting(self): - creds = self._get_creds(replication_allowed=True, - revealed_to_rodc=True) - nonexistent_rid = self._get_non_existent_rid() - tgt = self._get_tgt(creds, from_rodc=True, new_rid=nonexistent_rid) -- self._s4u2self(tgt, creds, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) -+ self._s4u2self(tgt, creds, expected_error=KDC_ERR_TGT_REVOKED) - - def test_user2user_rodc_sid_mismatch_nonexisting(self): - creds = self._get_creds(replication_allowed=True, -@@ -855,7 +847,7 @@ class KdcTgsTests(KDCBaseTest): - nonexistent_rid = self._get_non_existent_rid() - tgt = self._get_tgt(creds, from_rodc=True, new_rid=nonexistent_rid) - self._user2user(tgt, creds, -- expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) -+ expected_error=KDC_ERR_TGT_REVOKED) - - def test_tgs_rodc_requester_sid_mismatch_nonexisting(self): - creds = self._get_creds(replication_allowed=True, -@@ -863,7 +855,7 @@ class KdcTgsTests(KDCBaseTest): - nonexistent_rid = self._get_non_existent_rid() - tgt = self._get_tgt(creds, from_rodc=True, new_rid=nonexistent_rid, - can_modify_logon_info=False) -- self._run_tgs(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) -+ self._run_tgs(tgt, expected_error=KDC_ERR_TGT_REVOKED) - - def test_tgs_rodc_logon_info_sid_mismatch_nonexisting(self): - creds = self._get_creds(replication_allowed=True, -@@ -879,7 +871,7 @@ class KdcTgsTests(KDCBaseTest): - nonexistent_rid = self._get_non_existent_rid() - tgt = self._get_tgt(creds, from_rodc=True, new_rid=nonexistent_rid, - remove_requester_sid=True) -- self._run_tgs(tgt, expected_error=KDC_ERR_CLIENT_NAME_MISMATCH) -+ self._run_tgs(tgt, expected_error=KDC_ERR_TGT_REVOKED) - - # Test with an RODC-issued ticket where the client is not revealed to the - # RODC. -@@ -1111,8 +1103,7 @@ class KdcTgsTests(KDCBaseTest): - names=[user_name]) - - self._user2user(tgt, creds, sname=sname, -- expected_error=(KDC_ERR_BADMATCH, -- KDC_ERR_BADOPTION)) -+ expected_error=KDC_ERR_BADMATCH) - - def test_user2user_other_sname(self): - other_name = self.get_new_username() -@@ -1134,8 +1125,7 @@ class KdcTgsTests(KDCBaseTest): - sname = self.get_krbtgt_sname() - - self._user2user(tgt, creds, sname=sname, -- expected_error=(KDC_ERR_BADMATCH, -- KDC_ERR_BADOPTION)) -+ expected_error=KDC_ERR_BADMATCH) - - def test_user2user_wrong_srealm(self): - creds = self._get_creds() -@@ -1206,7 +1196,9 @@ class KdcTgsTests(KDCBaseTest): - - tgt = self._modify_tgt(tgt, cname=cname) - -- self._user2user(tgt, creds, expected_error=KDC_ERR_C_PRINCIPAL_UNKNOWN) -+ self._user2user(tgt, creds, -+ expected_error=(KDC_ERR_TGT_REVOKED, -+ KDC_ERR_C_PRINCIPAL_UNKNOWN)) - - def test_user2user_non_existent_sname(self): - creds = self._get_creds() -@@ -1522,8 +1514,7 @@ class KdcTgsTests(KDCBaseTest): - tgt = self._modify_tgt(tgt, renewable=True, - remove_requester_sid=True) - -- self._renew_tgt(tgt, expected_error=0, expect_pac=True, -- expect_requester_sid=False) # Note: not expected -+ self._renew_tgt(tgt, expected_error=KDC_ERR_TGT_REVOKED) - - def test_tgs_requester_sid_missing_rodc_renew(self): - creds = self._get_creds(replication_allowed=True, -@@ -1539,9 +1530,7 @@ class KdcTgsTests(KDCBaseTest): - tgt = self._modify_tgt(tgt, from_rodc=True, renewable=True, - remove_requester_sid=True) - -- self._renew_tgt(tgt, expected_error=0, expect_pac=True, -- expected_sid=sid, -- expect_requester_sid=True) -+ self._renew_tgt(tgt, expected_error=KDC_ERR_TGT_REVOKED) - - def test_tgs_pac_request_none(self): - creds = self._get_creds() -@@ -1655,10 +1644,10 @@ class KdcTgsTests(KDCBaseTest): - creds = self._get_creds() - tgt = self.get_tgt(creds, pac_request=False, expect_pac=None) - -- ticket = self._s4u2self(tgt, creds, expected_error=0, expect_pac=False) -+ ticket = self._s4u2self(tgt, creds, expected_error=0, expect_pac=True) - -- pac = self.get_ticket_pac(ticket, expect_pac=False) -- self.assertIsNone(pac) -+ pac = self.get_ticket_pac(ticket) -+ self.assertIsNotNone(pac) - - def test_s4u2self_pac_request_true(self): - creds = self._get_creds() -@@ -1753,10 +1742,10 @@ class KdcTgsTests(KDCBaseTest): - tgt = self.get_tgt(creds, pac_request=False, expect_pac=None) - tgt = self._modify_tgt(tgt, from_rodc=True) - -- ticket = self._run_tgs(tgt, expected_error=0, expect_pac=False) -+ ticket = self._run_tgs(tgt, expected_error=0, expect_pac=True) - - pac = self.get_ticket_pac(ticket, expect_pac=False) -- self.assertIsNone(pac) -+ self.assertIsNotNone(pac) - - def test_tgs_rodc_pac_request_true(self): - creds = self._get_creds(replication_allowed=True, -@@ -1784,7 +1773,8 @@ class KdcTgsTests(KDCBaseTest): - 'sAMAccountName') - samdb.modify(msg) - -- self._run_tgs(tgt, expected_error=KDC_ERR_C_PRINCIPAL_UNKNOWN) -+ self._run_tgs(tgt, expected_error=(KDC_ERR_TGT_REVOKED, -+ KDC_ERR_C_PRINCIPAL_UNKNOWN)) - - def _modify_renewable(self, enc_part): - # Set the renewable flag. -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 0aa3309b814..e6b90d3e16a 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 -@@ -32,6 +32,7 @@ from samba.tests.krb5.rfc4120_constants import ( - NT_PRINCIPAL, - NT_SRV_INST, - KDC_ERR_C_PRINCIPAL_UNKNOWN, -+ KDC_ERR_TGT_REVOKED, - ) - - global_asn1_print = False -@@ -322,21 +323,10 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): - - (rep, enc_part) = self.tgs_req( - cname, sname, uc.get_realm(), ticket, key, etype, -- service_creds=mc, expect_pac=False) -- self.check_tgs_reply(rep) -- -- # Check the contents of the service ticket -- ticket = rep['ticket'] -- enc_part = self.decode_service_ticket(mc, ticket) -- # -- # We get an empty authorization-data element in the ticket. -- # i.e. no PAC -- self.assertEqual([], enc_part['authorization-data']) -- # check the crealm and cname -- cname = enc_part['cname'] -- self.assertEqual(NT_PRINCIPAL, cname['name-type']) -- self.assertEqual(alt_name.encode('UTF8'), cname['name-string'][0]) -- self.assertEqual(realm.upper().encode('UTF8'), enc_part['crealm']) -+ service_creds=mc, expect_pac=False, -+ expect_edata=False, -+ expected_error_mode=KDC_ERR_TGT_REVOKED) -+ self.check_error_rep(rep, KDC_ERR_TGT_REVOKED) - - def test_nt_principal_step_4_b(self): - ''' Step 4, pre-authentication -@@ -703,21 +693,10 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest): - - (rep, enc_part) = self.tgs_req( - cname, sname, uc.get_realm(), ticket, key, etype, -- service_creds=mc, expect_pac=False) -- self.check_tgs_reply(rep) -- -- # Check the contents of the service ticket -- ticket = rep['ticket'] -- enc_part = self.decode_service_ticket(mc, ticket) -- # -- # We get an empty authorization-data element in the ticket. -- # i.e. no PAC -- self.assertEqual([], enc_part['authorization-data']) -- # check the crealm and cname -- cname = enc_part['cname'] -- self.assertEqual(NT_ENTERPRISE_PRINCIPAL, cname['name-type']) -- self.assertEqual(ename.encode('UTF8'), cname['name-string'][0]) -- self.assertEqual(realm.upper().encode('UTF8'), enc_part['crealm']) -+ service_creds=mc, expect_pac=False, -+ expect_edata=False, -+ expected_error_mode=KDC_ERR_TGT_REVOKED) -+ self.check_error_rep(rep, KDC_ERR_TGT_REVOKED) - - def test_nt_enterprise_principal_step_6_b(self): - ''' Step 4, pre-authentication -diff --git a/python/samba/tests/krb5/s4u_tests.py b/python/samba/tests/krb5/s4u_tests.py -index a80a7b3427e..5f37525f393 100755 ---- a/python/samba/tests/krb5/s4u_tests.py -+++ b/python/samba/tests/krb5/s4u_tests.py -@@ -42,6 +42,7 @@ from samba.tests.krb5.rfc4120_constants import ( - KDC_ERR_INAPP_CKSUM, - KDC_ERR_MODIFIED, - KDC_ERR_SUMTYPE_NOSUPP, -+ KDC_ERR_TGT_REVOKED, - KU_PA_ENC_TIMESTAMP, - KU_AS_REP_ENC_PART, - KU_TGS_REP_ENC_PART_SUB_KEY, -@@ -278,6 +279,8 @@ class S4UKerberosTests(KDCBaseTest): - etypes = kdc_dict.pop('etypes', (AES256_CTS_HMAC_SHA1_96, - ARCFOUR_HMAC_MD5)) - -+ expect_edata = kdc_dict.pop('expect_edata', None) -+ - def generate_s4u2self_padata(_kdc_exchange_dict, - _callback_dict, - req_body): -@@ -309,7 +312,8 @@ class S4UKerberosTests(KDCBaseTest): - tgt=service_tgt, - authenticator_subkey=authenticator_subkey, - kdc_options=str(kdc_options), -- expect_claims=False) -+ expect_claims=False, -+ expect_edata=expect_edata) - - self._generic_kdc_exchange(kdc_exchange_dict, - cname=None, -@@ -343,15 +347,14 @@ class S4UKerberosTests(KDCBaseTest): - - self._run_s4u2self_test( - { -- 'expected_error_mode': (KDC_ERR_GENERIC, -- KDC_ERR_BADOPTION), -- 'expected_status': ntstatus.NT_STATUS_INVALID_PARAMETER, -+ 'expected_error_mode': KDC_ERR_TGT_REVOKED, - 'client_opts': { - 'not_delegated': False - }, - 'kdc_options': 'forwardable', - 'modify_service_tgt_fn': forwardable_no_pac, -- 'expected_flags': 'forwardable' -+ 'expected_flags': 'forwardable', -+ 'expect_edata': False - }) - - # Test performing an S4U2Self operation without requesting a forwardable -@@ -674,8 +677,8 @@ class S4UKerberosTests(KDCBaseTest): - # contain a PAC. - self._run_delegation_test( - { -- 'expected_error_mode': (KDC_ERR_BADOPTION, -- KDC_ERR_MODIFIED), -+ 'expected_error_mode': (KDC_ERR_MODIFIED, -+ KDC_ERR_TGT_REVOKED), - 'allow_delegation': True, - 'modify_client_tkt_fn': self.remove_ticket_pac, - 'expect_edata': False -@@ -686,9 +689,10 @@ class S4UKerberosTests(KDCBaseTest): - # PAC. - self._run_delegation_test( - { -- 'expected_error_mode': 0, -+ 'expected_error_mode': KDC_ERR_TGT_REVOKED, - 'allow_delegation': True, -- 'modify_service_tgt_fn': self.remove_ticket_pac -+ 'modify_service_tgt_fn': self.remove_ticket_pac, -+ 'expect_edata': False - }) - - def test_constrained_delegation_no_client_pac_no_auth_data_required(self): -@@ -696,8 +700,8 @@ class S4UKerberosTests(KDCBaseTest): - # contain a PAC. - self._run_delegation_test( - { -- 'expected_error_mode': (KDC_ERR_BADOPTION, -- KDC_ERR_MODIFIED), -+ 'expected_error_mode': (KDC_ERR_MODIFIED, -+ KDC_ERR_BADOPTION), - 'allow_delegation': True, - 'modify_client_tkt_fn': self.remove_ticket_pac, - 'expect_edata': False, -@@ -711,13 +715,14 @@ class S4UKerberosTests(KDCBaseTest): - # PAC. - self._run_delegation_test( - { -- 'expected_error_mode': (KDC_ERR_BADOPTION, -- KDC_ERR_MODIFIED), -+ 'expected_error_mode': KDC_ERR_TGT_REVOKED, - 'allow_delegation': True, - 'modify_service_tgt_fn': self.remove_ticket_pac, - 'service2_opts': { - 'no_auth_data_required': True -- } -+ }, -+ 'expect_pac': False, -+ 'expect_edata': False - }) - - def test_constrained_delegation_non_forwardable(self): -@@ -812,12 +817,11 @@ class S4UKerberosTests(KDCBaseTest): - # PAC. - self._run_delegation_test( - { -- 'expected_error_mode': KDC_ERR_BADOPTION, -- 'expected_status': -- ntstatus.NT_STATUS_NOT_FOUND, -+ 'expected_error_mode': KDC_ERR_TGT_REVOKED, - 'allow_rbcd': True, - 'pac_options': '0001', # supports RBCD -- 'modify_service_tgt_fn': self.remove_ticket_pac -+ 'modify_service_tgt_fn': self.remove_ticket_pac, -+ 'expect_edata': False - }) - - def test_rbcd_no_client_pac_no_auth_data_required_a(self): -@@ -858,15 +862,14 @@ class S4UKerberosTests(KDCBaseTest): - # PAC. - self._run_delegation_test( - { -- 'expected_error_mode': KDC_ERR_BADOPTION, -- 'expected_status': -- ntstatus.NT_STATUS_NOT_FOUND, -+ 'expected_error_mode': KDC_ERR_TGT_REVOKED, - 'allow_rbcd': True, - 'pac_options': '0001', # supports RBCD - 'modify_service_tgt_fn': self.remove_ticket_pac, - 'service2_opts': { - 'no_auth_data_required': True -- } -+ }, -+ 'expect_edata': False - }) - - def test_rbcd_non_forwardable(self): -@@ -941,8 +944,8 @@ class S4UKerberosTests(KDCBaseTest): - 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) -+ expected_error_mode = (KDC_ERR_MODIFIED, -+ KDC_ERR_BADOPTION) - else: - expected_error_mode = KDC_ERR_GENERIC - -@@ -1061,8 +1064,7 @@ class S4UKerberosTests(KDCBaseTest): - 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_error_mode = KDC_ERR_MODIFIED - expected_status = ntstatus.NT_STATUS_WRONG_PASSWORD - else: - expected_error_mode = 0 -@@ -1162,8 +1164,7 @@ class S4UKerberosTests(KDCBaseTest): - 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_error_mode = KDC_ERR_SUMTYPE_NOSUPP - expected_status = ntstatus.NT_STATUS_LOGON_FAILURE - else: - expected_error_mode = KDC_ERR_GENERIC -diff --git a/python/samba/tests/krb5/test_rpc.py b/python/samba/tests/krb5/test_rpc.py -index 2d483986e83..5a3c7339cea 100755 ---- a/python/samba/tests/krb5/test_rpc.py -+++ b/python/samba/tests/krb5/test_rpc.py -@@ -24,7 +24,10 @@ import ldb - - from samba import NTSTATUSError, credentials - from samba.dcerpc import lsa --from samba.ntstatus import NT_STATUS_NO_IMPERSONATION_TOKEN -+from samba.ntstatus import ( -+ NT_STATUS_ACCESS_DENIED, -+ NT_STATUS_NO_IMPERSONATION_TOKEN -+) - - from samba.tests.krb5.kdc_base_test import KDCBaseTest - -@@ -103,7 +106,8 @@ class RpcTests(KDCBaseTest): - self.fail() - - enum, _ = e.args -- self.assertEqual(NT_STATUS_NO_IMPERSONATION_TOKEN, enum) -+ self.assertIn(enum, {NT_STATUS_ACCESS_DENIED, -+ NT_STATUS_NO_IMPERSONATION_TOKEN}) - return - - (account_name, _) = conn.GetUserName(None, None, None) -diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc -index 0f62627ae31..cfbe698fb15 100644 ---- a/selftest/knownfail_heimdal_kdc -+++ b/selftest/knownfail_heimdal_kdc -@@ -71,16 +71,21 @@ - # 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_client_pac(?!_no_auth_data_required) - ^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_no_auth_data_required - ^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_no_service_pac -+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_no_service_pac_no_auth_data_required - ^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_forwardable -+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_no_pac - ^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_constrained_delegation_no_auth_data_required -@@ -97,3 +102,62 @@ - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_not_revealed - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_not_revealed - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_not_revealed -+# -+# Alias tests -+# -+^samba.tests.krb5.alias_tests.samba.tests.krb5.alias_tests.AliasTests.test_create_alias_delete -+^samba.tests.krb5.alias_tests.samba.tests.krb5.alias_tests.AliasTests.test_create_alias_rename -+^samba.tests.krb5.alias_tests.samba.tests.krb5.alias_tests.AliasTests.test_dc_alias_delete -+^samba.tests.krb5.alias_tests.samba.tests.krb5.alias_tests.AliasTests.test_dc_alias_rename -+# -+# KDC TGS tests -+# -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_logon_info_only_sid_mismatch_existing -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_logon_info_only_sid_mismatch_nonexisting -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_remove_pac -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_remove_pac_client_no_auth_data_required -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_remove_pac_service_no_auth_data_required -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_authdata_no_pac -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_no_pac -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_sid_mismatch_existing -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_sid_mismatch_nonexisting -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_sid_mismatch_existing -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_sid_mismatch_nonexisting -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_requester_sid_mismatch_existing -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_requester_sid_mismatch_nonexisting -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_authdata_no_pac -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_no_pac -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_pac_request_false -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_sid_mismatch_existing -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_sid_mismatch_nonexisting -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_sid_mismatch_existing -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_sid_mismatch_nonexisting -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_authdata_no_pac -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_no_pac -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_req_from_rodc_no_requester_sid -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_req_no_requester_sid -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_renew -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_rodc_renew -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_logon_info_only_sid_mismatch_existing -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_logon_info_only_sid_mismatch_nonexisting -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_pac_request_false -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_requester_sid_mismatch_existing -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_requester_sid_mismatch_nonexisting -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_sid_mismatch_existing -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_sid_mismatch_nonexisting -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_sid_mismatch_existing -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_sid_mismatch_nonexisting -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_authdata_no_pac -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_no_pac -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_sid_mismatch_existing -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_sid_mismatch_nonexisting -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_sid_mismatch_existing -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_sid_mismatch_nonexisting -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_wrong_sname -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_wrong_sname_krbtgt -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_authdata_no_pac -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_no_pac -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_sid_mismatch_existing -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_sid_mismatch_nonexisting -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_sid_mismatch_existing -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_sid_mismatch_nonexisting -diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc -index c046a46a4f3..31010c16391 100644 ---- a/selftest/knownfail_mit_kdc -+++ b/selftest/knownfail_mit_kdc -@@ -368,6 +368,8 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ - # - # KDC TGT tests - # -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_logon_info_only_sid_mismatch_existing -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_logon_info_only_sid_mismatch_nonexisting - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_authdata_no_pac - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_no_pac - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_allowed_denied -@@ -379,6 +381,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_renew_rodc_revealed - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_sid_mismatch_existing - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_sid_mismatch_nonexisting -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_sid_mismatch_existing -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_sid_mismatch_nonexisting -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_authdata_no_pac -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_no_pac - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_req - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_allowed_denied - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_denied -@@ -394,6 +400,7 @@ 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_tgs_authdata_no_pac - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_no_pac - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rename -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_req_no_requester_sid - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_allowed_denied - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_denied - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_no_krbtgt_link -@@ -403,6 +410,8 @@ 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_tgs_rodc_revealed - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_sid_mismatch_existing - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_sid_mismatch_nonexisting -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_sid_mismatch_existing -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_sid_mismatch_nonexisting - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_authdata_no_pac - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_no_pac - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_no_sname -@@ -432,6 +441,8 @@ 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_validate_rodc_revealed - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_sid_mismatch_existing - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_sid_mismatch_nonexisting -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_sid_mismatch_existing -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_sid_mismatch_nonexisting - # - # PAC attributes tests - # --- -2.25.1 - - -From 011a468c786bac72ce8ad40544ffa7798fa38a97 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Wed, 24 Nov 2021 12:04:36 +1300 -Subject: [PATCH 28/99] tests/krb5: Remove unnecessary expect_pac arguments - -The value of expect_pac is not considered if we are expecting an error. - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett -(cherry picked from commit 28d501875a98fa2817262eb8ec68bf91528428c2) ---- - python/samba/tests/krb5/kdc_tgs_tests.py | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py -index 7ea15f0fbab..6160ef649e8 100755 ---- a/python/samba/tests/krb5/kdc_tgs_tests.py -+++ b/python/samba/tests/krb5/kdc_tgs_tests.py -@@ -412,7 +412,7 @@ class KdcTgsTests(KDCBaseTest): - self.assertIsNone(pac) - - self._make_tgs_request(client_creds, service_creds, tgt, -- expect_pac=False, expect_error=True) -+ expect_error=True) - - def test_remove_pac_client_no_auth_data_required(self): - client_creds = self.get_cached_creds( -@@ -427,7 +427,7 @@ class KdcTgsTests(KDCBaseTest): - self.assertIsNone(pac) - - self._make_tgs_request(client_creds, service_creds, tgt, -- expect_pac=False, expect_error=True) -+ expect_error=True) - - def test_remove_pac(self): - client_creds = self.get_client_creds() -@@ -440,7 +440,7 @@ class KdcTgsTests(KDCBaseTest): - self.assertIsNone(pac) - - self._make_tgs_request(client_creds, service_creds, tgt, -- expect_pac=False, expect_error=True) -+ expect_error=True) - - def test_upn_dns_info_ex_user(self): - client_creds = self.get_client_creds() --- -2.25.1 - - -From a696ddc90a9f31997478620807c7a4991fc851ab Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Tue, 30 Nov 2021 09:26:40 +1300 -Subject: [PATCH 29/99] tests/krb5: Add tests for invalid TGTs - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett -(cherry picked from commit 7574ba9f580fca552b80532a49d00e657fbdf4fd) ---- - python/samba/tests/krb5/kdc_tgs_tests.py | 16 ++++++++++++++++ - python/samba/tests/krb5/rfc4120_constants.py | 1 + - selftest/knownfail_mit_kdc | 3 ++- - 3 files changed, 19 insertions(+), 1 deletion(-) - -diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py -index 6160ef649e8..f5f091610ac 100755 ---- a/python/samba/tests/krb5/kdc_tgs_tests.py -+++ b/python/samba/tests/krb5/kdc_tgs_tests.py -@@ -44,6 +44,7 @@ from samba.tests.krb5.rfc4120_constants import ( - KDC_ERR_C_PRINCIPAL_UNKNOWN, - KDC_ERR_S_PRINCIPAL_UNKNOWN, - KDC_ERR_TGT_REVOKED, -+ KRB_ERR_TKT_NYV, - KDC_ERR_WRONG_REALM, - NT_PRINCIPAL, - NT_SRV_INST, -@@ -511,6 +512,21 @@ class KdcTgsTests(KDCBaseTest): - tgt = self._get_tgt(creds) - self._user2user(tgt, creds, expected_error=0) - -+ def test_tgs_req_invalid(self): -+ creds = self._get_creds() -+ tgt = self._get_tgt(creds, invalid=True) -+ self._run_tgs(tgt, expected_error=KRB_ERR_TKT_NYV) -+ -+ def test_s4u2self_req_invalid(self): -+ creds = self._get_creds() -+ tgt = self._get_tgt(creds, invalid=True) -+ self._s4u2self(tgt, creds, expected_error=KRB_ERR_TKT_NYV) -+ -+ def test_user2user_req_invalid(self): -+ creds = self._get_creds() -+ tgt = self._get_tgt(creds, invalid=True) -+ self._user2user(tgt, creds, expected_error=KRB_ERR_TKT_NYV) -+ - def test_tgs_req_no_requester_sid(self): - creds = self._get_creds() - tgt = self._get_tgt(creds, remove_requester_sid=True) -diff --git a/python/samba/tests/krb5/rfc4120_constants.py b/python/samba/tests/krb5/rfc4120_constants.py -index 5251e291fde..a9fdc5735dd 100644 ---- a/python/samba/tests/krb5/rfc4120_constants.py -+++ b/python/samba/tests/krb5/rfc4120_constants.py -@@ -76,6 +76,7 @@ KDC_ERR_TGT_REVOKED = 20 - KDC_ERR_PREAUTH_FAILED = 24 - KDC_ERR_PREAUTH_REQUIRED = 25 - KDC_ERR_BAD_INTEGRITY = 31 -+KRB_ERR_TKT_NYV = 33 - KDC_ERR_NOT_US = 35 - KDC_ERR_BADMATCH = 36 - KDC_ERR_SKEW = 37 -diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc -index 31010c16391..2aa7fb2b370 100644 ---- a/selftest/knownfail_mit_kdc -+++ b/selftest/knownfail_mit_kdc -@@ -385,7 +385,7 @@ 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_renew_sid_mismatch_nonexisting - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_authdata_no_pac - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_no_pac --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_req -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_req(?!_invalid) - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_allowed_denied - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_denied - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_no_krbtgt_link -@@ -415,6 +415,7 @@ 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_user2user_authdata_no_pac - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_no_pac - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_no_sname -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_req_invalid - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_allowed_denied - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_denied - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_no_krbtgt_link --- -2.25.1 - - -From 7197641eda7ba738cfcce40d43314588c6474251 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Wed, 24 Nov 2021 12:10:45 +1300 -Subject: [PATCH 30/99] tests/krb5: Add tests for TGS requests with a non-TGT - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett -(cherry picked from commit 778029c1dc443b87f4ed4b9d2c613d0e6fc45b0d) ---- - python/samba/tests/krb5/kdc_tgs_tests.py | 51 ++++++++++++++++++++++++ - selftest/knownfail_mit_kdc | 2 + - 2 files changed, 53 insertions(+) - -diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py -index f5f091610ac..52297c963e8 100755 ---- a/python/samba/tests/krb5/kdc_tgs_tests.py -+++ b/python/samba/tests/krb5/kdc_tgs_tests.py -@@ -40,6 +40,7 @@ from samba.tests.krb5.rfc4120_constants import ( - KDC_ERR_BADMATCH, - KDC_ERR_GENERIC, - KDC_ERR_MODIFIED, -+ KDC_ERR_NOT_US, - KDC_ERR_POLICY, - KDC_ERR_C_PRINCIPAL_UNKNOWN, - KDC_ERR_S_PRINCIPAL_UNKNOWN, -@@ -1234,6 +1235,56 @@ class KdcTgsTests(KDCBaseTest): - expected_error=(KDC_ERR_GENERIC, - KDC_ERR_S_PRINCIPAL_UNKNOWN)) - -+ def test_tgs_service_ticket(self): -+ creds = self._get_creds() -+ tgt = self._get_tgt(creds) -+ -+ service_creds = self.get_service_creds() -+ service_ticket = self.get_service_ticket(tgt, service_creds) -+ -+ self._run_tgs(service_ticket, -+ expected_error=(KDC_ERR_NOT_US, KDC_ERR_POLICY)) -+ -+ def test_renew_service_ticket(self): -+ creds = self._get_creds() -+ tgt = self._get_tgt(creds) -+ -+ service_creds = self.get_service_creds() -+ service_ticket = self.get_service_ticket(tgt, service_creds) -+ -+ service_ticket = self.modified_ticket( -+ service_ticket, -+ modify_fn=self._modify_renewable, -+ checksum_keys=self.get_krbtgt_checksum_key()) -+ -+ self._renew_tgt(service_ticket, -+ expected_error=KDC_ERR_POLICY) -+ -+ def test_validate_service_ticket(self): -+ creds = self._get_creds() -+ tgt = self._get_tgt(creds) -+ -+ service_creds = self.get_service_creds() -+ service_ticket = self.get_service_ticket(tgt, service_creds) -+ -+ service_ticket = self.modified_ticket( -+ service_ticket, -+ modify_fn=self._modify_invalid, -+ checksum_keys=self.get_krbtgt_checksum_key()) -+ -+ self._validate_tgt(service_ticket, -+ expected_error=KDC_ERR_POLICY) -+ -+ def test_s4u2self_service_ticket(self): -+ creds = self._get_creds() -+ tgt = self._get_tgt(creds) -+ -+ service_creds = self.get_service_creds() -+ service_ticket = self.get_service_ticket(tgt, service_creds) -+ -+ self._s4u2self(service_ticket, creds, -+ expected_error=(KDC_ERR_NOT_US, KDC_ERR_POLICY)) -+ - def test_user2user_service_ticket(self): - creds = self._get_creds() - tgt = self._get_tgt(creds) -diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc -index 2aa7fb2b370..8f8b0b18f18 100644 ---- a/selftest/knownfail_mit_kdc -+++ b/selftest/knownfail_mit_kdc -@@ -381,6 +381,7 @@ 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_renew_rodc_revealed - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_sid_mismatch_existing - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_sid_mismatch_nonexisting -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_service_ticket - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_sid_mismatch_existing - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_sid_mismatch_nonexisting - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_authdata_no_pac -@@ -442,6 +443,7 @@ 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_validate_rodc_revealed - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_sid_mismatch_existing - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_sid_mismatch_nonexisting -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_service_ticket - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_sid_mismatch_existing - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_sid_mismatch_nonexisting - # --- -2.25.1 - - -From e24898c41c572dc8ec1374e67a4e029207b21ee2 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Wed, 24 Nov 2021 12:09:18 +1300 -Subject: [PATCH 31/99] tests/krb5: Add TGS-REQ tests with FAST - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett -(cherry picked from commit ec823c2a83c639f1d7c422153a53d366750e5f2a) ---- - python/samba/tests/krb5/kdc_tgs_tests.py | 184 ++++++++++++++++++++++- - selftest/knownfail_heimdal_kdc | 13 ++ - selftest/knownfail_mit_kdc | 17 +++ - 3 files changed, 212 insertions(+), 2 deletions(-) - -diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py -index 52297c963e8..99a91528fa8 100755 ---- a/python/samba/tests/krb5/kdc_tgs_tests.py -+++ b/python/samba/tests/krb5/kdc_tgs_tests.py -@@ -32,6 +32,7 @@ os.environ["PYTHONUNBUFFERED"] = "1" - - import samba.tests.krb5.kcrypto as kcrypto - 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, -@@ -513,6 +514,11 @@ class KdcTgsTests(KDCBaseTest): - tgt = self._get_tgt(creds) - self._user2user(tgt, creds, expected_error=0) - -+ def test_fast_req(self): -+ creds = self._get_creds() -+ tgt = self._get_tgt(creds) -+ self._fast(tgt, creds, expected_error=0) -+ - def test_tgs_req_invalid(self): - creds = self._get_creds() - tgt = self._get_tgt(creds, invalid=True) -@@ -528,6 +534,12 @@ class KdcTgsTests(KDCBaseTest): - tgt = self._get_tgt(creds, invalid=True) - self._user2user(tgt, creds, expected_error=KRB_ERR_TKT_NYV) - -+ def test_fast_req_invalid(self): -+ creds = self._get_creds() -+ tgt = self._get_tgt(creds, invalid=True) -+ self._fast(tgt, creds, expected_error=KRB_ERR_TKT_NYV, -+ expected_sname=self.get_krbtgt_sname()) -+ - def test_tgs_req_no_requester_sid(self): - creds = self._get_creds() - tgt = self._get_tgt(creds, remove_requester_sid=True) -@@ -583,6 +595,12 @@ class KdcTgsTests(KDCBaseTest): - tgt = self._get_tgt(creds, remove_pac=True) - self._user2user(tgt, creds, expected_error=KDC_ERR_TGT_REVOKED) - -+ def test_fast_no_pac(self): -+ creds = self._get_creds() -+ tgt = self._get_tgt(creds, remove_pac=True) -+ self._fast(tgt, creds, expected_error=KDC_ERR_TGT_REVOKED, -+ expected_sname=self.get_krbtgt_sname()) -+ - # Test making a request with authdata and without a PAC. - def test_tgs_authdata_no_pac(self): - creds = self._get_creds() -@@ -613,6 +631,12 @@ class KdcTgsTests(KDCBaseTest): - tgt = self._get_tgt(creds, remove_pac=True, allow_empty_authdata=True) - self._user2user(tgt, creds, expected_error=KDC_ERR_TGT_REVOKED) - -+ def test_fast_authdata_no_pac(self): -+ creds = self._get_creds() -+ tgt = self._get_tgt(creds, remove_pac=True, allow_empty_authdata=True) -+ self._fast(tgt, creds, expected_error=KDC_ERR_TGT_REVOKED, -+ expected_sname=self.get_krbtgt_sname()) -+ - # Test changing the SID in the PAC to that of another account. - def test_tgs_sid_mismatch_existing(self): - creds = self._get_creds() -@@ -646,6 +670,14 @@ class KdcTgsTests(KDCBaseTest): - self._user2user(tgt, creds, - expected_error=KDC_ERR_TGT_REVOKED) - -+ def test_fast_sid_mismatch_existing(self): -+ creds = self._get_creds() -+ existing_rid = self._get_existing_rid() -+ tgt = self._get_tgt(creds, new_rid=existing_rid) -+ self._fast(tgt, creds, -+ expected_error=KDC_ERR_TGT_REVOKED, -+ expected_sname=self.get_krbtgt_sname()) -+ - def test_requester_sid_mismatch_existing(self): - creds = self._get_creds() - existing_rid = self._get_existing_rid() -@@ -702,6 +734,14 @@ class KdcTgsTests(KDCBaseTest): - self._user2user(tgt, creds, - expected_error=KDC_ERR_TGT_REVOKED) - -+ def test_fast_sid_mismatch_nonexisting(self): -+ creds = self._get_creds() -+ nonexistent_rid = self._get_non_existent_rid() -+ tgt = self._get_tgt(creds, new_rid=nonexistent_rid) -+ self._fast(tgt, creds, -+ expected_error=KDC_ERR_TGT_REVOKED, -+ expected_sname=self.get_krbtgt_sname()) -+ - def test_requester_sid_mismatch_nonexisting(self): - creds = self._get_creds() - nonexistent_rid = self._get_non_existent_rid() -@@ -799,6 +839,16 @@ class KdcTgsTests(KDCBaseTest): - self._user2user(tgt, creds, - expected_error=KDC_ERR_TGT_REVOKED) - -+ def test_fast_rodc_sid_mismatch_existing(self): -+ creds = self._get_creds(replication_allowed=True, -+ revealed_to_rodc=True) -+ existing_rid = self._get_existing_rid(replication_allowed=True, -+ revealed_to_rodc=True) -+ tgt = self._get_tgt(creds, from_rodc=True, new_rid=existing_rid) -+ self._fast(tgt, creds, -+ expected_error=KDC_ERR_TGT_REVOKED, -+ expected_sname=self.get_krbtgt_sname()) -+ - def test_tgs_rodc_requester_sid_mismatch_existing(self): - creds = self._get_creds(replication_allowed=True, - revealed_to_rodc=True) -@@ -866,6 +916,15 @@ class KdcTgsTests(KDCBaseTest): - self._user2user(tgt, creds, - expected_error=KDC_ERR_TGT_REVOKED) - -+ def test_fast_rodc_sid_mismatch_nonexisting(self): -+ creds = self._get_creds(replication_allowed=True, -+ revealed_to_rodc=True) -+ nonexistent_rid = self._get_non_existent_rid() -+ tgt = self._get_tgt(creds, from_rodc=True, new_rid=nonexistent_rid) -+ self._fast(tgt, creds, -+ expected_error=KDC_ERR_TGT_REVOKED, -+ expected_sname=self.get_krbtgt_sname()) -+ - def test_tgs_rodc_requester_sid_mismatch_nonexisting(self): - creds = self._get_creds(replication_allowed=True, - revealed_to_rodc=True) -@@ -955,6 +1014,14 @@ class KdcTgsTests(KDCBaseTest): - self._remove_rodc_partial_secrets() - self._user2user(tgt, creds, expected_error=KDC_ERR_POLICY) - -+ def test_fast_rodc_no_partial_secrets(self): -+ creds = self._get_creds(replication_allowed=True, -+ revealed_to_rodc=True) -+ tgt = self._get_tgt(creds, from_rodc=True) -+ self._remove_rodc_partial_secrets() -+ self._fast(tgt, creds, expected_error=KDC_ERR_POLICY, -+ expected_sname=self.get_krbtgt_sname()) -+ - # Test with an RODC-issued ticket where the RODC account does not have an - # msDS-KrbTgtLink. - def test_tgs_rodc_no_krbtgt_link(self): -@@ -992,6 +1059,14 @@ class KdcTgsTests(KDCBaseTest): - self._remove_rodc_krbtgt_link() - self._user2user(tgt, creds, expected_error=KDC_ERR_POLICY) - -+ def test_fast_rodc_no_krbtgt_link(self): -+ creds = self._get_creds(replication_allowed=True, -+ revealed_to_rodc=True) -+ tgt = self._get_tgt(creds, from_rodc=True) -+ self._remove_rodc_krbtgt_link() -+ self._fast(tgt, creds, expected_error=KDC_ERR_POLICY, -+ expected_sname=self.get_krbtgt_sname()) -+ - # Test with an RODC-issued ticket where the client is not allowed to - # replicate to the RODC. - def test_tgs_rodc_not_allowed(self): -@@ -1019,6 +1094,12 @@ class KdcTgsTests(KDCBaseTest): - tgt = self._get_tgt(creds, from_rodc=True) - self._user2user(tgt, creds, expected_error=KDC_ERR_TGT_REVOKED) - -+ def test_fast_rodc_not_allowed(self): -+ creds = self._get_creds(revealed_to_rodc=True) -+ tgt = self._get_tgt(creds, from_rodc=True) -+ self._fast(tgt, creds, expected_error=KDC_ERR_TGT_REVOKED, -+ expected_sname=self.get_krbtgt_sname()) -+ - # Test with an RODC-issued ticket where the client is denied from - # replicating to the RODC. - def test_tgs_rodc_denied(self): -@@ -1051,6 +1132,13 @@ class KdcTgsTests(KDCBaseTest): - tgt = self._get_tgt(creds, from_rodc=True) - self._user2user(tgt, creds, expected_error=KDC_ERR_TGT_REVOKED) - -+ def test_fast_rodc_denied(self): -+ creds = self._get_creds(replication_denied=True, -+ revealed_to_rodc=True) -+ tgt = self._get_tgt(creds, from_rodc=True) -+ self._fast(tgt, creds, expected_error=KDC_ERR_TGT_REVOKED, -+ expected_sname=self.get_krbtgt_sname()) -+ - # Test with an RODC-issued ticket where the client is both allowed and - # denied replicating to the RODC. - def test_tgs_rodc_allowed_denied(self): -@@ -1088,6 +1176,14 @@ class KdcTgsTests(KDCBaseTest): - tgt = self._get_tgt(creds, from_rodc=True) - self._user2user(tgt, creds, expected_error=KDC_ERR_TGT_REVOKED) - -+ def test_fast_rodc_allowed_denied(self): -+ creds = self._get_creds(replication_allowed=True, -+ replication_denied=True, -+ revealed_to_rodc=True) -+ tgt = self._get_tgt(creds, from_rodc=True) -+ self._fast(tgt, creds, expected_error=KDC_ERR_TGT_REVOKED, -+ expected_sname=self.get_krbtgt_sname()) -+ - # Test user-to-user with incorrect service principal names. - def test_user2user_matching_sname_host(self): - creds = self._get_creds() -@@ -1295,6 +1391,17 @@ class KdcTgsTests(KDCBaseTest): - self._user2user(service_ticket, creds, - expected_error=(KDC_ERR_MODIFIED, KDC_ERR_POLICY)) - -+ # Expected to fail against Windows, which does not produce a policy error. -+ def test_fast_service_ticket(self): -+ creds = self._get_creds() -+ tgt = self._get_tgt(creds) -+ -+ service_creds = self.get_service_creds() -+ service_ticket = self.get_service_ticket(tgt, service_creds) -+ -+ self._fast(service_ticket, creds, -+ expected_error=KDC_ERR_POLICY) -+ - def test_pac_attrs_none(self): - creds = self._get_creds() - self.get_tgt(creds, pac_request=None, -@@ -1792,6 +1899,34 @@ class KdcTgsTests(KDCBaseTest): - pac = self.get_ticket_pac(ticket) - self.assertIsNotNone(pac) - -+ def test_fast_pac_request_none(self): -+ creds = self._get_creds() -+ tgt = self.get_tgt(creds, pac_request=None) -+ -+ ticket = self._fast(tgt, creds, expected_error=0, expect_pac=True) -+ -+ pac = self.get_ticket_pac(ticket) -+ self.assertIsNotNone(pac) -+ -+ def test_fast_pac_request_false(self): -+ creds = self._get_creds() -+ tgt = self.get_tgt(creds, pac_request=False) -+ -+ ticket = self._fast(tgt, creds, expected_error=0, -+ expect_pac=True) -+ -+ pac = self.get_ticket_pac(ticket, expect_pac=True) -+ self.assertIsNotNone(pac) -+ -+ def test_fast_pac_request_true(self): -+ creds = self._get_creds() -+ tgt = self.get_tgt(creds, pac_request=True) -+ -+ ticket = self._fast(tgt, creds, expected_error=0, expect_pac=True) -+ -+ pac = self.get_ticket_pac(ticket) -+ self.assertIsNotNone(pac) -+ - def test_tgs_rodc_pac_request_none(self): - creds = self._get_creds(replication_allowed=True, - revealed_to_rodc=True) -@@ -2192,13 +2327,28 @@ class KdcTgsTests(KDCBaseTest): - srealm=srealm, - expect_pac=expect_pac) - -+ def _fast(self, armor_tgt, armor_tgt_creds, expected_error, -+ expected_sname=None, expect_pac=True): -+ user_creds = self._get_mach_creds() -+ user_tgt = self.get_tgt(user_creds) -+ -+ target_creds = self.get_service_creds() -+ -+ return self._tgs_req(user_tgt, expected_error, target_creds, -+ armor_tgt=armor_tgt, -+ expected_sname=expected_sname, -+ expect_pac=expect_pac) -+ - def _tgs_req(self, tgt, expected_error, target_creds, -+ armor_tgt=None, - kdc_options='0', - expected_cname=None, -+ expected_sname=None, - additional_ticket=None, - generate_padata_fn=None, - sname=None, - srealm=None, -+ use_fast=False, - expect_claims=True, - expect_pac=True, - expect_pac_attrs=None, -@@ -2214,7 +2364,8 @@ class KdcTgsTests(KDCBaseTest): - - if sname is False: - sname = None -- expected_sname = self.get_krbtgt_sname() -+ if expected_sname is None: -+ expected_sname = self.get_krbtgt_sname() - else: - if sname is None: - target_name = target_creds.get_username() -@@ -2229,7 +2380,8 @@ class KdcTgsTests(KDCBaseTest): - name_type=NT_PRINCIPAL, - names=['host', target_name]) - -- expected_sname = sname -+ if expected_sname is None: -+ expected_sname = sname - - if additional_ticket is not None: - additional_tickets = [additional_ticket.ticket] -@@ -2241,6 +2393,28 @@ class KdcTgsTests(KDCBaseTest): - - subkey = self.RandomKey(tgt.session_key.etype) - -+ if armor_tgt is not None: -+ armor_subkey = self.RandomKey(subkey.etype) -+ explicit_armor_key = self.generate_armor_key(armor_subkey, -+ armor_tgt.session_key) -+ armor_key = kcrypto.cf2(explicit_armor_key.key, -+ subkey.key, -+ b'explicitarmor', -+ b'tgsarmor') -+ armor_key = Krb5EncryptionKey(armor_key, None) -+ -+ generate_fast_fn = self.generate_simple_fast -+ generate_fast_armor_fn = self.generate_ap_req -+ -+ pac_options = '1' # claims support -+ else: -+ armor_subkey = None -+ armor_key = None -+ generate_fast_fn = None -+ generate_fast_armor_fn = None -+ -+ pac_options = None -+ - etypes = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) - - if expected_error: -@@ -2260,12 +2434,18 @@ class KdcTgsTests(KDCBaseTest): - expected_sname=expected_sname, - ticket_decryption_key=decryption_key, - generate_padata_fn=generate_padata_fn, -+ generate_fast_fn=generate_fast_fn, -+ generate_fast_armor_fn=generate_fast_armor_fn, - 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, - expected_status=expected_status, - tgt=tgt, -+ armor_key=armor_key, -+ armor_tgt=armor_tgt, -+ armor_subkey=armor_subkey, -+ pac_options=pac_options, - authenticator_subkey=subkey, - kdc_options=kdc_options, - expect_edata=expect_edata, -diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc -index cfbe698fb15..42b70e97f60 100644 ---- a/selftest/knownfail_heimdal_kdc -+++ b/selftest/knownfail_heimdal_kdc -@@ -112,6 +112,19 @@ - # - # KDC TGS tests - # -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_authdata_no_pac -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_no_pac -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_req_invalid -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_rodc_allowed_denied -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_rodc_denied -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_rodc_no_krbtgt_link -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_rodc_no_partial_secrets -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_rodc_not_allowed -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_rodc_sid_mismatch_existing -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_rodc_sid_mismatch_nonexisting -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_service_ticket -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_sid_mismatch_existing -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_sid_mismatch_nonexisting - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_logon_info_only_sid_mismatch_existing - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_logon_info_only_sid_mismatch_nonexisting - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_remove_pac -diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc -index 8f8b0b18f18..1723481c931 100644 ---- a/selftest/knownfail_mit_kdc -+++ b/selftest/knownfail_mit_kdc -@@ -368,6 +368,23 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ - # - # KDC TGT tests - # -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_authdata_no_pac -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_no_pac -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_pac_request_false -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_pac_request_none -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_pac_request_true -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_req -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_req_invalid -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_rodc_allowed_denied -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_rodc_denied -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_rodc_no_krbtgt_link -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_rodc_no_partial_secrets -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_rodc_not_allowed -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_rodc_sid_mismatch_existing -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_rodc_sid_mismatch_nonexisting -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_service_ticket -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_sid_mismatch_existing -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_sid_mismatch_nonexisting - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_logon_info_only_sid_mismatch_existing - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_logon_info_only_sid_mismatch_nonexisting - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_authdata_no_pac --- -2.25.1 - - -From 42f09fdbdbdc1c2a6fc6c29e8df9c54c345c8fbf Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Wed, 24 Nov 2021 12:37:08 +1300 -Subject: [PATCH 32/99] tests/krb5: Align PAC buffer checking to more closely - match Windows with PacRequestorEnforcement=2 - -We set EXPECT_EXTRA_PAC_BUFFERS to 0 for the moment. This signifies that -these checks are currently not enforced, which avoids a lot of test -failures. - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett -(cherry picked from commit ebc9137cee94dee9dcf0e47d5bc0dc83de7aaaa1) ---- - python/samba/tests/krb5/kdc_tgs_tests.py | 121 ++++++++++++++++------- - python/samba/tests/krb5/raw_testcase.py | 39 ++++++-- - selftest/knownfail_heimdal_kdc | 9 ++ - selftest/knownfail_mit_kdc | 6 ++ - source4/selftest/tests.py | 58 +++++++---- - 5 files changed, 168 insertions(+), 65 deletions(-) - -diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py -index 99a91528fa8..f14439a4ab5 100755 ---- a/python/samba/tests/krb5/kdc_tgs_tests.py -+++ b/python/samba/tests/krb5/kdc_tgs_tests.py -@@ -497,12 +497,18 @@ class KdcTgsTests(KDCBaseTest): - def test_renew_req(self): - creds = self._get_creds() - tgt = self._get_tgt(creds, renewable=True) -- self._renew_tgt(tgt, expected_error=0) -+ self._renew_tgt(tgt, expected_error=0, -+ expect_pac_attrs=True, -+ expect_pac_attrs_pac_request=True, -+ expect_requester_sid=True) - - def test_validate_req(self): - creds = self._get_creds() - tgt = self._get_tgt(creds, invalid=True) -- self._validate_tgt(tgt, expected_error=0) -+ self._validate_tgt(tgt, expected_error=0, -+ expect_pac_attrs=True, -+ expect_pac_attrs_pac_request=True, -+ expect_requester_sid=True) - - def test_s4u2self_req(self): - creds = self._get_creds() -@@ -774,13 +780,17 @@ class KdcTgsTests(KDCBaseTest): - creds = self._get_creds(replication_allowed=True, - revealed_to_rodc=True) - tgt = self._get_tgt(creds, renewable=True, from_rodc=True) -- self._renew_tgt(tgt, expected_error=0) -+ self._renew_tgt(tgt, expected_error=0, -+ expect_pac_attrs=False, -+ expect_requester_sid=True) - - def test_validate_rodc_revealed(self): - creds = self._get_creds(replication_allowed=True, - revealed_to_rodc=True) - tgt = self._get_tgt(creds, invalid=True, from_rodc=True) -- self._validate_tgt(tgt, expected_error=0) -+ self._validate_tgt(tgt, expected_error=0, -+ expect_pac_attrs=False, -+ expect_requester_sid=True) - - def test_s4u2self_rodc_revealed(self): - creds = self._get_creds(replication_allowed=True, -@@ -1434,7 +1444,8 @@ class KdcTgsTests(KDCBaseTest): - self._renew_tgt(tgt, expected_error=0, - expect_pac=True, - expect_pac_attrs=True, -- expect_pac_attrs_pac_request=None) -+ expect_pac_attrs_pac_request=None, -+ expect_requester_sid=True) - - def test_pac_attrs_renew_false(self): - creds = self._get_creds() -@@ -1447,7 +1458,8 @@ class KdcTgsTests(KDCBaseTest): - self._renew_tgt(tgt, expected_error=0, - expect_pac=True, - expect_pac_attrs=True, -- expect_pac_attrs_pac_request=False) -+ expect_pac_attrs_pac_request=False, -+ expect_requester_sid=True) - - def test_pac_attrs_renew_true(self): - creds = self._get_creds() -@@ -1460,7 +1472,8 @@ class KdcTgsTests(KDCBaseTest): - self._renew_tgt(tgt, expected_error=0, - expect_pac=True, - expect_pac_attrs=True, -- expect_pac_attrs_pac_request=True) -+ expect_pac_attrs_pac_request=True, -+ expect_requester_sid=True) - - def test_pac_attrs_rodc_renew_none(self): - creds = self._get_creds(replication_allowed=True, -@@ -1473,8 +1486,8 @@ class KdcTgsTests(KDCBaseTest): - - self._renew_tgt(tgt, expected_error=0, - expect_pac=True, -- expect_pac_attrs=True, -- expect_pac_attrs_pac_request=None) -+ expect_pac_attrs=False, -+ expect_requester_sid=True) - - def test_pac_attrs_rodc_renew_false(self): - creds = self._get_creds(replication_allowed=True, -@@ -1487,8 +1500,8 @@ class KdcTgsTests(KDCBaseTest): - - self._renew_tgt(tgt, expected_error=0, - expect_pac=True, -- expect_pac_attrs=True, -- expect_pac_attrs_pac_request=False) -+ expect_pac_attrs=False, -+ expect_requester_sid=True) - - def test_pac_attrs_rodc_renew_true(self): - creds = self._get_creds(replication_allowed=True, -@@ -1501,8 +1514,8 @@ class KdcTgsTests(KDCBaseTest): - - self._renew_tgt(tgt, expected_error=0, - expect_pac=True, -- expect_pac_attrs=True, -- expect_pac_attrs_pac_request=True) -+ expect_pac_attrs=False, -+ expect_requester_sid=True) - - def test_pac_attrs_missing_renew_none(self): - creds = self._get_creds() -@@ -1515,7 +1528,8 @@ class KdcTgsTests(KDCBaseTest): - - self._renew_tgt(tgt, expected_error=0, - expect_pac=True, -- expect_pac_attrs=False) -+ expect_pac_attrs=False, -+ expect_requester_sid=True) - - def test_pac_attrs_missing_renew_false(self): - creds = self._get_creds() -@@ -1528,7 +1542,8 @@ class KdcTgsTests(KDCBaseTest): - - self._renew_tgt(tgt, expected_error=0, - expect_pac=True, -- expect_pac_attrs=False) -+ expect_pac_attrs=False, -+ expect_requester_sid=True) - - def test_pac_attrs_missing_renew_true(self): - creds = self._get_creds() -@@ -1541,7 +1556,8 @@ class KdcTgsTests(KDCBaseTest): - - self._renew_tgt(tgt, expected_error=0, - expect_pac=True, -- expect_pac_attrs=False) -+ expect_pac_attrs=False, -+ expect_requester_sid=True) - - def test_pac_attrs_missing_rodc_renew_none(self): - creds = self._get_creds(replication_allowed=True, -@@ -1555,7 +1571,8 @@ class KdcTgsTests(KDCBaseTest): - - self._renew_tgt(tgt, expected_error=0, - expect_pac=True, -- expect_pac_attrs=False) -+ expect_pac_attrs=False, -+ expect_requester_sid=True) - - def test_pac_attrs_missing_rodc_renew_false(self): - creds = self._get_creds(replication_allowed=True, -@@ -1569,7 +1586,8 @@ class KdcTgsTests(KDCBaseTest): - - self._renew_tgt(tgt, expected_error=0, - expect_pac=True, -- expect_pac_attrs=False) -+ expect_pac_attrs=False, -+ expect_requester_sid=True) - - def test_pac_attrs_missing_rodc_renew_true(self): - creds = self._get_creds(replication_allowed=True, -@@ -1583,7 +1601,8 @@ class KdcTgsTests(KDCBaseTest): - - self._renew_tgt(tgt, expected_error=0, - expect_pac=True, -- expect_pac_attrs=False) -+ expect_pac_attrs=False, -+ expect_requester_sid=True) - - def test_tgs_pac_attrs_none(self): - creds = self._get_creds() -@@ -1593,8 +1612,7 @@ class KdcTgsTests(KDCBaseTest): - expect_pac_attrs_pac_request=None) - - self._run_tgs(tgt, expected_error=0, expect_pac=True, -- expect_pac_attrs=True, -- expect_pac_attrs_pac_request=None) -+ expect_pac_attrs=False) - - def test_tgs_pac_attrs_false(self): - creds = self._get_creds() -@@ -1603,7 +1621,8 @@ class KdcTgsTests(KDCBaseTest): - expect_pac_attrs=True, - expect_pac_attrs_pac_request=False) - -- self._run_tgs(tgt, expected_error=0, expect_pac=False) -+ self._run_tgs(tgt, expected_error=0, expect_pac=False, -+ expect_pac_attrs=False) - - def test_tgs_pac_attrs_true(self): - creds = self._get_creds() -@@ -1613,8 +1632,7 @@ class KdcTgsTests(KDCBaseTest): - expect_pac_attrs_pac_request=True) - - self._run_tgs(tgt, expected_error=0, expect_pac=True, -- expect_pac_attrs=True, -- expect_pac_attrs_pac_request=True) -+ expect_pac_attrs=False) - - def test_as_requester_sid(self): - creds = self._get_creds() -@@ -1639,8 +1657,7 @@ class KdcTgsTests(KDCBaseTest): - expect_requester_sid=True) - - self._run_tgs(tgt, expected_error=0, expect_pac=True, -- expected_sid=sid, -- expect_requester_sid=True) -+ expect_requester_sid=False) - - def test_tgs_requester_sid_renew(self): - creds = self._get_creds() -@@ -1655,6 +1672,8 @@ class KdcTgsTests(KDCBaseTest): - tgt = self._modify_tgt(tgt, renewable=True) - - self._renew_tgt(tgt, expected_error=0, expect_pac=True, -+ expect_pac_attrs=True, -+ expect_pac_attrs_pac_request=None, - expected_sid=sid, - expect_requester_sid=True) - -@@ -1672,6 +1691,7 @@ class KdcTgsTests(KDCBaseTest): - tgt = self._modify_tgt(tgt, from_rodc=True, renewable=True) - - self._renew_tgt(tgt, expected_error=0, expect_pac=True, -+ expect_pac_attrs=False, - expected_sid=sid, - expect_requester_sid=True) - -@@ -1738,7 +1758,10 @@ class KdcTgsTests(KDCBaseTest): - tgt = self.get_tgt(creds, pac_request=None) - tgt = self._modify_tgt(tgt, renewable=True) - -- tgt = self._renew_tgt(tgt, expected_error=0, expect_pac=None) -+ tgt = self._renew_tgt(tgt, expected_error=0, expect_pac=None, -+ expect_pac_attrs=True, -+ expect_pac_attrs_pac_request=None, -+ expect_requester_sid=True) - - ticket = self._run_tgs(tgt, expected_error=0, expect_pac=True) - -@@ -1750,7 +1773,10 @@ class KdcTgsTests(KDCBaseTest): - tgt = self.get_tgt(creds, pac_request=False, expect_pac=None) - tgt = self._modify_tgt(tgt, renewable=True) - -- tgt = self._renew_tgt(tgt, expected_error=0, expect_pac=None) -+ tgt = self._renew_tgt(tgt, expected_error=0, expect_pac=None, -+ expect_pac_attrs=True, -+ expect_pac_attrs_pac_request=False, -+ expect_requester_sid=True) - - ticket = self._run_tgs(tgt, expected_error=0, expect_pac=False) - -@@ -1762,7 +1788,10 @@ class KdcTgsTests(KDCBaseTest): - tgt = self.get_tgt(creds, pac_request=True) - tgt = self._modify_tgt(tgt, renewable=True) - -- tgt = self._renew_tgt(tgt, expected_error=0, expect_pac=None) -+ tgt = self._renew_tgt(tgt, expected_error=0, expect_pac=None, -+ expect_pac_attrs=True, -+ expect_pac_attrs_pac_request=True, -+ expect_requester_sid=True) - - ticket = self._run_tgs(tgt, expected_error=0, expect_pac=True) - -@@ -1774,7 +1803,10 @@ class KdcTgsTests(KDCBaseTest): - tgt = self.get_tgt(creds, pac_request=None) - tgt = self._modify_tgt(tgt, invalid=True) - -- tgt = self._validate_tgt(tgt, expected_error=0, expect_pac=None) -+ tgt = self._validate_tgt(tgt, expected_error=0, expect_pac=None, -+ expect_pac_attrs=True, -+ expect_pac_attrs_pac_request=None, -+ expect_requester_sid=True) - - ticket = self._run_tgs(tgt, expected_error=0, expect_pac=True) - -@@ -1786,7 +1818,10 @@ class KdcTgsTests(KDCBaseTest): - tgt = self.get_tgt(creds, pac_request=False, expect_pac=None) - tgt = self._modify_tgt(tgt, invalid=True) - -- tgt = self._validate_tgt(tgt, expected_error=0, expect_pac=None) -+ tgt = self._validate_tgt(tgt, expected_error=0, expect_pac=None, -+ expect_pac_attrs=True, -+ expect_pac_attrs_pac_request=False, -+ expect_requester_sid=True) - - ticket = self._run_tgs(tgt, expected_error=0, expect_pac=False) - -@@ -1798,7 +1833,10 @@ class KdcTgsTests(KDCBaseTest): - tgt = self.get_tgt(creds, pac_request=True) - tgt = self._modify_tgt(tgt, invalid=True) - -- tgt = self._validate_tgt(tgt, expected_error=0, expect_pac=None) -+ tgt = self._validate_tgt(tgt, expected_error=0, expect_pac=None, -+ expect_pac_attrs=True, -+ expect_pac_attrs_pac_request=True, -+ expect_requester_sid=True) - - ticket = self._run_tgs(tgt, expected_error=0, expect_pac=True) - -@@ -1946,7 +1984,7 @@ class KdcTgsTests(KDCBaseTest): - - ticket = self._run_tgs(tgt, expected_error=0, expect_pac=True) - -- pac = self.get_ticket_pac(ticket, expect_pac=False) -+ pac = self.get_ticket_pac(ticket) - self.assertIsNotNone(pac) - - def test_tgs_rodc_pac_request_true(self): -@@ -2279,12 +2317,21 @@ class KdcTgsTests(KDCBaseTest): - expect_requester_sid=expect_requester_sid, - expected_sid=expected_sid) - -- def _validate_tgt(self, tgt, expected_error, expect_pac=True): -+ def _validate_tgt(self, tgt, expected_error, expect_pac=True, -+ expect_pac_attrs=None, -+ expect_pac_attrs_pac_request=None, -+ expect_requester_sid=None, -+ expected_sid=None): - krbtgt_creds = self.get_krbtgt_creds() - kdc_options = str(krb5_asn1.KDCOptions('validate')) -- return self._tgs_req(tgt, expected_error, krbtgt_creds, -- kdc_options=kdc_options, -- expect_pac=expect_pac) -+ return self._tgs_req( -+ tgt, expected_error, krbtgt_creds, -+ kdc_options=kdc_options, -+ expect_pac=expect_pac, -+ expect_pac_attrs=expect_pac_attrs, -+ expect_pac_attrs_pac_request=expect_pac_attrs_pac_request, -+ expect_requester_sid=expect_requester_sid, -+ expected_sid=expected_sid) - - def _s4u2self(self, tgt, tgt_creds, expected_error, expect_pac=True, - expect_edata=False, expected_status=None): -diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py -index da3f69c79c6..14e655313fc 100644 ---- a/python/samba/tests/krb5/raw_testcase.py -+++ b/python/samba/tests/krb5/raw_testcase.py -@@ -602,6 +602,13 @@ class RawKerberosTest(TestCaseInTempDir): - expect_pac = '1' - cls.expect_pac = bool(int(expect_pac)) - -+ expect_extra_pac_buffers = samba.tests.env_get_var_value( -+ 'EXPECT_EXTRA_PAC_BUFFERS', -+ allow_missing=True) -+ if expect_extra_pac_buffers is None: -+ expect_extra_pac_buffers = '1' -+ cls.expect_extra_pac_buffers = bool(int(expect_extra_pac_buffers)) -+ - def setUp(self): - super().setUp() - self.do_asn1_print = False -@@ -2624,17 +2631,34 @@ class RawKerberosTest(TestCaseInTempDir): - if not self.tkt_sig_support: - require_strict.add(krb5pac.PAC_TYPE_TICKET_CHECKSUM) - -+ expect_extra_pac_buffers = rep_msg_type == KRB_AS_REP -+ - expect_pac_attrs = kdc_exchange_dict['expect_pac_attrs'] -+ -+ if expect_pac_attrs: -+ expect_pac_attrs_pac_request = kdc_exchange_dict[ -+ 'expect_pac_attrs_pac_request'] -+ else: -+ expect_pac_attrs_pac_request = kdc_exchange_dict[ -+ 'pac_request'] -+ -+ if expect_pac_attrs is None: -+ if self.expect_extra_pac_buffers: -+ expect_pac_attrs = expect_extra_pac_buffers -+ else: -+ require_strict.add(krb5pac.PAC_TYPE_ATTRIBUTES_INFO) - if expect_pac_attrs: - expected_types.append(krb5pac.PAC_TYPE_ATTRIBUTES_INFO) -- elif expect_pac_attrs is None: -- require_strict.add(krb5pac.PAC_TYPE_ATTRIBUTES_INFO) - - expect_requester_sid = kdc_exchange_dict['expect_requester_sid'] -+ -+ if expect_requester_sid is None: -+ if self.expect_extra_pac_buffers: -+ expect_requester_sid = expect_extra_pac_buffers -+ else: -+ require_strict.add(krb5pac.PAC_TYPE_REQUESTER_SID) - if expect_requester_sid: - expected_types.append(krb5pac.PAC_TYPE_REQUESTER_SID) -- elif expect_requester_sid is None: -- require_strict.add(krb5pac.PAC_TYPE_REQUESTER_SID) - - buffer_types = [pac_buffer.type - for pac_buffer in pac.buffers] -@@ -2722,9 +2746,6 @@ class RawKerberosTest(TestCaseInTempDir): - requested_pac = bool(flags & 1) - given_pac = bool(flags & 2) - -- expect_pac_attrs_pac_request = kdc_exchange_dict[ -- 'expect_pac_attrs_pac_request'] -- - self.assertEqual(expect_pac_attrs_pac_request is True, - requested_pac) - self.assertEqual(expect_pac_attrs_pac_request is None, -@@ -2734,8 +2755,8 @@ class RawKerberosTest(TestCaseInTempDir): - and expect_requester_sid): - requester_sid = pac_buffer.info.sid - -- self.assertIsNotNone(expected_sid) -- self.assertEqual(expected_sid, str(requester_sid)) -+ if expected_sid is not None: -+ self.assertEqual(expected_sid, str(requester_sid)) - - def generic_check_kdc_error(self, - kdc_exchange_dict, -diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc -index 42b70e97f60..475abc03182 100644 ---- a/selftest/knownfail_heimdal_kdc -+++ b/selftest/knownfail_heimdal_kdc -@@ -127,11 +127,15 @@ - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_sid_mismatch_nonexisting - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_logon_info_only_sid_mismatch_existing - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_logon_info_only_sid_mismatch_nonexisting -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_rodc_renew_false -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_rodc_renew_none -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_rodc_renew_true - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_remove_pac - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_remove_pac_client_no_auth_data_required - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_remove_pac_service_no_auth_data_required - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_authdata_no_pac - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_no_pac -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_revealed - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_sid_mismatch_existing - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_sid_mismatch_nonexisting - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_sid_mismatch_existing -@@ -147,10 +151,14 @@ - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_sid_mismatch_nonexisting - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_authdata_no_pac - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_no_pac -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_pac_attrs_none -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_pac_attrs_true - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_req_from_rodc_no_requester_sid - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_req_no_requester_sid -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid(?!_) - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_renew - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_rodc_renew -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_rodc_renew - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_logon_info_only_sid_mismatch_existing - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_logon_info_only_sid_mismatch_nonexisting - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_pac_request_false -@@ -170,6 +178,7 @@ - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_wrong_sname_krbtgt - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_authdata_no_pac - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_no_pac -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_revealed - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_sid_mismatch_existing - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_sid_mismatch_nonexisting - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_sid_mismatch_existing -diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc -index 1723481c931..1e63bb33d03 100644 ---- a/selftest/knownfail_mit_kdc -+++ b/selftest/knownfail_mit_kdc -@@ -389,6 +389,9 @@ 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_logon_info_only_sid_mismatch_nonexisting - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_authdata_no_pac - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_no_pac -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_pac_request_none -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_pac_request_true -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_req - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_allowed_denied - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_denied - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_no_krbtgt_link -@@ -451,6 +454,9 @@ 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_user2user_wrong_srealm - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_authdata_no_pac - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_no_pac -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_pac_request_none -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_pac_request_true -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_req - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_allowed_denied - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_denied - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_no_krbtgt_link -diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py -index ff523edd26b..7234767baa5 100755 ---- a/source4/selftest/tests.py -+++ b/source4/selftest/tests.py -@@ -905,12 +905,14 @@ for env in ['fileserver_smb1', 'nt4_member', 'clusteredmember', 'ktest', 'nt4_dc - have_fast_support = int('SAMBA_USES_MITKDC' in config_hash) - tkt_sig_support = int('SAMBA4_USES_HEIMDAL' in config_hash) - expect_pac = int('SAMBA4_USES_HEIMDAL' in config_hash) -+extra_pac_buffers = 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, - 'TKT_SIG_SUPPORT': tkt_sig_support, -- 'EXPECT_PAC': expect_pac}) -+ 'EXPECT_PAC': expect_pac, -+ 'EXPECT_EXTRA_PAC_BUFFERS': extra_pac_buffers}) - planoldpythontestsuite("ad_dc_default:local", "samba.tests.krb5.s4u_tests", - environ={'ADMIN_USERNAME':'$USERNAME', - 'ADMIN_PASSWORD':'$PASSWORD', -@@ -918,21 +920,24 @@ planoldpythontestsuite("ad_dc_default:local", "samba.tests.krb5.s4u_tests", - 'STRICT_CHECKING':'0', - 'FAST_SUPPORT': have_fast_support, - 'TKT_SIG_SUPPORT': tkt_sig_support, -- 'EXPECT_PAC': expect_pac}) -+ 'EXPECT_PAC': expect_pac, -+ 'EXPECT_EXTRA_PAC_BUFFERS': extra_pac_buffers}) - 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, -- 'EXPECT_PAC': expect_pac}) -+ 'EXPECT_PAC': expect_pac, -+ 'EXPECT_EXTRA_PAC_BUFFERS': extra_pac_buffers}) - - planoldpythontestsuite("ad_dc_default", "samba.tests.dsdb_dns") - - planoldpythontestsuite("fl2008r2dc:local", "samba.tests.krb5.xrealm_tests", - environ={'FAST_SUPPORT': have_fast_support, - 'TKT_SIG_SUPPORT': tkt_sig_support, -- 'EXPECT_PAC': expect_pac}) -+ 'EXPECT_PAC': expect_pac, -+ 'EXPECT_EXTRA_PAC_BUFFERS': extra_pac_buffers}) - - planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.test_ccache", - environ={ -@@ -941,7 +946,8 @@ planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.test_ccache", - 'STRICT_CHECKING': '0', - 'FAST_SUPPORT': have_fast_support, - 'TKT_SIG_SUPPORT': tkt_sig_support, -- 'EXPECT_PAC': expect_pac -+ 'EXPECT_PAC': expect_pac, -+ 'EXPECT_EXTRA_PAC_BUFFERS': extra_pac_buffers - }) - planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.test_ldap", - environ={ -@@ -950,7 +956,8 @@ planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.test_ldap", - 'STRICT_CHECKING': '0', - 'FAST_SUPPORT': have_fast_support, - 'TKT_SIG_SUPPORT': tkt_sig_support, -- 'EXPECT_PAC': expect_pac -+ 'EXPECT_PAC': expect_pac, -+ 'EXPECT_EXTRA_PAC_BUFFERS': extra_pac_buffers - }) - for env in ['ad_dc_default', 'ad_member']: - planoldpythontestsuite(env, "samba.tests.krb5.test_rpc", -@@ -960,7 +967,8 @@ for env in ['ad_dc_default', 'ad_member']: - 'STRICT_CHECKING': '0', - 'FAST_SUPPORT': have_fast_support, - 'TKT_SIG_SUPPORT': tkt_sig_support, -- 'EXPECT_PAC': expect_pac -+ 'EXPECT_PAC': expect_pac, -+ 'EXPECT_EXTRA_PAC_BUFFERS': extra_pac_buffers - }) - planoldpythontestsuite("ad_dc_smb1", "samba.tests.krb5.test_smb", - environ={ -@@ -969,7 +977,8 @@ planoldpythontestsuite("ad_dc_smb1", "samba.tests.krb5.test_smb", - 'STRICT_CHECKING': '0', - 'FAST_SUPPORT': have_fast_support, - 'TKT_SIG_SUPPORT': tkt_sig_support, -- 'EXPECT_PAC': expect_pac -+ 'EXPECT_PAC': expect_pac, -+ 'EXPECT_EXTRA_PAC_BUFFERS': extra_pac_buffers - }) - planoldpythontestsuite("ad_member_idmap_nss:local", - "samba.tests.krb5.test_min_domain_uid", -@@ -992,7 +1001,8 @@ planoldpythontestsuite("ad_member_idmap_nss:local", - 'STRICT_CHECKING': '0', - 'FAST_SUPPORT': have_fast_support, - 'TKT_SIG_SUPPORT': tkt_sig_support, -- 'EXPECT_PAC': expect_pac -+ 'EXPECT_PAC': expect_pac, -+ 'EXPECT_EXTRA_PAC_BUFFERS': extra_pac_buffers - }) - - for env in ["ad_dc", smbv1_disabled_testenv]: -@@ -1587,7 +1597,8 @@ for env in ["fl2008r2dc", "fl2003dc"]: - 'STRICT_CHECKING': '0', - 'FAST_SUPPORT': have_fast_support, - 'TKT_SIG_SUPPORT': tkt_sig_support, -- 'EXPECT_PAC': expect_pac -+ 'EXPECT_PAC': expect_pac, -+ 'EXPECT_EXTRA_PAC_BUFFERS': extra_pac_buffers - }) - - planoldpythontestsuite('fl2008r2dc', 'samba.tests.krb5.salt_tests', -@@ -1597,7 +1608,8 @@ planoldpythontestsuite('fl2008r2dc', 'samba.tests.krb5.salt_tests', - 'STRICT_CHECKING': '0', - 'FAST_SUPPORT': have_fast_support, - 'TKT_SIG_SUPPORT': tkt_sig_support, -- 'EXPECT_PAC': expect_pac -+ 'EXPECT_PAC': expect_pac, -+ 'EXPECT_EXTRA_PAC_BUFFERS': extra_pac_buffers - }) - - for env in ["rodc", "promoted_dc", "fl2000dc", "fl2008r2dc"]: -@@ -1620,7 +1632,8 @@ planpythontestsuite("ad_dc", "samba.tests.krb5.as_canonicalization_tests", - 'ADMIN_PASSWORD': '$PASSWORD', - 'FAST_SUPPORT': have_fast_support, - 'TKT_SIG_SUPPORT': tkt_sig_support, -- 'EXPECT_PAC': expect_pac -+ 'EXPECT_PAC': expect_pac, -+ 'EXPECT_EXTRA_PAC_BUFFERS': extra_pac_buffers - }) - planpythontestsuite("ad_dc", "samba.tests.krb5.compatability_tests", - environ={ -@@ -1629,12 +1642,14 @@ planpythontestsuite("ad_dc", "samba.tests.krb5.compatability_tests", - 'STRICT_CHECKING': '0', - 'FAST_SUPPORT': have_fast_support, - 'TKT_SIG_SUPPORT': tkt_sig_support, -- 'EXPECT_PAC': expect_pac -+ 'EXPECT_PAC': expect_pac, -+ 'EXPECT_EXTRA_PAC_BUFFERS': extra_pac_buffers - }) - planpythontestsuite("ad_dc", "samba.tests.krb5.kdc_tests", - environ={'FAST_SUPPORT': have_fast_support, - 'TKT_SIG_SUPPORT': tkt_sig_support, -- 'EXPECT_PAC': expect_pac}) -+ 'EXPECT_PAC': expect_pac, -+ 'EXPECT_EXTRA_PAC_BUFFERS': extra_pac_buffers}) - planpythontestsuite( - "ad_dc", - "samba.tests.krb5.kdc_tgs_tests", -@@ -1644,7 +1659,8 @@ planpythontestsuite( - 'STRICT_CHECKING': '0', - 'FAST_SUPPORT': have_fast_support, - 'TKT_SIG_SUPPORT': tkt_sig_support, -- 'EXPECT_PAC': expect_pac -+ 'EXPECT_PAC': expect_pac, -+ 'EXPECT_EXTRA_PAC_BUFFERS': extra_pac_buffers - }) - planpythontestsuite( - "ad_dc", -@@ -1655,7 +1671,8 @@ planpythontestsuite( - 'STRICT_CHECKING': '0', - 'FAST_SUPPORT': have_fast_support, - 'TKT_SIG_SUPPORT': tkt_sig_support, -- 'EXPECT_PAC': expect_pac -+ 'EXPECT_PAC': expect_pac, -+ 'EXPECT_EXTRA_PAC_BUFFERS': extra_pac_buffers - }) - planpythontestsuite( - "ad_dc", -@@ -1666,7 +1683,8 @@ planpythontestsuite( - 'STRICT_CHECKING': '0', - 'FAST_SUPPORT': have_fast_support, - 'TKT_SIG_SUPPORT': tkt_sig_support, -- 'EXPECT_PAC': expect_pac -+ 'EXPECT_PAC': expect_pac, -+ 'EXPECT_EXTRA_PAC_BUFFERS': extra_pac_buffers - }) - planpythontestsuite( - "ad_dc", -@@ -1677,7 +1695,8 @@ planpythontestsuite( - 'STRICT_CHECKING': '0', - 'FAST_SUPPORT': have_fast_support, - 'TKT_SIG_SUPPORT': tkt_sig_support, -- 'EXPECT_PAC': expect_pac -+ 'EXPECT_PAC': expect_pac, -+ 'EXPECT_EXTRA_PAC_BUFFERS': extra_pac_buffers - }) - planpythontestsuite( - "ad_dc", -@@ -1688,7 +1707,8 @@ planpythontestsuite( - 'STRICT_CHECKING': '0', - 'FAST_SUPPORT': have_fast_support, - 'TKT_SIG_SUPPORT': tkt_sig_support, -- 'EXPECT_PAC': expect_pac -+ 'EXPECT_PAC': expect_pac, -+ 'EXPECT_EXTRA_PAC_BUFFERS': extra_pac_buffers - }) - - for env in [ --- -2.25.1 - - -From 17e724b5bbfcaa96f2d4f4d9be790a0f7effe877 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Wed, 24 Nov 2021 13:10:52 +1300 -Subject: [PATCH 33/99] tests/krb5: Add tests for validation with requester SID - PAC buffer - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett -(cherry picked from commit ca80c47406e0f2b6fac2c55229306e21ccef9745) ---- - python/samba/tests/krb5/kdc_tgs_tests.py | 67 ++++++++++++++++++++++++ - selftest/knownfail_heimdal_kdc | 3 ++ - selftest/knownfail_mit_kdc | 4 ++ - 3 files changed, 74 insertions(+) - -diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py -index f14439a4ab5..50079a1710c 100755 ---- a/python/samba/tests/krb5/kdc_tgs_tests.py -+++ b/python/samba/tests/krb5/kdc_tgs_tests.py -@@ -1726,6 +1726,73 @@ class KdcTgsTests(KDCBaseTest): - - self._renew_tgt(tgt, expected_error=KDC_ERR_TGT_REVOKED) - -+ def test_tgs_requester_sid_validate(self): -+ creds = self._get_creds() -+ -+ samdb = self.get_samdb() -+ sid = self.get_objectSid(samdb, creds.get_dn()) -+ -+ tgt = self.get_tgt(creds, pac_request=None, -+ expect_pac=True, -+ expected_sid=sid, -+ expect_requester_sid=True) -+ tgt = self._modify_tgt(tgt, invalid=True) -+ -+ self._validate_tgt(tgt, expected_error=0, expect_pac=True, -+ expect_pac_attrs=True, -+ expect_pac_attrs_pac_request=None, -+ expected_sid=sid, -+ expect_requester_sid=True) -+ -+ def test_tgs_requester_sid_rodc_validate(self): -+ creds = self._get_creds(replication_allowed=True, -+ revealed_to_rodc=True) -+ -+ samdb = self.get_samdb() -+ sid = self.get_objectSid(samdb, creds.get_dn()) -+ -+ tgt = self.get_tgt(creds, pac_request=None, -+ expect_pac=True, -+ expected_sid=sid, -+ expect_requester_sid=True) -+ tgt = self._modify_tgt(tgt, from_rodc=True, invalid=True) -+ -+ self._validate_tgt(tgt, expected_error=0, expect_pac=True, -+ expect_pac_attrs=False, -+ expected_sid=sid, -+ expect_requester_sid=True) -+ -+ def test_tgs_requester_sid_missing_validate(self): -+ creds = self._get_creds() -+ -+ samdb = self.get_samdb() -+ sid = self.get_objectSid(samdb, creds.get_dn()) -+ -+ tgt = self.get_tgt(creds, pac_request=None, -+ expect_pac=True, -+ expected_sid=sid, -+ expect_requester_sid=True) -+ tgt = self._modify_tgt(tgt, invalid=True, -+ remove_requester_sid=True) -+ -+ self._validate_tgt(tgt, expected_error=KDC_ERR_TGT_REVOKED) -+ -+ def test_tgs_requester_sid_missing_rodc_validate(self): -+ creds = self._get_creds(replication_allowed=True, -+ revealed_to_rodc=True) -+ -+ samdb = self.get_samdb() -+ sid = self.get_objectSid(samdb, creds.get_dn()) -+ -+ tgt = self.get_tgt(creds, pac_request=None, -+ expect_pac=True, -+ expected_sid=sid, -+ expect_requester_sid=True) -+ tgt = self._modify_tgt(tgt, from_rodc=True, invalid=True, -+ remove_requester_sid=True) -+ -+ self._validate_tgt(tgt, expected_error=KDC_ERR_TGT_REVOKED) -+ - def test_tgs_pac_request_none(self): - creds = self._get_creds() - tgt = self.get_tgt(creds, pac_request=None) -diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc -index 475abc03182..c67cc302283 100644 ---- a/selftest/knownfail_heimdal_kdc -+++ b/selftest/knownfail_heimdal_kdc -@@ -158,7 +158,10 @@ - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid(?!_) - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_renew - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_rodc_renew -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_rodc_validate -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_validate - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_rodc_renew -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_rodc_validate - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_logon_info_only_sid_mismatch_existing - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_logon_info_only_sid_mismatch_nonexisting - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_pac_request_false -diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc -index 1e63bb33d03..76253fc7b4b 100644 ---- a/selftest/knownfail_mit_kdc -+++ b/selftest/knownfail_mit_kdc -@@ -512,8 +512,12 @@ 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_tgs_requester_sid - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_renew - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_rodc_renew -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_rodc_validate -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_validate - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_renew - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_rodc_renew -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_rodc_validate -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_validate - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_logon_info_only_sid_mismatch_existing - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_logon_info_only_sid_mismatch_nonexisting - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_logon_info_sid_mismatch_existing --- -2.25.1 - - -From 79ba192a73f601a86a59ef16aaf47c649790a980 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Wed, 24 Nov 2021 15:32:32 +1300 -Subject: [PATCH 34/99] tests/krb5: Add comments for tests that fail against - Windows - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett -(cherry picked from commit 749349efab9b401d33a4fc286473a924364a41c9) ---- - python/samba/tests/krb5/kdc_tgs_tests.py | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py -index 50079a1710c..ecc38538e61 100755 ---- a/python/samba/tests/krb5/kdc_tgs_tests.py -+++ b/python/samba/tests/krb5/kdc_tgs_tests.py -@@ -792,6 +792,8 @@ class KdcTgsTests(KDCBaseTest): - expect_pac_attrs=False, - expect_requester_sid=True) - -+ # This test fails on Windows, which gives KDC_ERR_C_PRINCIPAL_UNKNOWN when -+ # attempting to use S4U2Self with a TGT from an RODC. - def test_s4u2self_rodc_revealed(self): - creds = self._get_creds(replication_allowed=True, - revealed_to_rodc=True) -@@ -2370,6 +2372,8 @@ class KdcTgsTests(KDCBaseTest): - expect_requester_sid=expect_requester_sid, - expected_sid=expected_sid) - -+ # These tests fail against Windows, which does not implement ticket -+ # renewal. - def _renew_tgt(self, tgt, expected_error, expect_pac=True, - expect_pac_attrs=None, expect_pac_attrs_pac_request=None, - expect_requester_sid=None, expected_sid=None): -@@ -2384,6 +2388,8 @@ class KdcTgsTests(KDCBaseTest): - expect_requester_sid=expect_requester_sid, - expected_sid=expected_sid) - -+ # These tests fail against Windows, which does not implement ticket -+ # validation. - def _validate_tgt(self, tgt, expected_error, expect_pac=True, - expect_pac_attrs=None, - expect_pac_attrs_pac_request=None, --- -2.25.1 - - -From 78a82907caa55f9e6118fc2f7aa01509257fa166 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Thu, 18 Nov 2021 13:14:51 +1300 -Subject: [PATCH 35/99] heimdal:kdc: Fix error message for user-to-user - -We were checking the wrong variable to see whether a PAC was found or not. - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett -(cherry picked from commit 11fb9476ad3c09415d12b3cdf7934c293cbefcb2) ---- - source4/heimdal/kdc/krb5tgs.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c -index fb2ef8230c9..cde68b41714 100644 ---- a/source4/heimdal/kdc/krb5tgs.c -+++ b/source4/heimdal/kdc/krb5tgs.c -@@ -1629,7 +1629,7 @@ server_lookup: - ret = KRB5KDC_ERR_BADOPTION; - kdc_log(context, config, 0, - "Ticket not signed with PAC; user-to-user failed (%s).", -- mspac ? "Ticket unsigned" : "No PAC"); -+ user2user_pac ? "Ticket unsigned" : "No PAC"); - goto out; - } - --- -2.25.1 - - -From 9b5612a88c0a56b0a08595d21c87d1dff00e495a Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Thu, 18 Nov 2021 16:22:34 +1300 -Subject: [PATCH 36/99] s4:torture: Fix typo - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett -(cherry picked from commit 9cfb88ba04818b5e9cec3c96422e8e4a3080d490) ---- - source4/torture/krb5/kdc-canon-heimdal.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/source4/torture/krb5/kdc-canon-heimdal.c b/source4/torture/krb5/kdc-canon-heimdal.c -index e9466f2d9d7..38b3f1e7a62 100644 ---- a/source4/torture/krb5/kdc-canon-heimdal.c -+++ b/source4/torture/krb5/kdc-canon-heimdal.c -@@ -262,7 +262,7 @@ static bool torture_krb5_pre_send_as_req_test(struct torture_krb5_context *test_ - KRB5_NT_PRINCIPAL, - "krb5 libs unexpectedly " - "did not set principal " -- "as NT_SRV_HST!"); -+ "as NT_PRINCIPAL!"); - } else { - torture_assert_int_equal(test_context->tctx, - test_context->as_req.req_body.cname->name_type, --- -2.25.1 - - -From 37f9d30cbdaeb082382304d5cd6442ffcdca331e Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Wed, 24 Nov 2021 20:41:34 +1300 -Subject: [PATCH 37/99] heimdal:kdc: Adjust no-PAC error code to match Windows - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett -(cherry picked from commit f7a2fef8f49a86f63c3dc2f6a2d7d979fb53238a) ---- - selftest/knownfail_heimdal_kdc | 19 ------------------- - source4/heimdal/kdc/krb5tgs.c | 2 +- - 2 files changed, 1 insertion(+), 20 deletions(-) - -diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc -index c67cc302283..cf196a3260a 100644 ---- a/selftest/knownfail_heimdal_kdc -+++ b/selftest/knownfail_heimdal_kdc -@@ -71,21 +71,15 @@ - # 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_client_pac(?!_no_auth_data_required) --^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_no_auth_data_required - ^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_no_service_pac --^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_no_service_pac_no_auth_data_required - ^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_forwardable --^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_no_pac - ^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_constrained_delegation_no_auth_data_required -@@ -130,11 +124,6 @@ - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_rodc_renew_false - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_rodc_renew_none - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_rodc_renew_true --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_remove_pac --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_remove_pac_client_no_auth_data_required --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_remove_pac_service_no_auth_data_required --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_authdata_no_pac --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_no_pac - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_revealed - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_sid_mismatch_existing - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_sid_mismatch_nonexisting -@@ -142,15 +131,11 @@ - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_sid_mismatch_nonexisting - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_requester_sid_mismatch_existing - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_requester_sid_mismatch_nonexisting --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_authdata_no_pac --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_no_pac - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_pac_request_false - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_sid_mismatch_existing - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_sid_mismatch_nonexisting - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_sid_mismatch_existing - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_sid_mismatch_nonexisting --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_authdata_no_pac --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_no_pac - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_pac_attrs_none - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_pac_attrs_true - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_req_from_rodc_no_requester_sid -@@ -171,16 +156,12 @@ - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_sid_mismatch_nonexisting - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_sid_mismatch_existing - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_sid_mismatch_nonexisting --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_authdata_no_pac --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_no_pac - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_sid_mismatch_existing - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_sid_mismatch_nonexisting - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_sid_mismatch_existing - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_sid_mismatch_nonexisting - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_wrong_sname - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_wrong_sname_krbtgt --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_authdata_no_pac --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_no_pac - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_revealed - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_sid_mismatch_existing - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_sid_mismatch_nonexisting -diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c -index cde68b41714..6c5c51aa448 100644 ---- a/source4/heimdal/kdc/krb5tgs.c -+++ b/source4/heimdal/kdc/krb5tgs.c -@@ -78,7 +78,7 @@ check_PAC(krb5_context context, - return ret; - - if (pac == NULL) -- return KRB5KDC_ERR_BADOPTION; -+ return KRB5KDC_ERR_TGT_REVOKED; - - /* Verify the server signature. */ - ret = krb5_pac_verify(context, pac, tkt->authtime, client_principal, --- -2.25.1 - - -From 1bd26a254f2b7861852142e256c6d3bf7f718857 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Wed, 24 Nov 2021 20:41:45 +1300 -Subject: [PATCH 38/99] kdc: Adjust SID mismatch error code to match Windows - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett -(cherry picked from commit d5d22bf84a71492342287e54b555c9f024e7e71c) ---- - selftest/knownfail_heimdal_kdc | 35 ---------------------------------- - selftest/knownfail_mit_kdc | 8 -------- - source4/kdc/pac-glue.c | 6 +----- - 3 files changed, 1 insertion(+), 48 deletions(-) - -diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc -index cf196a3260a..fc2a3554f0d 100644 ---- a/selftest/knownfail_heimdal_kdc -+++ b/selftest/knownfail_heimdal_kdc -@@ -97,13 +97,6 @@ - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_not_revealed - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_not_revealed - # --# Alias tests --# --^samba.tests.krb5.alias_tests.samba.tests.krb5.alias_tests.AliasTests.test_create_alias_delete --^samba.tests.krb5.alias_tests.samba.tests.krb5.alias_tests.AliasTests.test_create_alias_rename --^samba.tests.krb5.alias_tests.samba.tests.krb5.alias_tests.AliasTests.test_dc_alias_delete --^samba.tests.krb5.alias_tests.samba.tests.krb5.alias_tests.AliasTests.test_dc_alias_rename --# - # KDC TGS tests - # - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_authdata_no_pac -@@ -119,23 +112,11 @@ - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_service_ticket - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_sid_mismatch_existing - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_sid_mismatch_nonexisting --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_logon_info_only_sid_mismatch_existing --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_logon_info_only_sid_mismatch_nonexisting - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_rodc_renew_false - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_rodc_renew_none - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_rodc_renew_true - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_revealed --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_sid_mismatch_existing --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_sid_mismatch_nonexisting --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_sid_mismatch_existing --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_sid_mismatch_nonexisting --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_requester_sid_mismatch_existing --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_requester_sid_mismatch_nonexisting - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_pac_request_false --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_sid_mismatch_existing --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_sid_mismatch_nonexisting --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_sid_mismatch_existing --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_sid_mismatch_nonexisting - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_pac_attrs_none - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_pac_attrs_true - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_req_from_rodc_no_requester_sid -@@ -147,23 +128,7 @@ - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_validate - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_rodc_renew - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_rodc_validate --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_logon_info_only_sid_mismatch_existing --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_logon_info_only_sid_mismatch_nonexisting - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_pac_request_false --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_requester_sid_mismatch_existing --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_requester_sid_mismatch_nonexisting --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_sid_mismatch_existing --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_sid_mismatch_nonexisting --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_sid_mismatch_existing --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_sid_mismatch_nonexisting --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_sid_mismatch_existing --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_rodc_sid_mismatch_nonexisting --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_sid_mismatch_existing --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_sid_mismatch_nonexisting - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_wrong_sname - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_wrong_sname_krbtgt - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_revealed --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_sid_mismatch_existing --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_sid_mismatch_nonexisting --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_sid_mismatch_existing --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_sid_mismatch_nonexisting -diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc -index 76253fc7b4b..806aaa707d7 100644 ---- a/selftest/knownfail_mit_kdc -+++ b/selftest/knownfail_mit_kdc -@@ -385,8 +385,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_fast_service_ticket - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_sid_mismatch_existing - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_sid_mismatch_nonexisting --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_logon_info_only_sid_mismatch_existing --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_logon_info_only_sid_mismatch_nonexisting - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_authdata_no_pac - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_no_pac - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_pac_request_none -@@ -402,8 +400,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_renew_rodc_sid_mismatch_existing - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_sid_mismatch_nonexisting - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_service_ticket --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_sid_mismatch_existing --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_sid_mismatch_nonexisting - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_authdata_no_pac - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_no_pac - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_req(?!_invalid) -@@ -431,8 +427,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_tgs_rodc_revealed - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_sid_mismatch_existing - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_sid_mismatch_nonexisting --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_sid_mismatch_existing --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_sid_mismatch_nonexisting - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_authdata_no_pac - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_no_pac - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_no_sname -@@ -467,8 +461,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_validate_rodc_sid_mismatch_existing - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_sid_mismatch_nonexisting - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_service_ticket --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_sid_mismatch_existing --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_sid_mismatch_nonexisting - # - # PAC attributes tests - # -diff --git a/source4/kdc/pac-glue.c b/source4/kdc/pac-glue.c -index e0e483662c0..2a96a683cd9 100644 ---- a/source4/kdc/pac-glue.c -+++ b/source4/kdc/pac-glue.c -@@ -1237,11 +1237,7 @@ krb5_error_code samba_kdc_validate_pac_blob( - "PAC[%s] != CLI[%s]\n", - dom_sid_str_buf(&pac_sid, &buf1), - dom_sid_str_buf(client_sid, &buf2)); --#if defined(KRB5KDC_ERR_CLIENT_NAME_MISMATCH) /* MIT */ -- code = KRB5KDC_ERR_CLIENT_NAME_MISMATCH; --#else /* Heimdal (where this is an enum) */ -- code = KRB5_KDC_ERR_CLIENT_NAME_MISMATCH; --#endif -+ code = KRB5KDC_ERR_TGT_REVOKED; - goto out; - } - --- -2.25.1 - - -From 99a11ec7e78aa8bc477de18253f068f3a0c84c19 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Thu, 25 Nov 2021 10:05:17 +1300 -Subject: [PATCH 39/99] tests/krb5: Add test for S4U2Self with wrong sname - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett -(cherry picked from commit bac5f75059450898937be891e863826e1350b62c) ---- - python/samba/tests/krb5/s4u_tests.py | 32 +++++++++++++++++++++++++++- - selftest/knownfail_heimdal_kdc | 1 + - 2 files changed, 32 insertions(+), 1 deletion(-) - -diff --git a/python/samba/tests/krb5/s4u_tests.py b/python/samba/tests/krb5/s4u_tests.py -index 5f37525f393..2953766ef21 100755 ---- a/python/samba/tests/krb5/s4u_tests.py -+++ b/python/samba/tests/krb5/s4u_tests.py -@@ -36,6 +36,7 @@ from samba.tests.krb5.raw_testcase import ( - from samba.tests.krb5.rfc4120_constants import ( - AES256_CTS_HMAC_SHA1_96, - ARCFOUR_HMAC_MD5, -+ KDC_ERR_BADMATCH, - KDC_ERR_BADOPTION, - KDC_ERR_BAD_INTEGRITY, - KDC_ERR_GENERIC, -@@ -243,7 +244,9 @@ class S4UKerberosTests(KDCBaseTest): - client_dn = client_creds.get_dn() - sid = self.get_objectSid(samdb, client_dn) - -- service_name = service_creds.get_username()[:-1] -+ service_name = kdc_dict.pop('service_name', None) -+ if service_name is None: -+ service_name = service_creds.get_username()[:-1] - service_sname = self.PrincipalName_create(name_type=NT_PRINCIPAL, - names=['host', service_name]) - -@@ -474,6 +477,33 @@ class S4UKerberosTests(KDCBaseTest): - 'expected_flags': 'forwardable' - }) - -+ # Do an S4U2Self with the sname in the request different to that of the -+ # service. We expect an error. -+ def test_s4u2self_wrong_sname(self): -+ other_creds = self.get_cached_creds( -+ account_type=self.AccountType.COMPUTER, -+ opts={ -+ 'trusted_to_auth_for_delegation': True, -+ 'id': 0 -+ }) -+ other_sname = other_creds.get_username()[:-1] -+ -+ self._run_s4u2self_test( -+ { -+ 'expected_error_mode': KDC_ERR_BADMATCH, -+ 'expect_edata': False, -+ 'client_opts': { -+ 'not_delegated': False -+ }, -+ 'service_opts': { -+ 'trusted_to_auth_for_delegation': True -+ }, -+ 'service_name': other_sname, -+ 'kdc_options': 'forwardable', -+ 'modify_service_tgt_fn': functools.partial( -+ self.set_ticket_forwardable, flag=True) -+ }) -+ - def _run_delegation_test(self, kdc_dict): - client_opts = kdc_dict.pop('client_opts', None) - client_creds = self.get_cached_creds( -diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc -index fc2a3554f0d..fd05719cc4c 100644 ---- a/selftest/knownfail_heimdal_kdc -+++ b/selftest/knownfail_heimdal_kdc -@@ -81,6 +81,7 @@ - ^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_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_wrong_sname - # - ^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 --- -2.25.1 - - -From daef3c8a3607575e077c2eff55a06867201d6f2b Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Tue, 23 Nov 2021 20:00:07 +1300 -Subject: [PATCH 40/99] kdc: Match Windows error code for mismatching sname - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett -(cherry picked from commit b6a25f5f016aef39c3b1d7be8b3ecfe021c03c83) ---- - selftest/knownfail_heimdal_kdc | 3 --- - source4/kdc/db-glue.c | 2 +- - 2 files changed, 1 insertion(+), 4 deletions(-) - -diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc -index fd05719cc4c..d89d69deed2 100644 ---- a/selftest/knownfail_heimdal_kdc -+++ b/selftest/knownfail_heimdal_kdc -@@ -81,7 +81,6 @@ - ^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_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_wrong_sname - # - ^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 -@@ -130,6 +129,4 @@ - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_rodc_renew - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_rodc_validate - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_pac_request_false --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_wrong_sname --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_wrong_sname_krbtgt - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_revealed -diff --git a/source4/kdc/db-glue.c b/source4/kdc/db-glue.c -index d017741e30a..bed0ff773f9 100644 ---- a/source4/kdc/db-glue.c -+++ b/source4/kdc/db-glue.c -@@ -2599,7 +2599,7 @@ samba_kdc_check_s4u2self(krb5_context context, - */ - if (!(orig_sid && target_sid && dom_sid_equal(orig_sid, target_sid))) { - talloc_free(frame); -- return KRB5KDC_ERR_BADOPTION; -+ return KRB5KRB_AP_ERR_BADMATCH; - } - - talloc_free(frame); --- -2.25.1 - - -From 0368939b7d60c08aa8f84dbb53a88d5c9ec96058 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Tue, 23 Nov 2021 20:15:41 +1300 -Subject: [PATCH 41/99] kdc: Always add the PAC if the header TGT is from an - RODC - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett -(cherry picked from commit 690a00a40c0a3f77da6e4dca42b630f2793a98b8) ---- - selftest/knownfail_heimdal_kdc | 1 - - source4/kdc/wdc-samba4.c | 2 +- - 2 files changed, 1 insertion(+), 2 deletions(-) - -diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc -index d89d69deed2..3b78491c837 100644 ---- a/selftest/knownfail_heimdal_kdc -+++ b/selftest/knownfail_heimdal_kdc -@@ -128,5 +128,4 @@ - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_validate - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_rodc_renew - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_rodc_validate --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_pac_request_false - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_revealed -diff --git a/source4/kdc/wdc-samba4.c b/source4/kdc/wdc-samba4.c -index ecd182702c3..8c3ce71529c 100644 ---- a/source4/kdc/wdc-samba4.c -+++ b/source4/kdc/wdc-samba4.c -@@ -471,7 +471,7 @@ static krb5_error_code samba_wdc_reget_pac2(krb5_context context, - goto out; - } - -- if (!server_skdc_entry->is_krbtgt) { -+ if (!is_untrusted && !server_skdc_entry->is_krbtgt) { - /* - * The client may have requested no PAC when obtaining the - * TGT. --- -2.25.1 - - -From 2903a913bf3ca96b9dd3f636b05530adc6e7994f Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Thu, 25 Nov 2021 10:32:44 +1300 -Subject: [PATCH 42/99] tests/krb5: Add tests for renewal and validation of - RODC TGTs with PAC requests - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett -(cherry picked from commit 73a48063469205099f02efdf3b8f0f1040dc7a3d) ---- - python/samba/tests/krb5/kdc_tgs_tests.py | 90 ++++++++++++++++++++++++ - selftest/knownfail_heimdal_kdc | 6 ++ - selftest/knownfail_mit_kdc | 6 ++ - 3 files changed, 102 insertions(+) - -diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py -index ecc38538e61..2923d53772a 100755 ---- a/python/samba/tests/krb5/kdc_tgs_tests.py -+++ b/python/samba/tests/krb5/kdc_tgs_tests.py -@@ -1867,6 +1867,51 @@ class KdcTgsTests(KDCBaseTest): - pac = self.get_ticket_pac(ticket) - self.assertIsNotNone(pac) - -+ def test_rodc_renew_pac_request_none(self): -+ creds = self._get_creds(replication_allowed=True, -+ revealed_to_rodc=True) -+ tgt = self.get_tgt(creds, pac_request=None) -+ tgt = self._modify_tgt(tgt, renewable=True, from_rodc=True) -+ -+ tgt = self._renew_tgt(tgt, expected_error=0, expect_pac=None, -+ expect_pac_attrs=False, -+ expect_requester_sid=True) -+ -+ ticket = self._run_tgs(tgt, expected_error=0, expect_pac=True) -+ -+ pac = self.get_ticket_pac(ticket) -+ self.assertIsNotNone(pac) -+ -+ def test_rodc_renew_pac_request_false(self): -+ creds = self._get_creds(replication_allowed=True, -+ revealed_to_rodc=True) -+ tgt = self.get_tgt(creds, pac_request=False, expect_pac=None) -+ tgt = self._modify_tgt(tgt, renewable=True, from_rodc=True) -+ -+ tgt = self._renew_tgt(tgt, expected_error=0, expect_pac=None, -+ expect_pac_attrs=False, -+ expect_requester_sid=True) -+ -+ ticket = self._run_tgs(tgt, expected_error=0, expect_pac=True) -+ -+ pac = self.get_ticket_pac(ticket) -+ self.assertIsNotNone(pac) -+ -+ def test_rodc_renew_pac_request_true(self): -+ creds = self._get_creds(replication_allowed=True, -+ revealed_to_rodc=True) -+ tgt = self.get_tgt(creds, pac_request=True) -+ tgt = self._modify_tgt(tgt, renewable=True, from_rodc=True) -+ -+ tgt = self._renew_tgt(tgt, expected_error=0, expect_pac=None, -+ expect_pac_attrs=False, -+ expect_requester_sid=True) -+ -+ ticket = self._run_tgs(tgt, expected_error=0, expect_pac=True) -+ -+ pac = self.get_ticket_pac(ticket) -+ self.assertIsNotNone(pac) -+ - def test_validate_pac_request_none(self): - creds = self._get_creds() - tgt = self.get_tgt(creds, pac_request=None) -@@ -1912,6 +1957,51 @@ class KdcTgsTests(KDCBaseTest): - pac = self.get_ticket_pac(ticket) - self.assertIsNotNone(pac) - -+ def test_rodc_validate_pac_request_none(self): -+ creds = self._get_creds(replication_allowed=True, -+ revealed_to_rodc=True) -+ tgt = self.get_tgt(creds, pac_request=None) -+ tgt = self._modify_tgt(tgt, invalid=True, from_rodc=True) -+ -+ tgt = self._validate_tgt(tgt, expected_error=0, expect_pac=None, -+ expect_pac_attrs=False, -+ expect_requester_sid=True) -+ -+ ticket = self._run_tgs(tgt, expected_error=0, expect_pac=True) -+ -+ pac = self.get_ticket_pac(ticket) -+ self.assertIsNotNone(pac) -+ -+ def test_rodc_validate_pac_request_false(self): -+ creds = self._get_creds(replication_allowed=True, -+ revealed_to_rodc=True) -+ tgt = self.get_tgt(creds, pac_request=False, expect_pac=None) -+ tgt = self._modify_tgt(tgt, invalid=True, from_rodc=True) -+ -+ tgt = self._validate_tgt(tgt, expected_error=0, expect_pac=None, -+ expect_pac_attrs=False, -+ expect_requester_sid=True) -+ -+ ticket = self._run_tgs(tgt, expected_error=0, expect_pac=True) -+ -+ pac = self.get_ticket_pac(ticket) -+ self.assertIsNotNone(pac) -+ -+ def test_rodc_validate_pac_request_true(self): -+ creds = self._get_creds(replication_allowed=True, -+ revealed_to_rodc=True) -+ tgt = self.get_tgt(creds, pac_request=True) -+ tgt = self._modify_tgt(tgt, invalid=True, from_rodc=True) -+ -+ tgt = self._validate_tgt(tgt, expected_error=0, expect_pac=None, -+ expect_pac_attrs=False, -+ expect_requester_sid=True) -+ -+ ticket = self._run_tgs(tgt, expected_error=0, expect_pac=True) -+ -+ pac = self.get_ticket_pac(ticket) -+ self.assertIsNotNone(pac) -+ - def test_s4u2self_pac_request_none(self): - creds = self._get_creds() - tgt = self.get_tgt(creds, pac_request=None) -diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc -index 3b78491c837..cc2396b2d38 100644 ---- a/selftest/knownfail_heimdal_kdc -+++ b/selftest/knownfail_heimdal_kdc -@@ -116,6 +116,12 @@ - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_rodc_renew_none - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_rodc_renew_true - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_revealed -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_rodc_renew_pac_request_false -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_rodc_renew_pac_request_none -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_rodc_renew_pac_request_true -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_rodc_validate_pac_request_false -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_rodc_validate_pac_request_none -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_rodc_validate_pac_request_true - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_pac_request_false - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_pac_attrs_none - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_pac_attrs_true -diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc -index 806aaa707d7..36be42d0481 100644 ---- a/selftest/knownfail_mit_kdc -+++ b/selftest/knownfail_mit_kdc -@@ -400,6 +400,12 @@ 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_renew_rodc_sid_mismatch_existing - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_sid_mismatch_nonexisting - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_service_ticket -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_rodc_renew_pac_request_false -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_rodc_renew_pac_request_none -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_rodc_renew_pac_request_true -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_rodc_validate_pac_request_false -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_rodc_validate_pac_request_none -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_rodc_validate_pac_request_true - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_authdata_no_pac - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_no_pac - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_req(?!_invalid) --- -2.25.1 - - -From 81a6fa876fd48af9998ee209d96e3cde1511e9f5 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Thu, 25 Nov 2021 13:24:57 +1300 -Subject: [PATCH 43/99] Revert "CVE-2020-25719 s4/torture: Expect additional - PAC buffers" - -This reverts commit fa4c9bcefdeed0a7106aab84df20b02435febc1f. - -We should not be generating these additional PAC buffers for service -tickets, only for TGTs. - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett -(cherry picked from commit e61983c7f2c4daade83b237efb990d0c0645b3a3) ---- - selftest/knownfail_heimdal_kdc | 39 ++++++++++++++++++++++++++++++++ - source4/torture/rpc/remote_pac.c | 24 ++------------------ - 2 files changed, 41 insertions(+), 22 deletions(-) - -diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc -index cc2396b2d38..1e42007f31f 100644 ---- a/selftest/knownfail_heimdal_kdc -+++ b/selftest/knownfail_heimdal_kdc -@@ -135,3 +135,42 @@ - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_rodc_renew - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_rodc_validate - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_revealed -+# -+# PAC tests -+# -+^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 5a1567f1bde..16249799e36 100644 ---- a/source4/torture/rpc/remote_pac.c -+++ b/source4/torture/rpc/remote_pac.c -@@ -308,7 +308,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 = 7; -+ num_pac_buffers = 5; - if (expect_pac_upn_dns_info) { - num_pac_buffers += 1; - } -@@ -365,18 +365,6 @@ static bool test_PACVerify(struct torture_context *tctx, - pac_buf->info != NULL, - "PAC_TYPE_TICKET_CHECKSUM info"); - -- pac_buf = get_pac_buffer(&pac_data_struct, PAC_TYPE_ATTRIBUTES_INFO); -- torture_assert_not_null(tctx, pac_buf, "PAC_TYPE_ATTRIBUTES_INFO"); -- torture_assert(tctx, -- pac_buf->info != NULL, -- "PAC_TYPE_ATTRIBUTES_INFO info"); -- -- pac_buf = get_pac_buffer(&pac_data_struct, PAC_TYPE_REQUESTER_SID); -- torture_assert_not_null(tctx, pac_buf, "PAC_TYPE_REQUESTER_SID"); -- torture_assert(tctx, -- pac_buf->info != NULL, -- "PAC_TYPE_REQUESTER_SID info"); -- - ok = netlogon_validate_pac(tctx, p, server_creds, secure_channel_type, test_machine_name, - negotiate_flags, pac_data, session_info); - -@@ -1140,7 +1128,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 = 9; -+ 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"); -@@ -1180,14 +1168,6 @@ static bool test_S4U2Proxy(struct torture_context *tctx, - talloc_asprintf(tctx, "%s@%s", self_princ, cli_credentials_get_realm(credentials)), - "wrong transited_services[0]"); - -- pac_buf = get_pac_buffer(&pac_data_struct, PAC_TYPE_ATTRIBUTES_INFO); -- torture_assert_not_null(tctx, pac_buf, "PAC_TYPE_ATTRIBUTES_INFO"); -- torture_assert_not_null(tctx, pac_buf->info, "PAC_TYPE_ATTRIBUTES_INFO info"); -- -- pac_buf = get_pac_buffer(&pac_data_struct, PAC_TYPE_REQUESTER_SID); -- torture_assert_not_null(tctx, pac_buf, "PAC_TYPE_REQUESTER_SID"); -- torture_assert_not_null(tctx, pac_buf->info, "PAC_TYPE_REQUESTER_SID info"); -- - return netlogon_validate_pac(tctx, p, server_creds, secure_channel_type, test_machine_name, - negotiate_flags, pac_data, session_info); - } --- -2.25.1 - - -From 88b71db4bb8315c6d53c820bfc7b680bf04114a9 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Wed, 24 Nov 2021 20:42:22 +1300 -Subject: [PATCH 44/99] kdc: Don't include extra PAC buffers in service tickets - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett -(cherry picked from commit 90025b6a4d250a15c0f988a9a9150ecfb63069ef) ---- - selftest/knownfail_heimdal_kdc | 42 ---------------------------------- - source4/kdc/wdc-samba4.c | 31 +++++++++++++++++-------- - 2 files changed, 21 insertions(+), 52 deletions(-) - -diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc -index 1e42007f31f..219ab11e16a 100644 ---- a/selftest/knownfail_heimdal_kdc -+++ b/selftest/knownfail_heimdal_kdc -@@ -123,11 +123,8 @@ - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_rodc_validate_pac_request_none - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_rodc_validate_pac_request_true - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_pac_request_false --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_pac_attrs_none --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_pac_attrs_true - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_req_from_rodc_no_requester_sid - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_req_no_requester_sid --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid(?!_) - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_renew - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_rodc_renew - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_rodc_validate -@@ -135,42 +132,3 @@ - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_rodc_renew - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_rodc_validate - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_revealed --# --# PAC tests --# --^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/kdc/wdc-samba4.c b/source4/kdc/wdc-samba4.c -index 8c3ce71529c..17af76f4edb 100644 ---- a/source4/kdc/wdc-samba4.c -+++ b/source4/kdc/wdc-samba4.c -@@ -132,6 +132,7 @@ static krb5_error_code samba_wdc_reget_pac2(krb5_context context, - krb5_error_code ret; - NTSTATUS nt_status; - bool is_in_db, is_untrusted; -+ bool is_krbtgt; - size_t num_types = 0; - uint32_t *types = NULL; - uint32_t forced_next_type = 0; -@@ -471,7 +472,9 @@ static krb5_error_code samba_wdc_reget_pac2(krb5_context context, - goto out; - } - -- if (!is_untrusted && !server_skdc_entry->is_krbtgt) { -+ is_krbtgt = krb5_principal_is_krbtgt(context, server->entry.principal); -+ -+ if (!is_untrusted && !is_krbtgt) { - /* - * The client may have requested no PAC when obtaining the - * TGT. -@@ -576,17 +579,25 @@ static krb5_error_code samba_wdc_reget_pac2(krb5_context context, - type_blob = data_blob_const(&zero_byte, 1); - break; - case PAC_TYPE_ATTRIBUTES_INFO: -- /* just copy... */ -- break; -+ if (is_krbtgt) { -+ /* just copy... */ -+ break; -+ } else { -+ continue; -+ } - case PAC_TYPE_REQUESTER_SID: -- /* -- * Replace in the RODC case, otherwise -- * requester_sid_blob is NULL and we just copy. -- */ -- if (requester_sid_blob != NULL) { -- type_blob = *requester_sid_blob; -+ if (is_krbtgt) { -+ /* -+ * Replace in the RODC case, otherwise -+ * requester_sid_blob is NULL and we just copy. -+ */ -+ if (requester_sid_blob != NULL) { -+ type_blob = *requester_sid_blob; -+ } -+ break; -+ } else { -+ continue; - } -- break; - default: - /* just copy... */ - break; --- -2.25.1 - - -From 081d6b571a81266b39b0efb70c1de492e3d60ae0 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Thu, 25 Nov 2021 10:53:49 +1300 -Subject: [PATCH 45/99] kdc: Remove PAC_TYPE_ATTRIBUTES_INFO from RODC-issued - tickets - -Windows ignores PAC_TYPE_ATTRIBUTES_INFO and always issues a PAC when -presented with an RODC-issued TGT. By removing this PAC buffer from -RODC-issued tickets, we ensure that an RODC-issued ticket will still -result in a PAC if it is first renewed or validated by the main DC. - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett -(cherry picked from commit 4b60e9516497c2e7f1545fe50887d0336b9893f2) ---- - selftest/knownfail_heimdal_kdc | 13 ------------- - source4/kdc/wdc-samba4.c | 2 +- - 2 files changed, 1 insertion(+), 14 deletions(-) - -diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc -index 219ab11e16a..7dccc3d4c0d 100644 ---- a/selftest/knownfail_heimdal_kdc -+++ b/selftest/knownfail_heimdal_kdc -@@ -112,16 +112,6 @@ - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_service_ticket - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_sid_mismatch_existing - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_sid_mismatch_nonexisting --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_rodc_renew_false --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_rodc_renew_none --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_rodc_renew_true --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_revealed --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_rodc_renew_pac_request_false --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_rodc_renew_pac_request_none --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_rodc_renew_pac_request_true --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_rodc_validate_pac_request_false --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_rodc_validate_pac_request_none --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_rodc_validate_pac_request_true - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_pac_request_false - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_req_from_rodc_no_requester_sid - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_req_no_requester_sid -@@ -129,6 +119,3 @@ - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_rodc_renew - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_rodc_validate - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_validate --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_rodc_renew --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_rodc_validate --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_revealed -diff --git a/source4/kdc/wdc-samba4.c b/source4/kdc/wdc-samba4.c -index 17af76f4edb..713720bcb99 100644 ---- a/source4/kdc/wdc-samba4.c -+++ b/source4/kdc/wdc-samba4.c -@@ -579,7 +579,7 @@ static krb5_error_code samba_wdc_reget_pac2(krb5_context context, - type_blob = data_blob_const(&zero_byte, 1); - break; - case PAC_TYPE_ATTRIBUTES_INFO: -- if (is_krbtgt) { -+ if (!is_untrusted && is_krbtgt) { - /* just copy... */ - break; - } else { --- -2.25.1 - - -From 992a924dfa401daa630931c5dbec2fe9537c7ea9 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Thu, 25 Nov 2021 12:46:40 +1300 -Subject: [PATCH 46/99] tests/krb5: Add a test for S4U2Self with no - authorization data required - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett -(cherry picked from commit 192d6edfe912105ec344dc554f872a24c03540a3) ---- - python/samba/tests/krb5/s4u_tests.py | 34 ++++++++++++++++++++++++++++ - selftest/knownfail_heimdal_kdc | 1 + - 2 files changed, 35 insertions(+) - -diff --git a/python/samba/tests/krb5/s4u_tests.py b/python/samba/tests/krb5/s4u_tests.py -index 2953766ef21..6ec9af11423 100755 ---- a/python/samba/tests/krb5/s4u_tests.py -+++ b/python/samba/tests/krb5/s4u_tests.py -@@ -324,6 +324,13 @@ class S4UKerberosTests(KDCBaseTest): - sname=service_sname, - etypes=etypes) - -+ if not expected_error_mode: -+ # Check that the ticket contains a PAC. -+ ticket = kdc_exchange_dict['rep_ticket_creds'] -+ -+ pac = self.get_ticket_pac(ticket) -+ self.assertIsNotNone(pac) -+ - # Ensure we used all the parameters given to us. - self.assertEqual({}, kdc_dict) - -@@ -504,6 +511,24 @@ class S4UKerberosTests(KDCBaseTest): - self.set_ticket_forwardable, flag=True) - }) - -+ # Do an S4U2Self where the service does not require authorization data. The -+ # resulting ticket should still contain a PAC. -+ def test_s4u2self_no_auth_data_required(self): -+ self._run_s4u2self_test( -+ { -+ 'client_opts': { -+ 'not_delegated': False -+ }, -+ 'service_opts': { -+ 'trusted_to_auth_for_delegation': True, -+ 'no_auth_data_required': True -+ }, -+ '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( -@@ -654,6 +679,15 @@ class S4UKerberosTests(KDCBaseTest): - etypes=etypes, - additional_tickets=additional_tickets) - -+ if not expected_error_mode: -+ # Check whether the ticket contains a PAC. -+ ticket = kdc_exchange_dict['rep_ticket_creds'] -+ pac = self.get_ticket_pac(ticket, expect_pac=expect_pac) -+ if expect_pac: -+ self.assertIsNotNone(pac) -+ else: -+ self.assertIsNone(pac) -+ - # Ensure we used all the parameters given to us. - self.assertEqual({}, kdc_dict) - -diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc -index 7dccc3d4c0d..363107f476e 100644 ---- a/selftest/knownfail_heimdal_kdc -+++ b/selftest/knownfail_heimdal_kdc -@@ -80,6 +80,7 @@ - ^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_forwardable -+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_no_auth_data_required - ^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_constrained_delegation_no_auth_data_required --- -2.25.1 - - -From 5e6c25f1ed08045f5341e425621e32a75e84ff27 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Tue, 23 Nov 2021 17:30:50 +1300 -Subject: [PATCH 47/99] heimdal:kdc: Always generate a PAC for S4U2Self - -If we decided not to put a PAC into the ticket, mspac would be NULL -here, and the resulting ticket would not contain a PAC. This could -happen if there was a request to omit the PAC or the service did not -require authorization data. Ensure that we always generate a PAC. - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett -(cherry picked from commit 1f4f3018c5001b289b91959a72d00575c8fc0ac1) ---- - selftest/knownfail_heimdal_kdc | 2 -- - source4/heimdal/kdc/krb5tgs.c | 13 +++++++------ - 2 files changed, 7 insertions(+), 8 deletions(-) - -diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc -index 363107f476e..ace0550fd15 100644 ---- a/selftest/knownfail_heimdal_kdc -+++ b/selftest/knownfail_heimdal_kdc -@@ -80,7 +80,6 @@ - ^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_forwardable --^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_no_auth_data_required - ^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_constrained_delegation_no_auth_data_required -@@ -113,7 +112,6 @@ - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_service_ticket - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_sid_mismatch_existing - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_sid_mismatch_nonexisting --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_pac_request_false - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_req_from_rodc_no_requester_sid - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_req_no_requester_sid - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_renew -diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c -index 6c5c51aa448..dc356b4daa5 100644 ---- a/source4/heimdal/kdc/krb5tgs.c -+++ b/source4/heimdal/kdc/krb5tgs.c -@@ -1846,12 +1846,13 @@ server_lookup: - if (mspac) { - krb5_pac_free(context, mspac); - mspac = NULL; -- ret = _kdc_pac_generate(context, s4u2self_impersonated_client, NULL, NULL, &mspac); -- if (ret) { -- kdc_log(context, config, 0, "PAC generation failed for -- %s", -- tpn); -- goto out; -- } -+ } -+ -+ ret = _kdc_pac_generate(context, s4u2self_impersonated_client, NULL, NULL, &mspac); -+ if (ret) { -+ kdc_log(context, config, 0, "PAC generation failed for -- %s", -+ tpn); -+ goto out; - } - - /* --- -2.25.1 - - -From 612c769ab7061906f2089e7af15c3745be610201 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Thu, 25 Nov 2021 09:29:42 +1300 -Subject: [PATCH 48/99] selftest: Properly check extra PAC buffers with Heimdal - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett -(cherry picked from commit ee4aa21c487fa80082a548b2e4f115a791e30340) ---- - selftest/knownfail_heimdal_kdc | 12 ++++++++++++ - source4/selftest/tests.py | 2 +- - 2 files changed, 13 insertions(+), 1 deletion(-) - -diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc -index ace0550fd15..4d7d6a67b92 100644 ---- a/selftest/knownfail_heimdal_kdc -+++ b/selftest/knownfail_heimdal_kdc -@@ -79,8 +79,15 @@ - ^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_no_auth_data_required -+^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 - # - ^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 -@@ -112,6 +119,11 @@ - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_service_ticket - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_sid_mismatch_existing - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_sid_mismatch_nonexisting -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_pac_request_false -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_pac_request_none -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_pac_request_true -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_req(?!_invalid) -+^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_revealed - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_req_from_rodc_no_requester_sid - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_req_no_requester_sid - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_renew -diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py -index 7234767baa5..f2ea9adb67f 100755 ---- a/source4/selftest/tests.py -+++ b/source4/selftest/tests.py -@@ -905,7 +905,7 @@ for env in ['fileserver_smb1', 'nt4_member', 'clusteredmember', 'ktest', 'nt4_dc - have_fast_support = int('SAMBA_USES_MITKDC' in config_hash) - tkt_sig_support = int('SAMBA4_USES_HEIMDAL' in config_hash) - expect_pac = int('SAMBA4_USES_HEIMDAL' in config_hash) --extra_pac_buffers = 0 -+extra_pac_buffers = 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 0426d20aeabba4dbd76bffbadd97a5c8afe2091e Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Tue, 23 Nov 2021 19:38:35 +1300 -Subject: [PATCH 49/99] heimdal:kdc: Do not generate extra PAC buffers for - S4U2Self service ticket - -Normally samba_wdc_get_pac() is used to generate the PAC for a TGT, but -when generating a service ticket for S4U2Self, we want to avoid adding -the additional PAC_ATTRIBUTES_INFO and PAC_REQUESTER_SID buffers. - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett -(cherry picked from commit 9bd26804852d957f81cb311e5142f9190f9afa65) ---- - selftest/knownfail_heimdal_kdc | 12 ------------ - source4/heimdal/kdc/kerberos5.c | 2 +- - source4/heimdal/kdc/krb5tgs.c | 3 ++- - source4/heimdal/kdc/windc.c | 5 +++-- - source4/heimdal/kdc/windc_plugin.h | 2 ++ - source4/kdc/wdc-samba4.c | 11 ++++++++--- - 6 files changed, 16 insertions(+), 19 deletions(-) - -diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc -index 4d7d6a67b92..ace0550fd15 100644 ---- a/selftest/knownfail_heimdal_kdc -+++ b/selftest/knownfail_heimdal_kdc -@@ -79,15 +79,8 @@ - ^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_no_auth_data_required --^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 - # - ^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 -@@ -119,11 +112,6 @@ - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_service_ticket - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_sid_mismatch_existing - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_sid_mismatch_nonexisting --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_pac_request_false --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_pac_request_none --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_pac_request_true --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_req(?!_invalid) --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_s4u2self_rodc_revealed - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_req_from_rodc_no_requester_sid - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_req_no_requester_sid - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_renew -diff --git a/source4/heimdal/kdc/kerberos5.c b/source4/heimdal/kdc/kerberos5.c -index 11b334e46fe..ad026dd617b 100644 ---- a/source4/heimdal/kdc/kerberos5.c -+++ b/source4/heimdal/kdc/kerberos5.c -@@ -1777,7 +1777,7 @@ _kdc_as_rep(krb5_context context, - - sent_pac_request = send_pac_p(context, req, &pac_request); - -- ret = _kdc_pac_generate(context, client, pk_reply_key, -+ ret = _kdc_pac_generate(context, client, server, pk_reply_key, - sent_pac_request ? &pac_request : NULL, - &p); - if (ret) { -diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c -index dc356b4daa5..38dba8493ae 100644 ---- a/source4/heimdal/kdc/krb5tgs.c -+++ b/source4/heimdal/kdc/krb5tgs.c -@@ -1848,7 +1848,8 @@ server_lookup: - mspac = NULL; - } - -- ret = _kdc_pac_generate(context, s4u2self_impersonated_client, NULL, NULL, &mspac); -+ ret = _kdc_pac_generate(context, s4u2self_impersonated_client, server, -+ NULL, NULL, &mspac); - if (ret) { - kdc_log(context, config, 0, "PAC generation failed for -- %s", - tpn); -diff --git a/source4/heimdal/kdc/windc.c b/source4/heimdal/kdc/windc.c -index 93b973f576b..0a5ae5025ec 100644 ---- a/source4/heimdal/kdc/windc.c -+++ b/source4/heimdal/kdc/windc.c -@@ -73,6 +73,7 @@ krb5_kdc_windc_init(krb5_context context) - krb5_error_code - _kdc_pac_generate(krb5_context context, - hdb_entry_ex *client, -+ hdb_entry_ex *server, - const krb5_keyblock *pk_reply_key, - const krb5_boolean *pac_request, - krb5_pac *pac) -@@ -88,9 +89,9 @@ _kdc_pac_generate(krb5_context context, - - if (windcft->pac_pk_generate != NULL && pk_reply_key != NULL) - return (windcft->pac_pk_generate)(windcctx, context, -- client, pk_reply_key, -+ client, server, pk_reply_key, - pac_request, pac); -- return (windcft->pac_generate)(windcctx, context, client, -+ return (windcft->pac_generate)(windcctx, context, client, server, - pac_request, pac); - } - -diff --git a/source4/heimdal/kdc/windc_plugin.h b/source4/heimdal/kdc/windc_plugin.h -index c7f2bcb5ed9..d239d0260e7 100644 ---- a/source4/heimdal/kdc/windc_plugin.h -+++ b/source4/heimdal/kdc/windc_plugin.h -@@ -55,12 +55,14 @@ struct hdb_entry_ex; - typedef krb5_error_code - (*krb5plugin_windc_pac_generate)(void *, krb5_context, - struct hdb_entry_ex *, /* client */ -+ struct hdb_entry_ex *, /* server */ - const krb5_boolean *, /* pac_request */ - krb5_pac *); - - typedef krb5_error_code - (*krb5plugin_windc_pac_pk_generate)(void *, krb5_context, - struct hdb_entry_ex *, /* client */ -+ struct hdb_entry_ex *, /* server */ - const krb5_keyblock *, /* pk_replykey */ - const krb5_boolean *, /* pac_request */ - krb5_pac *); -diff --git a/source4/kdc/wdc-samba4.c b/source4/kdc/wdc-samba4.c -index 713720bcb99..b1d011c09a9 100644 ---- a/source4/kdc/wdc-samba4.c -+++ b/source4/kdc/wdc-samba4.c -@@ -37,6 +37,7 @@ - */ - static krb5_error_code samba_wdc_get_pac(void *priv, krb5_context context, - struct hdb_entry_ex *client, -+ struct hdb_entry_ex *server, - const krb5_keyblock *pk_reply_key, - const krb5_boolean *pac_request, - krb5_pac *pac) -@@ -55,6 +56,7 @@ static krb5_error_code samba_wdc_get_pac(void *priv, krb5_context context, - struct samba_kdc_entry *skdc_entry = - talloc_get_type_abort(client->ctx, - struct samba_kdc_entry); -+ bool is_krbtgt; - - mem_ctx = talloc_named(client->ctx, 0, "samba_get_pac context"); - if (!mem_ctx) { -@@ -65,13 +67,15 @@ static krb5_error_code samba_wdc_get_pac(void *priv, krb5_context context, - cred_ndr_ptr = &cred_ndr; - } - -+ is_krbtgt = krb5_principal_is_krbtgt(context, server->entry.principal); -+ - nt_status = samba_kdc_get_pac_blobs(mem_ctx, skdc_entry, - &logon_blob, - cred_ndr_ptr, - &upn_blob, -- &pac_attrs_blob, -+ is_krbtgt ? &pac_attrs_blob : NULL, - pac_request, -- &requester_sid_blob, -+ is_krbtgt ? &requester_sid_blob : NULL, - NULL); - if (!NT_STATUS_IS_OK(nt_status)) { - talloc_free(mem_ctx); -@@ -101,10 +105,11 @@ static krb5_error_code samba_wdc_get_pac(void *priv, krb5_context context, - - static krb5_error_code samba_wdc_get_pac_compat(void *priv, krb5_context context, - struct hdb_entry_ex *client, -+ struct hdb_entry_ex *server, - const krb5_boolean *pac_request, - krb5_pac *pac) - { -- return samba_wdc_get_pac(priv, context, client, NULL, pac_request, pac); -+ return samba_wdc_get_pac(priv, context, client, server, NULL, pac_request, pac); - } - - static krb5_error_code samba_wdc_reget_pac2(krb5_context context, --- -2.25.1 - - -From 2eef0f950bc8c2ed2309798a75d88823a81eefff Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Wed, 24 Nov 2021 20:41:54 +1300 -Subject: [PATCH 50/99] kdc: Require that PAC_REQUESTER_SID buffer is present - for TGTs - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett - -Autobuild-User(master): Andrew Bartlett -Autobuild-Date(master): Tue Nov 30 03:33:26 UTC 2021 on sn-devel-184 - -(cherry picked from commit 38c5bad4a853b19fe9a51fb059e150b153c4632a) ---- - selftest/knownfail_heimdal_kdc | 6 ------ - source4/kdc/wdc-samba4.c | 6 ++++++ - 2 files changed, 6 insertions(+), 6 deletions(-) - -diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc -index ace0550fd15..e9a560555da 100644 ---- a/selftest/knownfail_heimdal_kdc -+++ b/selftest/knownfail_heimdal_kdc -@@ -112,9 +112,3 @@ - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_service_ticket - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_sid_mismatch_existing - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_sid_mismatch_nonexisting --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_req_from_rodc_no_requester_sid --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_req_no_requester_sid --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_renew --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_rodc_renew --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_rodc_validate --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_validate -diff --git a/source4/kdc/wdc-samba4.c b/source4/kdc/wdc-samba4.c -index b1d011c09a9..d7ce34fb3a9 100644 ---- a/source4/kdc/wdc-samba4.c -+++ b/source4/kdc/wdc-samba4.c -@@ -459,6 +459,12 @@ static krb5_error_code samba_wdc_reget_pac2(krb5_context context, - talloc_free(mem_ctx); - return EINVAL; - } -+ if (delegated_proxy_principal == NULL && requester_sid_idx == -1) { -+ DEBUG(1, ("PAC_TYPE_REQUESTER_SID missing\n")); -+ SAFE_FREE(types); -+ talloc_free(mem_ctx); -+ return KRB5KDC_ERR_TGT_REVOKED; -+ } - - /* - * The server account may be set not to want the PAC. --- -2.25.1 - - -From d34d201773ae9c05e424a5c5d568c94483f1be69 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Tue, 7 Dec 2021 13:15:38 +1300 -Subject: [PATCH 51/99] kdc: Canonicalize realm for enterprise principals - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett - -Autobuild-User(master): Andrew Bartlett -Autobuild-Date(master): Tue Dec 7 04:54:35 UTC 2021 on sn-devel-184 - -(cherry picked from commit 8bd7b316bd61ef35f6e0baa0b65f0ef00910112c) ---- - selftest/knownfail.d/kdc-enterprise | 63 ----------------------------- - selftest/knownfail_heimdal_kdc | 3 -- - selftest/knownfail_mit_kdc | 36 +++++++++++++++++ - source4/kdc/db-glue.c | 24 +++++------ - 4 files changed, 47 insertions(+), 79 deletions(-) - delete mode 100644 selftest/knownfail.d/kdc-enterprise - -diff --git a/selftest/knownfail.d/kdc-enterprise b/selftest/knownfail.d/kdc-enterprise -deleted file mode 100644 -index c9b6c98a2ee..00000000000 ---- a/selftest/knownfail.d/kdc-enterprise -+++ /dev/null -@@ -1,63 +0,0 @@ --samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise\( --samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_NetbiosRealm\( --samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_NetbiosRealm_RemoveDollar\( --samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_NetbiosRealm_UPN\( --samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_NetbiosRealm_UPN_RemoveDollar\( --samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_RemoveDollar\( --samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UPN\( --samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UPN_RemoveDollar\( --samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_NetbiosRealm\( --samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_NetbiosRealm_RemoveDollar\( --samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_NetbiosRealm_UPN\( --samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_NetbiosRealm_UPN_RemoveDollar\( --samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UpperUserName_NetbiosRealm\( --samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UpperUserName_NetbiosRealm_RemoveDollar\( --samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UpperUserName_NetbiosRealm_UPN\( --samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UpperUserName_NetbiosRealm_UPN_RemoveDollar\( --samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName\( --samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_NetbiosRealm\( --samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_NetbiosRealm_RemoveDollar\( --samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_NetbiosRealm_UPN\( --samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_NetbiosRealm_UPN_RemoveDollar\( --samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_RemoveDollar\( --samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_UPN\( --samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_UPN_RemoveDollar\( --samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Enterprise\( --samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Enterprise_NetbiosRealm\( --samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Enterprise_NetbiosRealm_UPN\( --samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Enterprise_UPN\( --samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Enterprise_UpperRealm_NetbiosRealm\( --samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Enterprise_UpperRealm_NetbiosRealm_UPN\( --samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Enterprise_UpperRealm_UpperUserName_NetbiosRealm\( --samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Enterprise_UpperRealm_UpperUserName_NetbiosRealm_UPN\( --samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Enterprise_UpperUserName\( --samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Enterprise_UpperUserName_NetbiosRealm\( --samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Enterprise_UpperUserName_NetbiosRealm_UPN\( --samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_UserCredentials_Enterprise_UpperUserName_UPN\( -- -- -- --^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_AsReqSelf\( --^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_NetbiosRealm_AsReqSelf\( --^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_NetbiosRealm_RemoveDollar_AsReqSelf\( --^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_NetbiosRealm_UPN_AsReqSelf\( --^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_NetbiosRealm_UPN_RemoveDollar_AsReqSelf\( --^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_RemoveDollar_AsReqSelf\( --^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UPN_AsReqSelf\( --^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UPN_RemoveDollar_AsReqSelf\( --^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_NetbiosRealm_AsReqSelf\( --^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_NetbiosRealm_RemoveDollar_AsReqSelf\( --^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_NetbiosRealm_UPN_AsReqSelf\( --^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_NetbiosRealm_UPN_RemoveDollar_AsReqSelf\( --^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UpperUserName_NetbiosRealm_AsReqSelf\( --^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UpperUserName_NetbiosRealm_RemoveDollar_AsReqSelf\( --^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UpperUserName_NetbiosRealm_UPN_AsReqSelf\( --^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UpperUserName_NetbiosRealm_UPN_RemoveDollar_AsReqSelf\( --^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_AsReqSelf\( --^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_NetbiosRealm_AsReqSelf\( --^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_NetbiosRealm_RemoveDollar_AsReqSelf\( --^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_NetbiosRealm_UPN_AsReqSelf\( --^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_NetbiosRealm_UPN_RemoveDollar_AsReqSelf\( --^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_RemoveDollar_AsReqSelf\( --^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_UPN_AsReqSelf\( --^samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_UPN_RemoveDollar_AsReqSelf\( -diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc -index e9a560555da..692b9ecdd72 100644 ---- a/selftest/knownfail_heimdal_kdc -+++ b/selftest/knownfail_heimdal_kdc -@@ -5,9 +5,6 @@ - # - # Heimdal currently fails the following MS-KILE client principal lookup - # 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 --^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_4 --^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_5 - ^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_6_a - ^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_enterprise_principal_step_6_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_a -diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc -index 36be42d0481..6a4ddaa00ec 100644 ---- a/selftest/knownfail_mit_kdc -+++ b/selftest/knownfail_mit_kdc -@@ -56,17 +56,53 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ - samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperUserName_UPN\( - samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Canonicalize_UpperUserName_UPN_RemoveDollar\( - samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise\( -+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_AsReqSelf\( - samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_NetbiosRealm\( -+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_NetbiosRealm_AsReqSelf\( -+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_NetbiosRealm_RemoveDollar\( -+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_NetbiosRealm_RemoveDollar_AsReqSelf\( - samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_NetbiosRealm_UPN\( -+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_NetbiosRealm_UPN_AsReqSelf\( -+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_NetbiosRealm_UPN_RemoveDollar\( -+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_NetbiosRealm_UPN_RemoveDollar_AsReqSelf\( -+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_RemoveDollar\( -+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_RemoveDollar_AsReqSelf\( - samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UPN\( -+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UPN_AsReqSelf\( -+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UPN_RemoveDollar\( -+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UPN_RemoveDollar_AsReqSelf\( - samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_NetbiosRealm\( -+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_NetbiosRealm_AsReqSelf\( -+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_NetbiosRealm_RemoveDollar\( -+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_NetbiosRealm_RemoveDollar_AsReqSelf\( - samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_NetbiosRealm_UPN\( -+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_NetbiosRealm_UPN_AsReqSelf\( -+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_NetbiosRealm_UPN_RemoveDollar\( -+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_NetbiosRealm_UPN_RemoveDollar_AsReqSelf\( - samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UpperUserName_NetbiosRealm\( -+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UpperUserName_NetbiosRealm_AsReqSelf\( -+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UpperUserName_NetbiosRealm_RemoveDollar\( -+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UpperUserName_NetbiosRealm_RemoveDollar_AsReqSelf\( - samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UpperUserName_NetbiosRealm_UPN\( -+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UpperUserName_NetbiosRealm_UPN_AsReqSelf\( -+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UpperUserName_NetbiosRealm_UPN_RemoveDollar\( -+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperRealm_UpperUserName_NetbiosRealm_UPN_RemoveDollar_AsReqSelf\( - samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName\( -+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_AsReqSelf\( - samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_NetbiosRealm\( -+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_NetbiosRealm_AsReqSelf\( -+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_NetbiosRealm_RemoveDollar\( -+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_NetbiosRealm_RemoveDollar_AsReqSelf\( - samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_NetbiosRealm_UPN\( -+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_NetbiosRealm_UPN_AsReqSelf\( -+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_NetbiosRealm_UPN_RemoveDollar\( -+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_NetbiosRealm_UPN_RemoveDollar_AsReqSelf\( -+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_RemoveDollar\( -+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_RemoveDollar_AsReqSelf\( - samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_UPN\( -+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_UPN_AsReqSelf\( -+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_UPN_RemoveDollar\( -+samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_Enterprise_UpperUserName_UPN_RemoveDollar_AsReqSelf\( - samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_NetbiosRealm\( - samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_NetbiosRealm_RemoveDollar\( - samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_tests.KerberosASCanonicalizationTests.test_MachineCredentials_NetbiosRealm_UPN\( -diff --git a/source4/kdc/db-glue.c b/source4/kdc/db-glue.c -index bed0ff773f9..5752ffb821c 100644 ---- a/source4/kdc/db-glue.c -+++ b/source4/kdc/db-glue.c -@@ -980,19 +980,17 @@ static krb5_error_code samba_kdc_message2entry(krb5_context context, - goto out; - } - -- if (smb_krb5_principal_get_type(context, principal) != KRB5_NT_ENTERPRISE_PRINCIPAL) { -- /* While we have copied the client principal, tests -- * show that Win2k3 returns the 'corrected' realm, not -- * the client-specified realm. This code attempts to -- * replace the client principal's realm with the one -- * we determine from our records */ -- -- /* this has to be with malloc() */ -- ret = smb_krb5_principal_set_realm(context, entry_ex->entry.principal, lpcfg_realm(lp_ctx)); -- if (ret) { -- krb5_clear_error_message(context); -- goto out; -- } -+ /* While we have copied the client principal, tests -+ * show that Win2k3 returns the 'corrected' realm, not -+ * the client-specified realm. This code attempts to -+ * replace the client principal's realm with the one -+ * we determine from our records */ -+ -+ /* this has to be with malloc() */ -+ ret = smb_krb5_principal_set_realm(context, entry_ex->entry.principal, lpcfg_realm(lp_ctx)); -+ if (ret) { -+ krb5_clear_error_message(context); -+ goto out; - } - } - --- -2.25.1 - - -From 3ac74c8b94d6c2d109ee07712f55be01190a6816 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Tue, 14 Dec 2021 19:16:00 +1300 -Subject: [PATCH 52/99] tests/krb5: Correctly determine whether tickets are - service tickets - -Previously we expected tickets to contain a ticket checksum if the sname -was not the krbtgt. However, the ticket checksum should not be present -if we are performing an AS-REQ to our own account. Now we determine a -ticket is a service ticket only if the request is also a TGS-REQ. - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett -(cherry picked from commit 100be7eb8e70ba270a8e92957a5e47466160a901) ---- - python/samba/tests/krb5/compatability_tests.py | 10 ++++++---- - python/samba/tests/krb5/kdc_base_test.py | 2 +- - python/samba/tests/krb5/raw_testcase.py | 18 ++++++++++-------- - python/samba/tests/krb5/rodc_tests.py | 4 ++-- - 4 files changed, 19 insertions(+), 15 deletions(-) - -diff --git a/python/samba/tests/krb5/compatability_tests.py b/python/samba/tests/krb5/compatability_tests.py -index ed2dc565b6d..65e9e3788d5 100755 ---- a/python/samba/tests/krb5/compatability_tests.py -+++ b/python/samba/tests/krb5/compatability_tests.py -@@ -132,13 +132,14 @@ class SimpleKerberosTests(KDCBaseTest): - tgt = self.get_tgt(user_creds) - - # Ensure the PAC contains the expected checksums. -- self.verify_ticket(tgt, key) -+ self.verify_ticket(tgt, key, service_ticket=False) - - # 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) -+ self.verify_ticket(service_ticket, key, service_ticket=True, -+ expect_ticket_checksum=True) - - def test_mit_ticket_signature(self): - # Ensure that a DC does not issue tickets signed with its krbtgt key. -@@ -152,13 +153,14 @@ class SimpleKerberosTests(KDCBaseTest): - tgt = self.get_tgt(user_creds) - - # Ensure the PAC contains the expected checksums. -- self.verify_ticket(tgt, key) -+ self.verify_ticket(tgt, key, service_ticket=False) - - # 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) -+ self.verify_ticket(service_ticket, key, service_ticket=True, -+ expect_ticket_checksum=False) - - def as_pre_auth_req(self, creds, etypes): - user = creds.get_username() -diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py -index 6e96b982167..9506048ee2a 100644 ---- a/python/samba/tests/krb5/kdc_base_test.py -+++ b/python/samba/tests/krb5/kdc_base_test.py -@@ -1395,7 +1395,7 @@ class KDCBaseTest(RawKerberosTest): - krbtgt_creds = self.get_krbtgt_creds() - krbtgt_key = self.TicketDecryptionKey_from_creds(krbtgt_creds) - self.verify_ticket(service_ticket_creds, krbtgt_key, -- expect_pac=expect_pac, -+ service_ticket=True, expect_pac=expect_pac, - expect_ticket_checksum=self.tkt_sig_support) - - self.tkt_cache[cache_key] = service_ticket_creds -diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py -index 14e655313fc..a2241707d44 100644 ---- a/python/samba/tests/krb5/raw_testcase.py -+++ b/python/samba/tests/krb5/raw_testcase.py -@@ -2587,7 +2587,11 @@ class RawKerberosTest(TestCaseInTempDir): - self.assertIsNotNone(ticket_decryption_key) - - if ticket_decryption_key is not None: -- self.verify_ticket(ticket_creds, krbtgt_keys, expect_pac=expect_pac, -+ service_ticket = (not self.is_tgs(expected_sname) -+ and rep_msg_type == KRB_TGS_REP) -+ self.verify_ticket(ticket_creds, krbtgt_keys, -+ service_ticket=service_ticket, -+ expect_pac=expect_pac, - expect_ticket_checksum=expect_ticket_checksum - or self.tkt_sig_support) - -@@ -2624,14 +2628,14 @@ class RawKerberosTest(TestCaseInTempDir): - expected_types.append(krb5pac.PAC_TYPE_DEVICE_INFO) - expected_types.append(krb5pac.PAC_TYPE_DEVICE_CLAIMS_INFO) - -- if not self.is_tgs(expected_sname): -+ if not self.is_tgs(expected_sname) and rep_msg_type == KRB_TGS_REP: - expected_types.append(krb5pac.PAC_TYPE_TICKET_CHECKSUM) - - require_strict = {krb5pac.PAC_TYPE_CLIENT_CLAIMS_INFO} - if not self.tkt_sig_support: - require_strict.add(krb5pac.PAC_TYPE_TICKET_CHECKSUM) - -- expect_extra_pac_buffers = rep_msg_type == KRB_AS_REP -+ expect_extra_pac_buffers = self.is_tgs(expected_sname) - - expect_pac_attrs = kdc_exchange_dict['expect_pac_attrs'] - -@@ -3233,11 +3237,9 @@ class RawKerberosTest(TestCaseInTempDir): - ticket_blob) - self.assertEqual(expected_checksum, checksum) - -- def verify_ticket(self, ticket, krbtgt_keys, expect_pac=True, -+ def verify_ticket(self, ticket, krbtgt_keys, service_ticket, -+ expect_pac=True, - expect_ticket_checksum=True): -- # Check if the ticket is a TGT. -- is_tgt = self.is_tgt(ticket) -- - # Decrypt the ticket. - - key = ticket.decryption_key -@@ -3336,7 +3338,7 @@ class RawKerberosTest(TestCaseInTempDir): - kdc_ctype, - kdc_checksum) - -- if is_tgt: -+ if not service_ticket: - self.assertNotIn(krb5pac.PAC_TYPE_TICKET_CHECKSUM, checksums) - else: - ticket_checksum, ticket_ctype = checksums.get( -diff --git a/python/samba/tests/krb5/rodc_tests.py b/python/samba/tests/krb5/rodc_tests.py -index 0e252d90262..83ee35d650a 100755 ---- a/python/samba/tests/krb5/rodc_tests.py -+++ b/python/samba/tests/krb5/rodc_tests.py -@@ -58,14 +58,14 @@ class RodcKerberosTests(KDCBaseTest): - tgt = self.get_tgt(user_creds, to_rodc=True) - - # Ensure the PAC contains the expected checksums. -- self.verify_ticket(tgt, rodc_key) -+ self.verify_ticket(tgt, rodc_key, service_ticket=False) - - # 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) -+ self.verify_ticket(service_ticket, rodc_key, service_ticket=True) - - - if __name__ == "__main__": --- -2.25.1 - - -From 9a1bee7c95d04577ce129f86c0b23f4f73cd9aae Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Tue, 8 Feb 2022 12:15:36 +1300 -Subject: [PATCH 53/99] tests/krb5: Add helper function to modify ticket flags - -Signed-off-by: Joseph Sutton -Reviewed-by: Stefan Metzmacher -(cherry picked from commit ded5115f73dff5b8b2f3212988e03f9dbe0c2aa3) ---- - python/samba/tests/krb5/kdc_base_test.py | 14 ++++++++++++++ - python/samba/tests/krb5/kdc_tgs_tests.py | 18 ++---------------- - python/samba/tests/krb5/s4u_tests.py | 17 +++-------------- - 3 files changed, 19 insertions(+), 30 deletions(-) - -diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py -index 9506048ee2a..58b87eab25b 100644 ---- a/python/samba/tests/krb5/kdc_base_test.py -+++ b/python/samba/tests/krb5/kdc_base_test.py -@@ -1602,6 +1602,20 @@ class KDCBaseTest(RawKerberosTest): - enc_part, asn1Spec=krb5_asn1.EncTicketPart()) - return enc_ticket_part - -+ def modify_ticket_flag(self, enc_part, flag, value): -+ self.assertIsInstance(value, bool) -+ -+ flag = krb5_asn1.TicketFlags(flag) -+ pos = len(tuple(flag)) - 1 -+ -+ flags = enc_part['flags'] -+ self.assertLessEqual(pos, len(flags)) -+ -+ new_flags = flags[:pos] + str(int(value)) + flags[pos + 1:] -+ enc_part['flags'] = new_flags -+ -+ return enc_part -+ - def get_objectSid(self, samdb, dn): - ''' Get the objectSID for a DN - Note: performs an Ldb query. -diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py -index 2923d53772a..8cd27dec2aa 100755 ---- a/python/samba/tests/krb5/kdc_tgs_tests.py -+++ b/python/samba/tests/krb5/kdc_tgs_tests.py -@@ -2177,14 +2177,7 @@ class KdcTgsTests(KDCBaseTest): - - def _modify_renewable(self, enc_part): - # Set the renewable flag. -- renewable_flag = krb5_asn1.TicketFlags('renewable') -- pos = len(tuple(renewable_flag)) - 1 -- -- flags = enc_part['flags'] -- self.assertLessEqual(pos, len(flags)) -- -- new_flags = flags[:pos] + '1' + flags[pos + 1:] -- enc_part['flags'] = new_flags -+ enc_part = self.modify_ticket_flag(enc_part, 'renewable', value=True) - - # Set the renew-till time to be in the future. - renew_till = self.get_KerberosTime(offset=100 * 60 * 60) -@@ -2194,14 +2187,7 @@ class KdcTgsTests(KDCBaseTest): - - def _modify_invalid(self, enc_part): - # Set the invalid flag. -- invalid_flag = krb5_asn1.TicketFlags('invalid') -- pos = len(tuple(invalid_flag)) - 1 -- -- flags = enc_part['flags'] -- self.assertLessEqual(pos, len(flags)) -- -- new_flags = flags[:pos] + '1' + flags[pos + 1:] -- enc_part['flags'] = new_flags -+ enc_part = self.modify_ticket_flag(enc_part, 'invalid', value=True) - - # Set the ticket start time to be in the past. - past_time = self.get_KerberosTime(offset=-100 * 60 * 60) -diff --git a/python/samba/tests/krb5/s4u_tests.py b/python/samba/tests/krb5/s4u_tests.py -index 6ec9af11423..49dd89cd764 100755 ---- a/python/samba/tests/krb5/s4u_tests.py -+++ b/python/samba/tests/krb5/s4u_tests.py -@@ -1336,20 +1336,9 @@ class S4UKerberosTests(KDCBaseTest): - 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 -+ modify_fn = functools.partial(self.modify_ticket_flag, -+ flag='forwardable', -+ value=flag) - - if update_pac_checksums: - checksum_keys = self.get_krbtgt_checksum_key() --- -2.25.1 - - -From 19d76f103100f1a915486eb0bad2264dd203e71e Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Fri, 4 Mar 2022 16:57:27 +1300 -Subject: [PATCH 54/99] selftest: Simplify krb5 test environments - -It's not necessary to repeat the required environment variables for -every test. - -Signed-off-by: Joseph Sutton -Reviewed-by: Andreas Schneider -(cherry picked from commit e729606631b5bfaf7c4ad8c1e70697adf8274777) - -[jsutton@samba.org Fixed conflicts caused by missing check_cname, - check_padata and fast_support variables] ---- - source4/selftest/tests.py | 191 +++++++------------------------------- - 1 file changed, 35 insertions(+), 156 deletions(-) - -diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py -index f2ea9adb67f..dc340623f3e 100755 ---- a/source4/selftest/tests.py -+++ b/source4/selftest/tests.py -@@ -903,106 +903,59 @@ for env in ['fileserver_smb1', 'nt4_member', 'clusteredmember', 'ktest', 'nt4_dc - planoldpythontestsuite(env, "samba.tests.imports") - - have_fast_support = int('SAMBA_USES_MITKDC' in config_hash) -+claims_support = 0 -+compound_id_support = 0 - tkt_sig_support = int('SAMBA4_USES_HEIMDAL' in config_hash) - expect_pac = int('SAMBA4_USES_HEIMDAL' in config_hash) - extra_pac_buffers = int('SAMBA4_USES_HEIMDAL' in config_hash) -+krb5_environ = { -+ 'SERVICE_USERNAME': '$SERVER', -+ 'ADMIN_USERNAME': '$DC_USERNAME', -+ 'ADMIN_PASSWORD': '$DC_PASSWORD', -+ 'FOR_USER': '$DC_USERNAME', -+ 'STRICT_CHECKING':'0', -+ 'FAST_SUPPORT': have_fast_support, -+ 'CLAIMS_SUPPORT': claims_support, -+ 'COMPOUND_ID_SUPPORT': compound_id_support, -+ 'TKT_SIG_SUPPORT': tkt_sig_support, -+ 'EXPECT_PAC': expect_pac, -+ 'EXPECT_EXTRA_PAC_BUFFERS': extra_pac_buffers, -+} - planoldpythontestsuite("none", "samba.tests.krb5.kcrypto") - planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.simple_tests", -- environ={'SERVICE_USERNAME':'$SERVER', -- 'FAST_SUPPORT': have_fast_support, -- 'TKT_SIG_SUPPORT': tkt_sig_support, -- 'EXPECT_PAC': expect_pac, -- 'EXPECT_EXTRA_PAC_BUFFERS': extra_pac_buffers}) -+ environ=krb5_environ) - planoldpythontestsuite("ad_dc_default:local", "samba.tests.krb5.s4u_tests", -- environ={'ADMIN_USERNAME':'$USERNAME', -- 'ADMIN_PASSWORD':'$PASSWORD', -- 'FOR_USER':'$USERNAME', -- 'STRICT_CHECKING':'0', -- 'FAST_SUPPORT': have_fast_support, -- 'TKT_SIG_SUPPORT': tkt_sig_support, -- 'EXPECT_PAC': expect_pac, -- 'EXPECT_EXTRA_PAC_BUFFERS': extra_pac_buffers}) -+ environ=krb5_environ) - 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, -- 'EXPECT_PAC': expect_pac, -- 'EXPECT_EXTRA_PAC_BUFFERS': extra_pac_buffers}) -+ environ=krb5_environ) - - planoldpythontestsuite("ad_dc_default", "samba.tests.dsdb_dns") - - planoldpythontestsuite("fl2008r2dc:local", "samba.tests.krb5.xrealm_tests", -- environ={'FAST_SUPPORT': have_fast_support, -- 'TKT_SIG_SUPPORT': tkt_sig_support, -- 'EXPECT_PAC': expect_pac, -- 'EXPECT_EXTRA_PAC_BUFFERS': extra_pac_buffers}) -+ environ=krb5_environ) - - planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.test_ccache", -- environ={ -- 'ADMIN_USERNAME': '$USERNAME', -- 'ADMIN_PASSWORD': '$PASSWORD', -- 'STRICT_CHECKING': '0', -- 'FAST_SUPPORT': have_fast_support, -- 'TKT_SIG_SUPPORT': tkt_sig_support, -- 'EXPECT_PAC': expect_pac, -- 'EXPECT_EXTRA_PAC_BUFFERS': extra_pac_buffers -- }) -+ environ=krb5_environ) - planoldpythontestsuite("ad_dc_default", "samba.tests.krb5.test_ldap", -- environ={ -- 'ADMIN_USERNAME': '$USERNAME', -- 'ADMIN_PASSWORD': '$PASSWORD', -- 'STRICT_CHECKING': '0', -- 'FAST_SUPPORT': have_fast_support, -- 'TKT_SIG_SUPPORT': tkt_sig_support, -- 'EXPECT_PAC': expect_pac, -- 'EXPECT_EXTRA_PAC_BUFFERS': extra_pac_buffers -- }) -+ environ=krb5_environ) - for env in ['ad_dc_default', 'ad_member']: - planoldpythontestsuite(env, "samba.tests.krb5.test_rpc", -- environ={ -- 'ADMIN_USERNAME': '$DC_USERNAME', -- 'ADMIN_PASSWORD': '$DC_PASSWORD', -- 'STRICT_CHECKING': '0', -- 'FAST_SUPPORT': have_fast_support, -- 'TKT_SIG_SUPPORT': tkt_sig_support, -- 'EXPECT_PAC': expect_pac, -- 'EXPECT_EXTRA_PAC_BUFFERS': extra_pac_buffers -- }) -+ environ=krb5_environ) - planoldpythontestsuite("ad_dc_smb1", "samba.tests.krb5.test_smb", -- environ={ -- 'ADMIN_USERNAME': '$USERNAME', -- 'ADMIN_PASSWORD': '$PASSWORD', -- 'STRICT_CHECKING': '0', -- 'FAST_SUPPORT': have_fast_support, -- 'TKT_SIG_SUPPORT': tkt_sig_support, -- 'EXPECT_PAC': expect_pac, -- 'EXPECT_EXTRA_PAC_BUFFERS': extra_pac_buffers -- }) -+ environ=krb5_environ) - planoldpythontestsuite("ad_member_idmap_nss:local", - "samba.tests.krb5.test_min_domain_uid", -- environ={ -- 'ADMIN_USERNAME': '$DC_USERNAME', -- 'ADMIN_PASSWORD': '$DC_PASSWORD', -- 'STRICT_CHECKING': '0' -- }) -+ environ=krb5_environ) - planoldpythontestsuite("ad_member_idmap_nss:local", - "samba.tests.krb5.test_idmap_nss", - environ={ -- 'ADMIN_USERNAME': '$DC_USERNAME', -- 'ADMIN_PASSWORD': '$DC_PASSWORD', -+ **krb5_environ, - 'MAPPED_USERNAME': 'bob', - 'MAPPED_PASSWORD': 'Secret007', - 'UNMAPPED_USERNAME': 'jane', - 'UNMAPPED_PASSWORD': 'Secret007', - 'INVALID_USERNAME': 'joe', - 'INVALID_PASSWORD': 'Secret007', -- 'STRICT_CHECKING': '0', -- 'FAST_SUPPORT': have_fast_support, -- 'TKT_SIG_SUPPORT': tkt_sig_support, -- 'EXPECT_PAC': expect_pac, -- 'EXPECT_EXTRA_PAC_BUFFERS': extra_pac_buffers - }) - - for env in ["ad_dc", smbv1_disabled_testenv]: -@@ -1591,26 +1544,10 @@ plansmbtorture4testsuite('krb5.kdc', env, ['ncacn_np:$SERVER_IP', "-k", "yes", ' - "samba4.krb5.kdc with account having identical UPN and SPN") - for env in ["fl2008r2dc", "fl2003dc"]: - planoldpythontestsuite(env, "samba.tests.krb5.as_req_tests", -- environ={ -- 'ADMIN_USERNAME': '$USERNAME', -- 'ADMIN_PASSWORD': '$PASSWORD', -- 'STRICT_CHECKING': '0', -- 'FAST_SUPPORT': have_fast_support, -- 'TKT_SIG_SUPPORT': tkt_sig_support, -- 'EXPECT_PAC': expect_pac, -- 'EXPECT_EXTRA_PAC_BUFFERS': extra_pac_buffers -- }) -+ environ=krb5_environ) - - 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, -- 'EXPECT_PAC': expect_pac, -- 'EXPECT_EXTRA_PAC_BUFFERS': extra_pac_buffers -- }) -+ environ=krb5_environ) - - for env in ["rodc", "promoted_dc", "fl2000dc", "fl2008r2dc"]: - if env == "rodc": -@@ -1627,89 +1564,31 @@ for env in ["rodc", "promoted_dc", "fl2000dc", "fl2008r2dc"]: - "samba4.krb5.kdc with machine account") - - planpythontestsuite("ad_dc", "samba.tests.krb5.as_canonicalization_tests", -- environ={ -- 'ADMIN_USERNAME': '$USERNAME', -- 'ADMIN_PASSWORD': '$PASSWORD', -- 'FAST_SUPPORT': have_fast_support, -- 'TKT_SIG_SUPPORT': tkt_sig_support, -- 'EXPECT_PAC': expect_pac, -- 'EXPECT_EXTRA_PAC_BUFFERS': extra_pac_buffers -- }) -+ environ=krb5_environ) - planpythontestsuite("ad_dc", "samba.tests.krb5.compatability_tests", -- environ={ -- 'ADMIN_USERNAME': '$USERNAME', -- 'ADMIN_PASSWORD': '$PASSWORD', -- 'STRICT_CHECKING': '0', -- 'FAST_SUPPORT': have_fast_support, -- 'TKT_SIG_SUPPORT': tkt_sig_support, -- 'EXPECT_PAC': expect_pac, -- 'EXPECT_EXTRA_PAC_BUFFERS': extra_pac_buffers -- }) -+ environ=krb5_environ) - planpythontestsuite("ad_dc", "samba.tests.krb5.kdc_tests", -- environ={'FAST_SUPPORT': have_fast_support, -- 'TKT_SIG_SUPPORT': tkt_sig_support, -- 'EXPECT_PAC': expect_pac, -- 'EXPECT_EXTRA_PAC_BUFFERS': extra_pac_buffers}) -+ environ=krb5_environ) - planpythontestsuite( - "ad_dc", - "samba.tests.krb5.kdc_tgs_tests", -- environ={ -- 'ADMIN_USERNAME': '$USERNAME', -- 'ADMIN_PASSWORD': '$PASSWORD', -- 'STRICT_CHECKING': '0', -- 'FAST_SUPPORT': have_fast_support, -- 'TKT_SIG_SUPPORT': tkt_sig_support, -- 'EXPECT_PAC': expect_pac, -- 'EXPECT_EXTRA_PAC_BUFFERS': extra_pac_buffers -- }) -+ environ=krb5_environ) - planpythontestsuite( - "ad_dc", - "samba.tests.krb5.fast_tests", -- environ={ -- 'ADMIN_USERNAME': '$USERNAME', -- 'ADMIN_PASSWORD': '$PASSWORD', -- 'STRICT_CHECKING': '0', -- 'FAST_SUPPORT': have_fast_support, -- 'TKT_SIG_SUPPORT': tkt_sig_support, -- 'EXPECT_PAC': expect_pac, -- 'EXPECT_EXTRA_PAC_BUFFERS': extra_pac_buffers -- }) -+ environ=krb5_environ) - planpythontestsuite( - "ad_dc", - "samba.tests.krb5.ms_kile_client_principal_lookup_tests", -- environ={ -- 'ADMIN_USERNAME': '$USERNAME', -- 'ADMIN_PASSWORD': '$PASSWORD', -- 'STRICT_CHECKING': '0', -- 'FAST_SUPPORT': have_fast_support, -- 'TKT_SIG_SUPPORT': tkt_sig_support, -- 'EXPECT_PAC': expect_pac, -- 'EXPECT_EXTRA_PAC_BUFFERS': extra_pac_buffers -- }) -+ environ=krb5_environ) - planpythontestsuite( - "ad_dc", - "samba.tests.krb5.spn_tests", -- environ={ -- 'ADMIN_USERNAME': '$USERNAME', -- 'ADMIN_PASSWORD': '$PASSWORD', -- 'STRICT_CHECKING': '0', -- 'FAST_SUPPORT': have_fast_support, -- 'TKT_SIG_SUPPORT': tkt_sig_support, -- 'EXPECT_PAC': expect_pac, -- 'EXPECT_EXTRA_PAC_BUFFERS': extra_pac_buffers -- }) -+ environ=krb5_environ) - planpythontestsuite( - "ad_dc", - "samba.tests.krb5.alias_tests", -- environ={ -- 'ADMIN_USERNAME': '$USERNAME', -- 'ADMIN_PASSWORD': '$PASSWORD', -- 'STRICT_CHECKING': '0', -- 'FAST_SUPPORT': have_fast_support, -- 'TKT_SIG_SUPPORT': tkt_sig_support, -- 'EXPECT_PAC': expect_pac, -- 'EXPECT_EXTRA_PAC_BUFFERS': extra_pac_buffers -- }) -+ environ=krb5_environ) - - for env in [ - 'vampire_dc', --- -2.25.1 - - -From 8f4b78907bbfe915988d52724c66dae0e2eefa9b Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Wed, 15 Jun 2022 19:37:39 +1200 -Subject: [PATCH 55/99] CVE-2022-2031 s4:kdc: Add MIT support for - ATTRIBUTES_INFO and REQUESTER_SID PAC buffers - -So that we do not confuse TGTs and kpasswd tickets, it is critical to -check that the REQUESTER_SID buffer exists in TGTs, and to ensure that -it is not propagated to service tickets. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15047 - -Signed-off-by: Joseph Sutton - -[jsutton@samba.org Brought in changes to add ATTRIBUTES_INFO and - REQUESTER_SID buffers to new PACs, and updated knownfails] ---- - selftest/knownfail_mit_kdc | 17 ----- - source4/kdc/mit-kdb/kdb_samba_policies.c | 5 +- - source4/kdc/mit_samba.c | 93 +++++++++++++++++++++++- - source4/kdc/mit_samba.h | 1 + - 4 files changed, 94 insertions(+), 22 deletions(-) - -diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc -index 6a4ddaa00ec..095da10238c 100644 ---- a/selftest/knownfail_mit_kdc -+++ b/selftest/knownfail_mit_kdc -@@ -423,7 +423,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_fast_sid_mismatch_nonexisting - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_authdata_no_pac - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_no_pac --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_pac_request_none - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_pac_request_true - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_req - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_rodc_allowed_denied -@@ -459,7 +458,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_tgs_authdata_no_pac - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_no_pac - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rename --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_req_no_requester_sid - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_allowed_denied - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_denied - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_no_krbtgt_link -@@ -490,7 +488,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_user2user_wrong_srealm - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_authdata_no_pac - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_no_pac --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_pac_request_none - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_pac_request_true - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_req - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_validate_rodc_allowed_denied -@@ -508,21 +505,17 @@ 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_pac_attrs_false - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_missing_renew_false --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_missing_renew_none - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_missing_renew_true - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_missing_rodc_renew_false - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_missing_rodc_renew_none - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_missing_rodc_renew_true --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_none - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_renew_false --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_renew_none - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_renew_true - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_rodc_renew_false - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_rodc_renew_none - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_rodc_renew_true - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_pac_attrs_true - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_pac_attrs_false --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_pac_attrs_none - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_pac_attrs_true - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_req_from_rodc_no_pac_attrs - # -@@ -537,21 +530,11 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ - # - # PAC requester SID tests - # --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_as_requester_sid --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_logon_info_sid_mismatch_existing --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_logon_info_sid_mismatch_nonexisting --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_requester_sid_mismatch_existing --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_requester_sid_mismatch_nonexisting - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_req_from_rodc_no_requester_sid --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_renew - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_rodc_renew - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_rodc_validate --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_validate --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_renew - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_rodc_renew - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_rodc_validate --^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_validate - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_logon_info_only_sid_mismatch_existing - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_logon_info_only_sid_mismatch_nonexisting - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_logon_info_sid_mismatch_existing -diff --git a/source4/kdc/mit-kdb/kdb_samba_policies.c b/source4/kdc/mit-kdb/kdb_samba_policies.c -index f35210669c2..dada3b79144 100644 ---- a/source4/kdc/mit-kdb/kdb_samba_policies.c -+++ b/source4/kdc/mit-kdb/kdb_samba_policies.c -@@ -162,6 +162,7 @@ done: - - static krb5_error_code ks_get_pac(krb5_context context, - krb5_db_entry *client, -+ krb5_db_entry *server, - krb5_keyblock *client_key, - krb5_pac *pac) - { -@@ -176,6 +177,7 @@ static krb5_error_code ks_get_pac(krb5_context context, - code = mit_samba_get_pac(mit_ctx, - context, - client, -+ server, - client_key, - pac); - if (code != 0) { -@@ -423,7 +425,7 @@ krb5_error_code kdb_samba_db_sign_auth_data(krb5_context context, - */ - if (with_pac && generate_pac) { - DBG_DEBUG("Generate PAC for AS-REQ [%s]\n", client_name); -- code = ks_get_pac(context, client_entry, client_key, &pac); -+ code = ks_get_pac(context, client_entry, server, client_key, &pac); - if (code != 0) { - goto done; - } -@@ -474,6 +476,7 @@ krb5_error_code kdb_samba_db_sign_auth_data(krb5_context context, - - code = ks_get_pac(context, - client_entry, -+ server, - client_key, - &pac); - if (code != 0 && code != ENOENT) { -diff --git a/source4/kdc/mit_samba.c b/source4/kdc/mit_samba.c -index 53c137de2fd..ef4e8c2ed38 100644 ---- a/source4/kdc/mit_samba.c -+++ b/source4/kdc/mit_samba.c -@@ -433,6 +433,7 @@ int mit_samba_get_nextkey(struct mit_samba_context *ctx, - int mit_samba_get_pac(struct mit_samba_context *smb_ctx, - krb5_context context, - krb5_db_entry *client, -+ krb5_db_entry *server, - krb5_keyblock *client_key, - krb5_pac *pac) - { -@@ -443,9 +444,12 @@ int mit_samba_get_pac(struct mit_samba_context *smb_ctx, - DATA_BLOB **cred_ndr_ptr = NULL; - DATA_BLOB cred_blob = data_blob_null; - DATA_BLOB *pcred_blob = NULL; -+ DATA_BLOB *pac_attrs_blob = NULL; -+ DATA_BLOB *requester_sid_blob = NULL; - NTSTATUS nt_status; - krb5_error_code code; - struct samba_kdc_entry *skdc_entry; -+ bool is_krbtgt; - - skdc_entry = talloc_get_type_abort(client->e_data, - struct samba_kdc_entry); -@@ -464,12 +468,16 @@ int mit_samba_get_pac(struct mit_samba_context *smb_ctx, - } - #endif - -+ is_krbtgt = ks_is_tgs_principal(smb_ctx, server->princ); -+ - nt_status = samba_kdc_get_pac_blobs(tmp_ctx, - skdc_entry, - &logon_info_blob, - cred_ndr_ptr, - &upn_dns_info_blob, -- NULL, NULL, NULL, -+ is_krbtgt ? &pac_attrs_blob : NULL, -+ NULL, -+ is_krbtgt ? &requester_sid_blob : NULL, - NULL); - if (!NT_STATUS_IS_OK(nt_status)) { - talloc_free(tmp_ctx); -@@ -497,8 +505,8 @@ int mit_samba_get_pac(struct mit_samba_context *smb_ctx, - logon_info_blob, - pcred_blob, - upn_dns_info_blob, -- NULL, -- NULL, -+ pac_attrs_blob, -+ requester_sid_blob, - NULL, - pac); - -@@ -522,6 +530,7 @@ krb5_error_code mit_samba_reget_pac(struct mit_samba_context *ctx, - DATA_BLOB *pac_blob = NULL; - DATA_BLOB *upn_blob = NULL; - DATA_BLOB *deleg_blob = NULL; -+ DATA_BLOB *requester_sid_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; -@@ -537,8 +546,12 @@ krb5_error_code mit_samba_reget_pac(struct mit_samba_context *ctx, - 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; -+ ssize_t attrs_info_idx = -1; -+ ssize_t requester_sid_idx = -1; - krb5_pac new_pac = NULL; - bool ok; -+ bool is_krbtgt; - - /* Create a memory context early so code can use talloc_stackframe() */ - tmp_ctx = talloc_named(ctx, 0, "mit_samba_reget_pac context"); -@@ -546,6 +559,8 @@ krb5_error_code mit_samba_reget_pac(struct mit_samba_context *ctx, - return ENOMEM; - } - -+ is_krbtgt = ks_is_tgs_principal(ctx, server->princ); -+ - if (client != NULL) { - client_skdc_entry = - talloc_get_type_abort(client->e_data, -@@ -604,7 +619,7 @@ krb5_error_code mit_samba_reget_pac(struct mit_samba_context *ctx, - NULL, - &upn_blob, - NULL, NULL, -- NULL, -+ &requester_sid_blob, - NULL); - if (!NT_STATUS_IS_OK(nt_status)) { - code = EINVAL; -@@ -763,6 +778,45 @@ krb5_error_code mit_samba_reget_pac(struct mit_samba_context *ctx, - } - kdc_checksum_idx = i; - break; -+ case PAC_TYPE_TICKET_CHECKSUM: -+ if (tkt_checksum_idx != -1) { -+ DBG_WARNING("ticket checksum type[%u] twice " -+ "[%zd] and [%zu]: \n", -+ types[i], -+ tkt_checksum_idx, -+ i); -+ SAFE_FREE(types); -+ code = EINVAL; -+ goto done; -+ } -+ tkt_checksum_idx = i; -+ break; -+ case PAC_TYPE_ATTRIBUTES_INFO: -+ if (attrs_info_idx != -1) { -+ DBG_WARNING("attributes info type[%u] twice " -+ "[%zd] and [%zu]: \n", -+ types[i], -+ attrs_info_idx, -+ i); -+ SAFE_FREE(types); -+ code = EINVAL; -+ goto done; -+ } -+ attrs_info_idx = i; -+ break; -+ case PAC_TYPE_REQUESTER_SID: -+ if (requester_sid_idx != -1) { -+ DBG_WARNING("requester sid type[%u] twice" -+ "[%zd] and [%zu]: \n", -+ types[i], -+ requester_sid_idx, -+ i); -+ SAFE_FREE(types); -+ code = EINVAL; -+ goto done; -+ } -+ requester_sid_idx = i; -+ break; - default: - continue; - } -@@ -792,6 +846,13 @@ krb5_error_code mit_samba_reget_pac(struct mit_samba_context *ctx, - code = EINVAL; - goto done; - } -+ if (!(flags & KRB5_KDB_FLAG_CONSTRAINED_DELEGATION) && -+ requester_sid_idx == -1) { -+ DEBUG(1, ("PAC_TYPE_REQUESTER_SID missing\n")); -+ SAFE_FREE(types); -+ code = KRB5KDC_ERR_TGT_REVOKED; -+ goto done; -+ } - - /* Build an updated PAC */ - code = krb5_pac_init(context, &new_pac); -@@ -857,6 +918,10 @@ krb5_error_code mit_samba_reget_pac(struct mit_samba_context *ctx, - } - break; - case PAC_TYPE_SRV_CHECKSUM: -+ if (requester_sid_idx == -1 && requester_sid_blob != NULL) { -+ /* inject REQUESTER_SID */ -+ forced_next_type = PAC_TYPE_REQUESTER_SID; -+ } - /* - * This is generated in the main KDC code - */ -@@ -866,6 +931,26 @@ krb5_error_code mit_samba_reget_pac(struct mit_samba_context *ctx, - * This is generated in the main KDC code - */ - continue; -+ case PAC_TYPE_ATTRIBUTES_INFO: -+ if (!is_untrusted && is_krbtgt) { -+ /* just copy... */ -+ break; -+ } -+ -+ continue; -+ case PAC_TYPE_REQUESTER_SID: -+ if (!is_krbtgt) { -+ continue; -+ } -+ -+ /* -+ * Replace in the RODC case, otherwise -+ * requester_sid_blob is NULL and we just copy. -+ */ -+ if (requester_sid_blob != NULL) { -+ type_blob = *requester_sid_blob; -+ } -+ break; - default: - /* just copy... */ - break; -diff --git a/source4/kdc/mit_samba.h b/source4/kdc/mit_samba.h -index 636c77ec97c..4431e82a1b2 100644 ---- a/source4/kdc/mit_samba.h -+++ b/source4/kdc/mit_samba.h -@@ -50,6 +50,7 @@ int mit_samba_get_nextkey(struct mit_samba_context *ctx, - int mit_samba_get_pac(struct mit_samba_context *smb_ctx, - krb5_context context, - krb5_db_entry *client, -+ krb5_db_entry *server, - krb5_keyblock *client_key, - krb5_pac *pac); - --- -2.25.1 - - -From 6199a0763507ae96aad8d6b6dff50245d505404d Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Thu, 16 Jun 2022 10:33:29 +1200 -Subject: [PATCH 56/99] heimdal:kdc: Accommodate NULL data parameter in - krb5_pac_get_buffer() - -Signed-off-by: Joseph Sutton ---- - source4/heimdal/lib/krb5/pac.c | 10 ++++++---- - 1 file changed, 6 insertions(+), 4 deletions(-) - -diff --git a/source4/heimdal/lib/krb5/pac.c b/source4/heimdal/lib/krb5/pac.c -index 05bcc523080..100de904662 100644 ---- a/source4/heimdal/lib/krb5/pac.c -+++ b/source4/heimdal/lib/krb5/pac.c -@@ -394,10 +394,12 @@ krb5_pac_get_buffer(krb5_context context, krb5_pac p, - if (p->pac->buffers[i].type != type) - continue; - -- ret = krb5_data_copy(data, (unsigned char *)p->data.data + offset, len); -- if (ret) { -- krb5_set_error_message(context, ret, N_("malloc: out of memory", "")); -- return ret; -+ if (data) { -+ ret = krb5_data_copy(data, (unsigned char *)p->data.data + offset, len); -+ if (ret) { -+ krb5_set_error_message(context, ret, N_("malloc: out of memory", "")); -+ return ret; -+ } - } - return 0; - } --- -2.25.1 - - -From b0d3fd37a8884cf18f9c2bffc416035747d49977 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Fri, 27 May 2022 19:17:02 +1200 -Subject: [PATCH 57/99] CVE-2022-2031 s4:kpasswd: Account for missing target - principal - -This field is supposed to be optional. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15047 -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15049 -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15074 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andreas Schneider ---- - source4/kdc/kpasswd-service-mit.c | 22 ++++++++++++---------- - 1 file changed, 12 insertions(+), 10 deletions(-) - -diff --git a/source4/kdc/kpasswd-service-mit.c b/source4/kdc/kpasswd-service-mit.c -index 2117c1c1696..b53c1a4618a 100644 ---- a/source4/kdc/kpasswd-service-mit.c -+++ b/source4/kdc/kpasswd-service-mit.c -@@ -143,16 +143,18 @@ static krb5_error_code kpasswd_set_password(struct kdc_server *kdc, - return KRB5_KPASSWD_HARDERROR; - } - -- target_realm = smb_krb5_principal_get_realm( -- mem_ctx, context, target_principal); -- code = krb5_unparse_name_flags(context, -- target_principal, -- KRB5_PRINCIPAL_UNPARSE_NO_REALM, -- &target_name); -- if (code != 0) { -- DBG_WARNING("Failed to parse principal\n"); -- *error_string = "String conversion failed"; -- return KRB5_KPASSWD_HARDERROR; -+ if (target_principal != NULL) { -+ target_realm = smb_krb5_principal_get_realm( -+ mem_ctx, context, target_principal); -+ code = krb5_unparse_name_flags(context, -+ target_principal, -+ KRB5_PRINCIPAL_UNPARSE_NO_REALM, -+ &target_name); -+ if (code != 0) { -+ DBG_WARNING("Failed to parse principal\n"); -+ *error_string = "String conversion failed"; -+ return KRB5_KPASSWD_HARDERROR; -+ } - } - - if ((target_name != NULL && target_realm == NULL) || --- -2.25.1 - - -From e21702d20b6d4507708791c5a6a674b8bdadaab0 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Mon, 30 May 2022 19:17:41 +1200 -Subject: [PATCH 58/99] CVE-2022-2031 s4:kpasswd: Add MIT fallback for decoding - setpw structure - -The target principal and realm fields of the setpw structure are -supposed to be optional, but in MIT Kerberos they are mandatory. For -better compatibility and ease of testing, fall back to parsing the -simpler (containing only the new password) structure if the MIT function -fails to decode it. - -Although the target principal and realm fields should be optional, one -is not supposed to specified without the other, so we don't have to deal -with the case where only one is specified. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15047 -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15049 -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15074 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andreas Schneider ---- - source4/kdc/kpasswd-service-mit.c | 94 ++++++++++++++++++++++++++----- - 1 file changed, 79 insertions(+), 15 deletions(-) - -diff --git a/source4/kdc/kpasswd-service-mit.c b/source4/kdc/kpasswd-service-mit.c -index b53c1a4618a..9c4d2801669 100644 ---- a/source4/kdc/kpasswd-service-mit.c -+++ b/source4/kdc/kpasswd-service-mit.c -@@ -28,6 +28,7 @@ - #include "kdc/kpasswd_glue.h" - #include "kdc/kpasswd-service.h" - #include "kdc/kpasswd-helper.h" -+#include "../lib/util/asn1.h" - - #define RFC3244_VERSION 0xff80 - -@@ -35,6 +36,52 @@ krb5_error_code decode_krb5_setpw_req(const krb5_data *code, - krb5_data **password_out, - krb5_principal *target_out); - -+/* -+ * A fallback for when MIT refuses to parse a setpw structure without the -+ * (optional) target principal and realm -+ */ -+static bool decode_krb5_setpw_req_simple(TALLOC_CTX *mem_ctx, -+ const DATA_BLOB *decoded_data, -+ DATA_BLOB *clear_data) -+{ -+ struct asn1_data *asn1 = NULL; -+ bool ret; -+ -+ asn1 = asn1_init(mem_ctx, 3); -+ if (asn1 == NULL) { -+ return false; -+ } -+ -+ ret = asn1_load(asn1, *decoded_data); -+ if (!ret) { -+ goto out; -+ } -+ -+ ret = asn1_start_tag(asn1, ASN1_SEQUENCE(0)); -+ if (!ret) { -+ goto out; -+ } -+ ret = asn1_start_tag(asn1, ASN1_CONTEXT(0)); -+ if (!ret) { -+ goto out; -+ } -+ ret = asn1_read_OctetString(asn1, mem_ctx, clear_data); -+ if (!ret) { -+ goto out; -+ } -+ -+ ret = asn1_end_tag(asn1); -+ if (!ret) { -+ goto out; -+ } -+ ret = asn1_end_tag(asn1); -+ -+out: -+ asn1_free(asn1); -+ -+ return ret; -+} -+ - static krb5_error_code kpasswd_change_password(struct kdc_server *kdc, - TALLOC_CTX *mem_ctx, - struct auth_session_info *session_info, -@@ -93,9 +140,10 @@ static krb5_error_code kpasswd_set_password(struct kdc_server *kdc, - const char **error_string) - { - krb5_context context = kdc->smb_krb5_context->krb5_context; -+ DATA_BLOB clear_data; - krb5_data k_dec_data; -- krb5_data *k_clear_data; -- krb5_principal target_principal; -+ krb5_data *k_clear_data = NULL; -+ krb5_principal target_principal = NULL; - krb5_error_code code; - DATA_BLOB password; - char *target_realm = NULL; -@@ -114,29 +162,45 @@ static krb5_error_code kpasswd_set_password(struct kdc_server *kdc, - code = decode_krb5_setpw_req(&k_dec_data, - &k_clear_data, - &target_principal); -- if (code != 0) { -- DBG_WARNING("decode_krb5_setpw_req failed: %s\n", -- error_message(code)); -- ok = kpasswd_make_error_reply(mem_ctx, -- KRB5_KPASSWD_MALFORMED, -- "Failed to decode packet", -- kpasswd_reply); -+ if (code == 0) { -+ clear_data.data = (uint8_t *)k_clear_data->data; -+ clear_data.length = k_clear_data->length; -+ } else { -+ target_principal = NULL; -+ -+ /* -+ * The MIT decode failed, so fall back to trying the simple -+ * case, without target_principal. -+ */ -+ ok = decode_krb5_setpw_req_simple(mem_ctx, -+ decoded_data, -+ &clear_data); - if (!ok) { -- *error_string = "Failed to create reply"; -- return KRB5_KPASSWD_HARDERROR; -+ DBG_WARNING("decode_krb5_setpw_req failed: %s\n", -+ error_message(code)); -+ ok = kpasswd_make_error_reply(mem_ctx, -+ KRB5_KPASSWD_MALFORMED, -+ "Failed to decode packet", -+ kpasswd_reply); -+ if (!ok) { -+ *error_string = "Failed to create reply"; -+ return KRB5_KPASSWD_HARDERROR; -+ } -+ return 0; - } -- return 0; - } - - ok = convert_string_talloc_handle(mem_ctx, - lpcfg_iconv_handle(kdc->task->lp_ctx), - CH_UTF8, - CH_UTF16, -- (const char *)k_clear_data->data, -- k_clear_data->length, -+ clear_data.data, -+ clear_data.length, - (void **)&password.data, - &password.length); -- krb5_free_data(context, k_clear_data); -+ if (k_clear_data != NULL) { -+ krb5_free_data(context, k_clear_data); -+ } - if (!ok) { - DBG_WARNING("String conversion failed\n"); - *error_string = "String conversion failed"; --- -2.25.1 - - -From f4ea2a80d8440c4c7261229bd9285bce97226094 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Thu, 26 May 2022 16:34:01 +1200 -Subject: [PATCH 59/99] CVE-2022-32744 tests/krb5: Correctly handle specifying - account kvno - -The environment variable is a string, but we expect an integer. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15074 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andreas Schneider ---- - 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 a2241707d44..4120edf93b9 100644 ---- a/python/samba/tests/krb5/raw_testcase.py -+++ b/python/samba/tests/krb5/raw_testcase.py -@@ -724,7 +724,7 @@ class RawKerberosTest(TestCaseInTempDir): - fallback_default=False, - allow_missing=kvno_allow_missing) - if kvno is not None: -- c.set_kvno(kvno) -+ c.set_kvno(int(kvno)) - aes256_key = self.env_get_var('AES256_KEY_HEX', prefix, - fallback_default=False, - allow_missing=aes256_allow_missing) --- -2.25.1 - - -From 440aa37cc462ac9a230636e6758152c3a520fed4 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Thu, 26 May 2022 20:52:04 +1200 -Subject: [PATCH 60/99] CVE-2022-2031 tests/krb5: Split out _make_tgs_request() - -This allows us to make use of it in other tests. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15047 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andreas Schneider - -[jsutton@samba.org Fixed conflicts due to having older version of - _make_tgs_request()] ---- - python/samba/tests/krb5/kdc_base_test.py | 77 ++++++++++++++++++++++++ - python/samba/tests/krb5/kdc_tgs_tests.py | 76 ----------------------- - 2 files changed, 77 insertions(+), 76 deletions(-) - -diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py -index 58b87eab25b..2117663b26b 100644 ---- a/python/samba/tests/krb5/kdc_base_test.py -+++ b/python/samba/tests/krb5/kdc_base_test.py -@@ -67,6 +67,7 @@ from samba.tests.krb5.rfc4120_constants import ( - AES256_CTS_HMAC_SHA1_96, - ARCFOUR_HMAC_MD5, - KDC_ERR_PREAUTH_REQUIRED, -+ KDC_ERR_TGT_REVOKED, - KRB_AS_REP, - KRB_TGS_REP, - KRB_ERROR, -@@ -1538,6 +1539,82 @@ class KDCBaseTest(RawKerberosTest): - - return ticket_creds - -+ def _make_tgs_request(self, client_creds, service_creds, tgt, -+ pac_request=None, expect_pac=True, -+ expect_error=False, -+ expected_account_name=None, -+ expected_upn_name=None, -+ expected_sid=None): -+ 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) -+ -+ if expect_error: -+ expected_error_mode = KDC_ERR_TGT_REVOKED -+ check_error_fn = self.generic_check_kdc_error -+ check_rep_fn = None -+ else: -+ expected_error_mode = 0 -+ check_error_fn = None -+ check_rep_fn = self.generic_check_kdc_rep -+ -+ kdc_exchange_dict = self.tgs_exchange_dict( -+ expected_crealm=expected_crealm, -+ expected_cname=expected_cname, -+ expected_srealm=expected_srealm, -+ expected_sname=expected_sname, -+ expected_account_name=expected_account_name, -+ expected_upn_name=expected_upn_name, -+ expected_sid=expected_sid, -+ expected_supported_etypes=expected_supported_etypes, -+ ticket_decryption_key=target_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, -+ tgt=tgt, -+ authenticator_subkey=authenticator_subkey, -+ kdc_options=kdc_options, -+ pac_request=pac_request, -+ expect_pac=expect_pac, -+ expect_edata=False) -+ -+ rep = self._generic_kdc_exchange(kdc_exchange_dict, -+ cname=cname, -+ realm=realm, -+ sname=sname, -+ etypes=etypes) -+ if expect_error: -+ self.check_error_rep(rep, expected_error_mode) -+ -+ return None -+ else: -+ self.check_reply(rep, KRB_TGS_REP) -+ -+ return kdc_exchange_dict['rep_ticket_creds'] -+ - # Named tuple to contain values of interest when the PAC is decoded. - PacData = namedtuple( - "PacData", -diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py -index 8cd27dec2aa..e52f46152fa 100755 ---- a/python/samba/tests/krb5/kdc_tgs_tests.py -+++ b/python/samba/tests/krb5/kdc_tgs_tests.py -@@ -230,82 +230,6 @@ class KdcTgsTests(KDCBaseTest): - pac_data.account_sid, - "rep = {%s},%s" % (rep, pac_data)) - -- def _make_tgs_request(self, client_creds, service_creds, tgt, -- pac_request=None, expect_pac=True, -- expect_error=False, -- expected_account_name=None, -- expected_upn_name=None, -- expected_sid=None): -- 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) -- -- if expect_error: -- expected_error_mode = KDC_ERR_TGT_REVOKED -- check_error_fn = self.generic_check_kdc_error -- check_rep_fn = None -- else: -- expected_error_mode = 0 -- check_error_fn = None -- check_rep_fn = self.generic_check_kdc_rep -- -- kdc_exchange_dict = self.tgs_exchange_dict( -- expected_crealm=expected_crealm, -- expected_cname=expected_cname, -- expected_srealm=expected_srealm, -- expected_sname=expected_sname, -- expected_account_name=expected_account_name, -- expected_upn_name=expected_upn_name, -- expected_sid=expected_sid, -- expected_supported_etypes=expected_supported_etypes, -- ticket_decryption_key=target_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, -- tgt=tgt, -- authenticator_subkey=authenticator_subkey, -- kdc_options=kdc_options, -- pac_request=pac_request, -- expect_pac=expect_pac, -- expect_edata=False) -- -- rep = self._generic_kdc_exchange(kdc_exchange_dict, -- cname=cname, -- realm=realm, -- sname=sname, -- etypes=etypes) -- if expect_error: -- self.check_error_rep(rep, expected_error_mode) -- -- return None -- else: -- self.check_reply(rep, KRB_TGS_REP) -- -- return kdc_exchange_dict['rep_ticket_creds'] -- - def test_request(self): - client_creds = self.get_client_creds() - service_creds = self.get_service_creds() --- -2.25.1 - - -From efb69ab420f2c5a3074fff6192fbc9a1cd387870 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Tue, 24 May 2022 19:06:53 +1200 -Subject: [PATCH 61/99] CVE-2022-32744 tests/krb5: Correctly calculate salt for - pre-existing accounts - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15074 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andreas Schneider ---- - python/samba/tests/krb5/kdc_base_test.py | 1 + - python/samba/tests/krb5/raw_testcase.py | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py -index 2117663b26b..685a6f71f88 100644 ---- a/python/samba/tests/krb5/kdc_base_test.py -+++ b/python/samba/tests/krb5/kdc_base_test.py -@@ -1048,6 +1048,7 @@ class KDCBaseTest(RawKerberosTest): - - kvno = int(res[0]['msDS-KeyVersionNumber'][0]) - creds.set_kvno(kvno) -+ creds.set_workstation(username[:-1]) - creds.set_dn(dn) - - keys = self.get_keys(samdb, dn) -diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py -index 4120edf93b9..a9a98c36cbf 100644 ---- a/python/samba/tests/krb5/raw_testcase.py -+++ b/python/samba/tests/krb5/raw_testcase.py -@@ -834,6 +834,7 @@ class RawKerberosTest(TestCaseInTempDir): - allow_missing_password=allow_missing_password, - allow_missing_keys=allow_missing_keys) - c.set_gensec_features(c.get_gensec_features() | FEATURE_SEAL) -+ c.set_workstation('') - return c - - def get_rodc_krbtgt_creds(self, --- -2.25.1 - - -From 3bbb7bc57f0de9dfe8fa979b7e122cafc4f9c139 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Tue, 24 May 2022 19:13:54 +1200 -Subject: [PATCH 62/99] CVE-2022-2031 tests/krb5: Add new definitions for - kpasswd - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15047 -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15049 -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15074 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andreas Schneider ---- - python/samba/tests/krb5/rfc4120.asn1 | 6 ++++++ - python/samba/tests/krb5/rfc4120_constants.py | 13 +++++++++++++ - python/samba/tests/krb5/rfc4120_pyasn1.py | 13 ++++++++++++- - 3 files changed, 31 insertions(+), 1 deletion(-) - -diff --git a/python/samba/tests/krb5/rfc4120.asn1 b/python/samba/tests/krb5/rfc4120.asn1 -index e0831e1f86f..cac884be985 100644 ---- a/python/samba/tests/krb5/rfc4120.asn1 -+++ b/python/samba/tests/krb5/rfc4120.asn1 -@@ -567,6 +567,12 @@ PA-FX-FAST-REPLY ::= CHOICE { - ... - } - -+ChangePasswdDataMS ::= SEQUENCE { -+ newpasswd [0] OCTET STRING, -+ targname [1] PrincipalName OPTIONAL, -+ targrealm [2] Realm OPTIONAL -+} -+ - -- MS-KILE End - -- - -- -diff --git a/python/samba/tests/krb5/rfc4120_constants.py b/python/samba/tests/krb5/rfc4120_constants.py -index a9fdc5735dd..7f0f44500c7 100644 ---- a/python/samba/tests/krb5/rfc4120_constants.py -+++ b/python/samba/tests/krb5/rfc4120_constants.py -@@ -27,11 +27,13 @@ ARCFOUR_HMAC_MD5 = int( - - # Message types - KRB_ERROR = int(krb5_asn1.MessageTypeValues('krb-error')) -+KRB_AP_REP = int(krb5_asn1.MessageTypeValues('krb-ap-rep')) - KRB_AP_REQ = int(krb5_asn1.MessageTypeValues('krb-ap-req')) - KRB_AS_REP = int(krb5_asn1.MessageTypeValues('krb-as-rep')) - KRB_AS_REQ = int(krb5_asn1.MessageTypeValues('krb-as-req')) - KRB_TGS_REP = int(krb5_asn1.MessageTypeValues('krb-tgs-rep')) - KRB_TGS_REQ = int(krb5_asn1.MessageTypeValues('krb-tgs-req')) -+KRB_PRIV = int(krb5_asn1.MessageTypeValues('krb-priv')) - - # PAData types - PADATA_ENC_TIMESTAMP = int( -@@ -76,6 +78,7 @@ KDC_ERR_TGT_REVOKED = 20 - KDC_ERR_PREAUTH_FAILED = 24 - KDC_ERR_PREAUTH_REQUIRED = 25 - KDC_ERR_BAD_INTEGRITY = 31 -+KDC_ERR_TKT_EXPIRED = 32 - KRB_ERR_TKT_NYV = 33 - KDC_ERR_NOT_US = 35 - KDC_ERR_BADMATCH = 36 -@@ -87,6 +90,16 @@ KDC_ERR_WRONG_REALM = 68 - KDC_ERR_CLIENT_NAME_MISMATCH = 75 - KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTIONS = 93 - -+# Kpasswd error codes -+KPASSWD_SUCCESS = 0 -+KPASSWD_MALFORMED = 1 -+KPASSWD_HARDERROR = 2 -+KPASSWD_AUTHERROR = 3 -+KPASSWD_SOFTERROR = 4 -+KPASSWD_ACCESSDENIED = 5 -+KPASSWD_BAD_VERSION = 6 -+KPASSWD_INITIAL_FLAG_NEEDED = 7 -+ - # Extended error types - KERB_AP_ERR_TYPE_SKEW_RECOVERY = int( - krb5_asn1.KerbErrorDataTypeValues('kERB-AP-ERR-TYPE-SKEW-RECOVERY')) -diff --git a/python/samba/tests/krb5/rfc4120_pyasn1.py b/python/samba/tests/krb5/rfc4120_pyasn1.py -index 348dd8c63fb..3c02b0efbc1 100644 ---- a/python/samba/tests/krb5/rfc4120_pyasn1.py -+++ b/python/samba/tests/krb5/rfc4120_pyasn1.py -@@ -1,5 +1,5 @@ - # Auto-generated by asn1ate v.0.6.1.dev0 from rfc4120.asn1 --# (last modified on 2021-06-25 12:10:34.484667) -+# (last modified on 2022-05-13 20:03:06.039817) - - # KerberosV5Spec2 - from pyasn1.type import univ, char, namedtype, namedval, tag, constraint, useful -@@ -364,6 +364,17 @@ Authenticator.componentType = namedtype.NamedTypes( - ) - - -+class ChangePasswdDataMS(univ.Sequence): -+ pass -+ -+ -+ChangePasswdDataMS.componentType = namedtype.NamedTypes( -+ namedtype.NamedType('newpasswd', univ.OctetString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), -+ namedtype.OptionalNamedType('targname', PrincipalName().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1))), -+ namedtype.OptionalNamedType('targrealm', Realm().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))) -+) -+ -+ - class ChecksumTypeValues(univ.Integer): - pass - --- -2.25.1 - - -From 39db18962f5368957293cf678e4e7249a8b81ca8 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Tue, 24 May 2022 19:17:45 +1200 -Subject: [PATCH 63/99] CVE-2022-2031 tests/krb5: Add methods to create ASN1 - kpasswd structures - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15047 -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15049 -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15074 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andreas Schneider ---- - python/samba/tests/krb5/raw_testcase.py | 95 +++++++++++++++++++++++++ - 1 file changed, 95 insertions(+) - -diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py -index a9a98c36cbf..df41dff688d 100644 ---- a/python/samba/tests/krb5/raw_testcase.py -+++ b/python/samba/tests/krb5/raw_testcase.py -@@ -54,6 +54,7 @@ from samba.tests.krb5.rfc4120_constants import ( - KRB_AS_REP, - KRB_AS_REQ, - KRB_ERROR, -+ KRB_PRIV, - KRB_TGS_REP, - KRB_TGS_REQ, - KU_AP_REQ_AUTH, -@@ -63,6 +64,7 @@ from samba.tests.krb5.rfc4120_constants import ( - KU_FAST_FINISHED, - KU_FAST_REP, - KU_FAST_REQ_CHKSUM, -+ KU_KRB_PRIV, - KU_NON_KERB_CKSUM_SALT, - KU_TGS_REP_ENC_PART_SESSION, - KU_TGS_REP_ENC_PART_SUB_KEY, -@@ -1780,6 +1782,99 @@ class RawKerberosTest(TestCaseInTempDir): - PA_S4U2Self_obj, asn1Spec=krb5_asn1.PA_S4U2Self()) - return self.PA_DATA_create(PADATA_FOR_USER, pa_s4u2self) - -+ def ChangePasswdDataMS_create(self, -+ new_password, -+ target_princ=None, -+ target_realm=None): -+ ChangePasswdDataMS_obj = { -+ 'newpasswd': new_password, -+ } -+ if target_princ is not None: -+ ChangePasswdDataMS_obj['targname'] = target_princ -+ if target_realm is not None: -+ ChangePasswdDataMS_obj['targrealm'] = target_realm -+ -+ change_password_data = self.der_encode( -+ ChangePasswdDataMS_obj, asn1Spec=krb5_asn1.ChangePasswdDataMS()) -+ -+ return change_password_data -+ -+ def KRB_PRIV_create(self, -+ subkey, -+ user_data, -+ s_address, -+ timestamp=None, -+ usec=None, -+ seq_number=None, -+ r_address=None): -+ EncKrbPrivPart_obj = { -+ 'user-data': user_data, -+ 's-address': s_address, -+ } -+ if timestamp is not None: -+ EncKrbPrivPart_obj['timestamp'] = timestamp -+ if usec is not None: -+ EncKrbPrivPart_obj['usec'] = usec -+ if seq_number is not None: -+ EncKrbPrivPart_obj['seq-number'] = seq_number -+ if r_address is not None: -+ EncKrbPrivPart_obj['r-address'] = r_address -+ -+ enc_krb_priv_part = self.der_encode( -+ EncKrbPrivPart_obj, asn1Spec=krb5_asn1.EncKrbPrivPart()) -+ -+ enc_data = self.EncryptedData_create(subkey, -+ KU_KRB_PRIV, -+ enc_krb_priv_part) -+ -+ KRB_PRIV_obj = { -+ 'pvno': 5, -+ 'msg-type': KRB_PRIV, -+ 'enc-part': enc_data, -+ } -+ -+ krb_priv = self.der_encode( -+ KRB_PRIV_obj, asn1Spec=krb5_asn1.KRB_PRIV()) -+ -+ return krb_priv -+ -+ def kpasswd_create(self, -+ subkey, -+ user_data, -+ version, -+ seq_number, -+ ap_req, -+ local_address, -+ remote_address): -+ self.assertIsNotNone(self.s, 'call self.connect() first') -+ -+ timestamp, usec = self.get_KerberosTimeWithUsec() -+ -+ krb_priv = self.KRB_PRIV_create(subkey, -+ user_data, -+ s_address=local_address, -+ timestamp=timestamp, -+ usec=usec, -+ seq_number=seq_number, -+ r_address=remote_address) -+ -+ size = 6 + len(ap_req) + len(krb_priv) -+ self.assertLess(size, 0x10000) -+ -+ msg = bytearray() -+ msg.append(size >> 8) -+ msg.append(size & 0xff) -+ msg.append(version >> 8) -+ msg.append(version & 0xff) -+ msg.append(len(ap_req) >> 8) -+ msg.append(len(ap_req) & 0xff) -+ # Note: for sets, there could be a little-endian four-byte length here. -+ -+ msg.extend(ap_req) -+ msg.extend(krb_priv) -+ -+ return msg -+ - def _generic_kdc_exchange(self, - kdc_exchange_dict, # required - cname=None, # optional --- -2.25.1 - - -From 3852adddff6df4d9f6f4cc1add11b06c272d29ef Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Tue, 24 May 2022 19:21:37 +1200 -Subject: [PATCH 64/99] CVE-2022-2031 tests/krb5: Add 'port' parameter to - connect() - -This allows us to use the kpasswd port, 464. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15047 -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15049 -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15074 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andreas Schneider ---- - 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 df41dff688d..421143781ae 100644 ---- a/python/samba/tests/krb5/raw_testcase.py -+++ b/python/samba/tests/krb5/raw_testcase.py -@@ -638,10 +638,11 @@ class RawKerberosTest(TestCaseInTempDir): - if self.do_hexdump: - sys.stderr.write("disconnect[%s]\n" % reason) - -- def _connect_tcp(self, host): -- tcp_port = 88 -+ def _connect_tcp(self, host, port=None): -+ if port is None: -+ port = 88 - try: -- self.a = socket.getaddrinfo(host, tcp_port, socket.AF_UNSPEC, -+ self.a = socket.getaddrinfo(host, 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]) -@@ -654,9 +655,9 @@ class RawKerberosTest(TestCaseInTempDir): - self.s.close() - raise - -- def connect(self, host): -+ def connect(self, host, port=None): - self.assertNotConnected() -- self._connect_tcp(host) -+ self._connect_tcp(host, port) - if self.do_hexdump: - sys.stderr.write("connected[%s]\n" % host) - --- -2.25.1 - - -From b9e880b3d9cf5666947cae60adc0846385b04f54 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Tue, 24 May 2022 19:20:28 +1200 -Subject: [PATCH 65/99] CVE-2022-2031 tests/krb5: Add methods to send and - receive generic messages - -This allows us to send and receive kpasswd messages, while avoiding the -existing logic for encoding and decoding other Kerberos message types. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15047 -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15049 -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15074 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andreas Schneider ---- - python/samba/tests/krb5/raw_testcase.py | 44 +++++++++++++++---------- - 1 file changed, 27 insertions(+), 17 deletions(-) - -diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py -index 421143781ae..2aed5530455 100644 ---- a/python/samba/tests/krb5/raw_testcase.py -+++ b/python/samba/tests/krb5/raw_testcase.py -@@ -920,24 +920,28 @@ class RawKerberosTest(TestCaseInTempDir): - return blob - - def send_pdu(self, req, asn1_print=None, hexdump=None): -+ k5_pdu = self.der_encode( -+ req, native_decode=False, asn1_print=asn1_print, hexdump=False) -+ self.send_msg(k5_pdu, hexdump=hexdump) -+ -+ def send_msg(self, msg, hexdump=None): -+ header = struct.pack('>I', len(msg)) -+ req_pdu = header -+ req_pdu += msg -+ self.hex_dump("send_msg", header, hexdump=hexdump) -+ self.hex_dump("send_msg", msg, hexdump=hexdump) -+ - try: -- k5_pdu = self.der_encode( -- req, native_decode=False, asn1_print=asn1_print, hexdump=False) -- header = struct.pack('>I', len(k5_pdu)) -- req_pdu = header -- req_pdu += k5_pdu -- self.hex_dump("send_pdu", header, hexdump=hexdump) -- self.hex_dump("send_pdu", k5_pdu, hexdump=hexdump) - while True: - sent = self.s.send(req_pdu, 0) - if sent == len(req_pdu): -- break -+ return - req_pdu = req_pdu[sent:] - except socket.error as e: -- self._disconnect("send_pdu: %s" % e) -+ self._disconnect("send_msg: %s" % e) - raise - except IOError as e: -- self._disconnect("send_pdu: %s" % e) -+ self._disconnect("send_msg: %s" % e) - raise - - def recv_raw(self, num_recv=0xffff, hexdump=None, timeout=None): -@@ -963,16 +967,14 @@ class RawKerberosTest(TestCaseInTempDir): - return rep_pdu - - def recv_pdu_raw(self, asn1_print=None, hexdump=None, timeout=None): -- rep_pdu = None -- rep = None - raw_pdu = self.recv_raw( - num_recv=4, hexdump=hexdump, timeout=timeout) - if raw_pdu is None: -- return (None, None) -+ return None - header = struct.unpack(">I", raw_pdu[0:4]) - k5_len = header[0] - if k5_len == 0: -- return (None, "") -+ return "" - missing = k5_len - rep_pdu = b'' - while missing > 0: -@@ -981,6 +983,14 @@ class RawKerberosTest(TestCaseInTempDir): - self.assertGreaterEqual(len(raw_pdu), 1) - rep_pdu += raw_pdu - missing = k5_len - len(rep_pdu) -+ return rep_pdu -+ -+ def recv_reply(self, asn1_print=None, hexdump=None, timeout=None): -+ rep_pdu = self.recv_pdu_raw(asn1_print=asn1_print, -+ hexdump=hexdump, -+ timeout=timeout) -+ if not rep_pdu: -+ return None, rep_pdu - k5_raw = self.der_decode( - rep_pdu, - asn1Spec=None, -@@ -1002,9 +1012,9 @@ class RawKerberosTest(TestCaseInTempDir): - return (rep, rep_pdu) - - def recv_pdu(self, asn1_print=None, hexdump=None, timeout=None): -- (rep, rep_pdu) = self.recv_pdu_raw(asn1_print=asn1_print, -- hexdump=hexdump, -- timeout=timeout) -+ (rep, rep_pdu) = self.recv_reply(asn1_print=asn1_print, -+ hexdump=hexdump, -+ timeout=timeout) - return rep - - def assertIsConnected(self): --- -2.25.1 - - -From 57edd8e2e043bd226c91ab0791297c1d98549ff1 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Tue, 24 May 2022 19:26:56 +1200 -Subject: [PATCH 66/99] tests/krb5: Fix enum typo - -Signed-off-by: Joseph Sutton -Reviewed-by: Andreas Schneider ---- - python/samba/tests/krb5/kdc_base_test.py | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py -index 685a6f71f88..14f1d1a243d 100644 ---- a/python/samba/tests/krb5/kdc_base_test.py -+++ b/python/samba/tests/krb5/kdc_base_test.py -@@ -248,9 +248,9 @@ class KDCBaseTest(RawKerberosTest): - which is used by tearDownClass to clean up the created accounts. - ''' - if ou is None: -- if account_type is account_type.COMPUTER: -+ if account_type is self.AccountType.COMPUTER: - guid = DS_GUID_COMPUTERS_CONTAINER -- elif account_type is account_type.SERVER: -+ elif account_type is self.AccountType.SERVER: - guid = DS_GUID_DOMAIN_CONTROLLERS_CONTAINER - else: - guid = DS_GUID_USERS_CONTAINER --- -2.25.1 - - -From e44b70b862e93fb9a8139a7188ed7021d705d223 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Tue, 24 May 2022 19:30:12 +1200 -Subject: [PATCH 67/99] tests/krb5: Add option for creating accounts with - expired passwords - -Signed-off-by: Joseph Sutton -Reviewed-by: Andreas Schneider ---- - python/samba/tests/krb5/kdc_base_test.py | 10 ++++++++-- - 1 file changed, 8 insertions(+), 2 deletions(-) - -diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py -index 14f1d1a243d..777b3b4aaf1 100644 ---- a/python/samba/tests/krb5/kdc_base_test.py -+++ b/python/samba/tests/krb5/kdc_base_test.py -@@ -242,7 +242,8 @@ 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, add_dollar=True): -+ ou=None, account_control=0, add_dollar=True, -+ expired_password=False): - '''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. -@@ -294,6 +295,8 @@ class KDCBaseTest(RawKerberosTest): - details["servicePrincipalName"] = spn - if upn is not None: - details["userPrincipalName"] = upn -+ if expired_password: -+ details["pwdLastSet"] = "0" - if additional_details is not None: - details.update(additional_details) - samdb.add(details) -@@ -653,6 +656,7 @@ class KDCBaseTest(RawKerberosTest): - 'revealed_to_rodc': False, - 'revealed_to_mock_rodc': False, - 'no_auth_data_required': False, -+ 'expired_password': False, - 'supported_enctypes': None, - 'not_delegated': False, - 'delegation_to_spn': None, -@@ -695,6 +699,7 @@ class KDCBaseTest(RawKerberosTest): - revealed_to_rodc, - revealed_to_mock_rodc, - no_auth_data_required, -+ expired_password, - supported_enctypes, - not_delegated, - delegation_to_spn, -@@ -754,7 +759,8 @@ class KDCBaseTest(RawKerberosTest): - spn=spn, - additional_details=details, - account_control=user_account_control, -- add_dollar=add_dollar) -+ add_dollar=add_dollar, -+ expired_password=expired_password) - - keys = self.get_keys(samdb, dn) - self.creds_set_keys(creds, keys) --- -2.25.1 - - -From 2815de0510e222bc93f5b602b2cdd5c51f8adeb4 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Tue, 24 May 2022 19:34:59 +1200 -Subject: [PATCH 68/99] CVE-2022-2031 tests/krb5: Allow requesting a TGT to a - different sname and realm - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15047 -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15049 -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15074 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andreas Schneider - -[jsutton@samba.org Fixed conflict due to lacking rc4_support parameter] - -[jsutton@samba.org Fixed conflicts due to lacking client_name_type and - expected_cname parameters] ---- - python/samba/tests/krb5/kdc_base_test.py | 19 +++++++++++++------ - 1 file changed, 13 insertions(+), 6 deletions(-) - -diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py -index 777b3b4aaf1..c0ca881985a 100644 ---- a/python/samba/tests/krb5/kdc_base_test.py -+++ b/python/samba/tests/krb5/kdc_base_test.py -@@ -1344,10 +1344,12 @@ class KDCBaseTest(RawKerberosTest): - expected_flags=None, unexpected_flags=None, - pac_request=True, expect_pac=True, fresh=False): - user_name = tgt.cname['name-string'][0] -+ ticket_sname = tgt.sname - if target_name is None: - target_name = target_creds.get_username()[:-1] - cache_key = (user_name, target_name, service, to_rodc, kdc_options, - pac_request, str(expected_flags), str(unexpected_flags), -+ str(ticket_sname), - expect_pac) - - if not fresh: -@@ -1414,6 +1416,7 @@ class KDCBaseTest(RawKerberosTest): - expected_flags=None, unexpected_flags=None, - expected_account_name=None, expected_upn_name=None, - expected_sid=None, -+ sname=None, realm=None, - pac_request=True, expect_pac=True, - expect_pac_attrs=None, expect_pac_attrs_pac_request=None, - expect_requester_sid=None, -@@ -1422,6 +1425,7 @@ class KDCBaseTest(RawKerberosTest): - cache_key = (user_name, to_rodc, kdc_options, pac_request, - str(expected_flags), str(unexpected_flags), - expected_account_name, expected_upn_name, expected_sid, -+ str(sname), str(realm), - expect_pac, expect_pac_attrs, - expect_pac_attrs_pac_request, expect_requester_sid) - -@@ -1431,15 +1435,21 @@ class KDCBaseTest(RawKerberosTest): - if tgt is not None: - return tgt - -- realm = creds.get_realm() -+ if realm is None: -+ 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]) -+ if sname is None: -+ sname = self.PrincipalName_create(name_type=NT_SRV_INST, -+ names=['krbtgt', realm]) -+ expected_sname = self.PrincipalName_create( -+ name_type=NT_SRV_INST, names=['krbtgt', realm.upper()]) -+ else: -+ expected_sname = sname - - till = self.get_KerberosTime(offset=36000) - -@@ -1505,9 +1515,6 @@ class KDCBaseTest(RawKerberosTest): - - 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, --- -2.25.1 - - -From e56d66f729ba1713e59b2fb938cc09e69831ac0e Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Tue, 24 May 2022 19:57:57 +1200 -Subject: [PATCH 69/99] CVE-2022-2031 tests/krb5: Add kpasswd_exchange() method - -Now we can test the kpasswd service from Python. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15047 -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15049 -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15074 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andreas Schneider - -[jsutton@samba.org Fixed conflicts in imports] ---- - python/samba/tests/krb5/raw_testcase.py | 264 ++++++++++++++++++++++-- - 1 file changed, 251 insertions(+), 13 deletions(-) - -diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py -index 2aed5530455..57010ae73bd 100644 ---- a/python/samba/tests/krb5/raw_testcase.py -+++ b/python/samba/tests/krb5/raw_testcase.py -@@ -26,6 +26,8 @@ import binascii - import itertools - import collections - -+from enum import Enum -+ - from pyasn1.codec.der.decoder import decode as pyasn1_der_decode - from pyasn1.codec.der.encoder import encode as pyasn1_der_encode - from pyasn1.codec.native.decoder import decode as pyasn1_native_decode -@@ -33,6 +35,8 @@ from pyasn1.codec.native.encoder import encode as pyasn1_native_encode - - from pyasn1.codec.ber.encoder import BitStringEncoder - -+from pyasn1.error import PyAsn1Error -+ - from samba.credentials import Credentials - from samba.dcerpc import krb5pac, security - from samba.gensec import FEATURE_SEAL -@@ -50,6 +54,7 @@ from samba.tests.krb5.rfc4120_constants import ( - KDC_ERR_PREAUTH_FAILED, - KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTIONS, - KERB_ERR_TYPE_EXTENDED, -+ KRB_AP_REP, - KRB_AP_REQ, - KRB_AS_REP, - KRB_AS_REQ, -@@ -59,6 +64,7 @@ from samba.tests.krb5.rfc4120_constants import ( - KRB_TGS_REQ, - KU_AP_REQ_AUTH, - KU_AS_REP_ENC_PART, -+ KU_AP_REQ_ENC_PART, - KU_ENC_CHALLENGE_KDC, - KU_FAST_ENC, - KU_FAST_FINISHED, -@@ -73,6 +79,7 @@ from samba.tests.krb5.rfc4120_constants import ( - KU_TGS_REQ_AUTH_DAT_SESSION, - KU_TGS_REQ_AUTH_DAT_SUBKEY, - KU_TICKET, -+ NT_PRINCIPAL, - NT_SRV_INST, - NT_WELLKNOWN, - PADATA_ENCRYPTED_CHALLENGE, -@@ -515,6 +522,10 @@ class KerberosTicketCreds: - class RawKerberosTest(TestCaseInTempDir): - """A raw Kerberos Test case.""" - -+ class KpasswdMode(Enum): -+ SET = object() -+ CHANGE = object() -+ - pac_checksum_types = {krb5pac.PAC_TYPE_SRV_CHECKSUM, - krb5pac.PAC_TYPE_KDC_CHECKSUM, - krb5pac.PAC_TYPE_TICKET_CHECKSUM} -@@ -1886,6 +1897,224 @@ class RawKerberosTest(TestCaseInTempDir): - - return msg - -+ def get_enc_part(self, obj, key, usage): -+ self.assertElementEqual(obj, 'pvno', 5) -+ -+ enc_part = obj['enc-part'] -+ self.assertElementEqual(enc_part, 'etype', key.etype) -+ self.assertElementKVNO(enc_part, 'kvno', key.kvno) -+ -+ enc_part = key.decrypt(usage, enc_part['cipher']) -+ -+ return enc_part -+ -+ def kpasswd_exchange(self, -+ ticket, -+ new_password, -+ expected_code, -+ expected_msg, -+ mode, -+ target_princ=None, -+ target_realm=None, -+ ap_options=None, -+ send_seq_number=True): -+ if mode is self.KpasswdMode.SET: -+ version = 0xff80 -+ user_data = self.ChangePasswdDataMS_create(new_password, -+ target_princ, -+ target_realm) -+ elif mode is self.KpasswdMode.CHANGE: -+ self.assertIsNone(target_princ, -+ 'target_princ only valid for pw set') -+ self.assertIsNone(target_realm, -+ 'target_realm only valid for pw set') -+ -+ version = 1 -+ user_data = new_password.encode('utf-8') -+ else: -+ self.fail(f'invalid mode {mode}') -+ -+ subkey = self.RandomKey(kcrypto.Enctype.AES256) -+ -+ if ap_options is None: -+ ap_options = '0' -+ ap_options = str(krb5_asn1.APOptions(ap_options)) -+ -+ kdc_exchange_dict = { -+ 'tgt': ticket, -+ 'authenticator_subkey': subkey, -+ 'auth_data': None, -+ 'ap_options': ap_options, -+ } -+ -+ if send_seq_number: -+ seq_number = random.randint(0, 0xfffffffe) -+ else: -+ seq_number = None -+ -+ ap_req = self.generate_ap_req(kdc_exchange_dict, -+ None, -+ req_body=None, -+ armor=False, -+ usage=KU_AP_REQ_AUTH, -+ seq_number=seq_number) -+ -+ self.connect(self.host, port=464) -+ self.assertIsNotNone(self.s) -+ -+ family = self.s.family -+ -+ if family == socket.AF_INET: -+ addr_type = 2 # IPv4 -+ elif family == socket.AF_INET6: -+ addr_type = 24 # IPv6 -+ else: -+ self.fail(f'unknown family {family}') -+ -+ def create_address(ip): -+ return { -+ 'addr-type': addr_type, -+ 'address': socket.inet_pton(family, ip), -+ } -+ -+ local_ip = self.s.getsockname()[0] -+ local_address = create_address(local_ip) -+ -+ # remote_ip = self.s.getpeername()[0] -+ # remote_address = create_address(remote_ip) -+ -+ # TODO: due to a bug (?), MIT Kerberos will not accept the request -+ # unless r-address is set to our _local_ address. Heimdal, on the other -+ # hand, requires the r-address is set to the remote address (as -+ # expected). To avoid problems, avoid sending r-address for now. -+ remote_address = None -+ -+ msg = self.kpasswd_create(subkey, -+ user_data, -+ version, -+ seq_number, -+ ap_req, -+ local_address, -+ remote_address) -+ -+ self.send_msg(msg) -+ rep_pdu = self.recv_pdu_raw() -+ -+ self._disconnect('transaction done') -+ -+ self.assertIsNotNone(rep_pdu) -+ -+ header = rep_pdu[:6] -+ reply = rep_pdu[6:] -+ -+ reply_len = (header[0] << 8) | header[1] -+ reply_version = (header[2] << 8) | header[3] -+ ap_rep_len = (header[4] << 8) | header[5] -+ -+ self.assertEqual(reply_len, len(rep_pdu)) -+ self.assertEqual(1, reply_version) # KRB5_KPASSWD_VERS_CHANGEPW -+ self.assertLess(ap_rep_len, reply_len) -+ -+ self.assertNotEqual(0x7e, rep_pdu[1]) -+ self.assertNotEqual(0x5e, rep_pdu[1]) -+ -+ if ap_rep_len: -+ # We received an AP-REQ and KRB-PRIV as a response. This may or may -+ # not indicate an error, depending on the status code. -+ ap_rep = reply[:ap_rep_len] -+ krb_priv = reply[ap_rep_len:] -+ -+ key = ticket.session_key -+ -+ ap_rep = self.der_decode(ap_rep, asn1Spec=krb5_asn1.AP_REP()) -+ self.assertElementEqual(ap_rep, 'msg-type', KRB_AP_REP) -+ enc_part = self.get_enc_part(ap_rep, key, KU_AP_REQ_ENC_PART) -+ enc_part = self.der_decode( -+ enc_part, asn1Spec=krb5_asn1.EncAPRepPart()) -+ -+ self.assertElementPresent(enc_part, 'ctime') -+ self.assertElementPresent(enc_part, 'cusec') -+ # self.assertElementMissing(enc_part, 'subkey') # TODO -+ # self.assertElementPresent(enc_part, 'seq-number') # TODO -+ -+ try: -+ krb_priv = self.der_decode(krb_priv, asn1Spec=krb5_asn1.KRB_PRIV()) -+ except PyAsn1Error: -+ self.fail() -+ -+ self.assertElementEqual(krb_priv, 'msg-type', KRB_PRIV) -+ priv_enc_part = self.get_enc_part(krb_priv, subkey, KU_KRB_PRIV) -+ priv_enc_part = self.der_decode( -+ priv_enc_part, asn1Spec=krb5_asn1.EncKrbPrivPart()) -+ -+ self.assertElementMissing(priv_enc_part, 'timestamp') -+ self.assertElementMissing(priv_enc_part, 'usec') -+ # self.assertElementPresent(priv_enc_part, 'seq-number') # TODO -+ # self.assertElementEqual(priv_enc_part, 's-address', remote_address) # TODO -+ # self.assertElementMissing(priv_enc_part, 'r-address') # TODO -+ -+ result_data = priv_enc_part['user-data'] -+ else: -+ # We received a KRB-ERROR as a response, indicating an error. -+ krb_error = self.der_decode(reply, asn1Spec=krb5_asn1.KRB_ERROR()) -+ -+ sname = self.PrincipalName_create( -+ name_type=NT_PRINCIPAL, -+ names=['kadmin', 'changepw']) -+ realm = self.get_krbtgt_creds().get_realm().upper() -+ -+ self.assertElementEqual(krb_error, 'pvno', 5) -+ self.assertElementEqual(krb_error, 'msg-type', KRB_ERROR) -+ self.assertElementMissing(krb_error, 'ctime') -+ self.assertElementMissing(krb_error, 'usec') -+ self.assertElementPresent(krb_error, 'stime') -+ self.assertElementPresent(krb_error, 'susec') -+ -+ error_code = krb_error['error-code'] -+ if isinstance(expected_code, int): -+ self.assertEqual(error_code, expected_code) -+ else: -+ self.assertIn(error_code, expected_code) -+ -+ self.assertElementMissing(krb_error, 'crealm') -+ self.assertElementMissing(krb_error, 'cname') -+ self.assertElementEqual(krb_error, 'realm', realm.encode('utf-8')) -+ self.assertElementEqualPrincipal(krb_error, 'sname', sname) -+ self.assertElementMissing(krb_error, 'e-text') -+ -+ result_data = krb_error['e-data'] -+ -+ status = result_data[:2] -+ message = result_data[2:] -+ -+ status_code = (status[0] << 8) | status[1] -+ if isinstance(expected_code, int): -+ self.assertEqual(status_code, expected_code) -+ else: -+ self.assertIn(status_code, expected_code) -+ -+ if not message: -+ self.assertEqual(0, status_code, -+ 'got an error result, but no message') -+ return -+ -+ # Check the first character of the message. -+ if message[0]: -+ if isinstance(expected_msg, bytes): -+ self.assertEqual(message, expected_msg) -+ else: -+ self.assertIn(message, expected_msg) -+ else: -+ # We got AD password policy information. -+ self.assertEqual(30, len(message)) -+ -+ (empty_bytes, -+ min_length, -+ history_length, -+ properties, -+ expire_time, -+ min_age) = struct.unpack('>HIIIQQ', message) -+ - def _generic_kdc_exchange(self, - kdc_exchange_dict, # required - cname=None, # optional -@@ -1996,7 +2225,7 @@ class RawKerberosTest(TestCaseInTempDir): - self.assertIsNotNone(generate_fast_fn) - fast_ap_req = generate_fast_armor_fn(kdc_exchange_dict, - callback_dict, -- req_body, -+ None, - armor=True) - - fast_armor_type = kdc_exchange_dict['fast_armor_type'] -@@ -3211,31 +3440,39 @@ class RawKerberosTest(TestCaseInTempDir): - kdc_exchange_dict, - _callback_dict, - req_body, -- armor): -+ armor, -+ usage=None, -+ seq_number=None): -+ req_body_checksum = None -+ - if armor: -+ self.assertIsNone(req_body) -+ - tgt = kdc_exchange_dict['armor_tgt'] - authenticator_subkey = kdc_exchange_dict['armor_subkey'] -- -- req_body_checksum = None - else: - tgt = kdc_exchange_dict['tgt'] - authenticator_subkey = kdc_exchange_dict['authenticator_subkey'] -- body_checksum_type = kdc_exchange_dict['body_checksum_type'] - -- req_body_blob = self.der_encode(req_body, -- asn1Spec=krb5_asn1.KDC_REQ_BODY()) -+ if req_body is not None: -+ body_checksum_type = kdc_exchange_dict['body_checksum_type'] -+ -+ req_body_blob = self.der_encode( -+ req_body, asn1Spec=krb5_asn1.KDC_REQ_BODY()) - -- req_body_checksum = self.Checksum_create(tgt.session_key, -- KU_TGS_REQ_AUTH_CKSUM, -- req_body_blob, -- ctype=body_checksum_type) -+ req_body_checksum = self.Checksum_create( -+ tgt.session_key, -+ KU_TGS_REQ_AUTH_CKSUM, -+ req_body_blob, -+ ctype=body_checksum_type) - - auth_data = kdc_exchange_dict['auth_data'] - - subkey_obj = None - if authenticator_subkey is not None: - subkey_obj = authenticator_subkey.export_obj() -- seq_number = random.randint(0, 0xfffffffe) -+ if seq_number is None: -+ seq_number = random.randint(0, 0xfffffffe) - (ctime, cusec) = self.get_KerberosTimeWithUsec() - authenticator_obj = self.Authenticator_create( - crealm=tgt.crealm, -@@ -3250,7 +3487,8 @@ class RawKerberosTest(TestCaseInTempDir): - authenticator_obj, - asn1Spec=krb5_asn1.Authenticator()) - -- usage = KU_AP_REQ_AUTH if armor else KU_TGS_REQ_AUTH -+ if usage is None: -+ usage = KU_AP_REQ_AUTH if armor else KU_TGS_REQ_AUTH - authenticator = self.EncryptedData_create(tgt.session_key, - usage, - authenticator_blob) --- -2.25.1 - - -From b2c3b060baedf638d7b8ee7f3b2bc1c7f9b695ac Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Thu, 26 May 2022 16:35:03 +1200 -Subject: [PATCH 70/99] CVE-2022-32744 selftest: Specify Administrator kvno for - Python krb5 tests - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15074 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andreas Schneider ---- - source4/selftest/tests.py | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py -index dc340623f3e..c5fdf7fe294 100755 ---- a/source4/selftest/tests.py -+++ b/source4/selftest/tests.py -@@ -912,6 +912,7 @@ krb5_environ = { - 'SERVICE_USERNAME': '$SERVER', - 'ADMIN_USERNAME': '$DC_USERNAME', - 'ADMIN_PASSWORD': '$DC_PASSWORD', -+ 'ADMIN_KVNO': '1', - 'FOR_USER': '$DC_USERNAME', - 'STRICT_CHECKING':'0', - 'FAST_SUPPORT': have_fast_support, --- -2.25.1 - - -From 6fc3d93b4fe81be8e8f134c46d461d5815edda91 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Tue, 24 May 2022 19:59:16 +1200 -Subject: [PATCH 71/99] CVE-2022-2031 tests/krb5: Add tests for kpasswd service - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15047 -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15049 -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15074 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andreas Schneider - -[jsutton@samba.org Fixed conflicts in usage.py and knownfails; removed - MIT KDC 1.20-specific knownfails as it's not supported] - -[jsutton@samba.org Fixed conflicts in usage.py, knownfails, and - tests.py] ---- - python/samba/tests/krb5/kdc_base_test.py | 4 +- - python/samba/tests/krb5/kpasswd_tests.py | 1021 ++++++++++++++++++++++ - python/samba/tests/krb5/raw_testcase.py | 8 + - python/samba/tests/usage.py | 1 + - selftest/knownfail_heimdal_kdc | 26 + - selftest/knownfail_mit_kdc | 26 + - source4/selftest/tests.py | 4 + - 7 files changed, 1089 insertions(+), 1 deletion(-) - create mode 100755 python/samba/tests/krb5/kpasswd_tests.py - -diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py -index c0ca881985a..f0306dde110 100644 ---- a/python/samba/tests/krb5/kdc_base_test.py -+++ b/python/samba/tests/krb5/kdc_base_test.py -@@ -1586,7 +1586,9 @@ class KDCBaseTest(RawKerberosTest): - authenticator_subkey = self.RandomKey(kcrypto.Enctype.AES256) - - if expect_error: -- expected_error_mode = KDC_ERR_TGT_REVOKED -+ expected_error_mode = expect_error -+ if expected_error_mode is True: -+ expected_error_mode = KDC_ERR_TGT_REVOKED - check_error_fn = self.generic_check_kdc_error - check_rep_fn = None - else: -diff --git a/python/samba/tests/krb5/kpasswd_tests.py b/python/samba/tests/krb5/kpasswd_tests.py -new file mode 100755 -index 00000000000..3a6c7d818dc ---- /dev/null -+++ b/python/samba/tests/krb5/kpasswd_tests.py -@@ -0,0 +1,1021 @@ -+#!/usr/bin/env python3 -+# Unix SMB/CIFS implementation. -+# Copyright (C) Stefan Metzmacher 2020 -+# Copyright (C) Catalyst.Net Ltd -+# -+# 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 . -+# -+ -+import os -+import sys -+ -+from functools import partial -+ -+from samba import generate_random_password, unix2nttime -+from samba.dcerpc import krb5pac, security -+from samba.sd_utils import SDUtils -+ -+from samba.tests.krb5.kdc_base_test import KDCBaseTest -+from samba.tests.krb5.rfc4120_constants import ( -+ KDC_ERR_TGT_REVOKED, -+ KDC_ERR_TKT_EXPIRED, -+ KPASSWD_ACCESSDENIED, -+ KPASSWD_HARDERROR, -+ KPASSWD_INITIAL_FLAG_NEEDED, -+ KPASSWD_MALFORMED, -+ KPASSWD_SOFTERROR, -+ KPASSWD_SUCCESS, -+ NT_PRINCIPAL, -+ NT_SRV_INST, -+) -+ -+sys.path.insert(0, 'bin/python') -+os.environ['PYTHONUNBUFFERED'] = '1' -+ -+global_asn1_print = False -+global_hexdump = False -+ -+ -+# Note: these tests do not pass on Windows, which returns different error codes -+# to the ones we have chosen, and does not always return additional error data. -+class KpasswdTests(KDCBaseTest): -+ -+ def setUp(self): -+ super().setUp() -+ self.do_asn1_print = global_asn1_print -+ self.do_hexdump = global_hexdump -+ -+ samdb = self.get_samdb() -+ -+ # Get the old 'dSHeuristics' if it was set -+ dsheuristics = samdb.get_dsheuristics() -+ -+ # Reset the 'dSHeuristics' as they were before -+ self.addCleanup(samdb.set_dsheuristics, dsheuristics) -+ -+ # Set the 'dSHeuristics' to activate the correct 'userPassword' -+ # behaviour -+ samdb.set_dsheuristics('000000001') -+ -+ # Get the old 'minPwdAge' -+ minPwdAge = samdb.get_minPwdAge() -+ -+ # Reset the 'minPwdAge' as it was before -+ self.addCleanup(samdb.set_minPwdAge, minPwdAge) -+ -+ # Set it temporarily to '0' -+ samdb.set_minPwdAge('0') -+ -+ def _get_creds(self, expired=False): -+ opts = { -+ 'expired_password': expired -+ } -+ -+ # Create the account. -+ creds = self.get_cached_creds(account_type=self.AccountType.USER, -+ opts=opts, -+ use_cache=False) -+ -+ return creds -+ -+ def issued_by_rodc(self, ticket): -+ krbtgt_creds = self.get_mock_rodc_krbtgt_creds() -+ -+ krbtgt_key = self.TicketDecryptionKey_from_creds(krbtgt_creds) -+ checksum_keys = { -+ krb5pac.PAC_TYPE_KDC_CHECKSUM: krbtgt_key, -+ } -+ -+ return self.modified_ticket( -+ ticket, -+ new_ticket_key=krbtgt_key, -+ checksum_keys=checksum_keys) -+ -+ def get_kpasswd_sname(self): -+ return self.PrincipalName_create(name_type=NT_PRINCIPAL, -+ names=['kadmin', 'changepw']) -+ -+ def get_ticket_lifetime(self, ticket): -+ enc_part = ticket.ticket_private -+ -+ authtime = enc_part['authtime'] -+ starttime = enc_part.get('starttime', authtime) -+ endtime = enc_part['endtime'] -+ -+ starttime = self.get_EpochFromKerberosTime(starttime) -+ endtime = self.get_EpochFromKerberosTime(endtime) -+ -+ return endtime - starttime -+ -+ def add_requester_sid(self, pac, sid): -+ pac_buffers = pac.buffers -+ -+ buffer_types = [pac_buffer.type for pac_buffer in pac_buffers] -+ self.assertNotIn(krb5pac.PAC_TYPE_REQUESTER_SID, buffer_types) -+ -+ requester_sid = krb5pac.PAC_REQUESTER_SID() -+ requester_sid.sid = security.dom_sid(sid) -+ -+ requester_sid_buffer = krb5pac.PAC_BUFFER() -+ requester_sid_buffer.type = krb5pac.PAC_TYPE_REQUESTER_SID -+ requester_sid_buffer.info = requester_sid -+ -+ pac_buffers.append(requester_sid_buffer) -+ -+ pac.buffers = pac_buffers -+ pac.num_buffers += 1 -+ -+ return pac -+ -+ # Test setting a password with kpasswd. -+ def test_kpasswd_set(self): -+ # Create an account for testing. -+ creds = self._get_creds() -+ -+ # Get an initial ticket to kpasswd. -+ ticket = self.get_tgt(creds, sname=self.get_kpasswd_sname(), -+ kdc_options='0') -+ -+ expected_code = KPASSWD_SUCCESS -+ expected_msg = b'Password changed' -+ -+ # Set the password. -+ new_password = generate_random_password(32, 32) -+ self.kpasswd_exchange(ticket, -+ new_password, -+ expected_code, -+ expected_msg, -+ mode=self.KpasswdMode.SET) -+ -+ # Test the newly set password. -+ creds.update_password(new_password) -+ self.get_tgt(creds, fresh=True) -+ -+ # Test changing a password with kpasswd. -+ def test_kpasswd_change(self): -+ # Create an account for testing. -+ creds = self._get_creds() -+ -+ # Get an initial ticket to kpasswd. -+ ticket = self.get_tgt(creds, sname=self.get_kpasswd_sname(), -+ kdc_options='0') -+ -+ expected_code = KPASSWD_SUCCESS -+ expected_msg = b'Password changed' -+ -+ # Change the password. -+ new_password = generate_random_password(32, 32) -+ self.kpasswd_exchange(ticket, -+ new_password, -+ expected_code, -+ expected_msg, -+ mode=self.KpasswdMode.CHANGE) -+ -+ # Test the newly set password. -+ creds.update_password(new_password) -+ self.get_tgt(creds, fresh=True) -+ -+ # Test kpasswd without setting the canonicalize option. -+ def test_kpasswd_no_canonicalize(self): -+ # Create an account for testing. -+ creds = self._get_creds() -+ -+ sname = self.get_kpasswd_sname() -+ -+ # Get an initial ticket to kpasswd. -+ ticket = self.get_tgt(creds, sname=sname, -+ kdc_options='0') -+ -+ expected_code = KPASSWD_SUCCESS -+ expected_msg = b'Password changed' -+ -+ # Set the password. -+ new_password = generate_random_password(32, 32) -+ self.kpasswd_exchange(ticket, -+ new_password, -+ expected_code, -+ expected_msg, -+ mode=self.KpasswdMode.SET) -+ -+ creds.update_password(new_password) -+ -+ # Get an initial ticket to kpasswd. -+ ticket = self.get_tgt(creds, sname=sname, -+ kdc_options='0') -+ -+ # Change the password. -+ new_password = generate_random_password(32, 32) -+ self.kpasswd_exchange(ticket, -+ new_password, -+ expected_code, -+ expected_msg, -+ mode=self.KpasswdMode.CHANGE) -+ -+ # Test kpasswd with the canonicalize option reset and a non-canonical -+ # (by conversion to title case) realm. -+ def test_kpasswd_no_canonicalize_realm_case(self): -+ # Create an account for testing. -+ creds = self._get_creds() -+ -+ sname = self.get_kpasswd_sname() -+ realm = creds.get_realm().capitalize() # We use a title-cased realm. -+ -+ # Get an initial ticket to kpasswd. -+ ticket = self.get_tgt(creds, sname=sname, -+ realm=realm, -+ kdc_options='0') -+ -+ expected_code = KPASSWD_SUCCESS -+ expected_msg = b'Password changed' -+ -+ # Set the password. -+ new_password = generate_random_password(32, 32) -+ self.kpasswd_exchange(ticket, -+ new_password, -+ expected_code, -+ expected_msg, -+ mode=self.KpasswdMode.SET) -+ -+ creds.update_password(new_password) -+ -+ # Get an initial ticket to kpasswd. -+ ticket = self.get_tgt(creds, sname=sname, -+ realm=realm, -+ kdc_options='0') -+ -+ # Change the password. -+ new_password = generate_random_password(32, 32) -+ self.kpasswd_exchange(ticket, -+ new_password, -+ expected_code, -+ expected_msg, -+ mode=self.KpasswdMode.CHANGE) -+ -+ # Test kpasswd with the canonicalize option set. -+ def test_kpasswd_canonicalize(self): -+ # Create an account for testing. -+ creds = self._get_creds() -+ -+ # Get an initial ticket to kpasswd. We set the canonicalize flag here. -+ ticket = self.get_tgt(creds, sname=self.get_kpasswd_sname(), -+ kdc_options='canonicalize') -+ -+ expected_code = KPASSWD_SUCCESS -+ expected_msg = b'Password changed' -+ -+ # Set the password. -+ new_password = generate_random_password(32, 32) -+ self.kpasswd_exchange(ticket, -+ new_password, -+ expected_code, -+ expected_msg, -+ mode=self.KpasswdMode.SET) -+ -+ creds.update_password(new_password) -+ -+ # Get an initial ticket to kpasswd. We set the canonicalize flag here. -+ ticket = self.get_tgt(creds, sname=self.get_kpasswd_sname(), -+ kdc_options='canonicalize') -+ -+ # Change the password. -+ new_password = generate_random_password(32, 32) -+ self.kpasswd_exchange(ticket, -+ new_password, -+ expected_code, -+ expected_msg, -+ mode=self.KpasswdMode.CHANGE) -+ -+ # Test kpasswd with the canonicalize option set and a non-canonical (by -+ # conversion to title case) realm. -+ def test_kpasswd_canonicalize_realm_case(self): -+ # Create an account for testing. -+ creds = self._get_creds() -+ -+ sname = self.get_kpasswd_sname() -+ realm = creds.get_realm().capitalize() # We use a title-cased realm. -+ -+ # Get an initial ticket to kpasswd. We set the canonicalize flag here. -+ ticket = self.get_tgt(creds, sname=sname, -+ realm=realm, -+ kdc_options='canonicalize') -+ -+ expected_code = KPASSWD_SUCCESS -+ expected_msg = b'Password changed' -+ -+ # Set the password. -+ new_password = generate_random_password(32, 32) -+ self.kpasswd_exchange(ticket, -+ new_password, -+ expected_code, -+ expected_msg, -+ mode=self.KpasswdMode.SET) -+ -+ creds.update_password(new_password) -+ -+ # Get an initial ticket to kpasswd. We set the canonicalize flag here. -+ ticket = self.get_tgt(creds, sname=sname, -+ realm=realm, -+ kdc_options='canonicalize') -+ -+ # Change the password. -+ new_password = generate_random_password(32, 32) -+ self.kpasswd_exchange(ticket, -+ new_password, -+ expected_code, -+ expected_msg, -+ mode=self.KpasswdMode.CHANGE) -+ -+ # Test kpasswd rejects a password that does not meet complexity -+ # requirements. -+ def test_kpasswd_too_weak(self): -+ # Create an account for testing. -+ creds = self._get_creds() -+ -+ # Get an initial ticket to kpasswd. -+ ticket = self.get_tgt(creds, sname=self.get_kpasswd_sname(), -+ kdc_options='0') -+ -+ expected_code = KPASSWD_SOFTERROR -+ expected_msg = b'Password does not meet complexity requirements' -+ -+ # Set the password. -+ new_password = 'password' -+ self.kpasswd_exchange(ticket, -+ new_password, -+ expected_code, -+ expected_msg, -+ mode=self.KpasswdMode.SET) -+ -+ # Change the password. -+ self.kpasswd_exchange(ticket, -+ new_password, -+ expected_code, -+ expected_msg, -+ mode=self.KpasswdMode.CHANGE) -+ -+ # Test kpasswd rejects an empty new password. -+ def test_kpasswd_empty(self): -+ # Create an account for testing. -+ creds = self._get_creds() -+ -+ # Get an initial ticket to kpasswd. -+ ticket = self.get_tgt(creds, sname=self.get_kpasswd_sname(), -+ kdc_options='0') -+ -+ expected_code = KPASSWD_SOFTERROR, KPASSWD_HARDERROR -+ expected_msg = (b'Password too short, password must be at least 7 ' -+ b'characters long.', -+ b'String conversion failed!') -+ -+ # Set the password. -+ new_password = '' -+ self.kpasswd_exchange(ticket, -+ new_password, -+ expected_code, -+ expected_msg, -+ mode=self.KpasswdMode.SET) -+ -+ expected_code = KPASSWD_HARDERROR -+ expected_msg = b'String conversion failed!' -+ -+ # Change the password. -+ self.kpasswd_exchange(ticket, -+ new_password, -+ expected_code, -+ expected_msg, -+ mode=self.KpasswdMode.CHANGE) -+ -+ # Test kpasswd rejects a request that does not include a random sequence -+ # number. -+ def test_kpasswd_no_seq_number(self): -+ # Create an account for testing. -+ creds = self._get_creds() -+ -+ # Get an initial ticket to kpasswd. -+ ticket = self.get_tgt(creds, sname=self.get_kpasswd_sname(), -+ kdc_options='0') -+ -+ expected_code = KPASSWD_HARDERROR -+ expected_msg = b'gensec_unwrap failed - NT_STATUS_ACCESS_DENIED\n' -+ -+ # Set the password. -+ new_password = generate_random_password(32, 32) -+ self.kpasswd_exchange(ticket, -+ new_password, -+ expected_code, -+ expected_msg, -+ mode=self.KpasswdMode.SET, -+ send_seq_number=False) -+ -+ # Change the password. -+ self.kpasswd_exchange(ticket, -+ new_password, -+ expected_code, -+ expected_msg, -+ mode=self.KpasswdMode.CHANGE, -+ send_seq_number=False) -+ -+ # Test kpasswd rejects a ticket issued by an RODC. -+ def test_kpasswd_from_rodc(self): -+ # Create an account for testing. -+ creds = self._get_creds() -+ -+ # Get an initial ticket to kpasswd. -+ ticket = self.get_tgt(creds, sname=self.get_kpasswd_sname(), -+ kdc_options='0') -+ -+ # Have the ticket be issued by the RODC. -+ ticket = self.issued_by_rodc(ticket) -+ -+ expected_code = KPASSWD_HARDERROR -+ expected_msg = b'gensec_update failed - NT_STATUS_LOGON_FAILURE\n' -+ -+ # Set the password. -+ new_password = generate_random_password(32, 32) -+ self.kpasswd_exchange(ticket, -+ new_password, -+ expected_code, -+ expected_msg, -+ mode=self.KpasswdMode.SET) -+ -+ # Change the password. -+ self.kpasswd_exchange(ticket, -+ new_password, -+ expected_code, -+ expected_msg, -+ mode=self.KpasswdMode.CHANGE) -+ -+ # Test setting a password, specifying the principal of the target user. -+ def test_kpasswd_set_target_princ_only(self): -+ # Create an account for testing. -+ creds = self._get_creds() -+ username = creds.get_username() -+ -+ cname = self.PrincipalName_create(name_type=NT_PRINCIPAL, -+ names=username.split('/')) -+ -+ # Get an initial ticket to kpasswd. -+ ticket = self.get_tgt(creds, sname=self.get_kpasswd_sname(), -+ kdc_options='0') -+ -+ expected_code = KPASSWD_MALFORMED -+ expected_msg = (b'Realm and principal must be both present, or ' -+ b'neither present', -+ b'Failed to decode packet') -+ -+ # Change the password. -+ new_password = generate_random_password(32, 32) -+ self.kpasswd_exchange(ticket, -+ new_password, -+ expected_code, -+ expected_msg, -+ mode=self.KpasswdMode.SET, -+ target_princ=cname) -+ -+ # Test that kpasswd rejects a password set specifying only the realm of the -+ # target user. -+ def test_kpasswd_set_target_realm_only(self): -+ # Create an account for testing. -+ creds = self._get_creds() -+ -+ # Get an initial ticket to kpasswd. -+ ticket = self.get_tgt(creds, sname=self.get_kpasswd_sname(), -+ kdc_options='0') -+ -+ expected_code = KPASSWD_MALFORMED, KPASSWD_ACCESSDENIED -+ expected_msg = (b'Realm and principal must be both present, or ' -+ b'neither present', -+ b'Failed to decode packet', -+ b'No such user when changing password') -+ -+ # Change the password. -+ new_password = generate_random_password(32, 32) -+ self.kpasswd_exchange(ticket, -+ new_password, -+ expected_code, -+ expected_msg, -+ mode=self.KpasswdMode.SET, -+ target_realm=creds.get_realm()) -+ -+ # Show that a user cannot set a password, specifying both principal and -+ # realm of the target user, without having control access. -+ def test_kpasswd_set_target_princ_and_realm_no_access(self): -+ # Create an account for testing. -+ creds = self._get_creds() -+ username = creds.get_username() -+ -+ cname = self.PrincipalName_create(name_type=NT_PRINCIPAL, -+ names=username.split('/')) -+ -+ # Get an initial ticket to kpasswd. -+ ticket = self.get_tgt(creds, sname=self.get_kpasswd_sname(), -+ kdc_options='0') -+ -+ expected_code = KPASSWD_ACCESSDENIED -+ expected_msg = b'Not permitted to change password' -+ -+ # Change the password. -+ new_password = generate_random_password(32, 32) -+ self.kpasswd_exchange(ticket, -+ new_password, -+ expected_code, -+ expected_msg, -+ mode=self.KpasswdMode.SET, -+ target_princ=cname, -+ target_realm=creds.get_realm()) -+ -+ # Test setting a password, specifying both principal and realm of the -+ # target user, whem the user has control access on their account. -+ def test_kpasswd_set_target_princ_and_realm_access(self): -+ # Create an account for testing. -+ creds = self._get_creds() -+ username = creds.get_username() -+ tgt = self.get_tgt(creds) -+ -+ cname = self.PrincipalName_create(name_type=NT_PRINCIPAL, -+ names=username.split('/')) -+ -+ samdb = self.get_samdb() -+ sd_utils = SDUtils(samdb) -+ -+ user_dn = creds.get_dn() -+ user_sid = self.get_objectSid(samdb, user_dn) -+ -+ # Give the user control access on their account. -+ ace = f'(A;;CR;;;{user_sid})' -+ sd_utils.dacl_add_ace(user_dn, ace) -+ -+ # Get a non-initial ticket to kpasswd. Since we have the right to -+ # change the account's password, we don't need an initial ticket. -+ krbtgt_creds = self.get_krbtgt_creds() -+ ticket = self.get_service_ticket(tgt, -+ krbtgt_creds, -+ service='kadmin', -+ target_name='changepw', -+ kdc_options='0') -+ -+ expected_code = KPASSWD_SUCCESS -+ expected_msg = b'Password changed' -+ -+ # Change the password. -+ new_password = generate_random_password(32, 32) -+ self.kpasswd_exchange(ticket, -+ new_password, -+ expected_code, -+ expected_msg, -+ mode=self.KpasswdMode.SET, -+ target_princ=cname, -+ target_realm=creds.get_realm()) -+ -+ # Test setting a password when the existing password has expired. -+ def test_kpasswd_set_expired_password(self): -+ # Create an account for testing, with an expired password. -+ creds = self._get_creds(expired=True) -+ -+ # Get an initial ticket to kpasswd. -+ ticket = self.get_tgt(creds, sname=self.get_kpasswd_sname(), -+ kdc_options='0') -+ -+ expected_code = KPASSWD_SUCCESS -+ expected_msg = b'Password changed' -+ -+ # Set the password. -+ new_password = generate_random_password(32, 32) -+ self.kpasswd_exchange(ticket, -+ new_password, -+ expected_code, -+ expected_msg, -+ mode=self.KpasswdMode.SET) -+ -+ # Test changing a password when the existing password has expired. -+ def test_kpasswd_change_expired_password(self): -+ # Create an account for testing, with an expired password. -+ creds = self._get_creds(expired=True) -+ -+ # Get an initial ticket to kpasswd. -+ ticket = self.get_tgt(creds, sname=self.get_kpasswd_sname(), -+ kdc_options='0') -+ -+ expected_code = KPASSWD_SUCCESS -+ expected_msg = b'Password changed' -+ -+ # Change the password. -+ new_password = generate_random_password(32, 32) -+ self.kpasswd_exchange(ticket, -+ new_password, -+ expected_code, -+ expected_msg, -+ mode=self.KpasswdMode.CHANGE) -+ -+ # Check the lifetime of a kpasswd ticket is not more than two minutes. -+ def test_kpasswd_ticket_lifetime(self): -+ # Create an account for testing. -+ creds = self._get_creds() -+ -+ # Get an initial ticket to kpasswd. -+ ticket = self.get_tgt(creds, sname=self.get_kpasswd_sname(), -+ kdc_options='0') -+ -+ # Check the lifetime of the ticket is equal to two minutes. -+ lifetime = self.get_ticket_lifetime(ticket) -+ self.assertEqual(2 * 60, lifetime) -+ -+ # Ensure we cannot perform a TGS-REQ with a kpasswd ticket. -+ def test_kpasswd_ticket_tgs(self): -+ creds = self.get_client_creds() -+ -+ # Get an initial ticket to kpasswd. -+ ticket = self.get_tgt(creds, sname=self.get_kpasswd_sname(), -+ kdc_options='0') -+ -+ # Change the sname of the ticket to match that of a TGT. -+ realm = creds.get_realm() -+ krbtgt_sname = self.PrincipalName_create(name_type=NT_SRV_INST, -+ names=['krbtgt', realm]) -+ ticket.set_sname(krbtgt_sname) -+ -+ # Try to use that ticket to get a service ticket. -+ service_creds = self.get_service_creds() -+ -+ # This fails due to missing REQUESTER_SID buffer. -+ self._make_tgs_request(creds, service_creds, ticket, -+ expect_error=(KDC_ERR_TGT_REVOKED, -+ KDC_ERR_TKT_EXPIRED)) -+ -+ def modify_requester_sid_time(self, ticket, sid, lifetime): -+ # Get the krbtgt key. -+ krbtgt_creds = self.get_krbtgt_creds() -+ -+ krbtgt_key = self.TicketDecryptionKey_from_creds(krbtgt_creds) -+ checksum_keys = { -+ krb5pac.PAC_TYPE_KDC_CHECKSUM: krbtgt_key, -+ } -+ -+ # Set authtime and starttime to an hour in the past, to show that they -+ # do not affect ticket rejection. -+ start_time = self.get_KerberosTime(offset=-60 * 60) -+ -+ # Set the endtime of the ticket relative to our current time, so that -+ # the ticket has 'lifetime' seconds remaining to live. -+ end_time = self.get_KerberosTime(offset=lifetime) -+ -+ # Modify the times in the ticket. -+ def modify_ticket_times(enc_part): -+ enc_part['authtime'] = start_time -+ if 'starttime' in enc_part: -+ enc_part['starttime'] = start_time -+ -+ enc_part['endtime'] = end_time -+ -+ return enc_part -+ -+ # We have to set the times in both the ticket and the PAC, otherwise -+ # Heimdal will complain. -+ def modify_pac_time(pac): -+ pac_buffers = pac.buffers -+ -+ for pac_buffer in pac_buffers: -+ if pac_buffer.type == krb5pac.PAC_TYPE_LOGON_NAME: -+ logon_time = self.get_EpochFromKerberosTime(start_time) -+ pac_buffer.info.logon_time = unix2nttime(logon_time) -+ break -+ else: -+ self.fail('failed to find LOGON_NAME PAC buffer') -+ -+ pac.buffers = pac_buffers -+ -+ return pac -+ -+ # Add a requester SID to show that the KDC will then accept this -+ # kpasswd ticket as if it were a TGT. -+ def modify_pac_fn(pac): -+ pac = self.add_requester_sid(pac, sid=sid) -+ pac = modify_pac_time(pac) -+ return pac -+ -+ # Do the actual modification. -+ return self.modified_ticket(ticket, -+ new_ticket_key=krbtgt_key, -+ modify_fn=modify_ticket_times, -+ modify_pac_fn=modify_pac_fn, -+ checksum_keys=checksum_keys) -+ -+ # Ensure we cannot perform a TGS-REQ with a kpasswd ticket containing a -+ # requester SID and having a remaining lifetime of two minutes. -+ def test_kpasswd_ticket_requester_sid_tgs(self): -+ creds = self.get_client_creds() -+ -+ # Get an initial ticket to kpasswd. -+ ticket = self.get_tgt(creds, sname=self.get_kpasswd_sname(), -+ kdc_options='0') -+ -+ # Change the sname of the ticket to match that of a TGT. -+ realm = creds.get_realm() -+ krbtgt_sname = self.PrincipalName_create(name_type=NT_SRV_INST, -+ names=['krbtgt', realm]) -+ ticket.set_sname(krbtgt_sname) -+ -+ # Get the user's SID. -+ samdb = self.get_samdb() -+ -+ user_dn = creds.get_dn() -+ user_sid = self.get_objectSid(samdb, user_dn) -+ -+ # Modify the ticket to add a requester SID and give it two minutes to -+ # live. -+ ticket = self.modify_requester_sid_time(ticket, -+ sid=user_sid, -+ lifetime=2 * 60) -+ -+ # Try to use that ticket to get a service ticket. -+ service_creds = self.get_service_creds() -+ -+ # This fails due to the lifetime being too short. -+ self._make_tgs_request(creds, service_creds, ticket, -+ expect_error=KDC_ERR_TKT_EXPIRED) -+ -+ # Show we can perform a TGS-REQ with a kpasswd ticket containing a -+ # requester SID if the remaining lifetime exceeds two minutes. -+ def test_kpasswd_ticket_requester_sid_lifetime_tgs(self): -+ creds = self.get_client_creds() -+ -+ # Get an initial ticket to kpasswd. -+ ticket = self.get_tgt(creds, sname=self.get_kpasswd_sname(), -+ kdc_options='0') -+ -+ # Change the sname of the ticket to match that of a TGT. -+ realm = creds.get_realm() -+ krbtgt_sname = self.PrincipalName_create(name_type=NT_SRV_INST, -+ names=['krbtgt', realm]) -+ ticket.set_sname(krbtgt_sname) -+ -+ # Get the user's SID. -+ samdb = self.get_samdb() -+ -+ user_dn = creds.get_dn() -+ user_sid = self.get_objectSid(samdb, user_dn) -+ -+ # Modify the ticket to add a requester SID and give it two minutes and -+ # ten seconds to live. -+ ticket = self.modify_requester_sid_time(ticket, -+ sid=user_sid, -+ lifetime=2 * 60 + 10) -+ -+ # Try to use that ticket to get a service ticket. -+ service_creds = self.get_service_creds() -+ -+ # This succeeds. -+ self._make_tgs_request(creds, service_creds, ticket, -+ expect_error=False) -+ -+ # Test that kpasswd rejects requests with a service ticket. -+ def test_kpasswd_non_initial(self): -+ # Create an account for testing, and get a TGT. -+ creds = self._get_creds() -+ tgt = self.get_tgt(creds) -+ -+ # Get a non-initial ticket to kpasswd. -+ krbtgt_creds = self.get_krbtgt_creds() -+ ticket = self.get_service_ticket(tgt, -+ krbtgt_creds, -+ service='kadmin', -+ target_name='changepw', -+ kdc_options='0') -+ -+ expected_code = KPASSWD_INITIAL_FLAG_NEEDED -+ expected_msg = b'Expected an initial ticket' -+ -+ # Set the password. -+ new_password = generate_random_password(32, 32) -+ self.kpasswd_exchange(ticket, -+ new_password, -+ expected_code, -+ expected_msg, -+ mode=self.KpasswdMode.SET) -+ -+ # Change the password. -+ self.kpasswd_exchange(ticket, -+ new_password, -+ expected_code, -+ expected_msg, -+ mode=self.KpasswdMode.CHANGE) -+ -+ # Show that kpasswd accepts requests with a service ticket modified to set -+ # the 'initial' flag. -+ def test_kpasswd_initial(self): -+ # Create an account for testing, and get a TGT. -+ creds = self._get_creds() -+ -+ krbtgt_creds = self.get_krbtgt_creds() -+ -+ # Get a service ticket, and modify it to set the 'initial' flag. -+ def get_ticket(): -+ tgt = self.get_tgt(creds, fresh=True) -+ -+ # Get a non-initial ticket to kpasswd. -+ ticket = self.get_service_ticket(tgt, -+ krbtgt_creds, -+ service='kadmin', -+ target_name='changepw', -+ kdc_options='0', -+ fresh=True) -+ -+ set_initial_flag = partial(self.modify_ticket_flag, flag='initial', -+ value=True) -+ -+ checksum_keys = self.get_krbtgt_checksum_key() -+ return self.modified_ticket(ticket, -+ modify_fn=set_initial_flag, -+ checksum_keys=checksum_keys) -+ -+ expected_code = KPASSWD_SUCCESS -+ expected_msg = b'Password changed' -+ -+ ticket = get_ticket() -+ -+ # Set the password. -+ new_password = generate_random_password(32, 32) -+ self.kpasswd_exchange(ticket, -+ new_password, -+ expected_code, -+ expected_msg, -+ mode=self.KpasswdMode.SET) -+ -+ creds.update_password(new_password) -+ ticket = get_ticket() -+ -+ # Change the password. -+ new_password = generate_random_password(32, 32) -+ self.kpasswd_exchange(ticket, -+ new_password, -+ expected_code, -+ expected_msg, -+ mode=self.KpasswdMode.CHANGE) -+ -+ # Test that kpasswd rejects requests where the ticket is encrypted with a -+ # key other than the krbtgt's. -+ def test_kpasswd_wrong_key(self): -+ # Create an account for testing. -+ creds = self._get_creds() -+ -+ sname = self.get_kpasswd_sname() -+ -+ # Get an initial ticket to kpasswd. -+ ticket = self.get_tgt(creds, sname=sname, -+ kdc_options='0') -+ -+ # Get a key belonging to the Administrator account. -+ admin_creds = self.get_admin_creds() -+ admin_key = self.TicketDecryptionKey_from_creds(admin_creds) -+ self.assertIsNotNone(admin_key.kvno, -+ 'a kvno is required to tell the DB ' -+ 'which key to look up.') -+ checksum_keys = { -+ krb5pac.PAC_TYPE_KDC_CHECKSUM: admin_key, -+ } -+ -+ # Re-encrypt the ticket using the Administrator's key. -+ ticket = self.modified_ticket(ticket, -+ new_ticket_key=admin_key, -+ checksum_keys=checksum_keys) -+ -+ # Set the sname of the ticket to that of the Administrator account. -+ admin_sname = self.PrincipalName_create(name_type=NT_PRINCIPAL, -+ names=['Administrator']) -+ ticket.set_sname(admin_sname) -+ -+ expected_code = KPASSWD_HARDERROR -+ expected_msg = b'gensec_update failed - NT_STATUS_LOGON_FAILURE\n' -+ -+ # Set the password. -+ new_password = generate_random_password(32, 32) -+ self.kpasswd_exchange(ticket, -+ new_password, -+ expected_code, -+ expected_msg, -+ mode=self.KpasswdMode.SET) -+ -+ # Change the password. -+ self.kpasswd_exchange(ticket, -+ new_password, -+ expected_code, -+ expected_msg, -+ mode=self.KpasswdMode.CHANGE) -+ -+ def test_kpasswd_wrong_key_service(self): -+ # Create an account for testing. -+ creds = self.get_cached_creds(account_type=self.AccountType.COMPUTER, -+ use_cache=False) -+ -+ sname = self.get_kpasswd_sname() -+ -+ # Get an initial ticket to kpasswd. -+ ticket = self.get_tgt(creds, sname=sname, -+ kdc_options='0') -+ -+ # Get a key belonging to our account. -+ our_key = self.TicketDecryptionKey_from_creds(creds) -+ self.assertIsNotNone(our_key.kvno, -+ 'a kvno is required to tell the DB ' -+ 'which key to look up.') -+ checksum_keys = { -+ krb5pac.PAC_TYPE_KDC_CHECKSUM: our_key, -+ } -+ -+ # Re-encrypt the ticket using our key. -+ ticket = self.modified_ticket(ticket, -+ new_ticket_key=our_key, -+ checksum_keys=checksum_keys) -+ -+ # Set the sname of the ticket to that of our account. -+ username = creds.get_username() -+ sname = self.PrincipalName_create(name_type=NT_PRINCIPAL, -+ names=username.split('/')) -+ ticket.set_sname(sname) -+ -+ expected_code = KPASSWD_HARDERROR -+ expected_msg = b'gensec_update failed - NT_STATUS_LOGON_FAILURE\n' -+ -+ # Set the password. -+ new_password = generate_random_password(32, 32) -+ self.kpasswd_exchange(ticket, -+ new_password, -+ expected_code, -+ expected_msg, -+ mode=self.KpasswdMode.SET) -+ -+ # Change the password. -+ self.kpasswd_exchange(ticket, -+ new_password, -+ expected_code, -+ expected_msg, -+ mode=self.KpasswdMode.CHANGE) -+ -+ # Test that kpasswd rejects requests where the ticket is encrypted with a -+ # key belonging to a server account other than the krbtgt. -+ def test_kpasswd_wrong_key_server(self): -+ # Create an account for testing. -+ creds = self._get_creds() -+ -+ sname = self.get_kpasswd_sname() -+ -+ # Get an initial ticket to kpasswd. -+ ticket = self.get_tgt(creds, sname=sname, -+ kdc_options='0') -+ -+ # Get a key belonging to the DC's account. -+ dc_creds = self.get_dc_creds() -+ dc_key = self.TicketDecryptionKey_from_creds(dc_creds) -+ self.assertIsNotNone(dc_key.kvno, -+ 'a kvno is required to tell the DB ' -+ 'which key to look up.') -+ checksum_keys = { -+ krb5pac.PAC_TYPE_KDC_CHECKSUM: dc_key, -+ } -+ -+ # Re-encrypt the ticket using the DC's key. -+ ticket = self.modified_ticket(ticket, -+ new_ticket_key=dc_key, -+ checksum_keys=checksum_keys) -+ -+ # Set the sname of the ticket to that of the DC's account. -+ dc_username = dc_creds.get_username() -+ dc_sname = self.PrincipalName_create(name_type=NT_PRINCIPAL, -+ names=dc_username.split('/')) -+ ticket.set_sname(dc_sname) -+ -+ expected_code = KPASSWD_HARDERROR -+ expected_msg = b'gensec_update failed - NT_STATUS_LOGON_FAILURE\n' -+ -+ # Set the password. -+ new_password = generate_random_password(32, 32) -+ self.kpasswd_exchange(ticket, -+ new_password, -+ expected_code, -+ expected_msg, -+ mode=self.KpasswdMode.SET) -+ -+ # Change the password. -+ self.kpasswd_exchange(ticket, -+ new_password, -+ expected_code, -+ expected_msg, -+ mode=self.KpasswdMode.CHANGE) -+ -+ -+if __name__ == '__main__': -+ global_asn1_print = False -+ global_hexdump = False -+ import unittest -+ unittest.main() -diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py -index 57010ae73bd..4a78a8eadf3 100644 ---- a/python/samba/tests/krb5/raw_testcase.py -+++ b/python/samba/tests/krb5/raw_testcase.py -@@ -500,6 +500,10 @@ class KerberosCredentials(Credentials): - def get_upn(self): - return self.upn - -+ def update_password(self, password): -+ self.set_password(password) -+ self.set_kvno(self.get_kvno() + 1) -+ - - class KerberosTicketCreds: - def __init__(self, ticket, session_key, -@@ -518,6 +522,10 @@ class KerberosTicketCreds: - self.ticket_private = ticket_private - self.encpart_private = encpart_private - -+ def set_sname(self, sname): -+ self.ticket['sname'] = sname -+ self.sname = sname -+ - - class RawKerberosTest(TestCaseInTempDir): - """A raw Kerberos Test case.""" -diff --git a/python/samba/tests/usage.py b/python/samba/tests/usage.py -index 6bbd96e7a08..a1210ada579 100644 ---- a/python/samba/tests/usage.py -+++ b/python/samba/tests/usage.py -@@ -109,6 +109,7 @@ EXCLUDE_USAGE = { - 'python/samba/tests/krb5/alias_tests.py', - 'python/samba/tests/krb5/test_min_domain_uid.py', - 'python/samba/tests/krb5/test_idmap_nss.py', -+ 'python/samba/tests/krb5/kpasswd_tests.py', - } - - EXCLUDE_HELP = { -diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc -index 692b9ecdd72..9f2b855af4c 100644 ---- a/selftest/knownfail_heimdal_kdc -+++ b/selftest/knownfail_heimdal_kdc -@@ -109,3 +109,29 @@ - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_service_ticket - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_sid_mismatch_existing - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_sid_mismatch_nonexisting -+# -+# Kpasswd tests -+# -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_canonicalize.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_canonicalize_realm_case.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_change.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_change_expired_password.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_empty.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_from_rodc.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_initial.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_no_canonicalize.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_no_canonicalize_realm_case.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_no_seq_number.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_non_initial.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_set.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_set_expired_password.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_set_target_princ_and_realm_access.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_set_target_princ_and_realm_no_access.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_set_target_princ_only.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_set_target_realm_only.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_ticket_lifetime.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_ticket_requester_sid_tgs.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_too_weak.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key_server.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key_service.ad_dc -diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc -index 095da10238c..c8187ba5db3 100644 ---- a/selftest/knownfail_mit_kdc -+++ b/selftest/knownfail_mit_kdc -@@ -541,3 +541,29 @@ 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_tgs_rodc_logon_info_sid_mismatch_nonexisting - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_requester_sid_mismatch_existing - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_requester_sid_mismatch_nonexisting -+# -+# Kpasswd tests -+# -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_canonicalize.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_canonicalize_realm_case.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_change.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_change_expired_password.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_empty.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_from_rodc.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_initial.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_no_canonicalize.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_no_canonicalize_realm_case.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_no_seq_number.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_non_initial.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_set.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_set_expired_password.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_set_target_princ_and_realm_access.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_set_target_princ_and_realm_no_access.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_set_target_princ_only.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_set_target_realm_only.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_ticket_lifetime.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_ticket_requester_sid_tgs.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_too_weak.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key_server.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key_service.ad_dc -diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py -index c5fdf7fe294..102b17f5376 100755 ---- a/source4/selftest/tests.py -+++ b/source4/selftest/tests.py -@@ -1590,6 +1590,10 @@ planpythontestsuite( - "ad_dc", - "samba.tests.krb5.alias_tests", - environ=krb5_environ) -+planoldpythontestsuite( -+ 'ad_dc', -+ 'samba.tests.krb5.kpasswd_tests', -+ environ=krb5_environ) - - for env in [ - 'vampire_dc', --- -2.25.1 - - -From 2ee46c16d2aa706b686b50ccb66a2a3ad9852c50 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Fri, 27 May 2022 19:21:06 +1200 -Subject: [PATCH 72/99] CVE-2022-2031 s4:kpasswd: Correctly generate error - strings - -The error_data we create already has an explicit length, and should not -be zero-terminated, so we omit the trailing null byte. Previously, -Heimdal builds would leave a superfluous trailing null byte on error -strings, while MIT builds would omit the final character. - -The two bytes added to the string's length are for the prepended error -code. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15047 -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15049 -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15074 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andreas Schneider - -[jsutton@samba.org Removed MIT KDC 1.20-specific knownfails] ---- - selftest/knownfail_heimdal_kdc | 12 ------------ - selftest/knownfail_mit_kdc | 15 --------------- - source4/kdc/kpasswd-helper.c | 13 ++++++------- - 3 files changed, 6 insertions(+), 34 deletions(-) - -diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc -index 9f2b855af4c..5fd6e4aa0ed 100644 ---- a/selftest/knownfail_heimdal_kdc -+++ b/selftest/knownfail_heimdal_kdc -@@ -114,24 +114,12 @@ - # - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_canonicalize.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_canonicalize_realm_case.ad_dc --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_change.ad_dc --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_change_expired_password.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_empty.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_from_rodc.ad_dc --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_initial.ad_dc --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_no_canonicalize.ad_dc --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_no_canonicalize_realm_case.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_no_seq_number.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_non_initial.ad_dc --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_set.ad_dc --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_set_expired_password.ad_dc --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_set_target_princ_and_realm_access.ad_dc --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_set_target_princ_and_realm_no_access.ad_dc --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_set_target_princ_only.ad_dc --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_set_target_realm_only.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_ticket_lifetime.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_ticket_requester_sid_tgs.ad_dc --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_too_weak.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key_server.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key_service.ad_dc -diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc -index c8187ba5db3..6c8d6e45cdd 100644 ---- a/selftest/knownfail_mit_kdc -+++ b/selftest/knownfail_mit_kdc -@@ -544,26 +544,11 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ - # - # Kpasswd tests - # --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_canonicalize.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_canonicalize_realm_case.ad_dc --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_change.ad_dc --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_change_expired_password.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_empty.ad_dc --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_from_rodc.ad_dc --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_initial.ad_dc --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_no_canonicalize.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_no_canonicalize_realm_case.ad_dc --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_no_seq_number.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_non_initial.ad_dc --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_set.ad_dc --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_set_expired_password.ad_dc --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_set_target_princ_and_realm_access.ad_dc --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_set_target_princ_and_realm_no_access.ad_dc --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_set_target_princ_only.ad_dc --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_set_target_realm_only.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_ticket_lifetime.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_ticket_requester_sid_tgs.ad_dc --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_too_weak.ad_dc --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key_server.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key_service.ad_dc -diff --git a/source4/kdc/kpasswd-helper.c b/source4/kdc/kpasswd-helper.c -index 995f54825b5..55a2f5b3bf6 100644 ---- a/source4/kdc/kpasswd-helper.c -+++ b/source4/kdc/kpasswd-helper.c -@@ -48,17 +48,16 @@ bool kpasswd_make_error_reply(TALLOC_CTX *mem_ctx, - } - - /* -- * The string 's' has two terminating nul-bytes which are also -- * reflected by 'slen'. Normally Kerberos doesn't expect that strings -- * are nul-terminated, but Heimdal does! -+ * The string 's' has one terminating nul-byte which is also -+ * reflected by 'slen'. We subtract it from the length. - */ --#ifndef SAMBA4_USES_HEIMDAL -- if (slen < 2) { -+ if (slen < 1) { - talloc_free(s); - return false; - } -- slen -= 2; --#endif -+ slen--; -+ -+ /* Two bytes are added to the length to account for the error code. */ - if (2 + slen < slen) { - talloc_free(s); - return false; --- -2.25.1 - - -From b1003099c202d05b7d3f570fe313039aebdec3f9 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Wed, 18 May 2022 16:48:59 +1200 -Subject: [PATCH 73/99] CVE-2022-2031 s4:kpasswd: Don't return AP-REP on - failure - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15047 -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15049 -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15074 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andreas Schneider - -[jsutton@samba.org Removed MIT KDC 1.20-specific knownfails] ---- - selftest/knownfail_mit_kdc | 1 - - source4/kdc/kpasswd-service.c | 2 ++ - 2 files changed, 2 insertions(+), 1 deletion(-) - -diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc -index 6c8d6e45cdd..41a793ae082 100644 ---- a/selftest/knownfail_mit_kdc -+++ b/selftest/knownfail_mit_kdc -@@ -545,7 +545,6 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ - # Kpasswd tests - # - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_canonicalize_realm_case.ad_dc --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_empty.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_no_canonicalize_realm_case.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_non_initial.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_ticket_lifetime.ad_dc -diff --git a/source4/kdc/kpasswd-service.c b/source4/kdc/kpasswd-service.c -index 061aedc80e5..22e1295c11e 100644 ---- a/source4/kdc/kpasswd-service.c -+++ b/source4/kdc/kpasswd-service.c -@@ -256,6 +256,7 @@ kdc_code kpasswd_process(struct kdc_server *kdc, - &kpasswd_dec_reply, - &error_string); - if (code != 0) { -+ ap_rep_blob = data_blob_null; - error_code = code; - goto reply; - } -@@ -265,6 +266,7 @@ kdc_code kpasswd_process(struct kdc_server *kdc, - &kpasswd_dec_reply, - &enc_data_blob); - if (!NT_STATUS_IS_OK(status)) { -+ ap_rep_blob = data_blob_null; - error_code = KRB5_KPASSWD_HARDERROR; - error_string = talloc_asprintf(tmp_ctx, - "gensec_wrap failed - %s\n", --- -2.25.1 - - -From 38c83abffd325ee23649c190b8ffb3d27a2bdb68 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Fri, 27 May 2022 19:29:34 +1200 -Subject: [PATCH 74/99] CVE-2022-2031 lib:krb5_wrap: Generate valid error codes - in smb_krb5_mk_error() - -The error code passed in will be an offset from ERROR_TABLE_BASE_krb5, -so we need to subtract that before creating the error. Heimdal does this -internally, so it isn't needed there. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15047 -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15049 -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15074 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andreas Schneider ---- - lib/krb5_wrap/krb5_samba.c | 2 +- - selftest/knownfail_mit_kdc | 4 ++++ - 2 files changed, 5 insertions(+), 1 deletion(-) - -diff --git a/lib/krb5_wrap/krb5_samba.c b/lib/krb5_wrap/krb5_samba.c -index 76c2dcd2126..610efcc9b87 100644 ---- a/lib/krb5_wrap/krb5_samba.c -+++ b/lib/krb5_wrap/krb5_samba.c -@@ -237,7 +237,7 @@ krb5_error_code smb_krb5_mk_error(krb5_context context, - return code; - } - -- errpkt.error = error_code; -+ errpkt.error = error_code - ERROR_TABLE_BASE_krb5; - - errpkt.text.length = 0; - if (e_text != NULL) { -diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc -index 41a793ae082..e4300b4d20e 100644 ---- a/selftest/knownfail_mit_kdc -+++ b/selftest/knownfail_mit_kdc -@@ -545,9 +545,13 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ - # Kpasswd tests - # - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_canonicalize_realm_case.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_empty.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_from_rodc.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_no_canonicalize_realm_case.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_no_seq_number.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_non_initial.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_ticket_lifetime.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_ticket_requester_sid_tgs.ad_dc -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key_server.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key_service.ad_dc --- -2.25.1 - - -From 481a70c37464d356f60a30c5f51ffae755c4e6f0 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Wed, 18 May 2022 16:49:43 +1200 -Subject: [PATCH 75/99] CVE-2022-2031 s4:kpasswd: Return a kpasswd error code - in KRB-ERROR - -If we attempt to return an error code outside of Heimdal's allowed range -[KRB5KDC_ERR_NONE, KRB5_ERR_RCSID), it will be replaced with a GENERIC -error, and the error text will be set to the meaningless result of -krb5_get_error_message(). Avoid this by ensuring the error code is in -the correct range. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15047 -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15049 -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15074 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andreas Schneider ---- - selftest/knownfail_heimdal_kdc | 2 -- - selftest/knownfail_mit_kdc | 4 ---- - source4/kdc/kpasswd-service.c | 2 +- - 3 files changed, 1 insertion(+), 7 deletions(-) - -diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc -index 5fd6e4aa0ed..cb4f190d75f 100644 ---- a/selftest/knownfail_heimdal_kdc -+++ b/selftest/knownfail_heimdal_kdc -@@ -114,9 +114,7 @@ - # - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_canonicalize.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_canonicalize_realm_case.ad_dc --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_empty.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_from_rodc.ad_dc --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_no_seq_number.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_non_initial.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_ticket_lifetime.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_ticket_requester_sid_tgs.ad_dc -diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc -index e4300b4d20e..41a793ae082 100644 ---- a/selftest/knownfail_mit_kdc -+++ b/selftest/knownfail_mit_kdc -@@ -545,13 +545,9 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ - # Kpasswd tests - # - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_canonicalize_realm_case.ad_dc --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_empty.ad_dc --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_from_rodc.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_no_canonicalize_realm_case.ad_dc --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_no_seq_number.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_non_initial.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_ticket_lifetime.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_ticket_requester_sid_tgs.ad_dc --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key_server.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key_service.ad_dc -diff --git a/source4/kdc/kpasswd-service.c b/source4/kdc/kpasswd-service.c -index 22e1295c11e..379ddebf3ad 100644 ---- a/source4/kdc/kpasswd-service.c -+++ b/source4/kdc/kpasswd-service.c -@@ -315,7 +315,7 @@ reply: - } - - code = smb_krb5_mk_error(kdc->smb_krb5_context->krb5_context, -- error_code, -+ KRB5KDC_ERR_NONE + error_code, - NULL, /* e_text */ - &k_dec_data, - NULL, /* client */ --- -2.25.1 - - -From 9da789c73dd6675789b93fc0df0dfc8b274a86c3 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Wed, 18 May 2022 16:06:31 +1200 -Subject: [PATCH 76/99] CVE-2022-2031 gensec_krb5: Add helper function to check - if client sent an initial ticket - -This will be used in the kpasswd service to ensure that the client has -an initial ticket to kadmin/changepw, and not a service ticket. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15047 -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15049 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andreas Schneider ---- - source4/auth/gensec/gensec_krb5.c | 20 +----- - source4/auth/gensec/gensec_krb5_helpers.c | 72 ++++++++++++++++++++++ - source4/auth/gensec/gensec_krb5_helpers.h | 32 ++++++++++ - source4/auth/gensec/gensec_krb5_internal.h | 47 ++++++++++++++ - source4/auth/gensec/wscript_build | 4 ++ - 5 files changed, 157 insertions(+), 18 deletions(-) - create mode 100644 source4/auth/gensec/gensec_krb5_helpers.c - create mode 100644 source4/auth/gensec/gensec_krb5_helpers.h - create mode 100644 source4/auth/gensec/gensec_krb5_internal.h - -diff --git a/source4/auth/gensec/gensec_krb5.c b/source4/auth/gensec/gensec_krb5.c -index 7d87b3ac6b9..104e4639c44 100644 ---- a/source4/auth/gensec/gensec_krb5.c -+++ b/source4/auth/gensec/gensec_krb5.c -@@ -44,27 +44,11 @@ - #include "../lib/util/asn1.h" - #include "auth/kerberos/pac_utils.h" - #include "gensec_krb5.h" -+#include "gensec_krb5_internal.h" -+#include "gensec_krb5_helpers.h" - - _PUBLIC_ NTSTATUS gensec_krb5_init(TALLOC_CTX *); - --enum GENSEC_KRB5_STATE { -- GENSEC_KRB5_SERVER_START, -- GENSEC_KRB5_CLIENT_START, -- GENSEC_KRB5_CLIENT_MUTUAL_AUTH, -- GENSEC_KRB5_DONE --}; -- --struct gensec_krb5_state { -- enum GENSEC_KRB5_STATE state_position; -- struct smb_krb5_context *smb_krb5_context; -- krb5_auth_context auth_context; -- krb5_data enc_ticket; -- krb5_keyblock *keyblock; -- krb5_ticket *ticket; -- bool gssapi; -- krb5_flags ap_req_options; --}; -- - static int gensec_krb5_destroy(struct gensec_krb5_state *gensec_krb5_state) - { - if (!gensec_krb5_state->smb_krb5_context) { -diff --git a/source4/auth/gensec/gensec_krb5_helpers.c b/source4/auth/gensec/gensec_krb5_helpers.c -new file mode 100644 -index 00000000000..21f2f1e884e ---- /dev/null -+++ b/source4/auth/gensec/gensec_krb5_helpers.c -@@ -0,0 +1,72 @@ -+/* -+ Unix SMB/CIFS implementation. -+ -+ Kerberos backend for GENSEC -+ -+ Copyright (C) Andrew Bartlett 2004 -+ Copyright (C) Andrew Tridgell 2001 -+ Copyright (C) Luke Howard 2002-2003 -+ Copyright (C) Stefan Metzmacher 2004-2005 -+ -+ 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 . -+*/ -+ -+#include "includes.h" -+#include "auth/auth.h" -+#include "auth/gensec/gensec.h" -+#include "auth/gensec/gensec_internal.h" -+#include "gensec_krb5_internal.h" -+#include "gensec_krb5_helpers.h" -+#include "system/kerberos.h" -+#include "auth/kerberos/kerberos.h" -+ -+static struct gensec_krb5_state *get_private_state(const struct gensec_security *gensec_security) -+{ -+ struct gensec_krb5_state *gensec_krb5_state = NULL; -+ -+ if (strcmp(gensec_security->ops->name, "krb5") != 0) { -+ /* We require that the krb5 mechanism is being used. */ -+ return NULL; -+ } -+ -+ gensec_krb5_state = talloc_get_type(gensec_security->private_data, -+ struct gensec_krb5_state); -+ return gensec_krb5_state; -+} -+ -+/* -+ * Returns 1 if our ticket has the initial flag set, 0 if not, and -1 in case of -+ * error. -+ */ -+int gensec_krb5_initial_ticket(const struct gensec_security *gensec_security) -+{ -+ struct gensec_krb5_state *gensec_krb5_state = NULL; -+ -+ gensec_krb5_state = get_private_state(gensec_security); -+ if (gensec_krb5_state == NULL) { -+ return -1; -+ } -+ -+ if (gensec_krb5_state->ticket == NULL) { -+ /* We don't have a ticket */ -+ return -1; -+ } -+ -+#ifdef SAMBA4_USES_HEIMDAL -+ return gensec_krb5_state->ticket->ticket.flags.initial; -+#else /* MIT KERBEROS */ -+ return (gensec_krb5_state->ticket->enc_part2->flags & TKT_FLG_INITIAL) ? 1 : 0; -+#endif /* SAMBA4_USES_HEIMDAL */ -+} -diff --git a/source4/auth/gensec/gensec_krb5_helpers.h b/source4/auth/gensec/gensec_krb5_helpers.h -new file mode 100644 -index 00000000000..d7b694dad0c ---- /dev/null -+++ b/source4/auth/gensec/gensec_krb5_helpers.h -@@ -0,0 +1,32 @@ -+/* -+ Unix SMB/CIFS implementation. -+ -+ Kerberos backend for GENSEC -+ -+ Copyright (C) Andrew Bartlett 2004 -+ Copyright (C) Andrew Tridgell 2001 -+ Copyright (C) Luke Howard 2002-2003 -+ Copyright (C) Stefan Metzmacher 2004-2005 -+ -+ 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 . -+*/ -+ -+struct gensec_security; -+ -+/* -+ * Returns 1 if our ticket has the initial flag set, 0 if not, and -1 in case of -+ * error. -+ */ -+int gensec_krb5_initial_ticket(const struct gensec_security *gensec_security); -diff --git a/source4/auth/gensec/gensec_krb5_internal.h b/source4/auth/gensec/gensec_krb5_internal.h -new file mode 100644 -index 00000000000..0bb796f1b2a ---- /dev/null -+++ b/source4/auth/gensec/gensec_krb5_internal.h -@@ -0,0 +1,47 @@ -+/* -+ Unix SMB/CIFS implementation. -+ -+ Kerberos backend for GENSEC -+ -+ Copyright (C) Andrew Bartlett 2004 -+ Copyright (C) Andrew Tridgell 2001 -+ Copyright (C) Luke Howard 2002-2003 -+ Copyright (C) Stefan Metzmacher 2004-2005 -+ -+ 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 . -+*/ -+ -+#include "includes.h" -+#include "auth/gensec/gensec.h" -+#include "system/kerberos.h" -+#include "auth/kerberos/kerberos.h" -+ -+enum GENSEC_KRB5_STATE { -+ GENSEC_KRB5_SERVER_START, -+ GENSEC_KRB5_CLIENT_START, -+ GENSEC_KRB5_CLIENT_MUTUAL_AUTH, -+ GENSEC_KRB5_DONE -+}; -+ -+struct gensec_krb5_state { -+ enum GENSEC_KRB5_STATE state_position; -+ struct smb_krb5_context *smb_krb5_context; -+ krb5_auth_context auth_context; -+ krb5_data enc_ticket; -+ krb5_keyblock *keyblock; -+ krb5_ticket *ticket; -+ bool gssapi; -+ krb5_flags ap_req_options; -+}; -diff --git a/source4/auth/gensec/wscript_build b/source4/auth/gensec/wscript_build -index d14a50ff273..20271f1665b 100644 ---- a/source4/auth/gensec/wscript_build -+++ b/source4/auth/gensec/wscript_build -@@ -18,6 +18,10 @@ bld.SAMBA_MODULE('gensec_krb5', - enabled=bld.AD_DC_BUILD_IS_ENABLED() - ) - -+bld.SAMBA_SUBSYSTEM('gensec_krb5_helpers', -+ source='gensec_krb5_helpers.c', -+ deps='gensec_krb5', -+ enabled=bld.AD_DC_BUILD_IS_ENABLED()) - - bld.SAMBA_MODULE('gensec_gssapi', - source='gensec_gssapi.c', --- -2.25.1 - - -From 298884abb35db7b6a8c6100dfd7bb8b57b1117fd Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Wed, 18 May 2022 16:52:41 +1200 -Subject: [PATCH 77/99] CVE-2022-2031 s4:kpasswd: Require an initial ticket - -Ensure that for password changes the client uses an AS-REQ to get the -ticket to kpasswd, and not a TGS-REQ. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15047 -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15049 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andreas Schneider - -[jsutton@samba.org Removed MIT KDC 1.20-specific knownfails] ---- - selftest/knownfail_heimdal_kdc | 1 - - selftest/knownfail_mit_kdc | 1 - - source4/kdc/kpasswd-service-heimdal.c | 17 +++++++++++++++++ - source4/kdc/kpasswd-service-mit.c | 17 +++++++++++++++++ - source4/kdc/wscript_build | 1 + - 5 files changed, 35 insertions(+), 2 deletions(-) - -diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc -index cb4f190d75f..ab7230060ab 100644 ---- a/selftest/knownfail_heimdal_kdc -+++ b/selftest/knownfail_heimdal_kdc -@@ -115,7 +115,6 @@ - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_canonicalize.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_canonicalize_realm_case.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_from_rodc.ad_dc --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_non_initial.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_ticket_lifetime.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_ticket_requester_sid_tgs.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key.ad_dc -diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc -index 41a793ae082..0389672e5d9 100644 ---- a/selftest/knownfail_mit_kdc -+++ b/selftest/knownfail_mit_kdc -@@ -546,7 +546,6 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ - # - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_canonicalize_realm_case.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_no_canonicalize_realm_case.ad_dc --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_non_initial.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_ticket_lifetime.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_ticket_requester_sid_tgs.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key_server.ad_dc -diff --git a/source4/kdc/kpasswd-service-heimdal.c b/source4/kdc/kpasswd-service-heimdal.c -index c804852c3a7..1a6c2b60d03 100644 ---- a/source4/kdc/kpasswd-service-heimdal.c -+++ b/source4/kdc/kpasswd-service-heimdal.c -@@ -24,6 +24,7 @@ - #include "param/param.h" - #include "auth/auth.h" - #include "auth/gensec/gensec.h" -+#include "gensec_krb5_helpers.h" - #include "kdc/kdc-server.h" - #include "kdc/kpasswd_glue.h" - #include "kdc/kpasswd-service.h" -@@ -31,6 +32,7 @@ - - static krb5_error_code kpasswd_change_password(struct kdc_server *kdc, - TALLOC_CTX *mem_ctx, -+ const struct gensec_security *gensec_security, - struct auth_session_info *session_info, - DATA_BLOB *password, - DATA_BLOB *kpasswd_reply, -@@ -42,6 +44,17 @@ static krb5_error_code kpasswd_change_password(struct kdc_server *kdc, - const char *reject_string = NULL; - struct samr_DomInfo1 *dominfo; - bool ok; -+ int ret; -+ -+ /* -+ * We're doing a password change (rather than a password set), so check -+ * that we were given an initial ticket. -+ */ -+ ret = gensec_krb5_initial_ticket(gensec_security); -+ if (ret != 1) { -+ *error_string = "Expected an initial ticket"; -+ return KRB5_KPASSWD_INITIAL_FLAG_NEEDED; -+ } - - status = samdb_kpasswd_change_password(mem_ctx, - kdc->task->lp_ctx, -@@ -81,6 +94,7 @@ static krb5_error_code kpasswd_change_password(struct kdc_server *kdc, - - static krb5_error_code kpasswd_set_password(struct kdc_server *kdc, - TALLOC_CTX *mem_ctx, -+ const struct gensec_security *gensec_security, - struct auth_session_info *session_info, - DATA_BLOB *decoded_data, - DATA_BLOB *kpasswd_reply, -@@ -173,6 +187,7 @@ static krb5_error_code kpasswd_set_password(struct kdc_server *kdc, - free_ChangePasswdDataMS(&chpw); - return kpasswd_change_password(kdc, - mem_ctx, -+ gensec_security, - session_info, - &password, - kpasswd_reply, -@@ -272,6 +287,7 @@ krb5_error_code kpasswd_handle_request(struct kdc_server *kdc, - - return kpasswd_change_password(kdc, - mem_ctx, -+ gensec_security, - session_info, - &password, - kpasswd_reply, -@@ -280,6 +296,7 @@ krb5_error_code kpasswd_handle_request(struct kdc_server *kdc, - case KRB5_KPASSWD_VERS_SETPW: { - return kpasswd_set_password(kdc, - mem_ctx, -+ gensec_security, - session_info, - decoded_data, - kpasswd_reply, -diff --git a/source4/kdc/kpasswd-service-mit.c b/source4/kdc/kpasswd-service-mit.c -index 9c4d2801669..de4c6f3f622 100644 ---- a/source4/kdc/kpasswd-service-mit.c -+++ b/source4/kdc/kpasswd-service-mit.c -@@ -24,6 +24,7 @@ - #include "param/param.h" - #include "auth/auth.h" - #include "auth/gensec/gensec.h" -+#include "gensec_krb5_helpers.h" - #include "kdc/kdc-server.h" - #include "kdc/kpasswd_glue.h" - #include "kdc/kpasswd-service.h" -@@ -84,6 +85,7 @@ out: - - static krb5_error_code kpasswd_change_password(struct kdc_server *kdc, - TALLOC_CTX *mem_ctx, -+ const struct gensec_security *gensec_security, - struct auth_session_info *session_info, - DATA_BLOB *password, - DATA_BLOB *kpasswd_reply, -@@ -95,6 +97,17 @@ static krb5_error_code kpasswd_change_password(struct kdc_server *kdc, - const char *reject_string = NULL; - struct samr_DomInfo1 *dominfo; - bool ok; -+ int ret; -+ -+ /* -+ * We're doing a password change (rather than a password set), so check -+ * that we were given an initial ticket. -+ */ -+ ret = gensec_krb5_initial_ticket(gensec_security); -+ if (ret != 1) { -+ *error_string = "Expected an initial ticket"; -+ return KRB5_KPASSWD_INITIAL_FLAG_NEEDED; -+ } - - status = samdb_kpasswd_change_password(mem_ctx, - kdc->task->lp_ctx, -@@ -134,6 +147,7 @@ static krb5_error_code kpasswd_change_password(struct kdc_server *kdc, - - static krb5_error_code kpasswd_set_password(struct kdc_server *kdc, - TALLOC_CTX *mem_ctx, -+ const struct gensec_security *gensec_security, - struct auth_session_info *session_info, - DATA_BLOB *decoded_data, - DATA_BLOB *kpasswd_reply, -@@ -250,6 +264,7 @@ static krb5_error_code kpasswd_set_password(struct kdc_server *kdc, - - return kpasswd_change_password(kdc, - mem_ctx, -+ gensec_security, - session_info, - &password, - kpasswd_reply, -@@ -350,6 +365,7 @@ krb5_error_code kpasswd_handle_request(struct kdc_server *kdc, - - return kpasswd_change_password(kdc, - mem_ctx, -+ gensec_security, - session_info, - &password, - kpasswd_reply, -@@ -358,6 +374,7 @@ krb5_error_code kpasswd_handle_request(struct kdc_server *kdc, - case RFC3244_VERSION: { - return kpasswd_set_password(kdc, - mem_ctx, -+ gensec_security, - session_info, - decoded_data, - kpasswd_reply, -diff --git a/source4/kdc/wscript_build b/source4/kdc/wscript_build -index 0edca94e75f..13ba3947cf6 100644 ---- a/source4/kdc/wscript_build -+++ b/source4/kdc/wscript_build -@@ -88,6 +88,7 @@ bld.SAMBA_SUBSYSTEM('KPASSWD-SERVICE', - krb5samba - samba_server_gensec - KPASSWD_GLUE -+ gensec_krb5_helpers - ''') - - bld.SAMBA_SUBSYSTEM('KDC-GLUE', --- -2.25.1 - - -From a1df5b86e967dc190af5ba2ba07d8ef8b400b4b1 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Wed, 18 May 2022 17:11:49 +1200 -Subject: [PATCH 78/99] s4:kpasswd: Restructure code for clarity - -View with 'git show -b'. - -Signed-off-by: Joseph Sutton -Reviewed-by: Andreas Schneider ---- - source4/kdc/kpasswd-service-heimdal.c | 46 +++++++++++++-------------- - 1 file changed, 22 insertions(+), 24 deletions(-) - -diff --git a/source4/kdc/kpasswd-service-heimdal.c b/source4/kdc/kpasswd-service-heimdal.c -index 1a6c2b60d03..a0352d1ad35 100644 ---- a/source4/kdc/kpasswd-service-heimdal.c -+++ b/source4/kdc/kpasswd-service-heimdal.c -@@ -160,30 +160,7 @@ static krb5_error_code kpasswd_set_password(struct kdc_server *kdc, - return 0; - } - -- if (chpw.targname != NULL && chpw.targrealm != NULL) { -- code = krb5_build_principal_ext(context, -- &target_principal, -- strlen(*chpw.targrealm), -- *chpw.targrealm, -- 0); -- if (code != 0) { -- free_ChangePasswdDataMS(&chpw); -- return kpasswd_make_error_reply(mem_ctx, -- KRB5_KPASSWD_MALFORMED, -- "Failed to parse principal", -- kpasswd_reply); -- } -- code = copy_PrincipalName(chpw.targname, -- &target_principal->name); -- if (code != 0) { -- free_ChangePasswdDataMS(&chpw); -- krb5_free_principal(context, target_principal); -- return kpasswd_make_error_reply(mem_ctx, -- KRB5_KPASSWD_MALFORMED, -- "Failed to parse principal", -- kpasswd_reply); -- } -- } else { -+ if (chpw.targname == NULL || chpw.targrealm == NULL) { - free_ChangePasswdDataMS(&chpw); - return kpasswd_change_password(kdc, - mem_ctx, -@@ -193,7 +170,28 @@ static krb5_error_code kpasswd_set_password(struct kdc_server *kdc, - kpasswd_reply, - error_string); - } -+ code = krb5_build_principal_ext(context, -+ &target_principal, -+ strlen(*chpw.targrealm), -+ *chpw.targrealm, -+ 0); -+ if (code != 0) { -+ free_ChangePasswdDataMS(&chpw); -+ return kpasswd_make_error_reply(mem_ctx, -+ KRB5_KPASSWD_MALFORMED, -+ "Failed to parse principal", -+ kpasswd_reply); -+ } -+ code = copy_PrincipalName(chpw.targname, -+ &target_principal->name); - free_ChangePasswdDataMS(&chpw); -+ if (code != 0) { -+ krb5_free_principal(context, target_principal); -+ return kpasswd_make_error_reply(mem_ctx, -+ KRB5_KPASSWD_MALFORMED, -+ "Failed to parse principal", -+ kpasswd_reply); -+ } - - if (target_principal->name.name_string.len >= 2) { - is_service_principal = true; --- -2.25.1 - - -From 981948677c895e4e1d3b074f8a1a9c82fd65a80a Mon Sep 17 00:00:00 2001 -From: Andreas Schneider -Date: Tue, 24 May 2022 10:17:00 +0200 -Subject: [PATCH 79/99] CVE-2022-2031 testprogs: Fix auth with smbclient and - krb5 ccache - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15047 - -Signed-off-by: Andreas Schneider -Reviewed-by: Joseph Sutton ---- - testprogs/blackbox/test_kpasswd_heimdal.sh | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/testprogs/blackbox/test_kpasswd_heimdal.sh b/testprogs/blackbox/test_kpasswd_heimdal.sh -index 43f38b09de2..a73c6665a18 100755 ---- a/testprogs/blackbox/test_kpasswd_heimdal.sh -+++ b/testprogs/blackbox/test_kpasswd_heimdal.sh -@@ -71,7 +71,7 @@ testit "kinit with user password" \ - do_kinit $TEST_PRINCIPAL $TEST_PASSWORD || failed=`expr $failed + 1` - - test_smbclient "Test login with user kerberos ccache" \ -- "ls" "$SMB_UNC" --use-kerberos=required || failed=`expr $failed + 1` -+ "ls" "$SMB_UNC" --use-krb5-ccache=${KRB5CCNAME} || failed=`expr $failed + 1` - - testit "change user password with 'samba-tool user password' (unforced)" \ - $VALGRIND $PYTHON $samba_tool user password -W$DOMAIN -U$TEST_USERNAME%$TEST_PASSWORD --use-kerberos=off --newpassword=$TEST_PASSWORD_NEW || failed=`expr $failed + 1` -@@ -84,7 +84,7 @@ testit "kinit with user password" \ - do_kinit $TEST_PRINCIPAL $TEST_PASSWORD || failed=`expr $failed + 1` - - test_smbclient "Test login with user kerberos ccache" \ -- "ls" "$SMB_UNC" --use-kerberos=required || failed=`expr $failed + 1` -+ "ls" "$SMB_UNC" --use-krb5-ccache=${KRB5CCNAME} || failed=`expr $failed + 1` - - ########################################################### - ### check that a short password is rejected --- -2.25.1 - - -From 5dd0ef1991944a740b1d0107487d25d1acf5ebef Mon Sep 17 00:00:00 2001 -From: Andreas Schneider -Date: Thu, 19 May 2022 16:35:28 +0200 -Subject: [PATCH 80/99] CVE-2022-2031 testprogs: Add kadmin/changepw - canonicalization test with MIT kpasswd - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15047 - -Signed-off-by: Andreas Schneider -Reviewed-by: Joseph Sutton ---- - selftest/knownfail.d/kadmin_changepw | 1 + - testprogs/blackbox/test_kpasswd_heimdal.sh | 35 +++++++++++++++++++++- - 2 files changed, 35 insertions(+), 1 deletion(-) - create mode 100644 selftest/knownfail.d/kadmin_changepw - -diff --git a/selftest/knownfail.d/kadmin_changepw b/selftest/knownfail.d/kadmin_changepw -new file mode 100644 -index 00000000000..97c14793ea5 ---- /dev/null -+++ b/selftest/knownfail.d/kadmin_changepw -@@ -0,0 +1 @@ -+^samba4.blackbox.kpasswd.MIT kpasswd.change.user.password -diff --git a/testprogs/blackbox/test_kpasswd_heimdal.sh b/testprogs/blackbox/test_kpasswd_heimdal.sh -index a73c6665a18..698044a3fd3 100755 ---- a/testprogs/blackbox/test_kpasswd_heimdal.sh -+++ b/testprogs/blackbox/test_kpasswd_heimdal.sh -@@ -7,7 +7,7 @@ - - if [ $# -lt 6 ]; then - cat < "${PREFIX}/tmpkpasswdscript" < "${KRB5_CONFIG}" -+ testit "MIT kpasswd change user password" \ -+ "${texpect}" "${PREFIX}/tmpkpasswdscript" "${mit_kpasswd}" \ -+ "${TEST_PRINCIPAL}" || -+ failed=$((failed + 1)) -+ KRB5_CONFIG="${SAVE_KRB5_CONFIG}" -+ export KRB5_CONFIG -+fi -+ -+TEST_PASSWORD="${TEST_PASSWORD_NEW}" -+TEST_PASSWORD_NEW="testPaSS@03force%" -+ - ########################################################### - ### Force password change at login - ########################################################### --- -2.25.1 - - -From 3fd067c7d63e132a84bfc155769012e4261a9f07 Mon Sep 17 00:00:00 2001 -From: Andreas Schneider -Date: Tue, 24 May 2022 09:54:18 +0200 -Subject: [PATCH 81/99] CVE-2022-2031 s4:kdc: Implement is_kadmin_changepw() - helper function - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15047 - -Signed-off-by: Andreas Schneider -Reviewed-by: Joseph Sutton - -[jsutton@samba.org Adapted entry to entry_ex->entry] ---- - source4/kdc/db-glue.c | 16 +++++++++++----- - 1 file changed, 11 insertions(+), 5 deletions(-) - -diff --git a/source4/kdc/db-glue.c b/source4/kdc/db-glue.c -index 5752ffb821c..45159e6e64d 100644 ---- a/source4/kdc/db-glue.c -+++ b/source4/kdc/db-glue.c -@@ -816,6 +816,14 @@ static int principal_comp_strcmp(krb5_context context, - component, string, false); - } - -+static bool is_kadmin_changepw(krb5_context context, -+ krb5_const_principal principal) -+{ -+ return krb5_princ_size(context, principal) == 2 && -+ (principal_comp_strcmp(context, principal, 0, "kadmin") == 0) && -+ (principal_comp_strcmp(context, principal, 1, "changepw") == 0); -+} -+ - /* - * Construct an hdb_entry from a directory entry. - */ -@@ -1110,11 +1118,9 @@ static krb5_error_code samba_kdc_message2entry(krb5_context context, - * 'change password', as otherwise we could get into - * trouble, and not enforce the password expirty. - * Instead, only do it when request is for the kpasswd service */ -- if (ent_type == SAMBA_KDC_ENT_TYPE_SERVER -- && krb5_princ_size(context, principal) == 2 -- && (principal_comp_strcmp(context, principal, 0, "kadmin") == 0) -- && (principal_comp_strcmp(context, principal, 1, "changepw") == 0) -- && lpcfg_is_my_domain_or_realm(lp_ctx, realm)) { -+ if (ent_type == SAMBA_KDC_ENT_TYPE_SERVER && -+ is_kadmin_changepw(context, principal) && -+ lpcfg_is_my_domain_or_realm(lp_ctx, realm)) { - entry_ex->entry.flags.change_pw = 1; - } - --- -2.25.1 - - -From 5e7d75d8754d157d10e3e7d730445bddd91e5b9e Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Wed, 18 May 2022 16:56:01 +1200 -Subject: [PATCH 82/99] CVE-2022-2031 s4:kdc: Split out a - samba_kdc_get_entry_principal() function - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15047 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andreas Schneider - -[jsutton@samba.org Adapted entry to entry_ex->entry] - -[jsutton@samba.org Fixed conflicts caused by superfluous whitespace] ---- - source4/kdc/db-glue.c | 192 +++++++++++++++++++++++------------------- - 1 file changed, 107 insertions(+), 85 deletions(-) - -diff --git a/source4/kdc/db-glue.c b/source4/kdc/db-glue.c -index 45159e6e64d..ac0c206b5c1 100644 ---- a/source4/kdc/db-glue.c -+++ b/source4/kdc/db-glue.c -@@ -824,6 +824,101 @@ static bool is_kadmin_changepw(krb5_context context, - (principal_comp_strcmp(context, principal, 1, "changepw") == 0); - } - -+static krb5_error_code samba_kdc_get_entry_principal( -+ krb5_context context, -+ struct samba_kdc_db_context *kdc_db_ctx, -+ const char *samAccountName, -+ enum samba_kdc_ent_type ent_type, -+ unsigned flags, -+ krb5_const_principal in_princ, -+ krb5_principal *out_princ) -+{ -+ struct loadparm_context *lp_ctx = kdc_db_ctx->lp_ctx; -+ krb5_error_code ret = 0; -+ -+ /* -+ * If we are set to canonicalize, we get back the fixed UPPER -+ * case realm, and the real username (ie matching LDAP -+ * samAccountName) -+ * -+ * Otherwise, if we are set to enterprise, we -+ * get back the whole principal as-sent -+ * -+ * Finally, if we are not set to canonicalize, we get back the -+ * fixed UPPER case realm, but the as-sent username -+ */ -+ -+ if (ent_type == SAMBA_KDC_ENT_TYPE_KRBTGT) { -+ if (flags & (SDB_F_CANON|SDB_F_FORCE_CANON)) { -+ /* -+ * When requested to do so, ensure that the -+ * both realm values in the principal are set -+ * to the upper case, canonical realm -+ */ -+ ret = smb_krb5_make_principal(context, out_princ, -+ lpcfg_realm(lp_ctx), "krbtgt", -+ lpcfg_realm(lp_ctx), NULL); -+ if (ret) { -+ return ret; -+ } -+ smb_krb5_principal_set_type(context, *out_princ, KRB5_NT_SRV_INST); -+ } else { -+ ret = krb5_copy_principal(context, in_princ, out_princ); -+ if (ret) { -+ return ret; -+ } -+ /* -+ * this appears to be required regardless of -+ * the canonicalize flag from the client -+ */ -+ ret = smb_krb5_principal_set_realm(context, *out_princ, lpcfg_realm(lp_ctx)); -+ if (ret) { -+ return ret; -+ } -+ } -+ -+ } else if (ent_type == SAMBA_KDC_ENT_TYPE_ANY && in_princ == NULL) { -+ ret = smb_krb5_make_principal(context, out_princ, lpcfg_realm(lp_ctx), samAccountName, NULL); -+ if (ret) { -+ return ret; -+ } -+ } else if ((flags & SDB_F_FORCE_CANON) || -+ ((flags & SDB_F_CANON) && (flags & SDB_F_FOR_AS_REQ))) { -+ /* -+ * SDB_F_CANON maps from the canonicalize flag in the -+ * packet, and has a different meaning between AS-REQ -+ * and TGS-REQ. We only change the principal in the AS-REQ case -+ * -+ * The SDB_F_FORCE_CANON if for new MIT KDC code that wants -+ * the canonical name in all lookups, and takes care to -+ * canonicalize only when appropriate. -+ */ -+ ret = smb_krb5_make_principal(context, out_princ, lpcfg_realm(lp_ctx), samAccountName, NULL); -+ if (ret) { -+ return ret; -+ } -+ } else { -+ ret = krb5_copy_principal(context, in_princ, out_princ); -+ if (ret) { -+ return ret; -+ } -+ -+ /* While we have copied the client principal, tests -+ * show that Win2k3 returns the 'corrected' realm, not -+ * the client-specified realm. This code attempts to -+ * replace the client principal's realm with the one -+ * we determine from our records */ -+ -+ /* this has to be with malloc() */ -+ ret = smb_krb5_principal_set_realm(context, *out_princ, lpcfg_realm(lp_ctx)); -+ if (ret) { -+ return ret; -+ } -+ } -+ -+ return 0; -+} -+ - /* - * Construct an hdb_entry from a directory entry. - */ -@@ -913,93 +1008,8 @@ static krb5_error_code samba_kdc_message2entry(krb5_context context, - userAccountControl |= msDS_User_Account_Control_Computed; - } - -- /* -- * If we are set to canonicalize, we get back the fixed UPPER -- * case realm, and the real username (ie matching LDAP -- * samAccountName) -- * -- * Otherwise, if we are set to enterprise, we -- * get back the whole principal as-sent -- * -- * Finally, if we are not set to canonicalize, we get back the -- * fixed UPPER case realm, but the as-sent username -- */ -- - if (ent_type == SAMBA_KDC_ENT_TYPE_KRBTGT) { - p->is_krbtgt = true; -- -- if (flags & (SDB_F_CANON|SDB_F_FORCE_CANON)) { -- /* -- * When requested to do so, ensure that the -- * both realm values in the principal are set -- * to the upper case, canonical realm -- */ -- ret = smb_krb5_make_principal(context, &entry_ex->entry.principal, -- lpcfg_realm(lp_ctx), "krbtgt", -- lpcfg_realm(lp_ctx), NULL); -- if (ret) { -- krb5_clear_error_message(context); -- goto out; -- } -- smb_krb5_principal_set_type(context, entry_ex->entry.principal, KRB5_NT_SRV_INST); -- } else { -- ret = krb5_copy_principal(context, principal, &entry_ex->entry.principal); -- if (ret) { -- krb5_clear_error_message(context); -- goto out; -- } -- /* -- * this appears to be required regardless of -- * the canonicalize flag from the client -- */ -- ret = smb_krb5_principal_set_realm(context, entry_ex->entry.principal, lpcfg_realm(lp_ctx)); -- if (ret) { -- krb5_clear_error_message(context); -- goto out; -- } -- } -- -- } else if (ent_type == SAMBA_KDC_ENT_TYPE_ANY && principal == NULL) { -- ret = smb_krb5_make_principal(context, &entry_ex->entry.principal, lpcfg_realm(lp_ctx), samAccountName, NULL); -- if (ret) { -- krb5_clear_error_message(context); -- goto out; -- } -- } else if ((flags & SDB_F_FORCE_CANON) || -- ((flags & SDB_F_CANON) && (flags & SDB_F_FOR_AS_REQ))) { -- /* -- * SDB_F_CANON maps from the canonicalize flag in the -- * packet, and has a different meaning between AS-REQ -- * and TGS-REQ. We only change the principal in the AS-REQ case -- * -- * The SDB_F_FORCE_CANON if for new MIT KDC code that wants -- * the canonical name in all lookups, and takes care to -- * canonicalize only when appropriate. -- */ -- ret = smb_krb5_make_principal(context, &entry_ex->entry.principal, lpcfg_realm(lp_ctx), samAccountName, NULL); -- if (ret) { -- krb5_clear_error_message(context); -- goto out; -- } -- } else { -- ret = krb5_copy_principal(context, principal, &entry_ex->entry.principal); -- if (ret) { -- krb5_clear_error_message(context); -- goto out; -- } -- -- /* While we have copied the client principal, tests -- * show that Win2k3 returns the 'corrected' realm, not -- * the client-specified realm. This code attempts to -- * replace the client principal's realm with the one -- * we determine from our records */ -- -- /* this has to be with malloc() */ -- ret = smb_krb5_principal_set_realm(context, entry_ex->entry.principal, lpcfg_realm(lp_ctx)); -- if (ret) { -- krb5_clear_error_message(context); -- goto out; -- } - } - - /* First try and figure out the flags based on the userAccountControl */ -@@ -1185,6 +1195,18 @@ static krb5_error_code samba_kdc_message2entry(krb5_context context, - } - } - -+ ret = samba_kdc_get_entry_principal(context, -+ kdc_db_ctx, -+ samAccountName, -+ ent_type, -+ flags, -+ principal, -+ &entry_ex->entry.principal); -+ if (ret != 0) { -+ krb5_clear_error_message(context); -+ goto out; -+ } -+ - entry_ex->entry.valid_start = NULL; - - entry_ex->entry.max_life = malloc(sizeof(*entry_ex->entry.max_life)); --- -2.25.1 - - -From 8b9fe095b91ce62338829a6ac7012170e6af8898 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Wed, 25 May 2022 17:19:58 +1200 -Subject: [PATCH 83/99] CVE-2022-2031 s4:kdc: Refactor - samba_kdc_get_entry_principal() - -This eliminates some duplicate branches. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15047 - -Signed-off-by: Joseph Sutton -Pair-Programmed-With: Andreas Schneider -Reviewed-by: Andreas Schneider ---- - source4/kdc/db-glue.c | 116 ++++++++++++++++++++---------------------- - 1 file changed, 55 insertions(+), 61 deletions(-) - -diff --git a/source4/kdc/db-glue.c b/source4/kdc/db-glue.c -index ac0c206b5c1..385c118a073 100644 ---- a/source4/kdc/db-glue.c -+++ b/source4/kdc/db-glue.c -@@ -834,7 +834,8 @@ static krb5_error_code samba_kdc_get_entry_principal( - krb5_principal *out_princ) - { - struct loadparm_context *lp_ctx = kdc_db_ctx->lp_ctx; -- krb5_error_code ret = 0; -+ krb5_error_code code = 0; -+ bool canon = flags & (SDB_F_CANON|SDB_F_FORCE_CANON); - - /* - * If we are set to canonicalize, we get back the fixed UPPER -@@ -848,75 +849,68 @@ static krb5_error_code samba_kdc_get_entry_principal( - * fixed UPPER case realm, but the as-sent username - */ - -- if (ent_type == SAMBA_KDC_ENT_TYPE_KRBTGT) { -- if (flags & (SDB_F_CANON|SDB_F_FORCE_CANON)) { -- /* -- * When requested to do so, ensure that the -- * both realm values in the principal are set -- * to the upper case, canonical realm -- */ -- ret = smb_krb5_make_principal(context, out_princ, -- lpcfg_realm(lp_ctx), "krbtgt", -- lpcfg_realm(lp_ctx), NULL); -- if (ret) { -- return ret; -- } -- smb_krb5_principal_set_type(context, *out_princ, KRB5_NT_SRV_INST); -- } else { -- ret = krb5_copy_principal(context, in_princ, out_princ); -- if (ret) { -- return ret; -- } -- /* -- * this appears to be required regardless of -- * the canonicalize flag from the client -- */ -- ret = smb_krb5_principal_set_realm(context, *out_princ, lpcfg_realm(lp_ctx)); -- if (ret) { -- return ret; -- } -- } -+ if (ent_type == SAMBA_KDC_ENT_TYPE_KRBTGT && canon) { -+ /* -+ * When requested to do so, ensure that the -+ * both realm values in the principal are set -+ * to the upper case, canonical realm -+ */ -+ code = smb_krb5_make_principal(context, -+ out_princ, -+ lpcfg_realm(lp_ctx), -+ "krbtgt", -+ lpcfg_realm(lp_ctx), -+ NULL); -+ if (code != 0) { -+ return code; -+ } -+ smb_krb5_principal_set_type(context, -+ *out_princ, -+ KRB5_NT_SRV_INST); - -- } else if (ent_type == SAMBA_KDC_ENT_TYPE_ANY && in_princ == NULL) { -- ret = smb_krb5_make_principal(context, out_princ, lpcfg_realm(lp_ctx), samAccountName, NULL); -- if (ret) { -- return ret; -- } -- } else if ((flags & SDB_F_FORCE_CANON) || -- ((flags & SDB_F_CANON) && (flags & SDB_F_FOR_AS_REQ))) { -+ return 0; -+ } -+ -+ if ((canon && flags & (SDB_F_FORCE_CANON|SDB_F_FOR_AS_REQ)) || -+ (ent_type == SAMBA_KDC_ENT_TYPE_ANY && in_princ == NULL)) { - /* - * SDB_F_CANON maps from the canonicalize flag in the - * packet, and has a different meaning between AS-REQ -- * and TGS-REQ. We only change the principal in the AS-REQ case -+ * and TGS-REQ. We only change the principal in the -+ * AS-REQ case. - * -- * The SDB_F_FORCE_CANON if for new MIT KDC code that wants -- * the canonical name in all lookups, and takes care to -- * canonicalize only when appropriate. -+ * The SDB_F_FORCE_CANON if for new MIT KDC code that -+ * wants the canonical name in all lookups, and takes -+ * care to canonicalize only when appropriate. - */ -- ret = smb_krb5_make_principal(context, out_princ, lpcfg_realm(lp_ctx), samAccountName, NULL); -- if (ret) { -- return ret; -- } -- } else { -- ret = krb5_copy_principal(context, in_princ, out_princ); -- if (ret) { -- return ret; -- } -- -- /* While we have copied the client principal, tests -- * show that Win2k3 returns the 'corrected' realm, not -- * the client-specified realm. This code attempts to -- * replace the client principal's realm with the one -- * we determine from our records */ -+ code = smb_krb5_make_principal(context, -+ out_princ, -+ lpcfg_realm(lp_ctx), -+ samAccountName, -+ NULL); -+ return code; -+ } - -- /* this has to be with malloc() */ -- ret = smb_krb5_principal_set_realm(context, *out_princ, lpcfg_realm(lp_ctx)); -- if (ret) { -- return ret; -- } -+ /* -+ * For a krbtgt entry, this appears to be required regardless of the -+ * canonicalize flag from the client. -+ */ -+ code = krb5_copy_principal(context, in_princ, out_princ); -+ if (code != 0) { -+ return code; - } - -- return 0; -+ /* -+ * While we have copied the client principal, tests show that Win2k3 -+ * returns the 'corrected' realm, not the client-specified realm. This -+ * code attempts to replace the client principal's realm with the one -+ * we determine from our records -+ */ -+ code = smb_krb5_principal_set_realm(context, -+ *out_princ, -+ lpcfg_realm(lp_ctx)); -+ -+ return code; - } - - /* --- -2.25.1 - - -From 04e452890ada8390828aa4c5c87ceefe44daa50f Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Wed, 18 May 2022 16:56:01 +1200 -Subject: [PATCH 84/99] CVE-2022-2031 s4:kdc: Fix canonicalisation of - kadmin/changepw principal - -Since this principal goes through the samba_kdc_fetch_server() path, -setting the canonicalisation flag would cause the principal to be -replaced with the sAMAccountName; this meant requests to -kadmin/changepw@REALM would result in a ticket to krbtgt@REALM. Now we -properly handle canonicalisation for the kadmin/changepw principal. - -View with 'git show -b'. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15047 - -Pair-Programmed-With: Andreas Schneider -Signed-off-by: Andreas Schneider -Signed-off-by: Joseph Sutton -Reviewed-by: Andreas Schneider - -[jsutton@samba.org Adapted entry to entry_ex->entry; removed MIT KDC - 1.20-specific knownfails] ---- - selftest/knownfail.d/kadmin_changepw | 1 - - selftest/knownfail_heimdal_kdc | 2 - - source4/kdc/db-glue.c | 84 +++++++++++++++------------- - 3 files changed, 46 insertions(+), 41 deletions(-) - delete mode 100644 selftest/knownfail.d/kadmin_changepw - -diff --git a/selftest/knownfail.d/kadmin_changepw b/selftest/knownfail.d/kadmin_changepw -deleted file mode 100644 -index 97c14793ea5..00000000000 ---- a/selftest/knownfail.d/kadmin_changepw -+++ /dev/null -@@ -1 +0,0 @@ --^samba4.blackbox.kpasswd.MIT kpasswd.change.user.password -diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc -index ab7230060ab..6abbbf75391 100644 ---- a/selftest/knownfail_heimdal_kdc -+++ b/selftest/knownfail_heimdal_kdc -@@ -112,8 +112,6 @@ - # - # Kpasswd tests - # --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_canonicalize.ad_dc --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_canonicalize_realm_case.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_from_rodc.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_ticket_lifetime.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_ticket_requester_sid_tgs.ad_dc -diff --git a/source4/kdc/db-glue.c b/source4/kdc/db-glue.c -index 385c118a073..d2d7136608e 100644 ---- a/source4/kdc/db-glue.c -+++ b/source4/kdc/db-glue.c -@@ -830,6 +830,7 @@ static krb5_error_code samba_kdc_get_entry_principal( - const char *samAccountName, - enum samba_kdc_ent_type ent_type, - unsigned flags, -+ bool is_kadmin_changepw, - krb5_const_principal in_princ, - krb5_principal *out_princ) - { -@@ -849,46 +850,52 @@ static krb5_error_code samba_kdc_get_entry_principal( - * fixed UPPER case realm, but the as-sent username - */ - -- if (ent_type == SAMBA_KDC_ENT_TYPE_KRBTGT && canon) { -- /* -- * When requested to do so, ensure that the -- * both realm values in the principal are set -- * to the upper case, canonical realm -- */ -- code = smb_krb5_make_principal(context, -- out_princ, -- lpcfg_realm(lp_ctx), -- "krbtgt", -- lpcfg_realm(lp_ctx), -- NULL); -- if (code != 0) { -- return code; -- } -- smb_krb5_principal_set_type(context, -- *out_princ, -- KRB5_NT_SRV_INST); -+ /* -+ * We need to ensure that the kadmin/changepw principal isn't able to -+ * issue krbtgt tickets, even if canonicalization is turned on. -+ */ -+ if (!is_kadmin_changepw) { -+ if (ent_type == SAMBA_KDC_ENT_TYPE_KRBTGT && canon) { -+ /* -+ * When requested to do so, ensure that the -+ * both realm values in the principal are set -+ * to the upper case, canonical realm -+ */ -+ code = smb_krb5_make_principal(context, -+ out_princ, -+ lpcfg_realm(lp_ctx), -+ "krbtgt", -+ lpcfg_realm(lp_ctx), -+ NULL); -+ if (code != 0) { -+ return code; -+ } -+ smb_krb5_principal_set_type(context, -+ *out_princ, -+ KRB5_NT_SRV_INST); - -- return 0; -- } -+ return 0; -+ } - -- if ((canon && flags & (SDB_F_FORCE_CANON|SDB_F_FOR_AS_REQ)) || -- (ent_type == SAMBA_KDC_ENT_TYPE_ANY && in_princ == NULL)) { -- /* -- * SDB_F_CANON maps from the canonicalize flag in the -- * packet, and has a different meaning between AS-REQ -- * and TGS-REQ. We only change the principal in the -- * AS-REQ case. -- * -- * The SDB_F_FORCE_CANON if for new MIT KDC code that -- * wants the canonical name in all lookups, and takes -- * care to canonicalize only when appropriate. -- */ -- code = smb_krb5_make_principal(context, -- out_princ, -- lpcfg_realm(lp_ctx), -- samAccountName, -- NULL); -- return code; -+ if ((canon && flags & (SDB_F_FORCE_CANON|SDB_F_FOR_AS_REQ)) || -+ (ent_type == SAMBA_KDC_ENT_TYPE_ANY && in_princ == NULL)) { -+ /* -+ * SDB_F_CANON maps from the canonicalize flag in the -+ * packet, and has a different meaning between AS-REQ -+ * and TGS-REQ. We only change the principal in the -+ * AS-REQ case. -+ * -+ * The SDB_F_FORCE_CANON if for new MIT KDC code that -+ * wants the canonical name in all lookups, and takes -+ * care to canonicalize only when appropriate. -+ */ -+ code = smb_krb5_make_principal(context, -+ out_princ, -+ lpcfg_realm(lp_ctx), -+ samAccountName, -+ NULL); -+ return code; -+ } - } - - /* -@@ -1194,6 +1201,7 @@ static krb5_error_code samba_kdc_message2entry(krb5_context context, - samAccountName, - ent_type, - flags, -+ entry_ex->entry.flags.change_pw, - principal, - &entry_ex->entry.principal); - if (ret != 0) { --- -2.25.1 - - -From a46d0ac59f074f999217586f18ba8772a645b246 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Tue, 24 May 2022 17:53:49 +1200 -Subject: [PATCH 85/99] CVE-2022-2031 s4:kdc: Limit kpasswd ticket lifetime to - two minutes or less - -This matches the behaviour of Windows. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15047 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andreas Schneider - -[jsutton@samba.org Adapted entry to entry_ex->entry; included - samba_kdc.h header file] ---- - selftest/knownfail_heimdal_kdc | 1 - - selftest/knownfail_mit_kdc | 1 - - source4/kdc/db-glue.c | 5 +++++ - source4/kdc/mit-kdb/kdb_samba_principals.c | 2 +- - source4/kdc/samba_kdc.h | 2 ++ - 5 files changed, 8 insertions(+), 3 deletions(-) - -diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc -index 6abbbf75391..4fb838f0e11 100644 ---- a/selftest/knownfail_heimdal_kdc -+++ b/selftest/knownfail_heimdal_kdc -@@ -113,7 +113,6 @@ - # Kpasswd tests - # - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_from_rodc.ad_dc --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_ticket_lifetime.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_ticket_requester_sid_tgs.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key_server.ad_dc -diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc -index 0389672e5d9..ed8f7069319 100644 ---- a/selftest/knownfail_mit_kdc -+++ b/selftest/knownfail_mit_kdc -@@ -546,7 +546,6 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ - # - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_canonicalize_realm_case.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_no_canonicalize_realm_case.ad_dc --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_ticket_lifetime.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_ticket_requester_sid_tgs.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key_server.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key_service.ad_dc -diff --git a/source4/kdc/db-glue.c b/source4/kdc/db-glue.c -index d2d7136608e..073ec83c8cf 100644 ---- a/source4/kdc/db-glue.c -+++ b/source4/kdc/db-glue.c -@@ -1226,6 +1226,11 @@ static krb5_error_code samba_kdc_message2entry(krb5_context context, - kdc_db_ctx->policy.usr_tkt_lifetime); - } - -+ if (entry_ex->entry.flags.change_pw) { -+ /* Limit lifetime of kpasswd tickets to two minutes or less. */ -+ *entry_ex->entry.max_life = MIN(*entry_ex->entry.max_life, CHANGEPW_LIFETIME); -+ } -+ - entry_ex->entry.max_renew = malloc(sizeof(*entry_ex->entry.max_life)); - if (entry_ex->entry.max_renew == NULL) { - ret = ENOMEM; -diff --git a/source4/kdc/mit-kdb/kdb_samba_principals.c b/source4/kdc/mit-kdb/kdb_samba_principals.c -index 3917b9824c6..da21251179b 100644 ---- a/source4/kdc/mit-kdb/kdb_samba_principals.c -+++ b/source4/kdc/mit-kdb/kdb_samba_principals.c -@@ -27,6 +27,7 @@ - #include - #include - -+#include "kdc/samba_kdc.h" - #include "kdc/mit_samba.h" - #include "kdb_samba.h" - -@@ -34,7 +35,6 @@ - #define DBGC_CLASS DBGC_KERBEROS - - #define ADMIN_LIFETIME 60*60*3 /* 3 hours */ --#define CHANGEPW_LIFETIME 60*5 /* 5 minutes */ - - krb5_error_code ks_get_principal(krb5_context context, - krb5_const_principal principal, -diff --git a/source4/kdc/samba_kdc.h b/source4/kdc/samba_kdc.h -index e228a82ce6a..8010d7c35ed 100644 ---- a/source4/kdc/samba_kdc.h -+++ b/source4/kdc/samba_kdc.h -@@ -62,4 +62,6 @@ struct samba_kdc_entry { - - extern struct hdb_method hdb_samba4_interface; - -+#define CHANGEPW_LIFETIME 60*2 /* 2 minutes */ -+ - #endif /* _SAMBA_KDC_H_ */ --- -2.25.1 - - -From c7408dd944ee5a0de5f04079d158f4575fb9036a Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Mon, 30 May 2022 19:18:17 +1200 -Subject: [PATCH 86/99] CVE-2022-2031 s4:kdc: Reject tickets during the last - two minutes of their life - -For Heimdal, this now matches the behaviour of Windows. The object of -this requirement is to ensure we don't allow kpasswd tickets, not having -a lifetime of more than two minutes, to be passed off as TGTs. - -An existing requirement for TGTs to contain a REQUESTER_SID PAC buffer -suffices to prevent kpasswd ticket misuse, so this is just an additional -precaution on top. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15047 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andreas Schneider - -[jsutton@samba.org As we don't have access to the ticket or the request - in the plugin, rewrote check directly in Heimdal KDC] ---- - selftest/knownfail_heimdal_kdc | 1 - - source4/heimdal/kdc/krb5tgs.c | 19 ++++++++++++++++++- - 2 files changed, 18 insertions(+), 2 deletions(-) - -diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc -index 4fb838f0e11..dfe04dd1448 100644 ---- a/selftest/knownfail_heimdal_kdc -+++ b/selftest/knownfail_heimdal_kdc -@@ -113,7 +113,6 @@ - # Kpasswd tests - # - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_from_rodc.ad_dc --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_ticket_requester_sid_tgs.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key_server.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key_service.ad_dc -diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c -index 38dba8493ae..15be136496f 100644 ---- a/source4/heimdal/kdc/krb5tgs.c -+++ b/source4/heimdal/kdc/krb5tgs.c -@@ -33,6 +33,9 @@ - - #include "kdc_locl.h" - -+/* Awful hack to get access to 'struct samba_kdc_entry'. */ -+#include "../../kdc/samba_kdc.h" -+ - /* - * return the realm of a krbtgt-ticket or NULL - */ -@@ -130,6 +133,7 @@ check_PAC(krb5_context context, - static krb5_error_code - check_tgs_flags(krb5_context context, - krb5_kdc_configuration *config, -+ const hdb_entry_ex *krbtgt_in, - KDC_REQ_BODY *b, const EncTicketPart *tgt, EncTicketPart *et) - { - KDCOptions f = b->kdc_options; -@@ -244,6 +248,17 @@ check_tgs_flags(krb5_context context, - et->endtime = min(*et->renew_till, et->endtime); - } - -+ if (tgt->endtime - kdc_time <= CHANGEPW_LIFETIME) { -+ /* Check that the ticket has not arrived across a trust. */ -+ const struct samba_kdc_entry *skdc_entry = krbtgt_in->ctx; -+ if (!skdc_entry->is_trust) { -+ /* This may be a kpasswd ticket rather than a TGT, so don't accept it. */ -+ kdc_log(context, config, 0, -+ "Ticket is not a ticket-granting ticket"); -+ return KRB5KRB_AP_ERR_TKT_EXPIRED; -+ } -+ } -+ - #if 0 - /* checks for excess flags */ - if(f.request_anonymous && !config->allow_anonymous){ -@@ -510,6 +525,7 @@ tgs_make_reply(krb5_context context, - hdb_entry_ex *client, - krb5_principal client_principal, - const char *tgt_realm, -+ const hdb_entry_ex *krbtgt_in, - hdb_entry_ex *krbtgt, - krb5_pac mspac, - uint16_t rodc_id, -@@ -538,7 +554,7 @@ tgs_make_reply(krb5_context context, - ALLOC(et.starttime); - *et.starttime = kdc_time; - -- ret = check_tgs_flags(context, config, b, tgt, &et); -+ ret = check_tgs_flags(context, config, krbtgt_in, b, tgt, &et); - if(ret) - goto out; - -@@ -2129,6 +2145,7 @@ server_lookup: - client, - cp, - tgt_realm, -+ krbtgt, - krbtgt_out, - mspac, - rodc_id, --- -2.25.1 - - -From 389a5523485dfbd48e87b6ee9c39c6c2e16294a0 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Tue, 14 Jun 2022 15:23:55 +1200 -Subject: [PATCH 87/99] CVE-2022-2031 tests/krb5: Test truncated forms of - server principals - -We should not be able to use krb@REALM instead of krbtgt@REALM. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15047 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andreas Schneider - -[jsutton@samba.org Fixed conflicts due to having older version of - _run_as_req_enc_timestamp()] ---- - python/samba/tests/krb5/as_req_tests.py | 40 ++++++++++++++++++++++--- - selftest/knownfail_heimdal_kdc | 4 +++ - selftest/knownfail_mit_kdc | 4 +++ - 3 files changed, 44 insertions(+), 4 deletions(-) - -diff --git a/python/samba/tests/krb5/as_req_tests.py b/python/samba/tests/krb5/as_req_tests.py -index 315720f85d6..054a49b64aa 100755 ---- a/python/samba/tests/krb5/as_req_tests.py -+++ b/python/samba/tests/krb5/as_req_tests.py -@@ -27,6 +27,7 @@ from samba.tests.krb5.kdc_base_test import KDCBaseTest - import samba.tests.krb5.kcrypto as kcrypto - import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 - from samba.tests.krb5.rfc4120_constants import ( -+ KDC_ERR_S_PRINCIPAL_UNKNOWN, - KDC_ERR_ETYPE_NOSUPP, - KDC_ERR_PREAUTH_REQUIRED, - KU_PA_ENC_TIMESTAMP, -@@ -40,7 +41,8 @@ global_hexdump = False - - - class AsReqBaseTest(KDCBaseTest): -- def _run_as_req_enc_timestamp(self, client_creds): -+ def _run_as_req_enc_timestamp(self, client_creds, sname=None, -+ expected_error=None): - client_account = client_creds.get_username() - client_as_etypes = self.get_default_enctypes() - client_kvno = client_creds.get_kvno() -@@ -50,8 +52,9 @@ class AsReqBaseTest(KDCBaseTest): - - cname = self.PrincipalName_create(name_type=NT_PRINCIPAL, - names=[client_account]) -- sname = self.PrincipalName_create(name_type=NT_SRV_INST, -- names=[krbtgt_account, realm]) -+ if sname is None: -+ sname = self.PrincipalName_create(name_type=NT_SRV_INST, -+ names=[krbtgt_account, realm]) - - expected_crealm = realm - expected_cname = cname -@@ -63,7 +66,10 @@ class AsReqBaseTest(KDCBaseTest): - - initial_etypes = client_as_etypes - initial_kdc_options = krb5_asn1.KDCOptions('forwardable') -- initial_error_mode = KDC_ERR_PREAUTH_REQUIRED -+ if expected_error is not None: -+ initial_error_mode = expected_error -+ else: -+ initial_error_mode = KDC_ERR_PREAUTH_REQUIRED - - rep, kdc_exchange_dict = self._test_as_exchange(cname, - realm, -@@ -80,6 +86,10 @@ class AsReqBaseTest(KDCBaseTest): - None, - initial_kdc_options, - pac_request=True) -+ -+ if expected_error is not None: -+ return None -+ - etype_info2 = kdc_exchange_dict['preauth_etype_info2'] - self.assertIsNotNone(etype_info2) - -@@ -209,6 +219,28 @@ class AsReqKerberosTests(AsReqBaseTest): - client_creds = self.get_mach_creds() - self._run_as_req_enc_timestamp(client_creds) - -+ # Ensure we can't use truncated well-known principals such as krb@REALM -+ # instead of krbtgt@REALM. -+ def test_krbtgt_wrong_principal(self): -+ client_creds = self.get_client_creds() -+ -+ krbtgt_creds = self.get_krbtgt_creds() -+ -+ krbtgt_account = krbtgt_creds.get_username() -+ realm = krbtgt_creds.get_realm() -+ -+ # Truncate the name of the krbtgt principal. -+ krbtgt_account = krbtgt_account[:3] -+ -+ wrong_krbtgt_princ = self.PrincipalName_create( -+ name_type=NT_SRV_INST, -+ names=[krbtgt_account, realm]) -+ -+ self._run_as_req_enc_timestamp( -+ client_creds, -+ sname=wrong_krbtgt_princ, -+ expected_error=KDC_ERR_S_PRINCIPAL_UNKNOWN) -+ - - if __name__ == "__main__": - global_asn1_print = False -diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc -index dfe04dd1448..7ad9ee85778 100644 ---- a/selftest/knownfail_heimdal_kdc -+++ b/selftest/knownfail_heimdal_kdc -@@ -116,3 +116,7 @@ - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key_server.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key_service.ad_dc -+# -+# AS-REQ tests -+# -+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_krbtgt_wrong_principal\( -diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc -index ed8f7069319..ad0fa84aedb 100644 ---- a/selftest/knownfail_mit_kdc -+++ b/selftest/knownfail_mit_kdc -@@ -549,3 +549,7 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_ticket_requester_sid_tgs.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key_server.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key_service.ad_dc -+# -+# AS-REQ tests -+# -+^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_krbtgt_wrong_principal\( --- -2.25.1 - - -From 959ed604ee1588f9a92c269a014fbf12b72fb8a4 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Wed, 25 May 2022 20:00:55 +1200 -Subject: [PATCH 88/99] CVE-2022-2031 s4:kdc: Don't use strncmp to compare - principal components - -We would only compare the first 'n' characters, where 'n' is the length -of the principal component string, so 'k@REALM' would erroneously be -considered equal to 'krbtgt@REALM'. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15047 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andreas Schneider ---- - selftest/knownfail_heimdal_kdc | 4 ---- - selftest/knownfail_mit_kdc | 4 ---- - source4/kdc/db-glue.c | 27 ++++++++++++++++++++++----- - 3 files changed, 22 insertions(+), 13 deletions(-) - -diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc -index 7ad9ee85778..dfe04dd1448 100644 ---- a/selftest/knownfail_heimdal_kdc -+++ b/selftest/knownfail_heimdal_kdc -@@ -116,7 +116,3 @@ - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key_server.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key_service.ad_dc --# --# AS-REQ tests --# --^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_krbtgt_wrong_principal\( -diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc -index ad0fa84aedb..ed8f7069319 100644 ---- a/selftest/knownfail_mit_kdc -+++ b/selftest/knownfail_mit_kdc -@@ -549,7 +549,3 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_ticket_requester_sid_tgs.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key_server.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key_service.ad_dc --# --# AS-REQ tests --# --^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_krbtgt_wrong_principal\( -diff --git a/source4/kdc/db-glue.c b/source4/kdc/db-glue.c -index 073ec83c8cf..cfa2097acbd 100644 ---- a/source4/kdc/db-glue.c -+++ b/source4/kdc/db-glue.c -@@ -769,15 +769,19 @@ static int principal_comp_strcmp_int(krb5_context context, - bool do_strcasecmp) - { - const char *p; -- size_t len; - - #if defined(HAVE_KRB5_PRINCIPAL_GET_COMP_STRING) - p = krb5_principal_get_comp_string(context, principal, component); - if (p == NULL) { - return -1; - } -- len = strlen(p); -+ if (do_strcasecmp) { -+ return strcasecmp(p, string); -+ } else { -+ return strcmp(p, string); -+ } - #else -+ size_t len; - krb5_data *d; - if (component >= krb5_princ_size(context, principal)) { - return -1; -@@ -789,13 +793,26 @@ static int principal_comp_strcmp_int(krb5_context context, - } - - p = d->data; -- len = d->length; --#endif -+ -+ len = strlen(string); -+ -+ /* -+ * We explicitly return -1 or 1. Subtracting of the two lengths might -+ * give the wrong result if the result overflows or loses data when -+ * narrowed to int. -+ */ -+ if (d->length < len) { -+ return -1; -+ } else if (d->length > len) { -+ return 1; -+ } -+ - if (do_strcasecmp) { - return strncasecmp(p, string, len); - } else { -- return strncmp(p, string, len); -+ return memcmp(p, string, len); - } -+#endif - } - - static int principal_comp_strcasecmp(krb5_context context, --- -2.25.1 - - -From 4b0304ab670a5dc3819f93633c190f722e3906d7 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Thu, 26 May 2022 16:36:30 +1200 -Subject: [PATCH 89/99] CVE-2022-32744 s4:kdc: Rename keytab_name -> - kpasswd_keytab_name - -This makes explicitly clear the purpose of this keytab. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15074 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andreas Schneider - -[jsutton@samba.org Fixed conflicts due to lacking HDBGET support] ---- - source4/kdc/kdc-heimdal.c | 4 ++-- - source4/kdc/kdc-server.h | 2 +- - source4/kdc/kdc-service-mit.c | 4 ++-- - source4/kdc/kpasswd-service.c | 2 +- - 4 files changed, 6 insertions(+), 6 deletions(-) - -diff --git a/source4/kdc/kdc-heimdal.c b/source4/kdc/kdc-heimdal.c -index ce32d3cb1b3..ca202bd6f9d 100644 ---- a/source4/kdc/kdc-heimdal.c -+++ b/source4/kdc/kdc-heimdal.c -@@ -444,8 +444,8 @@ static void kdc_post_fork(struct task_server *task, struct process_details *pd) - return; - } - -- kdc->keytab_name = talloc_asprintf(kdc, "HDB:samba4&%p", kdc->base_ctx); -- if (kdc->keytab_name == NULL) { -+ kdc->kpasswd_keytab_name = talloc_asprintf(kdc, "HDB:samba4&%p", kdc->base_ctx); -+ if (kdc->kpasswd_keytab_name == NULL) { - task_server_terminate(task, - "kdc: Failed to set keytab name", - true); -diff --git a/source4/kdc/kdc-server.h b/source4/kdc/kdc-server.h -index fd883c2e4b4..89b30f122f5 100644 ---- a/source4/kdc/kdc-server.h -+++ b/source4/kdc/kdc-server.h -@@ -40,7 +40,7 @@ struct kdc_server { - struct ldb_context *samdb; - bool am_rodc; - uint32_t proxy_timeout; -- const char *keytab_name; -+ const char *kpasswd_keytab_name; - void *private_data; - }; - -diff --git a/source4/kdc/kdc-service-mit.c b/source4/kdc/kdc-service-mit.c -index 5d4180aa7cc..22663b6ecc8 100644 ---- a/source4/kdc/kdc-service-mit.c -+++ b/source4/kdc/kdc-service-mit.c -@@ -291,8 +291,8 @@ NTSTATUS mitkdc_task_init(struct task_server *task) - return NT_STATUS_INTERNAL_ERROR; - } - -- kdc->keytab_name = talloc_asprintf(kdc, "KDB:"); -- if (kdc->keytab_name == NULL) { -+ kdc->kpasswd_keytab_name = talloc_asprintf(kdc, "KDB:"); -+ if (kdc->kpasswd_keytab_name == NULL) { - task_server_terminate(task, - "KDC: Out of memory", - true); -diff --git a/source4/kdc/kpasswd-service.c b/source4/kdc/kpasswd-service.c -index 379ddebf3ad..aec30850173 100644 ---- a/source4/kdc/kpasswd-service.c -+++ b/source4/kdc/kpasswd-service.c -@@ -170,7 +170,7 @@ kdc_code kpasswd_process(struct kdc_server *kdc, - - rv = cli_credentials_set_keytab_name(server_credentials, - kdc->task->lp_ctx, -- kdc->keytab_name, -+ kdc->kpasswd_keytab_name, - CRED_SPECIFIED); - if (rv != 0) { - DBG_ERR("Failed to set credentials keytab name\n"); --- -2.25.1 - - -From faa0a83813d7e24016381da5a4b8c7f664d95acc Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Wed, 8 Jun 2022 13:53:29 +1200 -Subject: [PATCH 90/99] s4:kdc: Remove kadmin mode from HDB plugin - -It appears we no longer require it. - -Signed-off-by: Joseph Sutton -Reviewed-by: Andreas Schneider ---- - source4/kdc/hdb-samba4-plugin.c | 35 +++++++-------------------------- - 1 file changed, 7 insertions(+), 28 deletions(-) - -diff --git a/source4/kdc/hdb-samba4-plugin.c b/source4/kdc/hdb-samba4-plugin.c -index 6f76124995d..4b90a766f76 100644 ---- a/source4/kdc/hdb-samba4-plugin.c -+++ b/source4/kdc/hdb-samba4-plugin.c -@@ -21,40 +21,20 @@ - - #include "includes.h" - #include "kdc/kdc-glue.h" --#include "kdc/db-glue.h" --#include "lib/util/samba_util.h" - #include "lib/param/param.h" --#include "source4/lib/events/events.h" - - static krb5_error_code hdb_samba4_create(krb5_context context, struct HDB **db, const char *arg) - { - NTSTATUS nt_status; -- void *ptr; -- struct samba_kdc_base_context *base_ctx; -- -- if (sscanf(arg, "&%p", &ptr) == 1) { -- base_ctx = talloc_get_type_abort(ptr, struct samba_kdc_base_context); -- } else if (arg[0] == '\0' || file_exist(arg)) { -- /* This mode for use in kadmin, rather than in Samba */ -- -- setup_logging("hdb_samba4", DEBUG_DEFAULT_STDERR); -- -- base_ctx = talloc_zero(NULL, struct samba_kdc_base_context); -- if (!base_ctx) { -- return ENOMEM; -- } -- -- base_ctx->ev_ctx = s4_event_context_init(base_ctx); -- base_ctx->lp_ctx = loadparm_init_global(false); -- if (arg[0]) { -- lpcfg_load(base_ctx->lp_ctx, arg); -- } else { -- lpcfg_load_default(base_ctx->lp_ctx); -- } -- } else { -+ void *ptr = NULL; -+ struct samba_kdc_base_context *base_ctx = NULL; -+ -+ if (sscanf(arg, "&%p", &ptr) != 1) { - return EINVAL; - } - -+ base_ctx = talloc_get_type_abort(ptr, struct samba_kdc_base_context); -+ - /* The global kdc_mem_ctx and kdc_lp_ctx, Disgusting, ugly hack, but it means one less private hook */ - nt_status = hdb_samba4_create_kdc(base_ctx, context, db); - -@@ -90,8 +70,7 @@ static void hdb_samba4_fini(void *ctx) - - /* Only used in the hdb-backed keytab code - * for a keytab of 'samba4&
' or samba4, to find -- * kpasswd's key in the main DB, and to -- * copy all the keys into a file (libnet_keytab_export) -+ * kpasswd's key in the main DB - * - * The
is the string form of a pointer to a talloced struct hdb_samba_context - */ --- -2.25.1 - - -From e21efbabccbf9c422347e9e94b3f217186556ee7 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Thu, 26 May 2022 16:39:20 +1200 -Subject: [PATCH 91/99] CVE-2022-32744 s4:kdc: Modify HDB plugin to only look - up kpasswd principal - -This plugin is now only used by the kpasswd service. Thus, ensuring we -only look up the kadmin/changepw principal means we can't be fooled into -accepting tickets for other service principals. We make sure not to -specify a specific kvno, to ensure that we do not accept RODC-issued -tickets. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15074 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andreas Schneider - -[jsutton@samba.org Fixed knownfail conflicts] - -[jsutton@samba.org Renamed entry to entry_ex; fixed knownfail conflicts; - retained knownfail for test_kpasswd_from_rodc which now causes the KDC - to panic] ---- - selftest/knownfail_heimdal_kdc | 3 -- - source4/kdc/hdb-samba4-plugin.c | 2 +- - source4/kdc/hdb-samba4.c | 66 +++++++++++++++++++++++++++++++++ - source4/kdc/kdc-glue.h | 3 ++ - 4 files changed, 70 insertions(+), 4 deletions(-) - -diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc -index dfe04dd1448..1b5063d2630 100644 ---- a/selftest/knownfail_heimdal_kdc -+++ b/selftest/knownfail_heimdal_kdc -@@ -113,6 +113,3 @@ - # Kpasswd tests - # - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_from_rodc.ad_dc --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key.ad_dc --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key_server.ad_dc --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key_service.ad_dc -diff --git a/source4/kdc/hdb-samba4-plugin.c b/source4/kdc/hdb-samba4-plugin.c -index 4b90a766f76..dba25e825de 100644 ---- a/source4/kdc/hdb-samba4-plugin.c -+++ b/source4/kdc/hdb-samba4-plugin.c -@@ -36,7 +36,7 @@ static krb5_error_code hdb_samba4_create(krb5_context context, struct HDB **db, - base_ctx = talloc_get_type_abort(ptr, struct samba_kdc_base_context); - - /* The global kdc_mem_ctx and kdc_lp_ctx, Disgusting, ugly hack, but it means one less private hook */ -- nt_status = hdb_samba4_create_kdc(base_ctx, context, db); -+ nt_status = hdb_samba4_kpasswd_create_kdc(base_ctx, context, db); - - if (NT_STATUS_IS_OK(nt_status)) { - return 0; -diff --git a/source4/kdc/hdb-samba4.c b/source4/kdc/hdb-samba4.c -index 43e836f8360..a8aae50b5b0 100644 ---- a/source4/kdc/hdb-samba4.c -+++ b/source4/kdc/hdb-samba4.c -@@ -136,6 +136,47 @@ static krb5_error_code hdb_samba4_fetch_kvno(krb5_context context, HDB *db, - return code; - } - -+static krb5_error_code hdb_samba4_kpasswd_fetch_kvno(krb5_context context, HDB *db, -+ krb5_const_principal _principal, -+ unsigned flags, -+ krb5_kvno _kvno, -+ hdb_entry_ex *entry_ex) -+{ -+ struct samba_kdc_db_context *kdc_db_ctx = NULL; -+ krb5_error_code ret; -+ krb5_principal kpasswd_principal = NULL; -+ -+ kdc_db_ctx = talloc_get_type_abort(db->hdb_db, -+ struct samba_kdc_db_context); -+ -+ ret = smb_krb5_make_principal(context, &kpasswd_principal, -+ lpcfg_realm(kdc_db_ctx->lp_ctx), -+ "kadmin", "changepw", -+ NULL); -+ if (ret) { -+ return ret; -+ } -+ smb_krb5_principal_set_type(context, kpasswd_principal, KRB5_NT_SRV_INST); -+ -+ /* -+ * For the kpasswd service, always ensure we get the latest kvno. This -+ * also means we (correctly) refuse RODC-issued tickets. -+ */ -+ flags &= ~HDB_F_KVNO_SPECIFIED; -+ -+ /* Don't bother looking up a client or krbtgt. */ -+ flags &= ~(SDB_F_GET_CLIENT|SDB_F_GET_KRBTGT); -+ -+ ret = hdb_samba4_fetch_kvno(context, db, -+ kpasswd_principal, -+ flags, -+ 0, -+ entry_ex); -+ -+ krb5_free_principal(context, kpasswd_principal); -+ return ret; -+} -+ - static krb5_error_code hdb_samba4_firstkey(krb5_context context, HDB *db, unsigned flags, - hdb_entry_ex *entry) - { -@@ -194,6 +235,14 @@ static krb5_error_code hdb_samba4_nextkey(krb5_context context, HDB *db, unsigne - return ret; - } - -+static krb5_error_code hdb_samba4_nextkey_panic(krb5_context context, HDB *db, -+ unsigned flags, -+ hdb_entry_ex *entry) -+{ -+ DBG_ERR("Attempt to iterate kpasswd keytab => PANIC\n"); -+ smb_panic("hdb_samba4_nextkey_panic: Attempt to iterate kpasswd keytab"); -+} -+ - static krb5_error_code hdb_samba4_destroy(krb5_context context, HDB *db) - { - talloc_free(db); -@@ -522,3 +571,20 @@ NTSTATUS hdb_samba4_create_kdc(struct samba_kdc_base_context *base_ctx, - - return NT_STATUS_OK; - } -+ -+NTSTATUS hdb_samba4_kpasswd_create_kdc(struct samba_kdc_base_context *base_ctx, -+ krb5_context context, struct HDB **db) -+{ -+ NTSTATUS nt_status; -+ -+ nt_status = hdb_samba4_create_kdc(base_ctx, context, db); -+ if (!NT_STATUS_IS_OK(nt_status)) { -+ return nt_status; -+ } -+ -+ (*db)->hdb_fetch_kvno = hdb_samba4_kpasswd_fetch_kvno; -+ (*db)->hdb_firstkey = hdb_samba4_nextkey_panic; -+ (*db)->hdb_nextkey = hdb_samba4_nextkey_panic; -+ -+ return NT_STATUS_OK; -+} -diff --git a/source4/kdc/kdc-glue.h b/source4/kdc/kdc-glue.h -index c083b8c6429..ff8684e1666 100644 ---- a/source4/kdc/kdc-glue.h -+++ b/source4/kdc/kdc-glue.h -@@ -45,6 +45,9 @@ kdc_code kpasswdd_process(struct kdc_server *kdc, - NTSTATUS hdb_samba4_create_kdc(struct samba_kdc_base_context *base_ctx, - krb5_context context, struct HDB **db); - -+NTSTATUS hdb_samba4_kpasswd_create_kdc(struct samba_kdc_base_context *base_ctx, -+ krb5_context context, struct HDB **db); -+ - /* from kdc-glue.c */ - int kdc_check_pac(krb5_context krb5_context, - DATA_BLOB server_sig, --- -2.25.1 - - -From b64e1b4a510c81628feeb68af75afd3275ea75c3 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Mon, 30 May 2022 19:16:02 +1200 -Subject: [PATCH 92/99] CVE-2022-32744 s4:kpasswd: Ensure we pass the kpasswd - server principal into krb5_rd_req_ctx() - -To ensure that, when decrypting the kpasswd ticket, we look up the -correct principal and don't trust the sname from the ticket, we should -pass the principal name of the kpasswd service into krb5_rd_req_ctx(). -However, gensec_krb5_update_internal() will pass in NULL unless the -principal in our credentials is CRED_SPECIFIED. - -At present, our principal will be considered obtained as CRED_SMB_CONF -(from the cli_credentials_set_conf() a few lines up), so we explicitly -set the realm again, but this time as CRED_SPECIFIED. Now the value of -server_in_keytab that we provide to smb_krb5_rd_req_decoded() will not -be NULL. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15074 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andreas Schneider - -[jsutton@samba.org Removed knownfail as KDC no longer panics] ---- - selftest/knownfail_heimdal_kdc | 4 ---- - selftest/knownfail_mit_kdc | 2 -- - source4/kdc/kpasswd-service.c | 30 ++++++++++++++++++++++++++++++ - 3 files changed, 30 insertions(+), 6 deletions(-) - -diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc -index 1b5063d2630..692b9ecdd72 100644 ---- a/selftest/knownfail_heimdal_kdc -+++ b/selftest/knownfail_heimdal_kdc -@@ -109,7 +109,3 @@ - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_service_ticket - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_sid_mismatch_existing - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_sid_mismatch_nonexisting --# --# Kpasswd tests --# --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_from_rodc.ad_dc -diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc -index ed8f7069319..6cad47701ae 100644 ---- a/selftest/knownfail_mit_kdc -+++ b/selftest/knownfail_mit_kdc -@@ -547,5 +547,3 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_canonicalize_realm_case.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_no_canonicalize_realm_case.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_ticket_requester_sid_tgs.ad_dc --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key_server.ad_dc --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key_service.ad_dc -diff --git a/source4/kdc/kpasswd-service.c b/source4/kdc/kpasswd-service.c -index aec30850173..d2f1bb02906 100644 ---- a/source4/kdc/kpasswd-service.c -+++ b/source4/kdc/kpasswd-service.c -@@ -29,6 +29,7 @@ - #include "kdc/kdc-server.h" - #include "kdc/kpasswd-service.h" - #include "kdc/kpasswd-helper.h" -+#include "param/param.h" - - #define HEADER_LEN 6 - #ifndef RFC3244_VERSION -@@ -161,6 +162,20 @@ kdc_code kpasswd_process(struct kdc_server *kdc, - goto done; - } - -+ /* -+ * After calling cli_credentials_set_conf(), explicitly set the realm -+ * with CRED_SPECIFIED. We need to do this so the result of -+ * principal_from_credentials() called from the gensec layer is -+ * CRED_SPECIFIED rather than CRED_SMB_CONF, avoiding a fallback to -+ * match-by-key (very undesirable in this case). -+ */ -+ ok = cli_credentials_set_realm(server_credentials, -+ lpcfg_realm(kdc->task->lp_ctx), -+ CRED_SPECIFIED); -+ if (!ok) { -+ goto done; -+ } -+ - ok = cli_credentials_set_username(server_credentials, - "kadmin/changepw", - CRED_SPECIFIED); -@@ -168,6 +183,21 @@ kdc_code kpasswd_process(struct kdc_server *kdc, - goto done; - } - -+ /* Check that the server principal is indeed CRED_SPECIFIED. */ -+ { -+ char *principal = NULL; -+ enum credentials_obtained obtained; -+ -+ principal = cli_credentials_get_principal_and_obtained(server_credentials, -+ tmp_ctx, -+ &obtained); -+ if (obtained < CRED_SPECIFIED) { -+ goto done; -+ } -+ -+ TALLOC_FREE(principal); -+ } -+ - rv = cli_credentials_set_keytab_name(server_credentials, - kdc->task->lp_ctx, - kdc->kpasswd_keytab_name, --- -2.25.1 - - -From 22bd1bc2d7308167ea316c6b48f130d378ab4c8b Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Fri, 10 Jun 2022 19:17:11 +1200 -Subject: [PATCH 93/99] CVE-2022-2031 tests/krb5: Add test that we cannot - provide a TGT to kpasswd - -The kpasswd service should require a kpasswd service ticket, and -disallow TGTs. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15047 -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15049 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andreas Schneider - -[jsutton@samba.org Fixed knownfail conflicts] - -[jsutton@samba.org Fixed knownfail conflicts] ---- - python/samba/tests/krb5/kpasswd_tests.py | 28 ++++++++++++++++++++++++ - selftest/knownfail_heimdal_kdc | 4 ++++ - selftest/knownfail_mit_kdc | 4 ++++ - 3 files changed, 36 insertions(+) - -diff --git a/python/samba/tests/krb5/kpasswd_tests.py b/python/samba/tests/krb5/kpasswd_tests.py -index 3a6c7d818dc..0db857f7bbd 100755 ---- a/python/samba/tests/krb5/kpasswd_tests.py -+++ b/python/samba/tests/krb5/kpasswd_tests.py -@@ -31,6 +31,7 @@ from samba.tests.krb5.rfc4120_constants import ( - KDC_ERR_TGT_REVOKED, - KDC_ERR_TKT_EXPIRED, - KPASSWD_ACCESSDENIED, -+ KPASSWD_AUTHERROR, - KPASSWD_HARDERROR, - KPASSWD_INITIAL_FLAG_NEEDED, - KPASSWD_MALFORMED, -@@ -779,6 +780,33 @@ class KpasswdTests(KDCBaseTest): - self._make_tgs_request(creds, service_creds, ticket, - expect_error=False) - -+ # Show that we cannot provide a TGT to kpasswd to change the password. -+ def test_kpasswd_tgt(self): -+ # Create an account for testing, and get a TGT. -+ creds = self._get_creds() -+ tgt = self.get_tgt(creds) -+ -+ # Change the sname of the ticket to match that of kadmin/changepw. -+ tgt.set_sname(self.get_kpasswd_sname()) -+ -+ expected_code = KPASSWD_AUTHERROR -+ expected_msg = b'A TGT may not be used as a ticket to kpasswd' -+ -+ # Set the password. -+ new_password = generate_random_password(32, 32) -+ self.kpasswd_exchange(tgt, -+ new_password, -+ expected_code, -+ expected_msg, -+ mode=self.KpasswdMode.SET) -+ -+ # Change the password. -+ self.kpasswd_exchange(tgt, -+ new_password, -+ expected_code, -+ expected_msg, -+ mode=self.KpasswdMode.CHANGE) -+ - # Test that kpasswd rejects requests with a service ticket. - def test_kpasswd_non_initial(self): - # Create an account for testing, and get a TGT. -diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc -index 692b9ecdd72..7b439478eca 100644 ---- a/selftest/knownfail_heimdal_kdc -+++ b/selftest/knownfail_heimdal_kdc -@@ -109,3 +109,7 @@ - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_service_ticket - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_sid_mismatch_existing - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_sid_mismatch_nonexisting -+# -+# Kpasswd tests -+# -+^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_tgt.ad_dc -diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc -index 6cad47701ae..7e0cdd9a3b7 100644 ---- a/selftest/knownfail_mit_kdc -+++ b/selftest/knownfail_mit_kdc -@@ -547,3 +547,7 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_canonicalize_realm_case.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_no_canonicalize_realm_case.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_ticket_requester_sid_tgs.ad_dc -+# -+# Kpasswd tests -+# -+samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_tgt.ad_dc --- -2.25.1 - - -From be9945a4d8e774e8255dd9ae0ed29c9a953ce3ff Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Fri, 10 Jun 2022 19:18:07 +1200 -Subject: [PATCH 94/99] CVE-2022-2031 auth: Add ticket type field to - auth_user_info_dc and auth_session_info - -This field may be used to convey whether we were provided with a TGT or -a non-TGT. We ensure both structures are zeroed out to avoid incorrect -results being produced by an uninitialised field. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15047 -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15049 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andreas Schneider ---- - auth/auth_sam_reply.c | 2 +- - auth/auth_util.c | 2 +- - librpc/idl/auth.idl | 23 +++++++++++++++++++++++ - source4/auth/ntlm/auth_developer.c | 2 +- - source4/auth/sam.c | 2 +- - source4/auth/session.c | 2 ++ - source4/auth/system_session.c | 6 +++--- - 7 files changed, 32 insertions(+), 7 deletions(-) - -diff --git a/auth/auth_sam_reply.c b/auth/auth_sam_reply.c -index b5b6362dc93..2e27e5715d1 100644 ---- a/auth/auth_sam_reply.c -+++ b/auth/auth_sam_reply.c -@@ -416,7 +416,7 @@ NTSTATUS make_user_info_dc_netlogon_validation(TALLOC_CTX *mem_ctx, - return NT_STATUS_INVALID_LEVEL; - } - -- user_info_dc = talloc(mem_ctx, struct auth_user_info_dc); -+ user_info_dc = talloc_zero(mem_ctx, struct auth_user_info_dc); - NT_STATUS_HAVE_NO_MEMORY(user_info_dc); - - /* -diff --git a/auth/auth_util.c b/auth/auth_util.c -index fe01babd107..ec9094d0f15 100644 ---- a/auth/auth_util.c -+++ b/auth/auth_util.c -@@ -44,7 +44,7 @@ struct auth_session_info *copy_session_info(TALLOC_CTX *mem_ctx, - return NULL; - } - -- dst = talloc(mem_ctx, struct auth_session_info); -+ dst = talloc_zero(mem_ctx, struct auth_session_info); - if (dst == NULL) { - DBG_ERR("talloc failed\n"); - TALLOC_FREE(frame); -diff --git a/librpc/idl/auth.idl b/librpc/idl/auth.idl -index 7de3d4c6bfb..59ed2c3c5ea 100644 ---- a/librpc/idl/auth.idl -+++ b/librpc/idl/auth.idl -@@ -75,6 +75,26 @@ interface auth - [unique,charset(UTF8),string] char *sanitized_username; - } auth_user_info_unix; - -+ /* -+ * If the user was authenticated with a Kerberos ticket, this indicates -+ * the type of the ticket; TGT, or non-TGT (i.e. service ticket). If -+ * unset, the type is unknown. This indicator is useful for the KDC and -+ * the kpasswd service, which share the same account and keys. By -+ * ensuring it is provided with the appopriate ticket type, each service -+ * avoids accepting a ticket meant for the other. -+ * -+ * The heuristic used to determine the type is the presence or absence -+ * of a REQUESTER_SID buffer in the PAC; we use its presence to assume -+ * we have a TGT. This heuristic will fail for older Samba versions and -+ * Windows prior to Nov. 2021 updates, which lack support for this -+ * buffer. -+ */ -+ typedef enum { -+ TICKET_TYPE_UNKNOWN = 0, -+ TICKET_TYPE_TGT = 1, -+ TICKET_TYPE_NON_TGT = 2 -+ } ticket_type; -+ - /* This is the interim product of the auth subsystem, before - * privileges and local groups are handled */ - typedef [public] struct { -@@ -83,6 +103,7 @@ interface auth - auth_user_info *info; - [noprint] DATA_BLOB user_session_key; - [noprint] DATA_BLOB lm_session_key; -+ ticket_type ticket_type; - } auth_user_info_dc; - - typedef [public] struct { -@@ -112,6 +133,8 @@ interface auth - * We generate this in auth_generate_session_info() - */ - GUID unique_session_token; -+ -+ ticket_type ticket_type; - } auth_session_info; - - typedef [public] struct { -diff --git a/source4/auth/ntlm/auth_developer.c b/source4/auth/ntlm/auth_developer.c -index 1823989c68d..6e92252d5c5 100644 ---- a/source4/auth/ntlm/auth_developer.c -+++ b/source4/auth/ntlm/auth_developer.c -@@ -76,7 +76,7 @@ static NTSTATUS name_to_ntstatus_check_password(struct auth_method_context *ctx, - } - NT_STATUS_NOT_OK_RETURN(nt_status); - -- user_info_dc = talloc(mem_ctx, struct auth_user_info_dc); -+ user_info_dc = talloc_zero(mem_ctx, struct auth_user_info_dc); - NT_STATUS_HAVE_NO_MEMORY(user_info_dc); - - /* This returns a pointer to a struct dom_sid, which is the -diff --git a/source4/auth/sam.c b/source4/auth/sam.c -index 8b233bab3ad..7c609655fcb 100644 ---- a/source4/auth/sam.c -+++ b/source4/auth/sam.c -@@ -363,7 +363,7 @@ _PUBLIC_ NTSTATUS authsam_make_user_info_dc(TALLOC_CTX *mem_ctx, - TALLOC_CTX *tmp_ctx; - struct ldb_message_element *el; - -- user_info_dc = talloc(mem_ctx, struct auth_user_info_dc); -+ user_info_dc = talloc_zero(mem_ctx, struct auth_user_info_dc); - NT_STATUS_HAVE_NO_MEMORY(user_info_dc); - - tmp_ctx = talloc_new(user_info_dc); -diff --git a/source4/auth/session.c b/source4/auth/session.c -index 8cf8670d848..34ad557eebb 100644 ---- a/source4/auth/session.c -+++ b/source4/auth/session.c -@@ -222,6 +222,8 @@ _PUBLIC_ NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx, - - session_info->credentials = NULL; - -+ session_info->ticket_type = user_info_dc->ticket_type; -+ - talloc_steal(mem_ctx, session_info); - *_session_info = session_info; - talloc_free(tmp_ctx); -diff --git a/source4/auth/system_session.c b/source4/auth/system_session.c -index e46b4584817..17cfc4bab8b 100644 ---- a/source4/auth/system_session.c -+++ b/source4/auth/system_session.c -@@ -119,7 +119,7 @@ NTSTATUS auth_system_user_info_dc(TALLOC_CTX *mem_ctx, const char *netbios_name, - struct auth_user_info_dc *user_info_dc; - struct auth_user_info *info; - -- user_info_dc = talloc(mem_ctx, struct auth_user_info_dc); -+ user_info_dc = talloc_zero(mem_ctx, struct auth_user_info_dc); - NT_STATUS_HAVE_NO_MEMORY(user_info_dc); - - /* This returns a pointer to a struct dom_sid, which is the -@@ -195,7 +195,7 @@ static NTSTATUS auth_domain_admin_user_info_dc(TALLOC_CTX *mem_ctx, - struct auth_user_info_dc *user_info_dc; - struct auth_user_info *info; - -- user_info_dc = talloc(mem_ctx, struct auth_user_info_dc); -+ user_info_dc = talloc_zero(mem_ctx, struct auth_user_info_dc); - NT_STATUS_HAVE_NO_MEMORY(user_info_dc); - - user_info_dc->num_sids = 7; -@@ -364,7 +364,7 @@ _PUBLIC_ NTSTATUS auth_anonymous_user_info_dc(TALLOC_CTX *mem_ctx, - { - struct auth_user_info_dc *user_info_dc; - struct auth_user_info *info; -- user_info_dc = talloc(mem_ctx, struct auth_user_info_dc); -+ user_info_dc = talloc_zero(mem_ctx, struct auth_user_info_dc); - NT_STATUS_HAVE_NO_MEMORY(user_info_dc); - - /* This returns a pointer to a struct dom_sid, which is the --- -2.25.1 - - -From b7e3cb83005ef28c70dc8d64cd0a57ba80ae9f4e Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Fri, 10 Jun 2022 19:18:35 +1200 -Subject: [PATCH 95/99] CVE-2022-2031 s4:auth: Use PAC to determine whether - ticket is a TGT - -We use the presence or absence of a REQUESTER_SID PAC buffer to -determine whether the ticket is a TGT. We will later use this to reject -TGTs where a service ticket is expected. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15047 -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15049 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andreas Schneider ---- - source4/auth/kerberos/kerberos_pac.c | 44 ++++++++++++++++++++++++++++ - 1 file changed, 44 insertions(+) - -diff --git a/source4/auth/kerberos/kerberos_pac.c b/source4/auth/kerberos/kerberos_pac.c -index 54ef4d61b02..bd0ae20e007 100644 ---- a/source4/auth/kerberos/kerberos_pac.c -+++ b/source4/auth/kerberos/kerberos_pac.c -@@ -282,6 +282,28 @@ - return ret; - } - -+static krb5_error_code kerberos_pac_buffer_present(krb5_context context, -+ const krb5_pac pac, -+ uint32_t type) -+{ -+#ifdef SAMBA4_USES_HEIMDAL -+ return krb5_pac_get_buffer(context, pac, type, NULL); -+#else /* MIT */ -+ krb5_error_code ret; -+ krb5_data data; -+ -+ /* -+ * MIT won't let us pass NULL for the data parameter, so we are forced -+ * to allocate a new buffer and then immediately free it. -+ */ -+ ret = krb5_pac_get_buffer(context, pac, type, &data); -+ if (ret == 0) { -+ krb5_free_data_contents(context, &data); -+ } -+ return ret; -+#endif /* SAMBA4_USES_HEIMDAL */ -+} -+ - krb5_error_code kerberos_pac_to_user_info_dc(TALLOC_CTX *mem_ctx, - krb5_pac pac, - krb5_context context, -@@ -414,6 +436,28 @@ krb5_error_code kerberos_pac_to_user_info_dc(TALLOC_CTX *mem_ctx, - return EINVAL; - } - } -+ -+ /* -+ * Based on the presence of a REQUESTER_SID PAC buffer, ascertain -+ * whether the ticket is a TGT. This helps the KDC and kpasswd service -+ * ensure they do not accept tickets meant for the other. -+ * -+ * This heuristic will fail for older Samba versions and Windows prior -+ * to Nov. 2021 updates, which lack support for the REQUESTER_SID PAC -+ * buffer. -+ */ -+ ret = kerberos_pac_buffer_present(context, pac, PAC_TYPE_REQUESTER_SID); -+ if (ret == ENOENT) { -+ /* This probably isn't a TGT. */ -+ user_info_dc_out->ticket_type = TICKET_TYPE_NON_TGT; -+ } else if (ret != 0) { -+ talloc_free(tmp_ctx); -+ return ret; -+ } else { -+ /* This probably is a TGT. */ -+ user_info_dc_out->ticket_type = TICKET_TYPE_TGT; -+ } -+ - *user_info_dc = user_info_dc_out; - - return 0; --- -2.25.1 - - -From 63d353e7b5ef235a86bf6df595951dc831108234 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Fri, 10 Jun 2022 19:18:53 +1200 -Subject: [PATCH 96/99] CVE-2022-2031 s4:kpasswd: Do not accept TGTs as kpasswd - tickets - -If TGTs can be used as kpasswd tickets, the two-minute lifetime of a -authentic kpasswd ticket may be bypassed. Furthermore, kpasswd tickets -are not supposed to be cached, but using this flaw, a stolen credentials -cache containing a TGT may be used to change that account's password, -and thus is made more valuable to an attacker. - -Since all TGTs should be issued with a REQUESTER_SID PAC buffer, and -service tickets without it, we assert the absence of this buffer to -ensure we're not accepting a TGT. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15047 -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15049 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andreas Schneider - -[jsutton@samba.org Fixed knownfail conflicts] - -[jsutton@samba.org Fixed knownfail conflicts] ---- - selftest/knownfail_heimdal_kdc | 4 ---- - selftest/knownfail_mit_kdc | 4 ---- - source4/kdc/kpasswd-helper.c | 20 ++++++++++++++++++++ - source4/kdc/kpasswd-helper.h | 2 ++ - source4/kdc/kpasswd-service-heimdal.c | 13 +++++++++++++ - source4/kdc/kpasswd-service-mit.c | 13 +++++++++++++ - 6 files changed, 48 insertions(+), 8 deletions(-) - -diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc -index 7b439478eca..692b9ecdd72 100644 ---- a/selftest/knownfail_heimdal_kdc -+++ b/selftest/knownfail_heimdal_kdc -@@ -109,7 +109,3 @@ - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_service_ticket - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_sid_mismatch_existing - ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_sid_mismatch_nonexisting --# --# Kpasswd tests --# --^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_tgt.ad_dc -diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc -index 7e0cdd9a3b7..6cad47701ae 100644 ---- a/selftest/knownfail_mit_kdc -+++ b/selftest/knownfail_mit_kdc -@@ -547,7 +547,3 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_canonicalize_realm_case.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_no_canonicalize_realm_case.ad_dc - ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_ticket_requester_sid_tgs.ad_dc --# --# Kpasswd tests --# --samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_tgt.ad_dc -diff --git a/source4/kdc/kpasswd-helper.c b/source4/kdc/kpasswd-helper.c -index 55a2f5b3bf6..2ffdb79aea5 100644 ---- a/source4/kdc/kpasswd-helper.c -+++ b/source4/kdc/kpasswd-helper.c -@@ -241,3 +241,23 @@ NTSTATUS kpasswd_samdb_set_password(TALLOC_CTX *mem_ctx, - - return status; - } -+ -+krb5_error_code kpasswd_check_non_tgt(struct auth_session_info *session_info, -+ const char **error_string) -+{ -+ switch(session_info->ticket_type) { -+ case TICKET_TYPE_TGT: -+ /* TGTs are disallowed here. */ -+ *error_string = "A TGT may not be used as a ticket to kpasswd"; -+ return KRB5_KPASSWD_AUTHERROR; -+ case TICKET_TYPE_NON_TGT: -+ /* Non-TGTs are permitted, and expected. */ -+ break; -+ default: -+ /* In case we forgot to set the type. */ -+ *error_string = "Failed to ascertain that ticket to kpasswd is not a TGT"; -+ return KRB5_KPASSWD_HARDERROR; -+ } -+ -+ return 0; -+} -diff --git a/source4/kdc/kpasswd-helper.h b/source4/kdc/kpasswd-helper.h -index 8fad81e0a5d..94a6e2acfdd 100644 ---- a/source4/kdc/kpasswd-helper.h -+++ b/source4/kdc/kpasswd-helper.h -@@ -43,4 +43,6 @@ NTSTATUS kpasswd_samdb_set_password(TALLOC_CTX *mem_ctx, - enum samPwdChangeReason *reject_reason, - struct samr_DomInfo1 **dominfo); - -+krb5_error_code kpasswd_check_non_tgt(struct auth_session_info *session_info, -+ const char **error_string); - #endif /* _KPASSWD_HELPER_H */ -diff --git a/source4/kdc/kpasswd-service-heimdal.c b/source4/kdc/kpasswd-service-heimdal.c -index a0352d1ad35..4d009b9eb24 100644 ---- a/source4/kdc/kpasswd-service-heimdal.c -+++ b/source4/kdc/kpasswd-service-heimdal.c -@@ -253,6 +253,7 @@ krb5_error_code kpasswd_handle_request(struct kdc_server *kdc, - { - struct auth_session_info *session_info; - NTSTATUS status; -+ krb5_error_code code; - - status = gensec_session_info(gensec_security, - mem_ctx, -@@ -264,6 +265,18 @@ krb5_error_code kpasswd_handle_request(struct kdc_server *kdc, - return KRB5_KPASSWD_HARDERROR; - } - -+ /* -+ * Since the kpasswd service shares its keys with the krbtgt, we might -+ * have received a TGT rather than a kpasswd ticket. We need to check -+ * the ticket type to ensure that TGTs cannot be misused in this manner. -+ */ -+ code = kpasswd_check_non_tgt(session_info, -+ error_string); -+ if (code != 0) { -+ DBG_WARNING("%s\n", *error_string); -+ return code; -+ } -+ - switch(verno) { - case KRB5_KPASSWD_VERS_CHANGEPW: { - DATA_BLOB password = data_blob_null; -diff --git a/source4/kdc/kpasswd-service-mit.c b/source4/kdc/kpasswd-service-mit.c -index de4c6f3f622..6b051567b6e 100644 ---- a/source4/kdc/kpasswd-service-mit.c -+++ b/source4/kdc/kpasswd-service-mit.c -@@ -332,6 +332,7 @@ krb5_error_code kpasswd_handle_request(struct kdc_server *kdc, - { - struct auth_session_info *session_info; - NTSTATUS status; -+ krb5_error_code code; - - status = gensec_session_info(gensec_security, - mem_ctx, -@@ -344,6 +345,18 @@ krb5_error_code kpasswd_handle_request(struct kdc_server *kdc, - return KRB5_KPASSWD_HARDERROR; - } - -+ /* -+ * Since the kpasswd service shares its keys with the krbtgt, we might -+ * have received a TGT rather than a kpasswd ticket. We need to check -+ * the ticket type to ensure that TGTs cannot be misused in this manner. -+ */ -+ code = kpasswd_check_non_tgt(session_info, -+ error_string); -+ if (code != 0) { -+ DBG_WARNING("%s\n", *error_string); -+ return code; -+ } -+ - switch(verno) { - case 1: { - DATA_BLOB password; --- -2.25.1 - - -From 185a6d12935f55ad996de502e416114cc1f5aba0 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Thu, 23 Jun 2022 13:59:11 +1200 -Subject: [PATCH 97/99] CVE-2022-2031 testprogs: Add test for short-lived - ticket across an incoming trust - -We ensure that the KDC does not reject a TGS-REQ with our short-lived -TGT over an incoming trust. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15047 - -Signed-off-by: Joseph Sutton ---- - testprogs/blackbox/test_kinit_trusts_heimdal.sh | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/testprogs/blackbox/test_kinit_trusts_heimdal.sh b/testprogs/blackbox/test_kinit_trusts_heimdal.sh -index 52b1ac6589c..29ea1c510ce 100755 ---- a/testprogs/blackbox/test_kinit_trusts_heimdal.sh -+++ b/testprogs/blackbox/test_kinit_trusts_heimdal.sh -@@ -55,6 +55,10 @@ testit "kinit with password" $samba4kinit $enctype --password-file=$PREFIX/tmppa - test_smbclient "Test login with user kerberos ccache" 'ls' "$unc" --use-krb5-ccache=$KRB5CCNAME || failed=`expr $failed + 1` - rm -rf $KRB5CCNAME_PATH - -+testit "kinit with password and two minute lifetime" $samba4kinit $enctype --password-file=$PREFIX/tmppassfile --request-pac --server=krbtgt/$REALM@$TRUST_REALM --lifetime=2m $TRUST_USERNAME@$TRUST_REALM || failed=`expr $failed + 1` -+test_smbclient "Test login with user kerberos ccache and two minute lifetime" 'ls' "$unc" --use-krb5-ccache=$KRB5CCNAME || failed=`expr $failed + 1` -+rm -rf $KRB5CCNAME_PATH -+ - # Test with smbclient4 - smbclient="$samba4bindir/smbclient4" - testit "kinit with password" $samba4kinit $enctype --password-file=$PREFIX/tmppassfile --request-pac $TRUST_USERNAME@$TRUST_REALM || failed=`expr $failed + 1` -@@ -95,5 +99,5 @@ testit "wbinfo check outgoing trust pw" $VALGRIND $wbinfo --check-secret --domai - - test_smbclient "Test user login with the changed outgoing secret" 'ls' "$unc" --use-kerberos=required -U$USERNAME@$REALM%$PASSWORD || failed=`expr $failed + 1` - --rm -f $PREFIX/tmpccache tmpccfile tmppassfile tmpuserpassfile tmpuserccache -+rm -f $PREFIX/tmpccache $PREFIX/tmppassfile - exit $failed --- -2.25.1 diff --git a/backport-CVE-2022-32742.patch b/backport-CVE-2022-32742.patch deleted file mode 100644 index 049d0c97b401161adca3d36389f81c61eb1f6351..0000000000000000000000000000000000000000 --- a/backport-CVE-2022-32742.patch +++ /dev/null @@ -1,216 +0,0 @@ -From d6aef6838a674ab95ff9172f4ac67707667f9e00 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Tue, 7 Jun 2022 09:40:45 -0700 -Subject: [PATCH 98/99] CVE-2022-32742: s4: torture: Add raw.write.bad-write - test. - -Reproduces the test code in: - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15085 - -Add knownfail. - -Signed-off-by: Jeremy Allison -Reviewed-by: David Disseldorp ---- - selftest/knownfail.d/bad-write | 2 + - source4/torture/raw/write.c | 89 ++++++++++++++++++++++++++++++++++ - 2 files changed, 91 insertions(+) - create mode 100644 selftest/knownfail.d/bad-write - -diff --git a/selftest/knownfail.d/bad-write b/selftest/knownfail.d/bad-write -new file mode 100644 -index 00000000000..5fc16606a13 ---- /dev/null -+++ b/selftest/knownfail.d/bad-write -@@ -0,0 +1,2 @@ -+^samba3.raw.write.bad-write\(nt4_dc_smb1\) -+^samba3.raw.write.bad-write\(ad_dc_smb1\) -diff --git a/source4/torture/raw/write.c b/source4/torture/raw/write.c -index 0a2f50f425b..661485bb548 100644 ---- a/source4/torture/raw/write.c -+++ b/source4/torture/raw/write.c -@@ -25,6 +25,7 @@ - #include "libcli/libcli.h" - #include "torture/util.h" - #include "torture/raw/proto.h" -+#include "libcli/raw/raw_proto.h" - - #define CHECK_STATUS(status, correct) do { \ - if (!NT_STATUS_EQUAL(status, correct)) { \ -@@ -694,6 +695,93 @@ done: - return ret; - } - -+/* -+ test a deliberately bad SMB1 write. -+*/ -+static bool test_bad_write(struct torture_context *tctx, -+ struct smbcli_state *cli) -+{ -+ bool ret = false; -+ int fnum = -1; -+ struct smbcli_request *req = NULL; -+ const char *fname = BASEDIR "\\badwrite.txt"; -+ bool ok = false; -+ -+ if (!torture_setup_dir(cli, BASEDIR)) { -+ torture_fail(tctx, "failed to setup basedir"); -+ } -+ -+ torture_comment(tctx, "Testing RAW_BAD_WRITE\n"); -+ -+ fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE); -+ if (fnum == -1) { -+ torture_fail_goto(tctx, -+ done, -+ talloc_asprintf(tctx, -+ "Failed to create %s - %s\n", -+ fname, -+ smbcli_errstr(cli->tree))); -+ } -+ -+ req = smbcli_request_setup(cli->tree, -+ SMBwrite, -+ 5, -+ 0); -+ if (req == NULL) { -+ torture_fail_goto(tctx, -+ done, -+ talloc_asprintf(tctx, "talloc fail\n")); -+ } -+ -+ SSVAL(req->out.vwv, VWV(0), fnum); -+ SSVAL(req->out.vwv, VWV(1), 65535); /* bad write length. */ -+ SIVAL(req->out.vwv, VWV(2), 0); /* offset */ -+ SSVAL(req->out.vwv, VWV(4), 0); /* remaining. */ -+ -+ if (!smbcli_request_send(req)) { -+ torture_fail_goto(tctx, -+ done, -+ talloc_asprintf(tctx, "Send failed\n")); -+ } -+ -+ if (!smbcli_request_receive(req)) { -+ torture_fail_goto(tctx, -+ done, -+ talloc_asprintf(tctx, "Reveive failed\n")); -+ } -+ -+ /* -+ * Check for expected error codes. -+ * ntvfs returns NT_STATUS_UNSUCCESSFUL. -+ */ -+ ok = (NT_STATUS_EQUAL(req->status, NT_STATUS_INVALID_PARAMETER) || -+ NT_STATUS_EQUAL(req->status, NT_STATUS_UNSUCCESSFUL)); -+ -+ if (!ok) { -+ torture_fail_goto(tctx, -+ done, -+ talloc_asprintf(tctx, -+ "Should have returned " -+ "NT_STATUS_INVALID_PARAMETER or " -+ "NT_STATUS_UNSUCCESSFUL " -+ "got %s\n", -+ nt_errstr(req->status))); -+ } -+ -+ ret = true; -+ -+done: -+ if (req != NULL) { -+ smbcli_request_destroy(req); -+ } -+ if (fnum != -1) { -+ smbcli_close(cli->tree, fnum); -+ } -+ smb_raw_exit(cli->session); -+ smbcli_deltree(cli->tree, BASEDIR); -+ return ret; -+} -+ - /* - basic testing of write calls - */ -@@ -705,6 +793,7 @@ struct torture_suite *torture_raw_write(TALLOC_CTX *mem_ctx) - torture_suite_add_1smb_test(suite, "write unlock", test_writeunlock); - torture_suite_add_1smb_test(suite, "write close", test_writeclose); - torture_suite_add_1smb_test(suite, "writex", test_writex); -+ torture_suite_add_1smb_test(suite, "bad-write", test_bad_write); - - return suite; - } --- -2.25.1 - - -From a4707e4a955d01edf493cd0d7ab8b1ecb4ca7991 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Wed, 8 Jun 2022 13:50:51 -0700 -Subject: [PATCH 99/99] CVE-2022-32742: s3: smbd: Harden the smbreq_bufrem() - macro. - -Fixes the raw.write.bad-write test. - -NB. We need the two (==0) changes in source3/smbd/reply.c -as the gcc optimizer now knows that the return from -smbreq_bufrem() can never be less than zero. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15085 - -Remove knownfail. - -Signed-off-by: Jeremy Allison -Reviewed-by: David Disseldorp ---- - selftest/knownfail.d/bad-write | 2 -- - source3/include/smb_macros.h | 2 +- - source3/smbd/reply.c | 4 ++-- - 3 files changed, 3 insertions(+), 5 deletions(-) - delete mode 100644 selftest/knownfail.d/bad-write - -diff --git a/selftest/knownfail.d/bad-write b/selftest/knownfail.d/bad-write -deleted file mode 100644 -index 5fc16606a13..00000000000 ---- a/selftest/knownfail.d/bad-write -+++ /dev/null -@@ -1,2 +0,0 @@ --^samba3.raw.write.bad-write\(nt4_dc_smb1\) --^samba3.raw.write.bad-write\(ad_dc_smb1\) -diff --git a/source3/include/smb_macros.h b/source3/include/smb_macros.h -index ba2c76764d1..9f1d00835d7 100644 ---- a/source3/include/smb_macros.h -+++ b/source3/include/smb_macros.h -@@ -152,7 +152,7 @@ - - /* the remaining number of bytes in smb buffer 'buf' from pointer 'p'. */ - #define smb_bufrem(buf, p) (smb_buflen(buf)-PTR_DIFF(p, smb_buf(buf))) --#define smbreq_bufrem(req, p) (req->buflen - PTR_DIFF(p, req->buf)) -+#define smbreq_bufrem(req, p) ((req)->buflen < PTR_DIFF((p), (req)->buf) ? 0 : (req)->buflen - PTR_DIFF((p), (req)->buf)) - - - /* Note that chain_size must be available as an extern int to this macro. */ -diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c -index 879d5b2ae21..88c62b891ae 100644 ---- a/source3/smbd/reply.c -+++ b/source3/smbd/reply.c -@@ -344,7 +344,7 @@ size_t srvstr_get_path_req(TALLOC_CTX *mem_ctx, struct smb_request *req, - { - ssize_t bufrem = smbreq_bufrem(req, src); - -- if (bufrem < 0) { -+ if (bufrem == 0) { - *err = NT_STATUS_INVALID_PARAMETER; - return 0; - } -@@ -382,7 +382,7 @@ size_t srvstr_pull_req_talloc(TALLOC_CTX *ctx, struct smb_request *req, - { - ssize_t bufrem = smbreq_bufrem(req, src); - -- if (bufrem < 0) { -+ if (bufrem == 0) { - return 0; - } - --- -2.25.1 diff --git a/backport-CVE-2022-32745.patch b/backport-CVE-2022-32745.patch deleted file mode 100644 index 0bcdb25f563f9009e67f8c33e394889f2fc346ed..0000000000000000000000000000000000000000 --- a/backport-CVE-2022-32745.patch +++ /dev/null @@ -1,163 +0,0 @@ -From c231d424b89ba718262ed376431a982baaeef33f Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Wed, 16 Feb 2022 17:03:10 +1300 -Subject: [PATCH 15/99] CVE-2022-32745 s4/dsdb/samldb: Check for empty values - array - -This avoids potentially trying to access the first element of an empty -array. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15008 - -Signed-off-by: Joseph Sutton ---- - source4/dsdb/samdb/ldb_modules/samldb.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c -index b89d93910fd..3ecbd00e68e 100644 ---- a/source4/dsdb/samdb/ldb_modules/samldb.c -+++ b/source4/dsdb/samdb/ldb_modules/samldb.c -@@ -751,7 +751,7 @@ static int samldb_schema_add_handle_linkid(struct samldb_ctx *ac) - return ret; - } - -- if (el == NULL) { -+ if (el == NULL || el->num_values == 0) { - return LDB_SUCCESS; - } - -@@ -919,7 +919,7 @@ static int samldb_schema_add_handle_mapiid(struct samldb_ctx *ac) - return ret; - } - -- if (el == NULL) { -+ if (el == NULL || el->num_values == 0) { - return LDB_SUCCESS; - } - --- -2.25.1 - - -From d2dbb3b6818d429b12d54e68510286d033d4abd7 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Thu, 17 Feb 2022 11:11:53 +1300 -Subject: [PATCH 16/99] CVE-2022-32745 s4/dsdb/util: Use correct value for loop - count limit - -Currently, we can crash the server by sending a large number of values -of a specific attribute (such as sAMAccountName) spread across a few -message elements. If val_count is larger than the total number of -elements, we get an access beyond the elements array. - -Similarly, we can include unrelated message elements prior to the -message elements of the attribute in question, so that not all of the -attribute's values are copied into the returned elements values array. -This can cause the server to access uninitialised data, likely resulting -in a crash or unexpected behaviour. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15008 - -Signed-off-by: Joseph Sutton ---- - source4/dsdb/samdb/ldb_modules/util.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/source4/dsdb/samdb/ldb_modules/util.c b/source4/dsdb/samdb/ldb_modules/util.c -index 405febf0b3d..14947746837 100644 ---- a/source4/dsdb/samdb/ldb_modules/util.c -+++ b/source4/dsdb/samdb/ldb_modules/util.c -@@ -1546,7 +1546,7 @@ int dsdb_get_expected_new_values(TALLOC_CTX *mem_ctx, - - v = _el->values; - -- for (i = 0; i < val_count; i++) { -+ for (i = 0; i < msg->num_elements; i++) { - if (ldb_attr_cmp(msg->elements[i].name, attr_name) == 0) { - if ((operation == LDB_MODIFY) && - (LDB_FLAG_MOD_TYPE(msg->elements[i].flags) --- -2.25.1 - - -From d85bb9f5edc08ce2042be366c720dd027788f5bd Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Thu, 17 Feb 2022 11:13:38 +1300 -Subject: [PATCH 17/99] CVE-2022-32745 s4/dsdb/util: Don't call memcpy() with a - NULL pointer - -Doing so is undefined behaviour. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15008 - -Signed-off-by: Joseph Sutton ---- - source4/dsdb/samdb/ldb_modules/util.c | 12 ++++++++---- - 1 file changed, 8 insertions(+), 4 deletions(-) - -diff --git a/source4/dsdb/samdb/ldb_modules/util.c b/source4/dsdb/samdb/ldb_modules/util.c -index 14947746837..35ae110b5ef 100644 ---- a/source4/dsdb/samdb/ldb_modules/util.c -+++ b/source4/dsdb/samdb/ldb_modules/util.c -@@ -1548,15 +1548,19 @@ int dsdb_get_expected_new_values(TALLOC_CTX *mem_ctx, - - for (i = 0; i < msg->num_elements; i++) { - if (ldb_attr_cmp(msg->elements[i].name, attr_name) == 0) { -+ const struct ldb_message_element *tmp_el = &msg->elements[i]; - if ((operation == LDB_MODIFY) && -- (LDB_FLAG_MOD_TYPE(msg->elements[i].flags) -+ (LDB_FLAG_MOD_TYPE(tmp_el->flags) - == LDB_FLAG_MOD_DELETE)) { - continue; - } -+ if (tmp_el->values == NULL || tmp_el->num_values == 0) { -+ continue; -+ } - memcpy(v, -- msg->elements[i].values, -- msg->elements[i].num_values); -- v += msg->elements[i].num_values; -+ tmp_el->values, -+ tmp_el->num_values); -+ v += tmp_el->num_values; - } - } - --- -2.25.1 - - -From 6af497232e4ed24c33a29b77825fa854a73b5427 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Fri, 3 Jun 2022 16:16:31 +1200 -Subject: [PATCH 18/99] CVE-2022-32745 s4/dsdb/util: Correctly copy values into - message element - -To use memcpy(), we need to specify the number of bytes to copy, rather -than the number of ldb_val structures. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15008 - -Signed-off-by: Joseph Sutton ---- - source4/dsdb/samdb/ldb_modules/util.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/source4/dsdb/samdb/ldb_modules/util.c b/source4/dsdb/samdb/ldb_modules/util.c -index 35ae110b5ef..e7fe8f855df 100644 ---- a/source4/dsdb/samdb/ldb_modules/util.c -+++ b/source4/dsdb/samdb/ldb_modules/util.c -@@ -1559,7 +1559,7 @@ int dsdb_get_expected_new_values(TALLOC_CTX *mem_ctx, - } - memcpy(v, - tmp_el->values, -- tmp_el->num_values); -+ tmp_el->num_values * sizeof(*v)); - v += tmp_el->num_values; - } - } --- -2.25.1 - - diff --git a/backport-CVE-2022-32746.patch b/backport-CVE-2022-32746.patch deleted file mode 100644 index 9c25231eaea0cd2f1a365b84441253b089c5e144..0000000000000000000000000000000000000000 --- a/backport-CVE-2022-32746.patch +++ /dev/null @@ -1,1854 +0,0 @@ -From a258b3c0636b208de699b1e693d86f5ee9985cfd Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Tue, 14 Jun 2022 21:09:53 +1200 -Subject: [PATCH 01/99] CVE-2022-32746 s4/dsdb/objectclass_attrs: Fix typo - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15009 - -Signed-off-by: Joseph Sutton ---- - source4/dsdb/samdb/ldb_modules/objectclass_attrs.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/source4/dsdb/samdb/ldb_modules/objectclass_attrs.c b/source4/dsdb/samdb/ldb_modules/objectclass_attrs.c -index 6ab46a729a2..2a77353cdfc 100644 ---- a/source4/dsdb/samdb/ldb_modules/objectclass_attrs.c -+++ b/source4/dsdb/samdb/ldb_modules/objectclass_attrs.c -@@ -263,7 +263,7 @@ static int attr_handler(struct oc_context *ac) - LDB_CONTROL_AS_SYSTEM_OID); - if (!dsdb_module_am_system(ac->module) && !as_system) { - ldb_asprintf_errstring(ldb, -- "objectclass_attrs: attribute '%s' on entry '%s' must can only be modified as system", -+ "objectclass_attrs: attribute '%s' on entry '%s' can only be modified as system", - msg->elements[i].name, - ldb_dn_get_linearized(msg->dn)); - return LDB_ERR_CONSTRAINT_VIOLATION; --- -2.25.1 - - -From e2ef0f299aed8c0f9660f1d7912472d23e81fee8 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Tue, 21 Jun 2022 15:37:15 +1200 -Subject: [PATCH 02/99] CVE-2022-32746 s4:dsdb:tests: Add test for deleting a - disallowed SPN - -If an account has an SPN that requires Write Property to set, we should -still be able to delete it with just Validated Write. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15009 - -Signed-off-by: Joseph Sutton ---- - selftest/knownfail.d/acl-spn-delete | 1 + - source4/dsdb/tests/python/acl.py | 26 ++++++++++++++++++++++++++ - 2 files changed, 27 insertions(+) - create mode 100644 selftest/knownfail.d/acl-spn-delete - -diff --git a/selftest/knownfail.d/acl-spn-delete b/selftest/knownfail.d/acl-spn-delete -new file mode 100644 -index 00000000000..32018413c49 ---- /dev/null -+++ b/selftest/knownfail.d/acl-spn-delete -@@ -0,0 +1 @@ -+^samba4.ldap.acl.python.*__main__.AclSPNTests.test_delete_disallowed_spn\( -diff --git a/source4/dsdb/tests/python/acl.py b/source4/dsdb/tests/python/acl.py -index 70dca9b7678..3e5f7a44a79 100755 ---- a/source4/dsdb/tests/python/acl.py -+++ b/source4/dsdb/tests/python/acl.py -@@ -2285,6 +2285,32 @@ class AclSPNTests(AclTests): - else: - self.fail(f'able to add disallowed SPN {not_allowed_spn}') - -+ def test_delete_disallowed_spn(self): -+ # Grant Validated-SPN property. -+ mod = f'(OA;;SW;{security.GUID_DRS_VALIDATE_SPN};;{self.user_sid1})' -+ self.sd_utils.dacl_add_ace(self.computerdn, mod) -+ -+ spn_base = f'HOST/{self.computername}' -+ -+ not_allowed_spn = f'{spn_base}/{self.dcctx.get_domain_name()}' -+ -+ # Add a disallowed SPN as admin. -+ msg = Message(Dn(self.ldb_admin, self.computerdn)) -+ msg['servicePrincipalName'] = MessageElement(not_allowed_spn, -+ FLAG_MOD_ADD, -+ 'servicePrincipalName') -+ self.ldb_admin.modify(msg) -+ -+ # Ensure we are able to delete a disallowed SPN. -+ msg = Message(Dn(self.ldb_user1, self.computerdn)) -+ msg['servicePrincipalName'] = MessageElement(not_allowed_spn, -+ FLAG_MOD_DELETE, -+ 'servicePrincipalName') -+ try: -+ self.ldb_user1.modify(msg) -+ except LdbError: -+ self.fail(f'unable to delete disallowed SPN {not_allowed_spn}') -+ - - # tests SEC_ADS_LIST vs. SEC_ADS_LIST_OBJECT - @DynamicTestCase --- -2.25.1 - - -From 6bc5e73000a639bab3c3d6789bdf879d5395bf9c Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Tue, 21 Jun 2022 14:41:02 +1200 -Subject: [PATCH 03/99] CVE-2022-32746 s4/dsdb/partition: Fix LDB flags - comparison - -LDB_FLAG_MOD_* values are not actually flags, and the previous -comparison was equivalent to - -(req_msg->elements[el_idx].flags & LDB_FLAG_MOD_MASK) != 0 - -which is true whenever any of the LDB_FLAG_MOD_* values are set. Correct -the expression to what it was probably intended to be. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15009 - -Signed-off-by: Joseph Sutton ---- - source4/dsdb/samdb/ldb_modules/partition.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c -index 2544a106d13..2d90ca5d1b3 100644 ---- a/source4/dsdb/samdb/ldb_modules/partition.c -+++ b/source4/dsdb/samdb/ldb_modules/partition.c -@@ -493,8 +493,8 @@ static int partition_copy_all_callback_action( - * them here too - */ - for (el_idx=0; el_idx < req_msg->num_elements; el_idx++) { -- if (req_msg->elements[el_idx].flags & LDB_FLAG_MOD_DELETE -- || ((req_msg->elements[el_idx].flags & LDB_FLAG_MOD_REPLACE) && -+ if (LDB_FLAG_MOD_TYPE(req_msg->elements[el_idx].flags) == LDB_FLAG_MOD_DELETE -+ || ((LDB_FLAG_MOD_TYPE(req_msg->elements[el_idx].flags) == LDB_FLAG_MOD_REPLACE) && - req_msg->elements[el_idx].num_values == 0)) { - if (ldb_msg_find_element(modify_msg, - req_msg->elements[el_idx].name) != NULL) { --- -2.25.1 - - -From 39371352d8fc1d3ab0dd2baeacebd9ce48b4ef02 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Tue, 21 Jun 2022 14:49:51 +1200 -Subject: [PATCH 04/99] CVE-2022-32746 s4:torture: Fix LDB flags comparison - -LDB_FLAG_MOD_* values are not actually flags, and the previous -comparison was equivalent to - -(el->flags & LDB_FLAG_MOD_MASK) == 0 - -which is only true if none of the LDB_FLAG_MOD_* values are set. Correct -the expression to what it was probably intended to be. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15009 - -Signed-off-by: Joseph Sutton ---- - source4/torture/drs/rpc/dssync.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/source4/torture/drs/rpc/dssync.c b/source4/torture/drs/rpc/dssync.c -index f63e8a4ae7d..047bee116e9 100644 ---- a/source4/torture/drs/rpc/dssync.c -+++ b/source4/torture/drs/rpc/dssync.c -@@ -527,7 +527,9 @@ static bool test_analyse_objects(struct torture_context *tctx, - el = &new_msg->elements[idx]; - a = dsdb_attribute_by_lDAPDisplayName(ldap_schema, - el->name); -- if (!(el->flags & (LDB_FLAG_MOD_ADD|LDB_FLAG_MOD_REPLACE))) { -+ if (LDB_FLAG_MOD_TYPE(el->flags) != LDB_FLAG_MOD_ADD && -+ LDB_FLAG_MOD_TYPE(el->flags) != LDB_FLAG_MOD_REPLACE) -+ { - /* DRS only value */ - is_warning = false; - } else if (a->linkID & 1) { --- -2.25.1 - - -From 27efd19085d01e1e3702afb5dfd82eaf72c13bf9 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Tue, 21 Jun 2022 15:22:47 +1200 -Subject: [PATCH 05/99] CVE-2022-32746 s4/dsdb/acl: Fix LDB flags comparison - -LDB_FLAG_MOD_* values are not actually flags, and the previous -comparison was equivalent to - -(el->flags & LDB_FLAG_MOD_MASK) == 0 - -which is only true if none of the LDB_FLAG_MOD_* values are set, so we -would not successfully return if the element was a DELETE. Correct the -expression to what it was intended to be. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15009 - -Signed-off-by: Joseph Sutton ---- - selftest/knownfail.d/acl-spn-delete | 1 - - source4/dsdb/samdb/ldb_modules/acl.c | 5 +++-- - 2 files changed, 3 insertions(+), 3 deletions(-) - delete mode 100644 selftest/knownfail.d/acl-spn-delete - -diff --git a/selftest/knownfail.d/acl-spn-delete b/selftest/knownfail.d/acl-spn-delete -deleted file mode 100644 -index 32018413c49..00000000000 ---- a/selftest/knownfail.d/acl-spn-delete -+++ /dev/null -@@ -1 +0,0 @@ --^samba4.ldap.acl.python.*__main__.AclSPNTests.test_delete_disallowed_spn\( -diff --git a/source4/dsdb/samdb/ldb_modules/acl.c b/source4/dsdb/samdb/ldb_modules/acl.c -index 21e83276bfd..8016a2d4bd0 100644 ---- a/source4/dsdb/samdb/ldb_modules/acl.c -+++ b/source4/dsdb/samdb/ldb_modules/acl.c -@@ -734,8 +734,9 @@ static int acl_check_spn(TALLOC_CTX *mem_ctx, - * If not add or replace (eg delete), - * return success - */ -- if ((el->flags -- & (LDB_FLAG_MOD_ADD|LDB_FLAG_MOD_REPLACE)) == 0) { -+ if (LDB_FLAG_MOD_TYPE(el->flags) != LDB_FLAG_MOD_ADD && -+ LDB_FLAG_MOD_TYPE(el->flags) != LDB_FLAG_MOD_REPLACE) -+ { - talloc_free(tmp_ctx); - return LDB_SUCCESS; - } --- -2.25.1 - - -From 7c4439c7b7ff4caa7152f810ec9e83732fa70c3c Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Wed, 16 Feb 2022 12:43:52 +1300 -Subject: [PATCH 06/99] CVE-2022-32746 ldb:rdn_name: Use LDB_FLAG_MOD_TYPE() - for flags equality check - -Now unrelated flags will no longer affect the result. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15009 - -Signed-off-by: Joseph Sutton ---- - lib/ldb/modules/rdn_name.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/lib/ldb/modules/rdn_name.c b/lib/ldb/modules/rdn_name.c -index e69ad9315ae..25cffe07591 100644 ---- a/lib/ldb/modules/rdn_name.c -+++ b/lib/ldb/modules/rdn_name.c -@@ -545,7 +545,7 @@ static int rdn_name_modify(struct ldb_module *module, struct ldb_request *req) - if (e != NULL) { - ldb_asprintf_errstring(ldb, "Modify of 'distinguishedName' on %s not permitted, must use 'rename' operation instead", - ldb_dn_get_linearized(req->op.mod.message->dn)); -- if (e->flags == LDB_FLAG_MOD_REPLACE) { -+ if (LDB_FLAG_MOD_TYPE(e->flags) == LDB_FLAG_MOD_REPLACE) { - return LDB_ERR_CONSTRAINT_VIOLATION; - } else { - return LDB_ERR_UNWILLING_TO_PERFORM; --- -2.25.1 - - -From 47e2b1080e603b36b5d54a3e00f005983e6911e2 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Tue, 14 Jun 2022 19:49:19 +1200 -Subject: [PATCH 07/99] CVE-2022-32746 s4/dsdb/repl_meta_data: Use - LDB_FLAG_MOD_TYPE() for flags equality check - -Now unrelated flags will no longer affect the result. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15009 - -Signed-off-by: Joseph Sutton ---- - source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c -index ab506cec488..29ffda75c87 100644 ---- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c -+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c -@@ -3525,7 +3525,7 @@ static int replmd_modify(struct ldb_module *module, struct ldb_request *req) - return ldb_module_operr(module); - } - -- if (req->op.mod.message->elements[0].flags != LDB_FLAG_MOD_REPLACE) { -+ if (LDB_FLAG_MOD_TYPE(req->op.mod.message->elements[0].flags) != LDB_FLAG_MOD_REPLACE) { - return ldb_module_operr(module); - } - -@@ -3558,11 +3558,11 @@ static int replmd_modify(struct ldb_module *module, struct ldb_request *req) - return ldb_module_operr(module); - } - -- if (req->op.mod.message->elements[0].flags != LDB_FLAG_MOD_DELETE) { -+ if (LDB_FLAG_MOD_TYPE(req->op.mod.message->elements[0].flags) != LDB_FLAG_MOD_DELETE) { - return ldb_module_operr(module); - } - -- if (req->op.mod.message->elements[1].flags != LDB_FLAG_MOD_ADD) { -+ if (LDB_FLAG_MOD_TYPE(req->op.mod.message->elements[1].flags) != LDB_FLAG_MOD_ADD) { - return ldb_module_operr(module); - } - -@@ -3645,7 +3645,7 @@ static int replmd_modify(struct ldb_module *module, struct ldb_request *req) - return ldb_module_operr(module); - } - -- if (msg->elements[0].flags != LDB_FLAG_MOD_ADD) { -+ if (LDB_FLAG_MOD_TYPE(msg->elements[0].flags) != LDB_FLAG_MOD_ADD) { - talloc_free(ac); - return ldb_module_operr(module); - } --- -2.25.1 - - -From f2b821f24e9b144c2cb1a9ec85f3bf1fdd2c2a8e Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Tue, 14 Jun 2022 21:11:33 +1200 -Subject: [PATCH 08/99] CVE-2022-32746 s4/dsdb/tombstone_reanimate: Use - LDB_FLAG_MOD_TYPE() for flags equality check - -Now unrelated flags will no longer affect the result. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15009 - -Signed-off-by: Joseph Sutton ---- - source4/dsdb/samdb/ldb_modules/tombstone_reanimate.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/source4/dsdb/samdb/ldb_modules/tombstone_reanimate.c b/source4/dsdb/samdb/ldb_modules/tombstone_reanimate.c -index 64e05195798..5f8911c66be 100644 ---- a/source4/dsdb/samdb/ldb_modules/tombstone_reanimate.c -+++ b/source4/dsdb/samdb/ldb_modules/tombstone_reanimate.c -@@ -104,7 +104,7 @@ static bool is_tombstone_reanimate_request(struct ldb_request *req, - if (el_dn == NULL) { - return false; - } -- if (el_dn->flags != LDB_FLAG_MOD_REPLACE) { -+ if (LDB_FLAG_MOD_TYPE(el_dn->flags) != LDB_FLAG_MOD_REPLACE) { - return false; - } - if (el_dn->num_values != 1) { -@@ -117,7 +117,7 @@ static bool is_tombstone_reanimate_request(struct ldb_request *req, - return false; - } - -- if (el_deleted->flags != LDB_FLAG_MOD_DELETE) { -+ if (LDB_FLAG_MOD_TYPE(el_deleted->flags) != LDB_FLAG_MOD_DELETE) { - return false; - } - --- -2.25.1 - - -From ba27d18c2e8e1d0cf1828bb6d072489e5c6c9159 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Tue, 14 Jun 2022 21:12:39 +1200 -Subject: [PATCH 09/99] CVE-2022-32746 s4/registry: Use LDB_FLAG_MOD_TYPE() for - flags equality check - -Now unrelated flags will no longer affect the result. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15009 - -Signed-off-by: Joseph Sutton ---- - source4/lib/registry/ldb.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c -index e089355975b..db383a560da 100644 ---- a/source4/lib/registry/ldb.c -+++ b/source4/lib/registry/ldb.c -@@ -859,7 +859,7 @@ static WERROR ldb_set_value(struct hive_key *parent, - - /* Try first a "modify" and if this doesn't work do try an "add" */ - for (i = 0; i < msg->num_elements; i++) { -- if (msg->elements[i].flags != LDB_FLAG_MOD_DELETE) { -+ if (LDB_FLAG_MOD_TYPE(msg->elements[i].flags) != LDB_FLAG_MOD_DELETE) { - msg->elements[i].flags = LDB_FLAG_MOD_REPLACE; - } - } --- -2.25.1 - - -From 1294192b821d2d3af444b750baa75924042f1162 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Mon, 21 Feb 2022 16:10:32 +1300 -Subject: [PATCH 10/99] CVE-2022-32746 ldb: Add flag to mark message element - values as shared - -When making a shallow copy of an ldb message, mark the message elements -of the copy as sharing their values with the message elements in the -original message. - -This flag value will be heeded in the next commit. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15009 - -Signed-off-by: Joseph Sutton ---- - lib/ldb/common/ldb_msg.c | 43 +++++++++++++++++++++++++++++++----- - lib/ldb/include/ldb_module.h | 6 +++++ - 2 files changed, 43 insertions(+), 6 deletions(-) - -diff --git a/lib/ldb/common/ldb_msg.c b/lib/ldb/common/ldb_msg.c -index 57dfc5a04c2..2a9ce384bb9 100644 ---- a/lib/ldb/common/ldb_msg.c -+++ b/lib/ldb/common/ldb_msg.c -@@ -833,11 +833,7 @@ void ldb_msg_sort_elements(struct ldb_message *msg) - ldb_msg_element_compare_name); - } - --/* -- shallow copy a message - copying only the elements array so that the caller -- can safely add new elements without changing the message --*/ --struct ldb_message *ldb_msg_copy_shallow(TALLOC_CTX *mem_ctx, -+static struct ldb_message *ldb_msg_copy_shallow_impl(TALLOC_CTX *mem_ctx, - const struct ldb_message *msg) - { - struct ldb_message *msg2; -@@ -863,6 +859,35 @@ failed: - return NULL; - } - -+/* -+ shallow copy a message - copying only the elements array so that the caller -+ can safely add new elements without changing the message -+*/ -+struct ldb_message *ldb_msg_copy_shallow(TALLOC_CTX *mem_ctx, -+ const struct ldb_message *msg) -+{ -+ struct ldb_message *msg2; -+ unsigned int i; -+ -+ msg2 = ldb_msg_copy_shallow_impl(mem_ctx, msg); -+ if (msg2 == NULL) { -+ return NULL; -+ } -+ -+ for (i = 0; i < msg2->num_elements; ++i) { -+ /* -+ * Mark this message's elements as sharing their values with the -+ * original message, so that we don't inadvertently modify or -+ * free them. We don't mark the original message element as -+ * shared, so the original message element should not be -+ * modified or freed while the shallow copy lives. -+ */ -+ struct ldb_message_element *el = &msg2->elements[i]; -+ el->flags |= LDB_FLAG_INTERNAL_SHARED_VALUES; -+ } -+ -+ return msg2; -+} - - /* - copy a message, allocating new memory for all parts -@@ -873,7 +898,7 @@ struct ldb_message *ldb_msg_copy(TALLOC_CTX *mem_ctx, - struct ldb_message *msg2; - unsigned int i, j; - -- msg2 = ldb_msg_copy_shallow(mem_ctx, msg); -+ msg2 = ldb_msg_copy_shallow_impl(mem_ctx, msg); - if (msg2 == NULL) return NULL; - - if (msg2->dn != NULL) { -@@ -894,6 +919,12 @@ struct ldb_message *ldb_msg_copy(TALLOC_CTX *mem_ctx, - goto failed; - } - } -+ -+ /* -+ * Since we copied this element's values, we can mark them as -+ * not shared. -+ */ -+ el->flags &= ~LDB_FLAG_INTERNAL_SHARED_VALUES; - } - - return msg2; -diff --git a/lib/ldb/include/ldb_module.h b/lib/ldb/include/ldb_module.h -index 8c1e5ee7936..4c7c85a17f0 100644 ---- a/lib/ldb/include/ldb_module.h -+++ b/lib/ldb/include/ldb_module.h -@@ -96,6 +96,12 @@ struct ldb_module; - */ - #define LDB_FLAG_INTERNAL_FORCE_UNIQUE_INDEX 0x100 - -+/* -+ * indicates that this element's values are shared with another element (for -+ * example, in a shallow copy of an ldb_message) and should not be freed -+ */ -+#define LDB_FLAG_INTERNAL_SHARED_VALUES 0x200 -+ - /* an extended match rule that always fails to match */ - #define SAMBA_LDAP_MATCH_ALWAYS_FALSE "1.3.6.1.4.1.7165.4.5.1" - --- -2.25.1 - - -From 3a68efe1bbba4923f02b89a7f675398fbd73265e Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Wed, 16 Feb 2022 12:35:13 +1300 -Subject: [PATCH 11/99] CVE-2022-32746 ldb: Ensure shallow copy modifications - do not affect original message - -Using the newly added ldb flag, we can now detect when a message has -been shallow-copied so that its elements share their values with the -original message elements. Then when adding values to the copied -message, we now make a copy of the shared values array first. - -This should prevent a use-after-free that occurred in LDB modules when -new values were added to a shallow copy of a message by calling -talloc_realloc() on the original values array, invalidating the 'values' -pointer in the original message element. The original values pointer can -later be used in the database audit logging module which logs database -requests, and potentially cause a crash. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15009 - -Signed-off-by: Joseph Sutton ---- - lib/ldb/common/ldb_msg.c | 52 ++++++++++++++++++++++++++++++++------ - lib/ldb/include/ldb.h | 6 +++++ - source4/dsdb/common/util.c | 20 +++++---------- - 3 files changed, 56 insertions(+), 22 deletions(-) - -diff --git a/lib/ldb/common/ldb_msg.c b/lib/ldb/common/ldb_msg.c -index 2a9ce384bb9..44d3b29e9a7 100644 ---- a/lib/ldb/common/ldb_msg.c -+++ b/lib/ldb/common/ldb_msg.c -@@ -417,6 +417,47 @@ int ldb_msg_add(struct ldb_message *msg, - return LDB_SUCCESS; - } - -+/* -+ * add a value to a message element -+ */ -+int ldb_msg_element_add_value(TALLOC_CTX *mem_ctx, -+ struct ldb_message_element *el, -+ const struct ldb_val *val) -+{ -+ struct ldb_val *vals; -+ -+ if (el->flags & LDB_FLAG_INTERNAL_SHARED_VALUES) { -+ /* -+ * Another message is using this message element's values array, -+ * so we don't want to make any modifications to the original -+ * message, or potentially invalidate its own values by calling -+ * talloc_realloc(). Make a copy instead. -+ */ -+ el->flags &= ~LDB_FLAG_INTERNAL_SHARED_VALUES; -+ -+ vals = talloc_array(mem_ctx, struct ldb_val, -+ el->num_values + 1); -+ if (vals == NULL) { -+ return LDB_ERR_OPERATIONS_ERROR; -+ } -+ -+ if (el->values != NULL) { -+ memcpy(vals, el->values, el->num_values * sizeof(struct ldb_val)); -+ } -+ } else { -+ vals = talloc_realloc(mem_ctx, el->values, struct ldb_val, -+ el->num_values + 1); -+ if (vals == NULL) { -+ return LDB_ERR_OPERATIONS_ERROR; -+ } -+ } -+ el->values = vals; -+ el->values[el->num_values] = *val; -+ el->num_values++; -+ -+ return LDB_SUCCESS; -+} -+ - /* - add a value to a message - */ -@@ -426,7 +467,6 @@ int ldb_msg_add_value(struct ldb_message *msg, - struct ldb_message_element **return_el) - { - struct ldb_message_element *el; -- struct ldb_val *vals; - int ret; - - el = ldb_msg_find_element(msg, attr_name); -@@ -437,14 +477,10 @@ int ldb_msg_add_value(struct ldb_message *msg, - } - } - -- vals = talloc_realloc(msg->elements, el->values, struct ldb_val, -- el->num_values+1); -- if (!vals) { -- return LDB_ERR_OPERATIONS_ERROR; -+ ret = ldb_msg_element_add_value(msg->elements, el, val); -+ if (ret != LDB_SUCCESS) { -+ return ret; - } -- el->values = vals; -- el->values[el->num_values] = *val; -- el->num_values++; - - if (return_el) { - *return_el = el; -diff --git a/lib/ldb/include/ldb.h b/lib/ldb/include/ldb.h -index bc44157eaf4..129beefeaf5 100644 ---- a/lib/ldb/include/ldb.h -+++ b/lib/ldb/include/ldb.h -@@ -1981,6 +1981,12 @@ int ldb_msg_add_empty(struct ldb_message *msg, - int flags, - struct ldb_message_element **return_el); - -+/** -+ add a value to a message element -+*/ -+int ldb_msg_element_add_value(TALLOC_CTX *mem_ctx, -+ struct ldb_message_element *el, -+ const struct ldb_val *val); - /** - add a element to a ldb_message - */ -diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c -index 9b4afa45215..721e1e9d41d 100644 ---- a/source4/dsdb/common/util.c -+++ b/source4/dsdb/common/util.c -@@ -815,7 +815,7 @@ int samdb_msg_add_addval(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, - const char *value) - { - struct ldb_message_element *el; -- struct ldb_val val, *vals; -+ struct ldb_val val; - char *v; - unsigned int i; - bool found = false; -@@ -850,14 +850,10 @@ int samdb_msg_add_addval(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, - } - } - -- vals = talloc_realloc(msg->elements, el->values, struct ldb_val, -- el->num_values + 1); -- if (vals == NULL) { -+ ret = ldb_msg_element_add_value(msg->elements, el, &val); -+ if (ret != LDB_SUCCESS) { - return ldb_oom(sam_ldb); - } -- el->values = vals; -- el->values[el->num_values] = val; -- ++(el->num_values); - - return LDB_SUCCESS; - } -@@ -871,7 +867,7 @@ int samdb_msg_add_delval(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, - const char *value) - { - struct ldb_message_element *el; -- struct ldb_val val, *vals; -+ struct ldb_val val; - char *v; - unsigned int i; - bool found = false; -@@ -906,14 +902,10 @@ int samdb_msg_add_delval(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, - } - } - -- vals = talloc_realloc(msg->elements, el->values, struct ldb_val, -- el->num_values + 1); -- if (vals == NULL) { -+ ret = ldb_msg_element_add_value(msg->elements, el, &val); -+ if (ret != LDB_SUCCESS) { - return ldb_oom(sam_ldb); - } -- el->values = vals; -- el->values[el->num_values] = val; -- ++(el->num_values); - - return LDB_SUCCESS; - } --- -2.25.1 - - -From a25b97d0540fdb5a4a75fd85807d8963f14b607d Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Wed, 16 Feb 2022 16:30:03 +1300 -Subject: [PATCH 12/99] CVE-2022-32746 ldb: Add functions for appending to an - ldb_message - -Currently, there are many places where we use ldb_msg_add_empty() to add -an empty element to a message, and then call ldb_msg_add_value() or -similar to add values to that element. However, this performs an -unnecessary search of the message's elements to locate the new element. -Moreover, if an element with the same attribute name already exists -earlier in the message, the values will be added to that element, -instead of to the intended newly added element. - -A similar pattern exists where we add values to a message, and then call -ldb_msg_find_element() to locate that message element and sets its flags -to (e.g.) LDB_FLAG_MOD_REPLACE. This also performs an unnecessary -search, and may locate the wrong message element for setting the flags. - -To avoid these problems, add functions for appending a value to a -message, so that a particular value can be added to the end of a message -in a single operation. - -For ADD requests, it is important that no two message elements share the -same attribute name, otherwise things will break. (Normally, -ldb_msg_normalize() is called before processing the request to help -ensure this.) Thus, we must be careful not to append an attribute to an -ADD message, unless we are sure (e.g. through ldb_msg_find_element()) -that an existing element for that attribute is not present. - -These functions will be used in the next commit. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15009 - -Signed-off-by: Joseph Sutton ---- - lib/ldb/common/ldb_msg.c | 165 ++++++++++++++++++++++++++++++++++++++- - lib/ldb/include/ldb.h | 24 ++++++ - 2 files changed, 185 insertions(+), 4 deletions(-) - -diff --git a/lib/ldb/common/ldb_msg.c b/lib/ldb/common/ldb_msg.c -index 44d3b29e9a7..9cd7998e21c 100644 ---- a/lib/ldb/common/ldb_msg.c -+++ b/lib/ldb/common/ldb_msg.c -@@ -509,12 +509,15 @@ int ldb_msg_add_steal_value(struct ldb_message *msg, - - - /* -- add a string element to a message -+ add a string element to a message, specifying flags - */ --int ldb_msg_add_string(struct ldb_message *msg, -- const char *attr_name, const char *str) -+int ldb_msg_add_string_flags(struct ldb_message *msg, -+ const char *attr_name, const char *str, -+ int flags) - { - struct ldb_val val; -+ int ret; -+ struct ldb_message_element *el = NULL; - - val.data = discard_const_p(uint8_t, str); - val.length = strlen(str); -@@ -524,7 +527,25 @@ int ldb_msg_add_string(struct ldb_message *msg, - return LDB_SUCCESS; - } - -- return ldb_msg_add_value(msg, attr_name, &val, NULL); -+ ret = ldb_msg_add_value(msg, attr_name, &val, &el); -+ if (ret != LDB_SUCCESS) { -+ return ret; -+ } -+ -+ if (flags != 0) { -+ el->flags = flags; -+ } -+ -+ return LDB_SUCCESS; -+} -+ -+/* -+ add a string element to a message -+*/ -+int ldb_msg_add_string(struct ldb_message *msg, -+ const char *attr_name, const char *str) -+{ -+ return ldb_msg_add_string_flags(msg, attr_name, str, 0); - } - - /* -@@ -586,6 +607,142 @@ int ldb_msg_add_fmt(struct ldb_message *msg, - return ldb_msg_add_steal_value(msg, attr_name, &val); - } - -+static int ldb_msg_append_value_impl(struct ldb_message *msg, -+ const char *attr_name, -+ const struct ldb_val *val, -+ int flags, -+ struct ldb_message_element **return_el) -+{ -+ struct ldb_message_element *el = NULL; -+ int ret; -+ -+ ret = ldb_msg_add_empty(msg, attr_name, flags, &el); -+ if (ret != LDB_SUCCESS) { -+ return ret; -+ } -+ -+ ret = ldb_msg_element_add_value(msg->elements, el, val); -+ if (ret != LDB_SUCCESS) { -+ return ret; -+ } -+ -+ if (return_el != NULL) { -+ *return_el = el; -+ } -+ -+ return LDB_SUCCESS; -+} -+ -+/* -+ append a value to a message -+*/ -+int ldb_msg_append_value(struct ldb_message *msg, -+ const char *attr_name, -+ const struct ldb_val *val, -+ int flags) -+{ -+ return ldb_msg_append_value_impl(msg, attr_name, val, flags, NULL); -+} -+ -+/* -+ append a value to a message, stealing it into the 'right' place -+*/ -+int ldb_msg_append_steal_value(struct ldb_message *msg, -+ const char *attr_name, -+ struct ldb_val *val, -+ int flags) -+{ -+ int ret; -+ struct ldb_message_element *el = NULL; -+ -+ ret = ldb_msg_append_value_impl(msg, attr_name, val, flags, &el); -+ if (ret == LDB_SUCCESS) { -+ talloc_steal(el->values, val->data); -+ } -+ return ret; -+} -+ -+/* -+ append a string element to a message, stealing it into the 'right' place -+*/ -+int ldb_msg_append_steal_string(struct ldb_message *msg, -+ const char *attr_name, char *str, -+ int flags) -+{ -+ struct ldb_val val; -+ -+ val.data = (uint8_t *)str; -+ val.length = strlen(str); -+ -+ if (val.length == 0) { -+ /* allow empty strings as non-existent attributes */ -+ return LDB_SUCCESS; -+ } -+ -+ return ldb_msg_append_steal_value(msg, attr_name, &val, flags); -+} -+ -+/* -+ append a string element to a message -+*/ -+int ldb_msg_append_string(struct ldb_message *msg, -+ const char *attr_name, const char *str, int flags) -+{ -+ struct ldb_val val; -+ -+ val.data = discard_const_p(uint8_t, str); -+ val.length = strlen(str); -+ -+ if (val.length == 0) { -+ /* allow empty strings as non-existent attributes */ -+ return LDB_SUCCESS; -+ } -+ -+ return ldb_msg_append_value(msg, attr_name, &val, flags); -+} -+ -+/* -+ append a DN element to a message -+ WARNING: this uses the linearized string from the dn, and does not -+ copy the string. -+*/ -+int ldb_msg_append_linearized_dn(struct ldb_message *msg, const char *attr_name, -+ struct ldb_dn *dn, int flags) -+{ -+ char *str = ldb_dn_alloc_linearized(msg, dn); -+ -+ if (str == NULL) { -+ /* we don't want to have unknown DNs added */ -+ return LDB_ERR_OPERATIONS_ERROR; -+ } -+ -+ return ldb_msg_append_steal_string(msg, attr_name, str, flags); -+} -+ -+/* -+ append a printf formatted element to a message -+*/ -+int ldb_msg_append_fmt(struct ldb_message *msg, int flags, -+ const char *attr_name, const char *fmt, ...) -+{ -+ struct ldb_val val; -+ va_list ap; -+ char *str = NULL; -+ -+ va_start(ap, fmt); -+ str = talloc_vasprintf(msg, fmt, ap); -+ va_end(ap); -+ -+ if (str == NULL) { -+ return LDB_ERR_OPERATIONS_ERROR; -+ } -+ -+ val.data = (uint8_t *)str; -+ val.length = strlen(str); -+ -+ return ldb_msg_append_steal_value(msg, attr_name, &val, flags); -+} -+ - /* - compare two ldb_message_element structures - assumes case sensitive comparison -diff --git a/lib/ldb/include/ldb.h b/lib/ldb/include/ldb.h -index 129beefeaf5..63d8aedd672 100644 ---- a/lib/ldb/include/ldb.h -+++ b/lib/ldb/include/ldb.h -@@ -2002,12 +2002,36 @@ int ldb_msg_add_steal_value(struct ldb_message *msg, - struct ldb_val *val); - int ldb_msg_add_steal_string(struct ldb_message *msg, - const char *attr_name, char *str); -+int ldb_msg_add_string_flags(struct ldb_message *msg, -+ const char *attr_name, const char *str, -+ int flags); - int ldb_msg_add_string(struct ldb_message *msg, - const char *attr_name, const char *str); - int ldb_msg_add_linearized_dn(struct ldb_message *msg, const char *attr_name, - struct ldb_dn *dn); - int ldb_msg_add_fmt(struct ldb_message *msg, - const char *attr_name, const char *fmt, ...) PRINTF_ATTRIBUTE(3,4); -+/** -+ append a element to a ldb_message -+*/ -+int ldb_msg_append_value(struct ldb_message *msg, -+ const char *attr_name, -+ const struct ldb_val *val, -+ int flags); -+int ldb_msg_append_steal_value(struct ldb_message *msg, -+ const char *attr_name, -+ struct ldb_val *val, -+ int flags); -+int ldb_msg_append_steal_string(struct ldb_message *msg, -+ const char *attr_name, char *str, -+ int flags); -+int ldb_msg_append_string(struct ldb_message *msg, -+ const char *attr_name, const char *str, -+ int flags); -+int ldb_msg_append_linearized_dn(struct ldb_message *msg, const char *attr_name, -+ struct ldb_dn *dn, int flags); -+int ldb_msg_append_fmt(struct ldb_message *msg, int flags, -+ const char *attr_name, const char *fmt, ...) PRINTF_ATTRIBUTE(4,5); - - /** - compare two message elements - return 0 on match --- -2.25.1 - - -From 0446581bcce7c2d7f5ec22d8510a6e2069463d39 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Mon, 21 Feb 2022 16:27:37 +1300 -Subject: [PATCH 13/99] CVE-2022-32746 ldb: Make use of functions for appending - to an ldb_message - -This aims to minimise usage of the error-prone pattern of searching for -a just-added message element in order to make modifications to it (and -potentially finding the wrong element). - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15009 - -Signed-off-by: Joseph Sutton ---- - lib/ldb/ldb_map/ldb_map.c | 5 +- - lib/ldb/ldb_map/ldb_map_inbound.c | 9 +- - lib/ldb/modules/rdn_name.c | 22 +--- - source3/passdb/pdb_samba_dsdb.c | 14 +-- - source4/dns_server/dnsserver_common.c | 12 +- - source4/dsdb/common/util.c | 114 ++++++++++++++---- - source4/dsdb/samdb/ldb_modules/descriptor.c | 10 +- - source4/dsdb/samdb/ldb_modules/objectguid.c | 20 +-- - .../dsdb/samdb/ldb_modules/partition_init.c | 14 +-- - .../dsdb/samdb/ldb_modules/repl_meta_data.c | 24 +--- - source4/dsdb/samdb/ldb_modules/samldb.c | 78 +++++------- - .../samdb/ldb_modules/tombstone_reanimate.c | 12 +- - source4/nbt_server/wins/winsdb.c | 13 +- - source4/rpc_server/lsa/dcesrv_lsa.c | 55 +++------ - source4/winbind/idmap.c | 10 +- - 15 files changed, 183 insertions(+), 229 deletions(-) - -diff --git a/lib/ldb/ldb_map/ldb_map.c b/lib/ldb/ldb_map/ldb_map.c -index b453dff80d2..c7b0c228631 100644 ---- a/lib/ldb/ldb_map/ldb_map.c -+++ b/lib/ldb/ldb_map/ldb_map.c -@@ -946,10 +946,7 @@ struct ldb_request *map_build_fixup_req(struct map_context *ac, - if ( ! dn || ! ldb_dn_validate(msg->dn)) { - goto failed; - } -- if (ldb_msg_add_empty(msg, IS_MAPPED, LDB_FLAG_MOD_REPLACE, NULL) != 0) { -- goto failed; -- } -- if (ldb_msg_add_string(msg, IS_MAPPED, dn) != 0) { -+ if (ldb_msg_append_string(msg, IS_MAPPED, dn, LDB_FLAG_MOD_REPLACE) != 0) { - goto failed; - } - -diff --git a/lib/ldb/ldb_map/ldb_map_inbound.c b/lib/ldb/ldb_map/ldb_map_inbound.c -index 324295737da..50b9427c26c 100644 ---- a/lib/ldb/ldb_map/ldb_map_inbound.c -+++ b/lib/ldb/ldb_map/ldb_map_inbound.c -@@ -569,12 +569,9 @@ static int map_modify_do_local(struct map_context *ac) - /* No local record present, add it instead */ - /* Add local 'IS_MAPPED' */ - /* TODO: use GUIDs here instead */ -- if (ldb_msg_add_empty(ac->local_msg, IS_MAPPED, -- LDB_FLAG_MOD_ADD, NULL) != 0) { -- return LDB_ERR_OPERATIONS_ERROR; -- } -- ret = ldb_msg_add_linearized_dn(ac->local_msg, IS_MAPPED, -- ac->remote_req->op.mod.message->dn); -+ ret = ldb_msg_append_linearized_dn(ac->local_msg, IS_MAPPED, -+ ac->remote_req->op.mod.message->dn, -+ LDB_FLAG_MOD_ADD); - if (ret != 0) { - return LDB_ERR_OPERATIONS_ERROR; - } -diff --git a/lib/ldb/modules/rdn_name.c b/lib/ldb/modules/rdn_name.c -index 25cffe07591..3cb62bf567b 100644 ---- a/lib/ldb/modules/rdn_name.c -+++ b/lib/ldb/modules/rdn_name.c -@@ -308,16 +308,10 @@ static int rdn_rename_callback(struct ldb_request *req, struct ldb_reply *ares) - } - rdn_val = ldb_val_dup(msg, rdn_val_p); - -- if (ldb_msg_add_empty(msg, rdn_name, LDB_FLAG_MOD_REPLACE, NULL) != 0) { -+ if (ldb_msg_append_value(msg, rdn_name, &rdn_val, LDB_FLAG_MOD_REPLACE) != 0) { - goto error; - } -- if (ldb_msg_add_value(msg, rdn_name, &rdn_val, NULL) != 0) { -- goto error; -- } -- if (ldb_msg_add_empty(msg, "name", LDB_FLAG_MOD_REPLACE, NULL) != 0) { -- goto error; -- } -- if (ldb_msg_add_value(msg, "name", &rdn_val, NULL) != 0) { -+ if (ldb_msg_append_value(msg, "name", &rdn_val, LDB_FLAG_MOD_REPLACE) != 0) { - goto error; - } - -@@ -466,11 +460,7 @@ static int rdn_name_modify(struct ldb_module *module, struct ldb_request *req) - if (ret != 0) { - return ldb_module_oom(module); - } -- ret = ldb_msg_add_empty(msg, rdn_name, LDB_FLAG_MOD_ADD, NULL); -- if (ret != 0) { -- return ldb_module_oom(module); -- } -- ret = ldb_msg_add_value(msg, rdn_name, &rdn_val, NULL); -+ ret = ldb_msg_append_value(msg, rdn_name, &rdn_val, LDB_FLAG_MOD_ADD); - if (ret != 0) { - return ldb_module_oom(module); - } -@@ -479,11 +469,7 @@ static int rdn_name_modify(struct ldb_module *module, struct ldb_request *req) - if (ret != 0) { - return ldb_module_oom(module); - } -- ret = ldb_msg_add_empty(msg, "name", LDB_FLAG_MOD_ADD, NULL); -- if (ret != 0) { -- return ldb_module_oom(module); -- } -- ret = ldb_msg_add_value(msg, "name", &rdn_val, NULL); -+ ret = ldb_msg_append_value(msg, "name", &rdn_val, LDB_FLAG_MOD_ADD); - if (ret != 0) { - return ldb_module_oom(module); - } -diff --git a/source3/passdb/pdb_samba_dsdb.c b/source3/passdb/pdb_samba_dsdb.c -index 4f1d2f697f0..d9c31e57186 100644 ---- a/source3/passdb/pdb_samba_dsdb.c -+++ b/source3/passdb/pdb_samba_dsdb.c -@@ -2776,18 +2776,10 @@ static bool pdb_samba_dsdb_set_trusteddom_pw(struct pdb_methods *m, - } - - msg->num_elements = 0; -- ret = ldb_msg_add_empty(msg, "trustAuthOutgoing", -- LDB_FLAG_MOD_REPLACE, NULL); -+ ret = ldb_msg_append_value(msg, "trustAuthOutgoing", -+ &new_val, LDB_FLAG_MOD_REPLACE); - if (ret != LDB_SUCCESS) { -- DEBUG(0, ("ldb_msg_add_empty() failed\n")); -- TALLOC_FREE(tmp_ctx); -- ldb_transaction_cancel(state->ldb); -- return false; -- } -- ret = ldb_msg_add_value(msg, "trustAuthOutgoing", -- &new_val, NULL); -- if (ret != LDB_SUCCESS) { -- DEBUG(0, ("ldb_msg_add_value() failed\n")); -+ DEBUG(0, ("ldb_msg_append_value() failed\n")); - TALLOC_FREE(tmp_ctx); - ldb_transaction_cancel(state->ldb); - return false; -diff --git a/source4/dns_server/dnsserver_common.c b/source4/dns_server/dnsserver_common.c -index d1f896d6755..2b4d719b342 100644 ---- a/source4/dns_server/dnsserver_common.c -+++ b/source4/dns_server/dnsserver_common.c -@@ -1122,15 +1122,9 @@ WERROR dns_common_replace(struct ldb_context *samdb, - } - - if (was_tombstoned || become_tombstoned) { -- ret = ldb_msg_add_empty(msg, "dNSTombstoned", -- LDB_FLAG_MOD_REPLACE, NULL); -- if (ret != LDB_SUCCESS) { -- werr = DNS_ERR(SERVER_FAILURE); -- goto exit; -- } -- -- ret = ldb_msg_add_fmt(msg, "dNSTombstoned", "%s", -- become_tombstoned ? "TRUE" : "FALSE"); -+ ret = ldb_msg_append_fmt(msg, LDB_FLAG_MOD_REPLACE, -+ "dNSTombstoned", "%s", -+ become_tombstoned ? "TRUE" : "FALSE"); - if (ret != LDB_SUCCESS) { - werr = DNS_ERR(SERVER_FAILURE); - goto exit; -diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c -index 721e1e9d41d..beb2883cad2 100644 ---- a/source4/dsdb/common/util.c -+++ b/source4/dsdb/common/util.c -@@ -923,6 +923,16 @@ int samdb_msg_add_int(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct l - return ldb_msg_add_string(msg, attr_name, s); - } - -+int samdb_msg_add_int_flags(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg, -+ const char *attr_name, int v, int flags) -+{ -+ const char *s = talloc_asprintf(mem_ctx, "%d", v); -+ if (s == NULL) { -+ return ldb_oom(sam_ldb); -+ } -+ return ldb_msg_add_string_flags(msg, attr_name, s, flags); -+} -+ - /* - * Add an unsigned int element to a message - * -@@ -941,6 +951,12 @@ int samdb_msg_add_uint(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct - return samdb_msg_add_int(sam_ldb, mem_ctx, msg, attr_name, (int)v); - } - -+int samdb_msg_add_uint_flags(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg, -+ const char *attr_name, unsigned int v, int flags) -+{ -+ return samdb_msg_add_int_flags(sam_ldb, mem_ctx, msg, attr_name, (int)v, flags); -+} -+ - /* - add a (signed) int64_t element to a message - */ -@@ -972,6 +988,68 @@ int samdb_msg_add_uint64(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struc - return samdb_msg_add_int64(sam_ldb, mem_ctx, msg, attr_name, (int64_t)v); - } - -+/* -+ append a int element to a message -+*/ -+int samdb_msg_append_int(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg, -+ const char *attr_name, int v, int flags) -+{ -+ const char *s = talloc_asprintf(mem_ctx, "%d", v); -+ if (s == NULL) { -+ return ldb_oom(sam_ldb); -+ } -+ return ldb_msg_append_string(msg, attr_name, s, flags); -+} -+ -+/* -+ * Append an unsigned int element to a message -+ * -+ * The issue here is that we have not yet first cast to int32_t explicitly, -+ * before we cast to an signed int to printf() into the %d or cast to a -+ * int64_t before we then cast to a long long to printf into a %lld. -+ * -+ * There are *no* unsigned integers in Active Directory LDAP, even the RID -+ * allocations and ms-DS-Secondary-KrbTgt-Number are *signed* quantities. -+ * (See the schema, and the syntax definitions in schema_syntax.c). -+ * -+ */ -+int samdb_msg_append_uint(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg, -+ const char *attr_name, unsigned int v, int flags) -+{ -+ return samdb_msg_append_int(sam_ldb, mem_ctx, msg, attr_name, (int)v, flags); -+} -+ -+/* -+ append a (signed) int64_t element to a message -+*/ -+int samdb_msg_append_int64(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg, -+ const char *attr_name, int64_t v, int flags) -+{ -+ const char *s = talloc_asprintf(mem_ctx, "%lld", (long long)v); -+ if (s == NULL) { -+ return ldb_oom(sam_ldb); -+ } -+ return ldb_msg_append_string(msg, attr_name, s, flags); -+} -+ -+/* -+ * Append an unsigned int64_t (uint64_t) element to a message -+ * -+ * The issue here is that we have not yet first cast to int32_t explicitly, -+ * before we cast to an signed int to printf() into the %d or cast to a -+ * int64_t before we then cast to a long long to printf into a %lld. -+ * -+ * There are *no* unsigned integers in Active Directory LDAP, even the RID -+ * allocations and ms-DS-Secondary-KrbTgt-Number are *signed* quantities. -+ * (See the schema, and the syntax definitions in schema_syntax.c). -+ * -+ */ -+int samdb_msg_append_uint64(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg, -+ const char *attr_name, uint64_t v, int flags) -+{ -+ return samdb_msg_append_int64(sam_ldb, mem_ctx, msg, attr_name, (int64_t)v, flags); -+} -+ - /* - add a samr_Password element to a message - */ -@@ -2813,15 +2891,8 @@ NTSTATUS samdb_set_password_sid(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, - tdo_msg->num_elements = 0; - TALLOC_FREE(tdo_msg->elements); - -- ret = ldb_msg_add_empty(tdo_msg, "trustAuthIncoming", -- LDB_FLAG_MOD_REPLACE, NULL); -- if (ret != LDB_SUCCESS) { -- ldb_transaction_cancel(ldb); -- TALLOC_FREE(frame); -- return NT_STATUS_NO_MEMORY; -- } -- ret = ldb_msg_add_value(tdo_msg, "trustAuthIncoming", -- &new_val, NULL); -+ ret = ldb_msg_append_value(tdo_msg, "trustAuthIncoming", -+ &new_val, LDB_FLAG_MOD_REPLACE); - if (ret != LDB_SUCCESS) { - ldb_transaction_cancel(ldb); - TALLOC_FREE(frame); -@@ -3186,6 +3257,7 @@ int dsdb_find_guid_by_dn(struct ldb_context *ldb, - /* - adds the given GUID to the given ldb_message. This value is added - for the given attr_name (may be either "objectGUID" or "parentGUID"). -+ This function is used in processing 'add' requests. - */ - int dsdb_msg_add_guid(struct ldb_message *msg, - struct GUID *guid, -@@ -5655,7 +5727,8 @@ int dsdb_user_obj_set_defaults(struct ldb_context *ldb, - } - - /** -- * Sets 'sAMAccountType on user object based on userAccountControl -+ * Sets 'sAMAccountType on user object based on userAccountControl. -+ * This function is used in processing both 'add' and 'modify' requests. - * @param ldb Current ldb_context - * @param usr_obj ldb_message representing User object - * @param user_account_control Value for userAccountControl flags -@@ -5667,21 +5740,19 @@ int dsdb_user_obj_set_account_type(struct ldb_context *ldb, struct ldb_message * - { - int ret; - uint32_t account_type; -- struct ldb_message_element *el; - - account_type = ds_uf2atype(user_account_control); - if (account_type == 0) { - ldb_set_errstring(ldb, "dsdb: Unrecognized account type!"); - return LDB_ERR_UNWILLING_TO_PERFORM; - } -- ret = samdb_msg_add_uint(ldb, usr_obj, usr_obj, -- "sAMAccountType", -- account_type); -+ ret = samdb_msg_add_uint_flags(ldb, usr_obj, usr_obj, -+ "sAMAccountType", -+ account_type, -+ LDB_FLAG_MOD_REPLACE); - if (ret != LDB_SUCCESS) { - return ret; - } -- el = ldb_msg_find_element(usr_obj, "sAMAccountType"); -- el->flags = LDB_FLAG_MOD_REPLACE; - - if (account_type_p) { - *account_type_p = account_type; -@@ -5691,7 +5762,8 @@ int dsdb_user_obj_set_account_type(struct ldb_context *ldb, struct ldb_message * - } - - /** -- * Determine and set primaryGroupID based on userAccountControl value -+ * Determine and set primaryGroupID based on userAccountControl value. -+ * This function is used in processing both 'add' and 'modify' requests. - * @param ldb Current ldb_context - * @param usr_obj ldb_message representing User object - * @param user_account_control Value for userAccountControl flags -@@ -5703,17 +5775,15 @@ int dsdb_user_obj_set_primary_group_id(struct ldb_context *ldb, struct ldb_messa - { - int ret; - uint32_t rid; -- struct ldb_message_element *el; - - rid = ds_uf2prim_group_rid(user_account_control); - -- ret = samdb_msg_add_uint(ldb, usr_obj, usr_obj, -- "primaryGroupID", rid); -+ ret = samdb_msg_add_uint_flags(ldb, usr_obj, usr_obj, -+ "primaryGroupID", rid, -+ LDB_FLAG_MOD_REPLACE); - if (ret != LDB_SUCCESS) { - return ret; - } -- el = ldb_msg_find_element(usr_obj, "primaryGroupID"); -- el->flags = LDB_FLAG_MOD_REPLACE; - - if (group_rid_p) { - *group_rid_p = rid; -diff --git a/source4/dsdb/samdb/ldb_modules/descriptor.c b/source4/dsdb/samdb/ldb_modules/descriptor.c -index 8a4c2c3591f..10ed577328d 100644 ---- a/source4/dsdb/samdb/ldb_modules/descriptor.c -+++ b/source4/dsdb/samdb/ldb_modules/descriptor.c -@@ -861,14 +861,8 @@ static int descriptor_modify(struct ldb_module *module, struct ldb_request *req) - return ldb_module_done(req, NULL, NULL, LDB_SUCCESS); - } - -- ret = ldb_msg_add_empty(msg, "nTSecurityDescriptor", -- LDB_FLAG_MOD_REPLACE, -- &sd_element); -- if (ret != LDB_SUCCESS) { -- return ldb_oom(ldb); -- } -- ret = ldb_msg_add_value(msg, "nTSecurityDescriptor", -- sd, NULL); -+ ret = ldb_msg_append_value(msg, "nTSecurityDescriptor", -+ sd, LDB_FLAG_MOD_REPLACE); - if (ret != LDB_SUCCESS) { - return ldb_oom(ldb); - } -diff --git a/source4/dsdb/samdb/ldb_modules/objectguid.c b/source4/dsdb/samdb/ldb_modules/objectguid.c -index bc3260cf0d8..0fe995a5763 100644 ---- a/source4/dsdb/samdb/ldb_modules/objectguid.c -+++ b/source4/dsdb/samdb/ldb_modules/objectguid.c -@@ -41,7 +41,6 @@ - */ - static int add_time_element(struct ldb_message *msg, const char *attr, time_t t) - { -- struct ldb_message_element *el; - char *s; - int ret; - -@@ -54,16 +53,13 @@ static int add_time_element(struct ldb_message *msg, const char *attr, time_t t) - return LDB_ERR_OPERATIONS_ERROR; - } - -- ret = ldb_msg_add_string(msg, attr, s); -+ /* always set as replace. This works because on add ops, the flag -+ is ignored */ -+ ret = ldb_msg_append_string(msg, attr, s, LDB_FLAG_MOD_REPLACE); - if (ret != LDB_SUCCESS) { - return ret; - } - -- el = ldb_msg_find_element(msg, attr); -- /* always set as replace. This works because on add ops, the flag -- is ignored */ -- el->flags = LDB_FLAG_MOD_REPLACE; -- - return LDB_SUCCESS; - } - -@@ -73,23 +69,19 @@ static int add_time_element(struct ldb_message *msg, const char *attr, time_t t) - static int add_uint64_element(struct ldb_context *ldb, struct ldb_message *msg, - const char *attr, uint64_t v) - { -- struct ldb_message_element *el; - int ret; - - if (ldb_msg_find_element(msg, attr) != NULL) { - return LDB_SUCCESS; - } - -- ret = samdb_msg_add_uint64(ldb, msg, msg, attr, v); -+ /* always set as replace. This works because on add ops, the flag -+ is ignored */ -+ ret = samdb_msg_append_uint64(ldb, msg, msg, attr, v, LDB_FLAG_MOD_REPLACE); - if (ret != LDB_SUCCESS) { - return ret; - } - -- el = ldb_msg_find_element(msg, attr); -- /* always set as replace. This works because on add ops, the flag -- is ignored */ -- el->flags = LDB_FLAG_MOD_REPLACE; -- - return LDB_SUCCESS; - } - -diff --git a/source4/dsdb/samdb/ldb_modules/partition_init.c b/source4/dsdb/samdb/ldb_modules/partition_init.c -index 58c65ccedd0..484b5bffb27 100644 ---- a/source4/dsdb/samdb/ldb_modules/partition_init.c -+++ b/source4/dsdb/samdb/ldb_modules/partition_init.c -@@ -742,10 +742,6 @@ int partition_create(struct ldb_module *module, struct ldb_request *req) - } - - mod_msg->dn = ldb_dn_new(mod_msg, ldb, DSDB_PARTITION_DN); -- ret = ldb_msg_add_empty(mod_msg, DSDB_PARTITION_ATTR, LDB_FLAG_MOD_ADD, NULL); -- if (ret != LDB_SUCCESS) { -- return ret; -- } - - casefold_dn = ldb_dn_get_casefold(dn); - -@@ -785,18 +781,16 @@ int partition_create(struct ldb_module *module, struct ldb_request *req) - } - partition_record = talloc_asprintf(mod_msg, "%s:%s", casefold_dn, filename); - -- ret = ldb_msg_add_steal_string(mod_msg, DSDB_PARTITION_ATTR, partition_record); -+ ret = ldb_msg_append_steal_string(mod_msg, DSDB_PARTITION_ATTR, partition_record, -+ LDB_FLAG_MOD_ADD); - if (ret != LDB_SUCCESS) { - return ret; - } - - if (ldb_request_get_control(req, DSDB_CONTROL_PARTIAL_REPLICA)) { - /* this new partition is a partial replica */ -- ret = ldb_msg_add_empty(mod_msg, "partialReplica", LDB_FLAG_MOD_ADD, NULL); -- if (ret != LDB_SUCCESS) { -- return ret; -- } -- ret = ldb_msg_add_fmt(mod_msg, "partialReplica", "%s", ldb_dn_get_linearized(dn)); -+ ret = ldb_msg_append_fmt(mod_msg, LDB_FLAG_MOD_ADD, -+ "partialReplica", "%s", ldb_dn_get_linearized(dn)); - if (ret != LDB_SUCCESS) { - return ret; - } -diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c -index 29ffda75c87..eec1e639856 100644 ---- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c -+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c -@@ -3888,22 +3888,12 @@ static int replmd_rename_callback(struct ldb_request *req, struct ldb_reply *are - ldb_operr(ldb)); - } - -- if (ldb_msg_add_empty(msg, rdn_name, LDB_FLAG_MOD_REPLACE, NULL) != 0) { -+ if (ldb_msg_append_value(msg, rdn_name, rdn_val, LDB_FLAG_MOD_REPLACE) != 0) { - talloc_free(ares); - return ldb_module_done(ac->req, NULL, NULL, - ldb_oom(ldb)); - } -- if (ldb_msg_add_value(msg, rdn_name, rdn_val, NULL) != 0) { -- talloc_free(ares); -- return ldb_module_done(ac->req, NULL, NULL, -- ldb_oom(ldb)); -- } -- if (ldb_msg_add_empty(msg, "name", LDB_FLAG_MOD_REPLACE, NULL) != 0) { -- talloc_free(ares); -- return ldb_module_done(ac->req, NULL, NULL, -- ldb_oom(ldb)); -- } -- if (ldb_msg_add_value(msg, "name", rdn_val, NULL) != 0) { -+ if (ldb_msg_append_value(msg, "name", rdn_val, LDB_FLAG_MOD_REPLACE) != 0) { - talloc_free(ares); - return ldb_module_done(ac->req, NULL, NULL, - ldb_oom(ldb)); -@@ -5161,16 +5151,10 @@ static int replmd_name_modify(struct replmd_replicated_request *ar, - goto failed; - } - -- if (ldb_msg_add_empty(msg, rdn_name, LDB_FLAG_MOD_REPLACE, NULL) != 0) { -- goto failed; -- } -- if (ldb_msg_add_value(msg, rdn_name, rdn_val, NULL) != 0) { -- goto failed; -- } -- if (ldb_msg_add_empty(msg, "name", LDB_FLAG_MOD_REPLACE, NULL) != 0) { -+ if (ldb_msg_append_value(msg, rdn_name, rdn_val, LDB_FLAG_MOD_REPLACE) != 0) { - goto failed; - } -- if (ldb_msg_add_value(msg, "name", rdn_val, NULL) != 0) { -+ if (ldb_msg_append_value(msg, "name", rdn_val, LDB_FLAG_MOD_REPLACE) != 0) { - goto failed; - } - -diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c -index 24971d521aa..b89d93910fd 100644 ---- a/source4/dsdb/samdb/ldb_modules/samldb.c -+++ b/source4/dsdb/samdb/ldb_modules/samldb.c -@@ -1103,14 +1103,11 @@ static int samldb_rodc_add(struct samldb_ctx *ac) - return LDB_ERR_OTHER; - - found: -- ret = ldb_msg_add_empty(ac->msg, "msDS-SecondaryKrbTgtNumber", -- LDB_FLAG_INTERNAL_DISABLE_VALIDATION, NULL); -- if (ret != LDB_SUCCESS) { -- return ldb_operr(ldb); -- } - -- ret = samdb_msg_add_uint(ldb, ac->msg, ac->msg, -- "msDS-SecondaryKrbTgtNumber", krbtgt_number); -+ ldb_msg_remove_attr(ac->msg, "msDS-SecondaryKrbTgtNumber"); -+ ret = samdb_msg_append_uint(ldb, ac->msg, ac->msg, -+ "msDS-SecondaryKrbTgtNumber", krbtgt_number, -+ LDB_FLAG_INTERNAL_DISABLE_VALIDATION); - if (ret != LDB_SUCCESS) { - return ldb_operr(ldb); - } -@@ -1792,7 +1789,7 @@ static int samldb_objectclass_trigger(struct samldb_ctx *ac) - struct ldb_context *ldb = ldb_module_get_ctx(ac->module); - void *skip_allocate_sids = ldb_get_opaque(ldb, - "skip_allocate_sids"); -- struct ldb_message_element *el, *el2; -+ struct ldb_message_element *el; - struct dom_sid *sid; - int ret; - -@@ -1926,23 +1923,17 @@ static int samldb_objectclass_trigger(struct samldb_ctx *ac) - /* "isCriticalSystemObject" might be set */ - if (user_account_control & - (UF_SERVER_TRUST_ACCOUNT | UF_PARTIAL_SECRETS_ACCOUNT)) { -- ret = ldb_msg_add_string(ac->msg, "isCriticalSystemObject", -- "TRUE"); -+ ret = ldb_msg_add_string_flags(ac->msg, "isCriticalSystemObject", -+ "TRUE", LDB_FLAG_MOD_REPLACE); - if (ret != LDB_SUCCESS) { - return ret; - } -- el2 = ldb_msg_find_element(ac->msg, -- "isCriticalSystemObject"); -- el2->flags = LDB_FLAG_MOD_REPLACE; - } else if (user_account_control & UF_WORKSTATION_TRUST_ACCOUNT) { -- ret = ldb_msg_add_string(ac->msg, "isCriticalSystemObject", -- "FALSE"); -+ ret = ldb_msg_add_string_flags(ac->msg, "isCriticalSystemObject", -+ "FALSE", LDB_FLAG_MOD_REPLACE); - if (ret != LDB_SUCCESS) { - return ret; - } -- el2 = ldb_msg_find_element(ac->msg, -- "isCriticalSystemObject"); -- el2->flags = LDB_FLAG_MOD_REPLACE; - } - - /* Step 1.4: "userAccountControl" -> "primaryGroupID" mapping */ -@@ -2018,14 +2009,13 @@ static int samldb_objectclass_trigger(struct samldb_ctx *ac) - ldb_set_errstring(ldb, "samldb: Unrecognized account type!"); - return LDB_ERR_UNWILLING_TO_PERFORM; - } -- ret = samdb_msg_add_uint(ldb, ac->msg, ac->msg, -- "sAMAccountType", -- account_type); -+ ret = samdb_msg_add_uint_flags(ldb, ac->msg, ac->msg, -+ "sAMAccountType", -+ account_type, -+ LDB_FLAG_MOD_REPLACE); - if (ret != LDB_SUCCESS) { - return ret; - } -- el2 = ldb_msg_find_element(ac->msg, "sAMAccountType"); -- el2->flags = LDB_FLAG_MOD_REPLACE; - } - break; - } -@@ -2945,26 +2935,23 @@ static int samldb_user_account_control_change(struct samldb_ctx *ac) - } - - if (old_atype != new_atype) { -- ret = samdb_msg_add_uint(ldb, ac->msg, ac->msg, -- "sAMAccountType", new_atype); -+ ret = samdb_msg_append_uint(ldb, ac->msg, ac->msg, -+ "sAMAccountType", new_atype, -+ LDB_FLAG_MOD_REPLACE); - if (ret != LDB_SUCCESS) { - return ret; - } -- el = ldb_msg_find_element(ac->msg, "sAMAccountType"); -- el->flags = LDB_FLAG_MOD_REPLACE; - } - - /* As per MS-SAMR 3.1.1.8.10 these flags have not to be set */ - if ((clear_uac & UF_LOCKOUT) && (old_lockoutTime != 0)) { - /* "lockoutTime" reset as per MS-SAMR 3.1.1.8.10 */ - ldb_msg_remove_attr(ac->msg, "lockoutTime"); -- ret = samdb_msg_add_uint64(ldb, ac->msg, ac->msg, "lockoutTime", -- (NTTIME)0); -+ ret = samdb_msg_append_uint64(ldb, ac->msg, ac->msg, "lockoutTime", -+ (NTTIME)0, LDB_FLAG_MOD_REPLACE); - if (ret != LDB_SUCCESS) { - return ret; - } -- el = ldb_msg_find_element(ac->msg, "lockoutTime"); -- el->flags = LDB_FLAG_MOD_REPLACE; - } - - /* -@@ -2975,14 +2962,12 @@ static int samldb_user_account_control_change(struct samldb_ctx *ac) - * creating the attribute. - */ - if (old_is_critical != new_is_critical || old_atype != new_atype) { -- ret = ldb_msg_add_string(ac->msg, "isCriticalSystemObject", -- new_is_critical ? "TRUE": "FALSE"); -+ ret = ldb_msg_append_string(ac->msg, "isCriticalSystemObject", -+ new_is_critical ? "TRUE": "FALSE", -+ LDB_FLAG_MOD_REPLACE); - if (ret != LDB_SUCCESS) { - return ret; - } -- el = ldb_msg_find_element(ac->msg, -- "isCriticalSystemObject"); -- el->flags = LDB_FLAG_MOD_REPLACE; - } - - if (!ldb_msg_find_element(ac->msg, "primaryGroupID") && -@@ -2995,14 +2980,12 @@ static int samldb_user_account_control_change(struct samldb_ctx *ac) - } - } - -- ret = samdb_msg_add_uint(ldb, ac->msg, ac->msg, -- "primaryGroupID", new_pgrid); -+ ret = samdb_msg_append_uint(ldb, ac->msg, ac->msg, -+ "primaryGroupID", new_pgrid, -+ LDB_FLAG_MOD_REPLACE); - if (ret != LDB_SUCCESS) { - return ret; - } -- el = ldb_msg_find_element(ac->msg, -- "primaryGroupID"); -- el->flags = LDB_FLAG_MOD_REPLACE; - } - - /* Propagate eventual "userAccountControl" attribute changes */ -@@ -3205,13 +3188,12 @@ static int samldb_lockout_time(struct samldb_ctx *ac) - - /* lockoutTime == 0 resets badPwdCount */ - ldb_msg_remove_attr(ac->msg, "badPwdCount"); -- ret = samdb_msg_add_int(ldb, ac->msg, ac->msg, -- "badPwdCount", 0); -+ ret = samdb_msg_append_int(ldb, ac->msg, ac->msg, -+ "badPwdCount", 0, -+ LDB_FLAG_MOD_REPLACE); - if (ret != LDB_SUCCESS) { - return ret; - } -- el = ldb_msg_find_element(ac->msg, "badPwdCount"); -- el->flags = LDB_FLAG_MOD_REPLACE; - - return LDB_SUCCESS; - } -@@ -3309,13 +3291,11 @@ static int samldb_group_type_change(struct samldb_ctx *ac) - ldb_set_errstring(ldb, "samldb: Unrecognized account type!"); - return LDB_ERR_UNWILLING_TO_PERFORM; - } -- ret = samdb_msg_add_uint(ldb, ac->msg, ac->msg, "sAMAccountType", -- account_type); -+ ret = samdb_msg_append_uint(ldb, ac->msg, ac->msg, "sAMAccountType", -+ account_type, LDB_FLAG_MOD_REPLACE); - if (ret != LDB_SUCCESS) { - return ret; - } -- el = ldb_msg_find_element(ac->msg, "sAMAccountType"); -- el->flags = LDB_FLAG_MOD_REPLACE; - - return LDB_SUCCESS; - } -diff --git a/source4/dsdb/samdb/ldb_modules/tombstone_reanimate.c b/source4/dsdb/samdb/ldb_modules/tombstone_reanimate.c -index 5f8911c66be..99c5955e9e7 100644 ---- a/source4/dsdb/samdb/ldb_modules/tombstone_reanimate.c -+++ b/source4/dsdb/samdb/ldb_modules/tombstone_reanimate.c -@@ -294,14 +294,13 @@ static int tr_prepare_attributes(struct tr_context *ac) - return ldb_error(ldb, LDB_ERR_UNWILLING_TO_PERFORM, - "reanimate: Unrecognized account type!"); - } -- ret = samdb_msg_add_uint(ldb, ac->mod_msg, ac->mod_msg, -- "sAMAccountType", account_type); -+ ret = samdb_msg_append_uint(ldb, ac->mod_msg, ac->mod_msg, -+ "sAMAccountType", account_type, -+ LDB_FLAG_MOD_REPLACE); - if (ret != LDB_SUCCESS) { - return ldb_error(ldb, LDB_ERR_OPERATIONS_ERROR, - "reanimate: Failed to add sAMAccountType to restored object."); - } -- el = ldb_msg_find_element(ac->mod_msg, "sAMAccountType"); -- el->flags = LDB_FLAG_MOD_REPLACE; - - /* Default values set by Windows */ - ret = samdb_find_or_add_attribute(ldb, ac->mod_msg, -@@ -324,12 +323,11 @@ static int tr_prepare_attributes(struct tr_context *ac) - return ret; - } - -- ret = ldb_msg_add_string(ac->mod_msg, "objectCategory", value); -+ ret = ldb_msg_append_string(ac->mod_msg, "objectCategory", value, -+ LDB_FLAG_MOD_ADD); - if (ret != LDB_SUCCESS) { - return ret; - } -- el = ldb_msg_find_element(ac->mod_msg, "objectCategory"); -- el->flags = LDB_FLAG_MOD_ADD; - } - - return LDB_SUCCESS; -diff --git a/source4/nbt_server/wins/winsdb.c b/source4/nbt_server/wins/winsdb.c -index e4a7c2042ed..2a05e96bca4 100644 ---- a/source4/nbt_server/wins/winsdb.c -+++ b/source4/nbt_server/wins/winsdb.c -@@ -102,13 +102,11 @@ uint64_t winsdb_set_maxVersion(struct winsdb_handle *h, uint64_t newMaxVersion) - msg->dn = dn; - - -- ret = ldb_msg_add_empty(msg, "objectClass", LDB_FLAG_MOD_REPLACE, NULL); -+ ret = ldb_msg_append_string(msg, "objectClass", "winsMaxVersion", -+ LDB_FLAG_MOD_REPLACE); - if (ret != LDB_SUCCESS) goto failed; -- ret = ldb_msg_add_string(msg, "objectClass", "winsMaxVersion"); -- if (ret != LDB_SUCCESS) goto failed; -- ret = ldb_msg_add_empty(msg, "maxVersion", LDB_FLAG_MOD_REPLACE, NULL); -- if (ret != LDB_SUCCESS) goto failed; -- ret = ldb_msg_add_fmt(msg, "maxVersion", "%llu", (long long)newMaxVersion); -+ ret = ldb_msg_append_fmt(msg, LDB_FLAG_MOD_REPLACE, -+ "maxVersion", "%llu", (long long)newMaxVersion); - if (ret != LDB_SUCCESS) goto failed; - - ret = ldb_modify(wins_db, msg); -@@ -779,8 +777,7 @@ static struct ldb_message *winsdb_message(struct ldb_context *ldb, - ret |= ldb_msg_add_winsdb_addr(msg, rec, "address", rec->addresses[i]); - } - if (rec->registered_by) { -- ret |= ldb_msg_add_empty(msg, "registeredBy", 0, NULL); -- ret |= ldb_msg_add_string(msg, "registeredBy", rec->registered_by); -+ ret |= ldb_msg_append_string(msg, "registeredBy", rec->registered_by, 0); - } - if (ret != LDB_SUCCESS) goto failed; - return msg; -diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c -index 15b068aec62..a165ab2b9d6 100644 ---- a/source4/rpc_server/lsa/dcesrv_lsa.c -+++ b/source4/rpc_server/lsa/dcesrv_lsa.c -@@ -1778,12 +1778,7 @@ static NTSTATUS update_uint32_t_value(TALLOC_CTX *mem_ctx, - goto done; - } - -- ret = ldb_msg_add_empty(dest, attribute, flags, NULL); -- if (ret != LDB_SUCCESS) { -- return NT_STATUS_NO_MEMORY; -- } -- -- ret = samdb_msg_add_uint(sam_ldb, dest, dest, attribute, value); -+ ret = samdb_msg_append_uint(sam_ldb, dest, dest, attribute, value, flags); - if (ret != LDB_SUCCESS) { - return NT_STATUS_NO_MEMORY; - } -@@ -1874,13 +1869,7 @@ static NTSTATUS update_trust_user(TALLOC_CTX *mem_ctx, - continue; - } - -- ret = ldb_msg_add_empty(msg, attribute, -- LDB_FLAG_MOD_REPLACE, NULL); -- if (ret != LDB_SUCCESS) { -- return NT_STATUS_NO_MEMORY; -- } -- -- ret = ldb_msg_add_value(msg, attribute, &v, NULL); -+ ret = ldb_msg_append_value(msg, attribute, &v, LDB_FLAG_MOD_REPLACE); - if (ret != LDB_SUCCESS) { - return NT_STATUS_NO_MEMORY; - } -@@ -2166,28 +2155,30 @@ static NTSTATUS setInfoTrustedDomain_base(struct dcesrv_call_state *dce_call, - } - - if (add_incoming || del_incoming) { -- ret = ldb_msg_add_empty(msg, "trustAuthIncoming", -- LDB_FLAG_MOD_REPLACE, NULL); -- if (ret != LDB_SUCCESS) { -- return NT_STATUS_NO_MEMORY; -- } - if (add_incoming) { -- ret = ldb_msg_add_value(msg, "trustAuthIncoming", -- &trustAuthIncoming, NULL); -+ ret = ldb_msg_append_value(msg, "trustAuthIncoming", -+ &trustAuthIncoming, LDB_FLAG_MOD_REPLACE); -+ if (ret != LDB_SUCCESS) { -+ return NT_STATUS_NO_MEMORY; -+ } -+ } else { -+ ret = ldb_msg_add_empty(msg, "trustAuthIncoming", -+ LDB_FLAG_MOD_REPLACE, NULL); - if (ret != LDB_SUCCESS) { - return NT_STATUS_NO_MEMORY; - } - } - } - if (add_outgoing || del_outgoing) { -- ret = ldb_msg_add_empty(msg, "trustAuthOutgoing", -- LDB_FLAG_MOD_REPLACE, NULL); -- if (ret != LDB_SUCCESS) { -- return NT_STATUS_NO_MEMORY; -- } - if (add_outgoing) { -- ret = ldb_msg_add_value(msg, "trustAuthOutgoing", -- &trustAuthOutgoing, NULL); -+ ret = ldb_msg_append_value(msg, "trustAuthOutgoing", -+ &trustAuthOutgoing, LDB_FLAG_MOD_REPLACE); -+ if (ret != LDB_SUCCESS) { -+ return NT_STATUS_NO_MEMORY; -+ } -+ } else { -+ ret = ldb_msg_add_empty(msg, "trustAuthOutgoing", -+ LDB_FLAG_MOD_REPLACE, NULL); - if (ret != LDB_SUCCESS) { - return NT_STATUS_NO_MEMORY; - } -@@ -4635,14 +4626,8 @@ static NTSTATUS dcesrv_lsa_lsaRSetForestTrustInformation(struct dcesrv_call_stat - goto done; - } - -- ret = ldb_msg_add_empty(msg, "msDS-TrustForestTrustInfo", -- LDB_FLAG_MOD_REPLACE, NULL); -- if (ret != LDB_SUCCESS) { -- status = NT_STATUS_NO_MEMORY; -- goto done; -- } -- ret = ldb_msg_add_value(msg, "msDS-TrustForestTrustInfo", -- &ft_blob, NULL); -+ ret = ldb_msg_append_value(msg, "msDS-TrustForestTrustInfo", -+ &ft_blob, LDB_FLAG_MOD_REPLACE); - if (ret != LDB_SUCCESS) { - status = NT_STATUS_NO_MEMORY; - goto done; -diff --git a/source4/winbind/idmap.c b/source4/winbind/idmap.c -index c4039be473a..c6375f8357a 100644 ---- a/source4/winbind/idmap.c -+++ b/source4/winbind/idmap.c -@@ -672,14 +672,8 @@ static NTSTATUS idmap_sid_to_xid(struct idmap_context *idmap_ctx, - vals[1].data = (uint8_t *)hwm_string; - vals[1].length = strlen(hwm_string); - } else { -- ret = ldb_msg_add_empty(hwm_msg, "xidNumber", LDB_FLAG_MOD_ADD, -- NULL); -- if (ret != LDB_SUCCESS) { -- status = NT_STATUS_NONE_MAPPED; -- goto failed; -- } -- -- ret = ldb_msg_add_string(hwm_msg, "xidNumber", hwm_string); -+ ret = ldb_msg_append_string(hwm_msg, "xidNumber", hwm_string, -+ LDB_FLAG_MOD_ADD); - if (ret != LDB_SUCCESS) - { - status = NT_STATUS_NONE_MAPPED; --- -2.25.1 diff --git a/samba-4.15.3.tar.asc b/samba-4.15.3.tar.asc deleted file mode 100644 index dbc01c29fadbe22c01639d7d7198d4d3ac5c923b..0000000000000000000000000000000000000000 --- a/samba-4.15.3.tar.asc +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN PGP SIGNATURE----- - -iQIzBAABCgAdFiEEgfXigyvSVFoYl7cTqplEL7aAtiAFAmGww0kACgkQqplEL7aA -tiCzMg/+IzBD53oeYFSSt6V9o1ZhD/7bL425n/7Ea2iLaHkOEQWN3AgKV7h1rdSb -tS/Ys3xUf9LB1ZVkXbu17oWj5pG8aWcp6Ky80uXHycZ5X0/fcHegSU5SIyUfLs0F -d3BXvFWkPIy8H9a55wFTpJte2ofRoFqWUG4MAlOq83ummnmrz0W5j6QcufVIRjWq -hGMbg8Vjk+UEtKNO7fl8iSQ0ZRyXCkBR3biDBtMbvtoluaVkixxwwSPqgDoNXgju -ox2EbVfHLSHc+7Tb30uKQq/mf3uhf6ASIrajNVrXotK1fgpCCKnMLb9qRHEftttY -DwYKQvsrHCw9vYg/xyO2NOBr82mxjE6NBLsV1Kp8pdc4vInmAqOCsQpOuZ0SgO6u -sZk4c5AkfH7pZtHeNtlefiGe8/7ApU6UC6kkXT3mnLBtWKMBte9/NR6ZgCLle7tV -aAx6Io9j/rAeueRRgIK98bzxXSufjtFyNmM+Qr7IXnFHtJNM919ib4pr5DzpGwAc -+FMG0LfmU0XiUXcbw/IZ3AOD2DBwZC58ZezO3alUS8eRqNTP13v3Uhg9F78+eyah -Wbohx05Y4MA1ywtMd8z/dZn97nw3bw+z6fLNC//1Sq1qo1fXipaoSQW1LK9IHeVO -cV7cvd2c16p7NN3Op+34QY7Nc7b1uhtTV3v3tiEQYR/uQx+tyz8= -=fu6B ------END PGP SIGNATURE----- diff --git a/samba-4.17.2.tar.asc b/samba-4.17.2.tar.asc new file mode 100644 index 0000000000000000000000000000000000000000..146e2fb0b3354939bbbcc68c7acd2d1e56fa40f5 --- /dev/null +++ b/samba-4.17.2.tar.asc @@ -0,0 +1,16 @@ +-----BEGIN PGP SIGNATURE----- + +iQIzBAABCgAdFiEEgfXigyvSVFoYl7cTqplEL7aAtiAFAmNWbqoACgkQqplEL7aA +tiBRRBAArva0cDJeuSvlmC5t+i+WZTrFwg7txiu6a+GccMxwVIu9Ab2BeJSHA2Fe +Ghh9VGDkaaRlzyJNHZtnt5xn9tRcSVVAy4+8/hSroP0uW97JIyGRfnWNExsEyM6w +uSGFLsDpVsvpzMCfJqRm2umCO+XZ90M2ZQs6AlqbqyF6lHAY4jzI75o56T9GxijV +wx4gCdFSFQas79G/apNhuAuotqZHwEPxb8vUkoEgS1PbfbiVoYoI6RQDZ7WpOfwM +nKO3rbTGOZBGX7oJPUfSGPww/xrhoxaHv/9ixwruEqEPTUFQk+lWnY2DJ7EGGW5U +D7wSs/iW/TgDZAFsEv928odHNluSIZYktDBoKAG6cS/iiA3Bqv0U97CZBrJWj3P6 +vjpJECOHJDSq8UeimP4aToFP9NvZNr+GawNpOkL3N6lfPOIk7naRdqN7C01kNIoA +UX90K31J5YK440jlSwJ/uJAS1p1slvcsr+OYlAsRSc+Dug2biKonqv42qBgA+SvI +8pNOQVwINqujL/utoNbQ0Nu54RJ67C6l1Jh77Ng8OhtAtm5Jojm6ceXzms4pJCJ8 +8t/RO3/TqOl7ZxlBSsdiTt0peOAO/fvxpJYM3mVgWQBfjSNkHM8QhDJALXgKoJv3 +FXZG0peM5inxK70bDAN+fc0Ika74bT505OOtPzlwmjwxzHSKAJM= +=9Stz +-----END PGP SIGNATURE----- diff --git a/samba-4.15.3.tar.gz b/samba-4.17.2.tar.gz similarity index 53% rename from samba-4.15.3.tar.gz rename to samba-4.17.2.tar.gz index 10c234ee1f0ef06097d24809ed2f48f27a270e86..1a406016892ecd382e95e05ba9c90da184715d15 100644 Binary files a/samba-4.15.3.tar.gz and b/samba-4.17.2.tar.gz differ diff --git a/samba.spec b/samba.spec index 0bf17abb0ead63bde6e9bb97745a5d78bbcb8ffe..6ece23314c77255730b62d754449fa10239b6002 100644 --- a/samba.spec +++ b/samba.spec @@ -2,10 +2,10 @@ %bcond_without clustering %define samba_requires_eq() %(LC_ALL="C" echo '%*' | xargs -r rpm -q --qf 'Requires: %%{name} = %%{epoch}:%%{version}\\n' | sed -e 's/ (none):/ /' -e 's/ 0:/ /' | grep -v "is not") -%global talloc_version 2.3.3 -%global tdb_version 1.4.4 -%global tevent_version 0.11.0 -%global ldb_version 2.4.1-2 +%global talloc_version 2.3.4 +%global tdb_version 1.4.7 +%global tevent_version 0.13.0 +%global ldb_version 2.6.1 %undefine _strict_symbol_defs_build @@ -47,8 +47,8 @@ %global samba_depver %{version}-%{release} Name: samba -Version: 4.15.3 -Release: 12 +Version: 4.17.2 +Release: 1 Summary: A suite for Linux to interoperate with Windows License: GPLv3+ and LGPLv3+ @@ -62,49 +62,10 @@ Source4: smb.conf.vendor Source5: smb.conf.example Source6: pam_winbind.conf Source7: samba.pamd +Source8: usershares.conf.vendor Source201: README.downgrade -Patch0: backport-0001-CVE-2021-44142.patch -Patch1: backport-0002-CVE-2021-44142.patch -Patch2: backport-0003-CVE-2021-44142.patch -Patch3: backport-0004-CVE-2021-44142.patch -Patch4: backport-0005-CVE-2021-44142.patch -Patch5: backport-0001-CVE-2022-0336.patch -Patch6: backport-0002-CVE-2022-0336.patch -Patch7: backport-CVE-2021-44141.patch -Patch8: backport-CVE-2022-32746.patch -Patch9: backport-CVE-2022-32745.patch -Patch10: backport-CVE-2022-2031-CVE-2022-32744.patch -Patch11: backport-CVE-2022-32742.patch -Patch12: 0001-CVE-2022-32743-s4-acl-Add-tests-for-validated-dNSHos.patch -Patch13: 0002-CVE-2022-32743-tests-py_credentials-Add-tests-for-se.patch -Patch14: 0003-CVE-2022-32743-s4-torture-rpc-Fix-tests-to-match-Win.patch -Patch15: 0004-CVE-2022-32743-s4-dsdb-util-Add-dsdb_msg_get_single_.patch -Patch16: 0005-CVE-2022-32743-s4-dsdb-util-Add-function-to-check-fo.patch -Patch17: 0006-CVE-2022-32743-dsdb-Implement-validated-dNSHostName-.patch -Patch18: 0007-CVE-2022-32743-dsdb-common-Add-FORCE_ALLOW_VALIDATED.patch -Patch19: 0008-CVE-2022-32743-dsdb-modules-acl-Handle-FORCE_ALLOW_V.patch -Patch20: 0009-CVE-2022-32743-s4-rpc_server-netlogon-Remove-dNSHost.patch -Patch21: 0010-CVE-2022-32743-s4-rpc_server-netlogon-Always-observe.patch -Patch22: 0011-CVE-2022-32743-s4-rpc_server-netlogon-Connect-to-sam.patch -Patch23: 0012-CVE-2022-32743-dsdb-modules-acl-Account-for-sAMAccou.patch -Patch24: 0013-CVE-2022-32743-dsdb-modules-acl-Allow-simultaneous-s.patch -Patch25: 0014-CVE-2022-32743-s4-rpc_server-common-Add-dcesrv_samdb.patch -Patch26: 0015-CVE-2022-32743-s4-rpc_server-netlogon-Reconnect-to-s.patch -Patch27: backport-0001-CVE-2022-1615-util-genrand-don-t-ignore-errors-in-random-number-ge.patch -Patch28: backport-0002-CVE-2022-1615-py-uptodateness-more-details-in-missing-dn-report.patch -Patch29: backport-0001-CVE-2022-3437.patch -Patch30: backport-0002-CVE-2022-3437.patch -Patch31: backport-0003-CVE-2022-3437.patch -Patch32: backport-0004-CVE-2022-3437.patch -Patch33: backport-0005-CVE-2022-3437.patch -Patch34: backport-0006-CVE-2022-3437.patch -Patch35: backport-0007-CVE-2022-3437.patch -Patch36: backport-0008-CVE-2022-3437.patch -Patch37: backport-0009-CVE-2022-3437.patch -Patch38: backport-0010-CVE-2022-3437.patch -Patch39: backport-0011-CVE-2022-3437.patch BuildRequires: avahi-devel bison dbus-devel docbook-style-xsl e2fsprogs-devel flex gawk gnupg2 gnutls-devel >= 3.4.7 gpgme-devel BuildRequires: jansson-devel krb5-devel >= %{required_mit_krb5} libacl-devel libaio-devel libarchive-devel libattr-devel @@ -133,7 +94,7 @@ BuildRequires: libcephfs-devel %endif %if %{with_dc} -BuildRequires: python3-iso8601 bind krb5-server >= %{required_mit_krb5} python3-pyasn1 +BuildRequires: python3-iso8601 bind krb5-server >= %{required_mit_krb5} python3-pyasn1 >= 0.4.8 %endif BuildRequires: perl(ExtUtils::MakeMaker) perl(FindBin) perl(Parse::Yapp) libtalloc-devel >= %{talloc_version} python3-talloc-devel >= %{talloc_version} @@ -281,6 +242,9 @@ Samba AD. %package devel Summary: Developer tools for Samba libraries Requires: %{name}-libs = %{samba_depver} %{name}-client-libs = %{samba_depver} +%if %{with dc} +Requires: %{name}-dc-libs = %{samba_depver} +%endif Provides: samba4-devel = %{samba_depver} Obsoletes: samba4-devel < %{samba_depver} @@ -371,7 +335,7 @@ This package provides developer tools for the wbclient library. ### PYTHON3 %package -n python3-%{name} Summary: Python3 library package for %{name} -Requires: %{name} = %{samba_depver} %{name}-client = %{samba_depver} %{name}-common = %{samba_depver} +Requires: %{name}-client = %{samba_depver} %{name}-common = %{samba_depver} Requires: python3-talloc python3-tevent python3-tdb python3-ldb python3-dns Requires: %{name}-libs = %{samba_depver} Obsoletes: python2-samba @@ -382,6 +346,9 @@ Requires: libsmbclient = %{samba_depver} %if %with_libwbclient Requires: libwbclient = %{samba_depver} %endif +%if %{with dc} +Requires: %{name}-dc-libs = %{samba_depver} +%endif %description -n python3-%{name} This package contains the Python 3 libraries needed by programs @@ -402,6 +369,7 @@ If you want to run full set of Samba tests, you need to install this package. %package -n python3-samba-dc Summary: The Samba Python libraries for Samba AD Requires: python3-%{name} = %{samba_depver} +Requires: %{name}-dc-libs = %{samba_depver} %description -n python3-samba-dc This contains the Python libraries needed by programs @@ -445,6 +413,15 @@ Obsoletes: samba4-test < %{samba_depver} %{name}-test-libs %{name}-test-dev %{name}-test provides testing tools for both the server and client packages of Samba. +%package usershares +Summary: Provides support for non-root user shares +Requires: %{name} = %{samba_depver} +Requires: %{name}-common-tools = %{samba_depver} + +%description usershares +Installing this package will provide a configuration file, group and +directories to support non-root user shares. You can configure them +as a user using the `net usershare` command. %package winbind Summary: The winbind package for %{name} @@ -516,6 +493,7 @@ Winexe is a Remote Windows®-command executor %if %with_clustering_support %package -n ctdb Summary: A Clustered Database package based on Samba's Trivial Database (TDB) +Requires: %{name}-winbind-clients = %{samba_depver} Requires: %{name}-common = %{samba_depver} %{name}-client = %{samba_depver} coreutils psmisc Requires: sed tdb-tools gawk procps-ng net-tools ethtool iproute iptables util-linux systemd-units @@ -554,6 +532,9 @@ This package contains some man help files for %{name}. zcat %{SOURCE0} | gpgv2 --quiet --keyring %{SOURCE2} %{SOURCE1} - %autosetup -n %{name}-%{version} -p1 +rm -rf third_party/{aesni-intel,heimdal} +rm -f lib/crypto/{aes,rijndael}*.c + %build %global _talloc_lib ,talloc,pytalloc,pytalloc-util %global _tevent_lib ,tevent,pytevent @@ -565,7 +546,7 @@ zcat %{SOURCE0} | gpgv2 --quiet --keyring %{SOURCE2} %{SOURCE1} - %global _tdb_lib ,!tdb,!pytdb %global _ldb_lib ,!ldb,!pyldb,!pyldb-util -%global _samba_libraries !zlib,!popt%{_talloc_lib}%{_tevent_lib}%{_tdb_lib}%{_ldb_lib} +%global _samba_libraries !popt%{_talloc_lib}%{_tevent_lib}%{_tdb_lib}%{_ldb_lib} %global _samba_idmap_modules idmap_ad,idmap_rid,idmap_ldap,idmap_hash,idmap_tdb2 %global _samba_pdb_modules pdb_tdbsam,pdb_ldap,pdb_smbpasswd,pdb_wbc_sam,pdb_samba4 @@ -641,6 +622,9 @@ export LDFLAGS="%{__global_ldflags} -fuse-ld=gold" --systemd-smb-extra=%{_systemd_extra} \ --systemd-nmb-extra=%{_systemd_extra} \ --systemd-winbind-extra=%{_systemd_extra} \ +%if %with_clustering_support + --systemd-ctdb-extra=%{_systemd_extra} \ +%endif --systemd-samba-extra=%{_systemd_extra} %make_build @@ -663,6 +647,7 @@ install -d -m 0755 %{buildroot}/var/lib/samba/lock install -d -m 0755 %{buildroot}/var/lib/samba/private install -d -m 0755 %{buildroot}/var/lib/samba/scripts install -d -m 0755 %{buildroot}/var/lib/samba/sysvol +install -d -m 0755 %{buildroot}/var/lib/samba/usershares install -d -m 0755 %{buildroot}/var/lib/samba/winbindd_privileged install -d -m 0755 %{buildroot}/var/log/samba/old install -d -m 0755 %{buildroot}/run/samba @@ -694,6 +679,7 @@ install -m 0644 %{SOURCE4} %{buildroot}%{_sysconfdir}/samba/smb.conf sed -i -e '/printing = cups/d' -e '/printcap name = cups/d' -e '/load printers = yes/d' -e '/cups options = raw/d' %{buildroot}%{_sysconfdir}/samba/smb.conf %endif install -m 0644 %{SOURCE5} %{buildroot}%{_sysconfdir}/samba/smb.conf.example +install -m 0644 %{SOURCE8} %{buildroot}%{_sysconfdir}/samba/usershares.conf install -d -m 0755 %{buildroot}%{_sysconfdir}/security install -m 0644 %{SOURCE6} %{buildroot}%{_sysconfdir}/security/pam_winbind.conf @@ -729,10 +715,6 @@ install -m 0644 ctdb/config/ctdb.conf %{buildroot}%{_sysconfdir}/ctdb/ctdb.conf install -m 0644 %{SOURCE201} packaging/README.downgrade -%if %with_clustering_support -install -m 0644 ctdb/config/ctdb.service %{buildroot}%{_unitdir} -%endif - # NetworkManager online/offline script install -d -m 0755 %{buildroot}%{_prefix}/lib/NetworkManager/dispatcher.d/ install -m 0755 packaging/NetworkManager/30-winbind-systemd \ @@ -821,8 +803,6 @@ for i in \ %{_libdir}/samba/libdfs-server-ad-samba4.so \ %{_libdir}/samba/libdsdb-garbage-collect-tombstones-samba4.so \ %{_libdir}/samba/libscavenge-dns-records-samba4.so \ - %{_libdir}/samba/ldb/ildap.so \ - %{_libdir}/samba/ldb/ldbsamba_extensions.so \ %{_unitdir}/samba.service \ %{python3_sitearch}/samba/dcerpc/dnsserver.*.so \ %{python3_sitearch}/samba/dnsserver.py \ @@ -1055,6 +1035,9 @@ fi %ldconfig_scriptlets test +%pre usershares +getent group usershares >/dev/null || groupadd -r usershares || : + %pre winbind /usr/sbin/groupadd -g 88 wbpriv >/dev/null 2>&1 || : @@ -1176,7 +1159,17 @@ fi %{_libdir}/samba/vfs/widelinks.so %{_libdir}/samba/vfs/worm.so %{_libdir}/samba/vfs/xattr_tdb.so +%dir %{_libexecdir}/samba %{_libexecdir}/samba/samba-bgqd +%{_libexecdir}/samba/samba-dcerpcd +%{_libexecdir}/samba/rpcd_classic +%{_libexecdir}/samba/rpcd_epmapper +%{_libexecdir}/samba/rpcd_fsrvp +%{_libexecdir}/samba/rpcd_lsad +%{_libexecdir}/samba/rpcd_mdssvc +%{_libexecdir}/samba/rpcd_rpcecho +%{_libexecdir}/samba/rpcd_spoolss +%{_libexecdir}/samba/rpcd_winreg %dir %{_datadir}/samba %dir %{_datadir}/samba/mdssvc %{_datadir}/samba/mdssvc/elasticsearch_mappings.json @@ -1202,6 +1195,9 @@ fi %{_libdir}/samba/libshares-samba4.so %{_libdir}/samba/libsmbpasswdparser-samba4.so %{_libdir}/samba/libxattr-tdb-samba4.so +%{_libdir}/samba/libREG-FULL-samba4.so +%{_libdir}/samba/libRPC-SERVER-LOOP-samba4.so +%{_libdir}/samba/libRPC-WORKER-samba4.so %config(noreplace) /etc/ld.so.conf.d/* %files client @@ -1335,7 +1331,6 @@ fi %if ! %with_libwbclient %{_libdir}/samba/libwbclient.so.* -%{_libdir}/samba/libwinbind-client-samba4.so #endif ! with_libwbclient %endif @@ -1487,6 +1482,7 @@ fi %{_libdir}/samba/bind9/dlz_bind9_12.so %{_libdir}/samba/bind9/dlz_bind9_14.so %{_libdir}/samba/bind9/dlz_bind9_16.so +%{_libdir}/samba/bind9/dlz_bind9_18.so %config(noreplace) /etc/ld.so.conf.d/* #endif with_dc %endif @@ -1651,7 +1647,6 @@ fi %if %with_libwbclient %files -n libwbclient %{_libdir}/samba/wbclient/libwbclient.so.* -%{_libdir}/samba/libwinbind-client-samba4.so %config(noreplace) /etc/ld.so.conf.d/* %files -n libwbclient-devel @@ -1713,14 +1708,6 @@ fi %{python3_sitearch}/samba/__pycache__/dnsresolver.*.pyc %{python3_sitearch}/samba/__pycache__/drs_utils.*.pyc %{python3_sitearch}/samba/__pycache__/getopt.*.pyc -%{python3_sitearch}/samba/__pycache__/gpclass.*.pyc -%{python3_sitearch}/samba/__pycache__/gp_ext_loader.*.pyc -%{python3_sitearch}/samba/__pycache__/gp_gnome_settings_ext.*.pyc -%{python3_sitearch}/samba/__pycache__/gp_msgs_ext.*.pyc -%{python3_sitearch}/samba/__pycache__/gp_scripts_ext.*.pyc -%{python3_sitearch}/samba/__pycache__/gp_sec_ext.*.pyc -%{python3_sitearch}/samba/__pycache__/gp_smb_conf_ext.*.pyc -%{python3_sitearch}/samba/__pycache__/gp_sudoers_ext.*.pyc %{python3_sitearch}/samba/__pycache__/graph.*.pyc %{python3_sitearch}/samba/__pycache__/hostconfig.*.pyc %{python3_sitearch}/samba/__pycache__/idmap.*.pyc @@ -1738,14 +1725,6 @@ fi %{python3_sitearch}/samba/__pycache__/trust_utils.*.pyc %{python3_sitearch}/samba/__pycache__/upgrade.*.pyc %{python3_sitearch}/samba/__pycache__/upgradehelpers.*.pyc -%{python3_sitearch}/samba/__pycache__/vgp_access_ext.*.pyc -%{python3_sitearch}/samba/__pycache__/vgp_files_ext.*.pyc -%{python3_sitearch}/samba/__pycache__/vgp_issue_ext.*.pyc -%{python3_sitearch}/samba/__pycache__/vgp_motd_ext.*.pyc -%{python3_sitearch}/samba/__pycache__/vgp_openssh_ext.*.pyc -%{python3_sitearch}/samba/__pycache__/vgp_startup_scripts_ext.*.pyc -%{python3_sitearch}/samba/__pycache__/vgp_sudoers_ext.*.pyc -%{python3_sitearch}/samba/__pycache__/vgp_symlink_ext.*.pyc %{python3_sitearch}/samba/__pycache__/xattr.*.pyc %{python3_sitearch}/samba/_glue.*.so %{python3_sitearch}/samba/_ldb.*.so @@ -1807,11 +1786,6 @@ fi %{python3_sitearch}/samba/dsdb_dns.*.so %{python3_sitearch}/samba/gensec.*.so %{python3_sitearch}/samba/getopt.py -%{python3_sitearch}/samba/gpclass.py -%{python3_sitearch}/samba/gp_gnome_settings_ext.py -%{python3_sitearch}/samba/gp_scripts_ext.py -%{python3_sitearch}/samba/gp_sec_ext.py -%{python3_sitearch}/samba/gpo.*.so %{python3_sitearch}/samba/graph.py %{python3_sitearch}/samba/hostconfig.py %{python3_sitearch}/samba/idmap.py @@ -1830,10 +1804,57 @@ fi %{python3_sitearch}/samba/emulate/__init__.py %{python3_sitearch}/samba/emulate/traffic.py %{python3_sitearch}/samba/emulate/traffic_packets.py -%{python3_sitearch}/samba/gp_ext_loader.py -%{python3_sitearch}/samba/gp_msgs_ext.py -%{python3_sitearch}/samba/gp_smb_conf_ext.py -%{python3_sitearch}/samba/gp_sudoers_ext.py +%dir %{python3_sitearch}/samba/gp +%dir %{python3_sitearch}/samba/gp/__pycache__ +%{python3_sitearch}/samba/gp/__pycache__/gpclass.*.pyc +%{python3_sitearch}/samba/gp/__pycache__/gp_centrify_crontab_ext.*.pyc +%{python3_sitearch}/samba/gp/__pycache__/gp_centrify_sudoers_ext.*.pyc +%{python3_sitearch}/samba/gp/__pycache__/gp_cert_auto_enroll_ext.*.pyc +%{python3_sitearch}/samba/gp/__pycache__/gp_chromium_ext.*.pyc +%{python3_sitearch}/samba/gp/__pycache__/gp_ext_loader.*.pyc +%{python3_sitearch}/samba/gp/__pycache__/gp_firefox_ext.*.pyc +%{python3_sitearch}/samba/gp/__pycache__/gp_firewalld_ext.*.pyc +%{python3_sitearch}/samba/gp/__pycache__/gp_gnome_settings_ext.*.pyc +%{python3_sitearch}/samba/gp/__pycache__/gp_msgs_ext.*.pyc +%{python3_sitearch}/samba/gp/__pycache__/gp_scripts_ext.*.pyc +%{python3_sitearch}/samba/gp/__pycache__/gp_sec_ext.*.pyc +%{python3_sitearch}/samba/gp/__pycache__/gp_smb_conf_ext.*.pyc +%{python3_sitearch}/samba/gp/__pycache__/gp_sudoers_ext.*.pyc +%{python3_sitearch}/samba/gp/__pycache__/vgp_access_ext.*.pyc +%{python3_sitearch}/samba/gp/__pycache__/vgp_files_ext.*.pyc +%{python3_sitearch}/samba/gp/__pycache__/vgp_issue_ext.*.pyc +%{python3_sitearch}/samba/gp/__pycache__/vgp_motd_ext.*.pyc +%{python3_sitearch}/samba/gp/__pycache__/vgp_openssh_ext.*.pyc +%{python3_sitearch}/samba/gp/__pycache__/vgp_startup_scripts_ext.*.pyc +%{python3_sitearch}/samba/gp/__pycache__/vgp_sudoers_ext.*.pyc +%{python3_sitearch}/samba/gp/__pycache__/vgp_symlink_ext.*.pyc +%{python3_sitearch}/samba/gp/gpclass.py +%{python3_sitearch}/samba/gp/gp_gnome_settings_ext.py +%{python3_sitearch}/samba/gp/gp_scripts_ext.py +%{python3_sitearch}/samba/gp/gp_sec_ext.py +%{python3_sitearch}/samba/gp/gp_centrify_crontab_ext.py +%{python3_sitearch}/samba/gp/gp_centrify_sudoers_ext.py +%{python3_sitearch}/samba/gp/gp_cert_auto_enroll_ext.py +%{python3_sitearch}/samba/gp/gp_chromium_ext.py +%{python3_sitearch}/samba/gp/gp_ext_loader.py +%{python3_sitearch}/samba/gp/gp_firefox_ext.py +%{python3_sitearch}/samba/gp/gp_firewalld_ext.py +%{python3_sitearch}/samba/gp/gp_msgs_ext.py +%{python3_sitearch}/samba/gp/gp_smb_conf_ext.py +%{python3_sitearch}/samba/gp/gp_sudoers_ext.py +%dir %{python3_sitearch}/samba/gp/util +%dir %{python3_sitearch}/samba/gp/util/__pycache__ +%{python3_sitearch}/samba/gp/util/__pycache__/logging.*.pyc +%{python3_sitearch}/samba/gp/util/logging.py +%{python3_sitearch}/samba/gp/vgp_access_ext.py +%{python3_sitearch}/samba/gp/vgp_files_ext.py +%{python3_sitearch}/samba/gp/vgp_issue_ext.py +%{python3_sitearch}/samba/gp/vgp_motd_ext.py +%{python3_sitearch}/samba/gp/vgp_openssh_ext.py +%{python3_sitearch}/samba/gp/vgp_startup_scripts_ext.py +%{python3_sitearch}/samba/gp/vgp_sudoers_ext.py +%{python3_sitearch}/samba/gp/vgp_symlink_ext.py +%{python3_sitearch}/samba/gpo.*.so %dir %{python3_sitearch}/samba/gp_parse %{python3_sitearch}/samba/gp_parse/__init__.py %dir %{python3_sitearch}/samba/gp_parse/__pycache__ @@ -1928,9 +1949,11 @@ fi %{python3_sitearch}/samba/samba3/mdscli.*.so %{python3_sitearch}/samba/samba3/param.*.so %{python3_sitearch}/samba/samba3/passdb.*.so +%{python3_sitearch}/samba/samba3/smbconf.*.so %{python3_sitearch}/samba/samba3/smbd.*.so %{python3_sitearch}/samba/sd_utils.py %{python3_sitearch}/samba/sites.py +%{python3_sitearch}/samba/smbconf.*.so %{python3_sitearch}/samba/subnets.py %dir %{python3_sitearch}/samba/subunit %{python3_sitearch}/samba/subunit/__init__.py @@ -1942,14 +1965,6 @@ fi %{python3_sitearch}/samba/trust_utils.py %{python3_sitearch}/samba/upgrade.py %{python3_sitearch}/samba/upgradehelpers.py -%{python3_sitearch}/samba/vgp_access_ext.py -%{python3_sitearch}/samba/vgp_files_ext.py -%{python3_sitearch}/samba/vgp_issue_ext.py -%{python3_sitearch}/samba/vgp_motd_ext.py -%{python3_sitearch}/samba/vgp_openssh_ext.py -%{python3_sitearch}/samba/vgp_startup_scripts_ext.py -%{python3_sitearch}/samba/vgp_sudoers_ext.py -%{python3_sitearch}/samba/vgp_symlink_ext.py %{python3_sitearch}/samba/werror.*.so %{python3_sitearch}/samba/xattr.py %{python3_sitearch}/samba/xattr_native.*.so @@ -2079,6 +2094,7 @@ fi %{python3_sitearch}/samba/tests/__pycache__/ldap_spn.*.pyc %{python3_sitearch}/samba/tests/__pycache__/ldap_upn_sam_account.*.pyc %{python3_sitearch}/samba/tests/__pycache__/loadparm.*.pyc +%{python3_sitearch}/samba/tests/__pycache__/logfiles.*.pyc %{python3_sitearch}/samba/tests/__pycache__/libsmb.*.pyc %{python3_sitearch}/samba/tests/__pycache__/lsa_string.*.pyc %{python3_sitearch}/samba/tests/__pycache__/messaging.*.pyc @@ -2096,6 +2112,7 @@ fi %{python3_sitearch}/samba/tests/__pycache__/ntlm_auth_krb5.*.pyc %{python3_sitearch}/samba/tests/__pycache__/pam_winbind.*.pyc %{python3_sitearch}/samba/tests/__pycache__/pam_winbind_chauthtok.*.pyc +%{python3_sitearch}/samba/tests/__pycache__/pam_winbind_setcred.*.pyc %{python3_sitearch}/samba/tests/__pycache__/pam_winbind_warn_pwd_expire.*.pyc %{python3_sitearch}/samba/tests/__pycache__/param.*.pyc %{python3_sitearch}/samba/tests/__pycache__/password_hash.*.pyc @@ -2126,11 +2143,14 @@ fi %{python3_sitearch}/samba/tests/__pycache__/sddl.*.pyc %{python3_sitearch}/samba/tests/__pycache__/security.*.pyc %{python3_sitearch}/samba/tests/__pycache__/segfault.*.pyc +%{python3_sitearch}/samba/tests/__pycache__/sid_strings.*.pyc %{python3_sitearch}/samba/tests/__pycache__/smb.*.pyc +%{python3_sitearch}/samba/tests/__pycache__/smbconf.*.pyc %{python3_sitearch}/samba/tests/__pycache__/smb-notify.*.pyc %{python3_sitearch}/samba/tests/__pycache__/smbd_base.*.pyc %{python3_sitearch}/samba/tests/__pycache__/smbd_fuzztest.*.pyc %{python3_sitearch}/samba/tests/__pycache__/source.*.pyc +%{python3_sitearch}/samba/tests/__pycache__/source_chars.*.pyc %{python3_sitearch}/samba/tests/__pycache__/strings.*.pyc %{python3_sitearch}/samba/tests/__pycache__/subunitrun.*.pyc %{python3_sitearch}/samba/tests/__pycache__/tdb_util.*.pyc @@ -2160,6 +2180,7 @@ fi %{python3_sitearch}/samba/tests/blackbox/__pycache__/downgradedatabase.*.pyc %{python3_sitearch}/samba/tests/blackbox/__pycache__/mdsearch.*.pyc %{python3_sitearch}/samba/tests/blackbox/__pycache__/ndrdump.*.pyc +%{python3_sitearch}/samba/tests/blackbox/__pycache__/netads_dns.*.pyc %{python3_sitearch}/samba/tests/blackbox/__pycache__/netads_json.*.pyc %{python3_sitearch}/samba/tests/blackbox/__pycache__/samba_dnsupdate.*.pyc %{python3_sitearch}/samba/tests/blackbox/__pycache__/smbcacls.*.pyc @@ -2176,6 +2197,7 @@ fi %{python3_sitearch}/samba/tests/blackbox/downgradedatabase.py %{python3_sitearch}/samba/tests/blackbox/mdsearch.py %{python3_sitearch}/samba/tests/blackbox/ndrdump.py +%{python3_sitearch}/samba/tests/blackbox/netads_dns.py %{python3_sitearch}/samba/tests/blackbox/netads_json.py %{python3_sitearch}/samba/tests/blackbox/samba_dnsupdate.py %{python3_sitearch}/samba/tests/blackbox/smbcacls.py @@ -2300,11 +2322,15 @@ fi %{python3_sitearch}/samba/tests/krb5/__pycache__/kdc_tests.*.pyc %{python3_sitearch}/samba/tests/krb5/__pycache__/kdc_tgs_tests.*.pyc %{python3_sitearch}/samba/tests/krb5/__pycache__/kpasswd_tests.*.pyc +%{python3_sitearch}/samba/tests/krb5/__pycache__/lockout_tests.*.pyc %{python3_sitearch}/samba/tests/krb5/__pycache__/ms_kile_client_principal_lookup_tests.*.pyc +%{python3_sitearch}/samba/tests/krb5/__pycache__/nt_hash_tests.*.pyc +%{python3_sitearch}/samba/tests/krb5/__pycache__/pac_align_tests.*.pyc +%{python3_sitearch}/samba/tests/krb5/__pycache__/protected_users_tests.*.pyc %{python3_sitearch}/samba/tests/krb5/__pycache__/raw_testcase.*.pyc %{python3_sitearch}/samba/tests/krb5/__pycache__/rfc4120_constants.*.pyc %{python3_sitearch}/samba/tests/krb5/__pycache__/rfc4120_pyasn1.*.pyc -%{python3_sitearch}/samba/tests/krb5/__pycache__/rodc_tests*.pyc +%{python3_sitearch}/samba/tests/krb5/__pycache__/rodc_tests.*.pyc %{python3_sitearch}/samba/tests/krb5/__pycache__/salt_tests.*.pyc %{python3_sitearch}/samba/tests/krb5/__pycache__/simple_tests.*.pyc %{python3_sitearch}/samba/tests/krb5/__pycache__/spn_tests.*.pyc @@ -2326,7 +2352,11 @@ fi %{python3_sitearch}/samba/tests/krb5/kdc_tests.py %{python3_sitearch}/samba/tests/krb5/kdc_tgs_tests.py %{python3_sitearch}/samba/tests/krb5/kpasswd_tests.py +%{python3_sitearch}/samba/tests/krb5/lockout_tests.py %{python3_sitearch}/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py +%{python3_sitearch}/samba/tests/krb5/nt_hash_tests.py +%{python3_sitearch}/samba/tests/krb5/pac_align_tests.py +%{python3_sitearch}/samba/tests/krb5/protected_users_tests.py %{python3_sitearch}/samba/tests/krb5/raw_testcase.py %{python3_sitearch}/samba/tests/krb5/rfc4120_constants.py %{python3_sitearch}/samba/tests/krb5/rfc4120_pyasn1.py @@ -2349,6 +2379,7 @@ fi %{python3_sitearch}/samba/tests/ldap_upn_sam_account.py %{python3_sitearch}/samba/tests/libsmb.py %{python3_sitearch}/samba/tests/loadparm.py +%{python3_sitearch}/samba/tests/logfiles.py %{python3_sitearch}/samba/tests/lsa_string.py %{python3_sitearch}/samba/tests/messaging.py %{python3_sitearch}/samba/tests/ndr.py @@ -2365,6 +2396,7 @@ fi %{python3_sitearch}/samba/tests/ntlm_auth_krb5.py %{python3_sitearch}/samba/tests/pam_winbind.py %{python3_sitearch}/samba/tests/pam_winbind_chauthtok.py +%{python3_sitearch}/samba/tests/pam_winbind_setcred.py %{python3_sitearch}/samba/tests/pam_winbind_warn_pwd_expire.py %{python3_sitearch}/samba/tests/param.py %{python3_sitearch}/samba/tests/password_hash.py @@ -2409,6 +2441,7 @@ fi %{python3_sitearch}/samba/tests/samba_tool/__pycache__/help.*.pyc %{python3_sitearch}/samba/tests/samba_tool/__pycache__/join.*.pyc %{python3_sitearch}/samba/tests/samba_tool/__pycache__/join_lmdb_size.*.pyc +%{python3_sitearch}/samba/tests/samba_tool/__pycache__/join_member.*.pyc %{python3_sitearch}/samba/tests/samba_tool/__pycache__/ntacl.*.pyc %{python3_sitearch}/samba/tests/samba_tool/__pycache__/ou.*.pyc %{python3_sitearch}/samba/tests/samba_tool/__pycache__/passwordsettings.*.pyc @@ -2445,6 +2478,7 @@ fi %{python3_sitearch}/samba/tests/samba_tool/help.py %{python3_sitearch}/samba/tests/samba_tool/join.py %{python3_sitearch}/samba/tests/samba_tool/join_lmdb_size.py +%{python3_sitearch}/samba/tests/samba_tool/join_member.py %{python3_sitearch}/samba/tests/samba_tool/ntacl.py %{python3_sitearch}/samba/tests/samba_tool/ou.py %{python3_sitearch}/samba/tests/samba_tool/passwordsettings.py @@ -2471,11 +2505,14 @@ fi %{python3_sitearch}/samba/tests/sddl.py %{python3_sitearch}/samba/tests/security.py %{python3_sitearch}/samba/tests/segfault.py +%{python3_sitearch}/samba/tests/sid_strings.py %{python3_sitearch}/samba/tests/smb.py +%{python3_sitearch}/samba/tests/smbconf.py %{python3_sitearch}/samba/tests/smb-notify.py %{python3_sitearch}/samba/tests/smbd_base.py %{python3_sitearch}/samba/tests/smbd_fuzztest.py %{python3_sitearch}/samba/tests/source.py +%{python3_sitearch}/samba/tests/source_chars.py %{python3_sitearch}/samba/tests/strings.py %{python3_sitearch}/samba/tests/subunitrun.py %{python3_sitearch}/samba/tests/tdb_util.py @@ -2506,6 +2543,10 @@ fi %{_libdir}/samba/libdsdb-module-samba4.so %endif +%files usershares +%config(noreplace) %{_sysconfdir}/samba/usershares.conf +%attr(1770,root,usershares) %dir /var/lib/samba/usershares + ### WINBIND %files winbind %config(noreplace) /etc/ld.so.conf.d/* @@ -2572,7 +2613,6 @@ fi %config(noreplace) %{_sysconfdir}/ctdb/nfs-checks.d/50.rquotad.check %{_sbindir}/ctdbd -%{_sbindir}/ctdbd_wrapper %{_bindir}/ctdb %{_bindir}/ctdb_diagnostics %{_bindir}/ltdbtool @@ -3428,6 +3468,12 @@ fi %endif %changelog +* Tue Nov 08 2022 xinghe - 4.17.2-1 +- Type:enhancement +- ID:NA +- SUG:NA +- DESC: update to 4.17.2 + * Wed Oct 26 2022 xinghe - 4.15.3-12 - Type:cves - ID:CVE-2022-3437 diff --git a/smb.conf.example b/smb.conf.example index e672ce9e1e6a62f44dc61c5d70c29edd722cece8..4e6b5d4c7cb1be7fe3316594112c750fb0cb8b87 100644 --- a/smb.conf.example +++ b/smb.conf.example @@ -281,7 +281,7 @@ [printers] comment = All Printers - path = /var/spool/samba + path = /var/tmp browseable = no guest ok = no writable = no diff --git a/smb.conf.vendor b/smb.conf.vendor index fe3f80646f12d1e01fe128a0b576211d0529c72d..127382e930e9ccef75df36dd476a6a77b8636c44 100644 --- a/smb.conf.vendor +++ b/smb.conf.vendor @@ -14,6 +14,7 @@ load printers = yes cups options = raw + include = /etc/samba/usershares.conf [homes] comment = Home Directories valid users = %S, %D%w%S diff --git a/usershares.conf.vendor b/usershares.conf.vendor new file mode 100644 index 0000000000000000000000000000000000000000..38a7885c810da0d1e0efadd42e3c301dacb3a800 --- /dev/null +++ b/usershares.conf.vendor @@ -0,0 +1,3 @@ +[global] + usershare max shares = 100 + usershare allow guests = yes