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