r18942: add a ldb_set_create_perms() function in ldb. I didn't call it
[jelmer/samba4-debian.git] / source / 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_handle *init_ltdb_handle(struct ltdb_private *ltdb, struct ldb_module *module,
82                                           void *context,
83                                           int (*callback)(struct ldb_context *, void *, struct ldb_reply *))
84 {
85         struct ltdb_context *ac;
86         struct ldb_handle *h;
87
88         h = talloc_zero(ltdb, struct ldb_handle);
89         if (h == NULL) {
90                 ldb_set_errstring(module->ldb, "Out of Memory");
91                 return NULL;
92         }
93
94         h->module = module;
95
96         ac = talloc_zero(h, struct ltdb_context);
97         if (ac == NULL) {
98                 ldb_set_errstring(module->ldb, "Out of Memory");
99                 talloc_free(h);
100                 return NULL;
101         }
102
103         h->private_data = (void *)ac;
104
105         h->state = LDB_ASYNC_INIT;
106         h->status = LDB_SUCCESS;
107
108         ac->module = module;
109         ac->context = context;
110         ac->callback = callback;
111
112         return h;
113 }
114
115 /*
116   form a TDB_DATA for a record key
117   caller frees
118
119   note that the key for a record can depend on whether the 
120   dn refers to a case sensitive index record or not
121 */
122 struct TDB_DATA ltdb_key(struct ldb_module *module, const struct ldb_dn *dn)
123 {
124         struct ldb_context *ldb = module->ldb;
125         TDB_DATA key;
126         char *key_str = NULL;
127         char *dn_folded = NULL;
128
129         /*
130           most DNs are case insensitive. The exception is index DNs for
131           case sensitive attributes
132
133           there are 3 cases dealt with in this code:
134
135           1) if the dn doesn't start with @ then uppercase the attribute
136              names and the attributes values of case insensitive attributes
137           2) if the dn starts with @ then leave it alone - the indexing code handles
138              the rest
139         */
140
141         dn_folded = ldb_dn_linearize_casefold(ldb, dn);
142         if (!dn_folded) {
143                 goto failed;
144         }
145
146         key_str = talloc_asprintf(ldb, "DN=%s", dn_folded);
147
148         talloc_free(dn_folded);
149
150         if (!key_str) {
151                 goto failed;
152         }
153
154         key.dptr = (uint8_t *)key_str;
155         key.dsize = strlen(key_str) + 1;
156
157         return key;
158
159 failed:
160         errno = ENOMEM;
161         key.dptr = NULL;
162         key.dsize = 0;
163         return key;
164 }
165
166 /*
167   check special dn's have valid attributes
168   currently only @ATTRIBUTES is checked
169 */
170 int ltdb_check_special_dn(struct ldb_module *module, const struct ldb_message *msg)
171 {
172         int i, j;
173  
174         if (! ldb_dn_is_special(msg->dn) ||
175             ! ldb_dn_check_special(msg->dn, LTDB_ATTRIBUTES)) {
176                 return 0;
177         }
178
179         /* we have @ATTRIBUTES, let's check attributes are fine */
180         /* should we check that we deny multivalued attributes ? */
181         for (i = 0; i < msg->num_elements; i++) {
182                 for (j = 0; j < msg->elements[i].num_values; j++) {
183                         if (ltdb_check_at_attributes_values(&msg->elements[i].values[j]) != 0) {
184                                 ldb_set_errstring(module->ldb, "Invalid attribute value in an @ATTRIBUTES entry");
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 static int ltdb_add_internal(struct ldb_module *module, const struct ldb_message *msg)
257 {
258         int ret;
259         
260         ret = ltdb_check_special_dn(module, msg);
261         if (ret != LDB_SUCCESS) {
262                 return ret;
263         }
264         
265         if (ltdb_cache_load(module) != 0) {
266                 return LDB_ERR_OPERATIONS_ERROR;
267         }
268
269         ret = ltdb_store(module, msg, TDB_INSERT);
270
271         if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) {
272                 char *dn;
273
274                 dn = ldb_dn_linearize(module, msg->dn);
275                 if (!dn) {
276                         return ret;
277                 }
278                 ldb_asprintf_errstring(module->ldb, "Entry %s already exists", dn);
279                 talloc_free(dn);
280                 return ret;
281         }
282         
283         if (ret == LDB_SUCCESS) {
284                 ret = ltdb_modified(module, msg->dn);
285                 if (ret != LDB_SUCCESS) {
286                         return LDB_ERR_OPERATIONS_ERROR;
287                 }
288         }
289
290         return ret;
291 }
292
293 /*
294   add a record to the database
295 */
296 static int ltdb_add(struct ldb_module *module, struct ldb_request *req)
297 {
298         struct ltdb_private *ltdb = talloc_get_type(module->private_data, struct ltdb_private);
299         struct ltdb_context *ltdb_ac;
300         int tret, ret = LDB_SUCCESS;
301
302         if (req->controls != NULL) {
303                 ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Controls should not reach the ldb_tdb backend!\n");
304                 if (check_critical_controls(req->controls)) {
305                         return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
306                 }
307         }
308         
309         req->handle = init_ltdb_handle(ltdb, module, req->context, req->callback);
310         if (req->handle == NULL) {
311                 return LDB_ERR_OPERATIONS_ERROR;
312         }
313         ltdb_ac = talloc_get_type(req->handle->private_data, struct ltdb_context);
314
315         tret = ltdb_add_internal(module, req->op.add.message);
316         if (tret != LDB_SUCCESS) {
317                 req->handle->status = tret;
318                 goto done;
319         }
320         
321         if (ltdb_ac->callback) {
322                 ret = ltdb_ac->callback(module->ldb, ltdb_ac->context, NULL);
323         }
324 done:
325         req->handle->state = LDB_ASYNC_DONE;
326         return ret;
327 }
328
329 /*
330   delete a record from the database, not updating indexes (used for deleting
331   index records)
332 */
333 int ltdb_delete_noindex(struct ldb_module *module, const struct ldb_dn *dn)
334 {
335         struct ltdb_private *ltdb = module->private_data;
336         TDB_DATA tdb_key;
337         int ret;
338
339         tdb_key = ltdb_key(module, dn);
340         if (!tdb_key.dptr) {
341                 return LDB_ERR_OTHER;
342         }
343
344         ret = tdb_delete(ltdb->tdb, tdb_key);
345         talloc_free(tdb_key.dptr);
346
347         if (ret != 0) {
348                 ret = ltdb_err_map(tdb_error(ltdb->tdb));
349         }
350
351         return ret;
352 }
353
354 static int ltdb_delete_internal(struct ldb_module *module, const struct ldb_dn *dn)
355 {
356         struct ldb_message *msg;
357         int ret;
358
359         msg = talloc(module, struct ldb_message);
360         if (msg == NULL) {
361                 return LDB_ERR_OPERATIONS_ERROR;
362         }
363
364         /* in case any attribute of the message was indexed, we need
365            to fetch the old record */
366         ret = ltdb_search_dn1(module, dn, msg);
367         if (ret != 1) {
368                 /* not finding the old record is an error */
369                 talloc_free(msg);
370                 return LDB_ERR_NO_SUCH_OBJECT;
371         }
372
373         ret = ltdb_delete_noindex(module, dn);
374         if (ret != LDB_SUCCESS) {
375                 talloc_free(msg);
376                 return LDB_ERR_NO_SUCH_OBJECT;
377         }
378
379         /* remove any indexed attributes */
380         ret = ltdb_index_del(module, msg);
381         if (ret != LDB_SUCCESS) {
382                 talloc_free(msg);
383                 return LDB_ERR_OPERATIONS_ERROR;
384         }
385
386         ret = ltdb_modified(module, dn);
387         if (ret != LDB_SUCCESS) {
388                 return LDB_ERR_OPERATIONS_ERROR;
389         }
390
391         talloc_free(msg);
392         return LDB_SUCCESS;
393 }
394
395 /*
396   delete a record from the database
397 */
398 static int ltdb_delete(struct ldb_module *module, struct ldb_request *req)
399 {
400         struct ltdb_private *ltdb = talloc_get_type(module->private_data, struct ltdb_private);
401         struct ltdb_context *ltdb_ac;
402         int tret, ret = LDB_SUCCESS;
403
404         if (req->controls != NULL) {
405                 ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Controls should not reach the ldb_tdb backend!\n");
406                 if (check_critical_controls(req->controls)) {
407                         return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
408                 }
409         }
410         
411         req->handle = NULL;
412
413         if (ltdb_cache_load(module) != 0) {
414                 return LDB_ERR_OPERATIONS_ERROR;
415         }
416
417         req->handle = init_ltdb_handle(ltdb, module, req->context, req->callback);
418         if (req->handle == NULL) {
419                 return LDB_ERR_OPERATIONS_ERROR;
420         }
421         ltdb_ac = talloc_get_type(req->handle->private_data, struct ltdb_context);
422
423         tret = ltdb_delete_internal(module, req->op.del.dn);
424         if (tret != LDB_SUCCESS) {
425                 req->handle->status = tret; 
426                 goto done;
427         }
428
429         if (ltdb_ac->callback) {
430                 ret = ltdb_ac->callback(module->ldb, ltdb_ac->context, NULL);
431         }
432 done:
433         req->handle->state = LDB_ASYNC_DONE;
434         return ret;
435 }
436
437 /*
438   find an element by attribute name. At the moment this does a linear search, it should
439   be re-coded to use a binary search once all places that modify records guarantee
440   sorted order
441
442   return the index of the first matching element if found, otherwise -1
443 */
444 static int find_element(const struct ldb_message *msg, const char *name)
445 {
446         unsigned int i;
447         for (i=0;i<msg->num_elements;i++) {
448                 if (ldb_attr_cmp(msg->elements[i].name, name) == 0) {
449                         return i;
450                 }
451         }
452         return -1;
453 }
454
455
456 /*
457   add an element to an existing record. Assumes a elements array that we
458   can call re-alloc on, and assumed that we can re-use the data pointers from the 
459   passed in additional values. Use with care!
460
461   returns 0 on success, -1 on failure (and sets errno)
462 */
463 static int msg_add_element(struct ldb_context *ldb,
464                            struct ldb_message *msg, struct ldb_message_element *el)
465 {
466         struct ldb_message_element *e2;
467         unsigned int i;
468
469         e2 = talloc_realloc(msg, msg->elements, struct ldb_message_element, 
470                               msg->num_elements+1);
471         if (!e2) {
472                 errno = ENOMEM;
473                 return -1;
474         }
475
476         msg->elements = e2;
477
478         e2 = &msg->elements[msg->num_elements];
479
480         e2->name = el->name;
481         e2->flags = el->flags;
482         e2->values = NULL;
483         if (el->num_values != 0) {
484                 e2->values = talloc_array(msg->elements, struct ldb_val, el->num_values);
485                 if (!e2->values) {
486                         errno = ENOMEM;
487                         return -1;
488                 }
489         }
490         for (i=0;i<el->num_values;i++) {
491                 e2->values[i] = el->values[i];
492         }
493         e2->num_values = el->num_values;
494
495         msg->num_elements++;
496
497         return 0;
498 }
499
500 /*
501   delete all elements having a specified attribute name
502 */
503 static int msg_delete_attribute(struct ldb_module *module,
504                                 struct ldb_context *ldb,
505                                 struct ldb_message *msg, const char *name)
506 {
507         char *dn;
508         unsigned int i, j;
509
510         dn = ldb_dn_linearize(ldb, msg->dn);
511         if (dn == NULL) {
512                 return -1;
513         }
514
515         for (i=0;i<msg->num_elements;i++) {
516                 if (ldb_attr_cmp(msg->elements[i].name, name) == 0) {
517                         for (j=0;j<msg->elements[i].num_values;j++) {
518                                 ltdb_index_del_value(module, dn, &msg->elements[i], j);
519                         }
520                         talloc_free(msg->elements[i].values);
521                         if (msg->num_elements > (i+1)) {
522                                 memmove(&msg->elements[i], 
523                                         &msg->elements[i+1], 
524                                         sizeof(struct ldb_message_element)*
525                                         (msg->num_elements - (i+1)));
526                         }
527                         msg->num_elements--;
528                         i--;
529                         msg->elements = talloc_realloc(msg, msg->elements, 
530                                                          struct ldb_message_element, 
531                                                          msg->num_elements);
532                 }
533         }
534
535         talloc_free(dn);
536         return 0;
537 }
538
539 /*
540   delete all elements matching an attribute name/value 
541
542   return 0 on success, -1 on failure
543 */
544 static int msg_delete_element(struct ldb_module *module,
545                               struct ldb_message *msg, 
546                               const char *name,
547                               const struct ldb_val *val)
548 {
549         struct ldb_context *ldb = module->ldb;
550         unsigned int i;
551         int found;
552         struct ldb_message_element *el;
553         const struct ldb_attrib_handler *h;
554
555         found = find_element(msg, name);
556         if (found == -1) {
557                 return -1;
558         }
559
560         el = &msg->elements[found];
561
562         h = ldb_attrib_handler(ldb, el->name);
563
564         for (i=0;i<el->num_values;i++) {
565                 if (h->comparison_fn(ldb, ldb, &el->values[i], val) == 0) {
566                         if (i<el->num_values-1) {
567                                 memmove(&el->values[i], &el->values[i+1],
568                                         sizeof(el->values[i])*(el->num_values-(i+1)));
569                         }
570                         el->num_values--;
571                         if (el->num_values == 0) {
572                                 return msg_delete_attribute(module, ldb, msg, name);
573                         }
574                         return 0;
575                 }
576         }
577
578         return -1;
579 }
580
581
582 /*
583   modify a record - internal interface
584
585   yuck - this is O(n^2). Luckily n is usually small so we probably
586   get away with it, but if we ever have really large attribute lists 
587   then we'll need to look at this again
588 */
589 int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *msg)
590 {
591         struct ldb_context *ldb = module->ldb;
592         struct ltdb_private *ltdb = module->private_data;
593         TDB_DATA tdb_key, tdb_data;
594         struct ldb_message *msg2;
595         unsigned i, j;
596         int ret;
597
598         tdb_key = ltdb_key(module, msg->dn);
599         if (!tdb_key.dptr) {
600                 return LDB_ERR_OTHER;
601         }
602
603         tdb_data = tdb_fetch(ltdb->tdb, tdb_key);
604         if (!tdb_data.dptr) {
605                 talloc_free(tdb_key.dptr);
606                 return ltdb_err_map(tdb_error(ltdb->tdb));
607         }
608
609         msg2 = talloc(tdb_key.dptr, struct ldb_message);
610         if (msg2 == NULL) {
611                 talloc_free(tdb_key.dptr);
612                 return LDB_ERR_OTHER;
613         }
614
615         ret = ltdb_unpack_data(module, &tdb_data, msg2);
616         if (ret == -1) {
617                 ret = LDB_ERR_OTHER;
618                 goto failed;
619         }
620
621         if (!msg2->dn) {
622                 msg2->dn = msg->dn;
623         }
624
625         for (i=0;i<msg->num_elements;i++) {
626                 struct ldb_message_element *el = &msg->elements[i];
627                 struct ldb_message_element *el2;
628                 struct ldb_val *vals;
629                 char *dn;
630
631                 switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) {
632
633                 case LDB_FLAG_MOD_ADD:
634                         /* add this element to the message. fail if it
635                            already exists */
636                         ret = find_element(msg2, el->name);
637
638                         if (ret == -1) {
639                                 if (msg_add_element(ldb, msg2, el) != 0) {
640                                         ret = LDB_ERR_OTHER;
641                                         goto failed;
642                                 }
643                                 continue;
644                         }
645
646                         el2 = &msg2->elements[ret];
647
648                         /* An attribute with this name already exists, add all
649                          * values if they don't already exist. */
650
651                         for (j=0;j<el->num_values;j++) {
652                                 if (ldb_msg_find_val(el2, &el->values[j])) {
653                                         ldb_set_errstring(module->ldb, "Type or value exists");
654                                         ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
655                                         goto failed;
656                                 }
657                         }
658
659                         vals = talloc_realloc(msg2->elements, el2->values, struct ldb_val,
660                                                 el2->num_values + el->num_values);
661
662                         if (vals == NULL) {
663                                 ret = LDB_ERR_OTHER;
664                                 goto failed;
665                         }
666
667                         for (j=0;j<el->num_values;j++) {
668                                 vals[el2->num_values + j] =
669                                         ldb_val_dup(vals, &el->values[j]);
670                         }
671
672                         el2->values = vals;
673                         el2->num_values += el->num_values;
674
675                         break;
676
677                 case LDB_FLAG_MOD_REPLACE:
678                         /* replace all elements of this attribute name with the elements
679                            listed. The attribute not existing is not an error */
680                         msg_delete_attribute(module, ldb, msg2, msg->elements[i].name);
681
682                         /* add the replacement element, if not empty */
683                         if (msg->elements[i].num_values != 0 &&
684                             msg_add_element(ldb, msg2, &msg->elements[i]) != 0) {
685                                 ret = LDB_ERR_OTHER;
686                                 goto failed;
687                         }
688                         break;
689
690                 case LDB_FLAG_MOD_DELETE:
691
692                         dn = ldb_dn_linearize(msg2, msg->dn);
693                         if (dn == NULL) {
694                                 ret = LDB_ERR_OTHER;
695                                 goto failed;
696                         }
697
698                         /* we could be being asked to delete all
699                            values or just some values */
700                         if (msg->elements[i].num_values == 0) {
701                                 if (msg_delete_attribute(module, ldb, msg2, 
702                                                          msg->elements[i].name) != 0) {
703                                         ldb_asprintf_errstring(module->ldb, "No such attribute: %s for delete on %s", msg->elements[i].name, dn);
704                                         ret = LDB_ERR_NO_SUCH_ATTRIBUTE;
705                                         goto failed;
706                                 }
707                                 break;
708                         }
709                         for (j=0;j<msg->elements[i].num_values;j++) {
710                                 if (msg_delete_element(module,
711                                                        msg2, 
712                                                        msg->elements[i].name,
713                                                        &msg->elements[i].values[j]) != 0) {
714                                         ldb_asprintf_errstring(module->ldb, "No matching attribute value when deleting attribute: %s on %s", msg->elements[i].name, dn);
715                                         ret = LDB_ERR_NO_SUCH_ATTRIBUTE;
716                                         goto failed;
717                                 }
718                                 if (ltdb_index_del_value(module, dn, &msg->elements[i], j) != 0) {
719                                         ret = LDB_ERR_OTHER;
720                                         goto failed;
721                                 }
722                         }
723                         break;
724                 default:
725                         ldb_asprintf_errstring(module->ldb, "Invalid ldb_modify flags on %s: 0x%x", 
726                                                              msg->elements[i].name, 
727                                                              msg->elements[i].flags & LDB_FLAG_MOD_MASK);
728                         ret = LDB_ERR_PROTOCOL_ERROR;
729                         goto failed;
730                 }
731         }
732
733         /* we've made all the mods - save the modified record back into the database */
734         ret = ltdb_store(module, msg2, TDB_MODIFY);
735         if (ret != LDB_SUCCESS) {
736                 goto failed;
737         }
738
739         if (ltdb_modified(module, msg->dn) != LDB_SUCCESS) {
740                 ret = LDB_ERR_OPERATIONS_ERROR;
741                 goto failed;
742         }
743
744         talloc_free(tdb_key.dptr);
745         free(tdb_data.dptr);
746         return ret;
747
748 failed:
749         talloc_free(tdb_key.dptr);
750         free(tdb_data.dptr);
751         return ret;
752 }
753
754 /*
755   modify a record
756 */
757 static int ltdb_modify(struct ldb_module *module, struct ldb_request *req)
758 {
759         struct ltdb_private *ltdb = talloc_get_type(module->private_data, struct ltdb_private);
760         struct ltdb_context *ltdb_ac;
761         int tret, ret = LDB_SUCCESS;
762
763         if (req->controls != NULL) {
764                 ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Controls should not reach the ldb_tdb backend!\n");
765                 if (check_critical_controls(req->controls)) {
766                         return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
767                 }
768         }
769         
770         req->handle = NULL;
771
772         req->handle = init_ltdb_handle(ltdb, module, req->context, req->callback);
773         if (req->handle == NULL) {
774                 return LDB_ERR_OPERATIONS_ERROR;
775         }
776         ltdb_ac = talloc_get_type(req->handle->private_data, struct ltdb_context);
777
778         tret = ltdb_check_special_dn(module, req->op.mod.message);
779         if (tret != LDB_SUCCESS) {
780                 req->handle->status = tret;
781                 goto done;
782         }
783         
784         if (ltdb_cache_load(module) != 0) {
785                 ret = LDB_ERR_OPERATIONS_ERROR;
786                 goto done;
787         }
788
789         tret = ltdb_modify_internal(module, req->op.mod.message);
790         if (tret != LDB_SUCCESS) {
791                 req->handle->status = tret;
792                 goto done;
793         }
794
795         if (ltdb_ac->callback) {
796                 ret = ltdb_ac->callback(module->ldb, ltdb_ac->context, NULL);
797         }
798 done:
799         req->handle->state = LDB_ASYNC_DONE;
800         return ret;
801 }
802
803 /*
804   rename a record
805 */
806 static int ltdb_rename(struct ldb_module *module, struct ldb_request *req)
807 {
808         struct ltdb_private *ltdb = talloc_get_type(module->private_data, struct ltdb_private);
809         struct ltdb_context *ltdb_ac;
810         struct ldb_message *msg;
811         int tret, ret = LDB_SUCCESS;
812
813         if (req->controls != NULL) {
814                 ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Controls should not reach the ldb_tdb backend!\n");
815                 if (check_critical_controls(req->controls)) {
816                         return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
817                 }
818         }
819         
820         req->handle = NULL;
821
822         if (ltdb_cache_load(module) != 0) {
823                 return LDB_ERR_OPERATIONS_ERROR;
824         }
825
826         req->handle = init_ltdb_handle(ltdb, module, req->context, req->callback);
827         if (req->handle == NULL) {
828                 return LDB_ERR_OPERATIONS_ERROR;
829         }
830         ltdb_ac = talloc_get_type(req->handle->private_data, struct ltdb_context);
831
832         msg = talloc(ltdb_ac, struct ldb_message);
833         if (msg == NULL) {
834                 ret = LDB_ERR_OPERATIONS_ERROR;
835                 goto done;
836         }
837
838         /* in case any attribute of the message was indexed, we need
839            to fetch the old record */
840         tret = ltdb_search_dn1(module, req->op.rename.olddn, msg);
841         if (tret != 1) {
842                 /* not finding the old record is an error */
843                 req->handle->status = LDB_ERR_NO_SUCH_OBJECT;
844                 goto done;
845         }
846
847         msg->dn = ldb_dn_copy(msg, req->op.rename.newdn);
848         if (!msg->dn) {
849                 ret = LDB_ERR_OPERATIONS_ERROR;
850                 goto done;
851         }
852
853         tret = ltdb_add_internal(module, msg);
854         if (tret != LDB_SUCCESS) {
855                 ret = LDB_ERR_OPERATIONS_ERROR;
856                 goto done;
857         }
858
859         tret = ltdb_delete_internal(module, req->op.rename.olddn);
860         if (tret != LDB_SUCCESS) {
861                 ltdb_delete_internal(module, req->op.rename.newdn);
862                 ret = LDB_ERR_OPERATIONS_ERROR;
863                 goto done;
864         }
865
866         if (ltdb_ac->callback) {
867                 ret = ltdb_ac->callback(module->ldb, ltdb_ac->context, NULL);
868         }
869 done:
870         req->handle->state = LDB_ASYNC_DONE;
871         return ret;
872 }
873
874 static int ltdb_start_trans(struct ldb_module *module)
875 {
876         struct ltdb_private *ltdb = module->private_data;
877
878         if (tdb_transaction_start(ltdb->tdb) != 0) {
879                 return ltdb_err_map(tdb_error(ltdb->tdb));
880         }
881
882         return LDB_SUCCESS;
883 }
884
885 static int ltdb_end_trans(struct ldb_module *module)
886 {
887         struct ltdb_private *ltdb = module->private_data;
888
889         if (tdb_transaction_commit(ltdb->tdb) != 0) {
890                 return ltdb_err_map(tdb_error(ltdb->tdb));
891         }
892
893         return LDB_SUCCESS;
894 }
895
896 static int ltdb_del_trans(struct ldb_module *module)
897 {
898         struct ltdb_private *ltdb = module->private_data;
899
900         if (tdb_transaction_cancel(ltdb->tdb) != 0) {
901                 return ltdb_err_map(tdb_error(ltdb->tdb));
902         }
903
904         return LDB_SUCCESS;
905 }
906
907 static int ltdb_wait(struct ldb_handle *handle, enum ldb_wait_type type)
908 {
909         return handle->status;
910 }
911
912 static int ltdb_request(struct ldb_module *module, struct ldb_request *req)
913 {
914         /* check for oustanding critical controls and return an error if found */
915         if (req->controls != NULL) {
916                 ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Controls should not reach the ldb_tdb backend!\n");
917                 if (check_critical_controls(req->controls)) {
918                         return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
919                 }
920         }
921         
922         /* search, add, modify, delete, rename are handled by their own, no other op supported */
923         return LDB_ERR_OPERATIONS_ERROR;
924 }
925
926 /*
927   return sequenceNumber from @BASEINFO
928 */
929 static int ltdb_sequence_number(struct ldb_module *module, struct ldb_request *req)
930 {
931         TALLOC_CTX *tmp_ctx = talloc_new(req);
932         struct ldb_message *msg = NULL;
933         struct ldb_dn *dn = ldb_dn_explode(tmp_ctx, LTDB_BASEINFO);
934         int tret;
935
936         if (tmp_ctx == NULL) {
937                 talloc_free(tmp_ctx);
938                 return LDB_ERR_OPERATIONS_ERROR;
939         }
940
941         msg = talloc(tmp_ctx, struct ldb_message);
942         if (msg == NULL) {
943                 talloc_free(tmp_ctx);
944                 return LDB_ERR_OPERATIONS_ERROR;
945         }
946
947         req->op.seq_num.flags = 0;
948
949         tret = ltdb_search_dn1(module, dn, msg);
950         if (tret != 1) {
951                 talloc_free(tmp_ctx);
952                 req->op.seq_num.seq_num = 0;
953                 /* zero is as good as anything when we don't know */
954                 return LDB_SUCCESS;
955         }
956
957         switch (req->op.seq_num.type) {
958         case LDB_SEQ_HIGHEST_SEQ:
959                 req->op.seq_num.seq_num = ldb_msg_find_attr_as_uint64(msg, LTDB_SEQUENCE_NUMBER, 0);
960                 break;
961         case LDB_SEQ_NEXT:
962                 req->op.seq_num.seq_num = ldb_msg_find_attr_as_uint64(msg, LTDB_SEQUENCE_NUMBER, 0);
963                 req->op.seq_num.seq_num++;
964                 break;
965         case LDB_SEQ_HIGHEST_TIMESTAMP:
966         {
967                 const char *date = ldb_msg_find_attr_as_string(msg, LTDB_MOD_TIMESTAMP, NULL);
968                 if (date) {
969                         req->op.seq_num.seq_num = ldb_string_to_time(date);
970                 } else {
971                         req->op.seq_num.seq_num = 0;
972                         /* zero is as good as anything when we don't know */
973                 }
974                 break;
975         }
976         }
977         talloc_free(tmp_ctx);
978         return LDB_SUCCESS;
979 }
980
981 static const struct ldb_module_ops ltdb_ops = {
982         .name              = "tdb",
983         .search            = ltdb_search,
984         .add               = ltdb_add,
985         .modify            = ltdb_modify,
986         .del               = ltdb_delete,
987         .rename            = ltdb_rename,
988         .request           = ltdb_request,
989         .start_transaction = ltdb_start_trans,
990         .end_transaction   = ltdb_end_trans,
991         .del_transaction   = ltdb_del_trans,
992         .wait              = ltdb_wait,
993         .sequence_number   = ltdb_sequence_number
994 };
995
996 /*
997   connect to the database
998 */
999 static int ltdb_connect(struct ldb_context *ldb, const char *url, 
1000                         unsigned int flags, const char *options[],
1001                         struct ldb_module **module)
1002 {
1003         const char *path;
1004         int tdb_flags, open_flags;
1005         struct ltdb_private *ltdb;
1006
1007         /* parse the url */
1008         if (strchr(url, ':')) {
1009                 if (strncmp(url, "tdb://", 6) != 0) {
1010                         ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid tdb URL '%s'", url);
1011                         return -1;
1012                 }
1013                 path = url+6;
1014         } else {
1015                 path = url;
1016         }
1017
1018         tdb_flags = TDB_DEFAULT;
1019
1020         /* check for the 'nosync' option */
1021         if (flags & LDB_FLG_NOSYNC) {
1022                 tdb_flags |= TDB_NOSYNC;
1023         }
1024
1025         if (flags & LDB_FLG_RDONLY) {
1026                 open_flags = O_RDONLY;
1027         } else {
1028                 open_flags = O_CREAT | O_RDWR;
1029         }
1030
1031         ltdb = talloc_zero(ldb, struct ltdb_private);
1032         if (!ltdb) {
1033                 ldb_oom(ldb);
1034                 return -1;
1035         }
1036
1037         /* note that we use quite a large default hash size */
1038         ltdb->tdb = ltdb_wrap_open(ltdb, path, 10000, 
1039                                    tdb_flags, open_flags, 
1040                                    ldb->create_perms, ldb);
1041         if (!ltdb->tdb) {
1042                 ldb_debug(ldb, LDB_DEBUG_ERROR, "Unable to open tdb '%s'\n", path);
1043                 talloc_free(ltdb);
1044                 return -1;
1045         }
1046
1047         ltdb->sequence_number = 0;
1048
1049         *module = talloc(ldb, struct ldb_module);
1050         if (!module) {
1051                 ldb_oom(ldb);
1052                 talloc_free(ltdb);
1053                 return -1;
1054         }
1055         (*module)->ldb = ldb;
1056         (*module)->prev = (*module)->next = NULL;
1057         (*module)->private_data = ltdb;
1058         (*module)->ops = &ltdb_ops;
1059
1060         return 0;
1061 }
1062
1063 int ldb_tdb_init(void)
1064 {
1065         return ldb_register_backend("tdb", ltdb_connect);
1066 }