ldb/tests: avoid 'return void_function();' which isn't portable
[Samba.git] / lib / ldb / tests / ldb_mod_op_test.c
blobd024ab66e3e9a6fc293a1c6c408f0bb9e4ce6adb
1 /*
2 * from cmocka.c:
3 * These headers or their equivalents should be included prior to
4 * including
5 * this header file.
7 * #include <stdarg.h>
8 * #include <stddef.h>
9 * #include <setjmp.h>
11 * This allows test applications to use custom definitions of C standard
12 * library functions and types.
14 #include <stdarg.h>
15 #include <stddef.h>
16 #include <setjmp.h>
17 #include <cmocka.h>
19 #include <errno.h>
20 #include <unistd.h>
21 #include <talloc.h>
23 #define TEVENT_DEPRECATED 1
24 #include <tevent.h>
26 #include <ldb.h>
27 #include <ldb_module.h>
28 #include <ldb_private.h>
29 #include <string.h>
30 #include <ctype.h>
32 #include <sys/wait.h>
35 #define DEFAULT_BE "tdb"
37 #ifndef TEST_BE
38 #define TEST_BE DEFAULT_BE
39 #endif /* TEST_BE */
41 struct ldbtest_ctx {
42 struct tevent_context *ev;
43 struct ldb_context *ldb;
45 const char *dbfile;
46 const char *lockfile; /* lockfile is separate */
48 const char *dbpath;
51 static void unlink_old_db(struct ldbtest_ctx *test_ctx)
53 int ret;
55 errno = 0;
56 ret = unlink(test_ctx->lockfile);
57 if (ret == -1 && errno != ENOENT) {
58 fail();
61 errno = 0;
62 ret = unlink(test_ctx->dbfile);
63 if (ret == -1 && errno != ENOENT) {
64 fail();
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",
85 test_ctx->dbfile);
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);
93 *state = test_ctx;
94 return 0;
97 static int ldbtest_noconn_teardown(void **state)
99 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
100 struct ldbtest_ctx);
102 unlink_old_db(test_ctx);
103 talloc_free(test_ctx);
104 return 0;
107 static void test_connect(void **state)
109 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
110 struct ldbtest_ctx);
111 int ret;
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);
121 int ret;
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);
132 return msg;
135 static void test_ldif_message(void **state)
137 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
138 struct ldbtest_ctx);
139 char *got_ldif;
140 const char *expected_ldif =
141 "dn: dc=samba,dc=org\n"
142 "changetype: add\n"
143 "public: key\n"
144 "supersecret: password\n"
145 "binary:: //8=\n"
146 "\n";
148 struct ldb_message *msg = get_test_ldb_message(test_ctx,
149 test_ctx->ldb);
151 got_ldif = ldb_ldif_message_string(test_ctx->ldb,
152 test_ctx,
153 LDB_CHANGETYPE_ADD,
154 msg);
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,
162 struct ldbtest_ctx);
163 int ret;
164 char *got_ldif;
165 const char *expected_ldif =
166 "dn: dc=samba,dc=org\n"
167 "changetype: add\n"
168 "public: key\n"
169 "# supersecret::: REDACTED SECRET ATTRIBUTE\n"
170 "binary:: //8=\n"
171 "\n";
173 const char *secret_attrs[] = {
174 "supersecret",
175 NULL
178 struct ldb_message *msg = ldb_msg_new(test_ctx);
180 ldb_set_opaque(test_ctx->ldb,
181 LDB_SECRET_ATTRIBUTE_LIST_OPAQUE,
182 secret_attrs);
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,
194 test_ctx,
195 LDB_CHANGETYPE_ADD,
196 msg);
197 assert_string_equal(got_ldif, expected_ldif);
198 TALLOC_FREE(got_ldif);
199 assert_int_equal(ret, 0);
202 static int ldbtest_setup(void **state)
204 struct ldbtest_ctx *test_ctx;
205 int ret;
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);
212 *state = test_ctx;
213 return 0;
216 static int ldbtest_teardown(void **state)
218 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
219 struct ldbtest_ctx);
220 ldbtest_noconn_teardown((void **) &test_ctx);
221 return 0;
224 static void test_ldb_add(void **state)
226 int ret;
227 struct ldb_message *msg;
228 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
229 struct ldbtest_ctx);
230 TALLOC_CTX *tmp_ctx;
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)
252 int ret;
253 struct ldb_message *msg;
254 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
255 struct ldbtest_ctx);
256 TALLOC_CTX *tmp_ctx;
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);
276 msg->dn = basedn;
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);
291 msg->dn = basedn2;
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)
321 TALLOC_CTX *tmp_ctx;
322 struct ldb_dn *basedn;
323 struct ldb_result *result = NULL;
324 int ret;
325 int count;
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);
340 return count;
343 static int sub_search_count(struct ldbtest_ctx *test_ctx,
344 const char *base_dn,
345 const char *filter)
347 TALLOC_CTX *tmp_ctx;
348 struct ldb_dn *basedn;
349 struct ldb_result *result = NULL;
350 int ret;
351 int count;
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);
366 return count;
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
371 * line
373 static void assert_dn_exists(struct ldbtest_ctx *test_ctx,
374 const char *entry_dn)
376 int count;
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)
385 int count;
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,
392 struct ldb_dn *dn,
393 const char *cn_value)
395 int ret;
396 TALLOC_CTX *tmp_ctx;
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);
407 msg->dn = dn;
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)
422 int ret;
423 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
424 struct ldbtest_ctx);
425 const char *basedn = "dc=ldb_del_test";
426 struct ldb_dn *dn;
428 dn = ldb_dn_new_fmt(test_ctx, test_ctx->ldb, "%s", basedn);
429 assert_non_null(dn);
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,
442 struct ldbtest_ctx);
443 struct ldb_dn *basedn;
444 int ret;
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)
455 int ret;
456 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
457 struct ldbtest_ctx);
458 TALLOC_CTX *tmp_ctx;
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,
478 NULL);
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,
489 request);
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)
506 int ret;
507 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
508 struct ldbtest_ctx);
509 TALLOC_CTX *tmp_ctx;
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,
529 NULL);
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,
544 request);
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,
554 const char *key,
555 const char *val)
557 int ret;
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);
572 talloc_free(msg);
575 static struct ldb_result *get_keyval(struct ldbtest_ctx *test_ctx,
576 const char *key,
577 const char *val)
579 int ret;
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);
590 return result;
593 static void test_transactions(void **state)
595 int ret;
596 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
597 struct ldbtest_ctx);
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 static void test_nested_transactions(void **state)
631 int ret;
632 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
633 struct ldbtest_ctx);
634 struct ldb_result *res;
636 /* start lev-0 transaction */
637 ret = ldb_transaction_start(test_ctx->ldb);
638 assert_int_equal(ret, 0);
640 add_keyval(test_ctx, "vegetable", "carrot");
643 /* start another lev-1 nested transaction */
644 ret = ldb_transaction_start(test_ctx->ldb);
645 assert_int_equal(ret, 0);
647 add_keyval(test_ctx, "fruit", "apple");
649 /* abort lev-1 nested transaction */
650 ret = ldb_transaction_cancel(test_ctx->ldb);
651 assert_int_equal(ret, 0);
653 /* commit lev-0 transaction */
654 ret = ldb_transaction_commit(test_ctx->ldb);
655 assert_int_equal(ret, 0);
657 res = get_keyval(test_ctx, "vegetable", "carrot");
658 assert_non_null(res);
659 assert_int_equal(res->count, 1);
661 /* This documents the current ldb behaviour, i.e. nested
662 * transactions are not supported. And the cancellation of the nested
663 * transaction has no effect.
665 res = get_keyval(test_ctx, "fruit", "apple");
666 assert_non_null(res);
667 assert_int_equal(res->count, 1);
669 struct ldb_mod_test_ctx {
670 struct ldbtest_ctx *ldb_test_ctx;
671 const char *entry_dn;
674 struct keyval {
675 const char *key;
676 const char *val;
679 static struct ldb_message *build_mod_msg(TALLOC_CTX *mem_ctx,
680 struct ldbtest_ctx *test_ctx,
681 const char *dn,
682 int modify_flags,
683 struct keyval *kvs)
685 struct ldb_message *msg;
686 int ret;
687 int i;
689 msg = ldb_msg_new(mem_ctx);
690 assert_non_null(msg);
692 msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "%s", dn);
693 assert_non_null(msg->dn);
695 for (i = 0; kvs[i].key != NULL; i++) {
696 if (modify_flags) {
697 ret = ldb_msg_add_empty(msg, kvs[i].key,
698 modify_flags, NULL);
699 assert_int_equal(ret, 0);
702 if (kvs[i].val) {
703 ret = ldb_msg_add_string(msg, kvs[i].key, kvs[i].val);
704 assert_int_equal(ret, LDB_SUCCESS);
708 return msg;
711 static void ldb_test_add_data(TALLOC_CTX *mem_ctx,
712 struct ldbtest_ctx *ldb_test_ctx,
713 const char *basedn,
714 struct keyval *kvs)
716 TALLOC_CTX *tmp_ctx;
717 struct ldb_message *msg;
718 struct ldb_result *result = NULL;
719 int ret;
721 tmp_ctx = talloc_new(mem_ctx);
722 assert_non_null(tmp_ctx);
724 msg = build_mod_msg(tmp_ctx, ldb_test_ctx,
725 basedn, 0, kvs);
726 assert_non_null(msg);
728 ret = ldb_add(ldb_test_ctx->ldb, msg);
729 assert_int_equal(ret, LDB_SUCCESS);
731 ret = ldb_search(ldb_test_ctx->ldb, tmp_ctx, &result, msg->dn,
732 LDB_SCOPE_BASE, NULL, NULL);
733 assert_int_equal(ret, LDB_SUCCESS);
734 assert_non_null(result);
735 assert_int_equal(result->count, 1);
736 assert_string_equal(ldb_dn_get_linearized(result->msgs[0]->dn),
737 ldb_dn_get_linearized(msg->dn));
739 talloc_free(tmp_ctx);
742 static void ldb_test_remove_data(TALLOC_CTX *mem_ctx,
743 struct ldbtest_ctx *ldb_test_ctx,
744 const char *strdn)
746 TALLOC_CTX *tmp_ctx;
747 struct ldb_dn *basedn;
748 int ret;
749 size_t count;
751 tmp_ctx = talloc_new(mem_ctx);
752 assert_non_null(tmp_ctx);
754 basedn = ldb_dn_new_fmt(tmp_ctx, ldb_test_ctx->ldb,
755 "%s", strdn);
756 assert_non_null(basedn);
758 ret = ldb_delete(ldb_test_ctx->ldb, basedn);
759 assert_true(ret == LDB_SUCCESS || ret == LDB_ERR_NO_SUCH_OBJECT);
761 count = base_search_count(ldb_test_ctx, ldb_dn_get_linearized(basedn));
762 assert_int_equal(count, 0);
764 talloc_free(tmp_ctx);
767 static void mod_test_add_data(struct ldb_mod_test_ctx *mod_test_ctx,
768 struct keyval *kvs)
770 ldb_test_add_data(mod_test_ctx,
771 mod_test_ctx->ldb_test_ctx,
772 mod_test_ctx->entry_dn,
773 kvs);
776 static void mod_test_remove_data(struct ldb_mod_test_ctx *mod_test_ctx)
778 ldb_test_remove_data(mod_test_ctx,
779 mod_test_ctx->ldb_test_ctx,
780 mod_test_ctx->entry_dn);
783 static struct ldb_result *run_mod_test(struct ldb_mod_test_ctx *mod_test_ctx,
784 int modify_flags,
785 struct keyval *kvs)
787 TALLOC_CTX *tmp_ctx;
788 struct ldb_result *res;
789 struct ldb_message *mod_msg;
790 struct ldb_dn *basedn;
791 struct ldbtest_ctx *ldb_test_ctx;
792 int ret;
794 ldb_test_ctx = mod_test_ctx->ldb_test_ctx;
796 tmp_ctx = talloc_new(mod_test_ctx);
797 assert_non_null(tmp_ctx);
799 mod_msg = build_mod_msg(tmp_ctx, ldb_test_ctx, mod_test_ctx->entry_dn,
800 modify_flags, kvs);
801 assert_non_null(mod_msg);
803 ret = ldb_modify(ldb_test_ctx->ldb, mod_msg);
804 assert_int_equal(ret, LDB_SUCCESS);
806 basedn = ldb_dn_new_fmt(tmp_ctx, ldb_test_ctx->ldb,
807 "%s", mod_test_ctx->entry_dn);
808 assert_non_null(basedn);
810 ret = ldb_search(ldb_test_ctx->ldb, mod_test_ctx, &res, basedn,
811 LDB_SCOPE_BASE, NULL, NULL);
812 assert_int_equal(ret, LDB_SUCCESS);
813 assert_non_null(res);
814 assert_int_equal(res->count, 1);
815 assert_string_equal(ldb_dn_get_linearized(res->msgs[0]->dn),
816 ldb_dn_get_linearized(mod_msg->dn));
818 talloc_free(tmp_ctx);
819 return res;
822 static int ldb_modify_test_setup(void **state)
824 struct ldbtest_ctx *ldb_test_ctx;
825 struct ldb_mod_test_ctx *mod_test_ctx;
826 struct keyval kvs[] = {
827 { "cn", "test_mod_cn" },
828 { NULL, NULL },
831 ldbtest_setup((void **) &ldb_test_ctx);
833 mod_test_ctx = talloc(ldb_test_ctx, struct ldb_mod_test_ctx);
834 assert_non_null(mod_test_ctx);
836 mod_test_ctx->entry_dn = "dc=mod_test_entry";
837 mod_test_ctx->ldb_test_ctx = ldb_test_ctx;
839 mod_test_remove_data(mod_test_ctx);
840 mod_test_add_data(mod_test_ctx, kvs);
841 *state = mod_test_ctx;
842 return 0;
845 static int ldb_modify_test_teardown(void **state)
847 struct ldb_mod_test_ctx *mod_test_ctx = \
848 talloc_get_type_abort(*state,
849 struct ldb_mod_test_ctx);
850 struct ldbtest_ctx *ldb_test_ctx;
852 ldb_test_ctx = mod_test_ctx->ldb_test_ctx;
854 mod_test_remove_data(mod_test_ctx);
855 talloc_free(mod_test_ctx);
857 ldbtest_teardown((void **) &ldb_test_ctx);
858 return 0;
861 static void test_ldb_modify_add_key(void **state)
863 struct ldb_mod_test_ctx *mod_test_ctx = \
864 talloc_get_type_abort(*state,
865 struct ldb_mod_test_ctx);
866 struct keyval mod_kvs[] = {
867 { "name", "test_mod_name" },
868 { NULL, NULL },
870 struct ldb_result *res;
871 struct ldb_message_element *el;
873 res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_ADD, mod_kvs);
874 assert_non_null(res);
876 /* Check cn is intact and name was added */
877 assert_int_equal(res->count, 1);
878 el = ldb_msg_find_element(res->msgs[0], "cn");
879 assert_non_null(el);
880 assert_int_equal(el->num_values, 1);
881 assert_string_equal(el->values[0].data, "test_mod_cn");
883 el = ldb_msg_find_element(res->msgs[0], "name");
884 assert_non_null(el);
885 assert_int_equal(el->num_values, 1);
886 assert_string_equal(el->values[0].data, "test_mod_name");
889 static void test_ldb_modify_extend_key(void **state)
891 struct ldb_mod_test_ctx *mod_test_ctx = \
892 talloc_get_type_abort(*state,
893 struct ldb_mod_test_ctx);
894 struct keyval mod_kvs[] = {
895 { "cn", "test_mod_cn2" },
896 { NULL, NULL },
898 struct ldb_result *res;
899 struct ldb_message_element *el;
901 res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_ADD, mod_kvs);
902 assert_non_null(res);
904 /* Check cn was extended with another value */
905 assert_int_equal(res->count, 1);
906 el = ldb_msg_find_element(res->msgs[0], "cn");
907 assert_non_null(el);
908 assert_int_equal(el->num_values, 2);
909 assert_string_equal(el->values[0].data, "test_mod_cn");
910 assert_string_equal(el->values[1].data, "test_mod_cn2");
913 static void test_ldb_modify_add_key_noval(void **state)
915 struct ldb_mod_test_ctx *mod_test_ctx = \
916 talloc_get_type_abort(*state,
917 struct ldb_mod_test_ctx);
918 struct ldb_message *mod_msg;
919 struct ldbtest_ctx *ldb_test_ctx;
920 struct ldb_message_element *el;
921 int ret;
923 ldb_test_ctx = mod_test_ctx->ldb_test_ctx;
925 mod_msg = ldb_msg_new(mod_test_ctx);
926 assert_non_null(mod_msg);
928 mod_msg->dn = ldb_dn_new_fmt(mod_msg, ldb_test_ctx->ldb,
929 "%s", mod_test_ctx->entry_dn);
930 assert_non_null(mod_msg->dn);
932 el = talloc_zero(mod_msg, struct ldb_message_element);
933 el->flags = LDB_FLAG_MOD_ADD;
934 assert_non_null(el);
935 el->name = talloc_strdup(el, "cn");
936 assert_non_null(el->name);
938 mod_msg->elements = el;
939 mod_msg->num_elements = 1;
941 ret = ldb_modify(ldb_test_ctx->ldb, mod_msg);
942 assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION);
945 static void test_ldb_modify_replace_key(void **state)
947 struct ldb_mod_test_ctx *mod_test_ctx = \
948 talloc_get_type_abort(*state,
949 struct ldb_mod_test_ctx);
950 const char *new_cn = "new_cn";
951 struct keyval mod_kvs[] = {
952 { "cn", new_cn },
953 { NULL, NULL },
955 struct ldb_result *res;
956 struct ldb_message_element *el;
958 res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, mod_kvs);
959 assert_non_null(res);
961 /* Check cn was replaced */
962 assert_int_equal(res->count, 1);
963 el = ldb_msg_find_element(res->msgs[0], "cn");
964 assert_non_null(el);
965 assert_int_equal(el->num_values, 1);
966 assert_string_equal(el->values[0].data, new_cn);
969 static void test_ldb_modify_replace_noexist_key(void **state)
971 struct ldb_mod_test_ctx *mod_test_ctx = \
972 talloc_get_type_abort(*state,
973 struct ldb_mod_test_ctx);
974 struct keyval mod_kvs[] = {
975 { "name", "name_val" },
976 { NULL, NULL },
978 struct ldb_result *res;
979 struct ldb_message_element *el;
981 res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, mod_kvs);
982 assert_non_null(res);
984 /* Check cn is intact and name was added */
985 assert_int_equal(res->count, 1);
986 el = ldb_msg_find_element(res->msgs[0], "cn");
987 assert_non_null(el);
988 assert_int_equal(el->num_values, 1);
989 assert_string_equal(el->values[0].data, "test_mod_cn");
991 el = ldb_msg_find_element(res->msgs[0], mod_kvs[0].key);
992 assert_non_null(el);
993 assert_int_equal(el->num_values, 1);
994 assert_string_equal(el->values[0].data, mod_kvs[0].val);
997 static void test_ldb_modify_replace_zero_vals(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[] = {
1005 { "cn", NULL },
1006 { NULL, NULL },
1009 /* cn must be gone */
1010 res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, kvs);
1011 assert_non_null(res);
1012 el = ldb_msg_find_element(res->msgs[0], "cn");
1013 assert_null(el);
1016 static void test_ldb_modify_replace_noexist_key_zero_vals(void **state)
1018 struct ldb_mod_test_ctx *mod_test_ctx = \
1019 talloc_get_type_abort(*state,
1020 struct ldb_mod_test_ctx);
1021 struct ldb_message_element *el;
1022 struct ldb_result *res;
1023 struct keyval kvs[] = {
1024 { "noexist_key", NULL },
1025 { NULL, NULL },
1028 /* cn must be gone */
1029 res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, kvs);
1030 assert_non_null(res);
1032 /* cn should be intact */
1033 el = ldb_msg_find_element(res->msgs[0], "cn");
1034 assert_non_null(el);
1037 static void test_ldb_modify_del_key(void **state)
1039 struct ldb_mod_test_ctx *mod_test_ctx = \
1040 talloc_get_type_abort(*state,
1041 struct ldb_mod_test_ctx);
1042 struct ldb_message_element *el;
1043 struct ldb_result *res;
1044 struct keyval kvs[] = {
1045 { "cn", NULL },
1046 { NULL, NULL },
1049 /* cn must be gone */
1050 res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_DELETE, kvs);
1051 assert_non_null(res);
1053 el = ldb_msg_find_element(res->msgs[0], "cn");
1054 assert_null(el);
1057 static void test_ldb_modify_del_keyval(void **state)
1059 struct ldb_mod_test_ctx *mod_test_ctx = \
1060 talloc_get_type_abort(*state,
1061 struct ldb_mod_test_ctx);
1062 struct ldb_message_element *el;
1063 struct ldb_result *res;
1064 struct keyval kvs[] = {
1065 { "cn", "test_mod_cn" },
1066 { NULL, NULL },
1069 /* cn must be gone */
1070 res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_DELETE, kvs);
1071 assert_non_null(res);
1073 el = ldb_msg_find_element(res->msgs[0], "cn");
1074 assert_null(el);
1077 struct search_test_ctx {
1078 struct ldbtest_ctx *ldb_test_ctx;
1079 const char *base_dn;
1082 static char *get_full_dn(TALLOC_CTX *mem_ctx,
1083 struct search_test_ctx *search_test_ctx,
1084 const char *rdn)
1086 char *full_dn;
1088 full_dn = talloc_asprintf(mem_ctx,
1089 "%s,%s", rdn, search_test_ctx->base_dn);
1090 assert_non_null(full_dn);
1092 return full_dn;
1095 static void search_test_add_data(struct search_test_ctx *search_test_ctx,
1096 const char *rdn,
1097 struct keyval *kvs)
1099 char *full_dn;
1101 full_dn = get_full_dn(search_test_ctx, search_test_ctx, rdn);
1103 ldb_test_add_data(search_test_ctx,
1104 search_test_ctx->ldb_test_ctx,
1105 full_dn,
1106 kvs);
1109 static void search_test_remove_data(struct search_test_ctx *search_test_ctx,
1110 const char *rdn)
1112 char *full_dn;
1114 full_dn = talloc_asprintf(search_test_ctx,
1115 "%s,%s", rdn, search_test_ctx->base_dn);
1116 assert_non_null(full_dn);
1118 ldb_test_remove_data(search_test_ctx,
1119 search_test_ctx->ldb_test_ctx,
1120 full_dn);
1123 static int ldb_search_test_setup(void **state)
1125 struct ldbtest_ctx *ldb_test_ctx;
1126 struct search_test_ctx *search_test_ctx;
1127 struct keyval kvs[] = {
1128 { "cn", "test_search_cn" },
1129 { "cn", "test_search_cn2" },
1130 { "uid", "test_search_uid" },
1131 { "uid", "test_search_uid2" },
1132 { NULL, NULL },
1134 struct keyval kvs2[] = {
1135 { "cn", "test_search_2_cn" },
1136 { "cn", "test_search_2_cn2" },
1137 { "uid", "test_search_2_uid" },
1138 { "uid", "test_search_2_uid2" },
1139 { NULL, NULL },
1142 ldbtest_setup((void **) &ldb_test_ctx);
1144 search_test_ctx = talloc(ldb_test_ctx, struct search_test_ctx);
1145 assert_non_null(search_test_ctx);
1147 search_test_ctx->base_dn = "dc=search_test_entry";
1148 search_test_ctx->ldb_test_ctx = ldb_test_ctx;
1150 search_test_remove_data(search_test_ctx, "cn=test_search_cn");
1151 search_test_add_data(search_test_ctx, "cn=test_search_cn", kvs);
1153 search_test_remove_data(search_test_ctx, "cn=test_search_2_cn");
1154 search_test_add_data(search_test_ctx, "cn=test_search_2_cn", kvs2);
1156 *state = search_test_ctx;
1157 return 0;
1160 static int ldb_search_test_teardown(void **state)
1162 struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1163 struct search_test_ctx);
1164 struct ldbtest_ctx *ldb_test_ctx;
1166 ldb_test_ctx = search_test_ctx->ldb_test_ctx;
1168 search_test_remove_data(search_test_ctx, "cn=test_search_cn");
1169 search_test_remove_data(search_test_ctx, "cn=test_search_2_cn");
1170 ldbtest_teardown((void **) &ldb_test_ctx);
1171 return 0;
1174 static void assert_attr_has_vals(struct ldb_message *msg,
1175 const char *attr,
1176 const char *vals[],
1177 const size_t nvals)
1179 struct ldb_message_element *el;
1180 size_t i;
1182 el = ldb_msg_find_element(msg, attr);
1183 assert_non_null(el);
1185 assert_int_equal(el->num_values, nvals);
1186 for (i = 0; i < nvals; i++) {
1187 assert_string_equal(el->values[i].data,
1188 vals[i]);
1192 static void assert_has_no_attr(struct ldb_message *msg,
1193 const char *attr)
1195 struct ldb_message_element *el;
1197 el = ldb_msg_find_element(msg, attr);
1198 assert_null(el);
1201 static bool has_dn(struct ldb_message *msg, const char *dn)
1203 const char *msgdn;
1205 msgdn = ldb_dn_get_linearized(msg->dn);
1206 if (strcmp(dn, msgdn) == 0) {
1207 return true;
1210 return false;
1213 static void test_search_match_none(void **state)
1215 struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1216 struct search_test_ctx);
1217 size_t count;
1219 count = base_search_count(search_test_ctx->ldb_test_ctx,
1220 "dc=no_such_entry");
1221 assert_int_equal(count, 0);
1224 static void test_search_match_one(void **state)
1226 struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1227 struct search_test_ctx);
1228 int ret;
1229 struct ldb_dn *basedn;
1230 struct ldb_result *result = NULL;
1231 const char *cn_vals[] = { "test_search_cn",
1232 "test_search_cn2" };
1233 const char *uid_vals[] = { "test_search_uid",
1234 "test_search_uid2" };
1236 basedn = ldb_dn_new_fmt(search_test_ctx,
1237 search_test_ctx->ldb_test_ctx->ldb,
1238 "%s",
1239 search_test_ctx->base_dn);
1240 assert_non_null(basedn);
1242 ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
1243 search_test_ctx,
1244 &result,
1245 basedn,
1246 LDB_SCOPE_SUBTREE, NULL,
1247 "cn=test_search_cn");
1248 assert_int_equal(ret, 0);
1249 assert_non_null(result);
1250 assert_int_equal(result->count, 1);
1252 assert_attr_has_vals(result->msgs[0], "cn", cn_vals, 2);
1253 assert_attr_has_vals(result->msgs[0], "uid", uid_vals, 2);
1256 static void test_search_match_filter(void **state)
1258 struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1259 struct search_test_ctx);
1260 int ret;
1261 struct ldb_dn *basedn;
1262 struct ldb_result *result = NULL;
1263 const char *cn_vals[] = { "test_search_cn",
1264 "test_search_cn2" };
1265 const char *attrs[] = { "cn", NULL };
1267 basedn = ldb_dn_new_fmt(search_test_ctx,
1268 search_test_ctx->ldb_test_ctx->ldb,
1269 "%s",
1270 search_test_ctx->base_dn);
1271 assert_non_null(basedn);
1273 ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
1274 search_test_ctx,
1275 &result,
1276 basedn,
1277 LDB_SCOPE_SUBTREE,
1278 attrs,
1279 "cn=test_search_cn");
1280 assert_int_equal(ret, 0);
1281 assert_non_null(result);
1282 assert_int_equal(result->count, 1);
1284 assert_attr_has_vals(result->msgs[0], "cn", cn_vals, 2);
1285 assert_has_no_attr(result->msgs[0], "uid");
1288 static void assert_expected(struct search_test_ctx *search_test_ctx,
1289 struct ldb_message *msg)
1291 char *full_dn1;
1292 char *full_dn2;
1293 const char *cn_vals[] = { "test_search_cn",
1294 "test_search_cn2" };
1295 const char *uid_vals[] = { "test_search_uid",
1296 "test_search_uid2" };
1297 const char *cn2_vals[] = { "test_search_2_cn",
1298 "test_search_2_cn2" };
1299 const char *uid2_vals[] = { "test_search_2_uid",
1300 "test_search_2_uid2" };
1302 full_dn1 = get_full_dn(search_test_ctx,
1303 search_test_ctx,
1304 "cn=test_search_cn");
1306 full_dn2 = get_full_dn(search_test_ctx,
1307 search_test_ctx,
1308 "cn=test_search_2_cn");
1310 if (has_dn(msg, full_dn1) == true) {
1311 assert_attr_has_vals(msg, "cn", cn_vals, 2);
1312 assert_attr_has_vals(msg, "uid", uid_vals, 2);
1313 } else if (has_dn(msg, full_dn2) == true) {
1314 assert_attr_has_vals(msg, "cn", cn2_vals, 2);
1315 assert_attr_has_vals(msg, "uid", uid2_vals, 2);
1316 } else {
1317 fail();
1321 static void test_search_match_both(void **state)
1323 struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1324 struct search_test_ctx);
1325 int ret;
1326 struct ldb_dn *basedn;
1327 struct ldb_result *result = NULL;
1329 basedn = ldb_dn_new_fmt(search_test_ctx,
1330 search_test_ctx->ldb_test_ctx->ldb,
1331 "%s",
1332 search_test_ctx->base_dn);
1333 assert_non_null(basedn);
1335 ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
1336 search_test_ctx,
1337 &result,
1338 basedn,
1339 LDB_SCOPE_SUBTREE, NULL,
1340 "cn=test_search_*");
1341 assert_int_equal(ret, 0);
1342 assert_non_null(result);
1343 assert_int_equal(result->count, 2);
1345 assert_expected(search_test_ctx, result->msgs[0]);
1346 assert_expected(search_test_ctx, result->msgs[1]);
1349 static void test_search_match_basedn(void **state)
1351 struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1352 struct search_test_ctx);
1353 int ret;
1354 struct ldb_dn *basedn;
1355 struct ldb_result *result = NULL;
1356 struct ldb_message *msg;
1358 basedn = ldb_dn_new_fmt(search_test_ctx,
1359 search_test_ctx->ldb_test_ctx->ldb,
1360 "dc=nosuchdn");
1361 assert_non_null(basedn);
1363 ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
1364 search_test_ctx,
1365 &result,
1366 basedn,
1367 LDB_SCOPE_SUBTREE, NULL,
1368 "cn=*");
1369 assert_int_equal(ret, 0);
1371 /* Add 'checkBaseOnSearch' to @OPTIONS */
1372 msg = ldb_msg_new(search_test_ctx);
1373 assert_non_null(msg);
1375 msg->dn = ldb_dn_new_fmt(msg,
1376 search_test_ctx->ldb_test_ctx->ldb,
1377 "@OPTIONS");
1378 assert_non_null(msg->dn);
1380 ret = ldb_msg_add_string(msg, "checkBaseOnSearch", "TRUE");
1381 assert_int_equal(ret, 0);
1383 ret = ldb_add(search_test_ctx->ldb_test_ctx->ldb, msg);
1384 assert_int_equal(ret, 0);
1386 /* Search again */
1387 /* The search should return LDB_ERR_NO_SUCH_OBJECT */
1388 ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
1389 search_test_ctx,
1390 &result,
1391 basedn,
1392 LDB_SCOPE_SUBTREE, NULL,
1393 "cn=*");
1394 assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT);
1396 ret = ldb_delete(search_test_ctx->ldb_test_ctx->ldb, msg->dn);
1397 assert_int_equal(ret, 0);
1402 * This test is complex.
1403 * The purpose is to test for a deadlock detected between ldb_search()
1404 * and ldb_transaction_commit(). The deadlock happens if in process
1405 * (1) and (2):
1406 * - (1) the all-record lock is taken in ltdb_search()
1407 * - (2) the ldb_transaction_start() call is made
1408 * - (1) an un-indexed search starts (forced here by doing it in
1409 * the callback
1410 * - (2) the ldb_transaction_commit() is called.
1411 * This returns LDB_ERR_BUSY if the deadlock is detected
1413 * With ldb 1.1.31 and tdb 1.3.12 we avoid this only due to a missing
1414 * lock call in ltdb_search() due to a refcounting bug in
1415 * ltdb_lock_read()
1418 struct search_against_transaction_ctx {
1419 struct ldbtest_ctx *test_ctx;
1420 int res_count;
1421 pid_t child_pid;
1422 struct ldb_dn *basedn;
1425 static int test_ldb_search_against_transaction_callback2(struct ldb_request *req,
1426 struct ldb_reply *ares)
1428 struct search_against_transaction_ctx *ctx = req->context;
1429 switch (ares->type) {
1430 case LDB_REPLY_ENTRY:
1431 ctx->res_count++;
1432 if (ctx->res_count != 1) {
1433 return LDB_SUCCESS;
1436 break;
1438 case LDB_REPLY_REFERRAL:
1439 break;
1441 case LDB_REPLY_DONE:
1442 return ldb_request_done(req, LDB_SUCCESS);
1445 return 0;
1450 * This purpose of this callback is to trigger a transaction in
1451 * the child process while the all-record lock is held, but before
1452 * we take any locks in the tdb_traverse_read() handler.
1454 * In tdb 1.3.12 tdb_traverse_read() take the read transaction lock
1455 * however in ldb 1.1.31 ltdb_search() forgets to take the all-record
1456 * lock (except the very first time) due to a ref-counting bug.
1460 static int test_ldb_search_against_transaction_callback1(struct ldb_request *req,
1461 struct ldb_reply *ares)
1463 int ret, ret2;
1464 int pipes[2];
1465 char buf[2];
1466 struct search_against_transaction_ctx *ctx = req->context;
1467 switch (ares->type) {
1468 case LDB_REPLY_ENTRY:
1469 break;
1471 case LDB_REPLY_REFERRAL:
1472 return LDB_SUCCESS;
1474 case LDB_REPLY_DONE:
1475 return ldb_request_done(req, LDB_SUCCESS);
1478 ret = pipe(pipes);
1479 assert_int_equal(ret, 0);
1481 ctx->child_pid = fork();
1482 if (ctx->child_pid == 0) {
1483 TALLOC_CTX *tmp_ctx = NULL;
1484 struct ldb_message *msg;
1485 TALLOC_FREE(ctx->test_ctx->ldb);
1486 TALLOC_FREE(ctx->test_ctx->ev);
1487 ctx->test_ctx->ev = tevent_context_init(ctx->test_ctx);
1488 if (ctx->test_ctx->ev == NULL) {
1489 exit(LDB_ERR_OPERATIONS_ERROR);
1492 ctx->test_ctx->ldb = ldb_init(ctx->test_ctx,
1493 ctx->test_ctx->ev);
1494 if (ctx->test_ctx->ldb == NULL) {
1495 exit(LDB_ERR_OPERATIONS_ERROR);
1498 ret = ldb_connect(ctx->test_ctx->ldb,
1499 ctx->test_ctx->dbpath, 0, NULL);
1500 if (ret != LDB_SUCCESS) {
1501 exit(ret);
1504 tmp_ctx = talloc_new(ctx->test_ctx);
1505 if (tmp_ctx == NULL) {
1506 exit(LDB_ERR_OPERATIONS_ERROR);
1509 msg = ldb_msg_new(tmp_ctx);
1510 if (msg == NULL) {
1511 exit(LDB_ERR_OPERATIONS_ERROR);
1514 msg->dn = ldb_dn_new_fmt(msg, ctx->test_ctx->ldb,
1515 "dc=test");
1516 if (msg->dn == NULL) {
1517 exit(LDB_ERR_OPERATIONS_ERROR);
1520 ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
1521 if (ret != 0) {
1522 exit(LDB_ERR_OPERATIONS_ERROR);
1525 ret = ldb_transaction_start(ctx->test_ctx->ldb);
1526 if (ret != 0) {
1527 exit(ret);
1530 ret = write(pipes[1], "GO", 2);
1531 if (ret != 2) {
1532 exit(LDB_ERR_OPERATIONS_ERROR);
1535 ret = ldb_add(ctx->test_ctx->ldb, msg);
1536 if (ret != 0) {
1537 exit(ret);
1540 ret = ldb_transaction_commit(ctx->test_ctx->ldb);
1541 exit(ret);
1544 ret = read(pipes[0], buf, 2);
1545 assert_int_equal(ret, 2);
1547 /* This search must be unindexed (ie traverse in tdb) */
1548 ret = ldb_build_search_req(&req,
1549 ctx->test_ctx->ldb,
1550 ctx->test_ctx,
1551 ctx->basedn,
1552 LDB_SCOPE_SUBTREE,
1553 "cn=*", NULL,
1554 NULL,
1555 ctx,
1556 test_ldb_search_against_transaction_callback2,
1557 NULL);
1559 * we don't assert on these return codes until after the search is
1560 * finished, or the clean up will fail because we hold locks.
1563 ret2 = ldb_request(ctx->test_ctx->ldb, req);
1565 if (ret2 == LDB_SUCCESS) {
1566 ret2 = ldb_wait(req->handle, LDB_WAIT_ALL);
1568 assert_int_equal(ret, 0);
1569 assert_int_equal(ret2, 0);
1570 assert_int_equal(ctx->res_count, 2);
1572 return LDB_SUCCESS;
1575 static void test_ldb_search_against_transaction(void **state)
1577 struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1578 struct search_test_ctx);
1579 struct search_against_transaction_ctx
1580 ctx =
1581 { .res_count = 0,
1582 .test_ctx = search_test_ctx->ldb_test_ctx
1585 int ret;
1586 struct ldb_request *req;
1587 pid_t pid;
1588 int wstatus;
1589 struct ldb_dn *base_search_dn;
1591 tevent_loop_allow_nesting(search_test_ctx->ldb_test_ctx->ev);
1593 base_search_dn
1594 = ldb_dn_new_fmt(search_test_ctx,
1595 search_test_ctx->ldb_test_ctx->ldb,
1596 "cn=test_search_cn,%s",
1597 search_test_ctx->base_dn);
1598 assert_non_null(base_search_dn);
1600 ctx.basedn
1601 = ldb_dn_new_fmt(search_test_ctx,
1602 search_test_ctx->ldb_test_ctx->ldb,
1603 "%s",
1604 search_test_ctx->base_dn);
1605 assert_non_null(ctx.basedn);
1608 /* This search must be indexed (ie no traverse in tdb) */
1609 ret = ldb_build_search_req(&req,
1610 search_test_ctx->ldb_test_ctx->ldb,
1611 search_test_ctx,
1612 base_search_dn,
1613 LDB_SCOPE_BASE,
1614 "cn=*", NULL,
1615 NULL,
1616 &ctx,
1617 test_ldb_search_against_transaction_callback1,
1618 NULL);
1619 assert_int_equal(ret, 0);
1620 ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req);
1622 if (ret == LDB_SUCCESS) {
1623 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1625 assert_int_equal(ret, 0);
1626 assert_int_equal(ctx.res_count, 2);
1628 pid = waitpid(ctx.child_pid, &wstatus, 0);
1629 assert_int_equal(pid, ctx.child_pid);
1631 assert_true(WIFEXITED(wstatus));
1633 assert_int_equal(WEXITSTATUS(wstatus), 0);
1639 * This test is also complex.
1640 * The purpose is to test if a modify can occur during an ldb_search()
1641 * This would be a failure if if in process
1642 * (1) and (2):
1643 * - (1) ltdb_search() starts and calls back for one entry
1644 * - (2) one of the entries to be matched is modified
1645 * - (1) the indexed search tries to return the modified entry, but
1646 * it is no longer found, either:
1647 * - despite it still matching (dn changed)
1648 * - it no longer matching (attrs changed)
1650 * We also try un-indexed to show that the behaviour differs on this
1651 * point, which it should not (an index should only impact search
1652 * speed).
1655 struct modify_during_search_test_ctx {
1656 struct ldbtest_ctx *test_ctx;
1657 int res_count;
1658 pid_t child_pid;
1659 struct ldb_dn *basedn;
1660 bool got_cn;
1661 bool got_2_cn;
1662 bool rename;
1666 * This purpose of this callback is to trigger a write in
1667 * the child process while a search is in progress.
1669 * In tdb 1.3.12 tdb_traverse_read() take the read transaction lock
1670 * however in ldb 1.1.31 ltdb_search() forgets to take the all-record
1671 * lock (except the very first time) due to a ref-counting bug.
1673 * We assume that if the write will proceed, it will proceed in a 3
1674 * second window after the function is called.
1677 static int test_ldb_modify_during_search_callback1(struct ldb_request *req,
1678 struct ldb_reply *ares)
1680 int ret;
1681 int pipes[2];
1682 char buf[2];
1683 struct modify_during_search_test_ctx *ctx = req->context;
1684 switch (ares->type) {
1685 case LDB_REPLY_ENTRY:
1687 const struct ldb_val *cn_val
1688 = ldb_dn_get_component_val(ares->message->dn, 0);
1689 const char *cn = (char *)cn_val->data;
1690 ctx->res_count++;
1691 if (strcmp(cn, "test_search_cn") == 0) {
1692 ctx->got_cn = true;
1693 } else if (strcmp(cn, "test_search_2_cn") == 0) {
1694 ctx->got_2_cn = true;
1696 if (ctx->res_count == 2) {
1697 return LDB_SUCCESS;
1699 break;
1701 case LDB_REPLY_REFERRAL:
1702 return LDB_SUCCESS;
1704 case LDB_REPLY_DONE:
1705 return ldb_request_done(req, LDB_SUCCESS);
1708 ret = pipe(pipes);
1709 assert_int_equal(ret, 0);
1711 ctx->child_pid = fork();
1712 if (ctx->child_pid == 0 && ctx->rename) {
1713 TALLOC_CTX *tmp_ctx = NULL;
1714 struct ldb_dn *dn, *new_dn;
1715 TALLOC_FREE(ctx->test_ctx->ldb);
1716 TALLOC_FREE(ctx->test_ctx->ev);
1717 ctx->test_ctx->ev = tevent_context_init(ctx->test_ctx);
1718 if (ctx->test_ctx->ev == NULL) {
1719 exit(LDB_ERR_OPERATIONS_ERROR);
1722 ctx->test_ctx->ldb = ldb_init(ctx->test_ctx,
1723 ctx->test_ctx->ev);
1724 if (ctx->test_ctx->ldb == NULL) {
1725 exit(LDB_ERR_OPERATIONS_ERROR);
1728 ret = ldb_connect(ctx->test_ctx->ldb,
1729 ctx->test_ctx->dbpath, 0, NULL);
1730 if (ret != LDB_SUCCESS) {
1731 exit(ret);
1734 tmp_ctx = talloc_new(ctx->test_ctx);
1735 if (tmp_ctx == NULL) {
1736 exit(LDB_ERR_OPERATIONS_ERROR);
1739 if (ctx->got_cn) {
1740 /* Modify the other one */
1741 dn = ldb_dn_new_fmt(tmp_ctx, ctx->test_ctx->ldb,
1742 "cn=test_search_2_cn,"
1743 "dc=search_test_entry");
1744 } else {
1745 dn = ldb_dn_new_fmt(tmp_ctx, ctx->test_ctx->ldb,
1746 "cn=test_search_cn,"
1747 "dc=search_test_entry");
1749 if (dn == NULL) {
1750 exit(LDB_ERR_OPERATIONS_ERROR);
1753 new_dn = ldb_dn_new_fmt(tmp_ctx, ctx->test_ctx->ldb,
1754 "cn=test_search_cn_renamed,"
1755 "dc=search_test_entry");
1756 if (new_dn == NULL) {
1757 exit(LDB_ERR_OPERATIONS_ERROR);
1760 ret = ldb_transaction_start(ctx->test_ctx->ldb);
1761 if (ret != 0) {
1762 exit(ret);
1765 if (write(pipes[1], "GO", 2) != 2) {
1766 exit(LDB_ERR_OPERATIONS_ERROR);
1769 ret = ldb_rename(ctx->test_ctx->ldb, dn, new_dn);
1770 if (ret != 0) {
1771 exit(ret);
1774 ret = ldb_transaction_commit(ctx->test_ctx->ldb);
1775 exit(ret);
1777 } else if (ctx->child_pid == 0) {
1778 TALLOC_CTX *tmp_ctx = NULL;
1779 struct ldb_message *msg;
1780 struct ldb_message_element *el;
1781 TALLOC_FREE(ctx->test_ctx->ldb);
1782 TALLOC_FREE(ctx->test_ctx->ev);
1783 ctx->test_ctx->ev = tevent_context_init(ctx->test_ctx);
1784 if (ctx->test_ctx->ev == NULL) {
1785 exit(LDB_ERR_OPERATIONS_ERROR);
1788 ctx->test_ctx->ldb = ldb_init(ctx->test_ctx,
1789 ctx->test_ctx->ev);
1790 if (ctx->test_ctx->ldb == NULL) {
1791 exit(LDB_ERR_OPERATIONS_ERROR);
1794 ret = ldb_connect(ctx->test_ctx->ldb,
1795 ctx->test_ctx->dbpath, 0, NULL);
1796 if (ret != LDB_SUCCESS) {
1797 exit(ret);
1800 tmp_ctx = talloc_new(ctx->test_ctx);
1801 if (tmp_ctx == NULL) {
1802 exit(LDB_ERR_OPERATIONS_ERROR);
1805 msg = ldb_msg_new(tmp_ctx);
1806 if (msg == NULL) {
1807 exit(LDB_ERR_OPERATIONS_ERROR);
1810 if (ctx->got_cn) {
1811 /* Modify the other one */
1812 msg->dn = ldb_dn_new_fmt(msg, ctx->test_ctx->ldb,
1813 "cn=test_search_2_cn,"
1814 "dc=search_test_entry");
1815 } else {
1816 msg->dn = ldb_dn_new_fmt(msg, ctx->test_ctx->ldb,
1817 "cn=test_search_cn,"
1818 "dc=search_test_entry");
1820 if (msg->dn == NULL) {
1821 exit(LDB_ERR_OPERATIONS_ERROR);
1824 ret = ldb_msg_add_string(msg, "filterAttr", "TRUE");
1825 if (ret != 0) {
1826 exit(LDB_ERR_OPERATIONS_ERROR);
1828 el = ldb_msg_find_element(msg, "filterAttr");
1829 if (el == NULL) {
1830 exit(LDB_ERR_OPERATIONS_ERROR);
1832 el->flags = LDB_FLAG_MOD_REPLACE;
1834 ret = ldb_transaction_start(ctx->test_ctx->ldb);
1835 if (ret != 0) {
1836 exit(ret);
1839 if (write(pipes[1], "GO", 2) != 2) {
1840 exit(LDB_ERR_OPERATIONS_ERROR);
1843 ret = ldb_modify(ctx->test_ctx->ldb, msg);
1844 if (ret != 0) {
1845 exit(ret);
1848 ret = ldb_transaction_commit(ctx->test_ctx->ldb);
1849 exit(ret);
1853 * With TDB 1.3.13 and before "tdb: Remove locking from tdb_traverse_read()"
1854 * we will hang here because the child process can not proceed to
1855 * sending the "GO" as it is blocked at ldb_transaction_start().
1858 ret = read(pipes[0], buf, 2);
1859 assert_int_equal(ret, 2);
1861 sleep(3);
1863 return LDB_SUCCESS;
1866 static void test_ldb_modify_during_search(void **state, bool add_index,
1867 bool rename)
1869 struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1870 struct search_test_ctx);
1871 struct modify_during_search_test_ctx
1872 ctx =
1873 { .res_count = 0,
1874 .test_ctx = search_test_ctx->ldb_test_ctx,
1875 .rename = rename
1878 int ret;
1879 struct ldb_request *req;
1880 pid_t pid;
1881 int wstatus;
1883 if (add_index) {
1884 struct ldb_message *msg;
1885 struct ldb_dn *indexlist = ldb_dn_new(search_test_ctx,
1886 search_test_ctx->ldb_test_ctx->ldb,
1887 "@INDEXLIST");
1888 assert_non_null(indexlist);
1890 msg = ldb_msg_new(search_test_ctx);
1891 assert_non_null(msg);
1893 msg->dn = indexlist;
1895 ret = ldb_msg_add_string(msg, "@IDXATTR", "cn");
1896 assert_int_equal(ret, LDB_SUCCESS);
1898 ret = ldb_add(search_test_ctx->ldb_test_ctx->ldb,
1899 msg);
1901 assert_int_equal(ret, LDB_SUCCESS);
1904 tevent_loop_allow_nesting(search_test_ctx->ldb_test_ctx->ev);
1906 ctx.basedn
1907 = ldb_dn_new_fmt(search_test_ctx,
1908 search_test_ctx->ldb_test_ctx->ldb,
1909 "%s",
1910 search_test_ctx->base_dn);
1911 assert_non_null(ctx.basedn);
1915 * This search must be over multiple items, and should include
1916 * the new name after a rename, to show that it would match
1917 * both before and after that modify
1919 ret = ldb_build_search_req(&req,
1920 search_test_ctx->ldb_test_ctx->ldb,
1921 search_test_ctx,
1922 ctx.basedn,
1923 LDB_SCOPE_SUBTREE,
1924 "(&(!(filterAttr=*))"
1925 "(|(cn=test_search_cn_renamed)"
1926 "(cn=test_search_cn)"
1927 "(cn=test_search_2_cn)"
1928 "))",
1929 NULL,
1930 NULL,
1931 &ctx,
1932 test_ldb_modify_during_search_callback1,
1933 NULL);
1934 assert_int_equal(ret, 0);
1935 ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req);
1937 if (ret == LDB_SUCCESS) {
1938 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1940 assert_int_equal(ret, 0);
1941 assert_int_equal(ctx.res_count, 2);
1942 assert_int_equal(ctx.got_cn, true);
1943 assert_int_equal(ctx.got_2_cn, true);
1945 pid = waitpid(ctx.child_pid, &wstatus, 0);
1946 assert_int_equal(pid, ctx.child_pid);
1948 assert_true(WIFEXITED(wstatus));
1950 assert_int_equal(WEXITSTATUS(wstatus), 0);
1955 static void test_ldb_modify_during_indexed_search(void **state)
1957 test_ldb_modify_during_search(state, true, false);
1960 static void test_ldb_modify_during_unindexed_search(void **state)
1962 test_ldb_modify_during_search(state, false, false);
1965 static void test_ldb_rename_during_indexed_search(void **state)
1967 test_ldb_modify_during_search(state, true, true);
1970 static void test_ldb_rename_during_unindexed_search(void **state)
1972 test_ldb_modify_during_search(state, false, true);
1976 * This test is also complex.
1978 * The purpose is to test if a modify can occur during an ldb_search()
1979 * before the end of the callback
1981 * This would be a failure if if in process
1982 * (1) and (2):
1983 * - (1) ldb_search() starts and calls back for a number of entries
1984 * - (2) an entry in the DB is allowed to change before the callback returns
1985 * - (1) the callback can see the modification
1990 * This purpose of this callback is to trigger a write in
1991 * the child process while a search DONE callback is in progress.
1993 * In ldb 1.1.31 ldb_search() omitted to take a all-record
1994 * lock for the full duration of the search and callbacks
1996 * We assume that if the write will proceed, it will proceed in a 3
1997 * second window after the function is called.
2000 static int test_ldb_modify_during_whole_search_callback1(struct ldb_request *req,
2001 struct ldb_reply *ares)
2003 int ret;
2004 int pipes[2];
2005 char buf[2];
2006 struct modify_during_search_test_ctx *ctx = req->context;
2007 struct ldb_dn *search_dn;
2008 struct ldb_result *res2;
2009 unsigned res_count;
2010 switch (ares->type) {
2011 case LDB_REPLY_ENTRY:
2012 case LDB_REPLY_REFERRAL:
2013 return LDB_SUCCESS;
2015 case LDB_REPLY_DONE:
2016 break;
2019 ret = pipe(pipes);
2020 assert_int_equal(ret, 0);
2022 ctx->child_pid = fork();
2023 if (ctx->child_pid == 0) {
2024 TALLOC_CTX *tmp_ctx = NULL;
2025 struct ldb_message *msg;
2026 struct ldb_message_element *el;
2027 TALLOC_FREE(ctx->test_ctx->ldb);
2028 TALLOC_FREE(ctx->test_ctx->ev);
2029 ctx->test_ctx->ev = tevent_context_init(ctx->test_ctx);
2030 if (ctx->test_ctx->ev == NULL) {
2031 exit(LDB_ERR_OPERATIONS_ERROR);
2034 ctx->test_ctx->ldb = ldb_init(ctx->test_ctx,
2035 ctx->test_ctx->ev);
2036 if (ctx->test_ctx->ldb == NULL) {
2037 exit(LDB_ERR_OPERATIONS_ERROR);
2040 ret = ldb_connect(ctx->test_ctx->ldb,
2041 ctx->test_ctx->dbpath, 0, NULL);
2042 if (ret != LDB_SUCCESS) {
2043 exit(ret);
2046 tmp_ctx = talloc_new(ctx->test_ctx);
2047 if (tmp_ctx == NULL) {
2048 exit(LDB_ERR_OPERATIONS_ERROR);
2051 msg = ldb_msg_new(tmp_ctx);
2052 if (msg == NULL) {
2053 exit(LDB_ERR_OPERATIONS_ERROR);
2056 msg->dn = ldb_dn_new_fmt(msg, ctx->test_ctx->ldb,
2057 "cn=test_search_cn,"
2058 "dc=search_test_entry");
2059 if (msg->dn == NULL) {
2060 exit(LDB_ERR_OPERATIONS_ERROR);
2063 ret = ldb_msg_add_string(msg, "filterAttr", "TRUE");
2064 if (ret != 0) {
2065 exit(LDB_ERR_OPERATIONS_ERROR);
2067 el = ldb_msg_find_element(msg, "filterAttr");
2068 if (el == NULL) {
2069 exit(LDB_ERR_OPERATIONS_ERROR);
2071 el->flags = LDB_FLAG_MOD_REPLACE;
2073 ret = ldb_transaction_start(ctx->test_ctx->ldb);
2074 if (ret != 0) {
2075 exit(ret);
2078 if (write(pipes[1], "GO", 2) != 2) {
2079 exit(LDB_ERR_OPERATIONS_ERROR);
2082 ret = ldb_modify(ctx->test_ctx->ldb, msg);
2083 if (ret != 0) {
2084 exit(ret);
2087 ret = ldb_transaction_commit(ctx->test_ctx->ldb);
2088 exit(ret);
2091 ret = read(pipes[0], buf, 2);
2092 assert_int_equal(ret, 2);
2094 sleep(3);
2097 * If writes are not blocked until after this function, we
2098 * will be able to successfully search for this modification
2099 * here
2102 search_dn = ldb_dn_new_fmt(ares, ctx->test_ctx->ldb,
2103 "cn=test_search_cn,"
2104 "dc=search_test_entry");
2106 ret = ldb_search(ctx->test_ctx->ldb, ares,
2107 &res2, search_dn, LDB_SCOPE_BASE, NULL,
2108 "filterAttr=TRUE");
2111 * We do this in an unusual order, because if we fail an assert before
2112 * ldb_request_done(), we will also fail to clean up as we hold locks.
2115 res_count = res2->count;
2116 ldb_request_done(req, LDB_SUCCESS);
2117 assert_int_equal(ret, 0);
2119 /* We should not have got the result */
2120 assert_int_equal(res_count, 0);
2122 return ret;
2125 static void test_ldb_modify_during_whole_search(void **state)
2127 struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
2128 struct search_test_ctx);
2129 struct modify_during_search_test_ctx
2130 ctx =
2132 .test_ctx = search_test_ctx->ldb_test_ctx,
2135 int ret;
2136 struct ldb_request *req;
2137 pid_t pid;
2138 int wstatus;
2139 struct ldb_dn *search_dn;
2140 struct ldb_result *res2;
2142 tevent_loop_allow_nesting(search_test_ctx->ldb_test_ctx->ev);
2144 ctx.basedn
2145 = ldb_dn_new_fmt(search_test_ctx,
2146 search_test_ctx->ldb_test_ctx->ldb,
2147 "%s",
2148 search_test_ctx->base_dn);
2149 assert_non_null(ctx.basedn);
2153 * The search just needs to call DONE, we don't care about the
2154 * contents of the search for this test
2156 ret = ldb_build_search_req(&req,
2157 search_test_ctx->ldb_test_ctx->ldb,
2158 search_test_ctx,
2159 ctx.basedn,
2160 LDB_SCOPE_SUBTREE,
2161 "(&(!(filterAttr=*))"
2162 "(cn=test_search_cn))",
2163 NULL,
2164 NULL,
2165 &ctx,
2166 test_ldb_modify_during_whole_search_callback1,
2167 NULL);
2168 assert_int_equal(ret, 0);
2169 ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req);
2171 if (ret == LDB_SUCCESS) {
2172 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
2174 assert_int_equal(ret, 0);
2176 pid = waitpid(ctx.child_pid, &wstatus, 0);
2177 assert_int_equal(pid, ctx.child_pid);
2179 assert_true(WIFEXITED(wstatus));
2181 assert_int_equal(WEXITSTATUS(wstatus), 0);
2184 * If writes are blocked until after the search function, we
2185 * will be able to successfully search for this modification
2186 * now
2189 search_dn = ldb_dn_new_fmt(search_test_ctx,
2190 search_test_ctx->ldb_test_ctx->ldb,
2191 "cn=test_search_cn,"
2192 "dc=search_test_entry");
2194 ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
2195 search_test_ctx,
2196 &res2, search_dn, LDB_SCOPE_BASE, NULL,
2197 "filterAttr=TRUE");
2198 assert_int_equal(ret, 0);
2200 /* We got the result */
2201 assert_int_equal(res2->count, 1);
2205 * This test is also complex.
2207 * The purpose is to test if a modify can occur during an ldb_search()
2208 * before the request is destroyed with TALLOC_FREE()
2210 * This would be a failure if in process
2211 * (1) and (2):
2212 * - (1) ldb_search() starts and waits
2213 * - (2) an entry in the DB is allowed to change before the ldb_wait() is called
2214 * - (1) the original process can see the modification before the TALLOC_FREE()
2215 * also we check that
2216 * - (1) the original process can see the modification after the TALLOC_FREE()
2221 * This purpose of this callback is to trigger a write in
2222 * the child process before the ldb_wait() is called
2224 * In ldb 1.1.31 ldb_search() omitted to take a all-record
2225 * lock for the full duration of the search and callbacks
2227 * We assume that if the write will proceed, it will proceed in a 3
2228 * second window after the function is called.
2231 static int test_ldb_modify_before_ldb_wait_callback1(struct ldb_request *req,
2232 struct ldb_reply *ares)
2234 switch (ares->type) {
2235 case LDB_REPLY_ENTRY:
2236 case LDB_REPLY_REFERRAL:
2237 return LDB_SUCCESS;
2239 case LDB_REPLY_DONE:
2240 break;
2243 return ldb_request_done(req, LDB_SUCCESS);
2246 static void test_ldb_modify_before_ldb_wait(void **state)
2248 struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
2249 struct search_test_ctx);
2250 int ret;
2251 struct ldb_request *req;
2252 pid_t pid;
2253 int wstatus;
2254 struct ldb_dn *search_dn;
2255 struct ldb_dn *basedn;
2256 struct ldb_result *res2;
2257 int pipes[2];
2258 char buf[2];
2259 pid_t child_pid;
2260 unsigned res_count;
2262 search_dn = ldb_dn_new_fmt(search_test_ctx,
2263 search_test_ctx->ldb_test_ctx->ldb,
2264 "cn=test_search_cn,"
2265 "dc=search_test_entry");
2266 assert_non_null(search_dn);
2268 basedn = ldb_dn_new_fmt(search_test_ctx,
2269 search_test_ctx->ldb_test_ctx->ldb,
2270 "%s",
2271 search_test_ctx->base_dn);
2272 assert_non_null(basedn);
2275 * The search just needs to call DONE, we don't care about the
2276 * contents of the search for this test
2278 ret = ldb_build_search_req(&req,
2279 search_test_ctx->ldb_test_ctx->ldb,
2280 search_test_ctx,
2281 basedn,
2282 LDB_SCOPE_SUBTREE,
2283 "(&(!(filterAttr=*))"
2284 "(cn=test_search_cn))",
2285 NULL,
2286 NULL,
2287 NULL,
2288 test_ldb_modify_before_ldb_wait_callback1,
2289 NULL);
2290 assert_int_equal(ret, 0);
2291 ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req);
2293 ret = pipe(pipes);
2294 assert_int_equal(ret, 0);
2296 child_pid = fork();
2297 if (child_pid == 0) {
2298 TALLOC_CTX *tmp_ctx = NULL;
2299 struct ldb_message *msg;
2300 struct ldb_message_element *el;
2301 TALLOC_FREE(search_test_ctx->ldb_test_ctx->ldb);
2302 TALLOC_FREE(search_test_ctx->ldb_test_ctx->ev);
2303 search_test_ctx->ldb_test_ctx->ev = tevent_context_init(search_test_ctx->ldb_test_ctx);
2304 if (search_test_ctx->ldb_test_ctx->ev == NULL) {
2305 exit(LDB_ERR_OPERATIONS_ERROR);
2308 search_test_ctx->ldb_test_ctx->ldb = ldb_init(search_test_ctx->ldb_test_ctx,
2309 search_test_ctx->ldb_test_ctx->ev);
2310 if (search_test_ctx->ldb_test_ctx->ldb == NULL) {
2311 exit(LDB_ERR_OPERATIONS_ERROR);
2314 ret = ldb_connect(search_test_ctx->ldb_test_ctx->ldb,
2315 search_test_ctx->ldb_test_ctx->dbpath, 0, NULL);
2316 if (ret != LDB_SUCCESS) {
2317 exit(ret);
2320 tmp_ctx = talloc_new(search_test_ctx->ldb_test_ctx);
2321 if (tmp_ctx == NULL) {
2322 exit(LDB_ERR_OPERATIONS_ERROR);
2325 msg = ldb_msg_new(tmp_ctx);
2326 if (msg == NULL) {
2327 exit(LDB_ERR_OPERATIONS_ERROR);
2331 * We must re-create this DN from a string to ensure
2332 * it does not reference the now-gone LDB context of
2333 * the parent
2335 msg->dn = ldb_dn_new_fmt(search_test_ctx,
2336 search_test_ctx->ldb_test_ctx->ldb,
2337 "cn=test_search_cn,"
2338 "dc=search_test_entry");
2340 if (msg->dn == NULL) {
2341 exit(LDB_ERR_OPERATIONS_ERROR);
2344 ret = ldb_msg_add_string(msg, "filterAttr", "TRUE");
2345 if (ret != 0) {
2346 exit(LDB_ERR_OPERATIONS_ERROR);
2348 el = ldb_msg_find_element(msg, "filterAttr");
2349 if (el == NULL) {
2350 exit(LDB_ERR_OPERATIONS_ERROR);
2352 el->flags = LDB_FLAG_MOD_REPLACE;
2354 ret = ldb_transaction_start(search_test_ctx->ldb_test_ctx->ldb);
2355 if (ret != 0) {
2356 exit(ret);
2359 if (write(pipes[1], "GO", 2) != 2) {
2360 exit(LDB_ERR_OPERATIONS_ERROR);
2363 ret = ldb_modify(search_test_ctx->ldb_test_ctx->ldb, msg);
2364 if (ret != 0) {
2365 exit(ret);
2368 ret = ldb_transaction_commit(search_test_ctx->ldb_test_ctx->ldb);
2369 exit(ret);
2372 ret = read(pipes[0], buf, 2);
2373 assert_int_equal(ret, 2);
2375 sleep(3);
2378 * If writes are not blocked until after the (never called) ldb_wait(), we
2379 * will be able to successfully search for this modification
2380 * here
2383 ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb, search_test_ctx,
2384 &res2, search_dn, LDB_SCOPE_BASE, NULL,
2385 "filterAttr=TRUE");
2388 * We avoid making assertions before TALLOC_FREE()ing the request,
2389 * lest the assert fail and mess with the clean-up because we still
2390 * have locks.
2392 res_count = res2->count;
2393 TALLOC_FREE(req);
2395 /* We should not have got the result */
2396 assert_int_equal(res_count, 0);
2397 assert_int_equal(ret, 0);
2399 pid = waitpid(child_pid, &wstatus, 0);
2400 assert_int_equal(pid, child_pid);
2402 assert_true(WIFEXITED(wstatus));
2404 assert_int_equal(WEXITSTATUS(wstatus), 0);
2407 * If writes are blocked until after the search request was freed, we
2408 * will be able to successfully search for this modification
2409 * now
2412 search_dn = ldb_dn_new_fmt(search_test_ctx,
2413 search_test_ctx->ldb_test_ctx->ldb,
2414 "cn=test_search_cn,"
2415 "dc=search_test_entry");
2417 ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
2418 search_test_ctx,
2419 &res2, search_dn, LDB_SCOPE_BASE, NULL,
2420 "filterAttr=TRUE");
2421 assert_int_equal(ret, 0);
2423 /* We got the result */
2424 assert_int_equal(res2->count, 1);
2427 static int ldb_case_test_setup(void **state)
2429 int ret;
2430 struct ldb_ldif *ldif;
2431 struct ldbtest_ctx *ldb_test_ctx;
2432 const char *attrs_ldif = \
2433 "dn: @ATTRIBUTES\n"
2434 "cn: CASE_INSENSITIVE\n"
2435 "\n";
2436 struct keyval kvs[] = {
2437 { "cn", "CaseInsensitiveValue" },
2438 { "uid", "CaseSensitiveValue" },
2439 { NULL, NULL },
2443 ldbtest_setup((void **) &ldb_test_ctx);
2445 while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &attrs_ldif))) {
2446 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
2447 assert_int_equal(ret, LDB_SUCCESS);
2450 ldb_test_add_data(ldb_test_ctx,
2451 ldb_test_ctx,
2452 "cn=CaseInsensitiveValue",
2453 kvs);
2455 *state = ldb_test_ctx;
2456 return 0;
2459 static int ldb_case_test_teardown(void **state)
2461 int ret;
2462 struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
2463 struct ldbtest_ctx);
2465 struct ldb_dn *del_dn;
2467 del_dn = ldb_dn_new_fmt(ldb_test_ctx,
2468 ldb_test_ctx->ldb,
2469 "@ATTRIBUTES");
2470 assert_non_null(del_dn);
2472 ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
2473 assert_int_equal(ret, LDB_SUCCESS);
2475 assert_dn_doesnt_exist(ldb_test_ctx,
2476 "@ATTRIBUTES");
2478 ldb_test_remove_data(ldb_test_ctx, ldb_test_ctx,
2479 "cn=CaseInsensitiveValue");
2481 ldbtest_teardown((void **) &ldb_test_ctx);
2482 return 0;
2485 static void test_ldb_attrs_case_insensitive(void **state)
2487 int cnt;
2488 struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
2489 struct ldbtest_ctx);
2491 /* cn matches exact case */
2492 cnt = sub_search_count(ldb_test_ctx, "", "cn=CaseInsensitiveValue");
2493 assert_int_equal(cnt, 1);
2495 /* cn matches lower case */
2496 cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2497 assert_int_equal(cnt, 1);
2499 /* uid matches exact case */
2500 cnt = sub_search_count(ldb_test_ctx, "", "uid=CaseSensitiveValue");
2501 assert_int_equal(cnt, 1);
2503 /* uid does not match lower case */
2504 cnt = sub_search_count(ldb_test_ctx, "", "uid=casesensitivevalue");
2505 assert_int_equal(cnt, 0);
2508 static struct ldb_schema_attribute cn_attr_1;
2509 static struct ldb_schema_attribute cn_attr_2;
2510 static struct ldb_schema_attribute default_attr;
2513 override the name to attribute handler function
2515 static const struct ldb_schema_attribute *ldb_test_attribute_handler_override(struct ldb_context *ldb,
2516 void *private_data,
2517 const char *name)
2519 if (private_data != NULL && ldb_attr_cmp(name, "cn") == 0) {
2520 return &cn_attr_1;
2521 } else if (private_data == NULL && ldb_attr_cmp(name, "cn") == 0) {
2522 return &cn_attr_2;
2523 } else if (ldb_attr_cmp(name, "uid") == 0) {
2524 return &cn_attr_2;
2526 return &default_attr;
2529 static void test_ldb_attrs_case_handler(void **state)
2531 int cnt;
2532 int ret;
2533 const struct ldb_schema_syntax *syntax;
2535 struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
2536 struct ldbtest_ctx);
2537 struct ldb_context *ldb = ldb_test_ctx->ldb;
2539 /* cn matches lower case */
2540 cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2541 assert_int_equal(cnt, 1);
2543 syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_OCTET_STRING);
2544 assert_non_null(syntax);
2546 ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb,
2547 "*", 0,
2548 syntax, &default_attr);
2549 assert_int_equal(ret, LDB_SUCCESS);
2551 syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_OCTET_STRING);
2552 assert_non_null(syntax);
2554 ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb,
2555 "cn", 0,
2556 syntax, &cn_attr_1);
2557 assert_int_equal(ret, LDB_SUCCESS);
2560 * Set an attribute handler, which will fail to match as we
2561 * force case sensitive
2563 ldb_schema_attribute_set_override_handler(ldb,
2564 ldb_test_attribute_handler_override,
2565 (void *)1);
2567 /* cn does not matche lower case */
2568 cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2569 assert_int_equal(cnt, 0);
2571 syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_DIRECTORY_STRING);
2572 assert_non_null(syntax);
2574 ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb,
2575 "cn", 0,
2576 syntax, &cn_attr_2);
2577 assert_int_equal(ret, LDB_SUCCESS);
2580 * Set an attribute handler, which will match as we
2581 * force case insensitive
2583 ldb_schema_attribute_set_override_handler(ldb,
2584 ldb_test_attribute_handler_override,
2585 NULL);
2587 /* cn matches lower case */
2588 cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2589 assert_int_equal(cnt, 1);
2594 static void test_ldb_attrs_index_handler(void **state)
2596 int cnt;
2597 int ret;
2598 const struct ldb_schema_syntax *syntax;
2599 struct ldb_ldif *ldif;
2601 const char *index_ldif = \
2602 "dn: @INDEXLIST\n"
2603 "@IDXATTR: cn\n"
2604 "\n";
2606 struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
2607 struct ldbtest_ctx);
2608 struct ldb_context *ldb = ldb_test_ctx->ldb;
2610 /* cn matches lower case */
2611 cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2612 assert_int_equal(cnt, 1);
2614 syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_OCTET_STRING);
2615 assert_non_null(syntax);
2617 ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb,
2618 "cn", 0,
2619 syntax, &cn_attr_1);
2620 assert_int_equal(ret, LDB_SUCCESS);
2622 syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_DIRECTORY_STRING);
2623 assert_non_null(syntax);
2625 ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb,
2626 "cn", LDB_ATTR_FLAG_INDEXED,
2627 syntax, &cn_attr_2);
2628 assert_int_equal(ret, LDB_SUCCESS);
2630 syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_OCTET_STRING);
2631 assert_non_null(syntax);
2633 ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb,
2634 "", 0,
2635 syntax, &default_attr);
2636 assert_int_equal(ret, LDB_SUCCESS);
2639 * Set an attribute handler
2641 ldb_schema_attribute_set_override_handler(ldb,
2642 ldb_test_attribute_handler_override,
2643 NULL);
2645 /* cn matches lower case */
2646 cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2647 assert_int_equal(cnt, 1);
2649 /* Add the index (actually any modify will do) */
2650 while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &index_ldif))) {
2651 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
2652 assert_int_equal(ret, LDB_SUCCESS);
2655 ldb_schema_set_override_indexlist(ldb, false);
2657 /* cn does match as there is an index now */
2658 cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2659 assert_int_equal(cnt, 1);
2662 * Set an attribute handler, which will later fail to match as we
2663 * didn't re-index the DB
2665 ldb_schema_attribute_set_override_handler(ldb,
2666 ldb_test_attribute_handler_override,
2667 (void *)1);
2670 * cn does not match as we changed the case sensitivity, but
2671 * didn't re-index
2673 * This shows that the override is in control
2675 cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2676 assert_int_equal(cnt, 0);
2680 static int ldb_case_attrs_index_test_teardown(void **state)
2682 int ret;
2683 struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
2684 struct ldbtest_ctx);
2685 struct ldb_dn *del_dn;
2687 del_dn = ldb_dn_new_fmt(ldb_test_ctx,
2688 ldb_test_ctx->ldb,
2689 "@INDEXLIST");
2690 assert_non_null(del_dn);
2692 ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
2693 if (ret != LDB_ERR_NO_SUCH_OBJECT) {
2694 assert_int_equal(ret, LDB_SUCCESS);
2697 assert_dn_doesnt_exist(ldb_test_ctx,
2698 "@INDEXLIST");
2700 ldb_case_test_teardown(state);
2701 return 0;
2705 struct rename_test_ctx {
2706 struct ldbtest_ctx *ldb_test_ctx;
2708 struct ldb_dn *basedn;
2709 const char *str_basedn;
2711 const char *teardown_dn;
2714 static int ldb_rename_test_setup(void **state)
2716 struct ldbtest_ctx *ldb_test_ctx;
2717 struct rename_test_ctx *rename_test_ctx;
2718 const char *strdn = "dc=rename_test_entry_from";
2720 ldbtest_setup((void **) &ldb_test_ctx);
2722 rename_test_ctx = talloc(ldb_test_ctx, struct rename_test_ctx);
2723 assert_non_null(rename_test_ctx);
2724 rename_test_ctx->ldb_test_ctx = ldb_test_ctx;
2725 assert_non_null(rename_test_ctx->ldb_test_ctx);
2727 rename_test_ctx->basedn = ldb_dn_new_fmt(rename_test_ctx,
2728 rename_test_ctx->ldb_test_ctx->ldb,
2729 "%s", strdn);
2730 assert_non_null(rename_test_ctx->basedn);
2732 rename_test_ctx->str_basedn = strdn;
2733 rename_test_ctx->teardown_dn = strdn;
2735 add_dn_with_cn(ldb_test_ctx,
2736 rename_test_ctx->basedn,
2737 "test_rename_cn_val");
2739 *state = rename_test_ctx;
2740 return 0;
2743 static int ldb_rename_test_teardown(void **state)
2745 int ret;
2746 struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(*state,
2747 struct rename_test_ctx);
2748 struct ldbtest_ctx *ldb_test_ctx;
2749 struct ldb_dn *del_dn;
2751 ldb_test_ctx = rename_test_ctx->ldb_test_ctx;
2753 del_dn = ldb_dn_new_fmt(rename_test_ctx,
2754 rename_test_ctx->ldb_test_ctx->ldb,
2755 "%s", rename_test_ctx->teardown_dn);
2756 assert_non_null(del_dn);
2758 ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
2759 assert_int_equal(ret, LDB_SUCCESS);
2761 assert_dn_doesnt_exist(ldb_test_ctx,
2762 rename_test_ctx->teardown_dn);
2764 ldbtest_teardown((void **) &ldb_test_ctx);
2765 return 0;
2768 static void test_ldb_rename(void **state)
2770 struct rename_test_ctx *rename_test_ctx =
2771 talloc_get_type_abort(*state, struct rename_test_ctx);
2772 int ret;
2773 const char *str_new_dn = "dc=rename_test_entry_to";
2774 struct ldb_dn *new_dn;
2776 new_dn = ldb_dn_new_fmt(rename_test_ctx,
2777 rename_test_ctx->ldb_test_ctx->ldb,
2778 "%s", str_new_dn);
2779 assert_non_null(new_dn);
2781 ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
2782 rename_test_ctx->basedn,
2783 new_dn);
2784 assert_int_equal(ret, LDB_SUCCESS);
2786 assert_dn_exists(rename_test_ctx->ldb_test_ctx, str_new_dn);
2787 assert_dn_doesnt_exist(rename_test_ctx->ldb_test_ctx,
2788 rename_test_ctx->str_basedn);
2789 rename_test_ctx->teardown_dn = str_new_dn;
2791 /* FIXME - test the values which didn't change */
2794 static void test_ldb_rename_from_doesnt_exist(void **state)
2796 struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(
2797 *state,
2798 struct rename_test_ctx);
2799 int ret;
2800 const char *str_new_dn = "dc=rename_test_entry_to";
2801 const char *str_bad_old_dn = "dc=rename_test_no_such_entry";
2802 struct ldb_dn *new_dn;
2803 struct ldb_dn *bad_old_dn;
2805 new_dn = ldb_dn_new_fmt(rename_test_ctx,
2806 rename_test_ctx->ldb_test_ctx->ldb,
2807 "%s", str_new_dn);
2808 assert_non_null(new_dn);
2810 bad_old_dn = ldb_dn_new_fmt(rename_test_ctx,
2811 rename_test_ctx->ldb_test_ctx->ldb,
2812 "%s", str_bad_old_dn);
2813 assert_non_null(bad_old_dn);
2815 assert_dn_doesnt_exist(rename_test_ctx->ldb_test_ctx,
2816 str_bad_old_dn);
2818 ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
2819 bad_old_dn, new_dn);
2820 assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT);
2822 assert_dn_doesnt_exist(rename_test_ctx->ldb_test_ctx,
2823 str_new_dn);
2826 static void test_ldb_rename_to_exists(void **state)
2828 struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(
2829 *state,
2830 struct rename_test_ctx);
2831 int ret;
2832 const char *str_new_dn = "dc=rename_test_already_exists";
2833 struct ldb_dn *new_dn;
2835 new_dn = ldb_dn_new_fmt(rename_test_ctx,
2836 rename_test_ctx->ldb_test_ctx->ldb,
2837 "%s", str_new_dn);
2838 assert_non_null(new_dn);
2840 add_dn_with_cn(rename_test_ctx->ldb_test_ctx,
2841 new_dn,
2842 "test_rename_cn_val");
2844 ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
2845 rename_test_ctx->basedn,
2846 new_dn);
2847 assert_int_equal(ret, LDB_ERR_ENTRY_ALREADY_EXISTS);
2849 /* Old object must still exist */
2850 assert_dn_exists(rename_test_ctx->ldb_test_ctx,
2851 rename_test_ctx->str_basedn);
2853 ret = ldb_delete(rename_test_ctx->ldb_test_ctx->ldb,
2854 new_dn);
2855 assert_int_equal(ret, LDB_SUCCESS);
2857 assert_dn_exists(rename_test_ctx->ldb_test_ctx,
2858 rename_test_ctx->teardown_dn);
2861 static void test_ldb_rename_self(void **state)
2863 struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(
2864 *state,
2865 struct rename_test_ctx);
2866 int ret;
2868 /* Oddly enough, this is a success in ldb.. */
2869 ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
2870 rename_test_ctx->basedn,
2871 rename_test_ctx->basedn);
2872 assert_int_equal(ret, LDB_SUCCESS);
2874 /* Old object must still exist */
2875 assert_dn_exists(rename_test_ctx->ldb_test_ctx,
2876 rename_test_ctx->str_basedn);
2879 static void test_ldb_rename_dn_case_change(void **state)
2881 struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(
2882 *state,
2883 struct rename_test_ctx);
2884 int ret;
2885 char *str_new_dn;
2886 struct ldb_dn *new_dn;
2887 unsigned i;
2889 str_new_dn = talloc_strdup(rename_test_ctx, rename_test_ctx->str_basedn);
2890 assert_non_null(str_new_dn);
2891 for (i = 0; str_new_dn[i]; i++) {
2892 str_new_dn[i] = toupper(str_new_dn[i]);
2895 new_dn = ldb_dn_new_fmt(rename_test_ctx,
2896 rename_test_ctx->ldb_test_ctx->ldb,
2897 "%s", str_new_dn);
2898 assert_non_null(new_dn);
2900 ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
2901 rename_test_ctx->basedn,
2902 new_dn);
2903 assert_int_equal(ret, LDB_SUCCESS);
2905 /* DNs are case insensitive, so both searches will match */
2906 assert_dn_exists(rename_test_ctx->ldb_test_ctx, str_new_dn);
2907 assert_dn_exists(rename_test_ctx->ldb_test_ctx,
2908 rename_test_ctx->str_basedn);
2909 /* FIXME - test the values didn't change */
2912 static int ldb_read_only_setup(void **state)
2914 struct ldbtest_ctx *test_ctx;
2916 ldbtest_setup((void **) &test_ctx);
2918 *state = test_ctx;
2919 return 0;
2922 static int ldb_read_only_teardown(void **state)
2924 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
2925 struct ldbtest_ctx);
2926 ldbtest_teardown((void **) &test_ctx);
2927 return 0;
2930 static void test_read_only(void **state)
2932 struct ldb_context *ro_ldb = NULL;
2933 struct ldb_context *rw_ldb = NULL;
2934 int ret;
2935 TALLOC_CTX *tmp_ctx = NULL;
2937 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
2938 struct ldbtest_ctx);
2940 * Close the ldb context freeing it this will ensure it exists on
2941 * disk and can be opened in read only mode
2943 TALLOC_FREE(test_ctx->ldb);
2946 * Open the database in read only and read write mode,
2947 * ensure it's opend in read only mode first
2949 ro_ldb = ldb_init(test_ctx, test_ctx->ev);
2950 ret = ldb_connect(ro_ldb, test_ctx->dbpath, LDB_FLG_RDONLY, NULL);
2951 assert_int_equal(ret, 0);
2953 rw_ldb = ldb_init(test_ctx, test_ctx->ev);
2954 ret = ldb_connect(rw_ldb, test_ctx->dbpath, 0, NULL);
2955 assert_int_equal(ret, 0);
2959 * Set up a context for the temporary variables
2961 tmp_ctx = talloc_new(test_ctx);
2962 assert_non_null(tmp_ctx);
2965 * Ensure that we can search the read write database
2968 struct ldb_result *result = NULL;
2969 struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, rw_ldb,
2970 "dc=test");
2971 assert_non_null(dn);
2973 ret = ldb_search(rw_ldb, tmp_ctx, &result, dn,
2974 LDB_SCOPE_BASE, NULL, NULL);
2975 assert_int_equal(ret, LDB_SUCCESS);
2976 TALLOC_FREE(result);
2977 TALLOC_FREE(dn);
2981 * Ensure that we can search the read only database
2984 struct ldb_result *result = NULL;
2985 struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, ro_ldb,
2986 "dc=test");
2987 assert_non_null(dn);
2989 ret = ldb_search(ro_ldb, tmp_ctx, &result, dn,
2990 LDB_SCOPE_BASE, NULL, NULL);
2991 assert_int_equal(ret, LDB_SUCCESS);
2992 TALLOC_FREE(result);
2993 TALLOC_FREE(dn);
2996 * Ensure that a write to the read only database fails
2999 struct ldb_message *msg = NULL;
3000 msg = ldb_msg_new(tmp_ctx);
3001 assert_non_null(msg);
3003 msg->dn = ldb_dn_new_fmt(msg, ro_ldb, "dc=test");
3004 assert_non_null(msg->dn);
3006 ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
3007 assert_int_equal(ret, 0);
3009 ret = ldb_add(ro_ldb, msg);
3010 assert_int_equal(ret, LDB_ERR_UNWILLING_TO_PERFORM);
3011 TALLOC_FREE(msg);
3015 * Ensure that a write to the read write database succeeds
3018 struct ldb_message *msg = NULL;
3019 msg = ldb_msg_new(tmp_ctx);
3020 assert_non_null(msg);
3022 msg->dn = ldb_dn_new_fmt(msg, ro_ldb, "dc=test");
3023 assert_non_null(msg->dn);
3025 ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
3026 assert_int_equal(ret, 0);
3028 ret = ldb_add(rw_ldb, msg);
3029 assert_int_equal(ret, LDB_SUCCESS);
3030 TALLOC_FREE(msg);
3034 * Ensure that a delete from a read only database fails
3037 struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, ro_ldb, "dc=test");
3038 assert_non_null(dn);
3040 ret = ldb_delete(ro_ldb, dn);
3041 assert_int_equal(ret, LDB_ERR_UNWILLING_TO_PERFORM);
3042 TALLOC_FREE(dn);
3047 * Ensure that a delete from a read write succeeds
3050 struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, rw_ldb, "dc=test");
3051 assert_non_null(dn);
3053 ret = ldb_delete(rw_ldb, dn);
3054 assert_int_equal(ret, LDB_SUCCESS);
3055 TALLOC_FREE(dn);
3057 TALLOC_FREE(tmp_ctx);
3060 static bool unique_values = false;
3062 static int unique_index_test_module_add(
3063 struct ldb_module *module,
3064 struct ldb_request *req)
3066 if (unique_values) {
3067 struct ldb_message *msg = discard_const(req->op.add.message);
3068 struct ldb_message_element *el = NULL;
3069 el = ldb_msg_find_element(msg, "cn");
3070 if (el != NULL) {
3071 el->flags |= LDB_FLAG_INTERNAL_FORCE_UNIQUE_INDEX;
3075 return ldb_next_request(module, req);
3078 static int unique_index_test_module_init(struct ldb_module *module)
3080 return ldb_next_init(module);
3083 static const struct ldb_module_ops ldb_unique_index_test_module_ops = {
3084 .name = "unique_index_test",
3085 .init_context = unique_index_test_module_init,
3086 .add = unique_index_test_module_add,
3089 static int ldb_unique_index_test_setup(void **state)
3091 int ret;
3092 struct ldb_ldif *ldif;
3093 struct ldbtest_ctx *ldb_test_ctx;
3094 const char *attrs_ldif = \
3095 "dn: @ATTRIBUTES\n"
3096 "cn: UNIQUE_INDEX\n"
3097 "\n";
3098 const char *index_ldif = \
3099 "dn: @INDEXLIST\n"
3100 "@IDXATTR: cn\n"
3101 "\n";
3102 const char *options[] = {"modules:unique_index_test"};
3105 ret = ldb_register_module(&ldb_unique_index_test_module_ops);
3106 assert_true(ret == LDB_SUCCESS || ret == LDB_ERR_ENTRY_ALREADY_EXISTS);
3107 ldbtest_noconn_setup((void **) &ldb_test_ctx);
3110 ret = ldb_connect(ldb_test_ctx->ldb, ldb_test_ctx->dbpath, 0, options);
3111 assert_int_equal(ret, 0);
3113 while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &attrs_ldif))) {
3114 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
3115 assert_int_equal(ret, LDB_SUCCESS);
3118 while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &index_ldif))) {
3119 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
3120 assert_int_equal(ret, LDB_SUCCESS);
3123 unique_values = true;
3125 *state = ldb_test_ctx;
3126 return 0;
3129 static int ldb_unique_index_test_teardown(void **state)
3131 int ret;
3132 struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
3133 struct ldbtest_ctx);
3134 struct ldb_dn *del_dn;
3136 del_dn = ldb_dn_new_fmt(ldb_test_ctx,
3137 ldb_test_ctx->ldb,
3138 "@INDEXLIST");
3139 assert_non_null(del_dn);
3141 ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
3142 if (ret != LDB_ERR_NO_SUCH_OBJECT) {
3143 assert_int_equal(ret, LDB_SUCCESS);
3146 assert_dn_doesnt_exist(ldb_test_ctx,
3147 "@INDEXLIST");
3149 TALLOC_FREE(del_dn);
3151 del_dn = ldb_dn_new_fmt(ldb_test_ctx,
3152 ldb_test_ctx->ldb,
3153 "@ATTRIBUTES");
3154 assert_non_null(del_dn);
3156 ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
3157 if (ret != LDB_ERR_NO_SUCH_OBJECT) {
3158 assert_int_equal(ret, LDB_SUCCESS);
3161 assert_dn_doesnt_exist(ldb_test_ctx,
3162 "@ATTRIBUTES");
3164 ldbtest_teardown((void **) &ldb_test_ctx);
3165 return 0;
3169 static void test_ldb_add_unique_value_to_unique_index(void **state)
3171 int ret;
3172 struct ldb_message *msg;
3173 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3174 struct ldbtest_ctx);
3175 TALLOC_CTX *tmp_ctx;
3177 tmp_ctx = talloc_new(test_ctx);
3178 assert_non_null(tmp_ctx);
3180 msg = ldb_msg_new(tmp_ctx);
3181 assert_non_null(msg);
3183 msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "dc=test");
3184 assert_non_null(msg->dn);
3186 ret = ldb_msg_add_string(msg, "cn", "test_unique_index");
3187 assert_int_equal(ret, LDB_SUCCESS);
3189 ret = ldb_add(test_ctx->ldb, msg);
3190 assert_int_equal(ret, LDB_SUCCESS);
3192 talloc_free(tmp_ctx);
3195 static int ldb_non_unique_index_test_setup(void **state)
3197 int ret;
3198 struct ldb_ldif *ldif;
3199 struct ldbtest_ctx *ldb_test_ctx;
3200 const char *index_ldif = \
3201 "dn: @INDEXLIST\n"
3202 "@IDXATTR: cn\n"
3203 "\n";
3204 const char *options[] = {"modules:unique_index_test"};
3207 ret = ldb_register_module(&ldb_unique_index_test_module_ops);
3208 assert_true(ret == LDB_SUCCESS || ret == LDB_ERR_ENTRY_ALREADY_EXISTS);
3209 ldbtest_noconn_setup((void **) &ldb_test_ctx);
3212 ret = ldb_connect(ldb_test_ctx->ldb, ldb_test_ctx->dbpath, 0, options);
3213 assert_int_equal(ret, 0);
3215 while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &index_ldif))) {
3216 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
3217 assert_int_equal(ret, LDB_SUCCESS);
3220 unique_values = true;
3222 *state = ldb_test_ctx;
3223 return 0;
3226 static int ldb_non_unique_index_test_teardown(void **state)
3228 int ret;
3229 struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
3230 struct ldbtest_ctx);
3231 struct ldb_dn *del_dn;
3233 del_dn = ldb_dn_new_fmt(ldb_test_ctx,
3234 ldb_test_ctx->ldb,
3235 "@INDEXLIST");
3236 assert_non_null(del_dn);
3238 ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
3239 if (ret != LDB_ERR_NO_SUCH_OBJECT) {
3240 assert_int_equal(ret, LDB_SUCCESS);
3243 assert_dn_doesnt_exist(ldb_test_ctx,
3244 "@INDEXLIST");
3246 TALLOC_FREE(del_dn);
3248 ldbtest_teardown((void **) &ldb_test_ctx);
3249 return 0;
3252 static void test_ldb_add_duplicate_value_to_unique_index(void **state)
3254 int ret;
3255 struct ldb_message *msg01;
3256 struct ldb_message *msg02;
3257 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3258 struct ldbtest_ctx);
3259 TALLOC_CTX *tmp_ctx;
3261 tmp_ctx = talloc_new(test_ctx);
3262 assert_non_null(tmp_ctx);
3264 msg01 = ldb_msg_new(tmp_ctx);
3265 assert_non_null(msg01);
3267 msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3268 assert_non_null(msg01->dn);
3270 ret = ldb_msg_add_string(msg01, "cn", "test_unique_index");
3271 assert_int_equal(ret, LDB_SUCCESS);
3273 ret = ldb_add(test_ctx->ldb, msg01);
3274 assert_int_equal(ret, LDB_SUCCESS);
3276 msg02 = ldb_msg_new(tmp_ctx);
3277 assert_non_null(msg02);
3279 msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02");
3280 assert_non_null(msg02->dn);
3282 ret = ldb_msg_add_string(msg02, "cn", "test_unique_index");
3283 assert_int_equal(ret, LDB_SUCCESS);
3285 ret = ldb_add(test_ctx->ldb, msg02);
3286 assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION);
3287 talloc_free(tmp_ctx);
3290 static void test_ldb_add_to_index_duplicates_allowed(void **state)
3292 int ret;
3293 struct ldb_message *msg01;
3294 struct ldb_message *msg02;
3295 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3296 struct ldbtest_ctx);
3297 TALLOC_CTX *tmp_ctx;
3299 unique_values = false;
3301 tmp_ctx = talloc_new(test_ctx);
3302 assert_non_null(tmp_ctx);
3305 msg01 = ldb_msg_new(tmp_ctx);
3306 assert_non_null(msg01);
3308 msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3309 assert_non_null(msg01->dn);
3311 ret = ldb_msg_add_string(msg01, "cn", "test_unique_index");
3312 assert_int_equal(ret, LDB_SUCCESS);
3314 ret = ldb_add(test_ctx->ldb, msg01);
3315 assert_int_equal(ret, LDB_SUCCESS);
3317 msg02 = ldb_msg_new(tmp_ctx);
3318 assert_non_null(msg02);
3320 msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02");
3321 assert_non_null(msg02->dn);
3323 ret = ldb_msg_add_string(msg02, "cn", "test_unique_index");
3324 assert_int_equal(ret, LDB_SUCCESS);
3326 ret = ldb_add(test_ctx->ldb, msg02);
3327 assert_int_equal(ret, LDB_SUCCESS);
3328 talloc_free(tmp_ctx);
3331 static void test_ldb_add_to_index_unique_values_required(void **state)
3333 int ret;
3334 struct ldb_message *msg01;
3335 struct ldb_message *msg02;
3336 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3337 struct ldbtest_ctx);
3338 TALLOC_CTX *tmp_ctx;
3340 unique_values = true;
3342 tmp_ctx = talloc_new(test_ctx);
3343 assert_non_null(tmp_ctx);
3346 msg01 = ldb_msg_new(tmp_ctx);
3347 assert_non_null(msg01);
3349 msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3350 assert_non_null(msg01->dn);
3352 ret = ldb_msg_add_string(msg01, "cn", "test_unique_index");
3353 assert_int_equal(ret, LDB_SUCCESS);
3355 ret = ldb_add(test_ctx->ldb, msg01);
3356 assert_int_equal(ret, LDB_SUCCESS);
3358 msg02 = ldb_msg_new(tmp_ctx);
3359 assert_non_null(msg02);
3361 msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02");
3362 assert_non_null(msg02->dn);
3364 ret = ldb_msg_add_string(msg02, "cn", "test_unique_index");
3365 assert_int_equal(ret, LDB_SUCCESS);
3367 ret = ldb_add(test_ctx->ldb, msg02);
3368 assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION);
3369 talloc_free(tmp_ctx);
3372 static void ldb_debug_string(void *context, enum ldb_debug_level level,
3373 const char *fmt, va_list ap)
3376 if (level <= LDB_DEBUG_WARNING) {
3377 *((char **)context) = talloc_vasprintf(NULL, fmt, ap);
3381 static void test_ldb_unique_index_duplicate_logging(void **state)
3383 int ret;
3384 struct ldb_message *msg01;
3385 struct ldb_message *msg02;
3386 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3387 struct ldbtest_ctx);
3388 TALLOC_CTX *tmp_ctx;
3389 char *debug_string = NULL;
3390 char *p = NULL;
3392 ldb_set_debug(test_ctx->ldb, ldb_debug_string, &debug_string);
3393 tmp_ctx = talloc_new(test_ctx);
3394 assert_non_null(tmp_ctx);
3396 msg01 = ldb_msg_new(tmp_ctx);
3397 assert_non_null(msg01);
3399 msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3400 assert_non_null(msg01->dn);
3402 ret = ldb_msg_add_string(msg01, "cn", "test_unique_index");
3403 assert_int_equal(ret, LDB_SUCCESS);
3405 ret = ldb_add(test_ctx->ldb, msg01);
3406 assert_int_equal(ret, LDB_SUCCESS);
3408 msg02 = ldb_msg_new(tmp_ctx);
3409 assert_non_null(msg02);
3411 msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02");
3412 assert_non_null(msg02->dn);
3414 ret = ldb_msg_add_string(msg02, "cn", "test_unique_index");
3415 assert_int_equal(ret, LDB_SUCCESS);
3417 ret = ldb_add(test_ctx->ldb, msg02);
3418 assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION);
3420 assert_non_null(debug_string);
3421 p = strstr(
3422 debug_string,
3423 "unique index violation on cn "
3424 "in dc=test02, conficts with dc=test01 in "
3425 "@INDEX:CN:test_unique_index");
3426 assert_non_null(p);
3427 TALLOC_FREE(debug_string);
3428 talloc_free(tmp_ctx);
3431 static void test_ldb_duplicate_dn_logging(void **state)
3433 int ret;
3434 struct ldb_message *msg01;
3435 struct ldb_message *msg02;
3436 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3437 struct ldbtest_ctx);
3438 TALLOC_CTX *tmp_ctx;
3439 char *debug_string = NULL;
3441 ldb_set_debug(test_ctx->ldb, ldb_debug_string, &debug_string);
3442 tmp_ctx = talloc_new(test_ctx);
3443 assert_non_null(tmp_ctx);
3445 msg01 = ldb_msg_new(tmp_ctx);
3446 assert_non_null(msg01);
3448 msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3449 assert_non_null(msg01->dn);
3451 ret = ldb_msg_add_string(msg01, "cn", "test_unique_index01");
3452 assert_int_equal(ret, LDB_SUCCESS);
3454 ret = ldb_add(test_ctx->ldb, msg01);
3455 assert_int_equal(ret, LDB_SUCCESS);
3457 msg02 = ldb_msg_new(tmp_ctx);
3458 assert_non_null(msg02);
3460 msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test01");
3461 assert_non_null(msg02->dn);
3463 ret = ldb_msg_add_string(msg02, "cn", "test_unique_index02");
3464 assert_int_equal(ret, LDB_SUCCESS);
3466 ret = ldb_add(test_ctx->ldb, msg02);
3467 assert_int_equal(ret, LDB_ERR_ENTRY_ALREADY_EXISTS);
3469 assert_null(debug_string);
3470 talloc_free(tmp_ctx);
3473 static int ldb_guid_index_test_setup(void **state)
3475 int ret;
3476 struct ldb_ldif *ldif;
3477 struct ldbtest_ctx *ldb_test_ctx;
3478 const char *attrs_ldif = \
3479 "dn: @ATTRIBUTES\n"
3480 "cn: UNIQUE_INDEX\n"
3481 "\n";
3482 const char *index_ldif = \
3483 "dn: @INDEXLIST\n"
3484 "@IDXATTR: cn\n"
3485 "@IDXGUID: objectUUID\n"
3486 "@IDX_DN_GUID: GUID\n"
3487 "\n";
3489 ldbtest_noconn_setup((void **) &ldb_test_ctx);
3492 ret = ldb_connect(ldb_test_ctx->ldb, ldb_test_ctx->dbpath, 0, NULL);
3493 assert_int_equal(ret, 0);
3495 while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &attrs_ldif))) {
3496 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
3497 assert_int_equal(ret, LDB_SUCCESS);
3500 while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &index_ldif))) {
3501 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
3502 assert_int_equal(ret, LDB_SUCCESS);
3505 *state = ldb_test_ctx;
3506 return 0;
3509 static int ldb_guid_index_test_teardown(void **state)
3511 int ret;
3512 struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
3513 struct ldbtest_ctx);
3514 struct ldb_dn *del_dn;
3516 del_dn = ldb_dn_new_fmt(ldb_test_ctx,
3517 ldb_test_ctx->ldb,
3518 "@INDEXLIST");
3519 assert_non_null(del_dn);
3521 ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
3522 if (ret != LDB_ERR_NO_SUCH_OBJECT) {
3523 assert_int_equal(ret, LDB_SUCCESS);
3526 assert_dn_doesnt_exist(ldb_test_ctx,
3527 "@INDEXLIST");
3529 TALLOC_FREE(del_dn);
3531 del_dn = ldb_dn_new_fmt(ldb_test_ctx,
3532 ldb_test_ctx->ldb,
3533 "@ATTRIBUTES");
3534 assert_non_null(del_dn);
3536 ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
3537 if (ret != LDB_ERR_NO_SUCH_OBJECT) {
3538 assert_int_equal(ret, LDB_SUCCESS);
3541 assert_dn_doesnt_exist(ldb_test_ctx,
3542 "@ATTRIBUTES");
3544 ldbtest_teardown((void **) &ldb_test_ctx);
3545 return 0;
3549 static void test_ldb_unique_index_duplicate_with_guid(void **state)
3551 int ret;
3552 struct ldb_message *msg01;
3553 struct ldb_message *msg02;
3554 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3555 struct ldbtest_ctx);
3556 TALLOC_CTX *tmp_ctx;
3557 char *debug_string = NULL;
3558 char *p = NULL;
3560 ldb_set_debug(test_ctx->ldb, ldb_debug_string, &debug_string);
3561 tmp_ctx = talloc_new(test_ctx);
3562 assert_non_null(tmp_ctx);
3564 msg01 = ldb_msg_new(tmp_ctx);
3565 assert_non_null(msg01);
3567 msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3568 assert_non_null(msg01->dn);
3570 ret = ldb_msg_add_string(msg01, "cn", "test_unique_index");
3571 assert_int_equal(ret, LDB_SUCCESS);
3573 ret = ldb_msg_add_string(msg01, "objectUUID", "0123456789abcdef");
3574 assert_int_equal(ret, LDB_SUCCESS);
3576 ret = ldb_add(test_ctx->ldb, msg01);
3577 assert_int_equal(ret, LDB_SUCCESS);
3579 msg02 = ldb_msg_new(tmp_ctx);
3580 assert_non_null(msg01);
3582 msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02");
3583 assert_non_null(msg02->dn);
3585 ret = ldb_msg_add_string(msg02, "cn", "test_unique_index");
3586 assert_int_equal(ret, LDB_SUCCESS);
3588 ret = ldb_msg_add_string(msg02, "objectUUID", "0123456789abcde0");
3589 assert_int_equal(ret, LDB_SUCCESS);
3591 ret = ldb_add(test_ctx->ldb, msg02);
3592 assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION);
3594 assert_non_null(debug_string);
3595 p = strstr(
3596 debug_string,
3597 "unique index violation on cn in dc=test02, conficts with "
3598 "objectUUID 0123456789abcdef in @INDEX:CN:test_unique_index");
3599 assert_non_null(p);
3600 TALLOC_FREE(debug_string);
3601 talloc_free(tmp_ctx);
3604 static void test_ldb_guid_index_duplicate_dn_logging(void **state)
3606 int ret;
3607 struct ldb_message *msg01;
3608 struct ldb_message *msg02;
3609 struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3610 struct ldbtest_ctx);
3611 TALLOC_CTX *tmp_ctx;
3612 char *debug_string = NULL;
3614 ldb_set_debug(test_ctx->ldb, ldb_debug_string, &debug_string);
3615 tmp_ctx = talloc_new(test_ctx);
3616 assert_non_null(tmp_ctx);
3618 msg01 = ldb_msg_new(tmp_ctx);
3619 assert_non_null(msg01);
3621 msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3622 assert_non_null(msg01->dn);
3624 ret = ldb_msg_add_string(msg01, "cn", "test_unique_index01");
3625 assert_int_equal(ret, LDB_SUCCESS);
3627 ret = ldb_msg_add_string(msg01, "objectUUID", "0123456789abcdef");
3628 assert_int_equal(ret, LDB_SUCCESS);
3630 ret = ldb_add(test_ctx->ldb, msg01);
3631 assert_int_equal(ret, LDB_SUCCESS);
3633 msg02 = ldb_msg_new(tmp_ctx);
3634 assert_non_null(msg02);
3636 msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test01");
3637 assert_non_null(msg02->dn);
3639 ret = ldb_msg_add_string(msg02, "cn", "test_unique_index02");
3640 assert_int_equal(ret, LDB_SUCCESS);
3642 ret = ldb_msg_add_string(msg02, "objectUUID", "0123456789abcde1");
3643 assert_int_equal(ret, LDB_SUCCESS);
3645 ret = ldb_add(test_ctx->ldb, msg02);
3646 assert_int_equal(ret, LDB_ERR_ENTRY_ALREADY_EXISTS);
3648 assert_null(debug_string);
3649 talloc_free(tmp_ctx);
3652 static void test_ldb_talloc_destructor_transaction_cleanup(void **state)
3654 struct ldbtest_ctx *test_ctx = NULL;
3656 test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx);
3657 assert_non_null(test_ctx);
3659 ldb_transaction_start(test_ctx->ldb);
3662 * Trigger the destructor
3664 TALLOC_FREE(test_ctx->ldb);
3667 * Now ensure that a new connection can be opened
3670 TALLOC_CTX *tctx = talloc_new(test_ctx);
3671 struct ldbtest_ctx *ctx = talloc_zero(tctx, struct ldbtest_ctx);
3672 struct ldb_dn *basedn;
3673 struct ldb_result *result = NULL;
3674 int ret;
3676 ldbtest_setup((void *)&ctx);
3678 basedn = ldb_dn_new_fmt(tctx, ctx->ldb, "dc=test");
3679 assert_non_null(basedn);
3681 ret = ldb_search(ctx->ldb,
3682 tctx,
3683 &result,
3684 basedn,
3685 LDB_SCOPE_BASE,
3686 NULL,
3687 NULL);
3688 assert_int_equal(ret, 0);
3689 assert_non_null(result);
3690 assert_int_equal(result->count, 0);
3692 ldbtest_teardown((void *)&ctx);
3697 int main(int argc, const char **argv)
3699 const struct CMUnitTest tests[] = {
3700 cmocka_unit_test_setup_teardown(test_connect,
3701 ldbtest_noconn_setup,
3702 ldbtest_noconn_teardown),
3703 cmocka_unit_test_setup_teardown(test_ldif_message,
3704 ldbtest_noconn_setup,
3705 ldbtest_noconn_teardown),
3706 cmocka_unit_test_setup_teardown(test_ldif_message_redacted,
3707 ldbtest_noconn_setup,
3708 ldbtest_noconn_teardown),
3709 cmocka_unit_test_setup_teardown(test_ldb_add,
3710 ldbtest_setup,
3711 ldbtest_teardown),
3712 cmocka_unit_test_setup_teardown(test_ldb_search,
3713 ldbtest_setup,
3714 ldbtest_teardown),
3715 cmocka_unit_test_setup_teardown(test_ldb_del,
3716 ldbtest_setup,
3717 ldbtest_teardown),
3718 cmocka_unit_test_setup_teardown(test_ldb_del_noexist,
3719 ldbtest_setup,
3720 ldbtest_teardown),
3721 cmocka_unit_test_setup_teardown(test_ldb_handle,
3722 ldbtest_setup,
3723 ldbtest_teardown),
3724 cmocka_unit_test_setup_teardown(test_ldb_build_search_req,
3725 ldbtest_setup,
3726 ldbtest_teardown),
3727 cmocka_unit_test_setup_teardown(test_transactions,
3728 ldbtest_setup,
3729 ldbtest_teardown),
3730 cmocka_unit_test_setup_teardown(test_nested_transactions,
3731 ldbtest_setup,
3732 ldbtest_teardown),
3733 cmocka_unit_test_setup_teardown(test_ldb_modify_add_key,
3734 ldb_modify_test_setup,
3735 ldb_modify_test_teardown),
3736 cmocka_unit_test_setup_teardown(test_ldb_modify_extend_key,
3737 ldb_modify_test_setup,
3738 ldb_modify_test_teardown),
3739 cmocka_unit_test_setup_teardown(test_ldb_modify_add_key_noval,
3740 ldb_modify_test_setup,
3741 ldb_modify_test_teardown),
3742 cmocka_unit_test_setup_teardown(test_ldb_modify_replace_key,
3743 ldb_modify_test_setup,
3744 ldb_modify_test_teardown),
3745 cmocka_unit_test_setup_teardown(test_ldb_modify_replace_noexist_key,
3746 ldb_modify_test_setup,
3747 ldb_modify_test_teardown),
3748 cmocka_unit_test_setup_teardown(test_ldb_modify_replace_zero_vals,
3749 ldb_modify_test_setup,
3750 ldb_modify_test_teardown),
3751 cmocka_unit_test_setup_teardown(test_ldb_modify_replace_noexist_key_zero_vals,
3752 ldb_modify_test_setup,
3753 ldb_modify_test_teardown),
3754 cmocka_unit_test_setup_teardown(test_ldb_modify_del_key,
3755 ldb_modify_test_setup,
3756 ldb_modify_test_teardown),
3757 cmocka_unit_test_setup_teardown(test_ldb_modify_del_keyval,
3758 ldb_modify_test_setup,
3759 ldb_modify_test_teardown),
3760 cmocka_unit_test_setup_teardown(test_search_match_none,
3761 ldb_search_test_setup,
3762 ldb_search_test_teardown),
3763 cmocka_unit_test_setup_teardown(test_search_match_one,
3764 ldb_search_test_setup,
3765 ldb_search_test_teardown),
3766 cmocka_unit_test_setup_teardown(test_search_match_filter,
3767 ldb_search_test_setup,
3768 ldb_search_test_teardown),
3769 cmocka_unit_test_setup_teardown(test_search_match_both,
3770 ldb_search_test_setup,
3771 ldb_search_test_teardown),
3772 cmocka_unit_test_setup_teardown(test_search_match_basedn,
3773 ldb_search_test_setup,
3774 ldb_search_test_teardown),
3775 cmocka_unit_test_setup_teardown(test_ldb_search_against_transaction,
3776 ldb_search_test_setup,
3777 ldb_search_test_teardown),
3778 cmocka_unit_test_setup_teardown(test_ldb_modify_during_unindexed_search,
3779 ldb_search_test_setup,
3780 ldb_search_test_teardown),
3781 cmocka_unit_test_setup_teardown(test_ldb_modify_during_indexed_search,
3782 ldb_search_test_setup,
3783 ldb_search_test_teardown),
3784 cmocka_unit_test_setup_teardown(test_ldb_rename_during_unindexed_search,
3785 ldb_search_test_setup,
3786 ldb_search_test_teardown),
3787 cmocka_unit_test_setup_teardown(test_ldb_rename_during_indexed_search,
3788 ldb_search_test_setup,
3789 ldb_search_test_teardown),
3790 cmocka_unit_test_setup_teardown(test_ldb_modify_during_whole_search,
3791 ldb_search_test_setup,
3792 ldb_search_test_teardown),
3793 cmocka_unit_test_setup_teardown(test_ldb_modify_before_ldb_wait,
3794 ldb_search_test_setup,
3795 ldb_search_test_teardown),
3796 cmocka_unit_test_setup_teardown(test_ldb_attrs_case_insensitive,
3797 ldb_case_test_setup,
3798 ldb_case_test_teardown),
3799 cmocka_unit_test_setup_teardown(test_ldb_attrs_case_handler,
3800 ldb_case_test_setup,
3801 ldb_case_test_teardown),
3802 cmocka_unit_test_setup_teardown(test_ldb_attrs_index_handler,
3803 ldb_case_test_setup,
3804 ldb_case_attrs_index_test_teardown),
3805 cmocka_unit_test_setup_teardown(test_ldb_rename,
3806 ldb_rename_test_setup,
3807 ldb_rename_test_teardown),
3808 cmocka_unit_test_setup_teardown(test_ldb_rename_from_doesnt_exist,
3809 ldb_rename_test_setup,
3810 ldb_rename_test_teardown),
3811 cmocka_unit_test_setup_teardown(test_ldb_rename_to_exists,
3812 ldb_rename_test_setup,
3813 ldb_rename_test_teardown),
3814 cmocka_unit_test_setup_teardown(test_ldb_rename_self,
3815 ldb_rename_test_setup,
3816 ldb_rename_test_teardown),
3817 cmocka_unit_test_setup_teardown(test_ldb_rename_dn_case_change,
3818 ldb_rename_test_setup,
3819 ldb_rename_test_teardown),
3820 cmocka_unit_test_setup_teardown(test_read_only,
3821 ldb_read_only_setup,
3822 ldb_read_only_teardown),
3823 cmocka_unit_test_setup_teardown(
3824 test_ldb_add_unique_value_to_unique_index,
3825 ldb_unique_index_test_setup,
3826 ldb_unique_index_test_teardown),
3827 cmocka_unit_test_setup_teardown(
3828 test_ldb_add_duplicate_value_to_unique_index,
3829 ldb_unique_index_test_setup,
3830 ldb_unique_index_test_teardown),
3831 cmocka_unit_test_setup_teardown(
3832 test_ldb_add_to_index_duplicates_allowed,
3833 ldb_non_unique_index_test_setup,
3834 ldb_non_unique_index_test_teardown),
3835 cmocka_unit_test_setup_teardown(
3836 test_ldb_add_to_index_unique_values_required,
3837 ldb_non_unique_index_test_setup,
3838 ldb_non_unique_index_test_teardown),
3839 cmocka_unit_test_setup_teardown(
3840 test_ldb_unique_index_duplicate_logging,
3841 ldb_unique_index_test_setup,
3842 ldb_unique_index_test_teardown),
3843 cmocka_unit_test_setup_teardown(
3844 test_ldb_duplicate_dn_logging,
3845 ldb_unique_index_test_setup,
3846 ldb_unique_index_test_teardown),
3847 cmocka_unit_test_setup_teardown(
3848 test_ldb_guid_index_duplicate_dn_logging,
3849 ldb_guid_index_test_setup,
3850 ldb_guid_index_test_teardown),
3851 cmocka_unit_test_setup_teardown(
3852 test_ldb_unique_index_duplicate_with_guid,
3853 ldb_guid_index_test_setup,
3854 ldb_guid_index_test_teardown),
3855 cmocka_unit_test_setup_teardown(
3856 test_ldb_talloc_destructor_transaction_cleanup,
3857 ldbtest_setup,
3858 ldbtest_teardown),
3861 return cmocka_run_group_tests(tests, NULL, NULL);