git: dfaa714fc960 - main - net/samba413: Backport security fix from 4.14.14

From: Yasuhiro Kimura <yasu_at_FreeBSD.org>
Date: Tue, 11 Oct 2022 05:33:24 UTC
The branch main has been updated by yasu:

URL: https://cgit.FreeBSD.org/ports/commit/?id=dfaa714fc960fb4d0a5bc6983d3882a974857f12

commit dfaa714fc960fb4d0a5bc6983d3882a974857f12
Author:     Yasuhiro Kimura <yasu@FreeBSD.org>
AuthorDate: 2022-09-26 23:47:17 +0000
Commit:     Yasuhiro Kimura <yasu@FreeBSD.org>
CommitDate: 2022-10-11 05:32:29 +0000

    net/samba413: Backport security fix from 4.14.14
    
    * Add upstream patch to fix configure error with Python 3.11.
    * Fix plist error when AD_DC option is off and PYTHON3 option is on.
    * Replace BIND911 option with BIND918 as dns/bind911 is removed from
      ports tree and dns/bind918 is added instead.
    
    PR:             266641
    Approved by:    maintainer timeout
    MFH:            2022Q4
    Security:       f9140ad4-4920-11ed-a07e-080027f5fec9
---
 net/samba413/Makefile                  |     8 +-
 net/samba413/files/patch-samba-4.14.14 | 13366 +++++++++++++++++++++++++++++++
 net/samba413/files/patch-waf-2.0.20    |  1663 ++++
 net/samba413/files/patch-waf-2.0.21    |   703 ++
 net/samba413/files/patch-waf-2.0.22    |   596 ++
 net/samba413/files/patch-waf-2.0.23    |   877 ++
 net/samba413/files/patch-waf-2.0.24    |   164 +
 net/samba413/pkg-plist.ad_dc           |     2 -
 net/samba413/pkg-plist.python          |     3 +
 9 files changed, 17376 insertions(+), 6 deletions(-)

diff --git a/net/samba413/Makefile b/net/samba413/Makefile
index f1dea1c15f3d..ccbb438ecb6a 100644
--- a/net/samba413/Makefile
+++ b/net/samba413/Makefile
@@ -1,6 +1,6 @@
 PORTNAME=			${SAMBA4_BASENAME}413
 PORTVERSION=			${SAMBA4_VERSION}
-PORTREVISION=			1
+PORTREVISION=			2
 CATEGORIES?=			net
 MASTER_SITES=			SAMBA/samba/stable SAMBA/samba/rc
 DISTNAME=			${SAMBA4_DISTNAME}
@@ -96,7 +96,7 @@ OPTIONS_SINGLE_GSSAPI=		GSSAPI_BUILTIN GSSAPI_MIT
 OPTIONS_SINGLE_ZEROCONF=	ZEROCONF_NONE AVAHI MDNSRESPONDER
 
 OPTIONS_RADIO=			DNS
-OPTIONS_RADIO_DNS=		NSUPDATE BIND911 BIND916
+OPTIONS_RADIO_DNS=		NSUPDATE BIND916 BIND918
 # Make those default options
 OPTIONS_DEFAULT=		AD_DC ADS DOCS FAM LDAP \
 				PROFILE PYTHON3 QUOTAS SYSLOG UTMP \
@@ -129,8 +129,8 @@ ZEROCONF_DESC=			Zero configuration networking
 ZEROCONF_NONE_DESC=		Zeroconf support is absent
 
 DNS_DESC=			DNS frontend
-BIND911_DESC=			Use Bind 9.11 as AD DC DNS server frontend
 BIND916_DESC=			Use Bind 9.16 as AD DC DNS server frontend
+BIND918_DESC=			Use Bind 9.18 as AD DC DNS server frontend
 NSUPDATE_DESC=			Use samba NSUPDATE utility for AD DC
 ##############################################################################
 # XXX: Unconditional dependencies which can't be switched off(if present in
@@ -299,8 +299,8 @@ MDNSRESPONDER_CONFIGURE_ENABLE=	dnssd
 MDNSRESPONDER_LIB_DEPENDS=	libdns_sd.so:net/mDNSResponder
 MDNSRESPONDER_VARS=		SAMBA4_SERVICES+=mdnsd
 ##############################################################################
-BIND911_RUN_DEPENDS=		bind911>=9.11.0.0:dns/bind911
 BIND916_RUN_DEPENDS=		bind916>=9.16.0.0:dns/bind916
+BIND918_RUN_DEPENDS=		bind918>=9.18.0.0:dns/bind918
 NSUPDATE_RUN_DEPENDS=		samba-nsupdate:dns/samba-nsupdate
 ##############################################################################
 MEMORY_DEBUG_IMPLIES=		DEBUG
