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