r6867: this code will change the way the @ATTRIBUTES object is handled
[abartlet/samba.git/.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    
7
8      ** NOTE! The following LGPL license applies to the ldb
9      ** library. This does NOT imply that all of Samba is released
10      ** under the LGPL
11    
12    This library is free software; you can redistribute it and/or
13    modify it under the terms of the GNU Lesser General Public
14    License as published by the Free Software Foundation; either
15    version 2 of the License, or (at your option) any later version.
16
17    This library is distributed in the hope that it will be useful,
18    but WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20    Lesser General Public License for more details.
21
22    You should have received a copy of the GNU Lesser General Public
23    License along with this library; if not, write to the Free Software
24    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25 */
26
27 /*
28  *  Name: ldb
29  *
30  *  Component: ldb tdb backend
31  *
32  *  Description: core functions for tdb backend
33  *
34  *  Author: Andrew Tridgell
35  *  Author: Stefan Metzmacher
36  */
37
38 #include "includes.h"
39 #include "ldb/include/ldb.h"
40 #include "ldb/include/ldb_private.h"
41 #include "ldb/ldb_tdb/ldb_tdb.h"
42
43 #define LDBLOCK "INT_LDBLOCK"
44
45
46 /*
47   casefold a dn. We need to uppercase the attribute names, and the 
48   attribute values of case insensitive attributes. We also need to remove
49   extraneous spaces between elements
50 */
51 static char *ltdb_dn_fold(struct ldb_module *module, const char *dn)
52 {
53         const char *dn_orig = dn;
54         struct ldb_context *ldb = module->ldb;
55         TALLOC_CTX *tmp_ctx = talloc_new(ldb);
56         char *ret;
57         size_t len;
58
59         ret = talloc_strdup(tmp_ctx, "");
60         if (ret == NULL) goto failed;
61
62         while ((len = strcspn(dn, ",")) > 0) {
63                 char *p = strchr(dn, '=');
64                 char *attr, *value;
65                 int flags;
66
67                 if (p == NULL || (p-dn) > len) goto failed;
68
69                 attr = talloc_strndup(tmp_ctx, dn, p-dn);
70                 if (attr == NULL) goto failed;
71
72                 /* trim spaces from the attribute name */
73                 while (' ' == *attr) attr++;
74                 while (' ' == attr[strlen(attr)-1]) {
75                         attr[strlen(attr)-1] = 0;
76                 }
77                 if (*attr == 0) goto failed;
78
79                 value = talloc_strndup(tmp_ctx, p+1, len-(p+1-dn));
80                 if (value == NULL) goto failed;
81
82                 /* trim spaces from the value */
83                 while (' ' == *value) value++;
84                 while (' ' == value[strlen(value)-1]) {
85                         value[strlen(value)-1] = 0;
86                 }
87                 if (*value == 0) goto failed;
88
89                 flags = ltdb_attribute_flags(module, attr);
90
91                 attr = ldb_casefold(ldb, attr);
92                 if (attr == NULL) goto failed;
93                 talloc_steal(tmp_ctx, attr);
94
95                 if (flags & LTDB_FLAG_CASE_INSENSITIVE) {
96                         value = ldb_casefold(ldb, value);
97                         if (value == NULL) goto failed;
98                         talloc_steal(tmp_ctx, value);
99                 }               
100
101                 if (dn[len] == ',') {
102                         ret = talloc_asprintf_append(ret, "%s=%s,", attr, value);
103                 } else {
104                         ret = talloc_asprintf_append(ret, "%s=%s", attr, value);
105                 }
106                 if (ret == NULL) goto failed;
107
108                 dn += len;
109                 if (*dn == ',') dn++;
110         }
111
112         talloc_steal(ldb, ret);
113         talloc_free(tmp_ctx);
114         return ret;
115
116 failed:
117         talloc_free(tmp_ctx);
118         return ldb_casefold(ldb, dn_orig);
119 }
120
121 /*
122   form a TDB_DATA for a record key
123   caller frees
124
125   note that the key for a record can depend on whether the 
126   dn refers to a case sensitive index record or not
127 */
128 struct TDB_DATA ltdb_key(struct ldb_module *module, const char *dn)
129 {
130         struct ldb_context *ldb = module->ldb;
131         TDB_DATA key;
132         char *key_str = NULL;
133         char *dn_folded = NULL;
134         const char *prefix = LTDB_INDEX ":";
135         const char *s;
136         int flags;
137
138         /*
139           most DNs are case insensitive. The exception is index DNs for
140           case sensitive attributes
141
142           there are 3 cases dealt with in this code:
143
144           1) if the dn doesn't start with @INDEX: then uppercase the attribute
145              names and the attributes values of case insensitive attributes
146           2) if the dn starts with @INDEX:attr and 'attr' is a case insensitive
147              attribute then uppercase whole dn
148           3) if the dn starts with @INDEX:attr and 'attr' is a case sensitive
149              attribute then uppercase up to the value of the attribute, but 
150              not the value itself
151         */
152         if (strncmp(dn, prefix, strlen(prefix)) == 0 &&
153             (s = strchr(dn+strlen(prefix), ':'))) {
154                 char *attr_name, *attr_name_folded;
155                 attr_name = talloc_strndup(ldb, dn+strlen(prefix), (s-(dn+strlen(prefix))));
156                 if (!attr_name) {
157                         goto failed;
158                 }
159                 flags = ltdb_attribute_flags(module, attr_name);
160                 
161                 if (flags & LTDB_FLAG_CASE_INSENSITIVE) {
162                         dn_folded = ldb_casefold(ldb, dn);
163                 } else {
164                         attr_name_folded = ldb_casefold(ldb, attr_name);
165                         if (!attr_name_folded) {
166                                 goto failed;
167                         }
168                         dn_folded = talloc_asprintf(ldb, "%s:%s:%s",
169                                                     prefix, attr_name_folded,
170                                                     s+1);
171                         talloc_free(attr_name_folded);
172                 }
173                 talloc_free(attr_name);
174         } else {
175                 dn_folded = ltdb_dn_fold(module, dn);
176         }
177
178         if (!dn_folded) {
179                 goto failed;
180         }
181
182         key_str = talloc_asprintf(ldb, "DN=%s", dn_folded);
183         talloc_free(dn_folded);
184
185         if (!key_str) {
186                 goto failed;
187         }
188
189         key.dptr = key_str;
190         key.dsize = strlen(key_str)+1;
191
192         return key;
193
194 failed:
195         errno = ENOMEM;
196         key.dptr = NULL;
197         key.dsize = 0;
198         return key;
199 }
200
201 /*
202   lock the database for write - currently a single lock is used
203 */
204 static int ltdb_lock(struct ldb_module *module, const char *lockname)
205 {
206         struct ltdb_private *ltdb = module->private_data;
207         TDB_DATA key;
208         int ret;
209
210         if (lockname == NULL) {
211                 return -1;
212         }
213
214         key = ltdb_key(module, lockname);
215         if (!key.dptr) {
216                 return -1;
217         }
218
219         ret = tdb_chainlock(ltdb->tdb, key);
220
221         talloc_free(key.dptr);
222
223         return ret;
224 }
225
226 /*
227   unlock the database after a ltdb_lock()
228 */
229 static int ltdb_unlock(struct ldb_module *module, const char *lockname)
230 {
231         struct ltdb_private *ltdb = module->private_data;
232         TDB_DATA key;
233
234         if (lockname == NULL) {
235                 return -1;
236         }
237
238         key = ltdb_key(module, lockname);
239         if (!key.dptr) {
240                 return -1;
241         }
242
243         tdb_chainunlock(ltdb->tdb, key);
244
245         talloc_free(key.dptr);
246
247         return 0;
248 }
249
250
251 /*
252   lock the database for read - use by ltdb_search
253 */
254 int ltdb_lock_read(struct ldb_module *module)
255 {
256         struct ltdb_private *ltdb = module->private_data;
257         TDB_DATA key;
258         int ret;
259         key = ltdb_key(module, LDBLOCK);
260         if (!key.dptr) {
261                 return -1;
262         }
263         ret = tdb_chainlock_read(ltdb->tdb, key);
264         talloc_free(key.dptr);
265         return ret;
266 }
267
268 /*
269   unlock the database after a ltdb_lock_read()
270 */
271 int ltdb_unlock_read(struct ldb_module *module)
272 {
273         struct ltdb_private *ltdb = module->private_data;
274         TDB_DATA key;
275         key = ltdb_key(module, LDBLOCK);
276         if (!key.dptr) {
277                 return -1;
278         }
279         tdb_chainunlock_read(ltdb->tdb, key);
280         talloc_free(key.dptr);
281         return 0;
282 }
283
284 /*
285   check special dn's have valid attributes
286   currently only @ATTRIBUTES is checked
287 */
288 int ltdb_check_special_dn(struct ldb_module *module, const struct ldb_message *msg)
289 {
290         struct ltdb_private *ltdb = module->private_data;
291         int i, j;
292
293         if (strcmp(msg->dn, LTDB_ATTRIBUTES) != 0) {
294                 return 0;
295         }
296
297         /* we have @ATTRIBUTES, let's check attributes are fine */
298         /* should we check that we deny multivalued attributes ? */
299         for (i = 0; i < msg->num_elements; i++) {
300                 for (j = 0; j < msg->elements[i].num_values; j++) {
301                         if (ltdb_check_at_attributes_values(&msg->elements[i].values[j]) != 0) {
302                                 ltdb->last_err_string = "Invalid attribute value in an @ATTRIBUTES entry";
303                                 return -1;
304                         }
305                 }
306         }
307
308         return 0;
309 }
310
311
312 /*
313   we've made a modification to a dn - possibly reindex and 
314   update sequence number
315 */
316 static int ltdb_modified(struct ldb_module *module, const char *dn)
317 {
318         int ret = 0;
319
320         if (strcmp(dn, LTDB_INDEXLIST) == 0 ||
321             strcmp(dn, LTDB_ATTRIBUTES) == 0) {
322                 ret = ltdb_reindex(module);
323         }
324
325         if (ret == 0 &&
326             strcmp(dn, LTDB_BASEINFO) != 0) {
327                 ret = ltdb_increase_sequence_number(module);
328         }
329
330         return ret;
331 }
332
333 /*
334   store a record into the db
335 */
336 int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flgs)
337 {
338         struct ltdb_private *ltdb = module->private_data;
339         TDB_DATA tdb_key, tdb_data;
340         int ret;
341
342         tdb_key = ltdb_key(module, msg->dn);
343         if (!tdb_key.dptr) {
344                 return -1;
345         }
346
347         ret = ltdb_pack_data(module, msg, &tdb_data);
348         if (ret == -1) {
349                 talloc_free(tdb_key.dptr);
350                 return -1;
351         }
352
353         ret = tdb_store(ltdb->tdb, tdb_key, tdb_data, flgs);
354         if (ret == -1) {
355                 goto done;
356         }
357         
358         ret = ltdb_index_add(module, msg);
359         if (ret == -1) {
360                 tdb_delete(ltdb->tdb, tdb_key);
361         }
362
363 done:
364         talloc_free(tdb_key.dptr);
365         talloc_free(tdb_data.dptr);
366
367         return ret;
368 }
369
370
371 /*
372   add a record to the database
373 */
374 static int ltdb_add(struct ldb_module *module, const struct ldb_message *msg)
375 {
376         struct ltdb_private *ltdb = module->private_data;
377         int ret;
378
379         ltdb->last_err_string = NULL;
380
381         ret = ltdb_check_special_dn(module, msg);
382         if (ret != 0) {
383                 return ret;
384         }
385         
386         if (ltdb_lock(module, LDBLOCK) != 0) {
387                 return -1;
388         }
389
390         if (ltdb_cache_load(module) != 0) {
391                 ltdb_unlock(module, LDBLOCK);
392                 return -1;
393         }
394
395         ret = ltdb_store(module, msg, TDB_INSERT);
396
397         if (ret == 0) {
398                 ltdb_modified(module, msg->dn);
399         }
400
401         ltdb_unlock(module, LDBLOCK);
402         return ret;
403 }
404
405
406 /*
407   delete a record from the database, not updating indexes (used for deleting
408   index records)
409 */
410 int ltdb_delete_noindex(struct ldb_module *module, const char *dn)
411 {
412         struct ltdb_private *ltdb = module->private_data;
413         TDB_DATA tdb_key;
414         int ret;
415
416         tdb_key = ltdb_key(module, dn);
417         if (!tdb_key.dptr) {
418                 return -1;
419         }
420
421         ret = tdb_delete(ltdb->tdb, tdb_key);
422         talloc_free(tdb_key.dptr);
423
424         return ret;
425 }
426
427 /*
428   delete a record from the database
429 */
430 static int ltdb_delete(struct ldb_module *module, const char *dn)
431 {
432         struct ltdb_private *ltdb = module->private_data;
433         int ret;
434         struct ldb_message *msg = NULL;
435
436         ltdb->last_err_string = NULL;
437
438         if (ltdb_lock(module, LDBLOCK) != 0) {
439                 return -1;
440         }
441
442         if (ltdb_cache_load(module) != 0) {
443                 goto failed;
444         }
445
446         msg = talloc(module, struct ldb_message);
447         if (msg == NULL) {
448                 goto failed;
449         }
450
451         /* in case any attribute of the message was indexed, we need
452            to fetch the old record */
453         ret = ltdb_search_dn1(module, dn, msg);
454         if (ret != 1) {
455                 /* not finding the old record is an error */
456                 goto failed;
457         }
458
459         ret = ltdb_delete_noindex(module, dn);
460         if (ret == -1) {
461                 goto failed;
462         }
463
464         /* remove any indexed attributes */
465         ret = ltdb_index_del(module, msg);
466
467         if (ret == 0) {
468                 ltdb_modified(module, dn);
469         }
470
471         talloc_free(msg);
472         ltdb_unlock(module, LDBLOCK);
473         return ret;
474
475 failed:
476         talloc_free(msg);
477         ltdb_unlock(module, LDBLOCK);
478         return -1;
479 }
480
481
482 /*
483   find an element by attribute name. At the moment this does a linear search, it should
484   be re-coded to use a binary search once all places that modify records guarantee
485   sorted order
486
487   return the index of the first matching element if found, otherwise -1
488 */
489 static int find_element(const struct ldb_message *msg, const char *name)
490 {
491         unsigned int i;
492         for (i=0;i<msg->num_elements;i++) {
493                 if (ldb_attr_cmp(msg->elements[i].name, name) == 0) {
494                         return i;
495                 }
496         }
497         return -1;
498 }
499
500
501 /*
502   add an element to an existing record. Assumes a elements array that we
503   can call re-alloc on, and assumed that we can re-use the data pointers from the 
504   passed in additional values. Use with care!
505
506   returns 0 on success, -1 on failure (and sets errno)
507 */
508 static int msg_add_element(struct ldb_context *ldb,
509                            struct ldb_message *msg, struct ldb_message_element *el)
510 {
511         struct ldb_message_element *e2;
512         unsigned int i;
513
514         e2 = talloc_realloc(msg, msg->elements, struct ldb_message_element, 
515                               msg->num_elements+1);
516         if (!e2) {
517                 errno = ENOMEM;
518                 return -1;
519         }
520
521         msg->elements = e2;
522
523         e2 = &msg->elements[msg->num_elements];
524
525         e2->name = el->name;
526         e2->flags = el->flags;
527         e2->values = NULL;
528         if (el->num_values != 0) {
529                 e2->values = talloc_array(msg->elements, struct ldb_val, el->num_values);
530                 if (!e2->values) {
531                         errno = ENOMEM;
532                         return -1;
533                 }
534         }
535         for (i=0;i<el->num_values;i++) {
536                 e2->values[i] = el->values[i];
537         }
538         e2->num_values = el->num_values;
539
540         msg->num_elements++;
541
542         return 0;
543 }
544
545 /*
546   delete all elements having a specified attribute name
547 */
548 static int msg_delete_attribute(struct ldb_module *module,
549                                 struct ldb_context *ldb,
550                                 struct ldb_message *msg, const char *name)
551 {
552         unsigned int i, j;
553
554         for (i=0;i<msg->num_elements;i++) {
555                 if (ldb_attr_cmp(msg->elements[i].name, name) == 0) {
556                         for (j=0;j<msg->elements[i].num_values;j++) {
557                                 ltdb_index_del_value(module, msg->dn, &msg->elements[i], j);
558                         }
559                         talloc_free(msg->elements[i].values);
560                         if (msg->num_elements > (i+1)) {
561                                 memmove(&msg->elements[i], 
562                                         &msg->elements[i+1], 
563                                         sizeof(struct ldb_message_element)*
564                                         (msg->num_elements - (i+1)));
565                         }
566                         msg->num_elements--;
567                         i--;
568                         msg->elements = talloc_realloc(msg, msg->elements, 
569                                                          struct ldb_message_element, 
570                                                          msg->num_elements);
571                 }
572         }
573
574         return 0;
575 }
576
577 /*
578   delete all elements matching an attribute name/value 
579
580   return 0 on success, -1 on failure
581 */
582 static int msg_delete_element(struct ldb_module *module,
583                               struct ldb_message *msg, 
584                               const char *name,
585                               const struct ldb_val *val)
586 {
587         struct ldb_context *ldb = module->ldb;
588         unsigned int i;
589         int found;
590         struct ldb_message_element *el;
591
592         found = find_element(msg, name);
593         if (found == -1) {
594                 return -1;
595         }
596
597         el = &msg->elements[found];
598
599         for (i=0;i<el->num_values;i++) {
600                 if (ltdb_val_equal(module, msg->elements[i].name, &el->values[i], val)) {
601                         if (i<el->num_values-1) {
602                                 memmove(&el->values[i], &el->values[i+1],
603                                         sizeof(el->values[i])*(el->num_values-(i+1)));
604                         }
605                         el->num_values--;
606                         if (el->num_values == 0) {
607                                 return msg_delete_attribute(module, ldb, msg, name);
608                         }
609                         return 0;
610                 }
611         }
612
613         return -1;
614 }
615
616
617 /*
618   modify a record - internal interface
619
620   yuck - this is O(n^2). Luckily n is usually small so we probably
621   get away with it, but if we ever have really large attribute lists 
622   then we'll need to look at this again
623 */
624 int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *msg)
625 {
626         struct ldb_context *ldb = module->ldb;
627         struct ltdb_private *ltdb = module->private_data;
628         TDB_DATA tdb_key, tdb_data;
629         struct ldb_message *msg2;
630         unsigned i, j;
631         int ret;
632
633         tdb_key = ltdb_key(module, msg->dn);
634         if (!tdb_key.dptr) {
635                 return -1;
636         }
637
638         tdb_data = tdb_fetch(ltdb->tdb, tdb_key);
639         if (!tdb_data.dptr) {
640                 talloc_free(tdb_key.dptr);
641                 return -1;
642         }
643
644         msg2 = talloc(tdb_key.dptr, struct ldb_message);
645         if (msg2 == NULL) {
646                 talloc_free(tdb_key.dptr);
647                 return -1;
648         }
649
650         ret = ltdb_unpack_data(module, &tdb_data, msg2);
651         if (ret == -1) {
652                 talloc_free(tdb_key.dptr);
653                 free(tdb_data.dptr);
654                 return -1;
655         }
656
657         if (!msg2->dn) {
658                 msg2->dn = msg->dn;
659         }
660
661         for (i=0;i<msg->num_elements;i++) {
662                 struct ldb_message_element *el = &msg->elements[i];
663                 struct ldb_message_element *el2;
664                 struct ldb_val *vals;
665
666                 switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) {
667
668                 case LDB_FLAG_MOD_ADD:
669                         /* add this element to the message. fail if it
670                            already exists */
671                         ret = find_element(msg2, el->name);
672
673                         if (ret == -1) {
674                                 if (msg_add_element(ldb, msg2, el) != 0) {
675                                         goto failed;
676                                 }
677                                 continue;
678                         }
679
680                         el2 = &msg2->elements[ret];
681
682                         /* An attribute with this name already exists, add all
683                          * values if they don't already exist. */
684
685                         for (j=0;j<el->num_values;j++) {
686                                 if (ldb_msg_find_val(el2, &el->values[j])) {
687                                         ltdb->last_err_string =
688                                                 "Type or value exists";
689                                         goto failed;
690                                 }
691                         }
692
693                         vals = talloc_realloc(msg2->elements, el2->values, struct ldb_val,
694                                                 el2->num_values + el->num_values);
695
696                         if (vals == NULL)
697                                 goto failed;
698
699                         for (j=0;j<el->num_values;j++) {
700                                 vals[el2->num_values + j] =
701                                         ldb_val_dup(vals, &el->values[j]);
702                         }
703
704                         el2->values = vals;
705                         el2->num_values += el->num_values;
706
707                         break;
708
709                 case LDB_FLAG_MOD_REPLACE:
710                         /* replace all elements of this attribute name with the elements
711                            listed. The attribute not existing is not an error */
712                         msg_delete_attribute(module, ldb, msg2, msg->elements[i].name);
713
714                         /* add the replacement element, if not empty */
715                         if (msg->elements[i].num_values != 0 &&
716                             msg_add_element(ldb, msg2, &msg->elements[i]) != 0) {
717                                 goto failed;
718                         }
719                         break;
720
721                 case LDB_FLAG_MOD_DELETE:
722                         /* we could be being asked to delete all
723                            values or just some values */
724                         if (msg->elements[i].num_values == 0) {
725                                 if (msg_delete_attribute(module, ldb, msg2, 
726                                                          msg->elements[i].name) != 0) {
727                                         ltdb->last_err_string = "No such attribute";
728                                         goto failed;
729                                 }
730                                 break;
731                         }
732                         for (j=0;j<msg->elements[i].num_values;j++) {
733                                 if (msg_delete_element(module,
734                                                        msg2, 
735                                                        msg->elements[i].name,
736                                                        &msg->elements[i].values[j]) != 0) {
737                                         ltdb->last_err_string = "No such attribute";
738                                         goto failed;
739                                 }
740                                 if (ltdb_index_del_value(module, msg->dn, &msg->elements[i], j) != 0) {
741                                         goto failed;
742                                 }
743                         }
744                         break;
745                 }
746         }
747
748         /* we've made all the mods - save the modified record back into the database */
749         ret = ltdb_store(module, msg2, TDB_MODIFY);
750
751         talloc_free(tdb_key.dptr);
752         free(tdb_data.dptr);
753         return ret;
754
755 failed:
756         talloc_free(tdb_key.dptr);
757         free(tdb_data.dptr);
758         return -1;
759 }
760
761 /*
762   modify a record
763 */
764 static int ltdb_modify(struct ldb_module *module, const struct ldb_message *msg)
765 {
766         struct ltdb_private *ltdb = module->private_data;
767         int ret;
768
769         ltdb->last_err_string = NULL;
770
771         ret = ltdb_check_special_dn(module, msg);
772         if (ret != 0) {
773                 return ret;
774         }
775         
776         if (ltdb_lock(module, LDBLOCK) != 0) {
777                 return -1;
778         }
779
780         if (ltdb_cache_load(module) != 0) {
781                 ltdb_unlock(module, LDBLOCK);
782                 return -1;
783         }
784
785         ret = ltdb_modify_internal(module, msg);
786
787         if (ret == 0) {
788                 ltdb_modified(module, msg->dn);
789         }
790
791         ltdb_unlock(module, LDBLOCK);
792
793         return ret;
794 }
795
796 /*
797   rename a record
798 */
799 static int ltdb_rename(struct ldb_module *module, const char *olddn, const char *newdn)
800 {
801         struct ltdb_private *ltdb = module->private_data;
802         int ret;
803         struct ldb_message *msg;
804         const char *error_str;
805
806         ltdb->last_err_string = NULL;
807
808         if (ltdb_lock(module, LDBLOCK) != 0) {
809                 return -1;
810         }
811
812         msg = talloc(module, struct ldb_message);
813         if (msg == NULL) {
814                 goto failed;
815         }
816
817         /* in case any attribute of the message was indexed, we need
818            to fetch the old record */
819         ret = ltdb_search_dn1(module, olddn, msg);
820         if (ret != 1) {
821                 /* not finding the old record is an error */
822                 goto failed;
823         }
824
825         msg->dn = talloc_strdup(msg, newdn);
826         if (!msg->dn) {
827                 goto failed;
828         }
829
830         ret = ltdb_add(module, msg);
831         if (ret == -1) {
832                 goto failed;
833         }
834
835         ret = ltdb_delete(module, olddn);
836         error_str = ltdb->last_err_string;
837         if (ret == -1) {
838                 ltdb_delete(module, newdn);
839         }
840
841         ltdb->last_err_string = error_str;
842
843         talloc_free(msg);
844         ltdb_unlock(module, LDBLOCK);
845
846         return ret;
847
848 failed:
849         talloc_free(msg);
850         ltdb_unlock(module, LDBLOCK);
851         return -1;
852 }
853
854
855 /*
856   return extended error information
857 */
858 static const char *ltdb_errstring(struct ldb_module *module)
859 {
860         struct ltdb_private *ltdb = module->private_data;
861         if (ltdb->last_err_string) {
862                 return ltdb->last_err_string;
863         }
864         return tdb_errorstr(ltdb->tdb);
865 }
866
867
868 static const struct ldb_module_ops ltdb_ops = {
869         "tdb",
870         ltdb_search,
871         ltdb_add,
872         ltdb_modify,
873         ltdb_delete,
874         ltdb_rename,
875         ltdb_lock,
876         ltdb_unlock,
877         ltdb_errstring
878 };
879
880
881 /*
882   destroy the ltdb context
883 */
884 static int ltdb_destructor(void *p)
885 {
886         struct ltdb_private *ltdb = p;
887         tdb_close(ltdb->tdb);
888         return 0;
889 }
890
891 /*
892   connect to the database
893 */
894 struct ldb_context *ltdb_connect(const char *url, 
895                                  unsigned int flags, 
896                                  const char *options[])
897 {
898         const char *path;
899         int tdb_flags, open_flags;
900         struct ltdb_private *ltdb;
901         TDB_CONTEXT *tdb;
902         struct ldb_context *ldb;
903
904         ldb = talloc_zero(NULL, struct ldb_context);
905         if (!ldb) {
906                 errno = ENOMEM;
907                 return NULL;
908         }
909
910         /* parse the url */
911         if (strchr(url, ':')) {
912                 if (strncmp(url, "tdb://", 6) != 0) {
913                         errno = EINVAL;
914                         talloc_free(ldb);
915                         return NULL;
916                 }
917                 path = url+6;
918         } else {
919                 path = url;
920         }
921
922         tdb_flags = TDB_DEFAULT;
923
924         if (flags & LDB_FLG_RDONLY) {
925                 open_flags = O_RDONLY;
926         } else {
927                 open_flags = O_CREAT | O_RDWR;
928         }
929
930         /* note that we use quite a large default hash size */
931         tdb = tdb_open(path, 10000, tdb_flags, open_flags, 0666);
932         if (!tdb) {
933                 talloc_free(ldb);
934                 return NULL;
935         }
936
937         ltdb = talloc_zero(ldb, struct ltdb_private);
938         if (!ltdb) {
939                 tdb_close(tdb);
940                 talloc_free(ldb);
941                 errno = ENOMEM;
942                 return NULL;
943         }
944
945         ltdb->tdb = tdb;
946         ltdb->sequence_number = 0;
947
948         talloc_set_destructor(ltdb, ltdb_destructor);
949
950         ldb->modules = talloc(ldb, struct ldb_module);
951         if (!ldb->modules) {
952                 talloc_free(ldb);
953                 errno = ENOMEM;
954                 return NULL;
955         }
956         ldb->modules->ldb = ldb;
957         ldb->modules->prev = ldb->modules->next = NULL;
958         ldb->modules->private_data = ltdb;
959         ldb->modules->ops = &ltdb_ops;
960
961         return ldb;
962 }