4 Copyright (C) Andrew Tridgell 2004
5 Copyright (C) Stefan Metzmacher 2004
8 ** NOTE! The following LGPL license applies to the ldb
9 ** library. This does NOT imply that all of Samba is released
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.
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.
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
30 * Component: ldb tdb backend
32 * Description: core functions for tdb backend
34 * Author: Andrew Tridgell
35 * Author: Stefan Metzmacher
39 #include "ldb/include/ldb.h"
40 #include "ldb/include/ldb_private.h"
41 #include "ldb/ldb_tdb/ldb_tdb.h"
44 form a TDB_DATA for a record key
47 note that the key for a record can depend on whether the
48 dn refers to a case sensitive index record or not
50 struct TDB_DATA ltdb_key(struct ldb_module *module, const char *dn)
52 struct ldb_context *ldb = module->ldb;
55 char *dn_folded = NULL;
56 const char *prefix = LTDB_INDEX ":";
61 most DNs are case insensitive. The exception is index DNs for
62 case sensitive attributes
64 there are 3 cases dealt with in this code:
66 1) if the dn doesn't start with @INDEX: then uppercase whole dn
67 2) if the dn starts with @INDEX:attr and 'attr' is a case insensitive
68 attribute then uppercase whole dn
69 3) if the dn starts with @INDEX:attr and 'attr' is a case sensitive
70 attribute then uppercase up to the value of the attribute, but
73 if (strncmp(dn, prefix, strlen(prefix)) == 0 &&
74 (s = strchr(dn+strlen(prefix), ':'))) {
75 char *attr_name, *attr_name_folded;
76 attr_name = ldb_strndup(ldb, dn+strlen(prefix), (s-(dn+strlen(prefix))));
80 flags = ltdb_attribute_flags(module, attr_name);
82 if (flags & LTDB_FLAG_CASE_INSENSITIVE) {
83 dn_folded = ldb_casefold(ldb, dn);
85 attr_name_folded = ldb_casefold(ldb, attr_name);
86 if (!attr_name_folded) {
89 ldb_asprintf(ldb, &dn_folded, "%s:%s:%s",
90 prefix, attr_name_folded,
92 ldb_free(ldb, attr_name_folded);
94 ldb_free(ldb, attr_name);
96 dn_folded = ldb_casefold(ldb, dn);
103 ldb_asprintf(ldb, &key_str, "DN=%s", dn_folded);
104 ldb_free(ldb, dn_folded);
111 key.dsize = strlen(key_str)+1;
123 lock the database for write - currently a single lock is used
125 static int ltdb_lock(struct ldb_module *module)
127 struct ldb_context *ldb = module->ldb;
128 struct ltdb_private *ltdb = module->private_data;
132 key = ltdb_key(module, "LDBLOCK");
137 ret = tdb_chainlock(ltdb->tdb, key);
139 ldb_free(ldb, key.dptr);
145 unlock the database after a ltdb_lock()
147 static void ltdb_unlock(struct ldb_module *module)
149 struct ldb_context *ldb = module->ldb;
150 struct ltdb_private *ltdb = module->private_data;
153 key = ltdb_key(module, "LDBLOCK");
158 tdb_chainunlock(ltdb->tdb, key);
160 ldb_free(ldb, key.dptr);
165 we've made a modification to a dn - possibly reindex and
166 update sequence number
168 static int ltdb_modified(struct ldb_module *module, const char *dn)
172 if (strcmp(dn, LTDB_INDEXLIST) == 0 ||
173 strcmp(dn, LTDB_ATTRIBUTES) == 0) {
174 ret = ltdb_reindex(module);
178 strcmp(dn, LTDB_BASEINFO) != 0) {
179 ret = ltdb_increase_sequence_number(module);
186 store a record into the db
188 int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flgs)
190 struct ldb_context *ldb = module->ldb;
191 struct ltdb_private *ltdb = module->private_data;
192 TDB_DATA tdb_key, tdb_data;
195 tdb_key = ltdb_key(module, msg->dn);
200 ret = ltdb_pack_data(module, msg, &tdb_data);
202 ldb_free(ldb, tdb_key.dptr);
206 ret = tdb_store(ltdb->tdb, tdb_key, tdb_data, flgs);
211 ret = ltdb_index_add(module, msg);
213 tdb_delete(ltdb->tdb, tdb_key);
217 ldb_free(ldb, tdb_key.dptr);
218 ldb_free(ldb, tdb_data.dptr);
225 add a record to the database
227 static int ltdb_add(struct ldb_module *module, const struct ldb_message *msg)
229 struct ltdb_private *ltdb = module->private_data;
232 ltdb->last_err_string = NULL;
234 if (ltdb_lock(module) != 0) {
238 if (ltdb_cache_load(module) != 0) {
243 ret = ltdb_store(module, msg, TDB_INSERT);
246 ltdb_modified(module, msg->dn);
255 delete a record from the database, not updating indexes (used for deleting
258 int ltdb_delete_noindex(struct ldb_module *module, const char *dn)
260 struct ldb_context *ldb = module->ldb;
261 struct ltdb_private *ltdb = module->private_data;
265 tdb_key = ltdb_key(module, dn);
270 ret = tdb_delete(ltdb->tdb, tdb_key);
271 ldb_free(ldb, tdb_key.dptr);
277 delete a record from the database
279 static int ltdb_delete(struct ldb_module *module, const char *dn)
281 struct ltdb_private *ltdb = module->private_data;
283 struct ldb_message msg;
285 ltdb->last_err_string = NULL;
287 if (ltdb_lock(module) != 0) {
291 if (ltdb_cache_load(module) != 0) {
296 /* in case any attribute of the message was indexed, we need
297 to fetch the old record */
298 ret = ltdb_search_dn1(module, dn, &msg);
300 /* not finding the old record is an error */
304 ret = ltdb_delete_noindex(module, dn);
306 ltdb_search_dn1_free(module, &msg);
310 /* remove any indexed attributes */
311 ret = ltdb_index_del(module, &msg);
313 ltdb_search_dn1_free(module, &msg);
316 ltdb_modified(module, dn);
329 find an element by attribute name. At the moment this does a linear search, it should
330 be re-coded to use a binary search once all places that modify records guarantee
333 return the index of the first matching element if found, otherwise -1
335 static int find_element(const struct ldb_message *msg, const char *name)
338 for (i=0;i<msg->num_elements;i++) {
339 if (ldb_attr_cmp(msg->elements[i].name, name) == 0) {
348 add an element to an existing record. Assumes a elements array that we
349 can call re-alloc on, and assumed that we can re-use the data pointers from the
350 passed in additional values. Use with care!
352 returns 0 on success, -1 on failure (and sets errno)
354 static int msg_add_element(struct ldb_context *ldb,
355 struct ldb_message *msg, struct ldb_message_element *el)
357 struct ldb_message_element *e2;
360 e2 = ldb_realloc_p(ldb, msg->elements, struct ldb_message_element,
361 msg->num_elements+1);
369 e2 = &msg->elements[msg->num_elements];
372 e2->flags = el->flags;
374 if (el->num_values != 0) {
375 e2->values = ldb_malloc_array_p(ldb, struct ldb_val, el->num_values);
381 for (i=0;i<el->num_values;i++) {
382 e2->values[i] = el->values[i];
384 e2->num_values = el->num_values;
392 delete all elements having a specified attribute name
394 static int msg_delete_attribute(struct ldb_context *ldb,
395 struct ldb_message *msg, const char *name)
397 unsigned int i, count=0;
398 struct ldb_message_element *el2;
400 el2 = ldb_malloc_array_p(ldb, struct ldb_message_element, msg->num_elements);
406 for (i=0;i<msg->num_elements;i++) {
407 if (ldb_attr_cmp(msg->elements[i].name, name) != 0) {
408 el2[count++] = msg->elements[i];
410 ldb_free(ldb, msg->elements[i].values);
414 msg->num_elements = count;
415 ldb_free(ldb, msg->elements);
422 delete all elements matching an attribute name/value
424 return 0 on success, -1 on failure
426 static int msg_delete_element(struct ldb_module *module,
427 struct ldb_message *msg,
429 const struct ldb_val *val)
431 struct ldb_context *ldb = module->ldb;
434 struct ldb_message_element *el;
436 found = find_element(msg, name);
441 el = &msg->elements[found];
443 for (i=0;i<el->num_values;i++) {
444 if (ltdb_val_equal(module, msg->elements[i].name, &el->values[i], val)) {
445 if (i<el->num_values-1) {
446 memmove(&el->values[i], &el->values[i+1],
447 sizeof(el->values[i])*(el->num_values-(i+1)));
450 if (el->num_values == 0) {
451 return msg_delete_attribute(ldb, msg, name);
462 modify a record - internal interface
464 yuck - this is O(n^2). Luckily n is usually small so we probably
465 get away with it, but if we ever have really large attribute lists
466 then we'll need to look at this again
468 int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *msg)
470 struct ldb_context *ldb = module->ldb;
471 struct ltdb_private *ltdb = module->private_data;
472 TDB_DATA tdb_key, tdb_data;
473 struct ldb_message msg2;
477 tdb_key = ltdb_key(module, msg->dn);
482 tdb_data = tdb_fetch(ltdb->tdb, tdb_key);
483 if (!tdb_data.dptr) {
484 ldb_free(ldb, tdb_key.dptr);
488 ret = ltdb_unpack_data(module, &tdb_data, &msg2);
490 ldb_free(ldb, tdb_key.dptr);
499 for (i=0;i<msg->num_elements;i++) {
500 switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) {
502 case LDB_FLAG_MOD_ADD:
503 /* add this element to the message. fail if it
505 ret = find_element(&msg2, msg->elements[i].name);
507 ltdb->last_err_string = "Attribute exists";
510 if (msg_add_element(ldb, &msg2, &msg->elements[i]) != 0) {
515 case LDB_FLAG_MOD_REPLACE:
516 /* replace all elements of this attribute name with the elements
517 listed. The attribute not existing is not an error */
518 msg_delete_attribute(ldb, &msg2, msg->elements[i].name);
520 /* add the replacement element, if not empty */
521 if (msg->elements[i].num_values != 0 &&
522 msg_add_element(ldb, &msg2, &msg->elements[i]) != 0) {
527 case LDB_FLAG_MOD_DELETE:
528 /* we could be being asked to delete all
529 values or just some values */
530 if (msg->elements[i].num_values == 0) {
531 if (msg_delete_attribute(ldb, &msg2,
532 msg->elements[i].name) != 0) {
533 ltdb->last_err_string = "No such attribute";
538 for (j=0;j<msg->elements[i].num_values;j++) {
539 if (msg_delete_element(module,
541 msg->elements[i].name,
542 &msg->elements[i].values[j]) != 0) {
543 ltdb->last_err_string = "No such attribute";
551 /* we've made all the mods - save the modified record back into the database */
552 ret = ltdb_store(module, &msg2, TDB_MODIFY);
554 ldb_free(ldb, tdb_key.dptr);
556 ltdb_unpack_data_free(module, &msg2);
560 ldb_free(ldb, tdb_key.dptr);
562 ltdb_unpack_data_free(module, &msg2);
569 static int ltdb_modify(struct ldb_module *module, const struct ldb_message *msg)
571 struct ltdb_private *ltdb = module->private_data;
574 ltdb->last_err_string = NULL;
576 if (ltdb_lock(module) != 0) {
580 if (ltdb_cache_load(module) != 0) {
585 ret = ltdb_modify_internal(module, msg);
588 ltdb_modified(module, msg->dn);
599 static int ltdb_rename(struct ldb_module *module, const char *olddn, const char *newdn)
601 struct ldb_context *ldb = module->ldb;
602 struct ltdb_private *ltdb = module->private_data;
604 struct ldb_message msg;
605 const char *error_str;
607 ltdb->last_err_string = NULL;
609 if (ltdb_lock(module) != 0) {
613 /* in case any attribute of the message was indexed, we need
614 to fetch the old record */
615 ret = ltdb_search_dn1(module, olddn, &msg);
617 /* not finding the old record is an error */
621 msg.dn = ldb_strdup(ldb,newdn);
623 ltdb_search_dn1_free(module, &msg);
627 ret = ltdb_add(module, &msg);
629 ldb_free(ldb, msg.dn);
630 ltdb_search_dn1_free(module, &msg);
633 ldb_free(ldb, msg.dn);
634 ltdb_search_dn1_free(module, &msg);
636 ret = ltdb_delete(module, olddn);
637 error_str = ltdb->last_err_string;
639 ltdb_delete(module, newdn);
642 ltdb->last_err_string = error_str;
655 static int ltdb_close(struct ldb_module *module)
657 struct ldb_context *ldb = module->ldb;
658 struct ltdb_private *ltdb = module->private_data;
661 ltdb->last_err_string = NULL;
663 ltdb_cache_free(module);
664 ldb_set_alloc(ldb, NULL, NULL);
666 ret = tdb_close(ltdb->tdb);
674 return extended error information
676 static const char *ltdb_errstring(struct ldb_module *module)
678 struct ltdb_private *ltdb = module->private_data;
679 if (ltdb->last_err_string) {
680 return ltdb->last_err_string;
682 return tdb_errorstr(ltdb->tdb);
686 static const struct ldb_module_ops ltdb_ops = {
701 connect to the database
703 struct ldb_context *ltdb_connect(const char *url,
705 const char *options[])
708 int tdb_flags, open_flags;
709 struct ltdb_private *ltdb;
711 struct ldb_context *ldb;
713 ldb = calloc(1, sizeof(struct ldb_context));
720 if (strchr(url, ':')) {
721 if (strncmp(url, "tdb://", 6) != 0) {
730 tdb_flags = TDB_DEFAULT;
732 if (flags & LDB_FLG_RDONLY) {
733 open_flags = O_RDONLY;
735 open_flags = O_CREAT | O_RDWR;
738 /* note that we use quite a large default hash size */
739 tdb = tdb_open(path, 10000, tdb_flags, open_flags, 0666);
745 ltdb = ldb_malloc_p(ldb, struct ltdb_private);
754 ltdb->sequence_number = 0;
756 memset(<db->cache, 0, sizeof(ltdb->cache));
758 ldb->modules = ldb_malloc_p(ldb, struct ldb_module);
765 ldb->modules->ldb = ldb;
766 ldb->modules->prev = ldb->modules->next = NULL;
767 ldb->modules->private_data = ltdb;
768 ldb->modules->ops = <db_ops;