!133 update to 4.17.2

From: @xinghe_1 
Reviewed-by: @seuzw 
Signed-off-by: @seuzw
This commit is contained in:
openeuler-ci-bot 2022-11-09 03:32:46 +00:00 committed by Gitee
commit 065e0df906
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
47 changed files with 159 additions and 28092 deletions

View File

@ -1,815 +0,0 @@
From d277700710dc118f61065ed9e16e08e76820b66a Mon Sep 17 00:00:00 2001
From: Joseph Sutton <josephsutton@catalyst.net.nz>
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 <josephsutton@catalyst.net.nz>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
---
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

View File

@ -1,346 +0,0 @@
From b41691d0e546795bda994d94091b8e0a03ab96d6 Mon Sep 17 00:00:00 2001
From: Joseph Sutton <josephsutton@catalyst.net.nz>
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 <josephsutton@catalyst.net.nz>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
---
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

View File

@ -1,65 +0,0 @@
From e38b75a50f79c1d1ea2d7d4489896ca5aa16d9d9 Mon Sep 17 00:00:00 2001
From: Joseph Sutton <josephsutton@catalyst.net.nz>
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 <josephsutton@catalyst.net.nz>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
---
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

View File

@ -1,140 +0,0 @@
From 49ac07e786df58b914ee85e2db773c0ba8d4e171 Mon Sep 17 00:00:00 2001
From: Joseph Sutton <josephsutton@catalyst.net.nz>
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 <josephsutton@catalyst.net.nz>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
---
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

View File

@ -1,69 +0,0 @@
From 0d888f0c902ebd98cfb82d50ab8b8b3928341ee2 Mon Sep 17 00:00:00 2001
From: Joseph Sutton <josephsutton@catalyst.net.nz>
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 <josephsutton@catalyst.net.nz>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
---
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

View File

@ -1,339 +0,0 @@
From b95431ab2303eb258e37e88d8841f2fb79fc4af5 Mon Sep 17 00:00:00 2001
From: Joseph Sutton <josephsutton@catalyst.net.nz>
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 <josephsutton@catalyst.net.nz>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
---
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

View File

@ -1,67 +0,0 @@
From c2ab1f4696fa3f52918a126d0b37993a07f68bcb Mon Sep 17 00:00:00 2001
From: Joseph Sutton <josephsutton@catalyst.net.nz>
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 <josephsutton@catalyst.net.nz>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
---
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

View File

@ -1,240 +0,0 @@
From f9831259b9f6a49b9e1a7be75198d60374cdef2f Mon Sep 17 00:00:00 2001
From: Joseph Sutton <josephsutton@catalyst.net.nz>
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 <josephsutton@catalyst.net.nz>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
---
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

View File

@ -1,82 +0,0 @@
From d07641fc5a7d2fa323e6d6fe3223da3a6d682405 Mon Sep 17 00:00:00 2001
From: Joseph Sutton <josephsutton@catalyst.net.nz>
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 <josephsutton@catalyst.net.nz>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
---
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

View File

@ -1,52 +0,0 @@
From 02c2a8c7b01d6412393423813b710c88b20fb97f Mon Sep 17 00:00:00 2001
From: Joseph Sutton <josephsutton@catalyst.net.nz>
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 <josephsutton@catalyst.net.nz>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
---
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

View File

@ -1,71 +0,0 @@
From f545142380151a626848dbae9ee746167f3299fa Mon Sep 17 00:00:00 2001
From: Joseph Sutton <josephsutton@catalyst.net.nz>
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 <josephsutton@catalyst.net.nz>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
---
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

View File

@ -1,56 +0,0 @@
From 7638abd38a13f9d2b5c769eb12c70eacf49b3806 Mon Sep 17 00:00:00 2001
From: Joseph Sutton <josephsutton@catalyst.net.nz>
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 <josephsutton@catalyst.net.nz>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
---
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

View File

@ -1,217 +0,0 @@
From e1c52ac05a9ff505d2e5eac2f1ece4e95844ee71 Mon Sep 17 00:00:00 2001
From: Joseph Sutton <josephsutton@catalyst.net.nz>
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 <josephsutton@catalyst.net.nz>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
---
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

View File

@ -1,159 +0,0 @@
From 6b76bc7339addb14884c2d6ddb20c559c7fbe07d Mon Sep 17 00:00:00 2001
From: Joseph Sutton <josephsutton@catalyst.net.nz>
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 <josephsutton@catalyst.net.nz>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
---
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

View File

@ -1,70 +0,0 @@
From 15c86028a861139cee4560fe093c965ffc30eb13 Mon Sep 17 00:00:00 2001
From: Joseph Sutton <josephsutton@catalyst.net.nz>
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 <josephsutton@catalyst.net.nz>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Autobuild-User(master): Douglas Bagnall <dbagnall@samba.org>
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

View File

@ -1,31 +0,0 @@
From eee61be9b5867b63b73b0b1fea03f44a4e1235b7 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow@samba.org>
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 <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
---
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

View File

@ -1,52 +0,0 @@
From d392b10c55bbcedda01fdd87fe6035fa3a6986b3 Mon Sep 17 00:00:00 2001
From: Joseph Sutton <josephsutton@catalyst.net.nz>
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 <josephsutton@catalyst.net.nz>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
---
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

View File

@ -1,94 +0,0 @@
From 9849e7440e30853c61a80ce1f11b7b244ed766fe Mon Sep 17 00:00:00 2001
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
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 <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Andreas Schneider <asn@samba.org>
---
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 <gnutls/gnutls.h>
@@ -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

View File

