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"
43 #define LDBLOCK "INT_LDBLOCK"
46 form a TDB_DATA for a record key
49 note that the key for a record can depend on whether the
50 dn refers to a case sensitive index record or not
52 struct TDB_DATA ltdb_key(struct ldb_module *module, const char *dn)
54 struct ldb_context *ldb = module->ldb;
57 char *dn_folded = NULL;
58 const char *prefix = LTDB_INDEX ":";
63 most DNs are case insensitive. The exception is index DNs for
64 case sensitive attributes
66 there are 3 cases dealt with in this code:
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
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))));
82 flags = ltdb_attribute_flags(module, attr_name);
84 if (flags & LTDB_FLAG_CASE_INSENSITIVE) {
85 dn_folded = ldb_casefold(ldb, dn);
87 attr_name_folded = ldb_casefold(ldb, attr_name);
88 if (!attr_name_folded) {
91 ldb_asprintf(ldb, &dn_folded, "%s:%s:%s",
92 prefix, attr_name_folded,
94 ldb_free(ldb, attr_name_folded);
96 ldb_free(ldb, attr_name);
98 dn_folded = ldb_casefold(ldb, dn);
105 ldb_asprintf(ldb, &key_str, "DN=%s", dn_folded);
106 ldb_free(ldb, dn_folded);
113 key.dsize = strlen(key_str)+1;
125 lock the database for write - currently a single lock is used
127 static int ltdb_lock(struct ldb_module *module, const char *lockname)
129 struct ldb_context *ldb = module->ldb;
130 struct ltdb_private *ltdb = module->private_data;
134 if (lockname == NULL) {
138 key = ltdb_key(module, lockname);
143 ret = tdb_chainlock(ltdb->tdb, key);
145 ldb_free(ldb, key.dptr);
151 unlock the database after a ltdb_lock()
153 static int ltdb_unlock(struct ldb_module *module, const char *lockname)
155 struct ldb_context *ldb = module->ldb;
156 struct ltdb_private *ltdb = module->private_data;
159 if (lockname == NULL) {
163 key = ltdb_key(module, lockname);
168 tdb_chainunlock(ltdb->tdb, key);
170 ldb_free(ldb, key.dptr);
177 we've made a modification to a dn - possibly reindex and
178 update sequence number
180 static int ltdb_modified(struct ldb_module *module, const char *dn)
184 if (strcmp(dn, LTDB_INDEXLIST) == 0 ||
185 strcmp(dn, LTDB_ATTRIBUTES) == 0) {
186 ret = ltdb_reindex(module);
190 strcmp(dn, LTDB_BASEINFO) != 0) {
191 ret = ltdb_increase_sequence_number(module);
198 store a record into the db
200 int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flgs)
202 struct ldb_context *ldb = module->ldb;
203 struct ltdb_private *ltdb = module->private_data;
204 TDB_DATA tdb_key, tdb_data;
207 tdb_key = ltdb_key(module, msg->dn);
212 ret = ltdb_pack_data(module, msg, &tdb_data);
214 ldb_free(ldb, tdb_key.dptr);
218 ret = tdb_store(ltdb->tdb, tdb_key, tdb_data, flgs);
223 ret = ltdb_index_add(module, msg);
225 tdb_delete(ltdb->tdb, tdb_key);
229 ldb_free(ldb, tdb_key.dptr);
230 ldb_free(ldb, tdb_data.dptr);
237 add a record to the database
239 static int ltdb_add(struct ldb_module *module, const struct ldb_message *msg)
241 struct ltdb_private *ltdb = module->private_data;
244 ltdb->last_err_string = NULL;
246 if (ltdb_lock(module, LDBLOCK) != 0) {
250 if (ltdb_cache_load(module) != 0) {
251 ltdb_unlock(module, LDBLOCK);
255 ret = ltdb_store(module, msg, TDB_INSERT);
258 ltdb_modified(module, msg->dn);
261 ltdb_unlock(module, LDBLOCK);
267 delete a record from the database, not updating indexes (used for deleting
270 int ltdb_delete_noindex(struct ldb_module *module, const char *dn)
272 struct ldb_context *ldb = module->ldb;
273 struct ltdb_private *ltdb = module->private_data;
277 tdb_key = ltdb_key(module, dn);
282 ret = tdb_delete(ltdb->tdb, tdb_key);
283 ldb_free(ldb, tdb_key.dptr);
289 delete a record from the database
291 static int ltdb_delete(struct ldb_module *module, const char *dn)
293 struct ltdb_private *ltdb = module->private_data;
295 struct ldb_message msg;
297 ltdb->last_err_string = NULL;
299 if (ltdb_lock(module, LDBLOCK) != 0) {
303 if (ltdb_cache_load(module) != 0) {
304 ltdb_unlock(module, LDBLOCK);
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);
312 /* not finding the old record is an error */
316 ret = ltdb_delete_noindex(module, dn);
318 ltdb_search_dn1_free(module, &msg);
322 /* remove any indexed attributes */
323 ret = ltdb_index_del(module, &msg);
325 ltdb_search_dn1_free(module, &msg);
328 ltdb_modified(module, dn);
331 ltdb_unlock(module, LDBLOCK);
335 ltdb_unlock(module, LDBLOCK);
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
345 return the index of the first matching element if found, otherwise -1
347 static int find_element(const struct ldb_message *msg, const char *name)
350 for (i=0;i<msg->num_elements;i++) {
351 if (ldb_attr_cmp(msg->elements[i].name, name) == 0) {
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!
364 returns 0 on success, -1 on failure (and sets errno)
366 static int msg_add_element(struct ldb_context *ldb,
367 struct ldb_message *msg, struct ldb_message_element *el)
369 struct ldb_message_element *e2;
372 e2 = ldb_realloc_p(ldb, msg->elements, struct ldb_message_element,
373 msg->num_elements+1);
381 e2 = &msg->elements[msg->num_elements];
384 e2->flags = el->flags;
386 if (el->num_values != 0) {
387 e2->values = ldb_malloc_array_p(ldb, struct ldb_val, el->num_values);
393 for (i=0;i<el->num_values;i++) {
394 e2->values[i] = el->values[i];
396 e2->num_values = el->num_values;
404 delete all elements having a specified attribute name
406 static int msg_delete_attribute(struct ldb_context *ldb,
407 struct ldb_message *msg, const char *name)
409 unsigned int i, count=0;
410 struct ldb_message_element *el2;
412 el2 = ldb_malloc_array_p(ldb, struct ldb_message_element, msg->num_elements);
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];
422 ldb_free(ldb, msg->elements[i].values);
426 msg->num_elements = count;
427 ldb_free(ldb, msg->elements);
434 delete all elements matching an attribute name/value
436 return 0 on success, -1 on failure
438 static int msg_delete_element(struct ldb_module *module,
439 struct ldb_message *msg,
441 const struct ldb_val *val)
443 struct ldb_context *ldb = module->ldb;
446 struct ldb_message_element *el;
448 found = find_element(msg, name);
453 el = &msg->elements[found];
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)));
462 if (el->num_values == 0) {
463 return msg_delete_attribute(ldb, msg, name);
474 modify a record - internal interface
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
480 int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *msg)
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;
489 tdb_key = ltdb_key(module, msg->dn);
494 tdb_data = tdb_fetch(ltdb->tdb, tdb_key);
495 if (!tdb_data.dptr) {
496 ldb_free(ldb, tdb_key.dptr);
500 ret = ltdb_unpack_data(module, &tdb_data, &msg2);
502 ldb_free(ldb, tdb_key.dptr);
511 for (i=0;i<msg->num_elements;i++) {
512 switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) {
514 case LDB_FLAG_MOD_ADD:
515 /* add this element to the message. fail if it
517 ret = find_element(&msg2, msg->elements[i].name);
519 ltdb->last_err_string = "Attribute exists";
522 if (msg_add_element(ldb, &msg2, &msg->elements[i]) != 0) {
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);
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) {
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";
550 for (j=0;j<msg->elements[i].num_values;j++) {
551 if (msg_delete_element(module,
553 msg->elements[i].name,
554 &msg->elements[i].values[j]) != 0) {
555 ltdb->last_err_string = "No such attribute";
563 /* we've made all the mods - save the modified record back into the database */
564 ret = ltdb_store(module, &msg2, TDB_MODIFY);
566 ldb_free(ldb, tdb_key.dptr);
568 ltdb_unpack_data_free(module, &msg2);
572 ldb_free(ldb, tdb_key.dptr);
574 ltdb_unpack_data_free(module, &msg2);
581 static int ltdb_modify(struct ldb_module *module, const struct ldb_message *msg)
583 struct ltdb_private *ltdb = module->private_data;
586 ltdb->last_err_string = NULL;
588 if (ltdb_lock(module, LDBLOCK) != 0) {
592 if (ltdb_cache_load(module) != 0) {
593 ltdb_unlock(module, LDBLOCK);
597 ret = ltdb_modify_internal(module, msg);
600 ltdb_modified(module, msg->dn);
603 ltdb_unlock(module, LDBLOCK);
611 static int ltdb_rename(struct ldb_module *module, const char *olddn, const char *newdn)
613 struct ldb_context *ldb = module->ldb;
614 struct ltdb_private *ltdb = module->private_data;
616 struct ldb_message msg;
617 const char *error_str;
619 ltdb->last_err_string = NULL;
621 if (ltdb_lock(module, LDBLOCK) != 0) {
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);
629 /* not finding the old record is an error */
633 msg.dn = ldb_strdup(ldb,newdn);
635 ltdb_search_dn1_free(module, &msg);
639 ret = ltdb_add(module, &msg);
641 ldb_free(ldb, msg.dn);
642 ltdb_search_dn1_free(module, &msg);
645 ldb_free(ldb, msg.dn);
646 ltdb_search_dn1_free(module, &msg);
648 ret = ltdb_delete(module, olddn);
649 error_str = ltdb->last_err_string;
651 ltdb_delete(module, newdn);
654 ltdb->last_err_string = error_str;
656 ltdb_unlock(module, LDBLOCK);
660 ltdb_unlock(module, LDBLOCK);
667 static int ltdb_close(struct ldb_module *module)
669 struct ldb_context *ldb = module->ldb;
670 struct ltdb_private *ltdb = module->private_data;
673 ltdb->last_err_string = NULL;
675 ltdb_cache_free(module);
676 ldb_set_alloc(ldb, NULL, NULL);
678 ret = tdb_close(ltdb->tdb);
686 return extended error information
688 static const char *ltdb_errstring(struct ldb_module *module)
690 struct ltdb_private *ltdb = module->private_data;
691 if (ltdb->last_err_string) {
692 return ltdb->last_err_string;
694 return tdb_errorstr(ltdb->tdb);
698 static const struct ldb_module_ops ltdb_ops = {
715 connect to the database
717 struct ldb_context *ltdb_connect(const char *url,
719 const char *options[])
722 int tdb_flags, open_flags;
723 struct ltdb_private *ltdb;
725 struct ldb_context *ldb;
727 ldb = calloc(1, sizeof(struct ldb_context));
734 if (strchr(url, ':')) {
735 if (strncmp(url, "tdb://", 6) != 0) {
744 tdb_flags = TDB_DEFAULT;
746 if (flags & LDB_FLG_RDONLY) {
747 open_flags = O_RDONLY;
749 open_flags = O_CREAT | O_RDWR;
752 /* note that we use quite a large default hash size */
753 tdb = tdb_open(path, 10000, tdb_flags, open_flags, 0666);
759 ltdb = ldb_malloc_p(ldb, struct ltdb_private);
768 ltdb->sequence_number = 0;
770 memset(<db->cache, 0, sizeof(ltdb->cache));
772 ldb->modules = ldb_malloc_p(ldb, struct ldb_module);
779 ldb->modules->ldb = ldb;
780 ldb->modules->prev = ldb->modules->next = NULL;
781 ldb->modules->private_data = ltdb;
782 ldb->modules->ops = <db_ops;