r11958: - fixed memory leaks in the ldb_result handling in ldb operations
[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_errors.h"
41 #include "ldb/include/ldb_private.h"
42 #include "ldb/ldb_tdb/ldb_tdb.h"
43
44
45 /*
46   map a tdb error code to a ldb error code
47 */
48 static int ltdb_err_map(enum TDB_ERROR tdb_code)
49 {
50         switch (tdb_code) {
51         case TDB_SUCCESS:
52                 return LDB_SUCCESS;
53         case TDB_ERR_CORRUPT:
54         case TDB_ERR_OOM:
55         case TDB_ERR_EINVAL:
56                 return LDB_ERR_OPERATIONS_ERROR;
57         case TDB_ERR_IO:
58                 return LDB_ERR_PROTOCOL_ERROR;
59         case TDB_ERR_LOCK:
60         case TDB_ERR_NOLOCK:
61                 return LDB_ERR_BUSY;
62         case TDB_ERR_LOCK_TIMEOUT:
63                 return LDB_ERR_TIME_LIMIT_EXCEEDED;
64         case TDB_ERR_EXISTS:
65                 return LDB_ERR_ENTRY_ALREADY_EXISTS;
66         case TDB_ERR_NOEXIST:
67                 return LDB_ERR_NO_SUCH_OBJECT;
68         case TDB_ERR_RDONLY:
69                 return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
70         }
71         return LDB_ERR_OTHER;
72 }
73
74
75 /*
76   form a TDB_DATA for a record key
77   caller frees
78
79   note that the key for a record can depend on whether the 
80   dn refers to a case sensitive index record or not
81 */
82 struct TDB_DATA ltdb_key(struct ldb_module *module, const struct ldb_dn *dn)
83 {
84         struct ldb_context *ldb = module->ldb;
85         TDB_DATA key;
86         char *key_str = NULL;
87         char *dn_folded = NULL;
88
89         /*
90           most DNs are case insensitive. The exception is index DNs for
91           case sensitive attributes
92
93           there are 3 cases dealt with in this code:
94
95           1) if the dn doesn't start with @ then uppercase the attribute
96              names and the attributes values of case insensitive attributes
97           2) if the dn starts with @ then leave it alone - the indexing code handles
98              the rest
99         */
100
101         dn_folded = ldb_dn_linearize_casefold(ldb, dn);
102         if (!dn_folded) {
103                 goto failed;
104         }
105
106         key_str = talloc_asprintf(ldb, "DN=%s", dn_folded);
107
108         talloc_free(dn_folded);
109
110         if (!key_str) {
111                 goto failed;
112         }
113
114         key.dptr = (uint8_t *)key_str;
115         key.dsize = strlen(key_str) + 1;
116
117         return key;
118
119 failed:
120         errno = ENOMEM;
121         key.dptr = NULL;
122         key.dsize = 0;
123         return key;
124 }
125
126 /*
127   check special dn's have valid attributes
128   currently only @ATTRIBUTES is checked
129 */
130 int ltdb_check_special_dn(struct ldb_module *module, const struct ldb_message *msg)
131 {
132         int i, j;
133  
134         if (! ldb_dn_is_special(msg->dn) ||
135             ! ldb_dn_check_special(msg->dn, LTDB_ATTRIBUTES)) {
136                 return 0;
137         }
138
139         /* we have @ATTRIBUTES, let's check attributes are fine */
140         /* should we check that we deny multivalued attributes ? */
141         for (i = 0; i < msg->num_elements; i++) {
142                 for (j = 0; j < msg->elements[i].num_values; j++) {
143                         if (ltdb_check_at_attributes_values(&msg->elements[i].values[j]) != 0) {
144                                 char *err_string = talloc_strdup(module, "Invalid attribute value in an @ATTRIBUTES entry");
145                                 if (err_string) {
146                                         ldb_set_errstring(module, err_string);
147                                 }
148                                 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
149                         }
150                 }
151         }
152
153         return 0;
154 }
155
156
157 /*
158   we've made a modification to a dn - possibly reindex and 
159   update sequence number
160 */
161 static int ltdb_modified(struct ldb_module *module, const struct ldb_dn *dn)
162 {
163         int ret = 0;
164
165         if (ldb_dn_is_special(dn) &&
166             (ldb_dn_check_special(dn, LTDB_INDEXLIST) ||
167              ldb_dn_check_special(dn, LTDB_ATTRIBUTES)) ) {
168                 ret = ltdb_reindex(module);
169         }
170
171         if (ret == 0 &&
172             !(ldb_dn_is_special(dn) &&
173               ldb_dn_check_special(dn, LTDB_BASEINFO)) ) {
174                 ret = ltdb_increase_sequence_number(module);
175         }
176
177         return ret;
178 }
179
180 /*
181   store a record into the db
182 */
183 int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flgs)
184 {
185         struct ltdb_private *ltdb = module->private_data;
186         TDB_DATA tdb_key, tdb_data;
187         int ret;
188
189         tdb_key = ltdb_key(module, msg->dn);
190         if (!tdb_key.dptr) {
191                 return LDB_ERR_OTHER;
192         }
193
194         ret = ltdb_pack_data(module, msg, &tdb_data);
195         if (ret == -1) {
196                 talloc_free(tdb_key.dptr);
197                 return LDB_ERR_OTHER;
198         }
199
200         ret = tdb_store(ltdb->tdb, tdb_key, tdb_data, flgs);
201         if (ret == -1) {
202                 ret = ltdb_err_map(tdb_error(ltdb->tdb));
203                 goto done;
204         }
205         
206         ret = ltdb_index_add(module, msg);
207         if (ret == -1) {
208                 tdb_delete(ltdb->tdb, tdb_key);
209         }
210
211 done:
212         talloc_free(tdb_key.dptr);
213         talloc_free(tdb_data.dptr);
214
215         return ret;
216 }
217
218
219 /*
220   add a record to the database
221 */
222 static int ltdb_add(struct ldb_module *module, const struct ldb_message *msg)
223 {
224         int ret;
225
226         ret = ltdb_check_special_dn(module, msg);
227         if (ret != LDB_SUCCESS) {
228                 return ret;
229         }
230         
231         if (ltdb_cache_load(module) != 0) {
232                 return LDB_ERR_OTHER;
233         }
234
235         ret = ltdb_store(module, msg, TDB_INSERT);
236
237         if (ret == LDB_SUCCESS) {
238                 ltdb_modified(module, msg->dn);
239         }
240
241         return ret;
242 }
243
244
245 /*
246   delete a record from the database, not updating indexes (used for deleting
247   index records)
248 */
249 int ltdb_delete_noindex(struct ldb_module *module, const struct ldb_dn *dn)
250 {
251         struct ltdb_private *ltdb = module->private_data;
252         TDB_DATA tdb_key;
253         int ret;
254
255         tdb_key = ltdb_key(module, dn);
256         if (!tdb_key.dptr) {
257                 return LDB_ERR_OTHER;
258         }
259
260         ret = tdb_delete(ltdb->tdb, tdb_key);
261         talloc_free(tdb_key.dptr);
262
263         if (ret != 0) {
264                 ret = ltdb_err_map(tdb_error(ltdb->tdb));
265         }
266
267         return ret;
268 }
269
270 /*
271   delete a record from the database
272 */
273 static int ltdb_delete(struct ldb_module *module, const struct ldb_dn *dn)
274 {
275         struct ldb_message *msg = NULL;
276         int ret = LDB_ERR_OTHER;
277
278         if (ltdb_cache_load(module) != 0) {
279                 goto failed;
280         }
281
282         msg = talloc(module, struct ldb_message);
283         if (msg == NULL) {
284                 goto failed;
285         }
286
287         /* in case any attribute of the message was indexed, we need
288            to fetch the old record */
289         ret = ltdb_search_dn1(module, dn, msg);
290         if (ret != 1) {
291                 /* not finding the old record is an error */
292                 ret = LDB_ERR_NO_SUCH_OBJECT;
293                 goto failed;
294         }
295
296         ret = ltdb_delete_noindex(module, dn);
297         if (ret != LDB_SUCCESS) {
298                 goto failed;
299         }
300
301         /* remove any indexed attributes */
302         ret = ltdb_index_del(module, msg);
303         if (ret == LDB_SUCCESS) {
304                 ltdb_modified(module, dn);
305         } else
306                 ret = LDB_ERR_OTHER;
307
308         talloc_free(msg);
309         return ret;
310
311 failed:
312         talloc_free(msg);
313         return ret;
314 }
315
316
317 /*
318   find an element by attribute name. At the moment this does a linear search, it should
319   be re-coded to use a binary search once all places that modify records guarantee
320   sorted order
321
322   return the index of the first matching element if found, otherwise -1
323 */
324 static int find_element(const struct ldb_message *msg, const char *name)
325 {
326         unsigned int i;
327         for (i=0;i<msg->num_elements;i++) {
328                 if (ldb_attr_cmp(msg->elements[i].name, name) == 0) {
329                         return i;
330                 }
331         }
332         return -1;
333 }
334
335
336 /*
337   add an element to an existing record. Assumes a elements array that we
338   can call re-alloc on, and assumed that we can re-use the data pointers from the 
339   passed in additional values. Use with care!
340
341   returns 0 on success, -1 on failure (and sets errno)
342 */
343 static int msg_add_element(struct ldb_context *ldb,
344                            struct ldb_message *msg, struct ldb_message_element *el)
345 {
346         struct ldb_message_element *e2;
347         unsigned int i;
348
349         e2 = talloc_realloc(msg, msg->elements, struct ldb_message_element, 
350                               msg->num_elements+1);
351         if (!e2) {
352                 errno = ENOMEM;
353                 return -1;
354         }
355
356         msg->elements = e2;
357
358         e2 = &msg->elements[msg->num_elements];
359
360         e2->name = el->name;
361         e2->flags = el->flags;
362         e2->values = NULL;
363         if (el->num_values != 0) {
364                 e2->values = talloc_array(msg->elements, struct ldb_val, el->num_values);
365                 if (!e2->values) {
366                         errno = ENOMEM;
367                         return -1;
368                 }
369         }
370         for (i=0;i<el->num_values;i++) {
371                 e2->values[i] = el->values[i];
372         }
373         e2->num_values = el->num_values;
374
375         msg->num_elements++;
376
377         return 0;
378 }
379
380 /*
381   delete all elements having a specified attribute name
382 */
383 static int msg_delete_attribute(struct ldb_module *module,
384                                 struct ldb_context *ldb,
385                                 struct ldb_message *msg, const char *name)
386 {
387         char *dn;
388         unsigned int i, j;
389
390         dn = ldb_dn_linearize(ldb, msg->dn);
391         if (dn == NULL) {
392                 return -1;
393         }
394
395         for (i=0;i<msg->num_elements;i++) {
396                 if (ldb_attr_cmp(msg->elements[i].name, name) == 0) {
397                         for (j=0;j<msg->elements[i].num_values;j++) {
398                                 ltdb_index_del_value(module, dn, &msg->elements[i], j);
399                         }
400                         talloc_free(msg->elements[i].values);
401                         if (msg->num_elements > (i+1)) {
402                                 memmove(&msg->elements[i], 
403                                         &msg->elements[i+1], 
404                                         sizeof(struct ldb_message_element)*
405                                         (msg->num_elements - (i+1)));
406                         }
407                         msg->num_elements--;
408                         i--;
409                         msg->elements = talloc_realloc(msg, msg->elements, 
410                                                          struct ldb_message_element, 
411                                                          msg->num_elements);
412                 }
413         }
414
415         talloc_free(dn);
416         return 0;
417 }
418
419 /*
420   delete all elements matching an attribute name/value 
421
422   return 0 on success, -1 on failure
423 */
424 static int msg_delete_element(struct ldb_module *module,
425                               struct ldb_message *msg, 
426                               const char *name,
427                               const struct ldb_val *val)
428 {
429         struct ldb_context *ldb = module->ldb;
430         unsigned int i;
431         int found;
432         struct ldb_message_element *el;
433         const struct ldb_attrib_handler *h;
434
435         found = find_element(msg, name);
436         if (found == -1) {
437                 return -1;
438         }
439
440         el = &msg->elements[found];
441
442         h = ldb_attrib_handler(ldb, el->name);
443
444         for (i=0;i<el->num_values;i++) {
445                 if (h->comparison_fn(ldb, ldb, &el->values[i], val) == 0) {
446                         if (i<el->num_values-1) {
447                                 memmove(&el->values[i], &el->values[i+1],
448                                         sizeof(el->values[i])*(el->num_values-(i+1)));
449                         }
450                         el->num_values--;
451                         if (el->num_values == 0) {
452                                 return msg_delete_attribute(module, ldb, msg, name);
453                         }
454                         return 0;
455                 }
456         }
457
458         return -1;
459 }
460
461
462 /*
463   modify a record - internal interface
464
465   yuck - this is O(n^2). Luckily n is usually small so we probably
466   get away with it, but if we ever have really large attribute lists 
467   then we'll need to look at this again
468 */
469 int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *msg)
470 {
471         struct ldb_context *ldb = module->ldb;
472         struct ltdb_private *ltdb = module->private_data;
473         TDB_DATA tdb_key, tdb_data;
474         struct ldb_message *msg2;
475         unsigned i, j;
476         int ret;
477
478         tdb_key = ltdb_key(module, msg->dn);
479         if (!tdb_key.dptr) {
480                 return LDB_ERR_OTHER;
481         }
482
483         tdb_data = tdb_fetch(ltdb->tdb, tdb_key);
484         if (!tdb_data.dptr) {
485                 talloc_free(tdb_key.dptr);
486                 return ltdb_err_map(tdb_error(ltdb->tdb));
487         }
488
489         msg2 = talloc(tdb_key.dptr, struct ldb_message);
490         if (msg2 == NULL) {
491                 talloc_free(tdb_key.dptr);
492                 return LDB_ERR_OTHER;
493         }
494
495         ret = ltdb_unpack_data(module, &tdb_data, msg2);
496         if (ret == -1) {
497                 talloc_free(tdb_key.dptr);
498                 free(tdb_data.dptr);
499                 return LDB_ERR_OTHER;
500         }
501
502         if (!msg2->dn) {
503                 msg2->dn = msg->dn;
504         }
505
506         for (i=0;i<msg->num_elements;i++) {
507                 struct ldb_message_element *el = &msg->elements[i];
508                 struct ldb_message_element *el2;
509                 struct ldb_val *vals;
510                 char *err_string;
511                 char *dn;
512
513                 switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) {
514
515                 case LDB_FLAG_MOD_ADD:
516                         /* add this element to the message. fail if it
517                            already exists */
518                         ret = find_element(msg2, el->name);
519
520                         if (ret == -1) {
521                                 if (msg_add_element(ldb, msg2, el) != 0) {
522                                         ret = LDB_ERR_OTHER;
523                                         goto failed;
524                                 }
525                                 continue;
526                         }
527
528                         el2 = &msg2->elements[ret];
529
530                         /* An attribute with this name already exists, add all
531                          * values if they don't already exist. */
532
533                         for (j=0;j<el->num_values;j++) {
534                                 if (ldb_msg_find_val(el2, &el->values[j])) {
535                                         err_string = talloc_strdup(module, "Type or value exists");
536                                         if (err_string) ldb_set_errstring(module, err_string);
537                                         ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
538                                         goto failed;
539                                 }
540                         }
541
542                         vals = talloc_realloc(msg2->elements, el2->values, struct ldb_val,
543                                                 el2->num_values + el->num_values);
544
545                         if (vals == NULL)
546                                 goto failed;
547
548                         for (j=0;j<el->num_values;j++) {
549                                 vals[el2->num_values + j] =
550                                         ldb_val_dup(vals, &el->values[j]);
551                         }
552
553                         el2->values = vals;
554                         el2->num_values += el->num_values;
555
556                         break;
557
558                 case LDB_FLAG_MOD_REPLACE:
559                         /* replace all elements of this attribute name with the elements
560                            listed. The attribute not existing is not an error */
561                         msg_delete_attribute(module, ldb, msg2, msg->elements[i].name);
562
563                         /* add the replacement element, if not empty */
564                         if (msg->elements[i].num_values != 0 &&
565                             msg_add_element(ldb, msg2, &msg->elements[i]) != 0) {
566                                 goto failed;
567                         }
568                         break;
569
570                 case LDB_FLAG_MOD_DELETE:
571
572                         dn = ldb_dn_linearize(msg2, msg->dn);
573                         if (dn == NULL) goto failed;
574
575                         /* we could be being asked to delete all
576                            values or just some values */
577                         if (msg->elements[i].num_values == 0) {
578                                 if (msg_delete_attribute(module, ldb, msg2, 
579                                                          msg->elements[i].name) != 0) {
580                                         err_string = talloc_strdup(module, "No such attribute");
581                                         if (err_string) ldb_set_errstring(module, err_string);
582                                         ret = LDB_ERR_NO_SUCH_ATTRIBUTE;
583                                         goto failed;
584                                 }
585                                 break;
586                         }
587                         for (j=0;j<msg->elements[i].num_values;j++) {
588                                 if (msg_delete_element(module,
589                                                        msg2, 
590                                                        msg->elements[i].name,
591                                                        &msg->elements[i].values[j]) != 0) {
592                                         err_string = talloc_strdup(module, "No such attribute");
593                                         if (err_string) ldb_set_errstring(module, err_string);
594                                         ret = LDB_ERR_NO_SUCH_ATTRIBUTE;
595                                         goto failed;
596                                 }
597                                 if (ltdb_index_del_value(module, dn, &msg->elements[i], j) != 0) {
598                                         goto failed;
599                                 }
600                         }
601                         break;
602                 default:
603                         err_string = talloc_strdup(module, "Invalid ldb_modify flags");
604                         if (err_string) ldb_set_errstring(module, err_string);
605                         ret = LDB_ERR_PROTOCOL_ERROR;
606                         goto failed;
607                 }
608         }
609
610         /* we've made all the mods - save the modified record back into the database */
611         ret = ltdb_store(module, msg2, TDB_MODIFY);
612
613         talloc_free(tdb_key.dptr);
614         free(tdb_data.dptr);
615         return ret;
616
617 failed:
618         talloc_free(tdb_key.dptr);
619         free(tdb_data.dptr);
620         return ret;
621 }
622
623 /*
624   modify a record
625 */
626 static int ltdb_modify(struct ldb_module *module, const struct ldb_message *msg)
627 {
628         int ret;
629
630         ret = ltdb_check_special_dn(module, msg);
631         if (ret != 0) {
632                 return ret;
633         }
634         
635         if (ltdb_cache_load(module) != 0) {
636                 return -1;
637         }
638
639         ret = ltdb_modify_internal(module, msg);
640
641         if (ret == LDB_SUCCESS) {
642                 ltdb_modified(module, msg->dn);
643         }
644
645         return ret;
646 }
647
648 /*
649   rename a record
650 */
651 static int ltdb_rename(struct ldb_module *module, const struct ldb_dn *olddn, const struct ldb_dn *newdn)
652 {
653         struct ldb_message *msg;
654         char *error_str;
655         int ret = LDB_ERR_OTHER;
656
657         if (ltdb_cache_load(module) != 0) {
658                 return ret;
659         }
660
661         msg = talloc(module, struct ldb_message);
662         if (msg == NULL) {
663                 goto failed;
664         }
665
666         /* in case any attribute of the message was indexed, we need
667            to fetch the old record */
668         ret = ltdb_search_dn1(module, olddn, msg);
669         if (ret != 1) {
670                 /* not finding the old record is an error */
671                 ret = LDB_ERR_NO_SUCH_OBJECT;
672                 goto failed;
673         }
674
675         msg->dn = ldb_dn_copy(msg, newdn);
676         if (!msg->dn) {
677                 ret = LDB_ERR_OTHER;
678                 goto failed;
679         }
680
681         ret = ltdb_add(module, msg);
682         if (ret != LDB_SUCCESS) {
683                 goto failed;
684         }
685
686         ret = ltdb_delete(module, olddn);
687         error_str = talloc_strdup(module, ldb_errstring(module->ldb));
688         if (ret != LDB_SUCCESS) {
689                 ltdb_delete(module, newdn);
690         }
691
692         ldb_set_errstring(module, error_str);
693
694         talloc_free(msg);
695
696         return ret;
697
698 failed:
699         talloc_free(msg);
700         return ret;
701 }
702
703 static int ltdb_start_trans(struct ldb_module *module)
704 {
705         struct ltdb_private *ltdb = module->private_data;
706
707         if (tdb_transaction_start(ltdb->tdb) != 0) {
708                 return ltdb_err_map(tdb_error(ltdb->tdb));
709         }
710
711         return LDB_SUCCESS;
712 }
713
714 static int ltdb_end_trans(struct ldb_module *module)
715 {
716         struct ltdb_private *ltdb = module->private_data;
717
718         if (tdb_transaction_commit(ltdb->tdb) != 0) {
719                 return ltdb_err_map(tdb_error(ltdb->tdb));
720         }
721
722         return LDB_SUCCESS;
723 }
724
725 static int ltdb_del_trans(struct ldb_module *module)
726 {
727         struct ltdb_private *ltdb = module->private_data;
728
729         if (tdb_transaction_cancel(ltdb->tdb) != 0) {
730                 return ltdb_err_map(tdb_error(ltdb->tdb));
731         }
732
733         return LDB_SUCCESS;
734 }
735
736 static int ltdb_request(struct ldb_module *module, struct ldb_request *req)
737 {
738         switch (req->operation) {
739
740         case LDB_REQ_SEARCH:
741                 return ltdb_search_bytree(module,
742                                           req->op.search.base,
743                                           req->op.search.scope, 
744                                           req->op.search.tree, 
745                                           req->op.search.attrs, 
746                                           &req->op.search.res);
747
748         case LDB_REQ_ADD:
749                 return ltdb_add(module, req->op.add.message);
750
751         case LDB_REQ_MODIFY:
752                 return ltdb_modify(module, req->op.mod.message);
753
754         case LDB_REQ_DELETE:
755                 return ltdb_delete(module, req->op.del.dn);
756
757         case LDB_REQ_RENAME:
758                 return ltdb_rename(module,
759                                         req->op.rename.olddn,
760                                         req->op.rename.newdn);
761
762         default:
763                 return LDB_ERR_OPERATIONS_ERROR;
764
765         }
766 }
767
768 static const struct ldb_module_ops ltdb_ops = {
769         .name              = "tdb",
770         .request           = ltdb_request,
771         .start_transaction = ltdb_start_trans,
772         .end_transaction   = ltdb_end_trans,
773         .del_transaction   = ltdb_del_trans
774 };
775
776
777 /*
778   connect to the database
779 */
780 int ltdb_connect(struct ldb_context *ldb, const char *url, 
781                  unsigned int flags, const char *options[])
782 {
783         const char *path;
784         int tdb_flags, open_flags;
785         struct ltdb_private *ltdb;
786
787         /* parse the url */
788         if (strchr(url, ':')) {
789                 if (strncmp(url, "tdb://", 6) != 0) {
790                         ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid tdb URL '%s'", url);
791                         return -1;
792                 }
793                 path = url+6;
794         } else {
795                 path = url;
796         }
797
798         tdb_flags = TDB_DEFAULT;
799
800         /* check for the 'nosync' option */
801         if (flags & LDB_FLG_NOSYNC) {
802                 tdb_flags |= TDB_NOSYNC;
803         }
804
805         if (flags & LDB_FLG_RDONLY) {
806                 open_flags = O_RDONLY;
807         } else {
808                 open_flags = O_CREAT | O_RDWR;
809         }
810
811         ltdb = talloc_zero(ldb, struct ltdb_private);
812         if (!ltdb) {
813                 ldb_oom(ldb);
814                 return -1;
815         }
816
817         /* note that we use quite a large default hash size */
818         ltdb->tdb = ltdb_wrap_open(ltdb, path, 10000, tdb_flags, open_flags, 0666);
819         if (!ltdb->tdb) {
820                 ldb_debug(ldb, LDB_DEBUG_ERROR, "Unable to open tdb '%s'\n", path);
821                 talloc_free(ltdb);
822                 return -1;
823         }
824
825         ltdb->sequence_number = 0;
826
827         ldb->modules = talloc(ldb, struct ldb_module);
828         if (!ldb->modules) {
829                 ldb_oom(ldb);
830                 talloc_free(ltdb);
831                 return -1;
832         }
833         ldb->modules->ldb = ldb;
834         ldb->modules->prev = ldb->modules->next = NULL;
835         ldb->modules->private_data = ltdb;
836         ldb->modules->ops = &ltdb_ops;
837
838         return 0;
839 }