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