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 int ldbtest_setup(void **state)
119 struct ldbtest_ctx *test_ctx;
122 ldbtest_noconn_setup((void **) &test_ctx);
124 ret = ldb_connect(test_ctx->ldb, test_ctx->dbpath, 0, NULL);
125 assert_int_equal(ret, 0);
131 static int ldbtest_teardown(void **state)
133 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
135 ldbtest_noconn_teardown((void **) &test_ctx);
139 static void test_ldb_add(void **state)
142 struct ldb_message *msg;
143 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
147 tmp_ctx = talloc_new(test_ctx);
148 assert_non_null(tmp_ctx);
150 msg = ldb_msg_new(tmp_ctx);
151 assert_non_null(msg);
153 msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "dc=test");
154 assert_non_null(msg->dn);
156 ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
157 assert_int_equal(ret, 0);
159 ret = ldb_add(test_ctx->ldb, msg);
160 assert_int_equal(ret, 0);
162 talloc_free(tmp_ctx);
165 static void test_ldb_search(void **state)
168 struct ldb_message *msg;
169 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
172 struct ldb_dn *basedn;
173 struct ldb_dn *basedn2;
174 struct ldb_result *result = NULL;
176 tmp_ctx = talloc_new(test_ctx);
177 assert_non_null(tmp_ctx);
179 basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "dc=test");
180 assert_non_null(basedn);
182 ret = ldb_search(test_ctx->ldb, tmp_ctx, &result, basedn,
183 LDB_SCOPE_BASE, NULL, NULL);
184 assert_int_equal(ret, 0);
185 assert_non_null(result);
186 assert_int_equal(result->count, 0);
188 msg = ldb_msg_new(tmp_ctx);
189 assert_non_null(msg);
192 assert_non_null(msg->dn);
194 ret = ldb_msg_add_string(msg, "cn", "test_cn_val1");
195 assert_int_equal(ret, 0);
197 ret = ldb_add(test_ctx->ldb, msg);
198 assert_int_equal(ret, 0);
200 basedn2 = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "dc=test2");
201 assert_non_null(basedn2);
203 msg = ldb_msg_new(tmp_ctx);
204 assert_non_null(msg);
207 assert_non_null(msg->dn);
209 ret = ldb_msg_add_string(msg, "cn", "test_cn_val2");
210 assert_int_equal(ret, 0);
212 ret = ldb_add(test_ctx->ldb, msg);
213 assert_int_equal(ret, 0);
215 ret = ldb_search(test_ctx->ldb, tmp_ctx, &result, basedn,
216 LDB_SCOPE_BASE, NULL, NULL);
217 assert_int_equal(ret, 0);
218 assert_non_null(result);
219 assert_int_equal(result->count, 1);
220 assert_string_equal(ldb_dn_get_linearized(result->msgs[0]->dn),
221 ldb_dn_get_linearized(basedn));
223 ret = ldb_search(test_ctx->ldb, tmp_ctx, &result, basedn2,
224 LDB_SCOPE_BASE, NULL, NULL);
225 assert_int_equal(ret, 0);
226 assert_non_null(result);
227 assert_int_equal(result->count, 1);
228 assert_string_equal(ldb_dn_get_linearized(result->msgs[0]->dn),
229 ldb_dn_get_linearized(basedn2));
231 talloc_free(tmp_ctx);
234 static int base_search_count(struct ldbtest_ctx *test_ctx, const char *entry_dn)
237 struct ldb_dn *basedn;
238 struct ldb_result *result = NULL;
242 tmp_ctx = talloc_new(test_ctx);
243 assert_non_null(tmp_ctx);
245 basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "%s", entry_dn);
246 assert_non_null(basedn);
248 ret = ldb_search(test_ctx->ldb, tmp_ctx, &result, basedn,
249 LDB_SCOPE_BASE, NULL, NULL);
250 assert_int_equal(ret, LDB_SUCCESS);
251 assert_non_null(result);
253 count = result->count;
254 talloc_free(tmp_ctx);
258 static int sub_search_count(struct ldbtest_ctx *test_ctx,
263 struct ldb_dn *basedn;
264 struct ldb_result *result = NULL;
268 tmp_ctx = talloc_new(test_ctx);
269 assert_non_null(tmp_ctx);
271 basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "%s", base_dn);
272 assert_non_null(basedn);
274 ret = ldb_search(test_ctx->ldb, tmp_ctx, &result, basedn,
275 LDB_SCOPE_SUBTREE, NULL, "%s", filter);
276 assert_int_equal(ret, LDB_SUCCESS);
277 assert_non_null(result);
279 count = result->count;
280 talloc_free(tmp_ctx);
284 /* In general it would be better if utility test functions didn't assert
285 * but only returned a value, then assert in the test shows correct
288 static void assert_dn_exists(struct ldbtest_ctx *test_ctx,
289 const char *entry_dn)
293 count = base_search_count(test_ctx, entry_dn);
294 assert_int_equal(count, 1);
297 static void assert_dn_doesnt_exist(struct ldbtest_ctx *test_ctx,
298 const char *entry_dn)
302 count = base_search_count(test_ctx, entry_dn);
303 assert_int_equal(count, 0);
306 static void add_dn_with_cn(struct ldbtest_ctx *test_ctx,
308 const char *cn_value)
312 struct ldb_message *msg;
314 tmp_ctx = talloc_new(test_ctx);
315 assert_non_null(tmp_ctx);
317 assert_dn_doesnt_exist(test_ctx,
318 ldb_dn_get_linearized(dn));
320 msg = ldb_msg_new(tmp_ctx);
321 assert_non_null(msg);
324 ret = ldb_msg_add_string(msg, "cn", cn_value);
325 assert_int_equal(ret, LDB_SUCCESS);
327 ret = ldb_add(test_ctx->ldb, msg);
328 assert_int_equal(ret, LDB_SUCCESS);
330 assert_dn_exists(test_ctx,
331 ldb_dn_get_linearized(dn));
332 talloc_free(tmp_ctx);
335 static void test_ldb_del(void **state)
338 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
340 const char *basedn = "dc=ldb_del_test";
343 dn = ldb_dn_new_fmt(test_ctx, test_ctx->ldb, "%s", basedn);
346 add_dn_with_cn(test_ctx, dn, "test_del_cn_val");
348 ret = ldb_delete(test_ctx->ldb, dn);
349 assert_int_equal(ret, LDB_SUCCESS);
351 assert_dn_doesnt_exist(test_ctx, basedn);
354 static void test_ldb_del_noexist(void **state)
356 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
358 struct ldb_dn *basedn;
361 basedn = ldb_dn_new(test_ctx, test_ctx->ldb, "dc=nosuchplace");
362 assert_non_null(basedn);
364 ret = ldb_delete(test_ctx->ldb, basedn);
365 assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT);
368 static void test_ldb_handle(void **state)
371 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
374 struct ldb_dn *basedn;
375 struct ldb_request *request = NULL;
376 struct ldb_request *request2 = NULL;
377 struct ldb_result *res = NULL;
378 const char *attrs[] = { "cn", NULL };
380 tmp_ctx = talloc_new(test_ctx);
381 assert_non_null(tmp_ctx);
383 basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "dc=test");
384 assert_non_null(basedn);
386 res = talloc_zero(tmp_ctx, struct ldb_result);
387 assert_non_null(res);
389 ret = ldb_build_search_req(&request, test_ctx->ldb, tmp_ctx,
390 basedn, LDB_SCOPE_BASE,
391 NULL, attrs, NULL, res,
392 ldb_search_default_callback,
394 assert_int_equal(ret, 0);
396 /* We are against ldb_tdb, so expect private event contexts */
397 assert_ptr_not_equal(ldb_handle_get_event_context(request->handle),
398 ldb_get_event_context(test_ctx->ldb));
400 ret = ldb_build_search_req(&request2, test_ctx->ldb, tmp_ctx,
401 basedn, LDB_SCOPE_BASE,
402 NULL, attrs, NULL, res,
403 ldb_search_default_callback,
405 assert_int_equal(ret, 0);
407 /* Expect that same event context will be chained */
408 assert_ptr_equal(ldb_handle_get_event_context(request->handle),
409 ldb_handle_get_event_context(request2->handle));
411 /* Now force this to use the global context */
412 ldb_handle_use_global_event_context(request2->handle);
413 assert_ptr_equal(ldb_handle_get_event_context(request2->handle),
414 ldb_get_event_context(test_ctx->ldb));
416 talloc_free(tmp_ctx);
419 static void test_ldb_build_search_req(void **state)
422 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
425 struct ldb_dn *basedn;
426 struct ldb_request *request = NULL;
427 struct ldb_request *request2 = NULL;
428 struct ldb_result *res = NULL;
429 const char *attrs[] = { "cn", NULL };
431 tmp_ctx = talloc_new(test_ctx);
432 assert_non_null(tmp_ctx);
434 basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "dc=test");
435 assert_non_null(basedn);
437 res = talloc_zero(tmp_ctx, struct ldb_result);
438 assert_non_null(res);
440 ret = ldb_build_search_req(&request, test_ctx->ldb, tmp_ctx,
441 basedn, LDB_SCOPE_BASE,
442 NULL, attrs, NULL, res,
443 ldb_search_default_callback,
445 assert_int_equal(ret, 0);
447 assert_int_equal(request->operation, LDB_SEARCH);
448 assert_ptr_equal(request->op.search.base, basedn);
449 assert_int_equal(request->op.search.scope, LDB_SCOPE_BASE);
450 assert_non_null(request->op.search.tree);
451 assert_ptr_equal(request->op.search.attrs, attrs);
452 assert_ptr_equal(request->context, res);
453 assert_ptr_equal(request->callback, ldb_search_default_callback);
455 ret = ldb_build_search_req(&request2, test_ctx->ldb, tmp_ctx,
456 basedn, LDB_SCOPE_BASE,
457 NULL, attrs, NULL, res,
458 ldb_search_default_callback,
460 assert_int_equal(ret, 0);
461 assert_ptr_equal(request, request2->handle->parent);
462 assert_int_equal(request->starttime, request2->starttime);
463 assert_int_equal(request->timeout, request2->timeout);
465 talloc_free(tmp_ctx);
468 static void add_keyval(struct ldbtest_ctx *test_ctx,
473 struct ldb_message *msg;
475 msg = ldb_msg_new(test_ctx);
476 assert_non_null(msg);
478 msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "%s=%s", key, val);
479 assert_non_null(msg->dn);
481 ret = ldb_msg_add_string(msg, key, val);
482 assert_int_equal(ret, 0);
484 ret = ldb_add(test_ctx->ldb, msg);
485 assert_int_equal(ret, 0);
490 static struct ldb_result *get_keyval(struct ldbtest_ctx *test_ctx,
495 struct ldb_result *result;
496 struct ldb_dn *basedn;
498 basedn = ldb_dn_new_fmt(test_ctx, test_ctx->ldb, "%s=%s", key, val);
499 assert_non_null(basedn);
501 ret = ldb_search(test_ctx->ldb, test_ctx, &result, basedn,
502 LDB_SCOPE_BASE, NULL, NULL);
503 assert_int_equal(ret, 0);
508 static void test_transactions(void **state)
511 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
513 struct ldb_result *res;
515 /* start lev-0 transaction */
516 ret = ldb_transaction_start(test_ctx->ldb);
517 assert_int_equal(ret, 0);
519 add_keyval(test_ctx, "vegetable", "carrot");
521 /* commit lev-0 transaction */
522 ret = ldb_transaction_commit(test_ctx->ldb);
523 assert_int_equal(ret, 0);
525 /* start another lev-1 nested transaction */
526 ret = ldb_transaction_start(test_ctx->ldb);
527 assert_int_equal(ret, 0);
529 add_keyval(test_ctx, "fruit", "apple");
531 /* abort lev-1 nested transaction */
532 ret = ldb_transaction_cancel(test_ctx->ldb);
533 assert_int_equal(ret, 0);
535 res = get_keyval(test_ctx, "vegetable", "carrot");
536 assert_non_null(res);
537 assert_int_equal(res->count, 1);
539 res = get_keyval(test_ctx, "fruit", "apple");
540 assert_non_null(res);
541 assert_int_equal(res->count, 0);
544 struct ldb_mod_test_ctx {
545 struct ldbtest_ctx *ldb_test_ctx;
546 const char *entry_dn;
554 static struct ldb_message *build_mod_msg(TALLOC_CTX *mem_ctx,
555 struct ldbtest_ctx *test_ctx,
560 struct ldb_message *msg;
564 msg = ldb_msg_new(mem_ctx);
565 assert_non_null(msg);
567 msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "%s", dn);
568 assert_non_null(msg->dn);
570 for (i = 0; kvs[i].key != NULL; i++) {
572 ret = ldb_msg_add_empty(msg, kvs[i].key,
574 assert_int_equal(ret, 0);
578 ret = ldb_msg_add_string(msg, kvs[i].key, kvs[i].val);
579 assert_int_equal(ret, LDB_SUCCESS);
586 static void ldb_test_add_data(TALLOC_CTX *mem_ctx,
587 struct ldbtest_ctx *ldb_test_ctx,
592 struct ldb_message *msg;
593 struct ldb_result *result = NULL;
596 tmp_ctx = talloc_new(mem_ctx);
597 assert_non_null(tmp_ctx);
599 msg = build_mod_msg(tmp_ctx, ldb_test_ctx,
601 assert_non_null(msg);
603 ret = ldb_add(ldb_test_ctx->ldb, msg);
604 assert_int_equal(ret, LDB_SUCCESS);
606 ret = ldb_search(ldb_test_ctx->ldb, tmp_ctx, &result, msg->dn,
607 LDB_SCOPE_BASE, NULL, NULL);
608 assert_int_equal(ret, LDB_SUCCESS);
609 assert_non_null(result);
610 assert_int_equal(result->count, 1);
611 assert_string_equal(ldb_dn_get_linearized(result->msgs[0]->dn),
612 ldb_dn_get_linearized(msg->dn));
614 talloc_free(tmp_ctx);
617 static void ldb_test_remove_data(TALLOC_CTX *mem_ctx,
618 struct ldbtest_ctx *ldb_test_ctx,
622 struct ldb_dn *basedn;
626 tmp_ctx = talloc_new(mem_ctx);
627 assert_non_null(tmp_ctx);
629 basedn = ldb_dn_new_fmt(tmp_ctx, ldb_test_ctx->ldb,
631 assert_non_null(basedn);
633 ret = ldb_delete(ldb_test_ctx->ldb, basedn);
634 assert_true(ret == LDB_SUCCESS || ret == LDB_ERR_NO_SUCH_OBJECT);
636 count = base_search_count(ldb_test_ctx, ldb_dn_get_linearized(basedn));
637 assert_int_equal(count, 0);
639 talloc_free(tmp_ctx);
642 static void mod_test_add_data(struct ldb_mod_test_ctx *mod_test_ctx,
645 ldb_test_add_data(mod_test_ctx,
646 mod_test_ctx->ldb_test_ctx,
647 mod_test_ctx->entry_dn,
651 static void mod_test_remove_data(struct ldb_mod_test_ctx *mod_test_ctx)
653 ldb_test_remove_data(mod_test_ctx,
654 mod_test_ctx->ldb_test_ctx,
655 mod_test_ctx->entry_dn);
658 static struct ldb_result *run_mod_test(struct ldb_mod_test_ctx *mod_test_ctx,
663 struct ldb_result *res;
664 struct ldb_message *mod_msg;
665 struct ldb_dn *basedn;
666 struct ldbtest_ctx *ldb_test_ctx;
669 ldb_test_ctx = mod_test_ctx->ldb_test_ctx;
671 tmp_ctx = talloc_new(mod_test_ctx);
672 assert_non_null(tmp_ctx);
674 mod_msg = build_mod_msg(tmp_ctx, ldb_test_ctx, mod_test_ctx->entry_dn,
676 assert_non_null(mod_msg);
678 ret = ldb_modify(ldb_test_ctx->ldb, mod_msg);
679 assert_int_equal(ret, LDB_SUCCESS);
681 basedn = ldb_dn_new_fmt(tmp_ctx, ldb_test_ctx->ldb,
682 "%s", mod_test_ctx->entry_dn);
683 assert_non_null(basedn);
685 ret = ldb_search(ldb_test_ctx->ldb, mod_test_ctx, &res, basedn,
686 LDB_SCOPE_BASE, NULL, NULL);
687 assert_int_equal(ret, LDB_SUCCESS);
688 assert_non_null(res);
689 assert_int_equal(res->count, 1);
690 assert_string_equal(ldb_dn_get_linearized(res->msgs[0]->dn),
691 ldb_dn_get_linearized(mod_msg->dn));
693 talloc_free(tmp_ctx);
697 static int ldb_modify_test_setup(void **state)
699 struct ldbtest_ctx *ldb_test_ctx;
700 struct ldb_mod_test_ctx *mod_test_ctx;
701 struct keyval kvs[] = {
702 { "cn", "test_mod_cn" },
706 ldbtest_setup((void **) &ldb_test_ctx);
708 mod_test_ctx = talloc(ldb_test_ctx, struct ldb_mod_test_ctx);
709 assert_non_null(mod_test_ctx);
711 mod_test_ctx->entry_dn = "dc=mod_test_entry";
712 mod_test_ctx->ldb_test_ctx = ldb_test_ctx;
714 mod_test_remove_data(mod_test_ctx);
715 mod_test_add_data(mod_test_ctx, kvs);
716 *state = mod_test_ctx;
720 static int ldb_modify_test_teardown(void **state)
722 struct ldb_mod_test_ctx *mod_test_ctx = \
723 talloc_get_type_abort(*state,
724 struct ldb_mod_test_ctx);
725 struct ldbtest_ctx *ldb_test_ctx;
727 ldb_test_ctx = mod_test_ctx->ldb_test_ctx;
729 mod_test_remove_data(mod_test_ctx);
730 talloc_free(mod_test_ctx);
732 ldbtest_teardown((void **) &ldb_test_ctx);
736 static void test_ldb_modify_add_key(void **state)
738 struct ldb_mod_test_ctx *mod_test_ctx = \
739 talloc_get_type_abort(*state,
740 struct ldb_mod_test_ctx);
741 struct keyval mod_kvs[] = {
742 { "name", "test_mod_name" },
745 struct ldb_result *res;
746 struct ldb_message_element *el;
748 res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_ADD, mod_kvs);
749 assert_non_null(res);
751 /* Check cn is intact and name was added */
752 assert_int_equal(res->count, 1);
753 el = ldb_msg_find_element(res->msgs[0], "cn");
755 assert_int_equal(el->num_values, 1);
756 assert_string_equal(el->values[0].data, "test_mod_cn");
758 el = ldb_msg_find_element(res->msgs[0], "name");
760 assert_int_equal(el->num_values, 1);
761 assert_string_equal(el->values[0].data, "test_mod_name");
764 static void test_ldb_modify_extend_key(void **state)
766 struct ldb_mod_test_ctx *mod_test_ctx = \
767 talloc_get_type_abort(*state,
768 struct ldb_mod_test_ctx);
769 struct keyval mod_kvs[] = {
770 { "cn", "test_mod_cn2" },
773 struct ldb_result *res;
774 struct ldb_message_element *el;
776 res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_ADD, mod_kvs);
777 assert_non_null(res);
779 /* Check cn was extended with another value */
780 assert_int_equal(res->count, 1);
781 el = ldb_msg_find_element(res->msgs[0], "cn");
783 assert_int_equal(el->num_values, 2);
784 assert_string_equal(el->values[0].data, "test_mod_cn");
785 assert_string_equal(el->values[1].data, "test_mod_cn2");
788 static void test_ldb_modify_add_key_noval(void **state)
790 struct ldb_mod_test_ctx *mod_test_ctx = \
791 talloc_get_type_abort(*state,
792 struct ldb_mod_test_ctx);
793 struct ldb_message *mod_msg;
794 struct ldbtest_ctx *ldb_test_ctx;
795 struct ldb_message_element *el;
798 ldb_test_ctx = mod_test_ctx->ldb_test_ctx;
800 mod_msg = ldb_msg_new(mod_test_ctx);
801 assert_non_null(mod_msg);
803 mod_msg->dn = ldb_dn_new_fmt(mod_msg, ldb_test_ctx->ldb,
804 "%s", mod_test_ctx->entry_dn);
805 assert_non_null(mod_msg->dn);
807 el = talloc_zero(mod_msg, struct ldb_message_element);
808 el->flags = LDB_FLAG_MOD_ADD;
810 el->name = talloc_strdup(el, "cn");
811 assert_non_null(el->name);
813 mod_msg->elements = el;
814 mod_msg->num_elements = 1;
816 ret = ldb_modify(ldb_test_ctx->ldb, mod_msg);
817 assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION);
820 static void test_ldb_modify_replace_key(void **state)
822 struct ldb_mod_test_ctx *mod_test_ctx = \
823 talloc_get_type_abort(*state,
824 struct ldb_mod_test_ctx);
825 const char *new_cn = "new_cn";
826 struct keyval mod_kvs[] = {
830 struct ldb_result *res;
831 struct ldb_message_element *el;
833 res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, mod_kvs);
834 assert_non_null(res);
836 /* Check cn was replaced */
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, new_cn);
844 static void test_ldb_modify_replace_noexist_key(void **state)
846 struct ldb_mod_test_ctx *mod_test_ctx = \
847 talloc_get_type_abort(*state,
848 struct ldb_mod_test_ctx);
849 struct keyval mod_kvs[] = {
850 { "name", "name_val" },
853 struct ldb_result *res;
854 struct ldb_message_element *el;
856 res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, mod_kvs);
857 assert_non_null(res);
859 /* Check cn is intact and name was added */
860 assert_int_equal(res->count, 1);
861 el = ldb_msg_find_element(res->msgs[0], "cn");
863 assert_int_equal(el->num_values, 1);
864 assert_string_equal(el->values[0].data, "test_mod_cn");
866 el = ldb_msg_find_element(res->msgs[0], mod_kvs[0].key);
868 assert_int_equal(el->num_values, 1);
869 assert_string_equal(el->values[0].data, mod_kvs[0].val);
872 static void test_ldb_modify_replace_zero_vals(void **state)
874 struct ldb_mod_test_ctx *mod_test_ctx = \
875 talloc_get_type_abort(*state,
876 struct ldb_mod_test_ctx);
877 struct ldb_message_element *el;
878 struct ldb_result *res;
879 struct keyval kvs[] = {
884 /* cn must be gone */
885 res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, kvs);
886 assert_non_null(res);
887 el = ldb_msg_find_element(res->msgs[0], "cn");
891 static void test_ldb_modify_replace_noexist_key_zero_vals(void **state)
893 struct ldb_mod_test_ctx *mod_test_ctx = \
894 talloc_get_type_abort(*state,
895 struct ldb_mod_test_ctx);
896 struct ldb_message_element *el;
897 struct ldb_result *res;
898 struct keyval kvs[] = {
899 { "noexist_key", NULL },
903 /* cn must be gone */
904 res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, kvs);
905 assert_non_null(res);
907 /* cn should be intact */
908 el = ldb_msg_find_element(res->msgs[0], "cn");
912 static void test_ldb_modify_del_key(void **state)
914 struct ldb_mod_test_ctx *mod_test_ctx = \
915 talloc_get_type_abort(*state,
916 struct ldb_mod_test_ctx);
917 struct ldb_message_element *el;
918 struct ldb_result *res;
919 struct keyval kvs[] = {
924 /* cn must be gone */
925 res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_DELETE, kvs);
926 assert_non_null(res);
928 el = ldb_msg_find_element(res->msgs[0], "cn");
932 static void test_ldb_modify_del_keyval(void **state)
934 struct ldb_mod_test_ctx *mod_test_ctx = \
935 talloc_get_type_abort(*state,
936 struct ldb_mod_test_ctx);
937 struct ldb_message_element *el;
938 struct ldb_result *res;
939 struct keyval kvs[] = {
940 { "cn", "test_mod_cn" },
944 /* cn must be gone */
945 res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_DELETE, kvs);
946 assert_non_null(res);
948 el = ldb_msg_find_element(res->msgs[0], "cn");
952 struct search_test_ctx {
953 struct ldbtest_ctx *ldb_test_ctx;
957 static char *get_full_dn(TALLOC_CTX *mem_ctx,
958 struct search_test_ctx *search_test_ctx,
963 full_dn = talloc_asprintf(mem_ctx,
964 "%s,%s", rdn, search_test_ctx->base_dn);
965 assert_non_null(full_dn);
970 static void search_test_add_data(struct search_test_ctx *search_test_ctx,
976 full_dn = get_full_dn(search_test_ctx, search_test_ctx, rdn);
978 ldb_test_add_data(search_test_ctx,
979 search_test_ctx->ldb_test_ctx,
984 static void search_test_remove_data(struct search_test_ctx *search_test_ctx,
989 full_dn = talloc_asprintf(search_test_ctx,
990 "%s,%s", rdn, search_test_ctx->base_dn);
991 assert_non_null(full_dn);
993 ldb_test_remove_data(search_test_ctx,
994 search_test_ctx->ldb_test_ctx,
998 static int ldb_search_test_setup(void **state)
1000 struct ldbtest_ctx *ldb_test_ctx;
1001 struct search_test_ctx *search_test_ctx;
1002 struct keyval kvs[] = {
1003 { "cn", "test_search_cn" },
1004 { "cn", "test_search_cn2" },
1005 { "uid", "test_search_uid" },
1006 { "uid", "test_search_uid2" },
1009 struct keyval kvs2[] = {
1010 { "cn", "test_search_2_cn" },
1011 { "cn", "test_search_2_cn2" },
1012 { "uid", "test_search_2_uid" },
1013 { "uid", "test_search_2_uid2" },
1017 ldbtest_setup((void **) &ldb_test_ctx);
1019 search_test_ctx = talloc(ldb_test_ctx, struct search_test_ctx);
1020 assert_non_null(search_test_ctx);
1022 search_test_ctx->base_dn = "dc=search_test_entry";
1023 search_test_ctx->ldb_test_ctx = ldb_test_ctx;
1025 search_test_remove_data(search_test_ctx, "cn=test_search_cn");
1026 search_test_add_data(search_test_ctx, "cn=test_search_cn", kvs);
1028 search_test_remove_data(search_test_ctx, "cn=test_search_2_cn");
1029 search_test_add_data(search_test_ctx, "cn=test_search_2_cn", kvs2);
1031 *state = search_test_ctx;
1035 static int ldb_search_test_teardown(void **state)
1037 struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1038 struct search_test_ctx);
1039 struct ldbtest_ctx *ldb_test_ctx;
1041 ldb_test_ctx = search_test_ctx->ldb_test_ctx;
1043 search_test_remove_data(search_test_ctx, "cn=test_search_cn");
1044 search_test_remove_data(search_test_ctx, "cn=test_search_2_cn");
1045 ldbtest_teardown((void **) &ldb_test_ctx);
1049 static void assert_attr_has_vals(struct ldb_message *msg,
1054 struct ldb_message_element *el;
1057 el = ldb_msg_find_element(msg, attr);
1058 assert_non_null(el);
1060 assert_int_equal(el->num_values, nvals);
1061 for (i = 0; i < nvals; i++) {
1062 assert_string_equal(el->values[i].data,
1067 static void assert_has_no_attr(struct ldb_message *msg,
1070 struct ldb_message_element *el;
1072 el = ldb_msg_find_element(msg, attr);
1076 static bool has_dn(struct ldb_message *msg, const char *dn)
1080 msgdn = ldb_dn_get_linearized(msg->dn);
1081 if (strcmp(dn, msgdn) == 0) {
1088 static void test_search_match_none(void **state)
1090 struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1091 struct search_test_ctx);
1094 count = base_search_count(search_test_ctx->ldb_test_ctx,
1095 "dc=no_such_entry");
1096 assert_int_equal(count, 0);
1099 static void test_search_match_one(void **state)
1101 struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1102 struct search_test_ctx);
1104 struct ldb_dn *basedn;
1105 struct ldb_result *result = NULL;
1106 const char *cn_vals[] = { "test_search_cn",
1107 "test_search_cn2" };
1108 const char *uid_vals[] = { "test_search_uid",
1109 "test_search_uid2" };
1111 basedn = ldb_dn_new_fmt(search_test_ctx,
1112 search_test_ctx->ldb_test_ctx->ldb,
1114 search_test_ctx->base_dn);
1115 assert_non_null(basedn);
1117 ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
1121 LDB_SCOPE_SUBTREE, NULL,
1122 "cn=test_search_cn");
1123 assert_int_equal(ret, 0);
1124 assert_non_null(result);
1125 assert_int_equal(result->count, 1);
1127 assert_attr_has_vals(result->msgs[0], "cn", cn_vals, 2);
1128 assert_attr_has_vals(result->msgs[0], "uid", uid_vals, 2);
1131 static void test_search_match_filter(void **state)
1133 struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1134 struct search_test_ctx);
1136 struct ldb_dn *basedn;
1137 struct ldb_result *result = NULL;
1138 const char *cn_vals[] = { "test_search_cn",
1139 "test_search_cn2" };
1140 const char *attrs[] = { "cn", NULL };
1142 basedn = ldb_dn_new_fmt(search_test_ctx,
1143 search_test_ctx->ldb_test_ctx->ldb,
1145 search_test_ctx->base_dn);
1146 assert_non_null(basedn);
1148 ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
1154 "cn=test_search_cn");
1155 assert_int_equal(ret, 0);
1156 assert_non_null(result);
1157 assert_int_equal(result->count, 1);
1159 assert_attr_has_vals(result->msgs[0], "cn", cn_vals, 2);
1160 assert_has_no_attr(result->msgs[0], "uid");
1163 static void assert_expected(struct search_test_ctx *search_test_ctx,
1164 struct ldb_message *msg)
1168 const char *cn_vals[] = { "test_search_cn",
1169 "test_search_cn2" };
1170 const char *uid_vals[] = { "test_search_uid",
1171 "test_search_uid2" };
1172 const char *cn2_vals[] = { "test_search_2_cn",
1173 "test_search_2_cn2" };
1174 const char *uid2_vals[] = { "test_search_2_uid",
1175 "test_search_2_uid2" };
1177 full_dn1 = get_full_dn(search_test_ctx,
1179 "cn=test_search_cn");
1181 full_dn2 = get_full_dn(search_test_ctx,
1183 "cn=test_search_2_cn");
1185 if (has_dn(msg, full_dn1) == true) {
1186 assert_attr_has_vals(msg, "cn", cn_vals, 2);
1187 assert_attr_has_vals(msg, "uid", uid_vals, 2);
1188 } else if (has_dn(msg, full_dn2) == true) {
1189 assert_attr_has_vals(msg, "cn", cn2_vals, 2);
1190 assert_attr_has_vals(msg, "uid", uid2_vals, 2);
1196 static void test_search_match_both(void **state)
1198 struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1199 struct search_test_ctx);
1201 struct ldb_dn *basedn;
1202 struct ldb_result *result = NULL;
1204 basedn = ldb_dn_new_fmt(search_test_ctx,
1205 search_test_ctx->ldb_test_ctx->ldb,
1207 search_test_ctx->base_dn);
1208 assert_non_null(basedn);
1210 ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
1214 LDB_SCOPE_SUBTREE, NULL,
1215 "cn=test_search_*");
1216 assert_int_equal(ret, 0);
1217 assert_non_null(result);
1218 assert_int_equal(result->count, 2);
1220 assert_expected(search_test_ctx, result->msgs[0]);
1221 assert_expected(search_test_ctx, result->msgs[1]);
1224 static void test_search_match_basedn(void **state)
1226 struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1227 struct search_test_ctx);
1229 struct ldb_dn *basedn;
1230 struct ldb_result *result = NULL;
1231 struct ldb_message *msg;
1233 basedn = ldb_dn_new_fmt(search_test_ctx,
1234 search_test_ctx->ldb_test_ctx->ldb,
1236 assert_non_null(basedn);
1238 ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
1242 LDB_SCOPE_SUBTREE, NULL,
1244 assert_int_equal(ret, 0);
1246 /* Add 'checkBaseOnSearch' to @OPTIONS */
1247 msg = ldb_msg_new(search_test_ctx);
1248 assert_non_null(msg);
1250 msg->dn = ldb_dn_new_fmt(msg,
1251 search_test_ctx->ldb_test_ctx->ldb,
1253 assert_non_null(msg->dn);
1255 ret = ldb_msg_add_string(msg, "checkBaseOnSearch", "TRUE");
1256 assert_int_equal(ret, 0);
1258 ret = ldb_add(search_test_ctx->ldb_test_ctx->ldb, msg);
1259 assert_int_equal(ret, 0);
1262 /* The search should return LDB_ERR_NO_SUCH_OBJECT */
1263 ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
1267 LDB_SCOPE_SUBTREE, NULL,
1269 assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT);
1271 ret = ldb_delete(search_test_ctx->ldb_test_ctx->ldb, msg->dn);
1272 assert_int_equal(ret, 0);
1277 * This test is complex.
1278 * The purpose is to test for a deadlock detected between ldb_search()
1279 * and ldb_transaction_commit(). The deadlock happens if in process
1281 * - (1) the all-record lock is taken in ltdb_search()
1282 * - (2) the ldb_transaction_start() call is made
1283 * - (1) an un-indexed search starts (forced here by doing it in
1285 * - (2) the ldb_transaction_commit() is called.
1286 * This returns LDB_ERR_BUSY if the deadlock is detected
1288 * With ldb 1.1.31 and tdb 1.3.12 we avoid this only due to a missing
1289 * lock call in ltdb_search() due to a refcounting bug in
1293 struct search_against_transaction_ctx {
1294 struct ldbtest_ctx *test_ctx;
1297 struct ldb_dn *basedn;
1300 static int test_ldb_search_against_transaction_callback2(struct ldb_request *req,
1301 struct ldb_reply *ares)
1303 struct search_against_transaction_ctx *ctx = req->context;
1304 switch (ares->type) {
1305 case LDB_REPLY_ENTRY:
1307 if (ctx->res_count != 1) {
1313 case LDB_REPLY_REFERRAL:
1316 case LDB_REPLY_DONE:
1317 return ldb_request_done(req, LDB_SUCCESS);
1325 * This purpose of this callback is to trigger a transaction in
1326 * the child process while the all-record lock is held, but before
1327 * we take any locks in the tdb_traverse_read() handler.
1329 * In tdb 1.3.12 tdb_traverse_read() take the read transaction lock
1330 * however in ldb 1.1.31 ltdb_search() forgets to take the all-record
1331 * lock (except the very first time) due to a ref-counting bug.
1335 static int test_ldb_search_against_transaction_callback1(struct ldb_request *req,
1336 struct ldb_reply *ares)
1341 struct search_against_transaction_ctx *ctx = req->context;
1342 switch (ares->type) {
1343 case LDB_REPLY_ENTRY:
1346 case LDB_REPLY_REFERRAL:
1349 case LDB_REPLY_DONE:
1350 return ldb_request_done(req, LDB_SUCCESS);
1354 assert_int_equal(ret, 0);
1356 ctx->child_pid = fork();
1357 if (ctx->child_pid == 0) {
1358 TALLOC_CTX *tmp_ctx = NULL;
1359 struct ldb_message *msg;
1360 TALLOC_FREE(ctx->test_ctx->ldb);
1361 TALLOC_FREE(ctx->test_ctx->ev);
1362 ctx->test_ctx->ev = tevent_context_init(ctx->test_ctx);
1363 if (ctx->test_ctx->ev == NULL) {
1364 exit(LDB_ERR_OPERATIONS_ERROR);
1367 ctx->test_ctx->ldb = ldb_init(ctx->test_ctx,
1369 if (ctx->test_ctx->ldb == NULL) {
1370 exit(LDB_ERR_OPERATIONS_ERROR);
1373 ret = ldb_connect(ctx->test_ctx->ldb,
1374 ctx->test_ctx->dbpath, 0, NULL);
1375 if (ret != LDB_SUCCESS) {
1379 tmp_ctx = talloc_new(ctx->test_ctx);
1380 if (tmp_ctx == NULL) {
1381 exit(LDB_ERR_OPERATIONS_ERROR);
1384 msg = ldb_msg_new(tmp_ctx);
1386 exit(LDB_ERR_OPERATIONS_ERROR);
1389 msg->dn = ldb_dn_new_fmt(msg, ctx->test_ctx->ldb,
1391 if (msg->dn == NULL) {
1392 exit(LDB_ERR_OPERATIONS_ERROR);
1395 ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
1397 exit(LDB_ERR_OPERATIONS_ERROR);
1400 ret = ldb_transaction_start(ctx->test_ctx->ldb);
1405 ret = write(pipes[1], "GO", 2);
1407 exit(LDB_ERR_OPERATIONS_ERROR);
1410 ret = ldb_add(ctx->test_ctx->ldb, msg);
1415 ret = ldb_transaction_commit(ctx->test_ctx->ldb);
1419 ret = read(pipes[0], buf, 2);
1420 assert_int_equal(ret, 2);
1422 /* This search must be unindexed (ie traverse in tdb) */
1423 ret = ldb_build_search_req(&req,
1431 test_ldb_search_against_transaction_callback2,
1434 * we don't assert on these return codes until after the search is
1435 * finished, or the clean up will fail because we hold locks.
1438 ret2 = ldb_request(ctx->test_ctx->ldb, req);
1440 if (ret2 == LDB_SUCCESS) {
1441 ret2 = ldb_wait(req->handle, LDB_WAIT_ALL);
1443 assert_int_equal(ret, 0);
1444 assert_int_equal(ret2, 0);
1445 assert_int_equal(ctx->res_count, 2);
1450 static void test_ldb_search_against_transaction(void **state)
1452 struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1453 struct search_test_ctx);
1454 struct search_against_transaction_ctx
1457 .test_ctx = search_test_ctx->ldb_test_ctx
1461 struct ldb_request *req;
1464 struct ldb_dn *base_search_dn;
1466 tevent_loop_allow_nesting(search_test_ctx->ldb_test_ctx->ev);
1469 = ldb_dn_new_fmt(search_test_ctx,
1470 search_test_ctx->ldb_test_ctx->ldb,
1471 "cn=test_search_cn,%s",
1472 search_test_ctx->base_dn);
1473 assert_non_null(base_search_dn);
1476 = ldb_dn_new_fmt(search_test_ctx,
1477 search_test_ctx->ldb_test_ctx->ldb,
1479 search_test_ctx->base_dn);
1480 assert_non_null(ctx.basedn);
1483 /* This search must be indexed (ie no traverse in tdb) */
1484 ret = ldb_build_search_req(&req,
1485 search_test_ctx->ldb_test_ctx->ldb,
1492 test_ldb_search_against_transaction_callback1,
1494 assert_int_equal(ret, 0);
1495 ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req);
1497 if (ret == LDB_SUCCESS) {
1498 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1500 assert_int_equal(ret, 0);
1501 assert_int_equal(ctx.res_count, 2);
1503 pid = waitpid(ctx.child_pid, &wstatus, 0);
1504 assert_int_equal(pid, ctx.child_pid);
1506 assert_true(WIFEXITED(wstatus));
1508 assert_int_equal(WEXITSTATUS(wstatus), 0);
1514 * This test is also complex.
1515 * The purpose is to test if a modify can occur during an ldb_search()
1516 * This would be a failure if if in process
1518 * - (1) ltdb_search() starts and calls back for one entry
1519 * - (2) one of the entries to be matched is modified
1520 * - (1) the indexed search tries to return the modified entry, but
1521 * it is no longer found, either:
1522 * - despite it still matching (dn changed)
1523 * - it no longer matching (attrs changed)
1525 * We also try un-indexed to show that the behaviour differs on this
1526 * point, which it should not (an index should only impact search
1530 struct modify_during_search_test_ctx {
1531 struct ldbtest_ctx *test_ctx;
1534 struct ldb_dn *basedn;
1541 * This purpose of this callback is to trigger a write in
1542 * the child process while a search is in progress.
1544 * In tdb 1.3.12 tdb_traverse_read() take the read transaction lock
1545 * however in ldb 1.1.31 ltdb_search() forgets to take the all-record
1546 * lock (except the very first time) due to a ref-counting bug.
1548 * We assume that if the write will proceed, it will proceed in a 3
1549 * second window after the function is called.
1552 static int test_ldb_modify_during_search_callback1(struct ldb_request *req,
1553 struct ldb_reply *ares)
1558 struct modify_during_search_test_ctx *ctx = req->context;
1559 switch (ares->type) {
1560 case LDB_REPLY_ENTRY:
1562 const struct ldb_val *cn_val
1563 = ldb_dn_get_component_val(ares->message->dn, 0);
1564 const char *cn = (char *)cn_val->data;
1566 if (strcmp(cn, "test_search_cn") == 0) {
1568 } else if (strcmp(cn, "test_search_2_cn") == 0) {
1569 ctx->got_2_cn = true;
1571 if (ctx->res_count == 2) {
1576 case LDB_REPLY_REFERRAL:
1579 case LDB_REPLY_DONE:
1580 return ldb_request_done(req, LDB_SUCCESS);
1584 assert_int_equal(ret, 0);
1586 ctx->child_pid = fork();
1587 if (ctx->child_pid == 0 && ctx->rename) {
1588 TALLOC_CTX *tmp_ctx = NULL;
1589 struct ldb_dn *dn, *new_dn;
1590 TALLOC_FREE(ctx->test_ctx->ldb);
1591 TALLOC_FREE(ctx->test_ctx->ev);
1592 ctx->test_ctx->ev = tevent_context_init(ctx->test_ctx);
1593 if (ctx->test_ctx->ev == NULL) {
1594 exit(LDB_ERR_OPERATIONS_ERROR);
1597 ctx->test_ctx->ldb = ldb_init(ctx->test_ctx,
1599 if (ctx->test_ctx->ldb == NULL) {
1600 exit(LDB_ERR_OPERATIONS_ERROR);
1603 ret = ldb_connect(ctx->test_ctx->ldb,
1604 ctx->test_ctx->dbpath, 0, NULL);
1605 if (ret != LDB_SUCCESS) {
1609 tmp_ctx = talloc_new(ctx->test_ctx);
1610 if (tmp_ctx == NULL) {
1611 exit(LDB_ERR_OPERATIONS_ERROR);
1615 /* Modify the other one */
1616 dn = ldb_dn_new_fmt(tmp_ctx, ctx->test_ctx->ldb,
1617 "cn=test_search_2_cn,"
1618 "dc=search_test_entry");
1620 dn = ldb_dn_new_fmt(tmp_ctx, ctx->test_ctx->ldb,
1621 "cn=test_search_cn,"
1622 "dc=search_test_entry");
1625 exit(LDB_ERR_OPERATIONS_ERROR);
1628 new_dn = ldb_dn_new_fmt(tmp_ctx, ctx->test_ctx->ldb,
1629 "cn=test_search_cn_renamed,"
1630 "dc=search_test_entry");
1631 if (new_dn == NULL) {
1632 exit(LDB_ERR_OPERATIONS_ERROR);
1635 ret = ldb_transaction_start(ctx->test_ctx->ldb);
1640 if (write(pipes[1], "GO", 2) != 2) {
1641 exit(LDB_ERR_OPERATIONS_ERROR);
1644 ret = ldb_rename(ctx->test_ctx->ldb, dn, new_dn);
1649 ret = ldb_transaction_commit(ctx->test_ctx->ldb);
1652 } else if (ctx->child_pid == 0) {
1653 TALLOC_CTX *tmp_ctx = NULL;
1654 struct ldb_message *msg;
1655 struct ldb_message_element *el;
1656 TALLOC_FREE(ctx->test_ctx->ldb);
1657 TALLOC_FREE(ctx->test_ctx->ev);
1658 ctx->test_ctx->ev = tevent_context_init(ctx->test_ctx);
1659 if (ctx->test_ctx->ev == NULL) {
1660 exit(LDB_ERR_OPERATIONS_ERROR);
1663 ctx->test_ctx->ldb = ldb_init(ctx->test_ctx,
1665 if (ctx->test_ctx->ldb == NULL) {
1666 exit(LDB_ERR_OPERATIONS_ERROR);
1669 ret = ldb_connect(ctx->test_ctx->ldb,
1670 ctx->test_ctx->dbpath, 0, NULL);
1671 if (ret != LDB_SUCCESS) {
1675 tmp_ctx = talloc_new(ctx->test_ctx);
1676 if (tmp_ctx == NULL) {
1677 exit(LDB_ERR_OPERATIONS_ERROR);
1680 msg = ldb_msg_new(tmp_ctx);
1682 exit(LDB_ERR_OPERATIONS_ERROR);
1686 /* Modify the other one */
1687 msg->dn = ldb_dn_new_fmt(msg, ctx->test_ctx->ldb,
1688 "cn=test_search_2_cn,"
1689 "dc=search_test_entry");
1691 msg->dn = ldb_dn_new_fmt(msg, ctx->test_ctx->ldb,
1692 "cn=test_search_cn,"
1693 "dc=search_test_entry");
1695 if (msg->dn == NULL) {
1696 exit(LDB_ERR_OPERATIONS_ERROR);
1699 ret = ldb_msg_add_string(msg, "filterAttr", "TRUE");
1701 exit(LDB_ERR_OPERATIONS_ERROR);
1703 el = ldb_msg_find_element(msg, "filterAttr");
1705 exit(LDB_ERR_OPERATIONS_ERROR);
1707 el->flags = LDB_FLAG_MOD_REPLACE;
1709 ret = ldb_transaction_start(ctx->test_ctx->ldb);
1714 if (write(pipes[1], "GO", 2) != 2) {
1715 exit(LDB_ERR_OPERATIONS_ERROR);
1718 ret = ldb_modify(ctx->test_ctx->ldb, msg);
1723 ret = ldb_transaction_commit(ctx->test_ctx->ldb);
1728 * With TDB 1.3.13 and before "tdb: Remove locking from tdb_traverse_read()"
1729 * we will hang here because the child process can not proceed to
1730 * sending the "GO" as it is blocked at ldb_transaction_start().
1733 ret = read(pipes[0], buf, 2);
1734 assert_int_equal(ret, 2);
1741 static void test_ldb_modify_during_search(void **state, bool add_index,
1744 struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1745 struct search_test_ctx);
1746 struct modify_during_search_test_ctx
1749 .test_ctx = search_test_ctx->ldb_test_ctx,
1754 struct ldb_request *req;
1759 struct ldb_message *msg;
1760 struct ldb_dn *indexlist = ldb_dn_new(search_test_ctx,
1761 search_test_ctx->ldb_test_ctx->ldb,
1763 assert_non_null(indexlist);
1765 msg = ldb_msg_new(search_test_ctx);
1766 assert_non_null(msg);
1768 msg->dn = indexlist;
1770 ret = ldb_msg_add_string(msg, "@IDXATTR", "cn");
1771 assert_int_equal(ret, LDB_SUCCESS);
1773 ret = ldb_add(search_test_ctx->ldb_test_ctx->ldb,
1776 assert_int_equal(ret, LDB_SUCCESS);
1779 tevent_loop_allow_nesting(search_test_ctx->ldb_test_ctx->ev);
1782 = ldb_dn_new_fmt(search_test_ctx,
1783 search_test_ctx->ldb_test_ctx->ldb,
1785 search_test_ctx->base_dn);
1786 assert_non_null(ctx.basedn);
1790 * This search must be over multiple items, and should include
1791 * the new name after a rename, to show that it would match
1792 * both before and after that modify
1794 ret = ldb_build_search_req(&req,
1795 search_test_ctx->ldb_test_ctx->ldb,
1799 "(&(!(filterAttr=*))"
1800 "(|(cn=test_search_cn_renamed)"
1801 "(cn=test_search_cn)"
1802 "(cn=test_search_2_cn)"
1807 test_ldb_modify_during_search_callback1,
1809 assert_int_equal(ret, 0);
1810 ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req);
1812 if (ret == LDB_SUCCESS) {
1813 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1815 assert_int_equal(ret, 0);
1816 assert_int_equal(ctx.res_count, 2);
1817 assert_int_equal(ctx.got_cn, true);
1818 assert_int_equal(ctx.got_2_cn, true);
1820 pid = waitpid(ctx.child_pid, &wstatus, 0);
1821 assert_int_equal(pid, ctx.child_pid);
1823 assert_true(WIFEXITED(wstatus));
1825 assert_int_equal(WEXITSTATUS(wstatus), 0);
1830 static void test_ldb_modify_during_indexed_search(void **state)
1832 return test_ldb_modify_during_search(state, true, false);
1835 static void test_ldb_modify_during_unindexed_search(void **state)
1837 return test_ldb_modify_during_search(state, false, false);
1840 static void test_ldb_rename_during_indexed_search(void **state)
1842 return test_ldb_modify_during_search(state, true, true);
1845 static void test_ldb_rename_during_unindexed_search(void **state)
1847 return test_ldb_modify_during_search(state, false, true);
1851 * This test is also complex.
1853 * The purpose is to test if a modify can occur during an ldb_search()
1854 * before the end of the callback
1856 * This would be a failure if if in process
1858 * - (1) ldb_search() starts and calls back for a number of entries
1859 * - (2) an entry in the DB is allowed to change before the callback returns
1860 * - (1) the callback can see the modification
1865 * This purpose of this callback is to trigger a write in
1866 * the child process while a search DONE callback is in progress.
1868 * In ldb 1.1.31 ldb_search() omitted to take a all-record
1869 * lock for the full duration of the search and callbacks
1871 * We assume that if the write will proceed, it will proceed in a 3
1872 * second window after the function is called.
1875 static int test_ldb_modify_during_whole_search_callback1(struct ldb_request *req,
1876 struct ldb_reply *ares)
1881 struct modify_during_search_test_ctx *ctx = req->context;
1882 struct ldb_dn *search_dn;
1883 struct ldb_result *res2;
1885 switch (ares->type) {
1886 case LDB_REPLY_ENTRY:
1887 case LDB_REPLY_REFERRAL:
1890 case LDB_REPLY_DONE:
1895 assert_int_equal(ret, 0);
1897 ctx->child_pid = fork();
1898 if (ctx->child_pid == 0) {
1899 TALLOC_CTX *tmp_ctx = NULL;
1900 struct ldb_message *msg;
1901 struct ldb_message_element *el;
1902 TALLOC_FREE(ctx->test_ctx->ldb);
1903 TALLOC_FREE(ctx->test_ctx->ev);
1904 ctx->test_ctx->ev = tevent_context_init(ctx->test_ctx);
1905 if (ctx->test_ctx->ev == NULL) {
1906 exit(LDB_ERR_OPERATIONS_ERROR);
1909 ctx->test_ctx->ldb = ldb_init(ctx->test_ctx,
1911 if (ctx->test_ctx->ldb == NULL) {
1912 exit(LDB_ERR_OPERATIONS_ERROR);
1915 ret = ldb_connect(ctx->test_ctx->ldb,
1916 ctx->test_ctx->dbpath, 0, NULL);
1917 if (ret != LDB_SUCCESS) {
1921 tmp_ctx = talloc_new(ctx->test_ctx);
1922 if (tmp_ctx == NULL) {
1923 exit(LDB_ERR_OPERATIONS_ERROR);
1926 msg = ldb_msg_new(tmp_ctx);
1928 exit(LDB_ERR_OPERATIONS_ERROR);
1931 msg->dn = ldb_dn_new_fmt(msg, ctx->test_ctx->ldb,
1932 "cn=test_search_cn,"
1933 "dc=search_test_entry");
1934 if (msg->dn == NULL) {
1935 exit(LDB_ERR_OPERATIONS_ERROR);
1938 ret = ldb_msg_add_string(msg, "filterAttr", "TRUE");
1940 exit(LDB_ERR_OPERATIONS_ERROR);
1942 el = ldb_msg_find_element(msg, "filterAttr");
1944 exit(LDB_ERR_OPERATIONS_ERROR);
1946 el->flags = LDB_FLAG_MOD_REPLACE;
1948 ret = ldb_transaction_start(ctx->test_ctx->ldb);
1953 if (write(pipes[1], "GO", 2) != 2) {
1954 exit(LDB_ERR_OPERATIONS_ERROR);
1957 ret = ldb_modify(ctx->test_ctx->ldb, msg);
1962 ret = ldb_transaction_commit(ctx->test_ctx->ldb);
1966 ret = read(pipes[0], buf, 2);
1967 assert_int_equal(ret, 2);
1972 * If writes are not blocked until after this function, we
1973 * will be able to successfully search for this modification
1977 search_dn = ldb_dn_new_fmt(ares, ctx->test_ctx->ldb,
1978 "cn=test_search_cn,"
1979 "dc=search_test_entry");
1981 ret = ldb_search(ctx->test_ctx->ldb, ares,
1982 &res2, search_dn, LDB_SCOPE_BASE, NULL,
1986 * We do this in an unusual order, because if we fail an assert before
1987 * ldb_request_done(), we will also fail to clean up as we hold locks.
1990 res_count = res2->count;
1991 ldb_request_done(req, LDB_SUCCESS);
1992 assert_int_equal(ret, 0);
1994 /* We should not have got the result */
1995 assert_int_equal(res_count, 0);
2000 static void test_ldb_modify_during_whole_search(void **state)
2002 struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
2003 struct search_test_ctx);
2004 struct modify_during_search_test_ctx
2007 .test_ctx = search_test_ctx->ldb_test_ctx,
2011 struct ldb_request *req;
2014 struct ldb_dn *search_dn;
2015 struct ldb_result *res2;
2017 tevent_loop_allow_nesting(search_test_ctx->ldb_test_ctx->ev);
2020 = ldb_dn_new_fmt(search_test_ctx,
2021 search_test_ctx->ldb_test_ctx->ldb,
2023 search_test_ctx->base_dn);
2024 assert_non_null(ctx.basedn);
2028 * The search just needs to call DONE, we don't care about the
2029 * contents of the search for this test
2031 ret = ldb_build_search_req(&req,
2032 search_test_ctx->ldb_test_ctx->ldb,
2036 "(&(!(filterAttr=*))"
2037 "(cn=test_search_cn))",
2041 test_ldb_modify_during_whole_search_callback1,
2043 assert_int_equal(ret, 0);
2044 ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req);
2046 if (ret == LDB_SUCCESS) {
2047 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
2049 assert_int_equal(ret, 0);
2051 pid = waitpid(ctx.child_pid, &wstatus, 0);
2052 assert_int_equal(pid, ctx.child_pid);
2054 assert_true(WIFEXITED(wstatus));
2056 assert_int_equal(WEXITSTATUS(wstatus), 0);
2059 * If writes are blocked until after the search function, we
2060 * will be able to successfully search for this modification
2064 search_dn = ldb_dn_new_fmt(search_test_ctx,
2065 search_test_ctx->ldb_test_ctx->ldb,
2066 "cn=test_search_cn,"
2067 "dc=search_test_entry");
2069 ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
2071 &res2, search_dn, LDB_SCOPE_BASE, NULL,
2073 assert_int_equal(ret, 0);
2075 /* We got the result */
2076 assert_int_equal(res2->count, 1);
2080 * This test is also complex.
2082 * The purpose is to test if a modify can occur during an ldb_search()
2083 * before the request is destroyed with TALLOC_FREE()
2085 * This would be a failure if in process
2087 * - (1) ldb_search() starts and waits
2088 * - (2) an entry in the DB is allowed to change before the ldb_wait() is called
2089 * - (1) the original process can see the modification before the TALLOC_FREE()
2090 * also we check that
2091 * - (1) the original process can see the modification after the TALLOC_FREE()
2096 * This purpose of this callback is to trigger a write in
2097 * the child process before the ldb_wait() is called
2099 * In ldb 1.1.31 ldb_search() omitted to take a all-record
2100 * lock for the full duration of the search and callbacks
2102 * We assume that if the write will proceed, it will proceed in a 3
2103 * second window after the function is called.
2106 static int test_ldb_modify_before_ldb_wait_callback1(struct ldb_request *req,
2107 struct ldb_reply *ares)
2109 switch (ares->type) {
2110 case LDB_REPLY_ENTRY:
2111 case LDB_REPLY_REFERRAL:
2114 case LDB_REPLY_DONE:
2118 return ldb_request_done(req, LDB_SUCCESS);
2121 static void test_ldb_modify_before_ldb_wait(void **state)
2123 struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
2124 struct search_test_ctx);
2126 struct ldb_request *req;
2129 struct ldb_dn *search_dn;
2130 struct ldb_dn *basedn;
2131 struct ldb_result *res2;
2137 search_dn = ldb_dn_new_fmt(search_test_ctx,
2138 search_test_ctx->ldb_test_ctx->ldb,
2139 "cn=test_search_cn,"
2140 "dc=search_test_entry");
2141 assert_non_null(search_dn);
2143 basedn = ldb_dn_new_fmt(search_test_ctx,
2144 search_test_ctx->ldb_test_ctx->ldb,
2146 search_test_ctx->base_dn);
2147 assert_non_null(basedn);
2150 * The search just needs to call DONE, we don't care about the
2151 * contents of the search for this test
2153 ret = ldb_build_search_req(&req,
2154 search_test_ctx->ldb_test_ctx->ldb,
2158 "(&(!(filterAttr=*))"
2159 "(cn=test_search_cn))",
2163 test_ldb_modify_before_ldb_wait_callback1,
2165 assert_int_equal(ret, 0);
2166 ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req);
2169 assert_int_equal(ret, 0);
2172 if (child_pid == 0) {
2173 TALLOC_CTX *tmp_ctx = NULL;
2174 struct ldb_message *msg;
2175 struct ldb_message_element *el;
2176 TALLOC_FREE(search_test_ctx->ldb_test_ctx->ldb);
2177 TALLOC_FREE(search_test_ctx->ldb_test_ctx->ev);
2178 search_test_ctx->ldb_test_ctx->ev = tevent_context_init(search_test_ctx->ldb_test_ctx);
2179 if (search_test_ctx->ldb_test_ctx->ev == NULL) {
2180 exit(LDB_ERR_OPERATIONS_ERROR);
2183 search_test_ctx->ldb_test_ctx->ldb = ldb_init(search_test_ctx->ldb_test_ctx,
2184 search_test_ctx->ldb_test_ctx->ev);
2185 if (search_test_ctx->ldb_test_ctx->ldb == NULL) {
2186 exit(LDB_ERR_OPERATIONS_ERROR);
2189 ret = ldb_connect(search_test_ctx->ldb_test_ctx->ldb,
2190 search_test_ctx->ldb_test_ctx->dbpath, 0, NULL);
2191 if (ret != LDB_SUCCESS) {
2195 tmp_ctx = talloc_new(search_test_ctx->ldb_test_ctx);
2196 if (tmp_ctx == NULL) {
2197 exit(LDB_ERR_OPERATIONS_ERROR);
2200 msg = ldb_msg_new(tmp_ctx);
2202 exit(LDB_ERR_OPERATIONS_ERROR);
2206 * We must re-create this DN from a string to ensure
2207 * it does not reference the now-gone LDB context of
2210 msg->dn = ldb_dn_new_fmt(search_test_ctx,
2211 search_test_ctx->ldb_test_ctx->ldb,
2212 "cn=test_search_cn,"
2213 "dc=search_test_entry");
2215 if (msg->dn == NULL) {
2216 exit(LDB_ERR_OPERATIONS_ERROR);
2219 ret = ldb_msg_add_string(msg, "filterAttr", "TRUE");
2221 exit(LDB_ERR_OPERATIONS_ERROR);
2223 el = ldb_msg_find_element(msg, "filterAttr");
2225 exit(LDB_ERR_OPERATIONS_ERROR);
2227 el->flags = LDB_FLAG_MOD_REPLACE;
2229 ret = ldb_transaction_start(search_test_ctx->ldb_test_ctx->ldb);
2234 if (write(pipes[1], "GO", 2) != 2) {
2235 exit(LDB_ERR_OPERATIONS_ERROR);
2238 ret = ldb_modify(search_test_ctx->ldb_test_ctx->ldb, msg);
2243 ret = ldb_transaction_commit(search_test_ctx->ldb_test_ctx->ldb);
2247 ret = read(pipes[0], buf, 2);
2248 assert_int_equal(ret, 2);
2253 * If writes are not blocked until after the (never called) ldb_wait(), we
2254 * will be able to successfully search for this modification
2258 ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb, search_test_ctx,
2259 &res2, search_dn, LDB_SCOPE_BASE, NULL,
2263 * We avoid making assertions before TALLOC_FREE()ing the request,
2264 * lest the assert fail and mess with the clean-up because we still
2267 res_count = res2->count;
2270 /* We should not have got the result */
2271 assert_int_equal(res_count, 0);
2272 assert_int_equal(ret, 0);
2274 pid = waitpid(child_pid, &wstatus, 0);
2275 assert_int_equal(pid, child_pid);
2277 assert_true(WIFEXITED(wstatus));
2279 assert_int_equal(WEXITSTATUS(wstatus), 0);
2282 * If writes are blocked until after the search request was freed, we
2283 * will be able to successfully search for this modification
2287 search_dn = ldb_dn_new_fmt(search_test_ctx,
2288 search_test_ctx->ldb_test_ctx->ldb,
2289 "cn=test_search_cn,"
2290 "dc=search_test_entry");
2292 ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
2294 &res2, search_dn, LDB_SCOPE_BASE, NULL,
2296 assert_int_equal(ret, 0);
2298 /* We got the result */
2299 assert_int_equal(res2->count, 1);
2302 static int ldb_case_test_setup(void **state)
2305 struct ldb_ldif *ldif;
2306 struct ldbtest_ctx *ldb_test_ctx;
2307 const char *attrs_ldif = \
2309 "cn: CASE_INSENSITIVE\n"
2311 struct keyval kvs[] = {
2312 { "cn", "CaseInsensitiveValue" },
2313 { "uid", "CaseSensitiveValue" },
2318 ldbtest_setup((void **) &ldb_test_ctx);
2320 while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &attrs_ldif))) {
2321 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
2322 assert_int_equal(ret, LDB_SUCCESS);
2325 ldb_test_add_data(ldb_test_ctx,
2327 "cn=CaseInsensitiveValue",
2330 *state = ldb_test_ctx;
2334 static int ldb_case_test_teardown(void **state)
2337 struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
2338 struct ldbtest_ctx);
2340 struct ldb_dn *del_dn;
2342 del_dn = ldb_dn_new_fmt(ldb_test_ctx,
2345 assert_non_null(del_dn);
2347 ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
2348 assert_int_equal(ret, LDB_SUCCESS);
2350 assert_dn_doesnt_exist(ldb_test_ctx,
2353 ldb_test_remove_data(ldb_test_ctx, ldb_test_ctx,
2354 "cn=CaseInsensitiveValue");
2356 ldbtest_teardown((void **) &ldb_test_ctx);
2360 static void test_ldb_attrs_case_insensitive(void **state)
2363 struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
2364 struct ldbtest_ctx);
2366 /* cn matches exact case */
2367 cnt = sub_search_count(ldb_test_ctx, "", "cn=CaseInsensitiveValue");
2368 assert_int_equal(cnt, 1);
2370 /* cn matches lower case */
2371 cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2372 assert_int_equal(cnt, 1);
2374 /* uid matches exact case */
2375 cnt = sub_search_count(ldb_test_ctx, "", "uid=CaseSensitiveValue");
2376 assert_int_equal(cnt, 1);
2378 /* uid does not match lower case */
2379 cnt = sub_search_count(ldb_test_ctx, "", "uid=casesensitivevalue");
2380 assert_int_equal(cnt, 0);
2383 static struct ldb_schema_attribute cn_attr_1;
2384 static struct ldb_schema_attribute cn_attr_2;
2385 static struct ldb_schema_attribute default_attr;
2388 override the name to attribute handler function
2390 static const struct ldb_schema_attribute *ldb_test_attribute_handler_override(struct ldb_context *ldb,
2394 if (private_data != NULL && ldb_attr_cmp(name, "cn") == 0) {
2396 } else if (private_data == NULL && ldb_attr_cmp(name, "cn") == 0) {
2398 } else if (ldb_attr_cmp(name, "uid") == 0) {
2401 return &default_attr;
2404 static void test_ldb_attrs_case_handler(void **state)
2408 const struct ldb_schema_syntax *syntax;
2410 struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
2411 struct ldbtest_ctx);
2412 struct ldb_context *ldb = ldb_test_ctx->ldb;
2414 /* cn matches lower case */
2415 cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2416 assert_int_equal(cnt, 1);
2418 syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_OCTET_STRING);
2419 assert_non_null(syntax);
2421 ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb,
2423 syntax, &default_attr);
2424 assert_int_equal(ret, LDB_SUCCESS);
2426 syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_OCTET_STRING);
2427 assert_non_null(syntax);
2429 ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb,
2431 syntax, &cn_attr_1);
2432 assert_int_equal(ret, LDB_SUCCESS);
2435 * Set an attribute handler, which will fail to match as we
2436 * force case sensitive
2438 ldb_schema_attribute_set_override_handler(ldb,
2439 ldb_test_attribute_handler_override,
2442 /* cn does not matche lower case */
2443 cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2444 assert_int_equal(cnt, 0);
2446 syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_DIRECTORY_STRING);
2447 assert_non_null(syntax);
2449 ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb,
2451 syntax, &cn_attr_2);
2452 assert_int_equal(ret, LDB_SUCCESS);
2455 * Set an attribute handler, which will match as we
2456 * force case insensitive
2458 ldb_schema_attribute_set_override_handler(ldb,
2459 ldb_test_attribute_handler_override,
2462 /* cn matches lower case */
2463 cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2464 assert_int_equal(cnt, 1);
2469 static void test_ldb_attrs_index_handler(void **state)
2473 const struct ldb_schema_syntax *syntax;
2474 struct ldb_ldif *ldif;
2476 const char *index_ldif = \
2481 struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
2482 struct ldbtest_ctx);
2483 struct ldb_context *ldb = ldb_test_ctx->ldb;
2485 /* cn matches lower case */
2486 cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2487 assert_int_equal(cnt, 1);
2489 syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_OCTET_STRING);
2490 assert_non_null(syntax);
2492 ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb,
2494 syntax, &cn_attr_1);
2495 assert_int_equal(ret, LDB_SUCCESS);
2497 syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_DIRECTORY_STRING);
2498 assert_non_null(syntax);
2500 ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb,
2501 "cn", LDB_ATTR_FLAG_INDEXED,
2502 syntax, &cn_attr_2);
2503 assert_int_equal(ret, LDB_SUCCESS);
2506 * Set an attribute handler
2508 ldb_schema_attribute_set_override_handler(ldb,
2509 ldb_test_attribute_handler_override,
2512 /* cn matches lower case */
2513 cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2514 assert_int_equal(cnt, 1);
2516 /* Add the index (actually any modify will do) */
2517 while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &index_ldif))) {
2518 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
2519 assert_int_equal(ret, LDB_SUCCESS);
2522 ldb_schema_set_override_indexlist(ldb, false);
2524 /* cn does match as there is an index now */
2525 cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2526 assert_int_equal(cnt, 1);
2529 * Set an attribute handler, which will later fail to match as we
2530 * didn't re-index the DB
2532 ldb_schema_attribute_set_override_handler(ldb,
2533 ldb_test_attribute_handler_override,
2537 * cn does not match as we changed the case sensitivity, but
2540 * This shows that the override is in control
2542 cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2543 assert_int_equal(cnt, 0);
2547 static int ldb_case_attrs_index_test_teardown(void **state)
2550 struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
2551 struct ldbtest_ctx);
2552 struct ldb_dn *del_dn;
2554 del_dn = ldb_dn_new_fmt(ldb_test_ctx,
2557 assert_non_null(del_dn);
2559 ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
2560 if (ret != LDB_ERR_NO_SUCH_OBJECT) {
2561 assert_int_equal(ret, LDB_SUCCESS);
2564 assert_dn_doesnt_exist(ldb_test_ctx,
2567 ldb_case_test_teardown(state);
2572 struct rename_test_ctx {
2573 struct ldbtest_ctx *ldb_test_ctx;
2575 struct ldb_dn *basedn;
2576 const char *str_basedn;
2578 const char *teardown_dn;
2581 static int ldb_rename_test_setup(void **state)
2583 struct ldbtest_ctx *ldb_test_ctx;
2584 struct rename_test_ctx *rename_test_ctx;
2585 const char *strdn = "dc=rename_test_entry_from";
2587 ldbtest_setup((void **) &ldb_test_ctx);
2589 rename_test_ctx = talloc(ldb_test_ctx, struct rename_test_ctx);
2590 assert_non_null(rename_test_ctx);
2591 rename_test_ctx->ldb_test_ctx = ldb_test_ctx;
2592 assert_non_null(rename_test_ctx->ldb_test_ctx);
2594 rename_test_ctx->basedn = ldb_dn_new_fmt(rename_test_ctx,
2595 rename_test_ctx->ldb_test_ctx->ldb,
2597 assert_non_null(rename_test_ctx->basedn);
2599 rename_test_ctx->str_basedn = strdn;
2600 rename_test_ctx->teardown_dn = strdn;
2602 add_dn_with_cn(ldb_test_ctx,
2603 rename_test_ctx->basedn,
2604 "test_rename_cn_val");
2606 *state = rename_test_ctx;
2610 static int ldb_rename_test_teardown(void **state)
2613 struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(*state,
2614 struct rename_test_ctx);
2615 struct ldbtest_ctx *ldb_test_ctx;
2616 struct ldb_dn *del_dn;
2618 ldb_test_ctx = rename_test_ctx->ldb_test_ctx;
2620 del_dn = ldb_dn_new_fmt(rename_test_ctx,
2621 rename_test_ctx->ldb_test_ctx->ldb,
2622 "%s", rename_test_ctx->teardown_dn);
2623 assert_non_null(del_dn);
2625 ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
2626 assert_int_equal(ret, LDB_SUCCESS);
2628 assert_dn_doesnt_exist(ldb_test_ctx,
2629 rename_test_ctx->teardown_dn);
2631 ldbtest_teardown((void **) &ldb_test_ctx);
2635 static void test_ldb_rename(void **state)
2637 struct rename_test_ctx *rename_test_ctx =
2638 talloc_get_type_abort(*state, struct rename_test_ctx);
2640 const char *str_new_dn = "dc=rename_test_entry_to";
2641 struct ldb_dn *new_dn;
2643 new_dn = ldb_dn_new_fmt(rename_test_ctx,
2644 rename_test_ctx->ldb_test_ctx->ldb,
2646 assert_non_null(new_dn);
2648 ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
2649 rename_test_ctx->basedn,
2651 assert_int_equal(ret, LDB_SUCCESS);
2653 assert_dn_exists(rename_test_ctx->ldb_test_ctx, str_new_dn);
2654 assert_dn_doesnt_exist(rename_test_ctx->ldb_test_ctx,
2655 rename_test_ctx->str_basedn);
2656 rename_test_ctx->teardown_dn = str_new_dn;
2658 /* FIXME - test the values which didn't change */
2661 static void test_ldb_rename_from_doesnt_exist(void **state)
2663 struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(
2665 struct rename_test_ctx);
2667 const char *str_new_dn = "dc=rename_test_entry_to";
2668 const char *str_bad_old_dn = "dc=rename_test_no_such_entry";
2669 struct ldb_dn *new_dn;
2670 struct ldb_dn *bad_old_dn;
2672 new_dn = ldb_dn_new_fmt(rename_test_ctx,
2673 rename_test_ctx->ldb_test_ctx->ldb,
2675 assert_non_null(new_dn);
2677 bad_old_dn = ldb_dn_new_fmt(rename_test_ctx,
2678 rename_test_ctx->ldb_test_ctx->ldb,
2679 "%s", str_bad_old_dn);
2680 assert_non_null(bad_old_dn);
2682 assert_dn_doesnt_exist(rename_test_ctx->ldb_test_ctx,
2685 ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
2686 bad_old_dn, new_dn);
2687 assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT);
2689 assert_dn_doesnt_exist(rename_test_ctx->ldb_test_ctx,
2693 static void test_ldb_rename_to_exists(void **state)
2695 struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(
2697 struct rename_test_ctx);
2699 const char *str_new_dn = "dc=rename_test_already_exists";
2700 struct ldb_dn *new_dn;
2702 new_dn = ldb_dn_new_fmt(rename_test_ctx,
2703 rename_test_ctx->ldb_test_ctx->ldb,
2705 assert_non_null(new_dn);
2707 add_dn_with_cn(rename_test_ctx->ldb_test_ctx,
2709 "test_rename_cn_val");
2711 ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
2712 rename_test_ctx->basedn,
2714 assert_int_equal(ret, LDB_ERR_ENTRY_ALREADY_EXISTS);
2716 /* Old object must still exist */
2717 assert_dn_exists(rename_test_ctx->ldb_test_ctx,
2718 rename_test_ctx->str_basedn);
2720 ret = ldb_delete(rename_test_ctx->ldb_test_ctx->ldb,
2722 assert_int_equal(ret, LDB_SUCCESS);
2724 assert_dn_exists(rename_test_ctx->ldb_test_ctx,
2725 rename_test_ctx->teardown_dn);
2728 static void test_ldb_rename_self(void **state)
2730 struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(
2732 struct rename_test_ctx);
2735 /* Oddly enough, this is a success in ldb.. */
2736 ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
2737 rename_test_ctx->basedn,
2738 rename_test_ctx->basedn);
2739 assert_int_equal(ret, LDB_SUCCESS);
2741 /* Old object must still exist */
2742 assert_dn_exists(rename_test_ctx->ldb_test_ctx,
2743 rename_test_ctx->str_basedn);
2746 static void test_ldb_rename_dn_case_change(void **state)
2748 struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(
2750 struct rename_test_ctx);
2753 struct ldb_dn *new_dn;
2756 str_new_dn = talloc_strdup(rename_test_ctx, rename_test_ctx->str_basedn);
2757 assert_non_null(str_new_dn);
2758 for (i = 0; str_new_dn[i]; i++) {
2759 str_new_dn[i] = toupper(str_new_dn[i]);
2762 new_dn = ldb_dn_new_fmt(rename_test_ctx,
2763 rename_test_ctx->ldb_test_ctx->ldb,
2765 assert_non_null(new_dn);
2767 ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
2768 rename_test_ctx->basedn,
2770 assert_int_equal(ret, LDB_SUCCESS);
2772 /* DNs are case insensitive, so both searches will match */
2773 assert_dn_exists(rename_test_ctx->ldb_test_ctx, str_new_dn);
2774 assert_dn_exists(rename_test_ctx->ldb_test_ctx,
2775 rename_test_ctx->str_basedn);
2776 /* FIXME - test the values didn't change */
2779 int main(int argc, const char **argv)
2781 const struct CMUnitTest tests[] = {
2782 cmocka_unit_test_setup_teardown(test_connect,
2783 ldbtest_noconn_setup,
2784 ldbtest_noconn_teardown),
2785 cmocka_unit_test_setup_teardown(test_ldb_add,
2788 cmocka_unit_test_setup_teardown(test_ldb_search,
2791 cmocka_unit_test_setup_teardown(test_ldb_del,
2794 cmocka_unit_test_setup_teardown(test_ldb_del_noexist,
2797 cmocka_unit_test_setup_teardown(test_ldb_handle,
2800 cmocka_unit_test_setup_teardown(test_ldb_build_search_req,
2803 cmocka_unit_test_setup_teardown(test_transactions,
2806 cmocka_unit_test_setup_teardown(test_ldb_modify_add_key,
2807 ldb_modify_test_setup,
2808 ldb_modify_test_teardown),
2809 cmocka_unit_test_setup_teardown(test_ldb_modify_extend_key,
2810 ldb_modify_test_setup,
2811 ldb_modify_test_teardown),
2812 cmocka_unit_test_setup_teardown(test_ldb_modify_add_key_noval,
2813 ldb_modify_test_setup,
2814 ldb_modify_test_teardown),
2815 cmocka_unit_test_setup_teardown(test_ldb_modify_replace_key,
2816 ldb_modify_test_setup,
2817 ldb_modify_test_teardown),
2818 cmocka_unit_test_setup_teardown(test_ldb_modify_replace_noexist_key,
2819 ldb_modify_test_setup,
2820 ldb_modify_test_teardown),
2821 cmocka_unit_test_setup_teardown(test_ldb_modify_replace_zero_vals,
2822 ldb_modify_test_setup,
2823 ldb_modify_test_teardown),
2824 cmocka_unit_test_setup_teardown(test_ldb_modify_replace_noexist_key_zero_vals,
2825 ldb_modify_test_setup,
2826 ldb_modify_test_teardown),
2827 cmocka_unit_test_setup_teardown(test_ldb_modify_del_key,
2828 ldb_modify_test_setup,
2829 ldb_modify_test_teardown),
2830 cmocka_unit_test_setup_teardown(test_ldb_modify_del_keyval,
2831 ldb_modify_test_setup,
2832 ldb_modify_test_teardown),
2833 cmocka_unit_test_setup_teardown(test_search_match_none,
2834 ldb_search_test_setup,
2835 ldb_search_test_teardown),
2836 cmocka_unit_test_setup_teardown(test_search_match_one,
2837 ldb_search_test_setup,
2838 ldb_search_test_teardown),
2839 cmocka_unit_test_setup_teardown(test_search_match_filter,
2840 ldb_search_test_setup,
2841 ldb_search_test_teardown),
2842 cmocka_unit_test_setup_teardown(test_search_match_both,
2843 ldb_search_test_setup,
2844 ldb_search_test_teardown),
2845 cmocka_unit_test_setup_teardown(test_search_match_basedn,
2846 ldb_search_test_setup,
2847 ldb_search_test_teardown),
2848 cmocka_unit_test_setup_teardown(test_ldb_search_against_transaction,
2849 ldb_search_test_setup,
2850 ldb_search_test_teardown),
2851 cmocka_unit_test_setup_teardown(test_ldb_modify_during_unindexed_search,
2852 ldb_search_test_setup,
2853 ldb_search_test_teardown),
2854 cmocka_unit_test_setup_teardown(test_ldb_modify_during_indexed_search,
2855 ldb_search_test_setup,
2856 ldb_search_test_teardown),
2857 cmocka_unit_test_setup_teardown(test_ldb_rename_during_unindexed_search,
2858 ldb_search_test_setup,
2859 ldb_search_test_teardown),
2860 cmocka_unit_test_setup_teardown(test_ldb_rename_during_indexed_search,
2861 ldb_search_test_setup,
2862 ldb_search_test_teardown),
2863 cmocka_unit_test_setup_teardown(test_ldb_modify_during_whole_search,
2864 ldb_search_test_setup,
2865 ldb_search_test_teardown),
2866 cmocka_unit_test_setup_teardown(test_ldb_modify_before_ldb_wait,
2867 ldb_search_test_setup,
2868 ldb_search_test_teardown),
2869 cmocka_unit_test_setup_teardown(test_ldb_attrs_case_insensitive,
2870 ldb_case_test_setup,
2871 ldb_case_test_teardown),
2872 cmocka_unit_test_setup_teardown(test_ldb_attrs_case_handler,
2873 ldb_case_test_setup,
2874 ldb_case_test_teardown),
2875 cmocka_unit_test_setup_teardown(test_ldb_attrs_index_handler,
2876 ldb_case_test_setup,
2877 ldb_case_attrs_index_test_teardown),
2878 cmocka_unit_test_setup_teardown(test_ldb_rename,
2879 ldb_rename_test_setup,
2880 ldb_rename_test_teardown),
2881 cmocka_unit_test_setup_teardown(test_ldb_rename_from_doesnt_exist,
2882 ldb_rename_test_setup,
2883 ldb_rename_test_teardown),
2884 cmocka_unit_test_setup_teardown(test_ldb_rename_to_exists,
2885 ldb_rename_test_setup,
2886 ldb_rename_test_teardown),
2887 cmocka_unit_test_setup_teardown(test_ldb_rename_self,
2888 ldb_rename_test_setup,
2889 ldb_rename_test_teardown),
2890 cmocka_unit_test_setup_teardown(test_ldb_rename_dn_case_change,
2891 ldb_rename_test_setup,
2892 ldb_rename_test_teardown),
2895 return cmocka_run_group_tests(tests, NULL, NULL);