diff --git a/backport-0001-CVE-2023-0614.patch b/backport-0001-CVE-2023-0614.patch deleted file mode 100644 index 1fd382b3b3de70e8c977c6ac9028a702006bccc2..0000000000000000000000000000000000000000 --- a/backport-0001-CVE-2023-0614.patch +++ /dev/null @@ -1,174 +0,0 @@ -From 197d1f09158ee0575cd92c461ed12bdbf4efc074 Mon Sep 17 00:00:00 2001 -From: Andrew Bartlett -Date: Mon, 13 Mar 2023 14:25:56 +1300 -Subject: [PATCH 01/35] CVE-2023-0614 lib/ldb: Avoid allocation and memcpy() - for every wildcard match candidate - -The value can be quite large, the allocation will take much -longer than the actual match and is repeated per candidate -record. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15331 -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15270 - -Signed-off-by: Andrew Bartlett -Reviewed-by: Joseph Sutton -(cherry picked from commit cad96f59a08192df927fb1df4e9787c7f70991a2) - -[abartlet@samba.org Included in the security release as this - makes the new large_ldap.py timeout test more reliable] - -Conflict: NA -Reference: https://attachments.samba.org/attachment.cgi?id=17821 ---- - common/ldb_match.c | 60 +++++++++++++++++++++++++++++++------- - 1 file changed, 50 insertions(+), 10 deletions(-) - -diff --git a/common/ldb_match.c b/common/ldb_match.c -index 2f4d41f3441..51376871b4c 100644 ---- a/common/ldb_match.c -+++ b/common/ldb_match.c -@@ -34,6 +34,7 @@ - - #include "ldb_private.h" - #include "dlinklist.h" -+#include "ldb_handlers.h" - - /* - check if the scope matches in a search result -@@ -259,20 +260,42 @@ static int ldb_wildcard_compare(struct ldb_context *ldb, - return LDB_SUCCESS; - } - -- if (a->syntax->canonicalise_fn(ldb, ldb, &value, &val) != 0) { -- return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; -+ /* No need to just copy this value for a binary match */ -+ if (a->syntax->canonicalise_fn != ldb_handler_copy) { -+ if (a->syntax->canonicalise_fn(ldb, ldb, &value, &val) != 0) { -+ return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; -+ } -+ -+ /* -+ * Only set save_p if we allocate (call -+ * a->syntax->canonicalise_fn()), as we -+ * talloc_free(save_p) below to clean up -+ */ -+ save_p = val.data; -+ } else { -+ val = value; - } - -- save_p = val.data; - cnk.data = NULL; - - if ( ! tree->u.substring.start_with_wildcard ) { -+ uint8_t *cnk_to_free = NULL; - - chunk = tree->u.substring.chunks[c]; -- if (a->syntax->canonicalise_fn(ldb, ldb, chunk, &cnk) != 0) goto mismatch; -+ /* No need to just copy this value for a binary match */ -+ if (a->syntax->canonicalise_fn != ldb_handler_copy) { -+ if (a->syntax->canonicalise_fn(ldb, ldb, chunk, &cnk) != 0) { -+ goto mismatch; -+ } -+ -+ cnk_to_free = cnk.data; -+ } else { -+ cnk = *chunk; -+ } - - /* This deals with wildcard prefix searches on binary attributes (eg objectGUID) */ - if (cnk.length > val.length) { -+ TALLOC_FREE(cnk_to_free); - goto mismatch; - } - /* -@@ -280,32 +303,47 @@ static int ldb_wildcard_compare(struct ldb_context *ldb, - * we can cope with this. - */ - if (cnk.length == 0) { -+ TALLOC_FREE(cnk_to_free); -+ goto mismatch; -+ } -+ -+ if (memcmp((char *)val.data, (char *)cnk.data, cnk.length) != 0) { -+ TALLOC_FREE(cnk_to_free); - goto mismatch; - } - -- if (memcmp((char *)val.data, (char *)cnk.data, cnk.length) != 0) goto mismatch; - val.length -= cnk.length; - val.data += cnk.length; - c++; -- talloc_free(cnk.data); -+ TALLOC_FREE(cnk_to_free); - cnk.data = NULL; - } - - while (tree->u.substring.chunks[c]) { - uint8_t *p; -+ uint8_t *cnk_to_free = NULL; - - chunk = tree->u.substring.chunks[c]; -- if(a->syntax->canonicalise_fn(ldb, ldb, chunk, &cnk) != 0) { -- goto mismatch; -+ /* No need to just copy this value for a binary match */ -+ if (a->syntax->canonicalise_fn != ldb_handler_copy) { -+ if (a->syntax->canonicalise_fn(ldb, ldb, chunk, &cnk) != 0) { -+ goto mismatch; -+ } -+ -+ cnk_to_free = cnk.data; -+ } else { -+ cnk = *chunk; - } - /* - * Empty strings are returned as length 0. Ensure - * we can cope with this. - */ - if (cnk.length == 0) { -+ TALLOC_FREE(cnk_to_free); - goto mismatch; - } - if (cnk.length > val.length) { -+ TALLOC_FREE(cnk_to_free); - goto mismatch; - } - -@@ -320,6 +358,8 @@ static int ldb_wildcard_compare(struct ldb_context *ldb, - cmp = memcmp(p, - cnk.data, - cnk.length); -+ TALLOC_FREE(cnk_to_free); -+ - if (cmp != 0) { - goto mismatch; - } -@@ -331,15 +371,16 @@ static int ldb_wildcard_compare(struct ldb_context *ldb, - p = memmem((const void *)val.data, val.length, - (const void *)cnk.data, cnk.length); - if (p == NULL) { -+ TALLOC_FREE(cnk_to_free); - goto mismatch; - } - /* move val to the end of the match */ - p += cnk.length; - val.length -= (p - val.data); - val.data = p; -+ TALLOC_FREE(cnk_to_free); - } - c++; -- TALLOC_FREE(cnk.data); - } - - talloc_free(save_p); -@@ -349,7 +390,6 @@ static int ldb_wildcard_compare(struct ldb_context *ldb, - mismatch: - *matched = false; - talloc_free(save_p); -- talloc_free(cnk.data); - return LDB_SUCCESS; - } - --- -2.25.1 diff --git a/backport-0002-CVE-2023-0614.patch b/backport-0002-CVE-2023-0614.patch deleted file mode 100644 index 8234477cee304cdd1f42311a5d3f59215d35e8a0..0000000000000000000000000000000000000000 --- a/backport-0002-CVE-2023-0614.patch +++ /dev/null @@ -1,72 +0,0 @@ -From b01d3ae3261264236504475a26c54ab45dd2175f Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Fri, 27 Jan 2023 08:28:36 +1300 -Subject: [PATCH 05/34] CVE-2023-0614 ldb: Add functions for handling - inaccessible message elements - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15270 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett - -Conflict: NA -Reference: https://attachments.samba.org/attachment.cgi?id=17821 ---- - common/ldb_msg.c | 26 ++++++++++++++++++++++++++ - include/ldb_module.h | 4 ++++ - 2 files changed, 30 insertions(+) - -diff --git a/common/ldb_msg.c b/common/ldb_msg.c -index 9cd7998e21c..cbc7e32b2ba 100644 ---- a/common/ldb_msg.c -+++ b/common/ldb_msg.c -@@ -795,6 +795,32 @@ int ldb_msg_element_compare_name(struct ldb_message_element *el1, - return ldb_attr_cmp(el1->name, el2->name); - } - -+void ldb_msg_element_mark_inaccessible(struct ldb_message_element *el) -+{ -+ el->flags |= LDB_FLAG_INTERNAL_INACCESSIBLE_ATTRIBUTE; -+} -+ -+bool ldb_msg_element_is_inaccessible(const struct ldb_message_element *el) -+{ -+ return (el->flags & LDB_FLAG_INTERNAL_INACCESSIBLE_ATTRIBUTE) != 0; -+} -+ -+void ldb_msg_remove_inaccessible(struct ldb_message *msg) -+{ -+ unsigned i; -+ unsigned num_del = 0; -+ -+ for (i = 0; i < msg->num_elements; ++i) { -+ if (ldb_msg_element_is_inaccessible(&msg->elements[i])) { -+ ++num_del; -+ } else if (num_del) { -+ msg->elements[i - num_del] = msg->elements[i]; -+ } -+ } -+ -+ msg->num_elements -= num_del; -+} -+ - /* - convenience functions to return common types from a message - these return the first value if the attribute is multi-valued -diff --git a/include/ldb_module.h b/include/ldb_module.h -index 4c7c85a17f0..8481fd3991a 100644 ---- a/include/ldb_module.h -+++ b/include/ldb_module.h -@@ -513,6 +513,10 @@ struct ldb_extended_match_rule - int ldb_register_extended_match_rule(struct ldb_context *ldb, - const struct ldb_extended_match_rule *rule); - -+void ldb_msg_element_mark_inaccessible(struct ldb_message_element *el); -+bool ldb_msg_element_is_inaccessible(const struct ldb_message_element *el); -+void ldb_msg_remove_inaccessible(struct ldb_message *msg); -+ - /* - * these pack/unpack functions are exposed in the library for use by - * ldb tools like ldbdump and for use in tests, --- -2.25.1 diff --git a/backport-0003-CVE-2023-0614.patch b/backport-0003-CVE-2023-0614.patch deleted file mode 100644 index 47be7eea02910d17fbf0f787acc634a30d78573c..0000000000000000000000000000000000000000 --- a/backport-0003-CVE-2023-0614.patch +++ /dev/null @@ -1,409 +0,0 @@ -From e7445d18badee6c3b1bbee48c689eb2629c31681 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Wed, 15 Feb 2023 12:34:51 +1300 -Subject: [PATCH 07/34] CVE-2023-0614 ldb:tests: Ensure ldb_val data is - zero-terminated - -If the value of an ldb message element is not zero-terminated, calling -ldb_msg_find_attr_as_string() will cause the function to read off the -end of the buffer in an attempt to verify that the value is -zero-terminated. This can cause unexpected behaviour and make the test -randomly fail. - -To avoid this, we must have a terminating null byte that is *not* -counted as part of the length, and so we must calculate the length with -strlen() rather than sizeof. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15270 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett - -Conflict: NA -Reference: https://attachments.samba.org/attachment.cgi?id=17821 ---- - tests/ldb_filter_attrs_test.c | 171 +++++++++++++------------- - 1 file changed, 86 insertions(+), 85 deletions(-) - -diff --git a/tests/ldb_filter_attrs_test.c b/tests/ldb_filter_attrs_test.c -index 7d555e0da2e..442d9c77ed2 100644 ---- a/tests/ldb_filter_attrs_test.c -+++ b/tests/ldb_filter_attrs_test.c -@@ -36,6 +36,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -96,10 +97,10 @@ static void test_filter_attrs_one_attr_matched(void **state) - - const char *attrs[] = {"foo", NULL}; - -- uint8_t value[] = "The value.......end"; -+ char value[] = "The value.......end"; - struct ldb_val value_1 = { -- .data = value, -- .length = (sizeof(value)) -+ .data = (uint8_t *)value, -+ .length = strlen(value) - }; - struct ldb_message_element element_1 = { - .name = "foo", -@@ -130,9 +131,9 @@ static void test_filter_attrs_one_attr_matched(void **state) - assert_string_equal(filtered_msg->elements[0].name, "foo"); - assert_int_equal(filtered_msg->elements[0].num_values, 1); - assert_int_equal(filtered_msg->elements[0].values[0].length, -- sizeof(value)); -+ strlen(value)); - assert_memory_equal(filtered_msg->elements[0].values[0].data, -- value, sizeof(value)); -+ value, strlen(value)); - } - - /* -@@ -148,10 +149,10 @@ static void test_filter_attrs_one_attr_matched_of_many(void **state) - - const char *attrs[] = {"foo", "bar", "baz", NULL}; - -- uint8_t value[] = "The value.......end"; -+ char value[] = "The value.......end"; - struct ldb_val value_1 = { -- .data = value, -- .length = (sizeof(value)) -+ .data = (uint8_t *)value, -+ .length = strlen(value) - }; - struct ldb_message_element element_1 = { - .name = "foo", -@@ -182,9 +183,9 @@ static void test_filter_attrs_one_attr_matched_of_many(void **state) - assert_string_equal(filtered_msg->elements[0].name, "foo"); - assert_int_equal(filtered_msg->elements[0].num_values, 1); - assert_int_equal(filtered_msg->elements[0].values[0].length, -- sizeof(value)); -+ strlen(value)); - assert_memory_equal(filtered_msg->elements[0].values[0].data, -- value, sizeof(value)); -+ value, strlen(value)); - } - - /* -@@ -201,15 +202,15 @@ static void test_filter_attrs_two_attr_matched_attrs(void **state) - /* deliberatly the other order */ - const char *attrs[] = {"bar", "foo", NULL}; - -- uint8_t value1[] = "The value.......end"; -- uint8_t value2[] = "The value..MUST.end"; -+ char value1[] = "The value.......end"; -+ char value2[] = "The value..MUST.end"; - struct ldb_val value_1 = { -- .data = value1, -- .length = (sizeof(value1)) -+ .data = (uint8_t *)value1, -+ .length = strlen(value1) - }; - struct ldb_val value_2 = { -- .data = value2, -- .length = (sizeof(value2)) -+ .data = (uint8_t *)value2, -+ .length = strlen(value2) - }; - - /* foo and bar are the other order to in attrs */ -@@ -251,15 +252,15 @@ static void test_filter_attrs_two_attr_matched_attrs(void **state) - assert_string_equal(filtered_msg->elements[0].name, "foo"); - assert_int_equal(filtered_msg->elements[0].num_values, 1); - assert_int_equal(filtered_msg->elements[0].values[0].length, -- sizeof(value1)); -+ strlen(value1)); - assert_memory_equal(filtered_msg->elements[0].values[0].data, -- value1, sizeof(value1)); -+ value1, strlen(value1)); - assert_string_equal(filtered_msg->elements[1].name, "bar"); - assert_int_equal(filtered_msg->elements[1].num_values, 1); - assert_int_equal(filtered_msg->elements[1].values[0].length, -- sizeof(value2)); -+ strlen(value2)); - assert_memory_equal(filtered_msg->elements[1].values[0].data, -- value2, sizeof(value2)); -+ value2, strlen(value2)); - } - - /* -@@ -276,15 +277,15 @@ static void test_filter_attrs_two_attr_matched_one_attr(void **state) - /* deliberatly the other order */ - const char *attrs[] = {"bar", NULL}; - -- uint8_t value1[] = "The value.......end"; -- uint8_t value2[] = "The value..MUST.end"; -+ char value1[] = "The value.......end"; -+ char value2[] = "The value..MUST.end"; - struct ldb_val value_1 = { -- .data = value1, -- .length = (sizeof(value1)) -+ .data = (uint8_t *)value1, -+ .length = strlen(value1) - }; - struct ldb_val value_2 = { -- .data = value2, -- .length = (sizeof(value2)) -+ .data = (uint8_t *)value2, -+ .length = strlen(value2) - }; - - /* foo and bar are the other order to in attrs */ -@@ -326,9 +327,9 @@ static void test_filter_attrs_two_attr_matched_one_attr(void **state) - assert_string_equal(filtered_msg->elements[0].name, "bar"); - assert_int_equal(filtered_msg->elements[0].num_values, 1); - assert_int_equal(filtered_msg->elements[0].values[0].length, -- sizeof(value2)); -+ strlen(value2)); - assert_memory_equal(filtered_msg->elements[0].values[0].data, -- value2, sizeof(value2)); -+ value2, strlen(value2)); - } - - /* -@@ -345,15 +346,15 @@ static void test_filter_attrs_two_dup_attr_matched_one_attr(void **state) - /* deliberatly the other order */ - const char *attrs[] = {"bar", NULL}; - -- uint8_t value1[] = "The value.......end"; -- uint8_t value2[] = "The value..MUST.end"; -+ char value1[] = "The value.......end"; -+ char value2[] = "The value..MUST.end"; - struct ldb_val value_1 = { -- .data = value1, -- .length = (sizeof(value1)) -+ .data = (uint8_t *)value1, -+ .length = strlen(value1) - }; - struct ldb_val value_2 = { -- .data = value2, -- .length = (sizeof(value2)) -+ .data = (uint8_t *)value2, -+ .length = strlen(value2) - }; - - /* foo and bar are the other order to in attrs */ -@@ -400,15 +401,15 @@ static void test_filter_attrs_two_dup_attr_matched_dup(void **state) - - const char *attrs[] = {"bar", "bar", NULL}; - -- uint8_t value1[] = "The value.......end"; -- uint8_t value2[] = "The value..MUST.end"; -+ char value1[] = "The value.......end"; -+ char value2[] = "The value..MUST.end"; - struct ldb_val value_1 = { -- .data = value1, -- .length = (sizeof(value1)) -+ .data = (uint8_t *)value1, -+ .length = strlen(value1) - }; - struct ldb_val value_2 = { -- .data = value2, -- .length = (sizeof(value2)) -+ .data = (uint8_t *)value2, -+ .length = strlen(value2) - }; - - /* foo and bar are the other order to in attrs */ -@@ -445,15 +446,15 @@ static void test_filter_attrs_two_dup_attr_matched_dup(void **state) - assert_string_equal(filtered_msg->elements[0].name, "bar"); - assert_int_equal(filtered_msg->elements[0].num_values, 1); - assert_int_equal(filtered_msg->elements[0].values[0].length, -- sizeof(value1)); -+ strlen(value1)); - assert_memory_equal(filtered_msg->elements[0].values[0].data, -- value1, sizeof(value1)); -+ value1, strlen(value1)); - assert_string_equal(filtered_msg->elements[1].name, "bar"); - assert_int_equal(filtered_msg->elements[1].num_values, 1); - assert_int_equal(filtered_msg->elements[1].values[0].length, -- sizeof(value2)); -+ strlen(value2)); - assert_memory_equal(filtered_msg->elements[1].values[0].data, -- value2, sizeof(value2)); -+ value2, strlen(value2)); - } - - /* -@@ -469,15 +470,15 @@ static void test_filter_attrs_two_dup_attr_matched_one_of_two(void **state) - - const char *attrs[] = {"bar", "foo", NULL}; - -- uint8_t value1[] = "The value.......end"; -- uint8_t value2[] = "The value..MUST.end"; -+ char value1[] = "The value.......end"; -+ char value2[] = "The value..MUST.end"; - struct ldb_val value_1 = { -- .data = value1, -- .length = (sizeof(value1)) -+ .data = (uint8_t *)value1, -+ .length = strlen(value1) - }; - struct ldb_val value_2 = { -- .data = value2, -- .length = (sizeof(value2)) -+ .data = (uint8_t *)value2, -+ .length = strlen(value2) - }; - - /* foo and bar are the other order to in attrs */ -@@ -514,15 +515,15 @@ static void test_filter_attrs_two_dup_attr_matched_one_of_two(void **state) - assert_string_equal(filtered_msg->elements[0].name, "bar"); - assert_int_equal(filtered_msg->elements[0].num_values, 1); - assert_int_equal(filtered_msg->elements[0].values[0].length, -- sizeof(value1)); -+ strlen(value1)); - assert_memory_equal(filtered_msg->elements[0].values[0].data, -- value1, sizeof(value1)); -+ value1, strlen(value1)); - assert_string_equal(filtered_msg->elements[1].name, "bar"); - assert_int_equal(filtered_msg->elements[1].num_values, 1); - assert_int_equal(filtered_msg->elements[1].values[0].length, -- sizeof(value2)); -+ strlen(value2)); - assert_memory_equal(filtered_msg->elements[1].values[0].data, -- value2, sizeof(value2)); -+ value2, strlen(value2)); - } - - /* -@@ -538,15 +539,15 @@ static void test_filter_attrs_two_dup_attr_matched_star(void **state) - - const char *attrs[] = {"*", "foo", NULL}; - -- uint8_t value1[] = "The value.......end"; -- uint8_t value2[] = "The value..MUST.end"; -+ char value1[] = "The value.......end"; -+ char value2[] = "The value..MUST.end"; - struct ldb_val value_1 = { -- .data = value1, -- .length = (sizeof(value1)) -+ .data = (uint8_t *)value1, -+ .length = strlen(value1) - }; - struct ldb_val value_2 = { -- .data = value2, -- .length = (sizeof(value2)) -+ .data = (uint8_t *)value2, -+ .length = strlen(value2) - }; - - /* foo and bar are the other order to in attrs */ -@@ -586,15 +587,15 @@ static void test_filter_attrs_two_dup_attr_matched_star(void **state) - assert_string_equal(filtered_msg->elements[0].name, "bar"); - assert_int_equal(filtered_msg->elements[0].num_values, 1); - assert_int_equal(filtered_msg->elements[0].values[0].length, -- sizeof(value1)); -+ strlen(value1)); - assert_memory_equal(filtered_msg->elements[0].values[0].data, -- value1, sizeof(value1)); -+ value1, strlen(value1)); - assert_string_equal(filtered_msg->elements[1].name, "bar"); - assert_int_equal(filtered_msg->elements[1].num_values, 1); - assert_int_equal(filtered_msg->elements[1].values[0].length, -- sizeof(value2)); -+ strlen(value2)); - assert_memory_equal(filtered_msg->elements[1].values[0].data, -- value2, sizeof(value2)); -+ value2, strlen(value2)); - /* - * assert the ldb_filter_attrs does not modify filtered_msg.dn - * in this case -@@ -619,10 +620,10 @@ static void test_filter_attrs_one_attr_matched_star(void **state) - - const char *attrs[] = {"*", NULL}; - -- uint8_t value[] = "The value.......end"; -+ char value[] = "The value.......end"; - struct ldb_val value_1 = { -- .data = value, -- .length = (sizeof(value)) -+ .data = (uint8_t *)value, -+ .length = strlen(value) - }; - struct ldb_message_element element_1 = { - .name = "foo", -@@ -676,15 +677,15 @@ static void test_filter_attrs_two_attr_matched_star(void **state) - - const char *attrs[] = {"*", NULL}; - -- uint8_t value1[] = "The value.......end"; -- uint8_t value2[] = "The value..MUST.end"; -+ char value1[] = "The value.......end"; -+ char value2[] = "The value..MUST.end"; - struct ldb_val value_1 = { -- .data = value1, -- .length = (sizeof(value1)) -+ .data = (uint8_t *)value1, -+ .length = strlen(value1) - }; - struct ldb_val value_2 = { -- .data = value2, -- .length = (sizeof(value2)) -+ .data = (uint8_t *)value2, -+ .length = strlen(value2) - }; - struct ldb_message_element elements[] = { - { -@@ -750,10 +751,10 @@ static void test_filter_attrs_one_attr_matched_star_no_dn(void **state) - - const char *attrs[] = {"*", NULL}; - -- uint8_t value[] = "The value.......end"; -+ char value[] = "The value.......end"; - struct ldb_val value_1 = { -- .data = value, -- .length = (sizeof(value)) -+ .data = (uint8_t *)value, -+ .length = strlen(value) - }; - struct ldb_message_element element_1 = { - .name = "foo", -@@ -789,10 +790,10 @@ static void test_filter_attrs_one_attr_matched_star_dn(void **state) - - const char *attrs[] = {"*", "distinguishedName", NULL}; - -- uint8_t value[] = "The value.......end"; -+ char value[] = "The value.......end"; - struct ldb_val value_1 = { -- .data = value, -- .length = (sizeof(value)) -+ .data = (uint8_t *)value, -+ .length = strlen(value) - }; - struct ldb_message_element element_1 = { - .name = "foo", -@@ -844,10 +845,10 @@ static void test_filter_attrs_one_attr_matched_dn(void **state) - - const char *attrs[] = {"distinguishedName", NULL}; - -- uint8_t value[] = "The value.......end"; -+ char value[] = "The value.......end"; - struct ldb_val value_1 = { -- .data = value, -- .length = (sizeof(value)) -+ .data = (uint8_t *)value, -+ .length = strlen(value) - }; - struct ldb_message_element element_1 = { - .name = "foo", -@@ -894,10 +895,10 @@ static void test_filter_attrs_one_attr_empty_list(void **state) - - const char *attrs[] = {NULL}; - -- uint8_t value[] = "The value.......end"; -+ char value[] = "The value.......end"; - struct ldb_val value_1 = { -- .data = value, -- .length = (sizeof(value)) -+ .data = (uint8_t *)value, -+ .length = strlen(value) - }; - struct ldb_message_element element_1 = { - .name = "foo", --- -2.25.1 diff --git a/backport-0004-CVE-2023-0614.patch b/backport-0004-CVE-2023-0614.patch deleted file mode 100644 index 8f32e016e5a2574435a22294fb9573ed0e2c0d9b..0000000000000000000000000000000000000000 --- a/backport-0004-CVE-2023-0614.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 936bfcb6ef804d2224072f3770ca09fe2596ee1f Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Wed, 15 Feb 2023 14:08:57 +1300 -Subject: [PATCH 08/34] CVE-2023-0614 ldb:tests: Ensure all tests are accounted - for - -Add ldb_filter_attrs_test to the list of tests so that it actually gets -run. - -Remove a duplicate ldb_msg_test that was accidentally added in commit -5ca90e758ade97fb5e335029c7a1768094e70564. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15270 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett - -Conflict: NA -Reference: https://attachments.samba.org/attachment.cgi?id=17821 ---- - wscript | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/wscript b/wscript -index 60bb7cf48b3..c862229822d 100644 ---- a/wscript -+++ b/wscript -@@ -627,7 +627,6 @@ def test(ctx): - 'ldb_msg_test', - 'ldb_tdb_mod_op_test', - 'ldb_tdb_guid_mod_op_test', -- 'ldb_msg_test', - 'ldb_tdb_kv_ops_test', - 'ldb_tdb_test', - 'ldb_match_test', -@@ -637,7 +636,9 @@ def test(ctx): - # on operations which the TDB backend does not currently - # support - # 'ldb_key_value_sub_txn_tdb_test' -- 'ldb_parse_test'] -+ 'ldb_parse_test', -+ 'ldb_filter_attrs_test', -+ ] - - # if LIB_LDAP and LIB_LBER defined, then we can test ldb_ldap backend - # behavior regression for bz#14413 --- -2.25.1 diff --git a/backport-0005-CVE-2023-0614.patch b/backport-0005-CVE-2023-0614.patch deleted file mode 100644 index 255b77abedcb3ffb7c034310a02b0ccb7beeea24..0000000000000000000000000000000000000000 --- a/backport-0005-CVE-2023-0614.patch +++ /dev/null @@ -1,104 +0,0 @@ -From 83217ce77381f8faa3cde948e15a36db234d3033 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Fri, 3 Mar 2023 17:23:42 +1300 -Subject: [PATCH 09/34] CVE-2023-0614 ldb: Add function to take ownership of an - ldb message - -Many places in Samba depend upon various components of an ldb message -being talloc allocated, and hence able to be used as talloc contexts. -The elements and values of an unpacked ldb message point to unowned data -inside the memory-mapped database, and this function ensures that such -messages have talloc ownership of said elements and values. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15270 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett - -Conflict: NA -Reference: https://attachments.samba.org/attachment.cgi?id=17821 ---- - common/ldb_pack.c | 41 ++++++++++++++++++++++++++++++++++++ - include/ldb_module.h | 4 ++++ - 2 files changed, 45 insertions(+) - -diff --git a/common/ldb_pack.c b/common/ldb_pack.c -index e7dd364008a..028d96a619a 100644 ---- a/common/ldb_pack.c -+++ b/common/ldb_pack.c -@@ -690,6 +690,7 @@ static int ldb_unpack_data_flags_v1(struct ldb_context *ldb, - element->values = NULL; - if ((flags & LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC) && element->num_values == 1) { - element->values = &ldb_val_single_array[nelem]; -+ element->flags |= LDB_FLAG_INTERNAL_SHARED_VALUES; - } else if (element->num_values != 0) { - element->values = talloc_array(message->elements, - struct ldb_val, -@@ -932,6 +933,7 @@ static int ldb_unpack_data_flags_v2(struct ldb_context *ldb, - if ((flags & LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC) && - element->num_values == 1) { - element->values = &ldb_val_single_array[nelem]; -+ element->flags |= LDB_FLAG_INTERNAL_SHARED_VALUES; - } else if (element->num_values != 0) { - element->values = talloc_array(message->elements, - struct ldb_val, -@@ -1259,3 +1261,42 @@ failed: - TALLOC_FREE(filtered_msg->elements); - return -1; - } -+ -+/* Have an unpacked ldb message take talloc ownership of its elements. */ -+int ldb_msg_elements_take_ownership(struct ldb_message *msg) -+{ -+ unsigned int i = 0; -+ -+ for (i = 0; i < msg->num_elements; i++) { -+ struct ldb_message_element *el = &msg->elements[i]; -+ const char *name; -+ unsigned int j; -+ -+ name = talloc_strdup(msg->elements, -+ el->name); -+ if (name == NULL) { -+ return -1; -+ } -+ el->name = name; -+ -+ if (el->flags & LDB_FLAG_INTERNAL_SHARED_VALUES) { -+ struct ldb_val *values = talloc_memdup(msg->elements, el->values, -+ sizeof(struct ldb_val) * el->num_values); -+ if (values == NULL) { -+ return -1; -+ } -+ el->values = values; -+ el->flags &= ~LDB_FLAG_INTERNAL_SHARED_VALUES; -+ } -+ -+ for (j = 0; j < el->num_values; j++) { -+ struct ldb_val val = ldb_val_dup(el->values, &el->values[j]); -+ if (val.data == NULL && el->values[j].length != 0) { -+ return -1; -+ } -+ el->values[j] = val; -+ } -+ } -+ -+ return LDB_SUCCESS; -+} -diff --git a/include/ldb_module.h b/include/ldb_module.h -index 8481fd3991a..8c7f33496fb 100644 ---- a/include/ldb_module.h -+++ b/include/ldb_module.h -@@ -542,6 +542,10 @@ int ldb_filter_attrs(struct ldb_context *ldb, - const struct ldb_message *msg, - const char *const *attrs, - struct ldb_message *filtered_msg); -+ -+/* Have an unpacked ldb message take talloc ownership of its elements. */ -+int ldb_msg_elements_take_ownership(struct ldb_message *msg); -+ - /* - * Unpack a ldb message from a linear buffer in ldb_val - * --- -2.25.1 diff --git a/backport-0006-CVE-2023-0614.patch b/backport-0006-CVE-2023-0614.patch deleted file mode 100644 index 141bacc1b8fc2ad705a49b75cd8504080713ae07..0000000000000000000000000000000000000000 --- a/backport-0006-CVE-2023-0614.patch +++ /dev/null @@ -1,62 +0,0 @@ -From a9b625bc8ab00b83b55bcd21ba0df48e73e4df29 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Fri, 3 Mar 2023 17:26:04 +1300 -Subject: [PATCH 10/34] CVE-2023-0614 ldb: Add function to remove excess - capacity from an ldb message - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15270 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett - -[abartlet@samba.org Adapted to conflict from lack of new -ldb_ascii_toupper() in ldb_private.h] - -Conflict: NA -Reference: https://attachments.samba.org/attachment.cgi?id=17821 ---- - common/ldb_msg.c | 16 ++++++++++++++++ - include/ldb_private.h | 3 +++ - 2 files changed, 19 insertions(+) - -diff --git a/common/ldb_msg.c b/common/ldb_msg.c -index cbc7e32b2ba..2ea2cce2e83 100644 ---- a/common/ldb_msg.c -+++ b/common/ldb_msg.c -@@ -1497,6 +1497,22 @@ void ldb_msg_remove_attr(struct ldb_message *msg, const char *attr) - } - } - -+/* Reallocate elements to drop any excess capacity. */ -+void ldb_msg_shrink_to_fit(struct ldb_message *msg) -+{ -+ if (msg->num_elements > 0) { -+ struct ldb_message_element *elements = talloc_realloc(msg, -+ msg->elements, -+ struct ldb_message_element, -+ msg->num_elements); -+ if (elements != NULL) { -+ msg->elements = elements; -+ } -+ } else { -+ TALLOC_FREE(msg->elements); -+ } -+} -+ - /* - return a LDAP formatted GeneralizedTime string - */ -diff --git a/include/ldb_private.h b/include/ldb_private.h -index 4deb24691ca..338e71def6d 100644 ---- a/include/ldb_private.h -+++ b/include/ldb_private.h -@@ -317,4 +317,7 @@ int ldb_match_message(struct ldb_context *ldb, - const struct ldb_parse_tree *tree, - enum ldb_scope scope, bool *matched); - -+/* Reallocate elements to drop any excess capacity. */ -+void ldb_msg_shrink_to_fit(struct ldb_message *msg); -+ - #endif --- -2.25.1 diff --git a/backport-0007-CVE-2023-0614.patch b/backport-0007-CVE-2023-0614.patch deleted file mode 100644 index ed4a854431980c383e382b54bf4e111b26b8f1ef..0000000000000000000000000000000000000000 --- a/backport-0007-CVE-2023-0614.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 8b7374780e3e7b67e51a1b54a09bf48d89fa9f26 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Fri, 3 Mar 2023 17:27:38 +1300 -Subject: [PATCH 11/34] CVE-2023-0614 ldb: Add function to add - distinguishedName to message - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15270 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett - -[abartlet@samba.org Adapted to conflict from lack of new -ldb_ascii_toupper() in ldb_private.h] - -Conflict: NA -Reference: https://attachments.samba.org/attachment.cgi?id=17821 ---- - common/ldb_pack.c | 6 +++--- - include/ldb_private.h | 5 +++++ - 2 files changed, 8 insertions(+), 3 deletions(-) - -diff --git a/common/ldb_pack.c b/common/ldb_pack.c -index 028d96a619a..b0b0d64a5ba 100644 ---- a/common/ldb_pack.c -+++ b/common/ldb_pack.c -@@ -1098,7 +1098,7 @@ int ldb_unpack_data(struct ldb_context *ldb, - /* - add the special distinguishedName element - */ --static int msg_add_distinguished_name(struct ldb_message *msg) -+int ldb_msg_add_distinguished_name(struct ldb_message *msg) - { - const char *dn_attr = "distinguishedName"; - char *dn = NULL; -@@ -1158,7 +1158,7 @@ int ldb_filter_attrs(struct ldb_context *ldb, - - /* Shortcuts for the simple cases */ - } else if (add_dn && i == 1) { -- if (msg_add_distinguished_name(filtered_msg) != 0) { -+ if (ldb_msg_add_distinguished_name(filtered_msg) != 0) { - goto failed; - } - return 0; -@@ -1238,7 +1238,7 @@ int ldb_filter_attrs(struct ldb_context *ldb, - filtered_msg->num_elements = num_elements; - - if (add_dn) { -- if (msg_add_distinguished_name(filtered_msg) != 0) { -+ if (ldb_msg_add_distinguished_name(filtered_msg) != 0) { - goto failed; - } - } -diff --git a/include/ldb_private.h b/include/ldb_private.h -index 338e71def6d..ca43817d07a 100644 ---- a/include/ldb_private.h -+++ b/include/ldb_private.h -@@ -320,4 +320,9 @@ int ldb_match_message(struct ldb_context *ldb, - /* Reallocate elements to drop any excess capacity. */ - void ldb_msg_shrink_to_fit(struct ldb_message *msg); - -+/* -+ add the special distinguishedName element -+*/ -+int ldb_msg_add_distinguished_name(struct ldb_message *msg); -+ - #endif --- -2.25.1 diff --git a/backport-0008-CVE-2023-0614.patch b/backport-0008-CVE-2023-0614.patch deleted file mode 100644 index cc7294c2fee65b3031b6b4f84585a33a33227014..0000000000000000000000000000000000000000 --- a/backport-0008-CVE-2023-0614.patch +++ /dev/null @@ -1,1224 +0,0 @@ -From 4f8b4ce403ff68ca26d33d7272276052829c96f7 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Fri, 3 Mar 2023 17:29:03 +1300 -Subject: [PATCH 12/34] CVE-2023-0614 ldb: Add function to filter message in - place - -At present this function is an exact duplicate of ldb_filter_attrs(), -but in the next commit we shall modify it to work in place, without the -need for the allocation of a second message. - -The test is a near duplicate of the existing test for -ldb_filter_attrs(). - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15270 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett - -Conflict: NA -Reference: https://attachments.samba.org/attachment.cgi?id=17821 ---- - common/ldb_pack.c | 143 +++ - include/ldb_module.h | 10 + - .../tests/ldb_filter_attrs_in_place_test.c | 989 ++++++++++++++++++ - wscript | 6 + - 4 files changed, 1148 insertions(+) - create mode 100644 tests/ldb_filter_attrs_in_place_test.c - -diff --git a/common/ldb_pack.c b/common/ldb_pack.c -index b0b0d64a5ba..f19ac73fa5e 100644 ---- a/common/ldb_pack.c -+++ b/common/ldb_pack.c -@@ -1262,6 +1262,149 @@ failed: - return -1; - } - -+/* -+ * filter the specified list of attributes from msg, -+ * adding requested attributes, and perhaps all for *, -+ * but not the DN to filtered_msg. -+ */ -+int ldb_filter_attrs_in_place(struct ldb_context *ldb, -+ const struct ldb_message *msg, -+ const char *const *attrs, -+ struct ldb_message *filtered_msg) -+{ -+ unsigned int i; -+ bool keep_all = false; -+ bool add_dn = false; -+ uint32_t num_elements; -+ uint32_t elements_size; -+ -+ if (attrs) { -+ /* check for special attrs */ -+ for (i = 0; attrs[i]; i++) { -+ int cmp = strcmp(attrs[i], "*"); -+ if (cmp == 0) { -+ keep_all = true; -+ break; -+ } -+ cmp = ldb_attr_cmp(attrs[i], "distinguishedName"); -+ if (cmp == 0) { -+ add_dn = true; -+ } -+ } -+ } else { -+ keep_all = true; -+ } -+ -+ if (keep_all) { -+ add_dn = true; -+ elements_size = msg->num_elements + 1; -+ -+ /* Shortcuts for the simple cases */ -+ } else if (add_dn && i == 1) { -+ if (ldb_msg_add_distinguished_name(filtered_msg) != 0) { -+ goto failed; -+ } -+ return 0; -+ } else if (i == 0) { -+ return 0; -+ -+ /* -+ * Otherwise we are copying at most as many elements as we -+ * have attributes -+ */ -+ } else { -+ elements_size = i; -+ } -+ -+ filtered_msg->elements = talloc_array(filtered_msg, -+ struct ldb_message_element, -+ elements_size); -+ if (filtered_msg->elements == NULL) goto failed; -+ -+ num_elements = 0; -+ -+ for (i = 0; i < msg->num_elements; i++) { -+ struct ldb_message_element *el = &msg->elements[i]; -+ -+ /* -+ * el2 is assigned after the Pigeonhole principle -+ * check below for clarity -+ */ -+ struct ldb_message_element *el2 = NULL; -+ unsigned int j; -+ -+ if (keep_all == false) { -+ bool found = false; -+ for (j = 0; attrs[j]; j++) { -+ int cmp = ldb_attr_cmp(el->name, attrs[j]); -+ if (cmp == 0) { -+ found = true; -+ break; -+ } -+ } -+ if (found == false) { -+ continue; -+ } -+ } -+ -+ /* -+ * Pigeonhole principle: we can't have more elements -+ * than the number of attributes if they are unique in -+ * the DB. -+ */ -+ if (num_elements >= elements_size) { -+ goto failed; -+ } -+ -+ el2 = &filtered_msg->elements[num_elements]; -+ -+ *el2 = *el; -+ el2->name = talloc_strdup(filtered_msg->elements, -+ el->name); -+ if (el2->name == NULL) { -+ goto failed; -+ } -+ el2->values = talloc_array(filtered_msg->elements, -+ struct ldb_val, el->num_values); -+ if (el2->values == NULL) { -+ goto failed; -+ } -+ for (j=0;jnum_values;j++) { -+ el2->values[j] = ldb_val_dup(el2->values, &el->values[j]); -+ if (el2->values[j].data == NULL && el->values[j].length != 0) { -+ goto failed; -+ } -+ } -+ num_elements++; -+ } -+ -+ filtered_msg->num_elements = num_elements; -+ -+ if (add_dn) { -+ if (ldb_msg_add_distinguished_name(filtered_msg) != 0) { -+ goto failed; -+ } -+ } -+ -+ if (filtered_msg->num_elements > 0) { -+ filtered_msg->elements -+ = talloc_realloc(filtered_msg, -+ filtered_msg->elements, -+ struct ldb_message_element, -+ filtered_msg->num_elements); -+ if (filtered_msg->elements == NULL) { -+ goto failed; -+ } -+ } else { -+ TALLOC_FREE(filtered_msg->elements); -+ } -+ -+ return 0; -+failed: -+ TALLOC_FREE(filtered_msg->elements); -+ return -1; -+} -+ - /* Have an unpacked ldb message take talloc ownership of its elements. */ - int ldb_msg_elements_take_ownership(struct ldb_message *msg) - { -diff --git a/include/ldb_module.h b/include/ldb_module.h -index 8c7f33496fb..105093cf38c 100644 ---- a/include/ldb_module.h -+++ b/include/ldb_module.h -@@ -543,6 +543,16 @@ int ldb_filter_attrs(struct ldb_context *ldb, - const char *const *attrs, - struct ldb_message *filtered_msg); - -+/* -+ * filter the specified list of attributes from msg, -+ * adding requested attributes, and perhaps all for *, -+ * but not the DN to filtered_msg. -+ */ -+int ldb_filter_attrs_in_place(struct ldb_context *ldb, -+ const struct ldb_message *msg, -+ const char *const *attrs, -+ struct ldb_message *filtered_msg); -+ - /* Have an unpacked ldb message take talloc ownership of its elements. */ - int ldb_msg_elements_take_ownership(struct ldb_message *msg); - -diff --git a/tests/ldb_filter_attrs_in_place_test.c b/tests/ldb_filter_attrs_in_place_test.c -new file mode 100644 -index 00000000000..bef961f8f9c ---- /dev/null -+++ b/tests/ldb_filter_attrs_in_place_test.c -@@ -0,0 +1,989 @@ -+/* -+ * Tests exercising ldb_filter_attrs_in_place(). -+ * -+ * -+ * Copyright (C) Catalyst.NET Ltd 2017 -+ * Copyright (C) Andrew Bartlett 2019 -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ * -+ */ -+ -+/* -+ * from cmocka.c: -+ * These headers or their equivalents should be included prior to -+ * including -+ * this header file. -+ * -+ * #include -+ * #include -+ * #include -+ * -+ * This allows test applications to use custom definitions of C standard -+ * library functions and types. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "../include/ldb.h" -+#include "../include/ldb_module.h" -+ -+struct ldbtest_ctx { -+ struct tevent_context *ev; -+ struct ldb_context *ldb; -+}; -+ -+/* -+ * NOTE WELL: -+ * -+ * This test checks the current behaviour of the function, however -+ * this is not in a public ABI and many of the tested behaviours are -+ * not ideal. If the behaviour is deliberatly improved, this test -+ * should be updated without worry to the new better behaviour. -+ * -+ * In particular the test is particularly to ensure the current -+ * behaviour is memory-safe. -+ */ -+ -+static int setup(void **state) -+{ -+ struct ldbtest_ctx *test_ctx; -+ -+ test_ctx = talloc_zero(NULL, struct ldbtest_ctx); -+ assert_non_null(test_ctx); -+ -+ test_ctx->ev = tevent_context_init(test_ctx); -+ assert_non_null(test_ctx->ev); -+ -+ test_ctx->ldb = ldb_init(test_ctx, test_ctx->ev); -+ assert_non_null(test_ctx->ldb); -+ -+ *state = test_ctx; -+ return 0; -+} -+ -+static int teardown(void **state) -+{ -+ talloc_free(*state); -+ return 0; -+} -+ -+ -+/* -+ * Test against a record with only one attribute, matching the one in -+ * the list -+ */ -+static void test_filter_attrs_one_attr_matched(void **state) -+{ -+ struct ldbtest_ctx *ctx = *state; -+ int ret; -+ -+ struct ldb_message *filtered_msg = ldb_msg_new(ctx); -+ -+ const char *attrs[] = {"foo", NULL}; -+ -+ char value[] = "The value.......end"; -+ struct ldb_val value_1 = { -+ .data = (uint8_t *)value, -+ .length = strlen(value) -+ }; -+ struct ldb_message_element element_1 = { -+ .name = "foo", -+ .num_values = 1, -+ .values = &value_1 -+ }; -+ struct ldb_message in = { -+ .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), -+ .num_elements = 1, -+ .elements = &element_1, -+ }; -+ -+ assert_non_null(in.dn); -+ -+ ret = ldb_filter_attrs_in_place(ctx->ldb, -+ &in, -+ attrs, -+ filtered_msg); -+ assert_int_equal(ret, LDB_SUCCESS); -+ assert_non_null(filtered_msg); -+ -+ /* -+ * assert the ldb_filter_attrs_in_place does not read or modify -+ * filtered_msg.dn in this case -+ */ -+ assert_null(filtered_msg->dn); -+ assert_int_equal(filtered_msg->num_elements, 1); -+ assert_string_equal(filtered_msg->elements[0].name, "foo"); -+ assert_int_equal(filtered_msg->elements[0].num_values, 1); -+ assert_int_equal(filtered_msg->elements[0].values[0].length, -+ strlen(value)); -+ assert_memory_equal(filtered_msg->elements[0].values[0].data, -+ value, strlen(value)); -+} -+ -+/* -+ * Test against a record with only one attribute, matching the one of -+ * the multiple attributes in the list -+ */ -+static void test_filter_attrs_one_attr_matched_of_many(void **state) -+{ -+ struct ldbtest_ctx *ctx = *state; -+ int ret; -+ -+ struct ldb_message *filtered_msg = ldb_msg_new(ctx); -+ -+ const char *attrs[] = {"foo", "bar", "baz", NULL}; -+ -+ char value[] = "The value.......end"; -+ struct ldb_val value_1 = { -+ .data = (uint8_t *)value, -+ .length = strlen(value) -+ }; -+ struct ldb_message_element element_1 = { -+ .name = "foo", -+ .num_values = 1, -+ .values = &value_1 -+ }; -+ struct ldb_message in = { -+ .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), -+ .num_elements = 1, -+ .elements = &element_1, -+ }; -+ -+ assert_non_null(in.dn); -+ -+ ret = ldb_filter_attrs_in_place(ctx->ldb, -+ &in, -+ attrs, -+ filtered_msg); -+ assert_int_equal(ret, LDB_SUCCESS); -+ assert_non_null(filtered_msg); -+ -+ /* -+ * assert the ldb_filter_attrs_in_place does not read or modify -+ * filtered_msg.dn in this case -+ */ -+ assert_null(filtered_msg->dn); -+ assert_int_equal(filtered_msg->num_elements, 1); -+ assert_string_equal(filtered_msg->elements[0].name, "foo"); -+ assert_int_equal(filtered_msg->elements[0].num_values, 1); -+ assert_int_equal(filtered_msg->elements[0].values[0].length, -+ strlen(value)); -+ assert_memory_equal(filtered_msg->elements[0].values[0].data, -+ value, strlen(value)); -+} -+ -+/* -+ * Test against a record with only one attribute, matching both -+ * attributes in the list -+ */ -+static void test_filter_attrs_two_attr_matched_attrs(void **state) -+{ -+ struct ldbtest_ctx *ctx = *state; -+ int ret; -+ -+ struct ldb_message *filtered_msg = ldb_msg_new(ctx); -+ -+ /* deliberatly the other order */ -+ const char *attrs[] = {"bar", "foo", NULL}; -+ -+ char value1[] = "The value.......end"; -+ char value2[] = "The value..MUST.end"; -+ struct ldb_val value_1 = { -+ .data = (uint8_t *)value1, -+ .length = strlen(value1) -+ }; -+ struct ldb_val value_2 = { -+ .data = (uint8_t *)value2, -+ .length = strlen(value2) -+ }; -+ -+ /* foo and bar are the other order to in attrs */ -+ struct ldb_message_element elements[] = { -+ { -+ .name = "foo", -+ .num_values = 1, -+ .values = &value_1 -+ }, -+ { -+ .name = "bar", -+ .num_values = 1, -+ .values = &value_2 -+ } -+ }; -+ struct ldb_message in = { -+ .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), -+ .num_elements = 2, -+ .elements = elements, -+ }; -+ -+ assert_non_null(in.dn); -+ -+ ret = ldb_filter_attrs_in_place(ctx->ldb, -+ &in, -+ attrs, -+ filtered_msg); -+ assert_int_equal(ret, LDB_SUCCESS); -+ assert_non_null(filtered_msg); -+ assert_int_equal(filtered_msg->num_elements, 2); -+ -+ /* -+ * assert the ldb_filter_attrs_in_place does not read or modify -+ * filtered_msg.dn in this case -+ */ -+ assert_null(filtered_msg->dn); -+ -+ /* Assert that DB order is preserved */ -+ assert_string_equal(filtered_msg->elements[0].name, "foo"); -+ assert_int_equal(filtered_msg->elements[0].num_values, 1); -+ assert_int_equal(filtered_msg->elements[0].values[0].length, -+ strlen(value1)); -+ assert_memory_equal(filtered_msg->elements[0].values[0].data, -+ value1, strlen(value1)); -+ assert_string_equal(filtered_msg->elements[1].name, "bar"); -+ assert_int_equal(filtered_msg->elements[1].num_values, 1); -+ assert_int_equal(filtered_msg->elements[1].values[0].length, -+ strlen(value2)); -+ assert_memory_equal(filtered_msg->elements[1].values[0].data, -+ value2, strlen(value2)); -+} -+ -+/* -+ * Test against a record with two attributes, only of which is in -+ * the list -+ */ -+static void test_filter_attrs_two_attr_matched_one_attr(void **state) -+{ -+ struct ldbtest_ctx *ctx = *state; -+ int ret; -+ -+ struct ldb_message *filtered_msg = ldb_msg_new(ctx); -+ -+ /* deliberatly the other order */ -+ const char *attrs[] = {"bar", NULL}; -+ -+ char value1[] = "The value.......end"; -+ char value2[] = "The value..MUST.end"; -+ struct ldb_val value_1 = { -+ .data = (uint8_t *)value1, -+ .length = strlen(value1) -+ }; -+ struct ldb_val value_2 = { -+ .data = (uint8_t *)value2, -+ .length = strlen(value2) -+ }; -+ -+ /* foo and bar are the other order to in attrs */ -+ struct ldb_message_element elements[] = { -+ { -+ .name = "foo", -+ .num_values = 1, -+ .values = &value_1 -+ }, -+ { -+ .name = "bar", -+ .num_values = 1, -+ .values = &value_2 -+ } -+ }; -+ struct ldb_message in = { -+ .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), -+ .num_elements = 2, -+ .elements = elements, -+ }; -+ -+ assert_non_null(in.dn); -+ -+ ret = ldb_filter_attrs_in_place(ctx->ldb, -+ &in, -+ attrs, -+ filtered_msg); -+ assert_int_equal(ret, LDB_SUCCESS); -+ assert_non_null(filtered_msg); -+ assert_int_equal(filtered_msg->num_elements, 1); -+ -+ /* -+ * assert the ldb_filter_attrs_in_place does not read or modify -+ * filtered_msg.dn in this case -+ */ -+ assert_null(filtered_msg->dn); -+ -+ /* Assert that DB order is preserved */ -+ assert_string_equal(filtered_msg->elements[0].name, "bar"); -+ assert_int_equal(filtered_msg->elements[0].num_values, 1); -+ assert_int_equal(filtered_msg->elements[0].values[0].length, -+ strlen(value2)); -+ assert_memory_equal(filtered_msg->elements[0].values[0].data, -+ value2, strlen(value2)); -+} -+ -+/* -+ * Test against a record with two attributes, both matching the one -+ * specified attribute in the list (a corrupt record) -+ */ -+static void test_filter_attrs_two_dup_attr_matched_one_attr(void **state) -+{ -+ struct ldbtest_ctx *ctx = *state; -+ int ret; -+ -+ struct ldb_message *filtered_msg = ldb_msg_new(ctx); -+ -+ /* deliberatly the other order */ -+ const char *attrs[] = {"bar", NULL}; -+ -+ char value1[] = "The value.......end"; -+ char value2[] = "The value..MUST.end"; -+ struct ldb_val value_1 = { -+ .data = (uint8_t *)value1, -+ .length = strlen(value1) -+ }; -+ struct ldb_val value_2 = { -+ .data = (uint8_t *)value2, -+ .length = strlen(value2) -+ }; -+ -+ /* foo and bar are the other order to in attrs */ -+ struct ldb_message_element elements[] = { -+ { -+ .name = "bar", -+ .num_values = 1, -+ .values = &value_1 -+ }, -+ { -+ .name = "bar", -+ .num_values = 1, -+ .values = &value_2 -+ } -+ }; -+ struct ldb_message in = { -+ .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), -+ .num_elements = 2, -+ .elements = elements, -+ }; -+ -+ assert_non_null(in.dn); -+ -+ ret = ldb_filter_attrs_in_place(ctx->ldb, -+ &in, -+ attrs, -+ filtered_msg); -+ -+ /* This should fail the pidgenhole test */ -+ assert_int_equal(ret, -1); -+ assert_null(filtered_msg->elements); -+} -+ -+/* -+ * Test against a record with two attributes, both matching the one -+ * specified attribute in the list (a corrupt record) -+ */ -+static void test_filter_attrs_two_dup_attr_matched_dup(void **state) -+{ -+ struct ldbtest_ctx *ctx = *state; -+ int ret; -+ -+ struct ldb_message *filtered_msg = ldb_msg_new(ctx); -+ -+ const char *attrs[] = {"bar", "bar", NULL}; -+ -+ char value1[] = "The value.......end"; -+ char value2[] = "The value..MUST.end"; -+ struct ldb_val value_1 = { -+ .data = (uint8_t *)value1, -+ .length = strlen(value1) -+ }; -+ struct ldb_val value_2 = { -+ .data = (uint8_t *)value2, -+ .length = strlen(value2) -+ }; -+ -+ /* foo and bar are the other order to in attrs */ -+ struct ldb_message_element elements[] = { -+ { -+ .name = "bar", -+ .num_values = 1, -+ .values = &value_1 -+ }, -+ { -+ .name = "bar", -+ .num_values = 1, -+ .values = &value_2 -+ } -+ }; -+ struct ldb_message in = { -+ .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), -+ .num_elements = 2, -+ .elements = elements, -+ }; -+ -+ assert_non_null(in.dn); -+ -+ ret = ldb_filter_attrs_in_place(ctx->ldb, -+ &in, -+ attrs, -+ filtered_msg); -+ -+ /* This does not fail the pidgenhole test */ -+ assert_int_equal(ret, LDB_SUCCESS); -+ assert_int_equal(filtered_msg->num_elements, 2); -+ -+ /* Assert that DB order is preserved */ -+ assert_string_equal(filtered_msg->elements[0].name, "bar"); -+ assert_int_equal(filtered_msg->elements[0].num_values, 1); -+ assert_int_equal(filtered_msg->elements[0].values[0].length, -+ strlen(value1)); -+ assert_memory_equal(filtered_msg->elements[0].values[0].data, -+ value1, strlen(value1)); -+ assert_string_equal(filtered_msg->elements[1].name, "bar"); -+ assert_int_equal(filtered_msg->elements[1].num_values, 1); -+ assert_int_equal(filtered_msg->elements[1].values[0].length, -+ strlen(value2)); -+ assert_memory_equal(filtered_msg->elements[1].values[0].data, -+ value2, strlen(value2)); -+} -+ -+/* -+ * Test against a record with two attributes, both matching one of the -+ * specified attributes in the list (a corrupt record) -+ */ -+static void test_filter_attrs_two_dup_attr_matched_one_of_two(void **state) -+{ -+ struct ldbtest_ctx *ctx = *state; -+ int ret; -+ -+ struct ldb_message *filtered_msg = ldb_msg_new(ctx); -+ -+ const char *attrs[] = {"bar", "foo", NULL}; -+ -+ char value1[] = "The value.......end"; -+ char value2[] = "The value..MUST.end"; -+ struct ldb_val value_1 = { -+ .data = (uint8_t *)value1, -+ .length = strlen(value1) -+ }; -+ struct ldb_val value_2 = { -+ .data = (uint8_t *)value2, -+ .length = strlen(value2) -+ }; -+ -+ /* foo and bar are the other order to in attrs */ -+ struct ldb_message_element elements[] = { -+ { -+ .name = "bar", -+ .num_values = 1, -+ .values = &value_1 -+ }, -+ { -+ .name = "bar", -+ .num_values = 1, -+ .values = &value_2 -+ } -+ }; -+ struct ldb_message in = { -+ .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), -+ .num_elements = 2, -+ .elements = elements, -+ }; -+ -+ assert_non_null(in.dn); -+ -+ ret = ldb_filter_attrs_in_place(ctx->ldb, -+ &in, -+ attrs, -+ filtered_msg); -+ -+ /* This does not fail the pidgenhole test */ -+ assert_int_equal(ret, LDB_SUCCESS); -+ assert_int_equal(filtered_msg->num_elements, 2); -+ -+ /* Assert that DB order is preserved */ -+ assert_string_equal(filtered_msg->elements[0].name, "bar"); -+ assert_int_equal(filtered_msg->elements[0].num_values, 1); -+ assert_int_equal(filtered_msg->elements[0].values[0].length, -+ strlen(value1)); -+ assert_memory_equal(filtered_msg->elements[0].values[0].data, -+ value1, strlen(value1)); -+ assert_string_equal(filtered_msg->elements[1].name, "bar"); -+ assert_int_equal(filtered_msg->elements[1].num_values, 1); -+ assert_int_equal(filtered_msg->elements[1].values[0].length, -+ strlen(value2)); -+ assert_memory_equal(filtered_msg->elements[1].values[0].data, -+ value2, strlen(value2)); -+} -+ -+/* -+ * Test against a record with two attributes against * (but not the -+ * other named attribute) (a corrupt record) -+ */ -+static void test_filter_attrs_two_dup_attr_matched_star(void **state) -+{ -+ struct ldbtest_ctx *ctx = *state; -+ int ret; -+ -+ struct ldb_message *filtered_msg = ldb_msg_new(ctx); -+ -+ const char *attrs[] = {"*", "foo", NULL}; -+ -+ char value1[] = "The value.......end"; -+ char value2[] = "The value..MUST.end"; -+ struct ldb_val value_1 = { -+ .data = (uint8_t *)value1, -+ .length = strlen(value1) -+ }; -+ struct ldb_val value_2 = { -+ .data = (uint8_t *)value2, -+ .length = strlen(value2) -+ }; -+ -+ /* foo and bar are the other order to in attrs */ -+ struct ldb_message_element elements[] = { -+ { -+ .name = "bar", -+ .num_values = 1, -+ .values = &value_1 -+ }, -+ { -+ .name = "bar", -+ .num_values = 1, -+ .values = &value_2 -+ } -+ }; -+ struct ldb_message in = { -+ .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), -+ .num_elements = 2, -+ .elements = elements, -+ }; -+ -+ assert_non_null(in.dn); -+ -+ /* Needed as * implies distinguishedName */ -+ filtered_msg->dn = in.dn; -+ -+ ret = ldb_filter_attrs_in_place(ctx->ldb, -+ &in, -+ attrs, -+ filtered_msg); -+ -+ /* This does not fail the pidgenhole test */ -+ assert_int_equal(ret, LDB_SUCCESS); -+ assert_int_equal(filtered_msg->num_elements, 3); -+ -+ /* Assert that DB order is preserved */ -+ assert_string_equal(filtered_msg->elements[0].name, "bar"); -+ assert_int_equal(filtered_msg->elements[0].num_values, 1); -+ assert_int_equal(filtered_msg->elements[0].values[0].length, -+ strlen(value1)); -+ assert_memory_equal(filtered_msg->elements[0].values[0].data, -+ value1, strlen(value1)); -+ assert_string_equal(filtered_msg->elements[1].name, "bar"); -+ assert_int_equal(filtered_msg->elements[1].num_values, 1); -+ assert_int_equal(filtered_msg->elements[1].values[0].length, -+ strlen(value2)); -+ assert_memory_equal(filtered_msg->elements[1].values[0].data, -+ value2, strlen(value2)); -+ /* -+ * assert the ldb_filter_attrs_in_place does not modify filtered_msg.dn -+ * in this case -+ */ -+ assert_ptr_equal(filtered_msg->dn, in.dn); -+ assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, -+ "distinguishedName", -+ NULL), -+ ldb_dn_get_linearized(in.dn)); -+} -+ -+/* -+ * Test against a record with only one attribute, matching the * in -+ * the list -+ */ -+static void test_filter_attrs_one_attr_matched_star(void **state) -+{ -+ struct ldbtest_ctx *ctx = *state; -+ int ret; -+ -+ struct ldb_message *filtered_msg = ldb_msg_new(ctx); -+ -+ const char *attrs[] = {"*", NULL}; -+ -+ char value[] = "The value.......end"; -+ struct ldb_val value_1 = { -+ .data = (uint8_t *)value, -+ .length = strlen(value) -+ }; -+ struct ldb_message_element element_1 = { -+ .name = "foo", -+ .num_values = 1, -+ .values = &value_1 -+ }; -+ struct ldb_message in = { -+ .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), -+ .num_elements = 1, -+ .elements = &element_1, -+ }; -+ -+ assert_non_null(in.dn); -+ -+ /* Needed as * implies distinguishedName */ -+ filtered_msg->dn = in.dn; -+ -+ ret = ldb_filter_attrs_in_place(ctx->ldb, -+ &in, -+ attrs, -+ filtered_msg); -+ assert_int_equal(ret, LDB_SUCCESS); -+ assert_non_null(filtered_msg); -+ assert_int_equal(filtered_msg->num_elements, 2); -+ -+ /* -+ * assert the ldb_filter_attrs_in_place does not modify filtered_msg.dn -+ * in this case -+ */ -+ assert_ptr_equal(filtered_msg->dn, in.dn); -+ assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, -+ "distinguishedName", -+ NULL), -+ ldb_dn_get_linearized(in.dn)); -+ assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, -+ "foo", -+ NULL), -+ value); -+} -+ -+/* -+ * Test against a record with two attributes, matching the * in -+ * the list -+ */ -+static void test_filter_attrs_two_attr_matched_star(void **state) -+{ -+ struct ldbtest_ctx *ctx = *state; -+ int ret; -+ -+ struct ldb_message *filtered_msg = ldb_msg_new(ctx); -+ -+ const char *attrs[] = {"*", NULL}; -+ -+ char value1[] = "The value.......end"; -+ char value2[] = "The value..MUST.end"; -+ struct ldb_val value_1 = { -+ .data = (uint8_t *)value1, -+ .length = strlen(value1) -+ }; -+ struct ldb_val value_2 = { -+ .data = (uint8_t *)value2, -+ .length = strlen(value2) -+ }; -+ struct ldb_message_element elements[] = { -+ { -+ .name = "foo", -+ .num_values = 1, -+ .values = &value_1 -+ }, -+ { -+ .name = "bar", -+ .num_values = 1, -+ .values = &value_2 -+ } -+ }; -+ struct ldb_message in = { -+ .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), -+ .num_elements = 2, -+ .elements = elements, -+ }; -+ -+ assert_non_null(in.dn); -+ -+ /* Needed as * implies distinguishedName */ -+ filtered_msg->dn = in.dn; -+ -+ ret = ldb_filter_attrs_in_place(ctx->ldb, -+ &in, -+ attrs, -+ filtered_msg); -+ assert_int_equal(ret, LDB_SUCCESS); -+ assert_non_null(filtered_msg); -+ assert_int_equal(filtered_msg->num_elements, 3); -+ -+ /* -+ * assert the ldb_filter_attrs_in_place does not modify filtered_msg.dn -+ * in this case -+ */ -+ assert_ptr_equal(filtered_msg->dn, in.dn); -+ assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, -+ "distinguishedName", -+ NULL), -+ ldb_dn_get_linearized(in.dn)); -+ assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, -+ "foo", -+ NULL), -+ value1); -+ assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, -+ "bar", -+ NULL), -+ value2); -+} -+ -+/* -+ * Test against a record with only one attribute, matching the * in -+ * the list, but without the DN being pre-filled. Fails due to need -+ * to contstruct the distinguishedName -+ */ -+static void test_filter_attrs_one_attr_matched_star_no_dn(void **state) -+{ -+ struct ldbtest_ctx *ctx = *state; -+ int ret; -+ -+ struct ldb_message *filtered_msg = ldb_msg_new(ctx); -+ -+ const char *attrs[] = {"*", NULL}; -+ -+ char value[] = "The value.......end"; -+ struct ldb_val value_1 = { -+ .data = (uint8_t *)value, -+ .length = strlen(value) -+ }; -+ struct ldb_message_element element_1 = { -+ .name = "foo", -+ .num_values = 1, -+ .values = &value_1 -+ }; -+ struct ldb_message in = { -+ .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), -+ .num_elements = 1, -+ .elements = &element_1, -+ }; -+ -+ assert_non_null(in.dn); -+ -+ ret = ldb_filter_attrs_in_place(ctx->ldb, -+ &in, -+ attrs, -+ filtered_msg); -+ assert_int_equal(ret, -1); -+ assert_null(filtered_msg->elements); -+} -+ -+/* -+ * Test against a record with only one attribute, matching the * in -+ * the list plus requsesting distinguishedName -+ */ -+static void test_filter_attrs_one_attr_matched_star_dn(void **state) -+{ -+ struct ldbtest_ctx *ctx = *state; -+ int ret; -+ -+ struct ldb_message *filtered_msg = ldb_msg_new(ctx); -+ -+ const char *attrs[] = {"*", "distinguishedName", NULL}; -+ -+ char value[] = "The value.......end"; -+ struct ldb_val value_1 = { -+ .data = (uint8_t *)value, -+ .length = strlen(value) -+ }; -+ struct ldb_message_element element_1 = { -+ .name = "foo", -+ .num_values = 1, -+ .values = &value_1 -+ }; -+ struct ldb_message in = { -+ .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), -+ .num_elements = 1, -+ .elements = &element_1, -+ }; -+ -+ assert_non_null(in.dn); -+ -+ /* Needed for distinguishedName */ -+ filtered_msg->dn = in.dn; -+ -+ ret = ldb_filter_attrs_in_place(ctx->ldb, -+ &in, -+ attrs, -+ filtered_msg); -+ assert_int_equal(ret, LDB_SUCCESS); -+ assert_non_null(filtered_msg); -+ assert_int_equal(filtered_msg->num_elements, 2); -+ -+ /* show that ldb_filter_attrs_in_place does not modify in.dn */ -+ assert_ptr_equal(filtered_msg->dn, in.dn); -+ -+ assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, -+ "distinguishedName", -+ NULL), -+ ldb_dn_get_linearized(in.dn)); -+ assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, -+ "foo", -+ NULL), -+ value); -+} -+ -+/* -+ * Test against a record with only one attribute, but returning -+ * distinguishedName from the list (only) -+ */ -+static void test_filter_attrs_one_attr_matched_dn(void **state) -+{ -+ struct ldbtest_ctx *ctx = *state; -+ int ret; -+ -+ struct ldb_message *filtered_msg = ldb_msg_new(ctx); -+ -+ const char *attrs[] = {"distinguishedName", NULL}; -+ -+ char value[] = "The value.......end"; -+ struct ldb_val value_1 = { -+ .data = (uint8_t *)value, -+ .length = strlen(value) -+ }; -+ struct ldb_message_element element_1 = { -+ .name = "foo", -+ .num_values = 1, -+ .values = &value_1 -+ }; -+ struct ldb_message in = { -+ .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), -+ .num_elements = 1, -+ .elements = &element_1, -+ }; -+ -+ assert_non_null(in.dn); -+ -+ /* Needed for distinguishedName */ -+ filtered_msg->dn = in.dn; -+ -+ ret = ldb_filter_attrs_in_place(ctx->ldb, -+ &in, -+ attrs, -+ filtered_msg); -+ assert_int_equal(ret, LDB_SUCCESS); -+ assert_non_null(filtered_msg); -+ assert_int_equal(filtered_msg->num_elements, 1); -+ -+ /* show that ldb_filter_attrs_in_place does not modify in.dn */ -+ assert_ptr_equal(filtered_msg->dn, in.dn); -+ assert_string_equal(filtered_msg->elements[0].name, "distinguishedName"); -+ assert_int_equal(filtered_msg->elements[0].num_values, 1); -+ assert_string_equal(filtered_msg->elements[0].values[0].data, -+ ldb_dn_get_linearized(in.dn)); -+} -+ -+/* -+ * Test against a record with only one attribute, not matching the -+ * empty attribute list -+ */ -+static void test_filter_attrs_one_attr_empty_list(void **state) -+{ -+ struct ldbtest_ctx *ctx = *state; -+ int ret; -+ -+ struct ldb_message *filtered_msg = ldb_msg_new(ctx); -+ -+ const char *attrs[] = {NULL}; -+ -+ char value[] = "The value.......end"; -+ struct ldb_val value_1 = { -+ .data = (uint8_t *)value, -+ .length = strlen(value) -+ }; -+ struct ldb_message_element element_1 = { -+ .name = "foo", -+ .num_values = 1, -+ .values = &value_1 -+ }; -+ struct ldb_message in = { -+ .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), -+ .num_elements = 1, -+ .elements = &element_1, -+ }; -+ -+ assert_non_null(in.dn); -+ -+ ret = ldb_filter_attrs_in_place(ctx->ldb, -+ &in, -+ attrs, -+ filtered_msg); -+ assert_int_equal(ret, LDB_SUCCESS); -+ assert_non_null(filtered_msg); -+ assert_int_equal(filtered_msg->num_elements, 0); -+ assert_null(filtered_msg->dn); -+ assert_null(filtered_msg->elements); -+} -+ -+int main(int argc, const char **argv) -+{ -+ const struct CMUnitTest tests[] = { -+ cmocka_unit_test_setup_teardown( -+ test_filter_attrs_one_attr_matched, -+ setup, -+ teardown), -+ cmocka_unit_test_setup_teardown( -+ test_filter_attrs_one_attr_matched_of_many, -+ setup, -+ teardown), -+ cmocka_unit_test_setup_teardown( -+ test_filter_attrs_two_attr_matched_attrs, -+ setup, -+ teardown), -+ cmocka_unit_test_setup_teardown( -+ test_filter_attrs_two_attr_matched_one_attr, -+ setup, -+ teardown), -+ cmocka_unit_test_setup_teardown( -+ test_filter_attrs_two_dup_attr_matched_one_attr, -+ setup, -+ teardown), -+ cmocka_unit_test_setup_teardown( -+ test_filter_attrs_two_dup_attr_matched_dup, -+ setup, -+ teardown), -+ cmocka_unit_test_setup_teardown( -+ test_filter_attrs_two_dup_attr_matched_one_of_two, -+ setup, -+ teardown), -+ cmocka_unit_test_setup_teardown( -+ test_filter_attrs_two_dup_attr_matched_star, -+ setup, -+ teardown), -+ cmocka_unit_test_setup_teardown( -+ test_filter_attrs_one_attr_matched_star, -+ setup, -+ teardown), -+ cmocka_unit_test_setup_teardown( -+ test_filter_attrs_two_attr_matched_star, -+ setup, -+ teardown), -+ cmocka_unit_test_setup_teardown( -+ test_filter_attrs_one_attr_matched_star_no_dn, -+ setup, -+ teardown), -+ cmocka_unit_test_setup_teardown( -+ test_filter_attrs_one_attr_matched_star_dn, -+ setup, -+ teardown), -+ cmocka_unit_test_setup_teardown( -+ test_filter_attrs_one_attr_matched_dn, -+ setup, -+ teardown), -+ cmocka_unit_test_setup_teardown( -+ test_filter_attrs_one_attr_empty_list, -+ setup, -+ teardown), -+ }; -+ -+ return cmocka_run_group_tests(tests, NULL, NULL); -+} -diff --git a/wscript b/wscript -index c862229822d..7e02309c1d5 100644 ---- a/wscript -+++ b/wscript -@@ -518,6 +518,11 @@ def build(bld): - deps='cmocka ldb ldb_tdb_err_map', - install=False) - -+ bld.SAMBA_BINARY('ldb_filter_attrs_in_place_test', -+ source='tests/ldb_filter_attrs_in_place_test.c', -+ deps='cmocka ldb ldb_tdb_err_map', -+ install=False) -+ - bld.SAMBA_BINARY('ldb_key_value_sub_txn_tdb_test', - bld.SUBDIR('ldb_key_value', - '''ldb_kv_search.c -@@ -638,6 +643,7 @@ def test(ctx): - # 'ldb_key_value_sub_txn_tdb_test' - 'ldb_parse_test', - 'ldb_filter_attrs_test', -+ 'ldb_filter_attrs_in_place_test', - ] - - # if LIB_LDAP and LIB_LBER defined, then we can test ldb_ldap backend --- -2.25.1 diff --git a/backport-0009-CVE-2023-0614.patch b/backport-0009-CVE-2023-0614.patch deleted file mode 100644 index 89a8aeba9855946d3a2cae20e43cc0f03974ee00..0000000000000000000000000000000000000000 --- a/backport-0009-CVE-2023-0614.patch +++ /dev/null @@ -1,1275 +0,0 @@ -From fd0f06e43f03bc8b8c5b4a978a119e4401c02160 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Fri, 3 Mar 2023 17:30:19 +1300 -Subject: [PATCH 13/34] CVE-2023-0614 ldb: Make ldb_filter_attrs_in_place() - work in place - -ldb_filter_attrs() previously did too much. Now its replacement, -ldb_filter_attrs_in_place(), only does the actual filtering, while -taking ownership of each element's values is handled in a separate -function, ldb_msg_elements_take_ownership(). - -Also, ldb_filter_attrs_in_place() no longer adds the distinguishedName -to the message if it is missing. That is handled in another function, -ldb_msg_add_distinguished_name(). - -As we're now modifying the original message rather than copying it into -a new one, we no longer need the filtered_msg parameter. - -We adapt a test, based on ldb_filter_attrs_test, to exercise the new -function. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15270 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett - -Conflict: NA -Reference: https://attachments.samba.org/attachment.cgi?id=17821 ---- - common/ldb_pack.c | 129 +--- - include/ldb_module.h | 11 +- - .../tests/ldb_filter_attrs_in_place_test.c | 609 ++++++++---------- - 3 files changed, 307 insertions(+), 442 deletions(-) - -diff --git a/common/ldb_pack.c b/common/ldb_pack.c -index f19ac73fa5e..28b9a8dfe07 100644 ---- a/common/ldb_pack.c -+++ b/common/ldb_pack.c -@@ -1264,19 +1264,16 @@ failed: - - /* - * filter the specified list of attributes from msg, -- * adding requested attributes, and perhaps all for *, -- * but not the DN to filtered_msg. -+ * adding requested attributes, and perhaps all for *. -+ * Unlike ldb_filter_attrs(), the DN will not be added -+ * if it is missing. - */ --int ldb_filter_attrs_in_place(struct ldb_context *ldb, -- const struct ldb_message *msg, -- const char *const *attrs, -- struct ldb_message *filtered_msg) -+int ldb_filter_attrs_in_place(struct ldb_message *msg, -+ const char *const *attrs) - { -- unsigned int i; -+ unsigned int i = 0; - bool keep_all = false; -- bool add_dn = false; -- uint32_t num_elements; -- uint32_t elements_size; -+ unsigned int num_del = 0; - - if (attrs) { - /* check for special attrs */ -@@ -1286,123 +1283,41 @@ int ldb_filter_attrs_in_place(struct ldb_context *ldb, - keep_all = true; - break; - } -- cmp = ldb_attr_cmp(attrs[i], "distinguishedName"); -- if (cmp == 0) { -- add_dn = true; -- } - } -- } else { -- keep_all = true; -- } -- -- if (keep_all) { -- add_dn = true; -- elements_size = msg->num_elements + 1; -- -- /* Shortcuts for the simple cases */ -- } else if (add_dn && i == 1) { -- if (ldb_msg_add_distinguished_name(filtered_msg) != 0) { -- goto failed; -+ if (!keep_all && i == 0) { -+ msg->num_elements = 0; -+ return LDB_SUCCESS; - } -- return 0; -- } else if (i == 0) { -- return 0; -- -- /* -- * Otherwise we are copying at most as many elements as we -- * have attributes -- */ - } else { -- elements_size = i; -+ keep_all = true; - } - -- filtered_msg->elements = talloc_array(filtered_msg, -- struct ldb_message_element, -- elements_size); -- if (filtered_msg->elements == NULL) goto failed; -- -- num_elements = 0; -- - for (i = 0; i < msg->num_elements; i++) { -- struct ldb_message_element *el = &msg->elements[i]; -- -- /* -- * el2 is assigned after the Pigeonhole principle -- * check below for clarity -- */ -- struct ldb_message_element *el2 = NULL; -+ bool found = false; - unsigned int j; - -- if (keep_all == false) { -- bool found = false; -+ if (keep_all) { -+ found = true; -+ } else { - for (j = 0; attrs[j]; j++) { -- int cmp = ldb_attr_cmp(el->name, attrs[j]); -+ int cmp = ldb_attr_cmp(msg->elements[i].name, attrs[j]); - if (cmp == 0) { - found = true; - break; - } - } -- if (found == false) { -- continue; -- } -- } -- -- /* -- * Pigeonhole principle: we can't have more elements -- * than the number of attributes if they are unique in -- * the DB. -- */ -- if (num_elements >= elements_size) { -- goto failed; - } - -- el2 = &filtered_msg->elements[num_elements]; -- -- *el2 = *el; -- el2->name = talloc_strdup(filtered_msg->elements, -- el->name); -- if (el2->name == NULL) { -- goto failed; -- } -- el2->values = talloc_array(filtered_msg->elements, -- struct ldb_val, el->num_values); -- if (el2->values == NULL) { -- goto failed; -+ if (!found) { -+ ++num_del; -+ } else if (num_del != 0) { -+ msg->elements[i - num_del] = msg->elements[i]; - } -- for (j=0;jnum_values;j++) { -- el2->values[j] = ldb_val_dup(el2->values, &el->values[j]); -- if (el2->values[j].data == NULL && el->values[j].length != 0) { -- goto failed; -- } -- } -- num_elements++; - } - -- filtered_msg->num_elements = num_elements; -- -- if (add_dn) { -- if (ldb_msg_add_distinguished_name(filtered_msg) != 0) { -- goto failed; -- } -- } -+ msg->num_elements -= num_del; - -- if (filtered_msg->num_elements > 0) { -- filtered_msg->elements -- = talloc_realloc(filtered_msg, -- filtered_msg->elements, -- struct ldb_message_element, -- filtered_msg->num_elements); -- if (filtered_msg->elements == NULL) { -- goto failed; -- } -- } else { -- TALLOC_FREE(filtered_msg->elements); -- } -- -- return 0; --failed: -- TALLOC_FREE(filtered_msg->elements); -- return -1; -+ return LDB_SUCCESS; - } - - /* Have an unpacked ldb message take talloc ownership of its elements. */ -diff --git a/include/ldb_module.h b/include/ldb_module.h -index 105093cf38c..4ae381ba5be 100644 ---- a/include/ldb_module.h -+++ b/include/ldb_module.h -@@ -545,13 +545,12 @@ int ldb_filter_attrs(struct ldb_context *ldb, - - /* - * filter the specified list of attributes from msg, -- * adding requested attributes, and perhaps all for *, -- * but not the DN to filtered_msg. -+ * adding requested attributes, and perhaps all for *. -+ * Unlike ldb_filter_attrs(), the DN will not be added -+ * if it is missing. - */ --int ldb_filter_attrs_in_place(struct ldb_context *ldb, -- const struct ldb_message *msg, -- const char *const *attrs, -- struct ldb_message *filtered_msg); -+int ldb_filter_attrs_in_place(struct ldb_message *msg, -+ const char *const *attrs); - - /* Have an unpacked ldb message take talloc ownership of its elements. */ - int ldb_msg_elements_take_ownership(struct ldb_message *msg); -diff --git a/tests/ldb_filter_attrs_in_place_test.c b/tests/ldb_filter_attrs_in_place_test.c -index bef961f8f9c..da333c73c99 100644 ---- a/tests/ldb_filter_attrs_in_place_test.c -+++ b/tests/ldb_filter_attrs_in_place_test.c -@@ -83,17 +83,41 @@ static int teardown(void **state) - return 0; - } - -+static void msg_add_dn(struct ldb_message *msg) -+{ -+ const char *dn_attr = "distinguishedName"; -+ char *dn = NULL; -+ int ret; -+ -+ assert_null(ldb_msg_find_element(msg, dn_attr)); -+ -+ assert_non_null(msg->dn); -+ dn = ldb_dn_alloc_linearized(msg, msg->dn); -+ assert_non_null(dn); -+ -+ /* -+ * The message's elements must be talloc allocated to call -+ * ldb_msg_add_steal_string(). -+ */ -+ msg->elements = talloc_memdup(msg, -+ msg->elements, -+ msg->num_elements * sizeof(msg->elements[0])); -+ assert_non_null(msg->elements); -+ -+ ret = ldb_msg_add_steal_string(msg, dn_attr, dn); -+ assert_int_equal(ret, LDB_SUCCESS); -+} - - /* - * Test against a record with only one attribute, matching the one in - * the list - */ --static void test_filter_attrs_one_attr_matched(void **state) -+static void test_filter_attrs_in_place_one_attr_matched(void **state) - { - struct ldbtest_ctx *ctx = *state; - int ret; - -- struct ldb_message *filtered_msg = ldb_msg_new(ctx); -+ struct ldb_message *msg = ldb_msg_new(ctx); - - const char *attrs[] = {"foo", NULL}; - -@@ -107,32 +131,25 @@ static void test_filter_attrs_one_attr_matched(void **state) - .num_values = 1, - .values = &value_1 - }; -- struct ldb_message in = { -- .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), -- .num_elements = 1, -- .elements = &element_1, -- }; - -- assert_non_null(in.dn); -+ assert_non_null(msg); -+ msg->dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"); -+ msg->num_elements = 1; -+ msg->elements = &element_1; - -- ret = ldb_filter_attrs_in_place(ctx->ldb, -- &in, -- attrs, -- filtered_msg); -+ assert_non_null(msg->dn); -+ msg_add_dn(msg); -+ -+ ret = ldb_filter_attrs_in_place(msg, attrs); - assert_int_equal(ret, LDB_SUCCESS); -- assert_non_null(filtered_msg); - -- /* -- * assert the ldb_filter_attrs_in_place does not read or modify -- * filtered_msg.dn in this case -- */ -- assert_null(filtered_msg->dn); -- assert_int_equal(filtered_msg->num_elements, 1); -- assert_string_equal(filtered_msg->elements[0].name, "foo"); -- assert_int_equal(filtered_msg->elements[0].num_values, 1); -- assert_int_equal(filtered_msg->elements[0].values[0].length, -+ assert_non_null(msg->dn); -+ assert_int_equal(msg->num_elements, 1); -+ assert_string_equal(msg->elements[0].name, "foo"); -+ assert_int_equal(msg->elements[0].num_values, 1); -+ assert_int_equal(msg->elements[0].values[0].length, - strlen(value)); -- assert_memory_equal(filtered_msg->elements[0].values[0].data, -+ assert_memory_equal(msg->elements[0].values[0].data, - value, strlen(value)); - } - -@@ -140,12 +157,12 @@ static void test_filter_attrs_one_attr_matched(void **state) - * Test against a record with only one attribute, matching the one of - * the multiple attributes in the list - */ --static void test_filter_attrs_one_attr_matched_of_many(void **state) -+static void test_filter_attrs_in_place_one_attr_matched_of_many(void **state) - { - struct ldbtest_ctx *ctx = *state; - int ret; - -- struct ldb_message *filtered_msg = ldb_msg_new(ctx); -+ struct ldb_message *msg = ldb_msg_new(ctx); - - const char *attrs[] = {"foo", "bar", "baz", NULL}; - -@@ -159,32 +176,25 @@ static void test_filter_attrs_one_attr_matched_of_many(void **state) - .num_values = 1, - .values = &value_1 - }; -- struct ldb_message in = { -- .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), -- .num_elements = 1, -- .elements = &element_1, -- }; - -- assert_non_null(in.dn); -+ assert_non_null(msg); -+ msg->dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"); -+ msg->num_elements = 1; -+ msg->elements = &element_1; - -- ret = ldb_filter_attrs_in_place(ctx->ldb, -- &in, -- attrs, -- filtered_msg); -+ assert_non_null(msg->dn); -+ msg_add_dn(msg); -+ -+ ret = ldb_filter_attrs_in_place(msg, attrs); - assert_int_equal(ret, LDB_SUCCESS); -- assert_non_null(filtered_msg); - -- /* -- * assert the ldb_filter_attrs_in_place does not read or modify -- * filtered_msg.dn in this case -- */ -- assert_null(filtered_msg->dn); -- assert_int_equal(filtered_msg->num_elements, 1); -- assert_string_equal(filtered_msg->elements[0].name, "foo"); -- assert_int_equal(filtered_msg->elements[0].num_values, 1); -- assert_int_equal(filtered_msg->elements[0].values[0].length, -+ assert_non_null(msg->dn); -+ assert_int_equal(msg->num_elements, 1); -+ assert_string_equal(msg->elements[0].name, "foo"); -+ assert_int_equal(msg->elements[0].num_values, 1); -+ assert_int_equal(msg->elements[0].values[0].length, - strlen(value)); -- assert_memory_equal(filtered_msg->elements[0].values[0].data, -+ assert_memory_equal(msg->elements[0].values[0].data, - value, strlen(value)); - } - -@@ -192,12 +202,12 @@ static void test_filter_attrs_one_attr_matched_of_many(void **state) - * Test against a record with only one attribute, matching both - * attributes in the list - */ --static void test_filter_attrs_two_attr_matched_attrs(void **state) -+static void test_filter_attrs_in_place_two_attr_matched_attrs(void **state) - { - struct ldbtest_ctx *ctx = *state; - int ret; - -- struct ldb_message *filtered_msg = ldb_msg_new(ctx); -+ struct ldb_message *msg = ldb_msg_new(ctx); - - /* deliberatly the other order */ - const char *attrs[] = {"bar", "foo", NULL}; -@@ -226,40 +236,33 @@ static void test_filter_attrs_two_attr_matched_attrs(void **state) - .values = &value_2 - } - }; -- struct ldb_message in = { -- .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), -- .num_elements = 2, -- .elements = elements, -- }; - -- assert_non_null(in.dn); -+ assert_non_null(msg); -+ msg->dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"); -+ msg->num_elements = 2; -+ msg->elements = elements; - -- ret = ldb_filter_attrs_in_place(ctx->ldb, -- &in, -- attrs, -- filtered_msg); -+ assert_non_null(msg->dn); -+ msg_add_dn(msg); -+ -+ ret = ldb_filter_attrs_in_place(msg, attrs); - assert_int_equal(ret, LDB_SUCCESS); -- assert_non_null(filtered_msg); -- assert_int_equal(filtered_msg->num_elements, 2); -+ assert_int_equal(msg->num_elements, 2); - -- /* -- * assert the ldb_filter_attrs_in_place does not read or modify -- * filtered_msg.dn in this case -- */ -- assert_null(filtered_msg->dn); -+ assert_non_null(msg->dn); - - /* Assert that DB order is preserved */ -- assert_string_equal(filtered_msg->elements[0].name, "foo"); -- assert_int_equal(filtered_msg->elements[0].num_values, 1); -- assert_int_equal(filtered_msg->elements[0].values[0].length, -+ assert_string_equal(msg->elements[0].name, "foo"); -+ assert_int_equal(msg->elements[0].num_values, 1); -+ assert_int_equal(msg->elements[0].values[0].length, - strlen(value1)); -- assert_memory_equal(filtered_msg->elements[0].values[0].data, -+ assert_memory_equal(msg->elements[0].values[0].data, - value1, strlen(value1)); -- assert_string_equal(filtered_msg->elements[1].name, "bar"); -- assert_int_equal(filtered_msg->elements[1].num_values, 1); -- assert_int_equal(filtered_msg->elements[1].values[0].length, -+ assert_string_equal(msg->elements[1].name, "bar"); -+ assert_int_equal(msg->elements[1].num_values, 1); -+ assert_int_equal(msg->elements[1].values[0].length, - strlen(value2)); -- assert_memory_equal(filtered_msg->elements[1].values[0].data, -+ assert_memory_equal(msg->elements[1].values[0].data, - value2, strlen(value2)); - } - -@@ -267,14 +270,13 @@ static void test_filter_attrs_two_attr_matched_attrs(void **state) - * Test against a record with two attributes, only of which is in - * the list - */ --static void test_filter_attrs_two_attr_matched_one_attr(void **state) -+static void test_filter_attrs_in_place_two_attr_matched_one_attr(void **state) - { - struct ldbtest_ctx *ctx = *state; - int ret; - -- struct ldb_message *filtered_msg = ldb_msg_new(ctx); -+ struct ldb_message *msg = ldb_msg_new(ctx); - -- /* deliberatly the other order */ - const char *attrs[] = {"bar", NULL}; - - char value1[] = "The value.......end"; -@@ -288,7 +290,6 @@ static void test_filter_attrs_two_attr_matched_one_attr(void **state) - .length = strlen(value2) - }; - -- /* foo and bar are the other order to in attrs */ - struct ldb_message_element elements[] = { - { - .name = "foo", -@@ -301,34 +302,27 @@ static void test_filter_attrs_two_attr_matched_one_attr(void **state) - .values = &value_2 - } - }; -- struct ldb_message in = { -- .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), -- .num_elements = 2, -- .elements = elements, -- }; - -- assert_non_null(in.dn); -+ assert_non_null(msg); -+ msg->dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"); -+ msg->num_elements = 2; -+ msg->elements = elements; - -- ret = ldb_filter_attrs_in_place(ctx->ldb, -- &in, -- attrs, -- filtered_msg); -+ assert_non_null(msg->dn); -+ msg_add_dn(msg); -+ -+ ret = ldb_filter_attrs_in_place(msg, attrs); - assert_int_equal(ret, LDB_SUCCESS); -- assert_non_null(filtered_msg); -- assert_int_equal(filtered_msg->num_elements, 1); -+ assert_int_equal(msg->num_elements, 1); - -- /* -- * assert the ldb_filter_attrs_in_place does not read or modify -- * filtered_msg.dn in this case -- */ -- assert_null(filtered_msg->dn); -+ assert_non_null(msg->dn); - - /* Assert that DB order is preserved */ -- assert_string_equal(filtered_msg->elements[0].name, "bar"); -- assert_int_equal(filtered_msg->elements[0].num_values, 1); -- assert_int_equal(filtered_msg->elements[0].values[0].length, -+ assert_string_equal(msg->elements[0].name, "bar"); -+ assert_int_equal(msg->elements[0].num_values, 1); -+ assert_int_equal(msg->elements[0].values[0].length, - strlen(value2)); -- assert_memory_equal(filtered_msg->elements[0].values[0].data, -+ assert_memory_equal(msg->elements[0].values[0].data, - value2, strlen(value2)); - } - -@@ -336,14 +330,13 @@ static void test_filter_attrs_two_attr_matched_one_attr(void **state) - * Test against a record with two attributes, both matching the one - * specified attribute in the list (a corrupt record) - */ --static void test_filter_attrs_two_dup_attr_matched_one_attr(void **state) -+static void test_filter_attrs_in_place_two_dup_attr_matched_one_attr(void **state) - { - struct ldbtest_ctx *ctx = *state; - int ret; - -- struct ldb_message *filtered_msg = ldb_msg_new(ctx); -+ struct ldb_message *msg = ldb_msg_new(ctx); - -- /* deliberatly the other order */ - const char *attrs[] = {"bar", NULL}; - - char value1[] = "The value.......end"; -@@ -357,7 +350,6 @@ static void test_filter_attrs_two_dup_attr_matched_one_attr(void **state) - .length = strlen(value2) - }; - -- /* foo and bar are the other order to in attrs */ - struct ldb_message_element elements[] = { - { - .name = "bar", -@@ -370,34 +362,49 @@ static void test_filter_attrs_two_dup_attr_matched_one_attr(void **state) - .values = &value_2 - } - }; -- struct ldb_message in = { -- .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), -- .num_elements = 2, -- .elements = elements, -- }; - -- assert_non_null(in.dn); -+ assert_non_null(msg); -+ msg->dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"); -+ msg->num_elements = 2; -+ msg->elements = elements; -+ -+ assert_non_null(msg->dn); -+ msg_add_dn(msg); -+ -+ ret = ldb_filter_attrs_in_place(msg, attrs); - -- ret = ldb_filter_attrs_in_place(ctx->ldb, -- &in, -- attrs, -- filtered_msg); -+ /* Both elements match the filter */ -+ assert_int_equal(ret, LDB_SUCCESS); -+ assert_int_equal(msg->num_elements, 2); -+ -+ assert_non_null(msg->dn); - -- /* This should fail the pidgenhole test */ -- assert_int_equal(ret, -1); -- assert_null(filtered_msg->elements); -+ /* Assert that DB order is preserved */ -+ assert_string_equal(msg->elements[0].name, "bar"); -+ assert_int_equal(msg->elements[0].num_values, 1); -+ assert_int_equal(msg->elements[0].values[0].length, -+ strlen(value1)); -+ assert_memory_equal(msg->elements[0].values[0].data, -+ value1, strlen(value1)); -+ -+ assert_string_equal(msg->elements[1].name, "bar"); -+ assert_int_equal(msg->elements[1].num_values, 1); -+ assert_int_equal(msg->elements[1].values[0].length, -+ strlen(value2)); -+ assert_memory_equal(msg->elements[1].values[0].data, -+ value2, strlen(value2)); - } - - /* - * Test against a record with two attributes, both matching the one - * specified attribute in the list (a corrupt record) - */ --static void test_filter_attrs_two_dup_attr_matched_dup(void **state) -+static void test_filter_attrs_in_place_two_dup_attr_matched_dup(void **state) - { - struct ldbtest_ctx *ctx = *state; - int ret; - -- struct ldb_message *filtered_msg = ldb_msg_new(ctx); -+ struct ldb_message *msg = ldb_msg_new(ctx); - - const char *attrs[] = {"bar", "bar", NULL}; - -@@ -412,7 +419,6 @@ static void test_filter_attrs_two_dup_attr_matched_dup(void **state) - .length = strlen(value2) - }; - -- /* foo and bar are the other order to in attrs */ - struct ldb_message_element elements[] = { - { - .name = "bar", -@@ -425,35 +431,33 @@ static void test_filter_attrs_two_dup_attr_matched_dup(void **state) - .values = &value_2 - } - }; -- struct ldb_message in = { -- .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), -- .num_elements = 2, -- .elements = elements, -- }; - -- assert_non_null(in.dn); -+ assert_non_null(msg); -+ msg->dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"); -+ msg->num_elements = 2; -+ msg->elements = elements; -+ -+ assert_non_null(msg->dn); -+ msg_add_dn(msg); - -- ret = ldb_filter_attrs_in_place(ctx->ldb, -- &in, -- attrs, -- filtered_msg); -+ ret = ldb_filter_attrs_in_place(msg, attrs); - - /* This does not fail the pidgenhole test */ - assert_int_equal(ret, LDB_SUCCESS); -- assert_int_equal(filtered_msg->num_elements, 2); -+ assert_int_equal(msg->num_elements, 2); - - /* Assert that DB order is preserved */ -- assert_string_equal(filtered_msg->elements[0].name, "bar"); -- assert_int_equal(filtered_msg->elements[0].num_values, 1); -- assert_int_equal(filtered_msg->elements[0].values[0].length, -+ assert_string_equal(msg->elements[0].name, "bar"); -+ assert_int_equal(msg->elements[0].num_values, 1); -+ assert_int_equal(msg->elements[0].values[0].length, - strlen(value1)); -- assert_memory_equal(filtered_msg->elements[0].values[0].data, -+ assert_memory_equal(msg->elements[0].values[0].data, - value1, strlen(value1)); -- assert_string_equal(filtered_msg->elements[1].name, "bar"); -- assert_int_equal(filtered_msg->elements[1].num_values, 1); -- assert_int_equal(filtered_msg->elements[1].values[0].length, -+ assert_string_equal(msg->elements[1].name, "bar"); -+ assert_int_equal(msg->elements[1].num_values, 1); -+ assert_int_equal(msg->elements[1].values[0].length, - strlen(value2)); -- assert_memory_equal(filtered_msg->elements[1].values[0].data, -+ assert_memory_equal(msg->elements[1].values[0].data, - value2, strlen(value2)); - } - -@@ -461,12 +465,12 @@ static void test_filter_attrs_two_dup_attr_matched_dup(void **state) - * Test against a record with two attributes, both matching one of the - * specified attributes in the list (a corrupt record) - */ --static void test_filter_attrs_two_dup_attr_matched_one_of_two(void **state) -+static void test_filter_attrs_in_place_two_dup_attr_matched_one_of_two(void **state) - { - struct ldbtest_ctx *ctx = *state; - int ret; - -- struct ldb_message *filtered_msg = ldb_msg_new(ctx); -+ struct ldb_message *msg = ldb_msg_new(ctx); - - const char *attrs[] = {"bar", "foo", NULL}; - -@@ -481,7 +485,6 @@ static void test_filter_attrs_two_dup_attr_matched_one_of_two(void **state) - .length = strlen(value2) - }; - -- /* foo and bar are the other order to in attrs */ - struct ldb_message_element elements[] = { - { - .name = "bar", -@@ -494,35 +497,33 @@ static void test_filter_attrs_two_dup_attr_matched_one_of_two(void **state) - .values = &value_2 - } - }; -- struct ldb_message in = { -- .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), -- .num_elements = 2, -- .elements = elements, -- }; - -- assert_non_null(in.dn); -+ assert_non_null(msg); -+ msg->dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"); -+ msg->num_elements = 2; -+ msg->elements = elements; - -- ret = ldb_filter_attrs_in_place(ctx->ldb, -- &in, -- attrs, -- filtered_msg); -+ assert_non_null(msg->dn); -+ msg_add_dn(msg); -+ -+ ret = ldb_filter_attrs_in_place(msg, attrs); - - /* This does not fail the pidgenhole test */ - assert_int_equal(ret, LDB_SUCCESS); -- assert_int_equal(filtered_msg->num_elements, 2); -+ assert_int_equal(msg->num_elements, 2); - - /* Assert that DB order is preserved */ -- assert_string_equal(filtered_msg->elements[0].name, "bar"); -- assert_int_equal(filtered_msg->elements[0].num_values, 1); -- assert_int_equal(filtered_msg->elements[0].values[0].length, -+ assert_string_equal(msg->elements[0].name, "bar"); -+ assert_int_equal(msg->elements[0].num_values, 1); -+ assert_int_equal(msg->elements[0].values[0].length, - strlen(value1)); -- assert_memory_equal(filtered_msg->elements[0].values[0].data, -+ assert_memory_equal(msg->elements[0].values[0].data, - value1, strlen(value1)); -- assert_string_equal(filtered_msg->elements[1].name, "bar"); -- assert_int_equal(filtered_msg->elements[1].num_values, 1); -- assert_int_equal(filtered_msg->elements[1].values[0].length, -+ assert_string_equal(msg->elements[1].name, "bar"); -+ assert_int_equal(msg->elements[1].num_values, 1); -+ assert_int_equal(msg->elements[1].values[0].length, - strlen(value2)); -- assert_memory_equal(filtered_msg->elements[1].values[0].data, -+ assert_memory_equal(msg->elements[1].values[0].data, - value2, strlen(value2)); - } - -@@ -530,12 +531,12 @@ static void test_filter_attrs_two_dup_attr_matched_one_of_two(void **state) - * Test against a record with two attributes against * (but not the - * other named attribute) (a corrupt record) - */ --static void test_filter_attrs_two_dup_attr_matched_star(void **state) -+static void test_filter_attrs_in_place_two_dup_attr_matched_star(void **state) - { - struct ldbtest_ctx *ctx = *state; - int ret; - -- struct ldb_message *filtered_msg = ldb_msg_new(ctx); -+ struct ldb_message *msg = ldb_msg_new(ctx); - - const char *attrs[] = {"*", "foo", NULL}; - -@@ -550,7 +551,6 @@ static void test_filter_attrs_two_dup_attr_matched_star(void **state) - .length = strlen(value2) - }; - -- /* foo and bar are the other order to in attrs */ - struct ldb_message_element elements[] = { - { - .name = "bar", -@@ -563,60 +563,52 @@ static void test_filter_attrs_two_dup_attr_matched_star(void **state) - .values = &value_2 - } - }; -- struct ldb_message in = { -- .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), -- .num_elements = 2, -- .elements = elements, -- }; - -- assert_non_null(in.dn); -+ assert_non_null(msg); -+ msg->dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"); -+ msg->num_elements = 2; -+ msg->elements = elements; - -- /* Needed as * implies distinguishedName */ -- filtered_msg->dn = in.dn; -+ assert_non_null(msg->dn); -+ msg_add_dn(msg); - -- ret = ldb_filter_attrs_in_place(ctx->ldb, -- &in, -- attrs, -- filtered_msg); -+ ret = ldb_filter_attrs_in_place(msg, attrs); - - /* This does not fail the pidgenhole test */ - assert_int_equal(ret, LDB_SUCCESS); -- assert_int_equal(filtered_msg->num_elements, 3); -+ assert_int_equal(msg->num_elements, 3); - - /* Assert that DB order is preserved */ -- assert_string_equal(filtered_msg->elements[0].name, "bar"); -- assert_int_equal(filtered_msg->elements[0].num_values, 1); -- assert_int_equal(filtered_msg->elements[0].values[0].length, -+ assert_string_equal(msg->elements[0].name, "bar"); -+ assert_int_equal(msg->elements[0].num_values, 1); -+ assert_int_equal(msg->elements[0].values[0].length, - strlen(value1)); -- assert_memory_equal(filtered_msg->elements[0].values[0].data, -+ assert_memory_equal(msg->elements[0].values[0].data, - value1, strlen(value1)); -- assert_string_equal(filtered_msg->elements[1].name, "bar"); -- assert_int_equal(filtered_msg->elements[1].num_values, 1); -- assert_int_equal(filtered_msg->elements[1].values[0].length, -+ assert_string_equal(msg->elements[1].name, "bar"); -+ assert_int_equal(msg->elements[1].num_values, 1); -+ assert_int_equal(msg->elements[1].values[0].length, - strlen(value2)); -- assert_memory_equal(filtered_msg->elements[1].values[0].data, -+ assert_memory_equal(msg->elements[1].values[0].data, - value2, strlen(value2)); -- /* -- * assert the ldb_filter_attrs_in_place does not modify filtered_msg.dn -- * in this case -- */ -- assert_ptr_equal(filtered_msg->dn, in.dn); -- assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, -+ -+ assert_non_null(msg->dn); -+ assert_string_equal(ldb_msg_find_attr_as_string(msg, - "distinguishedName", - NULL), -- ldb_dn_get_linearized(in.dn)); -+ ldb_dn_get_linearized(msg->dn)); - } - - /* - * Test against a record with only one attribute, matching the * in - * the list - */ --static void test_filter_attrs_one_attr_matched_star(void **state) -+static void test_filter_attrs_in_place_one_attr_matched_star(void **state) - { - struct ldbtest_ctx *ctx = *state; - int ret; - -- struct ldb_message *filtered_msg = ldb_msg_new(ctx); -+ struct ldb_message *msg = ldb_msg_new(ctx); - - const char *attrs[] = {"*", NULL}; - -@@ -630,35 +622,25 @@ static void test_filter_attrs_one_attr_matched_star(void **state) - .num_values = 1, - .values = &value_1 - }; -- struct ldb_message in = { -- .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), -- .num_elements = 1, -- .elements = &element_1, -- }; - -- assert_non_null(in.dn); -+ assert_non_null(msg); -+ msg->dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"); -+ msg->num_elements = 1; -+ msg->elements = &element_1; - -- /* Needed as * implies distinguishedName */ -- filtered_msg->dn = in.dn; -+ assert_non_null(msg->dn); -+ msg_add_dn(msg); - -- ret = ldb_filter_attrs_in_place(ctx->ldb, -- &in, -- attrs, -- filtered_msg); -+ ret = ldb_filter_attrs_in_place(msg, attrs); - assert_int_equal(ret, LDB_SUCCESS); -- assert_non_null(filtered_msg); -- assert_int_equal(filtered_msg->num_elements, 2); -+ assert_int_equal(msg->num_elements, 2); - -- /* -- * assert the ldb_filter_attrs_in_place does not modify filtered_msg.dn -- * in this case -- */ -- assert_ptr_equal(filtered_msg->dn, in.dn); -- assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, -+ assert_non_null(msg->dn); -+ assert_string_equal(ldb_msg_find_attr_as_string(msg, - "distinguishedName", - NULL), -- ldb_dn_get_linearized(in.dn)); -- assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, -+ ldb_dn_get_linearized(msg->dn)); -+ assert_string_equal(ldb_msg_find_attr_as_string(msg, - "foo", - NULL), - value); -@@ -668,12 +650,12 @@ static void test_filter_attrs_one_attr_matched_star(void **state) - * Test against a record with two attributes, matching the * in - * the list - */ --static void test_filter_attrs_two_attr_matched_star(void **state) -+static void test_filter_attrs_in_place_two_attr_matched_star(void **state) - { - struct ldbtest_ctx *ctx = *state; - int ret; - -- struct ldb_message *filtered_msg = ldb_msg_new(ctx); -+ struct ldb_message *msg = ldb_msg_new(ctx); - - const char *attrs[] = {"*", NULL}; - -@@ -699,39 +681,29 @@ static void test_filter_attrs_two_attr_matched_star(void **state) - .values = &value_2 - } - }; -- struct ldb_message in = { -- .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), -- .num_elements = 2, -- .elements = elements, -- }; - -- assert_non_null(in.dn); -+ assert_non_null(msg); -+ msg->dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"); -+ msg->num_elements = 2; -+ msg->elements = elements; - -- /* Needed as * implies distinguishedName */ -- filtered_msg->dn = in.dn; -+ assert_non_null(msg->dn); -+ msg_add_dn(msg); - -- ret = ldb_filter_attrs_in_place(ctx->ldb, -- &in, -- attrs, -- filtered_msg); -+ ret = ldb_filter_attrs_in_place(msg, attrs); - assert_int_equal(ret, LDB_SUCCESS); -- assert_non_null(filtered_msg); -- assert_int_equal(filtered_msg->num_elements, 3); -+ assert_int_equal(msg->num_elements, 3); - -- /* -- * assert the ldb_filter_attrs_in_place does not modify filtered_msg.dn -- * in this case -- */ -- assert_ptr_equal(filtered_msg->dn, in.dn); -- assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, -+ assert_non_null(msg->dn); -+ assert_string_equal(ldb_msg_find_attr_as_string(msg, - "distinguishedName", - NULL), -- ldb_dn_get_linearized(in.dn)); -- assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, -+ ldb_dn_get_linearized(msg->dn)); -+ assert_string_equal(ldb_msg_find_attr_as_string(msg, - "foo", - NULL), - value1); -- assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, -+ assert_string_equal(ldb_msg_find_attr_as_string(msg, - "bar", - NULL), - value2); -@@ -739,15 +711,15 @@ static void test_filter_attrs_two_attr_matched_star(void **state) - - /* - * Test against a record with only one attribute, matching the * in -- * the list, but without the DN being pre-filled. Fails due to need -- * to contstruct the distinguishedName -+ * the list, but without the DN being pre-filled. Succeeds, but the -+ * distinguishedName is not added. - */ --static void test_filter_attrs_one_attr_matched_star_no_dn(void **state) -+static void test_filter_attrs_in_place_one_attr_matched_star_no_dn(void **state) - { - struct ldbtest_ctx *ctx = *state; - int ret; - -- struct ldb_message *filtered_msg = ldb_msg_new(ctx); -+ struct ldb_message *msg = ldb_msg_new(ctx); - - const char *attrs[] = {"*", NULL}; - -@@ -761,32 +733,29 @@ static void test_filter_attrs_one_attr_matched_star_no_dn(void **state) - .num_values = 1, - .values = &value_1 - }; -- struct ldb_message in = { -- .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), -- .num_elements = 1, -- .elements = &element_1, -- }; - -- assert_non_null(in.dn); -+ assert_non_null(msg); -+ msg->dn = NULL; -+ msg->num_elements = 1; -+ msg->elements = &element_1; -+ -+ assert_null(msg->dn); - -- ret = ldb_filter_attrs_in_place(ctx->ldb, -- &in, -- attrs, -- filtered_msg); -- assert_int_equal(ret, -1); -- assert_null(filtered_msg->elements); -+ ret = ldb_filter_attrs_in_place(msg, attrs); -+ assert_int_equal(ret, LDB_SUCCESS); -+ assert_int_equal(msg->num_elements, 1); - } - - /* - * Test against a record with only one attribute, matching the * in - * the list plus requsesting distinguishedName - */ --static void test_filter_attrs_one_attr_matched_star_dn(void **state) -+static void test_filter_attrs_in_place_one_attr_matched_star_dn(void **state) - { - struct ldbtest_ctx *ctx = *state; - int ret; - -- struct ldb_message *filtered_msg = ldb_msg_new(ctx); -+ struct ldb_message *msg = ldb_msg_new(ctx); - - const char *attrs[] = {"*", "distinguishedName", NULL}; - -@@ -800,33 +769,26 @@ static void test_filter_attrs_one_attr_matched_star_dn(void **state) - .num_values = 1, - .values = &value_1 - }; -- struct ldb_message in = { -- .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), -- .num_elements = 1, -- .elements = &element_1, -- }; - -- assert_non_null(in.dn); -+ assert_non_null(msg); -+ msg->dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"); -+ msg->num_elements = 1; -+ msg->elements = &element_1; - -- /* Needed for distinguishedName */ -- filtered_msg->dn = in.dn; -+ assert_non_null(msg->dn); -+ msg_add_dn(msg); - -- ret = ldb_filter_attrs_in_place(ctx->ldb, -- &in, -- attrs, -- filtered_msg); -+ ret = ldb_filter_attrs_in_place(msg, attrs); - assert_int_equal(ret, LDB_SUCCESS); -- assert_non_null(filtered_msg); -- assert_int_equal(filtered_msg->num_elements, 2); -+ assert_int_equal(msg->num_elements, 2); - -- /* show that ldb_filter_attrs_in_place does not modify in.dn */ -- assert_ptr_equal(filtered_msg->dn, in.dn); -+ assert_non_null(msg->dn); - -- assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, -+ assert_string_equal(ldb_msg_find_attr_as_string(msg, - "distinguishedName", - NULL), -- ldb_dn_get_linearized(in.dn)); -- assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, -+ ldb_dn_get_linearized(msg->dn)); -+ assert_string_equal(ldb_msg_find_attr_as_string(msg, - "foo", - NULL), - value); -@@ -836,12 +798,12 @@ static void test_filter_attrs_one_attr_matched_star_dn(void **state) - * Test against a record with only one attribute, but returning - * distinguishedName from the list (only) - */ --static void test_filter_attrs_one_attr_matched_dn(void **state) -+static void test_filter_attrs_in_place_one_attr_matched_dn(void **state) - { - struct ldbtest_ctx *ctx = *state; - int ret; - -- struct ldb_message *filtered_msg = ldb_msg_new(ctx); -+ struct ldb_message *msg = ldb_msg_new(ctx); - - const char *attrs[] = {"distinguishedName", NULL}; - -@@ -855,43 +817,36 @@ static void test_filter_attrs_one_attr_matched_dn(void **state) - .num_values = 1, - .values = &value_1 - }; -- struct ldb_message in = { -- .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), -- .num_elements = 1, -- .elements = &element_1, -- }; - -- assert_non_null(in.dn); -+ assert_non_null(msg); -+ msg->dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"); -+ msg->num_elements = 1; -+ msg->elements = &element_1; - -- /* Needed for distinguishedName */ -- filtered_msg->dn = in.dn; -+ assert_non_null(msg->dn); -+ msg_add_dn(msg); - -- ret = ldb_filter_attrs_in_place(ctx->ldb, -- &in, -- attrs, -- filtered_msg); -+ ret = ldb_filter_attrs_in_place(msg, attrs); - assert_int_equal(ret, LDB_SUCCESS); -- assert_non_null(filtered_msg); -- assert_int_equal(filtered_msg->num_elements, 1); -- -- /* show that ldb_filter_attrs_in_place does not modify in.dn */ -- assert_ptr_equal(filtered_msg->dn, in.dn); -- assert_string_equal(filtered_msg->elements[0].name, "distinguishedName"); -- assert_int_equal(filtered_msg->elements[0].num_values, 1); -- assert_string_equal(filtered_msg->elements[0].values[0].data, -- ldb_dn_get_linearized(in.dn)); -+ assert_int_equal(msg->num_elements, 1); -+ -+ assert_non_null(msg->dn); -+ assert_string_equal(msg->elements[0].name, "distinguishedName"); -+ assert_int_equal(msg->elements[0].num_values, 1); -+ assert_string_equal(msg->elements[0].values[0].data, -+ ldb_dn_get_linearized(msg->dn)); - } - - /* - * Test against a record with only one attribute, not matching the - * empty attribute list - */ --static void test_filter_attrs_one_attr_empty_list(void **state) -+static void test_filter_attrs_in_place_one_attr_empty_list(void **state) - { - struct ldbtest_ctx *ctx = *state; - int ret; - -- struct ldb_message *filtered_msg = ldb_msg_new(ctx); -+ struct ldb_message *msg = ldb_msg_new(ctx); - - const char *attrs[] = {NULL}; - -@@ -905,82 +860,78 @@ static void test_filter_attrs_one_attr_empty_list(void **state) - .num_values = 1, - .values = &value_1 - }; -- struct ldb_message in = { -- .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), -- .num_elements = 1, -- .elements = &element_1, -- }; - -- assert_non_null(in.dn); -+ assert_non_null(msg); -+ msg->dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"); -+ msg->num_elements = 1; -+ msg->elements = &element_1; -+ -+ assert_non_null(msg->dn); -+ msg_add_dn(msg); - -- ret = ldb_filter_attrs_in_place(ctx->ldb, -- &in, -- attrs, -- filtered_msg); -+ ret = ldb_filter_attrs_in_place(msg, attrs); - assert_int_equal(ret, LDB_SUCCESS); -- assert_non_null(filtered_msg); -- assert_int_equal(filtered_msg->num_elements, 0); -- assert_null(filtered_msg->dn); -- assert_null(filtered_msg->elements); -+ assert_int_equal(msg->num_elements, 0); -+ assert_non_null(msg->dn); - } - - int main(int argc, const char **argv) - { - const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown( -- test_filter_attrs_one_attr_matched, -+ test_filter_attrs_in_place_one_attr_matched, - setup, - teardown), - cmocka_unit_test_setup_teardown( -- test_filter_attrs_one_attr_matched_of_many, -+ test_filter_attrs_in_place_one_attr_matched_of_many, - setup, - teardown), - cmocka_unit_test_setup_teardown( -- test_filter_attrs_two_attr_matched_attrs, -+ test_filter_attrs_in_place_two_attr_matched_attrs, - setup, - teardown), - cmocka_unit_test_setup_teardown( -- test_filter_attrs_two_attr_matched_one_attr, -+ test_filter_attrs_in_place_two_attr_matched_one_attr, - setup, - teardown), - cmocka_unit_test_setup_teardown( -- test_filter_attrs_two_dup_attr_matched_one_attr, -+ test_filter_attrs_in_place_two_dup_attr_matched_one_attr, - setup, - teardown), - cmocka_unit_test_setup_teardown( -- test_filter_attrs_two_dup_attr_matched_dup, -+ test_filter_attrs_in_place_two_dup_attr_matched_dup, - setup, - teardown), - cmocka_unit_test_setup_teardown( -- test_filter_attrs_two_dup_attr_matched_one_of_two, -+ test_filter_attrs_in_place_two_dup_attr_matched_one_of_two, - setup, - teardown), - cmocka_unit_test_setup_teardown( -- test_filter_attrs_two_dup_attr_matched_star, -+ test_filter_attrs_in_place_two_dup_attr_matched_star, - setup, - teardown), - cmocka_unit_test_setup_teardown( -- test_filter_attrs_one_attr_matched_star, -+ test_filter_attrs_in_place_one_attr_matched_star, - setup, - teardown), - cmocka_unit_test_setup_teardown( -- test_filter_attrs_two_attr_matched_star, -+ test_filter_attrs_in_place_two_attr_matched_star, - setup, - teardown), - cmocka_unit_test_setup_teardown( -- test_filter_attrs_one_attr_matched_star_no_dn, -+ test_filter_attrs_in_place_one_attr_matched_star_no_dn, - setup, - teardown), - cmocka_unit_test_setup_teardown( -- test_filter_attrs_one_attr_matched_star_dn, -+ test_filter_attrs_in_place_one_attr_matched_star_dn, - setup, - teardown), - cmocka_unit_test_setup_teardown( -- test_filter_attrs_one_attr_matched_dn, -+ test_filter_attrs_in_place_one_attr_matched_dn, - setup, - teardown), - cmocka_unit_test_setup_teardown( -- test_filter_attrs_one_attr_empty_list, -+ test_filter_attrs_in_place_one_attr_empty_list, - setup, - teardown), - }; --- -2.25.1 diff --git a/backport-0010-CVE-2023-0614.patch b/backport-0010-CVE-2023-0614.patch deleted file mode 100644 index d75d15ec942ae49369372a385e8ab0f41b4fd057..0000000000000000000000000000000000000000 --- a/backport-0010-CVE-2023-0614.patch +++ /dev/null @@ -1,257 +0,0 @@ -From 8e84201f508b2893b6ec9383c656cccb08b148ef Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Mon, 27 Feb 2023 10:31:52 +1300 -Subject: [PATCH 14/34] CVE-2023-0614 ldb: Make use of - ldb_filter_attrs_in_place() - -Change all uses of ldb_kv_filter_attrs() to use -ldb_filter_attrs_in_place() instead. This function does less work than -its predecessor, and no longer requires the allocation of a second ldb -message. Some of the work is able to be split out into separate -functions that each accomplish a single task, with a purpose to make the -code clearer. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15270 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett - -Conflict: NA -Reference: https://attachments.samba.org/attachment.cgi?id=17821 ---- - ldb_key_value/ldb_kv.h | 6 +- - ldb_key_value/ldb_kv_index.c | 27 +++++---- - ldb_key_value/ldb_kv_search.c | 86 ++++++++++++++------------- - 4 files changed, 66 insertions(+), 65 deletions(-) - -diff --git a/ldb_key_value/ldb_kv.h b/ldb_key_value/ldb_kv.h -index ac474b04b4c..7d5a40e76e9 100644 ---- a/ldb_key_value/ldb_kv.h -+++ b/ldb_key_value/ldb_kv.h -@@ -301,10 +301,8 @@ int ldb_kv_search_key(struct ldb_module *module, - const struct ldb_val ldb_key, - struct ldb_message *msg, - unsigned int unpack_flags); --int ldb_kv_filter_attrs(struct ldb_context *ldb, -- const struct ldb_message *msg, -- const char *const *attrs, -- struct ldb_message *filtered_msg); -+int ldb_kv_filter_attrs_in_place(struct ldb_message *msg, -+ const char *const *attrs); - int ldb_kv_search(struct ldb_kv_context *ctx); - - /* -diff --git a/ldb_key_value/ldb_kv_index.c b/ldb_key_value/ldb_kv_index.c -index d70e5f619ef..203266ea8c9 100644 ---- a/ldb_key_value/ldb_kv_index.c -+++ b/ldb_key_value/ldb_kv_index.c -@@ -2264,7 +2264,6 @@ static int ldb_kv_index_filter(struct ldb_kv_private *ldb_kv, - { - struct ldb_context *ldb = ldb_module_get_ctx(ac->module); - struct ldb_message *msg; -- struct ldb_message *filtered_msg; - unsigned int i; - unsigned int num_keys = 0; - uint8_t previous_guid_key[LDB_KV_GUID_KEY_SIZE] = {0}; -@@ -2456,27 +2455,31 @@ static int ldb_kv_index_filter(struct ldb_kv_private *ldb_kv, - continue; - } - -- filtered_msg = ldb_msg_new(ac); -- if (filtered_msg == NULL) { -- TALLOC_FREE(keys); -- TALLOC_FREE(msg); -+ ret = ldb_msg_add_distinguished_name(msg); -+ if (ret == -1) { -+ talloc_free(msg); - return LDB_ERR_OPERATIONS_ERROR; - } - -- filtered_msg->dn = talloc_steal(filtered_msg, msg->dn); -- - /* filter the attributes that the user wants */ -- ret = ldb_kv_filter_attrs(ldb, msg, ac->attrs, filtered_msg); -+ ret = ldb_kv_filter_attrs_in_place(msg, ac->attrs); -+ if (ret != LDB_SUCCESS) { -+ talloc_free(keys); -+ talloc_free(msg); -+ return LDB_ERR_OPERATIONS_ERROR; -+ } - -- talloc_free(msg); -+ ldb_msg_shrink_to_fit(msg); - -- if (ret == -1) { -- TALLOC_FREE(filtered_msg); -+ /* Ensure the message elements are all talloc'd. */ -+ ret = ldb_msg_elements_take_ownership(msg); -+ if (ret != LDB_SUCCESS) { - talloc_free(keys); -+ talloc_free(msg); - return LDB_ERR_OPERATIONS_ERROR; - } - -- ret = ldb_module_send_entry(ac->req, filtered_msg, NULL); -+ ret = ldb_module_send_entry(ac->req, msg, NULL); - if (ret != LDB_SUCCESS) { - /* Regardless of success or failure, the msg - * is the callbacks responsiblity, and should -diff --git a/ldb_key_value/ldb_kv_search.c b/ldb_key_value/ldb_kv_search.c -index 46031b99c16..f3333510eab 100644 ---- a/ldb_key_value/ldb_kv_search.c -+++ b/ldb_key_value/ldb_kv_search.c -@@ -292,15 +292,13 @@ int ldb_kv_search_dn1(struct ldb_module *module, - - /* - * filter the specified list of attributes from msg, -- * adding requested attributes, and perhaps all for *, -- * but not the DN to filtered_msg. -+ * adding requested attributes, and perhaps all for *. -+ * The DN will not be added if it is missing. - */ --int ldb_kv_filter_attrs(struct ldb_context *ldb, -- const struct ldb_message *msg, -- const char *const *attrs, -- struct ldb_message *filtered_msg) -+int ldb_kv_filter_attrs_in_place(struct ldb_message *msg, -+ const char *const *attrs) - { -- return ldb_filter_attrs(ldb, msg, attrs, filtered_msg); -+ return ldb_filter_attrs_in_place(msg, attrs); - } - - /* -@@ -313,7 +311,7 @@ static int search_func(_UNUSED_ struct ldb_kv_private *ldb_kv, - { - struct ldb_context *ldb; - struct ldb_kv_context *ac; -- struct ldb_message *msg, *filtered_msg; -+ struct ldb_message *msg; - struct timeval now; - int ret, timeval_cmp; - bool matched; -@@ -410,25 +408,31 @@ static int search_func(_UNUSED_ struct ldb_kv_private *ldb_kv, - return 0; - } - -- filtered_msg = ldb_msg_new(ac); -- if (filtered_msg == NULL) { -- TALLOC_FREE(msg); -+ ret = ldb_msg_add_distinguished_name(msg); -+ if (ret == -1) { -+ talloc_free(msg); - return LDB_ERR_OPERATIONS_ERROR; - } - -- filtered_msg->dn = talloc_steal(filtered_msg, msg->dn); -- - /* filter the attributes that the user wants */ -- ret = ldb_kv_filter_attrs(ldb, msg, ac->attrs, filtered_msg); -- talloc_free(msg); -+ ret = ldb_kv_filter_attrs_in_place(msg, ac->attrs); -+ if (ret != LDB_SUCCESS) { -+ talloc_free(msg); -+ ac->error = LDB_ERR_OPERATIONS_ERROR; -+ return -1; -+ } - -- if (ret == -1) { -- TALLOC_FREE(filtered_msg); -+ ldb_msg_shrink_to_fit(msg); -+ -+ /* Ensure the message elements are all talloc'd. */ -+ ret = ldb_msg_elements_take_ownership(msg); -+ if (ret != LDB_SUCCESS) { -+ talloc_free(msg); - ac->error = LDB_ERR_OPERATIONS_ERROR; - return -1; - } - -- ret = ldb_module_send_entry(ac->req, filtered_msg, NULL); -+ ret = ldb_module_send_entry(ac->req, msg, NULL); - if (ret != LDB_SUCCESS) { - ac->request_terminated = true; - /* the callback failed, abort the operation */ -@@ -491,7 +495,7 @@ static int ldb_kv_search_full(struct ldb_kv_context *ctx) - static int ldb_kv_search_and_return_base(struct ldb_kv_private *ldb_kv, - struct ldb_kv_context *ctx) - { -- struct ldb_message *msg, *filtered_msg; -+ struct ldb_message *msg; - struct ldb_context *ldb = ldb_module_get_ctx(ctx->module); - const char *dn_linearized; - const char *msg_dn_linearized; -@@ -549,12 +553,6 @@ static int ldb_kv_search_and_return_base(struct ldb_kv_private *ldb_kv, - dn_linearized = ldb_dn_get_linearized(ctx->base); - msg_dn_linearized = ldb_dn_get_linearized(msg->dn); - -- filtered_msg = ldb_msg_new(ctx); -- if (filtered_msg == NULL) { -- talloc_free(msg); -- return LDB_ERR_OPERATIONS_ERROR; -- } -- - if (strcmp(dn_linearized, msg_dn_linearized) == 0) { - /* - * If the DN is exactly the same string, then -@@ -562,36 +560,42 @@ static int ldb_kv_search_and_return_base(struct ldb_kv_private *ldb_kv, - * returned result, as it has already been - * casefolded - */ -- filtered_msg->dn = ldb_dn_copy(filtered_msg, ctx->base); -+ struct ldb_dn *dn = ldb_dn_copy(msg, ctx->base); -+ if (dn != NULL) { -+ msg->dn = dn; -+ } - } - -- /* -- * If the ldb_dn_copy() failed, or if we did not choose that -- * optimisation (filtered_msg is zeroed at allocation), -- * steal the one from the unpack -- */ -- if (filtered_msg->dn == NULL) { -- filtered_msg->dn = talloc_steal(filtered_msg, msg->dn); -+ ret = ldb_msg_add_distinguished_name(msg); -+ if (ret == -1) { -+ talloc_free(msg); -+ return LDB_ERR_OPERATIONS_ERROR; - } - - /* - * filter the attributes that the user wants. - */ -- ret = ldb_kv_filter_attrs(ldb, msg, ctx->attrs, filtered_msg); -- if (ret == -1) { -+ ret = ldb_kv_filter_attrs_in_place(msg, ctx->attrs); -+ if (ret != LDB_SUCCESS) { -+ talloc_free(msg); -+ return LDB_ERR_OPERATIONS_ERROR; -+ } -+ -+ ldb_msg_shrink_to_fit(msg); -+ -+ /* Ensure the message elements are all talloc'd. */ -+ ret = ldb_msg_elements_take_ownership(msg); -+ if (ret != LDB_SUCCESS) { - talloc_free(msg); -- filtered_msg = NULL; - return LDB_ERR_OPERATIONS_ERROR; - } - - /* -- * Remove any extended components possibly copied in from -- * msg->dn, we just want the casefold components -+ * Remove any extended components, we just want the casefold components - */ -- ldb_dn_remove_extended_components(filtered_msg->dn); -- talloc_free(msg); -+ ldb_dn_remove_extended_components(msg->dn); - -- ret = ldb_module_send_entry(ctx->req, filtered_msg, NULL); -+ ret = ldb_module_send_entry(ctx->req, msg, NULL); - if (ret != LDB_SUCCESS) { - /* Regardless of success or failure, the msg - * is the callbacks responsiblity, and should --- -2.25.1 diff --git a/backport-0011-CVE-2023-0614.patch b/backport-0011-CVE-2023-0614.patch deleted file mode 100644 index 15497bedcf43f0e218d5dd8a8b34350b2a70dc74..0000000000000000000000000000000000000000 --- a/backport-0011-CVE-2023-0614.patch +++ /dev/null @@ -1,66 +0,0 @@ -From b23fb132e63a6d3d791469614593c43906686ac9 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Fri, 3 Mar 2023 17:31:54 +1300 -Subject: [PATCH 20/34] CVE-2023-0614 ldb: Add ldb_parse_tree_get_attr() - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15270 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett - -Conflict: NA -Reference: https://attachments.samba.org/attachment.cgi?id=17821 ---- - common/ldb_parse.c | 25 +++++++++++++++++++++++++ - include/ldb_module.h | 3 +++ - 2 files changed, 28 insertions(+) - -diff --git a/common/ldb_parse.c b/common/ldb_parse.c -index f0045ad2093..2d102ff750e 100644 ---- a/common/ldb_parse.c -+++ b/common/ldb_parse.c -@@ -997,3 +997,28 @@ struct ldb_parse_tree *ldb_parse_tree_copy_shallow(TALLOC_CTX *mem_ctx, - - return nt; - } -+ -+/* Get the attribute (if any) associated with the top node of a parse tree. */ -+const char *ldb_parse_tree_get_attr(const struct ldb_parse_tree *tree) -+{ -+ switch (tree->operation) { -+ case LDB_OP_AND: -+ case LDB_OP_OR: -+ case LDB_OP_NOT: -+ return NULL; -+ case LDB_OP_EQUALITY: -+ return tree->u.equality.attr; -+ case LDB_OP_SUBSTRING: -+ return tree->u.substring.attr; -+ case LDB_OP_GREATER: -+ case LDB_OP_LESS: -+ case LDB_OP_APPROX: -+ return tree->u.comparison.attr; -+ case LDB_OP_PRESENT: -+ return tree->u.present.attr; -+ case LDB_OP_EXTENDED: -+ return tree->u.extended.attr; -+ } -+ -+ return NULL; -+} -diff --git a/include/ldb_module.h b/include/ldb_module.h -index 4ae381ba5be..bd369ed9512 100644 ---- a/include/ldb_module.h -+++ b/include/ldb_module.h -@@ -490,6 +490,9 @@ int ldb_init_module(const char *version); - */ - bool ldb_dn_replace_components(struct ldb_dn *dn, struct ldb_dn *new_dn); - -+/* Get the attribute (if any) associated with the top node of a parse tree. */ -+const char *ldb_parse_tree_get_attr(const struct ldb_parse_tree *tree); -+ - /* - walk a parse tree, calling the provided callback on each node - */ --- -2.25.1 diff --git a/backport-0012-CVE-2023-0614.patch b/backport-0012-CVE-2023-0614.patch deleted file mode 100644 index e7ecd5fb8f67e2b4f57ee6332937091b64111be2..0000000000000000000000000000000000000000 --- a/backport-0012-CVE-2023-0614.patch +++ /dev/null @@ -1,231 +0,0 @@ -From f87af853e2db99269acea572dcc109bc6f797aa9 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Fri, 3 Mar 2023 17:34:29 +1300 -Subject: [PATCH 24/34] CVE-2023-0614 ldb: Prevent disclosure of confidential - attributes - -Add a hook, acl_redact_msg_for_filter(), in the aclread module, that -marks inaccessible any message elements used by an LDAP search filter -that the user has no right to access. Make the various ldb_match_*() -functions check whether message elements are accessible, and refuse to -match any that are not. Remaining message elements, not mentioned in the -search filter, are checked in aclread_callback(), and any inaccessible -elements are removed at this point. - -Certain attributes, namely objectClass, distinguishedName, name, and -objectGUID, are always present, and hence the presence of said -attributes is always allowed to be checked in a search filter. This -corresponds with the behaviour of Windows. - -Further, we unconditionally allow the attributes isDeleted and -isRecycled in a check for presence or equality. Windows is not known to -make this special exception, but it seems mostly harmless, and should -mitigate the performance impact on searches made by the show_deleted -module. - -As a result of all these changes, our behaviour regarding confidential -attributes happens to match Windows more closely. For the test in -confidential_attr.py, we can now model our attribute handling with -DC_MODE_RETURN_ALL, which corresponds to the behaviour exhibited by -Windows. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15270 - -Pair-Programmed-With: Andrew Bartlett - -Signed-off-by: Joseph Sutton -Signed-off-by: Andrew Bartlett -Reviewed-by: Andrew Bartlett - -[abartlet@samba.org adapted due to Samba 4.17 and lower -not having the patches for CVE-2020-25720] - -Conflict: NA -Reference: https://attachments.samba.org/attachment.cgi?id=17821 ---- - common/ldb_match.c | 37 + - include/ldb_module.h | 11 + - include/ldb_private.h | 5 + - ldb_key_value/ldb_kv_index.c | 8 + - ldb_key_value/ldb_kv_search.c | 15 + - 12 files changed, 672 insertions(+), 455 deletions(-) - delete mode 100644 selftest/knownfail.d/confidential-attr-timing - -diff --git a/common/ldb_match.c b/common/ldb_match.c -index 2f4d41f3441..17314f1b9ca 100644 ---- a/common/ldb_match.c -+++ b/common/ldb_match.c -@@ -98,6 +98,11 @@ static int ldb_match_present(struct ldb_context *ldb, - return LDB_SUCCESS; - } - -+ if (ldb_msg_element_is_inaccessible(el)) { -+ *matched = false; -+ return LDB_SUCCESS; -+ } -+ - a = ldb_schema_attribute_by_name(ldb, el->name); - if (!a) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; -@@ -139,6 +144,11 @@ static int ldb_match_comparison(struct ldb_context *ldb, - return LDB_SUCCESS; - } - -+ if (ldb_msg_element_is_inaccessible(el)) { -+ *matched = false; -+ return LDB_SUCCESS; -+ } -+ - a = ldb_schema_attribute_by_name(ldb, el->name); - if (!a) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; -@@ -209,6 +219,11 @@ static int ldb_match_equality(struct ldb_context *ldb, - return LDB_SUCCESS; - } - -+ if (ldb_msg_element_is_inaccessible(el)) { -+ *matched = false; -+ return LDB_SUCCESS; -+ } -+ - a = ldb_schema_attribute_by_name(ldb, el->name); - if (a == NULL) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; -@@ -370,6 +385,11 @@ static int ldb_match_substring(struct ldb_context *ldb, - return LDB_SUCCESS; - } - -+ if (ldb_msg_element_is_inaccessible(el)) { -+ *matched = false; -+ return LDB_SUCCESS; -+ } -+ - for (i = 0; i < el->num_values; i++) { - int ret; - ret = ldb_wildcard_compare(ldb, tree, el->values[i], matched); -@@ -443,6 +463,11 @@ static int ldb_match_bitmask(struct ldb_context *ldb, - return LDB_SUCCESS; - } - -+ if (ldb_msg_element_is_inaccessible(el)) { -+ *matched = false; -+ return LDB_SUCCESS; -+ } -+ - for (i=0;inum_values;i++) { - int ret; - struct ldb_val *v = &el->values[i]; -@@ -741,3 +766,15 @@ int ldb_register_extended_match_rule(struct ldb_context *ldb, - return LDB_SUCCESS; - } - -+int ldb_register_redact_callback(struct ldb_context *ldb, -+ ldb_redact_fn redact_fn, -+ struct ldb_module *module) -+{ -+ if (ldb->redact.callback != NULL) { -+ return LDB_ERR_ENTRY_ALREADY_EXISTS; -+ } -+ -+ ldb->redact.callback = redact_fn; -+ ldb->redact.module = module; -+ return LDB_SUCCESS; -+} -diff --git a/include/ldb_module.h b/include/ldb_module.h -index bd369ed9512..0f14b1ad346 100644 ---- a/include/ldb_module.h -+++ b/include/ldb_module.h -@@ -102,6 +102,12 @@ struct ldb_module; - */ - #define LDB_FLAG_INTERNAL_SHARED_VALUES 0x200 - -+/* -+ * this attribute has been access checked. We know the user has the right to -+ * view it. Used internally in Samba aclread module. -+ */ -+#define LDB_FLAG_INTERNAL_ACCESS_CHECKED 0x400 -+ - /* 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" - -@@ -520,6 +526,11 @@ void ldb_msg_element_mark_inaccessible(struct ldb_message_element *el); - bool ldb_msg_element_is_inaccessible(const struct ldb_message_element *el); - void ldb_msg_remove_inaccessible(struct ldb_message *msg); - -+typedef int (*ldb_redact_fn)(struct ldb_module *, struct ldb_request *, struct ldb_message *); -+int ldb_register_redact_callback(struct ldb_context *ldb, -+ ldb_redact_fn redact_fn, -+ struct ldb_module *module); -+ - /* - * these pack/unpack functions are exposed in the library for use by - * ldb tools like ldbdump and for use in tests, -diff --git a/include/ldb_private.h b/include/ldb_private.h -index ca43817d07a..b0a42f6421c 100644 ---- a/include/ldb_private.h -+++ b/include/ldb_private.h -@@ -119,6 +119,11 @@ struct ldb_context { - struct ldb_extended_match_entry *prev, *next; - } *extended_match_rules; - -+ struct { -+ struct ldb_module *module; -+ ldb_redact_fn callback; -+ } redact; -+ - /* custom utf8 functions */ - struct ldb_utf8_fns utf8_fns; - -diff --git a/ldb_key_value/ldb_kv_index.c b/ldb_key_value/ldb_kv_index.c -index 203266ea8c9..163052fecf7 100644 ---- a/ldb_key_value/ldb_kv_index.c -+++ b/ldb_key_value/ldb_kv_index.c -@@ -2428,6 +2428,14 @@ static int ldb_kv_index_filter(struct ldb_kv_private *ldb_kv, - return LDB_ERR_OPERATIONS_ERROR; - } - -+ if (ldb->redact.callback != NULL) { -+ ret = ldb->redact.callback(ldb->redact.module, ac->req, msg); -+ if (ret != LDB_SUCCESS) { -+ talloc_free(msg); -+ return ret; -+ } -+ } -+ - /* - * We trust the index for LDB_SCOPE_ONELEVEL - * unless the index key has been truncated. -diff --git a/ldb_key_value/ldb_kv_search.c b/ldb_key_value/ldb_kv_search.c -index f3333510eab..d187ba223e1 100644 ---- a/ldb_key_value/ldb_kv_search.c -+++ b/ldb_key_value/ldb_kv_search.c -@@ -395,6 +395,14 @@ static int search_func(_UNUSED_ struct ldb_kv_private *ldb_kv, - } - } - -+ if (ldb->redact.callback != NULL) { -+ ret = ldb->redact.callback(ldb->redact.module, ac->req, msg); -+ if (ret != LDB_SUCCESS) { -+ talloc_free(msg); -+ return ret; -+ } -+ } -+ - /* see if it matches the given expression */ - ret = ldb_match_msg_error(ldb, msg, - ac->tree, ac->base, ac->scope, &matched); -@@ -530,6 +538,13 @@ static int ldb_kv_search_and_return_base(struct ldb_kv_private *ldb_kv, - return ret; - } - -+ if (ldb->redact.callback != NULL) { -+ ret = ldb->redact.callback(ldb->redact.module, ctx->req, msg); -+ if (ret != LDB_SUCCESS) { -+ talloc_free(msg); -+ return ret; -+ } -+ } - - /* - * We use this, not ldb_match_msg_error() as we know --- diff --git a/backport-0013-CVE-2023-0614.patch b/backport-0013-CVE-2023-0614.patch deleted file mode 100644 index be342b53ea532786521d5e16002cabaef40a1f9f..0000000000000000000000000000000000000000 --- a/backport-0013-CVE-2023-0614.patch +++ /dev/null @@ -1,130 +0,0 @@ -From 94efa3fc3053a623a7a5c3a4a6428356bc334152 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Tue, 14 Feb 2023 13:17:24 +1300 -Subject: [PATCH 27/34] CVE-2023-0614 ldb: Centralise checking for inaccessible - matches - -This makes it less likely that we forget to handle a case. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15270 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett - -Conflict: NA -Reference: https://attachments.samba.org/attachment.cgi?id=17821 ---- - common/ldb_match.c | 56 +++++++++++++++++------------- - 2 files changed, 31 insertions(+), 30 deletions(-) - -diff --git a/common/ldb_match.c b/common/ldb_match.c -index 17314f1b9ca..645cb695ef1 100644 ---- a/common/ldb_match.c -+++ b/common/ldb_match.c -@@ -98,11 +98,6 @@ static int ldb_match_present(struct ldb_context *ldb, - return LDB_SUCCESS; - } - -- if (ldb_msg_element_is_inaccessible(el)) { -- *matched = false; -- return LDB_SUCCESS; -- } -- - a = ldb_schema_attribute_by_name(ldb, el->name); - if (!a) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; -@@ -144,11 +139,6 @@ static int ldb_match_comparison(struct ldb_context *ldb, - return LDB_SUCCESS; - } - -- if (ldb_msg_element_is_inaccessible(el)) { -- *matched = false; -- return LDB_SUCCESS; -- } -- - a = ldb_schema_attribute_by_name(ldb, el->name); - if (!a) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; -@@ -219,11 +209,6 @@ static int ldb_match_equality(struct ldb_context *ldb, - return LDB_SUCCESS; - } - -- if (ldb_msg_element_is_inaccessible(el)) { -- *matched = false; -- return LDB_SUCCESS; -- } -- - a = ldb_schema_attribute_by_name(ldb, el->name); - if (a == NULL) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; -@@ -385,11 +370,6 @@ static int ldb_match_substring(struct ldb_context *ldb, - return LDB_SUCCESS; - } - -- if (ldb_msg_element_is_inaccessible(el)) { -- *matched = false; -- return LDB_SUCCESS; -- } -- - for (i = 0; i < el->num_values; i++) { - int ret; - ret = ldb_wildcard_compare(ldb, tree, el->values[i], matched); -@@ -463,11 +443,6 @@ static int ldb_match_bitmask(struct ldb_context *ldb, - return LDB_SUCCESS; - } - -- if (ldb_msg_element_is_inaccessible(el)) { -- *matched = false; -- return LDB_SUCCESS; -- } -- - for (i=0;inum_values;i++) { - int ret; - struct ldb_val *v = &el->values[i]; -@@ -556,6 +531,26 @@ static int ldb_match_extended(struct ldb_context *ldb, - &tree->u.extended.value, matched); - } - -+static bool ldb_must_suppress_match(const struct ldb_message *msg, -+ const struct ldb_parse_tree *tree) -+{ -+ const char *attr = NULL; -+ struct ldb_message_element *el = NULL; -+ -+ attr = ldb_parse_tree_get_attr(tree); -+ if (attr == NULL) { -+ return false; -+ } -+ -+ /* find the message element */ -+ el = ldb_msg_find_element(msg, attr); -+ if (el == NULL) { -+ return false; -+ } -+ -+ return ldb_msg_element_is_inaccessible(el); -+} -+ - /* - Check if a particular message will match the given filter - -@@ -580,6 +575,17 @@ int ldb_match_message(struct ldb_context *ldb, - return LDB_SUCCESS; - } - -+ /* -+ * Suppress matches on confidential attributes (handled -+ * manually in extended matches as these can do custom things -+ * like read other parts of the DB or other attributes). -+ */ -+ if (tree->operation != LDB_OP_EXTENDED) { -+ if (ldb_must_suppress_match(msg, tree)) { -+ return LDB_SUCCESS; -+ } -+ } -+ - switch (tree->operation) { - case LDB_OP_AND: - for (i=0;iu.list.num_elements;i++) { --- -2.25.1 diff --git a/backport-0014-CVE-2023-0614.patch b/backport-0014-CVE-2023-0614.patch deleted file mode 100644 index a23886d947d2414c27f348aa2bd430f73e791b48..0000000000000000000000000000000000000000 --- a/backport-0014-CVE-2023-0614.patch +++ /dev/null @@ -1,155 +0,0 @@ -From a0c888bd0ed2ec5b4d84f9df241bebd5d428818c Mon Sep 17 00:00:00 2001 -From: Joseph Sutton -Date: Fri, 3 Mar 2023 17:35:55 +1300 -Subject: [PATCH 28/34] CVE-2023-0614 ldb: Filter on search base before - redacting message - -Redaction may be expensive if we end up needing to fetch a security -descriptor to verify rights to an attribute. Checking the search scope -is probably cheaper, so do that first. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15270 - -Signed-off-by: Joseph Sutton -Reviewed-by: Andrew Bartlett - -Conflict: NA -Reference: https://attachments.samba.org/attachment.cgi?id=17821 ---- - common/ldb_match.c | 8 +++--- - include/ldb_private.h | 8 ++++++ - ldb_key_value/ldb_kv_index.c | 40 +++++++++++++++------------ - ldb_key_value/ldb_kv_search.c | 14 ++++++++-- - 4 files changed, 47 insertions(+), 23 deletions(-) - -diff --git a/common/ldb_match.c b/common/ldb_match.c -index 645cb695ef1..8e27ecbe723 100644 ---- a/common/ldb_match.c -+++ b/common/ldb_match.c -@@ -38,10 +38,10 @@ - /* - check if the scope matches in a search result - */ --static int ldb_match_scope(struct ldb_context *ldb, -- struct ldb_dn *base, -- struct ldb_dn *dn, -- enum ldb_scope scope) -+int ldb_match_scope(struct ldb_context *ldb, -+ struct ldb_dn *base, -+ struct ldb_dn *dn, -+ enum ldb_scope scope) - { - int ret = 0; - -diff --git a/include/ldb_private.h b/include/ldb_private.h -index b0a42f6421c..5e29de34f79 100644 ---- a/include/ldb_private.h -+++ b/include/ldb_private.h -@@ -322,6 +322,14 @@ int ldb_match_message(struct ldb_context *ldb, - const struct ldb_parse_tree *tree, - enum ldb_scope scope, bool *matched); - -+/* -+ check if the scope matches in a search result -+*/ -+int ldb_match_scope(struct ldb_context *ldb, -+ struct ldb_dn *base, -+ struct ldb_dn *dn, -+ enum ldb_scope scope); -+ - /* Reallocate elements to drop any excess capacity. */ - void ldb_msg_shrink_to_fit(struct ldb_message *msg); - -diff --git a/ldb_key_value/ldb_kv_index.c b/ldb_key_value/ldb_kv_index.c -index 163052fecf7..aac0913f431 100644 ---- a/ldb_key_value/ldb_kv_index.c -+++ b/ldb_key_value/ldb_kv_index.c -@@ -2428,31 +2428,37 @@ static int ldb_kv_index_filter(struct ldb_kv_private *ldb_kv, - return LDB_ERR_OPERATIONS_ERROR; - } - -- if (ldb->redact.callback != NULL) { -- ret = ldb->redact.callback(ldb->redact.module, ac->req, msg); -- if (ret != LDB_SUCCESS) { -- talloc_free(msg); -- return ret; -- } -- } -- - /* - * We trust the index for LDB_SCOPE_ONELEVEL - * unless the index key has been truncated. - * - * LDB_SCOPE_BASE is not passed in by our only caller. - */ -- if (ac->scope == LDB_SCOPE_ONELEVEL && -- ldb_kv->cache->one_level_indexes && -- scope_one_truncation == KEY_NOT_TRUNCATED) { -- ret = ldb_match_message(ldb, msg, ac->tree, -- ac->scope, &matched); -- } else { -- ret = ldb_match_msg_error(ldb, msg, -- ac->tree, ac->base, -- ac->scope, &matched); -+ if (ac->scope != LDB_SCOPE_ONELEVEL || -+ !ldb_kv->cache->one_level_indexes || -+ scope_one_truncation != KEY_NOT_TRUNCATED) -+ { -+ /* -+ * The redaction callback may be expensive to call if it -+ * fetches a security descriptor. Check the DN early and -+ * bail out if it doesn't match the base. -+ */ -+ if (!ldb_match_scope(ldb, ac->base, msg->dn, ac->scope)) { -+ talloc_free(msg); -+ continue; -+ } -+ } -+ -+ if (ldb->redact.callback != NULL) { -+ ret = ldb->redact.callback(ldb->redact.module, ac->req, msg); -+ if (ret != LDB_SUCCESS) { -+ talloc_free(msg); -+ return ret; -+ } - } - -+ ret = ldb_match_message(ldb, msg, ac->tree, -+ ac->scope, &matched); - if (ret != LDB_SUCCESS) { - talloc_free(keys); - talloc_free(msg); -diff --git a/ldb_key_value/ldb_kv_search.c b/ldb_key_value/ldb_kv_search.c -index d187ba223e1..27f68caef01 100644 ---- a/ldb_key_value/ldb_kv_search.c -+++ b/ldb_key_value/ldb_kv_search.c -@@ -395,6 +395,16 @@ static int search_func(_UNUSED_ struct ldb_kv_private *ldb_kv, - } - } - -+ /* -+ * The redaction callback may be expensive to call if it fetches a -+ * security descriptor. Check the DN early and bail out if it doesn't -+ * match the base. -+ */ -+ if (!ldb_match_scope(ldb, ac->base, msg->dn, ac->scope)) { -+ talloc_free(msg); -+ return 0; -+ } -+ - if (ldb->redact.callback != NULL) { - ret = ldb->redact.callback(ldb->redact.module, ac->req, msg); - if (ret != LDB_SUCCESS) { -@@ -404,8 +414,8 @@ static int search_func(_UNUSED_ struct ldb_kv_private *ldb_kv, - } - - /* see if it matches the given expression */ -- ret = ldb_match_msg_error(ldb, msg, -- ac->tree, ac->base, ac->scope, &matched); -+ ret = ldb_match_message(ldb, msg, -+ ac->tree, ac->scope, &matched); - if (ret != LDB_SUCCESS) { - talloc_free(msg); - ac->error = LDB_ERR_OPERATIONS_ERROR; --- -2.25.1 diff --git a/ldb-2.6.1.tar.asc b/ldb-2.6.1.tar.asc deleted file mode 100644 index 4fd13fd51ccf62c132b4738b927983e7799db967..0000000000000000000000000000000000000000 --- a/ldb-2.6.1.tar.asc +++ /dev/null @@ -1,11 +0,0 @@ ------BEGIN PGP SIGNATURE----- - -iQEzBAABCgAdFiEEkUejOXGVGO6QEby1R5ORYRMIQCUFAmLhN68ACgkQR5ORYRMI -QCWqKAgAswqnQft1oEc4c2DIJIF9jcXfLeOz4czUndBu5st6h3KVqZDCWjUAdPdX -BrYV+6cLTtDSjH0nQocnvtwm3AbVPxwukBglVtEuq0DU4fk8DptzRJvyLy2vU5VP -sKQQ+uwgYSWnKeds0PjPNMxpompeurDbQ1n4XgW4BzRQpK4Gvg6ZXBGg+q5nKht2 -+PfQTVuaPi4O6gUWfxDbLBBPNDf97gz21Sa8pS1K3sspcPQJzMNumXs/d9LBhU1G -BaDanganpN1Ru724J18jvZ8NEogldHuSk29DljreHiiWY2hEVlp5rZDTgrlYOP50 -b9kfHAnpBcHhQZlLf2/hponIccDo6A== -=ccfS ------END PGP SIGNATURE----- diff --git a/ldb-2.6.1.tar.gz b/ldb-2.6.1.tar.gz deleted file mode 100644 index 806074e5ffd18b36d1314b983c5afa21090f58e7..0000000000000000000000000000000000000000 Binary files a/ldb-2.6.1.tar.gz and /dev/null differ diff --git a/ldb-2.7.2.tar.asc b/ldb-2.7.2.tar.asc new file mode 100644 index 0000000000000000000000000000000000000000..8f0547f6cc2b30b986ab02ae629e34bf2c5c80d1 --- /dev/null +++ b/ldb-2.7.2.tar.asc @@ -0,0 +1,11 @@ +-----BEGIN PGP SIGNATURE----- + +iQEzBAABCgAdFiEEkUejOXGVGO6QEby1R5ORYRMIQCUFAmQkQQAACgkQR5ORYRMI +QCVLegf/edHMC2+MZrMuMAbmRPb/cFxzYhHzDLuDyXcW0v6M0TDhu2eRamXk1XT0 +SFR5ah/qdhC1TeYOMpXhKPTpuvEURKkCK1vLj002djaNy4hEmHUsF7aNFW9Kd2QN +2hatsIn9EhPafOppgpJ34oVEF+ta9aA07rDwcRAPiCUq4/IW6qnEieC+zCjVLlTd +2+1gfUaC2iUj7g9qkXLg21XRPRwkv8xvpUlJ+SBMphyo6uoBzVzDB+nzOGqpO4n9 +QAj6iUC0I9faLlXljgeSi+DaM1E5n/slgkl6ko2Chcba6ZtSxKLE69X3RenAu8d3 +Cf+ATsT5+Ra5CPY2PJv5Z1A2SCHd/w== +=ukNT +-----END PGP SIGNATURE----- diff --git a/ldb-2.7.2.tar.gz b/ldb-2.7.2.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..5c72acc3cd2f8e2bce0708514ec01e26a153bce6 Binary files /dev/null and b/ldb-2.7.2.tar.gz differ diff --git a/libldb.spec b/libldb.spec index 4bbb8472baabcad1fadd31c704d1e11c92b79b40..7d3448a1161028ddd7240fd5fa0b4d6ea88bce0f 100644 --- a/libldb.spec +++ b/libldb.spec @@ -1,36 +1,22 @@ %global with_lmdb 1 %global with_python3 1 -%global talloc_version 2.3.4 -%global tdb_version 1.4.7 -%global tevent_version 0.13.0 +%global talloc_version 2.4.0 +%global tdb_version 1.4.8 +%global tevent_version 0.14.1 Name: libldb -Version: 2.6.1 -Release: 2 +Version: 2.7.2 +Release: 1 Summary: A schema-less, ldap like, API and database Requires: libtalloc%{?_isa} >= %{talloc_version} Requires: libtdb%{?_isa} >= %{tdb_version} Requires: libtevent%{?_isa} >= %{tevent_version} -License: LGPLv3+ +License: LGPL-3.0-or-later URL: http://ldb.samba.org/ Source0: http://samba.org/ftp/ldb/ldb-%{version}.tar.gz Source1: http://samba.org/ftp/ldb/ldb-%{version}.tar.asc Patch0: backport-Skip-ldb_lmdb_free_list_test-on-ppc64el-ppc64-and-sp.patch -patch0001: backport-0001-CVE-2023-0614.patch -patch0002: backport-0002-CVE-2023-0614.patch -patch0003: backport-0003-CVE-2023-0614.patch -patch0004: backport-0004-CVE-2023-0614.patch -patch0005: backport-0005-CVE-2023-0614.patch -patch0006: backport-0006-CVE-2023-0614.patch -patch0007: backport-0007-CVE-2023-0614.patch -patch0008: backport-0008-CVE-2023-0614.patch -patch0009: backport-0009-CVE-2023-0614.patch -patch0010: backport-0010-CVE-2023-0614.patch -patch0011: backport-0011-CVE-2023-0614.patch -patch0012: backport-0012-CVE-2023-0614.patch -patch0013: backport-0013-CVE-2023-0614.patch -patch0014: backport-0014-CVE-2023-0614.patch BuildRequires: gcc libtalloc-devel >= %{talloc_version} libtdb-devel >= %{tdb_version} BuildRequires: libtevent-devel >= %{tevent_version} lmdb-devel >= 0.9.16 popt-devel @@ -184,6 +170,12 @@ echo "%{_libdir}/ldb" > %{buildroot}/etc/ld.so.conf.d/%{name}-%{_arch}.conf %{_mandir}/man1/ldbsearch.1.* %changelog +* Sat Jul 22 2023 yanglu - 2.7.2-1 +- Type:requirement +- ID:NA +- SUG:NA +- DESC:update libldb version to 2.7.2 + * Sat Apr 01 2023 xinghe - 2.6.1-2 - Type:CVE - ID:CVE-2023-0614