ldb: Ensure we can open a new LDB after a fork()
[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         struct ldb_ldif *ldif;
206 #ifdef GUID_IDX
207         const char *index_ldif =                \
208                 "dn: @INDEXLIST\n"
209                 "@IDXGUID: objectUUID\n"
210                 "@IDX_DN_GUID: GUID\n"
211                 "\n";
212 #else
213         const char *index_ldif = "\n";
214 #endif
215         int ret;
216
217         ldbtest_noconn_setup((void **) &test_ctx);
218
219         ret = ldb_connect(test_ctx->ldb, test_ctx->dbpath, 0, NULL);
220         assert_int_equal(ret, 0);
221
222         while ((ldif = ldb_ldif_read_string(test_ctx->ldb, &index_ldif))) {
223                 ret = ldb_add(test_ctx->ldb, ldif->msg);
224                 assert_int_equal(ret, LDB_SUCCESS);
225         }
226         *state = test_ctx;
227         return 0;
228 }
229
230 static int ldbtest_teardown(void **state)
231 {
232         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
233                                                         struct ldbtest_ctx);
234         ldbtest_noconn_teardown((void **) &test_ctx);
235         return 0;
236 }
237
238 static void test_ldb_add(void **state)
239 {
240         int ret;
241         struct ldb_message *msg;
242         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
243                                                         struct ldbtest_ctx);
244         TALLOC_CTX *tmp_ctx;
245
246         tmp_ctx = talloc_new(test_ctx);
247         assert_non_null(tmp_ctx);
248
249         msg = ldb_msg_new(tmp_ctx);
250         assert_non_null(msg);
251
252         msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "dc=test");
253         assert_non_null(msg->dn);
254
255         ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
256         assert_int_equal(ret, 0);
257
258         ret = ldb_msg_add_string(msg, "objectUUID", "0123456789abcdef");
259         assert_int_equal(ret, 0);
260
261         ret = ldb_add(test_ctx->ldb, msg);
262         assert_int_equal(ret, 0);
263
264         talloc_free(tmp_ctx);
265 }
266
267 static void test_ldb_search(void **state)
268 {
269         int ret;
270         struct ldb_message *msg;
271         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
272                                                         struct ldbtest_ctx);
273         TALLOC_CTX *tmp_ctx;
274         struct ldb_dn *basedn;
275         struct ldb_dn *basedn2;
276         struct ldb_result *result = NULL;
277
278         tmp_ctx = talloc_new(test_ctx);
279         assert_non_null(tmp_ctx);
280
281         basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "dc=test");
282         assert_non_null(basedn);
283
284         ret = ldb_search(test_ctx->ldb, tmp_ctx, &result, basedn,
285                          LDB_SCOPE_BASE, NULL, NULL);
286         assert_int_equal(ret, 0);
287         assert_non_null(result);
288         assert_int_equal(result->count, 0);
289
290         msg = ldb_msg_new(tmp_ctx);
291         assert_non_null(msg);
292
293         msg->dn = basedn;
294         assert_non_null(msg->dn);
295
296         ret = ldb_msg_add_string(msg, "cn", "test_cn_val1");
297         assert_int_equal(ret, 0);
298
299         ret = ldb_msg_add_string(msg, "objectUUID", "0123456789abcde1");
300         assert_int_equal(ret, 0);
301
302         ret = ldb_add(test_ctx->ldb, msg);
303         assert_int_equal(ret, 0);
304
305         basedn2 = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "dc=test2");
306         assert_non_null(basedn2);
307
308         msg = ldb_msg_new(tmp_ctx);
309         assert_non_null(msg);
310
311         msg->dn = basedn2;
312         assert_non_null(msg->dn);
313
314         ret = ldb_msg_add_string(msg, "cn", "test_cn_val2");
315         assert_int_equal(ret, 0);
316
317         ret = ldb_msg_add_string(msg, "objectUUID", "0123456789abcde2");
318         assert_int_equal(ret, 0);
319
320         ret = ldb_add(test_ctx->ldb, msg);
321         assert_int_equal(ret, 0);
322
323         ret = ldb_search(test_ctx->ldb, tmp_ctx, &result, basedn,
324                          LDB_SCOPE_BASE, NULL, NULL);
325         assert_int_equal(ret, 0);
326         assert_non_null(result);
327         assert_int_equal(result->count, 1);
328         assert_string_equal(ldb_dn_get_linearized(result->msgs[0]->dn),
329                             ldb_dn_get_linearized(basedn));
330
331         ret = ldb_search(test_ctx->ldb, tmp_ctx, &result, basedn2,
332                          LDB_SCOPE_BASE, NULL, NULL);
333         assert_int_equal(ret, 0);
334         assert_non_null(result);
335         assert_int_equal(result->count, 1);
336         assert_string_equal(ldb_dn_get_linearized(result->msgs[0]->dn),
337                             ldb_dn_get_linearized(basedn2));
338
339         talloc_free(tmp_ctx);
340 }
341
342 static int base_search_count(struct ldbtest_ctx *test_ctx, const char *entry_dn)
343 {
344         TALLOC_CTX *tmp_ctx;
345         struct ldb_dn *basedn;
346         struct ldb_result *result = NULL;
347         int ret;
348         int count;
349
350         tmp_ctx = talloc_new(test_ctx);
351         assert_non_null(tmp_ctx);
352
353         basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "%s", entry_dn);
354         assert_non_null(basedn);
355
356         ret = ldb_search(test_ctx->ldb, tmp_ctx, &result, basedn,
357                          LDB_SCOPE_BASE, NULL, NULL);
358         assert_int_equal(ret, LDB_SUCCESS);
359         assert_non_null(result);
360
361         count = result->count;
362         talloc_free(tmp_ctx);
363         return count;
364 }
365
366 static int sub_search_count(struct ldbtest_ctx *test_ctx,
367                             const char *base_dn,
368                             const char *filter)
369 {
370         TALLOC_CTX *tmp_ctx;
371         struct ldb_dn *basedn;
372         struct ldb_result *result = NULL;
373         int ret;
374         int count;
375
376         tmp_ctx = talloc_new(test_ctx);
377         assert_non_null(tmp_ctx);
378
379         basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "%s", base_dn);
380         assert_non_null(basedn);
381
382         ret = ldb_search(test_ctx->ldb, tmp_ctx, &result, basedn,
383                          LDB_SCOPE_SUBTREE, NULL, "%s", filter);
384         assert_int_equal(ret, LDB_SUCCESS);
385         assert_non_null(result);
386
387         count = result->count;
388         talloc_free(tmp_ctx);
389         return count;
390 }
391
392 /* In general it would be better if utility test functions didn't assert
393  * but only returned a value, then assert in the test shows correct
394  * line
395  */
396 static void assert_dn_exists(struct ldbtest_ctx *test_ctx,
397                              const char *entry_dn)
398 {
399         int count;
400
401         count = base_search_count(test_ctx, entry_dn);
402         assert_int_equal(count, 1);
403 }
404
405 static void assert_dn_doesnt_exist(struct ldbtest_ctx *test_ctx,
406                                    const char *entry_dn)
407 {
408         int count;
409
410         count = base_search_count(test_ctx, entry_dn);
411         assert_int_equal(count, 0);
412 }
413
414 static void add_dn_with_cn(struct ldbtest_ctx *test_ctx,
415                            struct ldb_dn *dn,
416                            const char *cn_value,
417                            const char *uuid_value)
418 {
419         int ret;
420         TALLOC_CTX *tmp_ctx;
421         struct ldb_message *msg;
422
423         tmp_ctx = talloc_new(test_ctx);
424         assert_non_null(tmp_ctx);
425
426         assert_dn_doesnt_exist(test_ctx,
427                                ldb_dn_get_linearized(dn));
428
429         msg = ldb_msg_new(tmp_ctx);
430         assert_non_null(msg);
431         msg->dn = dn;
432
433         ret = ldb_msg_add_string(msg, "cn", cn_value);
434         assert_int_equal(ret, LDB_SUCCESS);
435
436         ret = ldb_msg_add_string(msg, "objectUUID", uuid_value);
437         assert_int_equal(ret, 0);
438
439         ret = ldb_add(test_ctx->ldb, msg);
440         assert_int_equal(ret, LDB_SUCCESS);
441
442         assert_dn_exists(test_ctx,
443                          ldb_dn_get_linearized(dn));
444         talloc_free(tmp_ctx);
445 }
446
447 static void test_ldb_del(void **state)
448 {
449         int ret;
450         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
451                                                         struct ldbtest_ctx);
452         const char *basedn = "dc=ldb_del_test";
453         struct ldb_dn *dn;
454
455         dn = ldb_dn_new_fmt(test_ctx, test_ctx->ldb, "%s", basedn);
456         assert_non_null(dn);
457
458         add_dn_with_cn(test_ctx, dn,
459                        "test_del_cn_val",
460                        "0123456789abcdef");
461
462         ret = ldb_delete(test_ctx->ldb, dn);
463         assert_int_equal(ret, LDB_SUCCESS);
464
465         assert_dn_doesnt_exist(test_ctx, basedn);
466 }
467
468 static void test_ldb_del_noexist(void **state)
469 {
470         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
471                                                              struct ldbtest_ctx);
472         struct ldb_dn *basedn;
473         int ret;
474
475         basedn = ldb_dn_new(test_ctx, test_ctx->ldb, "dc=nosuchplace");
476         assert_non_null(basedn);
477
478         ret = ldb_delete(test_ctx->ldb, basedn);
479         assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT);
480 }
481
482 static void test_ldb_handle(void **state)
483 {
484         int ret;
485         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
486                                                         struct ldbtest_ctx);
487         TALLOC_CTX *tmp_ctx;
488         struct ldb_dn *basedn;
489         struct ldb_request *request = NULL;
490         struct ldb_request *request2 = NULL;
491         struct ldb_result *res = NULL;
492         const char *attrs[] = { "cn", NULL };
493
494         tmp_ctx = talloc_new(test_ctx);
495         assert_non_null(tmp_ctx);
496
497         basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "dc=test");
498         assert_non_null(basedn);
499
500         res = talloc_zero(tmp_ctx, struct ldb_result);
501         assert_non_null(res);
502
503         ret = ldb_build_search_req(&request, test_ctx->ldb, tmp_ctx,
504                                    basedn, LDB_SCOPE_BASE,
505                                    NULL, attrs, NULL, res,
506                                    ldb_search_default_callback,
507                                    NULL);
508         assert_int_equal(ret, 0);
509
510         /* We are against ldb_tdb, so expect private event contexts */
511         assert_ptr_not_equal(ldb_handle_get_event_context(request->handle),
512                              ldb_get_event_context(test_ctx->ldb));
513
514         ret = ldb_build_search_req(&request2, test_ctx->ldb, tmp_ctx,
515                                    basedn, LDB_SCOPE_BASE,
516                                    NULL, attrs, NULL, res,
517                                    ldb_search_default_callback,
518                                    request);
519         assert_int_equal(ret, 0);
520
521         /* Expect that same event context will be chained */
522         assert_ptr_equal(ldb_handle_get_event_context(request->handle),
523                          ldb_handle_get_event_context(request2->handle));
524
525         /* Now force this to use the global context */
526         ldb_handle_use_global_event_context(request2->handle);
527         assert_ptr_equal(ldb_handle_get_event_context(request2->handle),
528                          ldb_get_event_context(test_ctx->ldb));
529
530         talloc_free(tmp_ctx);
531 }
532
533 static void test_ldb_build_search_req(void **state)
534 {
535         int ret;
536         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
537                                                         struct ldbtest_ctx);
538         TALLOC_CTX *tmp_ctx;
539         struct ldb_dn *basedn;
540         struct ldb_request *request = NULL;
541         struct ldb_request *request2 = NULL;
542         struct ldb_result *res = NULL;
543         const char *attrs[] = { "cn", NULL };
544
545         tmp_ctx = talloc_new(test_ctx);
546         assert_non_null(tmp_ctx);
547
548         basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "dc=test");
549         assert_non_null(basedn);
550
551         res = talloc_zero(tmp_ctx, struct ldb_result);
552         assert_non_null(res);
553
554         ret = ldb_build_search_req(&request, test_ctx->ldb, tmp_ctx,
555                                    basedn, LDB_SCOPE_BASE,
556                                    NULL, attrs, NULL, res,
557                                    ldb_search_default_callback,
558                                    NULL);
559         assert_int_equal(ret, 0);
560
561         assert_int_equal(request->operation, LDB_SEARCH);
562         assert_ptr_equal(request->op.search.base, basedn);
563         assert_int_equal(request->op.search.scope, LDB_SCOPE_BASE);
564         assert_non_null(request->op.search.tree);
565         assert_ptr_equal(request->op.search.attrs, attrs);
566         assert_ptr_equal(request->context, res);
567         assert_ptr_equal(request->callback, ldb_search_default_callback);
568
569         ret = ldb_build_search_req(&request2, test_ctx->ldb, tmp_ctx,
570                                    basedn, LDB_SCOPE_BASE,
571                                    NULL, attrs, NULL, res,
572                                    ldb_search_default_callback,
573                                    request);
574         assert_int_equal(ret, 0);
575         assert_ptr_equal(request, request2->handle->parent);
576         assert_int_equal(request->starttime, request2->starttime);
577         assert_int_equal(request->timeout, request2->timeout);
578
579         talloc_free(tmp_ctx);
580 }
581
582 static void add_keyval(struct ldbtest_ctx *test_ctx,
583                        const char *key,
584                        const char *val,
585                        const char *uuid)
586 {
587         int ret;
588         struct ldb_message *msg;
589
590         msg = ldb_msg_new(test_ctx);
591         assert_non_null(msg);
592
593         msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "%s=%s", key, val);
594         assert_non_null(msg->dn);
595
596         ret = ldb_msg_add_string(msg, key, val);
597         assert_int_equal(ret, 0);
598
599         ret = ldb_msg_add_string(msg, "objectUUID", uuid);
600         assert_int_equal(ret, 0);
601
602         ret = ldb_add(test_ctx->ldb, msg);
603         assert_int_equal(ret, 0);
604
605         talloc_free(msg);
606 }
607
608 static struct ldb_result *get_keyval(struct ldbtest_ctx *test_ctx,
609                                      const char *key,
610                                      const char *val)
611 {
612         int ret;
613         struct ldb_result *result;
614         struct ldb_dn *basedn;
615
616         basedn = ldb_dn_new_fmt(test_ctx, test_ctx->ldb, "%s=%s", key, val);
617         assert_non_null(basedn);
618
619         ret = ldb_search(test_ctx->ldb, test_ctx, &result, basedn,
620                         LDB_SCOPE_BASE, NULL, NULL);
621         assert_int_equal(ret, 0);
622
623         return result;
624 }
625
626 static void test_transactions(void **state)
627 {
628         int ret;
629         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
630                         struct ldbtest_ctx);
631         struct ldb_result *res;
632
633         /* start lev-0 transaction */
634         ret = ldb_transaction_start(test_ctx->ldb);
635         assert_int_equal(ret, 0);
636
637         add_keyval(test_ctx, "vegetable", "carrot",
638                    "0123456789abcde0");
639
640         /* commit lev-0 transaction */
641         ret = ldb_transaction_commit(test_ctx->ldb);
642         assert_int_equal(ret, 0);
643
644         /* start another lev-1 nested transaction */
645         ret = ldb_transaction_start(test_ctx->ldb);
646         assert_int_equal(ret, 0);
647
648         add_keyval(test_ctx, "fruit", "apple",
649                    "0123456789abcde1");
650
651         /* abort lev-1 nested transaction */
652         ret = ldb_transaction_cancel(test_ctx->ldb);
653         assert_int_equal(ret, 0);
654
655         res = get_keyval(test_ctx, "vegetable", "carrot");
656         assert_non_null(res);
657         assert_int_equal(res->count, 1);
658
659         res = get_keyval(test_ctx, "fruit", "apple");
660         assert_non_null(res);
661         assert_int_equal(res->count, 0);
662 }
663
664 static void test_nested_transactions(void **state)
665 {
666         int ret;
667         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
668                         struct ldbtest_ctx);
669         struct ldb_result *res;
670
671         /* start lev-0 transaction */
672         ret = ldb_transaction_start(test_ctx->ldb);
673         assert_int_equal(ret, 0);
674
675         add_keyval(test_ctx, "vegetable", "carrot",
676                    "0123456789abcde0");
677
678
679         /* start another lev-1 nested transaction */
680         ret = ldb_transaction_start(test_ctx->ldb);
681         assert_int_equal(ret, 0);
682
683         add_keyval(test_ctx, "fruit", "apple",
684                    "0123456789abcde1");
685
686         /* abort lev-1 nested transaction */
687         ret = ldb_transaction_cancel(test_ctx->ldb);
688         assert_int_equal(ret, 0);
689
690         /* commit lev-0 transaction */
691         ret = ldb_transaction_commit(test_ctx->ldb);
692         assert_int_equal(ret, 0);
693
694         res = get_keyval(test_ctx, "vegetable", "carrot");
695         assert_non_null(res);
696         assert_int_equal(res->count, 1);
697
698         /* This documents the current ldb behaviour,  i.e. nested
699          * transactions are not supported.  And the cancellation of the nested
700          * transaction has no effect.
701          */
702         res = get_keyval(test_ctx, "fruit", "apple");
703         assert_non_null(res);
704         assert_int_equal(res->count, 1);
705 }
706 struct ldb_mod_test_ctx {
707         struct ldbtest_ctx *ldb_test_ctx;
708         const char *entry_dn;
709 };
710
711 struct keyval {
712         const char *key;
713         const char *val;
714 };
715
716 static struct ldb_message *build_mod_msg(TALLOC_CTX *mem_ctx,
717                                          struct ldbtest_ctx *test_ctx,
718                                          const char *dn,
719                                          int modify_flags,
720                                          struct keyval *kvs)
721 {
722         struct ldb_message *msg;
723         int ret;
724         int i;
725
726         msg = ldb_msg_new(mem_ctx);
727         assert_non_null(msg);
728
729         msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "%s", dn);
730         assert_non_null(msg->dn);
731
732         for (i = 0; kvs[i].key != NULL; i++) {
733                 if (modify_flags) {
734                         ret = ldb_msg_add_empty(msg, kvs[i].key,
735                                                 modify_flags, NULL);
736                         assert_int_equal(ret, 0);
737                 }
738
739                 if (kvs[i].val) {
740                         ret = ldb_msg_add_string(msg, kvs[i].key, kvs[i].val);
741                         assert_int_equal(ret, LDB_SUCCESS);
742                 }
743         }
744
745         return msg;
746 }
747
748 static void ldb_test_add_data(TALLOC_CTX *mem_ctx,
749                               struct ldbtest_ctx *ldb_test_ctx,
750                               const char *basedn,
751                               struct keyval *kvs)
752 {
753         TALLOC_CTX *tmp_ctx;
754         struct ldb_message *msg;
755         struct ldb_result *result = NULL;
756         int ret;
757
758         tmp_ctx = talloc_new(mem_ctx);
759         assert_non_null(tmp_ctx);
760
761         msg = build_mod_msg(tmp_ctx, ldb_test_ctx,
762                             basedn, 0, kvs);
763         assert_non_null(msg);
764
765         ret = ldb_add(ldb_test_ctx->ldb, msg);
766         assert_int_equal(ret, LDB_SUCCESS);
767
768         ret = ldb_search(ldb_test_ctx->ldb, tmp_ctx, &result, msg->dn,
769                          LDB_SCOPE_BASE, NULL, NULL);
770         assert_int_equal(ret, LDB_SUCCESS);
771         assert_non_null(result);
772         assert_int_equal(result->count, 1);
773         assert_string_equal(ldb_dn_get_linearized(result->msgs[0]->dn),
774                             ldb_dn_get_linearized(msg->dn));
775
776         talloc_free(tmp_ctx);
777 }
778
779 static void ldb_test_remove_data(TALLOC_CTX *mem_ctx,
780                                  struct ldbtest_ctx *ldb_test_ctx,
781                                  const char *strdn)
782 {
783         TALLOC_CTX *tmp_ctx;
784         struct ldb_dn *basedn;
785         int ret;
786         size_t count;
787
788         tmp_ctx = talloc_new(mem_ctx);
789         assert_non_null(tmp_ctx);
790
791         basedn = ldb_dn_new_fmt(tmp_ctx, ldb_test_ctx->ldb,
792                                 "%s", strdn);
793         assert_non_null(basedn);
794
795         ret = ldb_delete(ldb_test_ctx->ldb, basedn);
796         assert_true(ret == LDB_SUCCESS || ret == LDB_ERR_NO_SUCH_OBJECT);
797
798         count = base_search_count(ldb_test_ctx, ldb_dn_get_linearized(basedn));
799         assert_int_equal(count, 0);
800
801         talloc_free(tmp_ctx);
802 }
803
804 static void mod_test_add_data(struct ldb_mod_test_ctx *mod_test_ctx,
805                               struct keyval *kvs)
806 {
807         ldb_test_add_data(mod_test_ctx,
808                           mod_test_ctx->ldb_test_ctx,
809                           mod_test_ctx->entry_dn,
810                           kvs);
811 }
812
813 static void mod_test_remove_data(struct ldb_mod_test_ctx *mod_test_ctx)
814 {
815         ldb_test_remove_data(mod_test_ctx,
816                              mod_test_ctx->ldb_test_ctx,
817                              mod_test_ctx->entry_dn);
818 }
819
820 static struct ldb_result *run_mod_test(struct ldb_mod_test_ctx *mod_test_ctx,
821                                        int modify_flags,
822                                        struct keyval *kvs)
823 {
824         TALLOC_CTX *tmp_ctx;
825         struct ldb_result *res;
826         struct ldb_message *mod_msg;
827         struct ldb_dn *basedn;
828         struct ldbtest_ctx *ldb_test_ctx;
829         int ret;
830
831         ldb_test_ctx = mod_test_ctx->ldb_test_ctx;
832
833         tmp_ctx = talloc_new(mod_test_ctx);
834         assert_non_null(tmp_ctx);
835
836         mod_msg = build_mod_msg(tmp_ctx, ldb_test_ctx, mod_test_ctx->entry_dn,
837                                 modify_flags, kvs);
838         assert_non_null(mod_msg);
839
840         ret = ldb_modify(ldb_test_ctx->ldb, mod_msg);
841         assert_int_equal(ret, LDB_SUCCESS);
842
843         basedn = ldb_dn_new_fmt(tmp_ctx, ldb_test_ctx->ldb,
844                         "%s", mod_test_ctx->entry_dn);
845         assert_non_null(basedn);
846
847         ret = ldb_search(ldb_test_ctx->ldb, mod_test_ctx, &res, basedn,
848                          LDB_SCOPE_BASE, NULL, NULL);
849         assert_int_equal(ret, LDB_SUCCESS);
850         assert_non_null(res);
851         assert_int_equal(res->count, 1);
852         assert_string_equal(ldb_dn_get_linearized(res->msgs[0]->dn),
853                             ldb_dn_get_linearized(mod_msg->dn));
854
855         talloc_free(tmp_ctx);
856         return res;
857 }
858
859 static int ldb_modify_test_setup(void **state)
860 {
861         struct ldbtest_ctx *ldb_test_ctx;
862         struct ldb_mod_test_ctx *mod_test_ctx;
863         struct keyval kvs[] = {
864                 { "cn", "test_mod_cn" },
865                 { "objectUUID", "0123456789abcdef"},
866                 { NULL, NULL },
867         };
868
869         ldbtest_setup((void **) &ldb_test_ctx);
870
871         mod_test_ctx = talloc(ldb_test_ctx, struct ldb_mod_test_ctx);
872         assert_non_null(mod_test_ctx);
873
874         mod_test_ctx->entry_dn = "dc=mod_test_entry";
875         mod_test_ctx->ldb_test_ctx = ldb_test_ctx;
876
877         mod_test_remove_data(mod_test_ctx);
878         mod_test_add_data(mod_test_ctx, kvs);
879         *state = mod_test_ctx;
880         return 0;
881 }
882
883 static int ldb_modify_test_teardown(void **state)
884 {
885         struct ldb_mod_test_ctx *mod_test_ctx = \
886                                 talloc_get_type_abort(*state,
887                                                       struct ldb_mod_test_ctx);
888         struct ldbtest_ctx *ldb_test_ctx;
889
890         ldb_test_ctx = mod_test_ctx->ldb_test_ctx;
891
892         mod_test_remove_data(mod_test_ctx);
893         talloc_free(mod_test_ctx);
894
895         ldbtest_teardown((void **) &ldb_test_ctx);
896         return 0;
897 }
898
899 static void test_ldb_modify_add_key(void **state)
900 {
901         struct ldb_mod_test_ctx *mod_test_ctx = \
902                                 talloc_get_type_abort(*state,
903                                                       struct ldb_mod_test_ctx);
904         struct keyval mod_kvs[] = {
905                 { "name", "test_mod_name" },
906                 { NULL, NULL },
907         };
908         struct ldb_result *res;
909         struct ldb_message_element *el;
910
911         res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_ADD, mod_kvs);
912         assert_non_null(res);
913
914         /* Check cn is intact and name was added */
915         assert_int_equal(res->count, 1);
916         el = ldb_msg_find_element(res->msgs[0], "cn");
917         assert_non_null(el);
918         assert_int_equal(el->num_values, 1);
919         assert_string_equal(el->values[0].data, "test_mod_cn");
920
921         el = ldb_msg_find_element(res->msgs[0], "name");
922         assert_non_null(el);
923         assert_int_equal(el->num_values, 1);
924         assert_string_equal(el->values[0].data, "test_mod_name");
925 }
926
927 static void test_ldb_modify_extend_key(void **state)
928 {
929         struct ldb_mod_test_ctx *mod_test_ctx = \
930                         talloc_get_type_abort(*state,
931                                               struct ldb_mod_test_ctx);
932         struct keyval mod_kvs[] = {
933                 { "cn", "test_mod_cn2" },
934                 { NULL, NULL },
935         };
936         struct ldb_result *res;
937         struct ldb_message_element *el;
938
939         res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_ADD, mod_kvs);
940         assert_non_null(res);
941
942         /* Check cn was extended with another value */
943         assert_int_equal(res->count, 1);
944         el = ldb_msg_find_element(res->msgs[0], "cn");
945         assert_non_null(el);
946         assert_int_equal(el->num_values, 2);
947         assert_string_equal(el->values[0].data, "test_mod_cn");
948         assert_string_equal(el->values[1].data, "test_mod_cn2");
949 }
950
951 static void test_ldb_modify_add_key_noval(void **state)
952 {
953         struct ldb_mod_test_ctx *mod_test_ctx = \
954                         talloc_get_type_abort(*state,
955                                               struct ldb_mod_test_ctx);
956         struct ldb_message *mod_msg;
957         struct ldbtest_ctx *ldb_test_ctx;
958         struct ldb_message_element *el;
959         int ret;
960
961         ldb_test_ctx = mod_test_ctx->ldb_test_ctx;
962
963         mod_msg = ldb_msg_new(mod_test_ctx);
964         assert_non_null(mod_msg);
965
966         mod_msg->dn = ldb_dn_new_fmt(mod_msg, ldb_test_ctx->ldb,
967                         "%s", mod_test_ctx->entry_dn);
968         assert_non_null(mod_msg->dn);
969
970         el = talloc_zero(mod_msg, struct ldb_message_element);
971         el->flags = LDB_FLAG_MOD_ADD;
972         assert_non_null(el);
973         el->name = talloc_strdup(el, "cn");
974         assert_non_null(el->name);
975
976         mod_msg->elements = el;
977         mod_msg->num_elements = 1;
978
979         ret = ldb_modify(ldb_test_ctx->ldb, mod_msg);
980         assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION);
981 }
982
983 static void test_ldb_modify_replace_key(void **state)
984 {
985         struct ldb_mod_test_ctx *mod_test_ctx = \
986                         talloc_get_type_abort(*state,
987                                               struct ldb_mod_test_ctx);
988         const char *new_cn = "new_cn";
989         struct keyval mod_kvs[] = {
990                 { "cn", new_cn },
991                 { NULL, NULL },
992         };
993         struct ldb_result *res;
994         struct ldb_message_element *el;
995
996         res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, mod_kvs);
997         assert_non_null(res);
998
999         /* Check cn was replaced */
1000         assert_int_equal(res->count, 1);
1001         el = ldb_msg_find_element(res->msgs[0], "cn");
1002         assert_non_null(el);
1003         assert_int_equal(el->num_values, 1);
1004         assert_string_equal(el->values[0].data, new_cn);
1005 }
1006
1007 static void test_ldb_modify_replace_noexist_key(void **state)
1008 {
1009         struct ldb_mod_test_ctx *mod_test_ctx = \
1010                         talloc_get_type_abort(*state,
1011                                               struct ldb_mod_test_ctx);
1012         struct keyval mod_kvs[] = {
1013                 { "name", "name_val" },
1014                 { NULL, NULL },
1015         };
1016         struct ldb_result *res;
1017         struct ldb_message_element *el;
1018
1019         res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, mod_kvs);
1020         assert_non_null(res);
1021
1022         /* Check cn is intact and name was added */
1023         assert_int_equal(res->count, 1);
1024         el = ldb_msg_find_element(res->msgs[0], "cn");
1025         assert_non_null(el);
1026         assert_int_equal(el->num_values, 1);
1027         assert_string_equal(el->values[0].data, "test_mod_cn");
1028
1029         el = ldb_msg_find_element(res->msgs[0], mod_kvs[0].key);
1030         assert_non_null(el);
1031         assert_int_equal(el->num_values, 1);
1032         assert_string_equal(el->values[0].data, mod_kvs[0].val);
1033 }
1034
1035 static void test_ldb_modify_replace_zero_vals(void **state)
1036 {
1037         struct ldb_mod_test_ctx *mod_test_ctx = \
1038                         talloc_get_type_abort(*state,
1039                                               struct ldb_mod_test_ctx);
1040         struct ldb_message_element *el;
1041         struct ldb_result *res;
1042         struct keyval kvs[] = {
1043                 { "cn", NULL },
1044                 { NULL, NULL },
1045         };
1046
1047         /* cn must be gone */
1048         res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, kvs);
1049         assert_non_null(res);
1050         el = ldb_msg_find_element(res->msgs[0], "cn");
1051         assert_null(el);
1052 }
1053
1054 static void test_ldb_modify_replace_noexist_key_zero_vals(void **state)
1055 {
1056         struct ldb_mod_test_ctx *mod_test_ctx = \
1057                         talloc_get_type_abort(*state,
1058                                               struct ldb_mod_test_ctx);
1059         struct ldb_message_element *el;
1060         struct ldb_result *res;
1061         struct keyval kvs[] = {
1062                 { "noexist_key", NULL },
1063                 { NULL, NULL },
1064         };
1065
1066         /* cn must be gone */
1067         res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, kvs);
1068         assert_non_null(res);
1069
1070         /* cn should be intact */
1071         el = ldb_msg_find_element(res->msgs[0], "cn");
1072         assert_non_null(el);
1073 }
1074
1075 static void test_ldb_modify_del_key(void **state)
1076 {
1077         struct ldb_mod_test_ctx *mod_test_ctx = \
1078                         talloc_get_type_abort(*state,
1079                                               struct ldb_mod_test_ctx);
1080         struct ldb_message_element *el;
1081         struct ldb_result *res;
1082         struct keyval kvs[] = {
1083                 { "cn", NULL },
1084                 { NULL, NULL },
1085         };
1086
1087         /* cn must be gone */
1088         res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_DELETE, kvs);
1089         assert_non_null(res);
1090
1091         el = ldb_msg_find_element(res->msgs[0], "cn");
1092         assert_null(el);
1093 }
1094
1095 static void test_ldb_modify_del_keyval(void **state)
1096 {
1097         struct ldb_mod_test_ctx *mod_test_ctx = \
1098                         talloc_get_type_abort(*state,
1099                                               struct ldb_mod_test_ctx);
1100         struct ldb_message_element *el;
1101         struct ldb_result *res;
1102         struct keyval kvs[] = {
1103                 { "cn", "test_mod_cn" },
1104                 { NULL, NULL },
1105         };
1106
1107         /* cn must be gone */
1108         res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_DELETE, kvs);
1109         assert_non_null(res);
1110
1111         el = ldb_msg_find_element(res->msgs[0], "cn");
1112         assert_null(el);
1113 }
1114
1115 struct search_test_ctx {
1116         struct ldbtest_ctx *ldb_test_ctx;
1117         const char *base_dn;
1118 };
1119
1120 static char *get_full_dn(TALLOC_CTX *mem_ctx,
1121                          struct search_test_ctx *search_test_ctx,
1122                          const char *rdn)
1123 {
1124         char *full_dn;
1125
1126         full_dn = talloc_asprintf(mem_ctx,
1127                                   "%s,%s", rdn, search_test_ctx->base_dn);
1128         assert_non_null(full_dn);
1129
1130         return full_dn;
1131 }
1132
1133 static void search_test_add_data(struct search_test_ctx *search_test_ctx,
1134                                  const char *rdn,
1135                                  struct keyval *kvs)
1136 {
1137         char *full_dn;
1138
1139         full_dn = get_full_dn(search_test_ctx, search_test_ctx, rdn);
1140
1141         ldb_test_add_data(search_test_ctx,
1142                           search_test_ctx->ldb_test_ctx,
1143                           full_dn,
1144                           kvs);
1145 }
1146
1147 static void search_test_remove_data(struct search_test_ctx *search_test_ctx,
1148                                     const char *rdn)
1149 {
1150         char *full_dn;
1151
1152         full_dn = talloc_asprintf(search_test_ctx,
1153                                   "%s,%s", rdn, search_test_ctx->base_dn);
1154         assert_non_null(full_dn);
1155
1156         ldb_test_remove_data(search_test_ctx,
1157                              search_test_ctx->ldb_test_ctx,
1158                              full_dn);
1159 }
1160
1161 static int ldb_search_test_setup(void **state)
1162 {
1163         struct ldbtest_ctx *ldb_test_ctx;
1164         struct search_test_ctx *search_test_ctx;
1165         struct keyval kvs[] = {
1166                 { "cn", "test_search_cn" },
1167                 { "cn", "test_search_cn2" },
1168                 { "uid", "test_search_uid" },
1169                 { "uid", "test_search_uid2" },
1170                 { "objectUUID", "0123456789abcde0"},
1171                 { NULL, NULL },
1172         };
1173         struct keyval kvs2[] = {
1174                 { "cn", "test_search_2_cn" },
1175                 { "cn", "test_search_2_cn2" },
1176                 { "uid", "test_search_2_uid" },
1177                 { "uid", "test_search_2_uid2" },
1178                 { "objectUUID", "0123456789abcde1"},
1179                 { NULL, NULL },
1180         };
1181
1182         ldbtest_setup((void **) &ldb_test_ctx);
1183
1184         search_test_ctx = talloc(ldb_test_ctx, struct search_test_ctx);
1185         assert_non_null(search_test_ctx);
1186
1187         search_test_ctx->base_dn = "dc=search_test_entry";
1188         search_test_ctx->ldb_test_ctx = ldb_test_ctx;
1189
1190         search_test_remove_data(search_test_ctx, "cn=test_search_cn");
1191         search_test_add_data(search_test_ctx, "cn=test_search_cn", kvs);
1192
1193         search_test_remove_data(search_test_ctx, "cn=test_search_2_cn");
1194         search_test_add_data(search_test_ctx, "cn=test_search_2_cn", kvs2);
1195
1196         *state = search_test_ctx;
1197         return 0;
1198 }
1199
1200 static int ldb_search_test_teardown(void **state)
1201 {
1202         struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1203                         struct search_test_ctx);
1204         struct ldbtest_ctx *ldb_test_ctx;
1205
1206         ldb_test_ctx = search_test_ctx->ldb_test_ctx;
1207
1208         search_test_remove_data(search_test_ctx, "cn=test_search_cn");
1209         search_test_remove_data(search_test_ctx, "cn=test_search_2_cn");
1210         ldbtest_teardown((void **) &ldb_test_ctx);
1211         return 0;
1212 }
1213
1214 static void assert_attr_has_vals(struct ldb_message *msg,
1215                                  const char *attr,
1216                                  const char *vals[],
1217                                  const size_t nvals)
1218 {
1219         struct ldb_message_element *el;
1220         size_t i;
1221
1222         el = ldb_msg_find_element(msg, attr);
1223         assert_non_null(el);
1224
1225         assert_int_equal(el->num_values, nvals);
1226         for (i = 0; i < nvals; i++) {
1227                 assert_string_equal(el->values[i].data,
1228                                     vals[i]);
1229         }
1230 }
1231
1232 static void assert_has_no_attr(struct ldb_message *msg,
1233                                const char *attr)
1234 {
1235         struct ldb_message_element *el;
1236
1237         el = ldb_msg_find_element(msg, attr);
1238         assert_null(el);
1239 }
1240
1241 static bool has_dn(struct ldb_message *msg, const char *dn)
1242 {
1243         const char *msgdn;
1244
1245         msgdn = ldb_dn_get_linearized(msg->dn);
1246         if (strcmp(dn, msgdn) == 0) {
1247                 return true;
1248         }
1249
1250         return false;
1251 }
1252
1253 static void test_search_match_none(void **state)
1254 {
1255         struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1256                         struct search_test_ctx);
1257         size_t count;
1258
1259         count = base_search_count(search_test_ctx->ldb_test_ctx,
1260                                   "dc=no_such_entry");
1261         assert_int_equal(count, 0);
1262 }
1263
1264 static void test_search_match_one(void **state)
1265 {
1266         struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1267                         struct search_test_ctx);
1268         int ret;
1269         struct ldb_dn *basedn;
1270         struct ldb_result *result = NULL;
1271         const char *cn_vals[] = { "test_search_cn",
1272                                   "test_search_cn2" };
1273         const char *uid_vals[] = { "test_search_uid",
1274                                    "test_search_uid2" };
1275
1276         basedn = ldb_dn_new_fmt(search_test_ctx,
1277                                 search_test_ctx->ldb_test_ctx->ldb,
1278                                 "%s",
1279                                 search_test_ctx->base_dn);
1280         assert_non_null(basedn);
1281
1282         ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
1283                          search_test_ctx,
1284                          &result,
1285                          basedn,
1286                          LDB_SCOPE_SUBTREE, NULL,
1287                          "cn=test_search_cn");
1288         assert_int_equal(ret, 0);
1289         assert_non_null(result);
1290         assert_int_equal(result->count, 1);
1291
1292         assert_attr_has_vals(result->msgs[0], "cn", cn_vals, 2);
1293         assert_attr_has_vals(result->msgs[0], "uid", uid_vals, 2);
1294 }
1295
1296 static void test_search_match_filter(void **state)
1297 {
1298         struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1299                         struct search_test_ctx);
1300         int ret;
1301         struct ldb_dn *basedn;
1302         struct ldb_result *result = NULL;
1303         const char *cn_vals[] = { "test_search_cn",
1304                                   "test_search_cn2" };
1305         const char *attrs[] = { "cn", NULL };
1306
1307         basedn = ldb_dn_new_fmt(search_test_ctx,
1308                                 search_test_ctx->ldb_test_ctx->ldb,
1309                                 "%s",
1310                                 search_test_ctx->base_dn);
1311         assert_non_null(basedn);
1312
1313         ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
1314                          search_test_ctx,
1315                          &result,
1316                          basedn,
1317                          LDB_SCOPE_SUBTREE,
1318                          attrs,
1319                          "cn=test_search_cn");
1320         assert_int_equal(ret, 0);
1321         assert_non_null(result);
1322         assert_int_equal(result->count, 1);
1323
1324         assert_attr_has_vals(result->msgs[0], "cn", cn_vals, 2);
1325         assert_has_no_attr(result->msgs[0], "uid");
1326 }
1327
1328 static void assert_expected(struct search_test_ctx *search_test_ctx,
1329                             struct ldb_message *msg)
1330 {
1331         char *full_dn1;
1332         char *full_dn2;
1333         const char *cn_vals[] = { "test_search_cn",
1334                                   "test_search_cn2" };
1335         const char *uid_vals[] = { "test_search_uid",
1336                                    "test_search_uid2" };
1337         const char *cn2_vals[] = { "test_search_2_cn",
1338                                    "test_search_2_cn2" };
1339         const char *uid2_vals[] = { "test_search_2_uid",
1340                                     "test_search_2_uid2" };
1341
1342         full_dn1 = get_full_dn(search_test_ctx,
1343                                search_test_ctx,
1344                                "cn=test_search_cn");
1345
1346         full_dn2 = get_full_dn(search_test_ctx,
1347                                search_test_ctx,
1348                                "cn=test_search_2_cn");
1349
1350         if (has_dn(msg, full_dn1) == true) {
1351                 assert_attr_has_vals(msg, "cn", cn_vals, 2);
1352                 assert_attr_has_vals(msg, "uid", uid_vals, 2);
1353         } else if (has_dn(msg, full_dn2) == true) {
1354                 assert_attr_has_vals(msg, "cn", cn2_vals, 2);
1355                 assert_attr_has_vals(msg, "uid", uid2_vals, 2);
1356         } else {
1357                 fail();
1358         }
1359 }
1360
1361 static void test_search_match_both(void **state)
1362 {
1363         struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1364                         struct search_test_ctx);
1365         int ret;
1366         struct ldb_dn *basedn;
1367         struct ldb_result *result = NULL;
1368
1369         basedn = ldb_dn_new_fmt(search_test_ctx,
1370                                 search_test_ctx->ldb_test_ctx->ldb,
1371                                 "%s",
1372                                 search_test_ctx->base_dn);
1373         assert_non_null(basedn);
1374
1375         ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
1376                          search_test_ctx,
1377                          &result,
1378                          basedn,
1379                          LDB_SCOPE_SUBTREE, NULL,
1380                          "cn=test_search_*");
1381         assert_int_equal(ret, 0);
1382         assert_non_null(result);
1383         assert_int_equal(result->count, 2);
1384
1385         assert_expected(search_test_ctx, result->msgs[0]);
1386         assert_expected(search_test_ctx, result->msgs[1]);
1387 }
1388
1389 static void test_search_match_basedn(void **state)
1390 {
1391         struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1392                         struct search_test_ctx);
1393         int ret;
1394         struct ldb_dn *basedn;
1395         struct ldb_result *result = NULL;
1396         struct ldb_message *msg;
1397
1398         basedn = ldb_dn_new_fmt(search_test_ctx,
1399                                 search_test_ctx->ldb_test_ctx->ldb,
1400                                 "dc=nosuchdn");
1401         assert_non_null(basedn);
1402
1403         ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
1404                          search_test_ctx,
1405                          &result,
1406                          basedn,
1407                          LDB_SCOPE_SUBTREE, NULL,
1408                          "cn=*");
1409         assert_int_equal(ret, 0);
1410
1411         /* Add 'checkBaseOnSearch' to @OPTIONS */
1412         msg = ldb_msg_new(search_test_ctx);
1413         assert_non_null(msg);
1414
1415         msg->dn = ldb_dn_new_fmt(msg,
1416                                  search_test_ctx->ldb_test_ctx->ldb,
1417                                  "@OPTIONS");
1418         assert_non_null(msg->dn);
1419
1420         ret = ldb_msg_add_string(msg, "checkBaseOnSearch", "TRUE");
1421         assert_int_equal(ret, 0);
1422
1423         ret = ldb_add(search_test_ctx->ldb_test_ctx->ldb, msg);
1424         assert_int_equal(ret, 0);
1425
1426         /* Search again */
1427         /* The search should return LDB_ERR_NO_SUCH_OBJECT */
1428         ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
1429                          search_test_ctx,
1430                          &result,
1431                          basedn,
1432                          LDB_SCOPE_SUBTREE, NULL,
1433                          "cn=*");
1434         assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT);
1435
1436         ret = ldb_delete(search_test_ctx->ldb_test_ctx->ldb, msg->dn);
1437         assert_int_equal(ret, 0);
1438 }
1439
1440
1441 /*
1442  * This test is complex.
1443  * The purpose is to test for a deadlock detected between ldb_search()
1444  * and ldb_transaction_commit().  The deadlock happens if in process
1445  * (1) and (2):
1446  *  - (1) the all-record lock is taken in ltdb_search()
1447  *  - (2) the ldb_transaction_start() call is made
1448  *  - (1) an un-indexed search starts (forced here by doing it in
1449  *        the callback
1450  *  - (2) the ldb_transaction_commit() is called.
1451  *        This returns LDB_ERR_BUSY if the deadlock is detected
1452  *
1453  * With ldb 1.1.31 and tdb 1.3.12 we avoid this only due to a missing
1454  * lock call in ltdb_search() due to a refcounting bug in
1455  * ltdb_lock_read()
1456  */
1457
1458 struct search_against_transaction_ctx {
1459         struct ldbtest_ctx *test_ctx;
1460         int res_count;
1461         pid_t child_pid;
1462         struct ldb_dn *basedn;
1463 };
1464
1465 static int test_ldb_search_against_transaction_callback2(struct ldb_request *req,
1466                                                          struct ldb_reply *ares)
1467 {
1468         struct search_against_transaction_ctx *ctx = req->context;
1469         switch (ares->type) {
1470         case LDB_REPLY_ENTRY:
1471                 ctx->res_count++;
1472                 if (ctx->res_count != 1) {
1473                         return LDB_SUCCESS;
1474                 }
1475
1476                 break;
1477
1478         case LDB_REPLY_REFERRAL:
1479                 break;
1480
1481         case LDB_REPLY_DONE:
1482                 return ldb_request_done(req, LDB_SUCCESS);
1483         }
1484
1485         return 0;
1486
1487 }
1488
1489 /*
1490  * This purpose of this callback is to trigger a transaction in
1491  * the child process while the all-record lock is held, but before
1492  * we take any locks in the tdb_traverse_read() handler.
1493  *
1494  * In tdb 1.3.12 tdb_traverse_read() take the read transaction lock
1495  * however in ldb 1.1.31 ltdb_search() forgets to take the all-record
1496  * lock (except the very first time) due to a ref-counting bug.
1497  *
1498  */
1499
1500 static int test_ldb_search_against_transaction_callback1(struct ldb_request *req,
1501                                                          struct ldb_reply *ares)
1502 {
1503         int ret, ret2;
1504         int pipes[2];
1505         char buf[2];
1506         struct search_against_transaction_ctx *ctx = req->context;
1507         switch (ares->type) {
1508         case LDB_REPLY_ENTRY:
1509                 break;
1510
1511         case LDB_REPLY_REFERRAL:
1512                 return LDB_SUCCESS;
1513
1514         case LDB_REPLY_DONE:
1515                 return ldb_request_done(req, LDB_SUCCESS);
1516         }
1517
1518         ret = pipe(pipes);
1519         assert_int_equal(ret, 0);
1520
1521         ctx->child_pid = fork();
1522         if (ctx->child_pid == 0) {
1523                 TALLOC_CTX *tmp_ctx = NULL;
1524                 struct ldb_message *msg;
1525                 TALLOC_FREE(ctx->test_ctx->ldb);
1526                 TALLOC_FREE(ctx->test_ctx->ev);
1527                 close(pipes[0]);
1528                 ctx->test_ctx->ev = tevent_context_init(ctx->test_ctx);
1529                 if (ctx->test_ctx->ev == NULL) {
1530                         exit(LDB_ERR_OPERATIONS_ERROR);
1531                 }
1532
1533                 ctx->test_ctx->ldb = ldb_init(ctx->test_ctx,
1534                                               ctx->test_ctx->ev);
1535                 if (ctx->test_ctx->ldb == NULL) {
1536                         exit(LDB_ERR_OPERATIONS_ERROR);
1537                 }
1538
1539                 ret = ldb_connect(ctx->test_ctx->ldb,
1540                                   ctx->test_ctx->dbpath, 0, NULL);
1541                 if (ret != LDB_SUCCESS) {
1542                         exit(ret);
1543                 }
1544
1545                 tmp_ctx = talloc_new(ctx->test_ctx);
1546                 if (tmp_ctx == NULL) {
1547                         exit(LDB_ERR_OPERATIONS_ERROR);
1548                 }
1549
1550                 msg = ldb_msg_new(tmp_ctx);
1551                 if (msg == NULL) {
1552                         exit(LDB_ERR_OPERATIONS_ERROR);
1553                 }
1554
1555                 msg->dn = ldb_dn_new_fmt(msg, ctx->test_ctx->ldb,
1556                                          "dc=test");
1557                 if (msg->dn == NULL) {
1558                         exit(LDB_ERR_OPERATIONS_ERROR);
1559                 }
1560
1561                 ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
1562                 if (ret != 0) {
1563                         exit(LDB_ERR_OPERATIONS_ERROR);
1564                 }
1565
1566                 ret = ldb_transaction_start(ctx->test_ctx->ldb);
1567                 if (ret != 0) {
1568                         exit(ret);
1569                 }
1570
1571                 ret = write(pipes[1], "GO", 2);
1572                 if (ret != 2) {
1573                         exit(LDB_ERR_OPERATIONS_ERROR);
1574                 }
1575
1576                 ret = ldb_msg_add_string(msg, "objectUUID",
1577                                          "0123456789abcdef");
1578                 if (ret != 0) {
1579                         exit(ret);
1580                 }
1581
1582                 ret = ldb_add(ctx->test_ctx->ldb, msg);
1583                 if (ret != 0) {
1584                         exit(ret);
1585                 }
1586
1587                 ret = ldb_transaction_commit(ctx->test_ctx->ldb);
1588                 exit(ret);
1589         }
1590         close(pipes[1]);
1591         ret = read(pipes[0], buf, 2);
1592         assert_int_equal(ret, 2);
1593
1594         /* This search must be unindexed (ie traverse in tdb) */
1595         ret = ldb_build_search_req(&req,
1596                                    ctx->test_ctx->ldb,
1597                                    ctx->test_ctx,
1598                                    ctx->basedn,
1599                                    LDB_SCOPE_SUBTREE,
1600                                    "cn=*", NULL,
1601                                    NULL,
1602                                    ctx,
1603                                    test_ldb_search_against_transaction_callback2,
1604                                    NULL);
1605         /*
1606          * we don't assert on these return codes until after the search is
1607          * finished, or the clean up will fail because we hold locks.
1608          */
1609
1610         ret2 = ldb_request(ctx->test_ctx->ldb, req);
1611
1612         if (ret2 == LDB_SUCCESS) {
1613                 ret2 = ldb_wait(req->handle, LDB_WAIT_ALL);
1614         }
1615         assert_int_equal(ret, 0);
1616         assert_int_equal(ret2, 0);
1617         assert_int_equal(ctx->res_count, 2);
1618
1619         return LDB_SUCCESS;
1620 }
1621
1622 static void test_ldb_search_against_transaction(void **state)
1623 {
1624         struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1625                         struct search_test_ctx);
1626         struct search_against_transaction_ctx
1627                 ctx =
1628                 { .res_count = 0,
1629                   .test_ctx = search_test_ctx->ldb_test_ctx
1630                 };
1631
1632         int ret;
1633         struct ldb_request *req;
1634         pid_t pid;
1635         int wstatus;
1636         struct ldb_dn *base_search_dn;
1637
1638         tevent_loop_allow_nesting(search_test_ctx->ldb_test_ctx->ev);
1639
1640         base_search_dn
1641                 = ldb_dn_new_fmt(search_test_ctx,
1642                                  search_test_ctx->ldb_test_ctx->ldb,
1643                                  "cn=test_search_cn,%s",
1644                                  search_test_ctx->base_dn);
1645         assert_non_null(base_search_dn);
1646
1647         ctx.basedn
1648                 = ldb_dn_new_fmt(search_test_ctx,
1649                                  search_test_ctx->ldb_test_ctx->ldb,
1650                                  "%s",
1651                                  search_test_ctx->base_dn);
1652         assert_non_null(ctx.basedn);
1653
1654
1655         /* This search must be indexed (ie no traverse in tdb) */
1656         ret = ldb_build_search_req(&req,
1657                                    search_test_ctx->ldb_test_ctx->ldb,
1658                                    search_test_ctx,
1659                                    base_search_dn,
1660                                    LDB_SCOPE_BASE,
1661                                    "cn=*", NULL,
1662                                    NULL,
1663                                    &ctx,
1664                                    test_ldb_search_against_transaction_callback1,
1665                                    NULL);
1666         assert_int_equal(ret, 0);
1667         ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req);
1668
1669         if (ret == LDB_SUCCESS) {
1670                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1671         }
1672         assert_int_equal(ret, 0);
1673         assert_int_equal(ctx.res_count, 2);
1674
1675         pid = waitpid(ctx.child_pid, &wstatus, 0);
1676         assert_int_equal(pid, ctx.child_pid);
1677
1678         assert_true(WIFEXITED(wstatus));
1679
1680         assert_int_equal(WEXITSTATUS(wstatus), 0);
1681
1682
1683 }
1684
1685 /*
1686  * This test is also complex.
1687  * The purpose is to test if a modify can occur during an ldb_search()
1688  * This would be a failure if if in process
1689  * (1) and (2):
1690  *  - (1) ltdb_search() starts and calls back for one entry
1691  *  - (2) one of the entries to be matched is modified
1692  *  - (1) the indexed search tries to return the modified entry, but
1693  *        it is no longer found, either:
1694  *          - despite it still matching (dn changed)
1695  *          - it no longer matching (attrs changed)
1696  *
1697  * We also try un-indexed to show that the behaviour differs on this
1698  * point, which it should not (an index should only impact search
1699  * speed).
1700  */
1701
1702 struct modify_during_search_test_ctx {
1703         struct ldbtest_ctx *test_ctx;
1704         int res_count;
1705         pid_t child_pid;
1706         struct ldb_dn *basedn;
1707         bool got_cn;
1708         bool got_2_cn;
1709         bool rename;
1710 };
1711
1712 /*
1713  * This purpose of this callback is to trigger a write in
1714  * the child process while a search is in progress.
1715  *
1716  * In tdb 1.3.12 tdb_traverse_read() take the read transaction lock
1717  * however in ldb 1.1.31 ltdb_search() forgets to take the all-record
1718  * lock (except the very first time) due to a ref-counting bug.
1719  *
1720  * We assume that if the write will proceed, it will proceed in a 3
1721  * second window after the function is called.
1722  */
1723
1724 static int test_ldb_modify_during_search_callback1(struct ldb_request *req,
1725                                                    struct ldb_reply *ares)
1726 {
1727         int ret;
1728         int pipes[2];
1729         char buf[2];
1730         struct modify_during_search_test_ctx *ctx = req->context;
1731         switch (ares->type) {
1732         case LDB_REPLY_ENTRY:
1733         {
1734                 const struct ldb_val *cn_val
1735                         = ldb_dn_get_component_val(ares->message->dn, 0);
1736                 const char *cn = (char *)cn_val->data;
1737                 ctx->res_count++;
1738                 if (strcmp(cn, "test_search_cn") == 0) {
1739                         ctx->got_cn = true;
1740                 } else if (strcmp(cn, "test_search_2_cn") == 0) {
1741                         ctx->got_2_cn = true;
1742                 }
1743                 if (ctx->res_count == 2) {
1744                         return LDB_SUCCESS;
1745                 }
1746                 break;
1747         }
1748         case LDB_REPLY_REFERRAL:
1749                 return LDB_SUCCESS;
1750
1751         case LDB_REPLY_DONE:
1752                 return ldb_request_done(req, LDB_SUCCESS);
1753         }
1754
1755         ret = pipe(pipes);
1756         assert_int_equal(ret, 0);
1757
1758         ctx->child_pid = fork();
1759         if (ctx->child_pid == 0 && ctx->rename) {
1760                 TALLOC_CTX *tmp_ctx = NULL;
1761                 struct ldb_dn *dn, *new_dn;
1762                 TALLOC_FREE(ctx->test_ctx->ldb);
1763                 TALLOC_FREE(ctx->test_ctx->ev);
1764                 close(pipes[0]);
1765                 ctx->test_ctx->ev = tevent_context_init(ctx->test_ctx);
1766                 if (ctx->test_ctx->ev == NULL) {
1767                         exit(LDB_ERR_OPERATIONS_ERROR);
1768                 }
1769
1770                 ctx->test_ctx->ldb = ldb_init(ctx->test_ctx,
1771                                               ctx->test_ctx->ev);
1772                 if (ctx->test_ctx->ldb == NULL) {
1773                         exit(LDB_ERR_OPERATIONS_ERROR);
1774                 }
1775
1776                 ret = ldb_connect(ctx->test_ctx->ldb,
1777                                   ctx->test_ctx->dbpath, 0, NULL);
1778                 if (ret != LDB_SUCCESS) {
1779                         exit(ret);
1780                 }
1781
1782                 tmp_ctx = talloc_new(ctx->test_ctx);
1783                 if (tmp_ctx == NULL) {
1784                         exit(LDB_ERR_OPERATIONS_ERROR);
1785                 }
1786
1787                 if (ctx->got_cn) {
1788                         /* Modify the other one */
1789                         dn = ldb_dn_new_fmt(tmp_ctx, ctx->test_ctx->ldb,
1790                                             "cn=test_search_2_cn,"
1791                                             "dc=search_test_entry");
1792                 } else {
1793                         dn = ldb_dn_new_fmt(tmp_ctx, ctx->test_ctx->ldb,
1794                                             "cn=test_search_cn,"
1795                                             "dc=search_test_entry");
1796                 }
1797                 if (dn == NULL) {
1798                         exit(LDB_ERR_OPERATIONS_ERROR);
1799                 }
1800
1801                 new_dn = ldb_dn_new_fmt(tmp_ctx, ctx->test_ctx->ldb,
1802                                         "cn=test_search_cn_renamed,"
1803                                         "dc=search_test_entry");
1804                 if (new_dn == NULL) {
1805                         exit(LDB_ERR_OPERATIONS_ERROR);
1806                 }
1807
1808                 ret = ldb_transaction_start(ctx->test_ctx->ldb);
1809                 if (ret != 0) {
1810                         exit(ret);
1811                 }
1812
1813                 if (write(pipes[1], "GO", 2) != 2) {
1814                         exit(LDB_ERR_OPERATIONS_ERROR);
1815                 }
1816
1817                 ret = ldb_rename(ctx->test_ctx->ldb, dn, new_dn);
1818                 if (ret != 0) {
1819                         exit(ret);
1820                 }
1821
1822                 ret = ldb_transaction_commit(ctx->test_ctx->ldb);
1823                 exit(ret);
1824
1825         } else if (ctx->child_pid == 0) {
1826                 TALLOC_CTX *tmp_ctx = NULL;
1827                 struct ldb_message *msg;
1828                 struct ldb_message_element *el;
1829                 TALLOC_FREE(ctx->test_ctx->ldb);
1830                 TALLOC_FREE(ctx->test_ctx->ev);
1831                 close(pipes[0]);
1832                 ctx->test_ctx->ev = tevent_context_init(ctx->test_ctx);
1833                 if (ctx->test_ctx->ev == NULL) {
1834                         exit(LDB_ERR_OPERATIONS_ERROR);
1835                 }
1836
1837                 ctx->test_ctx->ldb = ldb_init(ctx->test_ctx,
1838                                               ctx->test_ctx->ev);
1839                 if (ctx->test_ctx->ldb == NULL) {
1840                         exit(LDB_ERR_OPERATIONS_ERROR);
1841                 }
1842
1843                 ret = ldb_connect(ctx->test_ctx->ldb,
1844                                   ctx->test_ctx->dbpath, 0, NULL);
1845                 if (ret != LDB_SUCCESS) {
1846                         exit(ret);
1847                 }
1848
1849                 tmp_ctx = talloc_new(ctx->test_ctx);
1850                 if (tmp_ctx == NULL) {
1851                         exit(LDB_ERR_OPERATIONS_ERROR);
1852                 }
1853
1854                 msg = ldb_msg_new(tmp_ctx);
1855                 if (msg == NULL) {
1856                         exit(LDB_ERR_OPERATIONS_ERROR);
1857                 }
1858
1859                 if (ctx->got_cn) {
1860                         /* Modify the other one */
1861                         msg->dn = ldb_dn_new_fmt(msg, ctx->test_ctx->ldb,
1862                                                  "cn=test_search_2_cn,"
1863                                                  "dc=search_test_entry");
1864                 } else {
1865                         msg->dn = ldb_dn_new_fmt(msg, ctx->test_ctx->ldb,
1866                                                  "cn=test_search_cn,"
1867                                                  "dc=search_test_entry");
1868                 }
1869                 if (msg->dn == NULL) {
1870                         exit(LDB_ERR_OPERATIONS_ERROR);
1871                 }
1872
1873                 ret = ldb_msg_add_string(msg, "filterAttr", "TRUE");
1874                 if (ret != 0) {
1875                         exit(LDB_ERR_OPERATIONS_ERROR);
1876                 }
1877                 el = ldb_msg_find_element(msg, "filterAttr");
1878                 if (el == NULL) {
1879                         exit(LDB_ERR_OPERATIONS_ERROR);
1880                 }
1881                 el->flags = LDB_FLAG_MOD_REPLACE;
1882
1883                 ret = ldb_transaction_start(ctx->test_ctx->ldb);
1884                 if (ret != 0) {
1885                         exit(ret);
1886                 }
1887
1888                 if (write(pipes[1], "GO", 2) != 2) {
1889                         exit(LDB_ERR_OPERATIONS_ERROR);
1890                 }
1891
1892                 ret = ldb_modify(ctx->test_ctx->ldb, msg);
1893                 if (ret != 0) {
1894                         exit(ret);
1895                 }
1896
1897                 ret = ldb_transaction_commit(ctx->test_ctx->ldb);
1898                 exit(ret);
1899         }
1900
1901         /*
1902          * With TDB 1.3.13 and before "tdb: Remove locking from tdb_traverse_read()"
1903          * we will hang here because the child process can not proceed to
1904          * sending the "GO" as it is blocked at ldb_transaction_start().
1905          */
1906
1907         close(pipes[1]);
1908         ret = read(pipes[0], buf, 2);
1909         assert_int_equal(ret, 2);
1910
1911         sleep(3);
1912
1913         return LDB_SUCCESS;
1914 }
1915
1916 static void test_ldb_modify_during_search(void **state, bool add_index,
1917                                           bool rename)
1918 {
1919         struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1920                         struct search_test_ctx);
1921         struct modify_during_search_test_ctx
1922                 ctx =
1923                 { .res_count = 0,
1924                   .test_ctx = search_test_ctx->ldb_test_ctx,
1925                   .rename = rename
1926                 };
1927
1928         int ret;
1929         struct ldb_request *req;
1930         pid_t pid;
1931         int wstatus;
1932
1933         if (add_index) {
1934                 struct ldb_message *msg;
1935                 struct ldb_dn *indexlist = ldb_dn_new(search_test_ctx,
1936                                                       search_test_ctx->ldb_test_ctx->ldb,
1937                                                       "@INDEXLIST");
1938                 assert_non_null(indexlist);
1939
1940                 msg = ldb_msg_new(search_test_ctx);
1941                 assert_non_null(msg);
1942
1943                 msg->dn = indexlist;
1944
1945                 ret = ldb_msg_add_string(msg, "@IDXATTR", "cn");
1946                 assert_int_equal(ret, LDB_SUCCESS);
1947                 ret = ldb_add(search_test_ctx->ldb_test_ctx->ldb,
1948                               msg);
1949                 if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) {
1950                         msg->elements[0].flags = LDB_FLAG_MOD_ADD;
1951                         ret = ldb_modify(search_test_ctx->ldb_test_ctx->ldb,
1952                                          msg);
1953                 }
1954                 assert_int_equal(ret, LDB_SUCCESS);
1955         }
1956
1957         tevent_loop_allow_nesting(search_test_ctx->ldb_test_ctx->ev);
1958
1959         ctx.basedn
1960                 = ldb_dn_new_fmt(search_test_ctx,
1961                                  search_test_ctx->ldb_test_ctx->ldb,
1962                                  "%s",
1963                                  search_test_ctx->base_dn);
1964         assert_non_null(ctx.basedn);
1965
1966
1967         /*
1968          * This search must be over multiple items, and should include
1969          * the new name after a rename, to show that it would match
1970          * both before and after that modify
1971          */
1972         ret = ldb_build_search_req(&req,
1973                                    search_test_ctx->ldb_test_ctx->ldb,
1974                                    search_test_ctx,
1975                                    ctx.basedn,
1976                                    LDB_SCOPE_SUBTREE,
1977                                    "(&(!(filterAttr=*))"
1978                                      "(|(cn=test_search_cn_renamed)"
1979                                        "(cn=test_search_cn)"
1980                                        "(cn=test_search_2_cn)"
1981                                    "))",
1982                                    NULL,
1983                                    NULL,
1984                                    &ctx,
1985                                    test_ldb_modify_during_search_callback1,
1986                                    NULL);
1987         assert_int_equal(ret, 0);
1988         ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req);
1989
1990         if (ret == LDB_SUCCESS) {
1991                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1992         }
1993         assert_int_equal(ret, 0);
1994         assert_int_equal(ctx.res_count, 2);
1995         assert_int_equal(ctx.got_cn, true);
1996         assert_int_equal(ctx.got_2_cn, true);
1997
1998         pid = waitpid(ctx.child_pid, &wstatus, 0);
1999         assert_int_equal(pid, ctx.child_pid);
2000
2001         assert_true(WIFEXITED(wstatus));
2002
2003         assert_int_equal(WEXITSTATUS(wstatus), 0);
2004
2005
2006 }
2007
2008 static void test_ldb_modify_during_indexed_search(void **state)
2009 {
2010         test_ldb_modify_during_search(state, true, false);
2011 }
2012
2013 static void test_ldb_modify_during_unindexed_search(void **state)
2014 {
2015         test_ldb_modify_during_search(state, false, false);
2016 }
2017
2018 static void test_ldb_rename_during_indexed_search(void **state)
2019 {
2020         test_ldb_modify_during_search(state, true, true);
2021 }
2022
2023 static void test_ldb_rename_during_unindexed_search(void **state)
2024 {
2025         test_ldb_modify_during_search(state, false, true);
2026 }
2027
2028 /*
2029  * This test is also complex.
2030  *
2031  * The purpose is to test if a modify can occur during an ldb_search()
2032  * before the end of the callback
2033  *
2034  * This would be a failure if if in process
2035  * (1) and (2):
2036  *  - (1) ldb_search() starts and calls back for a number of entries
2037  *  - (2) an entry in the DB is allowed to change before the callback returns
2038  *  - (1) the callback can see the modification
2039  *
2040  */
2041
2042 /*
2043  * This purpose of this callback is to trigger a write in
2044  * the child process while a search DONE callback is in progress.
2045  *
2046  * In ldb 1.1.31 ldb_search() omitted to take a all-record
2047  * lock for the full duration of the search and callbacks
2048  *
2049  * We assume that if the write will proceed, it will proceed in a 3
2050  * second window after the function is called.
2051  */
2052
2053 static int test_ldb_modify_during_whole_search_callback1(struct ldb_request *req,
2054                                                          struct ldb_reply *ares)
2055 {
2056         int ret;
2057         int pipes[2];
2058         char buf[2];
2059         struct modify_during_search_test_ctx *ctx = req->context;
2060         struct ldb_dn *search_dn;
2061         struct ldb_result *res2;
2062         unsigned res_count;
2063         switch (ares->type) {
2064         case LDB_REPLY_ENTRY:
2065         case LDB_REPLY_REFERRAL:
2066                 return LDB_SUCCESS;
2067
2068         case LDB_REPLY_DONE:
2069                 break;
2070         }
2071
2072         ret = pipe(pipes);
2073         assert_int_equal(ret, 0);
2074
2075         ctx->child_pid = fork();
2076         if (ctx->child_pid == 0) {
2077                 TALLOC_CTX *tmp_ctx = NULL;
2078                 struct ldb_message *msg;
2079                 struct ldb_message_element *el;
2080                 TALLOC_FREE(ctx->test_ctx->ldb);
2081                 TALLOC_FREE(ctx->test_ctx->ev);
2082                 close(pipes[0]);
2083                 ctx->test_ctx->ev = tevent_context_init(ctx->test_ctx);
2084                 if (ctx->test_ctx->ev == NULL) {
2085                         exit(LDB_ERR_OPERATIONS_ERROR);
2086                 }
2087
2088                 ctx->test_ctx->ldb = ldb_init(ctx->test_ctx,
2089                                               ctx->test_ctx->ev);
2090                 if (ctx->test_ctx->ldb == NULL) {
2091                         exit(LDB_ERR_OPERATIONS_ERROR);
2092                 }
2093
2094                 ret = ldb_connect(ctx->test_ctx->ldb,
2095                                   ctx->test_ctx->dbpath, 0, NULL);
2096                 if (ret != LDB_SUCCESS) {
2097                         exit(ret);
2098                 }
2099
2100                 tmp_ctx = talloc_new(ctx->test_ctx);
2101                 if (tmp_ctx == NULL) {
2102                         exit(LDB_ERR_OPERATIONS_ERROR);
2103                 }
2104
2105                 msg = ldb_msg_new(tmp_ctx);
2106                 if (msg == NULL) {
2107                         exit(LDB_ERR_OPERATIONS_ERROR);
2108                 }
2109
2110                 msg->dn = ldb_dn_new_fmt(msg, ctx->test_ctx->ldb,
2111                                          "cn=test_search_cn,"
2112                                          "dc=search_test_entry");
2113                 if (msg->dn == NULL) {
2114                         exit(LDB_ERR_OPERATIONS_ERROR);
2115                 }
2116
2117                 ret = ldb_msg_add_string(msg, "filterAttr", "TRUE");
2118                 if (ret != 0) {
2119                         exit(LDB_ERR_OPERATIONS_ERROR);
2120                 }
2121                 el = ldb_msg_find_element(msg, "filterAttr");
2122                 if (el == NULL) {
2123                         exit(LDB_ERR_OPERATIONS_ERROR);
2124                 }
2125                 el->flags = LDB_FLAG_MOD_REPLACE;
2126
2127                 ret = ldb_transaction_start(ctx->test_ctx->ldb);
2128                 if (ret != 0) {
2129                         exit(ret);
2130                 }
2131
2132                 if (write(pipes[1], "GO", 2) != 2) {
2133                         exit(LDB_ERR_OPERATIONS_ERROR);
2134                 }
2135
2136                 ret = ldb_modify(ctx->test_ctx->ldb, msg);
2137                 if (ret != 0) {
2138                         exit(ret);
2139                 }
2140
2141                 ret = ldb_transaction_commit(ctx->test_ctx->ldb);
2142                 exit(ret);
2143         }
2144
2145         close(pipes[1]);
2146         ret = read(pipes[0], buf, 2);
2147         assert_int_equal(ret, 2);
2148
2149         sleep(3);
2150
2151         /*
2152          * If writes are not blocked until after this function, we
2153          * will be able to successfully search for this modification
2154          * here
2155          */
2156
2157         search_dn = ldb_dn_new_fmt(ares, ctx->test_ctx->ldb,
2158                                    "cn=test_search_cn,"
2159                                    "dc=search_test_entry");
2160
2161         ret = ldb_search(ctx->test_ctx->ldb, ares,
2162                          &res2, search_dn, LDB_SCOPE_BASE, NULL,
2163                          "filterAttr=TRUE");
2164
2165         /*
2166          * We do this in an unusual order, because if we fail an assert before
2167          * ldb_request_done(), we will also fail to clean up as we hold locks.
2168          */
2169
2170         res_count = res2->count;
2171         ldb_request_done(req, LDB_SUCCESS);
2172         assert_int_equal(ret, 0);
2173
2174         /* We should not have got the result */
2175         assert_int_equal(res_count, 0);
2176
2177         return ret;
2178 }
2179
2180 static void test_ldb_modify_during_whole_search(void **state)
2181 {
2182         struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
2183                         struct search_test_ctx);
2184         struct modify_during_search_test_ctx
2185                 ctx =
2186                 {
2187                   .test_ctx = search_test_ctx->ldb_test_ctx,
2188                 };
2189
2190         int ret;
2191         struct ldb_request *req;
2192         pid_t pid;
2193         int wstatus;
2194         struct ldb_dn *search_dn;
2195         struct ldb_result *res2;
2196
2197         tevent_loop_allow_nesting(search_test_ctx->ldb_test_ctx->ev);
2198
2199         ctx.basedn
2200                 = ldb_dn_new_fmt(search_test_ctx,
2201                                  search_test_ctx->ldb_test_ctx->ldb,
2202                                  "%s",
2203                                  search_test_ctx->base_dn);
2204         assert_non_null(ctx.basedn);
2205
2206
2207         /*
2208          * The search just needs to call DONE, we don't care about the
2209          * contents of the search for this test
2210          */
2211         ret = ldb_build_search_req(&req,
2212                                    search_test_ctx->ldb_test_ctx->ldb,
2213                                    search_test_ctx,
2214                                    ctx.basedn,
2215                                    LDB_SCOPE_SUBTREE,
2216                                    "(&(!(filterAttr=*))"
2217                                    "(cn=test_search_cn))",
2218                                    NULL,
2219                                    NULL,
2220                                    &ctx,
2221                                    test_ldb_modify_during_whole_search_callback1,
2222                                    NULL);
2223         assert_int_equal(ret, 0);
2224         ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req);
2225
2226         if (ret == LDB_SUCCESS) {
2227                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
2228         }
2229         assert_int_equal(ret, 0);
2230
2231         pid = waitpid(ctx.child_pid, &wstatus, 0);
2232         assert_int_equal(pid, ctx.child_pid);
2233
2234         assert_true(WIFEXITED(wstatus));
2235
2236         assert_int_equal(WEXITSTATUS(wstatus), 0);
2237
2238         /*
2239          * If writes are blocked until after the search function, we
2240          * will be able to successfully search for this modification
2241          * now
2242          */
2243
2244         search_dn = ldb_dn_new_fmt(search_test_ctx,
2245                                    search_test_ctx->ldb_test_ctx->ldb,
2246                                    "cn=test_search_cn,"
2247                                    "dc=search_test_entry");
2248
2249         ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
2250                          search_test_ctx,
2251                          &res2, search_dn, LDB_SCOPE_BASE, NULL,
2252                          "filterAttr=TRUE");
2253         assert_int_equal(ret, 0);
2254
2255         /* We got the result */
2256         assert_int_equal(res2->count, 1);
2257 }
2258
2259 /*
2260  * This test is also complex.
2261  *
2262  * The purpose is to test if a modify can occur during an ldb_search()
2263  * before the request is destroyed with TALLOC_FREE()
2264  *
2265  * This would be a failure if in process
2266  * (1) and (2):
2267  *  - (1) ldb_search() starts and waits
2268  *  - (2) an entry in the DB is allowed to change before the ldb_wait() is called
2269  *  - (1) the original process can see the modification before the TALLOC_FREE()
2270  * also we check that
2271  *  - (1) the original process can see the modification after the TALLOC_FREE()
2272  *
2273  */
2274
2275 /*
2276  * This purpose of this callback is to trigger a write in
2277  * the child process before the ldb_wait() is called
2278  *
2279  * In ldb 1.1.31 ldb_search() omitted to take a all-record
2280  * lock for the full duration of the search and callbacks
2281  *
2282  * We assume that if the write will proceed, it will proceed in a 3
2283  * second window after the function is called.
2284  */
2285
2286 static int test_ldb_modify_before_ldb_wait_callback1(struct ldb_request *req,
2287                                                      struct ldb_reply *ares)
2288 {
2289         switch (ares->type) {
2290         case LDB_REPLY_ENTRY:
2291         case LDB_REPLY_REFERRAL:
2292                 return LDB_SUCCESS;
2293
2294         case LDB_REPLY_DONE:
2295                 break;
2296         }
2297
2298         return ldb_request_done(req, LDB_SUCCESS);
2299 }
2300
2301 static void test_ldb_modify_before_ldb_wait(void **state)
2302 {
2303         struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
2304                         struct search_test_ctx);
2305         int ret;
2306         struct ldb_request *req;
2307         pid_t pid;
2308         int wstatus;
2309         struct ldb_dn *search_dn;
2310         struct ldb_dn *basedn;
2311         struct ldb_result *res2;
2312         int pipes[2];
2313         char buf[2];
2314         pid_t child_pid;
2315         unsigned res_count;
2316
2317         search_dn = ldb_dn_new_fmt(search_test_ctx,
2318                                    search_test_ctx->ldb_test_ctx->ldb,
2319                                    "cn=test_search_cn,"
2320                                    "dc=search_test_entry");
2321         assert_non_null(search_dn);
2322
2323         basedn = ldb_dn_new_fmt(search_test_ctx,
2324                                 search_test_ctx->ldb_test_ctx->ldb,
2325                                 "%s",
2326                                 search_test_ctx->base_dn);
2327         assert_non_null(basedn);
2328
2329         /*
2330          * The search just needs to call DONE, we don't care about the
2331          * contents of the search for this test
2332          */
2333         ret = ldb_build_search_req(&req,
2334                                    search_test_ctx->ldb_test_ctx->ldb,
2335                                    search_test_ctx,
2336                                    basedn,
2337                                    LDB_SCOPE_SUBTREE,
2338                                    "(&(!(filterAttr=*))"
2339                                    "(cn=test_search_cn))",
2340                                    NULL,
2341                                    NULL,
2342                                    NULL,
2343                                    test_ldb_modify_before_ldb_wait_callback1,
2344                                    NULL);
2345         assert_int_equal(ret, 0);
2346         ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req);
2347
2348         ret = pipe(pipes);
2349         assert_int_equal(ret, 0);
2350
2351         child_pid = fork();
2352         if (child_pid == 0) {
2353                 TALLOC_CTX *tmp_ctx = NULL;
2354                 struct ldb_message *msg;
2355                 struct ldb_message_element *el;
2356                 TALLOC_FREE(search_test_ctx->ldb_test_ctx->ldb);
2357                 TALLOC_FREE(search_test_ctx->ldb_test_ctx->ev);
2358                 close(pipes[0]);
2359                 search_test_ctx->ldb_test_ctx->ev = tevent_context_init(search_test_ctx->ldb_test_ctx);
2360                 if (search_test_ctx->ldb_test_ctx->ev == NULL) {
2361                         exit(LDB_ERR_OPERATIONS_ERROR);
2362                 }
2363
2364                 search_test_ctx->ldb_test_ctx->ldb = ldb_init(search_test_ctx->ldb_test_ctx,
2365                                              search_test_ctx->ldb_test_ctx->ev);
2366                 if (search_test_ctx->ldb_test_ctx->ldb == NULL) {
2367                         exit(LDB_ERR_OPERATIONS_ERROR);
2368                 }
2369
2370                 ret = ldb_connect(search_test_ctx->ldb_test_ctx->ldb,
2371                                   search_test_ctx->ldb_test_ctx->dbpath, 0, NULL);
2372                 if (ret != LDB_SUCCESS) {
2373                         exit(ret);
2374                 }
2375
2376                 tmp_ctx = talloc_new(search_test_ctx->ldb_test_ctx);
2377                 if (tmp_ctx == NULL) {
2378                         exit(LDB_ERR_OPERATIONS_ERROR);
2379                 }
2380
2381                 msg = ldb_msg_new(tmp_ctx);
2382                 if (msg == NULL) {
2383                         exit(LDB_ERR_OPERATIONS_ERROR);
2384                 }
2385
2386                 /*
2387                  * We must re-create this DN from a string to ensure
2388                  * it does not reference the now-gone LDB context of
2389                  * the parent
2390                  */
2391                 msg->dn = ldb_dn_new_fmt(search_test_ctx,
2392                                          search_test_ctx->ldb_test_ctx->ldb,
2393                                          "cn=test_search_cn,"
2394                                          "dc=search_test_entry");
2395
2396                 if (msg->dn == NULL) {
2397                         exit(LDB_ERR_OPERATIONS_ERROR);
2398                 }
2399
2400                 ret = ldb_msg_add_string(msg, "filterAttr", "TRUE");
2401                 if (ret != 0) {
2402                         exit(LDB_ERR_OPERATIONS_ERROR);
2403                 }
2404                 el = ldb_msg_find_element(msg, "filterAttr");
2405                 if (el == NULL) {
2406                         exit(LDB_ERR_OPERATIONS_ERROR);
2407                 }
2408                 el->flags = LDB_FLAG_MOD_REPLACE;
2409
2410                 ret = ldb_transaction_start(search_test_ctx->ldb_test_ctx->ldb);
2411                 if (ret != 0) {
2412                         exit(ret);
2413                 }
2414
2415                 if (write(pipes[1], "GO", 2) != 2) {
2416                         exit(LDB_ERR_OPERATIONS_ERROR);
2417                 }
2418
2419                 ret = ldb_modify(search_test_ctx->ldb_test_ctx->ldb, msg);
2420                 if (ret != 0) {
2421                         exit(ret);
2422                 }
2423
2424                 ret = ldb_transaction_commit(search_test_ctx->ldb_test_ctx->ldb);
2425                 exit(ret);
2426         }
2427         close(pipes[1]);
2428
2429         ret = read(pipes[0], buf, 2);
2430         assert_int_equal(ret, 2);
2431
2432         sleep(3);
2433
2434         /*
2435          * If writes are not blocked until after the (never called) ldb_wait(), we
2436          * will be able to successfully search for this modification
2437          * here
2438          */
2439
2440         ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb, search_test_ctx,
2441                          &res2, search_dn, LDB_SCOPE_BASE, NULL,
2442                          "filterAttr=TRUE");
2443
2444         /*
2445          * We avoid making assertions before TALLOC_FREE()ing the request,
2446          * lest the assert fail and mess with the clean-up because we still
2447          * have locks.
2448          */
2449         res_count = res2->count;
2450         TALLOC_FREE(req);
2451
2452         /* We should not have got the result */
2453         assert_int_equal(res_count, 0);
2454         assert_int_equal(ret, 0);
2455
2456         pid = waitpid(child_pid, &wstatus, 0);
2457         assert_int_equal(pid, child_pid);
2458
2459         assert_true(WIFEXITED(wstatus));
2460
2461         assert_int_equal(WEXITSTATUS(wstatus), 0);
2462
2463         /*
2464          * If writes are blocked until after the search request was freed, we
2465          * will be able to successfully search for this modification
2466          * now
2467          */
2468
2469         search_dn = ldb_dn_new_fmt(search_test_ctx,
2470                                    search_test_ctx->ldb_test_ctx->ldb,
2471                                    "cn=test_search_cn,"
2472                                    "dc=search_test_entry");
2473
2474         ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
2475                          search_test_ctx,
2476                          &res2, search_dn, LDB_SCOPE_BASE, NULL,
2477                          "filterAttr=TRUE");
2478         assert_int_equal(ret, 0);
2479
2480         /* We got the result */
2481         assert_int_equal(res2->count, 1);
2482 }
2483
2484 static int ldb_case_test_setup(void **state)
2485 {
2486         int ret;
2487         struct ldb_ldif *ldif;
2488         struct ldbtest_ctx *ldb_test_ctx;
2489         const char *attrs_ldif =  \
2490                 "dn: @ATTRIBUTES\n"
2491                 "cn: CASE_INSENSITIVE\n"
2492                 "\n";
2493         struct keyval kvs[] = {
2494                 { "cn", "CaseInsensitiveValue" },
2495                 { "uid", "CaseSensitiveValue" },
2496                 { "objectUUID", "0123456789abcdef" },
2497                 { NULL, NULL },
2498         };
2499
2500
2501         ldbtest_setup((void **) &ldb_test_ctx);
2502
2503         while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &attrs_ldif))) {
2504                 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
2505                 assert_int_equal(ret, LDB_SUCCESS);
2506         }
2507
2508         ldb_test_add_data(ldb_test_ctx,
2509                           ldb_test_ctx,
2510                           "cn=CaseInsensitiveValue",
2511                           kvs);
2512
2513         *state = ldb_test_ctx;
2514         return 0;
2515 }
2516
2517 static int ldb_case_test_teardown(void **state)
2518 {
2519         int ret;
2520         struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
2521                         struct ldbtest_ctx);
2522
2523         struct ldb_dn *del_dn;
2524
2525         del_dn = ldb_dn_new_fmt(ldb_test_ctx,
2526                                 ldb_test_ctx->ldb,
2527                                 "@ATTRIBUTES");
2528         assert_non_null(del_dn);
2529
2530         ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
2531         assert_int_equal(ret, LDB_SUCCESS);
2532
2533         assert_dn_doesnt_exist(ldb_test_ctx,
2534                                "@ATTRIBUTES");
2535
2536         ldb_test_remove_data(ldb_test_ctx, ldb_test_ctx,
2537                              "cn=CaseInsensitiveValue");
2538
2539         ldbtest_teardown((void **) &ldb_test_ctx);
2540         return 0;
2541 }
2542
2543 static void test_ldb_attrs_case_insensitive(void **state)
2544 {
2545         int cnt;
2546         struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
2547                         struct ldbtest_ctx);
2548
2549         /* cn matches exact case */
2550         cnt = sub_search_count(ldb_test_ctx, "", "cn=CaseInsensitiveValue");
2551         assert_int_equal(cnt, 1);
2552
2553         /* cn matches lower case */
2554         cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2555         assert_int_equal(cnt, 1);
2556
2557         /* uid matches exact case */
2558         cnt = sub_search_count(ldb_test_ctx, "", "uid=CaseSensitiveValue");
2559         assert_int_equal(cnt, 1);
2560
2561         /* uid does not match lower case */
2562         cnt = sub_search_count(ldb_test_ctx, "", "uid=casesensitivevalue");
2563         assert_int_equal(cnt, 0);
2564 }
2565
2566 static struct ldb_schema_attribute cn_attr_1;
2567 static struct ldb_schema_attribute cn_attr_2;
2568 static struct ldb_schema_attribute default_attr;
2569
2570 /*
2571   override the name to attribute handler function
2572  */
2573 static const struct ldb_schema_attribute *ldb_test_attribute_handler_override(struct ldb_context *ldb,
2574                                                                               void *private_data,
2575                                                                               const char *name)
2576 {
2577         if (private_data != NULL && ldb_attr_cmp(name, "cn") == 0) {
2578                 return &cn_attr_1;
2579         } else if (private_data == NULL && ldb_attr_cmp(name, "cn") == 0) {
2580                 return &cn_attr_2;
2581         } else if (ldb_attr_cmp(name, "uid") == 0) {
2582                 return &cn_attr_2;
2583         }
2584         return &default_attr;
2585 }
2586
2587 static void test_ldb_attrs_case_handler(void **state)
2588 {
2589         int cnt;
2590         int ret;
2591         const struct ldb_schema_syntax *syntax;
2592
2593         struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
2594                         struct ldbtest_ctx);
2595         struct ldb_context *ldb = ldb_test_ctx->ldb;
2596
2597         /* cn matches lower case */
2598         cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2599         assert_int_equal(cnt, 1);
2600
2601         syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_OCTET_STRING);
2602         assert_non_null(syntax);
2603
2604         ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb,
2605                                                     "*", 0,
2606                                                     syntax, &default_attr);
2607         assert_int_equal(ret, LDB_SUCCESS);
2608
2609         syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_OCTET_STRING);
2610         assert_non_null(syntax);
2611
2612         ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb,
2613                                                     "cn", 0,
2614                                                     syntax, &cn_attr_1);
2615         assert_int_equal(ret, LDB_SUCCESS);
2616
2617         /*
2618          * Set an attribute handler, which will fail to match as we
2619          * force case sensitive
2620          */
2621         ldb_schema_attribute_set_override_handler(ldb,
2622                                                   ldb_test_attribute_handler_override,
2623                                                   (void *)1);
2624
2625         /* cn does not matche lower case */
2626         cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2627         assert_int_equal(cnt, 0);
2628
2629         syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_DIRECTORY_STRING);
2630         assert_non_null(syntax);
2631
2632         ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb,
2633                                                     "cn", 0,
2634                                                     syntax, &cn_attr_2);
2635         assert_int_equal(ret, LDB_SUCCESS);
2636
2637         /*
2638          * Set an attribute handler, which will match as we
2639          * force case insensitive
2640          */
2641         ldb_schema_attribute_set_override_handler(ldb,
2642                                                   ldb_test_attribute_handler_override,
2643                                                   NULL);
2644
2645         /* cn matches lower case */
2646         cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2647         assert_int_equal(cnt, 1);
2648
2649 }
2650
2651
2652 static void test_ldb_attrs_index_handler(void **state)
2653 {
2654         int cnt;
2655         int ret;
2656         const struct ldb_schema_syntax *syntax;
2657         struct ldb_ldif *ldif;
2658
2659         const char *index_ldif =  \
2660                 "dn: @INDEXLIST\n"
2661                 "@IDXATTR: cn\n"
2662                 "\n";
2663
2664         struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
2665                         struct ldbtest_ctx);
2666         struct ldb_context *ldb = ldb_test_ctx->ldb;
2667
2668         /* cn matches lower case */
2669         cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2670         assert_int_equal(cnt, 1);
2671
2672         syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_OCTET_STRING);
2673         assert_non_null(syntax);
2674
2675         ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb,
2676                                                     "cn", 0,
2677                                                     syntax, &cn_attr_1);
2678         assert_int_equal(ret, LDB_SUCCESS);
2679
2680         syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_DIRECTORY_STRING);
2681         assert_non_null(syntax);
2682
2683         ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb,
2684                                                     "cn", LDB_ATTR_FLAG_INDEXED,
2685                                                     syntax, &cn_attr_2);
2686         assert_int_equal(ret, LDB_SUCCESS);
2687
2688         syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_OCTET_STRING);
2689         assert_non_null(syntax);
2690
2691         ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb,
2692                                                     "", 0,
2693                                                     syntax, &default_attr);
2694         assert_int_equal(ret, LDB_SUCCESS);
2695
2696         /*
2697          * Set an attribute handler
2698          */
2699         ldb_schema_attribute_set_override_handler(ldb,
2700                                                   ldb_test_attribute_handler_override,
2701                                                   NULL);
2702
2703         /* cn matches lower case */
2704         cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2705         assert_int_equal(cnt, 1);
2706
2707         /* Add the index (actually any modify will do) */
2708         while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &index_ldif))) {
2709                 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
2710                 if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) {
2711                         ldif->msg->elements[0].flags = LDB_FLAG_MOD_ADD;
2712                         ret = ldb_modify(ldb_test_ctx->ldb,
2713                                          ldif->msg);
2714                 }
2715                 assert_int_equal(ret, LDB_SUCCESS);
2716         }
2717
2718         ldb_schema_set_override_indexlist(ldb, false);
2719
2720         /* cn does match as there is an index now */
2721         cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2722         assert_int_equal(cnt, 1);
2723
2724         /*
2725          * Set an attribute handler, which will later fail to match as we
2726          * didn't re-index the DB
2727          */
2728         ldb_schema_attribute_set_override_handler(ldb,
2729                                                   ldb_test_attribute_handler_override,
2730                                                   (void *)1);
2731
2732         /*
2733          * cn does not match as we changed the case sensitivity, but
2734          * didn't re-index
2735          *
2736          * This shows that the override is in control
2737          */
2738         cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2739         assert_int_equal(cnt, 0);
2740
2741 }
2742
2743 static int ldb_case_attrs_index_test_teardown(void **state)
2744 {
2745         int ret;
2746         struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
2747                         struct ldbtest_ctx);
2748         struct ldb_dn *del_dn;
2749
2750         del_dn = ldb_dn_new_fmt(ldb_test_ctx,
2751                                 ldb_test_ctx->ldb,
2752                                 "@INDEXLIST");
2753         assert_non_null(del_dn);
2754
2755         ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
2756         if (ret != LDB_ERR_NO_SUCH_OBJECT) {
2757                 assert_int_equal(ret, LDB_SUCCESS);
2758         }
2759
2760         assert_dn_doesnt_exist(ldb_test_ctx,
2761                                "@INDEXLIST");
2762
2763         ldb_case_test_teardown(state);
2764         return 0;
2765 }
2766
2767
2768 struct rename_test_ctx {
2769         struct ldbtest_ctx *ldb_test_ctx;
2770
2771         struct ldb_dn *basedn;
2772         const char *str_basedn;
2773
2774         const char *teardown_dn;
2775 };
2776
2777 static int ldb_rename_test_setup(void **state)
2778 {
2779         struct ldbtest_ctx *ldb_test_ctx;
2780         struct rename_test_ctx *rename_test_ctx;
2781         const char *strdn = "dc=rename_test_entry_from";
2782
2783         ldbtest_setup((void **) &ldb_test_ctx);
2784
2785         rename_test_ctx = talloc(ldb_test_ctx, struct rename_test_ctx);
2786         assert_non_null(rename_test_ctx);
2787         rename_test_ctx->ldb_test_ctx = ldb_test_ctx;
2788         assert_non_null(rename_test_ctx->ldb_test_ctx);
2789
2790         rename_test_ctx->basedn = ldb_dn_new_fmt(rename_test_ctx,
2791                                 rename_test_ctx->ldb_test_ctx->ldb,
2792                                 "%s", strdn);
2793         assert_non_null(rename_test_ctx->basedn);
2794
2795         rename_test_ctx->str_basedn = strdn;
2796         rename_test_ctx->teardown_dn = strdn;
2797
2798         add_dn_with_cn(ldb_test_ctx,
2799                        rename_test_ctx->basedn,
2800                        "test_rename_cn_val",
2801                        "0123456789abcde0");
2802
2803         *state = rename_test_ctx;
2804         return 0;
2805 }
2806
2807 static int ldb_rename_test_teardown(void **state)
2808 {
2809         int ret;
2810         struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(*state,
2811                         struct rename_test_ctx);
2812         struct ldbtest_ctx *ldb_test_ctx;
2813         struct ldb_dn *del_dn;
2814
2815         ldb_test_ctx = rename_test_ctx->ldb_test_ctx;
2816
2817         del_dn = ldb_dn_new_fmt(rename_test_ctx,
2818                                 rename_test_ctx->ldb_test_ctx->ldb,
2819                                 "%s", rename_test_ctx->teardown_dn);
2820         assert_non_null(del_dn);
2821
2822         ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
2823         assert_int_equal(ret, LDB_SUCCESS);
2824
2825         assert_dn_doesnt_exist(ldb_test_ctx,
2826                                rename_test_ctx->teardown_dn);
2827
2828         ldbtest_teardown((void **) &ldb_test_ctx);
2829         return 0;
2830 }
2831
2832 static void test_ldb_rename(void **state)
2833 {
2834         struct rename_test_ctx *rename_test_ctx =
2835                 talloc_get_type_abort(*state, struct rename_test_ctx);
2836         int ret;
2837         const char *str_new_dn = "dc=rename_test_entry_to";
2838         struct ldb_dn *new_dn;
2839
2840         new_dn = ldb_dn_new_fmt(rename_test_ctx,
2841                                 rename_test_ctx->ldb_test_ctx->ldb,
2842                                 "%s", str_new_dn);
2843         assert_non_null(new_dn);
2844
2845         ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
2846                          rename_test_ctx->basedn,
2847                          new_dn);
2848         assert_int_equal(ret, LDB_SUCCESS);
2849
2850         assert_dn_exists(rename_test_ctx->ldb_test_ctx, str_new_dn);
2851         assert_dn_doesnt_exist(rename_test_ctx->ldb_test_ctx,
2852                                rename_test_ctx->str_basedn);
2853         rename_test_ctx->teardown_dn = str_new_dn;
2854
2855         /* FIXME - test the values which didn't change */
2856 }
2857
2858 static void test_ldb_rename_from_doesnt_exist(void **state)
2859 {
2860         struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(
2861                                                         *state,
2862                                                         struct rename_test_ctx);
2863         int ret;
2864         const char *str_new_dn = "dc=rename_test_entry_to";
2865         const char *str_bad_old_dn = "dc=rename_test_no_such_entry";
2866         struct ldb_dn *new_dn;
2867         struct ldb_dn *bad_old_dn;
2868
2869         new_dn = ldb_dn_new_fmt(rename_test_ctx,
2870                                 rename_test_ctx->ldb_test_ctx->ldb,
2871                                 "%s", str_new_dn);
2872         assert_non_null(new_dn);
2873
2874         bad_old_dn = ldb_dn_new_fmt(rename_test_ctx,
2875                                     rename_test_ctx->ldb_test_ctx->ldb,
2876                                     "%s", str_bad_old_dn);
2877         assert_non_null(bad_old_dn);
2878
2879         assert_dn_doesnt_exist(rename_test_ctx->ldb_test_ctx,
2880                                str_bad_old_dn);
2881
2882         ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
2883                          bad_old_dn, new_dn);
2884         assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT);
2885
2886         assert_dn_doesnt_exist(rename_test_ctx->ldb_test_ctx,
2887                                str_new_dn);
2888 }
2889
2890 static void test_ldb_rename_to_exists(void **state)
2891 {
2892         struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(
2893                                                         *state,
2894                                                         struct rename_test_ctx);
2895         int ret;
2896         const char *str_new_dn = "dc=rename_test_already_exists";
2897         struct ldb_dn *new_dn;
2898
2899         new_dn = ldb_dn_new_fmt(rename_test_ctx,
2900                                 rename_test_ctx->ldb_test_ctx->ldb,
2901                                 "%s", str_new_dn);
2902         assert_non_null(new_dn);
2903
2904         add_dn_with_cn(rename_test_ctx->ldb_test_ctx,
2905                        new_dn,
2906                        "test_rename_cn_val",
2907                        "0123456789abcde1");
2908
2909         ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
2910                          rename_test_ctx->basedn,
2911                          new_dn);
2912         assert_int_equal(ret, LDB_ERR_ENTRY_ALREADY_EXISTS);
2913
2914         /* Old object must still exist */
2915         assert_dn_exists(rename_test_ctx->ldb_test_ctx,
2916                          rename_test_ctx->str_basedn);
2917
2918         ret = ldb_delete(rename_test_ctx->ldb_test_ctx->ldb,
2919                          new_dn);
2920         assert_int_equal(ret, LDB_SUCCESS);
2921
2922         assert_dn_exists(rename_test_ctx->ldb_test_ctx,
2923                                rename_test_ctx->teardown_dn);
2924 }
2925
2926 static void test_ldb_rename_self(void **state)
2927 {
2928         struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(
2929                                                         *state,
2930                                                         struct rename_test_ctx);
2931         int ret;
2932
2933         /* Oddly enough, this is a success in ldb.. */
2934         ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
2935                          rename_test_ctx->basedn,
2936                          rename_test_ctx->basedn);
2937         assert_int_equal(ret, LDB_SUCCESS);
2938
2939         /* Old object must still exist */
2940         assert_dn_exists(rename_test_ctx->ldb_test_ctx,
2941                          rename_test_ctx->str_basedn);
2942 }
2943
2944 static void test_ldb_rename_dn_case_change(void **state)
2945 {
2946         struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(
2947                                                         *state,
2948                                                         struct rename_test_ctx);
2949         int ret;
2950         char *str_new_dn;
2951         struct ldb_dn *new_dn;
2952         unsigned i;
2953
2954         str_new_dn = talloc_strdup(rename_test_ctx, rename_test_ctx->str_basedn);
2955         assert_non_null(str_new_dn);
2956         for (i = 0; str_new_dn[i]; i++) {
2957                 str_new_dn[i] = toupper(str_new_dn[i]);
2958         }
2959
2960         new_dn = ldb_dn_new_fmt(rename_test_ctx,
2961                                 rename_test_ctx->ldb_test_ctx->ldb,
2962                                 "%s", str_new_dn);
2963         assert_non_null(new_dn);
2964
2965         ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
2966                          rename_test_ctx->basedn,
2967                          new_dn);
2968         assert_int_equal(ret, LDB_SUCCESS);
2969
2970         /* DNs are case insensitive, so both searches will match */
2971         assert_dn_exists(rename_test_ctx->ldb_test_ctx, str_new_dn);
2972         assert_dn_exists(rename_test_ctx->ldb_test_ctx,
2973                          rename_test_ctx->str_basedn);
2974         /* FIXME - test the values didn't change */
2975 }
2976
2977 static int ldb_read_only_setup(void **state)
2978 {
2979         struct ldbtest_ctx *test_ctx;
2980
2981         ldbtest_setup((void **) &test_ctx);
2982
2983         *state = test_ctx;
2984         return 0;
2985 }
2986
2987 static int ldb_read_only_teardown(void **state)
2988 {
2989         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
2990                                                         struct ldbtest_ctx);
2991         ldbtest_teardown((void **) &test_ctx);
2992         return 0;
2993 }
2994
2995 static void test_read_only(void **state)
2996 {
2997         struct ldb_context *ro_ldb = NULL;
2998         struct ldb_context *rw_ldb = NULL;
2999         int ret;
3000         TALLOC_CTX *tmp_ctx = NULL;
3001
3002         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3003                                                         struct ldbtest_ctx);
3004         /*
3005          * Close the ldb context freeing it this will ensure it exists on
3006          * disk and can be opened in read only mode
3007          */
3008         TALLOC_FREE(test_ctx->ldb);
3009
3010         /*
3011          * Open the database in read only and read write mode,
3012          * ensure it's opend in read only mode first
3013          */
3014         ro_ldb = ldb_init(test_ctx, test_ctx->ev);
3015         ret = ldb_connect(ro_ldb, test_ctx->dbpath, LDB_FLG_RDONLY, NULL);
3016         assert_int_equal(ret, 0);
3017
3018         rw_ldb = ldb_init(test_ctx, test_ctx->ev);
3019         ret = ldb_connect(rw_ldb, test_ctx->dbpath, 0, NULL);
3020         assert_int_equal(ret, 0);
3021
3022
3023         /*
3024          * Set up a context for the temporary variables
3025          */
3026         tmp_ctx = talloc_new(test_ctx);
3027         assert_non_null(tmp_ctx);
3028
3029         /*
3030          * Ensure that we can search the read write database
3031          */
3032         {
3033                 struct ldb_result *result = NULL;
3034                 struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, rw_ldb,
3035                                                        "dc=test");
3036                 assert_non_null(dn);
3037
3038                 ret = ldb_search(rw_ldb, tmp_ctx, &result, dn,
3039                                  LDB_SCOPE_BASE, NULL, NULL);
3040                 assert_int_equal(ret, LDB_SUCCESS);
3041                 TALLOC_FREE(result);
3042                 TALLOC_FREE(dn);
3043         }
3044
3045         /*
3046          * Ensure that we can search the read only database
3047          */
3048         {
3049                 struct ldb_result *result = NULL;
3050                 struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, ro_ldb,
3051                                                        "dc=test");
3052                 assert_non_null(dn);
3053
3054                 ret = ldb_search(ro_ldb, tmp_ctx, &result, dn,
3055                                  LDB_SCOPE_BASE, NULL, NULL);
3056                 assert_int_equal(ret, LDB_SUCCESS);
3057                 TALLOC_FREE(result);
3058                 TALLOC_FREE(dn);
3059         }
3060         /*
3061          * Ensure that a write to the read only database fails
3062          */
3063         {
3064                 struct ldb_message *msg = NULL;
3065                 msg = ldb_msg_new(tmp_ctx);
3066                 assert_non_null(msg);
3067
3068                 msg->dn = ldb_dn_new_fmt(msg, ro_ldb, "dc=test");
3069                 assert_non_null(msg->dn);
3070
3071                 ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
3072                 assert_int_equal(ret, 0);
3073
3074                 ret = ldb_msg_add_string(msg, "objectUUID",
3075                                          "0123456789abcde1");
3076                 assert_int_equal(ret, LDB_SUCCESS);
3077
3078                 ret = ldb_add(ro_ldb, msg);
3079                 assert_int_equal(ret, LDB_ERR_UNWILLING_TO_PERFORM);
3080                 TALLOC_FREE(msg);
3081         }
3082
3083         /*
3084          * Ensure that a write to the read write database succeeds
3085          */
3086         {
3087                 struct ldb_message *msg = NULL;
3088                 msg = ldb_msg_new(tmp_ctx);
3089                 assert_non_null(msg);
3090
3091                 msg->dn = ldb_dn_new_fmt(msg, rw_ldb, "dc=test");
3092                 assert_non_null(msg->dn);
3093
3094                 ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
3095                 assert_int_equal(ret, 0);
3096
3097                 ret = ldb_msg_add_string(msg, "objectUUID",
3098                                          "0123456789abcde2");
3099                 assert_int_equal(ret, LDB_SUCCESS);
3100
3101                 ret = ldb_add(rw_ldb, msg);
3102                 assert_int_equal(ret, LDB_SUCCESS);
3103                 TALLOC_FREE(msg);
3104         }
3105
3106         /*
3107          * Ensure that a delete from a read only database fails
3108          */
3109         {
3110                 struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, ro_ldb, "dc=test");
3111                 assert_non_null(dn);
3112
3113                 ret = ldb_delete(ro_ldb, dn);
3114                 assert_int_equal(ret, LDB_ERR_UNWILLING_TO_PERFORM);
3115                 TALLOC_FREE(dn);
3116         }
3117
3118
3119         /*
3120          * Ensure that a delete from a read write succeeds
3121          */
3122         {
3123                 struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, rw_ldb, "dc=test");
3124                 assert_non_null(dn);
3125
3126                 ret = ldb_delete(rw_ldb, dn);
3127                 assert_int_equal(ret, LDB_SUCCESS);
3128                 TALLOC_FREE(dn);
3129         }
3130         TALLOC_FREE(tmp_ctx);
3131 }
3132
3133 static bool unique_values = false;
3134
3135 static int unique_index_test_module_add(
3136         struct ldb_module *module,
3137         struct ldb_request *req)
3138 {
3139         if (unique_values) {
3140                 struct ldb_message *msg = discard_const(req->op.add.message);
3141                 struct ldb_message_element *el = NULL;
3142                 el = ldb_msg_find_element(msg, "cn");
3143                 if (el != NULL) {
3144                         el->flags |= LDB_FLAG_INTERNAL_FORCE_UNIQUE_INDEX;
3145                 }
3146         }
3147
3148         return ldb_next_request(module, req);
3149 }
3150
3151 static int unique_index_test_module_init(struct ldb_module *module)
3152 {
3153         return ldb_next_init(module);
3154 }
3155
3156 static const struct ldb_module_ops ldb_unique_index_test_module_ops = {
3157         .name           = "unique_index_test",
3158         .init_context   = unique_index_test_module_init,
3159         .add            = unique_index_test_module_add,
3160 };
3161
3162 static int ldb_unique_index_test_setup(void **state)
3163 {
3164         int ret;
3165         struct ldb_ldif *ldif;
3166         struct ldbtest_ctx *ldb_test_ctx;
3167         const char *attrs_ldif =  \
3168                 "dn: @ATTRIBUTES\n"
3169                 "cn: UNIQUE_INDEX\n"
3170                 "\n";
3171         const char *index_ldif =  \
3172                 "dn: @INDEXLIST\n"
3173                 "@IDXATTR: cn\n"
3174 #ifdef GUID_IDX
3175                 "@IDXGUID: objectUUID\n"
3176                 "@IDX_DN_GUID: GUID\n"
3177 #endif
3178                 "\n";
3179         const char *options[] = {"modules:unique_index_test", NULL};
3180
3181
3182         ret = ldb_register_module(&ldb_unique_index_test_module_ops);
3183         assert_true(ret == LDB_SUCCESS || ret == LDB_ERR_ENTRY_ALREADY_EXISTS);
3184         ldbtest_noconn_setup((void **) &ldb_test_ctx);
3185
3186
3187         ret = ldb_connect(ldb_test_ctx->ldb, ldb_test_ctx->dbpath, 0, options);
3188         assert_int_equal(ret, 0);
3189
3190         while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &attrs_ldif))) {
3191                 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
3192                 assert_int_equal(ret, LDB_SUCCESS);
3193         }
3194
3195         while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &index_ldif))) {
3196                 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
3197                 assert_int_equal(ret, LDB_SUCCESS);
3198         }
3199
3200         unique_values = true;
3201
3202         *state = ldb_test_ctx;
3203         return 0;
3204 }
3205
3206 static int ldb_unique_index_test_teardown(void **state)
3207 {
3208         int ret;
3209         struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
3210                         struct ldbtest_ctx);
3211         struct ldb_dn *del_dn;
3212
3213         del_dn = ldb_dn_new_fmt(ldb_test_ctx,
3214                                 ldb_test_ctx->ldb,
3215                                 "@INDEXLIST");
3216         assert_non_null(del_dn);
3217
3218         ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
3219         if (ret != LDB_ERR_NO_SUCH_OBJECT) {
3220                 assert_int_equal(ret, LDB_SUCCESS);
3221         }
3222
3223         assert_dn_doesnt_exist(ldb_test_ctx,
3224                                "@INDEXLIST");
3225
3226         TALLOC_FREE(del_dn);
3227
3228         del_dn = ldb_dn_new_fmt(ldb_test_ctx,
3229                                 ldb_test_ctx->ldb,
3230                                 "@ATTRIBUTES");
3231         assert_non_null(del_dn);
3232
3233         ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
3234         if (ret != LDB_ERR_NO_SUCH_OBJECT) {
3235                 assert_int_equal(ret, LDB_SUCCESS);
3236         }
3237
3238         assert_dn_doesnt_exist(ldb_test_ctx,
3239                                "@ATTRIBUTES");
3240
3241         ldbtest_teardown((void **) &ldb_test_ctx);
3242         return 0;
3243 }
3244
3245
3246 static void test_ldb_add_unique_value_to_unique_index(void **state)
3247 {
3248         int ret;
3249         struct ldb_message *msg;
3250         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3251                                                         struct ldbtest_ctx);
3252         TALLOC_CTX *tmp_ctx;
3253
3254         tmp_ctx = talloc_new(test_ctx);
3255         assert_non_null(tmp_ctx);
3256
3257         msg = ldb_msg_new(tmp_ctx);
3258         assert_non_null(msg);
3259
3260         msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "dc=test");
3261         assert_non_null(msg->dn);
3262
3263         ret = ldb_msg_add_string(msg, "cn", "test_unique_index");
3264         assert_int_equal(ret, LDB_SUCCESS);
3265
3266         ret = ldb_msg_add_string(msg, "objectUUID",
3267                                  "0123456789abcde1");
3268         assert_int_equal(ret, LDB_SUCCESS);
3269
3270         ret = ldb_add(test_ctx->ldb, msg);
3271         assert_int_equal(ret, LDB_SUCCESS);
3272
3273         talloc_free(tmp_ctx);
3274 }
3275
3276 static int ldb_non_unique_index_test_setup(void **state)
3277 {
3278         int ret;
3279         struct ldb_ldif *ldif;
3280         struct ldbtest_ctx *ldb_test_ctx;
3281         const char *index_ldif =  \
3282                 "dn: @INDEXLIST\n"
3283                 "@IDXATTR: cn\n"
3284 #ifdef GUID_IDX
3285                 "@IDXGUID: objectUUID\n"
3286                 "@IDX_DN_GUID: GUID\n"
3287 #endif
3288                 "\n";
3289         const char *options[] = {"modules:unique_index_test", NULL};
3290
3291
3292         ret = ldb_register_module(&ldb_unique_index_test_module_ops);
3293         assert_true(ret == LDB_SUCCESS || ret == LDB_ERR_ENTRY_ALREADY_EXISTS);
3294         ldbtest_noconn_setup((void **) &ldb_test_ctx);
3295
3296
3297         ret = ldb_connect(ldb_test_ctx->ldb, ldb_test_ctx->dbpath, 0, options);
3298         assert_int_equal(ret, 0);
3299
3300         while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &index_ldif))) {
3301                 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
3302                 assert_int_equal(ret, LDB_SUCCESS);
3303         }
3304
3305         unique_values = true;
3306
3307         *state = ldb_test_ctx;
3308         return 0;
3309 }
3310
3311 static int ldb_non_unique_index_test_teardown(void **state)
3312 {
3313         int ret;
3314         struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
3315                         struct ldbtest_ctx);
3316         struct ldb_dn *del_dn;
3317
3318         del_dn = ldb_dn_new_fmt(ldb_test_ctx,
3319                                 ldb_test_ctx->ldb,
3320                                 "@INDEXLIST");
3321         assert_non_null(del_dn);
3322
3323         ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
3324         if (ret != LDB_ERR_NO_SUCH_OBJECT) {
3325                 assert_int_equal(ret, LDB_SUCCESS);
3326         }
3327
3328         assert_dn_doesnt_exist(ldb_test_ctx,
3329                                "@INDEXLIST");
3330
3331         TALLOC_FREE(del_dn);
3332
3333         ldbtest_teardown((void **) &ldb_test_ctx);
3334         return 0;
3335 }
3336
3337 static void test_ldb_add_duplicate_value_to_unique_index(void **state)
3338 {
3339         int ret;
3340         struct ldb_message *msg01;
3341         struct ldb_message *msg02;
3342         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3343                                                         struct ldbtest_ctx);
3344         TALLOC_CTX *tmp_ctx;
3345
3346         tmp_ctx = talloc_new(test_ctx);
3347         assert_non_null(tmp_ctx);
3348
3349         msg01 = ldb_msg_new(tmp_ctx);
3350         assert_non_null(msg01);
3351
3352         msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3353         assert_non_null(msg01->dn);
3354
3355         ret = ldb_msg_add_string(msg01, "cn", "test_unique_index");
3356         assert_int_equal(ret, LDB_SUCCESS);
3357
3358         ret = ldb_msg_add_string(msg01, "objectUUID",
3359                                  "0123456789abcde1");
3360         assert_int_equal(ret, LDB_SUCCESS);
3361
3362         ret = ldb_add(test_ctx->ldb, msg01);
3363         assert_int_equal(ret, LDB_SUCCESS);
3364
3365         msg02 = ldb_msg_new(tmp_ctx);
3366         assert_non_null(msg02);
3367
3368         msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02");
3369         assert_non_null(msg02->dn);
3370
3371         ret = ldb_msg_add_string(msg02, "cn", "test_unique_index");
3372         assert_int_equal(ret, LDB_SUCCESS);
3373
3374         ret = ldb_msg_add_string(msg02, "objectUUID",
3375                                  "0123456789abcde2");
3376         assert_int_equal(ret, LDB_SUCCESS);
3377
3378         ret = ldb_add(test_ctx->ldb, msg02);
3379         assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION);
3380         talloc_free(tmp_ctx);
3381 }
3382
3383 static void test_ldb_add_to_index_duplicates_allowed(void **state)
3384 {
3385         int ret;
3386         struct ldb_message *msg01;
3387         struct ldb_message *msg02;
3388         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3389                                                         struct ldbtest_ctx);
3390         TALLOC_CTX *tmp_ctx;
3391
3392         unique_values = false;
3393
3394         tmp_ctx = talloc_new(test_ctx);
3395         assert_non_null(tmp_ctx);
3396
3397
3398         msg01 = ldb_msg_new(tmp_ctx);
3399         assert_non_null(msg01);
3400
3401         msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3402         assert_non_null(msg01->dn);
3403
3404         ret = ldb_msg_add_string(msg01, "cn", "test_unique_index");
3405         assert_int_equal(ret, LDB_SUCCESS);
3406
3407         ret = ldb_msg_add_string(msg01, "objectUUID",
3408                                  "0123456789abcde1");
3409
3410         ret = ldb_add(test_ctx->ldb, msg01);
3411         assert_int_equal(ret, LDB_SUCCESS);
3412
3413         msg02 = ldb_msg_new(tmp_ctx);
3414         assert_non_null(msg02);
3415
3416         msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02");
3417         assert_non_null(msg02->dn);
3418
3419         ret = ldb_msg_add_string(msg02, "cn", "test_unique_index");
3420         assert_int_equal(ret, LDB_SUCCESS);
3421
3422         ret = ldb_msg_add_string(msg02, "objectUUID",
3423                                  "0123456789abcde2");
3424
3425         ret = ldb_add(test_ctx->ldb, msg02);
3426         assert_int_equal(ret, LDB_SUCCESS);
3427         talloc_free(tmp_ctx);
3428 }
3429
3430 static void test_ldb_add_to_index_unique_values_required(void **state)
3431 {
3432         int ret;
3433         struct ldb_message *msg01;
3434         struct ldb_message *msg02;
3435         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3436                                                         struct ldbtest_ctx);
3437         TALLOC_CTX *tmp_ctx;
3438
3439         unique_values = true;
3440
3441         tmp_ctx = talloc_new(test_ctx);
3442         assert_non_null(tmp_ctx);
3443
3444
3445         msg01 = ldb_msg_new(tmp_ctx);
3446         assert_non_null(msg01);
3447
3448         msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3449         assert_non_null(msg01->dn);
3450
3451         ret = ldb_msg_add_string(msg01, "cn", "test_unique_index");
3452         assert_int_equal(ret, LDB_SUCCESS);
3453
3454         ret = ldb_msg_add_string(msg01, "objectUUID",
3455                                  "0123456789abcde1");
3456
3457         ret = ldb_add(test_ctx->ldb, msg01);
3458         assert_int_equal(ret, LDB_SUCCESS);
3459
3460         msg02 = ldb_msg_new(tmp_ctx);
3461         assert_non_null(msg02);
3462
3463         msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02");
3464         assert_non_null(msg02->dn);
3465
3466         ret = ldb_msg_add_string(msg02, "cn", "test_unique_index");
3467         assert_int_equal(ret, LDB_SUCCESS);
3468
3469         ret = ldb_msg_add_string(msg02, "objectUUID",
3470                                  "0123456789abcde2");
3471
3472         ret = ldb_add(test_ctx->ldb, msg02);
3473         assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION);
3474         talloc_free(tmp_ctx);
3475 }
3476
3477 static void ldb_debug_string(void *context, enum ldb_debug_level level,
3478                              const char *fmt, va_list ap)
3479 {
3480
3481         if (level <= LDB_DEBUG_WARNING) {
3482                 *((char **)context) = talloc_vasprintf(NULL, fmt, ap);
3483         }
3484 }
3485
3486 static void test_ldb_unique_index_duplicate_logging(void **state)
3487 {
3488         int ret;
3489         struct ldb_message *msg01;
3490         struct ldb_message *msg02;
3491         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3492                                                         struct ldbtest_ctx);
3493         TALLOC_CTX *tmp_ctx;
3494         char *debug_string = NULL;
3495         char *p = NULL;
3496
3497         /* The GUID mode is not compatible with this test */
3498 #ifdef GUID_IDX
3499         return;
3500 #endif
3501
3502         ldb_set_debug(test_ctx->ldb, ldb_debug_string, &debug_string);
3503         tmp_ctx = talloc_new(test_ctx);
3504         assert_non_null(tmp_ctx);
3505
3506         msg01 = ldb_msg_new(tmp_ctx);
3507         assert_non_null(msg01);
3508
3509         msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3510         assert_non_null(msg01->dn);
3511
3512         ret = ldb_msg_add_string(msg01, "cn", "test_unique_index");
3513         assert_int_equal(ret, LDB_SUCCESS);
3514
3515         ret = ldb_msg_add_string(msg01, "objectUUID",
3516                                  "0123456789abcde1");
3517
3518         ret = ldb_add(test_ctx->ldb, msg01);
3519         assert_int_equal(ret, LDB_SUCCESS);
3520
3521         msg02 = ldb_msg_new(tmp_ctx);
3522         assert_non_null(msg02);
3523
3524         msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02");
3525         assert_non_null(msg02->dn);
3526
3527         ret = ldb_msg_add_string(msg02, "cn", "test_unique_index");
3528         assert_int_equal(ret, LDB_SUCCESS);
3529
3530         ret = ldb_msg_add_string(msg02, "objectUUID",
3531                                  "0123456789abcde2");
3532
3533         ret = ldb_add(test_ctx->ldb, msg02);
3534         assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION);
3535
3536         assert_non_null(debug_string);
3537         p = strstr(
3538                 debug_string,
3539                 "unique index violation on cn "
3540                 "in dc=test02, conficts with dc=test01 in "
3541                 "@INDEX:CN:test_unique_index");
3542         assert_non_null(p);
3543         TALLOC_FREE(debug_string);
3544         talloc_free(tmp_ctx);
3545 }
3546
3547 static void test_ldb_duplicate_dn_logging(void **state)
3548 {
3549         int ret;
3550         struct ldb_message *msg01;
3551         struct ldb_message *msg02;
3552         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3553                                                         struct ldbtest_ctx);
3554         TALLOC_CTX *tmp_ctx;
3555         char *debug_string = NULL;
3556
3557         /* The GUID mode is not compatible with this test */
3558 #ifdef GUID_IDX
3559         return;
3560 #endif
3561
3562         ldb_set_debug(test_ctx->ldb, ldb_debug_string, &debug_string);
3563         tmp_ctx = talloc_new(test_ctx);
3564         assert_non_null(tmp_ctx);
3565
3566         msg01 = ldb_msg_new(tmp_ctx);
3567         assert_non_null(msg01);
3568
3569         msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3570         assert_non_null(msg01->dn);
3571
3572         ret = ldb_msg_add_string(msg01, "cn", "test_unique_index01");
3573         assert_int_equal(ret, LDB_SUCCESS);
3574
3575         ret = ldb_msg_add_string(msg01, "objectUUID",
3576                                  "0123456789abcde1");
3577
3578         ret = ldb_add(test_ctx->ldb, msg01);
3579         assert_int_equal(ret, LDB_SUCCESS);
3580
3581         msg02 = ldb_msg_new(tmp_ctx);
3582         assert_non_null(msg02);
3583
3584         msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test01");
3585         assert_non_null(msg02->dn);
3586
3587         ret = ldb_msg_add_string(msg02, "cn", "test_unique_index02");
3588         assert_int_equal(ret, LDB_SUCCESS);
3589
3590         ret = ldb_msg_add_string(msg02, "objectUUID",
3591                                  "0123456789abcde2");
3592
3593         ret = ldb_add(test_ctx->ldb, msg02);
3594         assert_int_equal(ret, LDB_ERR_ENTRY_ALREADY_EXISTS);
3595
3596         assert_null(debug_string);
3597         talloc_free(tmp_ctx);
3598 }
3599
3600 static int ldb_guid_index_test_setup(void **state)
3601 {
3602         int ret;
3603         struct ldb_ldif *ldif;
3604         struct ldbtest_ctx *ldb_test_ctx;
3605         const char *attrs_ldif =  \
3606                 "dn: @ATTRIBUTES\n"
3607                 "cn: UNIQUE_INDEX\n"
3608                 "\n";
3609         const char *index_ldif =  \
3610                 "dn: @INDEXLIST\n"
3611                 "@IDXATTR: cn\n"
3612                 "@IDXGUID: objectUUID\n"
3613                 "@IDX_DN_GUID: GUID\n"
3614                 "\n";
3615
3616         ldbtest_noconn_setup((void **) &ldb_test_ctx);
3617
3618
3619         ret = ldb_connect(ldb_test_ctx->ldb, ldb_test_ctx->dbpath, 0, NULL);
3620         assert_int_equal(ret, 0);
3621
3622         while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &attrs_ldif))) {
3623                 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
3624                 assert_int_equal(ret, LDB_SUCCESS);
3625         }
3626
3627         while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &index_ldif))) {
3628                 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
3629                 assert_int_equal(ret, LDB_SUCCESS);
3630         }
3631
3632         *state = ldb_test_ctx;
3633         return 0;
3634 }
3635
3636 static int ldb_guid_index_test_teardown(void **state)
3637 {
3638         int ret;
3639         struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
3640                         struct ldbtest_ctx);
3641         struct ldb_dn *del_dn;
3642
3643         del_dn = ldb_dn_new_fmt(ldb_test_ctx,
3644                                 ldb_test_ctx->ldb,
3645                                 "@INDEXLIST");
3646         assert_non_null(del_dn);
3647
3648         ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
3649         if (ret != LDB_ERR_NO_SUCH_OBJECT) {
3650                 assert_int_equal(ret, LDB_SUCCESS);
3651         }
3652
3653         assert_dn_doesnt_exist(ldb_test_ctx,
3654                                "@INDEXLIST");
3655
3656         TALLOC_FREE(del_dn);
3657
3658         del_dn = ldb_dn_new_fmt(ldb_test_ctx,
3659                                 ldb_test_ctx->ldb,
3660                                 "@ATTRIBUTES");
3661         assert_non_null(del_dn);
3662
3663         ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
3664         if (ret != LDB_ERR_NO_SUCH_OBJECT) {
3665                 assert_int_equal(ret, LDB_SUCCESS);
3666         }
3667
3668         assert_dn_doesnt_exist(ldb_test_ctx,
3669                                "@ATTRIBUTES");
3670
3671         ldbtest_teardown((void **) &ldb_test_ctx);
3672         return 0;
3673 }
3674
3675
3676 static void test_ldb_unique_index_duplicate_with_guid(void **state)
3677 {
3678         int ret;
3679         struct ldb_message *msg01;
3680         struct ldb_message *msg02;
3681         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3682                                                         struct ldbtest_ctx);
3683         TALLOC_CTX *tmp_ctx;
3684         char *debug_string = NULL;
3685         char *p = NULL;
3686
3687         ldb_set_debug(test_ctx->ldb, ldb_debug_string, &debug_string);
3688         tmp_ctx = talloc_new(test_ctx);
3689         assert_non_null(tmp_ctx);
3690
3691         msg01 = ldb_msg_new(tmp_ctx);
3692         assert_non_null(msg01);
3693
3694         msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3695         assert_non_null(msg01->dn);
3696
3697         ret = ldb_msg_add_string(msg01, "cn", "test_unique_index");
3698         assert_int_equal(ret, LDB_SUCCESS);
3699
3700         ret = ldb_msg_add_string(msg01, "objectUUID", "0123456789abcdef");
3701         assert_int_equal(ret, LDB_SUCCESS);
3702
3703         ret = ldb_add(test_ctx->ldb, msg01);
3704         assert_int_equal(ret, LDB_SUCCESS);
3705
3706         msg02 = ldb_msg_new(tmp_ctx);
3707         assert_non_null(msg01);
3708
3709         msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02");
3710         assert_non_null(msg02->dn);
3711
3712         ret = ldb_msg_add_string(msg02, "cn", "test_unique_index");
3713         assert_int_equal(ret, LDB_SUCCESS);
3714
3715         ret = ldb_msg_add_string(msg02, "objectUUID", "0123456789abcde0");
3716         assert_int_equal(ret, LDB_SUCCESS);
3717
3718         ret = ldb_add(test_ctx->ldb, msg02);
3719         assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION);
3720
3721         assert_non_null(debug_string);
3722         p = strstr(
3723                 debug_string,
3724                 "unique index violation on cn in dc=test02, conficts with "
3725                 "objectUUID 0123456789abcdef in @INDEX:CN:test_unique_index");
3726         assert_non_null(p);
3727         TALLOC_FREE(debug_string);
3728         talloc_free(tmp_ctx);
3729 }
3730
3731 static void test_ldb_guid_index_duplicate_dn_logging(void **state)
3732 {
3733         int ret;
3734         struct ldb_message *msg01;
3735         struct ldb_message *msg02;
3736         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3737                                                         struct ldbtest_ctx);
3738         TALLOC_CTX *tmp_ctx;
3739         char *debug_string = NULL;
3740
3741         ldb_set_debug(test_ctx->ldb, ldb_debug_string, &debug_string);
3742         tmp_ctx = talloc_new(test_ctx);
3743         assert_non_null(tmp_ctx);
3744
3745         msg01 = ldb_msg_new(tmp_ctx);
3746         assert_non_null(msg01);
3747
3748         msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3749         assert_non_null(msg01->dn);
3750
3751         ret = ldb_msg_add_string(msg01, "cn", "test_unique_index01");
3752         assert_int_equal(ret, LDB_SUCCESS);
3753
3754         ret = ldb_msg_add_string(msg01, "objectUUID", "0123456789abcdef");
3755         assert_int_equal(ret, LDB_SUCCESS);
3756
3757         ret = ldb_add(test_ctx->ldb, msg01);
3758         assert_int_equal(ret, LDB_SUCCESS);
3759
3760         msg02 = ldb_msg_new(tmp_ctx);
3761         assert_non_null(msg02);
3762
3763         msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test01");
3764         assert_non_null(msg02->dn);
3765
3766         ret = ldb_msg_add_string(msg02, "cn", "test_unique_index02");
3767         assert_int_equal(ret, LDB_SUCCESS);
3768
3769         ret = ldb_msg_add_string(msg02, "objectUUID", "0123456789abcde1");
3770         assert_int_equal(ret, LDB_SUCCESS);
3771
3772         ret = ldb_add(test_ctx->ldb, msg02);
3773         assert_int_equal(ret, LDB_ERR_ENTRY_ALREADY_EXISTS);
3774
3775         assert_null(debug_string);
3776         talloc_free(tmp_ctx);
3777 }
3778
3779 static void test_ldb_talloc_destructor_transaction_cleanup(void **state)
3780 {
3781         struct ldbtest_ctx *test_ctx = NULL;
3782
3783         test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx);
3784         assert_non_null(test_ctx);
3785
3786         ldb_transaction_start(test_ctx->ldb);
3787
3788         /*
3789          * Trigger the destructor
3790          */
3791         TALLOC_FREE(test_ctx->ldb);
3792
3793         /*
3794          * Now ensure that a new connection can be opened
3795          */
3796         {
3797                 TALLOC_CTX *tctx = talloc_new(test_ctx);
3798                 struct ldbtest_ctx *ctx = talloc_zero(tctx, struct ldbtest_ctx);
3799                 struct ldb_dn *basedn;
3800                 struct ldb_result *result = NULL;
3801                 int ret;
3802
3803                 ldbtest_setup((void *)&ctx);
3804
3805                 basedn = ldb_dn_new_fmt(tctx, ctx->ldb, "dc=test");
3806                 assert_non_null(basedn);
3807
3808                 ret = ldb_search(ctx->ldb,
3809                                  tctx,
3810                                  &result,
3811                                  basedn,
3812                                  LDB_SCOPE_BASE,
3813                                  NULL,
3814                                  NULL);
3815                 assert_int_equal(ret, 0);
3816                 assert_non_null(result);
3817                 assert_int_equal(result->count, 0);
3818
3819                 ldbtest_teardown((void *)&ctx);
3820         }
3821 }
3822
3823 static void test_transaction_start_across_fork(void **state)
3824 {
3825         struct ldb_context *ldb1 = NULL;
3826         int ret;
3827         struct ldbtest_ctx *test_ctx = NULL;
3828         int pipes[2];
3829         char buf[2];
3830         int wstatus;
3831         pid_t pid, child_pid;
3832
3833         test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx);
3834
3835         /*
3836          * Open the database
3837          */
3838         ldb1 = ldb_init(test_ctx, test_ctx->ev);
3839         ret = ldb_connect(ldb1, test_ctx->dbpath, 0, NULL);
3840         assert_int_equal(ret, 0);
3841
3842         ret = pipe(pipes);
3843         assert_int_equal(ret, 0);
3844
3845         child_pid = fork();
3846         if (child_pid == 0) {
3847                 close(pipes[0]);
3848                 ret = ldb_transaction_start(ldb1);
3849                 if (ret != LDB_ERR_PROTOCOL_ERROR) {
3850                         print_error(__location__": ldb_transaction_start "
3851                                     "returned (%d) %s\n",
3852                                     ret,
3853                                     ldb1->err_string);
3854                         exit(LDB_ERR_OTHER);
3855                 }
3856
3857                 ret = write(pipes[1], "GO", 2);
3858                 if (ret != 2) {
3859                         print_error(__location__
3860                                       " write returned (%d)",
3861                                       ret);
3862                         exit(LDB_ERR_OPERATIONS_ERROR);
3863                 }
3864                 exit(LDB_SUCCESS);
3865         }
3866         close(pipes[1]);
3867         ret = read(pipes[0], buf, 2);
3868         assert_int_equal(ret, 2);
3869
3870         pid = waitpid(child_pid, &wstatus, 0);
3871         assert_int_equal(pid, child_pid);
3872
3873         assert_true(WIFEXITED(wstatus));
3874
3875         assert_int_equal(WEXITSTATUS(wstatus), 0);
3876 }
3877
3878 static void test_transaction_commit_across_fork(void **state)
3879 {
3880         struct ldb_context *ldb1 = NULL;
3881         int ret;
3882         struct ldbtest_ctx *test_ctx = NULL;
3883         int pipes[2];
3884         char buf[2];
3885         int wstatus;
3886         pid_t pid, child_pid;
3887
3888         test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx);
3889
3890         /*
3891          * Open the database
3892          */
3893         ldb1 = ldb_init(test_ctx, test_ctx->ev);
3894         ret = ldb_connect(ldb1, test_ctx->dbpath, 0, NULL);
3895         assert_int_equal(ret, 0);
3896
3897         ret = ldb_transaction_start(ldb1);
3898         assert_int_equal(ret, 0);
3899
3900         ret = pipe(pipes);
3901         assert_int_equal(ret, 0);
3902
3903         child_pid = fork();
3904         if (child_pid == 0) {
3905                 close(pipes[0]);
3906                 ret = ldb_transaction_commit(ldb1);
3907
3908                 if (ret != LDB_ERR_PROTOCOL_ERROR) {
3909                         print_error(__location__": ldb_transaction_commit "
3910                                     "returned (%d) %s\n",
3911                                     ret,
3912                                     ldb1->err_string);
3913                         exit(LDB_ERR_OTHER);
3914                 }
3915
3916                 ret = write(pipes[1], "GO", 2);
3917                 if (ret != 2) {
3918                         print_error(__location__
3919                                       " write returned (%d)",
3920                                       ret);
3921                         exit(LDB_ERR_OPERATIONS_ERROR);
3922                 }
3923                 exit(LDB_SUCCESS);
3924         }
3925         close(pipes[1]);
3926         ret = read(pipes[0], buf, 2);
3927         assert_int_equal(ret, 2);
3928
3929         pid = waitpid(child_pid, &wstatus, 0);
3930         assert_int_equal(pid, child_pid);
3931
3932         assert_true(WIFEXITED(wstatus));
3933
3934         assert_int_equal(WEXITSTATUS(wstatus), 0);
3935 }
3936
3937 static void test_lock_read_across_fork(void **state)
3938 {
3939         struct ldb_context *ldb1 = NULL;
3940         int ret;
3941         struct ldbtest_ctx *test_ctx = NULL;
3942         int pipes[2];
3943         char buf[2];
3944         int wstatus;
3945         pid_t pid, child_pid;
3946
3947         test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx);
3948
3949         /*
3950          * Open the database
3951          */
3952         ldb1 = ldb_init(test_ctx, test_ctx->ev);
3953         ret = ldb_connect(ldb1, test_ctx->dbpath, 0, NULL);
3954         assert_int_equal(ret, 0);
3955
3956         ret = pipe(pipes);
3957         assert_int_equal(ret, 0);
3958
3959         child_pid = fork();
3960         if (child_pid == 0) {
3961                 struct ldb_dn *basedn;
3962                 struct ldb_result *result = NULL;
3963
3964                 close(pipes[0]);
3965
3966                 basedn = ldb_dn_new_fmt(test_ctx, test_ctx->ldb, "dc=test");
3967                 assert_non_null(basedn);
3968
3969                 ret = ldb_search(test_ctx->ldb,
3970                                  test_ctx,
3971                                  &result,
3972                                  basedn,
3973                                  LDB_SCOPE_BASE,
3974                                  NULL,
3975                                  NULL);
3976                 if (ret != LDB_ERR_PROTOCOL_ERROR) {
3977                         print_error(__location__": ldb_search "
3978                                     "returned (%d) %s\n",
3979                                     ret,
3980                                     ldb1->err_string);
3981                         exit(LDB_ERR_OTHER);
3982                 }
3983
3984                 ret = write(pipes[1], "GO", 2);
3985                 if (ret != 2) {
3986                         print_error(__location__
3987                                       " write returned (%d)",
3988                                       ret);
3989                         exit(LDB_ERR_OPERATIONS_ERROR);
3990                 }
3991                 exit(LDB_SUCCESS);
3992         }
3993         close(pipes[1]);
3994         ret = read(pipes[0], buf, 2);
3995         assert_int_equal(ret, 2);
3996
3997         pid = waitpid(child_pid, &wstatus, 0);
3998         assert_int_equal(pid, child_pid);
3999
4000         assert_true(WIFEXITED(wstatus));
4001
4002         assert_int_equal(WEXITSTATUS(wstatus), 0);
4003
4004         {
4005                 /*
4006                  * Ensure that the search actually succeeds on the opening
4007                  * pid
4008                  */
4009                 struct ldb_dn *basedn;
4010                 struct ldb_result *result = NULL;
4011
4012                 close(pipes[0]);
4013
4014                 basedn = ldb_dn_new_fmt(test_ctx, test_ctx->ldb, "dc=test");
4015                 assert_non_null(basedn);
4016
4017                 ret = ldb_search(test_ctx->ldb,
4018                                  test_ctx,
4019                                  &result,
4020                                  basedn,
4021                                  LDB_SCOPE_BASE,
4022                                  NULL,
4023                                  NULL);
4024                 assert_int_equal(0, ret);
4025         }
4026 }
4027
4028 static void test_multiple_opens_across_fork(void **state)
4029 {
4030         struct ldb_context *ldb1 = NULL;
4031         struct ldb_context *ldb2 = NULL;
4032         int ret;
4033         struct ldbtest_ctx *test_ctx = NULL;
4034         int pipes[2];
4035         char buf[2];
4036         int wstatus;
4037         pid_t pid, child_pid;
4038
4039         test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx);
4040
4041         /*
4042          * Open the database again
4043          */
4044         ldb1 = ldb_init(test_ctx, test_ctx->ev);
4045         ret = ldb_connect(ldb1, test_ctx->dbpath, LDB_FLG_RDONLY, NULL);
4046         assert_int_equal(ret, 0);
4047
4048         ldb2 = ldb_init(test_ctx, test_ctx->ev);
4049         ret = ldb_connect(ldb2, test_ctx->dbpath, 0, NULL);
4050         assert_int_equal(ret, 0);
4051
4052         ret = pipe(pipes);
4053         assert_int_equal(ret, 0);
4054
4055         child_pid = fork();
4056         if (child_pid == 0) {
4057                 struct ldb_context *ldb3 = NULL;
4058
4059                 close(pipes[0]);
4060                 ldb3 = ldb_init(test_ctx, test_ctx->ev);
4061                 ret = ldb_connect(ldb3, test_ctx->dbpath, 0, NULL);
4062                 if (ret != 0) {
4063                         print_error(__location__": ldb_connect returned (%d)\n",
4064                                     ret);
4065                         exit(ret);
4066                 }
4067                 ret = write(pipes[1], "GO", 2);
4068                 if (ret != 2) {
4069                         print_error(__location__
4070                                       " write returned (%d)",
4071                                       ret);
4072                         exit(LDB_ERR_OPERATIONS_ERROR);
4073                 }
4074                 exit(LDB_SUCCESS);
4075         }
4076         close(pipes[1]);
4077         ret = read(pipes[0], buf, 2);
4078         assert_int_equal(ret, 2);
4079
4080         pid = waitpid(child_pid, &wstatus, 0);
4081         assert_int_equal(pid, child_pid);
4082
4083         assert_true(WIFEXITED(wstatus));
4084
4085         assert_int_equal(WEXITSTATUS(wstatus), 0);
4086 }
4087
4088 int main(int argc, const char **argv)
4089 {
4090         const struct CMUnitTest tests[] = {
4091                 cmocka_unit_test_setup_teardown(test_connect,
4092                                                 ldbtest_noconn_setup,
4093                                                 ldbtest_noconn_teardown),
4094                 cmocka_unit_test_setup_teardown(test_ldif_message,
4095                                                 ldbtest_noconn_setup,
4096                                                 ldbtest_noconn_teardown),
4097                 cmocka_unit_test_setup_teardown(test_ldif_message_redacted,
4098                                                 ldbtest_noconn_setup,
4099                                                 ldbtest_noconn_teardown),
4100                 cmocka_unit_test_setup_teardown(test_ldb_add,
4101                                                 ldbtest_setup,
4102                                                 ldbtest_teardown),
4103                 cmocka_unit_test_setup_teardown(test_ldb_search,
4104                                                 ldbtest_setup,
4105                                                 ldbtest_teardown),
4106                 cmocka_unit_test_setup_teardown(test_ldb_del,
4107                                                 ldbtest_setup,
4108                                                 ldbtest_teardown),
4109                 cmocka_unit_test_setup_teardown(test_ldb_del_noexist,
4110                                                 ldbtest_setup,
4111                                                 ldbtest_teardown),
4112                 cmocka_unit_test_setup_teardown(test_ldb_handle,
4113                                                 ldbtest_setup,
4114                                                 ldbtest_teardown),
4115                 cmocka_unit_test_setup_teardown(test_ldb_build_search_req,
4116                                                 ldbtest_setup,
4117                                                 ldbtest_teardown),
4118                 cmocka_unit_test_setup_teardown(test_transactions,
4119                                                 ldbtest_setup,
4120                                                 ldbtest_teardown),
4121                 cmocka_unit_test_setup_teardown(test_nested_transactions,
4122                                                 ldbtest_setup,
4123                                                 ldbtest_teardown),
4124                 cmocka_unit_test_setup_teardown(test_ldb_modify_add_key,
4125                                                 ldb_modify_test_setup,
4126                                                 ldb_modify_test_teardown),
4127                 cmocka_unit_test_setup_teardown(test_ldb_modify_extend_key,
4128                                                 ldb_modify_test_setup,
4129                                                 ldb_modify_test_teardown),
4130                 cmocka_unit_test_setup_teardown(test_ldb_modify_add_key_noval,
4131                                                 ldb_modify_test_setup,
4132                                                 ldb_modify_test_teardown),
4133                 cmocka_unit_test_setup_teardown(test_ldb_modify_replace_key,
4134                                                 ldb_modify_test_setup,
4135                                                 ldb_modify_test_teardown),
4136                 cmocka_unit_test_setup_teardown(test_ldb_modify_replace_noexist_key,
4137                                                 ldb_modify_test_setup,
4138                                                 ldb_modify_test_teardown),
4139                 cmocka_unit_test_setup_teardown(test_ldb_modify_replace_zero_vals,
4140                                                 ldb_modify_test_setup,
4141                                                 ldb_modify_test_teardown),
4142                 cmocka_unit_test_setup_teardown(test_ldb_modify_replace_noexist_key_zero_vals,
4143                                                 ldb_modify_test_setup,
4144                                                 ldb_modify_test_teardown),
4145                 cmocka_unit_test_setup_teardown(test_ldb_modify_del_key,
4146                                                 ldb_modify_test_setup,
4147                                                 ldb_modify_test_teardown),
4148                 cmocka_unit_test_setup_teardown(test_ldb_modify_del_keyval,
4149                                                 ldb_modify_test_setup,
4150                                                 ldb_modify_test_teardown),
4151                 cmocka_unit_test_setup_teardown(test_search_match_none,
4152                                                 ldb_search_test_setup,
4153                                                 ldb_search_test_teardown),
4154                 cmocka_unit_test_setup_teardown(test_search_match_one,
4155                                                 ldb_search_test_setup,
4156                                                 ldb_search_test_teardown),
4157                 cmocka_unit_test_setup_teardown(test_search_match_filter,
4158                                                 ldb_search_test_setup,
4159                                                 ldb_search_test_teardown),
4160                 cmocka_unit_test_setup_teardown(test_search_match_both,
4161                                                 ldb_search_test_setup,
4162                                                 ldb_search_test_teardown),
4163                 cmocka_unit_test_setup_teardown(test_search_match_basedn,
4164                                                 ldb_search_test_setup,
4165                                                 ldb_search_test_teardown),
4166                 cmocka_unit_test_setup_teardown(test_ldb_search_against_transaction,
4167                                                 ldb_search_test_setup,
4168                                                 ldb_search_test_teardown),
4169                 cmocka_unit_test_setup_teardown(test_ldb_modify_during_unindexed_search,
4170                                                 ldb_search_test_setup,
4171                                                 ldb_search_test_teardown),
4172                 cmocka_unit_test_setup_teardown(test_ldb_modify_during_indexed_search,
4173                                                 ldb_search_test_setup,
4174                                                 ldb_search_test_teardown),
4175                 cmocka_unit_test_setup_teardown(test_ldb_rename_during_unindexed_search,
4176                                                 ldb_search_test_setup,
4177                                                 ldb_search_test_teardown),
4178                 cmocka_unit_test_setup_teardown(test_ldb_rename_during_indexed_search,
4179                                                 ldb_search_test_setup,
4180                                                 ldb_search_test_teardown),
4181                 cmocka_unit_test_setup_teardown(test_ldb_modify_during_whole_search,
4182                                                 ldb_search_test_setup,
4183                                                 ldb_search_test_teardown),
4184                 cmocka_unit_test_setup_teardown(test_ldb_modify_before_ldb_wait,
4185                                                 ldb_search_test_setup,
4186                                                 ldb_search_test_teardown),
4187                 cmocka_unit_test_setup_teardown(test_ldb_attrs_case_insensitive,
4188                                                 ldb_case_test_setup,
4189                                                 ldb_case_test_teardown),
4190                 cmocka_unit_test_setup_teardown(test_ldb_attrs_case_handler,
4191                                                 ldb_case_test_setup,
4192                                                 ldb_case_test_teardown),
4193                 cmocka_unit_test_setup_teardown(test_ldb_attrs_index_handler,
4194                                                 ldb_case_test_setup,
4195                                                 ldb_case_attrs_index_test_teardown),
4196                 cmocka_unit_test_setup_teardown(test_ldb_rename,
4197                                                 ldb_rename_test_setup,
4198                                                 ldb_rename_test_teardown),
4199                 cmocka_unit_test_setup_teardown(test_ldb_rename_from_doesnt_exist,
4200                                                 ldb_rename_test_setup,
4201                                                 ldb_rename_test_teardown),
4202                 cmocka_unit_test_setup_teardown(test_ldb_rename_to_exists,
4203                                                 ldb_rename_test_setup,
4204                                                 ldb_rename_test_teardown),
4205                 cmocka_unit_test_setup_teardown(test_ldb_rename_self,
4206                                                 ldb_rename_test_setup,
4207                                                 ldb_rename_test_teardown),
4208                 cmocka_unit_test_setup_teardown(test_ldb_rename_dn_case_change,
4209                                                 ldb_rename_test_setup,
4210                                                 ldb_rename_test_teardown),
4211                 cmocka_unit_test_setup_teardown(test_read_only,
4212                                                 ldb_read_only_setup,
4213                                                 ldb_read_only_teardown),
4214                 cmocka_unit_test_setup_teardown(
4215                         test_ldb_add_unique_value_to_unique_index,
4216                         ldb_unique_index_test_setup,
4217                         ldb_unique_index_test_teardown),
4218                 cmocka_unit_test_setup_teardown(
4219                         test_ldb_add_duplicate_value_to_unique_index,
4220                         ldb_unique_index_test_setup,
4221                         ldb_unique_index_test_teardown),
4222                 cmocka_unit_test_setup_teardown(
4223                         test_ldb_add_to_index_duplicates_allowed,
4224                         ldb_non_unique_index_test_setup,
4225                         ldb_non_unique_index_test_teardown),
4226                 cmocka_unit_test_setup_teardown(
4227                         test_ldb_add_to_index_unique_values_required,
4228                         ldb_non_unique_index_test_setup,
4229                         ldb_non_unique_index_test_teardown),
4230                 /* These tests are not compatible with mdb */
4231                 cmocka_unit_test_setup_teardown(
4232                         test_ldb_unique_index_duplicate_logging,
4233                         ldb_unique_index_test_setup,
4234                         ldb_unique_index_test_teardown),
4235                 cmocka_unit_test_setup_teardown(
4236                         test_ldb_duplicate_dn_logging,
4237                         ldb_unique_index_test_setup,
4238                         ldb_unique_index_test_teardown),
4239                 cmocka_unit_test_setup_teardown(
4240                         test_ldb_guid_index_duplicate_dn_logging,
4241                         ldb_guid_index_test_setup,
4242                         ldb_guid_index_test_teardown),
4243                 cmocka_unit_test_setup_teardown(
4244                         test_ldb_unique_index_duplicate_with_guid,
4245                         ldb_guid_index_test_setup,
4246                         ldb_guid_index_test_teardown),
4247                 cmocka_unit_test_setup_teardown(
4248                         test_ldb_talloc_destructor_transaction_cleanup,
4249                         ldbtest_setup,
4250                         ldbtest_teardown),
4251                 cmocka_unit_test_setup_teardown(
4252                         test_transaction_start_across_fork,
4253                         ldbtest_setup,
4254                         ldbtest_teardown),
4255                 cmocka_unit_test_setup_teardown(
4256                         test_transaction_commit_across_fork,
4257                         ldbtest_setup,
4258                         ldbtest_teardown),
4259                 cmocka_unit_test_setup_teardown(
4260                         test_lock_read_across_fork,
4261                         ldbtest_setup,
4262                         ldbtest_teardown),
4263                 cmocka_unit_test_setup_teardown(
4264                         test_multiple_opens_across_fork,
4265                         ldbtest_setup,
4266                         ldbtest_teardown),
4267         };
4268
4269         return cmocka_run_group_tests(tests, NULL, NULL);
4270 }