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 = talloc_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 dn_folded = talloc_asprintf(ldb, "%s:%s:%s",
92 prefix, attr_name_folded,
94 talloc_free(attr_name_folded);
96 talloc_free(attr_name);
98 dn_folded = ldb_casefold(ldb, dn);
105 key_str = talloc_asprintf(ldb, "DN=%s", dn_folded);
106 talloc_free(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 ltdb_private *ltdb = module->private_data;
133 if (lockname == NULL) {
137 key = ltdb_key(module, lockname);
142 ret = tdb_chainlock(ltdb->tdb, key);
144 talloc_free(key.dptr);
150 unlock the database after a ltdb_lock()
152 static int ltdb_unlock(struct ldb_module *module, const char *lockname)
154 struct ltdb_private *ltdb = module->private_data;
157 if (lockname == NULL) {
161 key = ltdb_key(module, lockname);
166 tdb_chainunlock(ltdb->tdb, key);
168 talloc_free(key.dptr);
175 we've made a modification to a dn - possibly reindex and
176 update sequence number
178 static int ltdb_modified(struct ldb_module *module, const char *dn)
182 if (strcmp(dn, LTDB_INDEXLIST) == 0 ||
183 strcmp(dn, LTDB_ATTRIBUTES) == 0) {
184 ret = ltdb_reindex(module);
188 strcmp(dn, LTDB_BASEINFO) != 0) {
189 ret = ltdb_increase_sequence_number(module);
196 store a record into the db
198 int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flgs)
200 struct ltdb_private *ltdb = module->private_data;
201 TDB_DATA tdb_key, tdb_data;
204 tdb_key = ltdb_key(module, msg->dn);
209 ret = ltdb_pack_data(module, msg, &tdb_data);
211 talloc_free(tdb_key.dptr);
215 ret = tdb_store(ltdb->tdb, tdb_key, tdb_data, flgs);
220 ret = ltdb_index_add(module, msg);
222 tdb_delete(ltdb->tdb, tdb_key);
226 talloc_free(tdb_key.dptr);
227 talloc_free(tdb_data.dptr);
234 add a record to the database
236 static int ltdb_add(struct ldb_module *module, const struct ldb_message *msg)
238 struct ltdb_private *ltdb = module->private_data;
241 ltdb->last_err_string = NULL;
243 if (ltdb_lock(module, LDBLOCK) != 0) {
247 if (ltdb_cache_load(module) != 0) {
248 ltdb_unlock(module, LDBLOCK);
252 ret = ltdb_store(module, msg, TDB_INSERT);
255 ltdb_modified(module, msg->dn);
258 ltdb_unlock(module, LDBLOCK);
264 delete a record from the database, not updating indexes (used for deleting
267 int ltdb_delete_noindex(struct ldb_module *module, const char *dn)
269 struct ltdb_private *ltdb = module->private_data;
273 tdb_key = ltdb_key(module, dn);
278 ret = tdb_delete(ltdb->tdb, tdb_key);
279 talloc_free(tdb_key.dptr);
285 delete a record from the database
287 static int ltdb_delete(struct ldb_module *module, const char *dn)
289 struct ltdb_private *ltdb = module->private_data;
291 struct ldb_message *msg = NULL;
293 ltdb->last_err_string = NULL;
295 if (ltdb_lock(module, LDBLOCK) != 0) {
299 if (ltdb_cache_load(module) != 0) {
303 msg = talloc(module, struct ldb_message);
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);
321 /* remove any indexed attributes */
322 ret = ltdb_index_del(module, msg);
325 ltdb_modified(module, dn);
329 ltdb_unlock(module, LDBLOCK);
334 ltdb_unlock(module, LDBLOCK);
340 find an element by attribute name. At the moment this does a linear search, it should
341 be re-coded to use a binary search once all places that modify records guarantee
344 return the index of the first matching element if found, otherwise -1
346 static int find_element(const struct ldb_message *msg, const char *name)
349 for (i=0;i<msg->num_elements;i++) {
350 if (ldb_attr_cmp(msg->elements[i].name, name) == 0) {
359 add an element to an existing record. Assumes a elements array that we
360 can call re-alloc on, and assumed that we can re-use the data pointers from the
361 passed in additional values. Use with care!
363 returns 0 on success, -1 on failure (and sets errno)
365 static int msg_add_element(struct ldb_context *ldb,
366 struct ldb_message *msg, struct ldb_message_element *el)
368 struct ldb_message_element *e2;
371 e2 = talloc_realloc(msg, msg->elements, struct ldb_message_element,
372 msg->num_elements+1);
380 e2 = &msg->elements[msg->num_elements];
383 e2->flags = el->flags;
385 if (el->num_values != 0) {
386 e2->values = talloc_array(msg->elements, struct ldb_val, el->num_values);
392 for (i=0;i<el->num_values;i++) {
393 e2->values[i] = el->values[i];
395 e2->num_values = el->num_values;
403 delete all elements having a specified attribute name
405 static int msg_delete_attribute(struct ldb_module *module,
406 struct ldb_context *ldb,
407 struct ldb_message *msg, const char *name)
411 for (i=0;i<msg->num_elements;i++) {
412 if (ldb_attr_cmp(msg->elements[i].name, name) == 0) {
413 for (j=0;j<msg->elements[i].num_values;j++) {
414 ltdb_index_del_value(module, msg->dn, &msg->elements[i], j);
416 talloc_free(msg->elements[i].values);
417 if (msg->num_elements > (i+1)) {
418 memmove(&msg->elements[i],
420 sizeof(struct ldb_message_element)*
421 (msg->num_elements - (i+1)));
425 msg->elements = talloc_realloc(msg, msg->elements,
426 struct ldb_message_element,
435 delete all elements matching an attribute name/value
437 return 0 on success, -1 on failure
439 static int msg_delete_element(struct ldb_module *module,
440 struct ldb_message *msg,
442 const struct ldb_val *val)
444 struct ldb_context *ldb = module->ldb;
447 struct ldb_message_element *el;
449 found = find_element(msg, name);
454 el = &msg->elements[found];
456 for (i=0;i<el->num_values;i++) {
457 if (ltdb_val_equal(module, msg->elements[i].name, &el->values[i], val)) {
458 if (i<el->num_values-1) {
459 memmove(&el->values[i], &el->values[i+1],
460 sizeof(el->values[i])*(el->num_values-(i+1)));
463 if (el->num_values == 0) {
464 return msg_delete_attribute(module, ldb, msg, name);
475 modify a record - internal interface
477 yuck - this is O(n^2). Luckily n is usually small so we probably
478 get away with it, but if we ever have really large attribute lists
479 then we'll need to look at this again
481 int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *msg)
483 struct ldb_context *ldb = module->ldb;
484 struct ltdb_private *ltdb = module->private_data;
485 TDB_DATA tdb_key, tdb_data;
486 struct ldb_message *msg2;
490 tdb_key = ltdb_key(module, msg->dn);
495 tdb_data = tdb_fetch(ltdb->tdb, tdb_key);
496 if (!tdb_data.dptr) {
497 talloc_free(tdb_key.dptr);
501 msg2 = talloc(tdb_key.dptr, struct ldb_message);
503 talloc_free(tdb_key.dptr);
507 ret = ltdb_unpack_data(module, &tdb_data, msg2);
509 talloc_free(tdb_key.dptr);
518 for (i=0;i<msg->num_elements;i++) {
519 struct ldb_message_element *el = &msg->elements[i];
520 struct ldb_message_element *el2;
521 struct ldb_val *vals;
523 switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) {
525 case LDB_FLAG_MOD_ADD:
526 /* add this element to the message. fail if it
528 ret = find_element(msg2, el->name);
531 if (msg_add_element(ldb, msg2, el) != 0) {
537 el2 = &msg2->elements[ret];
539 /* An attribute with this name already exists, add all
540 * values if they don't already exist. */
542 for (j=0;j<el->num_values;j++) {
543 if (ldb_msg_find_val(el2, &el->values[j])) {
544 ltdb->last_err_string =
545 "Type or value exists";
550 vals = talloc_realloc(msg2->elements, el2->values, struct ldb_val,
551 el2->num_values + el->num_values);
556 for (j=0;j<el->num_values;j++) {
557 vals[el2->num_values + j] =
558 ldb_val_dup(vals, &el->values[j]);
562 el2->num_values += el->num_values;
566 case LDB_FLAG_MOD_REPLACE:
567 /* replace all elements of this attribute name with the elements
568 listed. The attribute not existing is not an error */
569 msg_delete_attribute(module, ldb, msg2, msg->elements[i].name);
571 /* add the replacement element, if not empty */
572 if (msg->elements[i].num_values != 0 &&
573 msg_add_element(ldb, msg2, &msg->elements[i]) != 0) {
578 case LDB_FLAG_MOD_DELETE:
579 /* we could be being asked to delete all
580 values or just some values */
581 if (msg->elements[i].num_values == 0) {
582 if (msg_delete_attribute(module, ldb, msg2,
583 msg->elements[i].name) != 0) {
584 ltdb->last_err_string = "No such attribute";
589 for (j=0;j<msg->elements[i].num_values;j++) {
590 if (msg_delete_element(module,
592 msg->elements[i].name,
593 &msg->elements[i].values[j]) != 0) {
594 ltdb->last_err_string = "No such attribute";
597 if (ltdb_index_del_value(module, msg->dn, &msg->elements[i], j) != 0) {
605 /* we've made all the mods - save the modified record back into the database */
606 ret = ltdb_store(module, msg2, TDB_MODIFY);
608 talloc_free(tdb_key.dptr);
613 talloc_free(tdb_key.dptr);
621 static int ltdb_modify(struct ldb_module *module, const struct ldb_message *msg)
623 struct ltdb_private *ltdb = module->private_data;
626 ltdb->last_err_string = NULL;
628 if (ltdb_lock(module, LDBLOCK) != 0) {
632 if (ltdb_cache_load(module) != 0) {
633 ltdb_unlock(module, LDBLOCK);
637 ret = ltdb_modify_internal(module, msg);
640 ltdb_modified(module, msg->dn);
643 ltdb_unlock(module, LDBLOCK);
651 static int ltdb_rename(struct ldb_module *module, const char *olddn, const char *newdn)
653 struct ltdb_private *ltdb = module->private_data;
655 struct ldb_message *msg;
656 const char *error_str;
658 ltdb->last_err_string = NULL;
660 if (ltdb_lock(module, LDBLOCK) != 0) {
664 msg = talloc(module, struct ldb_message);
669 /* in case any attribute of the message was indexed, we need
670 to fetch the old record */
671 ret = ltdb_search_dn1(module, olddn, msg);
673 /* not finding the old record is an error */
677 msg->dn = talloc_strdup(msg, newdn);
682 ret = ltdb_add(module, msg);
687 ret = ltdb_delete(module, olddn);
688 error_str = ltdb->last_err_string;
690 ltdb_delete(module, newdn);
693 ltdb->last_err_string = error_str;
696 ltdb_unlock(module, LDBLOCK);
702 ltdb_unlock(module, LDBLOCK);
709 static int ltdb_close(struct ldb_module *module)
711 struct ldb_context *ldb = module->ldb;
718 return extended error information
720 static const char *ltdb_errstring(struct ldb_module *module)
722 struct ltdb_private *ltdb = module->private_data;
723 if (ltdb->last_err_string) {
724 return ltdb->last_err_string;
726 return tdb_errorstr(ltdb->tdb);
730 static const struct ldb_module_ops ltdb_ops = {
746 destroy the ltdb context
748 static int ltdb_destructor(void *p)
750 struct ltdb_private *ltdb = p;
751 tdb_close(ltdb->tdb);
756 connect to the database
758 struct ldb_context *ltdb_connect(const char *url,
760 const char *options[])
763 int tdb_flags, open_flags;
764 struct ltdb_private *ltdb;
766 struct ldb_context *ldb;
768 ldb = talloc_zero(NULL, struct ldb_context);
775 if (strchr(url, ':')) {
776 if (strncmp(url, "tdb://", 6) != 0) {
786 tdb_flags = TDB_DEFAULT;
788 if (flags & LDB_FLG_RDONLY) {
789 open_flags = O_RDONLY;
791 open_flags = O_CREAT | O_RDWR;
794 /* note that we use quite a large default hash size */
795 tdb = tdb_open(path, 10000, tdb_flags, open_flags, 0666);
801 ltdb = talloc_zero(ldb, struct ltdb_private);
810 ltdb->sequence_number = 0;
812 talloc_set_destructor(ltdb, ltdb_destructor);
814 ldb->modules = talloc(ldb, struct ldb_module);
820 ldb->modules->ldb = ldb;
821 ldb->modules->prev = ldb->modules->next = NULL;
822 ldb->modules->private_data = ltdb;
823 ldb->modules->ops = <db_ops;