r13996: simplify ldb_async_wait() some more
[samba.git] / source4 / lib / ldb / ldb_tdb / ldb_tdb.c
1 /* 
2    ldb database library
3
4    Copyright (C) Andrew Tridgell  2004
5    Copyright (C) Stefan Metzmacher  2004
6    Copyright (C) Simo Sorce       2006
7    
8
9      ** NOTE! The following LGPL license applies to the ldb
10      ** library. This does NOT imply that all of Samba is released
11      ** under the LGPL
12    
13    This library is free software; you can redistribute it and/or
14    modify it under the terms of the GNU Lesser General Public
15    License as published by the Free Software Foundation; either
16    version 2 of the License, or (at your option) any later version.
17
18    This library is distributed in the hope that it will be useful,
19    but WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21    Lesser General Public License for more details.
22
23    You should have received a copy of the GNU Lesser General Public
24    License along with this library; if not, write to the Free Software
25    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26 */
27
28 /*
29  *  Name: ldb_tdb
30  *
31  *  Component: ldb tdb backend
32  *
33  *  Description: core functions for tdb backend
34  *
35  *  Author: Andrew Tridgell
36  *  Author: Stefan Metzmacher
37  *
38  *  Modifications:
39  *
40  *  - description: make the module use asyncronous calls
41  *    date: Feb 2006
42  *    Author: Simo Sorce
43  */
44
45 #include "includes.h"
46 #include "ldb/include/includes.h"
47
48 #include "ldb/ldb_tdb/ldb_tdb.h"
49
50
51 /*
52   map a tdb error code to a ldb error code
53 */
54 static int ltdb_err_map(enum TDB_ERROR tdb_code)
55 {
56         switch (tdb_code) {
57         case TDB_SUCCESS:
58                 return LDB_SUCCESS;
59         case TDB_ERR_CORRUPT:
60         case TDB_ERR_OOM:
61         case TDB_ERR_EINVAL:
62                 return LDB_ERR_OPERATIONS_ERROR;
63         case TDB_ERR_IO:
64                 return LDB_ERR_PROTOCOL_ERROR;
65         case TDB_ERR_LOCK:
66         case TDB_ERR_NOLOCK:
67                 return LDB_ERR_BUSY;
68         case TDB_ERR_LOCK_TIMEOUT:
69                 return LDB_ERR_TIME_LIMIT_EXCEEDED;
70         case TDB_ERR_EXISTS:
71                 return LDB_ERR_ENTRY_ALREADY_EXISTS;
72         case TDB_ERR_NOEXIST:
73                 return LDB_ERR_NO_SUCH_OBJECT;
74         case TDB_ERR_RDONLY:
75                 return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
76         }
77         return LDB_ERR_OTHER;
78 }
79
80
81 struct ldb_async_handle *init_ltdb_handle(struct ltdb_private *ltdb, struct ldb_module *module,
82                                           void *context,
83                                           int (*callback)(struct ldb_context *, void *, struct ldb_async_result *))
84 {
85         struct ltdb_async_context *ac;
86         struct ldb_async_handle *h;
87
88         h = talloc_zero(ltdb, struct ldb_async_handle);
89         if (h == NULL) {
90                 ldb_set_errstring(module->ldb, talloc_asprintf(module, "Out of Memory"));
91                 return NULL;
92         }
93
94         h->module = module;
95
96         ac = talloc_zero(h, struct ltdb_async_context);
97         if (ac == NULL) {
98                 ldb_set_errstring(module->ldb, talloc_asprintf(module, "Out of Memory"));
99                 talloc_free(h);
100                 return NULL;
101         }
102
103         h->private_data = (void *)ac;
104
105         ac->module = module;
106         ac->context = context;
107         ac->callback = callback;
108
109         return h;
110 }
111
112 /*
113   form a TDB_DATA for a record key
114   caller frees
115
116   note that the key for a record can depend on whether the 
117   dn refers to a case sensitive index record or not
118 */
119 struct TDB_DATA ltdb_key(struct ldb_module *module, const struct ldb_dn *dn)
120 {
121         struct ldb_context *ldb = module->ldb;
122         TDB_DATA key;
123         char *key_str = NULL;
124         char *dn_folded = NULL;
125
126         /*
127           most DNs are case insensitive. The exception is index DNs for
128           case sensitive attributes
129
130           there are 3 cases dealt with in this code:
131
132           1) if the dn doesn't start with @ then uppercase the attribute
133              names and the attributes values of case insensitive attributes
134           2) if the dn starts with @ then leave it alone - the indexing code handles
135              the rest
136         */
137
138         dn_folded = ldb_dn_linearize_casefold(ldb, dn);
139         if (!dn_folded) {
140                 goto failed;
141         }
142
143         key_str = talloc_asprintf(ldb, "DN=%s", dn_folded);
144
145         talloc_free(dn_folded);
146
147         if (!key_str) {
148                 goto failed;
149         }
150
151         key.dptr = (uint8_t *)key_str;
152         key.dsize = strlen(key_str) + 1;
153
154         return key;
155
156 failed:
157         errno = ENOMEM;
158         key.dptr = NULL;
159         key.dsize = 0;
160         return key;
161 }
162
163 /*
164   check special dn's have valid attributes
165   currently only @ATTRIBUTES is checked
166 */
167 int ltdb_check_special_dn(struct ldb_module *module, const struct ldb_message *msg)
168 {
169         int i, j;
170  
171         if (! ldb_dn_is_special(msg->dn) ||
172             ! ldb_dn_check_special(msg->dn, LTDB_ATTRIBUTES)) {
173                 return 0;
174         }
175
176         /* we have @ATTRIBUTES, let's check attributes are fine */
177         /* should we check that we deny multivalued attributes ? */
178         for (i = 0; i < msg->num_elements; i++) {
179                 for (j = 0; j < msg->elements[i].num_values; j++) {
180                         if (ltdb_check_at_attributes_values(&msg->elements[i].values[j]) != 0) {
181                                 char *err_string = talloc_strdup(module, "Invalid attribute value in an @ATTRIBUTES entry");
182                                 if (err_string) {
183                                         ldb_set_errstring(module->ldb, err_string);
184                                 }
185                                 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
186                         }
187                 }
188         }
189
190         return 0;
191 }
192
193
194 /*
195   we've made a modification to a dn - possibly reindex and 
196   update sequence number
197 */
198 static int ltdb_modified(struct ldb_module *module, const struct ldb_dn *dn)
199 {
200         int ret = 0;
201
202         if (ldb_dn_is_special(dn) &&
203             (ldb_dn_check_special(dn, LTDB_INDEXLIST) ||
204              ldb_dn_check_special(dn, LTDB_ATTRIBUTES)) ) {
205                 ret = ltdb_reindex(module);
206         }
207
208         if (ret == 0 &&
209             !(ldb_dn_is_special(dn) &&
210               ldb_dn_check_special(dn, LTDB_BASEINFO)) ) {
211                 ret = ltdb_increase_sequence_number(module);
212         }
213
214         return ret;
215 }
216
217 /*
218   store a record into the db
219 */
220 int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flgs)
221 {
222         struct ltdb_private *ltdb = module->private_data;
223         TDB_DATA tdb_key, tdb_data;
224         int ret;
225
226         tdb_key = ltdb_key(module, msg->dn);
227         if (!tdb_key.dptr) {
228                 return LDB_ERR_OTHER;
229         }
230
231         ret = ltdb_pack_data(module, msg, &tdb_data);
232         if (ret == -1) {
233                 talloc_free(tdb_key.dptr);
234                 return LDB_ERR_OTHER;
235         }
236
237         ret = tdb_store(ltdb->tdb, tdb_key, tdb_data, flgs);
238         if (ret == -1) {
239                 ret = ltdb_err_map(tdb_error(ltdb->tdb));
240                 goto done;
241         }
242         
243         ret = ltdb_index_add(module, msg);
244         if (ret == -1) {
245                 tdb_delete(ltdb->tdb, tdb_key);
246         }
247
248 done:
249         talloc_free(tdb_key.dptr);
250         talloc_free(tdb_data.dptr);
251
252         return ret;
253 }
254
255
256 /*
257   add a record to the database
258 */
259 static int ltdb_add_async(struct ldb_module *module, const struct ldb_message *msg,
260                           void *context,
261                           int (*callback)(struct ldb_context *, void *, struct ldb_async_result *),
262                           struct ldb_async_handle **handle)
263 {
264         struct ltdb_private *ltdb = talloc_get_type(module->private_data, struct ltdb_private);
265         struct ltdb_async_context *ltdb_ac;
266         int ret = LDB_ERR_OPERATIONS_ERROR;
267
268         *handle = init_ltdb_handle(ltdb, module, context, callback);
269         if (*handle == NULL) {
270                 return ret;
271         }
272         ltdb_ac = talloc_get_type((*handle)->private_data, struct ltdb_async_context);
273         (*handle)->state = LDB_ASYNC_DONE;
274         (*handle)->status = LDB_SUCCESS;
275
276         ret = ltdb_check_special_dn(module, msg);
277         if (ret != LDB_SUCCESS) {
278                 talloc_free(*handle);
279                 return ret;
280         }
281         
282         if (ltdb_cache_load(module) != 0) {
283                 talloc_free(*handle);
284                 return LDB_ERR_OTHER;
285         }
286
287         ret = ltdb_store(module, msg, TDB_INSERT);
288
289         if (ret != LDB_SUCCESS) {
290                 (*handle)->status = ret;
291                 return LDB_SUCCESS;
292         }
293
294         ltdb_modified(module, msg->dn);
295
296         if (ltdb_ac->callback)
297                 (*handle)->status = ltdb_ac->callback(module->ldb, ltdb_ac->context, NULL);
298         
299         return LDB_SUCCESS;
300 }
301
302 static int ltdb_add(struct ldb_module *module, const struct ldb_message *msg)
303 {
304         struct ldb_async_handle *handle;
305         int ret;
306
307         ret = ltdb_add_async(module, msg, NULL, NULL, &handle);
308
309         if (ret != LDB_SUCCESS)
310                 return ret;
311
312         ret = ldb_async_wait(handle, LDB_WAIT_ALL);
313
314         talloc_free(handle);
315         return ret;
316 }
317
318 /*
319   delete a record from the database, not updating indexes (used for deleting
320   index records)
321 */
322 int ltdb_delete_noindex(struct ldb_module *module, const struct ldb_dn *dn)
323 {
324         struct ltdb_private *ltdb = module->private_data;
325         TDB_DATA tdb_key;
326         int ret;
327
328         tdb_key = ltdb_key(module, dn);
329         if (!tdb_key.dptr) {
330                 return LDB_ERR_OTHER;
331         }
332
333         ret = tdb_delete(ltdb->tdb, tdb_key);
334         talloc_free(tdb_key.dptr);
335
336         if (ret != 0) {
337                 ret = ltdb_err_map(tdb_error(ltdb->tdb));
338         }
339
340         return ret;
341 }
342
343 /*
344   delete a record from the database
345 */
346 static int ltdb_delete_async(struct ldb_module *module, const struct ldb_dn *dn,
347                              void *context,
348                              int (*callback)(struct ldb_context *, void *, struct ldb_async_result *),
349                              struct ldb_async_handle **handle)
350 {
351         struct ltdb_private *ltdb = talloc_get_type(module->private_data, struct ltdb_private);
352         struct ltdb_async_context *ltdb_ac;
353         struct ldb_message *msg;
354         int ret = LDB_ERR_OPERATIONS_ERROR;
355
356         *handle = NULL;
357
358         if (ltdb_cache_load(module) != 0) {
359                 goto failed;
360         }
361
362         *handle = init_ltdb_handle(ltdb, module, context, callback);
363         if (*handle == NULL) {
364                 goto failed;
365         }
366         ltdb_ac = talloc_get_type((*handle)->private_data, struct ltdb_async_context);
367         (*handle)->state = LDB_ASYNC_DONE;
368         (*handle)->status = LDB_SUCCESS;
369
370         msg = talloc(ltdb_ac, struct ldb_message);
371         if (msg == NULL) {
372                 goto failed;
373         }
374
375         /* in case any attribute of the message was indexed, we need
376            to fetch the old record */
377         ret = ltdb_search_dn1(module, dn, msg);
378         if (ret != 1) {
379                 /* not finding the old record is an error */
380                 (*handle)->status = LDB_ERR_NO_SUCH_OBJECT;
381                 return LDB_SUCCESS;
382         }
383
384         ret = ltdb_delete_noindex(module, dn);
385         if (ret != LDB_SUCCESS) {
386                 goto failed;
387         }
388
389         /* remove any indexed attributes */
390         ret = ltdb_index_del(module, msg);
391         if (ret) {
392                 goto failed;
393         }
394         ltdb_modified(module, dn);
395
396         if (ltdb_ac->callback)
397                 (*handle)->status = ltdb_ac->callback(module->ldb, ltdb_ac->context, NULL);
398         
399         return LDB_SUCCESS;
400
401 failed:
402         talloc_free(*handle);
403         return ret;
404 }
405
406 static int ltdb_delete(struct ldb_module *module, const struct ldb_dn *dn)
407 {
408         struct ldb_async_handle *handle;
409         int ret;
410
411         ret = ltdb_delete_async(module, dn, NULL, NULL, &handle);
412
413         if (ret != LDB_SUCCESS)
414                 return ret;
415
416         ret = ldb_async_wait(handle, LDB_WAIT_ALL);
417
418         talloc_free(handle);
419         return ret;
420 }
421
422
423 /*
424   find an element by attribute name. At the moment this does a linear search, it should
425   be re-coded to use a binary search once all places that modify records guarantee
426   sorted order
427
428   return the index of the first matching element if found, otherwise -1
429 */
430 static int find_element(const struct ldb_message *msg, const char *name)
431 {
432         unsigned int i;
433         for (i=0;i<msg->num_elements;i++) {
434                 if (ldb_attr_cmp(msg->elements[i].name, name) == 0) {
435                         return i;
436                 }
437         }
438         return -1;
439 }
440
441
442 /*
443   add an element to an existing record. Assumes a elements array that we
444   can call re-alloc on, and assumed that we can re-use the data pointers from the 
445   passed in additional values. Use with care!
446
447   returns 0 on success, -1 on failure (and sets errno)
448 */
449 static int msg_add_element(struct ldb_context *ldb,
450                            struct ldb_message *msg, struct ldb_message_element *el)
451 {
452         struct ldb_message_element *e2;
453         unsigned int i;
454
455         e2 = talloc_realloc(msg, msg->elements, struct ldb_message_element, 
456                               msg->num_elements+1);
457         if (!e2) {
458                 errno = ENOMEM;
459                 return -1;
460         }
461
462         msg->elements = e2;
463
464         e2 = &msg->elements[msg->num_elements];
465
466         e2->name = el->name;
467         e2->flags = el->flags;
468         e2->values = NULL;
469         if (el->num_values != 0) {
470                 e2->values = talloc_array(msg->elements, struct ldb_val, el->num_values);
471                 if (!e2->values) {
472                         errno = ENOMEM;
473                         return -1;
474                 }
475         }
476         for (i=0;i<el->num_values;i++) {
477                 e2->values[i] = el->values[i];
478         }
479         e2->num_values = el->num_values;
480
481         msg->num_elements++;
482
483         return 0;
484 }
485
486 /*
487   delete all elements having a specified attribute name
488 */
489 static int msg_delete_attribute(struct ldb_module *module,
490                                 struct ldb_context *ldb,
491                                 struct ldb_message *msg, const char *name)
492 {
493         char *dn;
494         unsigned int i, j;
495
496         dn = ldb_dn_linearize(ldb, msg->dn);
497         if (dn == NULL) {
498                 return -1;
499         }
500
501         for (i=0;i<msg->num_elements;i++) {
502                 if (ldb_attr_cmp(msg->elements[i].name, name) == 0) {
503                         for (j=0;j<msg->elements[i].num_values;j++) {
504                                 ltdb_index_del_value(module, dn, &msg->elements[i], j);
505                         }
506                         talloc_free(msg->elements[i].values);
507                         if (msg->num_elements > (i+1)) {
508                                 memmove(&msg->elements[i], 
509                                         &msg->elements[i+1], 
510                                         sizeof(struct ldb_message_element)*
511                                         (msg->num_elements - (i+1)));
512                         }
513                         msg->num_elements--;
514                         i--;
515                         msg->elements = talloc_realloc(msg, msg->elements, 
516                                                          struct ldb_message_element, 
517                                                          msg->num_elements);
518                 }
519         }
520
521         talloc_free(dn);
522         return 0;
523 }
524
525 /*
526   delete all elements matching an attribute name/value 
527
528   return 0 on success, -1 on failure
529 */
530 static int msg_delete_element(struct ldb_module *module,
531                               struct ldb_message *msg, 
532                               const char *name,
533                               const struct ldb_val *val)
534 {
535         struct ldb_context *ldb = module->ldb;
536         unsigned int i;
537         int found;
538         struct ldb_message_element *el;
539         const struct ldb_attrib_handler *h;
540
541         found = find_element(msg, name);
542         if (found == -1) {
543                 return -1;
544         }
545
546         el = &msg->elements[found];
547
548         h = ldb_attrib_handler(ldb, el->name);
549
550         for (i=0;i<el->num_values;i++) {
551                 if (h->comparison_fn(ldb, ldb, &el->values[i], val) == 0) {
552                         if (i<el->num_values-1) {
553                                 memmove(&el->values[i], &el->values[i+1],
554                                         sizeof(el->values[i])*(el->num_values-(i+1)));
555                         }
556                         el->num_values--;
557                         if (el->num_values == 0) {
558                                 return msg_delete_attribute(module, ldb, msg, name);
559                         }
560                         return 0;
561                 }
562         }
563
564         return -1;
565 }
566
567
568 /*
569   modify a record - internal interface
570
571   yuck - this is O(n^2). Luckily n is usually small so we probably
572   get away with it, but if we ever have really large attribute lists 
573   then we'll need to look at this again
574 */
575 int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *msg)
576 {
577         struct ldb_context *ldb = module->ldb;
578         struct ltdb_private *ltdb = module->private_data;
579         TDB_DATA tdb_key, tdb_data;
580         struct ldb_message *msg2;
581         unsigned i, j;
582         int ret;
583
584         tdb_key = ltdb_key(module, msg->dn);
585         if (!tdb_key.dptr) {
586                 return LDB_ERR_OTHER;
587         }
588
589         tdb_data = tdb_fetch(ltdb->tdb, tdb_key);
590         if (!tdb_data.dptr) {
591                 talloc_free(tdb_key.dptr);
592                 return ltdb_err_map(tdb_error(ltdb->tdb));
593         }
594
595         msg2 = talloc(tdb_key.dptr, struct ldb_message);
596         if (msg2 == NULL) {
597                 talloc_free(tdb_key.dptr);
598                 return LDB_ERR_OTHER;
599         }
600
601         ret = ltdb_unpack_data(module, &tdb_data, msg2);
602         if (ret == -1) {
603                 talloc_free(tdb_key.dptr);
604                 free(tdb_data.dptr);
605                 return LDB_ERR_OTHER;
606         }
607
608         if (!msg2->dn) {
609                 msg2->dn = msg->dn;
610         }
611
612         for (i=0;i<msg->num_elements;i++) {
613                 struct ldb_message_element *el = &msg->elements[i];
614                 struct ldb_message_element *el2;
615                 struct ldb_val *vals;
616                 char *err_string;
617                 char *dn;
618
619                 switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) {
620
621                 case LDB_FLAG_MOD_ADD:
622                         /* add this element to the message. fail if it
623                            already exists */
624                         ret = find_element(msg2, el->name);
625
626                         if (ret == -1) {
627                                 if (msg_add_element(ldb, msg2, el) != 0) {
628                                         ret = LDB_ERR_OTHER;
629                                         goto failed;
630                                 }
631                                 continue;
632                         }
633
634                         el2 = &msg2->elements[ret];
635
636                         /* An attribute with this name already exists, add all
637                          * values if they don't already exist. */
638
639                         for (j=0;j<el->num_values;j++) {
640                                 if (ldb_msg_find_val(el2, &el->values[j])) {
641                                         err_string = talloc_strdup(module, "Type or value exists");
642                                         if (err_string) ldb_set_errstring(module->ldb, err_string);
643                                         ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
644                                         goto failed;
645                                 }
646                         }
647
648                         vals = talloc_realloc(msg2->elements, el2->values, struct ldb_val,
649                                                 el2->num_values + el->num_values);
650
651                         if (vals == NULL)
652                                 goto failed;
653
654                         for (j=0;j<el->num_values;j++) {
655                                 vals[el2->num_values + j] =
656                                         ldb_val_dup(vals, &el->values[j]);
657                         }
658
659                         el2->values = vals;
660                         el2->num_values += el->num_values;
661
662                         break;
663
664                 case LDB_FLAG_MOD_REPLACE:
665                         /* replace all elements of this attribute name with the elements
666                            listed. The attribute not existing is not an error */
667                         msg_delete_attribute(module, ldb, msg2, msg->elements[i].name);
668
669                         /* add the replacement element, if not empty */
670                         if (msg->elements[i].num_values != 0 &&
671                             msg_add_element(ldb, msg2, &msg->elements[i]) != 0) {
672                                 goto failed;
673                         }
674                         break;
675
676                 case LDB_FLAG_MOD_DELETE:
677
678                         dn = ldb_dn_linearize(msg2, msg->dn);
679                         if (dn == NULL) goto failed;
680
681                         /* we could be being asked to delete all
682                            values or just some values */
683                         if (msg->elements[i].num_values == 0) {
684                                 if (msg_delete_attribute(module, ldb, msg2, 
685                                                          msg->elements[i].name) != 0) {
686                                         err_string = talloc_asprintf(module, "No such attribute: %s", msg->elements[i].name);
687                                         if (err_string) ldb_set_errstring(module->ldb, err_string);
688                                         ret = LDB_ERR_NO_SUCH_ATTRIBUTE;
689                                         goto failed;
690                                 }
691                                 break;
692                         }
693                         for (j=0;j<msg->elements[i].num_values;j++) {
694                                 if (msg_delete_element(module,
695                                                        msg2, 
696                                                        msg->elements[i].name,
697                                                        &msg->elements[i].values[j]) != 0) {
698                                         err_string = talloc_asprintf(module, "No such attribute: %s", msg->elements[i].name);
699                                         if (err_string) ldb_set_errstring(module->ldb, err_string);
700                                         ret = LDB_ERR_NO_SUCH_ATTRIBUTE;
701                                         goto failed;
702                                 }
703                                 if (ltdb_index_del_value(module, dn, &msg->elements[i], j) != 0) {
704                                         goto failed;
705                                 }
706                         }
707                         break;
708                 default:
709                         err_string = talloc_asprintf(module, "Invalid ldb_modify flags on %s: 0x%x", 
710                                                      msg->elements[i].name, 
711                                                      msg->elements[i].flags & LDB_FLAG_MOD_MASK);
712                         if (err_string) ldb_set_errstring(module->ldb, err_string);
713                         ret = LDB_ERR_PROTOCOL_ERROR;
714                         goto failed;
715                 }
716         }
717
718         /* we've made all the mods - save the modified record back into the database */
719         ret = ltdb_store(module, msg2, TDB_MODIFY);
720
721         talloc_free(tdb_key.dptr);
722         free(tdb_data.dptr);
723         return ret;
724
725 failed:
726         talloc_free(tdb_key.dptr);
727         free(tdb_data.dptr);
728         return ret;
729 }
730
731 /*
732   modify a record
733 */
734 static int ltdb_modify_async(struct ldb_module *module, const struct ldb_message *msg,
735                           void *context,
736                           int (*callback)(struct ldb_context *, void *, struct ldb_async_result *),
737                           struct ldb_async_handle **handle)
738 {
739         struct ltdb_private *ltdb = talloc_get_type(module->private_data, struct ltdb_private);
740         struct ltdb_async_context *ltdb_ac;
741         int ret = LDB_ERR_OPERATIONS_ERROR;
742
743         *handle = NULL;
744
745         *handle = init_ltdb_handle(ltdb, module, context, callback);
746         if (*handle == NULL) {
747                 return ret;
748         }
749         ltdb_ac = talloc_get_type((*handle)->private_data, struct ltdb_async_context);
750         (*handle)->state = LDB_ASYNC_DONE;
751         (*handle)->status = LDB_SUCCESS;
752
753         ret = ltdb_check_special_dn(module, msg);
754         if (ret != LDB_SUCCESS) {
755                 talloc_free(*handle);
756                 return ret;
757         }
758         
759         if (ltdb_cache_load(module) != 0) {
760                 talloc_free(*handle);
761                 return LDB_ERR_OTHER;
762         }
763
764         ret = ltdb_modify_internal(module, msg);
765
766         if (ret != LDB_SUCCESS) {
767                 (*handle)->status = ret;
768                 return LDB_SUCCESS;
769         }
770
771         ltdb_modified(module, msg->dn);
772
773         if (ltdb_ac->callback)
774                 (*handle)->status = ltdb_ac->callback(module->ldb, ltdb_ac->context, NULL);
775         
776         return LDB_SUCCESS;
777 }
778
779 static int ltdb_modify(struct ldb_module *module, const struct ldb_message *msg)
780 {
781         struct ldb_async_handle *handle;
782         int ret;
783
784         ret = ltdb_modify_async(module, msg, NULL, NULL, &handle);
785
786         if (ret != LDB_SUCCESS)
787                 return ret;
788
789         ret = ldb_async_wait(handle, LDB_WAIT_ALL);
790
791         talloc_free(handle);
792         return ret;
793 }
794
795 /*
796   rename a record
797 */
798 static int ltdb_rename_async(struct ldb_module *module, const struct ldb_dn *olddn, const struct ldb_dn *newdn,
799                              void *context,
800                              int (*callback)(struct ldb_context *, void *, struct ldb_async_result *),
801                              struct ldb_async_handle **handle)
802 {
803         struct ltdb_private *ltdb = talloc_get_type(module->private_data, struct ltdb_private);
804         struct ltdb_async_context *ltdb_ac;
805         struct ldb_message *msg;
806         int ret = LDB_ERR_OPERATIONS_ERROR;
807
808         *handle = NULL;
809
810         if (ltdb_cache_load(module) != 0) {
811                 return ret;
812         }
813
814         *handle = init_ltdb_handle(ltdb, module, context, callback);
815         if (*handle == NULL) {
816                 goto failed;
817         }
818         ltdb_ac = talloc_get_type((*handle)->private_data, struct ltdb_async_context);
819         (*handle)->state = LDB_ASYNC_DONE;
820         (*handle)->status = LDB_SUCCESS;
821
822         msg = talloc(ltdb_ac, struct ldb_message);
823         if (msg == NULL) {
824                 goto failed;
825         }
826
827         /* in case any attribute of the message was indexed, we need
828            to fetch the old record */
829         ret = ltdb_search_dn1(module, olddn, msg);
830         if (ret != 1) {
831                 /* not finding the old record is an error */
832                 (*handle)->status = LDB_ERR_NO_SUCH_OBJECT;
833                 return LDB_SUCCESS;
834         }
835
836         msg->dn = ldb_dn_copy(msg, newdn);
837         if (!msg->dn) {
838                 ret = LDB_ERR_OPERATIONS_ERROR;
839                 goto failed;
840         }
841
842         ret = ltdb_add(module, msg);
843         if (ret != LDB_SUCCESS) {
844                 (*handle)->status = LDB_ERR_OPERATIONS_ERROR;
845                 return LDB_SUCCESS;
846         }
847
848         ret = ltdb_delete(module, olddn);
849         if (ret != LDB_SUCCESS) {
850                 ltdb_delete(module, newdn);
851                 (*handle)->status = ret;
852                 return LDB_SUCCESS;
853         }
854
855         if (ltdb_ac->callback)
856                 (*handle)->status = ltdb_ac->callback(module->ldb, ltdb_ac->context, NULL);
857
858         return LDB_SUCCESS;
859
860 failed:
861         talloc_free(*handle);
862         return ret;
863 }
864
865 static int ltdb_rename(struct ldb_module *module, const struct ldb_dn *olddn, const struct ldb_dn *newdn)
866 {
867         struct ldb_async_handle *handle;
868         int ret;
869
870         ret = ltdb_rename_async(module, olddn, newdn, NULL, NULL, &handle);
871
872         if (ret != LDB_SUCCESS)
873                 return ret;
874
875         ret = ldb_async_wait(handle, LDB_WAIT_ALL);
876
877         talloc_free(handle);
878         return ret;
879 }
880
881 static int ltdb_start_trans(struct ldb_module *module)
882 {
883         struct ltdb_private *ltdb = module->private_data;
884
885         if (tdb_transaction_start(ltdb->tdb) != 0) {
886                 return ltdb_err_map(tdb_error(ltdb->tdb));
887         }
888
889         return LDB_SUCCESS;
890 }
891
892 static int ltdb_end_trans(struct ldb_module *module)
893 {
894         struct ltdb_private *ltdb = module->private_data;
895
896         if (tdb_transaction_commit(ltdb->tdb) != 0) {
897                 return ltdb_err_map(tdb_error(ltdb->tdb));
898         }
899
900         return LDB_SUCCESS;
901 }
902
903 static int ltdb_del_trans(struct ldb_module *module)
904 {
905         struct ltdb_private *ltdb = module->private_data;
906
907         if (tdb_transaction_cancel(ltdb->tdb) != 0) {
908                 return ltdb_err_map(tdb_error(ltdb->tdb));
909         }
910
911         return LDB_SUCCESS;
912 }
913
914 static int ltdb_async_wait(struct ldb_async_handle *handle, enum ldb_async_wait_type type)
915 {
916         return handle->status;
917 }
918
919 static int ltdb_request(struct ldb_module *module, struct ldb_request *req)
920 {
921         /* check for oustanding critical controls and return an error if found */
922
923         if (req->controls != NULL) {
924                 ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Controls should not reach the ldb_tdb backend!\n");
925         }
926
927         if (check_critical_controls(req->controls)) {
928                 return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
929         }
930         
931         switch (req->operation) {
932
933         case LDB_REQ_SEARCH:
934                 return ltdb_search_bytree(module,
935                                           req->op.search.base,
936                                           req->op.search.scope, 
937                                           req->op.search.tree, 
938                                           req->op.search.attrs,
939                                           &req->op.search.res);
940
941         case LDB_REQ_ADD:
942                 return ltdb_add(module, req->op.add.message);
943
944         case LDB_REQ_MODIFY:
945                 return ltdb_modify(module, req->op.mod.message);
946
947         case LDB_REQ_DELETE:
948                 return ltdb_delete(module, req->op.del.dn);
949
950         case LDB_REQ_RENAME:
951                 return ltdb_rename(module,
952                                         req->op.rename.olddn,
953                                         req->op.rename.newdn);
954
955         case LDB_ASYNC_SEARCH:
956                 return ltdb_search_async(module,
957                                         req->op.search.base,
958                                         req->op.search.scope, 
959                                         req->op.search.tree, 
960                                         req->op.search.attrs,
961                                         req->async.context,
962                                         req->async.callback,
963                                         &req->async.handle);
964
965         case LDB_ASYNC_ADD:
966                 return ltdb_add_async(module,
967                                         req->op.add.message,
968                                         req->async.context,
969                                         req->async.callback,
970                                         &req->async.handle);
971
972         case LDB_ASYNC_MODIFY:
973                 return ltdb_modify_async(module,
974                                         req->op.mod.message,
975                                         req->async.context,
976                                         req->async.callback,
977                                         &req->async.handle);
978
979         case LDB_ASYNC_DELETE:
980                 return ltdb_delete_async(module,
981                                         req->op.del.dn,
982                                         req->async.context,
983                                         req->async.callback,
984                                         &req->async.handle);
985
986         case LDB_ASYNC_RENAME:
987                 return ltdb_rename_async(module,
988                                         req->op.rename.olddn,
989                                         req->op.rename.newdn,
990                                         req->async.context,
991                                         req->async.callback,
992                                         &req->async.handle);
993
994         default:
995                 return LDB_ERR_OPERATIONS_ERROR;
996
997         }
998 }
999
1000 /*
1001   return sequenceNumber from @BASEINFO
1002 */
1003 static uint64_t ltdb_sequence_number(struct ldb_context *ldb)
1004 {
1005         TALLOC_CTX *tmp_ctx = talloc_new(ldb);
1006         const char *attrs[] = { "sequenceNumber", NULL };
1007         struct ldb_result *res = NULL;
1008         struct ldb_dn *dn = ldb_dn_explode(tmp_ctx, "@BASEINFO");
1009         int ret;
1010         uint64_t seq_num;
1011
1012         ret = ldb_search(ldb, dn, LDB_SCOPE_BASE, NULL, attrs, &res);
1013         talloc_steal(tmp_ctx, res);
1014         if (ret != LDB_SUCCESS || res->count != 1) {
1015                 talloc_free(tmp_ctx);
1016                 /* zero is as good as anything when we don't know */
1017                 return 0;
1018         }
1019
1020         seq_num = ldb_msg_find_uint64(res->msgs[0], "sequenceNumber", 0);
1021         talloc_free(tmp_ctx);
1022         return seq_num; 
1023 }
1024
1025 static const struct ldb_module_ops ltdb_ops = {
1026         .name              = "tdb",
1027         .request           = ltdb_request,
1028         .start_transaction = ltdb_start_trans,
1029         .end_transaction   = ltdb_end_trans,
1030         .del_transaction   = ltdb_del_trans,
1031         .async_wait        = ltdb_async_wait
1032 };
1033
1034
1035 /*
1036   connect to the database
1037 */
1038 static int ltdb_connect(struct ldb_context *ldb, const char *url, 
1039                  unsigned int flags, const char *options[])
1040 {
1041         const char *path;
1042         int tdb_flags, open_flags;
1043         struct ltdb_private *ltdb;
1044
1045         /* parse the url */
1046         if (strchr(url, ':')) {
1047                 if (strncmp(url, "tdb://", 6) != 0) {
1048                         ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid tdb URL '%s'", url);
1049                         return -1;
1050                 }
1051                 path = url+6;
1052         } else {
1053                 path = url;
1054         }
1055
1056         tdb_flags = TDB_DEFAULT;
1057
1058         /* check for the 'nosync' option */
1059         if (flags & LDB_FLG_NOSYNC) {
1060                 tdb_flags |= TDB_NOSYNC;
1061         }
1062
1063         if (flags & LDB_FLG_RDONLY) {
1064                 open_flags = O_RDONLY;
1065         } else {
1066                 open_flags = O_CREAT | O_RDWR;
1067         }
1068
1069         ltdb = talloc_zero(ldb, struct ltdb_private);
1070         if (!ltdb) {
1071                 ldb_oom(ldb);
1072                 return -1;
1073         }
1074
1075         /* note that we use quite a large default hash size */
1076         ltdb->tdb = ltdb_wrap_open(ltdb, path, 10000, tdb_flags, open_flags, 0666);
1077         if (!ltdb->tdb) {
1078                 ldb_debug(ldb, LDB_DEBUG_ERROR, "Unable to open tdb '%s'\n", path);
1079                 talloc_free(ltdb);
1080                 return -1;
1081         }
1082
1083         ltdb->sequence_number = 0;
1084
1085         ldb->modules = talloc(ldb, struct ldb_module);
1086         if (!ldb->modules) {
1087                 ldb_oom(ldb);
1088                 talloc_free(ltdb);
1089                 return -1;
1090         }
1091         ldb->modules->ldb = ldb;
1092         ldb->modules->prev = ldb->modules->next = NULL;
1093         ldb->modules->private_data = ltdb;
1094         ldb->modules->ops = &ltdb_ops;
1095         ldb->sequence_number = ltdb_sequence_number;
1096
1097         return 0;
1098 }
1099
1100 int ldb_tdb_init(void)
1101 {
1102         return ldb_register_backend("tdb:", ltdb_connect);
1103 }