ldb tests: fix null test on incorrect variable
[metze/samba/wip.git] / lib / ldb / tests / ldb_mod_op_test.c
1 /*
2  * from cmocka.c:
3  * These headers or their equivalents should be included prior to
4  * including
5  * this header file.
6  *
7  * #include <stdarg.h>
8  * #include <stddef.h>
9  * #include <setjmp.h>
10  *
11  * This allows test applications to use custom definitions of C standard
12  * library functions and types.
13  */
14 #include <stdarg.h>
15 #include <stddef.h>
16 #include <setjmp.h>
17 #include <cmocka.h>
18
19 #include <errno.h>
20 #include <unistd.h>
21 #include <talloc.h>
22
23 #define TEVENT_DEPRECATED 1
24 #include <tevent.h>
25
26 #include <ldb.h>
27 #include <ldb_module.h>
28 #include <ldb_private.h>
29 #include <string.h>
30 #include <ctype.h>
31
32 #include <sys/wait.h>
33
34
35 #define DEFAULT_BE  "tdb"
36
37 #ifndef TEST_BE
38 #define TEST_BE DEFAULT_BE
39 #endif /* TEST_BE */
40
41 struct ldbtest_ctx {
42         struct tevent_context *ev;
43         struct ldb_context *ldb;
44
45         const char *dbfile;
46         const char *lockfile;   /* lockfile is separate */
47
48         const char *dbpath;
49 };
50
51 static void unlink_old_db(struct ldbtest_ctx *test_ctx)
52 {
53         int ret;
54
55         errno = 0;
56         ret = unlink(test_ctx->lockfile);
57         if (ret == -1 && errno != ENOENT) {
58                 fail();
59         }
60
61         errno = 0;
62         ret = unlink(test_ctx->dbfile);
63         if (ret == -1 && errno != ENOENT) {
64                 fail();
65         }
66 }
67
68 static int ldbtest_noconn_setup(void **state)
69 {
70         struct ldbtest_ctx *test_ctx;
71
72         test_ctx = talloc_zero(NULL, struct ldbtest_ctx);
73         assert_non_null(test_ctx);
74
75         test_ctx->ev = tevent_context_init(test_ctx);
76         assert_non_null(test_ctx->ev);
77
78         test_ctx->ldb = ldb_init(test_ctx, test_ctx->ev);
79         assert_non_null(test_ctx->ldb);
80
81         test_ctx->dbfile = talloc_strdup(test_ctx, "apitest.ldb");
82         assert_non_null(test_ctx->dbfile);
83
84         test_ctx->lockfile = talloc_asprintf(test_ctx, "%s-lock",
85                                              test_ctx->dbfile);
86         assert_non_null(test_ctx->lockfile);
87
88         test_ctx->dbpath = talloc_asprintf(test_ctx,
89                         TEST_BE"://%s", test_ctx->dbfile);
90         assert_non_null(test_ctx->dbpath);
91
92         unlink_old_db(test_ctx);
93         *state = test_ctx;
94         return 0;
95 }
96
97 static int ldbtest_noconn_teardown(void **state)
98 {
99         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
100                                                         struct ldbtest_ctx);
101
102         unlink_old_db(test_ctx);
103         talloc_free(test_ctx);
104         return 0;
105 }
106
107 static void test_connect(void **state)
108 {
109         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
110                                                         struct ldbtest_ctx);
111         int ret;
112
113         ret = ldb_connect(test_ctx->ldb, test_ctx->dbpath, 0, NULL);
114         assert_int_equal(ret, 0);
115 }
116
117 static struct ldb_message *get_test_ldb_message(TALLOC_CTX *mem_ctx,
118                                                 struct ldb_context *ldb)
119 {
120         struct ldb_message *msg = ldb_msg_new(mem_ctx);
121         int ret;
122         assert_non_null(msg);
123
124         msg->dn = ldb_dn_new(msg, ldb, "dc=samba,dc=org");
125         assert_non_null(msg->dn);
126         ret = ldb_msg_add_string(msg, "public", "key");
127         assert_int_equal(ret, LDB_SUCCESS);
128         ret = ldb_msg_add_string(msg, "supersecret", "password");
129         assert_int_equal(ret, LDB_SUCCESS);
130         ret = ldb_msg_add_string(msg, "binary", "\xff\xff\0");
131         assert_int_equal(ret, LDB_SUCCESS);
132         return msg;
133 }
134
135 static void test_ldif_message(void **state)
136 {
137         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
138                                                         struct ldbtest_ctx);
139         char *got_ldif;
140         const char *expected_ldif =
141                 "dn: dc=samba,dc=org\n"
142                 "changetype: add\n"
143                 "public: key\n"
144                 "supersecret: password\n"
145                 "binary:: //8=\n"
146                 "\n";
147         
148         struct ldb_message *msg = get_test_ldb_message(test_ctx,
149                                                        test_ctx->ldb);
150
151         got_ldif = ldb_ldif_message_string(test_ctx->ldb,
152                                            test_ctx,
153                                            LDB_CHANGETYPE_ADD,
154                                            msg);
155         assert_string_equal(got_ldif, expected_ldif);
156         TALLOC_FREE(got_ldif);
157 }
158
159 static void test_ldif_message_redacted(void **state)
160 {
161         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
162                                                         struct ldbtest_ctx);
163         int ret;
164         char *got_ldif;
165         const char *expected_ldif =
166                 "dn: dc=samba,dc=org\n"
167                 "changetype: add\n"
168                 "public: key\n"
169                 "# supersecret::: REDACTED SECRET ATTRIBUTE\n"
170                 "binary:: //8=\n"
171                 "\n";
172
173         const char *secret_attrs[] = {
174                 "supersecret",
175                 NULL
176         };
177         
178         struct ldb_message *msg = ldb_msg_new(test_ctx);
179
180         ldb_set_opaque(test_ctx->ldb,
181                        LDB_SECRET_ATTRIBUTE_LIST_OPAQUE,
182                        secret_attrs);
183         
184         assert_non_null(msg);
185
186         msg->dn = ldb_dn_new(msg, test_ctx->ldb, "dc=samba,dc=org");
187         ret = ldb_msg_add_string(msg, "public", "key");
188         assert_int_equal(ret, LDB_SUCCESS);
189         ret = ldb_msg_add_string(msg, "supersecret", "password");
190         assert_int_equal(ret, LDB_SUCCESS);
191         ret = ldb_msg_add_string(msg, "binary", "\xff\xff\0");
192         assert_int_equal(ret, LDB_SUCCESS);
193         got_ldif = ldb_ldif_message_redacted_string(test_ctx->ldb,
194                                                     test_ctx,
195                                                     LDB_CHANGETYPE_ADD,
196                                                     msg);
197         assert_string_equal(got_ldif, expected_ldif);
198         TALLOC_FREE(got_ldif);
199         assert_int_equal(ret, 0);
200 }
201
202 static int ldbtest_setup(void **state)
203 {
204         struct ldbtest_ctx *test_ctx;
205         int ret;
206
207         ldbtest_noconn_setup((void **) &test_ctx);
208
209         ret = ldb_connect(test_ctx->ldb, test_ctx->dbpath, 0, NULL);
210         assert_int_equal(ret, 0);
211
212         *state = test_ctx;
213         return 0;
214 }
215
216 static int ldbtest_teardown(void **state)
217 {
218         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
219                                                         struct ldbtest_ctx);
220         ldbtest_noconn_teardown((void **) &test_ctx);
221         return 0;
222 }
223
224 static void test_ldb_add(void **state)
225 {
226         int ret;
227         struct ldb_message *msg;
228         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
229                                                         struct ldbtest_ctx);
230         TALLOC_CTX *tmp_ctx;
231
232         tmp_ctx = talloc_new(test_ctx);
233         assert_non_null(tmp_ctx);
234
235         msg = ldb_msg_new(tmp_ctx);
236         assert_non_null(msg);
237
238         msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "dc=test");
239         assert_non_null(msg->dn);
240
241         ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
242         assert_int_equal(ret, 0);
243
244         ret = ldb_add(test_ctx->ldb, msg);
245         assert_int_equal(ret, 0);
246
247         talloc_free(tmp_ctx);
248 }
249
250 static void test_ldb_search(void **state)
251 {
252         int ret;
253         struct ldb_message *msg;
254         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
255                                                         struct ldbtest_ctx);
256         TALLOC_CTX *tmp_ctx;
257         struct ldb_dn *basedn;
258         struct ldb_dn *basedn2;
259         struct ldb_result *result = NULL;
260
261         tmp_ctx = talloc_new(test_ctx);
262         assert_non_null(tmp_ctx);
263
264         basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "dc=test");
265         assert_non_null(basedn);
266
267         ret = ldb_search(test_ctx->ldb, tmp_ctx, &result, basedn,
268                          LDB_SCOPE_BASE, NULL, NULL);
269         assert_int_equal(ret, 0);
270         assert_non_null(result);
271         assert_int_equal(result->count, 0);
272
273         msg = ldb_msg_new(tmp_ctx);
274         assert_non_null(msg);
275
276         msg->dn = basedn;
277         assert_non_null(msg->dn);
278
279         ret = ldb_msg_add_string(msg, "cn", "test_cn_val1");
280         assert_int_equal(ret, 0);
281
282         ret = ldb_add(test_ctx->ldb, msg);
283         assert_int_equal(ret, 0);
284
285         basedn2 = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "dc=test2");
286         assert_non_null(basedn2);
287
288         msg = ldb_msg_new(tmp_ctx);
289         assert_non_null(msg);
290
291         msg->dn = basedn2;
292         assert_non_null(msg->dn);
293
294         ret = ldb_msg_add_string(msg, "cn", "test_cn_val2");
295         assert_int_equal(ret, 0);
296
297         ret = ldb_add(test_ctx->ldb, msg);
298         assert_int_equal(ret, 0);
299
300         ret = ldb_search(test_ctx->ldb, tmp_ctx, &result, basedn,
301                          LDB_SCOPE_BASE, NULL, NULL);
302         assert_int_equal(ret, 0);
303         assert_non_null(result);
304         assert_int_equal(result->count, 1);
305         assert_string_equal(ldb_dn_get_linearized(result->msgs[0]->dn),
306                             ldb_dn_get_linearized(basedn));
307
308         ret = ldb_search(test_ctx->ldb, tmp_ctx, &result, basedn2,
309                          LDB_SCOPE_BASE, NULL, NULL);
310         assert_int_equal(ret, 0);
311         assert_non_null(result);
312         assert_int_equal(result->count, 1);
313         assert_string_equal(ldb_dn_get_linearized(result->msgs[0]->dn),
314                             ldb_dn_get_linearized(basedn2));
315
316         talloc_free(tmp_ctx);
317 }
318
319 static int base_search_count(struct ldbtest_ctx *test_ctx, const char *entry_dn)
320 {
321         TALLOC_CTX *tmp_ctx;
322         struct ldb_dn *basedn;
323         struct ldb_result *result = NULL;
324         int ret;
325         int count;
326
327         tmp_ctx = talloc_new(test_ctx);
328         assert_non_null(tmp_ctx);
329
330         basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "%s", entry_dn);
331         assert_non_null(basedn);
332
333         ret = ldb_search(test_ctx->ldb, tmp_ctx, &result, basedn,
334                          LDB_SCOPE_BASE, NULL, NULL);
335         assert_int_equal(ret, LDB_SUCCESS);
336         assert_non_null(result);
337
338         count = result->count;
339         talloc_free(tmp_ctx);
340         return count;
341 }
342
343 static int sub_search_count(struct ldbtest_ctx *test_ctx,
344                             const char *base_dn,
345                             const char *filter)
346 {
347         TALLOC_CTX *tmp_ctx;
348         struct ldb_dn *basedn;
349         struct ldb_result *result = NULL;
350         int ret;
351         int count;
352
353         tmp_ctx = talloc_new(test_ctx);
354         assert_non_null(tmp_ctx);
355
356         basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "%s", base_dn);
357         assert_non_null(basedn);
358
359         ret = ldb_search(test_ctx->ldb, tmp_ctx, &result, basedn,
360                          LDB_SCOPE_SUBTREE, NULL, "%s", filter);
361         assert_int_equal(ret, LDB_SUCCESS);
362         assert_non_null(result);
363
364         count = result->count;
365         talloc_free(tmp_ctx);
366         return count;
367 }
368
369 /* In general it would be better if utility test functions didn't assert
370  * but only returned a value, then assert in the test shows correct
371  * line
372  */
373 static void assert_dn_exists(struct ldbtest_ctx *test_ctx,
374                              const char *entry_dn)
375 {
376         int count;
377
378         count = base_search_count(test_ctx, entry_dn);
379         assert_int_equal(count, 1);
380 }
381
382 static void assert_dn_doesnt_exist(struct ldbtest_ctx *test_ctx,
383                                    const char *entry_dn)
384 {
385         int count;
386
387         count = base_search_count(test_ctx, entry_dn);
388         assert_int_equal(count, 0);
389 }
390
391 static void add_dn_with_cn(struct ldbtest_ctx *test_ctx,
392                            struct ldb_dn *dn,
393                            const char *cn_value)
394 {
395         int ret;
396         TALLOC_CTX *tmp_ctx;
397         struct ldb_message *msg;
398
399         tmp_ctx = talloc_new(test_ctx);
400         assert_non_null(tmp_ctx);
401
402         assert_dn_doesnt_exist(test_ctx,
403                                ldb_dn_get_linearized(dn));
404
405         msg = ldb_msg_new(tmp_ctx);
406         assert_non_null(msg);
407         msg->dn = dn;
408
409         ret = ldb_msg_add_string(msg, "cn", cn_value);
410         assert_int_equal(ret, LDB_SUCCESS);
411
412         ret = ldb_add(test_ctx->ldb, msg);
413         assert_int_equal(ret, LDB_SUCCESS);
414
415         assert_dn_exists(test_ctx,
416                          ldb_dn_get_linearized(dn));
417         talloc_free(tmp_ctx);
418 }
419
420 static void test_ldb_del(void **state)
421 {
422         int ret;
423         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
424                                                         struct ldbtest_ctx);
425         const char *basedn = "dc=ldb_del_test";
426         struct ldb_dn *dn;
427
428         dn = ldb_dn_new_fmt(test_ctx, test_ctx->ldb, "%s", basedn);
429         assert_non_null(dn);
430
431         add_dn_with_cn(test_ctx, dn, "test_del_cn_val");
432
433         ret = ldb_delete(test_ctx->ldb, dn);
434         assert_int_equal(ret, LDB_SUCCESS);
435
436         assert_dn_doesnt_exist(test_ctx, basedn);
437 }
438
439 static void test_ldb_del_noexist(void **state)
440 {
441         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
442                                                              struct ldbtest_ctx);
443         struct ldb_dn *basedn;
444         int ret;
445
446         basedn = ldb_dn_new(test_ctx, test_ctx->ldb, "dc=nosuchplace");
447         assert_non_null(basedn);
448
449         ret = ldb_delete(test_ctx->ldb, basedn);
450         assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT);
451 }
452
453 static void test_ldb_handle(void **state)
454 {
455         int ret;
456         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
457                                                         struct ldbtest_ctx);
458         TALLOC_CTX *tmp_ctx;
459         struct ldb_dn *basedn;
460         struct ldb_request *request = NULL;
461         struct ldb_request *request2 = NULL;
462         struct ldb_result *res = NULL;
463         const char *attrs[] = { "cn", NULL };
464
465         tmp_ctx = talloc_new(test_ctx);
466         assert_non_null(tmp_ctx);
467
468         basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "dc=test");
469         assert_non_null(basedn);
470
471         res = talloc_zero(tmp_ctx, struct ldb_result);
472         assert_non_null(res);
473
474         ret = ldb_build_search_req(&request, test_ctx->ldb, tmp_ctx,
475                                    basedn, LDB_SCOPE_BASE,
476                                    NULL, attrs, NULL, res,
477                                    ldb_search_default_callback,
478                                    NULL);
479         assert_int_equal(ret, 0);
480
481         /* We are against ldb_tdb, so expect private event contexts */
482         assert_ptr_not_equal(ldb_handle_get_event_context(request->handle),
483                              ldb_get_event_context(test_ctx->ldb));
484
485         ret = ldb_build_search_req(&request2, test_ctx->ldb, tmp_ctx,
486                                    basedn, LDB_SCOPE_BASE,
487                                    NULL, attrs, NULL, res,
488                                    ldb_search_default_callback,
489                                    request);
490         assert_int_equal(ret, 0);
491
492         /* Expect that same event context will be chained */
493         assert_ptr_equal(ldb_handle_get_event_context(request->handle),
494                          ldb_handle_get_event_context(request2->handle));
495
496         /* Now force this to use the global context */
497         ldb_handle_use_global_event_context(request2->handle);
498         assert_ptr_equal(ldb_handle_get_event_context(request2->handle),
499                          ldb_get_event_context(test_ctx->ldb));
500
501         talloc_free(tmp_ctx);
502 }
503
504 static void test_ldb_build_search_req(void **state)
505 {
506         int ret;
507         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
508                                                         struct ldbtest_ctx);
509         TALLOC_CTX *tmp_ctx;
510         struct ldb_dn *basedn;
511         struct ldb_request *request = NULL;
512         struct ldb_request *request2 = NULL;
513         struct ldb_result *res = NULL;
514         const char *attrs[] = { "cn", NULL };
515
516         tmp_ctx = talloc_new(test_ctx);
517         assert_non_null(tmp_ctx);
518
519         basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "dc=test");
520         assert_non_null(basedn);
521
522         res = talloc_zero(tmp_ctx, struct ldb_result);
523         assert_non_null(res);
524
525         ret = ldb_build_search_req(&request, test_ctx->ldb, tmp_ctx,
526                                    basedn, LDB_SCOPE_BASE,
527                                    NULL, attrs, NULL, res,
528                                    ldb_search_default_callback,
529                                    NULL);
530         assert_int_equal(ret, 0);
531
532         assert_int_equal(request->operation, LDB_SEARCH);
533         assert_ptr_equal(request->op.search.base, basedn);
534         assert_int_equal(request->op.search.scope, LDB_SCOPE_BASE);
535         assert_non_null(request->op.search.tree);
536         assert_ptr_equal(request->op.search.attrs, attrs);
537         assert_ptr_equal(request->context, res);
538         assert_ptr_equal(request->callback, ldb_search_default_callback);
539
540         ret = ldb_build_search_req(&request2, test_ctx->ldb, tmp_ctx,
541                                    basedn, LDB_SCOPE_BASE,
542                                    NULL, attrs, NULL, res,
543                                    ldb_search_default_callback,
544                                    request);
545         assert_int_equal(ret, 0);
546         assert_ptr_equal(request, request2->handle->parent);
547         assert_int_equal(request->starttime, request2->starttime);
548         assert_int_equal(request->timeout, request2->timeout);
549
550         talloc_free(tmp_ctx);
551 }
552
553 static void add_keyval(struct ldbtest_ctx *test_ctx,
554                        const char *key,
555                        const char *val)
556 {
557         int ret;
558         struct ldb_message *msg;
559
560         msg = ldb_msg_new(test_ctx);
561         assert_non_null(msg);
562
563         msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "%s=%s", key, val);
564         assert_non_null(msg->dn);
565
566         ret = ldb_msg_add_string(msg, key, val);
567         assert_int_equal(ret, 0);
568
569         ret = ldb_add(test_ctx->ldb, msg);
570         assert_int_equal(ret, 0);
571
572         talloc_free(msg);
573 }
574
575 static struct ldb_result *get_keyval(struct ldbtest_ctx *test_ctx,
576                                      const char *key,
577                                      const char *val)
578 {
579         int ret;
580         struct ldb_result *result;
581         struct ldb_dn *basedn;
582
583         basedn = ldb_dn_new_fmt(test_ctx, test_ctx->ldb, "%s=%s", key, val);
584         assert_non_null(basedn);
585
586         ret = ldb_search(test_ctx->ldb, test_ctx, &result, basedn,
587                         LDB_SCOPE_BASE, NULL, NULL);
588         assert_int_equal(ret, 0);
589
590         return result;
591 }
592
593 static void test_transactions(void **state)
594 {
595         int ret;
596         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
597                         struct ldbtest_ctx);
598         struct ldb_result *res;
599
600         /* start lev-0 transaction */
601         ret = ldb_transaction_start(test_ctx->ldb);
602         assert_int_equal(ret, 0);
603
604         add_keyval(test_ctx, "vegetable", "carrot");
605
606         /* commit lev-0 transaction */
607         ret = ldb_transaction_commit(test_ctx->ldb);
608         assert_int_equal(ret, 0);
609
610         /* start another lev-1 nested transaction */
611         ret = ldb_transaction_start(test_ctx->ldb);
612         assert_int_equal(ret, 0);
613
614         add_keyval(test_ctx, "fruit", "apple");
615
616         /* abort lev-1 nested transaction */
617         ret = ldb_transaction_cancel(test_ctx->ldb);
618         assert_int_equal(ret, 0);
619
620         res = get_keyval(test_ctx, "vegetable", "carrot");
621         assert_non_null(res);
622         assert_int_equal(res->count, 1);
623
624         res = get_keyval(test_ctx, "fruit", "apple");
625         assert_non_null(res);
626         assert_int_equal(res->count, 0);
627 }
628
629 struct ldb_mod_test_ctx {
630         struct ldbtest_ctx *ldb_test_ctx;
631         const char *entry_dn;
632 };
633
634 struct keyval {
635         const char *key;
636         const char *val;
637 };
638
639 static struct ldb_message *build_mod_msg(TALLOC_CTX *mem_ctx,
640                                          struct ldbtest_ctx *test_ctx,
641                                          const char *dn,
642                                          int modify_flags,
643                                          struct keyval *kvs)
644 {
645         struct ldb_message *msg;
646         int ret;
647         int i;
648
649         msg = ldb_msg_new(mem_ctx);
650         assert_non_null(msg);
651
652         msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "%s", dn);
653         assert_non_null(msg->dn);
654
655         for (i = 0; kvs[i].key != NULL; i++) {
656                 if (modify_flags) {
657                         ret = ldb_msg_add_empty(msg, kvs[i].key,
658                                                 modify_flags, NULL);
659                         assert_int_equal(ret, 0);
660                 }
661
662                 if (kvs[i].val) {
663                         ret = ldb_msg_add_string(msg, kvs[i].key, kvs[i].val);
664                         assert_int_equal(ret, LDB_SUCCESS);
665                 }
666         }
667
668         return msg;
669 }
670
671 static void ldb_test_add_data(TALLOC_CTX *mem_ctx,
672                               struct ldbtest_ctx *ldb_test_ctx,
673                               const char *basedn,
674                               struct keyval *kvs)
675 {
676         TALLOC_CTX *tmp_ctx;
677         struct ldb_message *msg;
678         struct ldb_result *result = NULL;
679         int ret;
680
681         tmp_ctx = talloc_new(mem_ctx);
682         assert_non_null(tmp_ctx);
683
684         msg = build_mod_msg(tmp_ctx, ldb_test_ctx,
685                             basedn, 0, kvs);
686         assert_non_null(msg);
687
688         ret = ldb_add(ldb_test_ctx->ldb, msg);
689         assert_int_equal(ret, LDB_SUCCESS);
690
691         ret = ldb_search(ldb_test_ctx->ldb, tmp_ctx, &result, msg->dn,
692                          LDB_SCOPE_BASE, NULL, NULL);
693         assert_int_equal(ret, LDB_SUCCESS);
694         assert_non_null(result);
695         assert_int_equal(result->count, 1);
696         assert_string_equal(ldb_dn_get_linearized(result->msgs[0]->dn),
697                             ldb_dn_get_linearized(msg->dn));
698
699         talloc_free(tmp_ctx);
700 }
701
702 static void ldb_test_remove_data(TALLOC_CTX *mem_ctx,
703                                  struct ldbtest_ctx *ldb_test_ctx,
704                                  const char *strdn)
705 {
706         TALLOC_CTX *tmp_ctx;
707         struct ldb_dn *basedn;
708         int ret;
709         size_t count;
710
711         tmp_ctx = talloc_new(mem_ctx);
712         assert_non_null(tmp_ctx);
713
714         basedn = ldb_dn_new_fmt(tmp_ctx, ldb_test_ctx->ldb,
715                                 "%s", strdn);
716         assert_non_null(basedn);
717
718         ret = ldb_delete(ldb_test_ctx->ldb, basedn);
719         assert_true(ret == LDB_SUCCESS || ret == LDB_ERR_NO_SUCH_OBJECT);
720
721         count = base_search_count(ldb_test_ctx, ldb_dn_get_linearized(basedn));
722         assert_int_equal(count, 0);
723
724         talloc_free(tmp_ctx);
725 }
726
727 static void mod_test_add_data(struct ldb_mod_test_ctx *mod_test_ctx,
728                               struct keyval *kvs)
729 {
730         ldb_test_add_data(mod_test_ctx,
731                           mod_test_ctx->ldb_test_ctx,
732                           mod_test_ctx->entry_dn,
733                           kvs);
734 }
735
736 static void mod_test_remove_data(struct ldb_mod_test_ctx *mod_test_ctx)
737 {
738         ldb_test_remove_data(mod_test_ctx,
739                              mod_test_ctx->ldb_test_ctx,
740                              mod_test_ctx->entry_dn);
741 }
742
743 static struct ldb_result *run_mod_test(struct ldb_mod_test_ctx *mod_test_ctx,
744                                        int modify_flags,
745                                        struct keyval *kvs)
746 {
747         TALLOC_CTX *tmp_ctx;
748         struct ldb_result *res;
749         struct ldb_message *mod_msg;
750         struct ldb_dn *basedn;
751         struct ldbtest_ctx *ldb_test_ctx;
752         int ret;
753
754         ldb_test_ctx = mod_test_ctx->ldb_test_ctx;
755
756         tmp_ctx = talloc_new(mod_test_ctx);
757         assert_non_null(tmp_ctx);
758
759         mod_msg = build_mod_msg(tmp_ctx, ldb_test_ctx, mod_test_ctx->entry_dn,
760                                 modify_flags, kvs);
761         assert_non_null(mod_msg);
762
763         ret = ldb_modify(ldb_test_ctx->ldb, mod_msg);
764         assert_int_equal(ret, LDB_SUCCESS);
765
766         basedn = ldb_dn_new_fmt(tmp_ctx, ldb_test_ctx->ldb,
767                         "%s", mod_test_ctx->entry_dn);
768         assert_non_null(basedn);
769
770         ret = ldb_search(ldb_test_ctx->ldb, mod_test_ctx, &res, basedn,
771                          LDB_SCOPE_BASE, NULL, NULL);
772         assert_int_equal(ret, LDB_SUCCESS);
773         assert_non_null(res);
774         assert_int_equal(res->count, 1);
775         assert_string_equal(ldb_dn_get_linearized(res->msgs[0]->dn),
776                             ldb_dn_get_linearized(mod_msg->dn));
777
778         talloc_free(tmp_ctx);
779         return res;
780 }
781
782 static int ldb_modify_test_setup(void **state)
783 {
784         struct ldbtest_ctx *ldb_test_ctx;
785         struct ldb_mod_test_ctx *mod_test_ctx;
786         struct keyval kvs[] = {
787                 { "cn", "test_mod_cn" },
788                 { NULL, NULL },
789         };
790
791         ldbtest_setup((void **) &ldb_test_ctx);
792
793         mod_test_ctx = talloc(ldb_test_ctx, struct ldb_mod_test_ctx);
794         assert_non_null(mod_test_ctx);
795
796         mod_test_ctx->entry_dn = "dc=mod_test_entry";
797         mod_test_ctx->ldb_test_ctx = ldb_test_ctx;
798
799         mod_test_remove_data(mod_test_ctx);
800         mod_test_add_data(mod_test_ctx, kvs);
801         *state = mod_test_ctx;
802         return 0;
803 }
804
805 static int ldb_modify_test_teardown(void **state)
806 {
807         struct ldb_mod_test_ctx *mod_test_ctx = \
808                                 talloc_get_type_abort(*state,
809                                                       struct ldb_mod_test_ctx);
810         struct ldbtest_ctx *ldb_test_ctx;
811
812         ldb_test_ctx = mod_test_ctx->ldb_test_ctx;
813
814         mod_test_remove_data(mod_test_ctx);
815         talloc_free(mod_test_ctx);
816
817         ldbtest_teardown((void **) &ldb_test_ctx);
818         return 0;
819 }
820
821 static void test_ldb_modify_add_key(void **state)
822 {
823         struct ldb_mod_test_ctx *mod_test_ctx = \
824                                 talloc_get_type_abort(*state,
825                                                       struct ldb_mod_test_ctx);
826         struct keyval mod_kvs[] = {
827                 { "name", "test_mod_name" },
828                 { NULL, NULL },
829         };
830         struct ldb_result *res;
831         struct ldb_message_element *el;
832
833         res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_ADD, mod_kvs);
834         assert_non_null(res);
835
836         /* Check cn is intact and name was added */
837         assert_int_equal(res->count, 1);
838         el = ldb_msg_find_element(res->msgs[0], "cn");
839         assert_non_null(el);
840         assert_int_equal(el->num_values, 1);
841         assert_string_equal(el->values[0].data, "test_mod_cn");
842
843         el = ldb_msg_find_element(res->msgs[0], "name");
844         assert_non_null(el);
845         assert_int_equal(el->num_values, 1);
846         assert_string_equal(el->values[0].data, "test_mod_name");
847 }
848
849 static void test_ldb_modify_extend_key(void **state)
850 {
851         struct ldb_mod_test_ctx *mod_test_ctx = \
852                         talloc_get_type_abort(*state,
853                                               struct ldb_mod_test_ctx);
854         struct keyval mod_kvs[] = {
855                 { "cn", "test_mod_cn2" },
856                 { NULL, NULL },
857         };
858         struct ldb_result *res;
859         struct ldb_message_element *el;
860
861         res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_ADD, mod_kvs);
862         assert_non_null(res);
863
864         /* Check cn was extended with another value */
865         assert_int_equal(res->count, 1);
866         el = ldb_msg_find_element(res->msgs[0], "cn");
867         assert_non_null(el);
868         assert_int_equal(el->num_values, 2);
869         assert_string_equal(el->values[0].data, "test_mod_cn");
870         assert_string_equal(el->values[1].data, "test_mod_cn2");
871 }
872
873 static void test_ldb_modify_add_key_noval(void **state)
874 {
875         struct ldb_mod_test_ctx *mod_test_ctx = \
876                         talloc_get_type_abort(*state,
877                                               struct ldb_mod_test_ctx);
878         struct ldb_message *mod_msg;
879         struct ldbtest_ctx *ldb_test_ctx;
880         struct ldb_message_element *el;
881         int ret;
882
883         ldb_test_ctx = mod_test_ctx->ldb_test_ctx;
884
885         mod_msg = ldb_msg_new(mod_test_ctx);
886         assert_non_null(mod_msg);
887
888         mod_msg->dn = ldb_dn_new_fmt(mod_msg, ldb_test_ctx->ldb,
889                         "%s", mod_test_ctx->entry_dn);
890         assert_non_null(mod_msg->dn);
891
892         el = talloc_zero(mod_msg, struct ldb_message_element);
893         el->flags = LDB_FLAG_MOD_ADD;
894         assert_non_null(el);
895         el->name = talloc_strdup(el, "cn");
896         assert_non_null(el->name);
897
898         mod_msg->elements = el;
899         mod_msg->num_elements = 1;
900
901         ret = ldb_modify(ldb_test_ctx->ldb, mod_msg);
902         assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION);
903 }
904
905 static void test_ldb_modify_replace_key(void **state)
906 {
907         struct ldb_mod_test_ctx *mod_test_ctx = \
908                         talloc_get_type_abort(*state,
909                                               struct ldb_mod_test_ctx);
910         const char *new_cn = "new_cn";
911         struct keyval mod_kvs[] = {
912                 { "cn", new_cn },
913                 { NULL, NULL },
914         };
915         struct ldb_result *res;
916         struct ldb_message_element *el;
917
918         res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, mod_kvs);
919         assert_non_null(res);
920
921         /* Check cn was replaced */
922         assert_int_equal(res->count, 1);
923         el = ldb_msg_find_element(res->msgs[0], "cn");
924         assert_non_null(el);
925         assert_int_equal(el->num_values, 1);
926         assert_string_equal(el->values[0].data, new_cn);
927 }
928
929 static void test_ldb_modify_replace_noexist_key(void **state)
930 {
931         struct ldb_mod_test_ctx *mod_test_ctx = \
932                         talloc_get_type_abort(*state,
933                                               struct ldb_mod_test_ctx);
934         struct keyval mod_kvs[] = {
935                 { "name", "name_val" },
936                 { NULL, NULL },
937         };
938         struct ldb_result *res;
939         struct ldb_message_element *el;
940
941         res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, mod_kvs);
942         assert_non_null(res);
943
944         /* Check cn is intact and name was added */
945         assert_int_equal(res->count, 1);
946         el = ldb_msg_find_element(res->msgs[0], "cn");
947         assert_non_null(el);
948         assert_int_equal(el->num_values, 1);
949         assert_string_equal(el->values[0].data, "test_mod_cn");
950
951         el = ldb_msg_find_element(res->msgs[0], mod_kvs[0].key);
952         assert_non_null(el);
953         assert_int_equal(el->num_values, 1);
954         assert_string_equal(el->values[0].data, mod_kvs[0].val);
955 }
956
957 static void test_ldb_modify_replace_zero_vals(void **state)
958 {
959         struct ldb_mod_test_ctx *mod_test_ctx = \
960                         talloc_get_type_abort(*state,
961                                               struct ldb_mod_test_ctx);
962         struct ldb_message_element *el;
963         struct ldb_result *res;
964         struct keyval kvs[] = {
965                 { "cn", NULL },
966                 { NULL, NULL },
967         };
968
969         /* cn must be gone */
970         res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, kvs);
971         assert_non_null(res);
972         el = ldb_msg_find_element(res->msgs[0], "cn");
973         assert_null(el);
974 }
975
976 static void test_ldb_modify_replace_noexist_key_zero_vals(void **state)
977 {
978         struct ldb_mod_test_ctx *mod_test_ctx = \
979                         talloc_get_type_abort(*state,
980                                               struct ldb_mod_test_ctx);
981         struct ldb_message_element *el;
982         struct ldb_result *res;
983         struct keyval kvs[] = {
984                 { "noexist_key", NULL },
985                 { NULL, NULL },
986         };
987
988         /* cn must be gone */
989         res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, kvs);
990         assert_non_null(res);
991
992         /* cn should be intact */
993         el = ldb_msg_find_element(res->msgs[0], "cn");
994         assert_non_null(el);
995 }
996
997 static void test_ldb_modify_del_key(void **state)
998 {
999         struct ldb_mod_test_ctx *mod_test_ctx = \
1000                         talloc_get_type_abort(*state,
1001                                               struct ldb_mod_test_ctx);
1002         struct ldb_message_element *el;
1003         struct ldb_result *res;
1004         struct keyval kvs[] = {
1005                 { "cn", NULL },
1006                 { NULL, NULL },
1007         };
1008
1009         /* cn must be gone */
1010         res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_DELETE, kvs);
1011         assert_non_null(res);
1012
1013         el = ldb_msg_find_element(res->msgs[0], "cn");
1014         assert_null(el);
1015 }
1016
1017 static void test_ldb_modify_del_keyval(void **state)
1018 {
1019         struct ldb_mod_test_ctx *mod_test_ctx = \
1020                         talloc_get_type_abort(*state,
1021                                               struct ldb_mod_test_ctx);
1022         struct ldb_message_element *el;
1023         struct ldb_result *res;
1024         struct keyval kvs[] = {
1025                 { "cn", "test_mod_cn" },
1026                 { NULL, NULL },
1027         };
1028
1029         /* cn must be gone */
1030         res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_DELETE, kvs);
1031         assert_non_null(res);
1032
1033         el = ldb_msg_find_element(res->msgs[0], "cn");
1034         assert_null(el);
1035 }
1036
1037 struct search_test_ctx {
1038         struct ldbtest_ctx *ldb_test_ctx;
1039         const char *base_dn;
1040 };
1041
1042 static char *get_full_dn(TALLOC_CTX *mem_ctx,
1043                          struct search_test_ctx *search_test_ctx,
1044                          const char *rdn)
1045 {
1046         char *full_dn;
1047
1048         full_dn = talloc_asprintf(mem_ctx,
1049                                   "%s,%s", rdn, search_test_ctx->base_dn);
1050         assert_non_null(full_dn);
1051
1052         return full_dn;
1053 }
1054
1055 static void search_test_add_data(struct search_test_ctx *search_test_ctx,
1056                                  const char *rdn,
1057                                  struct keyval *kvs)
1058 {
1059         char *full_dn;
1060
1061         full_dn = get_full_dn(search_test_ctx, search_test_ctx, rdn);
1062
1063         ldb_test_add_data(search_test_ctx,
1064                           search_test_ctx->ldb_test_ctx,
1065                           full_dn,
1066                           kvs);
1067 }
1068
1069 static void search_test_remove_data(struct search_test_ctx *search_test_ctx,
1070                                     const char *rdn)
1071 {
1072         char *full_dn;
1073
1074         full_dn = talloc_asprintf(search_test_ctx,
1075                                   "%s,%s", rdn, search_test_ctx->base_dn);
1076         assert_non_null(full_dn);
1077
1078         ldb_test_remove_data(search_test_ctx,
1079                              search_test_ctx->ldb_test_ctx,
1080                              full_dn);
1081 }
1082
1083 static int ldb_search_test_setup(void **state)
1084 {
1085         struct ldbtest_ctx *ldb_test_ctx;
1086         struct search_test_ctx *search_test_ctx;
1087         struct keyval kvs[] = {
1088                 { "cn", "test_search_cn" },
1089                 { "cn", "test_search_cn2" },
1090                 { "uid", "test_search_uid" },
1091                 { "uid", "test_search_uid2" },
1092                 { NULL, NULL },
1093         };
1094         struct keyval kvs2[] = {
1095                 { "cn", "test_search_2_cn" },
1096                 { "cn", "test_search_2_cn2" },
1097                 { "uid", "test_search_2_uid" },
1098                 { "uid", "test_search_2_uid2" },
1099                 { NULL, NULL },
1100         };
1101
1102         ldbtest_setup((void **) &ldb_test_ctx);
1103
1104         search_test_ctx = talloc(ldb_test_ctx, struct search_test_ctx);
1105         assert_non_null(search_test_ctx);
1106
1107         search_test_ctx->base_dn = "dc=search_test_entry";
1108         search_test_ctx->ldb_test_ctx = ldb_test_ctx;
1109
1110         search_test_remove_data(search_test_ctx, "cn=test_search_cn");
1111         search_test_add_data(search_test_ctx, "cn=test_search_cn", kvs);
1112
1113         search_test_remove_data(search_test_ctx, "cn=test_search_2_cn");
1114         search_test_add_data(search_test_ctx, "cn=test_search_2_cn", kvs2);
1115
1116         *state = search_test_ctx;
1117         return 0;
1118 }
1119
1120 static int ldb_search_test_teardown(void **state)
1121 {
1122         struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1123                         struct search_test_ctx);
1124         struct ldbtest_ctx *ldb_test_ctx;
1125
1126         ldb_test_ctx = search_test_ctx->ldb_test_ctx;
1127
1128         search_test_remove_data(search_test_ctx, "cn=test_search_cn");
1129         search_test_remove_data(search_test_ctx, "cn=test_search_2_cn");
1130         ldbtest_teardown((void **) &ldb_test_ctx);
1131         return 0;
1132 }
1133
1134 static void assert_attr_has_vals(struct ldb_message *msg,
1135                                  const char *attr,
1136                                  const char *vals[],
1137                                  const size_t nvals)
1138 {
1139         struct ldb_message_element *el;
1140         size_t i;
1141
1142         el = ldb_msg_find_element(msg, attr);
1143         assert_non_null(el);
1144
1145         assert_int_equal(el->num_values, nvals);
1146         for (i = 0; i < nvals; i++) {
1147                 assert_string_equal(el->values[i].data,
1148                                     vals[i]);
1149         }
1150 }
1151
1152 static void assert_has_no_attr(struct ldb_message *msg,
1153                                const char *attr)
1154 {
1155         struct ldb_message_element *el;
1156
1157         el = ldb_msg_find_element(msg, attr);
1158         assert_null(el);
1159 }
1160
1161 static bool has_dn(struct ldb_message *msg, const char *dn)
1162 {
1163         const char *msgdn;
1164
1165         msgdn = ldb_dn_get_linearized(msg->dn);
1166         if (strcmp(dn, msgdn) == 0) {
1167                 return true;
1168         }
1169
1170         return false;
1171 }
1172
1173 static void test_search_match_none(void **state)
1174 {
1175         struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1176                         struct search_test_ctx);
1177         size_t count;
1178
1179         count = base_search_count(search_test_ctx->ldb_test_ctx,
1180                                   "dc=no_such_entry");
1181         assert_int_equal(count, 0);
1182 }
1183
1184 static void test_search_match_one(void **state)
1185 {
1186         struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1187                         struct search_test_ctx);
1188         int ret;
1189         struct ldb_dn *basedn;
1190         struct ldb_result *result = NULL;
1191         const char *cn_vals[] = { "test_search_cn",
1192                                   "test_search_cn2" };
1193         const char *uid_vals[] = { "test_search_uid",
1194                                    "test_search_uid2" };
1195
1196         basedn = ldb_dn_new_fmt(search_test_ctx,
1197                                 search_test_ctx->ldb_test_ctx->ldb,
1198                                 "%s",
1199                                 search_test_ctx->base_dn);
1200         assert_non_null(basedn);
1201
1202         ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
1203                          search_test_ctx,
1204                          &result,
1205                          basedn,
1206                          LDB_SCOPE_SUBTREE, NULL,
1207                          "cn=test_search_cn");
1208         assert_int_equal(ret, 0);
1209         assert_non_null(result);
1210         assert_int_equal(result->count, 1);
1211
1212         assert_attr_has_vals(result->msgs[0], "cn", cn_vals, 2);
1213         assert_attr_has_vals(result->msgs[0], "uid", uid_vals, 2);
1214 }
1215
1216 static void test_search_match_filter(void **state)
1217 {
1218         struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1219                         struct search_test_ctx);
1220         int ret;
1221         struct ldb_dn *basedn;
1222         struct ldb_result *result = NULL;
1223         const char *cn_vals[] = { "test_search_cn",
1224                                   "test_search_cn2" };
1225         const char *attrs[] = { "cn", NULL };
1226
1227         basedn = ldb_dn_new_fmt(search_test_ctx,
1228                                 search_test_ctx->ldb_test_ctx->ldb,
1229                                 "%s",
1230                                 search_test_ctx->base_dn);
1231         assert_non_null(basedn);
1232
1233         ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
1234                          search_test_ctx,
1235                          &result,
1236                          basedn,
1237                          LDB_SCOPE_SUBTREE,
1238                          attrs,
1239                          "cn=test_search_cn");
1240         assert_int_equal(ret, 0);
1241         assert_non_null(result);
1242         assert_int_equal(result->count, 1);
1243
1244         assert_attr_has_vals(result->msgs[0], "cn", cn_vals, 2);
1245         assert_has_no_attr(result->msgs[0], "uid");
1246 }
1247
1248 static void assert_expected(struct search_test_ctx *search_test_ctx,
1249                             struct ldb_message *msg)
1250 {
1251         char *full_dn1;
1252         char *full_dn2;
1253         const char *cn_vals[] = { "test_search_cn",
1254                                   "test_search_cn2" };
1255         const char *uid_vals[] = { "test_search_uid",
1256                                    "test_search_uid2" };
1257         const char *cn2_vals[] = { "test_search_2_cn",
1258                                    "test_search_2_cn2" };
1259         const char *uid2_vals[] = { "test_search_2_uid",
1260                                     "test_search_2_uid2" };
1261
1262         full_dn1 = get_full_dn(search_test_ctx,
1263                                search_test_ctx,
1264                                "cn=test_search_cn");
1265
1266         full_dn2 = get_full_dn(search_test_ctx,
1267                                search_test_ctx,
1268                                "cn=test_search_2_cn");
1269
1270         if (has_dn(msg, full_dn1) == true) {
1271                 assert_attr_has_vals(msg, "cn", cn_vals, 2);
1272                 assert_attr_has_vals(msg, "uid", uid_vals, 2);
1273         } else if (has_dn(msg, full_dn2) == true) {
1274                 assert_attr_has_vals(msg, "cn", cn2_vals, 2);
1275                 assert_attr_has_vals(msg, "uid", uid2_vals, 2);
1276         } else {
1277                 fail();
1278         }
1279 }
1280
1281 static void test_search_match_both(void **state)
1282 {
1283         struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1284                         struct search_test_ctx);
1285         int ret;
1286         struct ldb_dn *basedn;
1287         struct ldb_result *result = NULL;
1288
1289         basedn = ldb_dn_new_fmt(search_test_ctx,
1290                                 search_test_ctx->ldb_test_ctx->ldb,
1291                                 "%s",
1292                                 search_test_ctx->base_dn);
1293         assert_non_null(basedn);
1294
1295         ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
1296                          search_test_ctx,
1297                          &result,
1298                          basedn,
1299                          LDB_SCOPE_SUBTREE, NULL,
1300                          "cn=test_search_*");
1301         assert_int_equal(ret, 0);
1302         assert_non_null(result);
1303         assert_int_equal(result->count, 2);
1304
1305         assert_expected(search_test_ctx, result->msgs[0]);
1306         assert_expected(search_test_ctx, result->msgs[1]);
1307 }
1308
1309 static void test_search_match_basedn(void **state)
1310 {
1311         struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1312                         struct search_test_ctx);
1313         int ret;
1314         struct ldb_dn *basedn;
1315         struct ldb_result *result = NULL;
1316         struct ldb_message *msg;
1317
1318         basedn = ldb_dn_new_fmt(search_test_ctx,
1319                                 search_test_ctx->ldb_test_ctx->ldb,
1320                                 "dc=nosuchdn");
1321         assert_non_null(basedn);
1322
1323         ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
1324                          search_test_ctx,
1325                          &result,
1326                          basedn,
1327                          LDB_SCOPE_SUBTREE, NULL,
1328                          "cn=*");
1329         assert_int_equal(ret, 0);
1330
1331         /* Add 'checkBaseOnSearch' to @OPTIONS */
1332         msg = ldb_msg_new(search_test_ctx);
1333         assert_non_null(msg);
1334
1335         msg->dn = ldb_dn_new_fmt(msg,
1336                                  search_test_ctx->ldb_test_ctx->ldb,
1337                                  "@OPTIONS");
1338         assert_non_null(msg->dn);
1339
1340         ret = ldb_msg_add_string(msg, "checkBaseOnSearch", "TRUE");
1341         assert_int_equal(ret, 0);
1342
1343         ret = ldb_add(search_test_ctx->ldb_test_ctx->ldb, msg);
1344         assert_int_equal(ret, 0);
1345
1346         /* Search again */
1347         /* The search should return LDB_ERR_NO_SUCH_OBJECT */
1348         ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
1349                          search_test_ctx,
1350                          &result,
1351                          basedn,
1352                          LDB_SCOPE_SUBTREE, NULL,
1353                          "cn=*");
1354         assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT);
1355
1356         ret = ldb_delete(search_test_ctx->ldb_test_ctx->ldb, msg->dn);
1357         assert_int_equal(ret, 0);
1358 }
1359
1360
1361 /*
1362  * This test is complex.
1363  * The purpose is to test for a deadlock detected between ldb_search()
1364  * and ldb_transaction_commit().  The deadlock happens if in process
1365  * (1) and (2):
1366  *  - (1) the all-record lock is taken in ltdb_search()
1367  *  - (2) the ldb_transaction_start() call is made
1368  *  - (1) an un-indexed search starts (forced here by doing it in
1369  *        the callback
1370  *  - (2) the ldb_transaction_commit() is called.
1371  *        This returns LDB_ERR_BUSY if the deadlock is detected
1372  *
1373  * With ldb 1.1.31 and tdb 1.3.12 we avoid this only due to a missing
1374  * lock call in ltdb_search() due to a refcounting bug in
1375  * ltdb_lock_read()
1376  */
1377
1378 struct search_against_transaction_ctx {
1379         struct ldbtest_ctx *test_ctx;
1380         int res_count;
1381         pid_t child_pid;
1382         struct ldb_dn *basedn;
1383 };
1384
1385 static int test_ldb_search_against_transaction_callback2(struct ldb_request *req,
1386                                                          struct ldb_reply *ares)
1387 {
1388         struct search_against_transaction_ctx *ctx = req->context;
1389         switch (ares->type) {
1390         case LDB_REPLY_ENTRY:
1391                 ctx->res_count++;
1392                 if (ctx->res_count != 1) {
1393                         return LDB_SUCCESS;
1394                 }
1395
1396                 break;
1397
1398         case LDB_REPLY_REFERRAL:
1399                 break;
1400
1401         case LDB_REPLY_DONE:
1402                 return ldb_request_done(req, LDB_SUCCESS);
1403         }
1404
1405         return 0;
1406
1407 }
1408
1409 /*
1410  * This purpose of this callback is to trigger a transaction in
1411  * the child process while the all-record lock is held, but before
1412  * we take any locks in the tdb_traverse_read() handler.
1413  *
1414  * In tdb 1.3.12 tdb_traverse_read() take the read transaction lock
1415  * however in ldb 1.1.31 ltdb_search() forgets to take the all-record
1416  * lock (except the very first time) due to a ref-counting bug.
1417  *
1418  */
1419
1420 static int test_ldb_search_against_transaction_callback1(struct ldb_request *req,
1421                                                          struct ldb_reply *ares)
1422 {
1423         int ret, ret2;
1424         int pipes[2];
1425         char buf[2];
1426         struct search_against_transaction_ctx *ctx = req->context;
1427         switch (ares->type) {
1428         case LDB_REPLY_ENTRY:
1429                 break;
1430
1431         case LDB_REPLY_REFERRAL:
1432                 return LDB_SUCCESS;
1433
1434         case LDB_REPLY_DONE:
1435                 return ldb_request_done(req, LDB_SUCCESS);
1436         }
1437
1438         ret = pipe(pipes);
1439         assert_int_equal(ret, 0);
1440
1441         ctx->child_pid = fork();
1442         if (ctx->child_pid == 0) {
1443                 TALLOC_CTX *tmp_ctx = NULL;
1444                 struct ldb_message *msg;
1445                 TALLOC_FREE(ctx->test_ctx->ldb);
1446                 TALLOC_FREE(ctx->test_ctx->ev);
1447                 ctx->test_ctx->ev = tevent_context_init(ctx->test_ctx);
1448                 if (ctx->test_ctx->ev == NULL) {
1449                         exit(LDB_ERR_OPERATIONS_ERROR);
1450                 }
1451
1452                 ctx->test_ctx->ldb = ldb_init(ctx->test_ctx,
1453                                               ctx->test_ctx->ev);
1454                 if (ctx->test_ctx->ldb == NULL) {
1455                         exit(LDB_ERR_OPERATIONS_ERROR);
1456                 }
1457
1458                 ret = ldb_connect(ctx->test_ctx->ldb,
1459                                   ctx->test_ctx->dbpath, 0, NULL);
1460                 if (ret != LDB_SUCCESS) {
1461                         exit(ret);
1462                 }
1463
1464                 tmp_ctx = talloc_new(ctx->test_ctx);
1465                 if (tmp_ctx == NULL) {
1466                         exit(LDB_ERR_OPERATIONS_ERROR);
1467                 }
1468
1469                 msg = ldb_msg_new(tmp_ctx);
1470                 if (msg == NULL) {
1471                         exit(LDB_ERR_OPERATIONS_ERROR);
1472                 }
1473
1474                 msg->dn = ldb_dn_new_fmt(msg, ctx->test_ctx->ldb,
1475                                          "dc=test");
1476                 if (msg->dn == NULL) {
1477                         exit(LDB_ERR_OPERATIONS_ERROR);
1478                 }
1479
1480                 ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
1481                 if (ret != 0) {
1482                         exit(LDB_ERR_OPERATIONS_ERROR);
1483                 }
1484
1485                 ret = ldb_transaction_start(ctx->test_ctx->ldb);
1486                 if (ret != 0) {
1487                         exit(ret);
1488                 }
1489
1490                 ret = write(pipes[1], "GO", 2);
1491                 if (ret != 2) {
1492                         exit(LDB_ERR_OPERATIONS_ERROR);
1493                 }
1494
1495                 ret = ldb_add(ctx->test_ctx->ldb, msg);
1496                 if (ret != 0) {
1497                         exit(ret);
1498                 }
1499
1500                 ret = ldb_transaction_commit(ctx->test_ctx->ldb);
1501                 exit(ret);
1502         }
1503
1504         ret = read(pipes[0], buf, 2);
1505         assert_int_equal(ret, 2);
1506
1507         /* This search must be unindexed (ie traverse in tdb) */
1508         ret = ldb_build_search_req(&req,
1509                                    ctx->test_ctx->ldb,
1510                                    ctx->test_ctx,
1511                                    ctx->basedn,
1512                                    LDB_SCOPE_SUBTREE,
1513                                    "cn=*", NULL,
1514                                    NULL,
1515                                    ctx,
1516                                    test_ldb_search_against_transaction_callback2,
1517                                    NULL);
1518         /*
1519          * we don't assert on these return codes until after the search is
1520          * finished, or the clean up will fail because we hold locks.
1521          */
1522
1523         ret2 = ldb_request(ctx->test_ctx->ldb, req);
1524
1525         if (ret2 == LDB_SUCCESS) {
1526                 ret2 = ldb_wait(req->handle, LDB_WAIT_ALL);
1527         }
1528         assert_int_equal(ret, 0);
1529         assert_int_equal(ret2, 0);
1530         assert_int_equal(ctx->res_count, 2);
1531
1532         return LDB_SUCCESS;
1533 }
1534
1535 static void test_ldb_search_against_transaction(void **state)
1536 {
1537         struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1538                         struct search_test_ctx);
1539         struct search_against_transaction_ctx
1540                 ctx =
1541                 { .res_count = 0,
1542                   .test_ctx = search_test_ctx->ldb_test_ctx
1543                 };
1544
1545         int ret;
1546         struct ldb_request *req;
1547         pid_t pid;
1548         int wstatus;
1549         struct ldb_dn *base_search_dn;
1550
1551         tevent_loop_allow_nesting(search_test_ctx->ldb_test_ctx->ev);
1552
1553         base_search_dn
1554                 = ldb_dn_new_fmt(search_test_ctx,
1555                                  search_test_ctx->ldb_test_ctx->ldb,
1556                                  "cn=test_search_cn,%s",
1557                                  search_test_ctx->base_dn);
1558         assert_non_null(base_search_dn);
1559
1560         ctx.basedn
1561                 = ldb_dn_new_fmt(search_test_ctx,
1562                                  search_test_ctx->ldb_test_ctx->ldb,
1563                                  "%s",
1564                                  search_test_ctx->base_dn);
1565         assert_non_null(ctx.basedn);
1566
1567
1568         /* This search must be indexed (ie no traverse in tdb) */
1569         ret = ldb_build_search_req(&req,
1570                                    search_test_ctx->ldb_test_ctx->ldb,
1571                                    search_test_ctx,
1572                                    base_search_dn,
1573                                    LDB_SCOPE_BASE,
1574                                    "cn=*", NULL,
1575                                    NULL,
1576                                    &ctx,
1577                                    test_ldb_search_against_transaction_callback1,
1578                                    NULL);
1579         assert_int_equal(ret, 0);
1580         ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req);
1581
1582         if (ret == LDB_SUCCESS) {
1583                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1584         }
1585         assert_int_equal(ret, 0);
1586         assert_int_equal(ctx.res_count, 2);
1587
1588         pid = waitpid(ctx.child_pid, &wstatus, 0);
1589         assert_int_equal(pid, ctx.child_pid);
1590
1591         assert_true(WIFEXITED(wstatus));
1592
1593         assert_int_equal(WEXITSTATUS(wstatus), 0);
1594
1595
1596 }
1597
1598 /*
1599  * This test is also complex.
1600  * The purpose is to test if a modify can occur during an ldb_search()
1601  * This would be a failure if if in process
1602  * (1) and (2):
1603  *  - (1) ltdb_search() starts and calls back for one entry
1604  *  - (2) one of the entries to be matched is modified
1605  *  - (1) the indexed search tries to return the modified entry, but
1606  *        it is no longer found, either:
1607  *          - despite it still matching (dn changed)
1608  *          - it no longer matching (attrs changed)
1609  *
1610  * We also try un-indexed to show that the behaviour differs on this
1611  * point, which it should not (an index should only impact search
1612  * speed).
1613  */
1614
1615 struct modify_during_search_test_ctx {
1616         struct ldbtest_ctx *test_ctx;
1617         int res_count;
1618         pid_t child_pid;
1619         struct ldb_dn *basedn;
1620         bool got_cn;
1621         bool got_2_cn;
1622         bool rename;
1623 };
1624
1625 /*
1626  * This purpose of this callback is to trigger a write in
1627  * the child process while a search is in progress.
1628  *
1629  * In tdb 1.3.12 tdb_traverse_read() take the read transaction lock
1630  * however in ldb 1.1.31 ltdb_search() forgets to take the all-record
1631  * lock (except the very first time) due to a ref-counting bug.
1632  *
1633  * We assume that if the write will proceed, it will proceed in a 3
1634  * second window after the function is called.
1635  */
1636
1637 static int test_ldb_modify_during_search_callback1(struct ldb_request *req,
1638                                                    struct ldb_reply *ares)
1639 {
1640         int ret;
1641         int pipes[2];
1642         char buf[2];
1643         struct modify_during_search_test_ctx *ctx = req->context;
1644         switch (ares->type) {
1645         case LDB_REPLY_ENTRY:
1646         {
1647                 const struct ldb_val *cn_val
1648                         = ldb_dn_get_component_val(ares->message->dn, 0);
1649                 const char *cn = (char *)cn_val->data;
1650                 ctx->res_count++;
1651                 if (strcmp(cn, "test_search_cn") == 0) {
1652                         ctx->got_cn = true;
1653                 } else if (strcmp(cn, "test_search_2_cn") == 0) {
1654                         ctx->got_2_cn = true;
1655                 }
1656                 if (ctx->res_count == 2) {
1657                         return LDB_SUCCESS;
1658                 }
1659                 break;
1660         }
1661         case LDB_REPLY_REFERRAL:
1662                 return LDB_SUCCESS;
1663
1664         case LDB_REPLY_DONE:
1665                 return ldb_request_done(req, LDB_SUCCESS);
1666         }
1667
1668         ret = pipe(pipes);
1669         assert_int_equal(ret, 0);
1670
1671         ctx->child_pid = fork();
1672         if (ctx->child_pid == 0 && ctx->rename) {
1673                 TALLOC_CTX *tmp_ctx = NULL;
1674                 struct ldb_dn *dn, *new_dn;
1675                 TALLOC_FREE(ctx->test_ctx->ldb);
1676                 TALLOC_FREE(ctx->test_ctx->ev);
1677                 ctx->test_ctx->ev = tevent_context_init(ctx->test_ctx);
1678                 if (ctx->test_ctx->ev == NULL) {
1679                         exit(LDB_ERR_OPERATIONS_ERROR);
1680                 }
1681
1682                 ctx->test_ctx->ldb = ldb_init(ctx->test_ctx,
1683                                               ctx->test_ctx->ev);
1684                 if (ctx->test_ctx->ldb == NULL) {
1685                         exit(LDB_ERR_OPERATIONS_ERROR);
1686                 }
1687
1688                 ret = ldb_connect(ctx->test_ctx->ldb,
1689                                   ctx->test_ctx->dbpath, 0, NULL);
1690                 if (ret != LDB_SUCCESS) {
1691                         exit(ret);
1692                 }
1693
1694                 tmp_ctx = talloc_new(ctx->test_ctx);
1695                 if (tmp_ctx == NULL) {
1696                         exit(LDB_ERR_OPERATIONS_ERROR);
1697                 }
1698
1699                 if (ctx->got_cn) {
1700                         /* Modify the other one */
1701                         dn = ldb_dn_new_fmt(tmp_ctx, ctx->test_ctx->ldb,
1702                                             "cn=test_search_2_cn,"
1703                                             "dc=search_test_entry");
1704                 } else {
1705                         dn = ldb_dn_new_fmt(tmp_ctx, ctx->test_ctx->ldb,
1706                                             "cn=test_search_cn,"
1707                                             "dc=search_test_entry");
1708                 }
1709                 if (dn == NULL) {
1710                         exit(LDB_ERR_OPERATIONS_ERROR);
1711                 }
1712
1713                 new_dn = ldb_dn_new_fmt(tmp_ctx, ctx->test_ctx->ldb,
1714                                         "cn=test_search_cn_renamed,"
1715                                         "dc=search_test_entry");
1716                 if (new_dn == NULL) {
1717                         exit(LDB_ERR_OPERATIONS_ERROR);
1718                 }
1719
1720                 ret = ldb_transaction_start(ctx->test_ctx->ldb);
1721                 if (ret != 0) {
1722                         exit(ret);
1723                 }
1724
1725                 if (write(pipes[1], "GO", 2) != 2) {
1726                         exit(LDB_ERR_OPERATIONS_ERROR);
1727                 }
1728
1729                 ret = ldb_rename(ctx->test_ctx->ldb, dn, new_dn);
1730                 if (ret != 0) {
1731                         exit(ret);
1732                 }
1733
1734                 ret = ldb_transaction_commit(ctx->test_ctx->ldb);
1735                 exit(ret);
1736
1737         } else if (ctx->child_pid == 0) {
1738                 TALLOC_CTX *tmp_ctx = NULL;
1739                 struct ldb_message *msg;
1740                 struct ldb_message_element *el;
1741                 TALLOC_FREE(ctx->test_ctx->ldb);
1742                 TALLOC_FREE(ctx->test_ctx->ev);
1743                 ctx->test_ctx->ev = tevent_context_init(ctx->test_ctx);
1744                 if (ctx->test_ctx->ev == NULL) {
1745                         exit(LDB_ERR_OPERATIONS_ERROR);
1746                 }
1747
1748                 ctx->test_ctx->ldb = ldb_init(ctx->test_ctx,
1749                                               ctx->test_ctx->ev);
1750                 if (ctx->test_ctx->ldb == NULL) {
1751                         exit(LDB_ERR_OPERATIONS_ERROR);
1752                 }
1753
1754                 ret = ldb_connect(ctx->test_ctx->ldb,
1755                                   ctx->test_ctx->dbpath, 0, NULL);
1756                 if (ret != LDB_SUCCESS) {
1757                         exit(ret);
1758                 }
1759
1760                 tmp_ctx = talloc_new(ctx->test_ctx);
1761                 if (tmp_ctx == NULL) {
1762                         exit(LDB_ERR_OPERATIONS_ERROR);
1763                 }
1764
1765                 msg = ldb_msg_new(tmp_ctx);
1766                 if (msg == NULL) {
1767                         exit(LDB_ERR_OPERATIONS_ERROR);
1768                 }
1769
1770                 if (ctx->got_cn) {
1771                         /* Modify the other one */
1772                         msg->dn = ldb_dn_new_fmt(msg, ctx->test_ctx->ldb,
1773                                                  "cn=test_search_2_cn,"
1774                                                  "dc=search_test_entry");
1775                 } else {
1776                         msg->dn = ldb_dn_new_fmt(msg, ctx->test_ctx->ldb,
1777                                                  "cn=test_search_cn,"
1778                                                  "dc=search_test_entry");
1779                 }
1780                 if (msg->dn == NULL) {
1781                         exit(LDB_ERR_OPERATIONS_ERROR);
1782                 }
1783
1784                 ret = ldb_msg_add_string(msg, "filterAttr", "TRUE");
1785                 if (ret != 0) {
1786                         exit(LDB_ERR_OPERATIONS_ERROR);
1787                 }
1788                 el = ldb_msg_find_element(msg, "filterAttr");
1789                 if (el == NULL) {
1790                         exit(LDB_ERR_OPERATIONS_ERROR);
1791                 }
1792                 el->flags = LDB_FLAG_MOD_REPLACE;
1793
1794                 ret = ldb_transaction_start(ctx->test_ctx->ldb);
1795                 if (ret != 0) {
1796                         exit(ret);
1797                 }
1798
1799                 if (write(pipes[1], "GO", 2) != 2) {
1800                         exit(LDB_ERR_OPERATIONS_ERROR);
1801                 }
1802
1803                 ret = ldb_modify(ctx->test_ctx->ldb, msg);
1804                 if (ret != 0) {
1805                         exit(ret);
1806                 }
1807
1808                 ret = ldb_transaction_commit(ctx->test_ctx->ldb);
1809                 exit(ret);
1810         }
1811
1812         /*
1813          * With TDB 1.3.13 and before "tdb: Remove locking from tdb_traverse_read()"
1814          * we will hang here because the child process can not proceed to
1815          * sending the "GO" as it is blocked at ldb_transaction_start().
1816          */
1817
1818         ret = read(pipes[0], buf, 2);
1819         assert_int_equal(ret, 2);
1820
1821         sleep(3);
1822
1823         return LDB_SUCCESS;
1824 }
1825
1826 static void test_ldb_modify_during_search(void **state, bool add_index,
1827                                           bool rename)
1828 {
1829         struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
1830                         struct search_test_ctx);
1831         struct modify_during_search_test_ctx
1832                 ctx =
1833                 { .res_count = 0,
1834                   .test_ctx = search_test_ctx->ldb_test_ctx,
1835                   .rename = rename
1836                 };
1837
1838         int ret;
1839         struct ldb_request *req;
1840         pid_t pid;
1841         int wstatus;
1842
1843         if (add_index) {
1844                 struct ldb_message *msg;
1845                 struct ldb_dn *indexlist = ldb_dn_new(search_test_ctx,
1846                                                       search_test_ctx->ldb_test_ctx->ldb,
1847                                                       "@INDEXLIST");
1848                 assert_non_null(indexlist);
1849
1850                 msg = ldb_msg_new(search_test_ctx);
1851                 assert_non_null(msg);
1852
1853                 msg->dn = indexlist;
1854
1855                 ret = ldb_msg_add_string(msg, "@IDXATTR", "cn");
1856                 assert_int_equal(ret, LDB_SUCCESS);
1857
1858                 ret = ldb_add(search_test_ctx->ldb_test_ctx->ldb,
1859                               msg);
1860
1861                 assert_int_equal(ret, LDB_SUCCESS);
1862         }
1863
1864         tevent_loop_allow_nesting(search_test_ctx->ldb_test_ctx->ev);
1865
1866         ctx.basedn
1867                 = ldb_dn_new_fmt(search_test_ctx,
1868                                  search_test_ctx->ldb_test_ctx->ldb,
1869                                  "%s",
1870                                  search_test_ctx->base_dn);
1871         assert_non_null(ctx.basedn);
1872
1873
1874         /*
1875          * This search must be over multiple items, and should include
1876          * the new name after a rename, to show that it would match
1877          * both before and after that modify
1878          */
1879         ret = ldb_build_search_req(&req,
1880                                    search_test_ctx->ldb_test_ctx->ldb,
1881                                    search_test_ctx,
1882                                    ctx.basedn,
1883                                    LDB_SCOPE_SUBTREE,
1884                                    "(&(!(filterAttr=*))"
1885                                      "(|(cn=test_search_cn_renamed)"
1886                                        "(cn=test_search_cn)"
1887                                        "(cn=test_search_2_cn)"
1888                                    "))",
1889                                    NULL,
1890                                    NULL,
1891                                    &ctx,
1892                                    test_ldb_modify_during_search_callback1,
1893                                    NULL);
1894         assert_int_equal(ret, 0);
1895         ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req);
1896
1897         if (ret == LDB_SUCCESS) {
1898                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1899         }
1900         assert_int_equal(ret, 0);
1901         assert_int_equal(ctx.res_count, 2);
1902         assert_int_equal(ctx.got_cn, true);
1903         assert_int_equal(ctx.got_2_cn, true);
1904
1905         pid = waitpid(ctx.child_pid, &wstatus, 0);
1906         assert_int_equal(pid, ctx.child_pid);
1907
1908         assert_true(WIFEXITED(wstatus));
1909
1910         assert_int_equal(WEXITSTATUS(wstatus), 0);
1911
1912
1913 }
1914
1915 static void test_ldb_modify_during_indexed_search(void **state)
1916 {
1917         return test_ldb_modify_during_search(state, true, false);
1918 }
1919
1920 static void test_ldb_modify_during_unindexed_search(void **state)
1921 {
1922         return test_ldb_modify_during_search(state, false, false);
1923 }
1924
1925 static void test_ldb_rename_during_indexed_search(void **state)
1926 {
1927         return test_ldb_modify_during_search(state, true, true);
1928 }
1929
1930 static void test_ldb_rename_during_unindexed_search(void **state)
1931 {
1932         return test_ldb_modify_during_search(state, false, true);
1933 }
1934
1935 /*
1936  * This test is also complex.
1937  *
1938  * The purpose is to test if a modify can occur during an ldb_search()
1939  * before the end of the callback
1940  *
1941  * This would be a failure if if in process
1942  * (1) and (2):
1943  *  - (1) ldb_search() starts and calls back for a number of entries
1944  *  - (2) an entry in the DB is allowed to change before the callback returns
1945  *  - (1) the callback can see the modification
1946  *
1947  */
1948
1949 /*
1950  * This purpose of this callback is to trigger a write in
1951  * the child process while a search DONE callback is in progress.
1952  *
1953  * In ldb 1.1.31 ldb_search() omitted to take a all-record
1954  * lock for the full duration of the search and callbacks
1955  *
1956  * We assume that if the write will proceed, it will proceed in a 3
1957  * second window after the function is called.
1958  */
1959
1960 static int test_ldb_modify_during_whole_search_callback1(struct ldb_request *req,
1961                                                          struct ldb_reply *ares)
1962 {
1963         int ret;
1964         int pipes[2];
1965         char buf[2];
1966         struct modify_during_search_test_ctx *ctx = req->context;
1967         struct ldb_dn *search_dn;
1968         struct ldb_result *res2;
1969         unsigned res_count;
1970         switch (ares->type) {
1971         case LDB_REPLY_ENTRY:
1972         case LDB_REPLY_REFERRAL:
1973                 return LDB_SUCCESS;
1974
1975         case LDB_REPLY_DONE:
1976                 break;
1977         }
1978
1979         ret = pipe(pipes);
1980         assert_int_equal(ret, 0);
1981
1982         ctx->child_pid = fork();
1983         if (ctx->child_pid == 0) {
1984                 TALLOC_CTX *tmp_ctx = NULL;
1985                 struct ldb_message *msg;
1986                 struct ldb_message_element *el;
1987                 TALLOC_FREE(ctx->test_ctx->ldb);
1988                 TALLOC_FREE(ctx->test_ctx->ev);
1989                 ctx->test_ctx->ev = tevent_context_init(ctx->test_ctx);
1990                 if (ctx->test_ctx->ev == NULL) {
1991                         exit(LDB_ERR_OPERATIONS_ERROR);
1992                 }
1993
1994                 ctx->test_ctx->ldb = ldb_init(ctx->test_ctx,
1995                                               ctx->test_ctx->ev);
1996                 if (ctx->test_ctx->ldb == NULL) {
1997                         exit(LDB_ERR_OPERATIONS_ERROR);
1998                 }
1999
2000                 ret = ldb_connect(ctx->test_ctx->ldb,
2001                                   ctx->test_ctx->dbpath, 0, NULL);
2002                 if (ret != LDB_SUCCESS) {
2003                         exit(ret);
2004                 }
2005
2006                 tmp_ctx = talloc_new(ctx->test_ctx);
2007                 if (tmp_ctx == NULL) {
2008                         exit(LDB_ERR_OPERATIONS_ERROR);
2009                 }
2010
2011                 msg = ldb_msg_new(tmp_ctx);
2012                 if (msg == NULL) {
2013                         exit(LDB_ERR_OPERATIONS_ERROR);
2014                 }
2015
2016                 msg->dn = ldb_dn_new_fmt(msg, ctx->test_ctx->ldb,
2017                                          "cn=test_search_cn,"
2018                                          "dc=search_test_entry");
2019                 if (msg->dn == NULL) {
2020                         exit(LDB_ERR_OPERATIONS_ERROR);
2021                 }
2022
2023                 ret = ldb_msg_add_string(msg, "filterAttr", "TRUE");
2024                 if (ret != 0) {
2025                         exit(LDB_ERR_OPERATIONS_ERROR);
2026                 }
2027                 el = ldb_msg_find_element(msg, "filterAttr");
2028                 if (el == NULL) {
2029                         exit(LDB_ERR_OPERATIONS_ERROR);
2030                 }
2031                 el->flags = LDB_FLAG_MOD_REPLACE;
2032
2033                 ret = ldb_transaction_start(ctx->test_ctx->ldb);
2034                 if (ret != 0) {
2035                         exit(ret);
2036                 }
2037
2038                 if (write(pipes[1], "GO", 2) != 2) {
2039                         exit(LDB_ERR_OPERATIONS_ERROR);
2040                 }
2041
2042                 ret = ldb_modify(ctx->test_ctx->ldb, msg);
2043                 if (ret != 0) {
2044                         exit(ret);
2045                 }
2046
2047                 ret = ldb_transaction_commit(ctx->test_ctx->ldb);
2048                 exit(ret);
2049         }
2050
2051         ret = read(pipes[0], buf, 2);
2052         assert_int_equal(ret, 2);
2053
2054         sleep(3);
2055
2056         /*
2057          * If writes are not blocked until after this function, we
2058          * will be able to successfully search for this modification
2059          * here
2060          */
2061
2062         search_dn = ldb_dn_new_fmt(ares, ctx->test_ctx->ldb,
2063                                    "cn=test_search_cn,"
2064                                    "dc=search_test_entry");
2065
2066         ret = ldb_search(ctx->test_ctx->ldb, ares,
2067                          &res2, search_dn, LDB_SCOPE_BASE, NULL,
2068                          "filterAttr=TRUE");
2069
2070         /*
2071          * We do this in an unusual order, because if we fail an assert before
2072          * ldb_request_done(), we will also fail to clean up as we hold locks.
2073          */
2074
2075         res_count = res2->count;
2076         ldb_request_done(req, LDB_SUCCESS);
2077         assert_int_equal(ret, 0);
2078
2079         /* We should not have got the result */
2080         assert_int_equal(res_count, 0);
2081
2082         return ret;
2083 }
2084
2085 static void test_ldb_modify_during_whole_search(void **state)
2086 {
2087         struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
2088                         struct search_test_ctx);
2089         struct modify_during_search_test_ctx
2090                 ctx =
2091                 {
2092                   .test_ctx = search_test_ctx->ldb_test_ctx,
2093                 };
2094
2095         int ret;
2096         struct ldb_request *req;
2097         pid_t pid;
2098         int wstatus;
2099         struct ldb_dn *search_dn;
2100         struct ldb_result *res2;
2101
2102         tevent_loop_allow_nesting(search_test_ctx->ldb_test_ctx->ev);
2103
2104         ctx.basedn
2105                 = ldb_dn_new_fmt(search_test_ctx,
2106                                  search_test_ctx->ldb_test_ctx->ldb,
2107                                  "%s",
2108                                  search_test_ctx->base_dn);
2109         assert_non_null(ctx.basedn);
2110
2111
2112         /*
2113          * The search just needs to call DONE, we don't care about the
2114          * contents of the search for this test
2115          */
2116         ret = ldb_build_search_req(&req,
2117                                    search_test_ctx->ldb_test_ctx->ldb,
2118                                    search_test_ctx,
2119                                    ctx.basedn,
2120                                    LDB_SCOPE_SUBTREE,
2121                                    "(&(!(filterAttr=*))"
2122                                    "(cn=test_search_cn))",
2123                                    NULL,
2124                                    NULL,
2125                                    &ctx,
2126                                    test_ldb_modify_during_whole_search_callback1,
2127                                    NULL);
2128         assert_int_equal(ret, 0);
2129         ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req);
2130
2131         if (ret == LDB_SUCCESS) {
2132                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
2133         }
2134         assert_int_equal(ret, 0);
2135
2136         pid = waitpid(ctx.child_pid, &wstatus, 0);
2137         assert_int_equal(pid, ctx.child_pid);
2138
2139         assert_true(WIFEXITED(wstatus));
2140
2141         assert_int_equal(WEXITSTATUS(wstatus), 0);
2142
2143         /*
2144          * If writes are blocked until after the search function, we
2145          * will be able to successfully search for this modification
2146          * now
2147          */
2148
2149         search_dn = ldb_dn_new_fmt(search_test_ctx,
2150                                    search_test_ctx->ldb_test_ctx->ldb,
2151                                    "cn=test_search_cn,"
2152                                    "dc=search_test_entry");
2153
2154         ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
2155                          search_test_ctx,
2156                          &res2, search_dn, LDB_SCOPE_BASE, NULL,
2157                          "filterAttr=TRUE");
2158         assert_int_equal(ret, 0);
2159
2160         /* We got the result */
2161         assert_int_equal(res2->count, 1);
2162 }
2163
2164 /*
2165  * This test is also complex.
2166  *
2167  * The purpose is to test if a modify can occur during an ldb_search()
2168  * before the request is destroyed with TALLOC_FREE()
2169  *
2170  * This would be a failure if in process
2171  * (1) and (2):
2172  *  - (1) ldb_search() starts and waits
2173  *  - (2) an entry in the DB is allowed to change before the ldb_wait() is called
2174  *  - (1) the original process can see the modification before the TALLOC_FREE()
2175  * also we check that
2176  *  - (1) the original process can see the modification after the TALLOC_FREE()
2177  *
2178  */
2179
2180 /*
2181  * This purpose of this callback is to trigger a write in
2182  * the child process before the ldb_wait() is called
2183  *
2184  * In ldb 1.1.31 ldb_search() omitted to take a all-record
2185  * lock for the full duration of the search and callbacks
2186  *
2187  * We assume that if the write will proceed, it will proceed in a 3
2188  * second window after the function is called.
2189  */
2190
2191 static int test_ldb_modify_before_ldb_wait_callback1(struct ldb_request *req,
2192                                                      struct ldb_reply *ares)
2193 {
2194         switch (ares->type) {
2195         case LDB_REPLY_ENTRY:
2196         case LDB_REPLY_REFERRAL:
2197                 return LDB_SUCCESS;
2198
2199         case LDB_REPLY_DONE:
2200                 break;
2201         }
2202
2203         return ldb_request_done(req, LDB_SUCCESS);
2204 }
2205
2206 static void test_ldb_modify_before_ldb_wait(void **state)
2207 {
2208         struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state,
2209                         struct search_test_ctx);
2210         int ret;
2211         struct ldb_request *req;
2212         pid_t pid;
2213         int wstatus;
2214         struct ldb_dn *search_dn;
2215         struct ldb_dn *basedn;
2216         struct ldb_result *res2;
2217         int pipes[2];
2218         char buf[2];
2219         pid_t child_pid;
2220         unsigned res_count;
2221
2222         search_dn = ldb_dn_new_fmt(search_test_ctx,
2223                                    search_test_ctx->ldb_test_ctx->ldb,
2224                                    "cn=test_search_cn,"
2225                                    "dc=search_test_entry");
2226         assert_non_null(search_dn);
2227
2228         basedn = ldb_dn_new_fmt(search_test_ctx,
2229                                 search_test_ctx->ldb_test_ctx->ldb,
2230                                 "%s",
2231                                 search_test_ctx->base_dn);
2232         assert_non_null(basedn);
2233
2234         /*
2235          * The search just needs to call DONE, we don't care about the
2236          * contents of the search for this test
2237          */
2238         ret = ldb_build_search_req(&req,
2239                                    search_test_ctx->ldb_test_ctx->ldb,
2240                                    search_test_ctx,
2241                                    basedn,
2242                                    LDB_SCOPE_SUBTREE,
2243                                    "(&(!(filterAttr=*))"
2244                                    "(cn=test_search_cn))",
2245                                    NULL,
2246                                    NULL,
2247                                    NULL,
2248                                    test_ldb_modify_before_ldb_wait_callback1,
2249                                    NULL);
2250         assert_int_equal(ret, 0);
2251         ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req);
2252
2253         ret = pipe(pipes);
2254         assert_int_equal(ret, 0);
2255
2256         child_pid = fork();
2257         if (child_pid == 0) {
2258                 TALLOC_CTX *tmp_ctx = NULL;
2259                 struct ldb_message *msg;
2260                 struct ldb_message_element *el;
2261                 TALLOC_FREE(search_test_ctx->ldb_test_ctx->ldb);
2262                 TALLOC_FREE(search_test_ctx->ldb_test_ctx->ev);
2263                 search_test_ctx->ldb_test_ctx->ev = tevent_context_init(search_test_ctx->ldb_test_ctx);
2264                 if (search_test_ctx->ldb_test_ctx->ev == NULL) {
2265                         exit(LDB_ERR_OPERATIONS_ERROR);
2266                 }
2267
2268                 search_test_ctx->ldb_test_ctx->ldb = ldb_init(search_test_ctx->ldb_test_ctx,
2269                                              search_test_ctx->ldb_test_ctx->ev);
2270                 if (search_test_ctx->ldb_test_ctx->ldb == NULL) {
2271                         exit(LDB_ERR_OPERATIONS_ERROR);
2272                 }
2273
2274                 ret = ldb_connect(search_test_ctx->ldb_test_ctx->ldb,
2275                                   search_test_ctx->ldb_test_ctx->dbpath, 0, NULL);
2276                 if (ret != LDB_SUCCESS) {
2277                         exit(ret);
2278                 }
2279
2280                 tmp_ctx = talloc_new(search_test_ctx->ldb_test_ctx);
2281                 if (tmp_ctx == NULL) {
2282                         exit(LDB_ERR_OPERATIONS_ERROR);
2283                 }
2284
2285                 msg = ldb_msg_new(tmp_ctx);
2286                 if (msg == NULL) {
2287                         exit(LDB_ERR_OPERATIONS_ERROR);
2288                 }
2289
2290                 /*
2291                  * We must re-create this DN from a string to ensure
2292                  * it does not reference the now-gone LDB context of
2293                  * the parent
2294                  */
2295                 msg->dn = ldb_dn_new_fmt(search_test_ctx,
2296                                          search_test_ctx->ldb_test_ctx->ldb,
2297                                          "cn=test_search_cn,"
2298                                          "dc=search_test_entry");
2299
2300                 if (msg->dn == NULL) {
2301                         exit(LDB_ERR_OPERATIONS_ERROR);
2302                 }
2303
2304                 ret = ldb_msg_add_string(msg, "filterAttr", "TRUE");
2305                 if (ret != 0) {
2306                         exit(LDB_ERR_OPERATIONS_ERROR);
2307                 }
2308                 el = ldb_msg_find_element(msg, "filterAttr");
2309                 if (el == NULL) {
2310                         exit(LDB_ERR_OPERATIONS_ERROR);
2311                 }
2312                 el->flags = LDB_FLAG_MOD_REPLACE;
2313
2314                 ret = ldb_transaction_start(search_test_ctx->ldb_test_ctx->ldb);
2315                 if (ret != 0) {
2316                         exit(ret);
2317                 }
2318
2319                 if (write(pipes[1], "GO", 2) != 2) {
2320                         exit(LDB_ERR_OPERATIONS_ERROR);
2321                 }
2322
2323                 ret = ldb_modify(search_test_ctx->ldb_test_ctx->ldb, msg);
2324                 if (ret != 0) {
2325                         exit(ret);
2326                 }
2327
2328                 ret = ldb_transaction_commit(search_test_ctx->ldb_test_ctx->ldb);
2329                 exit(ret);
2330         }
2331
2332         ret = read(pipes[0], buf, 2);
2333         assert_int_equal(ret, 2);
2334
2335         sleep(3);
2336
2337         /*
2338          * If writes are not blocked until after the (never called) ldb_wait(), we
2339          * will be able to successfully search for this modification
2340          * here
2341          */
2342
2343         ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb, search_test_ctx,
2344                          &res2, search_dn, LDB_SCOPE_BASE, NULL,
2345                          "filterAttr=TRUE");
2346
2347         /*
2348          * We avoid making assertions before TALLOC_FREE()ing the request,
2349          * lest the assert fail and mess with the clean-up because we still
2350          * have locks.
2351          */
2352         res_count = res2->count;
2353         TALLOC_FREE(req);
2354
2355         /* We should not have got the result */
2356         assert_int_equal(res_count, 0);
2357         assert_int_equal(ret, 0);
2358
2359         pid = waitpid(child_pid, &wstatus, 0);
2360         assert_int_equal(pid, child_pid);
2361
2362         assert_true(WIFEXITED(wstatus));
2363
2364         assert_int_equal(WEXITSTATUS(wstatus), 0);
2365
2366         /*
2367          * If writes are blocked until after the search request was freed, we
2368          * will be able to successfully search for this modification
2369          * now
2370          */
2371
2372         search_dn = ldb_dn_new_fmt(search_test_ctx,
2373                                    search_test_ctx->ldb_test_ctx->ldb,
2374                                    "cn=test_search_cn,"
2375                                    "dc=search_test_entry");
2376
2377         ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb,
2378                          search_test_ctx,
2379                          &res2, search_dn, LDB_SCOPE_BASE, NULL,
2380                          "filterAttr=TRUE");
2381         assert_int_equal(ret, 0);
2382
2383         /* We got the result */
2384         assert_int_equal(res2->count, 1);
2385 }
2386
2387 static int ldb_case_test_setup(void **state)
2388 {
2389         int ret;
2390         struct ldb_ldif *ldif;
2391         struct ldbtest_ctx *ldb_test_ctx;
2392         const char *attrs_ldif =  \
2393                 "dn: @ATTRIBUTES\n"
2394                 "cn: CASE_INSENSITIVE\n"
2395                 "\n";
2396         struct keyval kvs[] = {
2397                 { "cn", "CaseInsensitiveValue" },
2398                 { "uid", "CaseSensitiveValue" },
2399                 { NULL, NULL },
2400         };
2401
2402
2403         ldbtest_setup((void **) &ldb_test_ctx);
2404
2405         while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &attrs_ldif))) {
2406                 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
2407                 assert_int_equal(ret, LDB_SUCCESS);
2408         }
2409
2410         ldb_test_add_data(ldb_test_ctx,
2411                           ldb_test_ctx,
2412                           "cn=CaseInsensitiveValue",
2413                           kvs);
2414
2415         *state = ldb_test_ctx;
2416         return 0;
2417 }
2418
2419 static int ldb_case_test_teardown(void **state)
2420 {
2421         int ret;
2422         struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
2423                         struct ldbtest_ctx);
2424
2425         struct ldb_dn *del_dn;
2426
2427         del_dn = ldb_dn_new_fmt(ldb_test_ctx,
2428                                 ldb_test_ctx->ldb,
2429                                 "@ATTRIBUTES");
2430         assert_non_null(del_dn);
2431
2432         ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
2433         assert_int_equal(ret, LDB_SUCCESS);
2434
2435         assert_dn_doesnt_exist(ldb_test_ctx,
2436                                "@ATTRIBUTES");
2437
2438         ldb_test_remove_data(ldb_test_ctx, ldb_test_ctx,
2439                              "cn=CaseInsensitiveValue");
2440
2441         ldbtest_teardown((void **) &ldb_test_ctx);
2442         return 0;
2443 }
2444
2445 static void test_ldb_attrs_case_insensitive(void **state)
2446 {
2447         int cnt;
2448         struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
2449                         struct ldbtest_ctx);
2450
2451         /* cn matches exact case */
2452         cnt = sub_search_count(ldb_test_ctx, "", "cn=CaseInsensitiveValue");
2453         assert_int_equal(cnt, 1);
2454
2455         /* cn matches lower case */
2456         cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2457         assert_int_equal(cnt, 1);
2458
2459         /* uid matches exact case */
2460         cnt = sub_search_count(ldb_test_ctx, "", "uid=CaseSensitiveValue");
2461         assert_int_equal(cnt, 1);
2462
2463         /* uid does not match lower case */
2464         cnt = sub_search_count(ldb_test_ctx, "", "uid=casesensitivevalue");
2465         assert_int_equal(cnt, 0);
2466 }
2467
2468 static struct ldb_schema_attribute cn_attr_1;
2469 static struct ldb_schema_attribute cn_attr_2;
2470 static struct ldb_schema_attribute default_attr;
2471
2472 /*
2473   override the name to attribute handler function
2474  */
2475 static const struct ldb_schema_attribute *ldb_test_attribute_handler_override(struct ldb_context *ldb,
2476                                                                               void *private_data,
2477                                                                               const char *name)
2478 {
2479         if (private_data != NULL && ldb_attr_cmp(name, "cn") == 0) {
2480                 return &cn_attr_1;
2481         } else if (private_data == NULL && ldb_attr_cmp(name, "cn") == 0) {
2482                 return &cn_attr_2;
2483         } else if (ldb_attr_cmp(name, "uid") == 0) {
2484                 return &cn_attr_2;
2485         }
2486         return &default_attr;
2487 }
2488
2489 static void test_ldb_attrs_case_handler(void **state)
2490 {
2491         int cnt;
2492         int ret;
2493         const struct ldb_schema_syntax *syntax;
2494
2495         struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
2496                         struct ldbtest_ctx);
2497         struct ldb_context *ldb = ldb_test_ctx->ldb;
2498
2499         /* cn matches lower case */
2500         cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2501         assert_int_equal(cnt, 1);
2502
2503         syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_OCTET_STRING);
2504         assert_non_null(syntax);
2505
2506         ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb,
2507                                                     "*", 0,
2508                                                     syntax, &default_attr);
2509         assert_int_equal(ret, LDB_SUCCESS);
2510
2511         syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_OCTET_STRING);
2512         assert_non_null(syntax);
2513
2514         ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb,
2515                                                     "cn", 0,
2516                                                     syntax, &cn_attr_1);
2517         assert_int_equal(ret, LDB_SUCCESS);
2518
2519         /*
2520          * Set an attribute handler, which will fail to match as we
2521          * force case sensitive
2522          */
2523         ldb_schema_attribute_set_override_handler(ldb,
2524                                                   ldb_test_attribute_handler_override,
2525                                                   (void *)1);
2526
2527         /* cn does not matche lower case */
2528         cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2529         assert_int_equal(cnt, 0);
2530
2531         syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_DIRECTORY_STRING);
2532         assert_non_null(syntax);
2533
2534         ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb,
2535                                                     "cn", 0,
2536                                                     syntax, &cn_attr_2);
2537         assert_int_equal(ret, LDB_SUCCESS);
2538
2539         /*
2540          * Set an attribute handler, which will match as we
2541          * force case insensitive
2542          */
2543         ldb_schema_attribute_set_override_handler(ldb,
2544                                                   ldb_test_attribute_handler_override,
2545                                                   NULL);
2546
2547         /* cn matches lower case */
2548         cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2549         assert_int_equal(cnt, 1);
2550
2551 }
2552
2553
2554 static void test_ldb_attrs_index_handler(void **state)
2555 {
2556         int cnt;
2557         int ret;
2558         const struct ldb_schema_syntax *syntax;
2559         struct ldb_ldif *ldif;
2560
2561         const char *index_ldif =  \
2562                 "dn: @INDEXLIST\n"
2563                 "@IDXATTR: cn\n"
2564                 "\n";
2565
2566         struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
2567                         struct ldbtest_ctx);
2568         struct ldb_context *ldb = ldb_test_ctx->ldb;
2569
2570         /* cn matches lower case */
2571         cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2572         assert_int_equal(cnt, 1);
2573
2574         syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_OCTET_STRING);
2575         assert_non_null(syntax);
2576
2577         ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb,
2578                                                     "cn", 0,
2579                                                     syntax, &cn_attr_1);
2580         assert_int_equal(ret, LDB_SUCCESS);
2581
2582         syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_DIRECTORY_STRING);
2583         assert_non_null(syntax);
2584
2585         ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb,
2586                                                     "cn", LDB_ATTR_FLAG_INDEXED,
2587                                                     syntax, &cn_attr_2);
2588         assert_int_equal(ret, LDB_SUCCESS);
2589
2590         /*
2591          * Set an attribute handler
2592          */
2593         ldb_schema_attribute_set_override_handler(ldb,
2594                                                   ldb_test_attribute_handler_override,
2595                                                   NULL);
2596
2597         /* cn matches lower case */
2598         cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2599         assert_int_equal(cnt, 1);
2600
2601         /* Add the index (actually any modify will do) */
2602         while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &index_ldif))) {
2603                 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
2604                 assert_int_equal(ret, LDB_SUCCESS);
2605         }
2606
2607         ldb_schema_set_override_indexlist(ldb, false);
2608
2609         /* cn does match as there is an index now */
2610         cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2611         assert_int_equal(cnt, 1);
2612
2613         /*
2614          * Set an attribute handler, which will later fail to match as we
2615          * didn't re-index the DB
2616          */
2617         ldb_schema_attribute_set_override_handler(ldb,
2618                                                   ldb_test_attribute_handler_override,
2619                                                   (void *)1);
2620
2621         /*
2622          * cn does not match as we changed the case sensitivity, but
2623          * didn't re-index
2624          *
2625          * This shows that the override is in control
2626          */
2627         cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue");
2628         assert_int_equal(cnt, 0);
2629
2630 }
2631
2632 static int ldb_case_attrs_index_test_teardown(void **state)
2633 {
2634         int ret;
2635         struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
2636                         struct ldbtest_ctx);
2637         struct ldb_dn *del_dn;
2638
2639         del_dn = ldb_dn_new_fmt(ldb_test_ctx,
2640                                 ldb_test_ctx->ldb,
2641                                 "@INDEXLIST");
2642         assert_non_null(del_dn);
2643
2644         ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
2645         if (ret != LDB_ERR_NO_SUCH_OBJECT) {
2646                 assert_int_equal(ret, LDB_SUCCESS);
2647         }
2648
2649         assert_dn_doesnt_exist(ldb_test_ctx,
2650                                "@INDEXLIST");
2651
2652         ldb_case_test_teardown(state);
2653         return 0;
2654 }
2655
2656
2657 struct rename_test_ctx {
2658         struct ldbtest_ctx *ldb_test_ctx;
2659
2660         struct ldb_dn *basedn;
2661         const char *str_basedn;
2662
2663         const char *teardown_dn;
2664 };
2665
2666 static int ldb_rename_test_setup(void **state)
2667 {
2668         struct ldbtest_ctx *ldb_test_ctx;
2669         struct rename_test_ctx *rename_test_ctx;
2670         const char *strdn = "dc=rename_test_entry_from";
2671
2672         ldbtest_setup((void **) &ldb_test_ctx);
2673
2674         rename_test_ctx = talloc(ldb_test_ctx, struct rename_test_ctx);
2675         assert_non_null(rename_test_ctx);
2676         rename_test_ctx->ldb_test_ctx = ldb_test_ctx;
2677         assert_non_null(rename_test_ctx->ldb_test_ctx);
2678
2679         rename_test_ctx->basedn = ldb_dn_new_fmt(rename_test_ctx,
2680                                 rename_test_ctx->ldb_test_ctx->ldb,
2681                                 "%s", strdn);
2682         assert_non_null(rename_test_ctx->basedn);
2683
2684         rename_test_ctx->str_basedn = strdn;
2685         rename_test_ctx->teardown_dn = strdn;
2686
2687         add_dn_with_cn(ldb_test_ctx,
2688                        rename_test_ctx->basedn,
2689                        "test_rename_cn_val");
2690
2691         *state = rename_test_ctx;
2692         return 0;
2693 }
2694
2695 static int ldb_rename_test_teardown(void **state)
2696 {
2697         int ret;
2698         struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(*state,
2699                         struct rename_test_ctx);
2700         struct ldbtest_ctx *ldb_test_ctx;
2701         struct ldb_dn *del_dn;
2702
2703         ldb_test_ctx = rename_test_ctx->ldb_test_ctx;
2704
2705         del_dn = ldb_dn_new_fmt(rename_test_ctx,
2706                                 rename_test_ctx->ldb_test_ctx->ldb,
2707                                 "%s", rename_test_ctx->teardown_dn);
2708         assert_non_null(del_dn);
2709
2710         ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
2711         assert_int_equal(ret, LDB_SUCCESS);
2712
2713         assert_dn_doesnt_exist(ldb_test_ctx,
2714                                rename_test_ctx->teardown_dn);
2715
2716         ldbtest_teardown((void **) &ldb_test_ctx);
2717         return 0;
2718 }
2719
2720 static void test_ldb_rename(void **state)
2721 {
2722         struct rename_test_ctx *rename_test_ctx =
2723                 talloc_get_type_abort(*state, struct rename_test_ctx);
2724         int ret;
2725         const char *str_new_dn = "dc=rename_test_entry_to";
2726         struct ldb_dn *new_dn;
2727
2728         new_dn = ldb_dn_new_fmt(rename_test_ctx,
2729                                 rename_test_ctx->ldb_test_ctx->ldb,
2730                                 "%s", str_new_dn);
2731         assert_non_null(new_dn);
2732
2733         ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
2734                          rename_test_ctx->basedn,
2735                          new_dn);
2736         assert_int_equal(ret, LDB_SUCCESS);
2737
2738         assert_dn_exists(rename_test_ctx->ldb_test_ctx, str_new_dn);
2739         assert_dn_doesnt_exist(rename_test_ctx->ldb_test_ctx,
2740                                rename_test_ctx->str_basedn);
2741         rename_test_ctx->teardown_dn = str_new_dn;
2742
2743         /* FIXME - test the values which didn't change */
2744 }
2745
2746 static void test_ldb_rename_from_doesnt_exist(void **state)
2747 {
2748         struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(
2749                                                         *state,
2750                                                         struct rename_test_ctx);
2751         int ret;
2752         const char *str_new_dn = "dc=rename_test_entry_to";
2753         const char *str_bad_old_dn = "dc=rename_test_no_such_entry";
2754         struct ldb_dn *new_dn;
2755         struct ldb_dn *bad_old_dn;
2756
2757         new_dn = ldb_dn_new_fmt(rename_test_ctx,
2758                                 rename_test_ctx->ldb_test_ctx->ldb,
2759                                 "%s", str_new_dn);
2760         assert_non_null(new_dn);
2761
2762         bad_old_dn = ldb_dn_new_fmt(rename_test_ctx,
2763                                     rename_test_ctx->ldb_test_ctx->ldb,
2764                                     "%s", str_bad_old_dn);
2765         assert_non_null(bad_old_dn);
2766
2767         assert_dn_doesnt_exist(rename_test_ctx->ldb_test_ctx,
2768                                str_bad_old_dn);
2769
2770         ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
2771                          bad_old_dn, new_dn);
2772         assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT);
2773
2774         assert_dn_doesnt_exist(rename_test_ctx->ldb_test_ctx,
2775                                str_new_dn);
2776 }
2777
2778 static void test_ldb_rename_to_exists(void **state)
2779 {
2780         struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(
2781                                                         *state,
2782                                                         struct rename_test_ctx);
2783         int ret;
2784         const char *str_new_dn = "dc=rename_test_already_exists";
2785         struct ldb_dn *new_dn;
2786
2787         new_dn = ldb_dn_new_fmt(rename_test_ctx,
2788                                 rename_test_ctx->ldb_test_ctx->ldb,
2789                                 "%s", str_new_dn);
2790         assert_non_null(new_dn);
2791
2792         add_dn_with_cn(rename_test_ctx->ldb_test_ctx,
2793                        new_dn,
2794                        "test_rename_cn_val");
2795
2796         ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
2797                          rename_test_ctx->basedn,
2798                          new_dn);
2799         assert_int_equal(ret, LDB_ERR_ENTRY_ALREADY_EXISTS);
2800
2801         /* Old object must still exist */
2802         assert_dn_exists(rename_test_ctx->ldb_test_ctx,
2803                          rename_test_ctx->str_basedn);
2804
2805         ret = ldb_delete(rename_test_ctx->ldb_test_ctx->ldb,
2806                          new_dn);
2807         assert_int_equal(ret, LDB_SUCCESS);
2808
2809         assert_dn_exists(rename_test_ctx->ldb_test_ctx,
2810                                rename_test_ctx->teardown_dn);
2811 }
2812
2813 static void test_ldb_rename_self(void **state)
2814 {
2815         struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(
2816                                                         *state,
2817                                                         struct rename_test_ctx);
2818         int ret;
2819
2820         /* Oddly enough, this is a success in ldb.. */
2821         ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
2822                          rename_test_ctx->basedn,
2823                          rename_test_ctx->basedn);
2824         assert_int_equal(ret, LDB_SUCCESS);
2825
2826         /* Old object must still exist */
2827         assert_dn_exists(rename_test_ctx->ldb_test_ctx,
2828                          rename_test_ctx->str_basedn);
2829 }
2830
2831 static void test_ldb_rename_dn_case_change(void **state)
2832 {
2833         struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(
2834                                                         *state,
2835                                                         struct rename_test_ctx);
2836         int ret;
2837         char *str_new_dn;
2838         struct ldb_dn *new_dn;
2839         unsigned i;
2840
2841         str_new_dn = talloc_strdup(rename_test_ctx, rename_test_ctx->str_basedn);
2842         assert_non_null(str_new_dn);
2843         for (i = 0; str_new_dn[i]; i++) {
2844                 str_new_dn[i] = toupper(str_new_dn[i]);
2845         }
2846
2847         new_dn = ldb_dn_new_fmt(rename_test_ctx,
2848                                 rename_test_ctx->ldb_test_ctx->ldb,
2849                                 "%s", str_new_dn);
2850         assert_non_null(new_dn);
2851
2852         ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb,
2853                          rename_test_ctx->basedn,
2854                          new_dn);
2855         assert_int_equal(ret, LDB_SUCCESS);
2856
2857         /* DNs are case insensitive, so both searches will match */
2858         assert_dn_exists(rename_test_ctx->ldb_test_ctx, str_new_dn);
2859         assert_dn_exists(rename_test_ctx->ldb_test_ctx,
2860                          rename_test_ctx->str_basedn);
2861         /* FIXME - test the values didn't change */
2862 }
2863
2864 static int ldb_read_only_setup(void **state)
2865 {
2866         struct ldbtest_ctx *test_ctx;
2867
2868         ldbtest_setup((void **) &test_ctx);
2869
2870         *state = test_ctx;
2871         return 0;
2872 }
2873
2874 static int ldb_read_only_teardown(void **state)
2875 {
2876         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
2877                                                         struct ldbtest_ctx);
2878         ldbtest_teardown((void **) &test_ctx);
2879         return 0;
2880 }
2881
2882 static void test_read_only(void **state)
2883 {
2884         struct ldb_context *ro_ldb = NULL;
2885         struct ldb_context *rw_ldb = NULL;
2886         int ret;
2887         TALLOC_CTX *tmp_ctx = NULL;
2888
2889         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
2890                                                         struct ldbtest_ctx);
2891         /*
2892          * Close the ldb context freeing it this will ensure it exists on
2893          * disk and can be opened in read only mode
2894          */
2895         TALLOC_FREE(test_ctx->ldb);
2896
2897         /*
2898          * Open the database in read only and read write mode,
2899          * ensure it's opend in read only mode first
2900          */
2901         ro_ldb = ldb_init(test_ctx, test_ctx->ev);
2902         ret = ldb_connect(ro_ldb, test_ctx->dbpath, LDB_FLG_RDONLY, NULL);
2903         assert_int_equal(ret, 0);
2904
2905         rw_ldb = ldb_init(test_ctx, test_ctx->ev);
2906         ret = ldb_connect(rw_ldb, test_ctx->dbpath, 0, NULL);
2907         assert_int_equal(ret, 0);
2908
2909
2910         /*
2911          * Set up a context for the temporary variables
2912          */
2913         tmp_ctx = talloc_new(test_ctx);
2914         assert_non_null(tmp_ctx);
2915
2916         /*
2917          * Ensure that we can search the read write database
2918          */
2919         {
2920                 struct ldb_result *result = NULL;
2921                 struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, rw_ldb,
2922                                                        "dc=test");
2923                 assert_non_null(dn);
2924
2925                 ret = ldb_search(rw_ldb, tmp_ctx, &result, dn,
2926                                  LDB_SCOPE_BASE, NULL, NULL);
2927                 assert_int_equal(ret, LDB_SUCCESS);
2928                 TALLOC_FREE(result);
2929                 TALLOC_FREE(dn);
2930         }
2931
2932         /*
2933          * Ensure that we can search the read only database
2934          */
2935         {
2936                 struct ldb_result *result = NULL;
2937                 struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, ro_ldb,
2938                                                        "dc=test");
2939                 assert_non_null(dn);
2940
2941                 ret = ldb_search(ro_ldb, tmp_ctx, &result, dn,
2942                                  LDB_SCOPE_BASE, NULL, NULL);
2943                 assert_int_equal(ret, LDB_SUCCESS);
2944                 TALLOC_FREE(result);
2945                 TALLOC_FREE(dn);
2946         }
2947         /*
2948          * Ensure that a write to the read only database fails
2949          */
2950         {
2951                 struct ldb_message *msg = NULL;
2952                 msg = ldb_msg_new(tmp_ctx);
2953                 assert_non_null(msg);
2954
2955                 msg->dn = ldb_dn_new_fmt(msg, ro_ldb, "dc=test");
2956                 assert_non_null(msg->dn);
2957
2958                 ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
2959                 assert_int_equal(ret, 0);
2960
2961                 ret = ldb_add(ro_ldb, msg);
2962                 assert_int_equal(ret, LDB_ERR_UNWILLING_TO_PERFORM);
2963                 TALLOC_FREE(msg);
2964         }
2965
2966         /*
2967          * Ensure that a write to the read write database succeeds
2968          */
2969         {
2970                 struct ldb_message *msg = NULL;
2971                 msg = ldb_msg_new(tmp_ctx);
2972                 assert_non_null(msg);
2973
2974                 msg->dn = ldb_dn_new_fmt(msg, ro_ldb, "dc=test");
2975                 assert_non_null(msg->dn);
2976
2977                 ret = ldb_msg_add_string(msg, "cn", "test_cn_val");
2978                 assert_int_equal(ret, 0);
2979
2980                 ret = ldb_add(rw_ldb, msg);
2981                 assert_int_equal(ret, LDB_SUCCESS);
2982                 TALLOC_FREE(msg);
2983         }
2984
2985         /*
2986          * Ensure that a delete from a read only database fails
2987          */
2988         {
2989                 struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, ro_ldb, "dc=test");
2990                 assert_non_null(dn);
2991
2992                 ret = ldb_delete(ro_ldb, dn);
2993                 assert_int_equal(ret, LDB_ERR_UNWILLING_TO_PERFORM);
2994                 TALLOC_FREE(dn);
2995         }
2996
2997
2998         /*
2999          * Ensure that a delete from a read write succeeds
3000          */
3001         {
3002                 struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, rw_ldb, "dc=test");
3003                 assert_non_null(dn);
3004
3005                 ret = ldb_delete(rw_ldb, dn);
3006                 assert_int_equal(ret, LDB_SUCCESS);
3007                 TALLOC_FREE(dn);
3008         }
3009         TALLOC_FREE(tmp_ctx);
3010 }
3011
3012 static bool unique_values = false;
3013
3014 static int unique_index_test_module_add(
3015         struct ldb_module *module,
3016         struct ldb_request *req)
3017 {
3018         if (unique_values) {
3019                 struct ldb_message *msg = discard_const(req->op.add.message);
3020                 struct ldb_message_element *el = NULL;
3021                 el = ldb_msg_find_element(msg, "cn");
3022                 if (el != NULL) {
3023                         el->flags |= LDB_FLAG_INTERNAL_FORCE_UNIQUE_INDEX;
3024                 }
3025         }
3026
3027         return ldb_next_request(module, req);
3028 }
3029
3030 static int unique_index_test_module_init(struct ldb_module *module)
3031 {
3032         return ldb_next_init(module);
3033 }
3034
3035 static const struct ldb_module_ops ldb_unique_index_test_module_ops = {
3036         .name           = "unique_index_test",
3037         .init_context   = unique_index_test_module_init,
3038         .add            = unique_index_test_module_add,
3039 };
3040
3041 static int ldb_unique_index_test_setup(void **state)
3042 {
3043         int ret;
3044         struct ldb_ldif *ldif;
3045         struct ldbtest_ctx *ldb_test_ctx;
3046         const char *attrs_ldif =  \
3047                 "dn: @ATTRIBUTES\n"
3048                 "cn: UNIQUE_INDEX\n"
3049                 "\n";
3050         const char *index_ldif =  \
3051                 "dn: @INDEXLIST\n"
3052                 "@IDXATTR: cn\n"
3053                 "\n";
3054         const char *options[] = {"modules:unique_index_test"};
3055
3056
3057         ret = ldb_register_module(&ldb_unique_index_test_module_ops);
3058         assert_true(ret == LDB_SUCCESS || ret == LDB_ERR_ENTRY_ALREADY_EXISTS);
3059         ldbtest_noconn_setup((void **) &ldb_test_ctx);
3060
3061
3062         ret = ldb_connect(ldb_test_ctx->ldb, ldb_test_ctx->dbpath, 0, options);
3063         assert_int_equal(ret, 0);
3064
3065         while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &attrs_ldif))) {
3066                 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
3067                 assert_int_equal(ret, LDB_SUCCESS);
3068         }
3069
3070         while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &index_ldif))) {
3071                 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
3072                 assert_int_equal(ret, LDB_SUCCESS);
3073         }
3074
3075         unique_values = true;
3076
3077         *state = ldb_test_ctx;
3078         return 0;
3079 }
3080
3081 static int ldb_unique_index_test_teardown(void **state)
3082 {
3083         int ret;
3084         struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
3085                         struct ldbtest_ctx);
3086         struct ldb_dn *del_dn;
3087
3088         del_dn = ldb_dn_new_fmt(ldb_test_ctx,
3089                                 ldb_test_ctx->ldb,
3090                                 "@INDEXLIST");
3091         assert_non_null(del_dn);
3092
3093         ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
3094         if (ret != LDB_ERR_NO_SUCH_OBJECT) {
3095                 assert_int_equal(ret, LDB_SUCCESS);
3096         }
3097
3098         assert_dn_doesnt_exist(ldb_test_ctx,
3099                                "@INDEXLIST");
3100
3101         TALLOC_FREE(del_dn);
3102
3103         del_dn = ldb_dn_new_fmt(ldb_test_ctx,
3104                                 ldb_test_ctx->ldb,
3105                                 "@ATTRIBUTES");
3106         assert_non_null(del_dn);
3107
3108         ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
3109         if (ret != LDB_ERR_NO_SUCH_OBJECT) {
3110                 assert_int_equal(ret, LDB_SUCCESS);
3111         }
3112
3113         assert_dn_doesnt_exist(ldb_test_ctx,
3114                                "@ATTRIBUTES");
3115
3116         ldbtest_teardown((void **) &ldb_test_ctx);
3117         return 0;
3118 }
3119
3120
3121 static void test_ldb_add_unique_value_to_unique_index(void **state)
3122 {
3123         int ret;
3124         struct ldb_message *msg;
3125         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3126                                                         struct ldbtest_ctx);
3127         TALLOC_CTX *tmp_ctx;
3128
3129         tmp_ctx = talloc_new(test_ctx);
3130         assert_non_null(tmp_ctx);
3131
3132         msg = ldb_msg_new(tmp_ctx);
3133         assert_non_null(msg);
3134
3135         msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "dc=test");
3136         assert_non_null(msg->dn);
3137
3138         ret = ldb_msg_add_string(msg, "cn", "test_unique_index");
3139         assert_int_equal(ret, LDB_SUCCESS);
3140
3141         ret = ldb_add(test_ctx->ldb, msg);
3142         assert_int_equal(ret, LDB_SUCCESS);
3143
3144         talloc_free(tmp_ctx);
3145 }
3146
3147 static int ldb_non_unique_index_test_setup(void **state)
3148 {
3149         int ret;
3150         struct ldb_ldif *ldif;
3151         struct ldbtest_ctx *ldb_test_ctx;
3152         const char *index_ldif =  \
3153                 "dn: @INDEXLIST\n"
3154                 "@IDXATTR: cn\n"
3155                 "\n";
3156         const char *options[] = {"modules:unique_index_test"};
3157
3158
3159         ret = ldb_register_module(&ldb_unique_index_test_module_ops);
3160         assert_true(ret == LDB_SUCCESS || ret == LDB_ERR_ENTRY_ALREADY_EXISTS);
3161         ldbtest_noconn_setup((void **) &ldb_test_ctx);
3162
3163
3164         ret = ldb_connect(ldb_test_ctx->ldb, ldb_test_ctx->dbpath, 0, options);
3165         assert_int_equal(ret, 0);
3166
3167         while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &index_ldif))) {
3168                 ret = ldb_add(ldb_test_ctx->ldb, ldif->msg);
3169                 assert_int_equal(ret, LDB_SUCCESS);
3170         }
3171
3172         unique_values = true;
3173
3174         *state = ldb_test_ctx;
3175         return 0;
3176 }
3177
3178 static int ldb_non_unique_index_test_teardown(void **state)
3179 {
3180         int ret;
3181         struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state,
3182                         struct ldbtest_ctx);
3183         struct ldb_dn *del_dn;
3184
3185         del_dn = ldb_dn_new_fmt(ldb_test_ctx,
3186                                 ldb_test_ctx->ldb,
3187                                 "@INDEXLIST");
3188         assert_non_null(del_dn);
3189
3190         ret = ldb_delete(ldb_test_ctx->ldb, del_dn);
3191         if (ret != LDB_ERR_NO_SUCH_OBJECT) {
3192                 assert_int_equal(ret, LDB_SUCCESS);
3193         }
3194
3195         assert_dn_doesnt_exist(ldb_test_ctx,
3196                                "@INDEXLIST");
3197
3198         TALLOC_FREE(del_dn);
3199
3200         ldbtest_teardown((void **) &ldb_test_ctx);
3201         return 0;
3202 }
3203
3204 static void test_ldb_add_duplicate_value_to_unique_index(void **state)
3205 {
3206         int ret;
3207         struct ldb_message *msg01;
3208         struct ldb_message *msg02;
3209         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3210                                                         struct ldbtest_ctx);
3211         TALLOC_CTX *tmp_ctx;
3212
3213         tmp_ctx = talloc_new(test_ctx);
3214         assert_non_null(tmp_ctx);
3215
3216         msg01 = ldb_msg_new(tmp_ctx);
3217         assert_non_null(msg01);
3218
3219         msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3220         assert_non_null(msg01->dn);
3221
3222         ret = ldb_msg_add_string(msg01, "cn", "test_unique_index");
3223         assert_int_equal(ret, LDB_SUCCESS);
3224
3225         ret = ldb_add(test_ctx->ldb, msg01);
3226         assert_int_equal(ret, LDB_SUCCESS);
3227
3228         msg02 = ldb_msg_new(tmp_ctx);
3229         assert_non_null(msg02);
3230
3231         msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02");
3232         assert_non_null(msg02->dn);
3233
3234         ret = ldb_msg_add_string(msg02, "cn", "test_unique_index");
3235         assert_int_equal(ret, LDB_SUCCESS);
3236
3237         ret = ldb_add(test_ctx->ldb, msg02);
3238         assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION);
3239         talloc_free(tmp_ctx);
3240 }
3241
3242 static void test_ldb_add_to_index_duplicates_allowed(void **state)
3243 {
3244         int ret;
3245         struct ldb_message *msg01;
3246         struct ldb_message *msg02;
3247         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3248                                                         struct ldbtest_ctx);
3249         TALLOC_CTX *tmp_ctx;
3250
3251         unique_values = false;
3252
3253         tmp_ctx = talloc_new(test_ctx);
3254         assert_non_null(tmp_ctx);
3255
3256
3257         msg01 = ldb_msg_new(tmp_ctx);
3258         assert_non_null(msg01);
3259
3260         msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3261         assert_non_null(msg01->dn);
3262
3263         ret = ldb_msg_add_string(msg01, "cn", "test_unique_index");
3264         assert_int_equal(ret, LDB_SUCCESS);
3265
3266         ret = ldb_add(test_ctx->ldb, msg01);
3267         assert_int_equal(ret, LDB_SUCCESS);
3268
3269         msg02 = ldb_msg_new(tmp_ctx);
3270         assert_non_null(msg02);
3271
3272         msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02");
3273         assert_non_null(msg02->dn);
3274
3275         ret = ldb_msg_add_string(msg02, "cn", "test_unique_index");
3276         assert_int_equal(ret, LDB_SUCCESS);
3277
3278         ret = ldb_add(test_ctx->ldb, msg02);
3279         assert_int_equal(ret, LDB_SUCCESS);
3280         talloc_free(tmp_ctx);
3281 }
3282
3283 static void test_ldb_add_to_index_unique_values_required(void **state)
3284 {
3285         int ret;
3286         struct ldb_message *msg01;
3287         struct ldb_message *msg02;
3288         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
3289                                                         struct ldbtest_ctx);
3290         TALLOC_CTX *tmp_ctx;
3291
3292         unique_values = true;
3293
3294         tmp_ctx = talloc_new(test_ctx);
3295         assert_non_null(tmp_ctx);
3296
3297
3298         msg01 = ldb_msg_new(tmp_ctx);
3299         assert_non_null(msg01);
3300
3301         msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01");
3302         assert_non_null(msg01->dn);
3303
3304         ret = ldb_msg_add_string(msg01, "cn", "test_unique_index");
3305         assert_int_equal(ret, LDB_SUCCESS);
3306
3307         ret = ldb_add(test_ctx->ldb, msg01);
3308         assert_int_equal(ret, LDB_SUCCESS);
3309
3310         msg02 = ldb_msg_new(tmp_ctx);
3311         assert_non_null(msg01);
3312
3313         msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02");
3314         assert_non_null(msg02->dn);
3315
3316         ret = ldb_msg_add_string(msg02, "cn", "test_unique_index");
3317         assert_int_equal(ret, LDB_SUCCESS);
3318
3319         ret = ldb_add(test_ctx->ldb, msg02);
3320         assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION);
3321         talloc_free(tmp_ctx);
3322 }
3323 int main(int argc, const char **argv)
3324 {
3325         const struct CMUnitTest tests[] = {
3326                 cmocka_unit_test_setup_teardown(test_connect,
3327                                                 ldbtest_noconn_setup,
3328                                                 ldbtest_noconn_teardown),
3329                 cmocka_unit_test_setup_teardown(test_ldif_message,
3330                                                 ldbtest_noconn_setup,
3331                                                 ldbtest_noconn_teardown),
3332                 cmocka_unit_test_setup_teardown(test_ldif_message_redacted,
3333                                                 ldbtest_noconn_setup,
3334                                                 ldbtest_noconn_teardown),
3335                 cmocka_unit_test_setup_teardown(test_ldb_add,
3336                                                 ldbtest_setup,
3337                                                 ldbtest_teardown),
3338                 cmocka_unit_test_setup_teardown(test_ldb_search,
3339                                                 ldbtest_setup,
3340                                                 ldbtest_teardown),
3341                 cmocka_unit_test_setup_teardown(test_ldb_del,
3342                                                 ldbtest_setup,
3343                                                 ldbtest_teardown),
3344                 cmocka_unit_test_setup_teardown(test_ldb_del_noexist,
3345                                                 ldbtest_setup,
3346                                                 ldbtest_teardown),
3347                 cmocka_unit_test_setup_teardown(test_ldb_handle,
3348                                                 ldbtest_setup,
3349                                                 ldbtest_teardown),
3350                 cmocka_unit_test_setup_teardown(test_ldb_build_search_req,
3351                                                 ldbtest_setup,
3352                                                 ldbtest_teardown),
3353                 cmocka_unit_test_setup_teardown(test_transactions,
3354                                                 ldbtest_setup,
3355                                                 ldbtest_teardown),
3356                 cmocka_unit_test_setup_teardown(test_ldb_modify_add_key,
3357                                                 ldb_modify_test_setup,
3358                                                 ldb_modify_test_teardown),
3359                 cmocka_unit_test_setup_teardown(test_ldb_modify_extend_key,
3360                                                 ldb_modify_test_setup,
3361                                                 ldb_modify_test_teardown),
3362                 cmocka_unit_test_setup_teardown(test_ldb_modify_add_key_noval,
3363                                                 ldb_modify_test_setup,
3364                                                 ldb_modify_test_teardown),
3365                 cmocka_unit_test_setup_teardown(test_ldb_modify_replace_key,
3366                                                 ldb_modify_test_setup,
3367                                                 ldb_modify_test_teardown),
3368                 cmocka_unit_test_setup_teardown(test_ldb_modify_replace_noexist_key,
3369                                                 ldb_modify_test_setup,
3370                                                 ldb_modify_test_teardown),
3371                 cmocka_unit_test_setup_teardown(test_ldb_modify_replace_zero_vals,
3372                                                 ldb_modify_test_setup,
3373                                                 ldb_modify_test_teardown),
3374                 cmocka_unit_test_setup_teardown(test_ldb_modify_replace_noexist_key_zero_vals,
3375                                                 ldb_modify_test_setup,
3376                                                 ldb_modify_test_teardown),
3377                 cmocka_unit_test_setup_teardown(test_ldb_modify_del_key,
3378                                                 ldb_modify_test_setup,
3379                                                 ldb_modify_test_teardown),
3380                 cmocka_unit_test_setup_teardown(test_ldb_modify_del_keyval,
3381                                                 ldb_modify_test_setup,
3382                                                 ldb_modify_test_teardown),
3383                 cmocka_unit_test_setup_teardown(test_search_match_none,
3384                                                 ldb_search_test_setup,
3385                                                 ldb_search_test_teardown),
3386                 cmocka_unit_test_setup_teardown(test_search_match_one,
3387                                                 ldb_search_test_setup,
3388                                                 ldb_search_test_teardown),
3389                 cmocka_unit_test_setup_teardown(test_search_match_filter,
3390                                                 ldb_search_test_setup,
3391                                                 ldb_search_test_teardown),
3392                 cmocka_unit_test_setup_teardown(test_search_match_both,
3393                                                 ldb_search_test_setup,
3394                                                 ldb_search_test_teardown),
3395                 cmocka_unit_test_setup_teardown(test_search_match_basedn,
3396                                                 ldb_search_test_setup,
3397                                                 ldb_search_test_teardown),
3398                 cmocka_unit_test_setup_teardown(test_ldb_search_against_transaction,
3399                                                 ldb_search_test_setup,
3400                                                 ldb_search_test_teardown),
3401                 cmocka_unit_test_setup_teardown(test_ldb_modify_during_unindexed_search,
3402                                                 ldb_search_test_setup,
3403                                                 ldb_search_test_teardown),
3404                 cmocka_unit_test_setup_teardown(test_ldb_modify_during_indexed_search,
3405                                                 ldb_search_test_setup,
3406                                                 ldb_search_test_teardown),
3407                 cmocka_unit_test_setup_teardown(test_ldb_rename_during_unindexed_search,
3408                                                 ldb_search_test_setup,
3409                                                 ldb_search_test_teardown),
3410                 cmocka_unit_test_setup_teardown(test_ldb_rename_during_indexed_search,
3411                                                 ldb_search_test_setup,
3412                                                 ldb_search_test_teardown),
3413                 cmocka_unit_test_setup_teardown(test_ldb_modify_during_whole_search,
3414                                                 ldb_search_test_setup,
3415                                                 ldb_search_test_teardown),
3416                 cmocka_unit_test_setup_teardown(test_ldb_modify_before_ldb_wait,
3417                                                 ldb_search_test_setup,
3418                                                 ldb_search_test_teardown),
3419                 cmocka_unit_test_setup_teardown(test_ldb_attrs_case_insensitive,
3420                                                 ldb_case_test_setup,
3421                                                 ldb_case_test_teardown),
3422                 cmocka_unit_test_setup_teardown(test_ldb_attrs_case_handler,
3423                                                 ldb_case_test_setup,
3424                                                 ldb_case_test_teardown),
3425                 cmocka_unit_test_setup_teardown(test_ldb_attrs_index_handler,
3426                                                 ldb_case_test_setup,
3427                                                 ldb_case_attrs_index_test_teardown),
3428                 cmocka_unit_test_setup_teardown(test_ldb_rename,
3429                                                 ldb_rename_test_setup,
3430                                                 ldb_rename_test_teardown),
3431                 cmocka_unit_test_setup_teardown(test_ldb_rename_from_doesnt_exist,
3432                                                 ldb_rename_test_setup,
3433                                                 ldb_rename_test_teardown),
3434                 cmocka_unit_test_setup_teardown(test_ldb_rename_to_exists,
3435                                                 ldb_rename_test_setup,
3436                                                 ldb_rename_test_teardown),
3437                 cmocka_unit_test_setup_teardown(test_ldb_rename_self,
3438                                                 ldb_rename_test_setup,
3439                                                 ldb_rename_test_teardown),
3440                 cmocka_unit_test_setup_teardown(test_ldb_rename_dn_case_change,
3441                                                 ldb_rename_test_setup,
3442                                                 ldb_rename_test_teardown),
3443                 cmocka_unit_test_setup_teardown(test_read_only,
3444                                                 ldb_read_only_setup,
3445                                                 ldb_read_only_teardown),
3446                 cmocka_unit_test_setup_teardown(
3447                         test_ldb_add_unique_value_to_unique_index,
3448                         ldb_unique_index_test_setup,
3449                         ldb_unique_index_test_teardown),
3450                 cmocka_unit_test_setup_teardown(
3451                         test_ldb_add_duplicate_value_to_unique_index,
3452                         ldb_unique_index_test_setup,
3453                         ldb_unique_index_test_teardown),
3454                 cmocka_unit_test_setup_teardown(
3455                         test_ldb_add_to_index_duplicates_allowed,
3456                         ldb_non_unique_index_test_setup,
3457                         ldb_non_unique_index_test_teardown),
3458                 cmocka_unit_test_setup_teardown(
3459                         test_ldb_add_to_index_unique_values_required,
3460                         ldb_non_unique_index_test_setup,
3461                         ldb_non_unique_index_test_teardown),
3462         };
3463
3464         return cmocka_run_group_tests(tests, NULL, NULL);
3465 }