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_module *module,
407 struct ldb_context *ldb,
408 struct ldb_message *msg, const char *name)
410 unsigned int i, j, count=0;
411 struct ldb_message_element *el2;
413 el2 = ldb_malloc_array_p(ldb, struct ldb_message_element, msg->num_elements);
419 for (i=0;i<msg->num_elements;i++) {
420 if (ldb_attr_cmp(msg->elements[i].name, name) != 0) {
421 el2[count++] = msg->elements[i];
423 for (j=0;j<msg->elements[i].num_values;j++) {
424 ltdb_index_del_value(module, msg->dn, &msg->elements[i], j);
426 ldb_free(ldb, msg->elements[i].values);
430 msg->num_elements = count;
431 ldb_free(ldb, msg->elements);
438 delete all elements matching an attribute name/value
440 return 0 on success, -1 on failure
442 static int msg_delete_element(struct ldb_module *module,
443 struct ldb_message *msg,
445 const struct ldb_val *val)
447 struct ldb_context *ldb = module->ldb;
450 struct ldb_message_element *el;
452 found = find_element(msg, name);
457 el = &msg->elements[found];
459 for (i=0;i<el->num_values;i++) {
460 if (ltdb_val_equal(module, msg->elements[i].name, &el->values[i], val)) {
461 if (i<el->num_values-1) {
462 memmove(&el->values[i], &el->values[i+1],
463 sizeof(el->values[i])*(el->num_values-(i+1)));
466 if (el->num_values == 0) {
467 return msg_delete_attribute(module, ldb, msg, name);
478 modify a record - internal interface
480 yuck - this is O(n^2). Luckily n is usually small so we probably
481 get away with it, but if we ever have really large attribute lists
482 then we'll need to look at this again
484 int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *msg)
486 struct ldb_context *ldb = module->ldb;
487 struct ltdb_private *ltdb = module->private_data;
488 TDB_DATA tdb_key, tdb_data;
489 struct ldb_message msg2;
493 tdb_key = ltdb_key(module, msg->dn);
498 tdb_data = tdb_fetch(ltdb->tdb, tdb_key);
499 if (!tdb_data.dptr) {
500 ldb_free(ldb, tdb_key.dptr);
504 ret = ltdb_unpack_data(module, &tdb_data, &msg2);
506 ldb_free(ldb, tdb_key.dptr);
515 for (i=0;i<msg->num_elements;i++) {
516 switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) {
518 case LDB_FLAG_MOD_ADD:
519 /* add this element to the message. fail if it
521 ret = find_element(&msg2, msg->elements[i].name);
523 for (j=0;j<msg->elements[i].num_values;j++) {
524 if (ldb_msg_find_val(&msg2.elements[ret],
525 &msg->elements[i].values[j])) {
526 ltdb->last_err_string = "Type or value exists";
531 if (msg_add_element(ldb, &msg2, &msg->elements[i]) != 0) {
536 case LDB_FLAG_MOD_REPLACE:
537 /* replace all elements of this attribute name with the elements
538 listed. The attribute not existing is not an error */
539 msg_delete_attribute(module, ldb, &msg2, msg->elements[i].name);
541 /* add the replacement element, if not empty */
542 if (msg->elements[i].num_values != 0 &&
543 msg_add_element(ldb, &msg2, &msg->elements[i]) != 0) {
548 case LDB_FLAG_MOD_DELETE:
549 /* we could be being asked to delete all
550 values or just some values */
551 if (msg->elements[i].num_values == 0) {
552 if (msg_delete_attribute(module, ldb, &msg2,
553 msg->elements[i].name) != 0) {
554 ltdb->last_err_string = "No such attribute";
559 for (j=0;j<msg->elements[i].num_values;j++) {
560 if (msg_delete_element(module,
562 msg->elements[i].name,
563 &msg->elements[i].values[j]) != 0) {
564 ltdb->last_err_string = "No such attribute";
567 if (ltdb_index_del_value(module, msg->dn, &msg->elements[i], j) != 0) {
575 /* we've made all the mods - save the modified record back into the database */
576 ret = ltdb_store(module, &msg2, TDB_MODIFY);
578 ldb_free(ldb, tdb_key.dptr);
580 ltdb_unpack_data_free(module, &msg2);
584 ldb_free(ldb, tdb_key.dptr);
586 ltdb_unpack_data_free(module, &msg2);
593 static int ltdb_modify(struct ldb_module *module, const struct ldb_message *msg)
595 struct ltdb_private *ltdb = module->private_data;
598 ltdb->last_err_string = NULL;
600 if (ltdb_lock(module, LDBLOCK) != 0) {
604 if (ltdb_cache_load(module) != 0) {
605 ltdb_unlock(module, LDBLOCK);
609 ret = ltdb_modify_internal(module, msg);
612 ltdb_modified(module, msg->dn);
615 ltdb_unlock(module, LDBLOCK);
623 static int ltdb_rename(struct ldb_module *module, const char *olddn, const char *newdn)
625 struct ldb_context *ldb = module->ldb;
626 struct ltdb_private *ltdb = module->private_data;
628 struct ldb_message msg;
629 const char *error_str;
631 ltdb->last_err_string = NULL;
633 if (ltdb_lock(module, LDBLOCK) != 0) {
637 /* in case any attribute of the message was indexed, we need
638 to fetch the old record */
639 ret = ltdb_search_dn1(module, olddn, &msg);
641 /* not finding the old record is an error */
645 msg.dn = ldb_strdup(ldb,newdn);
647 ltdb_search_dn1_free(module, &msg);
651 ret = ltdb_add(module, &msg);
653 ldb_free(ldb, msg.dn);
654 ltdb_search_dn1_free(module, &msg);
657 ldb_free(ldb, msg.dn);
658 ltdb_search_dn1_free(module, &msg);
660 ret = ltdb_delete(module, olddn);
661 error_str = ltdb->last_err_string;
663 ltdb_delete(module, newdn);
666 ltdb->last_err_string = error_str;
668 ltdb_unlock(module, LDBLOCK);
672 ltdb_unlock(module, LDBLOCK);
679 static int ltdb_close(struct ldb_module *module)
681 struct ldb_context *ldb = module->ldb;
682 struct ltdb_private *ltdb = module->private_data;
685 ltdb->last_err_string = NULL;
687 ltdb_cache_free(module);
688 ldb_set_alloc(ldb, NULL, NULL);
690 ret = tdb_close(ltdb->tdb);
698 return extended error information
700 static const char *ltdb_errstring(struct ldb_module *module)
702 struct ltdb_private *ltdb = module->private_data;
703 if (ltdb->last_err_string) {
704 return ltdb->last_err_string;
706 return tdb_errorstr(ltdb->tdb);
710 static const struct ldb_module_ops ltdb_ops = {
727 connect to the database
729 struct ldb_context *ltdb_connect(const char *url,
731 const char *options[])
734 int tdb_flags, open_flags;
735 struct ltdb_private *ltdb;
737 struct ldb_context *ldb;
739 ldb = calloc(1, sizeof(struct ldb_context));
746 if (strchr(url, ':')) {
747 if (strncmp(url, "tdb://", 6) != 0) {
756 tdb_flags = TDB_DEFAULT;
758 if (flags & LDB_FLG_RDONLY) {
759 open_flags = O_RDONLY;
761 open_flags = O_CREAT | O_RDWR;
764 /* note that we use quite a large default hash size */
765 tdb = tdb_open(path, 10000, tdb_flags, open_flags, 0666);
771 ltdb = ldb_malloc_p(ldb, struct ltdb_private);
780 ltdb->sequence_number = 0;
782 memset(<db->cache, 0, sizeof(ltdb->cache));
784 ldb->modules = ldb_malloc_p(ldb, struct ldb_module);
791 ldb->modules->ldb = ldb;
792 ldb->modules->prev = ldb->modules->next = NULL;
793 ldb->modules->private_data = ltdb;
794 ldb->modules->ops = <db_ops;