3 * These headers or their equivalents should be included prior to
11 * This allows test applications to use custom definitions of C standard
12 * library functions and types.
23 #define TEVENT_DEPRECATED 1
27 #include <ldb_module.h>
28 #include <ldb_private.h>
35 #define DEFAULT_BE "tdb"
38 #define TEST_BE DEFAULT_BE
42 struct tevent_context *ev;
43 struct ldb_context *ldb;
46 const char *lockfile; /* lockfile is separate */
51 static void unlink_old_db(struct ldbtest_ctx *test_ctx)
56 ret = unlink(test_ctx->lockfile);
57 if (ret == -1 && errno != ENOENT) {
62 ret = unlink(test_ctx->dbfile);
63 if (ret == -1 && errno != ENOENT) {
68 static int ldbtest_noconn_setup(void **state)
70 struct ldbtest_ctx *test_ctx;
72 test_ctx = talloc_zero(NULL, struct ldbtest_ctx);
73 assert_non_null(test_ctx);
75 test_ctx->ev = tevent_context_init(test_ctx);
76 assert_non_null(test_ctx->ev);
78 test_ctx->ldb = ldb_init(test_ctx, test_ctx->ev);
79 assert_non_null(test_ctx->ldb);
81 test_ctx->dbfile = talloc_strdup(test_ctx, "apitest.ldb");
82 assert_non_null(test_ctx->dbfile);
84 test_ctx->lockfile = talloc_asprintf(test_ctx, "%s-lock",
86 assert_non_null(test_ctx->lockfile);
88 test_ctx->dbpath = talloc_asprintf(test_ctx,
89 TEST_BE"://%s", test_ctx->dbfile);
90 assert_non_null(test_ctx->dbpath);
92 unlink_old_db(test_ctx);
97 static int ldbtest_noconn_teardown(void **state)
99 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
102 unlink_old_db(test_ctx);
103 talloc_free(test_ctx);
107 static void test_connect(void **state)
109 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
113 ret = ldb_connect(test_ctx->ldb, test_ctx->dbpath, 0, NULL);
114 assert_int_equal(ret, 0);
117 static struct ldb_message *get_test_ldb_message(TALLOC_CTX *mem_ctx,
118 struct ldb_context *ldb)
120 struct ldb_message *msg = ldb_msg_new(mem_ctx);
122 assert_non_null(msg);
124 msg->dn = ldb_dn_new(msg, ldb, "dc=samba,dc=org");
125 assert_non_null(msg->dn);
126 ret = ldb_msg_add_string(msg, "public", "key");
127 assert_int_equal(ret, LDB_SUCCESS);
128 ret = ldb_msg_add_string(msg, "supersecret", "password");
129 assert_int_equal(ret, LDB_SUCCESS);
130 ret = ldb_msg_add_string(msg, "binary", "\xff\xff\0");
131 assert_int_equal(ret, LDB_SUCCESS);
135 static void test_ldif_message(void **state)
137 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
140 const char *expected_ldif =
141 "dn: dc=samba,dc=org\n"
144 "supersecret: password\n"
148 struct ldb_message *msg = get_test_ldb_message(test_ctx,
151 got_ldif = ldb_ldif_message_string(test_ctx->ldb,
155 assert_string_equal(got_ldif, expected_ldif);
156 TALLOC_FREE(got_ldif);
159 static void test_ldif_message_redacted(void **state)
161 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
165 const char *expected_ldif =
166 "dn: dc=samba,dc=org\n"
169 "# supersecret::: REDACTED SECRET ATTRIBUTE\n"
173 const char *secret_attrs[] = {
178 struct ldb_message *msg = ldb_msg_new(test_ctx);
180 ldb_set_opaque(test_ctx->ldb,
181 LDB_SECRET_ATTRIBUTE_LIST_OPAQUE,
184 assert_non_null(msg);
186 msg->dn = ldb_dn_new(msg, test_ctx->ldb, "dc=samba,dc=org");
187 ret = ldb_msg_add_string(msg, "public", "key");
188 assert_int_equal(ret, LDB_SUCCESS);
189 ret = ldb_msg_add_string(msg, "supersecret", "password");
190 assert_int_equal(ret, LDB_SUCCESS);
191 ret = ldb_msg_add_string(msg, "binary", "\xff\xff\0");
192 assert_int_equal(ret, LDB_SUCCESS);
193 got_ldif = ldb_ldif_message_redacted_string(test_ctx->ldb,
197 assert_string_equal(got_ldif, expected_ldif);
198 TALLOC_FREE(got_ldif);
199 assert_int_equal(ret, 0);
202 static int ldbtest_setup(void **state)
204 struct ldbtest_ctx *test_ctx;
205 struct ldb_ldif *ldif;
207 const char *index_ldif = \
209 "@IDXGUID: objectUUID\n"
210 "@IDX_DN_GUID: GUID\n"
213 const char *index_ldif = "\n";
217 ldbtest_noconn_setup((void **) &test_ctx);
219 ret = ldb_connect(test_ctx->ldb, test_ctx->dbpath, 0, NULL);
220 assert_int_equal(ret, 0);
222 while ((ldif = ldb_ldif_read_string(test_ctx->ldb, &index_ldif))) {
223 ret = ldb_add(test_ctx->ldb, ldif->msg);
224 assert_int_equal(ret, LDB_SUCCESS);
230 static int ldbtest_teardown(void **state)
232 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
234 ldbtest_noconn_teardown((void **) &test_ctx);
238 static void test_ldb_add(void **state)
241 struct ldb_message *msg;
242 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
246 tmp_ctx = talloc_new(test_ctx);
247 assert_non_null(tmp_ctx);
249 msg = ldb_msg_new(tmp_ctx);
250 assert_non_null(msg);
252 msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "dc=test");
253 assert_non_null(msg->dn);
255 ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
256 assert_int_equal(ret, 0);
258 ret = ldb_msg_add_string(msg, "objectUUID", "0123456789abcdef");
259 assert_int_equal(ret, 0);
261 ret = ldb_add(test_ctx->ldb, msg);
262 assert_int_equal(ret, 0);
264 talloc_free(tmp_ctx);
267 static void test_ldb_search(void **state)
270 struct ldb_message *msg;
271 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
274 struct ldb_dn *basedn;
275 struct ldb_dn *basedn2;
276 struct ldb_result *result = NULL;
278 tmp_ctx = talloc_new(test_ctx);
279 assert_non_null(tmp_ctx);
281 basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "dc=test");
282 assert_non_null(basedn);
284 ret = ldb_search(test_ctx->ldb, tmp_ctx, &result, basedn,
285 LDB_SCOPE_BASE, NULL, NULL);
286 assert_int_equal(ret, 0);
287 assert_non_null(result);
288 assert_int_equal(result->count, 0);
290 msg = ldb_msg_new(tmp_ctx);
291 assert_non_null(msg);
294 assert_non_null(msg->dn);
296 ret = ldb_msg_add_string(msg, "cn", "test_cn_val1");
297 assert_int_equal(ret, 0);
299 ret = ldb_msg_add_string(msg, "objectUUID", "0123456789abcde1");
300 assert_int_equal(ret, 0);
302 ret = ldb_add(test_ctx->ldb, msg);
303 assert_int_equal(ret, 0);
305 basedn2 = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "dc=test2");
306 assert_non_null(basedn2);
308 msg = ldb_msg_new(tmp_ctx);
309 assert_non_null(msg);
312 assert_non_null(msg->dn);
314 ret = ldb_msg_add_string(msg, "cn", "test_cn_val2");
315 assert_int_equal(ret, 0);
317 ret = ldb_msg_add_string(msg, "objectUUID", "0123456789abcde2");
318 assert_int_equal(ret, 0);
320 ret = ldb_add(test_ctx->ldb, msg);
321 assert_int_equal(ret, 0);
323 ret = ldb_search(test_ctx->ldb, tmp_ctx, &result, basedn,
324 LDB_SCOPE_BASE, NULL, NULL);
325 assert_int_equal(ret, 0);
326 assert_non_null(result);
327 assert_int_equal(result->count, 1);
328 assert_string_equal(ldb_dn_get_linearized(result->msgs[0]->dn),
329 ldb_dn_get_linearized(basedn));
331 ret = ldb_search(test_ctx->ldb, tmp_ctx, &result, basedn2,
332 LDB_SCOPE_BASE, NULL, NULL);
333 assert_int_equal(ret, 0);
334 assert_non_null(result);
335 assert_int_equal(result->count, 1);
336 assert_string_equal(ldb_dn_get_linearized(result->msgs[0]->dn),
337 ldb_dn_get_linearized(basedn2));
339 talloc_free(tmp_ctx);
342 static int base_search_count(struct ldbtest_ctx *test_ctx, const char *entry_dn)
345 struct ldb_dn *basedn;
346 struct ldb_result *result = NULL;
350 tmp_ctx = talloc_new(test_ctx);
351 assert_non_null(tmp_ctx);
353 basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "%s", entry_dn);
354 assert_non_null(basedn);
356 ret = ldb_search(test_ctx->ldb, tmp_ctx, &result, basedn,
357 LDB_SCOPE_BASE, NULL, NULL);
358 assert_int_equal(ret, LDB_SUCCESS);
359 assert_non_null(result);
361 count = result->count;
362 talloc_free(tmp_ctx);
366 static int sub_search_count(struct ldbtest_ctx *test_ctx,
371 struct ldb_dn *basedn;
372 struct ldb_result *result = NULL;
376 tmp_ctx = talloc_new(test_ctx);
377 assert_non_null(tmp_ctx);
379 basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "%s", base_dn);
380 assert_non_null(basedn);
382 ret = ldb_search(test_ctx->ldb, tmp_ctx, &result, basedn,
383 LDB_SCOPE_SUBTREE, NULL, "%s", filter);
384 assert_int_equal(ret, LDB_SUCCESS);
385 assert_non_null(result);
387 count = result->count;
388 talloc_free(tmp_ctx);
392 /* In general it would be better if utility test functions didn't assert
393 * but only returned a value, then assert in the test shows correct
396 static void assert_dn_exists(struct ldbtest_ctx *test_ctx,
397 const char *entry_dn)
401 count = base_search_count(test_ctx, entry_dn);
402 assert_int_equal(count, 1);
405 static void assert_dn_doesnt_exist(struct ldbtest_ctx *test_ctx,
406 const char *entry_dn)
410 count = base_search_count(test_ctx, entry_dn);
411 assert_int_equal(count, 0);
414 static void add_dn_with_cn(struct ldbtest_ctx *test_ctx,
416 const char *cn_value,
417 const char *uuid_value)
421 struct ldb_message *msg;
423 tmp_ctx = talloc_new(test_ctx);
424 assert_non_null(tmp_ctx);
426 assert_dn_doesnt_exist(test_ctx,
427 ldb_dn_get_linearized(dn));
429 msg = ldb_msg_new(tmp_ctx);
430 assert_non_null(msg);
433 ret = ldb_msg_add_string(msg, "cn", cn_value);
434 assert_int_equal(ret, LDB_SUCCESS);
436 ret = ldb_msg_add_string(msg, "objectUUID", uuid_value);
437 assert_int_equal(ret, 0);
439 ret = ldb_add(test_ctx->ldb, msg);
440 assert_int_equal(ret, LDB_SUCCESS);
442 assert_dn_exists(test_ctx,
443 ldb_dn_get_linearized(dn));
444 talloc_free(tmp_ctx);
447 static void test_ldb_del(void **state)
450 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
452 const char *basedn = "dc=ldb_del_test";
455 dn = ldb_dn_new_fmt(test_ctx, test_ctx->ldb, "%s", basedn);
458 add_dn_with_cn(test_ctx, dn,
462 ret = ldb_delete(test_ctx->ldb, dn);
463 assert_int_equal(ret, LDB_SUCCESS);
465 assert_dn_doesnt_exist(test_ctx, basedn);
468 static void test_ldb_del_noexist(void **state)
470 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
472 struct ldb_dn *basedn;
475 basedn = ldb_dn_new(test_ctx, test_ctx->ldb, "dc=nosuchplace");
476 assert_non_null(basedn);
478 ret = ldb_delete(test_ctx->ldb, basedn);
479 assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT);
482 static void test_ldb_handle(void **state)
485 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
488 struct ldb_dn *basedn;
489 struct ldb_request *request = NULL;
490 struct ldb_request *request2 = NULL;
491 struct ldb_result *res = NULL;
492 const char *attrs[] = { "cn", NULL };
494 tmp_ctx = talloc_new(test_ctx);
495 assert_non_null(tmp_ctx);
497 basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "dc=test");
498 assert_non_null(basedn);
500 res = talloc_zero(tmp_ctx, struct ldb_result);
501 assert_non_null(res);
503 ret = ldb_build_search_req(&request, test_ctx->ldb, tmp_ctx,
504 basedn, LDB_SCOPE_BASE,
505 NULL, attrs, NULL, res,
506 ldb_search_default_callback,
508 assert_int_equal(ret, 0);
510 /* We are against ldb_tdb, so expect private event contexts */
511 assert_ptr_not_equal(ldb_handle_get_event_context(request->handle),
512 ldb_get_event_context(test_ctx->ldb));
514 ret = ldb_build_search_req(&request2, test_ctx->ldb, tmp_ctx,
515 basedn, LDB_SCOPE_BASE,
516 NULL, attrs, NULL, res,
517 ldb_search_default_callback,
519 assert_int_equal(ret, 0);
521 /* Expect that same event context will be chained */
522 assert_ptr_equal(ldb_handle_get_event_context(request->handle),
523 ldb_handle_get_event_context(request2->handle));
525 /* Now force this to use the global context */
526 ldb_handle_use_global_event_context(request2->handle);
527 assert_ptr_equal(ldb_handle_get_event_context(request2->handle),
528 ldb_get_event_context(test_ctx->ldb));
530 talloc_free(tmp_ctx);
533 static void test_ldb_build_search_req(void **state)
536 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
539 struct ldb_dn *basedn;
540 struct ldb_request *request = NULL;
541 struct ldb_request *request2 = NULL;
542 struct ldb_result *res = NULL;
543 const char *attrs[] = { "cn", NULL };
545 tmp_ctx = talloc_new(test_ctx);
546 assert_non_null(tmp_ctx);
548 basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "dc=test");
549 assert_non_null(basedn);
551 res = talloc_zero(tmp_ctx, struct ldb_result);
552 assert_non_null(res);
554 ret = ldb_build_search_req(&request, test_ctx->ldb, tmp_ctx,
555 basedn, LDB_SCOPE_BASE,
556 NULL, attrs, NULL, res,
557 ldb_search_default_callback,
559 assert_int_equal(ret, 0);
561 assert_int_equal(request->operation, LDB_SEARCH);
562 assert_ptr_equal(request->op.search.base, basedn);
563 assert_int_equal(request->op.search.scope, LDB_SCOPE_BASE);
564 assert_non_null(request->op.search.tree);
565 assert_ptr_equal(request->op.search.attrs, attrs);
566 assert_ptr_equal(request->context, res);
567 assert_ptr_equal(request->callback, ldb_search_default_callback);
569 ret = ldb_build_search_req(&request2, test_ctx->ldb, tmp_ctx,
570 basedn, LDB_SCOPE_BASE,
571 NULL, attrs, NULL, res,
572 ldb_search_default_callback,
574 assert_int_equal(ret, 0);
575 assert_ptr_equal(request, request2->handle->parent);
576 assert_int_equal(request->starttime, request2->starttime);
577 assert_int_equal(request->timeout, request2->timeout);
579 talloc_free(tmp_ctx);
582 static void add_keyval(struct ldbtest_ctx *test_ctx,
588 struct ldb_message *msg;
590 msg = ldb_msg_new(test_ctx);
591 assert_non_null(msg);
593 msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "%s=%s", key, val);
594 assert_non_null(msg->dn);
596 ret = ldb_msg_add_string(msg, key, val);
597 assert_int_equal(ret, 0);
599 ret = ldb_msg_add_string(msg, "objectUUID", uuid);
600 assert_int_equal(ret, 0);
602 ret = ldb_add(test_ctx->ldb, msg);
603 assert_int_equal(ret, 0);
608 static struct ldb_result *get_keyval(struct ldbtest_ctx *test_ctx,
613 struct ldb_result *result;
614 struct ldb_dn *basedn;
616 basedn = ldb_dn_new_fmt(test_ctx, test_ctx->ldb, "%s=%s", key, val);
617 assert_non_null(basedn);
619 ret = ldb_search(test_ctx->ldb, test_ctx, &result, basedn,
620 LDB_SCOPE_BASE, NULL, NULL);
621 assert_int_equal(ret, 0);
626 static void test_transactions(void **state)
629 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
631 struct ldb_result *res;
633 /* start lev-0 transaction */
634 ret = ldb_transaction_start(test_ctx->ldb);
635 assert_int_equal(ret, 0);
637 add_keyval(test_ctx, "vegetable", "carrot",
640 /* commit lev-0 transaction */
641 ret = ldb_transaction_commit(test_ctx->ldb);
642 assert_int_equal(ret, 0);
644 /* start another lev-1 nested transaction */
645 ret = ldb_transaction_start(test_ctx->ldb);
646 assert_int_equal(ret, 0);
648 add_keyval(test_ctx, "fruit", "apple",
651 /* abort lev-1 nested transaction */
652 ret = ldb_transaction_cancel(test_ctx->ldb);
653 assert_int_equal(ret, 0);
655 res = get_keyval(test_ctx, "vegetable", "carrot");
656 assert_non_null(res);
657 assert_int_equal(res->count, 1);
659 res = get_keyval(test_ctx, "fruit", "apple");
660 assert_non_null(res);
661 assert_int_equal(res->count, 0);
664 static void test_nested_transactions(void **state)
667 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
669 struct ldb_result *res;
671 /* start lev-0 transaction */
672 ret = ldb_transaction_start(test_ctx->ldb);
673 assert_int_equal(ret, 0);
675 add_keyval(test_ctx, "vegetable", "carrot",
679 /* start another lev-1 nested transaction */
680 ret = ldb_transaction_start(test_ctx->ldb);
681 assert_int_equal(ret, 0);
683 add_keyval(test_ctx, "fruit", "apple",
686 /* abort lev-1 nested transaction */
687 ret = ldb_transaction_cancel(test_ctx->ldb);
688 assert_int_equal(ret, 0);
690 /* commit lev-0 transaction */
691 ret = ldb_transaction_commit(test_ctx->ldb);
692 assert_int_equal(ret, 0);
694 res = get_keyval(test_ctx, "vegetable", "carrot");
695 assert_non_null(res);
696 assert_int_equal(res->count, 1);
698 /* This documents the current ldb behaviour, i.e. nested
699 * transactions are not supported. And the cancellation of the nested
700 * transaction has no effect.
702 res = get_keyval(test_ctx, "fruit", "apple");
703 assert_non_null(res);
704 assert_int_equal(res->count, 1);
706 struct ldb_mod_test_ctx {
707 struct ldbtest_ctx *ldb_test_ctx;
708 const char *entry_dn;
716 static struct ldb_message *build_mod_msg(TALLOC_CTX *mem_ctx,
717 struct ldbtest_ctx *test_ctx,
722 struct ldb_message *msg;
726 msg = ldb_msg_new(mem_ctx);
727 assert_non_null(msg);
729 msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "%s", dn);
730 assert_non_null(msg->dn);
732 for (i = 0; kvs[i].key != NULL; i++) {
734 ret = ldb_msg_add_empty(msg, kvs[i].key,
736 assert_int_equal(ret, 0);
740 ret = ldb_msg_add_string(msg, kvs[i].key, kvs[i].val);
741 assert_int_equal(ret, LDB_SUCCESS);
748 static void ldb_test_add_data(TALLOC_CTX *mem_ctx,
749 struct ldbtest_ctx *ldb_test_ctx,
754 struct ldb_message *msg;
755 struct ldb_result *result = NULL;
758 tmp_ctx = talloc_new(mem_ctx);
759 assert_non_null(tmp_ctx);
761 msg = build_mod_msg(tmp_ctx, ldb_test_ctx,
763 assert_non_null(msg);
765 ret = ldb_add(ldb_test_ctx->ldb, msg);
766 assert_int_equal(ret, LDB_SUCCESS);
768 ret = ldb_search(ldb_test_ctx->ldb, tmp_ctx, &result, msg->dn,
769 LDB_SCOPE_BASE, NULL, NULL);
770 assert_int_equal(ret, LDB_SUCCESS);
771 assert_non_null(result);
772 assert_int_equal(result->count, 1);
773 assert_string_equal(ldb_dn_get_linearized(result->msgs[0]->dn),
774 ldb_dn_get_linearized(msg->dn));
776 talloc_free(tmp_ctx);
779 static void ldb_test_remove_data(TALLOC_CTX *mem_ctx,
780 struct ldbtest_ctx *ldb_test_ctx,
784 struct ldb_dn *basedn;
788 tmp_ctx = talloc_new(mem_ctx);
789 assert_non_null(tmp_ctx);
791 basedn = ldb_dn_new_fmt(tmp_ctx, ldb_test_ctx->ldb,
793 assert_non_null(basedn);
795 ret = ldb_delete(ldb_test_ctx->ldb, basedn);
796 assert_true(ret == LDB_SUCCESS || ret == LDB_ERR_NO_SUCH_OBJECT);
798 count = base_search_count(ldb_test_ctx, ldb_dn_get_linearized(basedn));
799 assert_int_equal(count, 0);
801 talloc_free(tmp_ctx);
804 static void mod_test_add_data(struct ldb_mod_test_ctx *mod_test_ctx,
807 ldb_test_add_data(mod_test_ctx,
808 mod_test_ctx->ldb_test_ctx,
809 mod_test_ctx->entry_dn,
813 static void mod_test_remove_data(struct ldb_mod_test_ctx *mod_test_ctx)
815 ldb_test_remove_data(mod_test_ctx,
816 mod_test_ctx->ldb_test_ctx,
817 mod_test_ctx->entry_dn);
820 static struct ldb_result *run_mod_test(struct ldb_mod_test_ctx *mod_test_ctx,
825 struct ldb_result *res;
826 struct ldb_message *mod_msg;
827 struct ldb_dn *basedn;
828 struct ldbtest_ctx *ldb_test_ctx;
831 ldb_test_ctx = mod_test_ctx->ldb_test_ctx;
833 tmp_ctx = talloc_new(mod_test_ctx);
834 assert_non_null(tmp_ctx);
836 mod_msg = build_mod_msg(tmp_ctx, ldb_test_ctx, mod_test_ctx->entry_dn,
838 assert_non_null(mod_msg);
840 ret = ldb_modify(ldb_test_ctx->ldb, mod_msg);
841 assert_int_equal(ret, LDB_SUCCESS);
843 basedn = ldb_dn_new_fmt(tmp_ctx, ldb_test_ctx->ldb,
844 "%s", mod_test_ctx->entry_dn);
845 assert_non_null(basedn);
847 ret = ldb_search(ldb_test_ctx->ldb, mod_test_ctx, &res, basedn,
848 LDB_SCOPE_BASE, NULL, NULL);
849 assert_int_equal(ret, LDB_SUCCESS);
850 assert_non_null(res);
851 assert_int_equal(res->count, 1);
852 assert_string_equal(ldb_dn_get_linearized(res->msgs[0]->dn),
853 ldb_dn_get_linearized(mod_msg->dn));
855 talloc_free(tmp_ctx);
859 static int ldb_modify_test_setup(void **state)
861 struct ldbtest_ctx *ldb_test_ctx;
862 struct ldb_mod_test_ctx *mod_test_ctx;
863 struct keyval kvs[] = {
864 { "cn", "test_mod_cn" },
865 { "objectUUID", "0123456789abcdef"},
869 ldbtest_setup((void **) &ldb_test_ctx);
871 mod_test_ctx = talloc(ldb_test_ctx, struct ldb_mod_test_ctx);
872 assert_non_null(mod_test_ctx);
874 mod_test_ctx->entry_dn = "dc=mod_test_entry";
875 mod_test_ctx->ldb_test_ctx = ldb_test_ctx;
877 mod_test_remove_data(mod_test_ctx);
878 mod_test_add_data(mod_test_ctx, kvs);
879 *state = mod_test_ctx;
883 static int ldb_modify_test_teardown(void **state)
885 struct ldb_mod_test_ctx *mod_test_ctx = \
886 talloc_get_type_abort(*state,
887 struct ldb_mod_test_ctx);
888 struct ldbtest_ctx *ldb_test_ctx;
890 ldb_test_ctx = mod_test_ctx->ldb_test_ctx;
892 mod_test_remove_data(mod_test_ctx);
893 talloc_free(mod_test_ctx);
895 ldbtest_teardown((void **) &ldb_test_ctx);
899 static void test_ldb_modify_add_key(void **state)
901 struct ldb_mod_test_ctx *mod_test_ctx = \
902 talloc_get_type_abort(*state,
903 struct ldb_mod_test_ctx);
904 struct keyval mod_kvs[] = {
905 { "name", "test_mod_name" },
908 struct ldb_result *res;
909 struct ldb_message_element *el;
911 res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_ADD, mod_kvs);
912 assert_non_null(res);
914 /* Check cn is intact and name was added */
915 assert_int_equal(res->count, 1);
916 el = ldb_msg_find_element(res->msgs[0], "cn");
918 assert_int_equal(el->num_values, 1);
919 assert_string_equal(el->values[0].data, "test_mod_cn");
921 el = ldb_msg_find_element(res->msgs[0], "name");
923 assert_int_equal(el->num_values, 1);
924 assert_string_equal(el->values[0].data, "test_mod_name");
927 static void test_ldb_modify_extend_key(void **state)
929 struct ldb_mod_test_ctx *mod_test_ctx = \
930 talloc_get_type_abort(*state,
931 struct ldb_mod_test_ctx);
932 struct keyval mod_kvs[] = {
933 { "cn", "test_mod_cn2" },
936 struct ldb_result *res;
937 struct ldb_message_element *el;
939 res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_ADD, mod_kvs);
940 assert_non_null(res);
942 /* Check cn was extended with another value */
943 assert_int_equal(res->count, 1);
944 el = ldb_msg_find_element(res->msgs[0], "cn");
946 assert_int_equal(el->num_values, 2);
947 assert_string_equal(el->values[0].data, "test_mod_cn");
948 assert_string_equal(el->values[1].data, "test_mod_cn2");
951 static void test_ldb_modify_add_key_noval(void **state)
953 struct ldb_mod_test_ctx *mod_test_ctx = \
954 talloc_get_type_abort(*state,
955 struct ldb_mod_test_ctx);
956 struct ldb_message *mod_msg;
957 struct ldbtest_ctx *ldb_test_ctx;
958 struct ldb_message_element *el;
961 ldb_test_ctx = mod_test_ctx->ldb_test_ctx;
963 mod_msg = ldb_msg_new(mod_test_ctx);
964 assert_non_null(mod_msg);
966 mod_msg->dn = ldb_dn_new_fmt(mod_msg, ldb_test_ctx->ldb,
967 "%s", mod_test_ctx->entry_dn);
968 assert_non_null(mod_msg->dn);
970 el = talloc_zero(mod_msg, struct ldb_message_element);
971 el->flags = LDB_FLAG_MOD_ADD;
973 el->name = talloc_strdup(el, "cn");
974 assert_non_null(el->name);
976 mod_msg->elements = el;
977 mod_msg->num_elements = 1;
979 ret = ldb_modify(ldb_test_ctx->ldb, mod_msg);
980 assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION);
983 static void test_ldb_modify_replace_key(void **state)
985 struct ldb_mod_test_ctx *mod_test_ctx = \
986 talloc_get_type_abort(*state,
987 struct ldb_mod_test_ctx);
988 const char *new_cn = "new_cn";
989 struct keyval mod_kvs[] = {
993 struct ldb_result *res;
994 struct ldb_message_element *el;
996 res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, mod_kvs);
997 assert_non_null(res);
999 /* Check cn was replaced */
1000 assert_int_equal(res->count, 1);
1001 el = ldb_msg_find_element(res->msgs[0], "cn");
1002 assert_non_null(el);
1003 assert_int_equal(el->num_values, 1);
1004 assert_string_equal(el->values[0].data, new_cn);
1007 static void test_ldb_modify_replace_noexist_key(void **state)
1009 struct ldb_mod_test_ctx *mod_test_ctx = \
1010 talloc_get_type_abort(*state,
1011 struct ldb_mod_test_ctx);
1012 struct keyval mod_kvs[] = {
1013 { "name", "name_val" },
1016 struct ldb_result *res;
1017 struct ldb_message_element *el;
1019 res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, mod_kvs);
1020 assert_non_null(res);
1022 /* Check cn is intact and name was added */
1023 assert_int_equal(res->count, 1);
1024 el = ldb_msg_find_element(res->msgs[0], "cn");
1025 assert_non_null(el);
1026 assert_int_equal(el->num_values, 1);
1027 assert_string_equal(el->values[0].data, "test_mod_cn");
1029 el = ldb_msg_find_element(res->msgs[0], mod_kvs[0].key);
1030 assert_non_null(el);
1031 assert_int_equal(el->num_values, 1);
1032 assert_string_equal(el->values[0].data, mod_kvs[0].val);
1035 static void test_ldb_modify_replace_zero_vals(void **state)
1037 struct ldb_mod_test_ctx *mod_test_ctx = \
1038 talloc_get_type_abort(*state,
1039 struct ldb_mod_test_ctx);
1040 struct ldb_message_element *el;
1041 struct ldb_result *res;
1042 struct keyval kvs[] = {
1047 /* cn must be gone */
1048 res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, kvs);
1049 assert_non_null(res);
1050 el = ldb_msg_find_element(res->msgs[0], "cn");
1054 static void test_ldb_modify_replace_noexist_key_zero_vals(void **state)
1056 struct ldb_mod_test_ctx *mod_test_ctx = \
1057 talloc_get_type_abort(*state,
1058 struct ldb_mod_test_ctx);
1059 struct ldb_message_element *el;
1060 struct ldb_result *res;
1061 struct keyval kvs[] = {
1062 { "noexist_key", NULL },
1066 /* cn must be gone */
1067 res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, kvs);
1068 assert_non_null(res);
1070 /* cn should be intact */
1071 el = ldb_msg_find_element(res->msgs[0], "cn");
1072 assert_non_null(el);
1075 static void test_ldb_modify_del_key(void **state)
1077 struct ldb_mod_test_ctx *mod_test_ctx = \
1078 talloc_get_type_abort(*state,
1079 struct ldb_mod_test_ctx);
1080 struct ldb_message_element *el;
1081 struct ldb_result *res;
1082 struct keyval kvs[] = {
1087 /* cn must be gone */
1088 res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_DELETE, kvs);
1089 assert_non_null(res);
1091 el = ldb_msg_find_element(res->msgs[0], "cn");
1095 static void test_ldb_modify_del_keyval(void **state)
1097 struct ldb_mod_test_ctx *mod_test_ctx = \
1098 talloc_get_type_abort(*state,
1099 struct ldb_mod_test_ctx);
1100 struct ldb_message_element *el;
1101 struct ldb_result *res;
1102 struct keyval kvs[] = {
1103 { "cn", "test_mod_cn" },
1107 /* cn must be gone */
1108 res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_DELETE, kvs);
1109 assert_non_null(res);
1111 el = ldb_msg_find_element(res->msgs[0], "cn");
1115 struct search_test_ctx {
1116 struct ldbtest_ctx *ldb_test_ctx;
1117 const char *base_dn;
1120 static char *get_full_dn(TALLOC_CTX *mem_ctx,
1121 struct search_test_ctx *search_test_ctx,
1126 full_dn = talloc_asprintf(mem_ctx,
1127 "%s,%s", rdn, search_test_ctx->base_dn);
1128 assert_non_null(full_dn);
1133 static void search_test_add_data(struct search_test_ctx *search_test_ctx,
1139 full_dn = get_full_dn(search_test_ctx, search_test_ctx, rdn);
1141 ldb_test_add_data(search_test_ctx,
1142 search_test_ctx->ldb_test_ctx,
1147 static void search_test_remove_data(struct search_test_ctx *search_test_ctx,
1152 full_dn = talloc_asprintf(search_test_ctx,
1153 "%s,%s", rdn, search_test_ctx->base_dn);
1154 assert_non_null(full_dn);
1156 ldb_test_remove_data(search_test_ctx,
1157 search_test_ctx->ldb_test_ctx,
1161 static int ldb_search_test_setup(void **state)
1163 struct ldbtest_ctx *ldb_test_ctx;
1164 struct search_test_ctx *search_test_ctx;
1165 struct keyval kvs[] = {
1166 { "cn", "test_search_cn" },
1167 { "cn", "test_search_cn2" },
1168 { "uid", "test_search_uid" },
1169 { "uid", "test_search_uid2" },
1170 { "objectUUID", "0123456789abcde0"},
1173 struct keyval kvs2[] = {
1174 { "cn", "test_search_2_cn" },
1175 { "cn", "test_search_2_cn2" },
1176 { "uid", "test_search_2_uid" },
1177 { "uid", "test_search_2_uid2" },
1178 { "objectUUID", "0123456789abcde1"},
1182 ldbtest_setup((void **) &ldb_test_ctx);
1184 search_test_ctx = talloc(ldb_test_ctx, struct search_test_ctx);
1185 assert_non_null(search_test_ctx);
1187 search_test_ctx->base_dn = "dc=search_test_entry";
1188 search_test_ctx->ldb_test_ctx = ldb_test_ctx;
1190 search_test_remove_data(search_test_ctx, "cn=test_search_cn");
1191 search_test_add_data(search_test_ctx, "cn=test_search_cn", kvs);
1193 search_test_remove_data(search_test_ctx, "cn=test_search_2_cn");
1194 search_test_add_data(search_test_ctx, "cn=test_search_2_cn", kvs2);
1196 *state = search_test_ctx;
1200 static int ldb_search_test_teardown(void **state)
1202 struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1203 struct search_test_ctx);
1204 struct ldbtest_ctx *ldb_test_ctx;
1206 ldb_test_ctx = search_test_ctx->ldb_test_ctx;
1208 search_test_remove_data(search_test_ctx, "cn=test_search_cn");
1209 search_test_remove_data(search_test_ctx, "cn=test_search_2_cn");
1210 ldbtest_teardown((void **) &ldb_test_ctx);
1214 static void assert_attr_has_vals(struct ldb_message *msg,
1219 struct ldb_message_element *el;
1222 el = ldb_msg_find_element(msg, attr);
1223 assert_non_null(el);
1225 assert_int_equal(el->num_values, nvals);
1226 for (i = 0; i < nvals; i++) {
1227 assert_string_equal(el->values[i].data,
1232 static void assert_has_no_attr(struct ldb_message *msg,
1235 struct ldb_message_element *el;
1237 el = ldb_msg_find_element(msg, attr);
1241 static bool has_dn(struct ldb_message *msg, const char *dn)
1245 msgdn = ldb_dn_get_linearized(msg->dn);
1246 if (strcmp(dn, msgdn) == 0) {
1253 static void test_search_match_none(void **state)
1255 struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1256 struct search_test_ctx);
1259 count = base_search_count(search_test_ctx->ldb_test_ctx,
1260 "dc=no_such_entry");
1261 assert_int_equal(count, 0);
1264 static void test_search_match_one(void **state)
1266 struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1267 struct search_test_ctx);
1269 struct ldb_dn *basedn;
1270 struct ldb_result *result = NULL;
1271 const char *cn_vals[] = { "test_search_cn",
1272 "test_search_cn2" };
1273 const char *uid_vals[] = { "test_search_uid",
1274 "test_search_uid2" };
1276 basedn = ldb_dn_new_fmt(search_test_ctx,
1277 search_test_ctx->ldb_test_ctx->ldb,
1279 search_test_ctx->base_dn);
1280 assert_non_null(basedn);
1282 ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
1286 LDB_SCOPE_SUBTREE, NULL,
1287 "cn=test_search_cn");
1288 assert_int_equal(ret, 0);
1289 assert_non_null(result);
1290 assert_int_equal(result->count, 1);
1292 assert_attr_has_vals(result->msgs[0], "cn", cn_vals, 2);
1293 assert_attr_has_vals(result->msgs[0], "uid", uid_vals, 2);
1296 static void test_search_match_filter(void **state)
1298 struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1299 struct search_test_ctx);
1301 struct ldb_dn *basedn;
1302 struct ldb_result *result = NULL;
1303 const char *cn_vals[] = { "test_search_cn",
1304 "test_search_cn2" };
1305 const char *attrs[] = { "cn", NULL };
1307 basedn = ldb_dn_new_fmt(search_test_ctx,
1308 search_test_ctx->ldb_test_ctx->ldb,
1310 search_test_ctx->base_dn);
1311 assert_non_null(basedn);
1313 ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
1319 "cn=test_search_cn");
1320 assert_int_equal(ret, 0);
1321 assert_non_null(result);
1322 assert_int_equal(result->count, 1);
1324 assert_attr_has_vals(result->msgs[0], "cn", cn_vals, 2);
1325 assert_has_no_attr(result->msgs[0], "uid");
1328 static void assert_expected(struct search_test_ctx *search_test_ctx,
1329 struct ldb_message *msg)
1333 const char *cn_vals[] = { "test_search_cn",
1334 "test_search_cn2" };
1335 const char *uid_vals[] = { "test_search_uid",
1336 "test_search_uid2" };
1337 const char *cn2_vals[] = { "test_search_2_cn",
1338 "test_search_2_cn2" };
1339 const char *uid2_vals[] = { "test_search_2_uid",
1340 "test_search_2_uid2" };
1342 full_dn1 = get_full_dn(search_test_ctx,
1344 "cn=test_search_cn");
1346 full_dn2 = get_full_dn(search_test_ctx,
1348 "cn=test_search_2_cn");
1350 if (has_dn(msg, full_dn1) == true) {
1351 assert_attr_has_vals(msg, "cn", cn_vals, 2);
1352 assert_attr_has_vals(msg, "uid", uid_vals, 2);
1353 } else if (has_dn(msg, full_dn2) == true) {
1354 assert_attr_has_vals(msg, "cn", cn2_vals, 2);
1355 assert_attr_has_vals(msg, "uid", uid2_vals, 2);
1361 static void test_search_match_both(void **state)
1363 struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1364 struct search_test_ctx);
1366 struct ldb_dn *basedn;
1367 struct ldb_result *result = NULL;
1369 basedn = ldb_dn_new_fmt(search_test_ctx,
1370 search_test_ctx->ldb_test_ctx->ldb,
1372 search_test_ctx->base_dn);
1373 assert_non_null(basedn);
1375 ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
1379 LDB_SCOPE_SUBTREE, NULL,
1380 "cn=test_search_*");
1381 assert_int_equal(ret, 0);
1382 assert_non_null(result);
1383 assert_int_equal(result->count, 2);
1385 assert_expected(search_test_ctx, result->msgs[0]);
1386 assert_expected(search_test_ctx, result->msgs[1]);
1389 static void test_search_match_basedn(void **state)
1391 struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1392 struct search_test_ctx);
1394 struct ldb_dn *basedn;
1395 struct ldb_result *result = NULL;
1396 struct ldb_message *msg;
1398 basedn = ldb_dn_new_fmt(search_test_ctx,
1399 search_test_ctx->ldb_test_ctx->ldb,
1401 assert_non_null(basedn);
1403 ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
1407 LDB_SCOPE_SUBTREE, NULL,
1409 assert_int_equal(ret, 0);
1411 /* Add 'checkBaseOnSearch' to @OPTIONS */
1412 msg = ldb_msg_new(search_test_ctx);
1413 assert_non_null(msg);
1415 msg->dn = ldb_dn_new_fmt(msg,
1416 search_test_ctx->ldb_test_ctx->ldb,
1418 assert_non_null(msg->dn);
1420 ret = ldb_msg_add_string(msg, "checkBaseOnSearch", "TRUE");
1421 assert_int_equal(ret, 0);
1423 ret = ldb_add(search_test_ctx->ldb_test_ctx->ldb, msg);
1424 assert_int_equal(ret, 0);
1427 /* The search should return LDB_ERR_NO_SUCH_OBJECT */
1428 ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
1432 LDB_SCOPE_SUBTREE, NULL,
1434 assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT);
1436 ret = ldb_delete(search_test_ctx->ldb_test_ctx->ldb, msg->dn);
1437 assert_int_equal(ret, 0);
1442 * This test is complex.
1443 * The purpose is to test for a deadlock detected between ldb_search()
1444 * and ldb_transaction_commit(). The deadlock happens if in process
1446 * - (1) the all-record lock is taken in ltdb_search()
1447 * - (2) the ldb_transaction_start() call is made
1448 * - (1) an un-indexed search starts (forced here by doing it in
1450 * - (2) the ldb_transaction_commit() is called.
1451 * This returns LDB_ERR_BUSY if the deadlock is detected
1453 * With ldb 1.1.31 and tdb 1.3.12 we avoid this only due to a missing
1454 * lock call in ltdb_search() due to a refcounting bug in
1458 struct search_against_transaction_ctx {
1459 struct ldbtest_ctx *test_ctx;
1462 struct ldb_dn *basedn;
1465 static int test_ldb_search_against_transaction_callback2(struct ldb_request *req,
1466 struct ldb_reply *ares)
1468 struct search_against_transaction_ctx *ctx = req->context;
1469 switch (ares->type) {
1470 case LDB_REPLY_ENTRY:
1472 if (ctx->res_count != 1) {
1478 case LDB_REPLY_REFERRAL:
1481 case LDB_REPLY_DONE:
1482 return ldb_request_done(req, LDB_SUCCESS);
1490 * This purpose of this callback is to trigger a transaction in
1491 * the child process while the all-record lock is held, but before
1492 * we take any locks in the tdb_traverse_read() handler.
1494 * In tdb 1.3.12 tdb_traverse_read() take the read transaction lock
1495 * however in ldb 1.1.31 ltdb_search() forgets to take the all-record
1496 * lock (except the very first time) due to a ref-counting bug.
1500 static int test_ldb_search_against_transaction_callback1(struct ldb_request *req,
1501 struct ldb_reply *ares)
1506 struct search_against_transaction_ctx *ctx = req->context;
1507 switch (ares->type) {
1508 case LDB_REPLY_ENTRY:
1511 case LDB_REPLY_REFERRAL:
1514 case LDB_REPLY_DONE:
1515 return ldb_request_done(req, LDB_SUCCESS);
1519 assert_int_equal(ret, 0);
1521 ctx->child_pid = fork();
1522 if (ctx->child_pid == 0) {
1523 TALLOC_CTX *tmp_ctx = NULL;
1524 struct ldb_message *msg;
1525 TALLOC_FREE(ctx->test_ctx->ldb);
1526 TALLOC_FREE(ctx->test_ctx->ev);
1528 ctx->test_ctx->ev = tevent_context_init(ctx->test_ctx);
1529 if (ctx->test_ctx->ev == NULL) {
1530 exit(LDB_ERR_OPERATIONS_ERROR);
1533 ctx->test_ctx->ldb = ldb_init(ctx->test_ctx,
1535 if (ctx->test_ctx->ldb == NULL) {
1536 exit(LDB_ERR_OPERATIONS_ERROR);
1539 ret = ldb_connect(ctx->test_ctx->ldb,
1540 ctx->test_ctx->dbpath, 0, NULL);
1541 if (ret != LDB_SUCCESS) {
1545 tmp_ctx = talloc_new(ctx->test_ctx);
1546 if (tmp_ctx == NULL) {
1547 exit(LDB_ERR_OPERATIONS_ERROR);
1550 msg = ldb_msg_new(tmp_ctx);
1552 exit(LDB_ERR_OPERATIONS_ERROR);
1555 msg->dn = ldb_dn_new_fmt(msg, ctx->test_ctx->ldb,
1557 if (msg->dn == NULL) {
1558 exit(LDB_ERR_OPERATIONS_ERROR);
1561 ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
1563 exit(LDB_ERR_OPERATIONS_ERROR);
1566 ret = ldb_transaction_start(ctx->test_ctx->ldb);
1571 ret = write(pipes[1], "GO", 2);
1573 exit(LDB_ERR_OPERATIONS_ERROR);
1576 ret = ldb_msg_add_string(msg, "objectUUID",
1577 "0123456789abcdef");
1582 ret = ldb_add(ctx->test_ctx->ldb, msg);
1587 ret = ldb_transaction_commit(ctx->test_ctx->ldb);
1591 ret = read(pipes[0], buf, 2);
1592 assert_int_equal(ret, 2);
1594 /* This search must be unindexed (ie traverse in tdb) */
1595 ret = ldb_build_search_req(&req,
1603 test_ldb_search_against_transaction_callback2,
1606 * we don't assert on these return codes until after the search is
1607 * finished, or the clean up will fail because we hold locks.
1610 ret2 = ldb_request(ctx->test_ctx->ldb, req);
1612 if (ret2 == LDB_SUCCESS) {
1613 ret2 = ldb_wait(req->handle, LDB_WAIT_ALL);
1615 assert_int_equal(ret, 0);
1616 assert_int_equal(ret2, 0);
1617 assert_int_equal(ctx->res_count, 2);
1622 static void test_ldb_search_against_transaction(void **state)
1624 struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1625 struct search_test_ctx);
1626 struct search_against_transaction_ctx
1629 .test_ctx = search_test_ctx->ldb_test_ctx
1633 struct ldb_request *req;
1636 struct ldb_dn *base_search_dn;
1638 tevent_loop_allow_nesting(search_test_ctx->ldb_test_ctx->ev);
1641 = ldb_dn_new_fmt(search_test_ctx,
1642 search_test_ctx->ldb_test_ctx->ldb,
1643 "cn=test_search_cn,%s",
1644 search_test_ctx->base_dn);
1645 assert_non_null(base_search_dn);
1648 = ldb_dn_new_fmt(search_test_ctx,
1649 search_test_ctx->ldb_test_ctx->ldb,
1651 search_test_ctx->base_dn);
1652 assert_non_null(ctx.basedn);
1655 /* This search must be indexed (ie no traverse in tdb) */
1656 ret = ldb_build_search_req(&req,
1657 search_test_ctx->ldb_test_ctx->ldb,
1664 test_ldb_search_against_transaction_callback1,
1666 assert_int_equal(ret, 0);
1667 ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req);
1669 if (ret == LDB_SUCCESS) {
1670 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1672 assert_int_equal(ret, 0);
1673 assert_int_equal(ctx.res_count, 2);
1675 pid = waitpid(ctx.child_pid, &wstatus, 0);
1676 assert_int_equal(pid, ctx.child_pid);
1678 assert_true(WIFEXITED(wstatus));
1680 assert_int_equal(WEXITSTATUS(wstatus), 0);
1686 * This test is also complex.
1687 * The purpose is to test if a modify can occur during an ldb_search()
1688 * This would be a failure if if in process
1690 * - (1) ltdb_search() starts and calls back for one entry
1691 * - (2) one of the entries to be matched is modified
1692 * - (1) the indexed search tries to return the modified entry, but
1693 * it is no longer found, either:
1694 * - despite it still matching (dn changed)
1695 * - it no longer matching (attrs changed)
1697 * We also try un-indexed to show that the behaviour differs on this
1698 * point, which it should not (an index should only impact search
1702 struct modify_during_search_test_ctx {
1703 struct ldbtest_ctx *test_ctx;
1706 struct ldb_dn *basedn;
1713 * This purpose of this callback is to trigger a write in
1714 * the child process while a search is in progress.
1716 * In tdb 1.3.12 tdb_traverse_read() take the read transaction lock
1717 * however in ldb 1.1.31 ltdb_search() forgets to take the all-record
1718 * lock (except the very first time) due to a ref-counting bug.
1720 * We assume that if the write will proceed, it will proceed in a 3
1721 * second window after the function is called.
1724 static int test_ldb_modify_during_search_callback1(struct ldb_request *req,
1725 struct ldb_reply *ares)
1730 struct modify_during_search_test_ctx *ctx = req->context;
1731 switch (ares->type) {
1732 case LDB_REPLY_ENTRY:
1734 const struct ldb_val *cn_val
1735 = ldb_dn_get_component_val(ares->message->dn, 0);
1736 const char *cn = (char *)cn_val->data;
1738 if (strcmp(cn, "test_search_cn") == 0) {
1740 } else if (strcmp(cn, "test_search_2_cn") == 0) {
1741 ctx->got_2_cn = true;
1743 if (ctx->res_count == 2) {
1748 case LDB_REPLY_REFERRAL:
1751 case LDB_REPLY_DONE:
1752 return ldb_request_done(req, LDB_SUCCESS);
1756 assert_int_equal(ret, 0);
1758 ctx->child_pid = fork();
1759 if (ctx->child_pid == 0 && ctx->rename) {
1760 TALLOC_CTX *tmp_ctx = NULL;
1761 struct ldb_dn *dn, *new_dn;
1762 TALLOC_FREE(ctx->test_ctx->ldb);
1763 TALLOC_FREE(ctx->test_ctx->ev);
1765 ctx->test_ctx->ev = tevent_context_init(ctx->test_ctx);
1766 if (ctx->test_ctx->ev == NULL) {
1767 exit(LDB_ERR_OPERATIONS_ERROR);
1770 ctx->test_ctx->ldb = ldb_init(ctx->test_ctx,
1772 if (ctx->test_ctx->ldb == NULL) {
1773 exit(LDB_ERR_OPERATIONS_ERROR);
1776 ret = ldb_connect(ctx->test_ctx->ldb,
1777 ctx->test_ctx->dbpath, 0, NULL);
1778 if (ret != LDB_SUCCESS) {
1782 tmp_ctx = talloc_new(ctx->test_ctx);
1783 if (tmp_ctx == NULL) {
1784 exit(LDB_ERR_OPERATIONS_ERROR);
1788 /* Modify the other one */
1789 dn = ldb_dn_new_fmt(tmp_ctx, ctx->test_ctx->ldb,
1790 "cn=test_search_2_cn,"
1791 "dc=search_test_entry");
1793 dn = ldb_dn_new_fmt(tmp_ctx, ctx->test_ctx->ldb,
1794 "cn=test_search_cn,"
1795 "dc=search_test_entry");
1798 exit(LDB_ERR_OPERATIONS_ERROR);
1801 new_dn = ldb_dn_new_fmt(tmp_ctx, ctx->test_ctx->ldb,
1802 "cn=test_search_cn_renamed,"
1803 "dc=search_test_entry");
1804 if (new_dn == NULL) {
1805 exit(LDB_ERR_OPERATIONS_ERROR);
1808 ret = ldb_transaction_start(ctx->test_ctx->ldb);
1813 if (write(pipes[1], "GO", 2) != 2) {
1814 exit(LDB_ERR_OPERATIONS_ERROR);
1817 ret = ldb_rename(ctx->test_ctx->ldb, dn, new_dn);
1822 ret = ldb_transaction_commit(ctx->test_ctx->ldb);
1825 } else if (ctx->child_pid == 0) {
1826 TALLOC_CTX *tmp_ctx = NULL;
1827 struct ldb_message *msg;
1828 struct ldb_message_element *el;
1829 TALLOC_FREE(ctx->test_ctx->ldb);
1830 TALLOC_FREE(ctx->test_ctx->ev);
1832 ctx->test_ctx->ev = tevent_context_init(ctx->test_ctx);
1833 if (ctx->test_ctx->ev == NULL) {
1834 exit(LDB_ERR_OPERATIONS_ERROR);
1837 ctx->test_ctx->ldb = ldb_init(ctx->test_ctx,
1839 if (ctx->test_ctx->ldb == NULL) {
1840 exit(LDB_ERR_OPERATIONS_ERROR);
1843 ret = ldb_connect(ctx->test_ctx->ldb,
1844 ctx->test_ctx->dbpath, 0, NULL);
1845 if (ret != LDB_SUCCESS) {
1849 tmp_ctx = talloc_new(ctx->test_ctx);
1850 if (tmp_ctx == NULL) {
1851 exit(LDB_ERR_OPERATIONS_ERROR);
1854 msg = ldb_msg_new(tmp_ctx);
1856 exit(LDB_ERR_OPERATIONS_ERROR);
1860 /* Modify the other one */
1861 msg->dn = ldb_dn_new_fmt(msg, ctx->test_ctx->ldb,
1862 "cn=test_search_2_cn,"
1863 "dc=search_test_entry");
1865 msg->dn = ldb_dn_new_fmt(msg, ctx->test_ctx->ldb,
1866 "cn=test_search_cn,"
1867 "dc=search_test_entry");
1869 if (msg->dn == NULL) {
1870 exit(LDB_ERR_OPERATIONS_ERROR);
1873 ret = ldb_msg_add_string(msg, "filterAttr", "TRUE");
1875 exit(LDB_ERR_OPERATIONS_ERROR);
1877 el = ldb_msg_find_element(msg, "filterAttr");
1879 exit(LDB_ERR_OPERATIONS_ERROR);
1881 el->flags = LDB_FLAG_MOD_REPLACE;
1883 ret = ldb_transaction_start(ctx->test_ctx->ldb);
1888 if (write(pipes[1], "GO", 2) != 2) {
1889 exit(LDB_ERR_OPERATIONS_ERROR);
1892 ret = ldb_modify(ctx->test_ctx->ldb, msg);
1897 ret = ldb_transaction_commit(ctx->test_ctx->ldb);
1902 * With TDB 1.3.13 and before "tdb: Remove locking from tdb_traverse_read()"
1903 * we will hang here because the child process can not proceed to
1904 * sending the "GO" as it is blocked at ldb_transaction_start().
1908 ret = read(pipes[0], buf, 2);
1909 assert_int_equal(ret, 2);
1916 static void test_ldb_modify_during_search(void **state, bool add_index,
1919 struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1920 struct search_test_ctx);
1921 struct modify_during_search_test_ctx
1924 .test_ctx = search_test_ctx->ldb_test_ctx,
1929 struct ldb_request *req;
1934 struct ldb_message *msg;
1935 struct ldb_dn *indexlist = ldb_dn_new(search_test_ctx,
1936 search_test_ctx->ldb_test_ctx->ldb,
1938 assert_non_null(indexlist);
1940 msg = ldb_msg_new(search_test_ctx);
1941 assert_non_null(msg);
1943 msg->dn = indexlist;
1945 ret = ldb_msg_add_string(msg, "@IDXATTR", "cn");
1946 assert_int_equal(ret, LDB_SUCCESS);
1947 ret = ldb_add(search_test_ctx->ldb_test_ctx->ldb,
1949 if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) {
1950 msg->elements[0].flags = LDB_FLAG_MOD_ADD;
1951 ret = ldb_modify(search_test_ctx->ldb_test_ctx->ldb,
1954 assert_int_equal(ret, LDB_SUCCESS);
1957 tevent_loop_allow_nesting(search_test_ctx->ldb_test_ctx->ev);
1960 = ldb_dn_new_fmt(search_test_ctx,
1961 search_test_ctx->ldb_test_ctx->ldb,
1963 search_test_ctx->base_dn);
1964 assert_non_null(ctx.basedn);
1968 * This search must be over multiple items, and should include
1969 * the new name after a rename, to show that it would match
1970 * both before and after that modify
1972 ret = ldb_build_search_req(&req,
1973 search_test_ctx->ldb_test_ctx->ldb,
1977 "(&(!(filterAttr=*))"
1978 "(|(cn=test_search_cn_renamed)"
1979 "(cn=test_search_cn)"
1980 "(cn=test_search_2_cn)"
1985 test_ldb_modify_during_search_callback1,
1987 assert_int_equal(ret, 0);
1988 ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req);
1990 if (ret == LDB_SUCCESS) {
1991 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1993 assert_int_equal(ret, 0);
1994 assert_int_equal(ctx.res_count, 2);
1995 assert_int_equal(ctx.got_cn, true);
1996 assert_int_equal(ctx.got_2_cn, true);
1998 pid = waitpid(ctx.child_pid, &wstatus, 0);
1999 assert_int_equal(pid, ctx.child_pid);
2001 assert_true(WIFEXITED(wstatus));
2003 assert_int_equal(WEXITSTATUS(wstatus), 0);
2008 static void test_ldb_modify_during_indexed_search(void **state)
2010 test_ldb_modify_during_search(state, true, false);
2013 static void test_ldb_modify_during_unindexed_search(void **state)
2015 test_ldb_modify_during_search(state, false, false);
2018 static void test_ldb_rename_during_indexed_search(void **state)
2020 test_ldb_modify_during_search(state, true, true);
2023 static void test_ldb_rename_during_unindexed_search(void **state)
2025 test_ldb_modify_during_search(state, false, true);
2029 * This test is also complex.
2031 * The purpose is to test if a modify can occur during an ldb_search()
2032 * before the end of the callback
2034 * This would be a failure if if in process
2036 * - (1) ldb_search() starts and calls back for a number of entries
2037 * - (2) an entry in the DB is allowed to change before the callback returns
2038 * - (1) the callback can see the modification
2043 * This purpose of this callback is to trigger a write in
2044 * the child process while a search DONE callback is in progress.
2046 * In ldb 1.1.31 ldb_search() omitted to take a all-record
2047 * lock for the full duration of the search and callbacks
2049 * We assume that if the write will proceed, it will proceed in a 3
2050 * second window after the function is called.
2053 static int test_ldb_modify_during_whole_search_callback1(struct ldb_request *req,
2054 struct ldb_reply *ares)
2059 struct modify_during_search_test_ctx *ctx = req->context;
2060 struct ldb_dn *search_dn;
2061 struct ldb_result *res2;
2063 switch (ares->type) {
2064 case LDB_REPLY_ENTRY:
2065 case LDB_REPLY_REFERRAL:
2068 case LDB_REPLY_DONE:
2073 assert_int_equal(ret, 0);
2075 ctx->child_pid = fork();
2076 if (ctx->child_pid == 0) {
2077 TALLOC_CTX *tmp_ctx = NULL;
2078 struct ldb_message *msg;
2079 struct ldb_message_element *el;
2080 TALLOC_FREE(ctx->test_ctx->ldb);
2081 TALLOC_FREE(ctx->test_ctx->ev);
2083 ctx->test_ctx->ev = tevent_context_init(ctx->test_ctx);
2084 if (ctx->test_ctx->ev == NULL) {
2085 exit(LDB_ERR_OPERATIONS_ERROR);
2088 ctx->test_ctx->ldb = ldb_init(ctx->test_ctx,
2090 if (ctx->test_ctx->ldb == NULL) {
2091 exit(LDB_ERR_OPERATIONS_ERROR);
2094 ret = ldb_connect(ctx->test_ctx->ldb,
2095 ctx->test_ctx->dbpath, 0, NULL);
2096 if (ret != LDB_SUCCESS) {
2100 tmp_ctx = talloc_new(ctx->test_ctx);
2101 if (tmp_ctx == NULL) {
2102 exit(LDB_ERR_OPERATIONS_ERROR);
2105 msg = ldb_msg_new(tmp_ctx);
2107 exit(LDB_ERR_OPERATIONS_ERROR);
2110 msg->dn = ldb_dn_new_fmt(msg, ctx->test_ctx->ldb,
2111 "cn=test_search_cn,"
2112 "dc=search_test_entry");
2113 if (msg->dn == NULL) {
2114 exit(LDB_ERR_OPERATIONS_ERROR);
2117 ret = ldb_msg_add_string(msg, "filterAttr", "TRUE");
2119 exit(LDB_ERR_OPERATIONS_ERROR);
2121 el = ldb_msg_find_element(msg, "filterAttr");
2123 exit(LDB_ERR_OPERATIONS_ERROR);
2125 el->flags = LDB_FLAG_MOD_REPLACE;
2127 ret = ldb_transaction_start(ctx->test_ctx->ldb);
2132 if (write(pipes[1], "GO", 2) != 2) {
2133 exit(LDB_ERR_OPERATIONS_ERROR);
2136 ret = ldb_modify(ctx->test_ctx->ldb, msg);
2141 ret = ldb_transaction_commit(ctx->test_ctx->ldb);
2146 ret = read(pipes[0], buf, 2);
2147 assert_int_equal(ret, 2);
2152 * If writes are not blocked until after this function, we
2153 * will be able to successfully search for this modification
2157 search_dn = ldb_dn_new_fmt(ares, ctx->test_ctx->ldb,
2158 "cn=test_search_cn,"
2159 "dc=search_test_entry");
2161 ret = ldb_search(ctx->test_ctx->ldb, ares,
2162 &res2, search_dn, LDB_SCOPE_BASE, NULL,
2166 * We do this in an unusual order, because if we fail an assert before
2167 * ldb_request_done(), we will also fail to clean up as we hold locks.
2170 res_count = res2->count;
2171 ldb_request_done(req, LDB_SUCCESS);
2172 assert_int_equal(ret, 0);
2174 /* We should not have got the result */
2175 assert_int_equal(res_count, 0);
2180 static void test_ldb_modify_during_whole_search(void **state)
2182 struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
2183 struct search_test_ctx);
2184 struct modify_during_search_test_ctx
2187 .test_ctx = search_test_ctx->ldb_test_ctx,
2191 struct ldb_request *req;
2194 struct ldb_dn *search_dn;
2195 struct ldb_result *res2;
2197 tevent_loop_allow_nesting(search_test_ctx->ldb_test_ctx->ev);
2200 = ldb_dn_new_fmt(search_test_ctx,
2201 search_test_ctx->ldb_test_ctx->ldb,
2203 search_test_ctx->base_dn);
2204 assert_non_null(ctx.basedn);
2208 * The search just needs to call DONE, we don't care about the
2209 * contents of the search for this test
2211 ret = ldb_build_search_req(&req,
2212 search_test_ctx->ldb_test_ctx->ldb,
2216 "(&(!(filterAttr=*))"
2217 "(cn=test_search_cn))",
2221 test_ldb_modify_during_whole_search_callback1,
2223 assert_int_equal(ret, 0);
2224 ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req);
2226 if (ret == LDB_SUCCESS) {
2227 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
2229 assert_int_equal(ret, 0);
2231 pid = waitpid(ctx.child_pid, &wstatus, 0);
2232 assert_int_equal(pid, ctx.child_pid);
2234 assert_true(WIFEXITED(wstatus));
2236 assert_int_equal(WEXITSTATUS(wstatus), 0);
2239 * If writes are blocked until after the search function, we
2240 * will be able to successfully search for this modification
2244 search_dn = ldb_dn_new_fmt(search_test_ctx,
2245 search_test_ctx->ldb_test_ctx->ldb,
2246 "cn=test_search_cn,"
2247 "dc=search_test_entry");
2249 ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
2251 &res2, search_dn, LDB_SCOPE_BASE, NULL,
2253 assert_int_equal(ret, 0);
2255 /* We got the result */
2256 assert_int_equal(res2->count, 1);
2260 * This test is also complex.
2262 * The purpose is to test if a modify can occur during an ldb_search()
2263 * before the request is destroyed with TALLOC_FREE()
2265 * This would be a failure if in process
2267 * - (1) ldb_search() starts and waits
2268 * - (2) an entry in the DB is allowed to change before the ldb_wait() is called
2269 * - (1) the original process can see the modification before the TALLOC_FREE()
2270 * also we check that
2271 * - (1) the original process can see the modification after the TALLOC_FREE()
2276 * This purpose of this callback is to trigger a write in
2277 * the child process before the ldb_wait() is called
2279 * In ldb 1.1.31 ldb_search() omitted to take a all-record
2280 * lock for the full duration of the search and callbacks
2282 * We assume that if the write will proceed, it will proceed in a 3
2283 * second window after the function is called.
2286 static int test_ldb_modify_before_ldb_wait_callback1(struct ldb_request *req,
2287 struct ldb_reply *ares)
2289 switch (ares->type) {
2290 case LDB_REPLY_ENTRY:
2291 case LDB_REPLY_REFERRAL:
2294 case LDB_REPLY_DONE:
2298 return ldb_request_done(req, LDB_SUCCESS);
2301 static void test_ldb_modify_before_ldb_wait(void **state)
2303 struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
2304 struct search_test_ctx);
2306 struct ldb_request *req;
2309 struct ldb_dn *search_dn;
2310 struct ldb_dn *basedn;
2311 struct ldb_result *res2;
2317 search_dn = ldb_dn_new_fmt(search_test_ctx,
2318 search_test_ctx->ldb_test_ctx->ldb,
2319 "cn=test_search_cn,"
2320 "dc=search_test_entry");
2321 assert_non_null(search_dn);
2323 basedn = ldb_dn_new_fmt(search_test_ctx,
2324 search_test_ctx->ldb_test_ctx->ldb,
2326 search_test_ctx->base_dn);
2327 assert_non_null(basedn);
2330 * The search just needs to call DONE, we don't care about the
2331 * contents of the search for this test
2333 ret = ldb_build_search_req(&req,
2334 search_test_ctx->ldb_test_ctx->ldb,
2338 "(&(!(filterAttr=*))"
2339 "(cn=test_search_cn))",
2343 test_ldb_modify_before_ldb_wait_callback1,
2345 assert_int_equal(ret, 0);
2346 ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req);
2349 assert_int_equal(ret, 0);
2352 if (child_pid == 0) {
2353 TALLOC_CTX *tmp_ctx = NULL;
2354 struct ldb_message *msg;
2355 struct ldb_message_element *el;
2356 TALLOC_FREE(search_test_ctx->ldb_test_ctx->ldb);
2357 TALLOC_FREE(search_test_ctx->ldb_test_ctx->ev);
2359 search_test_ctx->ldb_test_ctx->ev = tevent_context_init(search_test_ctx->ldb_test_ctx);
2360 if (search_test_ctx->ldb_test_ctx->ev == NULL) {
2361 exit(LDB_ERR_OPERATIONS_ERROR);
2364 search_test_ctx->ldb_test_ctx->ldb = ldb_init(search_test_ctx->ldb_test_ctx,
2365 search_test_ctx->ldb_test_ctx->ev);
2366 if (search_test_ctx->ldb_test_ctx->ldb == NULL) {
2367 exit(LDB_ERR_OPERATIONS_ERROR);
2370 ret = ldb_connect(search_test_ctx->ldb_test_ctx->ldb,
2371 search_test_ctx->ldb_test_ctx->dbpath, 0, NULL);
2372 if (ret != LDB_SUCCESS) {
2376 tmp_ctx = talloc_new(search_test_ctx->ldb_test_ctx);
2377 if (tmp_ctx == NULL) {
2378 exit(LDB_ERR_OPERATIONS_ERROR);
2381 msg = ldb_msg_new(tmp_ctx);
2383 exit(LDB_ERR_OPERATIONS_ERROR);
2387 * We must re-create this DN from a string to ensure
2388 * it does not reference the now-gone LDB context of
2391 msg->dn = ldb_dn_new_fmt(search_test_ctx,
2392 search_test_ctx->ldb_test_ctx->ldb,
2393 "cn=test_search_cn,"
2394 "dc=search_test_entry");
2396 if (msg->dn == NULL) {
2397 exit(LDB_ERR_OPERATIONS_ERROR);
2400 ret = ldb_msg_add_string(msg, "filterAttr", "TRUE");
2402 exit(LDB_ERR_OPERATIONS_ERROR);
2404 el = ldb_msg_find_element(msg, "filterAttr");
2406 exit(LDB_ERR_OPERATIONS_ERROR);
2408 el->flags = LDB_FLAG_MOD_REPLACE;
2410 ret = ldb_transaction_start(search_test_ctx->ldb_test_ctx->ldb);
2415 if (write(pipes[1], "GO", 2) != 2) {
2416 exit(LDB_ERR_OPERATIONS_ERROR);
2419 ret = ldb_modify(search_test_ctx->ldb_test_ctx->ldb, msg);
2424 ret = ldb_transaction_commit(search_test_ctx->ldb_test_ctx->ldb);
2429 ret = read(pipes[0], buf, 2);
2430 assert_int_equal(ret, 2);
2435 * If writes are not blocked until after the (never called) ldb_wait(), we
2436 * will be able to successfully search for this modification
2440 ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb, search_test_ctx,
2441 &res2, search_dn, LDB_SCOPE_BASE, NULL,
2445 * We avoid making assertions before TALLOC_FREE()ing the request,
2446 * lest the assert fail and mess with the clean-up because we still
2449 res_count = res2->count;
2452 /* We should not have got the result */
2453 assert_int_equal(res_count, 0);
2454 assert_int_equal(ret, 0);
2456 pid = waitpid(child_pid, &wstatus, 0);
2457 assert_int_equal(pid, child_pid);
2459 assert_true(WIFEXITED(wstatus));
2461 assert_int_equal(WEXITSTATUS(wstatus), 0);
2464 * If writes are blocked until after the search request was freed, we
2465 * will be able to successfully search for this modification
2469 search_dn = ldb_dn_new_fmt(search_test_ctx,
2470 search_test_ctx->ldb_test_ctx->ldb,
2471 "cn=test_search_cn,"
2472 "dc=search_test_entry");
2474 ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
2476 &res2, search_dn, LDB_SCOPE_BASE, NULL,
2478 assert_int_equal(ret, 0);
2480 /* We got the result */
2481 assert_int_equal(res2->count, 1);
2484 static int ldb_case_test_setup(void **state)
2487 struct ldb_ldif *ldif;
2488 struct ldbtest_ctx *ldb_test_ctx;
2489 const char *attrs_ldif = \
2491 "cn: CASE_INSENSITIVE\n"
2493 struct keyval kvs[] = {
2494 { "cn", "CaseInsensitiveValue" },
2495 { "uid", "CaseSensitiveValue" },
2496 { "objectUUID", "0123456789abcdef" },
2501 ldbtest_setup((void **) &ldb_test_ctx);
2503 while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &attrs_ldif))) {
2504 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
2505 assert_int_equal(ret, LDB_SUCCESS);
2508 ldb_test_add_data(ldb_test_ctx,
2510 "cn=CaseInsensitiveValue",
2513 *state = ldb_test_ctx;
2517 static int ldb_case_test_teardown(void **state)
2520 struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
2521 struct ldbtest_ctx);
2523 struct ldb_dn *del_dn;
2525 del_dn = ldb_dn_new_fmt(ldb_test_ctx,
2528 assert_non_null(del_dn);
2530 ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
2531 assert_int_equal(ret, LDB_SUCCESS);
2533 assert_dn_doesnt_exist(ldb_test_ctx,
2536 ldb_test_remove_data(ldb_test_ctx, ldb_test_ctx,
2537 "cn=CaseInsensitiveValue");
2539 ldbtest_teardown((void **) &ldb_test_ctx);
2543 static void test_ldb_attrs_case_insensitive(void **state)
2546 struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
2547 struct ldbtest_ctx);
2549 /* cn matches exact case */
2550 cnt = sub_search_count(ldb_test_ctx, "", "cn=CaseInsensitiveValue");
2551 assert_int_equal(cnt, 1);
2553 /* cn matches lower case */
2554 cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2555 assert_int_equal(cnt, 1);
2557 /* uid matches exact case */
2558 cnt = sub_search_count(ldb_test_ctx, "", "uid=CaseSensitiveValue");
2559 assert_int_equal(cnt, 1);
2561 /* uid does not match lower case */
2562 cnt = sub_search_count(ldb_test_ctx, "", "uid=casesensitivevalue");
2563 assert_int_equal(cnt, 0);
2566 static struct ldb_schema_attribute cn_attr_1;
2567 static struct ldb_schema_attribute cn_attr_2;
2568 static struct ldb_schema_attribute default_attr;
2571 override the name to attribute handler function
2573 static const struct ldb_schema_attribute *ldb_test_attribute_handler_override(struct ldb_context *ldb,
2577 if (private_data != NULL && ldb_attr_cmp(name, "cn") == 0) {
2579 } else if (private_data == NULL && ldb_attr_cmp(name, "cn") == 0) {
2581 } else if (ldb_attr_cmp(name, "uid") == 0) {
2584 return &default_attr;
2587 static void test_ldb_attrs_case_handler(void **state)
2591 const struct ldb_schema_syntax *syntax;
2593 struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
2594 struct ldbtest_ctx);
2595 struct ldb_context *ldb = ldb_test_ctx->ldb;
2597 /* cn matches lower case */
2598 cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2599 assert_int_equal(cnt, 1);
2601 syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_OCTET_STRING);
2602 assert_non_null(syntax);
2604 ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb,
2606 syntax, &default_attr);
2607 assert_int_equal(ret, LDB_SUCCESS);
2609 syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_OCTET_STRING);
2610 assert_non_null(syntax);
2612 ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb,
2614 syntax, &cn_attr_1);
2615 assert_int_equal(ret, LDB_SUCCESS);
2618 * Set an attribute handler, which will fail to match as we
2619 * force case sensitive
2621 ldb_schema_attribute_set_override_handler(ldb,
2622 ldb_test_attribute_handler_override,
2625 /* cn does not matche lower case */
2626 cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2627 assert_int_equal(cnt, 0);
2629 syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_DIRECTORY_STRING);
2630 assert_non_null(syntax);
2632 ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb,
2634 syntax, &cn_attr_2);
2635 assert_int_equal(ret, LDB_SUCCESS);
2638 * Set an attribute handler, which will match as we
2639 * force case insensitive
2641 ldb_schema_attribute_set_override_handler(ldb,
2642 ldb_test_attribute_handler_override,
2645 /* cn matches lower case */
2646 cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2647 assert_int_equal(cnt, 1);
2652 static void test_ldb_attrs_index_handler(void **state)
2656 const struct ldb_schema_syntax *syntax;
2657 struct ldb_ldif *ldif;
2659 const char *index_ldif = \
2664 struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
2665 struct ldbtest_ctx);
2666 struct ldb_context *ldb = ldb_test_ctx->ldb;
2668 /* cn matches lower case */
2669 cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2670 assert_int_equal(cnt, 1);
2672 syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_OCTET_STRING);
2673 assert_non_null(syntax);
2675 ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb,
2677 syntax, &cn_attr_1);
2678 assert_int_equal(ret, LDB_SUCCESS);
2680 syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_DIRECTORY_STRING);
2681 assert_non_null(syntax);
2683 ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb,
2684 "cn", LDB_ATTR_FLAG_INDEXED,
2685 syntax, &cn_attr_2);
2686 assert_int_equal(ret, LDB_SUCCESS);
2688 syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_OCTET_STRING);
2689 assert_non_null(syntax);
2691 ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb,
2693 syntax, &default_attr);
2694 assert_int_equal(ret, LDB_SUCCESS);
2697 * Set an attribute handler
2699 ldb_schema_attribute_set_override_handler(ldb,
2700 ldb_test_attribute_handler_override,
2703 /* cn matches lower case */
2704 cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2705 assert_int_equal(cnt, 1);
2707 /* Add the index (actually any modify will do) */
2708 while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &index_ldif))) {
2709 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
2710 if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) {
2711 ldif->msg->elements[0].flags = LDB_FLAG_MOD_ADD;
2712 ret = ldb_modify(ldb_test_ctx->ldb,
2715 assert_int_equal(ret, LDB_SUCCESS);
2718 ldb_schema_set_override_indexlist(ldb, false);
2720 /* cn does match as there is an index now */
2721 cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2722 assert_int_equal(cnt, 1);
2725 * Set an attribute handler, which will later fail to match as we
2726 * didn't re-index the DB
2728 ldb_schema_attribute_set_override_handler(ldb,
2729 ldb_test_attribute_handler_override,
2733 * cn does not match as we changed the case sensitivity, but
2736 * This shows that the override is in control
2738 cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2739 assert_int_equal(cnt, 0);
2743 static int ldb_case_attrs_index_test_teardown(void **state)
2746 struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
2747 struct ldbtest_ctx);
2748 struct ldb_dn *del_dn;
2750 del_dn = ldb_dn_new_fmt(ldb_test_ctx,
2753 assert_non_null(del_dn);
2755 ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
2756 if (ret != LDB_ERR_NO_SUCH_OBJECT) {
2757 assert_int_equal(ret, LDB_SUCCESS);
2760 assert_dn_doesnt_exist(ldb_test_ctx,
2763 ldb_case_test_teardown(state);
2768 struct rename_test_ctx {
2769 struct ldbtest_ctx *ldb_test_ctx;
2771 struct ldb_dn *basedn;
2772 const char *str_basedn;
2774 const char *teardown_dn;
2777 static int ldb_rename_test_setup(void **state)
2779 struct ldbtest_ctx *ldb_test_ctx;
2780 struct rename_test_ctx *rename_test_ctx;
2781 const char *strdn = "dc=rename_test_entry_from";
2783 ldbtest_setup((void **) &ldb_test_ctx);
2785 rename_test_ctx = talloc(ldb_test_ctx, struct rename_test_ctx);
2786 assert_non_null(rename_test_ctx);
2787 rename_test_ctx->ldb_test_ctx = ldb_test_ctx;
2788 assert_non_null(rename_test_ctx->ldb_test_ctx);
2790 rename_test_ctx->basedn = ldb_dn_new_fmt(rename_test_ctx,
2791 rename_test_ctx->ldb_test_ctx->ldb,
2793 assert_non_null(rename_test_ctx->basedn);
2795 rename_test_ctx->str_basedn = strdn;
2796 rename_test_ctx->teardown_dn = strdn;
2798 add_dn_with_cn(ldb_test_ctx,
2799 rename_test_ctx->basedn,
2800 "test_rename_cn_val",
2801 "0123456789abcde0");
2803 *state = rename_test_ctx;
2807 static int ldb_rename_test_teardown(void **state)
2810 struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(*state,
2811 struct rename_test_ctx);
2812 struct ldbtest_ctx *ldb_test_ctx;
2813 struct ldb_dn *del_dn;
2815 ldb_test_ctx = rename_test_ctx->ldb_test_ctx;
2817 del_dn = ldb_dn_new_fmt(rename_test_ctx,
2818 rename_test_ctx->ldb_test_ctx->ldb,
2819 "%s", rename_test_ctx->teardown_dn);
2820 assert_non_null(del_dn);
2822 ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
2823 assert_int_equal(ret, LDB_SUCCESS);
2825 assert_dn_doesnt_exist(ldb_test_ctx,
2826 rename_test_ctx->teardown_dn);
2828 ldbtest_teardown((void **) &ldb_test_ctx);
2832 static void test_ldb_rename(void **state)
2834 struct rename_test_ctx *rename_test_ctx =
2835 talloc_get_type_abort(*state, struct rename_test_ctx);
2837 const char *str_new_dn = "dc=rename_test_entry_to";
2838 struct ldb_dn *new_dn;
2840 new_dn = ldb_dn_new_fmt(rename_test_ctx,
2841 rename_test_ctx->ldb_test_ctx->ldb,
2843 assert_non_null(new_dn);
2845 ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
2846 rename_test_ctx->basedn,
2848 assert_int_equal(ret, LDB_SUCCESS);
2850 assert_dn_exists(rename_test_ctx->ldb_test_ctx, str_new_dn);
2851 assert_dn_doesnt_exist(rename_test_ctx->ldb_test_ctx,
2852 rename_test_ctx->str_basedn);
2853 rename_test_ctx->teardown_dn = str_new_dn;
2855 /* FIXME - test the values which didn't change */
2858 static void test_ldb_rename_from_doesnt_exist(void **state)
2860 struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(
2862 struct rename_test_ctx);
2864 const char *str_new_dn = "dc=rename_test_entry_to";
2865 const char *str_bad_old_dn = "dc=rename_test_no_such_entry";
2866 struct ldb_dn *new_dn;
2867 struct ldb_dn *bad_old_dn;
2869 new_dn = ldb_dn_new_fmt(rename_test_ctx,
2870 rename_test_ctx->ldb_test_ctx->ldb,
2872 assert_non_null(new_dn);
2874 bad_old_dn = ldb_dn_new_fmt(rename_test_ctx,
2875 rename_test_ctx->ldb_test_ctx->ldb,
2876 "%s", str_bad_old_dn);
2877 assert_non_null(bad_old_dn);
2879 assert_dn_doesnt_exist(rename_test_ctx->ldb_test_ctx,
2882 ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
2883 bad_old_dn, new_dn);
2884 assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT);
2886 assert_dn_doesnt_exist(rename_test_ctx->ldb_test_ctx,
2890 static void test_ldb_rename_to_exists(void **state)
2892 struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(
2894 struct rename_test_ctx);
2896 const char *str_new_dn = "dc=rename_test_already_exists";
2897 struct ldb_dn *new_dn;
2899 new_dn = ldb_dn_new_fmt(rename_test_ctx,
2900 rename_test_ctx->ldb_test_ctx->ldb,
2902 assert_non_null(new_dn);
2904 add_dn_with_cn(rename_test_ctx->ldb_test_ctx,
2906 "test_rename_cn_val",
2907 "0123456789abcde1");
2909 ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
2910 rename_test_ctx->basedn,
2912 assert_int_equal(ret, LDB_ERR_ENTRY_ALREADY_EXISTS);
2914 /* Old object must still exist */
2915 assert_dn_exists(rename_test_ctx->ldb_test_ctx,
2916 rename_test_ctx->str_basedn);
2918 ret = ldb_delete(rename_test_ctx->ldb_test_ctx->ldb,
2920 assert_int_equal(ret, LDB_SUCCESS);
2922 assert_dn_exists(rename_test_ctx->ldb_test_ctx,
2923 rename_test_ctx->teardown_dn);
2926 static void test_ldb_rename_self(void **state)
2928 struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(
2930 struct rename_test_ctx);
2933 /* Oddly enough, this is a success in ldb.. */
2934 ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
2935 rename_test_ctx->basedn,
2936 rename_test_ctx->basedn);
2937 assert_int_equal(ret, LDB_SUCCESS);
2939 /* Old object must still exist */
2940 assert_dn_exists(rename_test_ctx->ldb_test_ctx,
2941 rename_test_ctx->str_basedn);
2944 static void test_ldb_rename_dn_case_change(void **state)
2946 struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(
2948 struct rename_test_ctx);
2951 struct ldb_dn *new_dn;
2954 str_new_dn = talloc_strdup(rename_test_ctx, rename_test_ctx->str_basedn);
2955 assert_non_null(str_new_dn);
2956 for (i = 0; str_new_dn[i]; i++) {
2957 str_new_dn[i] = toupper(str_new_dn[i]);
2960 new_dn = ldb_dn_new_fmt(rename_test_ctx,
2961 rename_test_ctx->ldb_test_ctx->ldb,
2963 assert_non_null(new_dn);
2965 ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
2966 rename_test_ctx->basedn,
2968 assert_int_equal(ret, LDB_SUCCESS);
2970 /* DNs are case insensitive, so both searches will match */
2971 assert_dn_exists(rename_test_ctx->ldb_test_ctx, str_new_dn);
2972 assert_dn_exists(rename_test_ctx->ldb_test_ctx,
2973 rename_test_ctx->str_basedn);
2974 /* FIXME - test the values didn't change */
2977 static int ldb_read_only_setup(void **state)
2979 struct ldbtest_ctx *test_ctx;
2981 ldbtest_setup((void **) &test_ctx);
2987 static int ldb_read_only_teardown(void **state)
2989 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
2990 struct ldbtest_ctx);
2991 ldbtest_teardown((void **) &test_ctx);
2995 static void test_read_only(void **state)
2997 struct ldb_context *ro_ldb = NULL;
2998 struct ldb_context *rw_ldb = NULL;
3000 TALLOC_CTX *tmp_ctx = NULL;
3002 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3003 struct ldbtest_ctx);
3005 * Close the ldb context freeing it this will ensure it exists on
3006 * disk and can be opened in read only mode
3008 TALLOC_FREE(test_ctx->ldb);
3011 * Open the database in read only and read write mode,
3012 * ensure it's opend in read only mode first
3014 ro_ldb = ldb_init(test_ctx, test_ctx->ev);
3015 ret = ldb_connect(ro_ldb, test_ctx->dbpath, LDB_FLG_RDONLY, NULL);
3016 assert_int_equal(ret, 0);
3018 rw_ldb = ldb_init(test_ctx, test_ctx->ev);
3019 ret = ldb_connect(rw_ldb, test_ctx->dbpath, 0, NULL);
3020 assert_int_equal(ret, 0);
3024 * Set up a context for the temporary variables
3026 tmp_ctx = talloc_new(test_ctx);
3027 assert_non_null(tmp_ctx);
3030 * Ensure that we can search the read write database
3033 struct ldb_result *result = NULL;
3034 struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, rw_ldb,
3036 assert_non_null(dn);
3038 ret = ldb_search(rw_ldb, tmp_ctx, &result, dn,
3039 LDB_SCOPE_BASE, NULL, NULL);
3040 assert_int_equal(ret, LDB_SUCCESS);
3041 TALLOC_FREE(result);
3046 * Ensure that we can search the read only database
3049 struct ldb_result *result = NULL;
3050 struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, ro_ldb,
3052 assert_non_null(dn);
3054 ret = ldb_search(ro_ldb, tmp_ctx, &result, dn,
3055 LDB_SCOPE_BASE, NULL, NULL);
3056 assert_int_equal(ret, LDB_SUCCESS);
3057 TALLOC_FREE(result);
3061 * Ensure that a write to the read only database fails
3064 struct ldb_message *msg = NULL;
3065 msg = ldb_msg_new(tmp_ctx);
3066 assert_non_null(msg);
3068 msg->dn = ldb_dn_new_fmt(msg, ro_ldb, "dc=test");
3069 assert_non_null(msg->dn);
3071 ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
3072 assert_int_equal(ret, 0);
3074 ret = ldb_msg_add_string(msg, "objectUUID",
3075 "0123456789abcde1");
3076 assert_int_equal(ret, LDB_SUCCESS);
3078 ret = ldb_add(ro_ldb, msg);
3079 assert_int_equal(ret, LDB_ERR_UNWILLING_TO_PERFORM);
3084 * Ensure that a write to the read write database succeeds
3087 struct ldb_message *msg = NULL;
3088 msg = ldb_msg_new(tmp_ctx);
3089 assert_non_null(msg);
3091 msg->dn = ldb_dn_new_fmt(msg, rw_ldb, "dc=test");
3092 assert_non_null(msg->dn);
3094 ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
3095 assert_int_equal(ret, 0);
3097 ret = ldb_msg_add_string(msg, "objectUUID",
3098 "0123456789abcde2");
3099 assert_int_equal(ret, LDB_SUCCESS);
3101 ret = ldb_add(rw_ldb, msg);
3102 assert_int_equal(ret, LDB_SUCCESS);
3107 * Ensure that a delete from a read only database fails
3110 struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, ro_ldb, "dc=test");
3111 assert_non_null(dn);
3113 ret = ldb_delete(ro_ldb, dn);
3114 assert_int_equal(ret, LDB_ERR_UNWILLING_TO_PERFORM);
3120 * Ensure that a delete from a read write succeeds
3123 struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, rw_ldb, "dc=test");
3124 assert_non_null(dn);
3126 ret = ldb_delete(rw_ldb, dn);
3127 assert_int_equal(ret, LDB_SUCCESS);
3130 TALLOC_FREE(tmp_ctx);
3133 static bool unique_values = false;
3135 static int unique_index_test_module_add(
3136 struct ldb_module *module,
3137 struct ldb_request *req)
3139 if (unique_values) {
3140 struct ldb_message *msg = discard_const(req->op.add.message);
3141 struct ldb_message_element *el = NULL;
3142 el = ldb_msg_find_element(msg, "cn");
3144 el->flags |= LDB_FLAG_INTERNAL_FORCE_UNIQUE_INDEX;
3148 return ldb_next_request(module, req);
3151 static int unique_index_test_module_init(struct ldb_module *module)
3153 return ldb_next_init(module);
3156 static const struct ldb_module_ops ldb_unique_index_test_module_ops = {
3157 .name = "unique_index_test",
3158 .init_context = unique_index_test_module_init,
3159 .add = unique_index_test_module_add,
3162 static int ldb_unique_index_test_setup(void **state)
3165 struct ldb_ldif *ldif;
3166 struct ldbtest_ctx *ldb_test_ctx;
3167 const char *attrs_ldif = \
3169 "cn: UNIQUE_INDEX\n"
3171 const char *index_ldif = \
3175 "@IDXGUID: objectUUID\n"
3176 "@IDX_DN_GUID: GUID\n"
3179 const char *options[] = {"modules:unique_index_test", NULL};
3182 ret = ldb_register_module(&ldb_unique_index_test_module_ops);
3183 assert_true(ret == LDB_SUCCESS || ret == LDB_ERR_ENTRY_ALREADY_EXISTS);
3184 ldbtest_noconn_setup((void **) &ldb_test_ctx);
3187 ret = ldb_connect(ldb_test_ctx->ldb, ldb_test_ctx->dbpath, 0, options);
3188 assert_int_equal(ret, 0);
3190 while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &attrs_ldif))) {
3191 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
3192 assert_int_equal(ret, LDB_SUCCESS);
3195 while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &index_ldif))) {
3196 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
3197 assert_int_equal(ret, LDB_SUCCESS);
3200 unique_values = true;
3202 *state = ldb_test_ctx;
3206 static int ldb_unique_index_test_teardown(void **state)
3209 struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
3210 struct ldbtest_ctx);
3211 struct ldb_dn *del_dn;
3213 del_dn = ldb_dn_new_fmt(ldb_test_ctx,
3216 assert_non_null(del_dn);
3218 ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
3219 if (ret != LDB_ERR_NO_SUCH_OBJECT) {
3220 assert_int_equal(ret, LDB_SUCCESS);
3223 assert_dn_doesnt_exist(ldb_test_ctx,
3226 TALLOC_FREE(del_dn);
3228 del_dn = ldb_dn_new_fmt(ldb_test_ctx,
3231 assert_non_null(del_dn);
3233 ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
3234 if (ret != LDB_ERR_NO_SUCH_OBJECT) {
3235 assert_int_equal(ret, LDB_SUCCESS);
3238 assert_dn_doesnt_exist(ldb_test_ctx,
3241 ldbtest_teardown((void **) &ldb_test_ctx);
3246 static void test_ldb_add_unique_value_to_unique_index(void **state)
3249 struct ldb_message *msg;
3250 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3251 struct ldbtest_ctx);
3252 TALLOC_CTX *tmp_ctx;
3254 tmp_ctx = talloc_new(test_ctx);
3255 assert_non_null(tmp_ctx);
3257 msg = ldb_msg_new(tmp_ctx);
3258 assert_non_null(msg);
3260 msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "dc=test");
3261 assert_non_null(msg->dn);
3263 ret = ldb_msg_add_string(msg, "cn", "test_unique_index");
3264 assert_int_equal(ret, LDB_SUCCESS);
3266 ret = ldb_msg_add_string(msg, "objectUUID",
3267 "0123456789abcde1");
3268 assert_int_equal(ret, LDB_SUCCESS);
3270 ret = ldb_add(test_ctx->ldb, msg);
3271 assert_int_equal(ret, LDB_SUCCESS);
3273 talloc_free(tmp_ctx);
3276 static int ldb_non_unique_index_test_setup(void **state)
3279 struct ldb_ldif *ldif;
3280 struct ldbtest_ctx *ldb_test_ctx;
3281 const char *index_ldif = \
3285 "@IDXGUID: objectUUID\n"
3286 "@IDX_DN_GUID: GUID\n"
3289 const char *options[] = {"modules:unique_index_test", NULL};
3292 ret = ldb_register_module(&ldb_unique_index_test_module_ops);
3293 assert_true(ret == LDB_SUCCESS || ret == LDB_ERR_ENTRY_ALREADY_EXISTS);
3294 ldbtest_noconn_setup((void **) &ldb_test_ctx);
3297 ret = ldb_connect(ldb_test_ctx->ldb, ldb_test_ctx->dbpath, 0, options);
3298 assert_int_equal(ret, 0);
3300 while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &index_ldif))) {
3301 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
3302 assert_int_equal(ret, LDB_SUCCESS);
3305 unique_values = true;
3307 *state = ldb_test_ctx;
3311 static int ldb_non_unique_index_test_teardown(void **state)
3314 struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
3315 struct ldbtest_ctx);
3316 struct ldb_dn *del_dn;
3318 del_dn = ldb_dn_new_fmt(ldb_test_ctx,
3321 assert_non_null(del_dn);
3323 ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
3324 if (ret != LDB_ERR_NO_SUCH_OBJECT) {
3325 assert_int_equal(ret, LDB_SUCCESS);
3328 assert_dn_doesnt_exist(ldb_test_ctx,
3331 TALLOC_FREE(del_dn);
3333 ldbtest_teardown((void **) &ldb_test_ctx);
3337 static void test_ldb_add_duplicate_value_to_unique_index(void **state)
3340 struct ldb_message *msg01;
3341 struct ldb_message *msg02;
3342 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3343 struct ldbtest_ctx);
3344 TALLOC_CTX *tmp_ctx;
3346 tmp_ctx = talloc_new(test_ctx);
3347 assert_non_null(tmp_ctx);
3349 msg01 = ldb_msg_new(tmp_ctx);
3350 assert_non_null(msg01);
3352 msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3353 assert_non_null(msg01->dn);
3355 ret = ldb_msg_add_string(msg01, "cn", "test_unique_index");
3356 assert_int_equal(ret, LDB_SUCCESS);
3358 ret = ldb_msg_add_string(msg01, "objectUUID",
3359 "0123456789abcde1");
3360 assert_int_equal(ret, LDB_SUCCESS);
3362 ret = ldb_add(test_ctx->ldb, msg01);
3363 assert_int_equal(ret, LDB_SUCCESS);
3365 msg02 = ldb_msg_new(tmp_ctx);
3366 assert_non_null(msg02);
3368 msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02");
3369 assert_non_null(msg02->dn);
3371 ret = ldb_msg_add_string(msg02, "cn", "test_unique_index");
3372 assert_int_equal(ret, LDB_SUCCESS);
3374 ret = ldb_msg_add_string(msg02, "objectUUID",
3375 "0123456789abcde2");
3376 assert_int_equal(ret, LDB_SUCCESS);
3378 ret = ldb_add(test_ctx->ldb, msg02);
3379 assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION);
3380 talloc_free(tmp_ctx);
3383 static void test_ldb_add_to_index_duplicates_allowed(void **state)
3386 struct ldb_message *msg01;
3387 struct ldb_message *msg02;
3388 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3389 struct ldbtest_ctx);
3390 TALLOC_CTX *tmp_ctx;
3392 unique_values = false;
3394 tmp_ctx = talloc_new(test_ctx);
3395 assert_non_null(tmp_ctx);
3398 msg01 = ldb_msg_new(tmp_ctx);
3399 assert_non_null(msg01);
3401 msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3402 assert_non_null(msg01->dn);
3404 ret = ldb_msg_add_string(msg01, "cn", "test_unique_index");
3405 assert_int_equal(ret, LDB_SUCCESS);
3407 ret = ldb_msg_add_string(msg01, "objectUUID",
3408 "0123456789abcde1");
3410 ret = ldb_add(test_ctx->ldb, msg01);
3411 assert_int_equal(ret, LDB_SUCCESS);
3413 msg02 = ldb_msg_new(tmp_ctx);
3414 assert_non_null(msg02);
3416 msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02");
3417 assert_non_null(msg02->dn);
3419 ret = ldb_msg_add_string(msg02, "cn", "test_unique_index");
3420 assert_int_equal(ret, LDB_SUCCESS);
3422 ret = ldb_msg_add_string(msg02, "objectUUID",
3423 "0123456789abcde2");
3425 ret = ldb_add(test_ctx->ldb, msg02);
3426 assert_int_equal(ret, LDB_SUCCESS);
3427 talloc_free(tmp_ctx);
3430 static void test_ldb_add_to_index_unique_values_required(void **state)
3433 struct ldb_message *msg01;
3434 struct ldb_message *msg02;
3435 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3436 struct ldbtest_ctx);
3437 TALLOC_CTX *tmp_ctx;
3439 unique_values = true;
3441 tmp_ctx = talloc_new(test_ctx);
3442 assert_non_null(tmp_ctx);
3445 msg01 = ldb_msg_new(tmp_ctx);
3446 assert_non_null(msg01);
3448 msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3449 assert_non_null(msg01->dn);
3451 ret = ldb_msg_add_string(msg01, "cn", "test_unique_index");
3452 assert_int_equal(ret, LDB_SUCCESS);
3454 ret = ldb_msg_add_string(msg01, "objectUUID",
3455 "0123456789abcde1");
3457 ret = ldb_add(test_ctx->ldb, msg01);
3458 assert_int_equal(ret, LDB_SUCCESS);
3460 msg02 = ldb_msg_new(tmp_ctx);
3461 assert_non_null(msg02);
3463 msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02");
3464 assert_non_null(msg02->dn);
3466 ret = ldb_msg_add_string(msg02, "cn", "test_unique_index");
3467 assert_int_equal(ret, LDB_SUCCESS);
3469 ret = ldb_msg_add_string(msg02, "objectUUID",
3470 "0123456789abcde2");
3472 ret = ldb_add(test_ctx->ldb, msg02);
3473 assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION);
3474 talloc_free(tmp_ctx);
3477 static void ldb_debug_string(void *context, enum ldb_debug_level level,
3478 const char *fmt, va_list ap)
3481 if (level <= LDB_DEBUG_WARNING) {
3482 *((char **)context) = talloc_vasprintf(NULL, fmt, ap);
3486 static void test_ldb_unique_index_duplicate_logging(void **state)
3489 struct ldb_message *msg01;
3490 struct ldb_message *msg02;
3491 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3492 struct ldbtest_ctx);
3493 TALLOC_CTX *tmp_ctx;
3494 char *debug_string = NULL;
3497 /* The GUID mode is not compatible with this test */
3502 ldb_set_debug(test_ctx->ldb, ldb_debug_string, &debug_string);
3503 tmp_ctx = talloc_new(test_ctx);
3504 assert_non_null(tmp_ctx);
3506 msg01 = ldb_msg_new(tmp_ctx);
3507 assert_non_null(msg01);
3509 msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3510 assert_non_null(msg01->dn);
3512 ret = ldb_msg_add_string(msg01, "cn", "test_unique_index");
3513 assert_int_equal(ret, LDB_SUCCESS);
3515 ret = ldb_msg_add_string(msg01, "objectUUID",
3516 "0123456789abcde1");
3518 ret = ldb_add(test_ctx->ldb, msg01);
3519 assert_int_equal(ret, LDB_SUCCESS);
3521 msg02 = ldb_msg_new(tmp_ctx);
3522 assert_non_null(msg02);
3524 msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02");
3525 assert_non_null(msg02->dn);
3527 ret = ldb_msg_add_string(msg02, "cn", "test_unique_index");
3528 assert_int_equal(ret, LDB_SUCCESS);
3530 ret = ldb_msg_add_string(msg02, "objectUUID",
3531 "0123456789abcde2");
3533 ret = ldb_add(test_ctx->ldb, msg02);
3534 assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION);
3536 assert_non_null(debug_string);
3539 "unique index violation on cn "
3540 "in dc=test02, conficts with dc=test01 in "
3541 "@INDEX:CN:test_unique_index");
3543 TALLOC_FREE(debug_string);
3544 talloc_free(tmp_ctx);
3547 static void test_ldb_duplicate_dn_logging(void **state)
3550 struct ldb_message *msg01;
3551 struct ldb_message *msg02;
3552 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3553 struct ldbtest_ctx);
3554 TALLOC_CTX *tmp_ctx;
3555 char *debug_string = NULL;
3557 /* The GUID mode is not compatible with this test */
3562 ldb_set_debug(test_ctx->ldb, ldb_debug_string, &debug_string);
3563 tmp_ctx = talloc_new(test_ctx);
3564 assert_non_null(tmp_ctx);
3566 msg01 = ldb_msg_new(tmp_ctx);
3567 assert_non_null(msg01);
3569 msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3570 assert_non_null(msg01->dn);
3572 ret = ldb_msg_add_string(msg01, "cn", "test_unique_index01");
3573 assert_int_equal(ret, LDB_SUCCESS);
3575 ret = ldb_msg_add_string(msg01, "objectUUID",
3576 "0123456789abcde1");
3578 ret = ldb_add(test_ctx->ldb, msg01);
3579 assert_int_equal(ret, LDB_SUCCESS);
3581 msg02 = ldb_msg_new(tmp_ctx);
3582 assert_non_null(msg02);
3584 msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test01");
3585 assert_non_null(msg02->dn);
3587 ret = ldb_msg_add_string(msg02, "cn", "test_unique_index02");
3588 assert_int_equal(ret, LDB_SUCCESS);
3590 ret = ldb_msg_add_string(msg02, "objectUUID",
3591 "0123456789abcde2");
3593 ret = ldb_add(test_ctx->ldb, msg02);
3594 assert_int_equal(ret, LDB_ERR_ENTRY_ALREADY_EXISTS);
3596 assert_null(debug_string);
3597 talloc_free(tmp_ctx);
3600 static int ldb_guid_index_test_setup(void **state)
3603 struct ldb_ldif *ldif;
3604 struct ldbtest_ctx *ldb_test_ctx;
3605 const char *attrs_ldif = \
3607 "cn: UNIQUE_INDEX\n"
3609 const char *index_ldif = \
3612 "@IDXGUID: objectUUID\n"
3613 "@IDX_DN_GUID: GUID\n"
3616 ldbtest_noconn_setup((void **) &ldb_test_ctx);
3619 ret = ldb_connect(ldb_test_ctx->ldb, ldb_test_ctx->dbpath, 0, NULL);
3620 assert_int_equal(ret, 0);
3622 while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &attrs_ldif))) {
3623 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
3624 assert_int_equal(ret, LDB_SUCCESS);
3627 while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &index_ldif))) {
3628 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
3629 assert_int_equal(ret, LDB_SUCCESS);
3632 *state = ldb_test_ctx;
3636 static int ldb_guid_index_test_teardown(void **state)
3639 struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
3640 struct ldbtest_ctx);
3641 struct ldb_dn *del_dn;
3643 del_dn = ldb_dn_new_fmt(ldb_test_ctx,
3646 assert_non_null(del_dn);
3648 ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
3649 if (ret != LDB_ERR_NO_SUCH_OBJECT) {
3650 assert_int_equal(ret, LDB_SUCCESS);
3653 assert_dn_doesnt_exist(ldb_test_ctx,
3656 TALLOC_FREE(del_dn);
3658 del_dn = ldb_dn_new_fmt(ldb_test_ctx,
3661 assert_non_null(del_dn);
3663 ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
3664 if (ret != LDB_ERR_NO_SUCH_OBJECT) {
3665 assert_int_equal(ret, LDB_SUCCESS);
3668 assert_dn_doesnt_exist(ldb_test_ctx,
3671 ldbtest_teardown((void **) &ldb_test_ctx);
3676 static void test_ldb_unique_index_duplicate_with_guid(void **state)
3679 struct ldb_message *msg01;
3680 struct ldb_message *msg02;
3681 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3682 struct ldbtest_ctx);
3683 TALLOC_CTX *tmp_ctx;
3684 char *debug_string = NULL;
3687 ldb_set_debug(test_ctx->ldb, ldb_debug_string, &debug_string);
3688 tmp_ctx = talloc_new(test_ctx);
3689 assert_non_null(tmp_ctx);
3691 msg01 = ldb_msg_new(tmp_ctx);
3692 assert_non_null(msg01);
3694 msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3695 assert_non_null(msg01->dn);
3697 ret = ldb_msg_add_string(msg01, "cn", "test_unique_index");
3698 assert_int_equal(ret, LDB_SUCCESS);
3700 ret = ldb_msg_add_string(msg01, "objectUUID", "0123456789abcdef");
3701 assert_int_equal(ret, LDB_SUCCESS);
3703 ret = ldb_add(test_ctx->ldb, msg01);
3704 assert_int_equal(ret, LDB_SUCCESS);
3706 msg02 = ldb_msg_new(tmp_ctx);
3707 assert_non_null(msg01);
3709 msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02");
3710 assert_non_null(msg02->dn);
3712 ret = ldb_msg_add_string(msg02, "cn", "test_unique_index");
3713 assert_int_equal(ret, LDB_SUCCESS);
3715 ret = ldb_msg_add_string(msg02, "objectUUID", "0123456789abcde0");
3716 assert_int_equal(ret, LDB_SUCCESS);
3718 ret = ldb_add(test_ctx->ldb, msg02);
3719 assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION);
3721 assert_non_null(debug_string);
3724 "unique index violation on cn in dc=test02, conficts with "
3725 "objectUUID 0123456789abcdef in @INDEX:CN:test_unique_index");
3727 TALLOC_FREE(debug_string);
3728 talloc_free(tmp_ctx);
3731 static void test_ldb_guid_index_duplicate_dn_logging(void **state)
3734 struct ldb_message *msg01;
3735 struct ldb_message *msg02;
3736 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3737 struct ldbtest_ctx);
3738 TALLOC_CTX *tmp_ctx;
3739 char *debug_string = NULL;
3741 ldb_set_debug(test_ctx->ldb, ldb_debug_string, &debug_string);
3742 tmp_ctx = talloc_new(test_ctx);
3743 assert_non_null(tmp_ctx);
3745 msg01 = ldb_msg_new(tmp_ctx);
3746 assert_non_null(msg01);
3748 msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3749 assert_non_null(msg01->dn);
3751 ret = ldb_msg_add_string(msg01, "cn", "test_unique_index01");
3752 assert_int_equal(ret, LDB_SUCCESS);
3754 ret = ldb_msg_add_string(msg01, "objectUUID", "0123456789abcdef");
3755 assert_int_equal(ret, LDB_SUCCESS);
3757 ret = ldb_add(test_ctx->ldb, msg01);
3758 assert_int_equal(ret, LDB_SUCCESS);
3760 msg02 = ldb_msg_new(tmp_ctx);
3761 assert_non_null(msg02);
3763 msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test01");
3764 assert_non_null(msg02->dn);
3766 ret = ldb_msg_add_string(msg02, "cn", "test_unique_index02");
3767 assert_int_equal(ret, LDB_SUCCESS);
3769 ret = ldb_msg_add_string(msg02, "objectUUID", "0123456789abcde1");
3770 assert_int_equal(ret, LDB_SUCCESS);
3772 ret = ldb_add(test_ctx->ldb, msg02);
3773 assert_int_equal(ret, LDB_ERR_ENTRY_ALREADY_EXISTS);
3775 assert_null(debug_string);
3776 talloc_free(tmp_ctx);
3779 static void test_ldb_talloc_destructor_transaction_cleanup(void **state)
3781 struct ldbtest_ctx *test_ctx = NULL;
3783 test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx);
3784 assert_non_null(test_ctx);
3786 ldb_transaction_start(test_ctx->ldb);
3789 * Trigger the destructor
3791 TALLOC_FREE(test_ctx->ldb);
3794 * Now ensure that a new connection can be opened
3797 TALLOC_CTX *tctx = talloc_new(test_ctx);
3798 struct ldbtest_ctx *ctx = talloc_zero(tctx, struct ldbtest_ctx);
3799 struct ldb_dn *basedn;
3800 struct ldb_result *result = NULL;
3803 ldbtest_setup((void *)&ctx);
3805 basedn = ldb_dn_new_fmt(tctx, ctx->ldb, "dc=test");
3806 assert_non_null(basedn);
3808 ret = ldb_search(ctx->ldb,
3815 assert_int_equal(ret, 0);
3816 assert_non_null(result);
3817 assert_int_equal(result->count, 0);
3819 ldbtest_teardown((void *)&ctx);
3823 static void test_transaction_start_across_fork(void **state)
3825 struct ldb_context *ldb1 = NULL;
3827 struct ldbtest_ctx *test_ctx = NULL;
3831 pid_t pid, child_pid;
3833 test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx);
3838 ldb1 = ldb_init(test_ctx, test_ctx->ev);
3839 ret = ldb_connect(ldb1, test_ctx->dbpath, 0, NULL);
3840 assert_int_equal(ret, 0);
3843 assert_int_equal(ret, 0);
3846 if (child_pid == 0) {
3848 ret = ldb_transaction_start(ldb1);
3849 if (ret != LDB_ERR_PROTOCOL_ERROR) {
3850 print_error(__location__": ldb_transaction_start "
3851 "returned (%d) %s\n",
3854 exit(LDB_ERR_OTHER);
3857 ret = write(pipes[1], "GO", 2);
3859 print_error(__location__
3860 " write returned (%d)",
3862 exit(LDB_ERR_OPERATIONS_ERROR);
3867 ret = read(pipes[0], buf, 2);
3868 assert_int_equal(ret, 2);
3870 pid = waitpid(child_pid, &wstatus, 0);
3871 assert_int_equal(pid, child_pid);
3873 assert_true(WIFEXITED(wstatus));
3875 assert_int_equal(WEXITSTATUS(wstatus), 0);
3878 static void test_transaction_commit_across_fork(void **state)
3880 struct ldb_context *ldb1 = NULL;
3882 struct ldbtest_ctx *test_ctx = NULL;
3886 pid_t pid, child_pid;
3888 test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx);
3893 ldb1 = ldb_init(test_ctx, test_ctx->ev);
3894 ret = ldb_connect(ldb1, test_ctx->dbpath, 0, NULL);
3895 assert_int_equal(ret, 0);
3897 ret = ldb_transaction_start(ldb1);
3898 assert_int_equal(ret, 0);
3901 assert_int_equal(ret, 0);
3904 if (child_pid == 0) {
3906 ret = ldb_transaction_commit(ldb1);
3908 if (ret != LDB_ERR_PROTOCOL_ERROR) {
3909 print_error(__location__": ldb_transaction_commit "
3910 "returned (%d) %s\n",
3913 exit(LDB_ERR_OTHER);
3916 ret = write(pipes[1], "GO", 2);
3918 print_error(__location__
3919 " write returned (%d)",
3921 exit(LDB_ERR_OPERATIONS_ERROR);
3926 ret = read(pipes[0], buf, 2);
3927 assert_int_equal(ret, 2);
3929 pid = waitpid(child_pid, &wstatus, 0);
3930 assert_int_equal(pid, child_pid);
3932 assert_true(WIFEXITED(wstatus));
3934 assert_int_equal(WEXITSTATUS(wstatus), 0);
3937 static void test_lock_read_across_fork(void **state)
3939 struct ldb_context *ldb1 = NULL;
3941 struct ldbtest_ctx *test_ctx = NULL;
3945 pid_t pid, child_pid;
3947 test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx);
3952 ldb1 = ldb_init(test_ctx, test_ctx->ev);
3953 ret = ldb_connect(ldb1, test_ctx->dbpath, 0, NULL);
3954 assert_int_equal(ret, 0);
3957 assert_int_equal(ret, 0);
3960 if (child_pid == 0) {
3961 struct ldb_dn *basedn;
3962 struct ldb_result *result = NULL;
3966 basedn = ldb_dn_new_fmt(test_ctx, test_ctx->ldb, "dc=test");
3967 assert_non_null(basedn);
3969 ret = ldb_search(test_ctx->ldb,
3976 if (ret != LDB_ERR_PROTOCOL_ERROR) {
3977 print_error(__location__": ldb_search "
3978 "returned (%d) %s\n",
3981 exit(LDB_ERR_OTHER);
3984 ret = write(pipes[1], "GO", 2);
3986 print_error(__location__
3987 " write returned (%d)",
3989 exit(LDB_ERR_OPERATIONS_ERROR);
3994 ret = read(pipes[0], buf, 2);
3995 assert_int_equal(ret, 2);
3997 pid = waitpid(child_pid, &wstatus, 0);
3998 assert_int_equal(pid, child_pid);
4000 assert_true(WIFEXITED(wstatus));
4002 assert_int_equal(WEXITSTATUS(wstatus), 0);
4006 * Ensure that the search actually succeeds on the opening
4009 struct ldb_dn *basedn;
4010 struct ldb_result *result = NULL;
4014 basedn = ldb_dn_new_fmt(test_ctx, test_ctx->ldb, "dc=test");
4015 assert_non_null(basedn);
4017 ret = ldb_search(test_ctx->ldb,
4024 assert_int_equal(0, ret);
4028 static void test_multiple_opens_across_fork(void **state)
4030 struct ldb_context *ldb1 = NULL;
4031 struct ldb_context *ldb2 = NULL;
4033 struct ldbtest_ctx *test_ctx = NULL;
4037 pid_t pid, child_pid;
4039 test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx);
4042 * Open the database again
4044 ldb1 = ldb_init(test_ctx, test_ctx->ev);
4045 ret = ldb_connect(ldb1, test_ctx->dbpath, LDB_FLG_RDONLY, NULL);
4046 assert_int_equal(ret, 0);
4048 ldb2 = ldb_init(test_ctx, test_ctx->ev);
4049 ret = ldb_connect(ldb2, test_ctx->dbpath, 0, NULL);
4050 assert_int_equal(ret, 0);
4053 assert_int_equal(ret, 0);
4056 if (child_pid == 0) {
4057 struct ldb_context *ldb3 = NULL;
4060 ldb3 = ldb_init(test_ctx, test_ctx->ev);
4061 ret = ldb_connect(ldb3, test_ctx->dbpath, 0, NULL);
4063 print_error(__location__": ldb_connect returned (%d)\n",
4067 ret = write(pipes[1], "GO", 2);
4069 print_error(__location__
4070 " write returned (%d)",
4072 exit(LDB_ERR_OPERATIONS_ERROR);
4077 ret = read(pipes[0], buf, 2);
4078 assert_int_equal(ret, 2);
4080 pid = waitpid(child_pid, &wstatus, 0);
4081 assert_int_equal(pid, child_pid);
4083 assert_true(WIFEXITED(wstatus));
4085 assert_int_equal(WEXITSTATUS(wstatus), 0);
4088 int main(int argc, const char **argv)
4090 const struct CMUnitTest tests[] = {
4091 cmocka_unit_test_setup_teardown(test_connect,
4092 ldbtest_noconn_setup,
4093 ldbtest_noconn_teardown),
4094 cmocka_unit_test_setup_teardown(test_ldif_message,
4095 ldbtest_noconn_setup,
4096 ldbtest_noconn_teardown),
4097 cmocka_unit_test_setup_teardown(test_ldif_message_redacted,
4098 ldbtest_noconn_setup,
4099 ldbtest_noconn_teardown),
4100 cmocka_unit_test_setup_teardown(test_ldb_add,
4103 cmocka_unit_test_setup_teardown(test_ldb_search,
4106 cmocka_unit_test_setup_teardown(test_ldb_del,
4109 cmocka_unit_test_setup_teardown(test_ldb_del_noexist,
4112 cmocka_unit_test_setup_teardown(test_ldb_handle,
4115 cmocka_unit_test_setup_teardown(test_ldb_build_search_req,
4118 cmocka_unit_test_setup_teardown(test_transactions,
4121 cmocka_unit_test_setup_teardown(test_nested_transactions,
4124 cmocka_unit_test_setup_teardown(test_ldb_modify_add_key,
4125 ldb_modify_test_setup,
4126 ldb_modify_test_teardown),
4127 cmocka_unit_test_setup_teardown(test_ldb_modify_extend_key,
4128 ldb_modify_test_setup,
4129 ldb_modify_test_teardown),
4130 cmocka_unit_test_setup_teardown(test_ldb_modify_add_key_noval,
4131 ldb_modify_test_setup,
4132 ldb_modify_test_teardown),
4133 cmocka_unit_test_setup_teardown(test_ldb_modify_replace_key,
4134 ldb_modify_test_setup,
4135 ldb_modify_test_teardown),
4136 cmocka_unit_test_setup_teardown(test_ldb_modify_replace_noexist_key,
4137 ldb_modify_test_setup,
4138 ldb_modify_test_teardown),
4139 cmocka_unit_test_setup_teardown(test_ldb_modify_replace_zero_vals,
4140 ldb_modify_test_setup,
4141 ldb_modify_test_teardown),
4142 cmocka_unit_test_setup_teardown(test_ldb_modify_replace_noexist_key_zero_vals,
4143 ldb_modify_test_setup,
4144 ldb_modify_test_teardown),
4145 cmocka_unit_test_setup_teardown(test_ldb_modify_del_key,
4146 ldb_modify_test_setup,
4147 ldb_modify_test_teardown),
4148 cmocka_unit_test_setup_teardown(test_ldb_modify_del_keyval,
4149 ldb_modify_test_setup,
4150 ldb_modify_test_teardown),
4151 cmocka_unit_test_setup_teardown(test_search_match_none,
4152 ldb_search_test_setup,
4153 ldb_search_test_teardown),
4154 cmocka_unit_test_setup_teardown(test_search_match_one,
4155 ldb_search_test_setup,
4156 ldb_search_test_teardown),
4157 cmocka_unit_test_setup_teardown(test_search_match_filter,
4158 ldb_search_test_setup,
4159 ldb_search_test_teardown),
4160 cmocka_unit_test_setup_teardown(test_search_match_both,
4161 ldb_search_test_setup,
4162 ldb_search_test_teardown),
4163 cmocka_unit_test_setup_teardown(test_search_match_basedn,
4164 ldb_search_test_setup,
4165 ldb_search_test_teardown),
4166 cmocka_unit_test_setup_teardown(test_ldb_search_against_transaction,
4167 ldb_search_test_setup,
4168 ldb_search_test_teardown),
4169 cmocka_unit_test_setup_teardown(test_ldb_modify_during_unindexed_search,
4170 ldb_search_test_setup,
4171 ldb_search_test_teardown),
4172 cmocka_unit_test_setup_teardown(test_ldb_modify_during_indexed_search,
4173 ldb_search_test_setup,
4174 ldb_search_test_teardown),
4175 cmocka_unit_test_setup_teardown(test_ldb_rename_during_unindexed_search,
4176 ldb_search_test_setup,
4177 ldb_search_test_teardown),
4178 cmocka_unit_test_setup_teardown(test_ldb_rename_during_indexed_search,
4179 ldb_search_test_setup,
4180 ldb_search_test_teardown),
4181 cmocka_unit_test_setup_teardown(test_ldb_modify_during_whole_search,
4182 ldb_search_test_setup,
4183 ldb_search_test_teardown),
4184 cmocka_unit_test_setup_teardown(test_ldb_modify_before_ldb_wait,
4185 ldb_search_test_setup,
4186 ldb_search_test_teardown),
4187 cmocka_unit_test_setup_teardown(test_ldb_attrs_case_insensitive,
4188 ldb_case_test_setup,
4189 ldb_case_test_teardown),
4190 cmocka_unit_test_setup_teardown(test_ldb_attrs_case_handler,
4191 ldb_case_test_setup,
4192 ldb_case_test_teardown),
4193 cmocka_unit_test_setup_teardown(test_ldb_attrs_index_handler,
4194 ldb_case_test_setup,
4195 ldb_case_attrs_index_test_teardown),
4196 cmocka_unit_test_setup_teardown(test_ldb_rename,
4197 ldb_rename_test_setup,
4198 ldb_rename_test_teardown),
4199 cmocka_unit_test_setup_teardown(test_ldb_rename_from_doesnt_exist,
4200 ldb_rename_test_setup,
4201 ldb_rename_test_teardown),
4202 cmocka_unit_test_setup_teardown(test_ldb_rename_to_exists,
4203 ldb_rename_test_setup,
4204 ldb_rename_test_teardown),
4205 cmocka_unit_test_setup_teardown(test_ldb_rename_self,
4206 ldb_rename_test_setup,
4207 ldb_rename_test_teardown),
4208 cmocka_unit_test_setup_teardown(test_ldb_rename_dn_case_change,
4209 ldb_rename_test_setup,
4210 ldb_rename_test_teardown),
4211 cmocka_unit_test_setup_teardown(test_read_only,
4212 ldb_read_only_setup,
4213 ldb_read_only_teardown),
4214 cmocka_unit_test_setup_teardown(
4215 test_ldb_add_unique_value_to_unique_index,
4216 ldb_unique_index_test_setup,
4217 ldb_unique_index_test_teardown),
4218 cmocka_unit_test_setup_teardown(
4219 test_ldb_add_duplicate_value_to_unique_index,
4220 ldb_unique_index_test_setup,
4221 ldb_unique_index_test_teardown),
4222 cmocka_unit_test_setup_teardown(
4223 test_ldb_add_to_index_duplicates_allowed,
4224 ldb_non_unique_index_test_setup,
4225 ldb_non_unique_index_test_teardown),
4226 cmocka_unit_test_setup_teardown(
4227 test_ldb_add_to_index_unique_values_required,
4228 ldb_non_unique_index_test_setup,
4229 ldb_non_unique_index_test_teardown),
4230 /* These tests are not compatible with mdb */
4231 cmocka_unit_test_setup_teardown(
4232 test_ldb_unique_index_duplicate_logging,
4233 ldb_unique_index_test_setup,
4234 ldb_unique_index_test_teardown),
4235 cmocka_unit_test_setup_teardown(
4236 test_ldb_duplicate_dn_logging,
4237 ldb_unique_index_test_setup,
4238 ldb_unique_index_test_teardown),
4239 cmocka_unit_test_setup_teardown(
4240 test_ldb_guid_index_duplicate_dn_logging,
4241 ldb_guid_index_test_setup,
4242 ldb_guid_index_test_teardown),
4243 cmocka_unit_test_setup_teardown(
4244 test_ldb_unique_index_duplicate_with_guid,
4245 ldb_guid_index_test_setup,
4246 ldb_guid_index_test_teardown),
4247 cmocka_unit_test_setup_teardown(
4248 test_ldb_talloc_destructor_transaction_cleanup,
4251 cmocka_unit_test_setup_teardown(
4252 test_transaction_start_across_fork,
4255 cmocka_unit_test_setup_teardown(
4256 test_transaction_commit_across_fork,
4259 cmocka_unit_test_setup_teardown(
4260 test_lock_read_across_fork,
4263 cmocka_unit_test_setup_teardown(
4264 test_multiple_opens_across_fork,
4269 return cmocka_run_group_tests(tests, NULL, NULL);