The Samba-Bugzilla – Attachment 17344 Details for
Bug 15096
[SECURITY] ldb memory handling issues
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
patch for these bugs for master under CI
ldb-memory-bug-15096-master-v1.patch (text/plain), 79.19 KB, created by
Andrew Bartlett
on 2022-06-14 04:11:30 UTC
(
hide
)
Description:
patch for these bugs for master under CI
Filename:
MIME Type:
Creator:
Andrew Bartlett
Created:
2022-06-14 04:11:30 UTC
Size:
79.19 KB
patch
obsolete
>From 2c34455394cf7bbaf355afb8078959cf3ff2f985 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 01/10] 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 a/lib/ldb/modules/rdn_name.c b/lib/ldb/modules/rdn_name.c >index e69ad9315ae..25cffe07591 100644 >--- a/lib/ldb/modules/rdn_name.c >+++ b/lib/ldb/modules/rdn_name.c >@@ -545,7 +545,7 @@ static int rdn_name_modify(struct ldb_module *module, struct ldb_request *req) > if (e != NULL) { > ldb_asprintf_errstring(ldb, "Modify of 'distinguishedName' on %s not permitted, must use 'rename' operation instead", > ldb_dn_get_linearized(req->op.mod.message->dn)); >- if (e->flags == LDB_FLAG_MOD_REPLACE) { >+ if (LDB_FLAG_MOD_TYPE(e->flags) == LDB_FLAG_MOD_REPLACE) { > return LDB_ERR_CONSTRAINT_VIOLATION; > } else { > return LDB_ERR_UNWILLING_TO_PERFORM; >-- >2.25.1 > > >From acdf919c4332f5f57a09c10b6a3319d57340f064 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 02/10] 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 a/lib/ldb/common/ldb_msg.c b/lib/ldb/common/ldb_msg.c >index 57dfc5a04c2..2a9ce384bb9 100644 >--- a/lib/ldb/common/ldb_msg.c >+++ b/lib/ldb/common/ldb_msg.c >@@ -833,11 +833,7 @@ void ldb_msg_sort_elements(struct ldb_message *msg) > ldb_msg_element_compare_name); > } > >-/* >- shallow copy a message - copying only the elements array so that the caller >- can safely add new elements without changing the message >-*/ >-struct ldb_message *ldb_msg_copy_shallow(TALLOC_CTX *mem_ctx, >+static struct ldb_message *ldb_msg_copy_shallow_impl(TALLOC_CTX *mem_ctx, > const struct ldb_message *msg) > { > struct ldb_message *msg2; >@@ -863,6 +859,35 @@ failed: > return NULL; > } > >+/* >+ shallow copy a message - copying only the elements array so that the caller >+ can safely add new elements without changing the message >+*/ >+struct ldb_message *ldb_msg_copy_shallow(TALLOC_CTX *mem_ctx, >+ const struct ldb_message *msg) >+{ >+ struct ldb_message *msg2; >+ unsigned int i; >+ >+ msg2 = ldb_msg_copy_shallow_impl(mem_ctx, msg); >+ if (msg2 == NULL) { >+ return NULL; >+ } >+ >+ for (i = 0; i < msg2->num_elements; ++i) { >+ /* >+ * Mark this message's elements as sharing their values with the >+ * original message, so that we don't inadvertently modify or >+ * free them. We don't mark the original message element as >+ * shared, so the original message element should not be >+ * modified or freed while the shallow copy lives. >+ */ >+ struct ldb_message_element *el = &msg2->elements[i]; >+ el->flags |= LDB_FLAG_INTERNAL_SHARED_VALUES; >+ } >+ >+ return msg2; >+} > > /* > copy a message, allocating new memory for all parts >@@ -873,7 +898,7 @@ struct ldb_message *ldb_msg_copy(TALLOC_CTX *mem_ctx, > struct ldb_message *msg2; > unsigned int i, j; > >- msg2 = ldb_msg_copy_shallow(mem_ctx, msg); >+ msg2 = ldb_msg_copy_shallow_impl(mem_ctx, msg); > if (msg2 == NULL) return NULL; > > if (msg2->dn != NULL) { >@@ -894,6 +919,12 @@ struct ldb_message *ldb_msg_copy(TALLOC_CTX *mem_ctx, > goto failed; > } > } >+ >+ /* >+ * Since we copied this element's values, we can mark them as >+ * not shared. >+ */ >+ el->flags &= ~LDB_FLAG_INTERNAL_SHARED_VALUES; > } > > return msg2; >diff --git a/lib/ldb/include/ldb_module.h b/lib/ldb/include/ldb_module.h >index 8c1e5ee7936..4c7c85a17f0 100644 >--- a/lib/ldb/include/ldb_module.h >+++ b/lib/ldb/include/ldb_module.h >@@ -96,6 +96,12 @@ struct ldb_module; > */ > #define LDB_FLAG_INTERNAL_FORCE_UNIQUE_INDEX 0x100 > >+/* >+ * indicates that this element's values are shared with another element (for >+ * example, in a shallow copy of an ldb_message) and should not be freed >+ */ >+#define LDB_FLAG_INTERNAL_SHARED_VALUES 0x200 >+ > /* an extended match rule that always fails to match */ > #define SAMBA_LDAP_MATCH_ALWAYS_FALSE "1.3.6.1.4.1.7165.4.5.1" > >-- >2.25.1 > > >From 64cd461d24b40fa31cb6bbdbd9c40292943c90fa 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 03/10] 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 a/lib/ldb/common/ldb_msg.c b/lib/ldb/common/ldb_msg.c >index 2a9ce384bb9..44d3b29e9a7 100644 >--- a/lib/ldb/common/ldb_msg.c >+++ b/lib/ldb/common/ldb_msg.c >@@ -417,6 +417,47 @@ int ldb_msg_add(struct ldb_message *msg, > return LDB_SUCCESS; > } > >+/* >+ * add a value to a message element >+ */ >+int ldb_msg_element_add_value(TALLOC_CTX *mem_ctx, >+ struct ldb_message_element *el, >+ const struct ldb_val *val) >+{ >+ struct ldb_val *vals; >+ >+ if (el->flags & LDB_FLAG_INTERNAL_SHARED_VALUES) { >+ /* >+ * Another message is using this message element's values array, >+ * so we don't want to make any modifications to the original >+ * message, or potentially invalidate its own values by calling >+ * talloc_realloc(). Make a copy instead. >+ */ >+ el->flags &= ~LDB_FLAG_INTERNAL_SHARED_VALUES; >+ >+ vals = talloc_array(mem_ctx, struct ldb_val, >+ el->num_values + 1); >+ if (vals == NULL) { >+ return LDB_ERR_OPERATIONS_ERROR; >+ } >+ >+ if (el->values != NULL) { >+ memcpy(vals, el->values, el->num_values * sizeof(struct ldb_val)); >+ } >+ } else { >+ vals = talloc_realloc(mem_ctx, el->values, struct ldb_val, >+ el->num_values + 1); >+ if (vals == NULL) { >+ return LDB_ERR_OPERATIONS_ERROR; >+ } >+ } >+ el->values = vals; >+ el->values[el->num_values] = *val; >+ el->num_values++; >+ >+ return LDB_SUCCESS; >+} >+ > /* > add a value to a message > */ >@@ -426,7 +467,6 @@ int ldb_msg_add_value(struct ldb_message *msg, > struct ldb_message_element **return_el) > { > struct ldb_message_element *el; >- struct ldb_val *vals; > int ret; > > el = ldb_msg_find_element(msg, attr_name); >@@ -437,14 +477,10 @@ int ldb_msg_add_value(struct ldb_message *msg, > } > } > >- vals = talloc_realloc(msg->elements, el->values, struct ldb_val, >- el->num_values+1); >- if (!vals) { >- return LDB_ERR_OPERATIONS_ERROR; >+ ret = ldb_msg_element_add_value(msg->elements, el, val); >+ if (ret != LDB_SUCCESS) { >+ return ret; > } >- el->values = vals; >- el->values[el->num_values] = *val; >- el->num_values++; > > if (return_el) { > *return_el = el; >diff --git a/lib/ldb/include/ldb.h b/lib/ldb/include/ldb.h >index bc44157eaf4..129beefeaf5 100644 >--- a/lib/ldb/include/ldb.h >+++ b/lib/ldb/include/ldb.h >@@ -1981,6 +1981,12 @@ int ldb_msg_add_empty(struct ldb_message *msg, > int flags, > struct ldb_message_element **return_el); > >+/** >+ add a value to a message element >+*/ >+int ldb_msg_element_add_value(TALLOC_CTX *mem_ctx, >+ struct ldb_message_element *el, >+ const struct ldb_val *val); > /** > add a element to a ldb_message > */ >diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c >index bd59de5cb32..0f22067c960 100644 >--- a/source4/dsdb/common/util.c >+++ b/source4/dsdb/common/util.c >@@ -795,7 +795,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; >@@ -830,14 +830,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; > } >@@ -851,7 +847,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; >@@ -886,14 +882,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 14936792a80c090575613a30ba6dba0938d8cdda 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 04/10] 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 a/lib/ldb/common/ldb_msg.c b/lib/ldb/common/ldb_msg.c >index 44d3b29e9a7..9cd7998e21c 100644 >--- a/lib/ldb/common/ldb_msg.c >+++ b/lib/ldb/common/ldb_msg.c >@@ -509,12 +509,15 @@ int ldb_msg_add_steal_value(struct ldb_message *msg, > > > /* >- add a string element to a message >+ add a string element to a message, specifying flags > */ >-int ldb_msg_add_string(struct ldb_message *msg, >- const char *attr_name, const char *str) >+int ldb_msg_add_string_flags(struct ldb_message *msg, >+ const char *attr_name, const char *str, >+ int flags) > { > struct ldb_val val; >+ int ret; >+ struct ldb_message_element *el = NULL; > > val.data = discard_const_p(uint8_t, str); > val.length = strlen(str); >@@ -524,7 +527,25 @@ int ldb_msg_add_string(struct ldb_message *msg, > return LDB_SUCCESS; > } > >- return ldb_msg_add_value(msg, attr_name, &val, NULL); >+ ret = ldb_msg_add_value(msg, attr_name, &val, &el); >+ if (ret != LDB_SUCCESS) { >+ return ret; >+ } >+ >+ if (flags != 0) { >+ el->flags = flags; >+ } >+ >+ return LDB_SUCCESS; >+} >+ >+/* >+ add a string element to a message >+*/ >+int ldb_msg_add_string(struct ldb_message *msg, >+ const char *attr_name, const char *str) >+{ >+ return ldb_msg_add_string_flags(msg, attr_name, str, 0); > } > > /* >@@ -586,6 +607,142 @@ int ldb_msg_add_fmt(struct ldb_message *msg, > return ldb_msg_add_steal_value(msg, attr_name, &val); > } > >+static int ldb_msg_append_value_impl(struct ldb_message *msg, >+ const char *attr_name, >+ const struct ldb_val *val, >+ int flags, >+ struct ldb_message_element **return_el) >+{ >+ struct ldb_message_element *el = NULL; >+ int ret; >+ >+ ret = ldb_msg_add_empty(msg, attr_name, flags, &el); >+ if (ret != LDB_SUCCESS) { >+ return ret; >+ } >+ >+ ret = ldb_msg_element_add_value(msg->elements, el, val); >+ if (ret != LDB_SUCCESS) { >+ return ret; >+ } >+ >+ if (return_el != NULL) { >+ *return_el = el; >+ } >+ >+ return LDB_SUCCESS; >+} >+ >+/* >+ append a value to a message >+*/ >+int ldb_msg_append_value(struct ldb_message *msg, >+ const char *attr_name, >+ const struct ldb_val *val, >+ int flags) >+{ >+ return ldb_msg_append_value_impl(msg, attr_name, val, flags, NULL); >+} >+ >+/* >+ append a value to a message, stealing it into the 'right' place >+*/ >+int ldb_msg_append_steal_value(struct ldb_message *msg, >+ const char *attr_name, >+ struct ldb_val *val, >+ int flags) >+{ >+ int ret; >+ struct ldb_message_element *el = NULL; >+ >+ ret = ldb_msg_append_value_impl(msg, attr_name, val, flags, &el); >+ if (ret == LDB_SUCCESS) { >+ talloc_steal(el->values, val->data); >+ } >+ return ret; >+} >+ >+/* >+ append a string element to a message, stealing it into the 'right' place >+*/ >+int ldb_msg_append_steal_string(struct ldb_message *msg, >+ const char *attr_name, char *str, >+ int flags) >+{ >+ struct ldb_val val; >+ >+ val.data = (uint8_t *)str; >+ val.length = strlen(str); >+ >+ if (val.length == 0) { >+ /* allow empty strings as non-existent attributes */ >+ return LDB_SUCCESS; >+ } >+ >+ return ldb_msg_append_steal_value(msg, attr_name, &val, flags); >+} >+ >+/* >+ append a string element to a message >+*/ >+int ldb_msg_append_string(struct ldb_message *msg, >+ const char *attr_name, const char *str, int flags) >+{ >+ struct ldb_val val; >+ >+ val.data = discard_const_p(uint8_t, str); >+ val.length = strlen(str); >+ >+ if (val.length == 0) { >+ /* allow empty strings as non-existent attributes */ >+ return LDB_SUCCESS; >+ } >+ >+ return ldb_msg_append_value(msg, attr_name, &val, flags); >+} >+ >+/* >+ append a DN element to a message >+ WARNING: this uses the linearized string from the dn, and does not >+ copy the string. >+*/ >+int ldb_msg_append_linearized_dn(struct ldb_message *msg, const char *attr_name, >+ struct ldb_dn *dn, int flags) >+{ >+ char *str = ldb_dn_alloc_linearized(msg, dn); >+ >+ if (str == NULL) { >+ /* we don't want to have unknown DNs added */ >+ return LDB_ERR_OPERATIONS_ERROR; >+ } >+ >+ return ldb_msg_append_steal_string(msg, attr_name, str, flags); >+} >+ >+/* >+ append a printf formatted element to a message >+*/ >+int ldb_msg_append_fmt(struct ldb_message *msg, int flags, >+ const char *attr_name, const char *fmt, ...) >+{ >+ struct ldb_val val; >+ va_list ap; >+ char *str = NULL; >+ >+ va_start(ap, fmt); >+ str = talloc_vasprintf(msg, fmt, ap); >+ va_end(ap); >+ >+ if (str == NULL) { >+ return LDB_ERR_OPERATIONS_ERROR; >+ } >+ >+ val.data = (uint8_t *)str; >+ val.length = strlen(str); >+ >+ return ldb_msg_append_steal_value(msg, attr_name, &val, flags); >+} >+ > /* > compare two ldb_message_element structures > assumes case sensitive comparison >diff --git a/lib/ldb/include/ldb.h b/lib/ldb/include/ldb.h >index 129beefeaf5..63d8aedd672 100644 >--- a/lib/ldb/include/ldb.h >+++ b/lib/ldb/include/ldb.h >@@ -2002,12 +2002,36 @@ int ldb_msg_add_steal_value(struct ldb_message *msg, > struct ldb_val *val); > int ldb_msg_add_steal_string(struct ldb_message *msg, > const char *attr_name, char *str); >+int ldb_msg_add_string_flags(struct ldb_message *msg, >+ const char *attr_name, const char *str, >+ int flags); > int ldb_msg_add_string(struct ldb_message *msg, > const char *attr_name, const char *str); > int ldb_msg_add_linearized_dn(struct ldb_message *msg, const char *attr_name, > struct ldb_dn *dn); > int ldb_msg_add_fmt(struct ldb_message *msg, > const char *attr_name, const char *fmt, ...) PRINTF_ATTRIBUTE(3,4); >+/** >+ append a element to a ldb_message >+*/ >+int ldb_msg_append_value(struct ldb_message *msg, >+ const char *attr_name, >+ const struct ldb_val *val, >+ int flags); >+int ldb_msg_append_steal_value(struct ldb_message *msg, >+ const char *attr_name, >+ struct ldb_val *val, >+ int flags); >+int ldb_msg_append_steal_string(struct ldb_message *msg, >+ const char *attr_name, char *str, >+ int flags); >+int ldb_msg_append_string(struct ldb_message *msg, >+ const char *attr_name, const char *str, >+ int flags); >+int ldb_msg_append_linearized_dn(struct ldb_message *msg, const char *attr_name, >+ struct ldb_dn *dn, int flags); >+int ldb_msg_append_fmt(struct ldb_message *msg, int flags, >+ const char *attr_name, const char *fmt, ...) PRINTF_ATTRIBUTE(4,5); > > /** > compare two message elements - return 0 on match >-- >2.25.1 > > >From bcfe458af4ccc870328c38e60f98354afed48069 Mon Sep 17 00:00:00 2001 >From: Joseph Sutton <josephsutton@catalyst.net.nz> >Date: Mon, 21 Feb 2022 16:27:37 +1300 >Subject: [PATCH 05/10] CVE-2022-32746 ldb: Make use of functions for appending > to an ldb_message > >This aims to minimise usage of the error-prone pattern of searching for >a just-added message element in order to make modifications to it (and >potentially finding the wrong element). > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=15009 > >Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> >--- > lib/ldb/ldb_map/ldb_map.c | 5 +- > lib/ldb/ldb_map/ldb_map_inbound.c | 9 +- > lib/ldb/modules/rdn_name.c | 22 +--- > source3/passdb/pdb_samba_dsdb.c | 14 +-- > source4/dns_server/dnsserver_common.c | 12 +- > source4/dsdb/common/util.c | 114 ++++++++++++++---- > source4/dsdb/samdb/ldb_modules/descriptor.c | 10 +- > source4/dsdb/samdb/ldb_modules/objectguid.c | 20 +-- > .../dsdb/samdb/ldb_modules/partition_init.c | 14 +-- > .../dsdb/samdb/ldb_modules/repl_meta_data.c | 24 +--- > source4/dsdb/samdb/ldb_modules/samldb.c | 78 +++++------- > .../samdb/ldb_modules/tombstone_reanimate.c | 12 +- > source4/nbt_server/wins/winsdb.c | 13 +- > source4/rpc_server/lsa/dcesrv_lsa.c | 55 +++------ > source4/winbind/idmap.c | 10 +- > 15 files changed, 183 insertions(+), 229 deletions(-) > >diff --git a/lib/ldb/ldb_map/ldb_map.c b/lib/ldb/ldb_map/ldb_map.c >index b453dff80d2..c7b0c228631 100644 >--- a/lib/ldb/ldb_map/ldb_map.c >+++ b/lib/ldb/ldb_map/ldb_map.c >@@ -946,10 +946,7 @@ struct ldb_request *map_build_fixup_req(struct map_context *ac, > if ( ! dn || ! ldb_dn_validate(msg->dn)) { > goto failed; > } >- if (ldb_msg_add_empty(msg, IS_MAPPED, LDB_FLAG_MOD_REPLACE, NULL) != 0) { >- goto failed; >- } >- if (ldb_msg_add_string(msg, IS_MAPPED, dn) != 0) { >+ if (ldb_msg_append_string(msg, IS_MAPPED, dn, LDB_FLAG_MOD_REPLACE) != 0) { > goto failed; > } > >diff --git a/lib/ldb/ldb_map/ldb_map_inbound.c b/lib/ldb/ldb_map/ldb_map_inbound.c >index 324295737da..50b9427c26c 100644 >--- a/lib/ldb/ldb_map/ldb_map_inbound.c >+++ b/lib/ldb/ldb_map/ldb_map_inbound.c >@@ -569,12 +569,9 @@ static int map_modify_do_local(struct map_context *ac) > /* No local record present, add it instead */ > /* Add local 'IS_MAPPED' */ > /* TODO: use GUIDs here instead */ >- if (ldb_msg_add_empty(ac->local_msg, IS_MAPPED, >- LDB_FLAG_MOD_ADD, NULL) != 0) { >- return LDB_ERR_OPERATIONS_ERROR; >- } >- ret = ldb_msg_add_linearized_dn(ac->local_msg, IS_MAPPED, >- ac->remote_req->op.mod.message->dn); >+ ret = ldb_msg_append_linearized_dn(ac->local_msg, IS_MAPPED, >+ ac->remote_req->op.mod.message->dn, >+ LDB_FLAG_MOD_ADD); > if (ret != 0) { > return LDB_ERR_OPERATIONS_ERROR; > } >diff --git a/lib/ldb/modules/rdn_name.c b/lib/ldb/modules/rdn_name.c >index 25cffe07591..3cb62bf567b 100644 >--- a/lib/ldb/modules/rdn_name.c >+++ b/lib/ldb/modules/rdn_name.c >@@ -308,16 +308,10 @@ static int rdn_rename_callback(struct ldb_request *req, struct ldb_reply *ares) > } > rdn_val = ldb_val_dup(msg, rdn_val_p); > >- if (ldb_msg_add_empty(msg, rdn_name, LDB_FLAG_MOD_REPLACE, NULL) != 0) { >+ if (ldb_msg_append_value(msg, rdn_name, &rdn_val, LDB_FLAG_MOD_REPLACE) != 0) { > goto error; > } >- if (ldb_msg_add_value(msg, rdn_name, &rdn_val, NULL) != 0) { >- goto error; >- } >- if (ldb_msg_add_empty(msg, "name", LDB_FLAG_MOD_REPLACE, NULL) != 0) { >- goto error; >- } >- if (ldb_msg_add_value(msg, "name", &rdn_val, NULL) != 0) { >+ if (ldb_msg_append_value(msg, "name", &rdn_val, LDB_FLAG_MOD_REPLACE) != 0) { > goto error; > } > >@@ -466,11 +460,7 @@ static int rdn_name_modify(struct ldb_module *module, struct ldb_request *req) > if (ret != 0) { > return ldb_module_oom(module); > } >- ret = ldb_msg_add_empty(msg, rdn_name, LDB_FLAG_MOD_ADD, NULL); >- if (ret != 0) { >- return ldb_module_oom(module); >- } >- ret = ldb_msg_add_value(msg, rdn_name, &rdn_val, NULL); >+ ret = ldb_msg_append_value(msg, rdn_name, &rdn_val, LDB_FLAG_MOD_ADD); > if (ret != 0) { > return ldb_module_oom(module); > } >@@ -479,11 +469,7 @@ static int rdn_name_modify(struct ldb_module *module, struct ldb_request *req) > if (ret != 0) { > return ldb_module_oom(module); > } >- ret = ldb_msg_add_empty(msg, "name", LDB_FLAG_MOD_ADD, NULL); >- if (ret != 0) { >- return ldb_module_oom(module); >- } >- ret = ldb_msg_add_value(msg, "name", &rdn_val, NULL); >+ ret = ldb_msg_append_value(msg, "name", &rdn_val, LDB_FLAG_MOD_ADD); > if (ret != 0) { > return ldb_module_oom(module); > } >diff --git a/source3/passdb/pdb_samba_dsdb.c b/source3/passdb/pdb_samba_dsdb.c >index 4f1d2f697f0..d9c31e57186 100644 >--- a/source3/passdb/pdb_samba_dsdb.c >+++ b/source3/passdb/pdb_samba_dsdb.c >@@ -2776,18 +2776,10 @@ static bool pdb_samba_dsdb_set_trusteddom_pw(struct pdb_methods *m, > } > > msg->num_elements = 0; >- ret = ldb_msg_add_empty(msg, "trustAuthOutgoing", >- LDB_FLAG_MOD_REPLACE, NULL); >+ ret = ldb_msg_append_value(msg, "trustAuthOutgoing", >+ &new_val, LDB_FLAG_MOD_REPLACE); > if (ret != LDB_SUCCESS) { >- DEBUG(0, ("ldb_msg_add_empty() failed\n")); >- TALLOC_FREE(tmp_ctx); >- ldb_transaction_cancel(state->ldb); >- return false; >- } >- ret = ldb_msg_add_value(msg, "trustAuthOutgoing", >- &new_val, NULL); >- if (ret != LDB_SUCCESS) { >- DEBUG(0, ("ldb_msg_add_value() failed\n")); >+ DEBUG(0, ("ldb_msg_append_value() failed\n")); > TALLOC_FREE(tmp_ctx); > ldb_transaction_cancel(state->ldb); > return false; >diff --git a/source4/dns_server/dnsserver_common.c b/source4/dns_server/dnsserver_common.c >index 71aeee8169d..03f76d4a871 100644 >--- a/source4/dns_server/dnsserver_common.c >+++ b/source4/dns_server/dnsserver_common.c >@@ -1124,15 +1124,9 @@ WERROR dns_common_replace(struct ldb_context *samdb, > } > > if (was_tombstoned || become_tombstoned) { >- ret = ldb_msg_add_empty(msg, "dNSTombstoned", >- LDB_FLAG_MOD_REPLACE, NULL); >- if (ret != LDB_SUCCESS) { >- werr = DNS_ERR(SERVER_FAILURE); >- goto exit; >- } >- >- ret = ldb_msg_add_fmt(msg, "dNSTombstoned", "%s", >- become_tombstoned ? "TRUE" : "FALSE"); >+ ret = ldb_msg_append_fmt(msg, LDB_FLAG_MOD_REPLACE, >+ "dNSTombstoned", "%s", >+ become_tombstoned ? "TRUE" : "FALSE"); > if (ret != LDB_SUCCESS) { > werr = DNS_ERR(SERVER_FAILURE); > goto exit; >diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c >index 0f22067c960..f8299e371ae 100644 >--- a/source4/dsdb/common/util.c >+++ b/source4/dsdb/common/util.c >@@ -903,6 +903,16 @@ int samdb_msg_add_int(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct l > return ldb_msg_add_string(msg, attr_name, s); > } > >+int samdb_msg_add_int_flags(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg, >+ const char *attr_name, int v, int flags) >+{ >+ const char *s = talloc_asprintf(mem_ctx, "%d", v); >+ if (s == NULL) { >+ return ldb_oom(sam_ldb); >+ } >+ return ldb_msg_add_string_flags(msg, attr_name, s, flags); >+} >+ > /* > * Add an unsigned int element to a message > * >@@ -921,6 +931,12 @@ int samdb_msg_add_uint(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct > return samdb_msg_add_int(sam_ldb, mem_ctx, msg, attr_name, (int)v); > } > >+int samdb_msg_add_uint_flags(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg, >+ const char *attr_name, unsigned int v, int flags) >+{ >+ return samdb_msg_add_int_flags(sam_ldb, mem_ctx, msg, attr_name, (int)v, flags); >+} >+ > /* > add a (signed) int64_t element to a message > */ >@@ -952,6 +968,68 @@ int samdb_msg_add_uint64(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struc > return samdb_msg_add_int64(sam_ldb, mem_ctx, msg, attr_name, (int64_t)v); > } > >+/* >+ append a int element to a message >+*/ >+int samdb_msg_append_int(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg, >+ const char *attr_name, int v, int flags) >+{ >+ const char *s = talloc_asprintf(mem_ctx, "%d", v); >+ if (s == NULL) { >+ return ldb_oom(sam_ldb); >+ } >+ return ldb_msg_append_string(msg, attr_name, s, flags); >+} >+ >+/* >+ * Append an unsigned int element to a message >+ * >+ * The issue here is that we have not yet first cast to int32_t explicitly, >+ * before we cast to an signed int to printf() into the %d or cast to a >+ * int64_t before we then cast to a long long to printf into a %lld. >+ * >+ * There are *no* unsigned integers in Active Directory LDAP, even the RID >+ * allocations and ms-DS-Secondary-KrbTgt-Number are *signed* quantities. >+ * (See the schema, and the syntax definitions in schema_syntax.c). >+ * >+ */ >+int samdb_msg_append_uint(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg, >+ const char *attr_name, unsigned int v, int flags) >+{ >+ return samdb_msg_append_int(sam_ldb, mem_ctx, msg, attr_name, (int)v, flags); >+} >+ >+/* >+ append a (signed) int64_t element to a message >+*/ >+int samdb_msg_append_int64(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg, >+ const char *attr_name, int64_t v, int flags) >+{ >+ const char *s = talloc_asprintf(mem_ctx, "%lld", (long long)v); >+ if (s == NULL) { >+ return ldb_oom(sam_ldb); >+ } >+ return ldb_msg_append_string(msg, attr_name, s, flags); >+} >+ >+/* >+ * Append an unsigned int64_t (uint64_t) element to a message >+ * >+ * The issue here is that we have not yet first cast to int32_t explicitly, >+ * before we cast to an signed int to printf() into the %d or cast to a >+ * int64_t before we then cast to a long long to printf into a %lld. >+ * >+ * There are *no* unsigned integers in Active Directory LDAP, even the RID >+ * allocations and ms-DS-Secondary-KrbTgt-Number are *signed* quantities. >+ * (See the schema, and the syntax definitions in schema_syntax.c). >+ * >+ */ >+int samdb_msg_append_uint64(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg, >+ const char *attr_name, uint64_t v, int flags) >+{ >+ return samdb_msg_append_int64(sam_ldb, mem_ctx, msg, attr_name, (int64_t)v, flags); >+} >+ > /* > add a samr_Password element to a message > */ >@@ -2780,15 +2858,8 @@ NTSTATUS samdb_set_password_sid(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, > tdo_msg->num_elements = 0; > TALLOC_FREE(tdo_msg->elements); > >- ret = ldb_msg_add_empty(tdo_msg, "trustAuthIncoming", >- LDB_FLAG_MOD_REPLACE, NULL); >- if (ret != LDB_SUCCESS) { >- ldb_transaction_cancel(ldb); >- TALLOC_FREE(frame); >- return NT_STATUS_NO_MEMORY; >- } >- ret = ldb_msg_add_value(tdo_msg, "trustAuthIncoming", >- &new_val, NULL); >+ ret = ldb_msg_append_value(tdo_msg, "trustAuthIncoming", >+ &new_val, LDB_FLAG_MOD_REPLACE); > if (ret != LDB_SUCCESS) { > ldb_transaction_cancel(ldb); > TALLOC_FREE(frame); >@@ -3153,6 +3224,7 @@ int dsdb_find_guid_by_dn(struct ldb_context *ldb, > /* > adds the given GUID to the given ldb_message. This value is added > for the given attr_name (may be either "objectGUID" or "parentGUID"). >+ This function is used in processing 'add' requests. > */ > int dsdb_msg_add_guid(struct ldb_message *msg, > struct GUID *guid, >@@ -5637,7 +5709,8 @@ int dsdb_user_obj_set_defaults(struct ldb_context *ldb, > } > > /** >- * Sets 'sAMAccountType on user object based on userAccountControl >+ * Sets 'sAMAccountType on user object based on userAccountControl. >+ * This function is used in processing both 'add' and 'modify' requests. > * @param ldb Current ldb_context > * @param usr_obj ldb_message representing User object > * @param user_account_control Value for userAccountControl flags >@@ -5649,21 +5722,19 @@ int dsdb_user_obj_set_account_type(struct ldb_context *ldb, struct ldb_message * > { > int ret; > uint32_t account_type; >- struct ldb_message_element *el; > > account_type = ds_uf2atype(user_account_control); > if (account_type == 0) { > ldb_set_errstring(ldb, "dsdb: Unrecognized account type!"); > return LDB_ERR_UNWILLING_TO_PERFORM; > } >- ret = samdb_msg_add_uint(ldb, usr_obj, usr_obj, >- "sAMAccountType", >- account_type); >+ ret = samdb_msg_add_uint_flags(ldb, usr_obj, usr_obj, >+ "sAMAccountType", >+ account_type, >+ LDB_FLAG_MOD_REPLACE); > if (ret != LDB_SUCCESS) { > return ret; > } >- el = ldb_msg_find_element(usr_obj, "sAMAccountType"); >- el->flags = LDB_FLAG_MOD_REPLACE; > > if (account_type_p) { > *account_type_p = account_type; >@@ -5673,7 +5744,8 @@ int dsdb_user_obj_set_account_type(struct ldb_context *ldb, struct ldb_message * > } > > /** >- * Determine and set primaryGroupID based on userAccountControl value >+ * Determine and set primaryGroupID based on userAccountControl value. >+ * This function is used in processing both 'add' and 'modify' requests. > * @param ldb Current ldb_context > * @param usr_obj ldb_message representing User object > * @param user_account_control Value for userAccountControl flags >@@ -5685,17 +5757,15 @@ int dsdb_user_obj_set_primary_group_id(struct ldb_context *ldb, struct ldb_messa > { > int ret; > uint32_t rid; >- struct ldb_message_element *el; > > rid = ds_uf2prim_group_rid(user_account_control); > >- ret = samdb_msg_add_uint(ldb, usr_obj, usr_obj, >- "primaryGroupID", rid); >+ ret = samdb_msg_add_uint_flags(ldb, usr_obj, usr_obj, >+ "primaryGroupID", rid, >+ LDB_FLAG_MOD_REPLACE); > if (ret != LDB_SUCCESS) { > return ret; > } >- el = ldb_msg_find_element(usr_obj, "primaryGroupID"); >- el->flags = LDB_FLAG_MOD_REPLACE; > > if (group_rid_p) { > *group_rid_p = rid; >diff --git a/source4/dsdb/samdb/ldb_modules/descriptor.c b/source4/dsdb/samdb/ldb_modules/descriptor.c >index 0f221b794d4..aef2e284dc7 100644 >--- a/source4/dsdb/samdb/ldb_modules/descriptor.c >+++ b/source4/dsdb/samdb/ldb_modules/descriptor.c >@@ -914,14 +914,8 @@ static int descriptor_modify(struct ldb_module *module, struct ldb_request *req) > return ldb_module_done(req, NULL, NULL, LDB_SUCCESS); > } > >- ret = ldb_msg_add_empty(msg, "nTSecurityDescriptor", >- LDB_FLAG_MOD_REPLACE, >- &sd_element); >- if (ret != LDB_SUCCESS) { >- return ldb_oom(ldb); >- } >- ret = ldb_msg_add_value(msg, "nTSecurityDescriptor", >- sd, NULL); >+ ret = ldb_msg_append_value(msg, "nTSecurityDescriptor", >+ sd, LDB_FLAG_MOD_REPLACE); > if (ret != LDB_SUCCESS) { > return ldb_oom(ldb); > } >diff --git a/source4/dsdb/samdb/ldb_modules/objectguid.c b/source4/dsdb/samdb/ldb_modules/objectguid.c >index 093d6ed74ca..cfc89184ff6 100644 >--- a/source4/dsdb/samdb/ldb_modules/objectguid.c >+++ b/source4/dsdb/samdb/ldb_modules/objectguid.c >@@ -41,7 +41,6 @@ > */ > static int add_time_element(struct ldb_message *msg, const char *attr, time_t t) > { >- struct ldb_message_element *el; > char *s; > int ret; > >@@ -54,16 +53,13 @@ static int add_time_element(struct ldb_message *msg, const char *attr, time_t t) > return LDB_ERR_OPERATIONS_ERROR; > } > >- ret = ldb_msg_add_string(msg, attr, s); >+ /* always set as replace. This works because on add ops, the flag >+ is ignored */ >+ ret = ldb_msg_append_string(msg, attr, s, LDB_FLAG_MOD_REPLACE); > if (ret != LDB_SUCCESS) { > return ret; > } > >- el = ldb_msg_find_element(msg, attr); >- /* always set as replace. This works because on add ops, the flag >- is ignored */ >- el->flags = LDB_FLAG_MOD_REPLACE; >- > return LDB_SUCCESS; > } > >@@ -73,23 +69,19 @@ static int add_time_element(struct ldb_message *msg, const char *attr, time_t t) > static int add_uint64_element(struct ldb_context *ldb, struct ldb_message *msg, > const char *attr, uint64_t v) > { >- struct ldb_message_element *el; > int ret; > > if (ldb_msg_find_element(msg, attr) != NULL) { > return LDB_SUCCESS; > } > >- ret = samdb_msg_add_uint64(ldb, msg, msg, attr, v); >+ /* always set as replace. This works because on add ops, the flag >+ is ignored */ >+ ret = samdb_msg_append_uint64(ldb, msg, msg, attr, v, LDB_FLAG_MOD_REPLACE); > if (ret != LDB_SUCCESS) { > return ret; > } > >- el = ldb_msg_find_element(msg, attr); >- /* always set as replace. This works because on add ops, the flag >- is ignored */ >- el->flags = LDB_FLAG_MOD_REPLACE; >- > return LDB_SUCCESS; > } > >diff --git a/source4/dsdb/samdb/ldb_modules/partition_init.c b/source4/dsdb/samdb/ldb_modules/partition_init.c >index 58c65ccedd0..484b5bffb27 100644 >--- a/source4/dsdb/samdb/ldb_modules/partition_init.c >+++ b/source4/dsdb/samdb/ldb_modules/partition_init.c >@@ -742,10 +742,6 @@ int partition_create(struct ldb_module *module, struct ldb_request *req) > } > > mod_msg->dn = ldb_dn_new(mod_msg, ldb, DSDB_PARTITION_DN); >- ret = ldb_msg_add_empty(mod_msg, DSDB_PARTITION_ATTR, LDB_FLAG_MOD_ADD, NULL); >- if (ret != LDB_SUCCESS) { >- return ret; >- } > > casefold_dn = ldb_dn_get_casefold(dn); > >@@ -785,18 +781,16 @@ int partition_create(struct ldb_module *module, struct ldb_request *req) > } > partition_record = talloc_asprintf(mod_msg, "%s:%s", casefold_dn, filename); > >- ret = ldb_msg_add_steal_string(mod_msg, DSDB_PARTITION_ATTR, partition_record); >+ ret = ldb_msg_append_steal_string(mod_msg, DSDB_PARTITION_ATTR, partition_record, >+ LDB_FLAG_MOD_ADD); > if (ret != LDB_SUCCESS) { > return ret; > } > > if (ldb_request_get_control(req, DSDB_CONTROL_PARTIAL_REPLICA)) { > /* this new partition is a partial replica */ >- ret = ldb_msg_add_empty(mod_msg, "partialReplica", LDB_FLAG_MOD_ADD, NULL); >- if (ret != LDB_SUCCESS) { >- return ret; >- } >- ret = ldb_msg_add_fmt(mod_msg, "partialReplica", "%s", ldb_dn_get_linearized(dn)); >+ ret = ldb_msg_append_fmt(mod_msg, LDB_FLAG_MOD_ADD, >+ "partialReplica", "%s", ldb_dn_get_linearized(dn)); > if (ret != LDB_SUCCESS) { > return ret; > } >diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c >index 4949e691a86..a39550e9e85 100644 >--- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c >+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c >@@ -3888,22 +3888,12 @@ static int replmd_rename_callback(struct ldb_request *req, struct ldb_reply *are > ldb_operr(ldb)); > } > >- if (ldb_msg_add_empty(msg, rdn_name, LDB_FLAG_MOD_REPLACE, NULL) != 0) { >+ if (ldb_msg_append_value(msg, rdn_name, rdn_val, LDB_FLAG_MOD_REPLACE) != 0) { > talloc_free(ares); > return ldb_module_done(ac->req, NULL, NULL, > ldb_oom(ldb)); > } >- if (ldb_msg_add_value(msg, rdn_name, rdn_val, NULL) != 0) { >- talloc_free(ares); >- return ldb_module_done(ac->req, NULL, NULL, >- ldb_oom(ldb)); >- } >- if (ldb_msg_add_empty(msg, "name", LDB_FLAG_MOD_REPLACE, NULL) != 0) { >- talloc_free(ares); >- return ldb_module_done(ac->req, NULL, NULL, >- ldb_oom(ldb)); >- } >- if (ldb_msg_add_value(msg, "name", rdn_val, NULL) != 0) { >+ if (ldb_msg_append_value(msg, "name", rdn_val, LDB_FLAG_MOD_REPLACE) != 0) { > talloc_free(ares); > return ldb_module_done(ac->req, NULL, NULL, > ldb_oom(ldb)); >@@ -5161,16 +5151,10 @@ static int replmd_name_modify(struct replmd_replicated_request *ar, > goto failed; > } > >- if (ldb_msg_add_empty(msg, rdn_name, LDB_FLAG_MOD_REPLACE, NULL) != 0) { >- goto failed; >- } >- if (ldb_msg_add_value(msg, rdn_name, rdn_val, NULL) != 0) { >- goto failed; >- } >- if (ldb_msg_add_empty(msg, "name", LDB_FLAG_MOD_REPLACE, NULL) != 0) { >+ if (ldb_msg_append_value(msg, rdn_name, rdn_val, LDB_FLAG_MOD_REPLACE) != 0) { > goto failed; > } >- if (ldb_msg_add_value(msg, "name", rdn_val, NULL) != 0) { >+ if (ldb_msg_append_value(msg, "name", rdn_val, LDB_FLAG_MOD_REPLACE) != 0) { > goto failed; > } > >diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c >index 24971d521aa..b89d93910fd 100644 >--- a/source4/dsdb/samdb/ldb_modules/samldb.c >+++ b/source4/dsdb/samdb/ldb_modules/samldb.c >@@ -1103,14 +1103,11 @@ static int samldb_rodc_add(struct samldb_ctx *ac) > return LDB_ERR_OTHER; > > found: >- ret = ldb_msg_add_empty(ac->msg, "msDS-SecondaryKrbTgtNumber", >- LDB_FLAG_INTERNAL_DISABLE_VALIDATION, NULL); >- if (ret != LDB_SUCCESS) { >- return ldb_operr(ldb); >- } > >- ret = samdb_msg_add_uint(ldb, ac->msg, ac->msg, >- "msDS-SecondaryKrbTgtNumber", krbtgt_number); >+ ldb_msg_remove_attr(ac->msg, "msDS-SecondaryKrbTgtNumber"); >+ ret = samdb_msg_append_uint(ldb, ac->msg, ac->msg, >+ "msDS-SecondaryKrbTgtNumber", krbtgt_number, >+ LDB_FLAG_INTERNAL_DISABLE_VALIDATION); > if (ret != LDB_SUCCESS) { > return ldb_operr(ldb); > } >@@ -1792,7 +1789,7 @@ static int samldb_objectclass_trigger(struct samldb_ctx *ac) > struct ldb_context *ldb = ldb_module_get_ctx(ac->module); > void *skip_allocate_sids = ldb_get_opaque(ldb, > "skip_allocate_sids"); >- struct ldb_message_element *el, *el2; >+ struct ldb_message_element *el; > struct dom_sid *sid; > int ret; > >@@ -1926,23 +1923,17 @@ static int samldb_objectclass_trigger(struct samldb_ctx *ac) > /* "isCriticalSystemObject" might be set */ > if (user_account_control & > (UF_SERVER_TRUST_ACCOUNT | UF_PARTIAL_SECRETS_ACCOUNT)) { >- ret = ldb_msg_add_string(ac->msg, "isCriticalSystemObject", >- "TRUE"); >+ ret = ldb_msg_add_string_flags(ac->msg, "isCriticalSystemObject", >+ "TRUE", LDB_FLAG_MOD_REPLACE); > if (ret != LDB_SUCCESS) { > return ret; > } >- el2 = ldb_msg_find_element(ac->msg, >- "isCriticalSystemObject"); >- el2->flags = LDB_FLAG_MOD_REPLACE; > } else if (user_account_control & UF_WORKSTATION_TRUST_ACCOUNT) { >- ret = ldb_msg_add_string(ac->msg, "isCriticalSystemObject", >- "FALSE"); >+ ret = ldb_msg_add_string_flags(ac->msg, "isCriticalSystemObject", >+ "FALSE", LDB_FLAG_MOD_REPLACE); > if (ret != LDB_SUCCESS) { > return ret; > } >- el2 = ldb_msg_find_element(ac->msg, >- "isCriticalSystemObject"); >- el2->flags = LDB_FLAG_MOD_REPLACE; > } > > /* Step 1.4: "userAccountControl" -> "primaryGroupID" mapping */ >@@ -2018,14 +2009,13 @@ static int samldb_objectclass_trigger(struct samldb_ctx *ac) > ldb_set_errstring(ldb, "samldb: Unrecognized account type!"); > return LDB_ERR_UNWILLING_TO_PERFORM; > } >- ret = samdb_msg_add_uint(ldb, ac->msg, ac->msg, >- "sAMAccountType", >- account_type); >+ ret = samdb_msg_add_uint_flags(ldb, ac->msg, ac->msg, >+ "sAMAccountType", >+ account_type, >+ LDB_FLAG_MOD_REPLACE); > if (ret != LDB_SUCCESS) { > return ret; > } >- el2 = ldb_msg_find_element(ac->msg, "sAMAccountType"); >- el2->flags = LDB_FLAG_MOD_REPLACE; > } > break; > } >@@ -2945,26 +2935,23 @@ static int samldb_user_account_control_change(struct samldb_ctx *ac) > } > > if (old_atype != new_atype) { >- ret = samdb_msg_add_uint(ldb, ac->msg, ac->msg, >- "sAMAccountType", new_atype); >+ ret = samdb_msg_append_uint(ldb, ac->msg, ac->msg, >+ "sAMAccountType", new_atype, >+ LDB_FLAG_MOD_REPLACE); > if (ret != LDB_SUCCESS) { > return ret; > } >- el = ldb_msg_find_element(ac->msg, "sAMAccountType"); >- el->flags = LDB_FLAG_MOD_REPLACE; > } > > /* As per MS-SAMR 3.1.1.8.10 these flags have not to be set */ > if ((clear_uac & UF_LOCKOUT) && (old_lockoutTime != 0)) { > /* "lockoutTime" reset as per MS-SAMR 3.1.1.8.10 */ > ldb_msg_remove_attr(ac->msg, "lockoutTime"); >- ret = samdb_msg_add_uint64(ldb, ac->msg, ac->msg, "lockoutTime", >- (NTTIME)0); >+ ret = samdb_msg_append_uint64(ldb, ac->msg, ac->msg, "lockoutTime", >+ (NTTIME)0, LDB_FLAG_MOD_REPLACE); > if (ret != LDB_SUCCESS) { > return ret; > } >- el = ldb_msg_find_element(ac->msg, "lockoutTime"); >- el->flags = LDB_FLAG_MOD_REPLACE; > } > > /* >@@ -2975,14 +2962,12 @@ static int samldb_user_account_control_change(struct samldb_ctx *ac) > * creating the attribute. > */ > if (old_is_critical != new_is_critical || old_atype != new_atype) { >- ret = ldb_msg_add_string(ac->msg, "isCriticalSystemObject", >- new_is_critical ? "TRUE": "FALSE"); >+ ret = ldb_msg_append_string(ac->msg, "isCriticalSystemObject", >+ new_is_critical ? "TRUE": "FALSE", >+ LDB_FLAG_MOD_REPLACE); > if (ret != LDB_SUCCESS) { > return ret; > } >- el = ldb_msg_find_element(ac->msg, >- "isCriticalSystemObject"); >- el->flags = LDB_FLAG_MOD_REPLACE; > } > > if (!ldb_msg_find_element(ac->msg, "primaryGroupID") && >@@ -2995,14 +2980,12 @@ static int samldb_user_account_control_change(struct samldb_ctx *ac) > } > } > >- ret = samdb_msg_add_uint(ldb, ac->msg, ac->msg, >- "primaryGroupID", new_pgrid); >+ ret = samdb_msg_append_uint(ldb, ac->msg, ac->msg, >+ "primaryGroupID", new_pgrid, >+ LDB_FLAG_MOD_REPLACE); > if (ret != LDB_SUCCESS) { > return ret; > } >- el = ldb_msg_find_element(ac->msg, >- "primaryGroupID"); >- el->flags = LDB_FLAG_MOD_REPLACE; > } > > /* Propagate eventual "userAccountControl" attribute changes */ >@@ -3205,13 +3188,12 @@ static int samldb_lockout_time(struct samldb_ctx *ac) > > /* lockoutTime == 0 resets badPwdCount */ > ldb_msg_remove_attr(ac->msg, "badPwdCount"); >- ret = samdb_msg_add_int(ldb, ac->msg, ac->msg, >- "badPwdCount", 0); >+ ret = samdb_msg_append_int(ldb, ac->msg, ac->msg, >+ "badPwdCount", 0, >+ LDB_FLAG_MOD_REPLACE); > if (ret != LDB_SUCCESS) { > return ret; > } >- el = ldb_msg_find_element(ac->msg, "badPwdCount"); >- el->flags = LDB_FLAG_MOD_REPLACE; > > return LDB_SUCCESS; > } >@@ -3309,13 +3291,11 @@ static int samldb_group_type_change(struct samldb_ctx *ac) > ldb_set_errstring(ldb, "samldb: Unrecognized account type!"); > return LDB_ERR_UNWILLING_TO_PERFORM; > } >- ret = samdb_msg_add_uint(ldb, ac->msg, ac->msg, "sAMAccountType", >- account_type); >+ ret = samdb_msg_append_uint(ldb, ac->msg, ac->msg, "sAMAccountType", >+ account_type, LDB_FLAG_MOD_REPLACE); > if (ret != LDB_SUCCESS) { > return ret; > } >- el = ldb_msg_find_element(ac->msg, "sAMAccountType"); >- el->flags = LDB_FLAG_MOD_REPLACE; > > return LDB_SUCCESS; > } >diff --git a/source4/dsdb/samdb/ldb_modules/tombstone_reanimate.c b/source4/dsdb/samdb/ldb_modules/tombstone_reanimate.c >index 64e05195798..5ad45f28f15 100644 >--- a/source4/dsdb/samdb/ldb_modules/tombstone_reanimate.c >+++ b/source4/dsdb/samdb/ldb_modules/tombstone_reanimate.c >@@ -294,14 +294,13 @@ static int tr_prepare_attributes(struct tr_context *ac) > return ldb_error(ldb, LDB_ERR_UNWILLING_TO_PERFORM, > "reanimate: Unrecognized account type!"); > } >- ret = samdb_msg_add_uint(ldb, ac->mod_msg, ac->mod_msg, >- "sAMAccountType", account_type); >+ ret = samdb_msg_append_uint(ldb, ac->mod_msg, ac->mod_msg, >+ "sAMAccountType", account_type, >+ LDB_FLAG_MOD_REPLACE); > if (ret != LDB_SUCCESS) { > return ldb_error(ldb, LDB_ERR_OPERATIONS_ERROR, > "reanimate: Failed to add sAMAccountType to restored object."); > } >- el = ldb_msg_find_element(ac->mod_msg, "sAMAccountType"); >- el->flags = LDB_FLAG_MOD_REPLACE; > > /* Default values set by Windows */ > ret = samdb_find_or_add_attribute(ldb, ac->mod_msg, >@@ -324,12 +323,11 @@ static int tr_prepare_attributes(struct tr_context *ac) > return ret; > } > >- ret = ldb_msg_add_string(ac->mod_msg, "objectCategory", value); >+ ret = ldb_msg_append_string(ac->mod_msg, "objectCategory", value, >+ LDB_FLAG_MOD_ADD); > if (ret != LDB_SUCCESS) { > return ret; > } >- el = ldb_msg_find_element(ac->mod_msg, "objectCategory"); >- el->flags = LDB_FLAG_MOD_ADD; > } > > return LDB_SUCCESS; >diff --git a/source4/nbt_server/wins/winsdb.c b/source4/nbt_server/wins/winsdb.c >index e4a7c2042ed..2a05e96bca4 100644 >--- a/source4/nbt_server/wins/winsdb.c >+++ b/source4/nbt_server/wins/winsdb.c >@@ -102,13 +102,11 @@ uint64_t winsdb_set_maxVersion(struct winsdb_handle *h, uint64_t newMaxVersion) > msg->dn = dn; > > >- ret = ldb_msg_add_empty(msg, "objectClass", LDB_FLAG_MOD_REPLACE, NULL); >+ ret = ldb_msg_append_string(msg, "objectClass", "winsMaxVersion", >+ LDB_FLAG_MOD_REPLACE); > if (ret != LDB_SUCCESS) goto failed; >- ret = ldb_msg_add_string(msg, "objectClass", "winsMaxVersion"); >- if (ret != LDB_SUCCESS) goto failed; >- ret = ldb_msg_add_empty(msg, "maxVersion", LDB_FLAG_MOD_REPLACE, NULL); >- if (ret != LDB_SUCCESS) goto failed; >- ret = ldb_msg_add_fmt(msg, "maxVersion", "%llu", (long long)newMaxVersion); >+ ret = ldb_msg_append_fmt(msg, LDB_FLAG_MOD_REPLACE, >+ "maxVersion", "%llu", (long long)newMaxVersion); > if (ret != LDB_SUCCESS) goto failed; > > ret = ldb_modify(wins_db, msg); >@@ -779,8 +777,7 @@ static struct ldb_message *winsdb_message(struct ldb_context *ldb, > ret |= ldb_msg_add_winsdb_addr(msg, rec, "address", rec->addresses[i]); > } > if (rec->registered_by) { >- ret |= ldb_msg_add_empty(msg, "registeredBy", 0, NULL); >- ret |= ldb_msg_add_string(msg, "registeredBy", rec->registered_by); >+ ret |= ldb_msg_append_string(msg, "registeredBy", rec->registered_by, 0); > } > if (ret != LDB_SUCCESS) goto failed; > return msg; >diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c >index 185e0044de1..575bf845539 100644 >--- a/source4/rpc_server/lsa/dcesrv_lsa.c >+++ b/source4/rpc_server/lsa/dcesrv_lsa.c >@@ -1760,12 +1760,7 @@ static NTSTATUS update_uint32_t_value(TALLOC_CTX *mem_ctx, > goto done; > } > >- ret = ldb_msg_add_empty(dest, attribute, flags, NULL); >- if (ret != LDB_SUCCESS) { >- return NT_STATUS_NO_MEMORY; >- } >- >- ret = samdb_msg_add_uint(sam_ldb, dest, dest, attribute, value); >+ ret = samdb_msg_append_uint(sam_ldb, dest, dest, attribute, value, flags); > if (ret != LDB_SUCCESS) { > return NT_STATUS_NO_MEMORY; > } >@@ -1856,13 +1851,7 @@ static NTSTATUS update_trust_user(TALLOC_CTX *mem_ctx, > continue; > } > >- ret = ldb_msg_add_empty(msg, attribute, >- LDB_FLAG_MOD_REPLACE, NULL); >- if (ret != LDB_SUCCESS) { >- return NT_STATUS_NO_MEMORY; >- } >- >- ret = ldb_msg_add_value(msg, attribute, &v, NULL); >+ ret = ldb_msg_append_value(msg, attribute, &v, LDB_FLAG_MOD_REPLACE); > if (ret != LDB_SUCCESS) { > return NT_STATUS_NO_MEMORY; > } >@@ -2148,28 +2137,30 @@ static NTSTATUS setInfoTrustedDomain_base(struct dcesrv_call_state *dce_call, > } > > if (add_incoming || del_incoming) { >- ret = ldb_msg_add_empty(msg, "trustAuthIncoming", >- LDB_FLAG_MOD_REPLACE, NULL); >- if (ret != LDB_SUCCESS) { >- return NT_STATUS_NO_MEMORY; >- } > if (add_incoming) { >- ret = ldb_msg_add_value(msg, "trustAuthIncoming", >- &trustAuthIncoming, NULL); >+ ret = ldb_msg_append_value(msg, "trustAuthIncoming", >+ &trustAuthIncoming, LDB_FLAG_MOD_REPLACE); >+ if (ret != LDB_SUCCESS) { >+ return NT_STATUS_NO_MEMORY; >+ } >+ } else { >+ ret = ldb_msg_add_empty(msg, "trustAuthIncoming", >+ LDB_FLAG_MOD_REPLACE, NULL); > if (ret != LDB_SUCCESS) { > return NT_STATUS_NO_MEMORY; > } > } > } > if (add_outgoing || del_outgoing) { >- ret = ldb_msg_add_empty(msg, "trustAuthOutgoing", >- LDB_FLAG_MOD_REPLACE, NULL); >- if (ret != LDB_SUCCESS) { >- return NT_STATUS_NO_MEMORY; >- } > if (add_outgoing) { >- ret = ldb_msg_add_value(msg, "trustAuthOutgoing", >- &trustAuthOutgoing, NULL); >+ ret = ldb_msg_append_value(msg, "trustAuthOutgoing", >+ &trustAuthOutgoing, LDB_FLAG_MOD_REPLACE); >+ if (ret != LDB_SUCCESS) { >+ return NT_STATUS_NO_MEMORY; >+ } >+ } else { >+ ret = ldb_msg_add_empty(msg, "trustAuthOutgoing", >+ LDB_FLAG_MOD_REPLACE, NULL); > if (ret != LDB_SUCCESS) { > return NT_STATUS_NO_MEMORY; > } >@@ -4617,14 +4608,8 @@ static NTSTATUS dcesrv_lsa_lsaRSetForestTrustInformation(struct dcesrv_call_stat > goto done; > } > >- ret = ldb_msg_add_empty(msg, "msDS-TrustForestTrustInfo", >- LDB_FLAG_MOD_REPLACE, NULL); >- if (ret != LDB_SUCCESS) { >- status = NT_STATUS_NO_MEMORY; >- goto done; >- } >- ret = ldb_msg_add_value(msg, "msDS-TrustForestTrustInfo", >- &ft_blob, NULL); >+ ret = ldb_msg_append_value(msg, "msDS-TrustForestTrustInfo", >+ &ft_blob, LDB_FLAG_MOD_REPLACE); > if (ret != LDB_SUCCESS) { > status = NT_STATUS_NO_MEMORY; > goto done; >diff --git a/source4/winbind/idmap.c b/source4/winbind/idmap.c >index c4039be473a..c6375f8357a 100644 >--- a/source4/winbind/idmap.c >+++ b/source4/winbind/idmap.c >@@ -672,14 +672,8 @@ static NTSTATUS idmap_sid_to_xid(struct idmap_context *idmap_ctx, > vals[1].data = (uint8_t *)hwm_string; > vals[1].length = strlen(hwm_string); > } else { >- ret = ldb_msg_add_empty(hwm_msg, "xidNumber", LDB_FLAG_MOD_ADD, >- NULL); >- if (ret != LDB_SUCCESS) { >- status = NT_STATUS_NONE_MAPPED; >- goto failed; >- } >- >- ret = ldb_msg_add_string(hwm_msg, "xidNumber", hwm_string); >+ ret = ldb_msg_append_string(hwm_msg, "xidNumber", hwm_string, >+ LDB_FLAG_MOD_ADD); > if (ret != LDB_SUCCESS) > { > status = NT_STATUS_NONE_MAPPED; >-- >2.25.1 > > >From 9b481fafa14cdd55dfabf120ada8f2bc94ca5d86 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Tue, 14 Jun 2022 15:43:26 +1200 >Subject: [PATCH 06/10] ldb: Release LDB 2.6.1 > >* CVE-2022-32746 Use-after-free occurring in database audit logging module (bug 15009) > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >--- > lib/ldb/ABI/ldb-2.6.1.sigs | 291 ++++++++++++++++++++++++++++++ > lib/ldb/ABI/pyldb-util-2.6.1.sigs | 3 + > lib/ldb/wscript | 2 +- > 3 files changed, 295 insertions(+), 1 deletion(-) > create mode 100644 lib/ldb/ABI/ldb-2.6.1.sigs > create mode 100644 lib/ldb/ABI/pyldb-util-2.6.1.sigs > >diff --git a/lib/ldb/ABI/ldb-2.6.1.sigs b/lib/ldb/ABI/ldb-2.6.1.sigs >new file mode 100644 >index 00000000000..40388d9e330 >--- /dev/null >+++ b/lib/ldb/ABI/ldb-2.6.1.sigs >@@ -0,0 +1,291 @@ >+ldb_add: int (struct ldb_context *, const struct ldb_message *) >+ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) >+ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) >+ldb_attr_casefold: char *(TALLOC_CTX *, const char *) >+ldb_attr_dn: int (const char *) >+ldb_attr_in_list: int (const char * const *, const char *) >+ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) >+ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) >+ldb_base64_decode: int (char *) >+ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) >+ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) >+ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) >+ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) >+ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) >+ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) >+ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) >+ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) >+ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) >+ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) >+ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) >+ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) >+ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) >+ldb_check_critical_controls: int (struct ldb_control **) >+ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) >+ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) >+ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) >+ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) >+ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) >+ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) >+ldb_debug_add: void (struct ldb_context *, const char *, ...) >+ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) >+ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) >+ldb_delete: int (struct ldb_context *, struct ldb_dn *) >+ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) >+ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) >+ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) >+ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) >+ldb_dn_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) >+ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) >+ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) >+ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) >+ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) >+ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) >+ldb_dn_check_special: bool (struct ldb_dn *, const char *) >+ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) >+ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) >+ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) >+ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) >+ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) >+ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) >+ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) >+ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) >+ldb_dn_get_casefold: const char *(struct ldb_dn *) >+ldb_dn_get_comp_num: int (struct ldb_dn *) >+ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) >+ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) >+ldb_dn_get_extended_comp_num: int (struct ldb_dn *) >+ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) >+ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) >+ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) >+ldb_dn_get_linearized: const char *(struct ldb_dn *) >+ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) >+ldb_dn_get_rdn_name: const char *(struct ldb_dn *) >+ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) >+ldb_dn_has_extended: bool (struct ldb_dn *) >+ldb_dn_is_null: bool (struct ldb_dn *) >+ldb_dn_is_special: bool (struct ldb_dn *) >+ldb_dn_is_valid: bool (struct ldb_dn *) >+ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) >+ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) >+ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) >+ldb_dn_minimise: bool (struct ldb_dn *) >+ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) >+ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) >+ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) >+ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) >+ldb_dn_remove_extended_components: void (struct ldb_dn *) >+ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) >+ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) >+ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) >+ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) >+ldb_dn_validate: bool (struct ldb_dn *) >+ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) >+ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) >+ldb_errstring: const char *(struct ldb_context *) >+ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) >+ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) >+ldb_filter_attrs: int (struct ldb_context *, const struct ldb_message *, const char * const *, struct ldb_message *) >+ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) >+ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) >+ldb_get_create_perms: unsigned int (struct ldb_context *) >+ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) >+ldb_get_event_context: struct tevent_context *(struct ldb_context *) >+ldb_get_flags: unsigned int (struct ldb_context *) >+ldb_get_opaque: void *(struct ldb_context *, const char *) >+ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) >+ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) >+ldb_global_init: int (void) >+ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) >+ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) >+ldb_handle_use_global_event_context: void (struct ldb_handle *) >+ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) >+ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) >+ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) >+ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) >+ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) >+ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) >+ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) >+ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) >+ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) >+ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) >+ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) >+ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) >+ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) >+ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) >+ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) >+ldb_load_modules: int (struct ldb_context *, const char **) >+ldb_map_add: int (struct ldb_module *, struct ldb_request *) >+ldb_map_delete: int (struct ldb_module *, struct ldb_request *) >+ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) >+ldb_map_modify: int (struct ldb_module *, struct ldb_request *) >+ldb_map_rename: int (struct ldb_module *, struct ldb_request *) >+ldb_map_search: int (struct ldb_module *, struct ldb_request *) >+ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) >+ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) >+ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) >+ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) >+ldb_mod_register_control: int (struct ldb_module *, const char *) >+ldb_modify: int (struct ldb_context *, const struct ldb_message *) >+ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) >+ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) >+ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) >+ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) >+ldb_module_flags: uint32_t (struct ldb_context *) >+ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) >+ldb_module_get_name: const char *(struct ldb_module *) >+ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) >+ldb_module_get_private: void *(struct ldb_module *) >+ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) >+ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) >+ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) >+ldb_module_next: struct ldb_module *(struct ldb_module *) >+ldb_module_popt_options: struct poptOption **(struct ldb_context *) >+ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) >+ldb_module_send_referral: int (struct ldb_request *, char *) >+ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) >+ldb_module_set_private: void (struct ldb_module *, void *) >+ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) >+ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) >+ldb_modules_load: int (const char *, const char *) >+ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) >+ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) >+ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) >+ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) >+ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) >+ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) >+ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) >+ldb_msg_add_string_flags: int (struct ldb_message *, const char *, const char *, int) >+ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) >+ldb_msg_append_fmt: int (struct ldb_message *, int, const char *, const char *, ...) >+ldb_msg_append_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *, int) >+ldb_msg_append_steal_string: int (struct ldb_message *, const char *, char *, int) >+ldb_msg_append_steal_value: int (struct ldb_message *, const char *, struct ldb_val *, int) >+ldb_msg_append_string: int (struct ldb_message *, const char *, const char *, int) >+ldb_msg_append_value: int (struct ldb_message *, const char *, const struct ldb_val *, int) >+ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) >+ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) >+ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) >+ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) >+ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) >+ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) >+ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) >+ldb_msg_element_add_value: int (TALLOC_CTX *, struct ldb_message_element *, const struct ldb_val *) >+ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) >+ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) >+ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) >+ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) >+ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) >+ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) >+ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) >+ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) >+ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) >+ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) >+ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) >+ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) >+ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) >+ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) >+ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) >+ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) >+ldb_msg_new: struct ldb_message *(TALLOC_CTX *) >+ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) >+ldb_msg_remove_attr: void (struct ldb_message *, const char *) >+ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) >+ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) >+ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) >+ldb_msg_sort_elements: void (struct ldb_message *) >+ldb_next_del_trans: int (struct ldb_module *) >+ldb_next_end_trans: int (struct ldb_module *) >+ldb_next_init: int (struct ldb_module *) >+ldb_next_prepare_commit: int (struct ldb_module *) >+ldb_next_read_lock: int (struct ldb_module *) >+ldb_next_read_unlock: int (struct ldb_module *) >+ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) >+ldb_next_request: int (struct ldb_module *, struct ldb_request *) >+ldb_next_start_trans: int (struct ldb_module *) >+ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) >+ldb_options_copy: const char **(TALLOC_CTX *, const char **) >+ldb_options_find: const char *(struct ldb_context *, const char **, const char *) >+ldb_options_get: const char **(struct ldb_context *) >+ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *, uint32_t) >+ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) >+ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) >+ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) >+ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) >+ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) >+ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) >+ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) >+ldb_register_backend: int (const char *, ldb_connect_fn, bool) >+ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) >+ldb_register_hook: int (ldb_hook_fn) >+ldb_register_module: int (const struct ldb_module_ops *) >+ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) >+ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) >+ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) >+ldb_req_get_custom_flags: uint32_t (struct ldb_request *) >+ldb_req_is_untrusted: bool (struct ldb_request *) >+ldb_req_location: const char *(struct ldb_request *) >+ldb_req_mark_trusted: void (struct ldb_request *) >+ldb_req_mark_untrusted: void (struct ldb_request *) >+ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) >+ldb_req_set_location: void (struct ldb_request *, const char *) >+ldb_request: int (struct ldb_context *, struct ldb_request *) >+ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) >+ldb_request_done: int (struct ldb_request *, int) >+ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) >+ldb_request_get_status: int (struct ldb_request *) >+ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) >+ldb_request_set_state: void (struct ldb_request *, int) >+ldb_reset_err_string: void (struct ldb_context *) >+ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) >+ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) >+ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) >+ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) >+ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) >+ldb_schema_attribute_remove: void (struct ldb_context *, const char *) >+ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) >+ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) >+ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) >+ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) >+ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) >+ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) >+ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) >+ldb_set_create_perms: void (struct ldb_context *, unsigned int) >+ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) >+ldb_set_debug_stderr: int (struct ldb_context *) >+ldb_set_default_dns: void (struct ldb_context *) >+ldb_set_errstring: void (struct ldb_context *, const char *) >+ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) >+ldb_set_flags: void (struct ldb_context *, unsigned int) >+ldb_set_modules_dir: void (struct ldb_context *, const char *) >+ldb_set_opaque: int (struct ldb_context *, const char *, void *) >+ldb_set_require_private_event_context: void (struct ldb_context *) >+ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) >+ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) >+ldb_set_utf8_default: void (struct ldb_context *) >+ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) >+ldb_setup_wellknown_attributes: int (struct ldb_context *) >+ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) >+ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) >+ldb_strerror: const char *(int) >+ldb_string_to_time: time_t (const char *) >+ldb_string_utc_to_time: time_t (const char *) >+ldb_timestring: char *(TALLOC_CTX *, time_t) >+ldb_timestring_utc: char *(TALLOC_CTX *, time_t) >+ldb_transaction_cancel: int (struct ldb_context *) >+ldb_transaction_cancel_noerr: int (struct ldb_context *) >+ldb_transaction_commit: int (struct ldb_context *) >+ldb_transaction_prepare_commit: int (struct ldb_context *) >+ldb_transaction_start: int (struct ldb_context *) >+ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) >+ldb_unpack_data_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, unsigned int) >+ldb_unpack_get_format: int (const struct ldb_val *, uint32_t *) >+ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) >+ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) >+ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) >+ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) >+ldb_val_string_cmp: int (const struct ldb_val *, const char *) >+ldb_val_to_time: int (const struct ldb_val *, time_t *) >+ldb_valid_attr_name: int (const char *) >+ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) >+ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) >diff --git a/lib/ldb/ABI/pyldb-util-2.6.1.sigs b/lib/ldb/ABI/pyldb-util-2.6.1.sigs >new file mode 100644 >index 00000000000..164a806b2ff >--- /dev/null >+++ b/lib/ldb/ABI/pyldb-util-2.6.1.sigs >@@ -0,0 +1,3 @@ >+pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) >+pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) >+pyldb_check_type: bool (PyObject *, const char *) >diff --git a/lib/ldb/wscript b/lib/ldb/wscript >index 63d0ceaf234..60bb7cf48b3 100644 >--- a/lib/ldb/wscript >+++ b/lib/ldb/wscript >@@ -2,7 +2,7 @@ > > APPNAME = 'ldb' > # For Samba 4.17.x >-VERSION = '2.6.0' >+VERSION = '2.6.1' > > import sys, os > >-- >2.25.1 > > >From 8de845d1c2c751386587e8d820384bef20f8b565 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 07/10] 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 ab8c0067bf046cad908df75b15c609341e937bf2 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 08/10] 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 72b7b07e617ebef4f533a5bc48a0b958645ab0cd 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 09/10] 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 bb26e931ff73d3591df07a3c78901b1cb286d8c8 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 10/10] 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 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Flags:
jsutton
:
ci-passed-
Actions:
View
Attachments on
bug 15096
:
17344
|
17376
|
17380
|
17382
|
17383
|
17384
|
17385
|
17435
|
17448