5878143d8f629847bf850ef3556ede4e8fa24784
[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 struct ldb_mod_test_ctx {
630         struct ldbtest_ctx *ldb_test_ctx;
631         const char *entry_dn;
632 };
633
634 struct keyval {
635         const char *key;
636         const char *val;
637 };
638
639 static struct ldb_message *build_mod_msg(TALLOC_CTX *mem_ctx,
640                                          struct ldbtest_ctx *test_ctx,
641                                          const char *dn,
642                                          int modify_flags,
643                                          struct keyval *kvs)
644 {
645         struct ldb_message *msg;
646         int ret;
647         int i;
648
649         msg = ldb_msg_new(mem_ctx);
650         assert_non_null(msg);
651
652         msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "%s", dn);
653         assert_non_null(msg->dn);
654
655         for (i = 0; kvs[i].key != NULL; i++) {
656                 if (modify_flags) {
657                         ret = ldb_msg_add_empty(msg, kvs[i].key,
658                                                 modify_flags, NULL);
659                         assert_int_equal(ret, 0);
660                 }
661
662                 if (kvs[i].val) {
663                         ret = ldb_msg_add_string(msg, kvs[i].key, kvs[i].val);
664                         assert_int_equal(ret, LDB_SUCCESS);
665                 }
666         }
667
668         return msg;
669 }
670
671 static void ldb_test_add_data(TALLOC_CTX *mem_ctx,
672                               struct ldbtest_ctx *ldb_test_ctx,
673                               const char *basedn,
674                               struct keyval *kvs)
675 {
676         TALLOC_CTX *tmp_ctx;
677         struct ldb_message *msg;
678         struct ldb_result *result = NULL;
679         int ret;
680
681         tmp_ctx = talloc_new(mem_ctx);
682         assert_non_null(tmp_ctx);
683
684         msg = build_mod_msg(tmp_ctx, ldb_test_ctx,
685                             basedn, 0, kvs);
686         assert_non_null(msg);
687
688         ret = ldb_add(ldb_test_ctx->ldb, msg);
689         assert_int_equal(ret, LDB_SUCCESS);
690
691         ret = ldb_search(ldb_test_ctx->ldb, tmp_ctx, &result, msg->dn,
692                          LDB_SCOPE_BASE, NULL, NULL);
693         assert_int_equal(ret, LDB_SUCCESS);
694         assert_non_null(result);
695         assert_int_equal(result->count, 1);
696         assert_string_equal(ldb_dn_get_linearized(result->msgs[0]->dn),
697                             ldb_dn_get_linearized(msg->dn));
698
699         talloc_free(tmp_ctx);
700 }
701
702 static void ldb_test_remove_data(TALLOC_CTX *mem_ctx,
703                                  struct ldbtest_ctx *ldb_test_ctx,
704                                  const char *strdn)
705 {
706         TALLOC_CTX *tmp_ctx;
707         struct ldb_dn *basedn;
708         int ret;
709         size_t count;
710
711         tmp_ctx = talloc_new(mem_ctx);
712         assert_non_null(tmp_ctx);
713
714         basedn = ldb_dn_new_fmt(tmp_ctx, ldb_test_ctx->ldb,
715                                 "%s", strdn);
716         assert_non_null(basedn);
717
718         ret = ldb_delete(ldb_test_ctx->ldb, basedn);
719         assert_true(ret == LDB_SUCCESS || ret == LDB_ERR_NO_SUCH_OBJECT);
720
721         count = base_search_count(ldb_test_ctx, ldb_dn_get_linearized(basedn));
722         assert_int_equal(count, 0);
723
724         talloc_free(tmp_ctx);
725 }
726
727 static void mod_test_add_data(struct ldb_mod_test_ctx *mod_test_ctx,
728                               struct keyval *kvs)
729 {
730         ldb_test_add_data(mod_test_ctx,
731                           mod_test_ctx->ldb_test_ctx,
732                           mod_test_ctx->entry_dn,
733                           kvs);
734 }
735
736 static void mod_test_remove_data(struct ldb_mod_test_ctx *mod_test_ctx)
737 {
738         ldb_test_remove_data(mod_test_ctx,
739                              mod_test_ctx->ldb_test_ctx,
740                              mod_test_ctx->entry_dn);
741 }
742
743 static struct ldb_result *run_mod_test(struct ldb_mod_test_ctx *mod_test_ctx,
744                                        int modify_flags,
745                                        struct keyval *kvs)
746 {
747         TALLOC_CTX *tmp_ctx;
748         struct ldb_result *res;
749         struct ldb_message *mod_msg;
750         struct ldb_dn *basedn;
751         struct ldbtest_ctx *ldb_test_ctx;
752         int ret;
753
754         ldb_test_ctx = mod_test_ctx->ldb_test_ctx;
755
756         tmp_ctx = talloc_new(mod_test_ctx);
757         assert_non_null(tmp_ctx);
758
759         mod_msg = build_mod_msg(tmp_ctx, ldb_test_ctx, mod_test_ctx->entry_dn,
760                                 modify_flags, kvs);
761         assert_non_null(mod_msg);
762
763         ret = ldb_modify(ldb_test_ctx->ldb, mod_msg);
764         assert_int_equal(ret, LDB_SUCCESS);
765
766         basedn = ldb_dn_new_fmt(tmp_ctx, ldb_test_ctx->ldb,
767                         "%s", mod_test_ctx->entry_dn);
768         assert_non_null(basedn);
769
770         ret = ldb_search(ldb_test_ctx->ldb, mod_test_ctx, &res, basedn,
771                          LDB_SCOPE_BASE, NULL, NULL);
772         assert_int_equal(ret, LDB_SUCCESS);
773         assert_non_null(res);
774         assert_int_equal(res->count, 1);
775         assert_string_equal(ldb_dn_get_linearized(res->msgs[0]->dn),
776                             ldb_dn_get_linearized(mod_msg->dn));
777
778         talloc_free(tmp_ctx);
779         return res;
780 }
781
782 static int ldb_modify_test_setup(void **state)
783 {
784         struct ldbtest_ctx *ldb_test_ctx;
785         struct ldb_mod_test_ctx *mod_test_ctx;
786         struct keyval kvs[] = {
787                 { "cn", "test_mod_cn" },
788                 { NULL, NULL },
789         };
790
791         ldbtest_setup((void **) &ldb_test_ctx);
792
793         mod_test_ctx = talloc(ldb_test_ctx, struct ldb_mod_test_ctx);
794         assert_non_null(mod_test_ctx);
795
796         mod_test_ctx->entry_dn = "dc=mod_test_entry";
797         mod_test_ctx->ldb_test_ctx = ldb_test_ctx;
798
799         mod_test_remove_data(mod_test_ctx);
800         mod_test_add_data(mod_test_ctx, kvs);
801         *state = mod_test_ctx;
802         return 0;
803 }
804
805 static int ldb_modify_test_teardown(void **state)
806 {
807         struct ldb_mod_test_ctx *mod_test_ctx = \
808                                 talloc_get_type_abort(*state,
809                                                       struct ldb_mod_test_ctx);
810         struct ldbtest_ctx *ldb_test_ctx;
811
812         ldb_test_ctx = mod_test_ctx->ldb_test_ctx;
813
814         mod_test_remove_data(mod_test_ctx);
815         talloc_free(mod_test_ctx);
816
817         ldbtest_teardown((void **) &ldb_test_ctx);
818         return 0;
819 }
820
821 static void test_ldb_modify_add_key(void **state)
822 {
823         struct ldb_mod_test_ctx *mod_test_ctx = \
824                                 talloc_get_type_abort(*state,
825                                                       struct ldb_mod_test_ctx);
826         struct keyval mod_kvs[] = {
827                 { "name", "test_mod_name" },
828                 { NULL, NULL },
829         };
830         struct ldb_result *res;
831         struct ldb_message_element *el;
832
833         res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_ADD, mod_kvs);
834         assert_non_null(res);
835
836         /* Check cn is intact and name was added */
837         assert_int_equal(res->count, 1);
838         el = ldb_msg_find_element(res->msgs[0], "cn");
839         assert_non_null(el);
840         assert_int_equal(el->num_values, 1);
841         assert_string_equal(el->values[0].data, "test_mod_cn");
842
843         el = ldb_msg_find_element(res->msgs[0], "name");
844         assert_non_null(el);
845         assert_int_equal(el->num_values, 1);
846         assert_string_equal(el->values[0].data, "test_mod_name");
847 }
848
849 static void test_ldb_modify_extend_key(void **state)
850 {
851         struct ldb_mod_test_ctx *mod_test_ctx = \
852                         talloc_get_type_abort(*state,
853                                               struct ldb_mod_test_ctx);
854         struct keyval mod_kvs[] = {
855                 { "cn", "test_mod_cn2" },
856                 { NULL, NULL },
857         };
858         struct ldb_result *res;
859         struct ldb_message_element *el;
860
861         res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_ADD, mod_kvs);
862         assert_non_null(res);
863
864         /* Check cn was extended with another value */
865         assert_int_equal(res->count, 1);
866         el = ldb_msg_find_element(res->msgs[0], "cn");
867         assert_non_null(el);
868         assert_int_equal(el->num_values, 2);
869         assert_string_equal(el->values[0].data, "test_mod_cn");
870         assert_string_equal(el->values[1].data, "test_mod_cn2");
871 }
872
873 static void test_ldb_modify_add_key_noval(void **state)
874 {
875         struct ldb_mod_test_ctx *mod_test_ctx = \
876                         talloc_get_type_abort(*state,
877                                               struct ldb_mod_test_ctx);
878         struct ldb_message *mod_msg;
879         struct ldbtest_ctx *ldb_test_ctx;
880         struct ldb_message_element *el;
881         int ret;
882
883         ldb_test_ctx = mod_test_ctx->ldb_test_ctx;
884
885         mod_msg = ldb_msg_new(mod_test_ctx);
886         assert_non_null(mod_msg);
887
888         mod_msg->dn = ldb_dn_new_fmt(mod_msg, ldb_test_ctx->ldb,
889                         "%s", mod_test_ctx->entry_dn);
890         assert_non_null(mod_msg->dn);
891
892         el = talloc_zero(mod_msg, struct ldb_message_element);
893         el->flags = LDB_FLAG_MOD_ADD;
894         assert_non_null(el);
895         el->name = talloc_strdup(el, "cn");
896         assert_non_null(el->name);
897
898         mod_msg->elements = el;
899         mod_msg->num_elements = 1;
900
901         ret = ldb_modify(ldb_test_ctx->ldb, mod_msg);
902         assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION);
903 }
904
905 static void test_ldb_modify_replace_key(void **state)
906 {
907         struct ldb_mod_test_ctx *mod_test_ctx = \
908                         talloc_get_type_abort(*state,
909                                               struct ldb_mod_test_ctx);
910         const char *new_cn = "new_cn";
911         struct keyval mod_kvs[] = {
912                 { "cn", new_cn },
913                 { NULL, NULL },
914         };
915         struct ldb_result *res;
916         struct ldb_message_element *el;
917
918         res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, mod_kvs);
919         assert_non_null(res);
920
921         /* Check cn was replaced */
922         assert_int_equal(res->count, 1);
923         el = ldb_msg_find_element(res->msgs[0], "cn");
924         assert_non_null(el);
925         assert_int_equal(el->num_values, 1);
926         assert_string_equal(el->values[0].data, new_cn);
927 }
928
929 static void test_ldb_modify_replace_noexist_key(void **state)
930 {
931         struct ldb_mod_test_ctx *mod_test_ctx = \
932                         talloc_get_type_abort(*state,
933                                               struct ldb_mod_test_ctx);
934         struct keyval mod_kvs[] = {
935                 { "name", "name_val" },
936                 { NULL, NULL },
937         };
938         struct ldb_result *res;
939         struct ldb_message_element *el;
940
941         res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, mod_kvs);
942         assert_non_null(res);
943
944         /* Check cn is intact and name was added */
945         assert_int_equal(res->count, 1);
946         el = ldb_msg_find_element(res->msgs[0], "cn");
947         assert_non_null(el);
948         assert_int_equal(el->num_values, 1);
949         assert_string_equal(el->values[0].data, "test_mod_cn");
950
951         el = ldb_msg_find_element(res->msgs[0], mod_kvs[0].key);
952         assert_non_null(el);
953         assert_int_equal(el->num_values, 1);
954         assert_string_equal(el->values[0].data, mod_kvs[0].val);
955 }
956
957 static void test_ldb_modify_replace_zero_vals(void **state)
958 {
959         struct ldb_mod_test_ctx *mod_test_ctx = \
960                         talloc_get_type_abort(*state,
961                                               struct ldb_mod_test_ctx);
962         struct ldb_message_element *el;
963         struct ldb_result *res;
964         struct keyval kvs[] = {
965                 { "cn", NULL },
966                 { NULL, NULL },
967         };
968
969         /* cn must be gone */
970         res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, kvs);
971         assert_non_null(res);
972         el = ldb_msg_find_element(res->msgs[0], "cn");
973         assert_null(el);
974 }
975
976 static void test_ldb_modify_replace_noexist_key_zero_vals(void **state)
977 {
978         struct ldb_mod_test_ctx *mod_test_ctx = \
979                         talloc_get_type_abort(*state,
980                                               struct ldb_mod_test_ctx);
981         struct ldb_message_element *el;
982         struct ldb_result *res;
983         struct keyval kvs[] = {
984                 { "noexist_key", NULL },
985                 { NULL, NULL },
986         };
987
988         /* cn must be gone */
989         res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, kvs);
990         assert_non_null(res);
991
992         /* cn should be intact */
993         el = ldb_msg_find_element(res->msgs[0], "cn");
994         assert_non_null(el);
995 }
996
997 static void test_ldb_modify_del_key(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_DELETE, kvs);
1011         assert_non_null(res);
1012
1013         el = ldb_msg_find_element(res->msgs[0], "cn");
1014         assert_null(el);
1015 }
1016
1017 static void test_ldb_modify_del_keyval(void **state)
1018 {
1019         struct ldb_mod_test_ctx *mod_test_ctx = \
1020                         talloc_get_type_abort(*state,
1021                                               struct ldb_mod_test_ctx);
1022         struct ldb_message_element *el;
1023         struct ldb_result *res;
1024         struct keyval kvs[] = {
1025                 { "cn", "test_mod_cn" },
1026                 { NULL, NULL },
1027         };
1028
1029         /* cn must be gone */
1030         res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_DELETE, kvs);
1031         assert_non_null(res);
1032
1033         el = ldb_msg_find_element(res->msgs[0], "cn");
1034         assert_null(el);
1035 }
1036
1037 struct search_test_ctx {
1038         struct ldbtest_ctx *ldb_test_ctx;
1039         const char *base_dn;
1040 };
1041
1042 static char *get_full_dn(TALLOC_CTX *mem_ctx,
1043                          struct search_test_ctx *search_test_ctx,
1044                          const char *rdn)
1045 {
1046         char *full_dn;
1047
1048         full_dn = talloc_asprintf(mem_ctx,
1049                                   "%s,%s", rdn, search_test_ctx->base_dn);
1050         assert_non_null(full_dn);
1051
1052         return full_dn;
1053 }
1054
1055 static void search_test_add_data(struct search_test_ctx *search_test_ctx,
1056                                  const char *rdn,
1057                                  struct keyval *kvs)
1058 {
1059         char *full_dn;
1060
1061         full_dn = get_full_dn(search_test_ctx, search_test_ctx, rdn);
1062
1063         ldb_test_add_data(search_test_ctx,
1064                           search_test_ctx->ldb_test_ctx,
1065                           full_dn,
1066                           kvs);
1067 }
1068
1069 static void search_test_remove_data(struct search_test_ctx *search_test_ctx,
1070                                     const char *rdn)
1071 {
1072         char *full_dn;
1073
1074         full_dn = talloc_asprintf(search_test_ctx,
1075                                   "%s,%s", rdn, search_test_ctx->base_dn);
1076         assert_non_null(full_dn);
1077
1078         ldb_test_remove_data(search_test_ctx,
1079                              search_test_ctx->ldb_test_ctx,
1080                              full_dn);
1081 }
1082
1083 static int ldb_search_test_setup(void **state)
1084 {
1085         struct ldbtest_ctx *ldb_test_ctx;
1086         struct search_test_ctx *search_test_ctx;
1087         struct keyval kvs[] = {
1088                 { "cn", "test_search_cn" },
1089                 { "cn", "test_search_cn2" },
1090                 { "uid", "test_search_uid" },
1091                 { "uid", "test_search_uid2" },
1092                 { NULL, NULL },
1093         };
1094         struct keyval kvs2[] = {
1095                 { "cn", "test_search_2_cn" },
1096                 { "cn", "test_search_2_cn2" },
1097                 { "uid", "test_search_2_uid" },
1098                 { "uid", "test_search_2_uid2" },
1099                 { NULL, NULL },
1100         };
1101
1102         ldbtest_setup((void **) &ldb_test_ctx);
1103
1104         search_test_ctx = talloc(ldb_test_ctx, struct search_test_ctx);
1105         assert_non_null(search_test_ctx);
1106
1107         search_test_ctx->base_dn = "dc=search_test_entry";
1108         search_test_ctx->ldb_test_ctx = ldb_test_ctx;
1109
1110         search_test_remove_data(search_test_ctx, "cn=test_search_cn");
1111         search_test_add_data(search_test_ctx, "cn=test_search_cn", kvs);
1112
1113         search_test_remove_data(search_test_ctx, "cn=test_search_2_cn");
1114         search_test_add_data(search_test_ctx, "cn=test_search_2_cn", kvs2);
1115
1116         *state = search_test_ctx;
1117         return 0;
1118 }
1119
1120 static int ldb_search_test_teardown(void **state)
1121 {
1122         struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1123                         struct search_test_ctx);
1124         struct ldbtest_ctx *ldb_test_ctx;
1125
1126         ldb_test_ctx = search_test_ctx->ldb_test_ctx;
1127
1128         search_test_remove_data(search_test_ctx, "cn=test_search_cn");
1129         search_test_remove_data(search_test_ctx, "cn=test_search_2_cn");
1130         ldbtest_teardown((void **) &ldb_test_ctx);
1131         return 0;
1132 }
1133
1134 static void assert_attr_has_vals(struct ldb_message *msg,
1135                                  const char *attr,
1136                                  const char *vals[],
1137                                  const size_t nvals)
1138 {
1139         struct ldb_message_element *el;
1140         size_t i;
1141
1142         el = ldb_msg_find_element(msg, attr);
1143         assert_non_null(el);
1144
1145         assert_int_equal(el->num_values, nvals);
1146         for (i = 0; i < nvals; i++) {
1147                 assert_string_equal(el->values[i].data,
1148                                     vals[i]);
1149         }
1150 }
1151
1152 static void assert_has_no_attr(struct ldb_message *msg,
1153                                const char *attr)
1154 {
1155         struct ldb_message_element *el;
1156
1157         el = ldb_msg_find_element(msg, attr);
1158         assert_null(el);
1159 }
1160
1161 static bool has_dn(struct ldb_message *msg, const char *dn)
1162 {
1163         const char *msgdn;
1164
1165         msgdn = ldb_dn_get_linearized(msg->dn);
1166         if (strcmp(dn, msgdn) == 0) {
1167                 return true;
1168         }
1169
1170         return false;
1171 }
1172
1173 static void test_search_match_none(void **state)
1174 {
1175         struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1176                         struct search_test_ctx);
1177         size_t count;
1178
1179         count = base_search_count(search_test_ctx->ldb_test_ctx,
1180                                   "dc=no_such_entry");
1181         assert_int_equal(count, 0);
1182 }
1183
1184 static void test_search_match_one(void **state)
1185 {
1186         struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1187                         struct search_test_ctx);
1188         int ret;
1189         struct ldb_dn *basedn;
1190         struct ldb_result *result = NULL;
1191         const char *cn_vals[] = { "test_search_cn",
1192                                   "test_search_cn2" };
1193         const char *uid_vals[] = { "test_search_uid",
1194                                    "test_search_uid2" };
1195
1196         basedn = ldb_dn_new_fmt(search_test_ctx,
1197                                 search_test_ctx->ldb_test_ctx->ldb,
1198                                 "%s",
1199                                 search_test_ctx->base_dn);
1200         assert_non_null(basedn);
1201
1202         ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
1203                          search_test_ctx,
1204                          &result,
1205                          basedn,
1206                          LDB_SCOPE_SUBTREE, NULL,
1207                          "cn=test_search_cn");
1208         assert_int_equal(ret, 0);
1209         assert_non_null(result);
1210         assert_int_equal(result->count, 1);
1211
1212         assert_attr_has_vals(result->msgs[0], "cn", cn_vals, 2);
1213         assert_attr_has_vals(result->msgs[0], "uid", uid_vals, 2);
1214 }
1215
1216 static void test_search_match_filter(void **state)
1217 {
1218         struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1219                         struct search_test_ctx);
1220         int ret;
1221         struct ldb_dn *basedn;
1222         struct ldb_result *result = NULL;
1223         const char *cn_vals[] = { "test_search_cn",
1224                                   "test_search_cn2" };
1225         const char *attrs[] = { "cn", NULL };
1226
1227         basedn = ldb_dn_new_fmt(search_test_ctx,
1228                                 search_test_ctx->ldb_test_ctx->ldb,
1229                                 "%s",
1230                                 search_test_ctx->base_dn);
1231         assert_non_null(basedn);
1232
1233         ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
1234                          search_test_ctx,
1235                          &result,
1236                          basedn,
1237                          LDB_SCOPE_SUBTREE,
1238                          attrs,
1239                          "cn=test_search_cn");
1240         assert_int_equal(ret, 0);
1241         assert_non_null(result);
1242         assert_int_equal(result->count, 1);
1243
1244         assert_attr_has_vals(result->msgs[0], "cn", cn_vals, 2);
1245         assert_has_no_attr(result->msgs[0], "uid");
1246 }
1247
1248 static void assert_expected(struct search_test_ctx *search_test_ctx,
1249                             struct ldb_message *msg)
1250 {
1251         char *full_dn1;
1252         char *full_dn2;
1253         const char *cn_vals[] = { "test_search_cn",
1254                                   "test_search_cn2" };
1255         const char *uid_vals[] = { "test_search_uid",
1256                                    "test_search_uid2" };
1257         const char *cn2_vals[] = { "test_search_2_cn",
1258                                    "test_search_2_cn2" };
1259         const char *uid2_vals[] = { "test_search_2_uid",
1260                                     "test_search_2_uid2" };
1261
1262         full_dn1 = get_full_dn(search_test_ctx,
1263                                search_test_ctx,
1264                                "cn=test_search_cn");
1265
1266         full_dn2 = get_full_dn(search_test_ctx,
1267                                search_test_ctx,
1268                                "cn=test_search_2_cn");
1269
1270         if (has_dn(msg, full_dn1) == true) {
1271                 assert_attr_has_vals(msg, "cn", cn_vals, 2);
1272                 assert_attr_has_vals(msg, "uid", uid_vals, 2);
1273         } else if (has_dn(msg, full_dn2) == true) {
1274                 assert_attr_has_vals(msg, "cn", cn2_vals, 2);
1275                 assert_attr_has_vals(msg, "uid", uid2_vals, 2);
1276         } else {
1277                 fail();
1278         }
1279 }
1280
1281 static void test_search_match_both(void **state)
1282 {
1283         struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1284                         struct search_test_ctx);
1285         int ret;
1286         struct ldb_dn *basedn;
1287         struct ldb_result *result = NULL;
1288
1289         basedn = ldb_dn_new_fmt(search_test_ctx,
1290                                 search_test_ctx->ldb_test_ctx->ldb,
1291                                 "%s",
1292                                 search_test_ctx->base_dn);
1293         assert_non_null(basedn);
1294
1295         ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
1296                          search_test_ctx,
1297                          &result,
1298                          basedn,
1299                          LDB_SCOPE_SUBTREE, NULL,
1300                          "cn=test_search_*");
1301         assert_int_equal(ret, 0);
1302         assert_non_null(result);
1303         assert_int_equal(result->count, 2);
1304
1305         assert_expected(search_test_ctx, result->msgs[0]);
1306         assert_expected(search_test_ctx, result->msgs[1]);
1307 }
1308
1309 static void test_search_match_basedn(void **state)
1310 {
1311         struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1312                         struct search_test_ctx);
1313         int ret;
1314         struct ldb_dn *basedn;
1315         struct ldb_result *result = NULL;
1316         struct ldb_message *msg;
1317
1318         basedn = ldb_dn_new_fmt(search_test_ctx,
1319                                 search_test_ctx->ldb_test_ctx->ldb,
1320                                 "dc=nosuchdn");
1321         assert_non_null(basedn);
1322
1323         ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
1324                          search_test_ctx,
1325                          &result,
1326                          basedn,
1327                          LDB_SCOPE_SUBTREE, NULL,
1328                          "cn=*");
1329         assert_int_equal(ret, 0);
1330
1331         /* Add 'checkBaseOnSearch' to @OPTIONS */
1332         msg = ldb_msg_new(search_test_ctx);
1333         assert_non_null(msg);
1334
1335         msg->dn = ldb_dn_new_fmt(msg,
1336                                  search_test_ctx->ldb_test_ctx->ldb,
1337                                  "@OPTIONS");
1338         assert_non_null(msg->dn);
1339
1340         ret = ldb_msg_add_string(msg, "checkBaseOnSearch", "TRUE");
1341         assert_int_equal(ret, 0);
1342
1343         ret = ldb_add(search_test_ctx->ldb_test_ctx->ldb, msg);
1344         assert_int_equal(ret, 0);
1345
1346         /* Search again */
1347         /* The search should return LDB_ERR_NO_SUCH_OBJECT */
1348         ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
1349                          search_test_ctx,
1350                          &result,
1351                          basedn,
1352                          LDB_SCOPE_SUBTREE, NULL,
1353                          "cn=*");
1354         assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT);
1355
1356         ret = ldb_delete(search_test_ctx->ldb_test_ctx->ldb, msg->dn);
1357         assert_int_equal(ret, 0);
1358 }
1359
1360
1361 /*
1362  * This test is complex.
1363  * The purpose is to test for a deadlock detected between ldb_search()
1364  * and ldb_transaction_commit().  The deadlock happens if in process
1365  * (1) and (2):
1366  *  - (1) the all-record lock is taken in ltdb_search()
1367  *  - (2) the ldb_transaction_start() call is made
1368  *  - (1) an un-indexed search starts (forced here by doing it in
1369  *        the callback
1370  *  - (2) the ldb_transaction_commit() is called.
1371  *        This returns LDB_ERR_BUSY if the deadlock is detected
1372  *
1373  * With ldb 1.1.31 and tdb 1.3.12 we avoid this only due to a missing
1374  * lock call in ltdb_search() due to a refcounting bug in
1375  * ltdb_lock_read()
1376  */
1377
1378 struct search_against_transaction_ctx {
1379         struct ldbtest_ctx *test_ctx;
1380         int res_count;
1381         pid_t child_pid;
1382         struct ldb_dn *basedn;
1383 };
1384
1385 static int test_ldb_search_against_transaction_callback2(struct ldb_request *req,
1386                                                          struct ldb_reply *ares)
1387 {
1388         struct search_against_transaction_ctx *ctx = req->context;
1389         switch (ares->type) {
1390         case LDB_REPLY_ENTRY:
1391                 ctx->res_count++;
1392                 if (ctx->res_count != 1) {
1393                         return LDB_SUCCESS;
1394                 }
1395
1396                 break;
1397
1398         case LDB_REPLY_REFERRAL:
1399                 break;
1400
1401         case LDB_REPLY_DONE:
1402                 return ldb_request_done(req, LDB_SUCCESS);
1403         }
1404
1405         return 0;
1406
1407 }
1408
1409 /*
1410  * This purpose of this callback is to trigger a transaction in
1411  * the child process while the all-record lock is held, but before
1412  * we take any locks in the tdb_traverse_read() handler.
1413  *
1414  * In tdb 1.3.12 tdb_traverse_read() take the read transaction lock
1415  * however in ldb 1.1.31 ltdb_search() forgets to take the all-record
1416  * lock (except the very first time) due to a ref-counting bug.
1417  *
1418  */
1419
1420 static int test_ldb_search_against_transaction_callback1(struct ldb_request *req,
1421                                                          struct ldb_reply *ares)
1422 {
1423         int ret, ret2;
1424         int pipes[2];
1425         char buf[2];
1426         struct search_against_transaction_ctx *ctx = req->context;
1427         switch (ares->type) {
1428         case LDB_REPLY_ENTRY:
1429                 break;
1430
1431         case LDB_REPLY_REFERRAL:
1432                 return LDB_SUCCESS;
1433
1434         case LDB_REPLY_DONE:
1435                 return ldb_request_done(req, LDB_SUCCESS);
1436         }
1437
1438         ret = pipe(pipes);
1439         assert_int_equal(ret, 0);
1440
1441         ctx->child_pid = fork();
1442         if (ctx->child_pid == 0) {
1443                 TALLOC_CTX *tmp_ctx = NULL;
1444                 struct ldb_message *msg;
1445                 TALLOC_FREE(ctx->test_ctx->ldb);
1446                 TALLOC_FREE(ctx->test_ctx->ev);
1447                 ctx->test_ctx->ev = tevent_context_init(ctx->test_ctx);
1448                 if (ctx->test_ctx->ev == NULL) {
1449                         exit(LDB_ERR_OPERATIONS_ERROR);
1450                 }
1451
1452                 ctx->test_ctx->ldb = ldb_init(ctx->test_ctx,
1453                                               ctx->test_ctx->ev);
1454                 if (ctx->test_ctx->ldb == NULL) {
1455                         exit(LDB_ERR_OPERATIONS_ERROR);
1456                 }
1457
1458                 ret = ldb_connect(ctx->test_ctx->ldb,
1459                                   ctx->test_ctx->dbpath, 0, NULL);
1460                 if (ret != LDB_SUCCESS) {
1461                         exit(ret);
1462                 }
1463
1464                 tmp_ctx = talloc_new(ctx->test_ctx);
1465                 if (tmp_ctx == NULL) {
1466                         exit(LDB_ERR_OPERATIONS_ERROR);
1467                 }
1468
1469                 msg = ldb_msg_new(tmp_ctx);
1470                 if (msg == NULL) {
1471                         exit(LDB_ERR_OPERATIONS_ERROR);
1472                 }
1473
1474                 msg->dn = ldb_dn_new_fmt(msg, ctx->test_ctx->ldb,
1475                                          "dc=test");
1476                 if (msg->dn == NULL) {
1477                         exit(LDB_ERR_OPERATIONS_ERROR);
1478                 }
1479
1480                 ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
1481                 if (ret != 0) {
1482                         exit(LDB_ERR_OPERATIONS_ERROR);
1483                 }
1484
1485                 ret = ldb_transaction_start(ctx->test_ctx->ldb);
1486                 if (ret != 0) {
1487                         exit(ret);
1488                 }
1489
1490                 ret = write(pipes[1], "GO", 2);
1491                 if (ret != 2) {
1492                         exit(LDB_ERR_OPERATIONS_ERROR);
1493                 }
1494
1495                 ret = ldb_add(ctx->test_ctx->ldb, msg);
1496                 if (ret != 0) {
1497                         exit(ret);
1498                 }
1499
1500                 ret = ldb_transaction_commit(ctx->test_ctx->ldb);
1501                 exit(ret);
1502         }
1503
1504         ret = read(pipes[0], buf, 2);
1505         assert_int_equal(ret, 2);
1506
1507         /* This search must be unindexed (ie traverse in tdb) */
1508         ret = ldb_build_search_req(&req,
1509                                    ctx->test_ctx->ldb,
1510                                    ctx->test_ctx,
1511                                    ctx->basedn,
1512                                    LDB_SCOPE_SUBTREE,
1513                                    "cn=*", NULL,
1514                                    NULL,
1515                                    ctx,
1516                                    test_ldb_search_against_transaction_callback2,
1517                                    NULL);
1518         /*
1519          * we don't assert on these return codes until after the search is
1520          * finished, or the clean up will fail because we hold locks.
1521          */
1522
1523         ret2 = ldb_request(ctx->test_ctx->ldb, req);
1524
1525         if (ret2 == LDB_SUCCESS) {
1526                 ret2 = ldb_wait(req->handle, LDB_WAIT_ALL);
1527         }
1528         assert_int_equal(ret, 0);
1529         assert_int_equal(ret2, 0);
1530         assert_int_equal(ctx->res_count, 2);
1531
1532         return LDB_SUCCESS;
1533 }
1534
1535 static void test_ldb_search_against_transaction(void **state)
1536 {
1537         struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1538                         struct search_test_ctx);
1539         struct search_against_transaction_ctx
1540                 ctx =
1541                 { .res_count = 0,
1542                   .test_ctx = search_test_ctx->ldb_test_ctx
1543                 };
1544
1545         int ret;
1546         struct ldb_request *req;
1547         pid_t pid;
1548         int wstatus;
1549         struct ldb_dn *base_search_dn;
1550
1551         tevent_loop_allow_nesting(search_test_ctx->ldb_test_ctx->ev);
1552
1553         base_search_dn
1554                 = ldb_dn_new_fmt(search_test_ctx,
1555                                  search_test_ctx->ldb_test_ctx->ldb,
1556                                  "cn=test_search_cn,%s",
1557                                  search_test_ctx->base_dn);
1558         assert_non_null(base_search_dn);
1559
1560         ctx.basedn
1561                 = ldb_dn_new_fmt(search_test_ctx,
1562                                  search_test_ctx->ldb_test_ctx->ldb,
1563                                  "%s",
1564                                  search_test_ctx->base_dn);
1565         assert_non_null(ctx.basedn);
1566
1567
1568         /* This search must be indexed (ie no traverse in tdb) */
1569         ret = ldb_build_search_req(&req,
1570                                    search_test_ctx->ldb_test_ctx->ldb,
1571                                    search_test_ctx,
1572                                    base_search_dn,
1573                                    LDB_SCOPE_BASE,
1574                                    "cn=*", NULL,
1575                                    NULL,
1576                                    &ctx,
1577                                    test_ldb_search_against_transaction_callback1,
1578                                    NULL);
1579         assert_int_equal(ret, 0);
1580         ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req);
1581
1582         if (ret == LDB_SUCCESS) {
1583                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1584         }
1585         assert_int_equal(ret, 0);
1586         assert_int_equal(ctx.res_count, 2);
1587
1588         pid = waitpid(ctx.child_pid, &wstatus, 0);
1589         assert_int_equal(pid, ctx.child_pid);
1590
1591         assert_true(WIFEXITED(wstatus));
1592
1593         assert_int_equal(WEXITSTATUS(wstatus), 0);
1594
1595
1596 }
1597
1598 /*
1599  * This test is also complex.
1600  * The purpose is to test if a modify can occur during an ldb_search()
1601  * This would be a failure if if in process
1602  * (1) and (2):
1603  *  - (1) ltdb_search() starts and calls back for one entry
1604  *  - (2) one of the entries to be matched is modified
1605  *  - (1) the indexed search tries to return the modified entry, but
1606  *        it is no longer found, either:
1607  *          - despite it still matching (dn changed)
1608  *          - it no longer matching (attrs changed)
1609  *
1610  * We also try un-indexed to show that the behaviour differs on this
1611  * point, which it should not (an index should only impact search
1612  * speed).
1613  */
1614
1615 struct modify_during_search_test_ctx {
1616         struct ldbtest_ctx *test_ctx;
1617         int res_count;
1618         pid_t child_pid;
1619         struct ldb_dn *basedn;
1620         bool got_cn;
1621         bool got_2_cn;
1622         bool rename;
1623 };
1624
1625 /*
1626  * This purpose of this callback is to trigger a write in
1627  * the child process while a search is in progress.
1628  *
1629  * In tdb 1.3.12 tdb_traverse_read() take the read transaction lock
1630  * however in ldb 1.1.31 ltdb_search() forgets to take the all-record
1631  * lock (except the very first time) due to a ref-counting bug.
1632  *
1633  * We assume that if the write will proceed, it will proceed in a 3
1634  * second window after the function is called.
1635  */
1636
1637 static int test_ldb_modify_during_search_callback1(struct ldb_request *req,
1638                                                    struct ldb_reply *ares)
1639 {
1640         int ret;
1641         int pipes[2];
1642         char buf[2];
1643         struct modify_during_search_test_ctx *ctx = req->context;
1644         switch (ares->type) {
1645         case LDB_REPLY_ENTRY:
1646         {
1647                 const struct ldb_val *cn_val
1648                         = ldb_dn_get_component_val(ares->message->dn, 0);
1649                 const char *cn = (char *)cn_val->data;
1650                 ctx->res_count++;
1651                 if (strcmp(cn, "test_search_cn") == 0) {
1652                         ctx->got_cn = true;
1653                 } else if (strcmp(cn, "test_search_2_cn") == 0) {
1654                         ctx->got_2_cn = true;
1655                 }
1656                 if (ctx->res_count == 2) {
1657                         return LDB_SUCCESS;
1658                 }
1659                 break;
1660         }
1661         case LDB_REPLY_REFERRAL:
1662                 return LDB_SUCCESS;
1663
1664         case LDB_REPLY_DONE:
1665                 return ldb_request_done(req, LDB_SUCCESS);
1666         }
1667
1668         ret = pipe(pipes);
1669         assert_int_equal(ret, 0);
1670
1671         ctx->child_pid = fork();
1672         if (ctx->child_pid == 0 && ctx->rename) {
1673                 TALLOC_CTX *tmp_ctx = NULL;
1674                 struct ldb_dn *dn, *new_dn;
1675                 TALLOC_FREE(ctx->test_ctx->ldb);
1676                 TALLOC_FREE(ctx->test_ctx->ev);
1677                 ctx->test_ctx->ev = tevent_context_init(ctx->test_ctx);
1678                 if (ctx->test_ctx->ev == NULL) {
1679                         exit(LDB_ERR_OPERATIONS_ERROR);
1680                 }
1681
1682                 ctx->test_ctx->ldb = ldb_init(ctx->test_ctx,
1683                                               ctx->test_ctx->ev);
1684                 if (ctx->test_ctx->ldb == NULL) {
1685                         exit(LDB_ERR_OPERATIONS_ERROR);
1686                 }
1687
1688                 ret = ldb_connect(ctx->test_ctx->ldb,
1689                                   ctx->test_ctx->dbpath, 0, NULL);
1690                 if (ret != LDB_SUCCESS) {
1691                         exit(ret);
1692                 }
1693
1694                 tmp_ctx = talloc_new(ctx->test_ctx);
1695                 if (tmp_ctx == NULL) {
1696                         exit(LDB_ERR_OPERATIONS_ERROR);
1697                 }
1698
1699                 if (ctx->got_cn) {
1700                         /* Modify the other one */
1701                         dn = ldb_dn_new_fmt(tmp_ctx, ctx->test_ctx->ldb,
1702                                             "cn=test_search_2_cn,"
1703                                             "dc=search_test_entry");
1704                 } else {
1705                         dn = ldb_dn_new_fmt(tmp_ctx, ctx->test_ctx->ldb,
1706                                             "cn=test_search_cn,"
1707                                             "dc=search_test_entry");
1708                 }
1709                 if (dn == NULL) {
1710                         exit(LDB_ERR_OPERATIONS_ERROR);
1711                 }
1712
1713                 new_dn = ldb_dn_new_fmt(tmp_ctx, ctx->test_ctx->ldb,
1714                                         "cn=test_search_cn_renamed,"
1715                                         "dc=search_test_entry");
1716                 if (new_dn == NULL) {
1717                         exit(LDB_ERR_OPERATIONS_ERROR);
1718                 }
1719
1720                 ret = ldb_transaction_start(ctx->test_ctx->ldb);
1721                 if (ret != 0) {
1722                         exit(ret);
1723                 }
1724
1725                 if (write(pipes[1], "GO", 2) != 2) {
1726                         exit(LDB_ERR_OPERATIONS_ERROR);
1727                 }
1728
1729                 ret = ldb_rename(ctx->test_ctx->ldb, dn, new_dn);
1730                 if (ret != 0) {
1731                         exit(ret);
1732                 }
1733
1734                 ret = ldb_transaction_commit(ctx->test_ctx->ldb);
1735                 exit(ret);
1736
1737         } else if (ctx->child_pid == 0) {
1738                 TALLOC_CTX *tmp_ctx = NULL;
1739                 struct ldb_message *msg;
1740                 struct ldb_message_element *el;
1741                 TALLOC_FREE(ctx->test_ctx->ldb);
1742                 TALLOC_FREE(ctx->test_ctx->ev);
1743                 ctx->test_ctx->ev = tevent_context_init(ctx->test_ctx);
1744                 if (ctx->test_ctx->ev == NULL) {
1745                         exit(LDB_ERR_OPERATIONS_ERROR);
1746                 }
1747
1748                 ctx->test_ctx->ldb = ldb_init(ctx->test_ctx,
1749                                               ctx->test_ctx->ev);
1750                 if (ctx->test_ctx->ldb == NULL) {
1751                         exit(LDB_ERR_OPERATIONS_ERROR);
1752                 }
1753
1754                 ret = ldb_connect(ctx->test_ctx->ldb,
1755                                   ctx->test_ctx->dbpath, 0, NULL);
1756                 if (ret != LDB_SUCCESS) {
1757                         exit(ret);
1758                 }
1759
1760                 tmp_ctx = talloc_new(ctx->test_ctx);
1761                 if (tmp_ctx == NULL) {
1762                         exit(LDB_ERR_OPERATIONS_ERROR);
1763                 }
1764
1765                 msg = ldb_msg_new(tmp_ctx);
1766                 if (msg == NULL) {
1767                         exit(LDB_ERR_OPERATIONS_ERROR);
1768                 }
1769
1770                 if (ctx->got_cn) {
1771                         /* Modify the other one */
1772                         msg->dn = ldb_dn_new_fmt(msg, ctx->test_ctx->ldb,
1773                                                  "cn=test_search_2_cn,"
1774                                                  "dc=search_test_entry");
1775                 } else {
1776                         msg->dn = ldb_dn_new_fmt(msg, ctx->test_ctx->ldb,
1777                                                  "cn=test_search_cn,"
1778                                                  "dc=search_test_entry");
1779                 }
1780                 if (msg->dn == NULL) {
1781                         exit(LDB_ERR_OPERATIONS_ERROR);
1782                 }
1783
1784                 ret = ldb_msg_add_string(msg, "filterAttr", "TRUE");
1785                 if (ret != 0) {
1786                         exit(LDB_ERR_OPERATIONS_ERROR);
1787                 }
1788                 el = ldb_msg_find_element(msg, "filterAttr");
1789                 if (el == NULL) {
1790                         exit(LDB_ERR_OPERATIONS_ERROR);
1791                 }
1792                 el->flags = LDB_FLAG_MOD_REPLACE;
1793
1794                 ret = ldb_transaction_start(ctx->test_ctx->ldb);
1795                 if (ret != 0) {
1796                         exit(ret);
1797                 }
1798
1799                 if (write(pipes[1], "GO", 2) != 2) {
1800                         exit(LDB_ERR_OPERATIONS_ERROR);
1801                 }
1802
1803                 ret = ldb_modify(ctx->test_ctx->ldb, msg);
1804                 if (ret != 0) {
1805                         exit(ret);
1806                 }
1807
1808                 ret = ldb_transaction_commit(ctx->test_ctx->ldb);
1809                 exit(ret);
1810         }
1811
1812         /*
1813          * With TDB 1.3.13 and before "tdb: Remove locking from tdb_traverse_read()"
1814          * we will hang here because the child process can not proceed to
1815          * sending the "GO" as it is blocked at ldb_transaction_start().
1816          */
1817
1818         ret = read(pipes[0], buf, 2);
1819         assert_int_equal(ret, 2);
1820
1821         sleep(3);
1822
1823         return LDB_SUCCESS;
1824 }
1825
1826 static void test_ldb_modify_during_search(void **state, bool add_index,
1827                                           bool rename)
1828 {
1829         struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1830                         struct search_test_ctx);
1831         struct modify_during_search_test_ctx
1832                 ctx =
1833                 { .res_count = 0,
1834                   .test_ctx = search_test_ctx->ldb_test_ctx,
1835                   .rename = rename
1836                 };
1837
1838         int ret;
1839         struct ldb_request *req;
1840         pid_t pid;
1841         int wstatus;
1842
1843         if (add_index) {
1844                 struct ldb_message *msg;
1845                 struct ldb_dn *indexlist = ldb_dn_new(search_test_ctx,
1846                                                       search_test_ctx->ldb_test_ctx->ldb,
1847                                                       "@INDEXLIST");
1848                 assert_non_null(indexlist);
1849
1850                 msg = ldb_msg_new(search_test_ctx);
1851                 assert_non_null(msg);
1852
1853                 msg->dn = indexlist;
1854
1855                 ret = ldb_msg_add_string(msg, "@IDXATTR", "cn");
1856                 assert_int_equal(ret, LDB_SUCCESS);
1857
1858                 ret = ldb_add(search_test_ctx->ldb_test_ctx->ldb,
1859                               msg);
1860
1861                 assert_int_equal(ret, LDB_SUCCESS);
1862         }
1863
1864         tevent_loop_allow_nesting(search_test_ctx->ldb_test_ctx->ev);
1865
1866         ctx.basedn
1867                 = ldb_dn_new_fmt(search_test_ctx,
1868                                  search_test_ctx->ldb_test_ctx->ldb,
1869                                  "%s",
1870                                  search_test_ctx->base_dn);
1871         assert_non_null(ctx.basedn);
1872
1873
1874         /*
1875          * This search must be over multiple items, and should include
1876          * the new name after a rename, to show that it would match
1877          * both before and after that modify
1878          */
1879         ret = ldb_build_search_req(&req,
1880                                    search_test_ctx->ldb_test_ctx->ldb,
1881                                    search_test_ctx,
1882                                    ctx.basedn,
1883                                    LDB_SCOPE_SUBTREE,
1884                                    "(&(!(filterAttr=*))"
1885                                      "(|(cn=test_search_cn_renamed)"
1886                                        "(cn=test_search_cn)"
1887                                        "(cn=test_search_2_cn)"
1888                                    "))",
1889                                    NULL,
1890                                    NULL,
1891                                    &ctx,
1892                                    test_ldb_modify_during_search_callback1,
1893                                    NULL);
1894         assert_int_equal(ret, 0);
1895         ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req);
1896
1897         if (ret == LDB_SUCCESS) {
1898                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1899         }
1900         assert_int_equal(ret, 0);
1901         assert_int_equal(ctx.res_count, 2);
1902         assert_int_equal(ctx.got_cn, true);
1903         assert_int_equal(ctx.got_2_cn, true);
1904
1905         pid = waitpid(ctx.child_pid, &wstatus, 0);
1906         assert_int_equal(pid, ctx.child_pid);
1907
1908         assert_true(WIFEXITED(wstatus));
1909
1910         assert_int_equal(WEXITSTATUS(wstatus), 0);
1911
1912
1913 }
1914
1915 static void test_ldb_modify_during_indexed_search(void **state)
1916 {
1917         return test_ldb_modify_during_search(state, true, false);
1918 }
1919
1920 static void test_ldb_modify_during_unindexed_search(void **state)
1921 {
1922         return test_ldb_modify_during_search(state, false, false);
1923 }
1924
1925 static void test_ldb_rename_during_indexed_search(void **state)
1926 {
1927         return test_ldb_modify_during_search(state, true, true);
1928 }
1929
1930 static void test_ldb_rename_during_unindexed_search(void **state)
1931 {
1932         return test_ldb_modify_during_search(state, false, true);
1933 }
1934
1935 /*
1936  * This test is also complex.
1937  *
1938  * The purpose is to test if a modify can occur during an ldb_search()
1939  * before the end of the callback
1940  *
1941  * This would be a failure if if in process
1942  * (1) and (2):
1943  *  - (1) ldb_search() starts and calls back for a number of entries
1944  *  - (2) an entry in the DB is allowed to change before the callback returns
1945  *  - (1) the callback can see the modification
1946  *
1947  */
1948
1949 /*
1950  * This purpose of this callback is to trigger a write in
1951  * the child process while a search DONE callback is in progress.
1952  *
1953  * In ldb 1.1.31 ldb_search() omitted to take a all-record
1954  * lock for the full duration of the search and callbacks
1955  *
1956  * We assume that if the write will proceed, it will proceed in a 3
1957  * second window after the function is called.
1958  */
1959
1960 static int test_ldb_modify_during_whole_search_callback1(struct ldb_request *req,
1961                                                          struct ldb_reply *ares)
1962 {
1963         int ret;
1964         int pipes[2];
1965         char buf[2];
1966         struct modify_during_search_test_ctx *ctx = req->context;
1967         struct ldb_dn *search_dn;
1968         struct ldb_result *res2;
1969         unsigned res_count;
1970         switch (ares->type) {
1971         case LDB_REPLY_ENTRY:
1972         case LDB_REPLY_REFERRAL:
1973                 return LDB_SUCCESS;
1974
1975         case LDB_REPLY_DONE:
1976                 break;
1977         }
1978
1979         ret = pipe(pipes);
1980         assert_int_equal(ret, 0);
1981
1982         ctx->child_pid = fork();
1983         if (ctx->child_pid == 0) {
1984                 TALLOC_CTX *tmp_ctx = NULL;
1985                 struct ldb_message *msg;
1986                 struct ldb_message_element *el;
1987                 TALLOC_FREE(ctx->test_ctx->ldb);
1988                 TALLOC_FREE(ctx->test_ctx->ev);
1989                 ctx->test_ctx->ev = tevent_context_init(ctx->test_ctx);
1990                 if (ctx->test_ctx->ev == NULL) {
1991                         exit(LDB_ERR_OPERATIONS_ERROR);
1992                 }
1993
1994                 ctx->test_ctx->ldb = ldb_init(ctx->test_ctx,
1995                                               ctx->test_ctx->ev);
1996                 if (ctx->test_ctx->ldb == NULL) {
1997                         exit(LDB_ERR_OPERATIONS_ERROR);
1998                 }
1999
2000                 ret = ldb_connect(ctx->test_ctx->ldb,
2001                                   ctx->test_ctx->dbpath, 0, NULL);
2002                 if (ret != LDB_SUCCESS) {
2003                         exit(ret);
2004                 }
2005
2006                 tmp_ctx = talloc_new(ctx->test_ctx);
2007                 if (tmp_ctx == NULL) {
2008                         exit(LDB_ERR_OPERATIONS_ERROR);
2009                 }
2010
2011                 msg = ldb_msg_new(tmp_ctx);
2012                 if (msg == NULL) {
2013                         exit(LDB_ERR_OPERATIONS_ERROR);
2014                 }
2015
2016                 msg->dn = ldb_dn_new_fmt(msg, ctx->test_ctx->ldb,
2017                                          "cn=test_search_cn,"
2018                                          "dc=search_test_entry");
2019                 if (msg->dn == NULL) {
2020                         exit(LDB_ERR_OPERATIONS_ERROR);
2021                 }
2022
2023                 ret = ldb_msg_add_string(msg, "filterAttr", "TRUE");
2024                 if (ret != 0) {
2025                         exit(LDB_ERR_OPERATIONS_ERROR);
2026                 }
2027                 el = ldb_msg_find_element(msg, "filterAttr");
2028                 if (el == NULL) {
2029                         exit(LDB_ERR_OPERATIONS_ERROR);
2030                 }
2031                 el->flags = LDB_FLAG_MOD_REPLACE;
2032
2033                 ret = ldb_transaction_start(ctx->test_ctx->ldb);
2034                 if (ret != 0) {
2035                         exit(ret);
2036                 }
2037
2038                 if (write(pipes[1], "GO", 2) != 2) {
2039                         exit(LDB_ERR_OPERATIONS_ERROR);
2040                 }
2041
2042                 ret = ldb_modify(ctx->test_ctx->ldb, msg);
2043                 if (ret != 0) {
2044                         exit(ret);
2045                 }
2046
2047                 ret = ldb_transaction_commit(ctx->test_ctx->ldb);
2048                 exit(ret);
2049         }
2050
2051         ret = read(pipes[0], buf, 2);
2052         assert_int_equal(ret, 2);
2053
2054         sleep(3);
2055
2056         /*
2057          * If writes are not blocked until after this function, we
2058          * will be able to successfully search for this modification
2059          * here
2060          */
2061
2062         search_dn = ldb_dn_new_fmt(ares, ctx->test_ctx->ldb,
2063                                    "cn=test_search_cn,"
2064                                    "dc=search_test_entry");
2065
2066         ret = ldb_search(ctx->test_ctx->ldb, ares,
2067                          &res2, search_dn, LDB_SCOPE_BASE, NULL,
2068                          "filterAttr=TRUE");
2069
2070         /*
2071          * We do this in an unusual order, because if we fail an assert before
2072          * ldb_request_done(), we will also fail to clean up as we hold locks.
2073          */
2074
2075         res_count = res2->count;
2076         ldb_request_done(req, LDB_SUCCESS);
2077         assert_int_equal(ret, 0);
2078
2079         /* We should not have got the result */
2080         assert_int_equal(res_count, 0);
2081
2082         return ret;
2083 }
2084
2085 static void test_ldb_modify_during_whole_search(void **state)
2086 {
2087         struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
2088                         struct search_test_ctx);
2089         struct modify_during_search_test_ctx
2090                 ctx =
2091                 {
2092                   .test_ctx = search_test_ctx->ldb_test_ctx,
2093                 };
2094
2095         int ret;
2096         struct ldb_request *req;
2097         pid_t pid;
2098         int wstatus;
2099         struct ldb_dn *search_dn;
2100         struct ldb_result *res2;
2101
2102         tevent_loop_allow_nesting(search_test_ctx->ldb_test_ctx->ev);
2103
2104         ctx.basedn
2105                 = ldb_dn_new_fmt(search_test_ctx,
2106                                  search_test_ctx->ldb_test_ctx->ldb,
2107                                  "%s",
2108                                  search_test_ctx->base_dn);
2109         assert_non_null(ctx.basedn);
2110
2111
2112         /*
2113          * The search just needs to call DONE, we don't care about the
2114          * contents of the search for this test
2115          */
2116         ret = ldb_build_search_req(&req,
2117                                    search_test_ctx->ldb_test_ctx->ldb,
2118                                    search_test_ctx,
2119                                    ctx.basedn,
2120                                    LDB_SCOPE_SUBTREE,
2121                                    "(&(!(filterAttr=*))"
2122                                    "(cn=test_search_cn))",
2123                                    NULL,
2124                                    NULL,
2125                                    &ctx,
2126                                    test_ldb_modify_during_whole_search_callback1,
2127                                    NULL);
2128         assert_int_equal(ret, 0);
2129         ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req);
2130
2131         if (ret == LDB_SUCCESS) {
2132                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
2133         }
2134         assert_int_equal(ret, 0);
2135
2136         pid = waitpid(ctx.child_pid, &wstatus, 0);
2137         assert_int_equal(pid, ctx.child_pid);
2138
2139         assert_true(WIFEXITED(wstatus));
2140
2141         assert_int_equal(WEXITSTATUS(wstatus), 0);
2142
2143         /*
2144          * If writes are blocked until after the search function, we
2145          * will be able to successfully search for this modification
2146          * now
2147          */
2148
2149         search_dn = ldb_dn_new_fmt(search_test_ctx,
2150                                    search_test_ctx->ldb_test_ctx->ldb,
2151                                    "cn=test_search_cn,"
2152                                    "dc=search_test_entry");
2153
2154         ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
2155                          search_test_ctx,
2156                          &res2, search_dn, LDB_SCOPE_BASE, NULL,
2157                          "filterAttr=TRUE");
2158         assert_int_equal(ret, 0);
2159
2160         /* We got the result */
2161         assert_int_equal(res2->count, 1);
2162 }
2163
2164 /*
2165  * This test is also complex.
2166  *
2167  * The purpose is to test if a modify can occur during an ldb_search()
2168  * before the request is destroyed with TALLOC_FREE()
2169  *
2170  * This would be a failure if in process
2171  * (1) and (2):
2172  *  - (1) ldb_search() starts and waits
2173  *  - (2) an entry in the DB is allowed to change before the ldb_wait() is called
2174  *  - (1) the original process can see the modification before the TALLOC_FREE()
2175  * also we check that
2176  *  - (1) the original process can see the modification after the TALLOC_FREE()
2177  *
2178  */
2179
2180 /*
2181  * This purpose of this callback is to trigger a write in
2182  * the child process before the ldb_wait() is called
2183  *
2184  * In ldb 1.1.31 ldb_search() omitted to take a all-record
2185  * lock for the full duration of the search and callbacks
2186  *
2187  * We assume that if the write will proceed, it will proceed in a 3
2188  * second window after the function is called.
2189  */
2190
2191 static int test_ldb_modify_before_ldb_wait_callback1(struct ldb_request *req,
2192                                                      struct ldb_reply *ares)
2193 {
2194         switch (ares->type) {
2195         case LDB_REPLY_ENTRY:
2196         case LDB_REPLY_REFERRAL:
2197                 return LDB_SUCCESS;
2198
2199         case LDB_REPLY_DONE:
2200                 break;
2201         }
2202
2203         return ldb_request_done(req, LDB_SUCCESS);
2204 }
2205
2206 static void test_ldb_modify_before_ldb_wait(void **state)
2207 {
2208         struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
2209                         struct search_test_ctx);
2210         int ret;
2211         struct ldb_request *req;
2212         pid_t pid;
2213         int wstatus;
2214         struct ldb_dn *search_dn;
2215         struct ldb_dn *basedn;
2216         struct ldb_result *res2;
2217         int pipes[2];
2218         char buf[2];
2219         pid_t child_pid;
2220         unsigned res_count;
2221
2222         search_dn = ldb_dn_new_fmt(search_test_ctx,
2223                                    search_test_ctx->ldb_test_ctx->ldb,
2224                                    "cn=test_search_cn,"
2225                                    "dc=search_test_entry");
2226         assert_non_null(search_dn);
2227
2228         basedn = ldb_dn_new_fmt(search_test_ctx,
2229                                 search_test_ctx->ldb_test_ctx->ldb,
2230                                 "%s",
2231                                 search_test_ctx->base_dn);
2232         assert_non_null(basedn);
2233
2234         /*
2235          * The search just needs to call DONE, we don't care about the
2236          * contents of the search for this test
2237          */
2238         ret = ldb_build_search_req(&req,
2239                                    search_test_ctx->ldb_test_ctx->ldb,
2240                                    search_test_ctx,
2241                                    basedn,
2242                                    LDB_SCOPE_SUBTREE,
2243                                    "(&(!(filterAttr=*))"
2244                                    "(cn=test_search_cn))",
2245                                    NULL,
2246                                    NULL,
2247                                    NULL,
2248                                    test_ldb_modify_before_ldb_wait_callback1,
2249                                    NULL);
2250         assert_int_equal(ret, 0);
2251         ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req);
2252
2253         ret = pipe(pipes);
2254         assert_int_equal(ret, 0);
2255
2256         child_pid = fork();
2257         if (child_pid == 0) {
2258                 TALLOC_CTX *tmp_ctx = NULL;
2259                 struct ldb_message *msg;
2260                 struct ldb_message_element *el;
2261                 TALLOC_FREE(search_test_ctx->ldb_test_ctx->ldb);
2262                 TALLOC_FREE(search_test_ctx->ldb_test_ctx->ev);
2263                 search_test_ctx->ldb_test_ctx->ev = tevent_context_init(search_test_ctx->ldb_test_ctx);
2264                 if (search_test_ctx->ldb_test_ctx->ev == NULL) {
2265                         exit(LDB_ERR_OPERATIONS_ERROR);
2266                 }
2267
2268                 search_test_ctx->ldb_test_ctx->ldb = ldb_init(search_test_ctx->ldb_test_ctx,
2269                                              search_test_ctx->ldb_test_ctx->ev);
2270                 if (search_test_ctx->ldb_test_ctx->ldb == NULL) {
2271                         exit(LDB_ERR_OPERATIONS_ERROR);
2272                 }
2273
2274                 ret = ldb_connect(search_test_ctx->ldb_test_ctx->ldb,
2275                                   search_test_ctx->ldb_test_ctx->dbpath, 0, NULL);
2276                 if (ret != LDB_SUCCESS) {
2277                         exit(ret);
2278                 }
2279
2280                 tmp_ctx = talloc_new(search_test_ctx->ldb_test_ctx);
2281                 if (tmp_ctx == NULL) {
2282                         exit(LDB_ERR_OPERATIONS_ERROR);
2283                 }
2284
2285                 msg = ldb_msg_new(tmp_ctx);
2286                 if (msg == NULL) {
2287                         exit(LDB_ERR_OPERATIONS_ERROR);
2288                 }
2289
2290                 /*
2291                  * We must re-create this DN from a string to ensure
2292                  * it does not reference the now-gone LDB context of
2293                  * the parent
2294                  */
2295                 msg->dn = ldb_dn_new_fmt(search_test_ctx,
2296                                          search_test_ctx->ldb_test_ctx->ldb,
2297                                          "cn=test_search_cn,"
2298                                          "dc=search_test_entry");
2299
2300                 if (msg->dn == NULL) {
2301                         exit(LDB_ERR_OPERATIONS_ERROR);
2302                 }
2303
2304                 ret = ldb_msg_add_string(msg, "filterAttr", "TRUE");
2305                 if (ret != 0) {
2306                         exit(LDB_ERR_OPERATIONS_ERROR);
2307                 }
2308                 el = ldb_msg_find_element(msg, "filterAttr");
2309                 if (el == NULL) {
2310                         exit(LDB_ERR_OPERATIONS_ERROR);
2311                 }
2312                 el->flags = LDB_FLAG_MOD_REPLACE;
2313
2314                 ret = ldb_transaction_start(search_test_ctx->ldb_test_ctx->ldb);
2315                 if (ret != 0) {
2316                         exit(ret);
2317                 }
2318
2319                 if (write(pipes[1], "GO", 2) != 2) {
2320                         exit(LDB_ERR_OPERATIONS_ERROR);
2321                 }
2322
2323                 ret = ldb_modify(search_test_ctx->ldb_test_ctx->ldb, msg);
2324                 if (ret != 0) {
2325                         exit(ret);
2326                 }
2327
2328                 ret = ldb_transaction_commit(search_test_ctx->ldb_test_ctx->ldb);
2329                 exit(ret);
2330         }
2331
2332         ret = read(pipes[0], buf, 2);
2333         assert_int_equal(ret, 2);
2334
2335         sleep(3);
2336
2337         /*
2338          * If writes are not blocked until after the (never called) ldb_wait(), we
2339          * will be able to successfully search for this modification
2340          * here
2341          */
2342
2343         ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb, search_test_ctx,
2344                          &res2, search_dn, LDB_SCOPE_BASE, NULL,
2345                          "filterAttr=TRUE");
2346
2347         /*
2348          * We avoid making assertions before TALLOC_FREE()ing the request,
2349          * lest the assert fail and mess with the clean-up because we still
2350          * have locks.
2351          */
2352         res_count = res2->count;
2353         TALLOC_FREE(req);
2354
2355         /* We should not have got the result */
2356         assert_int_equal(res_count, 0);
2357         assert_int_equal(ret, 0);
2358
2359         pid = waitpid(child_pid, &wstatus, 0);
2360         assert_int_equal(pid, child_pid);
2361
2362         assert_true(WIFEXITED(wstatus));
2363
2364         assert_int_equal(WEXITSTATUS(wstatus), 0);
2365
2366         /*
2367          * If writes are blocked until after the search request was freed, we
2368          * will be able to successfully search for this modification
2369          * now
2370          */
2371
2372         search_dn = ldb_dn_new_fmt(search_test_ctx,
2373                                    search_test_ctx->ldb_test_ctx->ldb,
2374                                    "cn=test_search_cn,"
2375                                    "dc=search_test_entry");
2376
2377         ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
2378                          search_test_ctx,
2379                          &res2, search_dn, LDB_SCOPE_BASE, NULL,
2380                          "filterAttr=TRUE");
2381         assert_int_equal(ret, 0);
2382
2383         /* We got the result */
2384         assert_int_equal(res2->count, 1);
2385 }
2386
2387 static int ldb_case_test_setup(void **state)
2388 {
2389         int ret;
2390         struct ldb_ldif *ldif;
2391         struct ldbtest_ctx *ldb_test_ctx;
2392         const char *attrs_ldif =  \
2393                 "dn: @ATTRIBUTES\n"
2394                 "cn: CASE_INSENSITIVE\n"
2395                 "\n";
2396         struct keyval kvs[] = {
2397                 { "cn", "CaseInsensitiveValue" },
2398                 { "uid", "CaseSensitiveValue" },
2399                 { NULL, NULL },
2400         };
2401
2402
2403         ldbtest_setup((void **) &ldb_test_ctx);
2404
2405         while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &attrs_ldif))) {
2406                 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
2407                 assert_int_equal(ret, LDB_SUCCESS);
2408         }
2409
2410         ldb_test_add_data(ldb_test_ctx,
2411                           ldb_test_ctx,
2412                           "cn=CaseInsensitiveValue",
2413                           kvs);
2414
2415         *state = ldb_test_ctx;
2416         return 0;
2417 }
2418
2419 static int ldb_case_test_teardown(void **state)
2420 {
2421         int ret;
2422         struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
2423                         struct ldbtest_ctx);
2424
2425         struct ldb_dn *del_dn;
2426
2427         del_dn = ldb_dn_new_fmt(ldb_test_ctx,
2428                                 ldb_test_ctx->ldb,
2429                                 "@ATTRIBUTES");
2430         assert_non_null(del_dn);
2431
2432         ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
2433         assert_int_equal(ret, LDB_SUCCESS);
2434
2435         assert_dn_doesnt_exist(ldb_test_ctx,
2436                                "@ATTRIBUTES");
2437
2438         ldb_test_remove_data(ldb_test_ctx, ldb_test_ctx,
2439                              "cn=CaseInsensitiveValue");
2440
2441         ldbtest_teardown((void **) &ldb_test_ctx);
2442         return 0;
2443 }
2444
2445 static void test_ldb_attrs_case_insensitive(void **state)
2446 {
2447         int cnt;
2448         struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
2449                         struct ldbtest_ctx);
2450
2451         /* cn matches exact case */
2452         cnt = sub_search_count(ldb_test_ctx, "", "cn=CaseInsensitiveValue");
2453         assert_int_equal(cnt, 1);
2454
2455         /* cn matches lower case */
2456         cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2457         assert_int_equal(cnt, 1);
2458
2459         /* uid matches exact case */
2460         cnt = sub_search_count(ldb_test_ctx, "", "uid=CaseSensitiveValue");
2461         assert_int_equal(cnt, 1);
2462
2463         /* uid does not match lower case */
2464         cnt = sub_search_count(ldb_test_ctx, "", "uid=casesensitivevalue");
2465         assert_int_equal(cnt, 0);
2466 }
2467
2468 static struct ldb_schema_attribute cn_attr_1;
2469 static struct ldb_schema_attribute cn_attr_2;
2470 static struct ldb_schema_attribute default_attr;
2471
2472 /*
2473   override the name to attribute handler function
2474  */
2475 static const struct ldb_schema_attribute *ldb_test_attribute_handler_override(struct ldb_context *ldb,
2476                                                                               void *private_data,
2477                                                                               const char *name)
2478 {
2479         if (private_data != NULL && ldb_attr_cmp(name, "cn") == 0) {
2480                 return &cn_attr_1;
2481         } else if (private_data == NULL && ldb_attr_cmp(name, "cn") == 0) {
2482                 return &cn_attr_2;
2483         } else if (ldb_attr_cmp(name, "uid") == 0) {
2484                 return &cn_attr_2;
2485         }
2486         return &default_attr;
2487 }
2488
2489 static void test_ldb_attrs_case_handler(void **state)
2490 {
2491         int cnt;
2492         int ret;
2493         const struct ldb_schema_syntax *syntax;
2494
2495         struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
2496                         struct ldbtest_ctx);
2497         struct ldb_context *ldb = ldb_test_ctx->ldb;
2498
2499         /* cn matches lower case */
2500         cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2501         assert_int_equal(cnt, 1);
2502
2503         syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_OCTET_STRING);
2504         assert_non_null(syntax);
2505
2506         ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb,
2507                                                     "*", 0,
2508                                                     syntax, &default_attr);
2509         assert_int_equal(ret, LDB_SUCCESS);
2510
2511         syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_OCTET_STRING);
2512         assert_non_null(syntax);
2513
2514         ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb,
2515                                                     "cn", 0,
2516                                                     syntax, &cn_attr_1);
2517         assert_int_equal(ret, LDB_SUCCESS);
2518
2519         /*
2520          * Set an attribute handler, which will fail to match as we
2521          * force case sensitive
2522          */
2523         ldb_schema_attribute_set_override_handler(ldb,
2524                                                   ldb_test_attribute_handler_override,
2525                                                   (void *)1);
2526
2527         /* cn does not matche lower case */
2528         cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2529         assert_int_equal(cnt, 0);
2530
2531         syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_DIRECTORY_STRING);
2532         assert_non_null(syntax);
2533
2534         ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb,
2535                                                     "cn", 0,
2536                                                     syntax, &cn_attr_2);
2537         assert_int_equal(ret, LDB_SUCCESS);
2538
2539         /*
2540          * Set an attribute handler, which will match as we
2541          * force case insensitive
2542          */
2543         ldb_schema_attribute_set_override_handler(ldb,
2544                                                   ldb_test_attribute_handler_override,
2545                                                   NULL);
2546
2547         /* cn matches lower case */
2548         cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2549         assert_int_equal(cnt, 1);
2550
2551 }
2552
2553
2554 static void test_ldb_attrs_index_handler(void **state)
2555 {
2556         int cnt;
2557         int ret;
2558         const struct ldb_schema_syntax *syntax;
2559         struct ldb_ldif *ldif;
2560
2561         const char *index_ldif =  \
2562                 "dn: @INDEXLIST\n"
2563                 "@IDXATTR: cn\n"
2564                 "\n";
2565
2566         struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
2567                         struct ldbtest_ctx);
2568         struct ldb_context *ldb = ldb_test_ctx->ldb;
2569
2570         /* cn matches lower case */
2571         cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2572         assert_int_equal(cnt, 1);
2573
2574         syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_OCTET_STRING);
2575         assert_non_null(syntax);
2576
2577         ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb,
2578                                                     "cn", 0,
2579                                                     syntax, &cn_attr_1);
2580         assert_int_equal(ret, LDB_SUCCESS);
2581
2582         syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_DIRECTORY_STRING);
2583         assert_non_null(syntax);
2584
2585         ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb,
2586                                                     "cn", LDB_ATTR_FLAG_INDEXED,
2587                                                     syntax, &cn_attr_2);
2588         assert_int_equal(ret, LDB_SUCCESS);
2589
2590         syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_OCTET_STRING);
2591         assert_non_null(syntax);
2592
2593         ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb,
2594                                                     "", 0,
2595                                                     syntax, &default_attr);
2596         assert_int_equal(ret, LDB_SUCCESS);
2597
2598         /*
2599          * Set an attribute handler
2600          */
2601         ldb_schema_attribute_set_override_handler(ldb,
2602                                                   ldb_test_attribute_handler_override,
2603                                                   NULL);
2604
2605         /* cn matches lower case */
2606         cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2607         assert_int_equal(cnt, 1);
2608
2609         /* Add the index (actually any modify will do) */
2610         while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &index_ldif))) {
2611                 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
2612                 assert_int_equal(ret, LDB_SUCCESS);
2613         }
2614
2615         ldb_schema_set_override_indexlist(ldb, false);
2616
2617         /* cn does match as there is an index now */
2618         cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2619         assert_int_equal(cnt, 1);
2620
2621         /*
2622          * Set an attribute handler, which will later fail to match as we
2623          * didn't re-index the DB
2624          */
2625         ldb_schema_attribute_set_override_handler(ldb,
2626                                                   ldb_test_attribute_handler_override,
2627                                                   (void *)1);
2628
2629         /*
2630          * cn does not match as we changed the case sensitivity, but
2631          * didn't re-index
2632          *
2633          * This shows that the override is in control
2634          */
2635         cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2636         assert_int_equal(cnt, 0);
2637
2638 }
2639
2640 static int ldb_case_attrs_index_test_teardown(void **state)
2641 {
2642         int ret;
2643         struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
2644                         struct ldbtest_ctx);
2645         struct ldb_dn *del_dn;
2646
2647         del_dn = ldb_dn_new_fmt(ldb_test_ctx,
2648                                 ldb_test_ctx->ldb,
2649                                 "@INDEXLIST");
2650         assert_non_null(del_dn);
2651
2652         ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
2653         if (ret != LDB_ERR_NO_SUCH_OBJECT) {
2654                 assert_int_equal(ret, LDB_SUCCESS);
2655         }
2656
2657         assert_dn_doesnt_exist(ldb_test_ctx,
2658                                "@INDEXLIST");
2659
2660         ldb_case_test_teardown(state);
2661         return 0;
2662 }
2663
2664
2665 struct rename_test_ctx {
2666         struct ldbtest_ctx *ldb_test_ctx;
2667
2668         struct ldb_dn *basedn;
2669         const char *str_basedn;
2670
2671         const char *teardown_dn;
2672 };
2673
2674 static int ldb_rename_test_setup(void **state)
2675 {
2676         struct ldbtest_ctx *ldb_test_ctx;
2677         struct rename_test_ctx *rename_test_ctx;
2678         const char *strdn = "dc=rename_test_entry_from";
2679
2680         ldbtest_setup((void **) &ldb_test_ctx);
2681
2682         rename_test_ctx = talloc(ldb_test_ctx, struct rename_test_ctx);
2683         assert_non_null(rename_test_ctx);
2684         rename_test_ctx->ldb_test_ctx = ldb_test_ctx;
2685         assert_non_null(rename_test_ctx->ldb_test_ctx);
2686
2687         rename_test_ctx->basedn = ldb_dn_new_fmt(rename_test_ctx,
2688                                 rename_test_ctx->ldb_test_ctx->ldb,
2689                                 "%s", strdn);
2690         assert_non_null(rename_test_ctx->basedn);
2691
2692         rename_test_ctx->str_basedn = strdn;
2693         rename_test_ctx->teardown_dn = strdn;
2694
2695         add_dn_with_cn(ldb_test_ctx,
2696                        rename_test_ctx->basedn,
2697                        "test_rename_cn_val");
2698
2699         *state = rename_test_ctx;
2700         return 0;
2701 }
2702
2703 static int ldb_rename_test_teardown(void **state)
2704 {
2705         int ret;
2706         struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(*state,
2707                         struct rename_test_ctx);
2708         struct ldbtest_ctx *ldb_test_ctx;
2709         struct ldb_dn *del_dn;
2710
2711         ldb_test_ctx = rename_test_ctx->ldb_test_ctx;
2712
2713         del_dn = ldb_dn_new_fmt(rename_test_ctx,
2714                                 rename_test_ctx->ldb_test_ctx->ldb,
2715                                 "%s", rename_test_ctx->teardown_dn);
2716         assert_non_null(del_dn);
2717
2718         ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
2719         assert_int_equal(ret, LDB_SUCCESS);
2720
2721         assert_dn_doesnt_exist(ldb_test_ctx,
2722                                rename_test_ctx->teardown_dn);
2723
2724         ldbtest_teardown((void **) &ldb_test_ctx);
2725         return 0;
2726 }
2727
2728 static void test_ldb_rename(void **state)
2729 {
2730         struct rename_test_ctx *rename_test_ctx =
2731                 talloc_get_type_abort(*state, struct rename_test_ctx);
2732         int ret;
2733         const char *str_new_dn = "dc=rename_test_entry_to";
2734         struct ldb_dn *new_dn;
2735
2736         new_dn = ldb_dn_new_fmt(rename_test_ctx,
2737                                 rename_test_ctx->ldb_test_ctx->ldb,
2738                                 "%s", str_new_dn);
2739         assert_non_null(new_dn);
2740
2741         ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
2742                          rename_test_ctx->basedn,
2743                          new_dn);
2744         assert_int_equal(ret, LDB_SUCCESS);
2745
2746         assert_dn_exists(rename_test_ctx->ldb_test_ctx, str_new_dn);
2747         assert_dn_doesnt_exist(rename_test_ctx->ldb_test_ctx,
2748                                rename_test_ctx->str_basedn);
2749         rename_test_ctx->teardown_dn = str_new_dn;
2750
2751         /* FIXME - test the values which didn't change */
2752 }
2753
2754 static void test_ldb_rename_from_doesnt_exist(void **state)
2755 {
2756         struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(
2757                                                         *state,
2758                                                         struct rename_test_ctx);
2759         int ret;
2760         const char *str_new_dn = "dc=rename_test_entry_to";
2761         const char *str_bad_old_dn = "dc=rename_test_no_such_entry";
2762         struct ldb_dn *new_dn;
2763         struct ldb_dn *bad_old_dn;
2764
2765         new_dn = ldb_dn_new_fmt(rename_test_ctx,
2766                                 rename_test_ctx->ldb_test_ctx->ldb,
2767                                 "%s", str_new_dn);
2768         assert_non_null(new_dn);
2769
2770         bad_old_dn = ldb_dn_new_fmt(rename_test_ctx,
2771                                     rename_test_ctx->ldb_test_ctx->ldb,
2772                                     "%s", str_bad_old_dn);
2773         assert_non_null(bad_old_dn);
2774
2775         assert_dn_doesnt_exist(rename_test_ctx->ldb_test_ctx,
2776                                str_bad_old_dn);
2777
2778         ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
2779                          bad_old_dn, new_dn);
2780         assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT);
2781
2782         assert_dn_doesnt_exist(rename_test_ctx->ldb_test_ctx,
2783                                str_new_dn);
2784 }
2785
2786 static void test_ldb_rename_to_exists(void **state)
2787 {
2788         struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(
2789                                                         *state,
2790                                                         struct rename_test_ctx);
2791         int ret;
2792         const char *str_new_dn = "dc=rename_test_already_exists";
2793         struct ldb_dn *new_dn;
2794
2795         new_dn = ldb_dn_new_fmt(rename_test_ctx,
2796                                 rename_test_ctx->ldb_test_ctx->ldb,
2797                                 "%s", str_new_dn);
2798         assert_non_null(new_dn);
2799
2800         add_dn_with_cn(rename_test_ctx->ldb_test_ctx,
2801                        new_dn,
2802                        "test_rename_cn_val");
2803
2804         ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
2805                          rename_test_ctx->basedn,
2806                          new_dn);
2807         assert_int_equal(ret, LDB_ERR_ENTRY_ALREADY_EXISTS);
2808
2809         /* Old object must still exist */
2810         assert_dn_exists(rename_test_ctx->ldb_test_ctx,
2811                          rename_test_ctx->str_basedn);
2812
2813         ret = ldb_delete(rename_test_ctx->ldb_test_ctx->ldb,
2814                          new_dn);
2815         assert_int_equal(ret, LDB_SUCCESS);
2816
2817         assert_dn_exists(rename_test_ctx->ldb_test_ctx,
2818                                rename_test_ctx->teardown_dn);
2819 }
2820
2821 static void test_ldb_rename_self(void **state)
2822 {
2823         struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(
2824                                                         *state,
2825                                                         struct rename_test_ctx);
2826         int ret;
2827
2828         /* Oddly enough, this is a success in ldb.. */
2829         ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
2830                          rename_test_ctx->basedn,
2831                          rename_test_ctx->basedn);
2832         assert_int_equal(ret, LDB_SUCCESS);
2833
2834         /* Old object must still exist */
2835         assert_dn_exists(rename_test_ctx->ldb_test_ctx,
2836                          rename_test_ctx->str_basedn);
2837 }
2838
2839 static void test_ldb_rename_dn_case_change(void **state)
2840 {
2841         struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(
2842                                                         *state,
2843                                                         struct rename_test_ctx);
2844         int ret;
2845         char *str_new_dn;
2846         struct ldb_dn *new_dn;
2847         unsigned i;
2848
2849         str_new_dn = talloc_strdup(rename_test_ctx, rename_test_ctx->str_basedn);
2850         assert_non_null(str_new_dn);
2851         for (i = 0; str_new_dn[i]; i++) {
2852                 str_new_dn[i] = toupper(str_new_dn[i]);
2853         }
2854
2855         new_dn = ldb_dn_new_fmt(rename_test_ctx,
2856                                 rename_test_ctx->ldb_test_ctx->ldb,
2857                                 "%s", str_new_dn);
2858         assert_non_null(new_dn);
2859
2860         ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
2861                          rename_test_ctx->basedn,
2862                          new_dn);
2863         assert_int_equal(ret, LDB_SUCCESS);
2864
2865         /* DNs are case insensitive, so both searches will match */
2866         assert_dn_exists(rename_test_ctx->ldb_test_ctx, str_new_dn);
2867         assert_dn_exists(rename_test_ctx->ldb_test_ctx,
2868                          rename_test_ctx->str_basedn);
2869         /* FIXME - test the values didn't change */
2870 }
2871
2872 static int ldb_read_only_setup(void **state)
2873 {
2874         struct ldbtest_ctx *test_ctx;
2875
2876         ldbtest_setup((void **) &test_ctx);
2877
2878         *state = test_ctx;
2879         return 0;
2880 }
2881
2882 static int ldb_read_only_teardown(void **state)
2883 {
2884         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
2885                                                         struct ldbtest_ctx);
2886         ldbtest_teardown((void **) &test_ctx);
2887         return 0;
2888 }
2889
2890 static void test_read_only(void **state)
2891 {
2892         struct ldb_context *ro_ldb = NULL;
2893         struct ldb_context *rw_ldb = NULL;
2894         int ret;
2895         TALLOC_CTX *tmp_ctx = NULL;
2896
2897         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
2898                                                         struct ldbtest_ctx);
2899         /*
2900          * Close the ldb context freeing it this will ensure it exists on
2901          * disk and can be opened in read only mode
2902          */
2903         TALLOC_FREE(test_ctx->ldb);
2904
2905         /*
2906          * Open the database in read only and read write mode,
2907          * ensure it's opend in read only mode first
2908          */
2909         ro_ldb = ldb_init(test_ctx, test_ctx->ev);
2910         ret = ldb_connect(ro_ldb, test_ctx->dbpath, LDB_FLG_RDONLY, NULL);
2911         assert_int_equal(ret, 0);
2912
2913         rw_ldb = ldb_init(test_ctx, test_ctx->ev);
2914         ret = ldb_connect(rw_ldb, test_ctx->dbpath, 0, NULL);
2915         assert_int_equal(ret, 0);
2916
2917
2918         /*
2919          * Set up a context for the temporary variables
2920          */
2921         tmp_ctx = talloc_new(test_ctx);
2922         assert_non_null(tmp_ctx);
2923
2924         /*
2925          * Ensure that we can search the read write database
2926          */
2927         {
2928                 struct ldb_result *result = NULL;
2929                 struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, rw_ldb,
2930                                                        "dc=test");
2931                 assert_non_null(dn);
2932
2933                 ret = ldb_search(rw_ldb, tmp_ctx, &result, dn,
2934                                  LDB_SCOPE_BASE, NULL, NULL);
2935                 assert_int_equal(ret, LDB_SUCCESS);
2936                 TALLOC_FREE(result);
2937                 TALLOC_FREE(dn);
2938         }
2939
2940         /*
2941          * Ensure that we can search the read only database
2942          */
2943         {
2944                 struct ldb_result *result = NULL;
2945                 struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, ro_ldb,
2946                                                        "dc=test");
2947                 assert_non_null(dn);
2948
2949                 ret = ldb_search(ro_ldb, tmp_ctx, &result, dn,
2950                                  LDB_SCOPE_BASE, NULL, NULL);
2951                 assert_int_equal(ret, LDB_SUCCESS);
2952                 TALLOC_FREE(result);
2953                 TALLOC_FREE(dn);
2954         }
2955         /*
2956          * Ensure that a write to the read only database fails
2957          */
2958         {
2959                 struct ldb_message *msg = NULL;
2960                 msg = ldb_msg_new(tmp_ctx);
2961                 assert_non_null(msg);
2962
2963                 msg->dn = ldb_dn_new_fmt(msg, ro_ldb, "dc=test");
2964                 assert_non_null(msg->dn);
2965
2966                 ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
2967                 assert_int_equal(ret, 0);
2968
2969                 ret = ldb_add(ro_ldb, msg);
2970                 assert_int_equal(ret, LDB_ERR_UNWILLING_TO_PERFORM);
2971                 TALLOC_FREE(msg);
2972         }
2973
2974         /*
2975          * Ensure that a write to the read write database succeeds
2976          */
2977         {
2978                 struct ldb_message *msg = NULL;
2979                 msg = ldb_msg_new(tmp_ctx);
2980                 assert_non_null(msg);
2981
2982                 msg->dn = ldb_dn_new_fmt(msg, ro_ldb, "dc=test");
2983                 assert_non_null(msg->dn);
2984
2985                 ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
2986                 assert_int_equal(ret, 0);
2987
2988                 ret = ldb_add(rw_ldb, msg);
2989                 assert_int_equal(ret, LDB_SUCCESS);
2990                 TALLOC_FREE(msg);
2991         }
2992
2993         /*
2994          * Ensure that a delete from a read only database fails
2995          */
2996         {
2997                 struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, ro_ldb, "dc=test");
2998                 assert_non_null(dn);
2999
3000                 ret = ldb_delete(ro_ldb, dn);
3001                 assert_int_equal(ret, LDB_ERR_UNWILLING_TO_PERFORM);
3002                 TALLOC_FREE(dn);
3003         }
3004
3005
3006         /*
3007          * Ensure that a delete from a read write succeeds
3008          */
3009         {
3010                 struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, rw_ldb, "dc=test");
3011                 assert_non_null(dn);
3012
3013                 ret = ldb_delete(rw_ldb, dn);
3014                 assert_int_equal(ret, LDB_SUCCESS);
3015                 TALLOC_FREE(dn);
3016         }
3017         TALLOC_FREE(tmp_ctx);
3018 }
3019
3020 static bool unique_values = false;
3021
3022 static int unique_index_test_module_add(
3023         struct ldb_module *module,
3024         struct ldb_request *req)
3025 {
3026         if (unique_values) {
3027                 struct ldb_message *msg = discard_const(req->op.add.message);
3028                 struct ldb_message_element *el = NULL;
3029                 el = ldb_msg_find_element(msg, "cn");
3030                 if (el != NULL) {
3031                         el->flags |= LDB_FLAG_INTERNAL_FORCE_UNIQUE_INDEX;
3032                 }
3033         }
3034
3035         return ldb_next_request(module, req);
3036 }
3037
3038 static int unique_index_test_module_init(struct ldb_module *module)
3039 {
3040         return ldb_next_init(module);
3041 }
3042
3043 static const struct ldb_module_ops ldb_unique_index_test_module_ops = {
3044         .name           = "unique_index_test",
3045         .init_context   = unique_index_test_module_init,
3046         .add            = unique_index_test_module_add,
3047 };
3048
3049 static int ldb_unique_index_test_setup(void **state)
3050 {
3051         int ret;
3052         struct ldb_ldif *ldif;
3053         struct ldbtest_ctx *ldb_test_ctx;
3054         const char *attrs_ldif =  \
3055                 "dn: @ATTRIBUTES\n"
3056                 "cn: UNIQUE_INDEX\n"
3057                 "\n";
3058         const char *index_ldif =  \
3059                 "dn: @INDEXLIST\n"
3060                 "@IDXATTR: cn\n"
3061                 "\n";
3062         const char *options[] = {"modules:unique_index_test"};
3063
3064
3065         ret = ldb_register_module(&ldb_unique_index_test_module_ops);
3066         assert_true(ret == LDB_SUCCESS || ret == LDB_ERR_ENTRY_ALREADY_EXISTS);
3067         ldbtest_noconn_setup((void **) &ldb_test_ctx);
3068
3069
3070         ret = ldb_connect(ldb_test_ctx->ldb, ldb_test_ctx->dbpath, 0, options);
3071         assert_int_equal(ret, 0);
3072
3073         while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &attrs_ldif))) {
3074                 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
3075                 assert_int_equal(ret, LDB_SUCCESS);
3076         }
3077
3078         while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &index_ldif))) {
3079                 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
3080                 assert_int_equal(ret, LDB_SUCCESS);
3081         }
3082
3083         unique_values = true;
3084
3085         *state = ldb_test_ctx;
3086         return 0;
3087 }
3088
3089 static int ldb_unique_index_test_teardown(void **state)
3090 {
3091         int ret;
3092         struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
3093                         struct ldbtest_ctx);
3094         struct ldb_dn *del_dn;
3095
3096         del_dn = ldb_dn_new_fmt(ldb_test_ctx,
3097                                 ldb_test_ctx->ldb,
3098                                 "@INDEXLIST");
3099         assert_non_null(del_dn);
3100
3101         ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
3102         if (ret != LDB_ERR_NO_SUCH_OBJECT) {
3103                 assert_int_equal(ret, LDB_SUCCESS);
3104         }
3105
3106         assert_dn_doesnt_exist(ldb_test_ctx,
3107                                "@INDEXLIST");
3108
3109         TALLOC_FREE(del_dn);
3110
3111         del_dn = ldb_dn_new_fmt(ldb_test_ctx,
3112                                 ldb_test_ctx->ldb,
3113                                 "@ATTRIBUTES");
3114         assert_non_null(del_dn);
3115
3116         ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
3117         if (ret != LDB_ERR_NO_SUCH_OBJECT) {
3118                 assert_int_equal(ret, LDB_SUCCESS);
3119         }
3120
3121         assert_dn_doesnt_exist(ldb_test_ctx,
3122                                "@ATTRIBUTES");
3123
3124         ldbtest_teardown((void **) &ldb_test_ctx);
3125         return 0;
3126 }
3127
3128
3129 static void test_ldb_add_unique_value_to_unique_index(void **state)
3130 {
3131         int ret;
3132         struct ldb_message *msg;
3133         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3134                                                         struct ldbtest_ctx);
3135         TALLOC_CTX *tmp_ctx;
3136
3137         tmp_ctx = talloc_new(test_ctx);
3138         assert_non_null(tmp_ctx);
3139
3140         msg = ldb_msg_new(tmp_ctx);
3141         assert_non_null(msg);
3142
3143         msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "dc=test");
3144         assert_non_null(msg->dn);
3145
3146         ret = ldb_msg_add_string(msg, "cn", "test_unique_index");
3147         assert_int_equal(ret, LDB_SUCCESS);
3148
3149         ret = ldb_add(test_ctx->ldb, msg);
3150         assert_int_equal(ret, LDB_SUCCESS);
3151
3152         talloc_free(tmp_ctx);
3153 }
3154
3155 static int ldb_non_unique_index_test_setup(void **state)
3156 {
3157         int ret;
3158         struct ldb_ldif *ldif;
3159         struct ldbtest_ctx *ldb_test_ctx;
3160         const char *index_ldif =  \
3161                 "dn: @INDEXLIST\n"
3162                 "@IDXATTR: cn\n"
3163                 "\n";
3164         const char *options[] = {"modules:unique_index_test"};
3165
3166
3167         ret = ldb_register_module(&ldb_unique_index_test_module_ops);
3168         assert_true(ret == LDB_SUCCESS || ret == LDB_ERR_ENTRY_ALREADY_EXISTS);
3169         ldbtest_noconn_setup((void **) &ldb_test_ctx);
3170
3171
3172         ret = ldb_connect(ldb_test_ctx->ldb, ldb_test_ctx->dbpath, 0, options);
3173         assert_int_equal(ret, 0);
3174
3175         while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &index_ldif))) {
3176                 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
3177                 assert_int_equal(ret, LDB_SUCCESS);
3178         }
3179
3180         unique_values = true;
3181
3182         *state = ldb_test_ctx;
3183         return 0;
3184 }
3185
3186 static int ldb_non_unique_index_test_teardown(void **state)
3187 {
3188         int ret;
3189         struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
3190                         struct ldbtest_ctx);
3191         struct ldb_dn *del_dn;
3192
3193         del_dn = ldb_dn_new_fmt(ldb_test_ctx,
3194                                 ldb_test_ctx->ldb,
3195                                 "@INDEXLIST");
3196         assert_non_null(del_dn);
3197
3198         ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
3199         if (ret != LDB_ERR_NO_SUCH_OBJECT) {
3200                 assert_int_equal(ret, LDB_SUCCESS);
3201         }
3202
3203         assert_dn_doesnt_exist(ldb_test_ctx,
3204                                "@INDEXLIST");
3205
3206         TALLOC_FREE(del_dn);
3207
3208         ldbtest_teardown((void **) &ldb_test_ctx);
3209         return 0;
3210 }
3211
3212 static void test_ldb_add_duplicate_value_to_unique_index(void **state)
3213 {
3214         int ret;
3215         struct ldb_message *msg01;
3216         struct ldb_message *msg02;
3217         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3218                                                         struct ldbtest_ctx);
3219         TALLOC_CTX *tmp_ctx;
3220
3221         tmp_ctx = talloc_new(test_ctx);
3222         assert_non_null(tmp_ctx);
3223
3224         msg01 = ldb_msg_new(tmp_ctx);
3225         assert_non_null(msg01);
3226
3227         msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3228         assert_non_null(msg01->dn);
3229
3230         ret = ldb_msg_add_string(msg01, "cn", "test_unique_index");
3231         assert_int_equal(ret, LDB_SUCCESS);
3232
3233         ret = ldb_add(test_ctx->ldb, msg01);
3234         assert_int_equal(ret, LDB_SUCCESS);
3235
3236         msg02 = ldb_msg_new(tmp_ctx);
3237         assert_non_null(msg02);
3238
3239         msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02");
3240         assert_non_null(msg02->dn);
3241
3242         ret = ldb_msg_add_string(msg02, "cn", "test_unique_index");
3243         assert_int_equal(ret, LDB_SUCCESS);
3244
3245         ret = ldb_add(test_ctx->ldb, msg02);
3246         assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION);
3247         talloc_free(tmp_ctx);
3248 }
3249
3250 static void test_ldb_add_to_index_duplicates_allowed(void **state)
3251 {
3252         int ret;
3253         struct ldb_message *msg01;
3254         struct ldb_message *msg02;
3255         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3256                                                         struct ldbtest_ctx);
3257         TALLOC_CTX *tmp_ctx;
3258
3259         unique_values = false;
3260
3261         tmp_ctx = talloc_new(test_ctx);
3262         assert_non_null(tmp_ctx);
3263
3264
3265         msg01 = ldb_msg_new(tmp_ctx);
3266         assert_non_null(msg01);
3267
3268         msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3269         assert_non_null(msg01->dn);
3270
3271         ret = ldb_msg_add_string(msg01, "cn", "test_unique_index");
3272         assert_int_equal(ret, LDB_SUCCESS);
3273
3274         ret = ldb_add(test_ctx->ldb, msg01);
3275         assert_int_equal(ret, LDB_SUCCESS);
3276
3277         msg02 = ldb_msg_new(tmp_ctx);
3278         assert_non_null(msg02);
3279
3280         msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02");
3281         assert_non_null(msg02->dn);
3282
3283         ret = ldb_msg_add_string(msg02, "cn", "test_unique_index");
3284         assert_int_equal(ret, LDB_SUCCESS);
3285
3286         ret = ldb_add(test_ctx->ldb, msg02);
3287         assert_int_equal(ret, LDB_SUCCESS);
3288         talloc_free(tmp_ctx);
3289 }
3290
3291 static void test_ldb_add_to_index_unique_values_required(void **state)
3292 {
3293         int ret;
3294         struct ldb_message *msg01;
3295         struct ldb_message *msg02;
3296         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3297                                                         struct ldbtest_ctx);
3298         TALLOC_CTX *tmp_ctx;
3299
3300         unique_values = true;
3301
3302         tmp_ctx = talloc_new(test_ctx);
3303         assert_non_null(tmp_ctx);
3304
3305
3306         msg01 = ldb_msg_new(tmp_ctx);
3307         assert_non_null(msg01);
3308
3309         msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3310         assert_non_null(msg01->dn);
3311
3312         ret = ldb_msg_add_string(msg01, "cn", "test_unique_index");
3313         assert_int_equal(ret, LDB_SUCCESS);
3314
3315         ret = ldb_add(test_ctx->ldb, msg01);
3316         assert_int_equal(ret, LDB_SUCCESS);
3317
3318         msg02 = ldb_msg_new(tmp_ctx);
3319         assert_non_null(msg02);
3320
3321         msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02");
3322         assert_non_null(msg02->dn);
3323
3324         ret = ldb_msg_add_string(msg02, "cn", "test_unique_index");
3325         assert_int_equal(ret, LDB_SUCCESS);
3326
3327         ret = ldb_add(test_ctx->ldb, msg02);
3328         assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION);
3329         talloc_free(tmp_ctx);
3330 }
3331
3332 static void ldb_debug_string(void *context, enum ldb_debug_level level,
3333                              const char *fmt, va_list ap)
3334 {
3335
3336         if (level <= LDB_DEBUG_WARNING) {
3337                 *((char **)context) = talloc_vasprintf(NULL, fmt, ap);
3338         }
3339 }
3340
3341 static void test_ldb_unique_index_duplicate_logging(void **state)
3342 {
3343         int ret;
3344         struct ldb_message *msg01;
3345         struct ldb_message *msg02;
3346         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3347                                                         struct ldbtest_ctx);
3348         TALLOC_CTX *tmp_ctx;
3349         char *debug_string = NULL;
3350         char *p = NULL;
3351
3352         ldb_set_debug(test_ctx->ldb, ldb_debug_string, &debug_string);
3353         tmp_ctx = talloc_new(test_ctx);
3354         assert_non_null(tmp_ctx);
3355
3356         msg01 = ldb_msg_new(tmp_ctx);
3357         assert_non_null(msg01);
3358
3359         msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3360         assert_non_null(msg01->dn);
3361
3362         ret = ldb_msg_add_string(msg01, "cn", "test_unique_index");
3363         assert_int_equal(ret, LDB_SUCCESS);
3364
3365         ret = ldb_add(test_ctx->ldb, msg01);
3366         assert_int_equal(ret, LDB_SUCCESS);
3367
3368         msg02 = ldb_msg_new(tmp_ctx);
3369         assert_non_null(msg02);
3370
3371         msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02");
3372         assert_non_null(msg02->dn);
3373
3374         ret = ldb_msg_add_string(msg02, "cn", "test_unique_index");
3375         assert_int_equal(ret, LDB_SUCCESS);
3376
3377         ret = ldb_add(test_ctx->ldb, msg02);
3378         assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION);
3379
3380         assert_non_null(debug_string);
3381         p = strstr(
3382                 debug_string,
3383                 "unique index violation on cn "
3384                 "in dc=test02, conficts with dc=test01 in "
3385                 "@INDEX:CN:test_unique_index");
3386         assert_non_null(p);
3387         TALLOC_FREE(debug_string);
3388         talloc_free(tmp_ctx);
3389 }
3390
3391 static void test_ldb_duplicate_dn_logging(void **state)
3392 {
3393         int ret;
3394         struct ldb_message *msg01;
3395         struct ldb_message *msg02;
3396         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3397                                                         struct ldbtest_ctx);
3398         TALLOC_CTX *tmp_ctx;
3399         char *debug_string = NULL;
3400
3401         ldb_set_debug(test_ctx->ldb, ldb_debug_string, &debug_string);
3402         tmp_ctx = talloc_new(test_ctx);
3403         assert_non_null(tmp_ctx);
3404
3405         msg01 = ldb_msg_new(tmp_ctx);
3406         assert_non_null(msg01);
3407
3408         msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3409         assert_non_null(msg01->dn);
3410
3411         ret = ldb_msg_add_string(msg01, "cn", "test_unique_index01");
3412         assert_int_equal(ret, LDB_SUCCESS);
3413
3414         ret = ldb_add(test_ctx->ldb, msg01);
3415         assert_int_equal(ret, LDB_SUCCESS);
3416
3417         msg02 = ldb_msg_new(tmp_ctx);
3418         assert_non_null(msg02);
3419
3420         msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test01");
3421         assert_non_null(msg02->dn);
3422
3423         ret = ldb_msg_add_string(msg02, "cn", "test_unique_index02");
3424         assert_int_equal(ret, LDB_SUCCESS);
3425
3426         ret = ldb_add(test_ctx->ldb, msg02);
3427         assert_int_equal(ret, LDB_ERR_ENTRY_ALREADY_EXISTS);
3428
3429         assert_null(debug_string);
3430         talloc_free(tmp_ctx);
3431 }
3432
3433 static int ldb_guid_index_test_setup(void **state)
3434 {
3435         int ret;
3436         struct ldb_ldif *ldif;
3437         struct ldbtest_ctx *ldb_test_ctx;
3438         const char *attrs_ldif =  \
3439                 "dn: @ATTRIBUTES\n"
3440                 "cn: UNIQUE_INDEX\n"
3441                 "\n";
3442         const char *index_ldif =  \
3443                 "dn: @INDEXLIST\n"
3444                 "@IDXATTR: cn\n"
3445                 "@IDXGUID: objectUUID\n"
3446                 "@IDX_DN_GUID: GUID\n"
3447                 "\n";
3448
3449         ldbtest_noconn_setup((void **) &ldb_test_ctx);
3450
3451
3452         ret = ldb_connect(ldb_test_ctx->ldb, ldb_test_ctx->dbpath, 0, NULL);
3453         assert_int_equal(ret, 0);
3454
3455         while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &attrs_ldif))) {
3456                 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
3457                 assert_int_equal(ret, LDB_SUCCESS);
3458         }
3459
3460         while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &index_ldif))) {
3461                 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
3462                 assert_int_equal(ret, LDB_SUCCESS);
3463         }
3464
3465         *state = ldb_test_ctx;
3466         return 0;
3467 }
3468
3469 static int ldb_guid_index_test_teardown(void **state)
3470 {
3471         int ret;
3472         struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
3473                         struct ldbtest_ctx);
3474         struct ldb_dn *del_dn;
3475
3476         del_dn = ldb_dn_new_fmt(ldb_test_ctx,
3477                                 ldb_test_ctx->ldb,
3478                                 "@INDEXLIST");
3479         assert_non_null(del_dn);
3480
3481         ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
3482         if (ret != LDB_ERR_NO_SUCH_OBJECT) {
3483                 assert_int_equal(ret, LDB_SUCCESS);
3484         }
3485
3486         assert_dn_doesnt_exist(ldb_test_ctx,
3487                                "@INDEXLIST");
3488
3489         TALLOC_FREE(del_dn);
3490
3491         del_dn = ldb_dn_new_fmt(ldb_test_ctx,
3492                                 ldb_test_ctx->ldb,
3493                                 "@ATTRIBUTES");
3494         assert_non_null(del_dn);
3495
3496         ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
3497         if (ret != LDB_ERR_NO_SUCH_OBJECT) {
3498                 assert_int_equal(ret, LDB_SUCCESS);
3499         }
3500
3501         assert_dn_doesnt_exist(ldb_test_ctx,
3502                                "@ATTRIBUTES");
3503
3504         ldbtest_teardown((void **) &ldb_test_ctx);
3505         return 0;
3506 }
3507
3508
3509 static void test_ldb_unique_index_duplicate_with_guid(void **state)
3510 {
3511         int ret;
3512         struct ldb_message *msg01;
3513         struct ldb_message *msg02;
3514         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3515                                                         struct ldbtest_ctx);
3516         TALLOC_CTX *tmp_ctx;
3517         char *debug_string = NULL;
3518         char *p = NULL;
3519
3520         ldb_set_debug(test_ctx->ldb, ldb_debug_string, &debug_string);
3521         tmp_ctx = talloc_new(test_ctx);
3522         assert_non_null(tmp_ctx);
3523
3524         msg01 = ldb_msg_new(tmp_ctx);
3525         assert_non_null(msg01);
3526
3527         msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3528         assert_non_null(msg01->dn);
3529
3530         ret = ldb_msg_add_string(msg01, "cn", "test_unique_index");
3531         assert_int_equal(ret, LDB_SUCCESS);
3532
3533         ret = ldb_msg_add_string(msg01, "objectUUID", "0123456789abcdef");
3534         assert_int_equal(ret, LDB_SUCCESS);
3535
3536         ret = ldb_add(test_ctx->ldb, msg01);
3537         assert_int_equal(ret, LDB_SUCCESS);
3538
3539         msg02 = ldb_msg_new(tmp_ctx);
3540         assert_non_null(msg01);
3541
3542         msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02");
3543         assert_non_null(msg02->dn);
3544
3545         ret = ldb_msg_add_string(msg02, "cn", "test_unique_index");
3546         assert_int_equal(ret, LDB_SUCCESS);
3547
3548         ret = ldb_msg_add_string(msg02, "objectUUID", "0123456789abcde0");
3549         assert_int_equal(ret, LDB_SUCCESS);
3550
3551         ret = ldb_add(test_ctx->ldb, msg02);
3552         assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION);
3553
3554         assert_non_null(debug_string);
3555         p = strstr(
3556                 debug_string,
3557                 "unique index violation on cn in dc=test02, conficts with "
3558                 "objectUUID 0123456789abcdef in @INDEX:CN:test_unique_index");
3559         assert_non_null(p);
3560         TALLOC_FREE(debug_string);
3561         talloc_free(tmp_ctx);
3562 }
3563
3564 static void test_ldb_guid_index_duplicate_dn_logging(void **state)
3565 {
3566         int ret;
3567         struct ldb_message *msg01;
3568         struct ldb_message *msg02;
3569         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3570                                                         struct ldbtest_ctx);
3571         TALLOC_CTX *tmp_ctx;
3572         char *debug_string = NULL;
3573
3574         ldb_set_debug(test_ctx->ldb, ldb_debug_string, &debug_string);
3575         tmp_ctx = talloc_new(test_ctx);
3576         assert_non_null(tmp_ctx);
3577
3578         msg01 = ldb_msg_new(tmp_ctx);
3579         assert_non_null(msg01);
3580
3581         msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3582         assert_non_null(msg01->dn);
3583
3584         ret = ldb_msg_add_string(msg01, "cn", "test_unique_index01");
3585         assert_int_equal(ret, LDB_SUCCESS);
3586
3587         ret = ldb_msg_add_string(msg01, "objectUUID", "0123456789abcdef");
3588         assert_int_equal(ret, LDB_SUCCESS);
3589
3590         ret = ldb_add(test_ctx->ldb, msg01);
3591         assert_int_equal(ret, LDB_SUCCESS);
3592
3593         msg02 = ldb_msg_new(tmp_ctx);
3594         assert_non_null(msg02);
3595
3596         msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test01");
3597         assert_non_null(msg02->dn);
3598
3599         ret = ldb_msg_add_string(msg02, "cn", "test_unique_index02");
3600         assert_int_equal(ret, LDB_SUCCESS);
3601
3602         ret = ldb_msg_add_string(msg02, "objectUUID", "0123456789abcde1");
3603         assert_int_equal(ret, LDB_SUCCESS);
3604
3605         ret = ldb_add(test_ctx->ldb, msg02);
3606         assert_int_equal(ret, LDB_ERR_ENTRY_ALREADY_EXISTS);
3607
3608         assert_null(debug_string);
3609         talloc_free(tmp_ctx);
3610 }
3611
3612
3613 int main(int argc, const char **argv)
3614 {
3615         const struct CMUnitTest tests[] = {
3616                 cmocka_unit_test_setup_teardown(test_connect,
3617                                                 ldbtest_noconn_setup,
3618                                                 ldbtest_noconn_teardown),
3619                 cmocka_unit_test_setup_teardown(test_ldif_message,
3620                                                 ldbtest_noconn_setup,
3621                                                 ldbtest_noconn_teardown),
3622                 cmocka_unit_test_setup_teardown(test_ldif_message_redacted,
3623                                                 ldbtest_noconn_setup,
3624                                                 ldbtest_noconn_teardown),
3625                 cmocka_unit_test_setup_teardown(test_ldb_add,
3626                                                 ldbtest_setup,
3627                                                 ldbtest_teardown),
3628                 cmocka_unit_test_setup_teardown(test_ldb_search,
3629                                                 ldbtest_setup,
3630                                                 ldbtest_teardown),
3631                 cmocka_unit_test_setup_teardown(test_ldb_del,
3632                                                 ldbtest_setup,
3633                                                 ldbtest_teardown),
3634                 cmocka_unit_test_setup_teardown(test_ldb_del_noexist,
3635                                                 ldbtest_setup,
3636                                                 ldbtest_teardown),
3637                 cmocka_unit_test_setup_teardown(test_ldb_handle,
3638                                                 ldbtest_setup,
3639                                                 ldbtest_teardown),
3640                 cmocka_unit_test_setup_teardown(test_ldb_build_search_req,
3641                                                 ldbtest_setup,
3642                                                 ldbtest_teardown),
3643                 cmocka_unit_test_setup_teardown(test_transactions,
3644                                                 ldbtest_setup,
3645                                                 ldbtest_teardown),
3646                 cmocka_unit_test_setup_teardown(test_ldb_modify_add_key,
3647                                                 ldb_modify_test_setup,
3648                                                 ldb_modify_test_teardown),
3649                 cmocka_unit_test_setup_teardown(test_ldb_modify_extend_key,
3650                                                 ldb_modify_test_setup,
3651                                                 ldb_modify_test_teardown),
3652                 cmocka_unit_test_setup_teardown(test_ldb_modify_add_key_noval,
3653                                                 ldb_modify_test_setup,
3654                                                 ldb_modify_test_teardown),
3655                 cmocka_unit_test_setup_teardown(test_ldb_modify_replace_key,
3656                                                 ldb_modify_test_setup,
3657                                                 ldb_modify_test_teardown),
3658                 cmocka_unit_test_setup_teardown(test_ldb_modify_replace_noexist_key,
3659                                                 ldb_modify_test_setup,
3660                                                 ldb_modify_test_teardown),
3661                 cmocka_unit_test_setup_teardown(test_ldb_modify_replace_zero_vals,
3662                                                 ldb_modify_test_setup,
3663                                                 ldb_modify_test_teardown),
3664                 cmocka_unit_test_setup_teardown(test_ldb_modify_replace_noexist_key_zero_vals,
3665                                                 ldb_modify_test_setup,
3666                                                 ldb_modify_test_teardown),
3667                 cmocka_unit_test_setup_teardown(test_ldb_modify_del_key,
3668                                                 ldb_modify_test_setup,
3669                                                 ldb_modify_test_teardown),
3670                 cmocka_unit_test_setup_teardown(test_ldb_modify_del_keyval,
3671                                                 ldb_modify_test_setup,
3672                                                 ldb_modify_test_teardown),
3673                 cmocka_unit_test_setup_teardown(test_search_match_none,
3674                                                 ldb_search_test_setup,
3675                                                 ldb_search_test_teardown),
3676                 cmocka_unit_test_setup_teardown(test_search_match_one,
3677                                                 ldb_search_test_setup,
3678                                                 ldb_search_test_teardown),
3679                 cmocka_unit_test_setup_teardown(test_search_match_filter,
3680                                                 ldb_search_test_setup,
3681                                                 ldb_search_test_teardown),
3682                 cmocka_unit_test_setup_teardown(test_search_match_both,
3683                                                 ldb_search_test_setup,
3684                                                 ldb_search_test_teardown),
3685                 cmocka_unit_test_setup_teardown(test_search_match_basedn,
3686                                                 ldb_search_test_setup,
3687                                                 ldb_search_test_teardown),
3688                 cmocka_unit_test_setup_teardown(test_ldb_search_against_transaction,
3689                                                 ldb_search_test_setup,
3690                                                 ldb_search_test_teardown),
3691                 cmocka_unit_test_setup_teardown(test_ldb_modify_during_unindexed_search,
3692                                                 ldb_search_test_setup,
3693                                                 ldb_search_test_teardown),
3694                 cmocka_unit_test_setup_teardown(test_ldb_modify_during_indexed_search,
3695                                                 ldb_search_test_setup,
3696                                                 ldb_search_test_teardown),
3697                 cmocka_unit_test_setup_teardown(test_ldb_rename_during_unindexed_search,
3698                                                 ldb_search_test_setup,
3699                                                 ldb_search_test_teardown),
3700                 cmocka_unit_test_setup_teardown(test_ldb_rename_during_indexed_search,
3701                                                 ldb_search_test_setup,
3702                                                 ldb_search_test_teardown),
3703                 cmocka_unit_test_setup_teardown(test_ldb_modify_during_whole_search,
3704                                                 ldb_search_test_setup,
3705                                                 ldb_search_test_teardown),
3706                 cmocka_unit_test_setup_teardown(test_ldb_modify_before_ldb_wait,
3707                                                 ldb_search_test_setup,
3708                                                 ldb_search_test_teardown),
3709                 cmocka_unit_test_setup_teardown(test_ldb_attrs_case_insensitive,
3710                                                 ldb_case_test_setup,
3711                                                 ldb_case_test_teardown),
3712                 cmocka_unit_test_setup_teardown(test_ldb_attrs_case_handler,
3713                                                 ldb_case_test_setup,
3714                                                 ldb_case_test_teardown),
3715                 cmocka_unit_test_setup_teardown(test_ldb_attrs_index_handler,
3716                                                 ldb_case_test_setup,
3717                                                 ldb_case_attrs_index_test_teardown),
3718                 cmocka_unit_test_setup_teardown(test_ldb_rename,
3719                                                 ldb_rename_test_setup,
3720                                                 ldb_rename_test_teardown),
3721                 cmocka_unit_test_setup_teardown(test_ldb_rename_from_doesnt_exist,
3722                                                 ldb_rename_test_setup,
3723                                                 ldb_rename_test_teardown),
3724                 cmocka_unit_test_setup_teardown(test_ldb_rename_to_exists,
3725                                                 ldb_rename_test_setup,
3726                                                 ldb_rename_test_teardown),
3727                 cmocka_unit_test_setup_teardown(test_ldb_rename_self,
3728                                                 ldb_rename_test_setup,
3729                                                 ldb_rename_test_teardown),
3730                 cmocka_unit_test_setup_teardown(test_ldb_rename_dn_case_change,
3731                                                 ldb_rename_test_setup,
3732                                                 ldb_rename_test_teardown),
3733                 cmocka_unit_test_setup_teardown(test_read_only,
3734                                                 ldb_read_only_setup,
3735                                                 ldb_read_only_teardown),
3736                 cmocka_unit_test_setup_teardown(
3737                         test_ldb_add_unique_value_to_unique_index,
3738                         ldb_unique_index_test_setup,
3739                         ldb_unique_index_test_teardown),
3740                 cmocka_unit_test_setup_teardown(
3741                         test_ldb_add_duplicate_value_to_unique_index,
3742                         ldb_unique_index_test_setup,
3743                         ldb_unique_index_test_teardown),
3744                 cmocka_unit_test_setup_teardown(
3745                         test_ldb_add_to_index_duplicates_allowed,
3746                         ldb_non_unique_index_test_setup,
3747                         ldb_non_unique_index_test_teardown),
3748                 cmocka_unit_test_setup_teardown(
3749                         test_ldb_add_to_index_unique_values_required,
3750                         ldb_non_unique_index_test_setup,
3751                         ldb_non_unique_index_test_teardown),
3752                 cmocka_unit_test_setup_teardown(
3753                         test_ldb_unique_index_duplicate_logging,
3754                         ldb_unique_index_test_setup,
3755                         ldb_unique_index_test_teardown),
3756                 cmocka_unit_test_setup_teardown(
3757                         test_ldb_duplicate_dn_logging,
3758                         ldb_unique_index_test_setup,
3759                         ldb_unique_index_test_teardown),
3760                 cmocka_unit_test_setup_teardown(
3761                         test_ldb_guid_index_duplicate_dn_logging,
3762                         ldb_guid_index_test_setup,
3763                         ldb_guid_index_test_teardown),
3764                 cmocka_unit_test_setup_teardown(
3765                         test_ldb_unique_index_duplicate_with_guid,
3766                         ldb_guid_index_test_setup,
3767                         ldb_guid_index_test_teardown),
3768         };
3769
3770         return cmocka_run_group_tests(tests, NULL, NULL);
3771 }