Fix bug #9147 - winbind can't fetch user or group info from AD via LDAP
[Samba.git] / source3 / lib / ldb / ldb_tdb / ldb_tdb.c
blob27cc0c69c6b2b9b9e7b454a9e3c9ecf1c58c286f
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 3 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, see <http://www.gnu.org/licenses/>.
28 * Name: ldb_tdb
30 * Component: ldb tdb backend
32 * Description: core functions for tdb backend
34 * Author: Andrew Tridgell
35 * Author: Stefan Metzmacher
37 * Modifications:
39 * - description: make the module use asyncronous calls
40 * date: Feb 2006
41 * Author: Simo Sorce
44 #include "includes.h"
45 #include "ldb/include/includes.h"
47 #include "ldb/ldb_tdb/ldb_tdb.h"
49 int ltdb_check_special_dn(struct ldb_module *module, const struct ldb_message *msg);
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 struct ldb_request *req)
84 struct ltdb_context *ac;
85 struct ldb_handle *h;
87 h = talloc_zero(req, struct ldb_handle);
88 if (h == NULL) {
89 ldb_set_errstring(module->ldb, "Out of Memory");
90 return NULL;
93 h->module = module;
95 ac = talloc_zero(h, struct ltdb_context);
96 if (ac == NULL) {
97 ldb_set_errstring(module->ldb, "Out of Memory");
98 talloc_free(h);
99 return NULL;
102 h->private_data = (void *)ac;
104 h->state = LDB_ASYNC_INIT;
105 h->status = LDB_SUCCESS;
107 ac->module = module;
108 ac->context = req->context;
109 ac->callback = req->callback;
111 return h;
115 form a TDB_DATA for a record key
116 caller frees
118 note that the key for a record can depend on whether the
119 dn refers to a case sensitive index record or not
121 struct TDB_DATA ltdb_key(struct ldb_module *module, const struct ldb_dn *dn)
123 struct ldb_context *ldb = module->ldb;
124 TDB_DATA key;
125 char *key_str = NULL;
126 char *dn_folded = NULL;
129 most DNs are case insensitive. The exception is index DNs for
130 case sensitive attributes
132 there are 3 cases dealt with in this code:
134 1) if the dn doesn't start with @ then uppercase the attribute
135 names and the attributes values of case insensitive attributes
136 2) if the dn starts with @ then leave it alone - the indexing code handles
137 the rest
140 dn_folded = ldb_dn_linearize_casefold(ldb, ldb, dn);
141 if (!dn_folded) {
142 goto failed;
145 key_str = talloc_asprintf(ldb, "DN=%s", dn_folded);
147 talloc_free(dn_folded);
149 if (!key_str) {
150 goto failed;
153 key.dptr = (uint8_t *)key_str;
154 key.dsize = strlen(key_str) + 1;
156 return key;
158 failed:
159 errno = ENOMEM;
160 key.dptr = NULL;
161 key.dsize = 0;
162 return key;
166 check special dn's have valid attributes
167 currently only @ATTRIBUTES is checked
169 int ltdb_check_special_dn(struct ldb_module *module, const struct ldb_message *msg)
171 int i, j;
173 if (! ldb_dn_is_special(msg->dn) ||
174 ! ldb_dn_check_special(msg->dn, LTDB_ATTRIBUTES)) {
175 return 0;
178 /* we have @ATTRIBUTES, let's check attributes are fine */
179 /* should we check that we deny multivalued attributes ? */
180 for (i = 0; i < msg->num_elements; i++) {
181 for (j = 0; j < msg->elements[i].num_values; j++) {
182 if (ltdb_check_at_attributes_values(&msg->elements[i].values[j]) != 0) {
183 ldb_set_errstring(module->ldb, "Invalid attribute value in an @ATTRIBUTES entry");
184 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
189 return 0;
194 we've made a modification to a dn - possibly reindex and
195 update sequence number
197 static int ltdb_modified(struct ldb_module *module, const struct ldb_dn *dn)
199 int ret = 0;
201 if (ldb_dn_is_special(dn) &&
202 (ldb_dn_check_special(dn, LTDB_INDEXLIST) ||
203 ldb_dn_check_special(dn, LTDB_ATTRIBUTES)) ) {
204 ret = ltdb_reindex(module);
207 if (ret == 0 &&
208 !(ldb_dn_is_special(dn) &&
209 ldb_dn_check_special(dn, LTDB_BASEINFO)) ) {
210 ret = ltdb_increase_sequence_number(module);
213 return ret;
217 store a record into the db
219 int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flgs)
221 struct ltdb_private *ltdb =
222 talloc_get_type(module->private_data, struct ltdb_private);
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);
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 =
336 talloc_get_type(module->private_data, struct ltdb_private);
337 TDB_DATA tdb_key;
338 int ret;
340 tdb_key = ltdb_key(module, dn);
341 if (!tdb_key.dptr) {
342 return LDB_ERR_OTHER;
345 ret = tdb_delete(ltdb->tdb, tdb_key);
346 talloc_free(tdb_key.dptr);
348 if (ret != 0) {
349 ret = ltdb_err_map(tdb_error(ltdb->tdb));
352 return ret;
355 static int ltdb_delete_internal(struct ldb_module *module, const struct ldb_dn *dn)
357 struct ldb_message *msg;
358 int ret;
360 msg = talloc(module, struct ldb_message);
361 if (msg == NULL) {
362 return LDB_ERR_OPERATIONS_ERROR;
365 /* in case any attribute of the message was indexed, we need
366 to fetch the old record */
367 ret = ltdb_search_dn1(module, dn, msg);
368 if (ret != 1) {
369 /* not finding the old record is an error */
370 talloc_free(msg);
371 return LDB_ERR_NO_SUCH_OBJECT;
374 ret = ltdb_delete_noindex(module, dn);
375 if (ret != LDB_SUCCESS) {
376 talloc_free(msg);
377 return LDB_ERR_NO_SUCH_OBJECT;
380 /* remove any indexed attributes */
381 ret = ltdb_index_del(module, msg);
382 if (ret != LDB_SUCCESS) {
383 talloc_free(msg);
384 return LDB_ERR_OPERATIONS_ERROR;
387 ret = ltdb_modified(module, dn);
388 if (ret != LDB_SUCCESS) {
389 talloc_free(msg);
390 return LDB_ERR_OPERATIONS_ERROR;
393 talloc_free(msg);
394 return LDB_SUCCESS;
398 delete a record from the database
400 static int ltdb_delete(struct ldb_module *module, struct ldb_request *req)
402 struct ltdb_private *ltdb = talloc_get_type(module->private_data, struct ltdb_private);
403 struct ltdb_context *ltdb_ac;
404 int tret, ret = LDB_SUCCESS;
406 if (req->controls != NULL) {
407 ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Controls should not reach the ldb_tdb backend!\n");
408 if (check_critical_controls(req->controls)) {
409 return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
413 req->handle = NULL;
415 if (ltdb_cache_load(module) != 0) {
416 return LDB_ERR_OPERATIONS_ERROR;
419 req->handle = init_ltdb_handle(ltdb, module, req);
420 if (req->handle == NULL) {
421 return LDB_ERR_OPERATIONS_ERROR;
423 ltdb_ac = talloc_get_type(req->handle->private_data, struct ltdb_context);
425 tret = ltdb_delete_internal(module, req->op.del.dn);
426 if (tret != LDB_SUCCESS) {
427 req->handle->status = tret;
428 goto done;
431 if (ltdb_ac->callback) {
432 ret = ltdb_ac->callback(module->ldb, ltdb_ac->context, NULL);
434 done:
435 req->handle->state = LDB_ASYNC_DONE;
436 return ret;
440 find an element by attribute name. At the moment this does a linear search, it should
441 be re-coded to use a binary search once all places that modify records guarantee
442 sorted order
444 return the index of the first matching element if found, otherwise -1
446 static int find_element(const struct ldb_message *msg, const char *name)
448 unsigned int i;
449 for (i=0;i<msg->num_elements;i++) {
450 if (ldb_attr_cmp(msg->elements[i].name, name) == 0) {
451 return i;
454 return -1;
459 add an element to an existing record. Assumes a elements array that we
460 can call re-alloc on, and assumed that we can re-use the data pointers from the
461 passed in additional values. Use with care!
463 returns 0 on success, -1 on failure (and sets errno)
465 static int msg_add_element(struct ldb_context *ldb,
466 struct ldb_message *msg, struct ldb_message_element *el)
468 struct ldb_message_element *e2;
469 unsigned int i;
471 e2 = talloc_realloc(msg, msg->elements, struct ldb_message_element,
472 msg->num_elements+1);
473 if (!e2) {
474 errno = ENOMEM;
475 return -1;
478 msg->elements = e2;
480 e2 = &msg->elements[msg->num_elements];
482 e2->name = el->name;
483 e2->flags = el->flags;
484 e2->values = NULL;
485 if (el->num_values != 0) {
486 e2->values = talloc_array(msg->elements, struct ldb_val, el->num_values);
487 if (!e2->values) {
488 errno = ENOMEM;
489 return -1;
492 for (i=0;i<el->num_values;i++) {
493 e2->values[i] = el->values[i];
495 e2->num_values = el->num_values;
497 msg->num_elements++;
499 return 0;
503 delete all elements having a specified attribute name
505 static int msg_delete_attribute(struct ldb_module *module,
506 struct ldb_context *ldb,
507 struct ldb_message *msg, const char *name)
509 char *dn;
510 unsigned int i, j;
512 dn = ldb_dn_linearize(ldb, msg->dn);
513 if (dn == NULL) {
514 return -1;
517 for (i=0;i<msg->num_elements;i++) {
518 if (ldb_attr_cmp(msg->elements[i].name, name) == 0) {
519 for (j=0;j<msg->elements[i].num_values;j++) {
520 ltdb_index_del_value(module, dn, &msg->elements[i], j);
522 talloc_free(msg->elements[i].values);
523 if (msg->num_elements > (i+1)) {
524 memmove(&msg->elements[i],
525 &msg->elements[i+1],
526 sizeof(struct ldb_message_element)*
527 (msg->num_elements - (i+1)));
529 msg->num_elements--;
530 i--;
531 msg->elements = talloc_realloc(msg, msg->elements,
532 struct ldb_message_element,
533 msg->num_elements);
537 talloc_free(dn);
538 return 0;
542 delete all elements matching an attribute name/value
544 return 0 on success, -1 on failure
546 static int msg_delete_element(struct ldb_module *module,
547 struct ldb_message *msg,
548 const char *name,
549 const struct ldb_val *val)
551 struct ldb_context *ldb = module->ldb;
552 unsigned int i;
553 int found;
554 struct ldb_message_element *el;
555 const struct ldb_attrib_handler *h;
557 found = find_element(msg, name);
558 if (found == -1) {
559 return -1;
562 el = &msg->elements[found];
564 h = ldb_attrib_handler(ldb, el->name);
566 for (i=0;i<el->num_values;i++) {
567 if (h->comparison_fn(ldb, ldb, &el->values[i], val) == 0) {
568 if (i<el->num_values-1) {
569 memmove(&el->values[i], &el->values[i+1],
570 sizeof(el->values[i])*(el->num_values-(i+1)));
572 el->num_values--;
573 if (el->num_values == 0) {
574 return msg_delete_attribute(module, ldb, msg, name);
576 return 0;
580 return -1;
585 modify a record - internal interface
587 yuck - this is O(n^2). Luckily n is usually small so we probably
588 get away with it, but if we ever have really large attribute lists
589 then we'll need to look at this again
591 int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *msg)
593 struct ldb_context *ldb = module->ldb;
594 struct ltdb_private *ltdb =
595 talloc_get_type(module->private_data, struct ltdb_private);
596 TDB_DATA tdb_key, tdb_data;
597 struct ldb_message *msg2;
598 unsigned i, j;
599 int ret;
601 tdb_key = ltdb_key(module, msg->dn);
602 if (!tdb_key.dptr) {
603 return LDB_ERR_OTHER;
606 tdb_data = tdb_fetch(ltdb->tdb, tdb_key);
607 if (!tdb_data.dptr) {
608 talloc_free(tdb_key.dptr);
609 return ltdb_err_map(tdb_error(ltdb->tdb));
612 msg2 = talloc(tdb_key.dptr, struct ldb_message);
613 if (msg2 == NULL) {
614 talloc_free(tdb_key.dptr);
615 return LDB_ERR_OTHER;
618 ret = ltdb_unpack_data(module, &tdb_data, msg2);
619 if (ret == -1) {
620 ret = LDB_ERR_OTHER;
621 goto failed;
624 if (!msg2->dn) {
625 msg2->dn = msg->dn;
628 for (i=0;i<msg->num_elements;i++) {
629 struct ldb_message_element *el = &msg->elements[i];
630 struct ldb_message_element *el2;
631 struct ldb_val *vals;
632 char *dn;
634 switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) {
636 case LDB_FLAG_MOD_ADD:
637 /* add this element to the message. fail if it
638 already exists */
639 ret = find_element(msg2, el->name);
641 if (ret == -1) {
642 if (msg_add_element(ldb, msg2, el) != 0) {
643 ret = LDB_ERR_OTHER;
644 goto failed;
646 continue;
649 el2 = &msg2->elements[ret];
651 /* An attribute with this name already exists, add all
652 * values if they don't already exist. */
654 for (j=0;j<el->num_values;j++) {
655 if (ldb_msg_find_val(el2, &el->values[j])) {
656 ldb_set_errstring(module->ldb, "Type or value exists");
657 ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
658 goto failed;
662 vals = talloc_realloc(msg2->elements, el2->values, struct ldb_val,
663 el2->num_values + el->num_values);
665 if (vals == NULL) {
666 ret = LDB_ERR_OTHER;
667 goto failed;
670 for (j=0;j<el->num_values;j++) {
671 vals[el2->num_values + j] =
672 ldb_val_dup(vals, &el->values[j]);
675 el2->values = vals;
676 el2->num_values += el->num_values;
678 break;
680 case LDB_FLAG_MOD_REPLACE:
681 /* replace all elements of this attribute name with the elements
682 listed. The attribute not existing is not an error */
683 msg_delete_attribute(module, ldb, msg2, msg->elements[i].name);
685 /* add the replacement element, if not empty */
686 if (msg->elements[i].num_values != 0 &&
687 msg_add_element(ldb, msg2, &msg->elements[i]) != 0) {
688 ret = LDB_ERR_OTHER;
689 goto failed;
691 break;
693 case LDB_FLAG_MOD_DELETE:
695 dn = ldb_dn_linearize(msg2, msg->dn);
696 if (dn == NULL) {
697 ret = LDB_ERR_OTHER;
698 goto failed;
701 /* we could be being asked to delete all
702 values or just some values */
703 if (msg->elements[i].num_values == 0) {
704 if (msg_delete_attribute(module, ldb, msg2,
705 msg->elements[i].name) != 0) {
706 ldb_asprintf_errstring(module->ldb, "No such attribute: %s for delete on %s", msg->elements[i].name, dn);
707 ret = LDB_ERR_NO_SUCH_ATTRIBUTE;
708 goto failed;
710 break;
712 for (j=0;j<msg->elements[i].num_values;j++) {
713 if (msg_delete_element(module,
714 msg2,
715 msg->elements[i].name,
716 &msg->elements[i].values[j]) != 0) {
717 ldb_asprintf_errstring(module->ldb, "No matching attribute value when deleting attribute: %s on %s", msg->elements[i].name, dn);
718 ret = LDB_ERR_NO_SUCH_ATTRIBUTE;
719 goto failed;
721 if (ltdb_index_del_value(module, dn, &msg->elements[i], j) != 0) {
722 ret = LDB_ERR_OTHER;
723 goto failed;
726 break;
727 default:
728 ldb_asprintf_errstring(module->ldb, "Invalid ldb_modify flags on %s: 0x%x",
729 msg->elements[i].name,
730 msg->elements[i].flags & LDB_FLAG_MOD_MASK);
731 ret = LDB_ERR_PROTOCOL_ERROR;
732 goto failed;
736 /* we've made all the mods - save the modified record back into the database */
737 ret = ltdb_store(module, msg2, TDB_MODIFY);
738 if (ret != LDB_SUCCESS) {
739 goto failed;
742 if (ltdb_modified(module, msg->dn) != LDB_SUCCESS) {
743 ret = LDB_ERR_OPERATIONS_ERROR;
744 goto failed;
747 talloc_free(tdb_key.dptr);
748 free(tdb_data.dptr);
749 return ret;
751 failed:
752 talloc_free(tdb_key.dptr);
753 free(tdb_data.dptr);
754 return ret;
758 modify a record
760 static int ltdb_modify(struct ldb_module *module, struct ldb_request *req)
762 struct ltdb_private *ltdb = talloc_get_type(module->private_data, struct ltdb_private);
763 struct ltdb_context *ltdb_ac;
764 int tret, ret = LDB_SUCCESS;
766 if (req->controls != NULL) {
767 ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Controls should not reach the ldb_tdb backend!\n");
768 if (check_critical_controls(req->controls)) {
769 return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
773 req->handle = NULL;
775 req->handle = init_ltdb_handle(ltdb, module, req);
776 if (req->handle == NULL) {
777 return LDB_ERR_OPERATIONS_ERROR;
779 ltdb_ac = talloc_get_type(req->handle->private_data, struct ltdb_context);
781 tret = ltdb_check_special_dn(module, req->op.mod.message);
782 if (tret != LDB_SUCCESS) {
783 req->handle->status = tret;
784 goto done;
787 if (ltdb_cache_load(module) != 0) {
788 ret = LDB_ERR_OPERATIONS_ERROR;
789 goto done;
792 tret = ltdb_modify_internal(module, req->op.mod.message);
793 if (tret != LDB_SUCCESS) {
794 req->handle->status = tret;
795 goto done;
798 if (ltdb_ac->callback) {
799 ret = ltdb_ac->callback(module->ldb, ltdb_ac->context, NULL);
801 done:
802 req->handle->state = LDB_ASYNC_DONE;
803 return ret;
807 rename a record
809 static int ltdb_rename(struct ldb_module *module, struct ldb_request *req)
811 struct ltdb_private *ltdb = talloc_get_type(module->private_data, struct ltdb_private);
812 struct ltdb_context *ltdb_ac;
813 struct ldb_message *msg;
814 int tret, ret = LDB_SUCCESS;
816 if (req->controls != NULL) {
817 ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Controls should not reach the ldb_tdb backend!\n");
818 if (check_critical_controls(req->controls)) {
819 return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
823 req->handle = NULL;
825 if (ltdb_cache_load(module) != 0) {
826 return LDB_ERR_OPERATIONS_ERROR;
829 req->handle = init_ltdb_handle(ltdb, module, req);
830 if (req->handle == NULL) {
831 return LDB_ERR_OPERATIONS_ERROR;
833 ltdb_ac = talloc_get_type(req->handle->private_data, struct ltdb_context);
835 msg = talloc(ltdb_ac, struct ldb_message);
836 if (msg == NULL) {
837 ret = LDB_ERR_OPERATIONS_ERROR;
838 goto done;
841 /* in case any attribute of the message was indexed, we need
842 to fetch the old record */
843 tret = ltdb_search_dn1(module, req->op.rename.olddn, msg);
844 if (tret != 1) {
845 /* not finding the old record is an error */
846 req->handle->status = LDB_ERR_NO_SUCH_OBJECT;
847 goto done;
850 msg->dn = ldb_dn_copy(msg, req->op.rename.newdn);
851 if (!msg->dn) {
852 ret = LDB_ERR_OPERATIONS_ERROR;
853 goto done;
856 tret = ltdb_add_internal(module, msg);
857 if (tret != LDB_SUCCESS) {
858 ret = LDB_ERR_OPERATIONS_ERROR;
859 goto done;
862 tret = ltdb_delete_internal(module, req->op.rename.olddn);
863 if (tret != LDB_SUCCESS) {
864 ltdb_delete_internal(module, req->op.rename.newdn);
865 ret = LDB_ERR_OPERATIONS_ERROR;
866 goto done;
869 if (ltdb_ac->callback) {
870 ret = ltdb_ac->callback(module->ldb, ltdb_ac->context, NULL);
872 done:
873 req->handle->state = LDB_ASYNC_DONE;
874 return ret;
877 static int ltdb_start_trans(struct ldb_module *module)
879 struct ltdb_private *ltdb =
880 talloc_get_type(module->private_data, struct ltdb_private);
882 if (tdb_transaction_start(ltdb->tdb) != 0) {
883 return ltdb_err_map(tdb_error(ltdb->tdb));
886 return LDB_SUCCESS;
889 static int ltdb_end_trans(struct ldb_module *module)
891 struct ltdb_private *ltdb =
892 talloc_get_type(module->private_data, struct ltdb_private);
894 if (tdb_transaction_commit(ltdb->tdb) != 0) {
895 return ltdb_err_map(tdb_error(ltdb->tdb));
898 return LDB_SUCCESS;
901 static int ltdb_del_trans(struct ldb_module *module)
903 struct ltdb_private *ltdb =
904 talloc_get_type(module->private_data, struct ltdb_private);
906 if (tdb_transaction_cancel(ltdb->tdb) != 0) {
907 return ltdb_err_map(tdb_error(ltdb->tdb));
910 return LDB_SUCCESS;
913 static int ltdb_wait(struct ldb_handle *handle, enum ldb_wait_type type)
915 return handle->status;
918 static int ltdb_request(struct ldb_module *module, struct ldb_request *req)
920 /* check for oustanding critical controls and return an error if found */
921 if (req->controls != NULL) {
922 ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Controls should not reach the ldb_tdb backend!\n");
923 if (check_critical_controls(req->controls)) {
924 return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
928 /* search, add, modify, delete, rename are handled by their own, no other op supported */
929 return LDB_ERR_OPERATIONS_ERROR;
933 return sequenceNumber from @BASEINFO
935 static int ltdb_sequence_number(struct ldb_module *module, struct ldb_request *req)
937 TALLOC_CTX *tmp_ctx = talloc_new(req);
938 struct ldb_message *msg = NULL;
939 struct ldb_dn *dn = ldb_dn_explode(tmp_ctx, LTDB_BASEINFO);
940 int tret;
942 if (tmp_ctx == NULL) {
943 talloc_free(tmp_ctx);
944 return LDB_ERR_OPERATIONS_ERROR;
947 msg = talloc(tmp_ctx, struct ldb_message);
948 if (msg == NULL) {
949 talloc_free(tmp_ctx);
950 return LDB_ERR_OPERATIONS_ERROR;
953 req->op.seq_num.flags = 0;
955 tret = ltdb_search_dn1(module, dn, msg);
956 if (tret != 1) {
957 talloc_free(tmp_ctx);
958 req->op.seq_num.seq_num = 0;
959 /* zero is as good as anything when we don't know */
960 return LDB_SUCCESS;
963 switch (req->op.seq_num.type) {
964 case LDB_SEQ_HIGHEST_SEQ:
965 req->op.seq_num.seq_num = ldb_msg_find_attr_as_uint64(msg, LTDB_SEQUENCE_NUMBER, 0);
966 break;
967 case LDB_SEQ_NEXT:
968 req->op.seq_num.seq_num = ldb_msg_find_attr_as_uint64(msg, LTDB_SEQUENCE_NUMBER, 0);
969 req->op.seq_num.seq_num++;
970 break;
971 case LDB_SEQ_HIGHEST_TIMESTAMP:
973 const char *date = ldb_msg_find_attr_as_string(msg, LTDB_MOD_TIMESTAMP, NULL);
974 if (date) {
975 req->op.seq_num.seq_num = ldb_string_to_time(date);
976 } else {
977 req->op.seq_num.seq_num = 0;
978 /* zero is as good as anything when we don't know */
980 break;
983 talloc_free(tmp_ctx);
984 return LDB_SUCCESS;
987 static const struct ldb_module_ops ltdb_ops = {
988 .name = "tdb",
989 .search = ltdb_search,
990 .add = ltdb_add,
991 .modify = ltdb_modify,
992 .del = ltdb_delete,
993 .rename = ltdb_rename,
994 .request = ltdb_request,
995 .start_transaction = ltdb_start_trans,
996 .end_transaction = ltdb_end_trans,
997 .del_transaction = ltdb_del_trans,
998 .wait = ltdb_wait,
999 .sequence_number = ltdb_sequence_number
1003 connect to the database
1005 static int ltdb_connect(struct ldb_context *ldb, const char *url,
1006 unsigned int flags, const char *options[],
1007 struct ldb_module **module)
1009 const char *path;
1010 int tdb_flags, open_flags;
1011 struct ltdb_private *ltdb;
1013 /* parse the url */
1014 if (strchr(url, ':')) {
1015 if (strncmp(url, "tdb://", 6) != 0) {
1016 ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid tdb URL '%s'", url);
1017 return -1;
1019 path = url+6;
1020 } else {
1021 path = url;
1024 tdb_flags = TDB_DEFAULT | TDB_SEQNUM;
1026 /* check for the 'nosync' option */
1027 if (flags & LDB_FLG_NOSYNC) {
1028 tdb_flags |= TDB_NOSYNC;
1031 /* and nommap option */
1032 if (flags & LDB_FLG_NOMMAP) {
1033 tdb_flags |= TDB_NOMMAP;
1036 if (flags & LDB_FLG_RDONLY) {
1037 open_flags = O_RDONLY;
1038 } else {
1039 open_flags = O_CREAT | O_RDWR;
1042 ltdb = talloc_zero(ldb, struct ltdb_private);
1043 if (!ltdb) {
1044 ldb_oom(ldb);
1045 return -1;
1048 /* note that we use quite a large default hash size */
1049 ltdb->tdb = ltdb_wrap_open(ltdb, path, 10000,
1050 tdb_flags, open_flags,
1051 ldb->create_perms, ldb);
1052 if (!ltdb->tdb) {
1053 ldb_debug(ldb, LDB_DEBUG_ERROR, "Unable to open tdb '%s'\n", path);
1054 talloc_free(ltdb);
1055 return -1;
1058 ltdb->sequence_number = 0;
1060 *module = talloc(ldb, struct ldb_module);
1061 if ((*module) == NULL) {
1062 ldb_oom(ldb);
1063 talloc_free(ltdb);
1064 return -1;
1066 talloc_set_name_const(*module, "ldb_tdb backend");
1067 (*module)->ldb = ldb;
1068 (*module)->prev = (*module)->next = NULL;
1069 (*module)->private_data = ltdb;
1070 (*module)->ops = &ltdb_ops;
1072 if (ltdb_cache_load(*module) != 0) {
1073 talloc_free(*module);
1074 talloc_free(ltdb);
1075 return -1;
1078 return 0;
1081 int ldb_tdb_init(void)
1083 return ldb_register_backend("tdb", ltdb_connect);