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);
2590 syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_OCTET_STRING);
2591 assert_non_null(syntax);
2593 ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb,
2595 syntax, &default_attr);
2596 assert_int_equal(ret, LDB_SUCCESS);
2599 * Set an attribute handler
2601 ldb_schema_attribute_set_override_handler(ldb,
2602 ldb_test_attribute_handler_override,
2605 /* cn matches lower case */
2606 cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2607 assert_int_equal(cnt, 1);
2609 /* Add the index (actually any modify will do) */
2610 while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &index_ldif))) {
2611 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
2612 assert_int_equal(ret, LDB_SUCCESS);
2615 ldb_schema_set_override_indexlist(ldb, false);
2617 /* cn does match as there is an index now */
2618 cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2619 assert_int_equal(cnt, 1);
2622 * Set an attribute handler, which will later fail to match as we
2623 * didn't re-index the DB
2625 ldb_schema_attribute_set_override_handler(ldb,
2626 ldb_test_attribute_handler_override,
2630 * cn does not match as we changed the case sensitivity, but
2633 * This shows that the override is in control
2635 cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2636 assert_int_equal(cnt, 0);
2640 static int ldb_case_attrs_index_test_teardown(void **state)
2643 struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
2644 struct ldbtest_ctx);
2645 struct ldb_dn *del_dn;
2647 del_dn = ldb_dn_new_fmt(ldb_test_ctx,
2650 assert_non_null(del_dn);
2652 ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
2653 if (ret != LDB_ERR_NO_SUCH_OBJECT) {
2654 assert_int_equal(ret, LDB_SUCCESS);
2657 assert_dn_doesnt_exist(ldb_test_ctx,
2660 ldb_case_test_teardown(state);
2665 struct rename_test_ctx {
2666 struct ldbtest_ctx *ldb_test_ctx;
2668 struct ldb_dn *basedn;
2669 const char *str_basedn;
2671 const char *teardown_dn;
2674 static int ldb_rename_test_setup(void **state)
2676 struct ldbtest_ctx *ldb_test_ctx;
2677 struct rename_test_ctx *rename_test_ctx;
2678 const char *strdn = "dc=rename_test_entry_from";
2680 ldbtest_setup((void **) &ldb_test_ctx);
2682 rename_test_ctx = talloc(ldb_test_ctx, struct rename_test_ctx);
2683 assert_non_null(rename_test_ctx);
2684 rename_test_ctx->ldb_test_ctx = ldb_test_ctx;
2685 assert_non_null(rename_test_ctx->ldb_test_ctx);
2687 rename_test_ctx->basedn = ldb_dn_new_fmt(rename_test_ctx,
2688 rename_test_ctx->ldb_test_ctx->ldb,
2690 assert_non_null(rename_test_ctx->basedn);
2692 rename_test_ctx->str_basedn = strdn;
2693 rename_test_ctx->teardown_dn = strdn;
2695 add_dn_with_cn(ldb_test_ctx,
2696 rename_test_ctx->basedn,
2697 "test_rename_cn_val");
2699 *state = rename_test_ctx;
2703 static int ldb_rename_test_teardown(void **state)
2706 struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(*state,
2707 struct rename_test_ctx);
2708 struct ldbtest_ctx *ldb_test_ctx;
2709 struct ldb_dn *del_dn;
2711 ldb_test_ctx = rename_test_ctx->ldb_test_ctx;
2713 del_dn = ldb_dn_new_fmt(rename_test_ctx,
2714 rename_test_ctx->ldb_test_ctx->ldb,
2715 "%s", rename_test_ctx->teardown_dn);
2716 assert_non_null(del_dn);
2718 ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
2719 assert_int_equal(ret, LDB_SUCCESS);
2721 assert_dn_doesnt_exist(ldb_test_ctx,
2722 rename_test_ctx->teardown_dn);
2724 ldbtest_teardown((void **) &ldb_test_ctx);
2728 static void test_ldb_rename(void **state)
2730 struct rename_test_ctx *rename_test_ctx =
2731 talloc_get_type_abort(*state, struct rename_test_ctx);
2733 const char *str_new_dn = "dc=rename_test_entry_to";
2734 struct ldb_dn *new_dn;
2736 new_dn = ldb_dn_new_fmt(rename_test_ctx,
2737 rename_test_ctx->ldb_test_ctx->ldb,
2739 assert_non_null(new_dn);
2741 ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
2742 rename_test_ctx->basedn,
2744 assert_int_equal(ret, LDB_SUCCESS);
2746 assert_dn_exists(rename_test_ctx->ldb_test_ctx, str_new_dn);
2747 assert_dn_doesnt_exist(rename_test_ctx->ldb_test_ctx,
2748 rename_test_ctx->str_basedn);
2749 rename_test_ctx->teardown_dn = str_new_dn;
2751 /* FIXME - test the values which didn't change */
2754 static void test_ldb_rename_from_doesnt_exist(void **state)
2756 struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(
2758 struct rename_test_ctx);
2760 const char *str_new_dn = "dc=rename_test_entry_to";
2761 const char *str_bad_old_dn = "dc=rename_test_no_such_entry";
2762 struct ldb_dn *new_dn;
2763 struct ldb_dn *bad_old_dn;
2765 new_dn = ldb_dn_new_fmt(rename_test_ctx,
2766 rename_test_ctx->ldb_test_ctx->ldb,
2768 assert_non_null(new_dn);
2770 bad_old_dn = ldb_dn_new_fmt(rename_test_ctx,
2771 rename_test_ctx->ldb_test_ctx->ldb,
2772 "%s", str_bad_old_dn);
2773 assert_non_null(bad_old_dn);
2775 assert_dn_doesnt_exist(rename_test_ctx->ldb_test_ctx,
2778 ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
2779 bad_old_dn, new_dn);
2780 assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT);
2782 assert_dn_doesnt_exist(rename_test_ctx->ldb_test_ctx,
2786 static void test_ldb_rename_to_exists(void **state)
2788 struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(
2790 struct rename_test_ctx);
2792 const char *str_new_dn = "dc=rename_test_already_exists";
2793 struct ldb_dn *new_dn;
2795 new_dn = ldb_dn_new_fmt(rename_test_ctx,
2796 rename_test_ctx->ldb_test_ctx->ldb,
2798 assert_non_null(new_dn);
2800 add_dn_with_cn(rename_test_ctx->ldb_test_ctx,
2802 "test_rename_cn_val");
2804 ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
2805 rename_test_ctx->basedn,
2807 assert_int_equal(ret, LDB_ERR_ENTRY_ALREADY_EXISTS);
2809 /* Old object must still exist */
2810 assert_dn_exists(rename_test_ctx->ldb_test_ctx,
2811 rename_test_ctx->str_basedn);
2813 ret = ldb_delete(rename_test_ctx->ldb_test_ctx->ldb,
2815 assert_int_equal(ret, LDB_SUCCESS);
2817 assert_dn_exists(rename_test_ctx->ldb_test_ctx,
2818 rename_test_ctx->teardown_dn);
2821 static void test_ldb_rename_self(void **state)
2823 struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(
2825 struct rename_test_ctx);
2828 /* Oddly enough, this is a success in ldb.. */
2829 ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
2830 rename_test_ctx->basedn,
2831 rename_test_ctx->basedn);
2832 assert_int_equal(ret, LDB_SUCCESS);
2834 /* Old object must still exist */
2835 assert_dn_exists(rename_test_ctx->ldb_test_ctx,
2836 rename_test_ctx->str_basedn);
2839 static void test_ldb_rename_dn_case_change(void **state)
2841 struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(
2843 struct rename_test_ctx);
2846 struct ldb_dn *new_dn;
2849 str_new_dn = talloc_strdup(rename_test_ctx, rename_test_ctx->str_basedn);
2850 assert_non_null(str_new_dn);
2851 for (i = 0; str_new_dn[i]; i++) {
2852 str_new_dn[i] = toupper(str_new_dn[i]);
2855 new_dn = ldb_dn_new_fmt(rename_test_ctx,
2856 rename_test_ctx->ldb_test_ctx->ldb,
2858 assert_non_null(new_dn);
2860 ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
2861 rename_test_ctx->basedn,
2863 assert_int_equal(ret, LDB_SUCCESS);
2865 /* DNs are case insensitive, so both searches will match */
2866 assert_dn_exists(rename_test_ctx->ldb_test_ctx, str_new_dn);
2867 assert_dn_exists(rename_test_ctx->ldb_test_ctx,
2868 rename_test_ctx->str_basedn);
2869 /* FIXME - test the values didn't change */
2872 static int ldb_read_only_setup(void **state)
2874 struct ldbtest_ctx *test_ctx;
2876 ldbtest_setup((void **) &test_ctx);
2882 static int ldb_read_only_teardown(void **state)
2884 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
2885 struct ldbtest_ctx);
2886 ldbtest_teardown((void **) &test_ctx);
2890 static void test_read_only(void **state)
2892 struct ldb_context *ro_ldb = NULL;
2893 struct ldb_context *rw_ldb = NULL;
2895 TALLOC_CTX *tmp_ctx = NULL;
2897 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
2898 struct ldbtest_ctx);
2900 * Close the ldb context freeing it this will ensure it exists on
2901 * disk and can be opened in read only mode
2903 TALLOC_FREE(test_ctx->ldb);
2906 * Open the database in read only and read write mode,
2907 * ensure it's opend in read only mode first
2909 ro_ldb = ldb_init(test_ctx, test_ctx->ev);
2910 ret = ldb_connect(ro_ldb, test_ctx->dbpath, LDB_FLG_RDONLY, NULL);
2911 assert_int_equal(ret, 0);
2913 rw_ldb = ldb_init(test_ctx, test_ctx->ev);
2914 ret = ldb_connect(rw_ldb, test_ctx->dbpath, 0, NULL);
2915 assert_int_equal(ret, 0);
2919 * Set up a context for the temporary variables
2921 tmp_ctx = talloc_new(test_ctx);
2922 assert_non_null(tmp_ctx);
2925 * Ensure that we can search the read write database
2928 struct ldb_result *result = NULL;
2929 struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, rw_ldb,
2931 assert_non_null(dn);
2933 ret = ldb_search(rw_ldb, tmp_ctx, &result, dn,
2934 LDB_SCOPE_BASE, NULL, NULL);
2935 assert_int_equal(ret, LDB_SUCCESS);
2936 TALLOC_FREE(result);
2941 * Ensure that we can search the read only database
2944 struct ldb_result *result = NULL;
2945 struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, ro_ldb,
2947 assert_non_null(dn);
2949 ret = ldb_search(ro_ldb, tmp_ctx, &result, dn,
2950 LDB_SCOPE_BASE, NULL, NULL);
2951 assert_int_equal(ret, LDB_SUCCESS);
2952 TALLOC_FREE(result);
2956 * Ensure that a write to the read only database fails
2959 struct ldb_message *msg = NULL;
2960 msg = ldb_msg_new(tmp_ctx);
2961 assert_non_null(msg);
2963 msg->dn = ldb_dn_new_fmt(msg, ro_ldb, "dc=test");
2964 assert_non_null(msg->dn);
2966 ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
2967 assert_int_equal(ret, 0);
2969 ret = ldb_add(ro_ldb, msg);
2970 assert_int_equal(ret, LDB_ERR_UNWILLING_TO_PERFORM);
2975 * Ensure that a write to the read write database succeeds
2978 struct ldb_message *msg = NULL;
2979 msg = ldb_msg_new(tmp_ctx);
2980 assert_non_null(msg);
2982 msg->dn = ldb_dn_new_fmt(msg, ro_ldb, "dc=test");
2983 assert_non_null(msg->dn);
2985 ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
2986 assert_int_equal(ret, 0);
2988 ret = ldb_add(rw_ldb, msg);
2989 assert_int_equal(ret, LDB_SUCCESS);
2994 * Ensure that a delete from a read only database fails
2997 struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, ro_ldb, "dc=test");
2998 assert_non_null(dn);
3000 ret = ldb_delete(ro_ldb, dn);
3001 assert_int_equal(ret, LDB_ERR_UNWILLING_TO_PERFORM);
3007 * Ensure that a delete from a read write succeeds
3010 struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, rw_ldb, "dc=test");
3011 assert_non_null(dn);
3013 ret = ldb_delete(rw_ldb, dn);
3014 assert_int_equal(ret, LDB_SUCCESS);
3017 TALLOC_FREE(tmp_ctx);
3020 static bool unique_values = false;
3022 static int unique_index_test_module_add(
3023 struct ldb_module *module,
3024 struct ldb_request *req)
3026 if (unique_values) {
3027 struct ldb_message *msg = discard_const(req->op.add.message);
3028 struct ldb_message_element *el = NULL;
3029 el = ldb_msg_find_element(msg, "cn");
3031 el->flags |= LDB_FLAG_INTERNAL_FORCE_UNIQUE_INDEX;
3035 return ldb_next_request(module, req);
3038 static int unique_index_test_module_init(struct ldb_module *module)
3040 return ldb_next_init(module);
3043 static const struct ldb_module_ops ldb_unique_index_test_module_ops = {
3044 .name = "unique_index_test",
3045 .init_context = unique_index_test_module_init,
3046 .add = unique_index_test_module_add,
3049 static int ldb_unique_index_test_setup(void **state)
3052 struct ldb_ldif *ldif;
3053 struct ldbtest_ctx *ldb_test_ctx;
3054 const char *attrs_ldif = \
3056 "cn: UNIQUE_INDEX\n"
3058 const char *index_ldif = \
3062 const char *options[] = {"modules:unique_index_test"};
3065 ret = ldb_register_module(&ldb_unique_index_test_module_ops);
3066 assert_true(ret == LDB_SUCCESS || ret == LDB_ERR_ENTRY_ALREADY_EXISTS);
3067 ldbtest_noconn_setup((void **) &ldb_test_ctx);
3070 ret = ldb_connect(ldb_test_ctx->ldb, ldb_test_ctx->dbpath, 0, options);
3071 assert_int_equal(ret, 0);
3073 while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &attrs_ldif))) {
3074 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
3075 assert_int_equal(ret, LDB_SUCCESS);
3078 while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &index_ldif))) {
3079 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
3080 assert_int_equal(ret, LDB_SUCCESS);
3083 unique_values = true;
3085 *state = ldb_test_ctx;
3089 static int ldb_unique_index_test_teardown(void **state)
3092 struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
3093 struct ldbtest_ctx);
3094 struct ldb_dn *del_dn;
3096 del_dn = ldb_dn_new_fmt(ldb_test_ctx,
3099 assert_non_null(del_dn);
3101 ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
3102 if (ret != LDB_ERR_NO_SUCH_OBJECT) {
3103 assert_int_equal(ret, LDB_SUCCESS);
3106 assert_dn_doesnt_exist(ldb_test_ctx,
3109 TALLOC_FREE(del_dn);
3111 del_dn = ldb_dn_new_fmt(ldb_test_ctx,
3114 assert_non_null(del_dn);
3116 ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
3117 if (ret != LDB_ERR_NO_SUCH_OBJECT) {
3118 assert_int_equal(ret, LDB_SUCCESS);
3121 assert_dn_doesnt_exist(ldb_test_ctx,
3124 ldbtest_teardown((void **) &ldb_test_ctx);
3129 static void test_ldb_add_unique_value_to_unique_index(void **state)
3132 struct ldb_message *msg;
3133 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3134 struct ldbtest_ctx);
3135 TALLOC_CTX *tmp_ctx;
3137 tmp_ctx = talloc_new(test_ctx);
3138 assert_non_null(tmp_ctx);
3140 msg = ldb_msg_new(tmp_ctx);
3141 assert_non_null(msg);
3143 msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "dc=test");
3144 assert_non_null(msg->dn);
3146 ret = ldb_msg_add_string(msg, "cn", "test_unique_index");
3147 assert_int_equal(ret, LDB_SUCCESS);
3149 ret = ldb_add(test_ctx->ldb, msg);
3150 assert_int_equal(ret, LDB_SUCCESS);
3152 talloc_free(tmp_ctx);
3155 static int ldb_non_unique_index_test_setup(void **state)
3158 struct ldb_ldif *ldif;
3159 struct ldbtest_ctx *ldb_test_ctx;
3160 const char *index_ldif = \
3164 const char *options[] = {"modules:unique_index_test"};
3167 ret = ldb_register_module(&ldb_unique_index_test_module_ops);
3168 assert_true(ret == LDB_SUCCESS || ret == LDB_ERR_ENTRY_ALREADY_EXISTS);
3169 ldbtest_noconn_setup((void **) &ldb_test_ctx);
3172 ret = ldb_connect(ldb_test_ctx->ldb, ldb_test_ctx->dbpath, 0, options);
3173 assert_int_equal(ret, 0);
3175 while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &index_ldif))) {
3176 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
3177 assert_int_equal(ret, LDB_SUCCESS);
3180 unique_values = true;
3182 *state = ldb_test_ctx;
3186 static int ldb_non_unique_index_test_teardown(void **state)
3189 struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
3190 struct ldbtest_ctx);
3191 struct ldb_dn *del_dn;
3193 del_dn = ldb_dn_new_fmt(ldb_test_ctx,
3196 assert_non_null(del_dn);
3198 ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
3199 if (ret != LDB_ERR_NO_SUCH_OBJECT) {
3200 assert_int_equal(ret, LDB_SUCCESS);
3203 assert_dn_doesnt_exist(ldb_test_ctx,
3206 TALLOC_FREE(del_dn);
3208 ldbtest_teardown((void **) &ldb_test_ctx);
3212 static void test_ldb_add_duplicate_value_to_unique_index(void **state)
3215 struct ldb_message *msg01;
3216 struct ldb_message *msg02;
3217 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3218 struct ldbtest_ctx);
3219 TALLOC_CTX *tmp_ctx;
3221 tmp_ctx = talloc_new(test_ctx);
3222 assert_non_null(tmp_ctx);
3224 msg01 = ldb_msg_new(tmp_ctx);
3225 assert_non_null(msg01);
3227 msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3228 assert_non_null(msg01->dn);
3230 ret = ldb_msg_add_string(msg01, "cn", "test_unique_index");
3231 assert_int_equal(ret, LDB_SUCCESS);
3233 ret = ldb_add(test_ctx->ldb, msg01);
3234 assert_int_equal(ret, LDB_SUCCESS);
3236 msg02 = ldb_msg_new(tmp_ctx);
3237 assert_non_null(msg02);
3239 msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02");
3240 assert_non_null(msg02->dn);
3242 ret = ldb_msg_add_string(msg02, "cn", "test_unique_index");
3243 assert_int_equal(ret, LDB_SUCCESS);
3245 ret = ldb_add(test_ctx->ldb, msg02);
3246 assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION);
3247 talloc_free(tmp_ctx);
3250 static void test_ldb_add_to_index_duplicates_allowed(void **state)
3253 struct ldb_message *msg01;
3254 struct ldb_message *msg02;
3255 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3256 struct ldbtest_ctx);
3257 TALLOC_CTX *tmp_ctx;
3259 unique_values = false;
3261 tmp_ctx = talloc_new(test_ctx);
3262 assert_non_null(tmp_ctx);
3265 msg01 = ldb_msg_new(tmp_ctx);
3266 assert_non_null(msg01);
3268 msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3269 assert_non_null(msg01->dn);
3271 ret = ldb_msg_add_string(msg01, "cn", "test_unique_index");
3272 assert_int_equal(ret, LDB_SUCCESS);
3274 ret = ldb_add(test_ctx->ldb, msg01);
3275 assert_int_equal(ret, LDB_SUCCESS);
3277 msg02 = ldb_msg_new(tmp_ctx);
3278 assert_non_null(msg02);
3280 msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02");
3281 assert_non_null(msg02->dn);
3283 ret = ldb_msg_add_string(msg02, "cn", "test_unique_index");
3284 assert_int_equal(ret, LDB_SUCCESS);
3286 ret = ldb_add(test_ctx->ldb, msg02);
3287 assert_int_equal(ret, LDB_SUCCESS);
3288 talloc_free(tmp_ctx);
3291 static void test_ldb_add_to_index_unique_values_required(void **state)
3294 struct ldb_message *msg01;
3295 struct ldb_message *msg02;
3296 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3297 struct ldbtest_ctx);
3298 TALLOC_CTX *tmp_ctx;
3300 unique_values = true;
3302 tmp_ctx = talloc_new(test_ctx);
3303 assert_non_null(tmp_ctx);
3306 msg01 = ldb_msg_new(tmp_ctx);
3307 assert_non_null(msg01);
3309 msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3310 assert_non_null(msg01->dn);
3312 ret = ldb_msg_add_string(msg01, "cn", "test_unique_index");
3313 assert_int_equal(ret, LDB_SUCCESS);
3315 ret = ldb_add(test_ctx->ldb, msg01);
3316 assert_int_equal(ret, LDB_SUCCESS);
3318 msg02 = ldb_msg_new(tmp_ctx);
3319 assert_non_null(msg02);
3321 msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02");
3322 assert_non_null(msg02->dn);
3324 ret = ldb_msg_add_string(msg02, "cn", "test_unique_index");
3325 assert_int_equal(ret, LDB_SUCCESS);
3327 ret = ldb_add(test_ctx->ldb, msg02);
3328 assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION);
3329 talloc_free(tmp_ctx);
3332 static void ldb_debug_string(void *context, enum ldb_debug_level level,
3333 const char *fmt, va_list ap)
3336 if (level <= LDB_DEBUG_WARNING) {
3337 *((char **)context) = talloc_vasprintf(NULL, fmt, ap);
3341 static void test_ldb_unique_index_duplicate_logging(void **state)
3344 struct ldb_message *msg01;
3345 struct ldb_message *msg02;
3346 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3347 struct ldbtest_ctx);
3348 TALLOC_CTX *tmp_ctx;
3349 char *debug_string = NULL;
3352 ldb_set_debug(test_ctx->ldb, ldb_debug_string, &debug_string);
3353 tmp_ctx = talloc_new(test_ctx);
3354 assert_non_null(tmp_ctx);
3356 msg01 = ldb_msg_new(tmp_ctx);
3357 assert_non_null(msg01);
3359 msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3360 assert_non_null(msg01->dn);
3362 ret = ldb_msg_add_string(msg01, "cn", "test_unique_index");
3363 assert_int_equal(ret, LDB_SUCCESS);
3365 ret = ldb_add(test_ctx->ldb, msg01);
3366 assert_int_equal(ret, LDB_SUCCESS);
3368 msg02 = ldb_msg_new(tmp_ctx);
3369 assert_non_null(msg02);
3371 msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02");
3372 assert_non_null(msg02->dn);
3374 ret = ldb_msg_add_string(msg02, "cn", "test_unique_index");
3375 assert_int_equal(ret, LDB_SUCCESS);
3377 ret = ldb_add(test_ctx->ldb, msg02);
3378 assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION);
3380 assert_non_null(debug_string);
3383 "unique index violation on cn "
3384 "in dc=test02, conficts with dc=test01 in "
3385 "@INDEX:CN:test_unique_index");
3387 TALLOC_FREE(debug_string);
3388 talloc_free(tmp_ctx);
3391 static void test_ldb_duplicate_dn_logging(void **state)
3394 struct ldb_message *msg01;
3395 struct ldb_message *msg02;
3396 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3397 struct ldbtest_ctx);
3398 TALLOC_CTX *tmp_ctx;
3399 char *debug_string = NULL;
3401 ldb_set_debug(test_ctx->ldb, ldb_debug_string, &debug_string);
3402 tmp_ctx = talloc_new(test_ctx);
3403 assert_non_null(tmp_ctx);
3405 msg01 = ldb_msg_new(tmp_ctx);
3406 assert_non_null(msg01);
3408 msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3409 assert_non_null(msg01->dn);
3411 ret = ldb_msg_add_string(msg01, "cn", "test_unique_index01");
3412 assert_int_equal(ret, LDB_SUCCESS);
3414 ret = ldb_add(test_ctx->ldb, msg01);
3415 assert_int_equal(ret, LDB_SUCCESS);
3417 msg02 = ldb_msg_new(tmp_ctx);
3418 assert_non_null(msg02);
3420 msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test01");
3421 assert_non_null(msg02->dn);
3423 ret = ldb_msg_add_string(msg02, "cn", "test_unique_index02");
3424 assert_int_equal(ret, LDB_SUCCESS);
3426 ret = ldb_add(test_ctx->ldb, msg02);
3427 assert_int_equal(ret, LDB_ERR_ENTRY_ALREADY_EXISTS);
3429 assert_null(debug_string);
3430 talloc_free(tmp_ctx);
3433 static int ldb_guid_index_test_setup(void **state)
3436 struct ldb_ldif *ldif;
3437 struct ldbtest_ctx *ldb_test_ctx;
3438 const char *attrs_ldif = \
3440 "cn: UNIQUE_INDEX\n"
3442 const char *index_ldif = \
3445 "@IDXGUID: objectUUID\n"
3446 "@IDX_DN_GUID: GUID\n"
3449 ldbtest_noconn_setup((void **) &ldb_test_ctx);
3452 ret = ldb_connect(ldb_test_ctx->ldb, ldb_test_ctx->dbpath, 0, NULL);
3453 assert_int_equal(ret, 0);
3455 while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &attrs_ldif))) {
3456 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
3457 assert_int_equal(ret, LDB_SUCCESS);
3460 while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &index_ldif))) {
3461 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
3462 assert_int_equal(ret, LDB_SUCCESS);
3465 *state = ldb_test_ctx;
3469 static int ldb_guid_index_test_teardown(void **state)
3472 struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
3473 struct ldbtest_ctx);
3474 struct ldb_dn *del_dn;
3476 del_dn = ldb_dn_new_fmt(ldb_test_ctx,
3479 assert_non_null(del_dn);
3481 ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
3482 if (ret != LDB_ERR_NO_SUCH_OBJECT) {
3483 assert_int_equal(ret, LDB_SUCCESS);
3486 assert_dn_doesnt_exist(ldb_test_ctx,
3489 TALLOC_FREE(del_dn);
3491 del_dn = ldb_dn_new_fmt(ldb_test_ctx,
3494 assert_non_null(del_dn);
3496 ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
3497 if (ret != LDB_ERR_NO_SUCH_OBJECT) {
3498 assert_int_equal(ret, LDB_SUCCESS);
3501 assert_dn_doesnt_exist(ldb_test_ctx,
3504 ldbtest_teardown((void **) &ldb_test_ctx);
3509 static void test_ldb_unique_index_duplicate_with_guid(void **state)
3512 struct ldb_message *msg01;
3513 struct ldb_message *msg02;
3514 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3515 struct ldbtest_ctx);
3516 TALLOC_CTX *tmp_ctx;
3517 char *debug_string = NULL;
3520 ldb_set_debug(test_ctx->ldb, ldb_debug_string, &debug_string);
3521 tmp_ctx = talloc_new(test_ctx);
3522 assert_non_null(tmp_ctx);
3524 msg01 = ldb_msg_new(tmp_ctx);
3525 assert_non_null(msg01);
3527 msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3528 assert_non_null(msg01->dn);
3530 ret = ldb_msg_add_string(msg01, "cn", "test_unique_index");
3531 assert_int_equal(ret, LDB_SUCCESS);
3533 ret = ldb_msg_add_string(msg01, "objectUUID", "0123456789abcdef");
3534 assert_int_equal(ret, LDB_SUCCESS);
3536 ret = ldb_add(test_ctx->ldb, msg01);
3537 assert_int_equal(ret, LDB_SUCCESS);
3539 msg02 = ldb_msg_new(tmp_ctx);
3540 assert_non_null(msg01);
3542 msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02");
3543 assert_non_null(msg02->dn);
3545 ret = ldb_msg_add_string(msg02, "cn", "test_unique_index");
3546 assert_int_equal(ret, LDB_SUCCESS);
3548 ret = ldb_msg_add_string(msg02, "objectUUID", "0123456789abcde0");
3549 assert_int_equal(ret, LDB_SUCCESS);
3551 ret = ldb_add(test_ctx->ldb, msg02);
3552 assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION);
3554 assert_non_null(debug_string);
3557 "unique index violation on cn in dc=test02, conficts with "
3558 "objectUUID 0123456789abcdef in @INDEX:CN:test_unique_index");
3560 TALLOC_FREE(debug_string);
3561 talloc_free(tmp_ctx);
3564 static void test_ldb_guid_index_duplicate_dn_logging(void **state)
3567 struct ldb_message *msg01;
3568 struct ldb_message *msg02;
3569 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3570 struct ldbtest_ctx);
3571 TALLOC_CTX *tmp_ctx;
3572 char *debug_string = NULL;
3574 ldb_set_debug(test_ctx->ldb, ldb_debug_string, &debug_string);
3575 tmp_ctx = talloc_new(test_ctx);
3576 assert_non_null(tmp_ctx);
3578 msg01 = ldb_msg_new(tmp_ctx);
3579 assert_non_null(msg01);
3581 msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3582 assert_non_null(msg01->dn);
3584 ret = ldb_msg_add_string(msg01, "cn", "test_unique_index01");
3585 assert_int_equal(ret, LDB_SUCCESS);
3587 ret = ldb_msg_add_string(msg01, "objectUUID", "0123456789abcdef");
3588 assert_int_equal(ret, LDB_SUCCESS);
3590 ret = ldb_add(test_ctx->ldb, msg01);
3591 assert_int_equal(ret, LDB_SUCCESS);
3593 msg02 = ldb_msg_new(tmp_ctx);
3594 assert_non_null(msg02);
3596 msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test01");
3597 assert_non_null(msg02->dn);
3599 ret = ldb_msg_add_string(msg02, "cn", "test_unique_index02");
3600 assert_int_equal(ret, LDB_SUCCESS);
3602 ret = ldb_msg_add_string(msg02, "objectUUID", "0123456789abcde1");
3603 assert_int_equal(ret, LDB_SUCCESS);
3605 ret = ldb_add(test_ctx->ldb, msg02);
3606 assert_int_equal(ret, LDB_ERR_ENTRY_ALREADY_EXISTS);
3608 assert_null(debug_string);
3609 talloc_free(tmp_ctx);
3613 int main(int argc, const char **argv)
3615 const struct CMUnitTest tests[] = {
3616 cmocka_unit_test_setup_teardown(test_connect,
3617 ldbtest_noconn_setup,
3618 ldbtest_noconn_teardown),
3619 cmocka_unit_test_setup_teardown(test_ldif_message,
3620 ldbtest_noconn_setup,
3621 ldbtest_noconn_teardown),
3622 cmocka_unit_test_setup_teardown(test_ldif_message_redacted,
3623 ldbtest_noconn_setup,
3624 ldbtest_noconn_teardown),
3625 cmocka_unit_test_setup_teardown(test_ldb_add,
3628 cmocka_unit_test_setup_teardown(test_ldb_search,
3631 cmocka_unit_test_setup_teardown(test_ldb_del,
3634 cmocka_unit_test_setup_teardown(test_ldb_del_noexist,
3637 cmocka_unit_test_setup_teardown(test_ldb_handle,
3640 cmocka_unit_test_setup_teardown(test_ldb_build_search_req,
3643 cmocka_unit_test_setup_teardown(test_transactions,
3646 cmocka_unit_test_setup_teardown(test_ldb_modify_add_key,
3647 ldb_modify_test_setup,
3648 ldb_modify_test_teardown),
3649 cmocka_unit_test_setup_teardown(test_ldb_modify_extend_key,
3650 ldb_modify_test_setup,
3651 ldb_modify_test_teardown),
3652 cmocka_unit_test_setup_teardown(test_ldb_modify_add_key_noval,
3653 ldb_modify_test_setup,
3654 ldb_modify_test_teardown),
3655 cmocka_unit_test_setup_teardown(test_ldb_modify_replace_key,
3656 ldb_modify_test_setup,
3657 ldb_modify_test_teardown),
3658 cmocka_unit_test_setup_teardown(test_ldb_modify_replace_noexist_key,
3659 ldb_modify_test_setup,
3660 ldb_modify_test_teardown),
3661 cmocka_unit_test_setup_teardown(test_ldb_modify_replace_zero_vals,
3662 ldb_modify_test_setup,
3663 ldb_modify_test_teardown),
3664 cmocka_unit_test_setup_teardown(test_ldb_modify_replace_noexist_key_zero_vals,
3665 ldb_modify_test_setup,
3666 ldb_modify_test_teardown),
3667 cmocka_unit_test_setup_teardown(test_ldb_modify_del_key,
3668 ldb_modify_test_setup,
3669 ldb_modify_test_teardown),
3670 cmocka_unit_test_setup_teardown(test_ldb_modify_del_keyval,
3671 ldb_modify_test_setup,
3672 ldb_modify_test_teardown),
3673 cmocka_unit_test_setup_teardown(test_search_match_none,
3674 ldb_search_test_setup,
3675 ldb_search_test_teardown),
3676 cmocka_unit_test_setup_teardown(test_search_match_one,
3677 ldb_search_test_setup,
3678 ldb_search_test_teardown),
3679 cmocka_unit_test_setup_teardown(test_search_match_filter,
3680 ldb_search_test_setup,
3681 ldb_search_test_teardown),
3682 cmocka_unit_test_setup_teardown(test_search_match_both,
3683 ldb_search_test_setup,
3684 ldb_search_test_teardown),
3685 cmocka_unit_test_setup_teardown(test_search_match_basedn,
3686 ldb_search_test_setup,
3687 ldb_search_test_teardown),
3688 cmocka_unit_test_setup_teardown(test_ldb_search_against_transaction,
3689 ldb_search_test_setup,
3690 ldb_search_test_teardown),
3691 cmocka_unit_test_setup_teardown(test_ldb_modify_during_unindexed_search,
3692 ldb_search_test_setup,
3693 ldb_search_test_teardown),
3694 cmocka_unit_test_setup_teardown(test_ldb_modify_during_indexed_search,
3695 ldb_search_test_setup,
3696 ldb_search_test_teardown),
3697 cmocka_unit_test_setup_teardown(test_ldb_rename_during_unindexed_search,
3698 ldb_search_test_setup,
3699 ldb_search_test_teardown),
3700 cmocka_unit_test_setup_teardown(test_ldb_rename_during_indexed_search,
3701 ldb_search_test_setup,
3702 ldb_search_test_teardown),
3703 cmocka_unit_test_setup_teardown(test_ldb_modify_during_whole_search,
3704 ldb_search_test_setup,
3705 ldb_search_test_teardown),
3706 cmocka_unit_test_setup_teardown(test_ldb_modify_before_ldb_wait,
3707 ldb_search_test_setup,
3708 ldb_search_test_teardown),
3709 cmocka_unit_test_setup_teardown(test_ldb_attrs_case_insensitive,
3710 ldb_case_test_setup,
3711 ldb_case_test_teardown),
3712 cmocka_unit_test_setup_teardown(test_ldb_attrs_case_handler,
3713 ldb_case_test_setup,
3714 ldb_case_test_teardown),
3715 cmocka_unit_test_setup_teardown(test_ldb_attrs_index_handler,
3716 ldb_case_test_setup,
3717 ldb_case_attrs_index_test_teardown),
3718 cmocka_unit_test_setup_teardown(test_ldb_rename,
3719 ldb_rename_test_setup,
3720 ldb_rename_test_teardown),
3721 cmocka_unit_test_setup_teardown(test_ldb_rename_from_doesnt_exist,
3722 ldb_rename_test_setup,
3723 ldb_rename_test_teardown),
3724 cmocka_unit_test_setup_teardown(test_ldb_rename_to_exists,
3725 ldb_rename_test_setup,
3726 ldb_rename_test_teardown),
3727 cmocka_unit_test_setup_teardown(test_ldb_rename_self,
3728 ldb_rename_test_setup,
3729 ldb_rename_test_teardown),
3730 cmocka_unit_test_setup_teardown(test_ldb_rename_dn_case_change,
3731 ldb_rename_test_setup,
3732 ldb_rename_test_teardown),
3733 cmocka_unit_test_setup_teardown(test_read_only,
3734 ldb_read_only_setup,
3735 ldb_read_only_teardown),
3736 cmocka_unit_test_setup_teardown(
3737 test_ldb_add_unique_value_to_unique_index,
3738 ldb_unique_index_test_setup,
3739 ldb_unique_index_test_teardown),
3740 cmocka_unit_test_setup_teardown(
3741 test_ldb_add_duplicate_value_to_unique_index,
3742 ldb_unique_index_test_setup,
3743 ldb_unique_index_test_teardown),
3744 cmocka_unit_test_setup_teardown(
3745 test_ldb_add_to_index_duplicates_allowed,
3746 ldb_non_unique_index_test_setup,
3747 ldb_non_unique_index_test_teardown),
3748 cmocka_unit_test_setup_teardown(
3749 test_ldb_add_to_index_unique_values_required,
3750 ldb_non_unique_index_test_setup,
3751 ldb_non_unique_index_test_teardown),
3752 cmocka_unit_test_setup_teardown(
3753 test_ldb_unique_index_duplicate_logging,
3754 ldb_unique_index_test_setup,
3755 ldb_unique_index_test_teardown),
3756 cmocka_unit_test_setup_teardown(
3757 test_ldb_duplicate_dn_logging,
3758 ldb_unique_index_test_setup,
3759 ldb_unique_index_test_teardown),
3760 cmocka_unit_test_setup_teardown(
3761 test_ldb_guid_index_duplicate_dn_logging,
3762 ldb_guid_index_test_setup,
3763 ldb_guid_index_test_teardown),
3764 cmocka_unit_test_setup_teardown(
3765 test_ldb_unique_index_duplicate_with_guid,
3766 ldb_guid_index_test_setup,
3767 ldb_guid_index_test_teardown),
3770 return cmocka_run_group_tests(tests, NULL, NULL);