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;
207 ldbtest_noconn_setup((void **) &test_ctx);
209 ret = ldb_connect(test_ctx->ldb, test_ctx->dbpath, 0, NULL);
210 assert_int_equal(ret, 0);
216 static int ldbtest_teardown(void **state)
218 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
220 ldbtest_noconn_teardown((void **) &test_ctx);
224 static void test_ldb_add(void **state)
227 struct ldb_message *msg;
228 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
232 tmp_ctx = talloc_new(test_ctx);
233 assert_non_null(tmp_ctx);
235 msg = ldb_msg_new(tmp_ctx);
236 assert_non_null(msg);
238 msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "dc=test");
239 assert_non_null(msg->dn);
241 ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
242 assert_int_equal(ret, 0);
244 ret = ldb_add(test_ctx->ldb, msg);
245 assert_int_equal(ret, 0);
247 talloc_free(tmp_ctx);
250 static void test_ldb_search(void **state)
253 struct ldb_message *msg;
254 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
257 struct ldb_dn *basedn;
258 struct ldb_dn *basedn2;
259 struct ldb_result *result = NULL;
261 tmp_ctx = talloc_new(test_ctx);
262 assert_non_null(tmp_ctx);
264 basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "dc=test");
265 assert_non_null(basedn);
267 ret = ldb_search(test_ctx->ldb, tmp_ctx, &result, basedn,
268 LDB_SCOPE_BASE, NULL, NULL);
269 assert_int_equal(ret, 0);
270 assert_non_null(result);
271 assert_int_equal(result->count, 0);
273 msg = ldb_msg_new(tmp_ctx);
274 assert_non_null(msg);
277 assert_non_null(msg->dn);
279 ret = ldb_msg_add_string(msg, "cn", "test_cn_val1");
280 assert_int_equal(ret, 0);
282 ret = ldb_add(test_ctx->ldb, msg);
283 assert_int_equal(ret, 0);
285 basedn2 = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "dc=test2");
286 assert_non_null(basedn2);
288 msg = ldb_msg_new(tmp_ctx);
289 assert_non_null(msg);
292 assert_non_null(msg->dn);
294 ret = ldb_msg_add_string(msg, "cn", "test_cn_val2");
295 assert_int_equal(ret, 0);
297 ret = ldb_add(test_ctx->ldb, msg);
298 assert_int_equal(ret, 0);
300 ret = ldb_search(test_ctx->ldb, tmp_ctx, &result, basedn,
301 LDB_SCOPE_BASE, NULL, NULL);
302 assert_int_equal(ret, 0);
303 assert_non_null(result);
304 assert_int_equal(result->count, 1);
305 assert_string_equal(ldb_dn_get_linearized(result->msgs[0]->dn),
306 ldb_dn_get_linearized(basedn));
308 ret = ldb_search(test_ctx->ldb, tmp_ctx, &result, basedn2,
309 LDB_SCOPE_BASE, NULL, NULL);
310 assert_int_equal(ret, 0);
311 assert_non_null(result);
312 assert_int_equal(result->count, 1);
313 assert_string_equal(ldb_dn_get_linearized(result->msgs[0]->dn),
314 ldb_dn_get_linearized(basedn2));
316 talloc_free(tmp_ctx);
319 static int base_search_count(struct ldbtest_ctx *test_ctx, const char *entry_dn)
322 struct ldb_dn *basedn;
323 struct ldb_result *result = NULL;
327 tmp_ctx = talloc_new(test_ctx);
328 assert_non_null(tmp_ctx);
330 basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "%s", entry_dn);
331 assert_non_null(basedn);
333 ret = ldb_search(test_ctx->ldb, tmp_ctx, &result, basedn,
334 LDB_SCOPE_BASE, NULL, NULL);
335 assert_int_equal(ret, LDB_SUCCESS);
336 assert_non_null(result);
338 count = result->count;
339 talloc_free(tmp_ctx);
343 static int sub_search_count(struct ldbtest_ctx *test_ctx,
348 struct ldb_dn *basedn;
349 struct ldb_result *result = NULL;
353 tmp_ctx = talloc_new(test_ctx);
354 assert_non_null(tmp_ctx);
356 basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "%s", base_dn);
357 assert_non_null(basedn);
359 ret = ldb_search(test_ctx->ldb, tmp_ctx, &result, basedn,
360 LDB_SCOPE_SUBTREE, NULL, "%s", filter);
361 assert_int_equal(ret, LDB_SUCCESS);
362 assert_non_null(result);
364 count = result->count;
365 talloc_free(tmp_ctx);
369 /* In general it would be better if utility test functions didn't assert
370 * but only returned a value, then assert in the test shows correct
373 static void assert_dn_exists(struct ldbtest_ctx *test_ctx,
374 const char *entry_dn)
378 count = base_search_count(test_ctx, entry_dn);
379 assert_int_equal(count, 1);
382 static void assert_dn_doesnt_exist(struct ldbtest_ctx *test_ctx,
383 const char *entry_dn)
387 count = base_search_count(test_ctx, entry_dn);
388 assert_int_equal(count, 0);
391 static void add_dn_with_cn(struct ldbtest_ctx *test_ctx,
393 const char *cn_value)
397 struct ldb_message *msg;
399 tmp_ctx = talloc_new(test_ctx);
400 assert_non_null(tmp_ctx);
402 assert_dn_doesnt_exist(test_ctx,
403 ldb_dn_get_linearized(dn));
405 msg = ldb_msg_new(tmp_ctx);
406 assert_non_null(msg);
409 ret = ldb_msg_add_string(msg, "cn", cn_value);
410 assert_int_equal(ret, LDB_SUCCESS);
412 ret = ldb_add(test_ctx->ldb, msg);
413 assert_int_equal(ret, LDB_SUCCESS);
415 assert_dn_exists(test_ctx,
416 ldb_dn_get_linearized(dn));
417 talloc_free(tmp_ctx);
420 static void test_ldb_del(void **state)
423 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
425 const char *basedn = "dc=ldb_del_test";
428 dn = ldb_dn_new_fmt(test_ctx, test_ctx->ldb, "%s", basedn);
431 add_dn_with_cn(test_ctx, dn, "test_del_cn_val");
433 ret = ldb_delete(test_ctx->ldb, dn);
434 assert_int_equal(ret, LDB_SUCCESS);
436 assert_dn_doesnt_exist(test_ctx, basedn);
439 static void test_ldb_del_noexist(void **state)
441 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
443 struct ldb_dn *basedn;
446 basedn = ldb_dn_new(test_ctx, test_ctx->ldb, "dc=nosuchplace");
447 assert_non_null(basedn);
449 ret = ldb_delete(test_ctx->ldb, basedn);
450 assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT);
453 static void test_ldb_handle(void **state)
456 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
459 struct ldb_dn *basedn;
460 struct ldb_request *request = NULL;
461 struct ldb_request *request2 = NULL;
462 struct ldb_result *res = NULL;
463 const char *attrs[] = { "cn", NULL };
465 tmp_ctx = talloc_new(test_ctx);
466 assert_non_null(tmp_ctx);
468 basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "dc=test");
469 assert_non_null(basedn);
471 res = talloc_zero(tmp_ctx, struct ldb_result);
472 assert_non_null(res);
474 ret = ldb_build_search_req(&request, test_ctx->ldb, tmp_ctx,
475 basedn, LDB_SCOPE_BASE,
476 NULL, attrs, NULL, res,
477 ldb_search_default_callback,
479 assert_int_equal(ret, 0);
481 /* We are against ldb_tdb, so expect private event contexts */
482 assert_ptr_not_equal(ldb_handle_get_event_context(request->handle),
483 ldb_get_event_context(test_ctx->ldb));
485 ret = ldb_build_search_req(&request2, test_ctx->ldb, tmp_ctx,
486 basedn, LDB_SCOPE_BASE,
487 NULL, attrs, NULL, res,
488 ldb_search_default_callback,
490 assert_int_equal(ret, 0);
492 /* Expect that same event context will be chained */
493 assert_ptr_equal(ldb_handle_get_event_context(request->handle),
494 ldb_handle_get_event_context(request2->handle));
496 /* Now force this to use the global context */
497 ldb_handle_use_global_event_context(request2->handle);
498 assert_ptr_equal(ldb_handle_get_event_context(request2->handle),
499 ldb_get_event_context(test_ctx->ldb));
501 talloc_free(tmp_ctx);
504 static void test_ldb_build_search_req(void **state)
507 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
510 struct ldb_dn *basedn;
511 struct ldb_request *request = NULL;
512 struct ldb_request *request2 = NULL;
513 struct ldb_result *res = NULL;
514 const char *attrs[] = { "cn", NULL };
516 tmp_ctx = talloc_new(test_ctx);
517 assert_non_null(tmp_ctx);
519 basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "dc=test");
520 assert_non_null(basedn);
522 res = talloc_zero(tmp_ctx, struct ldb_result);
523 assert_non_null(res);
525 ret = ldb_build_search_req(&request, test_ctx->ldb, tmp_ctx,
526 basedn, LDB_SCOPE_BASE,
527 NULL, attrs, NULL, res,
528 ldb_search_default_callback,
530 assert_int_equal(ret, 0);
532 assert_int_equal(request->operation, LDB_SEARCH);
533 assert_ptr_equal(request->op.search.base, basedn);
534 assert_int_equal(request->op.search.scope, LDB_SCOPE_BASE);
535 assert_non_null(request->op.search.tree);
536 assert_ptr_equal(request->op.search.attrs, attrs);
537 assert_ptr_equal(request->context, res);
538 assert_ptr_equal(request->callback, ldb_search_default_callback);
540 ret = ldb_build_search_req(&request2, test_ctx->ldb, tmp_ctx,
541 basedn, LDB_SCOPE_BASE,
542 NULL, attrs, NULL, res,
543 ldb_search_default_callback,
545 assert_int_equal(ret, 0);
546 assert_ptr_equal(request, request2->handle->parent);
547 assert_int_equal(request->starttime, request2->starttime);
548 assert_int_equal(request->timeout, request2->timeout);
550 talloc_free(tmp_ctx);
553 static void add_keyval(struct ldbtest_ctx *test_ctx,
558 struct ldb_message *msg;
560 msg = ldb_msg_new(test_ctx);
561 assert_non_null(msg);
563 msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "%s=%s", key, val);
564 assert_non_null(msg->dn);
566 ret = ldb_msg_add_string(msg, key, val);
567 assert_int_equal(ret, 0);
569 ret = ldb_add(test_ctx->ldb, msg);
570 assert_int_equal(ret, 0);
575 static struct ldb_result *get_keyval(struct ldbtest_ctx *test_ctx,
580 struct ldb_result *result;
581 struct ldb_dn *basedn;
583 basedn = ldb_dn_new_fmt(test_ctx, test_ctx->ldb, "%s=%s", key, val);
584 assert_non_null(basedn);
586 ret = ldb_search(test_ctx->ldb, test_ctx, &result, basedn,
587 LDB_SCOPE_BASE, NULL, NULL);
588 assert_int_equal(ret, 0);
593 static void test_transactions(void **state)
596 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
598 struct ldb_result *res;
600 /* start lev-0 transaction */
601 ret = ldb_transaction_start(test_ctx->ldb);
602 assert_int_equal(ret, 0);
604 add_keyval(test_ctx, "vegetable", "carrot");
606 /* commit lev-0 transaction */
607 ret = ldb_transaction_commit(test_ctx->ldb);
608 assert_int_equal(ret, 0);
610 /* start another lev-1 nested transaction */
611 ret = ldb_transaction_start(test_ctx->ldb);
612 assert_int_equal(ret, 0);
614 add_keyval(test_ctx, "fruit", "apple");
616 /* abort lev-1 nested transaction */
617 ret = ldb_transaction_cancel(test_ctx->ldb);
618 assert_int_equal(ret, 0);
620 res = get_keyval(test_ctx, "vegetable", "carrot");
621 assert_non_null(res);
622 assert_int_equal(res->count, 1);
624 res = get_keyval(test_ctx, "fruit", "apple");
625 assert_non_null(res);
626 assert_int_equal(res->count, 0);
629 struct ldb_mod_test_ctx {
630 struct ldbtest_ctx *ldb_test_ctx;
631 const char *entry_dn;
639 static struct ldb_message *build_mod_msg(TALLOC_CTX *mem_ctx,
640 struct ldbtest_ctx *test_ctx,
645 struct ldb_message *msg;
649 msg = ldb_msg_new(mem_ctx);
650 assert_non_null(msg);
652 msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "%s", dn);
653 assert_non_null(msg->dn);
655 for (i = 0; kvs[i].key != NULL; i++) {
657 ret = ldb_msg_add_empty(msg, kvs[i].key,
659 assert_int_equal(ret, 0);
663 ret = ldb_msg_add_string(msg, kvs[i].key, kvs[i].val);
664 assert_int_equal(ret, LDB_SUCCESS);
671 static void ldb_test_add_data(TALLOC_CTX *mem_ctx,
672 struct ldbtest_ctx *ldb_test_ctx,
677 struct ldb_message *msg;
678 struct ldb_result *result = NULL;
681 tmp_ctx = talloc_new(mem_ctx);
682 assert_non_null(tmp_ctx);
684 msg = build_mod_msg(tmp_ctx, ldb_test_ctx,
686 assert_non_null(msg);
688 ret = ldb_add(ldb_test_ctx->ldb, msg);
689 assert_int_equal(ret, LDB_SUCCESS);
691 ret = ldb_search(ldb_test_ctx->ldb, tmp_ctx, &result, msg->dn,
692 LDB_SCOPE_BASE, NULL, NULL);
693 assert_int_equal(ret, LDB_SUCCESS);
694 assert_non_null(result);
695 assert_int_equal(result->count, 1);
696 assert_string_equal(ldb_dn_get_linearized(result->msgs[0]->dn),
697 ldb_dn_get_linearized(msg->dn));
699 talloc_free(tmp_ctx);
702 static void ldb_test_remove_data(TALLOC_CTX *mem_ctx,
703 struct ldbtest_ctx *ldb_test_ctx,
707 struct ldb_dn *basedn;
711 tmp_ctx = talloc_new(mem_ctx);
712 assert_non_null(tmp_ctx);
714 basedn = ldb_dn_new_fmt(tmp_ctx, ldb_test_ctx->ldb,
716 assert_non_null(basedn);
718 ret = ldb_delete(ldb_test_ctx->ldb, basedn);
719 assert_true(ret == LDB_SUCCESS || ret == LDB_ERR_NO_SUCH_OBJECT);
721 count = base_search_count(ldb_test_ctx, ldb_dn_get_linearized(basedn));
722 assert_int_equal(count, 0);
724 talloc_free(tmp_ctx);
727 static void mod_test_add_data(struct ldb_mod_test_ctx *mod_test_ctx,
730 ldb_test_add_data(mod_test_ctx,
731 mod_test_ctx->ldb_test_ctx,
732 mod_test_ctx->entry_dn,
736 static void mod_test_remove_data(struct ldb_mod_test_ctx *mod_test_ctx)
738 ldb_test_remove_data(mod_test_ctx,
739 mod_test_ctx->ldb_test_ctx,
740 mod_test_ctx->entry_dn);
743 static struct ldb_result *run_mod_test(struct ldb_mod_test_ctx *mod_test_ctx,
748 struct ldb_result *res;
749 struct ldb_message *mod_msg;
750 struct ldb_dn *basedn;
751 struct ldbtest_ctx *ldb_test_ctx;
754 ldb_test_ctx = mod_test_ctx->ldb_test_ctx;
756 tmp_ctx = talloc_new(mod_test_ctx);
757 assert_non_null(tmp_ctx);
759 mod_msg = build_mod_msg(tmp_ctx, ldb_test_ctx, mod_test_ctx->entry_dn,
761 assert_non_null(mod_msg);
763 ret = ldb_modify(ldb_test_ctx->ldb, mod_msg);
764 assert_int_equal(ret, LDB_SUCCESS);
766 basedn = ldb_dn_new_fmt(tmp_ctx, ldb_test_ctx->ldb,
767 "%s", mod_test_ctx->entry_dn);
768 assert_non_null(basedn);
770 ret = ldb_search(ldb_test_ctx->ldb, mod_test_ctx, &res, basedn,
771 LDB_SCOPE_BASE, NULL, NULL);
772 assert_int_equal(ret, LDB_SUCCESS);
773 assert_non_null(res);
774 assert_int_equal(res->count, 1);
775 assert_string_equal(ldb_dn_get_linearized(res->msgs[0]->dn),
776 ldb_dn_get_linearized(mod_msg->dn));
778 talloc_free(tmp_ctx);
782 static int ldb_modify_test_setup(void **state)
784 struct ldbtest_ctx *ldb_test_ctx;
785 struct ldb_mod_test_ctx *mod_test_ctx;
786 struct keyval kvs[] = {
787 { "cn", "test_mod_cn" },
791 ldbtest_setup((void **) &ldb_test_ctx);
793 mod_test_ctx = talloc(ldb_test_ctx, struct ldb_mod_test_ctx);
794 assert_non_null(mod_test_ctx);
796 mod_test_ctx->entry_dn = "dc=mod_test_entry";
797 mod_test_ctx->ldb_test_ctx = ldb_test_ctx;
799 mod_test_remove_data(mod_test_ctx);
800 mod_test_add_data(mod_test_ctx, kvs);
801 *state = mod_test_ctx;
805 static int ldb_modify_test_teardown(void **state)
807 struct ldb_mod_test_ctx *mod_test_ctx = \
808 talloc_get_type_abort(*state,
809 struct ldb_mod_test_ctx);
810 struct ldbtest_ctx *ldb_test_ctx;
812 ldb_test_ctx = mod_test_ctx->ldb_test_ctx;
814 mod_test_remove_data(mod_test_ctx);
815 talloc_free(mod_test_ctx);
817 ldbtest_teardown((void **) &ldb_test_ctx);
821 static void test_ldb_modify_add_key(void **state)
823 struct ldb_mod_test_ctx *mod_test_ctx = \
824 talloc_get_type_abort(*state,
825 struct ldb_mod_test_ctx);
826 struct keyval mod_kvs[] = {
827 { "name", "test_mod_name" },
830 struct ldb_result *res;
831 struct ldb_message_element *el;
833 res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_ADD, mod_kvs);
834 assert_non_null(res);
836 /* Check cn is intact and name was added */
837 assert_int_equal(res->count, 1);
838 el = ldb_msg_find_element(res->msgs[0], "cn");
840 assert_int_equal(el->num_values, 1);
841 assert_string_equal(el->values[0].data, "test_mod_cn");
843 el = ldb_msg_find_element(res->msgs[0], "name");
845 assert_int_equal(el->num_values, 1);
846 assert_string_equal(el->values[0].data, "test_mod_name");
849 static void test_ldb_modify_extend_key(void **state)
851 struct ldb_mod_test_ctx *mod_test_ctx = \
852 talloc_get_type_abort(*state,
853 struct ldb_mod_test_ctx);
854 struct keyval mod_kvs[] = {
855 { "cn", "test_mod_cn2" },
858 struct ldb_result *res;
859 struct ldb_message_element *el;
861 res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_ADD, mod_kvs);
862 assert_non_null(res);
864 /* Check cn was extended with another value */
865 assert_int_equal(res->count, 1);
866 el = ldb_msg_find_element(res->msgs[0], "cn");
868 assert_int_equal(el->num_values, 2);
869 assert_string_equal(el->values[0].data, "test_mod_cn");
870 assert_string_equal(el->values[1].data, "test_mod_cn2");
873 static void test_ldb_modify_add_key_noval(void **state)
875 struct ldb_mod_test_ctx *mod_test_ctx = \
876 talloc_get_type_abort(*state,
877 struct ldb_mod_test_ctx);
878 struct ldb_message *mod_msg;
879 struct ldbtest_ctx *ldb_test_ctx;
880 struct ldb_message_element *el;
883 ldb_test_ctx = mod_test_ctx->ldb_test_ctx;
885 mod_msg = ldb_msg_new(mod_test_ctx);
886 assert_non_null(mod_msg);
888 mod_msg->dn = ldb_dn_new_fmt(mod_msg, ldb_test_ctx->ldb,
889 "%s", mod_test_ctx->entry_dn);
890 assert_non_null(mod_msg->dn);
892 el = talloc_zero(mod_msg, struct ldb_message_element);
893 el->flags = LDB_FLAG_MOD_ADD;
895 el->name = talloc_strdup(el, "cn");
896 assert_non_null(el->name);
898 mod_msg->elements = el;
899 mod_msg->num_elements = 1;
901 ret = ldb_modify(ldb_test_ctx->ldb, mod_msg);
902 assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION);
905 static void test_ldb_modify_replace_key(void **state)
907 struct ldb_mod_test_ctx *mod_test_ctx = \
908 talloc_get_type_abort(*state,
909 struct ldb_mod_test_ctx);
910 const char *new_cn = "new_cn";
911 struct keyval mod_kvs[] = {
915 struct ldb_result *res;
916 struct ldb_message_element *el;
918 res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, mod_kvs);
919 assert_non_null(res);
921 /* Check cn was replaced */
922 assert_int_equal(res->count, 1);
923 el = ldb_msg_find_element(res->msgs[0], "cn");
925 assert_int_equal(el->num_values, 1);
926 assert_string_equal(el->values[0].data, new_cn);
929 static void test_ldb_modify_replace_noexist_key(void **state)
931 struct ldb_mod_test_ctx *mod_test_ctx = \
932 talloc_get_type_abort(*state,
933 struct ldb_mod_test_ctx);
934 struct keyval mod_kvs[] = {
935 { "name", "name_val" },
938 struct ldb_result *res;
939 struct ldb_message_element *el;
941 res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, mod_kvs);
942 assert_non_null(res);
944 /* Check cn is intact and name was added */
945 assert_int_equal(res->count, 1);
946 el = ldb_msg_find_element(res->msgs[0], "cn");
948 assert_int_equal(el->num_values, 1);
949 assert_string_equal(el->values[0].data, "test_mod_cn");
951 el = ldb_msg_find_element(res->msgs[0], mod_kvs[0].key);
953 assert_int_equal(el->num_values, 1);
954 assert_string_equal(el->values[0].data, mod_kvs[0].val);
957 static void test_ldb_modify_replace_zero_vals(void **state)
959 struct ldb_mod_test_ctx *mod_test_ctx = \
960 talloc_get_type_abort(*state,
961 struct ldb_mod_test_ctx);
962 struct ldb_message_element *el;
963 struct ldb_result *res;
964 struct keyval kvs[] = {
969 /* cn must be gone */
970 res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, kvs);
971 assert_non_null(res);
972 el = ldb_msg_find_element(res->msgs[0], "cn");
976 static void test_ldb_modify_replace_noexist_key_zero_vals(void **state)
978 struct ldb_mod_test_ctx *mod_test_ctx = \
979 talloc_get_type_abort(*state,
980 struct ldb_mod_test_ctx);
981 struct ldb_message_element *el;
982 struct ldb_result *res;
983 struct keyval kvs[] = {
984 { "noexist_key", NULL },
988 /* cn must be gone */
989 res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, kvs);
990 assert_non_null(res);
992 /* cn should be intact */
993 el = ldb_msg_find_element(res->msgs[0], "cn");
997 static void test_ldb_modify_del_key(void **state)
999 struct ldb_mod_test_ctx *mod_test_ctx = \
1000 talloc_get_type_abort(*state,
1001 struct ldb_mod_test_ctx);
1002 struct ldb_message_element *el;
1003 struct ldb_result *res;
1004 struct keyval kvs[] = {
1009 /* cn must be gone */
1010 res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_DELETE, kvs);
1011 assert_non_null(res);
1013 el = ldb_msg_find_element(res->msgs[0], "cn");
1017 static void test_ldb_modify_del_keyval(void **state)
1019 struct ldb_mod_test_ctx *mod_test_ctx = \
1020 talloc_get_type_abort(*state,
1021 struct ldb_mod_test_ctx);
1022 struct ldb_message_element *el;
1023 struct ldb_result *res;
1024 struct keyval kvs[] = {
1025 { "cn", "test_mod_cn" },
1029 /* cn must be gone */
1030 res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_DELETE, kvs);
1031 assert_non_null(res);
1033 el = ldb_msg_find_element(res->msgs[0], "cn");
1037 struct search_test_ctx {
1038 struct ldbtest_ctx *ldb_test_ctx;
1039 const char *base_dn;
1042 static char *get_full_dn(TALLOC_CTX *mem_ctx,
1043 struct search_test_ctx *search_test_ctx,
1048 full_dn = talloc_asprintf(mem_ctx,
1049 "%s,%s", rdn, search_test_ctx->base_dn);
1050 assert_non_null(full_dn);
1055 static void search_test_add_data(struct search_test_ctx *search_test_ctx,
1061 full_dn = get_full_dn(search_test_ctx, search_test_ctx, rdn);
1063 ldb_test_add_data(search_test_ctx,
1064 search_test_ctx->ldb_test_ctx,
1069 static void search_test_remove_data(struct search_test_ctx *search_test_ctx,
1074 full_dn = talloc_asprintf(search_test_ctx,
1075 "%s,%s", rdn, search_test_ctx->base_dn);
1076 assert_non_null(full_dn);
1078 ldb_test_remove_data(search_test_ctx,
1079 search_test_ctx->ldb_test_ctx,
1083 static int ldb_search_test_setup(void **state)
1085 struct ldbtest_ctx *ldb_test_ctx;
1086 struct search_test_ctx *search_test_ctx;
1087 struct keyval kvs[] = {
1088 { "cn", "test_search_cn" },
1089 { "cn", "test_search_cn2" },
1090 { "uid", "test_search_uid" },
1091 { "uid", "test_search_uid2" },
1094 struct keyval kvs2[] = {
1095 { "cn", "test_search_2_cn" },
1096 { "cn", "test_search_2_cn2" },
1097 { "uid", "test_search_2_uid" },
1098 { "uid", "test_search_2_uid2" },
1102 ldbtest_setup((void **) &ldb_test_ctx);
1104 search_test_ctx = talloc(ldb_test_ctx, struct search_test_ctx);
1105 assert_non_null(search_test_ctx);
1107 search_test_ctx->base_dn = "dc=search_test_entry";
1108 search_test_ctx->ldb_test_ctx = ldb_test_ctx;
1110 search_test_remove_data(search_test_ctx, "cn=test_search_cn");
1111 search_test_add_data(search_test_ctx, "cn=test_search_cn", kvs);
1113 search_test_remove_data(search_test_ctx, "cn=test_search_2_cn");
1114 search_test_add_data(search_test_ctx, "cn=test_search_2_cn", kvs2);
1116 *state = search_test_ctx;
1120 static int ldb_search_test_teardown(void **state)
1122 struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1123 struct search_test_ctx);
1124 struct ldbtest_ctx *ldb_test_ctx;
1126 ldb_test_ctx = search_test_ctx->ldb_test_ctx;
1128 search_test_remove_data(search_test_ctx, "cn=test_search_cn");
1129 search_test_remove_data(search_test_ctx, "cn=test_search_2_cn");
1130 ldbtest_teardown((void **) &ldb_test_ctx);
1134 static void assert_attr_has_vals(struct ldb_message *msg,
1139 struct ldb_message_element *el;
1142 el = ldb_msg_find_element(msg, attr);
1143 assert_non_null(el);
1145 assert_int_equal(el->num_values, nvals);
1146 for (i = 0; i < nvals; i++) {
1147 assert_string_equal(el->values[i].data,
1152 static void assert_has_no_attr(struct ldb_message *msg,
1155 struct ldb_message_element *el;
1157 el = ldb_msg_find_element(msg, attr);
1161 static bool has_dn(struct ldb_message *msg, const char *dn)
1165 msgdn = ldb_dn_get_linearized(msg->dn);
1166 if (strcmp(dn, msgdn) == 0) {
1173 static void test_search_match_none(void **state)
1175 struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1176 struct search_test_ctx);
1179 count = base_search_count(search_test_ctx->ldb_test_ctx,
1180 "dc=no_such_entry");
1181 assert_int_equal(count, 0);
1184 static void test_search_match_one(void **state)
1186 struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1187 struct search_test_ctx);
1189 struct ldb_dn *basedn;
1190 struct ldb_result *result = NULL;
1191 const char *cn_vals[] = { "test_search_cn",
1192 "test_search_cn2" };
1193 const char *uid_vals[] = { "test_search_uid",
1194 "test_search_uid2" };
1196 basedn = ldb_dn_new_fmt(search_test_ctx,
1197 search_test_ctx->ldb_test_ctx->ldb,
1199 search_test_ctx->base_dn);
1200 assert_non_null(basedn);
1202 ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
1206 LDB_SCOPE_SUBTREE, NULL,
1207 "cn=test_search_cn");
1208 assert_int_equal(ret, 0);
1209 assert_non_null(result);
1210 assert_int_equal(result->count, 1);
1212 assert_attr_has_vals(result->msgs[0], "cn", cn_vals, 2);
1213 assert_attr_has_vals(result->msgs[0], "uid", uid_vals, 2);
1216 static void test_search_match_filter(void **state)
1218 struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1219 struct search_test_ctx);
1221 struct ldb_dn *basedn;
1222 struct ldb_result *result = NULL;
1223 const char *cn_vals[] = { "test_search_cn",
1224 "test_search_cn2" };
1225 const char *attrs[] = { "cn", NULL };
1227 basedn = ldb_dn_new_fmt(search_test_ctx,
1228 search_test_ctx->ldb_test_ctx->ldb,
1230 search_test_ctx->base_dn);
1231 assert_non_null(basedn);
1233 ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
1239 "cn=test_search_cn");
1240 assert_int_equal(ret, 0);
1241 assert_non_null(result);
1242 assert_int_equal(result->count, 1);
1244 assert_attr_has_vals(result->msgs[0], "cn", cn_vals, 2);
1245 assert_has_no_attr(result->msgs[0], "uid");
1248 static void assert_expected(struct search_test_ctx *search_test_ctx,
1249 struct ldb_message *msg)
1253 const char *cn_vals[] = { "test_search_cn",
1254 "test_search_cn2" };
1255 const char *uid_vals[] = { "test_search_uid",
1256 "test_search_uid2" };
1257 const char *cn2_vals[] = { "test_search_2_cn",
1258 "test_search_2_cn2" };
1259 const char *uid2_vals[] = { "test_search_2_uid",
1260 "test_search_2_uid2" };
1262 full_dn1 = get_full_dn(search_test_ctx,
1264 "cn=test_search_cn");
1266 full_dn2 = get_full_dn(search_test_ctx,
1268 "cn=test_search_2_cn");
1270 if (has_dn(msg, full_dn1) == true) {
1271 assert_attr_has_vals(msg, "cn", cn_vals, 2);
1272 assert_attr_has_vals(msg, "uid", uid_vals, 2);
1273 } else if (has_dn(msg, full_dn2) == true) {
1274 assert_attr_has_vals(msg, "cn", cn2_vals, 2);
1275 assert_attr_has_vals(msg, "uid", uid2_vals, 2);
1281 static void test_search_match_both(void **state)
1283 struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1284 struct search_test_ctx);
1286 struct ldb_dn *basedn;
1287 struct ldb_result *result = NULL;
1289 basedn = ldb_dn_new_fmt(search_test_ctx,
1290 search_test_ctx->ldb_test_ctx->ldb,
1292 search_test_ctx->base_dn);
1293 assert_non_null(basedn);
1295 ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
1299 LDB_SCOPE_SUBTREE, NULL,
1300 "cn=test_search_*");
1301 assert_int_equal(ret, 0);
1302 assert_non_null(result);
1303 assert_int_equal(result->count, 2);
1305 assert_expected(search_test_ctx, result->msgs[0]);
1306 assert_expected(search_test_ctx, result->msgs[1]);
1309 static void test_search_match_basedn(void **state)
1311 struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1312 struct search_test_ctx);
1314 struct ldb_dn *basedn;
1315 struct ldb_result *result = NULL;
1316 struct ldb_message *msg;
1318 basedn = ldb_dn_new_fmt(search_test_ctx,
1319 search_test_ctx->ldb_test_ctx->ldb,
1321 assert_non_null(basedn);
1323 ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
1327 LDB_SCOPE_SUBTREE, NULL,
1329 assert_int_equal(ret, 0);
1331 /* Add 'checkBaseOnSearch' to @OPTIONS */
1332 msg = ldb_msg_new(search_test_ctx);
1333 assert_non_null(msg);
1335 msg->dn = ldb_dn_new_fmt(msg,
1336 search_test_ctx->ldb_test_ctx->ldb,
1338 assert_non_null(msg->dn);
1340 ret = ldb_msg_add_string(msg, "checkBaseOnSearch", "TRUE");
1341 assert_int_equal(ret, 0);
1343 ret = ldb_add(search_test_ctx->ldb_test_ctx->ldb, msg);
1344 assert_int_equal(ret, 0);
1347 /* The search should return LDB_ERR_NO_SUCH_OBJECT */
1348 ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
1352 LDB_SCOPE_SUBTREE, NULL,
1354 assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT);
1356 ret = ldb_delete(search_test_ctx->ldb_test_ctx->ldb, msg->dn);
1357 assert_int_equal(ret, 0);
1362 * This test is complex.
1363 * The purpose is to test for a deadlock detected between ldb_search()
1364 * and ldb_transaction_commit(). The deadlock happens if in process
1366 * - (1) the all-record lock is taken in ltdb_search()
1367 * - (2) the ldb_transaction_start() call is made
1368 * - (1) an un-indexed search starts (forced here by doing it in
1370 * - (2) the ldb_transaction_commit() is called.
1371 * This returns LDB_ERR_BUSY if the deadlock is detected
1373 * With ldb 1.1.31 and tdb 1.3.12 we avoid this only due to a missing
1374 * lock call in ltdb_search() due to a refcounting bug in
1378 struct search_against_transaction_ctx {
1379 struct ldbtest_ctx *test_ctx;
1382 struct ldb_dn *basedn;
1385 static int test_ldb_search_against_transaction_callback2(struct ldb_request *req,
1386 struct ldb_reply *ares)
1388 struct search_against_transaction_ctx *ctx = req->context;
1389 switch (ares->type) {
1390 case LDB_REPLY_ENTRY:
1392 if (ctx->res_count != 1) {
1398 case LDB_REPLY_REFERRAL:
1401 case LDB_REPLY_DONE:
1402 return ldb_request_done(req, LDB_SUCCESS);
1410 * This purpose of this callback is to trigger a transaction in
1411 * the child process while the all-record lock is held, but before
1412 * we take any locks in the tdb_traverse_read() handler.
1414 * In tdb 1.3.12 tdb_traverse_read() take the read transaction lock
1415 * however in ldb 1.1.31 ltdb_search() forgets to take the all-record
1416 * lock (except the very first time) due to a ref-counting bug.
1420 static int test_ldb_search_against_transaction_callback1(struct ldb_request *req,
1421 struct ldb_reply *ares)
1426 struct search_against_transaction_ctx *ctx = req->context;
1427 switch (ares->type) {
1428 case LDB_REPLY_ENTRY:
1431 case LDB_REPLY_REFERRAL:
1434 case LDB_REPLY_DONE:
1435 return ldb_request_done(req, LDB_SUCCESS);
1439 assert_int_equal(ret, 0);
1441 ctx->child_pid = fork();
1442 if (ctx->child_pid == 0) {
1443 TALLOC_CTX *tmp_ctx = NULL;
1444 struct ldb_message *msg;
1445 TALLOC_FREE(ctx->test_ctx->ldb);
1446 TALLOC_FREE(ctx->test_ctx->ev);
1447 ctx->test_ctx->ev = tevent_context_init(ctx->test_ctx);
1448 if (ctx->test_ctx->ev == NULL) {
1449 exit(LDB_ERR_OPERATIONS_ERROR);
1452 ctx->test_ctx->ldb = ldb_init(ctx->test_ctx,
1454 if (ctx->test_ctx->ldb == NULL) {
1455 exit(LDB_ERR_OPERATIONS_ERROR);
1458 ret = ldb_connect(ctx->test_ctx->ldb,
1459 ctx->test_ctx->dbpath, 0, NULL);
1460 if (ret != LDB_SUCCESS) {
1464 tmp_ctx = talloc_new(ctx->test_ctx);
1465 if (tmp_ctx == NULL) {
1466 exit(LDB_ERR_OPERATIONS_ERROR);
1469 msg = ldb_msg_new(tmp_ctx);
1471 exit(LDB_ERR_OPERATIONS_ERROR);
1474 msg->dn = ldb_dn_new_fmt(msg, ctx->test_ctx->ldb,
1476 if (msg->dn == NULL) {
1477 exit(LDB_ERR_OPERATIONS_ERROR);
1480 ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
1482 exit(LDB_ERR_OPERATIONS_ERROR);
1485 ret = ldb_transaction_start(ctx->test_ctx->ldb);
1490 ret = write(pipes[1], "GO", 2);
1492 exit(LDB_ERR_OPERATIONS_ERROR);
1495 ret = ldb_add(ctx->test_ctx->ldb, msg);
1500 ret = ldb_transaction_commit(ctx->test_ctx->ldb);
1504 ret = read(pipes[0], buf, 2);
1505 assert_int_equal(ret, 2);
1507 /* This search must be unindexed (ie traverse in tdb) */
1508 ret = ldb_build_search_req(&req,
1516 test_ldb_search_against_transaction_callback2,
1519 * we don't assert on these return codes until after the search is
1520 * finished, or the clean up will fail because we hold locks.
1523 ret2 = ldb_request(ctx->test_ctx->ldb, req);
1525 if (ret2 == LDB_SUCCESS) {
1526 ret2 = ldb_wait(req->handle, LDB_WAIT_ALL);
1528 assert_int_equal(ret, 0);
1529 assert_int_equal(ret2, 0);
1530 assert_int_equal(ctx->res_count, 2);
1535 static void test_ldb_search_against_transaction(void **state)
1537 struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1538 struct search_test_ctx);
1539 struct search_against_transaction_ctx
1542 .test_ctx = search_test_ctx->ldb_test_ctx
1546 struct ldb_request *req;
1549 struct ldb_dn *base_search_dn;
1551 tevent_loop_allow_nesting(search_test_ctx->ldb_test_ctx->ev);
1554 = ldb_dn_new_fmt(search_test_ctx,
1555 search_test_ctx->ldb_test_ctx->ldb,
1556 "cn=test_search_cn,%s",
1557 search_test_ctx->base_dn);
1558 assert_non_null(base_search_dn);
1561 = ldb_dn_new_fmt(search_test_ctx,
1562 search_test_ctx->ldb_test_ctx->ldb,
1564 search_test_ctx->base_dn);
1565 assert_non_null(ctx.basedn);
1568 /* This search must be indexed (ie no traverse in tdb) */
1569 ret = ldb_build_search_req(&req,
1570 search_test_ctx->ldb_test_ctx->ldb,
1577 test_ldb_search_against_transaction_callback1,
1579 assert_int_equal(ret, 0);
1580 ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req);
1582 if (ret == LDB_SUCCESS) {
1583 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1585 assert_int_equal(ret, 0);
1586 assert_int_equal(ctx.res_count, 2);
1588 pid = waitpid(ctx.child_pid, &wstatus, 0);
1589 assert_int_equal(pid, ctx.child_pid);
1591 assert_true(WIFEXITED(wstatus));
1593 assert_int_equal(WEXITSTATUS(wstatus), 0);
1599 * This test is also complex.
1600 * The purpose is to test if a modify can occur during an ldb_search()
1601 * This would be a failure if if in process
1603 * - (1) ltdb_search() starts and calls back for one entry
1604 * - (2) one of the entries to be matched is modified
1605 * - (1) the indexed search tries to return the modified entry, but
1606 * it is no longer found, either:
1607 * - despite it still matching (dn changed)
1608 * - it no longer matching (attrs changed)
1610 * We also try un-indexed to show that the behaviour differs on this
1611 * point, which it should not (an index should only impact search
1615 struct modify_during_search_test_ctx {
1616 struct ldbtest_ctx *test_ctx;
1619 struct ldb_dn *basedn;
1626 * This purpose of this callback is to trigger a write in
1627 * the child process while a search is in progress.
1629 * In tdb 1.3.12 tdb_traverse_read() take the read transaction lock
1630 * however in ldb 1.1.31 ltdb_search() forgets to take the all-record
1631 * lock (except the very first time) due to a ref-counting bug.
1633 * We assume that if the write will proceed, it will proceed in a 3
1634 * second window after the function is called.
1637 static int test_ldb_modify_during_search_callback1(struct ldb_request *req,
1638 struct ldb_reply *ares)
1643 struct modify_during_search_test_ctx *ctx = req->context;
1644 switch (ares->type) {
1645 case LDB_REPLY_ENTRY:
1647 const struct ldb_val *cn_val
1648 = ldb_dn_get_component_val(ares->message->dn, 0);
1649 const char *cn = (char *)cn_val->data;
1651 if (strcmp(cn, "test_search_cn") == 0) {
1653 } else if (strcmp(cn, "test_search_2_cn") == 0) {
1654 ctx->got_2_cn = true;
1656 if (ctx->res_count == 2) {
1661 case LDB_REPLY_REFERRAL:
1664 case LDB_REPLY_DONE:
1665 return ldb_request_done(req, LDB_SUCCESS);
1669 assert_int_equal(ret, 0);
1671 ctx->child_pid = fork();
1672 if (ctx->child_pid == 0 && ctx->rename) {
1673 TALLOC_CTX *tmp_ctx = NULL;
1674 struct ldb_dn *dn, *new_dn;
1675 TALLOC_FREE(ctx->test_ctx->ldb);
1676 TALLOC_FREE(ctx->test_ctx->ev);
1677 ctx->test_ctx->ev = tevent_context_init(ctx->test_ctx);
1678 if (ctx->test_ctx->ev == NULL) {
1679 exit(LDB_ERR_OPERATIONS_ERROR);
1682 ctx->test_ctx->ldb = ldb_init(ctx->test_ctx,
1684 if (ctx->test_ctx->ldb == NULL) {
1685 exit(LDB_ERR_OPERATIONS_ERROR);
1688 ret = ldb_connect(ctx->test_ctx->ldb,
1689 ctx->test_ctx->dbpath, 0, NULL);
1690 if (ret != LDB_SUCCESS) {
1694 tmp_ctx = talloc_new(ctx->test_ctx);
1695 if (tmp_ctx == NULL) {
1696 exit(LDB_ERR_OPERATIONS_ERROR);
1700 /* Modify the other one */
1701 dn = ldb_dn_new_fmt(tmp_ctx, ctx->test_ctx->ldb,
1702 "cn=test_search_2_cn,"
1703 "dc=search_test_entry");
1705 dn = ldb_dn_new_fmt(tmp_ctx, ctx->test_ctx->ldb,
1706 "cn=test_search_cn,"
1707 "dc=search_test_entry");
1710 exit(LDB_ERR_OPERATIONS_ERROR);
1713 new_dn = ldb_dn_new_fmt(tmp_ctx, ctx->test_ctx->ldb,
1714 "cn=test_search_cn_renamed,"
1715 "dc=search_test_entry");
1716 if (new_dn == NULL) {
1717 exit(LDB_ERR_OPERATIONS_ERROR);
1720 ret = ldb_transaction_start(ctx->test_ctx->ldb);
1725 if (write(pipes[1], "GO", 2) != 2) {
1726 exit(LDB_ERR_OPERATIONS_ERROR);
1729 ret = ldb_rename(ctx->test_ctx->ldb, dn, new_dn);
1734 ret = ldb_transaction_commit(ctx->test_ctx->ldb);
1737 } else if (ctx->child_pid == 0) {
1738 TALLOC_CTX *tmp_ctx = NULL;
1739 struct ldb_message *msg;
1740 struct ldb_message_element *el;
1741 TALLOC_FREE(ctx->test_ctx->ldb);
1742 TALLOC_FREE(ctx->test_ctx->ev);
1743 ctx->test_ctx->ev = tevent_context_init(ctx->test_ctx);
1744 if (ctx->test_ctx->ev == NULL) {
1745 exit(LDB_ERR_OPERATIONS_ERROR);
1748 ctx->test_ctx->ldb = ldb_init(ctx->test_ctx,
1750 if (ctx->test_ctx->ldb == NULL) {
1751 exit(LDB_ERR_OPERATIONS_ERROR);
1754 ret = ldb_connect(ctx->test_ctx->ldb,
1755 ctx->test_ctx->dbpath, 0, NULL);
1756 if (ret != LDB_SUCCESS) {
1760 tmp_ctx = talloc_new(ctx->test_ctx);
1761 if (tmp_ctx == NULL) {
1762 exit(LDB_ERR_OPERATIONS_ERROR);
1765 msg = ldb_msg_new(tmp_ctx);
1767 exit(LDB_ERR_OPERATIONS_ERROR);
1771 /* Modify the other one */
1772 msg->dn = ldb_dn_new_fmt(msg, ctx->test_ctx->ldb,
1773 "cn=test_search_2_cn,"
1774 "dc=search_test_entry");
1776 msg->dn = ldb_dn_new_fmt(msg, ctx->test_ctx->ldb,
1777 "cn=test_search_cn,"
1778 "dc=search_test_entry");
1780 if (msg->dn == NULL) {
1781 exit(LDB_ERR_OPERATIONS_ERROR);
1784 ret = ldb_msg_add_string(msg, "filterAttr", "TRUE");
1786 exit(LDB_ERR_OPERATIONS_ERROR);
1788 el = ldb_msg_find_element(msg, "filterAttr");
1790 exit(LDB_ERR_OPERATIONS_ERROR);
1792 el->flags = LDB_FLAG_MOD_REPLACE;
1794 ret = ldb_transaction_start(ctx->test_ctx->ldb);
1799 if (write(pipes[1], "GO", 2) != 2) {
1800 exit(LDB_ERR_OPERATIONS_ERROR);
1803 ret = ldb_modify(ctx->test_ctx->ldb, msg);
1808 ret = ldb_transaction_commit(ctx->test_ctx->ldb);
1813 * With TDB 1.3.13 and before "tdb: Remove locking from tdb_traverse_read()"
1814 * we will hang here because the child process can not proceed to
1815 * sending the "GO" as it is blocked at ldb_transaction_start().
1818 ret = read(pipes[0], buf, 2);
1819 assert_int_equal(ret, 2);
1826 static void test_ldb_modify_during_search(void **state, bool add_index,
1829 struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1830 struct search_test_ctx);
1831 struct modify_during_search_test_ctx
1834 .test_ctx = search_test_ctx->ldb_test_ctx,
1839 struct ldb_request *req;
1844 struct ldb_message *msg;
1845 struct ldb_dn *indexlist = ldb_dn_new(search_test_ctx,
1846 search_test_ctx->ldb_test_ctx->ldb,
1848 assert_non_null(indexlist);
1850 msg = ldb_msg_new(search_test_ctx);
1851 assert_non_null(msg);
1853 msg->dn = indexlist;
1855 ret = ldb_msg_add_string(msg, "@IDXATTR", "cn");
1856 assert_int_equal(ret, LDB_SUCCESS);
1858 ret = ldb_add(search_test_ctx->ldb_test_ctx->ldb,
1861 assert_int_equal(ret, LDB_SUCCESS);
1864 tevent_loop_allow_nesting(search_test_ctx->ldb_test_ctx->ev);
1867 = ldb_dn_new_fmt(search_test_ctx,
1868 search_test_ctx->ldb_test_ctx->ldb,
1870 search_test_ctx->base_dn);
1871 assert_non_null(ctx.basedn);
1875 * This search must be over multiple items, and should include
1876 * the new name after a rename, to show that it would match
1877 * both before and after that modify
1879 ret = ldb_build_search_req(&req,
1880 search_test_ctx->ldb_test_ctx->ldb,
1884 "(&(!(filterAttr=*))"
1885 "(|(cn=test_search_cn_renamed)"
1886 "(cn=test_search_cn)"
1887 "(cn=test_search_2_cn)"
1892 test_ldb_modify_during_search_callback1,
1894 assert_int_equal(ret, 0);
1895 ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req);
1897 if (ret == LDB_SUCCESS) {
1898 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1900 assert_int_equal(ret, 0);
1901 assert_int_equal(ctx.res_count, 2);
1902 assert_int_equal(ctx.got_cn, true);
1903 assert_int_equal(ctx.got_2_cn, true);
1905 pid = waitpid(ctx.child_pid, &wstatus, 0);
1906 assert_int_equal(pid, ctx.child_pid);
1908 assert_true(WIFEXITED(wstatus));
1910 assert_int_equal(WEXITSTATUS(wstatus), 0);
1915 static void test_ldb_modify_during_indexed_search(void **state)
1917 return test_ldb_modify_during_search(state, true, false);
1920 static void test_ldb_modify_during_unindexed_search(void **state)
1922 return test_ldb_modify_during_search(state, false, false);
1925 static void test_ldb_rename_during_indexed_search(void **state)
1927 return test_ldb_modify_during_search(state, true, true);
1930 static void test_ldb_rename_during_unindexed_search(void **state)
1932 return test_ldb_modify_during_search(state, false, true);
1936 * This test is also complex.
1938 * The purpose is to test if a modify can occur during an ldb_search()
1939 * before the end of the callback
1941 * This would be a failure if if in process
1943 * - (1) ldb_search() starts and calls back for a number of entries
1944 * - (2) an entry in the DB is allowed to change before the callback returns
1945 * - (1) the callback can see the modification
1950 * This purpose of this callback is to trigger a write in
1951 * the child process while a search DONE callback is in progress.
1953 * In ldb 1.1.31 ldb_search() omitted to take a all-record
1954 * lock for the full duration of the search and callbacks
1956 * We assume that if the write will proceed, it will proceed in a 3
1957 * second window after the function is called.
1960 static int test_ldb_modify_during_whole_search_callback1(struct ldb_request *req,
1961 struct ldb_reply *ares)
1966 struct modify_during_search_test_ctx *ctx = req->context;
1967 struct ldb_dn *search_dn;
1968 struct ldb_result *res2;
1970 switch (ares->type) {
1971 case LDB_REPLY_ENTRY:
1972 case LDB_REPLY_REFERRAL:
1975 case LDB_REPLY_DONE:
1980 assert_int_equal(ret, 0);
1982 ctx->child_pid = fork();
1983 if (ctx->child_pid == 0) {
1984 TALLOC_CTX *tmp_ctx = NULL;
1985 struct ldb_message *msg;
1986 struct ldb_message_element *el;
1987 TALLOC_FREE(ctx->test_ctx->ldb);
1988 TALLOC_FREE(ctx->test_ctx->ev);
1989 ctx->test_ctx->ev = tevent_context_init(ctx->test_ctx);
1990 if (ctx->test_ctx->ev == NULL) {
1991 exit(LDB_ERR_OPERATIONS_ERROR);
1994 ctx->test_ctx->ldb = ldb_init(ctx->test_ctx,
1996 if (ctx->test_ctx->ldb == NULL) {
1997 exit(LDB_ERR_OPERATIONS_ERROR);
2000 ret = ldb_connect(ctx->test_ctx->ldb,
2001 ctx->test_ctx->dbpath, 0, NULL);
2002 if (ret != LDB_SUCCESS) {
2006 tmp_ctx = talloc_new(ctx->test_ctx);
2007 if (tmp_ctx == NULL) {
2008 exit(LDB_ERR_OPERATIONS_ERROR);
2011 msg = ldb_msg_new(tmp_ctx);
2013 exit(LDB_ERR_OPERATIONS_ERROR);
2016 msg->dn = ldb_dn_new_fmt(msg, ctx->test_ctx->ldb,
2017 "cn=test_search_cn,"
2018 "dc=search_test_entry");
2019 if (msg->dn == NULL) {
2020 exit(LDB_ERR_OPERATIONS_ERROR);
2023 ret = ldb_msg_add_string(msg, "filterAttr", "TRUE");
2025 exit(LDB_ERR_OPERATIONS_ERROR);
2027 el = ldb_msg_find_element(msg, "filterAttr");
2029 exit(LDB_ERR_OPERATIONS_ERROR);
2031 el->flags = LDB_FLAG_MOD_REPLACE;
2033 ret = ldb_transaction_start(ctx->test_ctx->ldb);
2038 if (write(pipes[1], "GO", 2) != 2) {
2039 exit(LDB_ERR_OPERATIONS_ERROR);
2042 ret = ldb_modify(ctx->test_ctx->ldb, msg);
2047 ret = ldb_transaction_commit(ctx->test_ctx->ldb);
2051 ret = read(pipes[0], buf, 2);
2052 assert_int_equal(ret, 2);
2057 * If writes are not blocked until after this function, we
2058 * will be able to successfully search for this modification
2062 search_dn = ldb_dn_new_fmt(ares, ctx->test_ctx->ldb,
2063 "cn=test_search_cn,"
2064 "dc=search_test_entry");
2066 ret = ldb_search(ctx->test_ctx->ldb, ares,
2067 &res2, search_dn, LDB_SCOPE_BASE, NULL,
2071 * We do this in an unusual order, because if we fail an assert before
2072 * ldb_request_done(), we will also fail to clean up as we hold locks.
2075 res_count = res2->count;
2076 ldb_request_done(req, LDB_SUCCESS);
2077 assert_int_equal(ret, 0);
2079 /* We should not have got the result */
2080 assert_int_equal(res_count, 0);
2085 static void test_ldb_modify_during_whole_search(void **state)
2087 struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
2088 struct search_test_ctx);
2089 struct modify_during_search_test_ctx
2092 .test_ctx = search_test_ctx->ldb_test_ctx,
2096 struct ldb_request *req;
2099 struct ldb_dn *search_dn;
2100 struct ldb_result *res2;
2102 tevent_loop_allow_nesting(search_test_ctx->ldb_test_ctx->ev);
2105 = ldb_dn_new_fmt(search_test_ctx,
2106 search_test_ctx->ldb_test_ctx->ldb,
2108 search_test_ctx->base_dn);
2109 assert_non_null(ctx.basedn);
2113 * The search just needs to call DONE, we don't care about the
2114 * contents of the search for this test
2116 ret = ldb_build_search_req(&req,
2117 search_test_ctx->ldb_test_ctx->ldb,
2121 "(&(!(filterAttr=*))"
2122 "(cn=test_search_cn))",
2126 test_ldb_modify_during_whole_search_callback1,
2128 assert_int_equal(ret, 0);
2129 ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req);
2131 if (ret == LDB_SUCCESS) {
2132 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
2134 assert_int_equal(ret, 0);
2136 pid = waitpid(ctx.child_pid, &wstatus, 0);
2137 assert_int_equal(pid, ctx.child_pid);
2139 assert_true(WIFEXITED(wstatus));
2141 assert_int_equal(WEXITSTATUS(wstatus), 0);
2144 * If writes are blocked until after the search function, we
2145 * will be able to successfully search for this modification
2149 search_dn = ldb_dn_new_fmt(search_test_ctx,
2150 search_test_ctx->ldb_test_ctx->ldb,
2151 "cn=test_search_cn,"
2152 "dc=search_test_entry");
2154 ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
2156 &res2, search_dn, LDB_SCOPE_BASE, NULL,
2158 assert_int_equal(ret, 0);
2160 /* We got the result */
2161 assert_int_equal(res2->count, 1);
2165 * This test is also complex.
2167 * The purpose is to test if a modify can occur during an ldb_search()
2168 * before the request is destroyed with TALLOC_FREE()
2170 * This would be a failure if in process
2172 * - (1) ldb_search() starts and waits
2173 * - (2) an entry in the DB is allowed to change before the ldb_wait() is called
2174 * - (1) the original process can see the modification before the TALLOC_FREE()
2175 * also we check that
2176 * - (1) the original process can see the modification after the TALLOC_FREE()
2181 * This purpose of this callback is to trigger a write in
2182 * the child process before the ldb_wait() is called
2184 * In ldb 1.1.31 ldb_search() omitted to take a all-record
2185 * lock for the full duration of the search and callbacks
2187 * We assume that if the write will proceed, it will proceed in a 3
2188 * second window after the function is called.
2191 static int test_ldb_modify_before_ldb_wait_callback1(struct ldb_request *req,
2192 struct ldb_reply *ares)
2194 switch (ares->type) {
2195 case LDB_REPLY_ENTRY:
2196 case LDB_REPLY_REFERRAL:
2199 case LDB_REPLY_DONE:
2203 return ldb_request_done(req, LDB_SUCCESS);
2206 static void test_ldb_modify_before_ldb_wait(void **state)
2208 struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
2209 struct search_test_ctx);
2211 struct ldb_request *req;
2214 struct ldb_dn *search_dn;
2215 struct ldb_dn *basedn;
2216 struct ldb_result *res2;
2222 search_dn = ldb_dn_new_fmt(search_test_ctx,
2223 search_test_ctx->ldb_test_ctx->ldb,
2224 "cn=test_search_cn,"
2225 "dc=search_test_entry");
2226 assert_non_null(search_dn);
2228 basedn = ldb_dn_new_fmt(search_test_ctx,
2229 search_test_ctx->ldb_test_ctx->ldb,
2231 search_test_ctx->base_dn);
2232 assert_non_null(basedn);
2235 * The search just needs to call DONE, we don't care about the
2236 * contents of the search for this test
2238 ret = ldb_build_search_req(&req,
2239 search_test_ctx->ldb_test_ctx->ldb,
2243 "(&(!(filterAttr=*))"
2244 "(cn=test_search_cn))",
2248 test_ldb_modify_before_ldb_wait_callback1,
2250 assert_int_equal(ret, 0);
2251 ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req);
2254 assert_int_equal(ret, 0);
2257 if (child_pid == 0) {
2258 TALLOC_CTX *tmp_ctx = NULL;
2259 struct ldb_message *msg;
2260 struct ldb_message_element *el;
2261 TALLOC_FREE(search_test_ctx->ldb_test_ctx->ldb);
2262 TALLOC_FREE(search_test_ctx->ldb_test_ctx->ev);
2263 search_test_ctx->ldb_test_ctx->ev = tevent_context_init(search_test_ctx->ldb_test_ctx);
2264 if (search_test_ctx->ldb_test_ctx->ev == NULL) {
2265 exit(LDB_ERR_OPERATIONS_ERROR);
2268 search_test_ctx->ldb_test_ctx->ldb = ldb_init(search_test_ctx->ldb_test_ctx,
2269 search_test_ctx->ldb_test_ctx->ev);
2270 if (search_test_ctx->ldb_test_ctx->ldb == NULL) {
2271 exit(LDB_ERR_OPERATIONS_ERROR);
2274 ret = ldb_connect(search_test_ctx->ldb_test_ctx->ldb,
2275 search_test_ctx->ldb_test_ctx->dbpath, 0, NULL);
2276 if (ret != LDB_SUCCESS) {
2280 tmp_ctx = talloc_new(search_test_ctx->ldb_test_ctx);
2281 if (tmp_ctx == NULL) {
2282 exit(LDB_ERR_OPERATIONS_ERROR);
2285 msg = ldb_msg_new(tmp_ctx);
2287 exit(LDB_ERR_OPERATIONS_ERROR);
2291 * We must re-create this DN from a string to ensure
2292 * it does not reference the now-gone LDB context of
2295 msg->dn = ldb_dn_new_fmt(search_test_ctx,
2296 search_test_ctx->ldb_test_ctx->ldb,
2297 "cn=test_search_cn,"
2298 "dc=search_test_entry");
2300 if (msg->dn == NULL) {
2301 exit(LDB_ERR_OPERATIONS_ERROR);
2304 ret = ldb_msg_add_string(msg, "filterAttr", "TRUE");
2306 exit(LDB_ERR_OPERATIONS_ERROR);
2308 el = ldb_msg_find_element(msg, "filterAttr");
2310 exit(LDB_ERR_OPERATIONS_ERROR);
2312 el->flags = LDB_FLAG_MOD_REPLACE;
2314 ret = ldb_transaction_start(search_test_ctx->ldb_test_ctx->ldb);
2319 if (write(pipes[1], "GO", 2) != 2) {
2320 exit(LDB_ERR_OPERATIONS_ERROR);
2323 ret = ldb_modify(search_test_ctx->ldb_test_ctx->ldb, msg);
2328 ret = ldb_transaction_commit(search_test_ctx->ldb_test_ctx->ldb);
2332 ret = read(pipes[0], buf, 2);
2333 assert_int_equal(ret, 2);
2338 * If writes are not blocked until after the (never called) ldb_wait(), we
2339 * will be able to successfully search for this modification
2343 ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb, search_test_ctx,
2344 &res2, search_dn, LDB_SCOPE_BASE, NULL,
2348 * We avoid making assertions before TALLOC_FREE()ing the request,
2349 * lest the assert fail and mess with the clean-up because we still
2352 res_count = res2->count;
2355 /* We should not have got the result */
2356 assert_int_equal(res_count, 0);
2357 assert_int_equal(ret, 0);
2359 pid = waitpid(child_pid, &wstatus, 0);
2360 assert_int_equal(pid, child_pid);
2362 assert_true(WIFEXITED(wstatus));
2364 assert_int_equal(WEXITSTATUS(wstatus), 0);
2367 * If writes are blocked until after the search request was freed, we
2368 * will be able to successfully search for this modification
2372 search_dn = ldb_dn_new_fmt(search_test_ctx,
2373 search_test_ctx->ldb_test_ctx->ldb,
2374 "cn=test_search_cn,"
2375 "dc=search_test_entry");
2377 ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
2379 &res2, search_dn, LDB_SCOPE_BASE, NULL,
2381 assert_int_equal(ret, 0);
2383 /* We got the result */
2384 assert_int_equal(res2->count, 1);
2387 static int ldb_case_test_setup(void **state)
2390 struct ldb_ldif *ldif;
2391 struct ldbtest_ctx *ldb_test_ctx;
2392 const char *attrs_ldif = \
2394 "cn: CASE_INSENSITIVE\n"
2396 struct keyval kvs[] = {
2397 { "cn", "CaseInsensitiveValue" },
2398 { "uid", "CaseSensitiveValue" },
2403 ldbtest_setup((void **) &ldb_test_ctx);
2405 while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &attrs_ldif))) {
2406 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
2407 assert_int_equal(ret, LDB_SUCCESS);
2410 ldb_test_add_data(ldb_test_ctx,
2412 "cn=CaseInsensitiveValue",
2415 *state = ldb_test_ctx;
2419 static int ldb_case_test_teardown(void **state)
2422 struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
2423 struct ldbtest_ctx);
2425 struct ldb_dn *del_dn;
2427 del_dn = ldb_dn_new_fmt(ldb_test_ctx,
2430 assert_non_null(del_dn);
2432 ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
2433 assert_int_equal(ret, LDB_SUCCESS);
2435 assert_dn_doesnt_exist(ldb_test_ctx,
2438 ldb_test_remove_data(ldb_test_ctx, ldb_test_ctx,
2439 "cn=CaseInsensitiveValue");
2441 ldbtest_teardown((void **) &ldb_test_ctx);
2445 static void test_ldb_attrs_case_insensitive(void **state)
2448 struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
2449 struct ldbtest_ctx);
2451 /* cn matches exact case */
2452 cnt = sub_search_count(ldb_test_ctx, "", "cn=CaseInsensitiveValue");
2453 assert_int_equal(cnt, 1);
2455 /* cn matches lower case */
2456 cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2457 assert_int_equal(cnt, 1);
2459 /* uid matches exact case */
2460 cnt = sub_search_count(ldb_test_ctx, "", "uid=CaseSensitiveValue");
2461 assert_int_equal(cnt, 1);
2463 /* uid does not match lower case */
2464 cnt = sub_search_count(ldb_test_ctx, "", "uid=casesensitivevalue");
2465 assert_int_equal(cnt, 0);
2468 static struct ldb_schema_attribute cn_attr_1;
2469 static struct ldb_schema_attribute cn_attr_2;
2470 static struct ldb_schema_attribute default_attr;
2473 override the name to attribute handler function
2475 static const struct ldb_schema_attribute *ldb_test_attribute_handler_override(struct ldb_context *ldb,
2479 if (private_data != NULL && ldb_attr_cmp(name, "cn") == 0) {
2481 } else if (private_data == NULL && ldb_attr_cmp(name, "cn") == 0) {
2483 } else if (ldb_attr_cmp(name, "uid") == 0) {
2486 return &default_attr;
2489 static void test_ldb_attrs_case_handler(void **state)
2493 const struct ldb_schema_syntax *syntax;
2495 struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
2496 struct ldbtest_ctx);
2497 struct ldb_context *ldb = ldb_test_ctx->ldb;
2499 /* cn matches lower case */
2500 cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2501 assert_int_equal(cnt, 1);
2503 syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_OCTET_STRING);
2504 assert_non_null(syntax);
2506 ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb,
2508 syntax, &default_attr);
2509 assert_int_equal(ret, LDB_SUCCESS);
2511 syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_OCTET_STRING);
2512 assert_non_null(syntax);
2514 ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb,
2516 syntax, &cn_attr_1);
2517 assert_int_equal(ret, LDB_SUCCESS);
2520 * Set an attribute handler, which will fail to match as we
2521 * force case sensitive
2523 ldb_schema_attribute_set_override_handler(ldb,
2524 ldb_test_attribute_handler_override,
2527 /* cn does not matche lower case */
2528 cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2529 assert_int_equal(cnt, 0);
2531 syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_DIRECTORY_STRING);
2532 assert_non_null(syntax);
2534 ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb,
2536 syntax, &cn_attr_2);
2537 assert_int_equal(ret, LDB_SUCCESS);
2540 * Set an attribute handler, which will match as we
2541 * force case insensitive
2543 ldb_schema_attribute_set_override_handler(ldb,
2544 ldb_test_attribute_handler_override,
2547 /* cn matches lower case */
2548 cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2549 assert_int_equal(cnt, 1);
2554 static void test_ldb_attrs_index_handler(void **state)
2558 const struct ldb_schema_syntax *syntax;
2559 struct ldb_ldif *ldif;
2561 const char *index_ldif = \
2566 struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
2567 struct ldbtest_ctx);
2568 struct ldb_context *ldb = ldb_test_ctx->ldb;
2570 /* cn matches lower case */
2571 cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2572 assert_int_equal(cnt, 1);
2574 syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_OCTET_STRING);
2575 assert_non_null(syntax);
2577 ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb,
2579 syntax, &cn_attr_1);
2580 assert_int_equal(ret, LDB_SUCCESS);
2582 syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_DIRECTORY_STRING);
2583 assert_non_null(syntax);
2585 ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb,
2586 "cn", LDB_ATTR_FLAG_INDEXED,
2587 syntax, &cn_attr_2);
2588 assert_int_equal(ret, LDB_SUCCESS);
2591 * Set an attribute handler
2593 ldb_schema_attribute_set_override_handler(ldb,
2594 ldb_test_attribute_handler_override,
2597 /* cn matches lower case */
2598 cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2599 assert_int_equal(cnt, 1);
2601 /* Add the index (actually any modify will do) */
2602 while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &index_ldif))) {
2603 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
2604 assert_int_equal(ret, LDB_SUCCESS);
2607 ldb_schema_set_override_indexlist(ldb, false);
2609 /* cn does match as there is an index now */
2610 cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2611 assert_int_equal(cnt, 1);
2614 * Set an attribute handler, which will later fail to match as we
2615 * didn't re-index the DB
2617 ldb_schema_attribute_set_override_handler(ldb,
2618 ldb_test_attribute_handler_override,
2622 * cn does not match as we changed the case sensitivity, but
2625 * This shows that the override is in control
2627 cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2628 assert_int_equal(cnt, 0);
2632 static int ldb_case_attrs_index_test_teardown(void **state)
2635 struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
2636 struct ldbtest_ctx);
2637 struct ldb_dn *del_dn;
2639 del_dn = ldb_dn_new_fmt(ldb_test_ctx,
2642 assert_non_null(del_dn);
2644 ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
2645 if (ret != LDB_ERR_NO_SUCH_OBJECT) {
2646 assert_int_equal(ret, LDB_SUCCESS);
2649 assert_dn_doesnt_exist(ldb_test_ctx,
2652 ldb_case_test_teardown(state);
2657 struct rename_test_ctx {
2658 struct ldbtest_ctx *ldb_test_ctx;
2660 struct ldb_dn *basedn;
2661 const char *str_basedn;
2663 const char *teardown_dn;
2666 static int ldb_rename_test_setup(void **state)
2668 struct ldbtest_ctx *ldb_test_ctx;
2669 struct rename_test_ctx *rename_test_ctx;
2670 const char *strdn = "dc=rename_test_entry_from";
2672 ldbtest_setup((void **) &ldb_test_ctx);
2674 rename_test_ctx = talloc(ldb_test_ctx, struct rename_test_ctx);
2675 assert_non_null(rename_test_ctx);
2676 rename_test_ctx->ldb_test_ctx = ldb_test_ctx;
2677 assert_non_null(rename_test_ctx->ldb_test_ctx);
2679 rename_test_ctx->basedn = ldb_dn_new_fmt(rename_test_ctx,
2680 rename_test_ctx->ldb_test_ctx->ldb,
2682 assert_non_null(rename_test_ctx->basedn);
2684 rename_test_ctx->str_basedn = strdn;
2685 rename_test_ctx->teardown_dn = strdn;
2687 add_dn_with_cn(ldb_test_ctx,
2688 rename_test_ctx->basedn,
2689 "test_rename_cn_val");
2691 *state = rename_test_ctx;
2695 static int ldb_rename_test_teardown(void **state)
2698 struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(*state,
2699 struct rename_test_ctx);
2700 struct ldbtest_ctx *ldb_test_ctx;
2701 struct ldb_dn *del_dn;
2703 ldb_test_ctx = rename_test_ctx->ldb_test_ctx;
2705 del_dn = ldb_dn_new_fmt(rename_test_ctx,
2706 rename_test_ctx->ldb_test_ctx->ldb,
2707 "%s", rename_test_ctx->teardown_dn);
2708 assert_non_null(del_dn);
2710 ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
2711 assert_int_equal(ret, LDB_SUCCESS);
2713 assert_dn_doesnt_exist(ldb_test_ctx,
2714 rename_test_ctx->teardown_dn);
2716 ldbtest_teardown((void **) &ldb_test_ctx);
2720 static void test_ldb_rename(void **state)
2722 struct rename_test_ctx *rename_test_ctx =
2723 talloc_get_type_abort(*state, struct rename_test_ctx);
2725 const char *str_new_dn = "dc=rename_test_entry_to";
2726 struct ldb_dn *new_dn;
2728 new_dn = ldb_dn_new_fmt(rename_test_ctx,
2729 rename_test_ctx->ldb_test_ctx->ldb,
2731 assert_non_null(new_dn);
2733 ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
2734 rename_test_ctx->basedn,
2736 assert_int_equal(ret, LDB_SUCCESS);
2738 assert_dn_exists(rename_test_ctx->ldb_test_ctx, str_new_dn);
2739 assert_dn_doesnt_exist(rename_test_ctx->ldb_test_ctx,
2740 rename_test_ctx->str_basedn);
2741 rename_test_ctx->teardown_dn = str_new_dn;
2743 /* FIXME - test the values which didn't change */
2746 static void test_ldb_rename_from_doesnt_exist(void **state)
2748 struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(
2750 struct rename_test_ctx);
2752 const char *str_new_dn = "dc=rename_test_entry_to";
2753 const char *str_bad_old_dn = "dc=rename_test_no_such_entry";
2754 struct ldb_dn *new_dn;
2755 struct ldb_dn *bad_old_dn;
2757 new_dn = ldb_dn_new_fmt(rename_test_ctx,
2758 rename_test_ctx->ldb_test_ctx->ldb,
2760 assert_non_null(new_dn);
2762 bad_old_dn = ldb_dn_new_fmt(rename_test_ctx,
2763 rename_test_ctx->ldb_test_ctx->ldb,
2764 "%s", str_bad_old_dn);
2765 assert_non_null(bad_old_dn);
2767 assert_dn_doesnt_exist(rename_test_ctx->ldb_test_ctx,
2770 ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
2771 bad_old_dn, new_dn);
2772 assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT);
2774 assert_dn_doesnt_exist(rename_test_ctx->ldb_test_ctx,
2778 static void test_ldb_rename_to_exists(void **state)
2780 struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(
2782 struct rename_test_ctx);
2784 const char *str_new_dn = "dc=rename_test_already_exists";
2785 struct ldb_dn *new_dn;
2787 new_dn = ldb_dn_new_fmt(rename_test_ctx,
2788 rename_test_ctx->ldb_test_ctx->ldb,
2790 assert_non_null(new_dn);
2792 add_dn_with_cn(rename_test_ctx->ldb_test_ctx,
2794 "test_rename_cn_val");
2796 ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
2797 rename_test_ctx->basedn,
2799 assert_int_equal(ret, LDB_ERR_ENTRY_ALREADY_EXISTS);
2801 /* Old object must still exist */
2802 assert_dn_exists(rename_test_ctx->ldb_test_ctx,
2803 rename_test_ctx->str_basedn);
2805 ret = ldb_delete(rename_test_ctx->ldb_test_ctx->ldb,
2807 assert_int_equal(ret, LDB_SUCCESS);
2809 assert_dn_exists(rename_test_ctx->ldb_test_ctx,
2810 rename_test_ctx->teardown_dn);
2813 static void test_ldb_rename_self(void **state)
2815 struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(
2817 struct rename_test_ctx);
2820 /* Oddly enough, this is a success in ldb.. */
2821 ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
2822 rename_test_ctx->basedn,
2823 rename_test_ctx->basedn);
2824 assert_int_equal(ret, LDB_SUCCESS);
2826 /* Old object must still exist */
2827 assert_dn_exists(rename_test_ctx->ldb_test_ctx,
2828 rename_test_ctx->str_basedn);
2831 static void test_ldb_rename_dn_case_change(void **state)
2833 struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(
2835 struct rename_test_ctx);
2838 struct ldb_dn *new_dn;
2841 str_new_dn = talloc_strdup(rename_test_ctx, rename_test_ctx->str_basedn);
2842 assert_non_null(str_new_dn);
2843 for (i = 0; str_new_dn[i]; i++) {
2844 str_new_dn[i] = toupper(str_new_dn[i]);
2847 new_dn = ldb_dn_new_fmt(rename_test_ctx,
2848 rename_test_ctx->ldb_test_ctx->ldb,
2850 assert_non_null(new_dn);
2852 ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
2853 rename_test_ctx->basedn,
2855 assert_int_equal(ret, LDB_SUCCESS);
2857 /* DNs are case insensitive, so both searches will match */
2858 assert_dn_exists(rename_test_ctx->ldb_test_ctx, str_new_dn);
2859 assert_dn_exists(rename_test_ctx->ldb_test_ctx,
2860 rename_test_ctx->str_basedn);
2861 /* FIXME - test the values didn't change */
2864 static int ldb_read_only_setup(void **state)
2866 struct ldbtest_ctx *test_ctx;
2868 ldbtest_setup((void **) &test_ctx);
2874 static int ldb_read_only_teardown(void **state)
2876 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
2877 struct ldbtest_ctx);
2878 ldbtest_teardown((void **) &test_ctx);
2882 static void test_read_only(void **state)
2884 struct ldb_context *ro_ldb = NULL;
2885 struct ldb_context *rw_ldb = NULL;
2887 TALLOC_CTX *tmp_ctx = NULL;
2889 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
2890 struct ldbtest_ctx);
2892 * Close the ldb context freeing it this will ensure it exists on
2893 * disk and can be opened in read only mode
2895 TALLOC_FREE(test_ctx->ldb);
2898 * Open the database in read only and read write mode,
2899 * ensure it's opend in read only mode first
2901 ro_ldb = ldb_init(test_ctx, test_ctx->ev);
2902 ret = ldb_connect(ro_ldb, test_ctx->dbpath, LDB_FLG_RDONLY, NULL);
2903 assert_int_equal(ret, 0);
2905 rw_ldb = ldb_init(test_ctx, test_ctx->ev);
2906 ret = ldb_connect(rw_ldb, test_ctx->dbpath, 0, NULL);
2907 assert_int_equal(ret, 0);
2911 * Set up a context for the temporary variables
2913 tmp_ctx = talloc_new(test_ctx);
2914 assert_non_null(tmp_ctx);
2917 * Ensure that we can search the read write database
2920 struct ldb_result *result = NULL;
2921 struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, rw_ldb,
2923 assert_non_null(dn);
2925 ret = ldb_search(rw_ldb, tmp_ctx, &result, dn,
2926 LDB_SCOPE_BASE, NULL, NULL);
2927 assert_int_equal(ret, LDB_SUCCESS);
2928 TALLOC_FREE(result);
2933 * Ensure that we can search the read only database
2936 struct ldb_result *result = NULL;
2937 struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, ro_ldb,
2939 assert_non_null(dn);
2941 ret = ldb_search(ro_ldb, tmp_ctx, &result, dn,
2942 LDB_SCOPE_BASE, NULL, NULL);
2943 assert_int_equal(ret, LDB_SUCCESS);
2944 TALLOC_FREE(result);
2948 * Ensure that a write to the read only database fails
2951 struct ldb_message *msg = NULL;
2952 msg = ldb_msg_new(tmp_ctx);
2953 assert_non_null(msg);
2955 msg->dn = ldb_dn_new_fmt(msg, ro_ldb, "dc=test");
2956 assert_non_null(msg->dn);
2958 ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
2959 assert_int_equal(ret, 0);
2961 ret = ldb_add(ro_ldb, msg);
2962 assert_int_equal(ret, LDB_ERR_UNWILLING_TO_PERFORM);
2967 * Ensure that a write to the read write database succeeds
2970 struct ldb_message *msg = NULL;
2971 msg = ldb_msg_new(tmp_ctx);
2972 assert_non_null(msg);
2974 msg->dn = ldb_dn_new_fmt(msg, ro_ldb, "dc=test");
2975 assert_non_null(msg->dn);
2977 ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
2978 assert_int_equal(ret, 0);
2980 ret = ldb_add(rw_ldb, msg);
2981 assert_int_equal(ret, LDB_SUCCESS);
2986 * Ensure that a delete from a read only database fails
2989 struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, ro_ldb, "dc=test");
2990 assert_non_null(dn);
2992 ret = ldb_delete(ro_ldb, dn);
2993 assert_int_equal(ret, LDB_ERR_UNWILLING_TO_PERFORM);
2999 * Ensure that a delete from a read write succeeds
3002 struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, rw_ldb, "dc=test");
3003 assert_non_null(dn);
3005 ret = ldb_delete(rw_ldb, dn);
3006 assert_int_equal(ret, LDB_SUCCESS);
3009 TALLOC_FREE(tmp_ctx);
3012 static bool unique_values = false;
3014 static int unique_index_test_module_add(
3015 struct ldb_module *module,
3016 struct ldb_request *req)
3018 if (unique_values) {
3019 struct ldb_message *msg = discard_const(req->op.add.message);
3020 struct ldb_message_element *el = NULL;
3021 el = ldb_msg_find_element(msg, "cn");
3023 el->flags |= LDB_FLAG_INTERNAL_FORCE_UNIQUE_INDEX;
3027 return ldb_next_request(module, req);
3030 static int unique_index_test_module_init(struct ldb_module *module)
3032 return ldb_next_init(module);
3035 static const struct ldb_module_ops ldb_unique_index_test_module_ops = {
3036 .name = "unique_index_test",
3037 .init_context = unique_index_test_module_init,
3038 .add = unique_index_test_module_add,
3041 static int ldb_unique_index_test_setup(void **state)
3044 struct ldb_ldif *ldif;
3045 struct ldbtest_ctx *ldb_test_ctx;
3046 const char *attrs_ldif = \
3048 "cn: UNIQUE_INDEX\n"
3050 const char *index_ldif = \
3054 const char *options[] = {"modules:unique_index_test"};
3057 ret = ldb_register_module(&ldb_unique_index_test_module_ops);
3058 assert_true(ret == LDB_SUCCESS || ret == LDB_ERR_ENTRY_ALREADY_EXISTS);
3059 ldbtest_noconn_setup((void **) &ldb_test_ctx);
3062 ret = ldb_connect(ldb_test_ctx->ldb, ldb_test_ctx->dbpath, 0, options);
3063 assert_int_equal(ret, 0);
3065 while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &attrs_ldif))) {
3066 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
3067 assert_int_equal(ret, LDB_SUCCESS);
3070 while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &index_ldif))) {
3071 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
3072 assert_int_equal(ret, LDB_SUCCESS);
3075 unique_values = true;
3077 *state = ldb_test_ctx;
3081 static int ldb_unique_index_test_teardown(void **state)
3084 struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
3085 struct ldbtest_ctx);
3086 struct ldb_dn *del_dn;
3088 del_dn = ldb_dn_new_fmt(ldb_test_ctx,
3091 assert_non_null(del_dn);
3093 ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
3094 if (ret != LDB_ERR_NO_SUCH_OBJECT) {
3095 assert_int_equal(ret, LDB_SUCCESS);
3098 assert_dn_doesnt_exist(ldb_test_ctx,
3101 TALLOC_FREE(del_dn);
3103 del_dn = ldb_dn_new_fmt(ldb_test_ctx,
3106 assert_non_null(del_dn);
3108 ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
3109 if (ret != LDB_ERR_NO_SUCH_OBJECT) {
3110 assert_int_equal(ret, LDB_SUCCESS);
3113 assert_dn_doesnt_exist(ldb_test_ctx,
3116 ldbtest_teardown((void **) &ldb_test_ctx);
3121 static void test_ldb_add_unique_value_to_unique_index(void **state)
3124 struct ldb_message *msg;
3125 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3126 struct ldbtest_ctx);
3127 TALLOC_CTX *tmp_ctx;
3129 tmp_ctx = talloc_new(test_ctx);
3130 assert_non_null(tmp_ctx);
3132 msg = ldb_msg_new(tmp_ctx);
3133 assert_non_null(msg);
3135 msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "dc=test");
3136 assert_non_null(msg->dn);
3138 ret = ldb_msg_add_string(msg, "cn", "test_unique_index");
3139 assert_int_equal(ret, LDB_SUCCESS);
3141 ret = ldb_add(test_ctx->ldb, msg);
3142 assert_int_equal(ret, LDB_SUCCESS);
3144 talloc_free(tmp_ctx);
3147 static int ldb_non_unique_index_test_setup(void **state)
3150 struct ldb_ldif *ldif;
3151 struct ldbtest_ctx *ldb_test_ctx;
3152 const char *index_ldif = \
3156 const char *options[] = {"modules:unique_index_test"};
3159 ret = ldb_register_module(&ldb_unique_index_test_module_ops);
3160 assert_true(ret == LDB_SUCCESS || ret == LDB_ERR_ENTRY_ALREADY_EXISTS);
3161 ldbtest_noconn_setup((void **) &ldb_test_ctx);
3164 ret = ldb_connect(ldb_test_ctx->ldb, ldb_test_ctx->dbpath, 0, options);
3165 assert_int_equal(ret, 0);
3167 while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &index_ldif))) {
3168 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
3169 assert_int_equal(ret, LDB_SUCCESS);
3172 unique_values = true;
3174 *state = ldb_test_ctx;
3178 static int ldb_non_unique_index_test_teardown(void **state)
3181 struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
3182 struct ldbtest_ctx);
3183 struct ldb_dn *del_dn;
3185 del_dn = ldb_dn_new_fmt(ldb_test_ctx,
3188 assert_non_null(del_dn);
3190 ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
3191 if (ret != LDB_ERR_NO_SUCH_OBJECT) {
3192 assert_int_equal(ret, LDB_SUCCESS);
3195 assert_dn_doesnt_exist(ldb_test_ctx,
3198 TALLOC_FREE(del_dn);
3200 ldbtest_teardown((void **) &ldb_test_ctx);
3204 static void test_ldb_add_duplicate_value_to_unique_index(void **state)
3207 struct ldb_message *msg01;
3208 struct ldb_message *msg02;
3209 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3210 struct ldbtest_ctx);
3211 TALLOC_CTX *tmp_ctx;
3213 tmp_ctx = talloc_new(test_ctx);
3214 assert_non_null(tmp_ctx);
3216 msg01 = ldb_msg_new(tmp_ctx);
3217 assert_non_null(msg01);
3219 msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3220 assert_non_null(msg01->dn);
3222 ret = ldb_msg_add_string(msg01, "cn", "test_unique_index");
3223 assert_int_equal(ret, LDB_SUCCESS);
3225 ret = ldb_add(test_ctx->ldb, msg01);
3226 assert_int_equal(ret, LDB_SUCCESS);
3228 msg02 = ldb_msg_new(tmp_ctx);
3229 assert_non_null(msg01);
3231 msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02");
3232 assert_non_null(msg02->dn);
3234 ret = ldb_msg_add_string(msg02, "cn", "test_unique_index");
3235 assert_int_equal(ret, LDB_SUCCESS);
3237 ret = ldb_add(test_ctx->ldb, msg02);
3238 assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION);
3239 talloc_free(tmp_ctx);
3242 static void test_ldb_add_to_index_duplicates_allowed(void **state)
3245 struct ldb_message *msg01;
3246 struct ldb_message *msg02;
3247 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3248 struct ldbtest_ctx);
3249 TALLOC_CTX *tmp_ctx;
3251 unique_values = false;
3253 tmp_ctx = talloc_new(test_ctx);
3254 assert_non_null(tmp_ctx);
3257 msg01 = ldb_msg_new(tmp_ctx);
3258 assert_non_null(msg01);
3260 msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3261 assert_non_null(msg01->dn);
3263 ret = ldb_msg_add_string(msg01, "cn", "test_unique_index");
3264 assert_int_equal(ret, LDB_SUCCESS);
3266 ret = ldb_add(test_ctx->ldb, msg01);
3267 assert_int_equal(ret, LDB_SUCCESS);
3269 msg02 = ldb_msg_new(tmp_ctx);
3270 assert_non_null(msg01);
3272 msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02");
3273 assert_non_null(msg02->dn);
3275 ret = ldb_msg_add_string(msg02, "cn", "test_unique_index");
3276 assert_int_equal(ret, LDB_SUCCESS);
3278 ret = ldb_add(test_ctx->ldb, msg02);
3279 assert_int_equal(ret, LDB_SUCCESS);
3280 talloc_free(tmp_ctx);
3283 static void test_ldb_add_to_index_unique_values_required(void **state)
3286 struct ldb_message *msg01;
3287 struct ldb_message *msg02;
3288 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3289 struct ldbtest_ctx);
3290 TALLOC_CTX *tmp_ctx;
3292 unique_values = true;
3294 tmp_ctx = talloc_new(test_ctx);
3295 assert_non_null(tmp_ctx);
3298 msg01 = ldb_msg_new(tmp_ctx);
3299 assert_non_null(msg01);
3301 msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3302 assert_non_null(msg01->dn);
3304 ret = ldb_msg_add_string(msg01, "cn", "test_unique_index");
3305 assert_int_equal(ret, LDB_SUCCESS);
3307 ret = ldb_add(test_ctx->ldb, msg01);
3308 assert_int_equal(ret, LDB_SUCCESS);
3310 msg02 = ldb_msg_new(tmp_ctx);
3311 assert_non_null(msg01);
3313 msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02");
3314 assert_non_null(msg02->dn);
3316 ret = ldb_msg_add_string(msg02, "cn", "test_unique_index");
3317 assert_int_equal(ret, LDB_SUCCESS);
3319 ret = ldb_add(test_ctx->ldb, msg02);
3320 assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION);
3321 talloc_free(tmp_ctx);
3323 int main(int argc, const char **argv)
3325 const struct CMUnitTest tests[] = {
3326 cmocka_unit_test_setup_teardown(test_connect,
3327 ldbtest_noconn_setup,
3328 ldbtest_noconn_teardown),
3329 cmocka_unit_test_setup_teardown(test_ldif_message,
3330 ldbtest_noconn_setup,
3331 ldbtest_noconn_teardown),
3332 cmocka_unit_test_setup_teardown(test_ldif_message_redacted,
3333 ldbtest_noconn_setup,
3334 ldbtest_noconn_teardown),
3335 cmocka_unit_test_setup_teardown(test_ldb_add,
3338 cmocka_unit_test_setup_teardown(test_ldb_search,
3341 cmocka_unit_test_setup_teardown(test_ldb_del,
3344 cmocka_unit_test_setup_teardown(test_ldb_del_noexist,
3347 cmocka_unit_test_setup_teardown(test_ldb_handle,
3350 cmocka_unit_test_setup_teardown(test_ldb_build_search_req,
3353 cmocka_unit_test_setup_teardown(test_transactions,
3356 cmocka_unit_test_setup_teardown(test_ldb_modify_add_key,
3357 ldb_modify_test_setup,
3358 ldb_modify_test_teardown),
3359 cmocka_unit_test_setup_teardown(test_ldb_modify_extend_key,
3360 ldb_modify_test_setup,
3361 ldb_modify_test_teardown),
3362 cmocka_unit_test_setup_teardown(test_ldb_modify_add_key_noval,
3363 ldb_modify_test_setup,
3364 ldb_modify_test_teardown),
3365 cmocka_unit_test_setup_teardown(test_ldb_modify_replace_key,
3366 ldb_modify_test_setup,
3367 ldb_modify_test_teardown),
3368 cmocka_unit_test_setup_teardown(test_ldb_modify_replace_noexist_key,
3369 ldb_modify_test_setup,
3370 ldb_modify_test_teardown),
3371 cmocka_unit_test_setup_teardown(test_ldb_modify_replace_zero_vals,
3372 ldb_modify_test_setup,
3373 ldb_modify_test_teardown),
3374 cmocka_unit_test_setup_teardown(test_ldb_modify_replace_noexist_key_zero_vals,
3375 ldb_modify_test_setup,
3376 ldb_modify_test_teardown),
3377 cmocka_unit_test_setup_teardown(test_ldb_modify_del_key,
3378 ldb_modify_test_setup,
3379 ldb_modify_test_teardown),
3380 cmocka_unit_test_setup_teardown(test_ldb_modify_del_keyval,
3381 ldb_modify_test_setup,
3382 ldb_modify_test_teardown),
3383 cmocka_unit_test_setup_teardown(test_search_match_none,
3384 ldb_search_test_setup,
3385 ldb_search_test_teardown),
3386 cmocka_unit_test_setup_teardown(test_search_match_one,
3387 ldb_search_test_setup,
3388 ldb_search_test_teardown),
3389 cmocka_unit_test_setup_teardown(test_search_match_filter,
3390 ldb_search_test_setup,
3391 ldb_search_test_teardown),
3392 cmocka_unit_test_setup_teardown(test_search_match_both,
3393 ldb_search_test_setup,
3394 ldb_search_test_teardown),
3395 cmocka_unit_test_setup_teardown(test_search_match_basedn,
3396 ldb_search_test_setup,
3397 ldb_search_test_teardown),
3398 cmocka_unit_test_setup_teardown(test_ldb_search_against_transaction,
3399 ldb_search_test_setup,
3400 ldb_search_test_teardown),
3401 cmocka_unit_test_setup_teardown(test_ldb_modify_during_unindexed_search,
3402 ldb_search_test_setup,
3403 ldb_search_test_teardown),
3404 cmocka_unit_test_setup_teardown(test_ldb_modify_during_indexed_search,
3405 ldb_search_test_setup,
3406 ldb_search_test_teardown),
3407 cmocka_unit_test_setup_teardown(test_ldb_rename_during_unindexed_search,
3408 ldb_search_test_setup,
3409 ldb_search_test_teardown),
3410 cmocka_unit_test_setup_teardown(test_ldb_rename_during_indexed_search,
3411 ldb_search_test_setup,
3412 ldb_search_test_teardown),
3413 cmocka_unit_test_setup_teardown(test_ldb_modify_during_whole_search,
3414 ldb_search_test_setup,
3415 ldb_search_test_teardown),
3416 cmocka_unit_test_setup_teardown(test_ldb_modify_before_ldb_wait,
3417 ldb_search_test_setup,
3418 ldb_search_test_teardown),
3419 cmocka_unit_test_setup_teardown(test_ldb_attrs_case_insensitive,
3420 ldb_case_test_setup,
3421 ldb_case_test_teardown),
3422 cmocka_unit_test_setup_teardown(test_ldb_attrs_case_handler,
3423 ldb_case_test_setup,
3424 ldb_case_test_teardown),
3425 cmocka_unit_test_setup_teardown(test_ldb_attrs_index_handler,
3426 ldb_case_test_setup,
3427 ldb_case_attrs_index_test_teardown),
3428 cmocka_unit_test_setup_teardown(test_ldb_rename,
3429 ldb_rename_test_setup,
3430 ldb_rename_test_teardown),
3431 cmocka_unit_test_setup_teardown(test_ldb_rename_from_doesnt_exist,
3432 ldb_rename_test_setup,
3433 ldb_rename_test_teardown),
3434 cmocka_unit_test_setup_teardown(test_ldb_rename_to_exists,
3435 ldb_rename_test_setup,
3436 ldb_rename_test_teardown),
3437 cmocka_unit_test_setup_teardown(test_ldb_rename_self,
3438 ldb_rename_test_setup,
3439 ldb_rename_test_teardown),
3440 cmocka_unit_test_setup_teardown(test_ldb_rename_dn_case_change,
3441 ldb_rename_test_setup,
3442 ldb_rename_test_teardown),
3443 cmocka_unit_test_setup_teardown(test_read_only,
3444 ldb_read_only_setup,
3445 ldb_read_only_teardown),
3446 cmocka_unit_test_setup_teardown(
3447 test_ldb_add_unique_value_to_unique_index,
3448 ldb_unique_index_test_setup,
3449 ldb_unique_index_test_teardown),
3450 cmocka_unit_test_setup_teardown(
3451 test_ldb_add_duplicate_value_to_unique_index,
3452 ldb_unique_index_test_setup,
3453 ldb_unique_index_test_teardown),
3454 cmocka_unit_test_setup_teardown(
3455 test_ldb_add_to_index_duplicates_allowed,
3456 ldb_non_unique_index_test_setup,
3457 ldb_non_unique_index_test_teardown),
3458 cmocka_unit_test_setup_teardown(
3459 test_ldb_add_to_index_unique_values_required,
3460 ldb_non_unique_index_test_setup,
3461 ldb_non_unique_index_test_teardown),
3464 return cmocka_run_group_tests(tests, NULL, NULL);