ldb: Ignore these tests in mdb test mode
[samba.git] / lib / ldb / tests / ldb_mod_op_test.c
1 /*
2  * from cmocka.c:
3  * These headers or their equivalents should be included prior to
4  * including
5  * this header file.
6  *
7  * #include <stdarg.h>
8  * #include <stddef.h>
9  * #include <setjmp.h>
10  *
11  * This allows test applications to use custom definitions of C standard
12  * library functions and types.
13  */
14 #include <stdarg.h>
15 #include <stddef.h>
16 #include <setjmp.h>
17 #include <cmocka.h>
18
19 #include <errno.h>
20 #include <unistd.h>
21 #include <talloc.h>
22
23 #define TEVENT_DEPRECATED 1
24 #include <tevent.h>
25
26 #include <ldb.h>
27 #include <ldb_module.h>
28 #include <ldb_private.h>
29 #include <string.h>
30 #include <ctype.h>
31
32 #include <sys/wait.h>
33
34
35 #define DEFAULT_BE  "tdb"
36
37 #ifndef TEST_BE
38 #define TEST_BE DEFAULT_BE
39 #endif /* TEST_BE */
40
41 struct ldbtest_ctx {
42         struct tevent_context *ev;
43         struct ldb_context *ldb;
44
45         const char *dbfile;
46         const char *lockfile;   /* lockfile is separate */
47
48         const char *dbpath;
49 };
50
51 static void unlink_old_db(struct ldbtest_ctx *test_ctx)
52 {
53         int ret;
54
55         errno = 0;
56         ret = unlink(test_ctx->lockfile);
57         if (ret == -1 && errno != ENOENT) {
58                 fail();
59         }
60
61         errno = 0;
62         ret = unlink(test_ctx->dbfile);
63         if (ret == -1 && errno != ENOENT) {
64                 fail();
65         }
66 }
67
68 static int ldbtest_noconn_setup(void **state)
69 {
70         struct ldbtest_ctx *test_ctx;
71
72         test_ctx = talloc_zero(NULL, struct ldbtest_ctx);
73         assert_non_null(test_ctx);
74
75         test_ctx->ev = tevent_context_init(test_ctx);
76         assert_non_null(test_ctx->ev);
77
78         test_ctx->ldb = ldb_init(test_ctx, test_ctx->ev);
79         assert_non_null(test_ctx->ldb);
80
81         test_ctx->dbfile = talloc_strdup(test_ctx, "apitest.ldb");
82         assert_non_null(test_ctx->dbfile);
83
84         test_ctx->lockfile = talloc_asprintf(test_ctx, "%s-lock",
85                                              test_ctx->dbfile);
86         assert_non_null(test_ctx->lockfile);
87
88         test_ctx->dbpath = talloc_asprintf(test_ctx,
89                         TEST_BE"://%s", test_ctx->dbfile);
90         assert_non_null(test_ctx->dbpath);
91
92         unlink_old_db(test_ctx);
93         *state = test_ctx;
94         return 0;
95 }
96
97 static int ldbtest_noconn_teardown(void **state)
98 {
99         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
100                                                         struct ldbtest_ctx);
101
102         unlink_old_db(test_ctx);
103         talloc_free(test_ctx);
104         return 0;
105 }
106
107 static void test_connect(void **state)
108 {
109         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
110                                                         struct ldbtest_ctx);
111         int ret;
112
113         ret = ldb_connect(test_ctx->ldb, test_ctx->dbpath, 0, NULL);
114         assert_int_equal(ret, 0);
115 }
116
117 static struct ldb_message *get_test_ldb_message(TALLOC_CTX *mem_ctx,
118                                                 struct ldb_context *ldb)
119 {
120         struct ldb_message *msg = ldb_msg_new(mem_ctx);
121         int ret;
122         assert_non_null(msg);
123
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;
133 }
134
135 static void test_ldif_message(void **state)
136 {
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";
147         
148         struct ldb_message *msg = get_test_ldb_message(test_ctx,
149                                                        test_ctx->ldb);
150
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);
157 }
158
159 static void test_ldif_message_redacted(void **state)
160 {
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";
172
173         const char *secret_attrs[] = {
174                 "supersecret",
175                 NULL
176         };
177         
178         struct ldb_message *msg = ldb_msg_new(test_ctx);
179
180         ldb_set_opaque(test_ctx->ldb,
181                        LDB_SECRET_ATTRIBUTE_LIST_OPAQUE,
182                        secret_attrs);
183         
184         assert_non_null(msg);
185
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);
200 }
201
202 static int ldbtest_setup(void **state)
203 {
204         struct ldbtest_ctx *test_ctx;
205         int ret;
206
207         ldbtest_noconn_setup((void **) &test_ctx);
208
209         ret = ldb_connect(test_ctx->ldb, test_ctx->dbpath, 0, NULL);
210         assert_int_equal(ret, 0);
211
212         *state = test_ctx;
213         return 0;
214 }
215
216 static int ldbtest_teardown(void **state)
217 {
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;
222 }
223
224 static void test_ldb_add(void **state)
225 {
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;
231
232         tmp_ctx = talloc_new(test_ctx);
233         assert_non_null(tmp_ctx);
234
235         msg = ldb_msg_new(tmp_ctx);
236         assert_non_null(msg);
237
238         msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "dc=test");
239         assert_non_null(msg->dn);
240
241         ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
242         assert_int_equal(ret, 0);
243
244         ret = ldb_add(test_ctx->ldb, msg);
245         assert_int_equal(ret, 0);
246
247         talloc_free(tmp_ctx);
248 }
249
250 static void test_ldb_search(void **state)
251 {
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;
260
261         tmp_ctx = talloc_new(test_ctx);
262         assert_non_null(tmp_ctx);
263
264         basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "dc=test");
265         assert_non_null(basedn);
266
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);
272
273         msg = ldb_msg_new(tmp_ctx);
274         assert_non_null(msg);
275
276         msg->dn = basedn;
277         assert_non_null(msg->dn);
278
279         ret = ldb_msg_add_string(msg, "cn", "test_cn_val1");
280         assert_int_equal(ret, 0);
281
282         ret = ldb_add(test_ctx->ldb, msg);
283         assert_int_equal(ret, 0);
284
285         basedn2 = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "dc=test2");
286         assert_non_null(basedn2);
287
288         msg = ldb_msg_new(tmp_ctx);
289         assert_non_null(msg);
290
291         msg->dn = basedn2;
292         assert_non_null(msg->dn);
293
294         ret = ldb_msg_add_string(msg, "cn", "test_cn_val2");
295         assert_int_equal(ret, 0);
296
297         ret = ldb_add(test_ctx->ldb, msg);
298         assert_int_equal(ret, 0);
299
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));
307
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));
315
316         talloc_free(tmp_ctx);
317 }
318
319 static int base_search_count(struct ldbtest_ctx *test_ctx, const char *entry_dn)
320 {
321         TALLOC_CTX *tmp_ctx;
322         struct ldb_dn *basedn;
323         struct ldb_result *result = NULL;
324         int ret;
325         int count;
326
327         tmp_ctx = talloc_new(test_ctx);
328         assert_non_null(tmp_ctx);
329
330         basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "%s", entry_dn);
331         assert_non_null(basedn);
332
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);
337
338         count = result->count;
339         talloc_free(tmp_ctx);
340         return count;
341 }
342
343 static int sub_search_count(struct ldbtest_ctx *test_ctx,
344                             const char *base_dn,
345                             const char *filter)
346 {
347         TALLOC_CTX *tmp_ctx;
348         struct ldb_dn *basedn;
349         struct ldb_result *result = NULL;
350         int ret;
351         int count;
352
353         tmp_ctx = talloc_new(test_ctx);
354         assert_non_null(tmp_ctx);
355
356         basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "%s", base_dn);
357         assert_non_null(basedn);
358
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);
363
364         count = result->count;
365         talloc_free(tmp_ctx);
366         return count;
367 }
368
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
372  */
373 static void assert_dn_exists(struct ldbtest_ctx *test_ctx,
374                              const char *entry_dn)
375 {
376         int count;
377
378         count = base_search_count(test_ctx, entry_dn);
379         assert_int_equal(count, 1);
380 }
381
382 static void assert_dn_doesnt_exist(struct ldbtest_ctx *test_ctx,
383                                    const char *entry_dn)
384 {
385         int count;
386
387         count = base_search_count(test_ctx, entry_dn);
388         assert_int_equal(count, 0);
389 }
390
391 static void add_dn_with_cn(struct ldbtest_ctx *test_ctx,
392                            struct ldb_dn *dn,
393                            const char *cn_value)
394 {
395         int ret;
396         TALLOC_CTX *tmp_ctx;
397         struct ldb_message *msg;
398
399         tmp_ctx = talloc_new(test_ctx);
400         assert_non_null(tmp_ctx);
401
402         assert_dn_doesnt_exist(test_ctx,
403                                ldb_dn_get_linearized(dn));
404
405         msg = ldb_msg_new(tmp_ctx);
406         assert_non_null(msg);
407         msg->dn = dn;
408
409         ret = ldb_msg_add_string(msg, "cn", cn_value);
410         assert_int_equal(ret, LDB_SUCCESS);
411
412         ret = ldb_add(test_ctx->ldb, msg);
413         assert_int_equal(ret, LDB_SUCCESS);
414
415         assert_dn_exists(test_ctx,
416                          ldb_dn_get_linearized(dn));
417         talloc_free(tmp_ctx);
418 }
419
420 static void test_ldb_del(void **state)
421 {
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;
427
428         dn = ldb_dn_new_fmt(test_ctx, test_ctx->ldb, "%s", basedn);
429         assert_non_null(dn);
430
431         add_dn_with_cn(test_ctx, dn, "test_del_cn_val");
432
433         ret = ldb_delete(test_ctx->ldb, dn);
434         assert_int_equal(ret, LDB_SUCCESS);
435
436         assert_dn_doesnt_exist(test_ctx, basedn);
437 }
438
439 static void test_ldb_del_noexist(void **state)
440 {
441         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
442                                                              struct ldbtest_ctx);
443         struct ldb_dn *basedn;
444         int ret;
445
446         basedn = ldb_dn_new(test_ctx, test_ctx->ldb, "dc=nosuchplace");
447         assert_non_null(basedn);
448
449         ret = ldb_delete(test_ctx->ldb, basedn);
450         assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT);
451 }
452
453 static void test_ldb_handle(void **state)
454 {
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 };
464
465         tmp_ctx = talloc_new(test_ctx);
466         assert_non_null(tmp_ctx);
467
468         basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "dc=test");
469         assert_non_null(basedn);
470
471         res = talloc_zero(tmp_ctx, struct ldb_result);
472         assert_non_null(res);
473
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);
480
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));
484
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);
491
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));
495
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));
500
501         talloc_free(tmp_ctx);
502 }
503
504 static void test_ldb_build_search_req(void **state)
505 {
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 };
515
516         tmp_ctx = talloc_new(test_ctx);
517         assert_non_null(tmp_ctx);
518
519         basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "dc=test");
520         assert_non_null(basedn);
521
522         res = talloc_zero(tmp_ctx, struct ldb_result);
523         assert_non_null(res);
524
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);
531
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);
539
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);
549
550         talloc_free(tmp_ctx);
551 }
552
553 static void add_keyval(struct ldbtest_ctx *test_ctx,
554                        const char *key,
555                        const char *val)
556 {
557         int ret;
558         struct ldb_message *msg;
559
560         msg = ldb_msg_new(test_ctx);
561         assert_non_null(msg);
562
563         msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "%s=%s", key, val);
564         assert_non_null(msg->dn);
565
566         ret = ldb_msg_add_string(msg, key, val);
567         assert_int_equal(ret, 0);
568
569         ret = ldb_add(test_ctx->ldb, msg);
570         assert_int_equal(ret, 0);
571
572         talloc_free(msg);
573 }
574
575 static struct ldb_result *get_keyval(struct ldbtest_ctx *test_ctx,
576                                      const char *key,
577                                      const char *val)
578 {
579         int ret;
580         struct ldb_result *result;
581         struct ldb_dn *basedn;
582
583         basedn = ldb_dn_new_fmt(test_ctx, test_ctx->ldb, "%s=%s", key, val);
584         assert_non_null(basedn);
585
586         ret = ldb_search(test_ctx->ldb, test_ctx, &result, basedn,
587                         LDB_SCOPE_BASE, NULL, NULL);
588         assert_int_equal(ret, 0);
589
590         return result;
591 }
592
593 static void test_transactions(void **state)
594 {
595         int ret;
596         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
597                         struct ldbtest_ctx);
598         struct ldb_result *res;
599
600         /* start lev-0 transaction */
601         ret = ldb_transaction_start(test_ctx->ldb);
602         assert_int_equal(ret, 0);
603
604         add_keyval(test_ctx, "vegetable", "carrot");
605
606         /* commit lev-0 transaction */
607         ret = ldb_transaction_commit(test_ctx->ldb);
608         assert_int_equal(ret, 0);
609
610         /* start another lev-1 nested transaction */
611         ret = ldb_transaction_start(test_ctx->ldb);
612         assert_int_equal(ret, 0);
613
614         add_keyval(test_ctx, "fruit", "apple");
615
616         /* abort lev-1 nested transaction */
617         ret = ldb_transaction_cancel(test_ctx->ldb);
618         assert_int_equal(ret, 0);
619
620         res = get_keyval(test_ctx, "vegetable", "carrot");
621         assert_non_null(res);
622         assert_int_equal(res->count, 1);
623
624         res = get_keyval(test_ctx, "fruit", "apple");
625         assert_non_null(res);
626         assert_int_equal(res->count, 0);
627 }
628
629 static void test_nested_transactions(void **state)
630 {
631         int ret;
632         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
633                         struct ldbtest_ctx);
634         struct ldb_result *res;
635
636         /* start lev-0 transaction */
637         ret = ldb_transaction_start(test_ctx->ldb);
638         assert_int_equal(ret, 0);
639
640         add_keyval(test_ctx, "vegetable", "carrot");
641
642
643         /* start another lev-1 nested transaction */
644         ret = ldb_transaction_start(test_ctx->ldb);
645         assert_int_equal(ret, 0);
646
647         add_keyval(test_ctx, "fruit", "apple");
648
649         /* abort lev-1 nested transaction */
650         ret = ldb_transaction_cancel(test_ctx->ldb);
651         assert_int_equal(ret, 0);
652
653         /* commit lev-0 transaction */
654         ret = ldb_transaction_commit(test_ctx->ldb);
655         assert_int_equal(ret, 0);
656
657         res = get_keyval(test_ctx, "vegetable", "carrot");
658         assert_non_null(res);
659         assert_int_equal(res->count, 1);
660
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.
664          */
665         res = get_keyval(test_ctx, "fruit", "apple");
666         assert_non_null(res);
667         assert_int_equal(res->count, 1);
668 }
669 struct ldb_mod_test_ctx {
670         struct ldbtest_ctx *ldb_test_ctx;
671         const char *entry_dn;
672 };
673
674 struct keyval {
675         const char *key;
676         const char *val;
677 };
678
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)
684 {
685         struct ldb_message *msg;
686         int ret;
687         int i;
688
689         msg = ldb_msg_new(mem_ctx);
690         assert_non_null(msg);
691
692         msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "%s", dn);
693         assert_non_null(msg->dn);
694
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);
700                 }
701
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);
705                 }
706         }
707
708         return msg;
709 }
710
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)
715 {
716         TALLOC_CTX *tmp_ctx;
717         struct ldb_message *msg;
718         struct ldb_result *result = NULL;
719         int ret;
720
721         tmp_ctx = talloc_new(mem_ctx);
722         assert_non_null(tmp_ctx);
723
724         msg = build_mod_msg(tmp_ctx, ldb_test_ctx,
725                             basedn, 0, kvs);
726         assert_non_null(msg);
727
728         ret = ldb_add(ldb_test_ctx->ldb, msg);
729         assert_int_equal(ret, LDB_SUCCESS);
730
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));
738
739         talloc_free(tmp_ctx);
740 }
741
742 static void ldb_test_remove_data(TALLOC_CTX *mem_ctx,
743                                  struct ldbtest_ctx *ldb_test_ctx,
744                                  const char *strdn)
745 {
746         TALLOC_CTX *tmp_ctx;
747         struct ldb_dn *basedn;
748         int ret;
749         size_t count;
750
751         tmp_ctx = talloc_new(mem_ctx);
752         assert_non_null(tmp_ctx);
753
754         basedn = ldb_dn_new_fmt(tmp_ctx, ldb_test_ctx->ldb,
755                                 "%s", strdn);
756         assert_non_null(basedn);
757
758         ret = ldb_delete(ldb_test_ctx->ldb, basedn);
759         assert_true(ret == LDB_SUCCESS || ret == LDB_ERR_NO_SUCH_OBJECT);
760
761         count = base_search_count(ldb_test_ctx, ldb_dn_get_linearized(basedn));
762         assert_int_equal(count, 0);
763
764         talloc_free(tmp_ctx);
765 }
766
767 static void mod_test_add_data(struct ldb_mod_test_ctx *mod_test_ctx,
768                               struct keyval *kvs)
769 {
770         ldb_test_add_data(mod_test_ctx,
771                           mod_test_ctx->ldb_test_ctx,
772                           mod_test_ctx->entry_dn,
773                           kvs);
774 }
775
776 static void mod_test_remove_data(struct ldb_mod_test_ctx *mod_test_ctx)
777 {
778         ldb_test_remove_data(mod_test_ctx,
779                              mod_test_ctx->ldb_test_ctx,
780                              mod_test_ctx->entry_dn);
781 }
782
783 static struct ldb_result *run_mod_test(struct ldb_mod_test_ctx *mod_test_ctx,
784                                        int modify_flags,
785                                        struct keyval *kvs)
786 {
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;
793
794         ldb_test_ctx = mod_test_ctx->ldb_test_ctx;
795
796         tmp_ctx = talloc_new(mod_test_ctx);
797         assert_non_null(tmp_ctx);
798
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);
802
803         ret = ldb_modify(ldb_test_ctx->ldb, mod_msg);
804         assert_int_equal(ret, LDB_SUCCESS);
805
806         basedn = ldb_dn_new_fmt(tmp_ctx, ldb_test_ctx->ldb,
807                         "%s", mod_test_ctx->entry_dn);
808         assert_non_null(basedn);
809
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));
817
818         talloc_free(tmp_ctx);
819         return res;
820 }
821
822 static int ldb_modify_test_setup(void **state)
823 {
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 },
829         };
830
831         ldbtest_setup((void **) &ldb_test_ctx);
832
833         mod_test_ctx = talloc(ldb_test_ctx, struct ldb_mod_test_ctx);
834         assert_non_null(mod_test_ctx);
835
836         mod_test_ctx->entry_dn = "dc=mod_test_entry";
837         mod_test_ctx->ldb_test_ctx = ldb_test_ctx;
838
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;
843 }
844
845 static int ldb_modify_test_teardown(void **state)
846 {
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;
851
852         ldb_test_ctx = mod_test_ctx->ldb_test_ctx;
853
854         mod_test_remove_data(mod_test_ctx);
855         talloc_free(mod_test_ctx);
856
857         ldbtest_teardown((void **) &ldb_test_ctx);
858         return 0;
859 }
860
861 static void test_ldb_modify_add_key(void **state)
862 {
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 },
869         };
870         struct ldb_result *res;
871         struct ldb_message_element *el;
872
873         res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_ADD, mod_kvs);
874         assert_non_null(res);
875
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");
882
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");
887 }
888
889 static void test_ldb_modify_extend_key(void **state)
890 {
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 },
897         };
898         struct ldb_result *res;
899         struct ldb_message_element *el;
900
901         res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_ADD, mod_kvs);
902         assert_non_null(res);
903
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");
911 }
912
913 static void test_ldb_modify_add_key_noval(void **state)
914 {
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;
922
923         ldb_test_ctx = mod_test_ctx->ldb_test_ctx;
924
925         mod_msg = ldb_msg_new(mod_test_ctx);
926         assert_non_null(mod_msg);
927
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);
931
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);
937
938         mod_msg->elements = el;
939         mod_msg->num_elements = 1;
940
941         ret = ldb_modify(ldb_test_ctx->ldb, mod_msg);
942         assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION);
943 }
944
945 static void test_ldb_modify_replace_key(void **state)
946 {
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 },
954         };
955         struct ldb_result *res;
956         struct ldb_message_element *el;
957
958         res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, mod_kvs);
959         assert_non_null(res);
960
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);
967 }
968
969 static void test_ldb_modify_replace_noexist_key(void **state)
970 {
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 },
977         };
978         struct ldb_result *res;
979         struct ldb_message_element *el;
980
981         res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, mod_kvs);
982         assert_non_null(res);
983
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");
990
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);
995 }
996
997 static void test_ldb_modify_replace_zero_vals(void **state)
998 {
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 },
1007         };
1008
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);
1014 }
1015
1016 static void test_ldb_modify_replace_noexist_key_zero_vals(void **state)
1017 {
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 },
1026         };
1027
1028         /* cn must be gone */
1029         res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, kvs);
1030         assert_non_null(res);
1031
1032         /* cn should be intact */
1033         el = ldb_msg_find_element(res->msgs[0], "cn");
1034         assert_non_null(el);
1035 }
1036
1037 static void test_ldb_modify_del_key(void **state)
1038 {
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 },
1047         };
1048
1049         /* cn must be gone */
1050         res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_DELETE, kvs);
1051         assert_non_null(res);
1052
1053         el = ldb_msg_find_element(res->msgs[0], "cn");
1054         assert_null(el);
1055 }
1056
1057 static void test_ldb_modify_del_keyval(void **state)
1058 {
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 },
1067         };
1068
1069         /* cn must be gone */
1070         res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_DELETE, kvs);
1071         assert_non_null(res);
1072
1073         el = ldb_msg_find_element(res->msgs[0], "cn");
1074         assert_null(el);
1075 }
1076
1077 struct search_test_ctx {
1078         struct ldbtest_ctx *ldb_test_ctx;
1079         const char *base_dn;
1080 };
1081
1082 static char *get_full_dn(TALLOC_CTX *mem_ctx,
1083                          struct search_test_ctx *search_test_ctx,
1084                          const char *rdn)
1085 {
1086         char *full_dn;
1087
1088         full_dn = talloc_asprintf(mem_ctx,
1089                                   "%s,%s", rdn, search_test_ctx->base_dn);
1090         assert_non_null(full_dn);
1091
1092         return full_dn;
1093 }
1094
1095 static void search_test_add_data(struct search_test_ctx *search_test_ctx,
1096                                  const char *rdn,
1097                                  struct keyval *kvs)
1098 {
1099         char *full_dn;
1100
1101         full_dn = get_full_dn(search_test_ctx, search_test_ctx, rdn);
1102
1103         ldb_test_add_data(search_test_ctx,
1104                           search_test_ctx->ldb_test_ctx,
1105                           full_dn,
1106                           kvs);
1107 }
1108
1109 static void search_test_remove_data(struct search_test_ctx *search_test_ctx,
1110                                     const char *rdn)
1111 {
1112         char *full_dn;
1113
1114         full_dn = talloc_asprintf(search_test_ctx,
1115                                   "%s,%s", rdn, search_test_ctx->base_dn);
1116         assert_non_null(full_dn);
1117
1118         ldb_test_remove_data(search_test_ctx,
1119                              search_test_ctx->ldb_test_ctx,
1120                              full_dn);
1121 }
1122
1123 static int ldb_search_test_setup(void **state)
1124 {
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 },
1133         };
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 },
1140         };
1141
1142         ldbtest_setup((void **) &ldb_test_ctx);
1143
1144         search_test_ctx = talloc(ldb_test_ctx, struct search_test_ctx);
1145         assert_non_null(search_test_ctx);
1146
1147         search_test_ctx->base_dn = "dc=search_test_entry";
1148         search_test_ctx->ldb_test_ctx = ldb_test_ctx;
1149
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);
1152
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);
1155
1156         *state = search_test_ctx;
1157         return 0;
1158 }
1159
1160 static int ldb_search_test_teardown(void **state)
1161 {
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;
1165
1166         ldb_test_ctx = search_test_ctx->ldb_test_ctx;
1167
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;
1172 }
1173
1174 static void assert_attr_has_vals(struct ldb_message *msg,
1175                                  const char *attr,
1176                                  const char *vals[],
1177                                  const size_t nvals)
1178 {
1179         struct ldb_message_element *el;
1180         size_t i;
1181
1182         el = ldb_msg_find_element(msg, attr);
1183         assert_non_null(el);
1184
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]);
1189         }
1190 }
1191
1192 static void assert_has_no_attr(struct ldb_message *msg,
1193                                const char *attr)
1194 {
1195         struct ldb_message_element *el;
1196
1197         el = ldb_msg_find_element(msg, attr);
1198         assert_null(el);
1199 }
1200
1201 static bool has_dn(struct ldb_message *msg, const char *dn)
1202 {
1203         const char *msgdn;
1204
1205         msgdn = ldb_dn_get_linearized(msg->dn);
1206         if (strcmp(dn, msgdn) == 0) {
1207                 return true;
1208         }
1209
1210         return false;
1211 }
1212
1213 static void test_search_match_none(void **state)
1214 {
1215         struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1216                         struct search_test_ctx);
1217         size_t count;
1218
1219         count = base_search_count(search_test_ctx->ldb_test_ctx,
1220                                   "dc=no_such_entry");
1221         assert_int_equal(count, 0);
1222 }
1223
1224 static void test_search_match_one(void **state)
1225 {
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" };
1235
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);
1241
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);
1251
1252         assert_attr_has_vals(result->msgs[0], "cn", cn_vals, 2);
1253         assert_attr_has_vals(result->msgs[0], "uid", uid_vals, 2);
1254 }
1255
1256 static void test_search_match_filter(void **state)
1257 {
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 };
1266
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);
1272
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);
1283
1284         assert_attr_has_vals(result->msgs[0], "cn", cn_vals, 2);
1285         assert_has_no_attr(result->msgs[0], "uid");
1286 }
1287
1288 static void assert_expected(struct search_test_ctx *search_test_ctx,
1289                             struct ldb_message *msg)
1290 {
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" };
1301
1302         full_dn1 = get_full_dn(search_test_ctx,
1303                                search_test_ctx,
1304                                "cn=test_search_cn");
1305
1306         full_dn2 = get_full_dn(search_test_ctx,
1307                                search_test_ctx,
1308                                "cn=test_search_2_cn");
1309
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();
1318         }
1319 }
1320
1321 static void test_search_match_both(void **state)
1322 {
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;
1328
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);
1334
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);
1344
1345         assert_expected(search_test_ctx, result->msgs[0]);
1346         assert_expected(search_test_ctx, result->msgs[1]);
1347 }
1348
1349 static void test_search_match_basedn(void **state)
1350 {
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;
1357
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);
1362
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);
1370
1371         /* Add 'checkBaseOnSearch' to @OPTIONS */
1372         msg = ldb_msg_new(search_test_ctx);
1373         assert_non_null(msg);
1374
1375         msg->dn = ldb_dn_new_fmt(msg,
1376                                  search_test_ctx->ldb_test_ctx->ldb,
1377                                  "@OPTIONS");
1378         assert_non_null(msg->dn);
1379
1380         ret = ldb_msg_add_string(msg, "checkBaseOnSearch", "TRUE");
1381         assert_int_equal(ret, 0);
1382
1383         ret = ldb_add(search_test_ctx->ldb_test_ctx->ldb, msg);
1384         assert_int_equal(ret, 0);
1385
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);
1395
1396         ret = ldb_delete(search_test_ctx->ldb_test_ctx->ldb, msg->dn);
1397         assert_int_equal(ret, 0);
1398 }
1399
1400
1401 /*
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
1412  *
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()
1416  */
1417
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;
1423 };
1424
1425 static int test_ldb_search_against_transaction_callback2(struct ldb_request *req,
1426                                                          struct ldb_reply *ares)
1427 {
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;
1434                 }
1435
1436                 break;
1437
1438         case LDB_REPLY_REFERRAL:
1439                 break;
1440
1441         case LDB_REPLY_DONE:
1442                 return ldb_request_done(req, LDB_SUCCESS);
1443         }
1444
1445         return 0;
1446
1447 }
1448
1449 /*
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.
1453  *
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.
1457  *
1458  */
1459
1460 static int test_ldb_search_against_transaction_callback1(struct ldb_request *req,
1461                                                          struct ldb_reply *ares)
1462 {
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;
1470
1471         case LDB_REPLY_REFERRAL:
1472                 return LDB_SUCCESS;
1473
1474         case LDB_REPLY_DONE:
1475                 return ldb_request_done(req, LDB_SUCCESS);
1476         }
1477
1478         ret = pipe(pipes);
1479         assert_int_equal(ret, 0);
1480
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);
1490                 }
1491
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);
1496                 }
1497
1498                 ret = ldb_connect(ctx->test_ctx->ldb,
1499                                   ctx->test_ctx->dbpath, 0, NULL);
1500                 if (ret != LDB_SUCCESS) {
1501                         exit(ret);
1502                 }
1503
1504                 tmp_ctx = talloc_new(ctx->test_ctx);
1505                 if (tmp_ctx == NULL) {
1506                         exit(LDB_ERR_OPERATIONS_ERROR);
1507                 }
1508
1509                 msg = ldb_msg_new(tmp_ctx);
1510                 if (msg == NULL) {
1511                         exit(LDB_ERR_OPERATIONS_ERROR);
1512                 }
1513
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);
1518                 }
1519
1520                 ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
1521                 if (ret != 0) {
1522                         exit(LDB_ERR_OPERATIONS_ERROR);
1523                 }
1524
1525                 ret = ldb_transaction_start(ctx->test_ctx->ldb);
1526                 if (ret != 0) {
1527                         exit(ret);
1528                 }
1529
1530                 ret = write(pipes[1], "GO", 2);
1531                 if (ret != 2) {
1532                         exit(LDB_ERR_OPERATIONS_ERROR);
1533                 }
1534
1535                 ret = ldb_add(ctx->test_ctx->ldb, msg);
1536                 if (ret != 0) {
1537                         exit(ret);
1538                 }
1539
1540                 ret = ldb_transaction_commit(ctx->test_ctx->ldb);
1541                 exit(ret);
1542         }
1543
1544         ret = read(pipes[0], buf, 2);
1545         assert_int_equal(ret, 2);
1546
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);
1558         /*
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.
1561          */
1562
1563         ret2 = ldb_request(ctx->test_ctx->ldb, req);
1564
1565         if (ret2 == LDB_SUCCESS) {
1566                 ret2 = ldb_wait(req->handle, LDB_WAIT_ALL);
1567         }
1568         assert_int_equal(ret, 0);
1569         assert_int_equal(ret2, 0);
1570         assert_int_equal(ctx->res_count, 2);
1571
1572         return LDB_SUCCESS;
1573 }
1574
1575 static void test_ldb_search_against_transaction(void **state)
1576 {
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
1583                 };
1584
1585         int ret;
1586         struct ldb_request *req;
1587         pid_t pid;
1588         int wstatus;
1589         struct ldb_dn *base_search_dn;
1590
1591         tevent_loop_allow_nesting(search_test_ctx->ldb_test_ctx->ev);
1592
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);
1599
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);
1606
1607
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);
1621
1622         if (ret == LDB_SUCCESS) {
1623                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1624         }
1625         assert_int_equal(ret, 0);
1626         assert_int_equal(ctx.res_count, 2);
1627
1628         pid = waitpid(ctx.child_pid, &wstatus, 0);
1629         assert_int_equal(pid, ctx.child_pid);
1630
1631         assert_true(WIFEXITED(wstatus));
1632
1633         assert_int_equal(WEXITSTATUS(wstatus), 0);
1634
1635
1636 }
1637
1638 /*
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)
1649  *
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).
1653  */
1654
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;
1663 };
1664
1665 /*
1666  * This purpose of this callback is to trigger a write in
1667  * the child process while a search is in progress.
1668  *
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.
1672  *
1673  * We assume that if the write will proceed, it will proceed in a 3
1674  * second window after the function is called.
1675  */
1676
1677 static int test_ldb_modify_during_search_callback1(struct ldb_request *req,
1678                                                    struct ldb_reply *ares)
1679 {
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:
1686         {
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;
1695                 }
1696                 if (ctx->res_count == 2) {
1697                         return LDB_SUCCESS;
1698                 }
1699                 break;
1700         }
1701         case LDB_REPLY_REFERRAL:
1702                 return LDB_SUCCESS;
1703
1704         case LDB_REPLY_DONE:
1705                 return ldb_request_done(req, LDB_SUCCESS);
1706         }
1707
1708         ret = pipe(pipes);
1709         assert_int_equal(ret, 0);
1710
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);
1720                 }
1721
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);
1726                 }
1727
1728                 ret = ldb_connect(ctx->test_ctx->ldb,
1729                                   ctx->test_ctx->dbpath, 0, NULL);
1730                 if (ret != LDB_SUCCESS) {
1731                         exit(ret);
1732                 }
1733
1734                 tmp_ctx = talloc_new(ctx->test_ctx);
1735                 if (tmp_ctx == NULL) {
1736                         exit(LDB_ERR_OPERATIONS_ERROR);
1737                 }
1738
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");
1748                 }
1749                 if (dn == NULL) {
1750                         exit(LDB_ERR_OPERATIONS_ERROR);
1751                 }
1752
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);
1758                 }
1759
1760                 ret = ldb_transaction_start(ctx->test_ctx->ldb);
1761                 if (ret != 0) {
1762                         exit(ret);
1763                 }
1764
1765                 if (write(pipes[1], "GO", 2) != 2) {
1766                         exit(LDB_ERR_OPERATIONS_ERROR);
1767                 }
1768
1769                 ret = ldb_rename(ctx->test_ctx->ldb, dn, new_dn);
1770                 if (ret != 0) {
1771                         exit(ret);
1772                 }
1773
1774                 ret = ldb_transaction_commit(ctx->test_ctx->ldb);
1775                 exit(ret);
1776
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);
1786                 }
1787
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);
1792                 }
1793
1794                 ret = ldb_connect(ctx->test_ctx->ldb,
1795                                   ctx->test_ctx->dbpath, 0, NULL);
1796                 if (ret != LDB_SUCCESS) {
1797                         exit(ret);
1798                 }
1799
1800                 tmp_ctx = talloc_new(ctx->test_ctx);
1801                 if (tmp_ctx == NULL) {
1802                         exit(LDB_ERR_OPERATIONS_ERROR);
1803                 }
1804
1805                 msg = ldb_msg_new(tmp_ctx);
1806                 if (msg == NULL) {
1807                         exit(LDB_ERR_OPERATIONS_ERROR);
1808                 }
1809
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");
1819                 }
1820                 if (msg->dn == NULL) {
1821                         exit(LDB_ERR_OPERATIONS_ERROR);
1822                 }
1823
1824                 ret = ldb_msg_add_string(msg, "filterAttr", "TRUE");
1825                 if (ret != 0) {
1826                         exit(LDB_ERR_OPERATIONS_ERROR);
1827                 }
1828                 el = ldb_msg_find_element(msg, "filterAttr");
1829                 if (el == NULL) {
1830                         exit(LDB_ERR_OPERATIONS_ERROR);
1831                 }
1832                 el->flags = LDB_FLAG_MOD_REPLACE;
1833
1834                 ret = ldb_transaction_start(ctx->test_ctx->ldb);
1835                 if (ret != 0) {
1836                         exit(ret);
1837                 }
1838
1839                 if (write(pipes[1], "GO", 2) != 2) {
1840                         exit(LDB_ERR_OPERATIONS_ERROR);
1841                 }
1842
1843                 ret = ldb_modify(ctx->test_ctx->ldb, msg);
1844                 if (ret != 0) {
1845                         exit(ret);
1846                 }
1847
1848                 ret = ldb_transaction_commit(ctx->test_ctx->ldb);
1849                 exit(ret);
1850         }
1851
1852         /*
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().
1856          */
1857
1858         ret = read(pipes[0], buf, 2);
1859         assert_int_equal(ret, 2);
1860
1861         sleep(3);
1862
1863         return LDB_SUCCESS;
1864 }
1865
1866 static void test_ldb_modify_during_search(void **state, bool add_index,
1867                                           bool rename)
1868 {
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
1876                 };
1877
1878         int ret;
1879         struct ldb_request *req;
1880         pid_t pid;
1881         int wstatus;
1882
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);
1889
1890                 msg = ldb_msg_new(search_test_ctx);
1891                 assert_non_null(msg);
1892
1893                 msg->dn = indexlist;
1894
1895                 ret = ldb_msg_add_string(msg, "@IDXATTR", "cn");
1896                 assert_int_equal(ret, LDB_SUCCESS);
1897
1898                 ret = ldb_add(search_test_ctx->ldb_test_ctx->ldb,
1899                               msg);
1900
1901                 assert_int_equal(ret, LDB_SUCCESS);
1902         }
1903
1904         tevent_loop_allow_nesting(search_test_ctx->ldb_test_ctx->ev);
1905
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);
1912
1913
1914         /*
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
1918          */
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);
1936
1937         if (ret == LDB_SUCCESS) {
1938                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1939         }
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);
1944
1945         pid = waitpid(ctx.child_pid, &wstatus, 0);
1946         assert_int_equal(pid, ctx.child_pid);
1947
1948         assert_true(WIFEXITED(wstatus));
1949
1950         assert_int_equal(WEXITSTATUS(wstatus), 0);
1951
1952
1953 }
1954
1955 static void test_ldb_modify_during_indexed_search(void **state)
1956 {
1957         test_ldb_modify_during_search(state, true, false);
1958 }
1959
1960 static void test_ldb_modify_during_unindexed_search(void **state)
1961 {
1962         test_ldb_modify_during_search(state, false, false);
1963 }
1964
1965 static void test_ldb_rename_during_indexed_search(void **state)
1966 {
1967         test_ldb_modify_during_search(state, true, true);
1968 }
1969
1970 static void test_ldb_rename_during_unindexed_search(void **state)
1971 {
1972         test_ldb_modify_during_search(state, false, true);
1973 }
1974
1975 /*
1976  * This test is also complex.
1977  *
1978  * The purpose is to test if a modify can occur during an ldb_search()
1979  * before the end of the callback
1980  *
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
1986  *
1987  */
1988
1989 /*
1990  * This purpose of this callback is to trigger a write in
1991  * the child process while a search DONE callback is in progress.
1992  *
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
1995  *
1996  * We assume that if the write will proceed, it will proceed in a 3
1997  * second window after the function is called.
1998  */
1999
2000 static int test_ldb_modify_during_whole_search_callback1(struct ldb_request *req,
2001                                                          struct ldb_reply *ares)
2002 {
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;
2014
2015         case LDB_REPLY_DONE:
2016                 break;
2017         }
2018
2019         ret = pipe(pipes);
2020         assert_int_equal(ret, 0);
2021
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);
2032                 }
2033
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);
2038                 }
2039
2040                 ret = ldb_connect(ctx->test_ctx->ldb,
2041                                   ctx->test_ctx->dbpath, 0, NULL);
2042                 if (ret != LDB_SUCCESS) {
2043                         exit(ret);
2044                 }
2045
2046                 tmp_ctx = talloc_new(ctx->test_ctx);
2047                 if (tmp_ctx == NULL) {
2048                         exit(LDB_ERR_OPERATIONS_ERROR);
2049                 }
2050
2051                 msg = ldb_msg_new(tmp_ctx);
2052                 if (msg == NULL) {
2053                         exit(LDB_ERR_OPERATIONS_ERROR);
2054                 }
2055
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);
2061                 }
2062
2063                 ret = ldb_msg_add_string(msg, "filterAttr", "TRUE");
2064                 if (ret != 0) {
2065                         exit(LDB_ERR_OPERATIONS_ERROR);
2066                 }
2067                 el = ldb_msg_find_element(msg, "filterAttr");
2068                 if (el == NULL) {
2069                         exit(LDB_ERR_OPERATIONS_ERROR);
2070                 }
2071                 el->flags = LDB_FLAG_MOD_REPLACE;
2072
2073                 ret = ldb_transaction_start(ctx->test_ctx->ldb);
2074                 if (ret != 0) {
2075                         exit(ret);
2076                 }
2077
2078                 if (write(pipes[1], "GO", 2) != 2) {
2079                         exit(LDB_ERR_OPERATIONS_ERROR);
2080                 }
2081
2082                 ret = ldb_modify(ctx->test_ctx->ldb, msg);
2083                 if (ret != 0) {
2084                         exit(ret);
2085                 }
2086
2087                 ret = ldb_transaction_commit(ctx->test_ctx->ldb);
2088                 exit(ret);
2089         }
2090
2091         ret = read(pipes[0], buf, 2);
2092         assert_int_equal(ret, 2);
2093
2094         sleep(3);
2095
2096         /*
2097          * If writes are not blocked until after this function, we
2098          * will be able to successfully search for this modification
2099          * here
2100          */
2101
2102         search_dn = ldb_dn_new_fmt(ares, ctx->test_ctx->ldb,
2103                                    "cn=test_search_cn,"
2104                                    "dc=search_test_entry");
2105
2106         ret = ldb_search(ctx->test_ctx->ldb, ares,
2107                          &res2, search_dn, LDB_SCOPE_BASE, NULL,
2108                          "filterAttr=TRUE");
2109
2110         /*
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.
2113          */
2114
2115         res_count = res2->count;
2116         ldb_request_done(req, LDB_SUCCESS);
2117         assert_int_equal(ret, 0);
2118
2119         /* We should not have got the result */
2120         assert_int_equal(res_count, 0);
2121
2122         return ret;
2123 }
2124
2125 static void test_ldb_modify_during_whole_search(void **state)
2126 {
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 =
2131                 {
2132                   .test_ctx = search_test_ctx->ldb_test_ctx,
2133                 };
2134
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;
2141
2142         tevent_loop_allow_nesting(search_test_ctx->ldb_test_ctx->ev);
2143
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);
2150
2151
2152         /*
2153          * The search just needs to call DONE, we don't care about the
2154          * contents of the search for this test
2155          */
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);
2170
2171         if (ret == LDB_SUCCESS) {
2172                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
2173         }
2174         assert_int_equal(ret, 0);
2175
2176         pid = waitpid(ctx.child_pid, &wstatus, 0);
2177         assert_int_equal(pid, ctx.child_pid);
2178
2179         assert_true(WIFEXITED(wstatus));
2180
2181         assert_int_equal(WEXITSTATUS(wstatus), 0);
2182
2183         /*
2184          * If writes are blocked until after the search function, we
2185          * will be able to successfully search for this modification
2186          * now
2187          */
2188
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");
2193
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);
2199
2200         /* We got the result */
2201         assert_int_equal(res2->count, 1);
2202 }
2203
2204 /*
2205  * This test is also complex.
2206  *
2207  * The purpose is to test if a modify can occur during an ldb_search()
2208  * before the request is destroyed with TALLOC_FREE()
2209  *
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()
2217  *
2218  */
2219
2220 /*
2221  * This purpose of this callback is to trigger a write in
2222  * the child process before the ldb_wait() is called
2223  *
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
2226  *
2227  * We assume that if the write will proceed, it will proceed in a 3
2228  * second window after the function is called.
2229  */
2230
2231 static int test_ldb_modify_before_ldb_wait_callback1(struct ldb_request *req,
2232                                                      struct ldb_reply *ares)
2233 {
2234         switch (ares->type) {
2235         case LDB_REPLY_ENTRY:
2236         case LDB_REPLY_REFERRAL:
2237                 return LDB_SUCCESS;
2238
2239         case LDB_REPLY_DONE:
2240                 break;
2241         }
2242
2243         return ldb_request_done(req, LDB_SUCCESS);
2244 }
2245
2246 static void test_ldb_modify_before_ldb_wait(void **state)
2247 {
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;
2261
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);
2267
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);
2273
2274         /*
2275          * The search just needs to call DONE, we don't care about the
2276          * contents of the search for this test
2277          */
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);
2292
2293         ret = pipe(pipes);
2294         assert_int_equal(ret, 0);
2295
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);
2306                 }
2307
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);
2312                 }
2313
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);
2318                 }
2319
2320                 tmp_ctx = talloc_new(search_test_ctx->ldb_test_ctx);
2321                 if (tmp_ctx == NULL) {
2322                         exit(LDB_ERR_OPERATIONS_ERROR);
2323                 }
2324
2325                 msg = ldb_msg_new(tmp_ctx);
2326                 if (msg == NULL) {
2327                         exit(LDB_ERR_OPERATIONS_ERROR);
2328                 }
2329
2330                 /*
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
2334                  */
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");
2339
2340                 if (msg->dn == NULL) {
2341                         exit(LDB_ERR_OPERATIONS_ERROR);
2342                 }
2343
2344                 ret = ldb_msg_add_string(msg, "filterAttr", "TRUE");
2345                 if (ret != 0) {
2346                         exit(LDB_ERR_OPERATIONS_ERROR);
2347                 }
2348                 el = ldb_msg_find_element(msg, "filterAttr");
2349                 if (el == NULL) {
2350                         exit(LDB_ERR_OPERATIONS_ERROR);
2351                 }
2352                 el->flags = LDB_FLAG_MOD_REPLACE;
2353
2354                 ret = ldb_transaction_start(search_test_ctx->ldb_test_ctx->ldb);
2355                 if (ret != 0) {
2356                         exit(ret);
2357                 }
2358
2359                 if (write(pipes[1], "GO", 2) != 2) {
2360                         exit(LDB_ERR_OPERATIONS_ERROR);
2361                 }
2362
2363                 ret = ldb_modify(search_test_ctx->ldb_test_ctx->ldb, msg);
2364                 if (ret != 0) {
2365                         exit(ret);
2366                 }
2367
2368                 ret = ldb_transaction_commit(search_test_ctx->ldb_test_ctx->ldb);
2369                 exit(ret);
2370         }
2371
2372         ret = read(pipes[0], buf, 2);
2373         assert_int_equal(ret, 2);
2374
2375         sleep(3);
2376
2377         /*
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
2381          */
2382
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");
2386
2387         /*
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.
2391          */
2392         res_count = res2->count;
2393         TALLOC_FREE(req);
2394
2395         /* We should not have got the result */
2396         assert_int_equal(res_count, 0);
2397         assert_int_equal(ret, 0);
2398
2399         pid = waitpid(child_pid, &wstatus, 0);
2400         assert_int_equal(pid, child_pid);
2401
2402         assert_true(WIFEXITED(wstatus));
2403
2404         assert_int_equal(WEXITSTATUS(wstatus), 0);
2405
2406         /*
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
2410          */
2411
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");
2416
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);
2422
2423         /* We got the result */
2424         assert_int_equal(res2->count, 1);
2425 }
2426
2427 static int ldb_case_test_setup(void **state)
2428 {
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 },
2440         };
2441
2442
2443         ldbtest_setup((void **) &ldb_test_ctx);
2444
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);
2448         }
2449
2450         ldb_test_add_data(ldb_test_ctx,
2451                           ldb_test_ctx,
2452                           "cn=CaseInsensitiveValue",
2453                           kvs);
2454
2455         *state = ldb_test_ctx;
2456         return 0;
2457 }
2458
2459 static int ldb_case_test_teardown(void **state)
2460 {
2461         int ret;
2462         struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
2463                         struct ldbtest_ctx);
2464
2465         struct ldb_dn *del_dn;
2466
2467         del_dn = ldb_dn_new_fmt(ldb_test_ctx,
2468                                 ldb_test_ctx->ldb,
2469                                 "@ATTRIBUTES");
2470         assert_non_null(del_dn);
2471
2472         ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
2473         assert_int_equal(ret, LDB_SUCCESS);
2474
2475         assert_dn_doesnt_exist(ldb_test_ctx,
2476                                "@ATTRIBUTES");
2477
2478         ldb_test_remove_data(ldb_test_ctx, ldb_test_ctx,
2479                              "cn=CaseInsensitiveValue");
2480
2481         ldbtest_teardown((void **) &ldb_test_ctx);
2482         return 0;
2483 }
2484
2485 static void test_ldb_attrs_case_insensitive(void **state)
2486 {
2487         int cnt;
2488         struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
2489                         struct ldbtest_ctx);
2490
2491         /* cn matches exact case */
2492         cnt = sub_search_count(ldb_test_ctx, "", "cn=CaseInsensitiveValue");
2493         assert_int_equal(cnt, 1);
2494
2495         /* cn matches lower case */
2496         cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2497         assert_int_equal(cnt, 1);
2498
2499         /* uid matches exact case */
2500         cnt = sub_search_count(ldb_test_ctx, "", "uid=CaseSensitiveValue");
2501         assert_int_equal(cnt, 1);
2502
2503         /* uid does not match lower case */
2504         cnt = sub_search_count(ldb_test_ctx, "", "uid=casesensitivevalue");
2505         assert_int_equal(cnt, 0);
2506 }
2507
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;
2511
2512 /*
2513   override the name to attribute handler function
2514  */
2515 static const struct ldb_schema_attribute *ldb_test_attribute_handler_override(struct ldb_context *ldb,
2516                                                                               void *private_data,
2517                                                                               const char *name)
2518 {
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;
2525         }
2526         return &default_attr;
2527 }
2528
2529 static void test_ldb_attrs_case_handler(void **state)
2530 {
2531         int cnt;
2532         int ret;
2533         const struct ldb_schema_syntax *syntax;
2534
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;
2538
2539         /* cn matches lower case */
2540         cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2541         assert_int_equal(cnt, 1);
2542
2543         syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_OCTET_STRING);
2544         assert_non_null(syntax);
2545
2546         ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb,
2547                                                     "*", 0,
2548                                                     syntax, &default_attr);
2549         assert_int_equal(ret, LDB_SUCCESS);
2550
2551         syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_OCTET_STRING);
2552         assert_non_null(syntax);
2553
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);
2558
2559         /*
2560          * Set an attribute handler, which will fail to match as we
2561          * force case sensitive
2562          */
2563         ldb_schema_attribute_set_override_handler(ldb,
2564                                                   ldb_test_attribute_handler_override,
2565                                                   (void *)1);
2566
2567         /* cn does not matche lower case */
2568         cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2569         assert_int_equal(cnt, 0);
2570
2571         syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_DIRECTORY_STRING);
2572         assert_non_null(syntax);
2573
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);
2578
2579         /*
2580          * Set an attribute handler, which will match as we
2581          * force case insensitive
2582          */
2583         ldb_schema_attribute_set_override_handler(ldb,
2584                                                   ldb_test_attribute_handler_override,
2585                                                   NULL);
2586
2587         /* cn matches lower case */
2588         cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2589         assert_int_equal(cnt, 1);
2590
2591 }
2592
2593
2594 static void test_ldb_attrs_index_handler(void **state)
2595 {
2596         int cnt;
2597         int ret;
2598         const struct ldb_schema_syntax *syntax;
2599         struct ldb_ldif *ldif;
2600
2601         const char *index_ldif =  \
2602                 "dn: @INDEXLIST\n"
2603                 "@IDXATTR: cn\n"
2604                 "\n";
2605
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;
2609
2610         /* cn matches lower case */
2611         cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2612         assert_int_equal(cnt, 1);
2613
2614         syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_OCTET_STRING);
2615         assert_non_null(syntax);
2616
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);
2621
2622         syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_DIRECTORY_STRING);
2623         assert_non_null(syntax);
2624
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);
2629
2630         syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_OCTET_STRING);
2631         assert_non_null(syntax);
2632
2633         ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb,
2634                                                     "", 0,
2635                                                     syntax, &default_attr);
2636         assert_int_equal(ret, LDB_SUCCESS);
2637
2638         /*
2639          * Set an attribute handler
2640          */
2641         ldb_schema_attribute_set_override_handler(ldb,
2642                                                   ldb_test_attribute_handler_override,
2643                                                   NULL);
2644
2645         /* cn matches lower case */
2646         cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2647         assert_int_equal(cnt, 1);
2648
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);
2653         }
2654
2655         ldb_schema_set_override_indexlist(ldb, false);
2656
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);
2660
2661         /*
2662          * Set an attribute handler, which will later fail to match as we
2663          * didn't re-index the DB
2664          */
2665         ldb_schema_attribute_set_override_handler(ldb,
2666                                                   ldb_test_attribute_handler_override,
2667                                                   (void *)1);
2668
2669         /*
2670          * cn does not match as we changed the case sensitivity, but
2671          * didn't re-index
2672          *
2673          * This shows that the override is in control
2674          */
2675         cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2676         assert_int_equal(cnt, 0);
2677
2678 }
2679
2680 static int ldb_case_attrs_index_test_teardown(void **state)
2681 {
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;
2686
2687         del_dn = ldb_dn_new_fmt(ldb_test_ctx,
2688                                 ldb_test_ctx->ldb,
2689                                 "@INDEXLIST");
2690         assert_non_null(del_dn);
2691
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);
2695         }
2696
2697         assert_dn_doesnt_exist(ldb_test_ctx,
2698                                "@INDEXLIST");
2699
2700         ldb_case_test_teardown(state);
2701         return 0;
2702 }
2703
2704
2705 struct rename_test_ctx {
2706         struct ldbtest_ctx *ldb_test_ctx;
2707
2708         struct ldb_dn *basedn;
2709         const char *str_basedn;
2710
2711         const char *teardown_dn;
2712 };
2713
2714 static int ldb_rename_test_setup(void **state)
2715 {
2716         struct ldbtest_ctx *ldb_test_ctx;
2717         struct rename_test_ctx *rename_test_ctx;
2718         const char *strdn = "dc=rename_test_entry_from";
2719
2720         ldbtest_setup((void **) &ldb_test_ctx);
2721
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);
2726
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);
2731
2732         rename_test_ctx->str_basedn = strdn;
2733         rename_test_ctx->teardown_dn = strdn;
2734
2735         add_dn_with_cn(ldb_test_ctx,
2736                        rename_test_ctx->basedn,
2737                        "test_rename_cn_val");
2738
2739         *state = rename_test_ctx;
2740         return 0;
2741 }
2742
2743 static int ldb_rename_test_teardown(void **state)
2744 {
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;
2750
2751         ldb_test_ctx = rename_test_ctx->ldb_test_ctx;
2752
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);
2757
2758         ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
2759         assert_int_equal(ret, LDB_SUCCESS);
2760
2761         assert_dn_doesnt_exist(ldb_test_ctx,
2762                                rename_test_ctx->teardown_dn);
2763
2764         ldbtest_teardown((void **) &ldb_test_ctx);
2765         return 0;
2766 }
2767
2768 static void test_ldb_rename(void **state)
2769 {
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;
2775
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);
2780
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);
2785
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;
2790
2791         /* FIXME - test the values which didn't change */
2792 }
2793
2794 static void test_ldb_rename_from_doesnt_exist(void **state)
2795 {
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;
2804
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);
2809
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);
2814
2815         assert_dn_doesnt_exist(rename_test_ctx->ldb_test_ctx,
2816                                str_bad_old_dn);
2817
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);
2821
2822         assert_dn_doesnt_exist(rename_test_ctx->ldb_test_ctx,
2823                                str_new_dn);
2824 }
2825
2826 static void test_ldb_rename_to_exists(void **state)
2827 {
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;
2834
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);
2839
2840         add_dn_with_cn(rename_test_ctx->ldb_test_ctx,
2841                        new_dn,
2842                        "test_rename_cn_val");
2843
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);
2848
2849         /* Old object must still exist */
2850         assert_dn_exists(rename_test_ctx->ldb_test_ctx,
2851                          rename_test_ctx->str_basedn);
2852
2853         ret = ldb_delete(rename_test_ctx->ldb_test_ctx->ldb,
2854                          new_dn);
2855         assert_int_equal(ret, LDB_SUCCESS);
2856
2857         assert_dn_exists(rename_test_ctx->ldb_test_ctx,
2858                                rename_test_ctx->teardown_dn);
2859 }
2860
2861 static void test_ldb_rename_self(void **state)
2862 {
2863         struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(
2864                                                         *state,
2865                                                         struct rename_test_ctx);
2866         int ret;
2867
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);
2873
2874         /* Old object must still exist */
2875         assert_dn_exists(rename_test_ctx->ldb_test_ctx,
2876                          rename_test_ctx->str_basedn);
2877 }
2878
2879 static void test_ldb_rename_dn_case_change(void **state)
2880 {
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;
2888
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]);
2893         }
2894
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);
2899
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);
2904
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 */
2910 }
2911
2912 static int ldb_read_only_setup(void **state)
2913 {
2914         struct ldbtest_ctx *test_ctx;
2915
2916         ldbtest_setup((void **) &test_ctx);
2917
2918         *state = test_ctx;
2919         return 0;
2920 }
2921
2922 static int ldb_read_only_teardown(void **state)
2923 {
2924         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
2925                                                         struct ldbtest_ctx);
2926         ldbtest_teardown((void **) &test_ctx);
2927         return 0;
2928 }
2929
2930 static void test_read_only(void **state)
2931 {
2932         struct ldb_context *ro_ldb = NULL;
2933         struct ldb_context *rw_ldb = NULL;
2934         int ret;
2935         TALLOC_CTX *tmp_ctx = NULL;
2936
2937         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
2938                                                         struct ldbtest_ctx);
2939         /*
2940          * Close the ldb context freeing it this will ensure it exists on
2941          * disk and can be opened in read only mode
2942          */
2943         TALLOC_FREE(test_ctx->ldb);
2944
2945         /*
2946          * Open the database in read only and read write mode,
2947          * ensure it's opend in read only mode first
2948          */
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);
2952
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);
2956
2957
2958         /*
2959          * Set up a context for the temporary variables
2960          */
2961         tmp_ctx = talloc_new(test_ctx);
2962         assert_non_null(tmp_ctx);
2963
2964         /*
2965          * Ensure that we can search the read write database
2966          */
2967         {
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);
2972
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);
2978         }
2979
2980         /*
2981          * Ensure that we can search the read only database
2982          */
2983         {
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);
2988
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);
2994         }
2995         /*
2996          * Ensure that a write to the read only database fails
2997          */
2998         {
2999                 struct ldb_message *msg = NULL;
3000                 msg = ldb_msg_new(tmp_ctx);
3001                 assert_non_null(msg);
3002
3003                 msg->dn = ldb_dn_new_fmt(msg, ro_ldb, "dc=test");
3004                 assert_non_null(msg->dn);
3005
3006                 ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
3007                 assert_int_equal(ret, 0);
3008
3009                 ret = ldb_add(ro_ldb, msg);
3010                 assert_int_equal(ret, LDB_ERR_UNWILLING_TO_PERFORM);
3011                 TALLOC_FREE(msg);
3012         }
3013
3014         /*
3015          * Ensure that a write to the read write database succeeds
3016          */
3017         {
3018                 struct ldb_message *msg = NULL;
3019                 msg = ldb_msg_new(tmp_ctx);
3020                 assert_non_null(msg);
3021
3022                 msg->dn = ldb_dn_new_fmt(msg, ro_ldb, "dc=test");
3023                 assert_non_null(msg->dn);
3024
3025                 ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
3026                 assert_int_equal(ret, 0);
3027
3028                 ret = ldb_add(rw_ldb, msg);
3029                 assert_int_equal(ret, LDB_SUCCESS);
3030                 TALLOC_FREE(msg);
3031         }
3032
3033         /*
3034          * Ensure that a delete from a read only database fails
3035          */
3036         {
3037                 struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, ro_ldb, "dc=test");
3038                 assert_non_null(dn);
3039
3040                 ret = ldb_delete(ro_ldb, dn);
3041                 assert_int_equal(ret, LDB_ERR_UNWILLING_TO_PERFORM);
3042                 TALLOC_FREE(dn);
3043         }
3044
3045
3046         /*
3047          * Ensure that a delete from a read write succeeds
3048          */
3049         {
3050                 struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, rw_ldb, "dc=test");
3051                 assert_non_null(dn);
3052
3053                 ret = ldb_delete(rw_ldb, dn);
3054                 assert_int_equal(ret, LDB_SUCCESS);
3055                 TALLOC_FREE(dn);
3056         }
3057         TALLOC_FREE(tmp_ctx);
3058 }
3059
3060 static bool unique_values = false;
3061
3062 static int unique_index_test_module_add(
3063         struct ldb_module *module,
3064         struct ldb_request *req)
3065 {
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;
3072                 }
3073         }
3074
3075         return ldb_next_request(module, req);
3076 }
3077
3078 static int unique_index_test_module_init(struct ldb_module *module)
3079 {
3080         return ldb_next_init(module);
3081 }
3082
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,
3087 };
3088
3089 static int ldb_unique_index_test_setup(void **state)
3090 {
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", NULL};
3103
3104
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);
3108
3109
3110         ret = ldb_connect(ldb_test_ctx->ldb, ldb_test_ctx->dbpath, 0, options);
3111         assert_int_equal(ret, 0);
3112
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);
3116         }
3117
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);
3121         }
3122
3123         unique_values = true;
3124
3125         *state = ldb_test_ctx;
3126         return 0;
3127 }
3128
3129 static int ldb_unique_index_test_teardown(void **state)
3130 {
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;
3135
3136         del_dn = ldb_dn_new_fmt(ldb_test_ctx,
3137                                 ldb_test_ctx->ldb,
3138                                 "@INDEXLIST");
3139         assert_non_null(del_dn);
3140
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);
3144         }
3145
3146         assert_dn_doesnt_exist(ldb_test_ctx,
3147                                "@INDEXLIST");
3148
3149         TALLOC_FREE(del_dn);
3150
3151         del_dn = ldb_dn_new_fmt(ldb_test_ctx,
3152                                 ldb_test_ctx->ldb,
3153                                 "@ATTRIBUTES");
3154         assert_non_null(del_dn);
3155
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);
3159         }
3160
3161         assert_dn_doesnt_exist(ldb_test_ctx,
3162                                "@ATTRIBUTES");
3163
3164         ldbtest_teardown((void **) &ldb_test_ctx);
3165         return 0;
3166 }
3167
3168
3169 static void test_ldb_add_unique_value_to_unique_index(void **state)
3170 {
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;
3176
3177         tmp_ctx = talloc_new(test_ctx);
3178         assert_non_null(tmp_ctx);
3179
3180         msg = ldb_msg_new(tmp_ctx);
3181         assert_non_null(msg);
3182
3183         msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "dc=test");
3184         assert_non_null(msg->dn);
3185
3186         ret = ldb_msg_add_string(msg, "cn", "test_unique_index");
3187         assert_int_equal(ret, LDB_SUCCESS);
3188
3189         ret = ldb_add(test_ctx->ldb, msg);
3190         assert_int_equal(ret, LDB_SUCCESS);
3191
3192         talloc_free(tmp_ctx);
3193 }
3194
3195 static int ldb_non_unique_index_test_setup(void **state)
3196 {
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", NULL};
3205
3206
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);
3210
3211
3212         ret = ldb_connect(ldb_test_ctx->ldb, ldb_test_ctx->dbpath, 0, options);
3213         assert_int_equal(ret, 0);
3214
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);
3218         }
3219
3220         unique_values = true;
3221
3222         *state = ldb_test_ctx;
3223         return 0;
3224 }
3225
3226 static int ldb_non_unique_index_test_teardown(void **state)
3227 {
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;
3232
3233         del_dn = ldb_dn_new_fmt(ldb_test_ctx,
3234                                 ldb_test_ctx->ldb,
3235                                 "@INDEXLIST");
3236         assert_non_null(del_dn);
3237
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);
3241         }
3242
3243         assert_dn_doesnt_exist(ldb_test_ctx,
3244                                "@INDEXLIST");
3245
3246         TALLOC_FREE(del_dn);
3247
3248         ldbtest_teardown((void **) &ldb_test_ctx);
3249         return 0;
3250 }
3251
3252 static void test_ldb_add_duplicate_value_to_unique_index(void **state)
3253 {
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;
3260
3261         tmp_ctx = talloc_new(test_ctx);
3262         assert_non_null(tmp_ctx);
3263
3264         msg01 = ldb_msg_new(tmp_ctx);
3265         assert_non_null(msg01);
3266
3267         msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3268         assert_non_null(msg01->dn);
3269
3270         ret = ldb_msg_add_string(msg01, "cn", "test_unique_index");
3271         assert_int_equal(ret, LDB_SUCCESS);
3272
3273         ret = ldb_add(test_ctx->ldb, msg01);
3274         assert_int_equal(ret, LDB_SUCCESS);
3275
3276         msg02 = ldb_msg_new(tmp_ctx);
3277         assert_non_null(msg02);
3278
3279         msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02");
3280         assert_non_null(msg02->dn);
3281
3282         ret = ldb_msg_add_string(msg02, "cn", "test_unique_index");
3283         assert_int_equal(ret, LDB_SUCCESS);
3284
3285         ret = ldb_add(test_ctx->ldb, msg02);
3286         assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION);
3287         talloc_free(tmp_ctx);
3288 }
3289
3290 static void test_ldb_add_to_index_duplicates_allowed(void **state)
3291 {
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;
3298
3299         unique_values = false;
3300
3301         tmp_ctx = talloc_new(test_ctx);
3302         assert_non_null(tmp_ctx);
3303
3304
3305         msg01 = ldb_msg_new(tmp_ctx);
3306         assert_non_null(msg01);
3307
3308         msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3309         assert_non_null(msg01->dn);
3310
3311         ret = ldb_msg_add_string(msg01, "cn", "test_unique_index");
3312         assert_int_equal(ret, LDB_SUCCESS);
3313
3314         ret = ldb_add(test_ctx->ldb, msg01);
3315         assert_int_equal(ret, LDB_SUCCESS);
3316
3317         msg02 = ldb_msg_new(tmp_ctx);
3318         assert_non_null(msg02);
3319
3320         msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02");
3321         assert_non_null(msg02->dn);
3322
3323         ret = ldb_msg_add_string(msg02, "cn", "test_unique_index");
3324         assert_int_equal(ret, LDB_SUCCESS);
3325
3326         ret = ldb_add(test_ctx->ldb, msg02);
3327         assert_int_equal(ret, LDB_SUCCESS);
3328         talloc_free(tmp_ctx);
3329 }
3330
3331 static void test_ldb_add_to_index_unique_values_required(void **state)
3332 {
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;
3339
3340         unique_values = true;
3341
3342         tmp_ctx = talloc_new(test_ctx);
3343         assert_non_null(tmp_ctx);
3344
3345
3346         msg01 = ldb_msg_new(tmp_ctx);
3347         assert_non_null(msg01);
3348
3349         msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3350         assert_non_null(msg01->dn);
3351
3352         ret = ldb_msg_add_string(msg01, "cn", "test_unique_index");
3353         assert_int_equal(ret, LDB_SUCCESS);
3354
3355         ret = ldb_add(test_ctx->ldb, msg01);
3356         assert_int_equal(ret, LDB_SUCCESS);
3357
3358         msg02 = ldb_msg_new(tmp_ctx);
3359         assert_non_null(msg02);
3360
3361         msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02");
3362         assert_non_null(msg02->dn);
3363
3364         ret = ldb_msg_add_string(msg02, "cn", "test_unique_index");
3365         assert_int_equal(ret, LDB_SUCCESS);
3366
3367         ret = ldb_add(test_ctx->ldb, msg02);
3368         assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION);
3369         talloc_free(tmp_ctx);
3370 }
3371
3372 static void ldb_debug_string(void *context, enum ldb_debug_level level,
3373                              const char *fmt, va_list ap)
3374 {
3375
3376         if (level <= LDB_DEBUG_WARNING) {
3377                 *((char **)context) = talloc_vasprintf(NULL, fmt, ap);
3378         }
3379 }
3380
3381 static void test_ldb_unique_index_duplicate_logging(void **state)
3382 {
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;
3391
3392         /* The non-GUID mode is not compatible with mdb */
3393         if (strcmp(TEST_BE, "mdb") == 0) {
3394                 return;
3395         }
3396         
3397         ldb_set_debug(test_ctx->ldb, ldb_debug_string, &debug_string);
3398         tmp_ctx = talloc_new(test_ctx);
3399         assert_non_null(tmp_ctx);
3400
3401         msg01 = ldb_msg_new(tmp_ctx);
3402         assert_non_null(msg01);
3403
3404         msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3405         assert_non_null(msg01->dn);
3406
3407         ret = ldb_msg_add_string(msg01, "cn", "test_unique_index");
3408         assert_int_equal(ret, LDB_SUCCESS);
3409
3410         ret = ldb_add(test_ctx->ldb, msg01);
3411         assert_int_equal(ret, LDB_SUCCESS);
3412
3413         msg02 = ldb_msg_new(tmp_ctx);
3414         assert_non_null(msg02);
3415
3416         msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02");
3417         assert_non_null(msg02->dn);
3418
3419         ret = ldb_msg_add_string(msg02, "cn", "test_unique_index");
3420         assert_int_equal(ret, LDB_SUCCESS);
3421
3422         ret = ldb_add(test_ctx->ldb, msg02);
3423         assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION);
3424
3425         assert_non_null(debug_string);
3426         p = strstr(
3427                 debug_string,
3428                 "unique index violation on cn "
3429                 "in dc=test02, conficts with dc=test01 in "
3430                 "@INDEX:CN:test_unique_index");
3431         assert_non_null(p);
3432         TALLOC_FREE(debug_string);
3433         talloc_free(tmp_ctx);
3434 }
3435
3436 static void test_ldb_duplicate_dn_logging(void **state)
3437 {
3438         int ret;
3439         struct ldb_message *msg01;
3440         struct ldb_message *msg02;
3441         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3442                                                         struct ldbtest_ctx);
3443         TALLOC_CTX *tmp_ctx;
3444         char *debug_string = NULL;
3445
3446         /* The non-GUID mode is not compatible with mdb */
3447         if (strcmp(TEST_BE, "mdb") == 0) {
3448                 return;
3449         }
3450         
3451         ldb_set_debug(test_ctx->ldb, ldb_debug_string, &debug_string);
3452         tmp_ctx = talloc_new(test_ctx);
3453         assert_non_null(tmp_ctx);
3454
3455         msg01 = ldb_msg_new(tmp_ctx);
3456         assert_non_null(msg01);
3457
3458         msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3459         assert_non_null(msg01->dn);
3460
3461         ret = ldb_msg_add_string(msg01, "cn", "test_unique_index01");
3462         assert_int_equal(ret, LDB_SUCCESS);
3463
3464         ret = ldb_add(test_ctx->ldb, msg01);
3465         assert_int_equal(ret, LDB_SUCCESS);
3466
3467         msg02 = ldb_msg_new(tmp_ctx);
3468         assert_non_null(msg02);
3469
3470         msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test01");
3471         assert_non_null(msg02->dn);
3472
3473         ret = ldb_msg_add_string(msg02, "cn", "test_unique_index02");
3474         assert_int_equal(ret, LDB_SUCCESS);
3475
3476         ret = ldb_add(test_ctx->ldb, msg02);
3477         assert_int_equal(ret, LDB_ERR_ENTRY_ALREADY_EXISTS);
3478
3479         assert_null(debug_string);
3480         talloc_free(tmp_ctx);
3481 }
3482
3483 static int ldb_guid_index_test_setup(void **state)
3484 {
3485         int ret;
3486         struct ldb_ldif *ldif;
3487         struct ldbtest_ctx *ldb_test_ctx;
3488         const char *attrs_ldif =  \
3489                 "dn: @ATTRIBUTES\n"
3490                 "cn: UNIQUE_INDEX\n"
3491                 "\n";
3492         const char *index_ldif =  \
3493                 "dn: @INDEXLIST\n"
3494                 "@IDXATTR: cn\n"
3495                 "@IDXGUID: objectUUID\n"
3496                 "@IDX_DN_GUID: GUID\n"
3497                 "\n";
3498
3499         ldbtest_noconn_setup((void **) &ldb_test_ctx);
3500
3501
3502         ret = ldb_connect(ldb_test_ctx->ldb, ldb_test_ctx->dbpath, 0, NULL);
3503         assert_int_equal(ret, 0);
3504
3505         while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &attrs_ldif))) {
3506                 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
3507                 assert_int_equal(ret, LDB_SUCCESS);
3508         }
3509
3510         while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &index_ldif))) {
3511                 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
3512                 assert_int_equal(ret, LDB_SUCCESS);
3513         }
3514
3515         *state = ldb_test_ctx;
3516         return 0;
3517 }
3518
3519 static int ldb_guid_index_test_teardown(void **state)
3520 {
3521         int ret;
3522         struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
3523                         struct ldbtest_ctx);
3524         struct ldb_dn *del_dn;
3525
3526         del_dn = ldb_dn_new_fmt(ldb_test_ctx,
3527                                 ldb_test_ctx->ldb,
3528                                 "@INDEXLIST");
3529         assert_non_null(del_dn);
3530
3531         ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
3532         if (ret != LDB_ERR_NO_SUCH_OBJECT) {
3533                 assert_int_equal(ret, LDB_SUCCESS);
3534         }
3535
3536         assert_dn_doesnt_exist(ldb_test_ctx,
3537                                "@INDEXLIST");
3538
3539         TALLOC_FREE(del_dn);
3540
3541         del_dn = ldb_dn_new_fmt(ldb_test_ctx,
3542                                 ldb_test_ctx->ldb,
3543                                 "@ATTRIBUTES");
3544         assert_non_null(del_dn);
3545
3546         ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
3547         if (ret != LDB_ERR_NO_SUCH_OBJECT) {
3548                 assert_int_equal(ret, LDB_SUCCESS);
3549         }
3550
3551         assert_dn_doesnt_exist(ldb_test_ctx,
3552                                "@ATTRIBUTES");
3553
3554         ldbtest_teardown((void **) &ldb_test_ctx);
3555         return 0;
3556 }
3557
3558
3559 static void test_ldb_unique_index_duplicate_with_guid(void **state)
3560 {
3561         int ret;
3562         struct ldb_message *msg01;
3563         struct ldb_message *msg02;
3564         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3565                                                         struct ldbtest_ctx);
3566         TALLOC_CTX *tmp_ctx;
3567         char *debug_string = NULL;
3568         char *p = NULL;
3569
3570         ldb_set_debug(test_ctx->ldb, ldb_debug_string, &debug_string);
3571         tmp_ctx = talloc_new(test_ctx);
3572         assert_non_null(tmp_ctx);
3573
3574         msg01 = ldb_msg_new(tmp_ctx);
3575         assert_non_null(msg01);
3576
3577         msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3578         assert_non_null(msg01->dn);
3579
3580         ret = ldb_msg_add_string(msg01, "cn", "test_unique_index");
3581         assert_int_equal(ret, LDB_SUCCESS);
3582
3583         ret = ldb_msg_add_string(msg01, "objectUUID", "0123456789abcdef");
3584         assert_int_equal(ret, LDB_SUCCESS);
3585
3586         ret = ldb_add(test_ctx->ldb, msg01);
3587         assert_int_equal(ret, LDB_SUCCESS);
3588
3589         msg02 = ldb_msg_new(tmp_ctx);
3590         assert_non_null(msg01);
3591
3592         msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02");
3593         assert_non_null(msg02->dn);
3594
3595         ret = ldb_msg_add_string(msg02, "cn", "test_unique_index");
3596         assert_int_equal(ret, LDB_SUCCESS);
3597
3598         ret = ldb_msg_add_string(msg02, "objectUUID", "0123456789abcde0");
3599         assert_int_equal(ret, LDB_SUCCESS);
3600
3601         ret = ldb_add(test_ctx->ldb, msg02);
3602         assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION);
3603
3604         assert_non_null(debug_string);
3605         p = strstr(
3606                 debug_string,
3607                 "unique index violation on cn in dc=test02, conficts with "
3608                 "objectUUID 0123456789abcdef in @INDEX:CN:test_unique_index");
3609         assert_non_null(p);
3610         TALLOC_FREE(debug_string);
3611         talloc_free(tmp_ctx);
3612 }
3613
3614 static void test_ldb_guid_index_duplicate_dn_logging(void **state)
3615 {
3616         int ret;
3617         struct ldb_message *msg01;
3618         struct ldb_message *msg02;
3619         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3620                                                         struct ldbtest_ctx);
3621         TALLOC_CTX *tmp_ctx;
3622         char *debug_string = NULL;
3623
3624         ldb_set_debug(test_ctx->ldb, ldb_debug_string, &debug_string);
3625         tmp_ctx = talloc_new(test_ctx);
3626         assert_non_null(tmp_ctx);
3627
3628         msg01 = ldb_msg_new(tmp_ctx);
3629         assert_non_null(msg01);
3630
3631         msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3632         assert_non_null(msg01->dn);
3633
3634         ret = ldb_msg_add_string(msg01, "cn", "test_unique_index01");
3635         assert_int_equal(ret, LDB_SUCCESS);
3636
3637         ret = ldb_msg_add_string(msg01, "objectUUID", "0123456789abcdef");
3638         assert_int_equal(ret, LDB_SUCCESS);
3639
3640         ret = ldb_add(test_ctx->ldb, msg01);
3641         assert_int_equal(ret, LDB_SUCCESS);
3642
3643         msg02 = ldb_msg_new(tmp_ctx);
3644         assert_non_null(msg02);
3645
3646         msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test01");
3647         assert_non_null(msg02->dn);
3648
3649         ret = ldb_msg_add_string(msg02, "cn", "test_unique_index02");
3650         assert_int_equal(ret, LDB_SUCCESS);
3651
3652         ret = ldb_msg_add_string(msg02, "objectUUID", "0123456789abcde1");
3653         assert_int_equal(ret, LDB_SUCCESS);
3654
3655         ret = ldb_add(test_ctx->ldb, msg02);
3656         assert_int_equal(ret, LDB_ERR_ENTRY_ALREADY_EXISTS);
3657
3658         assert_null(debug_string);
3659         talloc_free(tmp_ctx);
3660 }
3661
3662 static void test_ldb_talloc_destructor_transaction_cleanup(void **state)
3663 {
3664         struct ldbtest_ctx *test_ctx = NULL;
3665
3666         test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx);
3667         assert_non_null(test_ctx);
3668
3669         ldb_transaction_start(test_ctx->ldb);
3670
3671         /*
3672          * Trigger the destructor
3673          */
3674         TALLOC_FREE(test_ctx->ldb);
3675
3676         /*
3677          * Now ensure that a new connection can be opened
3678          */
3679         {
3680                 TALLOC_CTX *tctx = talloc_new(test_ctx);
3681                 struct ldbtest_ctx *ctx = talloc_zero(tctx, struct ldbtest_ctx);
3682                 struct ldb_dn *basedn;
3683                 struct ldb_result *result = NULL;
3684                 int ret;
3685
3686                 ldbtest_setup((void *)&ctx);
3687
3688                 basedn = ldb_dn_new_fmt(tctx, ctx->ldb, "dc=test");
3689                 assert_non_null(basedn);
3690
3691                 ret = ldb_search(ctx->ldb,
3692                                  tctx,
3693                                  &result,
3694                                  basedn,
3695                                  LDB_SCOPE_BASE,
3696                                  NULL,
3697                                  NULL);
3698                 assert_int_equal(ret, 0);
3699                 assert_non_null(result);
3700                 assert_int_equal(result->count, 0);
3701
3702                 ldbtest_teardown((void *)&ctx);
3703         }
3704 }
3705
3706
3707 int main(int argc, const char **argv)
3708 {
3709         const struct CMUnitTest tests[] = {
3710                 cmocka_unit_test_setup_teardown(test_connect,
3711                                                 ldbtest_noconn_setup,
3712                                                 ldbtest_noconn_teardown),
3713                 cmocka_unit_test_setup_teardown(test_ldif_message,
3714                                                 ldbtest_noconn_setup,
3715                                                 ldbtest_noconn_teardown),
3716                 cmocka_unit_test_setup_teardown(test_ldif_message_redacted,
3717                                                 ldbtest_noconn_setup,
3718                                                 ldbtest_noconn_teardown),
3719                 cmocka_unit_test_setup_teardown(test_ldb_add,
3720                                                 ldbtest_setup,
3721                                                 ldbtest_teardown),
3722                 cmocka_unit_test_setup_teardown(test_ldb_search,
3723                                                 ldbtest_setup,
3724                                                 ldbtest_teardown),
3725                 cmocka_unit_test_setup_teardown(test_ldb_del,
3726                                                 ldbtest_setup,
3727                                                 ldbtest_teardown),
3728                 cmocka_unit_test_setup_teardown(test_ldb_del_noexist,
3729                                                 ldbtest_setup,
3730                                                 ldbtest_teardown),
3731                 cmocka_unit_test_setup_teardown(test_ldb_handle,
3732                                                 ldbtest_setup,
3733                                                 ldbtest_teardown),
3734                 cmocka_unit_test_setup_teardown(test_ldb_build_search_req,
3735                                                 ldbtest_setup,
3736                                                 ldbtest_teardown),
3737                 cmocka_unit_test_setup_teardown(test_transactions,
3738                                                 ldbtest_setup,
3739                                                 ldbtest_teardown),
3740                 cmocka_unit_test_setup_teardown(test_nested_transactions,
3741                                                 ldbtest_setup,
3742                                                 ldbtest_teardown),
3743                 cmocka_unit_test_setup_teardown(test_ldb_modify_add_key,
3744                                                 ldb_modify_test_setup,
3745                                                 ldb_modify_test_teardown),
3746                 cmocka_unit_test_setup_teardown(test_ldb_modify_extend_key,
3747                                                 ldb_modify_test_setup,
3748                                                 ldb_modify_test_teardown),
3749                 cmocka_unit_test_setup_teardown(test_ldb_modify_add_key_noval,
3750                                                 ldb_modify_test_setup,
3751                                                 ldb_modify_test_teardown),
3752                 cmocka_unit_test_setup_teardown(test_ldb_modify_replace_key,
3753                                                 ldb_modify_test_setup,
3754                                                 ldb_modify_test_teardown),
3755                 cmocka_unit_test_setup_teardown(test_ldb_modify_replace_noexist_key,
3756                                                 ldb_modify_test_setup,
3757                                                 ldb_modify_test_teardown),
3758                 cmocka_unit_test_setup_teardown(test_ldb_modify_replace_zero_vals,
3759                                                 ldb_modify_test_setup,
3760                                                 ldb_modify_test_teardown),
3761                 cmocka_unit_test_setup_teardown(test_ldb_modify_replace_noexist_key_zero_vals,
3762                                                 ldb_modify_test_setup,
3763                                                 ldb_modify_test_teardown),
3764                 cmocka_unit_test_setup_teardown(test_ldb_modify_del_key,
3765                                                 ldb_modify_test_setup,
3766                                                 ldb_modify_test_teardown),
3767                 cmocka_unit_test_setup_teardown(test_ldb_modify_del_keyval,
3768                                                 ldb_modify_test_setup,
3769                                                 ldb_modify_test_teardown),
3770                 cmocka_unit_test_setup_teardown(test_search_match_none,
3771                                                 ldb_search_test_setup,
3772                                                 ldb_search_test_teardown),
3773                 cmocka_unit_test_setup_teardown(test_search_match_one,
3774                                                 ldb_search_test_setup,
3775                                                 ldb_search_test_teardown),
3776                 cmocka_unit_test_setup_teardown(test_search_match_filter,
3777                                                 ldb_search_test_setup,
3778                                                 ldb_search_test_teardown),
3779                 cmocka_unit_test_setup_teardown(test_search_match_both,
3780                                                 ldb_search_test_setup,
3781                                                 ldb_search_test_teardown),
3782                 cmocka_unit_test_setup_teardown(test_search_match_basedn,
3783                                                 ldb_search_test_setup,
3784                                                 ldb_search_test_teardown),
3785                 cmocka_unit_test_setup_teardown(test_ldb_search_against_transaction,
3786                                                 ldb_search_test_setup,
3787                                                 ldb_search_test_teardown),
3788                 cmocka_unit_test_setup_teardown(test_ldb_modify_during_unindexed_search,
3789                                                 ldb_search_test_setup,
3790                                                 ldb_search_test_teardown),
3791                 cmocka_unit_test_setup_teardown(test_ldb_modify_during_indexed_search,
3792                                                 ldb_search_test_setup,
3793                                                 ldb_search_test_teardown),
3794                 cmocka_unit_test_setup_teardown(test_ldb_rename_during_unindexed_search,
3795                                                 ldb_search_test_setup,
3796                                                 ldb_search_test_teardown),
3797                 cmocka_unit_test_setup_teardown(test_ldb_rename_during_indexed_search,
3798                                                 ldb_search_test_setup,
3799                                                 ldb_search_test_teardown),
3800                 cmocka_unit_test_setup_teardown(test_ldb_modify_during_whole_search,
3801                                                 ldb_search_test_setup,
3802                                                 ldb_search_test_teardown),
3803                 cmocka_unit_test_setup_teardown(test_ldb_modify_before_ldb_wait,
3804                                                 ldb_search_test_setup,
3805                                                 ldb_search_test_teardown),
3806                 cmocka_unit_test_setup_teardown(test_ldb_attrs_case_insensitive,
3807                                                 ldb_case_test_setup,
3808                                                 ldb_case_test_teardown),
3809                 cmocka_unit_test_setup_teardown(test_ldb_attrs_case_handler,
3810                                                 ldb_case_test_setup,
3811                                                 ldb_case_test_teardown),
3812                 cmocka_unit_test_setup_teardown(test_ldb_attrs_index_handler,
3813                                                 ldb_case_test_setup,
3814                                                 ldb_case_attrs_index_test_teardown),
3815                 cmocka_unit_test_setup_teardown(test_ldb_rename,
3816                                                 ldb_rename_test_setup,
3817                                                 ldb_rename_test_teardown),
3818                 cmocka_unit_test_setup_teardown(test_ldb_rename_from_doesnt_exist,
3819                                                 ldb_rename_test_setup,
3820                                                 ldb_rename_test_teardown),
3821                 cmocka_unit_test_setup_teardown(test_ldb_rename_to_exists,
3822                                                 ldb_rename_test_setup,
3823                                                 ldb_rename_test_teardown),
3824                 cmocka_unit_test_setup_teardown(test_ldb_rename_self,
3825                                                 ldb_rename_test_setup,
3826                                                 ldb_rename_test_teardown),
3827                 cmocka_unit_test_setup_teardown(test_ldb_rename_dn_case_change,
3828                                                 ldb_rename_test_setup,
3829                                                 ldb_rename_test_teardown),
3830                 cmocka_unit_test_setup_teardown(test_read_only,
3831                                                 ldb_read_only_setup,
3832                                                 ldb_read_only_teardown),
3833                 cmocka_unit_test_setup_teardown(
3834                         test_ldb_add_unique_value_to_unique_index,
3835                         ldb_unique_index_test_setup,
3836                         ldb_unique_index_test_teardown),
3837                 cmocka_unit_test_setup_teardown(
3838                         test_ldb_add_duplicate_value_to_unique_index,
3839                         ldb_unique_index_test_setup,
3840                         ldb_unique_index_test_teardown),
3841                 cmocka_unit_test_setup_teardown(
3842                         test_ldb_add_to_index_duplicates_allowed,
3843                         ldb_non_unique_index_test_setup,
3844                         ldb_non_unique_index_test_teardown),
3845                 cmocka_unit_test_setup_teardown(
3846                         test_ldb_add_to_index_unique_values_required,
3847                         ldb_non_unique_index_test_setup,
3848                         ldb_non_unique_index_test_teardown),
3849                 /* These tests are not compatible with mdb */
3850                 cmocka_unit_test_setup_teardown(
3851                         test_ldb_unique_index_duplicate_logging,
3852                         ldb_unique_index_test_setup,
3853                         ldb_unique_index_test_teardown),
3854                 cmocka_unit_test_setup_teardown(
3855                         test_ldb_duplicate_dn_logging,
3856                         ldb_unique_index_test_setup,
3857                         ldb_unique_index_test_teardown),
3858                 cmocka_unit_test_setup_teardown(
3859                         test_ldb_guid_index_duplicate_dn_logging,
3860                         ldb_guid_index_test_setup,
3861                         ldb_guid_index_test_teardown),
3862                 cmocka_unit_test_setup_teardown(
3863                         test_ldb_unique_index_duplicate_with_guid,
3864                         ldb_guid_index_test_setup,
3865                         ldb_guid_index_test_teardown),
3866                 cmocka_unit_test_setup_teardown(
3867                         test_ldb_talloc_destructor_transaction_cleanup,
3868                         ldbtest_setup,
3869                         ldbtest_teardown),
3870         };
3871
3872         return cmocka_run_group_tests(tests, NULL, NULL);
3873 }