@ -1,39 +0,0 @@
From fe1204d9da2c6f761c4dc4421f67057b10eaf430 Mon Sep 17 00:00:00 2001
From: Joseph Sutton <josephsutton@catalyst.net.nz>
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 <josephsutton@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
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

View File

@ -1,38 +0,0 @@
From 22b4091924977f6437b59627f33a8e6f02b41011 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow@samba.org>
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 <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
---
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

View File

@ -1,41 +0,0 @@
From 7a516257ea310fa045bdf14e677eaa97f2a83c33 Mon Sep 17 00:00:00 2001
From: Joseph Sutton <josephsutton@catalyst.net.nz>
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 <josephsutton@catalyst.net.nz>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
---
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

View File

@ -1,34 +0,0 @@
From ffa84f2e5d335626b5f7311af8d2a7056b3e5c6f Mon Sep 17 00:00:00 2001
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
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 <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Andreas Schneider <asn@samba.org>
Autobuild-User(master): Andreas Schneider <asn@cryptomilk.org>
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

View File

@ -1,58 +0,0 @@
From a49a3ac8e082921c2793a073b5991c4693f167ab Mon Sep 17 00:00:00 2001
From: Joseph Sutton <josephsutton@catalyst.net.nz>
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 <josephsutton@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
[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

View File

@ -1,67 +0,0 @@
From b4c0b4620f12055207adb0519c8d91c3021f354a Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow@samba.org>
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 <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
---
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

File diff suppressed because it is too large Load Diff

View File

@ -1,451 +0,0 @@
From 4533a7b4319cd95815d2dcd5fe5075539fb850e5 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow@samba.org>
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 <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
[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 <slow@samba.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "adouble.c"
+#include <cmocka.h>
+
+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

View File

@ -1,81 +0,0 @@
From c22914f845b3eba1c9ad444333f3d044352b7e2c Mon Sep 17 00:00:00 2001
From: Joseph Sutton <josephsutton@catalyst.net.nz>
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 <josephsutton@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
[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

View File

@ -1,169 +0,0 @@
From 0e2b3fb982d1f53d111e10d9197ed2ec2e13712c Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow@samba.org>
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 <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
---
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

View File

@ -1,35 +0,0 @@
From 5f6dbf2ab29bcd30c701cab3daecf5a6a53a44cd Mon Sep 17 00:00:00 2001
From: Joseph Sutton <josephsutton@catalyst.net.nz>
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 <josephsutton@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
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

View File

@ -1,51 +0,0 @@
From 9f6f1e01aca4f00a5d23127803c81939253e0577 Mon Sep 17 00:00:00 2001
From: Joseph Sutton <josephsutton@catalyst.net.nz>
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 <josephsutton@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
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

View File

@ -1,57 +0,0 @@
From 5a62eb5734d50fe556934aefa3bac5698372f00e Mon Sep 17 00:00:00 2001
From: Joseph Sutton <josephsutton@catalyst.net.nz>
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 <josephsutton@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
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

View File

@ -1,50 +0,0 @@
From ebac8bf0478e19849f83af6d44b73d7ab3afd25b Mon Sep 17 00:00:00 2001
From: Joseph Sutton <josephsutton@catalyst.net.nz>
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 <josephsutton@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
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

View File

@ -1,79 +0,0 @@
From 1aca34515515f2cb00fbf5ad8b9212b319f01836 Mon Sep 17 00:00:00 2001
From: Joseph Sutton <josephsutton@catalyst.net.nz>
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 <josephsutton@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
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

View File

@ -1,48 +0,0 @@
From 77e0f2febaaf4d6e5e42f8e73a1f8f3c0e4a2985 Mon Sep 17 00:00:00 2001
From: Joseph Sutton <josephsutton@catalyst.net.nz>
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 <josephsutton@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
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

View File

@ -1,58 +0,0 @@
From e9db03736007721e37c4fba847ce4aa0c4520924 Mon Sep 17 00:00:00 2001
From: Joseph Sutton <josephsutton@catalyst.net.nz>
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 <josephsutton@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,216 +0,0 @@
From d6aef6838a674ab95ff9172f4ac67707667f9e00 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra@samba.org>
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 <jra@samba.org>
Reviewed-by: David Disseldorp <ddiss@samba.org>
---
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 <jra@samba.org>
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 <jra@samba.org>
Reviewed-by: David Disseldorp <ddiss@samba.org>
---
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

View File

@ -1,163 +0,0 @@
From c231d424b89ba718262ed376431a982baaeef33f Mon Sep 17 00:00:00 2001
From: Joseph Sutton <josephsutton@catalyst.net.nz>
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 <josephsutton@catalyst.net.nz>
---
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 <josephsutton@catalyst.net.nz>
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 <josephsutton@catalyst.net.nz>
---
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 <josephsutton@catalyst.net.nz>
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 <josephsutton@catalyst.net.nz>
---
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 <josephsutton@catalyst.net.nz>
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 <josephsutton@catalyst.net.nz>
---
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

File diff suppressed because it is too large Load Diff

View File

@ -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-----

16
samba-4.17.2.tar.asc Normal file
View File

@ -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-----

View File

@ -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 <xinghe2@h-partners.com> - 4.17.2-1
- Type:enhancement
- ID:NA
- SUG:NA
- DESC: update to 4.17.2
* Wed Oct 26 2022 xinghe <xinghe2@h-partners.com> - 4.15.3-12
- Type:cves
- ID:CVE-2022-3437

View File

@ -281,7 +281,7 @@
[printers]
comment = All Printers
path = /var/spool/samba
path = /var/tmp
browseable = no
guest ok = no
writable = no

View File

@ -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

3
usershares.conf.vendor Normal file
View File

@ -0,0 +1,3 @@
[global]
usershare max shares = 100
usershare allow guests = yes