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_errors.h"
41 #include "ldb/include/ldb_private.h"
42 #include "ldb/ldb_tdb/ldb_tdb.h"
45 form a TDB_DATA for a record key
48 note that the key for a record can depend on whether the
49 dn refers to a case sensitive index record or not
51 struct TDB_DATA ltdb_key(struct ldb_module *module, const struct ldb_dn *dn)
53 struct ldb_context *ldb = module->ldb;
56 char *dn_folded = NULL;
59 most DNs are case insensitive. The exception is index DNs for
60 case sensitive attributes
62 there are 3 cases dealt with in this code:
64 1) if the dn doesn't start with @ then uppercase the attribute
65 names and the attributes values of case insensitive attributes
66 2) if the dn starts with @ then leave it alone - the indexing code handles
70 dn_folded = ldb_dn_linearize_casefold(ldb, dn);
75 key_str = talloc_asprintf(ldb, "DN=%s", dn_folded);
77 talloc_free(dn_folded);
83 key.dptr = (uint8_t *)key_str;
84 key.dsize = strlen(key_str) + 1;
96 check special dn's have valid attributes
97 currently only @ATTRIBUTES is checked
99 int ltdb_check_special_dn(struct ldb_module *module, const struct ldb_message *msg)
103 if (! ldb_dn_is_special(msg->dn) ||
104 ! ldb_dn_check_special(msg->dn, LTDB_ATTRIBUTES)) {
108 /* we have @ATTRIBUTES, let's check attributes are fine */
109 /* should we check that we deny multivalued attributes ? */
110 for (i = 0; i < msg->num_elements; i++) {
111 for (j = 0; j < msg->elements[i].num_values; j++) {
112 if (ltdb_check_at_attributes_values(&msg->elements[i].values[j]) != 0) {
113 char *err_string = talloc_strdup(module, "Invalid attribute value in an @ATTRIBUTES entry");
115 ldb_set_errstring(module, err_string);
117 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
127 we've made a modification to a dn - possibly reindex and
128 update sequence number
130 static int ltdb_modified(struct ldb_module *module, const struct ldb_dn *dn)
134 if (ldb_dn_is_special(dn) &&
135 (ldb_dn_check_special(dn, LTDB_INDEXLIST) ||
136 ldb_dn_check_special(dn, LTDB_ATTRIBUTES)) ) {
137 ret = ltdb_reindex(module);
141 !(ldb_dn_is_special(dn) &&
142 ldb_dn_check_special(dn, LTDB_BASEINFO)) ) {
143 ret = ltdb_increase_sequence_number(module);
150 store a record into the db
152 int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flgs)
154 struct ltdb_private *ltdb = module->private_data;
155 TDB_DATA tdb_key, tdb_data;
158 tdb_key = ltdb_key(module, msg->dn);
160 return LDB_ERR_OTHER;
163 ret = ltdb_pack_data(module, msg, &tdb_data);
165 talloc_free(tdb_key.dptr);
166 return LDB_ERR_OTHER;
169 ret = tdb_store(ltdb->tdb, tdb_key, tdb_data, flgs);
175 ret = ltdb_index_add(module, msg);
177 tdb_delete(ltdb->tdb, tdb_key);
181 talloc_free(tdb_key.dptr);
182 talloc_free(tdb_data.dptr);
189 add a record to the database
191 static int ltdb_add(struct ldb_module *module, const struct ldb_message *msg)
195 ret = ltdb_check_special_dn(module, msg);
196 if (ret != LDB_SUCCESS) {
200 if (ltdb_cache_load(module) != 0) {
201 return LDB_ERR_OTHER;
204 ret = ltdb_store(module, msg, TDB_INSERT);
206 if (ret == LDB_SUCCESS) {
207 ltdb_modified(module, msg->dn);
215 delete a record from the database, not updating indexes (used for deleting
218 int ltdb_delete_noindex(struct ldb_module *module, const struct ldb_dn *dn)
220 struct ltdb_private *ltdb = module->private_data;
224 tdb_key = ltdb_key(module, dn);
226 return LDB_ERR_OTHER;
229 ret = tdb_delete(ltdb->tdb, tdb_key);
230 talloc_free(tdb_key.dptr);
232 if (ret != 0) ret = LDB_ERR_OTHER;
238 delete a record from the database
240 static int ltdb_delete(struct ldb_module *module, const struct ldb_dn *dn)
242 struct ldb_message *msg = NULL;
243 int ret = LDB_ERR_OTHER;
245 if (ltdb_cache_load(module) != 0) {
249 msg = talloc(module, struct ldb_message);
254 /* in case any attribute of the message was indexed, we need
255 to fetch the old record */
256 ret = ltdb_search_dn1(module, dn, msg);
258 /* not finding the old record is an error */
259 ret = LDB_ERR_NO_SUCH_OBJECT;
263 ret = ltdb_delete_noindex(module, dn);
264 if (ret != LDB_SUCCESS) {
268 /* remove any indexed attributes */
269 ret = ltdb_index_del(module, msg);
270 if (ret == LDB_SUCCESS) {
271 ltdb_modified(module, dn);
285 find an element by attribute name. At the moment this does a linear search, it should
286 be re-coded to use a binary search once all places that modify records guarantee
289 return the index of the first matching element if found, otherwise -1
291 static int find_element(const struct ldb_message *msg, const char *name)
294 for (i=0;i<msg->num_elements;i++) {
295 if (ldb_attr_cmp(msg->elements[i].name, name) == 0) {
304 add an element to an existing record. Assumes a elements array that we
305 can call re-alloc on, and assumed that we can re-use the data pointers from the
306 passed in additional values. Use with care!
308 returns 0 on success, -1 on failure (and sets errno)
310 static int msg_add_element(struct ldb_context *ldb,
311 struct ldb_message *msg, struct ldb_message_element *el)
313 struct ldb_message_element *e2;
316 e2 = talloc_realloc(msg, msg->elements, struct ldb_message_element,
317 msg->num_elements+1);
325 e2 = &msg->elements[msg->num_elements];
328 e2->flags = el->flags;
330 if (el->num_values != 0) {
331 e2->values = talloc_array(msg->elements, struct ldb_val, el->num_values);
337 for (i=0;i<el->num_values;i++) {
338 e2->values[i] = el->values[i];
340 e2->num_values = el->num_values;
348 delete all elements having a specified attribute name
350 static int msg_delete_attribute(struct ldb_module *module,
351 struct ldb_context *ldb,
352 struct ldb_message *msg, const char *name)
357 dn = ldb_dn_linearize(ldb, msg->dn);
362 for (i=0;i<msg->num_elements;i++) {
363 if (ldb_attr_cmp(msg->elements[i].name, name) == 0) {
364 for (j=0;j<msg->elements[i].num_values;j++) {
365 ltdb_index_del_value(module, dn, &msg->elements[i], j);
367 talloc_free(msg->elements[i].values);
368 if (msg->num_elements > (i+1)) {
369 memmove(&msg->elements[i],
371 sizeof(struct ldb_message_element)*
372 (msg->num_elements - (i+1)));
376 msg->elements = talloc_realloc(msg, msg->elements,
377 struct ldb_message_element,
387 delete all elements matching an attribute name/value
389 return 0 on success, -1 on failure
391 static int msg_delete_element(struct ldb_module *module,
392 struct ldb_message *msg,
394 const struct ldb_val *val)
396 struct ldb_context *ldb = module->ldb;
399 struct ldb_message_element *el;
400 const struct ldb_attrib_handler *h;
402 found = find_element(msg, name);
407 el = &msg->elements[found];
409 h = ldb_attrib_handler(ldb, el->name);
411 for (i=0;i<el->num_values;i++) {
412 if (h->comparison_fn(ldb, ldb, &el->values[i], val) == 0) {
413 if (i<el->num_values-1) {
414 memmove(&el->values[i], &el->values[i+1],
415 sizeof(el->values[i])*(el->num_values-(i+1)));
418 if (el->num_values == 0) {
419 return msg_delete_attribute(module, ldb, msg, name);
430 modify a record - internal interface
432 yuck - this is O(n^2). Luckily n is usually small so we probably
433 get away with it, but if we ever have really large attribute lists
434 then we'll need to look at this again
436 int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *msg)
438 struct ldb_context *ldb = module->ldb;
439 struct ltdb_private *ltdb = module->private_data;
440 TDB_DATA tdb_key, tdb_data;
441 struct ldb_message *msg2;
445 tdb_key = ltdb_key(module, msg->dn);
447 return LDB_ERR_OTHER;
450 tdb_data = tdb_fetch(ltdb->tdb, tdb_key);
451 if (!tdb_data.dptr) {
452 talloc_free(tdb_key.dptr);
453 return LDB_ERR_OTHER;
456 msg2 = talloc(tdb_key.dptr, struct ldb_message);
458 talloc_free(tdb_key.dptr);
459 return LDB_ERR_OTHER;
462 ret = ltdb_unpack_data(module, &tdb_data, msg2);
464 talloc_free(tdb_key.dptr);
466 return LDB_ERR_OTHER;
473 for (i=0;i<msg->num_elements;i++) {
474 struct ldb_message_element *el = &msg->elements[i];
475 struct ldb_message_element *el2;
476 struct ldb_val *vals;
480 switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) {
482 case LDB_FLAG_MOD_ADD:
483 /* add this element to the message. fail if it
485 ret = find_element(msg2, el->name);
488 if (msg_add_element(ldb, msg2, el) != 0) {
495 el2 = &msg2->elements[ret];
497 /* An attribute with this name already exists, add all
498 * values if they don't already exist. */
500 for (j=0;j<el->num_values;j++) {
501 if (ldb_msg_find_val(el2, &el->values[j])) {
502 err_string = talloc_strdup(module, "Type or value exists");
503 if (err_string) ldb_set_errstring(module, err_string);
504 ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
509 vals = talloc_realloc(msg2->elements, el2->values, struct ldb_val,
510 el2->num_values + el->num_values);
515 for (j=0;j<el->num_values;j++) {
516 vals[el2->num_values + j] =
517 ldb_val_dup(vals, &el->values[j]);
521 el2->num_values += el->num_values;
525 case LDB_FLAG_MOD_REPLACE:
526 /* replace all elements of this attribute name with the elements
527 listed. The attribute not existing is not an error */
528 msg_delete_attribute(module, ldb, msg2, msg->elements[i].name);
530 /* add the replacement element, if not empty */
531 if (msg->elements[i].num_values != 0 &&
532 msg_add_element(ldb, msg2, &msg->elements[i]) != 0) {
537 case LDB_FLAG_MOD_DELETE:
539 dn = ldb_dn_linearize(msg2, msg->dn);
540 if (dn == NULL) goto failed;
542 /* we could be being asked to delete all
543 values or just some values */
544 if (msg->elements[i].num_values == 0) {
545 if (msg_delete_attribute(module, ldb, msg2,
546 msg->elements[i].name) != 0) {
547 err_string = talloc_strdup(module, "No such attribute");
548 if (err_string) ldb_set_errstring(module, err_string);
549 ret = LDB_ERR_NO_SUCH_ATTRIBUTE;
554 for (j=0;j<msg->elements[i].num_values;j++) {
555 if (msg_delete_element(module,
557 msg->elements[i].name,
558 &msg->elements[i].values[j]) != 0) {
559 err_string = talloc_strdup(module, "No such attribute");
560 if (err_string) ldb_set_errstring(module, err_string);
561 ret = LDB_ERR_NO_SUCH_ATTRIBUTE;
564 if (ltdb_index_del_value(module, dn, &msg->elements[i], j) != 0) {
570 err_string = talloc_strdup(module, "Invalid ldb_modify flags");
571 if (err_string) ldb_set_errstring(module, err_string);
572 ret = LDB_ERR_PROTOCOL_ERROR;
577 /* we've made all the mods - save the modified record back into the database */
578 ret = ltdb_store(module, msg2, TDB_MODIFY);
580 talloc_free(tdb_key.dptr);
585 talloc_free(tdb_key.dptr);
593 static int ltdb_modify(struct ldb_module *module, const struct ldb_message *msg)
597 ret = ltdb_check_special_dn(module, msg);
602 if (ltdb_cache_load(module) != 0) {
606 ret = ltdb_modify_internal(module, msg);
608 if (ret == LDB_SUCCESS) {
609 ltdb_modified(module, msg->dn);
618 static int ltdb_rename(struct ldb_module *module, const struct ldb_dn *olddn, const struct ldb_dn *newdn)
620 struct ldb_message *msg;
622 int ret = LDB_ERR_OTHER;
624 if (ltdb_cache_load(module) != 0) {
628 msg = talloc(module, struct ldb_message);
633 /* in case any attribute of the message was indexed, we need
634 to fetch the old record */
635 ret = ltdb_search_dn1(module, olddn, msg);
637 /* not finding the old record is an error */
638 ret = LDB_ERR_NO_SUCH_OBJECT;
642 msg->dn = ldb_dn_copy(msg, newdn);
648 ret = ltdb_add(module, msg);
649 if (ret != LDB_SUCCESS) {
653 ret = ltdb_delete(module, olddn);
654 error_str = talloc_strdup(module, ldb_errstring(module->ldb));
655 if (ret != LDB_SUCCESS) {
656 ltdb_delete(module, newdn);
659 ldb_set_errstring(module, error_str);
670 static int ltdb_start_trans(struct ldb_module *module)
672 struct ltdb_private *ltdb = module->private_data;
674 if (tdb_transaction_start(ltdb->tdb) != 0) {
675 return LDB_ERR_OPERATIONS_ERROR;
681 static int ltdb_end_trans(struct ldb_module *module)
683 struct ltdb_private *ltdb = module->private_data;
685 if (tdb_transaction_commit(ltdb->tdb) != 0) {
686 return LDB_ERR_OPERATIONS_ERROR;
692 static int ltdb_del_trans(struct ldb_module *module)
694 struct ltdb_private *ltdb = module->private_data;
696 if (tdb_transaction_cancel(ltdb->tdb) != 0) {
697 return LDB_ERR_OPERATIONS_ERROR;
703 static const struct ldb_module_ops ltdb_ops = {
705 .search_bytree = ltdb_search_bytree,
706 .add_record = ltdb_add,
707 .modify_record = ltdb_modify,
708 .delete_record = ltdb_delete,
709 .rename_record = ltdb_rename,
710 .start_transaction = ltdb_start_trans,
711 .end_transaction = ltdb_end_trans,
712 .del_transaction = ltdb_del_trans
717 connect to the database
719 int ltdb_connect(struct ldb_context *ldb, const char *url,
720 unsigned int flags, const char *options[])
723 int tdb_flags, open_flags;
724 struct ltdb_private *ltdb;
727 if (strchr(url, ':')) {
728 if (strncmp(url, "tdb://", 6) != 0) {
729 ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid tdb URL '%s'", url);
737 tdb_flags = TDB_DEFAULT;
739 /* check for the 'nosync' option */
740 if (flags & LDB_FLG_NOSYNC) {
741 tdb_flags |= TDB_NOSYNC;
744 if (flags & LDB_FLG_RDONLY) {
745 open_flags = O_RDONLY;
747 open_flags = O_CREAT | O_RDWR;
750 ltdb = talloc_zero(ldb, struct ltdb_private);
756 /* note that we use quite a large default hash size */
757 ltdb->tdb = ltdb_wrap_open(ltdb, path, 10000, tdb_flags, open_flags, 0666);
759 ldb_debug(ldb, LDB_DEBUG_ERROR, "Unable to open tdb '%s'\n", path);
764 ltdb->sequence_number = 0;
766 ldb->modules = talloc(ldb, struct ldb_module);
772 ldb->modules->ldb = ldb;
773 ldb->modules->prev = ldb->modules->next = NULL;
774 ldb->modules->private_data = ltdb;
775 ldb->modules->ops = <db_ops;