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