r19071: Backport to SAMBA_3_0 as well
[Samba.git] / source / lib / ldb / ldb_tdb / ldb_tdb.c
blob5d4378390359077ff37a635de7a8809f7e89a431
1 /*
2 ldb database library
4 Copyright (C) Andrew Tridgell 2004
5 Copyright (C) Stefan Metzmacher 2004
6 Copyright (C) Simo Sorce 2006
9 ** NOTE! The following LGPL license applies to the ldb
10 ** library. This does NOT imply that all of Samba is released
11 ** under the LGPL
13 This library is free software; you can redistribute it and/or
14 modify it under the terms of the GNU Lesser General Public
15 License as published by the Free Software Foundation; either
16 version 2 of the License, or (at your option) any later version.
18 This library is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 Lesser General Public License for more details.
23 You should have received a copy of the GNU Lesser General Public
24 License along with this library; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 * Name: ldb_tdb
31 * Component: ldb tdb backend
33 * Description: core functions for tdb backend
35 * Author: Andrew Tridgell
36 * Author: Stefan Metzmacher
38 * Modifications:
40 * - description: make the module use asyncronous calls
41 * date: Feb 2006
42 * Author: Simo Sorce
45 #include "includes.h"
46 #include "ldb/include/includes.h"
48 #include "ldb/ldb_tdb/ldb_tdb.h"
52 map a tdb error code to a ldb error code
54 static int ltdb_err_map(enum TDB_ERROR tdb_code)
56 switch (tdb_code) {
57 case TDB_SUCCESS:
58 return LDB_SUCCESS;
59 case TDB_ERR_CORRUPT:
60 case TDB_ERR_OOM:
61 case TDB_ERR_EINVAL:
62 return LDB_ERR_OPERATIONS_ERROR;
63 case TDB_ERR_IO:
64 return LDB_ERR_PROTOCOL_ERROR;
65 case TDB_ERR_LOCK:
66 case TDB_ERR_NOLOCK:
67 return LDB_ERR_BUSY;
68 case TDB_ERR_LOCK_TIMEOUT:
69 return LDB_ERR_TIME_LIMIT_EXCEEDED;
70 case TDB_ERR_EXISTS:
71 return LDB_ERR_ENTRY_ALREADY_EXISTS;
72 case TDB_ERR_NOEXIST:
73 return LDB_ERR_NO_SUCH_OBJECT;
74 case TDB_ERR_RDONLY:
75 return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
77 return LDB_ERR_OTHER;
81 struct ldb_handle *init_ltdb_handle(struct ltdb_private *ltdb, struct ldb_module *module,
82 void *context,
83 int (*callback)(struct ldb_context *, void *, struct ldb_reply *))
85 struct ltdb_context *ac;
86 struct ldb_handle *h;
88 h = talloc_zero(ltdb, struct ldb_handle);
89 if (h == NULL) {
90 ldb_set_errstring(module->ldb, "Out of Memory");
91 return NULL;
94 h->module = module;
96 ac = talloc_zero(h, struct ltdb_context);
97 if (ac == NULL) {
98 ldb_set_errstring(module->ldb, "Out of Memory");
99 talloc_free(h);
100 return NULL;
103 h->private_data = (void *)ac;
105 h->state = LDB_ASYNC_INIT;
106 h->status = LDB_SUCCESS;
108 ac->module = module;
109 ac->context = context;
110 ac->callback = callback;
112 return h;
116 form a TDB_DATA for a record key
117 caller frees
119 note that the key for a record can depend on whether the
120 dn refers to a case sensitive index record or not
122 struct TDB_DATA ltdb_key(struct ldb_module *module, const struct ldb_dn *dn)
124 struct ldb_context *ldb = module->ldb;
125 TDB_DATA key;
126 char *key_str = NULL;
127 char *dn_folded = NULL;
130 most DNs are case insensitive. The exception is index DNs for
131 case sensitive attributes
133 there are 3 cases dealt with in this code:
135 1) if the dn doesn't start with @ then uppercase the attribute
136 names and the attributes values of case insensitive attributes
137 2) if the dn starts with @ then leave it alone - the indexing code handles
138 the rest
141 dn_folded = ldb_dn_linearize_casefold(ldb, dn);
142 if (!dn_folded) {
143 goto failed;
146 key_str = talloc_asprintf(ldb, "DN=%s", dn_folded);
148 talloc_free(dn_folded);
150 if (!key_str) {
151 goto failed;
154 key.dptr = (uint8_t *)key_str;
155 key.dsize = strlen(key_str) + 1;
157 return key;
159 failed:
160 errno = ENOMEM;
161 key.dptr = NULL;
162 key.dsize = 0;
163 return key;
167 check special dn's have valid attributes
168 currently only @ATTRIBUTES is checked
170 int ltdb_check_special_dn(struct ldb_module *module, const struct ldb_message *msg)
172 int i, j;
174 if (! ldb_dn_is_special(msg->dn) ||
175 ! ldb_dn_check_special(msg->dn, LTDB_ATTRIBUTES)) {
176 return 0;
179 /* we have @ATTRIBUTES, let's check attributes are fine */
180 /* should we check that we deny multivalued attributes ? */
181 for (i = 0; i < msg->num_elements; i++) {
182 for (j = 0; j < msg->elements[i].num_values; j++) {
183 if (ltdb_check_at_attributes_values(&msg->elements[i].values[j]) != 0) {
184 ldb_set_errstring(module->ldb, "Invalid attribute value in an @ATTRIBUTES entry");
185 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
190 return 0;
195 we've made a modification to a dn - possibly reindex and
196 update sequence number
198 static int ltdb_modified(struct ldb_module *module, const struct ldb_dn *dn)
200 int ret = 0;
202 if (ldb_dn_is_special(dn) &&
203 (ldb_dn_check_special(dn, LTDB_INDEXLIST) ||
204 ldb_dn_check_special(dn, LTDB_ATTRIBUTES)) ) {
205 ret = ltdb_reindex(module);
208 if (ret == 0 &&
209 !(ldb_dn_is_special(dn) &&
210 ldb_dn_check_special(dn, LTDB_BASEINFO)) ) {
211 ret = ltdb_increase_sequence_number(module);
214 return ret;
218 store a record into the db
220 int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flgs)
222 struct ltdb_private *ltdb = module->private_data;
223 TDB_DATA tdb_key, tdb_data;
224 int ret;
226 tdb_key = ltdb_key(module, msg->dn);
227 if (!tdb_key.dptr) {
228 return LDB_ERR_OTHER;
231 ret = ltdb_pack_data(module, msg, &tdb_data);
232 if (ret == -1) {
233 talloc_free(tdb_key.dptr);
234 return LDB_ERR_OTHER;
237 ret = tdb_store(ltdb->tdb, tdb_key, tdb_data, flgs);
238 if (ret == -1) {
239 ret = ltdb_err_map(tdb_error(ltdb->tdb));
240 goto done;
243 ret = ltdb_index_add(module, msg);
244 if (ret == -1) {
245 tdb_delete(ltdb->tdb, tdb_key);
248 done:
249 talloc_free(tdb_key.dptr);
250 talloc_free(tdb_data.dptr);
252 return ret;
256 static int ltdb_add_internal(struct ldb_module *module, const struct ldb_message *msg)
258 int ret;
260 ret = ltdb_check_special_dn(module, msg);
261 if (ret != LDB_SUCCESS) {
262 return ret;
265 if (ltdb_cache_load(module) != 0) {
266 return LDB_ERR_OPERATIONS_ERROR;
269 ret = ltdb_store(module, msg, TDB_INSERT);
271 if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) {
272 char *dn;
274 dn = ldb_dn_linearize(module, msg->dn);
275 if (!dn) {
276 return ret;
278 ldb_asprintf_errstring(module->ldb, "Entry %s already exists", dn);
279 talloc_free(dn);
280 return ret;
283 if (ret == LDB_SUCCESS) {
284 ret = ltdb_modified(module, msg->dn);
285 if (ret != LDB_SUCCESS) {
286 return LDB_ERR_OPERATIONS_ERROR;
290 return ret;
294 add a record to the database
296 static int ltdb_add(struct ldb_module *module, struct ldb_request *req)
298 struct ltdb_private *ltdb = talloc_get_type(module->private_data, struct ltdb_private);
299 struct ltdb_context *ltdb_ac;
300 int tret, ret = LDB_SUCCESS;
302 if (req->controls != NULL) {
303 ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Controls should not reach the ldb_tdb backend!\n");
304 if (check_critical_controls(req->controls)) {
305 return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
309 req->handle = init_ltdb_handle(ltdb, module, req->context, req->callback);
310 if (req->handle == NULL) {
311 return LDB_ERR_OPERATIONS_ERROR;
313 ltdb_ac = talloc_get_type(req->handle->private_data, struct ltdb_context);
315 tret = ltdb_add_internal(module, req->op.add.message);
316 if (tret != LDB_SUCCESS) {
317 req->handle->status = tret;
318 goto done;
321 if (ltdb_ac->callback) {
322 ret = ltdb_ac->callback(module->ldb, ltdb_ac->context, NULL);
324 done:
325 req->handle->state = LDB_ASYNC_DONE;
326 return ret;
330 delete a record from the database, not updating indexes (used for deleting
331 index records)
333 int ltdb_delete_noindex(struct ldb_module *module, const struct ldb_dn *dn)
335 struct ltdb_private *ltdb = module->private_data;
336 TDB_DATA tdb_key;
337 int ret;
339 tdb_key = ltdb_key(module, dn);
340 if (!tdb_key.dptr) {
341 return LDB_ERR_OTHER;
344 ret = tdb_delete(ltdb->tdb, tdb_key);
345 talloc_free(tdb_key.dptr);
347 if (ret != 0) {
348 ret = ltdb_err_map(tdb_error(ltdb->tdb));
351 return ret;
354 static int ltdb_delete_internal(struct ldb_module *module, const struct ldb_dn *dn)
356 struct ldb_message *msg;
357 int ret;
359 msg = talloc(module, struct ldb_message);
360 if (msg == NULL) {
361 return LDB_ERR_OPERATIONS_ERROR;
364 /* in case any attribute of the message was indexed, we need
365 to fetch the old record */
366 ret = ltdb_search_dn1(module, dn, msg);
367 if (ret != 1) {
368 /* not finding the old record is an error */
369 talloc_free(msg);
370 return LDB_ERR_NO_SUCH_OBJECT;
373 ret = ltdb_delete_noindex(module, dn);
374 if (ret != LDB_SUCCESS) {
375 talloc_free(msg);
376 return LDB_ERR_NO_SUCH_OBJECT;
379 /* remove any indexed attributes */
380 ret = ltdb_index_del(module, msg);
381 if (ret != LDB_SUCCESS) {
382 talloc_free(msg);
383 return LDB_ERR_OPERATIONS_ERROR;
386 ret = ltdb_modified(module, dn);
387 if (ret != LDB_SUCCESS) {
388 return LDB_ERR_OPERATIONS_ERROR;
391 talloc_free(msg);
392 return LDB_SUCCESS;
396 delete a record from the database
398 static int ltdb_delete(struct ldb_module *module, struct ldb_request *req)
400 struct ltdb_private *ltdb = talloc_get_type(module->private_data, struct ltdb_private);
401 struct ltdb_context *ltdb_ac;
402 int tret, ret = LDB_SUCCESS;
404 if (req->controls != NULL) {
405 ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Controls should not reach the ldb_tdb backend!\n");
406 if (check_critical_controls(req->controls)) {
407 return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
411 req->handle = NULL;
413 if (ltdb_cache_load(module) != 0) {
414 return LDB_ERR_OPERATIONS_ERROR;
417 req->handle = init_ltdb_handle(ltdb, module, req->context, req->callback);
418 if (req->handle == NULL) {
419 return LDB_ERR_OPERATIONS_ERROR;
421 ltdb_ac = talloc_get_type(req->handle->private_data, struct ltdb_context);
423 tret = ltdb_delete_internal(module, req->op.del.dn);
424 if (tret != LDB_SUCCESS) {
425 req->handle->status = tret;
426 goto done;
429 if (ltdb_ac->callback) {
430 ret = ltdb_ac->callback(module->ldb, ltdb_ac->context, NULL);
432 done:
433 req->handle->state = LDB_ASYNC_DONE;
434 return ret;
438 find an element by attribute name. At the moment this does a linear search, it should
439 be re-coded to use a binary search once all places that modify records guarantee
440 sorted order
442 return the index of the first matching element if found, otherwise -1
444 static int find_element(const struct ldb_message *msg, const char *name)
446 unsigned int i;
447 for (i=0;i<msg->num_elements;i++) {
448 if (ldb_attr_cmp(msg->elements[i].name, name) == 0) {
449 return i;
452 return -1;
457 add an element to an existing record. Assumes a elements array that we
458 can call re-alloc on, and assumed that we can re-use the data pointers from the
459 passed in additional values. Use with care!
461 returns 0 on success, -1 on failure (and sets errno)
463 static int msg_add_element(struct ldb_context *ldb,
464 struct ldb_message *msg, struct ldb_message_element *el)
466 struct ldb_message_element *e2;
467 unsigned int i;
469 e2 = talloc_realloc(msg, msg->elements, struct ldb_message_element,
470 msg->num_elements+1);
471 if (!e2) {
472 errno = ENOMEM;
473 return -1;
476 msg->elements = e2;
478 e2 = &msg->elements[msg->num_elements];
480 e2->name = el->name;
481 e2->flags = el->flags;
482 e2->values = NULL;
483 if (el->num_values != 0) {
484 e2->values = talloc_array(msg->elements, struct ldb_val, el->num_values);
485 if (!e2->values) {
486 errno = ENOMEM;
487 return -1;
490 for (i=0;i<el->num_values;i++) {
491 e2->values[i] = el->values[i];
493 e2->num_values = el->num_values;
495 msg->num_elements++;
497 return 0;
501 delete all elements having a specified attribute name
503 static int msg_delete_attribute(struct ldb_module *module,
504 struct ldb_context *ldb,
505 struct ldb_message *msg, const char *name)
507 char *dn;
508 unsigned int i, j;
510 dn = ldb_dn_linearize(ldb, msg->dn);
511 if (dn == NULL) {
512 return -1;
515 for (i=0;i<msg->num_elements;i++) {
516 if (ldb_attr_cmp(msg->elements[i].name, name) == 0) {
517 for (j=0;j<msg->elements[i].num_values;j++) {
518 ltdb_index_del_value(module, dn, &msg->elements[i], j);
520 talloc_free(msg->elements[i].values);
521 if (msg->num_elements > (i+1)) {
522 memmove(&msg->elements[i],
523 &msg->elements[i+1],
524 sizeof(struct ldb_message_element)*
525 (msg->num_elements - (i+1)));
527 msg->num_elements--;
528 i--;
529 msg->elements = talloc_realloc(msg, msg->elements,
530 struct ldb_message_element,
531 msg->num_elements);
535 talloc_free(dn);
536 return 0;
540 delete all elements matching an attribute name/value
542 return 0 on success, -1 on failure
544 static int msg_delete_element(struct ldb_module *module,
545 struct ldb_message *msg,
546 const char *name,
547 const struct ldb_val *val)
549 struct ldb_context *ldb = module->ldb;
550 unsigned int i;
551 int found;
552 struct ldb_message_element *el;
553 const struct ldb_attrib_handler *h;
555 found = find_element(msg, name);
556 if (found == -1) {
557 return -1;
560 el = &msg->elements[found];
562 h = ldb_attrib_handler(ldb, el->name);
564 for (i=0;i<el->num_values;i++) {
565 if (h->comparison_fn(ldb, ldb, &el->values[i], val) == 0) {
566 if (i<el->num_values-1) {
567 memmove(&el->values[i], &el->values[i+1],
568 sizeof(el->values[i])*(el->num_values-(i+1)));
570 el->num_values--;
571 if (el->num_values == 0) {
572 return msg_delete_attribute(module, ldb, msg, name);
574 return 0;
578 return -1;
583 modify a record - internal interface
585 yuck - this is O(n^2). Luckily n is usually small so we probably
586 get away with it, but if we ever have really large attribute lists
587 then we'll need to look at this again
589 int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *msg)
591 struct ldb_context *ldb = module->ldb;
592 struct ltdb_private *ltdb = module->private_data;
593 TDB_DATA tdb_key, tdb_data;
594 struct ldb_message *msg2;
595 unsigned i, j;
596 int ret;
598 tdb_key = ltdb_key(module, msg->dn);
599 if (!tdb_key.dptr) {
600 return LDB_ERR_OTHER;
603 tdb_data = tdb_fetch(ltdb->tdb, tdb_key);
604 if (!tdb_data.dptr) {
605 talloc_free(tdb_key.dptr);
606 return ltdb_err_map(tdb_error(ltdb->tdb));
609 msg2 = talloc(tdb_key.dptr, struct ldb_message);
610 if (msg2 == NULL) {
611 talloc_free(tdb_key.dptr);
612 return LDB_ERR_OTHER;
615 ret = ltdb_unpack_data(module, &tdb_data, msg2);
616 if (ret == -1) {
617 ret = LDB_ERR_OTHER;
618 goto failed;
621 if (!msg2->dn) {
622 msg2->dn = msg->dn;
625 for (i=0;i<msg->num_elements;i++) {
626 struct ldb_message_element *el = &msg->elements[i];
627 struct ldb_message_element *el2;
628 struct ldb_val *vals;
629 char *dn;
631 switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) {
633 case LDB_FLAG_MOD_ADD:
634 /* add this element to the message. fail if it
635 already exists */
636 ret = find_element(msg2, el->name);
638 if (ret == -1) {
639 if (msg_add_element(ldb, msg2, el) != 0) {
640 ret = LDB_ERR_OTHER;
641 goto failed;
643 continue;
646 el2 = &msg2->elements[ret];
648 /* An attribute with this name already exists, add all
649 * values if they don't already exist. */
651 for (j=0;j<el->num_values;j++) {
652 if (ldb_msg_find_val(el2, &el->values[j])) {
653 ldb_set_errstring(module->ldb, "Type or value exists");
654 ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
655 goto failed;
659 vals = talloc_realloc(msg2->elements, el2->values, struct ldb_val,
660 el2->num_values + el->num_values);
662 if (vals == NULL) {
663 ret = LDB_ERR_OTHER;
664 goto failed;
667 for (j=0;j<el->num_values;j++) {
668 vals[el2->num_values + j] =
669 ldb_val_dup(vals, &el->values[j]);
672 el2->values = vals;
673 el2->num_values += el->num_values;
675 break;
677 case LDB_FLAG_MOD_REPLACE:
678 /* replace all elements of this attribute name with the elements
679 listed. The attribute not existing is not an error */
680 msg_delete_attribute(module, ldb, msg2, msg->elements[i].name);
682 /* add the replacement element, if not empty */
683 if (msg->elements[i].num_values != 0 &&
684 msg_add_element(ldb, msg2, &msg->elements[i]) != 0) {
685 ret = LDB_ERR_OTHER;
686 goto failed;
688 break;
690 case LDB_FLAG_MOD_DELETE:
692 dn = ldb_dn_linearize(msg2, msg->dn);
693 if (dn == NULL) {
694 ret = LDB_ERR_OTHER;
695 goto failed;
698 /* we could be being asked to delete all
699 values or just some values */
700 if (msg->elements[i].num_values == 0) {
701 if (msg_delete_attribute(module, ldb, msg2,
702 msg->elements[i].name) != 0) {
703 ldb_asprintf_errstring(module->ldb, "No such attribute: %s for delete on %s", msg->elements[i].name, dn);
704 ret = LDB_ERR_NO_SUCH_ATTRIBUTE;
705 goto failed;
707 break;
709 for (j=0;j<msg->elements[i].num_values;j++) {
710 if (msg_delete_element(module,
711 msg2,
712 msg->elements[i].name,
713 &msg->elements[i].values[j]) != 0) {
714 ldb_asprintf_errstring(module->ldb, "No matching attribute value when deleting attribute: %s on %s", msg->elements[i].name, dn);
715 ret = LDB_ERR_NO_SUCH_ATTRIBUTE;
716 goto failed;
718 if (ltdb_index_del_value(module, dn, &msg->elements[i], j) != 0) {
719 ret = LDB_ERR_OTHER;
720 goto failed;
723 break;
724 default:
725 ldb_asprintf_errstring(module->ldb, "Invalid ldb_modify flags on %s: 0x%x",
726 msg->elements[i].name,
727 msg->elements[i].flags & LDB_FLAG_MOD_MASK);
728 ret = LDB_ERR_PROTOCOL_ERROR;
729 goto failed;
733 /* we've made all the mods - save the modified record back into the database */
734 ret = ltdb_store(module, msg2, TDB_MODIFY);
735 if (ret != LDB_SUCCESS) {
736 goto failed;
739 if (ltdb_modified(module, msg->dn) != LDB_SUCCESS) {
740 ret = LDB_ERR_OPERATIONS_ERROR;
741 goto failed;
744 talloc_free(tdb_key.dptr);
745 free(tdb_data.dptr);
746 return ret;
748 failed:
749 talloc_free(tdb_key.dptr);
750 free(tdb_data.dptr);
751 return ret;
755 modify a record
757 static int ltdb_modify(struct ldb_module *module, struct ldb_request *req)
759 struct ltdb_private *ltdb = talloc_get_type(module->private_data, struct ltdb_private);
760 struct ltdb_context *ltdb_ac;
761 int tret, ret = LDB_SUCCESS;
763 if (req->controls != NULL) {
764 ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Controls should not reach the ldb_tdb backend!\n");
765 if (check_critical_controls(req->controls)) {
766 return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
770 req->handle = NULL;
772 req->handle = init_ltdb_handle(ltdb, module, req->context, req->callback);
773 if (req->handle == NULL) {
774 return LDB_ERR_OPERATIONS_ERROR;
776 ltdb_ac = talloc_get_type(req->handle->private_data, struct ltdb_context);
778 tret = ltdb_check_special_dn(module, req->op.mod.message);
779 if (tret != LDB_SUCCESS) {
780 req->handle->status = tret;
781 goto done;
784 if (ltdb_cache_load(module) != 0) {
785 ret = LDB_ERR_OPERATIONS_ERROR;
786 goto done;
789 tret = ltdb_modify_internal(module, req->op.mod.message);
790 if (tret != LDB_SUCCESS) {
791 req->handle->status = tret;
792 goto done;
795 if (ltdb_ac->callback) {
796 ret = ltdb_ac->callback(module->ldb, ltdb_ac->context, NULL);
798 done:
799 req->handle->state = LDB_ASYNC_DONE;
800 return ret;
804 rename a record
806 static int ltdb_rename(struct ldb_module *module, struct ldb_request *req)
808 struct ltdb_private *ltdb = talloc_get_type(module->private_data, struct ltdb_private);
809 struct ltdb_context *ltdb_ac;
810 struct ldb_message *msg;
811 int tret, ret = LDB_SUCCESS;
813 if (req->controls != NULL) {
814 ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Controls should not reach the ldb_tdb backend!\n");
815 if (check_critical_controls(req->controls)) {
816 return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
820 req->handle = NULL;
822 if (ltdb_cache_load(module) != 0) {
823 return LDB_ERR_OPERATIONS_ERROR;
826 req->handle = init_ltdb_handle(ltdb, module, req->context, req->callback);
827 if (req->handle == NULL) {
828 return LDB_ERR_OPERATIONS_ERROR;
830 ltdb_ac = talloc_get_type(req->handle->private_data, struct ltdb_context);
832 msg = talloc(ltdb_ac, struct ldb_message);
833 if (msg == NULL) {
834 ret = LDB_ERR_OPERATIONS_ERROR;
835 goto done;
838 /* in case any attribute of the message was indexed, we need
839 to fetch the old record */
840 tret = ltdb_search_dn1(module, req->op.rename.olddn, msg);
841 if (tret != 1) {
842 /* not finding the old record is an error */
843 req->handle->status = LDB_ERR_NO_SUCH_OBJECT;
844 goto done;
847 msg->dn = ldb_dn_copy(msg, req->op.rename.newdn);
848 if (!msg->dn) {
849 ret = LDB_ERR_OPERATIONS_ERROR;
850 goto done;
853 tret = ltdb_add_internal(module, msg);
854 if (tret != LDB_SUCCESS) {
855 ret = LDB_ERR_OPERATIONS_ERROR;
856 goto done;
859 tret = ltdb_delete_internal(module, req->op.rename.olddn);
860 if (tret != LDB_SUCCESS) {
861 ltdb_delete_internal(module, req->op.rename.newdn);
862 ret = LDB_ERR_OPERATIONS_ERROR;
863 goto done;
866 if (ltdb_ac->callback) {
867 ret = ltdb_ac->callback(module->ldb, ltdb_ac->context, NULL);
869 done:
870 req->handle->state = LDB_ASYNC_DONE;
871 return ret;
874 static int ltdb_start_trans(struct ldb_module *module)
876 struct ltdb_private *ltdb = module->private_data;
878 if (tdb_transaction_start(ltdb->tdb) != 0) {
879 return ltdb_err_map(tdb_error(ltdb->tdb));
882 return LDB_SUCCESS;
885 static int ltdb_end_trans(struct ldb_module *module)
887 struct ltdb_private *ltdb = module->private_data;
889 if (tdb_transaction_commit(ltdb->tdb) != 0) {
890 return ltdb_err_map(tdb_error(ltdb->tdb));
893 return LDB_SUCCESS;
896 static int ltdb_del_trans(struct ldb_module *module)
898 struct ltdb_private *ltdb = module->private_data;
900 if (tdb_transaction_cancel(ltdb->tdb) != 0) {
901 return ltdb_err_map(tdb_error(ltdb->tdb));
904 return LDB_SUCCESS;
907 static int ltdb_wait(struct ldb_handle *handle, enum ldb_wait_type type)
909 return handle->status;
912 static int ltdb_request(struct ldb_module *module, struct ldb_request *req)
914 /* check for oustanding critical controls and return an error if found */
915 if (req->controls != NULL) {
916 ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Controls should not reach the ldb_tdb backend!\n");
917 if (check_critical_controls(req->controls)) {
918 return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
922 /* search, add, modify, delete, rename are handled by their own, no other op supported */
923 return LDB_ERR_OPERATIONS_ERROR;
927 return sequenceNumber from @BASEINFO
929 static int ltdb_sequence_number(struct ldb_module *module, struct ldb_request *req)
931 TALLOC_CTX *tmp_ctx = talloc_new(req);
932 struct ldb_message *msg = NULL;
933 struct ldb_dn *dn = ldb_dn_explode(tmp_ctx, LTDB_BASEINFO);
934 int tret;
936 if (tmp_ctx == NULL) {
937 talloc_free(tmp_ctx);
938 return LDB_ERR_OPERATIONS_ERROR;
941 msg = talloc(tmp_ctx, struct ldb_message);
942 if (msg == NULL) {
943 talloc_free(tmp_ctx);
944 return LDB_ERR_OPERATIONS_ERROR;
947 req->op.seq_num.flags = 0;
949 tret = ltdb_search_dn1(module, dn, msg);
950 if (tret != 1) {
951 talloc_free(tmp_ctx);
952 req->op.seq_num.seq_num = 0;
953 /* zero is as good as anything when we don't know */
954 return LDB_SUCCESS;
957 switch (req->op.seq_num.type) {
958 case LDB_SEQ_HIGHEST_SEQ:
959 req->op.seq_num.seq_num = ldb_msg_find_attr_as_uint64(msg, LTDB_SEQUENCE_NUMBER, 0);
960 break;
961 case LDB_SEQ_NEXT:
962 req->op.seq_num.seq_num = ldb_msg_find_attr_as_uint64(msg, LTDB_SEQUENCE_NUMBER, 0);
963 req->op.seq_num.seq_num++;
964 break;
965 case LDB_SEQ_HIGHEST_TIMESTAMP:
967 const char *date = ldb_msg_find_attr_as_string(msg, LTDB_MOD_TIMESTAMP, NULL);
968 if (date) {
969 req->op.seq_num.seq_num = ldb_string_to_time(date);
970 } else {
971 req->op.seq_num.seq_num = 0;
972 /* zero is as good as anything when we don't know */
974 break;
977 talloc_free(tmp_ctx);
978 return LDB_SUCCESS;
981 static const struct ldb_module_ops ltdb_ops = {
982 .name = "tdb",
983 .search = ltdb_search,
984 .add = ltdb_add,
985 .modify = ltdb_modify,
986 .del = ltdb_delete,
987 .rename = ltdb_rename,
988 .request = ltdb_request,
989 .start_transaction = ltdb_start_trans,
990 .end_transaction = ltdb_end_trans,
991 .del_transaction = ltdb_del_trans,
992 .wait = ltdb_wait,
993 .sequence_number = ltdb_sequence_number
997 connect to the database
999 static int ltdb_connect(struct ldb_context *ldb, const char *url,
1000 unsigned int flags, const char *options[],
1001 struct ldb_module **module)
1003 const char *path;
1004 int tdb_flags, open_flags;
1005 struct ltdb_private *ltdb;
1007 /* parse the url */
1008 if (strchr(url, ':')) {
1009 if (strncmp(url, "tdb://", 6) != 0) {
1010 ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid tdb URL '%s'", url);
1011 return -1;
1013 path = url+6;
1014 } else {
1015 path = url;
1018 tdb_flags = TDB_DEFAULT;
1020 /* check for the 'nosync' option */
1021 if (flags & LDB_FLG_NOSYNC) {
1022 tdb_flags |= TDB_NOSYNC;
1025 if (flags & LDB_FLG_RDONLY) {
1026 open_flags = O_RDONLY;
1027 } else {
1028 open_flags = O_CREAT | O_RDWR;
1031 ltdb = talloc_zero(ldb, struct ltdb_private);
1032 if (!ltdb) {
1033 ldb_oom(ldb);
1034 return -1;
1037 /* note that we use quite a large default hash size */
1038 ltdb->tdb = ltdb_wrap_open(ltdb, path, 10000,
1039 tdb_flags, open_flags, 0644, ldb);
1040 if (!ltdb->tdb) {
1041 ldb_debug(ldb, LDB_DEBUG_ERROR, "Unable to open tdb '%s'\n", path);
1042 talloc_free(ltdb);
1043 return -1;
1046 ltdb->sequence_number = 0;
1048 *module = talloc(ldb, struct ldb_module);
1049 if (!module) {
1050 ldb_oom(ldb);
1051 talloc_free(ltdb);
1052 return -1;
1054 (*module)->ldb = ldb;
1055 (*module)->prev = (*module)->next = NULL;
1056 (*module)->private_data = ltdb;
1057 (*module)->ops = &ltdb_ops;
1059 return 0;
1062 int ldb_tdb_init(void)
1064 return ldb_register_backend("tdb", ltdb_connect);