From 0e057b91d65e90f8f9ff978d2fd90b84afa162d0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 28 May 2018 13:01:18 +1200 Subject: [PATCH 01/12] ldb: Save a copy of the index result before calling the callbacks. Otherwise Samba modules like subtree_rename can fail as they modify the index during the callback. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13452 Signed-off-by: Andrew Bartlett Reviewed-by: Garming Sam (cherry picked from commit d02cd236dcbd8a44ecc85d1f7e95a48c95c0a479) --- lib/ldb/ldb_tdb/ldb_index.c | 79 +++++++++--- lib/ldb/tests/ldb_mod_op_test.c | 275 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 336 insertions(+), 18 deletions(-) diff --git a/lib/ldb/ldb_tdb/ldb_index.c b/lib/ldb/ldb_tdb/ldb_index.c index ee2027319e3..674c5fc41f8 100644 --- a/lib/ldb/ldb_tdb/ldb_index.c +++ b/lib/ldb/ldb_tdb/ldb_index.c @@ -1522,26 +1522,61 @@ static int ltdb_index_filter(struct ltdb_private *ltdb, struct ltdb_context *ac, uint32_t *match_count) { - struct ldb_context *ldb; + 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[LTDB_GUID_KEY_SIZE] = {}; + TDB_DATA *keys = NULL; + + /* + * We have to allocate the key list (rather than just walk the + * caller supplied list) as the callback could change the list + * (by modifying an indexed attribute hosted in the in-memory + * index cache!) + */ + keys = talloc_array(ac, TDB_DATA, dn_list->count); + if (keys == NULL) { + return ldb_module_oom(ac->module); + } - ldb = ldb_module_get_ctx(ac->module); + if (ltdb->cache->GUID_index_attribute != NULL) { + /* + * We speculate that the keys will be GUID based and so + * pre-fill in enough space for a GUID (avoiding a pile of + * small allocations) + */ + struct guid_tdb_key { + uint8_t guid_key[LTDB_GUID_KEY_SIZE]; + } *key_values = NULL; + + key_values = talloc_array(keys, + struct guid_tdb_key, + dn_list->count); + + for (i = 0; i < dn_list->count; i++) { + keys[i].dptr = key_values[i].guid_key; + keys[i].dsize = sizeof(key_values[i].guid_key); + } + if (key_values == NULL) { + return ldb_module_oom(ac->module); + } + } else { + for (i = 0; i < dn_list->count; i++) { + keys[i].dptr = NULL; + keys[i].dsize = 0; + } + } for (i = 0; i < dn_list->count; i++) { - uint8_t guid_key[LTDB_GUID_KEY_SIZE]; - TDB_DATA tdb_key = { - .dptr = guid_key, - .dsize = sizeof(guid_key) - }; int ret; - bool matched; - ret = ltdb_idx_to_key(ac->module, ltdb, - ac, &dn_list->dn[i], - &tdb_key); + ret = ltdb_idx_to_key(ac->module, + ltdb, + keys, + &dn_list->dn[i], + &keys[num_keys]); if (ret != LDB_SUCCESS) { return ret; } @@ -1558,28 +1593,35 @@ static int ltdb_index_filter(struct ltdb_private *ltdb, * LDB_FLAG_INTERNAL_DISABLE_SINGLE_VALUE_CHECK */ - if (memcmp(previous_guid_key, tdb_key.dptr, + if (memcmp(previous_guid_key, + keys[num_keys].dptr, sizeof(previous_guid_key)) == 0) { continue; } - memcpy(previous_guid_key, tdb_key.dptr, + memcpy(previous_guid_key, + keys[num_keys].dptr, sizeof(previous_guid_key)); } + num_keys++; + } + + /* + * Now that the list is a safe copy, send the callbacks + */ + for (i = 0; i < num_keys; i++) { + int ret; + bool matched; msg = ldb_msg_new(ac); if (!msg) { return LDB_ERR_OPERATIONS_ERROR; } - ret = ltdb_search_key(ac->module, ltdb, - tdb_key, msg, + keys[i], msg, LDB_UNPACK_DATA_FLAG_NO_DATA_ALLOC| LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC); - if (tdb_key.dptr != guid_key) { - TALLOC_FREE(tdb_key.dptr); - } if (ret == LDB_ERR_NO_SUCH_OBJECT) { /* the record has disappeared? yes, this can happen */ talloc_free(msg); @@ -1634,6 +1676,7 @@ static int ltdb_index_filter(struct ltdb_private *ltdb, (*match_count)++; } + TALLOC_FREE(keys); return LDB_SUCCESS; } diff --git a/lib/ldb/tests/ldb_mod_op_test.c b/lib/ldb/tests/ldb_mod_op_test.c index 0f8642d00a9..c8b9c1aa9ff 100644 --- a/lib/ldb/tests/ldb_mod_op_test.c +++ b/lib/ldb/tests/ldb_mod_op_test.c @@ -2384,6 +2384,269 @@ static void test_ldb_modify_before_ldb_wait(void **state) assert_int_equal(res2->count, 1); } +/* + * This test is also complex. + * The purpose is to test if a modify can occur during an ldb_search() + * This would be a failure if if in process + * (1) and (2): + * - (1) ltdb_search() starts and calls back for one entry + * - (2) one of the entries to be matched is modified + * - (1) the indexed search tries to return the modified entry, but + * it is no longer found, either: + * - despite it still matching (dn changed) + * - it no longer matching (attrs changed) + * + * We also try un-indexed to show that the behaviour differs on this + * point, which it should not (an index should only impact search + * speed). + */ + +/* + * This purpose of this callback is to trigger a write in the callback + * so as to change in in-memory index code while looping over the + * index result. + */ + +static int test_ldb_callback_modify_during_search_callback1(struct ldb_request *req, + struct ldb_reply *ares) +{ + int ret; + struct modify_during_search_test_ctx *ctx = req->context; + struct ldb_dn *dn = NULL, *new_dn = NULL; + TALLOC_CTX *tmp_ctx = talloc_new(ctx->test_ctx); + struct ldb_message *msg = NULL; + + assert_non_null(tmp_ctx); + + switch (ares->type) { + case LDB_REPLY_ENTRY: + { + const struct ldb_val *cn_val + = ldb_dn_get_component_val(ares->message->dn, 0); + const char *cn = (char *)cn_val->data; + ctx->res_count++; + if (strcmp(cn, "test_search_cn") == 0) { + ctx->got_cn = true; + } else if (strcmp(cn, "test_search_2_cn") == 0) { + ctx->got_2_cn = true; + } + if (ctx->res_count == 2) { + return LDB_SUCCESS; + } + break; + } + case LDB_REPLY_REFERRAL: + return LDB_SUCCESS; + + case LDB_REPLY_DONE: + return ldb_request_done(req, LDB_SUCCESS); + } + + if (ctx->rename) { + if (ctx->got_2_cn) { + /* Modify this one */ + dn = ldb_dn_new_fmt(tmp_ctx, + ctx->test_ctx->ldb, + "cn=test_search_2_cn,%s", + ldb_dn_get_linearized(ctx->basedn)); + } else { + dn = ldb_dn_new_fmt(tmp_ctx, + ctx->test_ctx->ldb, + "cn=test_search_cn,%s", + ldb_dn_get_linearized(ctx->basedn)); + } + assert_non_null(dn); + + new_dn = ldb_dn_new_fmt(tmp_ctx, + ctx->test_ctx->ldb, + "cn=test_search_cn_renamed," + "dc=not_search_test_entry"); + assert_non_null(new_dn); + + ret = ldb_rename(ctx->test_ctx->ldb, dn, new_dn); + assert_int_equal(ret, 0); + + } else { + if (ctx->got_2_cn) { + /* Delete this one */ + dn = ldb_dn_new_fmt(tmp_ctx, + ctx->test_ctx->ldb, + "cn=test_search_2_cn,%s", + ldb_dn_get_linearized(ctx->basedn)); + } else { + dn = ldb_dn_new_fmt(tmp_ctx, + ctx->test_ctx->ldb, + "cn=test_search_cn,%s", + ldb_dn_get_linearized(ctx->basedn)); + } + assert_non_null(dn); + + ret = ldb_delete(ctx->test_ctx->ldb, dn); + assert_int_equal(ret, 0); + } + + /* + * Now fill in the position we just removed from the + * index to ensure we fail the test (otherwise we just read + * past the end of the array and find the value we wanted to + * skip) + */ + msg = ldb_msg_new(tmp_ctx); + assert_non_null(msg); + + /* We deliberatly use ou= not cn= here */ + msg->dn = ldb_dn_new_fmt(msg, + ctx->test_ctx->ldb, + "ou=test_search_cn_extra,%s", + ldb_dn_get_linearized(ctx->basedn)); + + ret = ldb_msg_add_string(msg, + "objectUUID", + "0123456789abcde3"); + + ret = ldb_add(ctx->test_ctx->ldb, + msg); + assert_int_equal(ret, LDB_SUCCESS); + + TALLOC_FREE(tmp_ctx); + return LDB_SUCCESS; +} + +static void test_ldb_callback_modify_during_search(void **state, bool add_index, + bool rename) +{ + struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state, + struct search_test_ctx); + struct modify_during_search_test_ctx + ctx = + { .res_count = 0, + .test_ctx = search_test_ctx->ldb_test_ctx, + .rename = rename + }; + + int ret; + struct ldb_request *req; + + ret = ldb_transaction_start(search_test_ctx->ldb_test_ctx->ldb); + assert_int_equal(ret, 0); + + if (add_index) { + struct ldb_message *msg; + struct ldb_dn *indexlist = ldb_dn_new(search_test_ctx, + search_test_ctx->ldb_test_ctx->ldb, + "@INDEXLIST"); + assert_non_null(indexlist); + + msg = ldb_msg_new(search_test_ctx); + assert_non_null(msg); + + msg->dn = indexlist; + + ret = ldb_msg_add_string(msg, "@IDXONE", "1"); + assert_int_equal(ret, LDB_SUCCESS); + ret = ldb_msg_add_string(msg, "@IDXATTR", "cn"); + assert_int_equal(ret, LDB_SUCCESS); + ret = ldb_add(search_test_ctx->ldb_test_ctx->ldb, + msg); + if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) { + msg->elements[0].flags = LDB_FLAG_MOD_ADD; + msg->elements[1].flags = LDB_FLAG_MOD_ADD; + ret = ldb_modify(search_test_ctx->ldb_test_ctx->ldb, + msg); + } + assert_int_equal(ret, LDB_SUCCESS); + + /* + * Now bring the IDXONE index into memory by modifying + * it. This exposes an issue in ldb_tdb + */ + msg = ldb_msg_new(search_test_ctx); + assert_non_null(msg); + + msg->dn = ldb_dn_new_fmt(search_test_ctx, + search_test_ctx->ldb_test_ctx->ldb, + "cn=test_search_cn_extra,%s", + search_test_ctx->base_dn); + + ret = ldb_msg_add_string(msg, + "objectUUID", + "0123456789abcde2"); + + ret = ldb_add(search_test_ctx->ldb_test_ctx->ldb, + msg); + assert_int_equal(ret, LDB_SUCCESS); + + ret = ldb_delete(search_test_ctx->ldb_test_ctx->ldb, + msg->dn); + assert_int_equal(ret, LDB_SUCCESS); + } + + tevent_loop_allow_nesting(search_test_ctx->ldb_test_ctx->ev); + + ctx.basedn + = ldb_dn_new_fmt(search_test_ctx, + search_test_ctx->ldb_test_ctx->ldb, + "%s", + search_test_ctx->base_dn); + assert_non_null(ctx.basedn); + + + /* + * This search must be over multiple items, and should include + * the new name after a rename, to show that it would match + * both before and after that modify + * + * This needs to be a search that isn't matched by an index so + * that we just use the one-level index. + */ + ret = ldb_build_search_req(&req, + search_test_ctx->ldb_test_ctx->ldb, + search_test_ctx, + ctx.basedn, + LDB_SCOPE_ONELEVEL, + "(cn=*)", + NULL, + NULL, + &ctx, + test_ldb_callback_modify_during_search_callback1, + NULL); + assert_int_equal(ret, 0); + + ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req); + + if (ret == LDB_SUCCESS) { + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + } + assert_int_equal(ret, 0); + + ret = ldb_transaction_commit(search_test_ctx->ldb_test_ctx->ldb); + assert_int_equal(ret, 0); + + assert_int_equal(ctx.res_count, 2); + assert_int_equal(ctx.got_cn, true); + assert_int_equal(ctx.got_2_cn, true); +} + +static void test_ldb_callback_delete_during_indexed_search(void **state) +{ + test_ldb_callback_modify_during_search(state, true, false); +} + +static void test_ldb_callback_delete_during_unindexed_search(void **state) +{ + test_ldb_callback_modify_during_search(state, false, false); +} + +static void test_ldb_callback_rename_during_indexed_search(void **state) +{ + test_ldb_callback_modify_during_search(state, true, true); +} + +static void test_ldb_callback_rename_during_unindexed_search(void **state) +{ + test_ldb_callback_modify_during_search(state, false, true); +} + static int ldb_case_test_setup(void **state) { int ret; @@ -3692,6 +3955,18 @@ int main(int argc, const char **argv) cmocka_unit_test_setup_teardown(test_ldb_rename_during_indexed_search, ldb_search_test_setup, ldb_search_test_teardown), + cmocka_unit_test_setup_teardown(test_ldb_callback_rename_during_unindexed_search, + ldb_search_test_setup, + ldb_search_test_teardown), + cmocka_unit_test_setup_teardown(test_ldb_callback_rename_during_indexed_search, + ldb_search_test_setup, + ldb_search_test_teardown), + cmocka_unit_test_setup_teardown(test_ldb_callback_delete_during_unindexed_search, + ldb_search_test_setup, + ldb_search_test_teardown), + cmocka_unit_test_setup_teardown(test_ldb_callback_delete_during_indexed_search, + ldb_search_test_setup, + ldb_search_test_teardown), cmocka_unit_test_setup_teardown(test_ldb_modify_during_whole_search, ldb_search_test_setup, ldb_search_test_teardown), -- 2.11.0 From 72ad8bb80a191080d5e09fa332d357a216ab315b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 28 May 2018 13:02:16 +1200 Subject: [PATCH 02/12] ldb: Indicate that the ltdb_dn_list_sort() in list_union is a bit subtle. Signed-off-by: Andrew Bartlett Reviewed-by: Stefan Metzmacher Reviewed-by: Garming Sam (cherry picked from commit 3632775d7ad31e06437ed76b8731d9895930caa1) --- lib/ldb/ldb_tdb/ldb_index.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/ldb/ldb_tdb/ldb_index.c b/lib/ldb/ldb_tdb/ldb_index.c index 674c5fc41f8..6da64cfa4ce 100644 --- a/lib/ldb/ldb_tdb/ldb_index.c +++ b/lib/ldb/ldb_tdb/ldb_index.c @@ -1120,6 +1120,9 @@ static bool list_union(struct ldb_context *ldb, /* * Sort the lists (if not in GUID DN mode) so we can do * the de-duplication during the merge + * + * NOTE: This can sort the in-memory index values, as list or + * list2 might not be a copy! */ ltdb_dn_list_sort(ltdb, list); ltdb_dn_list_sort(ltdb, list2); -- 2.11.0 From e325f2873e3b6d9f198da1e08352ec105228e1e7 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 28 May 2018 14:12:52 +1200 Subject: [PATCH 03/12] ldb: Explain why an entry can vanish from the index Signed-off-by: Andrew Bartlett Reviewed-by: Stefan Metzmacher Reviewed-by: Garming Sam (cherry picked from commit 9e143ee9b9f7be53c193cee3153f64c4dedc07e9) --- lib/ldb/ldb_tdb/ldb_index.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/ldb/ldb_tdb/ldb_index.c b/lib/ldb/ldb_tdb/ldb_index.c index 6da64cfa4ce..3a1aa23aa7e 100644 --- a/lib/ldb/ldb_tdb/ldb_index.c +++ b/lib/ldb/ldb_tdb/ldb_index.c @@ -1626,7 +1626,12 @@ static int ltdb_index_filter(struct ltdb_private *ltdb, LDB_UNPACK_DATA_FLAG_NO_DATA_ALLOC| LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC); if (ret == LDB_ERR_NO_SUCH_OBJECT) { - /* the record has disappeared? yes, this can happen */ + /* + * the record has disappeared? yes, this can + * happen if the entry is deleted by something + * operating in the callback (not another + * process, as we have a read lock) + */ talloc_free(msg); continue; } -- 2.11.0 From 72854d9a09949778cd444aaa41c7722fe03c8e32 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 29 May 2018 10:04:29 +1200 Subject: [PATCH 04/12] ldb: One-level search was incorrectly falling back to full DB scan When no search filter is specified, the code falls back to using '(|(objectClass=*)(distinguishedName=*)'. ltdb_index_dn() then failed because matching against '*' is not indexed. The error return then caused the code to fallback to a full-scan of the DB, which could have a considerable performance hit. Instead, we want to continue on and do the ltdb_index_filter() over the indexed results that were returned. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13448 Signed-off-by: Tim Beale Signed-off-by: Andrew Bartlett Reviewed-by: Garming Sam (cherry picked from commit 88ae60ed186c9c479722ad62d65a07d0c2e71469) --- lib/ldb/ldb_tdb/ldb_index.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/lib/ldb/ldb_tdb/ldb_index.c b/lib/ldb/ldb_tdb/ldb_index.c index 3a1aa23aa7e..251f6295f54 100644 --- a/lib/ldb/ldb_tdb/ldb_index.c +++ b/lib/ldb/ldb_tdb/ldb_index.c @@ -1799,20 +1799,21 @@ int ltdb_search_indexed(struct ltdb_context *ac, uint32_t *match_count) } /* * Here we load the index for the tree. + * + * We only care if this is successful, if the + * index can't trim the result list down then + * the ONELEVEL index is still good enough. */ ret = ltdb_index_dn(ac->module, ltdb, ac->tree, idx_one_tree_list); - if (ret != LDB_SUCCESS) { - talloc_free(idx_one_tree_list); - talloc_free(dn_list); - return ret; - } - - if (!list_intersect(ldb, ltdb, - dn_list, idx_one_tree_list)) { - talloc_free(idx_one_tree_list); - talloc_free(dn_list); - return LDB_ERR_OPERATIONS_ERROR; + if (ret == LDB_SUCCESS) { + if (!list_intersect(ldb, ltdb, + dn_list, + idx_one_tree_list)) { + talloc_free(idx_one_tree_list); + talloc_free(dn_list); + return LDB_ERR_OPERATIONS_ERROR; + } } } break; -- 2.11.0 From 5bdb9431242e75f75bb07accd1b398f1e85c3d97 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 23 May 2018 17:15:38 +1200 Subject: [PATCH 05/12] ldb: Add tests for when we should expect a full scan BUG: https://bugzilla.samba.org/show_bug.cgi?id=13448 Signed-off-by: Andrew Bartlett Reviewed-by: Stefan Metzmacher Reviewed-by: Garming Sam (cherry picked from commit e99c199d811e607e7867e7b40d82a1642226c647) --- lib/ldb/ldb_tdb/ldb_search.c | 11 ++++- lib/ldb/ldb_tdb/ldb_tdb.c | 16 +++++++ lib/ldb/ldb_tdb/ldb_tdb.h | 6 +++ lib/ldb/tests/python/api.py | 104 ++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 135 insertions(+), 2 deletions(-) diff --git a/lib/ldb/ldb_tdb/ldb_search.c b/lib/ldb/ldb_tdb/ldb_search.c index 0af230f219b..af7393deda7 100644 --- a/lib/ldb/ldb_tdb/ldb_search.c +++ b/lib/ldb/ldb_tdb/ldb_search.c @@ -818,7 +818,7 @@ int ltdb_search(struct ltdb_context *ctx) * callback error */ if ( ! ctx->request_terminated && ret != LDB_SUCCESS) { /* Not indexed, so we need to do a full scan */ - if (ltdb->warn_unindexed) { + if (ltdb->warn_unindexed || ltdb->disable_full_db_scan) { /* useful for debugging when slow performance * is caused by unindexed searches */ char *expression = ldb_filter_from_tree(ctx, ctx->tree); @@ -831,6 +831,7 @@ int ltdb_search(struct ltdb_context *ctx) talloc_free(expression); } + if (match_count != 0) { /* the indexing code gave an error * after having returned at least one @@ -843,6 +844,14 @@ int ltdb_search(struct ltdb_context *ctx) ltdb_unlock_read(module); return LDB_ERR_OPERATIONS_ERROR; } + + if (ltdb->disable_full_db_scan) { + ldb_set_errstring(ldb, + "ldb FULL SEARCH disabled"); + ltdb_unlock_read(module); + return LDB_ERR_INAPPROPRIATE_MATCHING; + } + ret = ltdb_search_full(ctx); if (ret != LDB_SUCCESS) { ldb_set_errstring(ldb, "Indexed and full searches both failed!\n"); diff --git a/lib/ldb/ldb_tdb/ldb_tdb.c b/lib/ldb/ldb_tdb/ldb_tdb.c index a530a454b29..8802a31c761 100644 --- a/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/lib/ldb/ldb_tdb/ldb_tdb.c @@ -1965,6 +1965,22 @@ static int ltdb_connect(struct ldb_context *ldb, const char *url, ltdb->sequence_number = 0; + /* + * Override full DB scans + * + * A full DB scan is expensive on a large database. This + * option is for testing to show that the full DB scan is not + * triggered. + */ + { + const char *len_str = + ldb_options_find(ldb, options, + "disable_full_db_scan_for_self_test"); + if (len_str != NULL) { + ltdb->disable_full_db_scan = true; + } + } + module = ldb_module_new(ldb, ldb, "ldb_tdb backend", <db_ops); if (!module) { ldb_oom(ldb); diff --git a/lib/ldb/ldb_tdb/ldb_tdb.h b/lib/ldb/ldb_tdb/ldb_tdb.h index 9591ee59bf1..6788ab1c768 100644 --- a/lib/ldb/ldb_tdb/ldb_tdb.h +++ b/lib/ldb/ldb_tdb/ldb_tdb.h @@ -40,6 +40,12 @@ struct ltdb_private { bool reindex_failed; const struct ldb_schema_syntax *GUID_index_syntax; + + /* + * To allow testing that ensures the DB does not fall back + * to a full scan + */ + bool disable_full_db_scan; }; struct ltdb_context { diff --git a/lib/ldb/tests/python/api.py b/lib/ldb/tests/python/api.py index 1167517fd5c..a62b241444b 100755 --- a/lib/ldb/tests/python/api.py +++ b/lib/ldb/tests/python/api.py @@ -646,9 +646,16 @@ class SearchTests(LdbBaseTest): super(SearchTests, self).setUp() self.testdir = tempdir() self.filename = os.path.join(self.testdir, "search_test.ldb") + options = ["modules:rdn_name"] + if hasattr(self, 'IDXCHECK'): + options.append("disable_full_db_scan_for_self_test:1") self.l = ldb.Ldb(self.url(), flags=self.flags(), - options=["modules:rdn_name"]) + options=options) + try: + self.l.add(self.index) + except AttributeError: + pass self.l.add({"dn": "@ATTRIBUTES", "DC": "CASE_INSENSITIVE"}) @@ -929,6 +936,47 @@ class SearchTests(LdbBaseTest): expression="(|(x=y)(y=b))") self.assertEqual(len(res11), 20) + def test_one_unindexable(self): + """Testing a search""" + + try: + res11 = self.l.search(base="DC=samba,DC=org", + scope=ldb.SCOPE_ONELEVEL, + expression="(y=b*)") + if hasattr(self, 'IDX') and \ + not hasattr(self, 'IDXONE') and \ + hasattr(self, 'IDXCHECK'): + self.fail("Should have failed as un-indexed search") + + self.assertEqual(len(res11), 9) + + except ldb.LdbError as err: + enum = err.args[0] + estr = err.args[1] + self.assertEqual(enum, ldb.ERR_INAPPROPRIATE_MATCHING) + self.assertIn(estr, "ldb FULL SEARCH disabled") + + def test_one_unindexable_presence(self): + """Testing a search""" + + try: + res11 = self.l.search(base="DC=samba,DC=org", + scope=ldb.SCOPE_ONELEVEL, + expression="(y=*)") + if hasattr(self, 'IDX') and \ + not hasattr(self, 'IDXONE') and \ + hasattr(self, 'IDXCHECK'): + self.fail("Should have failed as un-indexed search") + + self.assertEqual(len(res11), 24) + + except ldb.LdbError as err: + enum = err.args[0] + estr = err.args[1] + self.assertEqual(enum, ldb.ERR_INAPPROPRIATE_MATCHING) + self.assertIn(estr, "ldb FULL SEARCH disabled") + + def test_subtree_and_or(self): """Testing a search""" @@ -1009,6 +1057,45 @@ class SearchTests(LdbBaseTest): expression="(@IDXONE=DC=SAMBA,DC=ORG)") self.assertEqual(len(res11), 0) + def test_subtree_unindexable(self): + """Testing a search""" + + try: + res11 = self.l.search(base="DC=samba,DC=org", + scope=ldb.SCOPE_SUBTREE, + expression="(y=b*)") + if hasattr(self, 'IDX') and \ + hasattr(self, 'IDXCHECK'): + self.fail("Should have failed as un-indexed search") + + self.assertEqual(len(res11), 9) + + except ldb.LdbError as err: + enum = err.args[0] + estr = err.args[1] + self.assertEqual(enum, ldb.ERR_INAPPROPRIATE_MATCHING) + self.assertIn(estr, "ldb FULL SEARCH disabled") + + def test_subtree_unindexable_presence(self): + """Testing a search""" + + try: + res11 = self.l.search(base="DC=samba,DC=org", + scope=ldb.SCOPE_SUBTREE, + expression="(y=*)") + if hasattr(self, 'IDX') and \ + hasattr(self, 'IDXCHECK'): + self.fail("Should have failed as un-indexed search") + + self.assertEqual(len(res11), 24) + + except ldb.LdbError as err: + enum = err.args[0] + estr = err.args[1] + self.assertEqual(enum, ldb.ERR_INAPPROPRIATE_MATCHING) + self.assertIn(estr, "ldb FULL SEARCH disabled") + + def test_dn_filter_one(self): """Testing that a dn= filter succeeds (or fails with disallowDNFilter @@ -1066,6 +1153,13 @@ class IndexedSearchTests(SearchTests): "@IDXATTR": [b"x", b"y", b"ou"]}) self.IDX = True +class IndexedCheckSearchTests(IndexedSearchTests): + """Test searches using the index, to ensure the index doesn't + break things (full scan disabled)""" + def setUp(self): + self.IDXCHECK = True + super(IndexedCheckSearchTests, self).setUp() + class IndexedSearchDnFilterTests(SearchTests): """Test searches using the index, to ensure the index doesn't break things""" @@ -1088,6 +1182,14 @@ class IndexedAndOneLevelSearchTests(SearchTests): "@IDXATTR": [b"x", b"y", b"ou"], "@IDXONE": [b"1"]}) self.IDX = True + self.IDXONE = True + +class IndexedCheckedAndOneLevelSearchTests(IndexedAndOneLevelSearchTests): + """Test searches using the index including @IDXONE, to ensure + the index doesn't break things (full scan disabled)""" + def setUp(self): + self.IDXCHECK = True + super(IndexedCheckedAndOneLevelSearchTests, self).setUp() class IndexedAndOneLevelDNFilterSearchTests(SearchTests): """Test searches using the index including @IDXONE, to ensure -- 2.11.0 From f847e6e2fd7396b2f3d53b2f0e475b61c7aadd70 Mon Sep 17 00:00:00 2001 From: Lukas Slebodnik Date: Sat, 21 Oct 2017 15:09:01 +0200 Subject: [PATCH 06/12] ldb: Fix memory leak on module context Introduced in e8cdacc509016d9273d63faf334d9f827585c3eb BUG: https://bugzilla.samba.org/show_bug.cgi?id=13459 Signed-off-by: Lukas Slebodnik Reviewed-by: Andrew Bartlett Reviewed-by: Garming Sam Autobuild-User(master): Andrew Bartlett Autobuild-Date(master): Fri Jun 1 11:10:24 CEST 2018 on sn-devel-144 (cherry picked from commit d161aa3522576545d269208426bb0014ee2ab35f) --- lib/ldb/ldb_tdb/ldb_index.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/ldb/ldb_tdb/ldb_index.c b/lib/ldb/ldb_tdb/ldb_index.c index 251f6295f54..290d9b6482b 100644 --- a/lib/ldb/ldb_tdb/ldb_index.c +++ b/lib/ldb/ldb_tdb/ldb_index.c @@ -523,9 +523,9 @@ static int ltdb_dn_list_store_full(struct ldb_module *module, if (list->count == 0) { ret = ltdb_delete_noindex(module, msg); if (ret == LDB_ERR_NO_SUCH_OBJECT) { - talloc_free(msg); - return LDB_SUCCESS; + ret = LDB_SUCCESS; } + talloc_free(msg); return ret; } -- 2.11.0 From bbff0a4c95565c7157780714a0bfe0d37d04513b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 13 Jun 2018 11:20:00 +0200 Subject: [PATCH 07/12] ldb_tdb: Use mem_ctx and so avoid leak onto long-term memory on duplicated add. After a duplicated add a small amount of memory can be leaked onto a long-term context. Found by Andrej Gessel https://github.com/andiges https://github.com/samba-team/samba/commit/e8fb45125e6a279b918694668e0d4fbddac10aee#commitcomment-29334102 BUG: https://bugzilla.samba.org/show_bug.cgi?id=13471 Signed-off-by: Andrew Bartlett Reviewed-by: Jeremy Allison Autobuild-User(master): Jeremy Allison Autobuild-Date(master): Fri Jun 15 04:39:41 CEST 2018 on sn-devel-144 (cherry picked from commit f4f3abfa0e18bb4968b37b1cac40cd8c185c8d7b) --- lib/ldb/ldb_tdb/ldb_tdb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ldb/ldb_tdb/ldb_tdb.c b/lib/ldb/ldb_tdb/ldb_tdb.c index 8802a31c761..f2d179c7db6 100644 --- a/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/lib/ldb/ldb_tdb/ldb_tdb.c @@ -575,7 +575,7 @@ static int ltdb_add_internal(struct ldb_module *module, if (mem_ctx == NULL) { return ldb_module_operr(module); } - ret2 = ltdb_search_base(module, module, + ret2 = ltdb_search_base(module, mem_ctx, msg->dn, &dn2); TALLOC_FREE(mem_ctx); if (ret2 == LDB_SUCCESS) { -- 2.11.0 From c09d93d46f5b0d32326e42e0a8f49c1fe37653a0 Mon Sep 17 00:00:00 2001 From: Andrej Gessel Date: Fri, 15 Jun 2018 11:02:15 +0200 Subject: [PATCH 08/12] ldb: check return values BUG: https://bugzilla.samba.org/show_bug.cgi?id=13475 Signed-off-by: Andrej Gessel Reviewed-by: Volker Lendecke Reviewed-by: Jeremy Allison (cherry picked from commit 6b52d21e6040699a72aff12fd6ebb34534dcb457) --- lib/ldb/ldb_tdb/ldb_index.c | 7 +++++++ lib/ldb/ldb_tdb/ldb_search.c | 5 ++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/ldb/ldb_tdb/ldb_index.c b/lib/ldb/ldb_tdb/ldb_index.c index 290d9b6482b..21d501d4ee5 100644 --- a/lib/ldb/ldb_tdb/ldb_index.c +++ b/lib/ldb/ldb_tdb/ldb_index.c @@ -433,6 +433,10 @@ normal_index: list->count = el->values[0].length / LTDB_GUID_SIZE; list->dn = talloc_array(list, struct ldb_val, list->count); + if (list->dn == NULL) { + talloc_free(msg); + return LDB_ERR_OPERATIONS_ERROR; + } /* * The actual data is on msg, due to @@ -621,6 +625,9 @@ static int ltdb_dn_list_store(struct ldb_module *module, struct ldb_dn *dn, } key.dptr = discard_const_p(unsigned char, ldb_dn_get_linearized(dn)); + if (key.dptr == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } key.dsize = strlen((char *)key.dptr); rec = tdb_fetch(ltdb->idxptr->itdb, key); diff --git a/lib/ldb/ldb_tdb/ldb_search.c b/lib/ldb/ldb_tdb/ldb_search.c index af7393deda7..fdae4cba62b 100644 --- a/lib/ldb/ldb_tdb/ldb_search.c +++ b/lib/ldb/ldb_tdb/ldb_search.c @@ -102,8 +102,11 @@ static int msg_add_distinguished_name(struct ldb_message *msg) el.values = &val; el.flags = 0; val.data = (uint8_t *)ldb_dn_alloc_linearized(msg, msg->dn); + if (val.data == NULL) { + return -1; + } val.length = strlen((char *)val.data); - + ret = msg_add_element(msg, &el, 1); return ret; } -- 2.11.0 From 326f2a159f189962e759b12374ba0ba3b568606c Mon Sep 17 00:00:00 2001 From: Andrej Gessel Date: Tue, 19 Jun 2018 10:07:51 +0200 Subject: [PATCH 09/12] check return value before using key_values there are also mem leaks in this function BUG: https://bugzilla.samba.org/show_bug.cgi?id=13475 Signed-off-by: Andrej Gessel Reviewed-by: Volker Lendecke Reviewed-by: Jeremy Allison (cherry picked from commit f75e8f58cd2390c092631803d333adadb475306a) --- lib/ldb/ldb_tdb/ldb_index.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/ldb/ldb_tdb/ldb_index.c b/lib/ldb/ldb_tdb/ldb_index.c index 21d501d4ee5..340e5c72550 100644 --- a/lib/ldb/ldb_tdb/ldb_index.c +++ b/lib/ldb/ldb_tdb/ldb_index.c @@ -1565,13 +1565,14 @@ static int ltdb_index_filter(struct ltdb_private *ltdb, struct guid_tdb_key, dn_list->count); + if (key_values == NULL) { + talloc_free(keys); + return ldb_module_oom(ac->module); + } for (i = 0; i < dn_list->count; i++) { keys[i].dptr = key_values[i].guid_key; keys[i].dsize = sizeof(key_values[i].guid_key); } - if (key_values == NULL) { - return ldb_module_oom(ac->module); - } } else { for (i = 0; i < dn_list->count; i++) { keys[i].dptr = NULL; @@ -1588,6 +1589,7 @@ static int ltdb_index_filter(struct ltdb_private *ltdb, &dn_list->dn[i], &keys[num_keys]); if (ret != LDB_SUCCESS) { + talloc_free(keys); return ret; } @@ -1625,6 +1627,7 @@ static int ltdb_index_filter(struct ltdb_private *ltdb, bool matched; msg = ldb_msg_new(ac); if (!msg) { + talloc_free(keys); return LDB_ERR_OPERATIONS_ERROR; } @@ -1645,6 +1648,7 @@ static int ltdb_index_filter(struct ltdb_private *ltdb, if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_OBJECT) { /* an internal error */ + talloc_free(keys); talloc_free(msg); return LDB_ERR_OPERATIONS_ERROR; } @@ -1662,6 +1666,7 @@ static int ltdb_index_filter(struct ltdb_private *ltdb, } if (ret != LDB_SUCCESS) { + talloc_free(keys); talloc_free(msg); return ret; } @@ -1676,6 +1681,7 @@ static int ltdb_index_filter(struct ltdb_private *ltdb, talloc_free(msg); if (ret == -1) { + talloc_free(keys); return LDB_ERR_OPERATIONS_ERROR; } @@ -1685,6 +1691,7 @@ static int ltdb_index_filter(struct ltdb_private *ltdb, * is the callbacks responsiblity, and should * not be talloc_free()'ed */ ac->request_terminated = true; + talloc_free(keys); return ret; } -- 2.11.0 From ba91258009313a3d776a5dc8f8604495150615d4 Mon Sep 17 00:00:00 2001 From: Andrej Gessel Date: Thu, 14 Jun 2018 12:19:29 +0200 Subject: [PATCH 10/12] Fix several mem leaks in ldb_index ldb_search ldb_tdb BUG: https://bugzilla.samba.org/show_bug.cgi?id=13475 Signed-off-by: Andrej Gessel Reviewed-by: Jeremy Allison Reviewed-by: Andrew Bartlett Autobuild-User(master): Andrew Bartlett Autobuild-Date(master): Fri Jun 15 23:07:25 CEST 2018 on sn-devel-144 (cherry picked from commit 3ca1c09f686fbfa9257cd95710dba4a98c3eeb8f) --- lib/ldb/ldb_tdb/ldb_index.c | 4 ++++ lib/ldb/ldb_tdb/ldb_search.c | 7 ++++--- lib/ldb/ldb_tdb/ldb_tdb.c | 2 ++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/ldb/ldb_tdb/ldb_index.c b/lib/ldb/ldb_tdb/ldb_index.c index 340e5c72550..40baeea5c2b 100644 --- a/lib/ldb/ldb_tdb/ldb_index.c +++ b/lib/ldb/ldb_tdb/ldb_index.c @@ -403,6 +403,7 @@ normal_index: "expected %d for %s", version, LTDB_INDEXING_VERSION, ldb_dn_get_linearized(dn)); + talloc_free(msg); return LDB_ERR_OPERATIONS_ERROR; } @@ -420,14 +421,17 @@ normal_index: "expected %d for %s", version, LTDB_GUID_INDEXING_VERSION, ldb_dn_get_linearized(dn)); + talloc_free(msg); return LDB_ERR_OPERATIONS_ERROR; } if (el->num_values != 1) { + talloc_free(msg); return LDB_ERR_OPERATIONS_ERROR; } if ((el->values[0].length % LTDB_GUID_SIZE) != 0) { + talloc_free(msg); return LDB_ERR_OPERATIONS_ERROR; } diff --git a/lib/ldb/ldb_tdb/ldb_search.c b/lib/ldb/ldb_tdb/ldb_search.c index fdae4cba62b..02890862cf7 100644 --- a/lib/ldb/ldb_tdb/ldb_search.c +++ b/lib/ldb/ldb_tdb/ldb_search.c @@ -408,7 +408,7 @@ int ltdb_filter_attrs(TALLOC_CTX *mem_ctx, /* Shortcuts for the simple cases */ } else if (add_dn && i == 1) { if (msg_add_distinguished_name(msg2) != 0) { - return -1; + goto failed; } *filtered_msg = msg2; return 0; @@ -474,7 +474,7 @@ int ltdb_filter_attrs(TALLOC_CTX *mem_ctx, if (add_dn) { if (msg_add_distinguished_name(msg2) != 0) { - return -1; + goto failed; } } @@ -483,7 +483,7 @@ int ltdb_filter_attrs(TALLOC_CTX *mem_ctx, struct ldb_message_element, msg2->num_elements); if (msg2->elements == NULL) { - return -1; + goto failed; } } else { talloc_free(msg2->elements); @@ -494,6 +494,7 @@ int ltdb_filter_attrs(TALLOC_CTX *mem_ctx, return 0; failed: + TALLOC_FREE(msg2); return -1; } diff --git a/lib/ldb/ldb_tdb/ldb_tdb.c b/lib/ldb/ldb_tdb/ldb_tdb.c index f2d179c7db6..701427609e9 100644 --- a/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/lib/ldb/ldb_tdb/ldb_tdb.c @@ -434,6 +434,7 @@ int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flg } if (ltdb->read_only) { + talloc_free(tdb_key_ctx); return LDB_ERR_UNWILLING_TO_PERFORM; } @@ -657,6 +658,7 @@ int ltdb_delete_noindex(struct ldb_module *module, } if (ltdb->read_only) { + talloc_free(tdb_key_ctx); return LDB_ERR_UNWILLING_TO_PERFORM; } -- 2.11.0 From f80f3382b2381e602e18848c072f14313a545f25 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 26 Jun 2018 14:59:26 +1200 Subject: [PATCH 11/12] .gitlab-ci.yml: Adapt to current GitLab CI setup Signed-off-by: Andrew Bartlett --- .gitlab-ci.yml => .gitlab-ci-private.yml | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) rename .gitlab-ci.yml => .gitlab-ci-private.yml (92%) diff --git a/.gitlab-ci.yml b/.gitlab-ci-private.yml similarity index 92% rename from .gitlab-ci.yml rename to .gitlab-ci-private.yml index 2ae9eb4032d..584b853c25e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci-private.yml @@ -1,12 +1,15 @@ # see https://docs.gitlab.com/ce/ci/yaml/README.html for all available options +image: registry.gitlab.com/samba-team/samba:latest + before_script: - echo "Build starting ..." build_samba: stage: build tags: - - autobuild + - docker + - private script: # this one takes about 4 hours to finish - python script/autobuild.py samba --verbose --tail --testbase /tmp/samba-testbase @@ -14,7 +17,8 @@ build_samba: build_samba_others: stage: build tags: - - autobuild + - docker + - private script: - python script/autobuild.py samba-nopython --verbose --tail --testbase /tmp/samba-testbase - python script/autobuild.py samba-systemkrb5 --verbose --tail --testbase /tmp/samba-testbase @@ -26,7 +30,8 @@ build_samba_others: build_ctdb: stage: build tags: - - autobuild + - docker + - private script: - python script/autobuild.py samba-ctdb --verbose --tail --testbase /tmp/samba-testbase - python script/autobuild.py ctdb --verbose --tail --testbase /tmp/samba-testbase @@ -34,7 +39,8 @@ build_ctdb: build_others: stage: build tags: - - autobuild + - docker + - private script: - python script/autobuild.py ldb --verbose --tail --testbase /tmp/samba-testbase - python script/autobuild.py pidl --verbose --tail --testbase /tmp/samba-testbase -- 2.11.0 From 3b0363dbc966d8afbfd05173db79e86bae41ecb2 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 26 Jun 2018 15:01:27 +1200 Subject: [PATCH 12/12] ldb: version 1.3.4 * Fix memory leaks and missing error checks (bug 13459, 13471, 13475) * Fix fallback to full scan (performance regression) on one-level search (bug 13448) * Fix read corruption (missing results) during writes, particularly during a Samba subtree rename (bug 13452) --- lib/ldb/ABI/ldb-1.3.4.sigs | 279 ++++++++++++++++++++++++++++++++++ lib/ldb/ABI/pyldb-util-1.3.4.sigs | 2 + lib/ldb/ABI/pyldb-util.py3-1.3.4.sigs | 2 + lib/ldb/wscript | 2 +- 4 files changed, 284 insertions(+), 1 deletion(-) create mode 100644 lib/ldb/ABI/ldb-1.3.4.sigs create mode 100644 lib/ldb/ABI/pyldb-util-1.3.4.sigs create mode 100644 lib/ldb/ABI/pyldb-util.py3-1.3.4.sigs diff --git a/lib/ldb/ABI/ldb-1.3.4.sigs b/lib/ldb/ABI/ldb-1.3.4.sigs new file mode 100644 index 00000000000..a31b84ef4b5 --- /dev/null +++ b/lib/ldb/ABI/ldb-1.3.4.sigs @@ -0,0 +1,279 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handle_use_global_event_context: void (struct ldb_handle *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) +ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_read_lock: int (struct ldb_module *) +ldb_next_read_unlock: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) +ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_require_private_event_context: void (struct ldb_context *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) +ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/lib/ldb/ABI/pyldb-util-1.3.4.sigs b/lib/ldb/ABI/pyldb-util-1.3.4.sigs new file mode 100644 index 00000000000..74d6719d2bc --- /dev/null +++ b/lib/ldb/ABI/pyldb-util-1.3.4.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/lib/ldb/ABI/pyldb-util.py3-1.3.4.sigs b/lib/ldb/ABI/pyldb-util.py3-1.3.4.sigs new file mode 100644 index 00000000000..74d6719d2bc --- /dev/null +++ b/lib/ldb/ABI/pyldb-util.py3-1.3.4.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/lib/ldb/wscript b/lib/ldb/wscript index 75ccff5a1cf..2477885cd32 100644 --- a/lib/ldb/wscript +++ b/lib/ldb/wscript @@ -1,7 +1,7 @@ #!/usr/bin/env python APPNAME = 'ldb' -VERSION = '1.3.3' +VERSION = '1.3.4' blddir = 'bin' -- 2.11.0