diff --git a/net/samba413/files/patch-samba-4.14.14 b/net/samba413/files/patch-samba-4.14.14
new file mode 100644
index 000000000000..4127ab67308e
--- /dev/null
+++ b/net/samba413/files/patch-samba-4.14.14
@@ -0,0 +1,13366 @@
+From 5d958156c7e5d6c1da61d18fe4fd105b22639b56 Mon Sep 17 00:00:00 2001
+From: Joseph Sutton <josephsutton@catalyst.net.nz>
+Date: Tue, 14 Jun 2022 21:09:53 +1200
+Subject: [PATCH 01/99] CVE-2022-32746 s4/dsdb/objectclass_attrs: Fix typo
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=15009
+
+Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
+---
+ source4/dsdb/samdb/ldb_modules/objectclass_attrs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git source4/dsdb/samdb/ldb_modules/objectclass_attrs.c source4/dsdb/samdb/ldb_modules/objectclass_attrs.c
+index 6ab46a729a2..2a77353cdfc 100644
+--- source4/dsdb/samdb/ldb_modules/objectclass_attrs.c
++++ source4/dsdb/samdb/ldb_modules/objectclass_attrs.c
+@@ -263,7 +263,7 @@ static int attr_handler(struct oc_context *ac)
+ 												LDB_CONTROL_AS_SYSTEM_OID);
+ 					if (!dsdb_module_am_system(ac->module) && !as_system) {
+ 						ldb_asprintf_errstring(ldb,
+-								       "objectclass_attrs: attribute '%s' on entry '%s' must can only be modified as system",
++								       "objectclass_attrs: attribute '%s' on entry '%s' can only be modified as system",
+ 								       msg->elements[i].name,
+ 								       ldb_dn_get_linearized(msg->dn));
+ 						return LDB_ERR_CONSTRAINT_VIOLATION;
+-- 
+2.25.1
+
+
+From 51cbeff886fe01db463448f8655a43d10040dc8b Mon Sep 17 00:00:00 2001
+From: Joseph Sutton <josephsutton@catalyst.net.nz>
+Date: Tue, 21 Jun 2022 15:37:15 +1200
+Subject: [PATCH 02/99] CVE-2022-32746 s4:dsdb:tests: Add test for deleting a
+ disallowed SPN
+
+If an account has an SPN that requires Write Property to set, we should
+still be able to delete it with just Validated Write.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=15009
+
+Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
+---
+ selftest/knownfail.d/acl-spn-delete |  1 +
+ source4/dsdb/tests/python/acl.py    | 26 ++++++++++++++++++++++++++
+ 2 files changed, 27 insertions(+)
+ create mode 100644 selftest/knownfail.d/acl-spn-delete
+
+diff --git selftest/knownfail.d/acl-spn-delete selftest/knownfail.d/acl-spn-delete
+new file mode 100644
+index 00000000000..32018413c49
+--- /dev/null
++++ selftest/knownfail.d/acl-spn-delete
+@@ -0,0 +1 @@
++^samba4.ldap.acl.python.*__main__.AclSPNTests.test_delete_disallowed_spn\(
+diff --git source4/dsdb/tests/python/acl.py source4/dsdb/tests/python/acl.py
+index df0fe12bf29..d90d3b3923f 100755
+--- source4/dsdb/tests/python/acl.py
++++ source4/dsdb/tests/python/acl.py
+@@ -2286,6 +2286,32 @@ class AclSPNTests(AclTests):
+         else:
+             self.fail(f'able to add disallowed SPN {not_allowed_spn}')
+ 
++    def test_delete_disallowed_spn(self):
++        # Grant Validated-SPN property.
++        mod = f'(OA;;SW;{security.GUID_DRS_VALIDATE_SPN};;{self.user_sid1})'
++        self.sd_utils.dacl_add_ace(self.computerdn, mod)
++
++        spn_base = f'HOST/{self.computername}'
++
++        not_allowed_spn = f'{spn_base}/{self.dcctx.get_domain_name()}'
++
++        # Add a disallowed SPN as admin.
++        msg = Message(Dn(self.ldb_admin, self.computerdn))
++        msg['servicePrincipalName'] = MessageElement(not_allowed_spn,
++                                                     FLAG_MOD_ADD,
++                                                     'servicePrincipalName')
++        self.ldb_admin.modify(msg)
++
++        # Ensure we are able to delete a disallowed SPN.
++        msg = Message(Dn(self.ldb_user1, self.computerdn))
++        msg['servicePrincipalName'] = MessageElement(not_allowed_spn,
++                                                     FLAG_MOD_DELETE,
++                                                     'servicePrincipalName')
++        try:
++            self.ldb_user1.modify(msg)
++        except LdbError:
++            self.fail(f'unable to delete disallowed SPN {not_allowed_spn}')
++
+ 
+ # tests SEC_ADS_LIST vs. SEC_ADS_LIST_OBJECT
+ @DynamicTestCase
+-- 
+2.25.1
+
+
+From a68553792a8512a2d266bbb86f064f78b5482a65 Mon Sep 17 00:00:00 2001
+From: Joseph Sutton <josephsutton@catalyst.net.nz>
+Date: Tue, 21 Jun 2022 14:41:02 +1200
+Subject: [PATCH 03/99] CVE-2022-32746 s4/dsdb/partition: Fix LDB flags
+ comparison
+
+LDB_FLAG_MOD_* values are not actually flags, and the previous
+comparison was equivalent to
+
+(req_msg->elements[el_idx].flags & LDB_FLAG_MOD_MASK) != 0
+
+which is true whenever any of the LDB_FLAG_MOD_* values are set. Correct
+the expression to what it was probably intended to be.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=15009
+
+Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
+---
+ source4/dsdb/samdb/ldb_modules/partition.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git source4/dsdb/samdb/ldb_modules/partition.c source4/dsdb/samdb/ldb_modules/partition.c
+index 2544a106d13..2d90ca5d1b3 100644
+--- source4/dsdb/samdb/ldb_modules/partition.c
++++ source4/dsdb/samdb/ldb_modules/partition.c
+@@ -493,8 +493,8 @@ static int partition_copy_all_callback_action(
+ 			 * them here too
+ 			 */
+ 			for (el_idx=0; el_idx < req_msg->num_elements; el_idx++) {
+-				if (req_msg->elements[el_idx].flags & LDB_FLAG_MOD_DELETE
+-				    || ((req_msg->elements[el_idx].flags & LDB_FLAG_MOD_REPLACE) &&
++				if (LDB_FLAG_MOD_TYPE(req_msg->elements[el_idx].flags) == LDB_FLAG_MOD_DELETE
++				    || ((LDB_FLAG_MOD_TYPE(req_msg->elements[el_idx].flags) == LDB_FLAG_MOD_REPLACE) &&
+ 					req_msg->elements[el_idx].num_values == 0)) {
+ 					if (ldb_msg_find_element(modify_msg,
+ 								 req_msg->elements[el_idx].name) != NULL) {
+-- 
+2.25.1
+
+
+From 582ac171364f0c28f54eaf4f21b5bfa7569b5233 Mon Sep 17 00:00:00 2001
+From: Joseph Sutton <josephsutton@catalyst.net.nz>
+Date: Tue, 21 Jun 2022 14:49:51 +1200
+Subject: [PATCH 04/99] CVE-2022-32746 s4:torture: Fix LDB flags comparison
+
+LDB_FLAG_MOD_* values are not actually flags, and the previous
+comparison was equivalent to
+
+(el->flags & LDB_FLAG_MOD_MASK) == 0
+
+which is only true if none of the LDB_FLAG_MOD_* values are set. Correct
+the expression to what it was probably intended to be.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=15009
+
+Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
+---
+ source4/torture/drs/rpc/dssync.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git source4/torture/drs/rpc/dssync.c source4/torture/drs/rpc/dssync.c
+index cde9f78692b..ff7ce2d9074 100644
+--- source4/torture/drs/rpc/dssync.c
++++ source4/torture/drs/rpc/dssync.c
+@@ -527,7 +527,9 @@ static bool test_analyse_objects(struct torture_context *tctx,
+ 				el = &new_msg->elements[idx];
+ 				a = dsdb_attribute_by_lDAPDisplayName(ldap_schema,
+ 				                                      el->name);
+-				if (!(el->flags & (LDB_FLAG_MOD_ADD|LDB_FLAG_MOD_REPLACE))) {
++				if (LDB_FLAG_MOD_TYPE(el->flags) != LDB_FLAG_MOD_ADD &&
++				    LDB_FLAG_MOD_TYPE(el->flags) != LDB_FLAG_MOD_REPLACE)
++				{
+ 					/* DRS only value */
+ 					is_warning = false;
+ 				} else if (a->linkID & 1) {
+-- 
+2.25.1
+
+
+From 0526d27e9eddd9c2a54434cf0dcdb136a6c659e4 Mon Sep 17 00:00:00 2001
+From: Joseph Sutton <josephsutton@catalyst.net.nz>
+Date: Tue, 21 Jun 2022 15:22:47 +1200
+Subject: [PATCH 05/99] CVE-2022-32746 s4/dsdb/acl: Fix LDB flags comparison
+
+LDB_FLAG_MOD_* values are not actually flags, and the previous
+comparison was equivalent to
+
+(el->flags & LDB_FLAG_MOD_MASK) == 0
+
+which is only true if none of the LDB_FLAG_MOD_* values are set, so we
+would not successfully return if the element was a DELETE. Correct the
+expression to what it was intended to be.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=15009
+
+Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
+---
+ selftest/knownfail.d/acl-spn-delete  | 1 -
+ source4/dsdb/samdb/ldb_modules/acl.c | 5 +++--
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+ delete mode 100644 selftest/knownfail.d/acl-spn-delete
+
+diff --git selftest/knownfail.d/acl-spn-delete selftest/knownfail.d/acl-spn-delete
+deleted file mode 100644
+index 32018413c49..00000000000
+--- selftest/knownfail.d/acl-spn-delete
++++ /dev/null
+@@ -1 +0,0 @@
+-^samba4.ldap.acl.python.*__main__.AclSPNTests.test_delete_disallowed_spn\(
+diff --git source4/dsdb/samdb/ldb_modules/acl.c source4/dsdb/samdb/ldb_modules/acl.c
+index 21e83276bfd..8016a2d4bd0 100644
+--- source4/dsdb/samdb/ldb_modules/acl.c
++++ source4/dsdb/samdb/ldb_modules/acl.c
+@@ -734,8 +734,9 @@ static int acl_check_spn(TALLOC_CTX *mem_ctx,
+ 		 * If not add or replace (eg delete),
+ 		 * return success
+ 		 */
+-		if ((el->flags
+-		     & (LDB_FLAG_MOD_ADD|LDB_FLAG_MOD_REPLACE)) == 0) {
++		if (LDB_FLAG_MOD_TYPE(el->flags) != LDB_FLAG_MOD_ADD &&
++		    LDB_FLAG_MOD_TYPE(el->flags) != LDB_FLAG_MOD_REPLACE)
++		{
+ 			talloc_free(tmp_ctx);
+ 			return LDB_SUCCESS;
+ 		}
+-- 
+2.25.1
+
+
+From 2869b5aa3148869edf0d079266542aef6e64608e Mon Sep 17 00:00:00 2001
+From: Joseph Sutton <josephsutton@catalyst.net.nz>
+Date: Wed, 16 Feb 2022 12:43:52 +1300
+Subject: [PATCH 06/99] CVE-2022-32746 ldb:rdn_name: Use LDB_FLAG_MOD_TYPE()
+ for flags equality check
+
+Now unrelated flags will no longer affect the result.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=15009
+
+Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
+---
+ lib/ldb/modules/rdn_name.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git lib/ldb/modules/rdn_name.c lib/ldb/modules/rdn_name.c
+index e69ad9315ae..25cffe07591 100644
+--- lib/ldb/modules/rdn_name.c
++++ lib/ldb/modules/rdn_name.c
+@@ -545,7 +545,7 @@ static int rdn_name_modify(struct ldb_module *module, struct ldb_request *req)
+ 	if (e != NULL) {
+ 		ldb_asprintf_errstring(ldb, "Modify of 'distinguishedName' on %s not permitted, must use 'rename' operation instead",
+ 				       ldb_dn_get_linearized(req->op.mod.message->dn));
+-		if (e->flags == LDB_FLAG_MOD_REPLACE) {
++		if (LDB_FLAG_MOD_TYPE(e->flags) == LDB_FLAG_MOD_REPLACE) {
+ 			return LDB_ERR_CONSTRAINT_VIOLATION;
+ 		} else {
+ 			return LDB_ERR_UNWILLING_TO_PERFORM;
+-- 
+2.25.1
+
+
+From 535b5a366a2ad054f729e57e282e402cf13b2efc Mon Sep 17 00:00:00 2001
+From: Joseph Sutton <josephsutton@catalyst.net.nz>
+Date: Tue, 14 Jun 2022 19:49:19 +1200
+Subject: [PATCH 07/99] CVE-2022-32746 s4/dsdb/repl_meta_data: Use
+ LDB_FLAG_MOD_TYPE() for flags equality check
+
+Now unrelated flags will no longer affect the result.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=15009
+
+Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
+---
+ source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git source4/dsdb/samdb/ldb_modules/repl_meta_data.c source4/dsdb/samdb/ldb_modules/repl_meta_data.c
+index ab506cec488..29ffda75c87 100644
+--- source4/dsdb/samdb/ldb_modules/repl_meta_data.c
++++ source4/dsdb/samdb/ldb_modules/repl_meta_data.c
+@@ -3525,7 +3525,7 @@ static int replmd_modify(struct ldb_module *module, struct ldb_request *req)
+ 			return ldb_module_operr(module);
+ 		}
+ 
+-		if (req->op.mod.message->elements[0].flags != LDB_FLAG_MOD_REPLACE) {
++		if (LDB_FLAG_MOD_TYPE(req->op.mod.message->elements[0].flags) != LDB_FLAG_MOD_REPLACE) {
+ 			return ldb_module_operr(module);
+ 		}
+ 
+@@ -3558,11 +3558,11 @@ static int replmd_modify(struct ldb_module *module, struct ldb_request *req)
+ 			return ldb_module_operr(module);
+ 		}
+ 
+-		if (req->op.mod.message->elements[0].flags != LDB_FLAG_MOD_DELETE) {
++		if (LDB_FLAG_MOD_TYPE(req->op.mod.message->elements[0].flags) != LDB_FLAG_MOD_DELETE) {
+ 			return ldb_module_operr(module);
+ 		}
+ 
+-		if (req->op.mod.message->elements[1].flags != LDB_FLAG_MOD_ADD) {
++		if (LDB_FLAG_MOD_TYPE(req->op.mod.message->elements[1].flags) != LDB_FLAG_MOD_ADD) {
+ 			return ldb_module_operr(module);
+ 		}
+ 
+@@ -3645,7 +3645,7 @@ static int replmd_modify(struct ldb_module *module, struct ldb_request *req)
+ 			return ldb_module_operr(module);
+ 		}
+ 
+-		if (msg->elements[0].flags != LDB_FLAG_MOD_ADD) {
++		if (LDB_FLAG_MOD_TYPE(msg->elements[0].flags) != LDB_FLAG_MOD_ADD) {
+ 			talloc_free(ac);
+ 			return ldb_module_operr(module);
+ 		}
+-- 
+2.25.1
+
+
+From bedd0b768c3f92645af033399aefd7ee971d9150 Mon Sep 17 00:00:00 2001
+From: Joseph Sutton <josephsutton@catalyst.net.nz>
+Date: Tue, 14 Jun 2022 21:11:33 +1200
+Subject: [PATCH 08/99] CVE-2022-32746 s4/dsdb/tombstone_reanimate: Use
+ LDB_FLAG_MOD_TYPE() for flags equality check
+
+Now unrelated flags will no longer affect the result.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=15009
+
+Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
+---
+ source4/dsdb/samdb/ldb_modules/tombstone_reanimate.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git source4/dsdb/samdb/ldb_modules/tombstone_reanimate.c source4/dsdb/samdb/ldb_modules/tombstone_reanimate.c
+index 64e05195798..5f8911c66be 100644
+--- source4/dsdb/samdb/ldb_modules/tombstone_reanimate.c
++++ source4/dsdb/samdb/ldb_modules/tombstone_reanimate.c
+@@ -104,7 +104,7 @@ static bool is_tombstone_reanimate_request(struct ldb_request *req,
+ 	if (el_dn == NULL) {
+ 		return false;
+ 	}
+-	if (el_dn->flags != LDB_FLAG_MOD_REPLACE) {
++	if (LDB_FLAG_MOD_TYPE(el_dn->flags) != LDB_FLAG_MOD_REPLACE) {
+ 		return false;
+ 	}
+ 	if (el_dn->num_values != 1) {
+@@ -117,7 +117,7 @@ static bool is_tombstone_reanimate_request(struct ldb_request *req,
+ 		return false;
+ 	}
+ 
+-	if (el_deleted->flags != LDB_FLAG_MOD_DELETE) {
++	if (LDB_FLAG_MOD_TYPE(el_deleted->flags) != LDB_FLAG_MOD_DELETE) {
+ 		return false;
+ 	}
+ 
+-- 
+2.25.1
+
+
+From 49dd9042f4ee380fa1dafcebcb54d0e1f0852463 Mon Sep 17 00:00:00 2001
+From: Joseph Sutton <josephsutton@catalyst.net.nz>
+Date: Tue, 14 Jun 2022 21:12:39 +1200
+Subject: [PATCH 09/99] CVE-2022-32746 s4/registry: Use LDB_FLAG_MOD_TYPE() for
+ flags equality check
+
+Now unrelated flags will no longer affect the result.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=15009
+
+Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
+---
+ source4/lib/registry/ldb.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git source4/lib/registry/ldb.c source4/lib/registry/ldb.c
+index e089355975b..db383a560da 100644
+--- source4/lib/registry/ldb.c
++++ source4/lib/registry/ldb.c
+@@ -859,7 +859,7 @@ static WERROR ldb_set_value(struct hive_key *parent,
+ 
+ 	/* Try first a "modify" and if this doesn't work do try an "add" */
+ 	for (i = 0; i < msg->num_elements; i++) {
+-		if (msg->elements[i].flags != LDB_FLAG_MOD_DELETE) {
++		if (LDB_FLAG_MOD_TYPE(msg->elements[i].flags) != LDB_FLAG_MOD_DELETE) {
+ 			msg->elements[i].flags = LDB_FLAG_MOD_REPLACE;
+ 		}
+ 	}
+-- 
+2.25.1
+
+
+From faa61ab3053d077ac9d0aa67e955217e85b660f4 Mon Sep 17 00:00:00 2001
+From: Joseph Sutton <josephsutton@catalyst.net.nz>
+Date: Mon, 21 Feb 2022 16:10:32 +1300
+Subject: [PATCH 10/99] CVE-2022-32746 ldb: Add flag to mark message element
+ values as shared
+
+When making a shallow copy of an ldb message, mark the message elements
+of the copy as sharing their values with the message elements in the
+original message.
+
+This flag value will be heeded in the next commit.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=15009
+
+Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
+---
+ lib/ldb/common/ldb_msg.c     | 43 +++++++++++++++++++++++++++++++-----
+ lib/ldb/include/ldb_module.h |  6 +++++
+ 2 files changed, 43 insertions(+), 6 deletions(-)
+
+diff --git lib/ldb/common/ldb_msg.c lib/ldb/common/ldb_msg.c
+index 57dfc5a04c2..2a9ce384bb9 100644
+--- lib/ldb/common/ldb_msg.c
++++ lib/ldb/common/ldb_msg.c
+@@ -833,11 +833,7 @@ void ldb_msg_sort_elements(struct ldb_message *msg)
+ 		       ldb_msg_element_compare_name);
+ }
+ 
+-/*
+-  shallow copy a message - copying only the elements array so that the caller
+-  can safely add new elements without changing the message
+-*/
+-struct ldb_message *ldb_msg_copy_shallow(TALLOC_CTX *mem_ctx,
++static struct ldb_message *ldb_msg_copy_shallow_impl(TALLOC_CTX *mem_ctx,
+ 					 const struct ldb_message *msg)
+ {
+ 	struct ldb_message *msg2;
+@@ -863,6 +859,35 @@ failed:
+ 	return NULL;
+ }
+ 
++/*
++  shallow copy a message - copying only the elements array so that the caller
++  can safely add new elements without changing the message
++*/
++struct ldb_message *ldb_msg_copy_shallow(TALLOC_CTX *mem_ctx,
++					 const struct ldb_message *msg)
++{
++	struct ldb_message *msg2;
++	unsigned int i;
++
++	msg2 = ldb_msg_copy_shallow_impl(mem_ctx, msg);
++	if (msg2 == NULL) {
++		return NULL;
++	}
++
++	for (i = 0; i < msg2->num_elements; ++i) {
++		/*
++		 * Mark this message's elements as sharing their values with the
++		 * original message, so that we don't inadvertently modify or
++		 * free them. We don't mark the original message element as
++		 * shared, so the original message element should not be
++		 * modified or freed while the shallow copy lives.
++		 */
++		struct ldb_message_element *el = &msg2->elements[i];
++		el->flags |= LDB_FLAG_INTERNAL_SHARED_VALUES;
++	}
++
++        return msg2;
++}
+ 
+ /*
+   copy a message, allocating new memory for all parts
+@@ -873,7 +898,7 @@ struct ldb_message *ldb_msg_copy(TALLOC_CTX *mem_ctx,
+ 	struct ldb_message *msg2;
+ 	unsigned int i, j;
+ 
+-	msg2 = ldb_msg_copy_shallow(mem_ctx, msg);
++	msg2 = ldb_msg_copy_shallow_impl(mem_ctx, msg);
+ 	if (msg2 == NULL) return NULL;
+ 
+ 	if (msg2->dn != NULL) {
+@@ -894,6 +919,12 @@ struct ldb_message *ldb_msg_copy(TALLOC_CTX *mem_ctx,
+ 				goto failed;
+ 			}
+ 		}
++
++                /*
++                 * Since we copied this element's values, we can mark them as
++                 * not shared.
++		 */
++		el->flags &= ~LDB_FLAG_INTERNAL_SHARED_VALUES;
+ 	}
+ 
+ 	return msg2;
+diff --git lib/ldb/include/ldb_module.h lib/ldb/include/ldb_module.h
+index 8c1e5ee7936..4c7c85a17f0 100644
+--- lib/ldb/include/ldb_module.h
++++ lib/ldb/include/ldb_module.h
+@@ -96,6 +96,12 @@ struct ldb_module;
+  */
+ #define LDB_FLAG_INTERNAL_FORCE_UNIQUE_INDEX 0x100
+ 
++/*
++ * indicates that this element's values are shared with another element (for
++ * example, in a shallow copy of an ldb_message) and should not be freed
++ */
++#define LDB_FLAG_INTERNAL_SHARED_VALUES 0x200
++
+ /* an extended match rule that always fails to match */
+ #define SAMBA_LDAP_MATCH_ALWAYS_FALSE "1.3.6.1.4.1.7165.4.5.1"
+ 
+-- 
+2.25.1
+
+
+From 4e5fb78c3dcff60aa8fd4b07dad4660bbb30532b Mon Sep 17 00:00:00 2001
+From: Joseph Sutton <josephsutton@catalyst.net.nz>
+Date: Wed, 16 Feb 2022 12:35:13 +1300
+Subject: [PATCH 11/99] CVE-2022-32746 ldb: Ensure shallow copy modifications
+ do not affect original message
+
+Using the newly added ldb flag, we can now detect when a message has
+been shallow-copied so that its elements share their values with the
+original message elements. Then when adding values to the copied
+message, we now make a copy of the shared values array first.
+
+This should prevent a use-after-free that occurred in LDB modules when
+new values were added to a shallow copy of a message by calling
+talloc_realloc() on the original values array, invalidating the 'values'
+pointer in the original message element. The original values pointer can
+later be used in the database audit logging module which logs database
+requests, and potentially cause a crash.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=15009
+
+Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
+---
+ lib/ldb/common/ldb_msg.c   | 52 ++++++++++++++++++++++++++++++++------
+ lib/ldb/include/ldb.h      |  6 +++++
+ source4/dsdb/common/util.c | 20 +++++----------
+ 3 files changed, 56 insertions(+), 22 deletions(-)
+
+diff --git lib/ldb/common/ldb_msg.c lib/ldb/common/ldb_msg.c
+index 2a9ce384bb9..44d3b29e9a7 100644
+--- lib/ldb/common/ldb_msg.c
++++ lib/ldb/common/ldb_msg.c
+@@ -417,6 +417,47 @@ int ldb_msg_add(struct ldb_message *msg,
+ 	return LDB_SUCCESS;
+ }
+ 
++/*
++ * add a value to a message element
++ */
++int ldb_msg_element_add_value(TALLOC_CTX *mem_ctx,
++			      struct ldb_message_element *el,
++			      const struct ldb_val *val)
++{
++	struct ldb_val *vals;
++
++	if (el->flags & LDB_FLAG_INTERNAL_SHARED_VALUES) {
++		/*
++		 * Another message is using this message element's values array,
++		 * so we don't want to make any modifications to the original
++		 * message, or potentially invalidate its own values by calling
++		 * talloc_realloc(). Make a copy instead.
++		 */
++		el->flags &= ~LDB_FLAG_INTERNAL_SHARED_VALUES;
++
++		vals = talloc_array(mem_ctx, struct ldb_val,
++				    el->num_values + 1);
++		if (vals == NULL) {
++			return LDB_ERR_OPERATIONS_ERROR;
++		}
++
++		if (el->values != NULL) {
++			memcpy(vals, el->values, el->num_values * sizeof(struct ldb_val));
++		}
++	} else {
++		vals = talloc_realloc(mem_ctx, el->values, struct ldb_val,
++				      el->num_values + 1);
++		if (vals == NULL) {
++			return LDB_ERR_OPERATIONS_ERROR;
++		}
++	}
++	el->values = vals;
++	el->values[el->num_values] = *val;
++	el->num_values++;
++
++	return LDB_SUCCESS;
++}
++
+ /*
+   add a value to a message
+ */
+@@ -426,7 +467,6 @@ int ldb_msg_add_value(struct ldb_message *msg,
+ 		      struct ldb_message_element **return_el)
+ {
+ 	struct ldb_message_element *el;
+-	struct ldb_val *vals;
+ 	int ret;
+ 
+ 	el = ldb_msg_find_element(msg, attr_name);
+@@ -437,14 +477,10 @@ int ldb_msg_add_value(struct ldb_message *msg,
+ 		}
+ 	}
+ 
+-	vals = talloc_realloc(msg->elements, el->values, struct ldb_val,
+-			      el->num_values+1);
+-	if (!vals) {
+-		return LDB_ERR_OPERATIONS_ERROR;
++	ret = ldb_msg_element_add_value(msg->elements, el, val);
++	if (ret != LDB_SUCCESS) {
++		return ret;
+ 	}
+-	el->values = vals;
+-	el->values[el->num_values] = *val;
+-	el->num_values++;
+ 
+ 	if (return_el) {
+ 		*return_el = el;
+diff --git lib/ldb/include/ldb.h lib/ldb/include/ldb.h
+index bc44157eaf4..129beefeaf5 100644
+--- lib/ldb/include/ldb.h
++++ lib/ldb/include/ldb.h
+@@ -1981,6 +1981,12 @@ int ldb_msg_add_empty(struct ldb_message *msg,
+ 		int flags,
+ 		struct ldb_message_element **return_el);
+ 
++/**
++   add a value to a message element
++*/
++int ldb_msg_element_add_value(TALLOC_CTX *mem_ctx,
++			      struct ldb_message_element *el,
++			      const struct ldb_val *val);
+ /**
+    add a element to a ldb_message
+ */
+diff --git source4/dsdb/common/util.c source4/dsdb/common/util.c
+index 5ce4c0a5e33..577b2a33873 100644
+--- source4/dsdb/common/util.c
++++ source4/dsdb/common/util.c
+@@ -816,7 +816,7 @@ int samdb_msg_add_addval(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx,
+ 			 const char *value)
+ {
+ 	struct ldb_message_element *el;
+-	struct ldb_val val, *vals;
++	struct ldb_val val;
+ 	char *v;
+ 	unsigned int i;
+ 	bool found = false;
+@@ -851,14 +851,10 @@ int samdb_msg_add_addval(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx,
+ 		}
+ 	}
+ 
+-	vals = talloc_realloc(msg->elements, el->values, struct ldb_val,
+-			      el->num_values + 1);
+-	if (vals == NULL) {
++	ret = ldb_msg_element_add_value(msg->elements, el, &val);
++	if (ret != LDB_SUCCESS) {
+ 		return ldb_oom(sam_ldb);
+ 	}
+-	el->values = vals;
+-	el->values[el->num_values] = val;
+-	++(el->num_values);
+ 
+ 	return LDB_SUCCESS;
+ }
+@@ -872,7 +868,7 @@ int samdb_msg_add_delval(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx,
+ 			 const char *value)
+ {
+ 	struct ldb_message_element *el;
+-	struct ldb_val val, *vals;
++	struct ldb_val val;
+ 	char *v;
+ 	unsigned int i;
+ 	bool found = false;
+@@ -907,14 +903,10 @@ int samdb_msg_add_delval(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx,
+ 		}
+ 	}
+ 
+-	vals = talloc_realloc(msg->elements, el->values, struct ldb_val,
+-			      el->num_values + 1);
+-	if (vals == NULL) {
++	ret = ldb_msg_element_add_value(msg->elements, el, &val);
++	if (ret != LDB_SUCCESS) {
+ 		return ldb_oom(sam_ldb);
+ 	}
+-	el->values = vals;
+-	el->values[el->num_values] = val;
+-	++(el->num_values);
+ 
+ 	return LDB_SUCCESS;
+ }
+-- 
+2.25.1
+
+
+From 512a2617b1593bdc16caeeeda4312a581cbb34e9 Mon Sep 17 00:00:00 2001
+From: Joseph Sutton <josephsutton@catalyst.net.nz>
+Date: Wed, 16 Feb 2022 16:30:03 +1300
+Subject: [PATCH 12/99] CVE-2022-32746 ldb: Add functions for appending to an
+ ldb_message
+
+Currently, there are many places where we use ldb_msg_add_empty() to add
+an empty element to a message, and then call ldb_msg_add_value() or
+similar to add values to that element. However, this performs an
+unnecessary search of the message's elements to locate the new element.
+Moreover, if an element with the same attribute name already exists
+earlier in the message, the values will be added to that element,
+instead of to the intended newly added element.
+
+A similar pattern exists where we add values to a message, and then call
+ldb_msg_find_element() to locate that message element and sets its flags
+to (e.g.) LDB_FLAG_MOD_REPLACE. This also performs an unnecessary
+search, and may locate the wrong message element for setting the flags.
+
+To avoid these problems, add functions for appending a value to a
+message, so that a particular value can be added to the end of a message
+in a single operation.
+
+For ADD requests, it is important that no two message elements share the
+same attribute name, otherwise things will break. (Normally,
+ldb_msg_normalize() is called before processing the request to help
+ensure this.) Thus, we must be careful not to append an attribute to an
+ADD message, unless we are sure (e.g. through ldb_msg_find_element())
+that an existing element for that attribute is not present.
+
+These functions will be used in the next commit.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=15009
+
+Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
+---
+ lib/ldb/common/ldb_msg.c | 165 ++++++++++++++++++++++++++++++++++++++-
+ lib/ldb/include/ldb.h    |  24 ++++++
+ 2 files changed, 185 insertions(+), 4 deletions(-)
+
+diff --git lib/ldb/common/ldb_msg.c lib/ldb/common/ldb_msg.c
+index 44d3b29e9a7..9cd7998e21c 100644
+--- lib/ldb/common/ldb_msg.c
++++ lib/ldb/common/ldb_msg.c
+@@ -509,12 +509,15 @@ int ldb_msg_add_steal_value(struct ldb_message *msg,
+ 
+ 
+ /*
+-  add a string element to a message
++  add a string element to a message, specifying flags
+ */
+-int ldb_msg_add_string(struct ldb_message *msg,
+-		       const char *attr_name, const char *str)
++int ldb_msg_add_string_flags(struct ldb_message *msg,
++			     const char *attr_name, const char *str,
++			     int flags)
+ {
+ 	struct ldb_val val;
++	int ret;
++	struct ldb_message_element *el = NULL;
+ 
+ 	val.data = discard_const_p(uint8_t, str);
+ 	val.length = strlen(str);
+@@ -524,7 +527,25 @@ int ldb_msg_add_string(struct ldb_message *msg,
+ 		return LDB_SUCCESS;
+ 	}
+ 
+-	return ldb_msg_add_value(msg, attr_name, &val, NULL);
++	ret = ldb_msg_add_value(msg, attr_name, &val, &el);
++	if (ret != LDB_SUCCESS) {
++		return ret;
++	}
++
++	if (flags != 0) {
++		el->flags = flags;
++	}
++
++	return LDB_SUCCESS;
++}
++
++/*
++  add a string element to a message
++*/
++int ldb_msg_add_string(struct ldb_message *msg,
++		       const char *attr_name, const char *str)
++{
++	return ldb_msg_add_string_flags(msg, attr_name, str, 0);
+ }
+ 
+ /*
+@@ -586,6 +607,142 @@ int ldb_msg_add_fmt(struct ldb_message *msg,
+ 	return ldb_msg_add_steal_value(msg, attr_name, &val);
+ }
+ 
++static int ldb_msg_append_value_impl(struct ldb_message *msg,
++				     const char *attr_name,
++				     const struct ldb_val *val,
++				     int flags,
++				     struct ldb_message_element **return_el)
++{
++	struct ldb_message_element *el = NULL;
++	int ret;
++
++	ret = ldb_msg_add_empty(msg, attr_name, flags, &el);
++	if (ret != LDB_SUCCESS) {
++		return ret;
++	}
++
++	ret = ldb_msg_element_add_value(msg->elements, el, val);
++	if (ret != LDB_SUCCESS) {
++		return ret;
++	}
++
++	if (return_el != NULL) {
++		*return_el = el;
++	}
++
++	return LDB_SUCCESS;
++}
++
++/*
++  append a value to a message
++*/
++int ldb_msg_append_value(struct ldb_message *msg,
++			 const char *attr_name,
++			 const struct ldb_val *val,
++			 int flags)
++{
++	return ldb_msg_append_value_impl(msg, attr_name, val, flags, NULL);
++}
++
++/*
++  append a value to a message, stealing it into the 'right' place
++*/
++int ldb_msg_append_steal_value(struct ldb_message *msg,
++			       const char *attr_name,
++			       struct ldb_val *val,
++			       int flags)
++{
++	int ret;
++	struct ldb_message_element *el = NULL;
++
++	ret = ldb_msg_append_value_impl(msg, attr_name, val, flags, &el);
++	if (ret == LDB_SUCCESS) {
++		talloc_steal(el->values, val->data);
++	}
++	return ret;
++}
++
++/*
++  append a string element to a message, stealing it into the 'right' place
++*/
++int ldb_msg_append_steal_string(struct ldb_message *msg,
++				const char *attr_name, char *str,
++				int flags)
++{
++	struct ldb_val val;
++
++	val.data = (uint8_t *)str;
++	val.length = strlen(str);
++
++	if (val.length == 0) {
++		/* allow empty strings as non-existent attributes */
++		return LDB_SUCCESS;
++	}
++
++	return ldb_msg_append_steal_value(msg, attr_name, &val, flags);
++}
++
++/*
++  append a string element to a message
++*/
++int ldb_msg_append_string(struct ldb_message *msg,
++			  const char *attr_name, const char *str, int flags)
++{
++	struct ldb_val val;
++
++	val.data = discard_const_p(uint8_t, str);
++	val.length = strlen(str);
++
++	if (val.length == 0) {
++		/* allow empty strings as non-existent attributes */
++		return LDB_SUCCESS;
++	}
++
++	return ldb_msg_append_value(msg, attr_name, &val, flags);
++}
++
++/*
++  append a DN element to a message
++  WARNING: this uses the linearized string from the dn, and does not
++  copy the string.
++*/
++int ldb_msg_append_linearized_dn(struct ldb_message *msg, const char *attr_name,
++				 struct ldb_dn *dn, int flags)
++{
++	char *str = ldb_dn_alloc_linearized(msg, dn);
++
++	if (str == NULL) {
++		/* we don't want to have unknown DNs added */
++		return LDB_ERR_OPERATIONS_ERROR;
++	}
++
++	return ldb_msg_append_steal_string(msg, attr_name, str, flags);
++}
++
++/*
++  append a printf formatted element to a message
++*/
++int ldb_msg_append_fmt(struct ldb_message *msg, int flags,
++		       const char *attr_name, const char *fmt, ...)
++{
++	struct ldb_val val;
++	va_list ap;
++	char *str = NULL;
++
++	va_start(ap, fmt);
++	str = talloc_vasprintf(msg, fmt, ap);
++	va_end(ap);
++
++	if (str == NULL) {
++		return LDB_ERR_OPERATIONS_ERROR;
++	}
++
++	val.data   = (uint8_t *)str;
*** 16529 LINES SKIPPED ***