r20865: remove useless warning, we now always pass the current partition
[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                                     struct ldb_request *req)
83 {
84         struct ltdb_context *ac;
85         struct ldb_handle *h;
86
87         h = talloc_zero(req, struct ldb_handle);
88         if (h == NULL) {
89                 ldb_set_errstring(module->ldb, "Out of Memory");
90                 return NULL;
91         }
92
93         h->module = module;
94
95         ac = talloc_zero(h, struct ltdb_context);
96         if (ac == NULL) {
97                 ldb_set_errstring(module->ldb, "Out of Memory");
98                 talloc_free(h);
99                 return NULL;
100         }
101
102         h->private_data = (void *)ac;
103
104         h->state = LDB_ASYNC_INIT;
105         h->status = LDB_SUCCESS;
106
107         ac->module = module;
108         ac->context = req->context;
109         ac->callback = req->callback;
110
111         return h;
112 }
113
114 /*
115   form a TDB_DATA for a record key
116   caller frees
117
118   note that the key for a record can depend on whether the 
119   dn refers to a case sensitive index record or not
120 */
121 struct TDB_DATA ltdb_key(struct ldb_module *module, struct ldb_dn *dn)
122 {
123         struct ldb_context *ldb = module->ldb;
124         TDB_DATA key;
125         char *key_str = NULL;
126         const char *dn_folded = NULL;
127
128         /*
129           most DNs are case insensitive. The exception is index DNs for
130           case sensitive attributes
131
132           there are 3 cases dealt with in this code:
133
134           1) if the dn doesn't start with @ then uppercase the attribute
135              names and the attributes values of case insensitive attributes
136           2) if the dn starts with @ then leave it alone - the indexing code handles
137              the rest
138         */
139
140         dn_folded = ldb_dn_get_casefold(dn);
141         if (!dn_folded) {
142                 goto failed;
143         }
144
145         key_str = talloc_strdup(ldb, "DN=");
146         if (!key_str) {
147                 goto failed;
148         }
149
150         key_str = talloc_append_string(ldb, key_str, dn_folded);
151         if (!key_str) {
152                 goto failed;
153         }
154
155         key.dptr = (uint8_t *)key_str;
156         key.dsize = strlen(key_str) + 1;
157
158         return key;
159
160 failed:
161         errno = ENOMEM;
162         key.dptr = NULL;
163         key.dsize = 0;
164         return key;
165 }
166
167 /*
168   check special dn's have valid attributes
169   currently only @ATTRIBUTES is checked
170 */
171 int ltdb_check_special_dn(struct ldb_module *module, const struct ldb_message *msg)
172 {
173         int i, j;
174  
175         if (! ldb_dn_is_special(msg->dn) ||
176             ! ldb_dn_check_special(msg->dn, LTDB_ATTRIBUTES)) {
177                 return 0;
178         }
179
180         /* we have @ATTRIBUTES, let's check attributes are fine */
181         /* should we check that we deny multivalued attributes ? */
182         for (i = 0; i < msg->num_elements; i++) {
183                 for (j = 0; j < msg->elements[i].num_values; j++) {
184                         if (ltdb_check_at_attributes_values(&msg->elements[i].values[j]) != 0) {
185                                 ldb_set_errstring(module->ldb, "Invalid attribute value in an @ATTRIBUTES entry");
186                                 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
187                         }
188                 }
189         }
190
191         return 0;
192 }
193
194
195 /*
196   we've made a modification to a dn - possibly reindex and 
197   update sequence number
198 */
199 static int ltdb_modified(struct ldb_module *module, struct ldb_dn *dn)
200 {
201         int ret = 0;
202
203         if (ldb_dn_is_special(dn) &&
204             (ldb_dn_check_special(dn, LTDB_INDEXLIST) ||
205              ldb_dn_check_special(dn, LTDB_ATTRIBUTES)) ) {
206                 ret = ltdb_reindex(module);
207         }
208
209         if (ret == 0 &&
210             !(ldb_dn_is_special(dn) &&
211               ldb_dn_check_special(dn, LTDB_BASEINFO)) ) {
212                 ret = ltdb_increase_sequence_number(module);
213         }
214
215         return ret;
216 }
217
218 /*
219   store a record into the db
220 */
221 int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flgs)
222 {
223         struct ltdb_private *ltdb =
224                 talloc_get_type(module->private_data, struct ltdb_private);
225         TDB_DATA tdb_key, tdb_data;
226         int ret;
227
228         tdb_key = ltdb_key(module, msg->dn);
229         if (!tdb_key.dptr) {
230                 return LDB_ERR_OTHER;
231         }
232
233         ret = ltdb_pack_data(module, msg, &tdb_data);
234         if (ret == -1) {
235                 talloc_free(tdb_key.dptr);
236                 return LDB_ERR_OTHER;
237         }
238
239         ret = tdb_store(ltdb->tdb, tdb_key, tdb_data, flgs);
240         if (ret == -1) {
241                 ret = ltdb_err_map(tdb_error(ltdb->tdb));
242                 goto done;
243         }
244         
245         ret = ltdb_index_add(module, msg);
246         if (ret == -1) {
247                 tdb_delete(ltdb->tdb, tdb_key);
248         }
249
250 done:
251         talloc_free(tdb_key.dptr);
252         talloc_free(tdb_data.dptr);
253
254         return ret;
255 }
256
257
258 static int ltdb_add_internal(struct ldb_module *module, const struct ldb_message *msg)
259 {
260         int ret;
261         
262         ret = ltdb_check_special_dn(module, msg);
263         if (ret != LDB_SUCCESS) {
264                 return ret;
265         }
266         
267         if (ltdb_cache_load(module) != 0) {
268                 return LDB_ERR_OPERATIONS_ERROR;
269         }
270
271         ret = ltdb_store(module, msg, TDB_INSERT);
272
273         if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) {
274                 ldb_asprintf_errstring(module->ldb, "Entry %s already exists", ldb_dn_get_linearized(msg->dn));
275                 return ret;
276         }
277         
278         if (ret == LDB_SUCCESS) {
279                 ret = ltdb_index_one(module, msg, 1);
280                 if (ret != LDB_SUCCESS) {
281                         return LDB_ERR_OPERATIONS_ERROR;
282                 }
283
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 (check_critical_controls(req->controls)) {
303                 return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
304         }
305         
306         req->handle = init_ltdb_handle(ltdb, module, req);
307         if (req->handle == NULL) {
308                 return LDB_ERR_OPERATIONS_ERROR;
309         }
310         ltdb_ac = talloc_get_type(req->handle->private_data, struct ltdb_context);
311
312         tret = ltdb_add_internal(module, req->op.add.message);
313         if (tret != LDB_SUCCESS) {
314                 req->handle->status = tret;
315                 goto done;
316         }
317         
318         if (ltdb_ac->callback) {
319                 ret = ltdb_ac->callback(module->ldb, ltdb_ac->context, NULL);
320         }
321 done:
322         req->handle->state = LDB_ASYNC_DONE;
323         return ret;
324 }
325
326 /*
327   delete a record from the database, not updating indexes (used for deleting
328   index records)
329 */
330 int ltdb_delete_noindex(struct ldb_module *module, struct ldb_dn *dn)
331 {
332         struct ltdb_private *ltdb =
333                 talloc_get_type(module->private_data, struct ltdb_private);
334         TDB_DATA tdb_key;
335         int ret;
336
337         tdb_key = ltdb_key(module, dn);
338         if (!tdb_key.dptr) {
339                 return LDB_ERR_OTHER;
340         }
341
342         ret = tdb_delete(ltdb->tdb, tdb_key);
343         talloc_free(tdb_key.dptr);
344
345         if (ret != 0) {
346                 ret = ltdb_err_map(tdb_error(ltdb->tdb));
347         }
348
349         return ret;
350 }
351
352 static int ltdb_delete_internal(struct ldb_module *module, struct ldb_dn *dn)
353 {
354         struct ldb_message *msg;
355         int ret;
356
357         msg = talloc(module, struct ldb_message);
358         if (msg == NULL) {
359                 return LDB_ERR_OPERATIONS_ERROR;
360         }
361
362         /* in case any attribute of the message was indexed, we need
363            to fetch the old record */
364         ret = ltdb_search_dn1(module, dn, msg);
365         if (ret != 1) {
366                 /* not finding the old record is an error */
367                 talloc_free(msg);
368                 return LDB_ERR_NO_SUCH_OBJECT;
369         }
370
371         ret = ltdb_delete_noindex(module, dn);
372         if (ret != LDB_SUCCESS) {
373                 talloc_free(msg);
374                 return LDB_ERR_NO_SUCH_OBJECT;
375         }
376
377         /* remove one level attribute */
378         ret = ltdb_index_one(module, msg, 0);
379         if (ret != LDB_SUCCESS) {
380                 talloc_free(msg);
381                 return LDB_ERR_OPERATIONS_ERROR;
382         }
383
384         /* remove any indexed attributes */
385         ret = ltdb_index_del(module, msg);
386         if (ret != LDB_SUCCESS) {
387                 talloc_free(msg);
388                 return LDB_ERR_OPERATIONS_ERROR;
389         }
390
391         ret = ltdb_modified(module, dn);
392         if (ret != LDB_SUCCESS) {
393                 talloc_free(msg);
394                 return LDB_ERR_OPERATIONS_ERROR;
395         }
396
397         talloc_free(msg);
398         return LDB_SUCCESS;
399 }
400
401 /*
402   delete a record from the database
403 */
404 static int ltdb_delete(struct ldb_module *module, struct ldb_request *req)
405 {
406         struct ltdb_private *ltdb = talloc_get_type(module->private_data, struct ltdb_private);
407         struct ltdb_context *ltdb_ac;
408         int tret, ret = LDB_SUCCESS;
409
410         if (check_critical_controls(req->controls)) {
411                 return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
412         }
413         
414         req->handle = NULL;
415
416         if (ltdb_cache_load(module) != 0) {
417                 return LDB_ERR_OPERATIONS_ERROR;
418         }
419
420         req->handle = init_ltdb_handle(ltdb, module, req);
421         if (req->handle == NULL) {
422                 return LDB_ERR_OPERATIONS_ERROR;
423         }
424         ltdb_ac = talloc_get_type(req->handle->private_data, struct ltdb_context);
425
426         tret = ltdb_delete_internal(module, req->op.del.dn);
427         if (tret != LDB_SUCCESS) {
428                 req->handle->status = tret; 
429                 goto done;
430         }
431
432         if (ltdb_ac->callback) {
433                 ret = ltdb_ac->callback(module->ldb, ltdb_ac->context, NULL);
434         }
435 done:
436         req->handle->state = LDB_ASYNC_DONE;
437         return ret;
438 }
439
440 /*
441   find an element by attribute name. At the moment this does a linear search, it should
442   be re-coded to use a binary search once all places that modify records guarantee
443   sorted order
444
445   return the index of the first matching element if found, otherwise -1
446 */
447 static int find_element(const struct ldb_message *msg, const char *name)
448 {
449         unsigned int i;
450         for (i=0;i<msg->num_elements;i++) {
451                 if (ldb_attr_cmp(msg->elements[i].name, name) == 0) {
452                         return i;
453                 }
454         }
455         return -1;
456 }
457
458
459 /*
460   add an element to an existing record. Assumes a elements array that we
461   can call re-alloc on, and assumed that we can re-use the data pointers from the 
462   passed in additional values. Use with care!
463
464   returns 0 on success, -1 on failure (and sets errno)
465 */
466 static int msg_add_element(struct ldb_context *ldb,
467                            struct ldb_message *msg, struct ldb_message_element *el)
468 {
469         struct ldb_message_element *e2;
470         unsigned int i;
471
472         e2 = talloc_realloc(msg, msg->elements, struct ldb_message_element, 
473                               msg->num_elements+1);
474         if (!e2) {
475                 errno = ENOMEM;
476                 return -1;
477         }
478
479         msg->elements = e2;
480
481         e2 = &msg->elements[msg->num_elements];
482
483         e2->name = el->name;
484         e2->flags = el->flags;
485         e2->values = NULL;
486         if (el->num_values != 0) {
487                 e2->values = talloc_array(msg->elements, struct ldb_val, el->num_values);
488                 if (!e2->values) {
489                         errno = ENOMEM;
490                         return -1;
491                 }
492         }
493         for (i=0;i<el->num_values;i++) {
494                 e2->values[i] = el->values[i];
495         }
496         e2->num_values = el->num_values;
497
498         msg->num_elements++;
499
500         return 0;
501 }
502
503 /*
504   delete all elements having a specified attribute name
505 */
506 static int msg_delete_attribute(struct ldb_module *module,
507                                 struct ldb_context *ldb,
508                                 struct ldb_message *msg, const char *name)
509 {
510         const char *dn;
511         unsigned int i, j;
512
513         dn = ldb_dn_get_linearized(msg->dn);
514         if (dn == NULL) {
515                 return -1;
516         }
517
518         for (i=0;i<msg->num_elements;i++) {
519                 if (ldb_attr_cmp(msg->elements[i].name, name) == 0) {
520                         for (j=0;j<msg->elements[i].num_values;j++) {
521                                 ltdb_index_del_value(module, dn, &msg->elements[i], j);
522                         }
523                         talloc_free(msg->elements[i].values);
524                         if (msg->num_elements > (i+1)) {
525                                 memmove(&msg->elements[i], 
526                                         &msg->elements[i+1], 
527                                         sizeof(struct ldb_message_element)*
528                                         (msg->num_elements - (i+1)));
529                         }
530                         msg->num_elements--;
531                         i--;
532                         msg->elements = talloc_realloc(msg, msg->elements, 
533                                                          struct ldb_message_element, 
534                                                          msg->num_elements);
535                 }
536         }
537
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_schema_attribute *a;
556
557         found = find_element(msg, name);
558         if (found == -1) {
559                 return -1;
560         }
561
562         el = &msg->elements[found];
563
564         a = ldb_schema_attribute_by_name(ldb, el->name);
565
566         for (i=0;i<el->num_values;i++) {
567                 if (a->syntax->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                 const 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_get_linearized(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 (check_critical_controls(req->controls)) {
767                 return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
768         }
769         
770         req->handle = NULL;
771
772         req->handle = init_ltdb_handle(ltdb, module, req);
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 (check_critical_controls(req->controls)) {
814                 return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
815         }
816         
817         req->handle = NULL;
818
819         if (ltdb_cache_load(module) != 0) {
820                 return LDB_ERR_OPERATIONS_ERROR;
821         }
822
823         req->handle = init_ltdb_handle(ltdb, module, req);
824         if (req->handle == NULL) {
825                 return LDB_ERR_OPERATIONS_ERROR;
826         }
827         ltdb_ac = talloc_get_type(req->handle->private_data, struct ltdb_context);
828
829         msg = talloc(ltdb_ac, struct ldb_message);
830         if (msg == NULL) {
831                 ret = LDB_ERR_OPERATIONS_ERROR;
832                 goto done;
833         }
834
835         /* in case any attribute of the message was indexed, we need
836            to fetch the old record */
837         tret = ltdb_search_dn1(module, req->op.rename.olddn, msg);
838         if (tret != 1) {
839                 /* not finding the old record is an error */
840                 req->handle->status = LDB_ERR_NO_SUCH_OBJECT;
841                 goto done;
842         }
843
844         msg->dn = ldb_dn_copy(msg, req->op.rename.newdn);
845         if (!msg->dn) {
846                 ret = LDB_ERR_OPERATIONS_ERROR;
847                 goto done;
848         }
849
850         tret = ltdb_add_internal(module, msg);
851         if (tret != LDB_SUCCESS) {
852                 ret = LDB_ERR_OPERATIONS_ERROR;
853                 goto done;
854         }
855
856         tret = ltdb_delete_internal(module, req->op.rename.olddn);
857         if (tret != LDB_SUCCESS) {
858                 ltdb_delete_internal(module, req->op.rename.newdn);
859                 ret = LDB_ERR_OPERATIONS_ERROR;
860                 goto done;
861         }
862
863         if (ltdb_ac->callback) {
864                 ret = ltdb_ac->callback(module->ldb, ltdb_ac->context, NULL);
865         }
866 done:
867         req->handle->state = LDB_ASYNC_DONE;
868         return ret;
869 }
870
871 static int ltdb_start_trans(struct ldb_module *module)
872 {
873         struct ltdb_private *ltdb =
874                 talloc_get_type(module->private_data, struct ltdb_private);
875
876         if (tdb_transaction_start(ltdb->tdb) != 0) {
877                 return ltdb_err_map(tdb_error(ltdb->tdb));
878         }
879
880         return LDB_SUCCESS;
881 }
882
883 static int ltdb_end_trans(struct ldb_module *module)
884 {
885         struct ltdb_private *ltdb =
886                 talloc_get_type(module->private_data, struct ltdb_private);
887
888         if (tdb_transaction_commit(ltdb->tdb) != 0) {
889                 return ltdb_err_map(tdb_error(ltdb->tdb));
890         }
891
892         return LDB_SUCCESS;
893 }
894
895 static int ltdb_del_trans(struct ldb_module *module)
896 {
897         struct ltdb_private *ltdb =
898                 talloc_get_type(module->private_data, struct ltdb_private);
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 (check_critical_controls(req->controls)) {
916                 return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
917         }
918         
919         /* search, add, modify, delete, rename are handled by their own, no other op supported */
920         return LDB_ERR_OPERATIONS_ERROR;
921 }
922
923 /*
924   return sequenceNumber from @BASEINFO
925 */
926 static int ltdb_sequence_number(struct ldb_module *module, struct ldb_request *req)
927 {
928         TALLOC_CTX *tmp_ctx = talloc_new(req);
929         struct ldb_message *msg = NULL;
930         struct ldb_dn *dn = ldb_dn_new(tmp_ctx, module->ldb, LTDB_BASEINFO);
931         int tret;
932
933         if (tmp_ctx == NULL) {
934                 talloc_free(tmp_ctx);
935                 return LDB_ERR_OPERATIONS_ERROR;
936         }
937
938         msg = talloc(tmp_ctx, struct ldb_message);
939         if (msg == NULL) {
940                 talloc_free(tmp_ctx);
941                 return LDB_ERR_OPERATIONS_ERROR;
942         }
943
944         req->op.seq_num.flags = 0;
945
946         tret = ltdb_search_dn1(module, dn, msg);
947         if (tret != 1) {
948                 talloc_free(tmp_ctx);
949                 req->op.seq_num.seq_num = 0;
950                 /* zero is as good as anything when we don't know */
951                 return LDB_SUCCESS;
952         }
953
954         switch (req->op.seq_num.type) {
955         case LDB_SEQ_HIGHEST_SEQ:
956                 req->op.seq_num.seq_num = ldb_msg_find_attr_as_uint64(msg, LTDB_SEQUENCE_NUMBER, 0);
957                 break;
958         case LDB_SEQ_NEXT:
959                 req->op.seq_num.seq_num = ldb_msg_find_attr_as_uint64(msg, LTDB_SEQUENCE_NUMBER, 0);
960                 req->op.seq_num.seq_num++;
961                 break;
962         case LDB_SEQ_HIGHEST_TIMESTAMP:
963         {
964                 const char *date = ldb_msg_find_attr_as_string(msg, LTDB_MOD_TIMESTAMP, NULL);
965                 if (date) {
966                         req->op.seq_num.seq_num = ldb_string_to_time(date);
967                 } else {
968                         req->op.seq_num.seq_num = 0;
969                         /* zero is as good as anything when we don't know */
970                 }
971                 break;
972         }
973         }
974         talloc_free(tmp_ctx);
975         return LDB_SUCCESS;
976 }
977
978 static const struct ldb_module_ops ltdb_ops = {
979         .name              = "tdb",
980         .search            = ltdb_search,
981         .add               = ltdb_add,
982         .modify            = ltdb_modify,
983         .del               = ltdb_delete,
984         .rename            = ltdb_rename,
985         .request           = ltdb_request,
986         .start_transaction = ltdb_start_trans,
987         .end_transaction   = ltdb_end_trans,
988         .del_transaction   = ltdb_del_trans,
989         .wait              = ltdb_wait,
990         .sequence_number   = ltdb_sequence_number
991 };
992
993 /*
994   connect to the database
995 */
996 static int ltdb_connect(struct ldb_context *ldb, const char *url, 
997                         unsigned int flags, const char *options[],
998                         struct ldb_module **module)
999 {
1000         const char *path;
1001         int tdb_flags, open_flags;
1002         struct ltdb_private *ltdb;
1003
1004         /* parse the url */
1005         if (strchr(url, ':')) {
1006                 if (strncmp(url, "tdb://", 6) != 0) {
1007                         ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid tdb URL '%s'", url);
1008                         return -1;
1009                 }
1010                 path = url+6;
1011         } else {
1012                 path = url;
1013         }
1014
1015         tdb_flags = TDB_DEFAULT | TDB_SEQNUM;
1016
1017         /* check for the 'nosync' option */
1018         if (flags & LDB_FLG_NOSYNC) {
1019                 tdb_flags |= TDB_NOSYNC;
1020         }
1021
1022         if (flags & LDB_FLG_RDONLY) {
1023                 open_flags = O_RDONLY;
1024         } else {
1025                 open_flags = O_CREAT | O_RDWR;
1026         }
1027
1028         ltdb = talloc_zero(ldb, struct ltdb_private);
1029         if (!ltdb) {
1030                 ldb_oom(ldb);
1031                 return -1;
1032         }
1033
1034         /* note that we use quite a large default hash size */
1035         ltdb->tdb = ltdb_wrap_open(ltdb, path, 10000, 
1036                                    tdb_flags, open_flags, 
1037                                    ldb->create_perms, ldb);
1038         if (!ltdb->tdb) {
1039                 ldb_debug(ldb, LDB_DEBUG_ERROR, "Unable to open tdb '%s'\n", path);
1040                 talloc_free(ltdb);
1041                 return -1;
1042         }
1043
1044         ltdb->sequence_number = 0;
1045
1046         *module = talloc(ldb, struct ldb_module);
1047         if (!module) {
1048                 ldb_oom(ldb);
1049                 talloc_free(ltdb);
1050                 return -1;
1051         }
1052         talloc_set_name_const(*module, "ldb_tdb backend");
1053         (*module)->ldb = ldb;
1054         (*module)->prev = (*module)->next = NULL;
1055         (*module)->private_data = ltdb;
1056         (*module)->ops = &ltdb_ops;
1057
1058         if (ltdb_cache_load(*module) != 0) {
1059                 talloc_free(*module);
1060                 talloc_free(ltdb);
1061                 return -1;
1062         }
1063
1064         return 0;
1065 }
1066
1067 int ldb_tdb_init(void)
1068 {
1069         return ldb_register_backend("tdb", ltdb_connect);
1070 }