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 for (j=0;j<msg->elements[i].num_values;j++) {
520 if (ldb_msg_find_val(&msg2.elements[ret],
521 &msg->elements[i].values[j])) {
522 ltdb->last_err_string = "Type or value exists";
527 if (msg_add_element(ldb, &msg2, &msg->elements[i]) != 0) {
532 case LDB_FLAG_MOD_REPLACE:
533 /* replace all elements of this attribute name with the elements
534 listed. The attribute not existing is not an error */
535 msg_delete_attribute(ldb, &msg2, msg->elements[i].name);
537 /* add the replacement element, if not empty */
538 if (msg->elements[i].num_values != 0 &&
539 msg_add_element(ldb, &msg2, &msg->elements[i]) != 0) {
544 case LDB_FLAG_MOD_DELETE:
545 /* we could be being asked to delete all
546 values or just some values */
547 if (msg->elements[i].num_values == 0) {
548 if (msg_delete_attribute(ldb, &msg2,
549 msg->elements[i].name) != 0) {
550 ltdb->last_err_string = "No such attribute";
555 for (j=0;j<msg->elements[i].num_values;j++) {
556 if (msg_delete_element(module,
558 msg->elements[i].name,
559 &msg->elements[i].values[j]) != 0) {
560 ltdb->last_err_string = "No such attribute";
568 /* we've made all the mods - save the modified record back into the database */
569 ret = ltdb_store(module, &msg2, TDB_MODIFY);
571 ldb_free(ldb, tdb_key.dptr);
573 ltdb_unpack_data_free(module, &msg2);
577 ldb_free(ldb, tdb_key.dptr);
579 ltdb_unpack_data_free(module, &msg2);
586 static int ltdb_modify(struct ldb_module *module, const struct ldb_message *msg)
588 struct ltdb_private *ltdb = module->private_data;
591 ltdb->last_err_string = NULL;
593 if (ltdb_lock(module, LDBLOCK) != 0) {
597 if (ltdb_cache_load(module) != 0) {
598 ltdb_unlock(module, LDBLOCK);
602 ret = ltdb_modify_internal(module, msg);
605 ltdb_modified(module, msg->dn);
608 ltdb_unlock(module, LDBLOCK);
616 static int ltdb_rename(struct ldb_module *module, const char *olddn, const char *newdn)
618 struct ldb_context *ldb = module->ldb;
619 struct ltdb_private *ltdb = module->private_data;
621 struct ldb_message msg;
622 const char *error_str;
624 ltdb->last_err_string = NULL;
626 if (ltdb_lock(module, LDBLOCK) != 0) {
630 /* in case any attribute of the message was indexed, we need
631 to fetch the old record */
632 ret = ltdb_search_dn1(module, olddn, &msg);
634 /* not finding the old record is an error */
638 msg.dn = ldb_strdup(ldb,newdn);
640 ltdb_search_dn1_free(module, &msg);
644 ret = ltdb_add(module, &msg);
646 ldb_free(ldb, msg.dn);
647 ltdb_search_dn1_free(module, &msg);
650 ldb_free(ldb, msg.dn);
651 ltdb_search_dn1_free(module, &msg);
653 ret = ltdb_delete(module, olddn);
654 error_str = ltdb->last_err_string;
656 ltdb_delete(module, newdn);
659 ltdb->last_err_string = error_str;
661 ltdb_unlock(module, LDBLOCK);
665 ltdb_unlock(module, LDBLOCK);
672 static int ltdb_close(struct ldb_module *module)
674 struct ldb_context *ldb = module->ldb;
675 struct ltdb_private *ltdb = module->private_data;
678 ltdb->last_err_string = NULL;
680 ltdb_cache_free(module);
681 ldb_set_alloc(ldb, NULL, NULL);
683 ret = tdb_close(ltdb->tdb);
691 return extended error information
693 static const char *ltdb_errstring(struct ldb_module *module)
695 struct ltdb_private *ltdb = module->private_data;
696 if (ltdb->last_err_string) {
697 return ltdb->last_err_string;
699 return tdb_errorstr(ltdb->tdb);
703 static const struct ldb_module_ops ltdb_ops = {
720 connect to the database
722 struct ldb_context *ltdb_connect(const char *url,
724 const char *options[])
727 int tdb_flags, open_flags;
728 struct ltdb_private *ltdb;
730 struct ldb_context *ldb;
732 ldb = calloc(1, sizeof(struct ldb_context));
739 if (strchr(url, ':')) {
740 if (strncmp(url, "tdb://", 6) != 0) {
749 tdb_flags = TDB_DEFAULT;
751 if (flags & LDB_FLG_RDONLY) {
752 open_flags = O_RDONLY;
754 open_flags = O_CREAT | O_RDWR;
757 /* note that we use quite a large default hash size */
758 tdb = tdb_open(path, 10000, tdb_flags, open_flags, 0666);
764 ltdb = ldb_malloc_p(ldb, struct ltdb_private);
773 ltdb->sequence_number = 0;
775 memset(<db->cache, 0, sizeof(ltdb->cache));
777 ldb->modules = ldb_malloc_p(ldb, struct ldb_module);
784 ldb->modules->ldb = ldb;
785 ldb->modules->prev = ldb->modules->next = NULL;
786 ldb->modules->private_data = ltdb;
787 ldb->modules->ops = <db_ops;