4 Copyright (C) Andrew Tridgell 2004
5 Copyright (C) Stefan Metzmacher 2004
6 Copyright (C) Simo Sorce 2006-2008
7 Copyright (C) Matthias Dieter Wallnöfer 2009
9 ** NOTE! The following LGPL license applies to the ldb
10 ** library. This does NOT imply that all of Samba is released
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/>.
30 * Component: ldb tdb backend
32 * Description: core functions for tdb backend
34 * Author: Andrew Tridgell
35 * Author: Stefan Metzmacher
39 * - description: make the module use asyncronous calls
43 * - description: make it possible to use event contexts
47 * - description: fix up memory leaks and small bugs
49 * Author: Matthias Dieter Wallnöfer
56 map a tdb error code to a ldb error code
58 int ltdb_err_map(enum TDB_ERROR tdb_code)
66 return LDB_ERR_OPERATIONS_ERROR;
68 return LDB_ERR_PROTOCOL_ERROR;
72 case TDB_ERR_LOCK_TIMEOUT:
73 return LDB_ERR_TIME_LIMIT_EXCEEDED;
75 return LDB_ERR_ENTRY_ALREADY_EXISTS;
77 return LDB_ERR_NO_SUCH_OBJECT;
79 return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
85 lock the database for read - use by ltdb_search and ltdb_sequence_number
87 int ltdb_lock_read(struct ldb_module *module)
89 void *data = ldb_module_get_private(module);
90 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
93 if (ltdb->in_transaction == 0 &&
94 ltdb->read_lock_count == 0) {
95 ret = tdb_lockall_read(ltdb->tdb);
98 ltdb->read_lock_count++;
104 unlock the database after a ltdb_lock_read()
106 int ltdb_unlock_read(struct ldb_module *module)
108 void *data = ldb_module_get_private(module);
109 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
110 if (ltdb->in_transaction == 0 && ltdb->read_lock_count == 1) {
111 return tdb_unlockall_read(ltdb->tdb);
113 ltdb->read_lock_count--;
119 form a TDB_DATA for a record key
122 note that the key for a record can depend on whether the
123 dn refers to a case sensitive index record or not
125 struct TDB_DATA ltdb_key(struct ldb_module *module, struct ldb_dn *dn)
127 struct ldb_context *ldb = ldb_module_get_ctx(module);
129 char *key_str = NULL;
130 const char *dn_folded = NULL;
133 most DNs are case insensitive. The exception is index DNs for
134 case sensitive attributes
136 there are 3 cases dealt with in this code:
138 1) if the dn doesn't start with @ then uppercase the attribute
139 names and the attributes values of case insensitive attributes
140 2) if the dn starts with @ then leave it alone -
141 the indexing code handles the rest
144 dn_folded = ldb_dn_get_casefold(dn);
149 key_str = talloc_strdup(ldb, "DN=");
154 key_str = talloc_strdup_append_buffer(key_str, dn_folded);
159 key.dptr = (uint8_t *)key_str;
160 key.dsize = strlen(key_str) + 1;
172 check special dn's have valid attributes
173 currently only @ATTRIBUTES is checked
175 static int ltdb_check_special_dn(struct ldb_module *module,
176 const struct ldb_message *msg)
178 struct ldb_context *ldb = ldb_module_get_ctx(module);
181 if (! ldb_dn_is_special(msg->dn) ||
182 ! ldb_dn_check_special(msg->dn, LTDB_ATTRIBUTES)) {
186 /* we have @ATTRIBUTES, let's check attributes are fine */
187 /* should we check that we deny multivalued attributes ? */
188 for (i = 0; i < msg->num_elements; i++) {
189 if (ldb_attr_cmp(msg->elements[i].name, "distinguishedName") == 0) continue;
191 for (j = 0; j < msg->elements[i].num_values; j++) {
192 if (ltdb_check_at_attributes_values(&msg->elements[i].values[j]) != 0) {
193 ldb_set_errstring(ldb, "Invalid attribute value in an @ATTRIBUTES entry");
194 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
204 we've made a modification to a dn - possibly reindex and
205 update sequence number
207 static int ltdb_modified(struct ldb_module *module, struct ldb_dn *dn)
209 int ret = LDB_SUCCESS;
210 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
212 /* only allow modifies inside a transaction, otherwise the
214 if (ltdb->in_transaction == 0) {
215 ldb_set_errstring(ldb_module_get_ctx(module), "ltdb modify without transaction");
216 return LDB_ERR_OPERATIONS_ERROR;
219 if (ldb_dn_is_special(dn) &&
220 (ldb_dn_check_special(dn, LTDB_INDEXLIST) ||
221 ldb_dn_check_special(dn, LTDB_ATTRIBUTES)) ) {
222 ret = ltdb_reindex(module);
225 /* If the modify was to a normal record, or any special except @BASEINFO, update the seq number */
226 if (ret == LDB_SUCCESS &&
227 !(ldb_dn_is_special(dn) &&
228 ldb_dn_check_special(dn, LTDB_BASEINFO)) ) {
229 ret = ltdb_increase_sequence_number(module);
232 /* If the modify was to @OPTIONS, reload the cache */
233 if (ldb_dn_is_special(dn) &&
234 (ldb_dn_check_special(dn, LTDB_OPTIONS)) ) {
235 ret = ltdb_cache_reload(module);
242 store a record into the db
244 int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flgs)
246 void *data = ldb_module_get_private(module);
247 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
248 TDB_DATA tdb_key, tdb_data;
249 int ret = LDB_SUCCESS;
251 tdb_key = ltdb_key(module, msg->dn);
252 if (tdb_key.dptr == NULL) {
253 return LDB_ERR_OTHER;
256 ret = ltdb_pack_data(module, msg, &tdb_data);
258 talloc_free(tdb_key.dptr);
259 return LDB_ERR_OTHER;
262 ret = tdb_store(ltdb->tdb, tdb_key, tdb_data, flgs);
264 ret = ltdb_err_map(tdb_error(ltdb->tdb));
269 talloc_free(tdb_key.dptr);
270 talloc_free(tdb_data.dptr);
276 static int ltdb_add_internal(struct ldb_module *module,
277 const struct ldb_message *msg)
279 struct ldb_context *ldb = ldb_module_get_ctx(module);
280 int ret = LDB_SUCCESS, i;
282 ret = ltdb_check_special_dn(module, msg);
283 if (ret != LDB_SUCCESS) {
287 if (ltdb_cache_load(module) != 0) {
288 return LDB_ERR_OPERATIONS_ERROR;
291 for (i=0;i<msg->num_elements;i++) {
292 struct ldb_message_element *el = &msg->elements[i];
293 const struct ldb_schema_attribute *a = ldb_schema_attribute_by_name(ldb, el->name);
295 if (el->num_values == 0) {
296 ldb_asprintf_errstring(ldb, "attribute %s on %s specified, but with 0 values (illegal)",
297 el->name, ldb_dn_get_linearized(msg->dn));
298 return LDB_ERR_CONSTRAINT_VIOLATION;
300 if (a && a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) {
301 if (el->num_values > 1) {
302 ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s specified more than once",
303 el->name, ldb_dn_get_linearized(msg->dn));
304 return LDB_ERR_CONSTRAINT_VIOLATION;
309 ret = ltdb_store(module, msg, TDB_INSERT);
310 if (ret != LDB_SUCCESS) {
311 if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) {
312 ldb_asprintf_errstring(ldb,
313 "Entry %s already exists",
314 ldb_dn_get_linearized(msg->dn));
319 ret = ltdb_index_add_new(module, msg);
320 if (ret != LDB_SUCCESS) {
324 ret = ltdb_modified(module, msg->dn);
330 add a record to the database
332 static int ltdb_add(struct ltdb_context *ctx)
334 struct ldb_module *module = ctx->module;
335 struct ldb_request *req = ctx->req;
336 int ret = LDB_SUCCESS;
338 ldb_request_set_state(req, LDB_ASYNC_PENDING);
340 if (ltdb_cache_load(module) != 0) {
341 return LDB_ERR_OPERATIONS_ERROR;
344 ret = ltdb_add_internal(module, req->op.add.message);
350 delete a record from the database, not updating indexes (used for deleting
353 int ltdb_delete_noindex(struct ldb_module *module, struct ldb_dn *dn)
355 void *data = ldb_module_get_private(module);
356 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
360 tdb_key = ltdb_key(module, dn);
362 return LDB_ERR_OTHER;
365 ret = tdb_delete(ltdb->tdb, tdb_key);
366 talloc_free(tdb_key.dptr);
369 ret = ltdb_err_map(tdb_error(ltdb->tdb));
375 static int ltdb_delete_internal(struct ldb_module *module, struct ldb_dn *dn)
377 struct ldb_message *msg;
378 int ret = LDB_SUCCESS;
380 msg = talloc(module, struct ldb_message);
382 return LDB_ERR_OPERATIONS_ERROR;
385 /* in case any attribute of the message was indexed, we need
386 to fetch the old record */
387 ret = ltdb_search_dn1(module, dn, msg);
388 if (ret != LDB_SUCCESS) {
389 /* not finding the old record is an error */
393 ret = ltdb_delete_noindex(module, dn);
394 if (ret != LDB_SUCCESS) {
398 /* remove any indexed attributes */
399 ret = ltdb_index_delete(module, msg);
400 if (ret != LDB_SUCCESS) {
404 ret = ltdb_modified(module, dn);
405 if (ret != LDB_SUCCESS) {
415 delete a record from the database
417 static int ltdb_delete(struct ltdb_context *ctx)
419 struct ldb_module *module = ctx->module;
420 struct ldb_request *req = ctx->req;
421 int ret = LDB_SUCCESS;
423 ldb_request_set_state(req, LDB_ASYNC_PENDING);
425 if (ltdb_cache_load(module) != 0) {
426 return LDB_ERR_OPERATIONS_ERROR;
429 ret = ltdb_delete_internal(module, req->op.del.dn);
435 find an element by attribute name. At the moment this does a linear search,
436 it should be re-coded to use a binary search once all places that modify
437 records guarantee sorted order
439 return the index of the first matching element if found, otherwise -1
441 static int find_element(const struct ldb_message *msg, const char *name)
444 for (i=0;i<msg->num_elements;i++) {
445 if (ldb_attr_cmp(msg->elements[i].name, name) == 0) {
454 add an element to an existing record. Assumes a elements array that we
455 can call re-alloc on, and assumed that we can re-use the data pointers from
456 the passed in additional values. Use with care!
458 returns 0 on success, -1 on failure (and sets errno)
460 static int ltdb_msg_add_element(struct ldb_context *ldb,
461 struct ldb_message *msg,
462 struct ldb_message_element *el)
464 struct ldb_message_element *e2;
467 if (el->num_values == 0) {
468 /* nothing to do here - we don't add empty elements */
472 e2 = talloc_realloc(msg, msg->elements, struct ldb_message_element,
473 msg->num_elements+1);
481 e2 = &msg->elements[msg->num_elements];
484 e2->flags = el->flags;
485 e2->values = talloc_array(msg->elements,
486 struct ldb_val, el->num_values);
491 for (i=0;i<el->num_values;i++) {
492 e2->values[i] = el->values[i];
494 e2->num_values = el->num_values;
502 delete all elements having a specified attribute name
504 static int msg_delete_attribute(struct ldb_module *module,
505 struct ldb_context *ldb,
506 struct ldb_message *msg, const char *name)
510 struct ldb_message_element *el;
512 el = ldb_msg_find_element(msg, name);
516 i = el - msg->elements;
518 ret = ltdb_index_del_element(module, msg->dn, el);
519 if (ret != LDB_SUCCESS) {
523 talloc_free(el->values);
524 if (msg->num_elements > (i+1)) {
525 memmove(el, el+1, sizeof(*el) * (msg->num_elements - (i+1)));
528 msg->elements = talloc_realloc(msg, msg->elements,
529 struct ldb_message_element,
535 delete all elements matching an attribute name/value
537 return 0 on success, -1 on failure
539 static int msg_delete_element(struct ldb_module *module,
540 struct ldb_message *msg,
542 const struct ldb_val *val)
544 struct ldb_context *ldb = ldb_module_get_ctx(module);
547 struct ldb_message_element *el;
548 const struct ldb_schema_attribute *a;
550 found = find_element(msg, name);
555 el = &msg->elements[found];
557 a = ldb_schema_attribute_by_name(ldb, el->name);
559 for (i=0;i<el->num_values;i++) {
560 if (a->syntax->comparison_fn(ldb, ldb,
561 &el->values[i], val) == 0) {
562 if (el->num_values == 1) {
563 return msg_delete_attribute(module, ldb, msg, name);
566 ret = ltdb_index_del_value(module, msg->dn, el, i);
567 if (ret != LDB_SUCCESS) {
571 if (i<el->num_values-1) {
572 memmove(&el->values[i], &el->values[i+1],
573 sizeof(el->values[i])*
574 (el->num_values-(i+1)));
578 /* per definition we find in a canonicalised message an
579 attribute value only once. So we are finished here */
590 modify a record - internal interface
592 yuck - this is O(n^2). Luckily n is usually small so we probably
593 get away with it, but if we ever have really large attribute lists
594 then we'll need to look at this again
596 int ltdb_modify_internal(struct ldb_module *module,
597 const struct ldb_message *msg)
599 struct ldb_context *ldb = ldb_module_get_ctx(module);
600 void *data = ldb_module_get_private(module);
601 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
602 TDB_DATA tdb_key, tdb_data;
603 struct ldb_message *msg2;
605 int ret = LDB_SUCCESS, idx;
607 tdb_key = ltdb_key(module, msg->dn);
609 return LDB_ERR_OTHER;
612 tdb_data = tdb_fetch(ltdb->tdb, tdb_key);
613 if (!tdb_data.dptr) {
614 talloc_free(tdb_key.dptr);
615 return ltdb_err_map(tdb_error(ltdb->tdb));
618 msg2 = talloc(tdb_key.dptr, struct ldb_message);
625 ret = ltdb_unpack_data(module, &tdb_data, msg2);
636 for (i=0; i<msg->num_elements; i++) {
637 struct ldb_message_element *el = &msg->elements[i], *el2;
638 struct ldb_val *vals;
639 const struct ldb_schema_attribute *a = ldb_schema_attribute_by_name(ldb, el->name);
642 if (ldb_attr_cmp(el->name, "distinguishedName") == 0) {
643 ldb_asprintf_errstring(ldb, "it is not permitted to perform a modify on 'distinguishedName' (use rename instead): %s",
644 ldb_dn_get_linearized(msg2->dn));
645 ret = LDB_ERR_CONSTRAINT_VIOLATION;
649 switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) {
650 case LDB_FLAG_MOD_ADD:
651 if (el->num_values == 0) {
652 ldb_asprintf_errstring(ldb, "attribute %s on %s specified, but with 0 values (illigal)",
653 el->name, ldb_dn_get_linearized(msg2->dn));
654 ret = LDB_ERR_CONSTRAINT_VIOLATION;
658 if (a && a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) {
659 if (el->num_values > 1) {
660 ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s specified more than once",
661 el->name, ldb_dn_get_linearized(msg2->dn));
662 ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
667 /* Checks if element already exists */
668 idx = find_element(msg2, el->name);
670 if (ltdb_msg_add_element(ldb, msg2, el) != 0) {
674 ret = ltdb_index_add_element(module, msg2->dn, el);
675 if (ret != LDB_SUCCESS) {
679 /* We cannot add another value on a existing one
680 if the attribute is single-valued */
681 if (a && a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) {
682 ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s specified more than once",
683 el->name, ldb_dn_get_linearized(msg2->dn));
684 ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
688 el2 = &(msg2->elements[idx]);
690 /* Check that values don't exist yet on multi-
691 valued attributes or aren't provided twice */
692 for (j=0; j<el->num_values; j++) {
693 if (ldb_msg_find_val(el2, &el->values[j]) != NULL) {
694 ldb_asprintf_errstring(ldb, "%s: value #%d already exists", el->name, j);
695 ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
698 if (ldb_msg_find_val(el, &el->values[j]) != &el->values[j]) {
699 ldb_asprintf_errstring(ldb, "%s: value #%d provided more than once", el->name, j);
700 ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
705 /* Now combine existing and new values to a new
707 vals = talloc_realloc(msg2->elements,
708 el2->values, struct ldb_val,
709 el2->num_values + el->num_values);
716 for (j=0; j<el->num_values; j++) {
717 vals[el2->num_values + j] =
718 ldb_val_dup(vals, &el->values[j]);
722 el2->num_values += el->num_values;
724 ret = ltdb_index_add_element(module, msg2->dn, el);
725 if (ret != LDB_SUCCESS) {
732 case LDB_FLAG_MOD_REPLACE:
733 if (a && a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) {
734 if (el->num_values > 1) {
735 ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s specified more than once",
736 el->name, ldb_dn_get_linearized(msg2->dn));
737 ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
742 /* TODO: This is O(n^2) - replace with more efficient check */
743 for (j=0; j<el->num_values; j++) {
744 if (ldb_msg_find_val(el, &el->values[j]) != &el->values[j]) {
745 ldb_asprintf_errstring(ldb, "%s: value #%d provided more than once", el->name, j);
746 ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
751 idx = find_element(msg2, el->name);
753 el2 = &(msg2->elements[idx]);
754 if (ldb_msg_element_compare(el, el2) == 0) {
755 /* we are replacing with the same values */
759 /* Delete the attribute if it exists in the DB */
760 if (msg_delete_attribute(module, ldb, msg2, el->name) != 0) {
766 /* Recreate it with the new values */
767 if (ltdb_msg_add_element(ldb, msg2, el) != 0) {
772 ret = ltdb_index_add_element(module, msg2->dn, el);
773 if (ret != LDB_SUCCESS) {
779 case LDB_FLAG_MOD_DELETE:
780 dn = ldb_dn_get_linearized(msg2->dn);
786 if (msg->elements[i].num_values == 0) {
787 /* Delete the whole attribute */
788 if (msg_delete_attribute(module, ldb, msg2,
789 msg->elements[i].name) != 0) {
790 ldb_asprintf_errstring(ldb, "No such attribute: %s for delete on %s",
791 msg->elements[i].name, dn);
792 ret = LDB_ERR_NO_SUCH_ATTRIBUTE;
796 /* Delete specified values from an attribute */
797 for (j=0; j < msg->elements[i].num_values; j++) {
798 if (msg_delete_element(module,
800 msg->elements[i].name,
801 &msg->elements[i].values[j]) != 0) {
802 ldb_asprintf_errstring(ldb, "No matching attribute value when deleting attribute: %s on %s",
803 msg->elements[i].name, dn);
804 ret = LDB_ERR_NO_SUCH_ATTRIBUTE;
811 ldb_asprintf_errstring(ldb,
812 "Invalid ldb_modify flags on %s: 0x%x",
813 msg->elements[i].name,
814 msg->elements[i].flags & LDB_FLAG_MOD_MASK);
815 ret = LDB_ERR_PROTOCOL_ERROR;
820 ret = ltdb_store(module, msg2, TDB_MODIFY);
821 if (ret != LDB_SUCCESS) {
825 ret = ltdb_modified(module, msg2->dn);
826 if (ret != LDB_SUCCESS) {
831 talloc_free(tdb_key.dptr);
838 static int ltdb_modify(struct ltdb_context *ctx)
840 struct ldb_module *module = ctx->module;
841 struct ldb_request *req = ctx->req;
842 int ret = LDB_SUCCESS;
844 ret = ltdb_check_special_dn(module, req->op.mod.message);
845 if (ret != LDB_SUCCESS) {
849 ldb_request_set_state(req, LDB_ASYNC_PENDING);
851 if (ltdb_cache_load(module) != 0) {
852 return LDB_ERR_OPERATIONS_ERROR;
855 ret = ltdb_modify_internal(module, req->op.mod.message);
863 static int ltdb_rename(struct ltdb_context *ctx)
865 struct ldb_module *module = ctx->module;
866 struct ldb_request *req = ctx->req;
867 struct ldb_message *msg;
868 int ret = LDB_SUCCESS;
870 ldb_request_set_state(req, LDB_ASYNC_PENDING);
872 if (ltdb_cache_load(ctx->module) != 0) {
873 return LDB_ERR_OPERATIONS_ERROR;
876 msg = talloc(ctx, struct ldb_message);
878 return LDB_ERR_OPERATIONS_ERROR;
881 /* in case any attribute of the message was indexed, we need
882 to fetch the old record */
883 ret = ltdb_search_dn1(module, req->op.rename.olddn, msg);
884 if (ret != LDB_SUCCESS) {
885 /* not finding the old record is an error */
889 /* Always delete first then add, to avoid conflicts with
890 * unique indexes. We rely on the transaction to make this
893 ret = ltdb_delete_internal(module, msg->dn);
894 if (ret != LDB_SUCCESS) {
898 msg->dn = ldb_dn_copy(msg, req->op.rename.newdn);
899 if (msg->dn == NULL) {
900 return LDB_ERR_OPERATIONS_ERROR;
903 ret = ltdb_add_internal(module, msg);
908 static int ltdb_start_trans(struct ldb_module *module)
910 void *data = ldb_module_get_private(module);
911 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
913 if (tdb_transaction_start(ltdb->tdb) != 0) {
914 return ltdb_err_map(tdb_error(ltdb->tdb));
917 ltdb->in_transaction++;
919 ltdb_index_transaction_start(module);
924 static int ltdb_prepare_commit(struct ldb_module *module)
926 void *data = ldb_module_get_private(module);
927 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
929 if (ltdb->in_transaction != 1) {
933 if (ltdb_index_transaction_commit(module) != 0) {
934 tdb_transaction_cancel(ltdb->tdb);
935 ltdb->in_transaction--;
936 return ltdb_err_map(tdb_error(ltdb->tdb));
939 if (tdb_transaction_prepare_commit(ltdb->tdb) != 0) {
940 ltdb->in_transaction--;
941 return ltdb_err_map(tdb_error(ltdb->tdb));
944 ltdb->prepared_commit = true;
949 static int ltdb_end_trans(struct ldb_module *module)
951 void *data = ldb_module_get_private(module);
952 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
954 if (!ltdb->prepared_commit) {
955 int ret = ltdb_prepare_commit(module);
956 if (ret != LDB_SUCCESS) {
961 ltdb->in_transaction--;
962 ltdb->prepared_commit = false;
964 if (tdb_transaction_commit(ltdb->tdb) != 0) {
965 return ltdb_err_map(tdb_error(ltdb->tdb));
971 static int ltdb_del_trans(struct ldb_module *module)
973 void *data = ldb_module_get_private(module);
974 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
976 ltdb->in_transaction--;
978 if (ltdb_index_transaction_cancel(module) != 0) {
979 tdb_transaction_cancel(ltdb->tdb);
980 return ltdb_err_map(tdb_error(ltdb->tdb));
983 if (tdb_transaction_cancel(ltdb->tdb) != 0) {
984 return ltdb_err_map(tdb_error(ltdb->tdb));
991 return sequenceNumber from @BASEINFO
993 static int ltdb_sequence_number(struct ltdb_context *ctx,
994 struct ldb_extended **ext)
996 struct ldb_context *ldb;
997 struct ldb_module *module = ctx->module;
998 struct ldb_request *req = ctx->req;
1000 struct ldb_seqnum_request *seq;
1001 struct ldb_seqnum_result *res;
1002 struct ldb_message *msg = NULL;
1005 int ret = LDB_SUCCESS;
1007 ldb = ldb_module_get_ctx(module);
1009 seq = talloc_get_type(req->op.extended.data,
1010 struct ldb_seqnum_request);
1012 return LDB_ERR_OPERATIONS_ERROR;
1015 ldb_request_set_state(req, LDB_ASYNC_PENDING);
1017 if (ltdb_lock_read(module) != 0) {
1018 return LDB_ERR_OPERATIONS_ERROR;
1021 res = talloc_zero(req, struct ldb_seqnum_result);
1023 ret = LDB_ERR_OPERATIONS_ERROR;
1026 tmp_ctx = talloc_new(req);
1027 if (tmp_ctx == NULL) {
1028 ret = LDB_ERR_OPERATIONS_ERROR;
1032 dn = ldb_dn_new(tmp_ctx, ldb, LTDB_BASEINFO);
1034 msg = talloc(tmp_ctx, struct ldb_message);
1036 ret = LDB_ERR_OPERATIONS_ERROR;
1040 ret = ltdb_search_dn1(module, dn, msg);
1041 if (ret != LDB_SUCCESS) {
1045 switch (seq->type) {
1046 case LDB_SEQ_HIGHEST_SEQ:
1047 res->seq_num = ldb_msg_find_attr_as_uint64(msg, LTDB_SEQUENCE_NUMBER, 0);
1050 res->seq_num = ldb_msg_find_attr_as_uint64(msg, LTDB_SEQUENCE_NUMBER, 0);
1053 case LDB_SEQ_HIGHEST_TIMESTAMP:
1054 date = ldb_msg_find_attr_as_string(msg, LTDB_MOD_TIMESTAMP, NULL);
1056 res->seq_num = ldb_string_to_time(date);
1059 /* zero is as good as anything when we don't know */
1064 *ext = talloc_zero(req, struct ldb_extended);
1066 ret = LDB_ERR_OPERATIONS_ERROR;
1069 (*ext)->oid = LDB_EXTENDED_SEQUENCE_NUMBER;
1070 (*ext)->data = talloc_steal(*ext, res);
1073 talloc_free(tmp_ctx);
1074 ltdb_unlock_read(module);
1078 static void ltdb_request_done(struct ltdb_context *ctx, int error)
1080 struct ldb_context *ldb;
1081 struct ldb_request *req;
1082 struct ldb_reply *ares;
1084 ldb = ldb_module_get_ctx(ctx->module);
1087 /* if we already returned an error just return */
1088 if (ldb_request_get_status(req) != LDB_SUCCESS) {
1092 ares = talloc_zero(req, struct ldb_reply);
1095 req->callback(req, NULL);
1098 ares->type = LDB_REPLY_DONE;
1099 ares->error = error;
1101 req->callback(req, ares);
1104 static void ltdb_timeout(struct tevent_context *ev,
1105 struct tevent_timer *te,
1109 struct ltdb_context *ctx;
1110 ctx = talloc_get_type(private_data, struct ltdb_context);
1112 if (!ctx->request_terminated) {
1113 /* request is done now */
1114 ltdb_request_done(ctx, LDB_ERR_TIME_LIMIT_EXCEEDED);
1117 if (!ctx->request_terminated) {
1118 /* neutralize the spy */
1119 ctx->spy->ctx = NULL;
1124 static void ltdb_request_extended_done(struct ltdb_context *ctx,
1125 struct ldb_extended *ext,
1128 struct ldb_context *ldb;
1129 struct ldb_request *req;
1130 struct ldb_reply *ares;
1132 ldb = ldb_module_get_ctx(ctx->module);
1135 /* if we already returned an error just return */
1136 if (ldb_request_get_status(req) != LDB_SUCCESS) {
1140 ares = talloc_zero(req, struct ldb_reply);
1143 req->callback(req, NULL);
1146 ares->type = LDB_REPLY_DONE;
1147 ares->response = ext;
1148 ares->error = error;
1150 req->callback(req, ares);
1153 static void ltdb_handle_extended(struct ltdb_context *ctx)
1155 struct ldb_extended *ext = NULL;
1158 if (strcmp(ctx->req->op.extended.oid,
1159 LDB_EXTENDED_SEQUENCE_NUMBER) == 0) {
1160 /* get sequence number */
1161 ret = ltdb_sequence_number(ctx, &ext);
1163 /* not recognized */
1164 ret = LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
1167 ltdb_request_extended_done(ctx, ext, ret);
1170 static void ltdb_callback(struct tevent_context *ev,
1171 struct tevent_timer *te,
1175 struct ltdb_context *ctx;
1178 ctx = talloc_get_type(private_data, struct ltdb_context);
1180 if (ctx->request_terminated) {
1184 switch (ctx->req->operation) {
1186 ret = ltdb_search(ctx);
1189 ret = ltdb_add(ctx);
1192 ret = ltdb_modify(ctx);
1195 ret = ltdb_delete(ctx);
1198 ret = ltdb_rename(ctx);
1201 ltdb_handle_extended(ctx);
1204 /* no other op supported */
1205 ret = LDB_ERR_UNWILLING_TO_PERFORM;
1208 if (!ctx->request_terminated) {
1209 /* request is done now */
1210 ltdb_request_done(ctx, ret);
1214 if (!ctx->request_terminated) {
1215 /* neutralize the spy */
1216 ctx->spy->ctx = NULL;
1221 static int ltdb_request_destructor(void *ptr)
1223 struct ltdb_req_spy *spy = talloc_get_type(ptr, struct ltdb_req_spy);
1225 if (spy->ctx != NULL) {
1226 spy->ctx->request_terminated = true;
1232 static int ltdb_handle_request(struct ldb_module *module,
1233 struct ldb_request *req)
1235 struct ldb_context *ldb;
1236 struct tevent_context *ev;
1237 struct ltdb_context *ac;
1238 struct tevent_timer *te;
1242 ldb = ldb_module_get_ctx(module);
1244 for (i = 0; req->controls && req->controls[i]; i++) {
1245 if (req->controls[i]->critical) {
1246 ldb_asprintf_errstring(ldb, "Unsupported critical extension %s",
1247 req->controls[i]->oid);
1248 return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
1252 if (req->starttime == 0 || req->timeout == 0) {
1253 ldb_set_errstring(ldb, "Invalid timeout settings");
1254 return LDB_ERR_TIME_LIMIT_EXCEEDED;
1257 ev = ldb_get_event_context(ldb);
1259 ac = talloc_zero(ldb, struct ltdb_context);
1262 return LDB_ERR_OPERATIONS_ERROR;
1265 ac->module = module;
1270 te = tevent_add_timer(ev, ac, tv, ltdb_callback, ac);
1273 return LDB_ERR_OPERATIONS_ERROR;
1276 tv.tv_sec = req->starttime + req->timeout;
1277 ac->timeout_event = tevent_add_timer(ev, ac, tv, ltdb_timeout, ac);
1278 if (NULL == ac->timeout_event) {
1280 return LDB_ERR_OPERATIONS_ERROR;
1283 /* set a spy so that we do not try to use the request context
1284 * if it is freed before ltdb_callback fires */
1285 ac->spy = talloc(req, struct ltdb_req_spy);
1286 if (NULL == ac->spy) {
1288 return LDB_ERR_OPERATIONS_ERROR;
1292 talloc_set_destructor((TALLOC_CTX *)ac->spy, ltdb_request_destructor);
1297 static const struct ldb_module_ops ltdb_ops = {
1299 .search = ltdb_handle_request,
1300 .add = ltdb_handle_request,
1301 .modify = ltdb_handle_request,
1302 .del = ltdb_handle_request,
1303 .rename = ltdb_handle_request,
1304 .extended = ltdb_handle_request,
1305 .start_transaction = ltdb_start_trans,
1306 .end_transaction = ltdb_end_trans,
1307 .prepare_commit = ltdb_prepare_commit,
1308 .del_transaction = ltdb_del_trans,
1312 connect to the database
1314 static int ltdb_connect(struct ldb_context *ldb, const char *url,
1315 unsigned int flags, const char *options[],
1316 struct ldb_module **_module)
1318 struct ldb_module *module;
1320 int tdb_flags, open_flags;
1321 struct ltdb_private *ltdb;
1324 if (strchr(url, ':')) {
1325 if (strncmp(url, "tdb://", 6) != 0) {
1326 ldb_debug(ldb, LDB_DEBUG_ERROR,
1327 "Invalid tdb URL '%s'", url);
1328 return LDB_ERR_OPERATIONS_ERROR;
1335 tdb_flags = TDB_DEFAULT | TDB_SEQNUM;
1337 /* check for the 'nosync' option */
1338 if (flags & LDB_FLG_NOSYNC) {
1339 tdb_flags |= TDB_NOSYNC;
1342 /* and nommap option */
1343 if (flags & LDB_FLG_NOMMAP) {
1344 tdb_flags |= TDB_NOMMAP;
1347 if (flags & LDB_FLG_RDONLY) {
1348 open_flags = O_RDONLY;
1350 open_flags = O_CREAT | O_RDWR;
1353 ltdb = talloc_zero(ldb, struct ltdb_private);
1356 return LDB_ERR_OPERATIONS_ERROR;
1359 /* note that we use quite a large default hash size */
1360 ltdb->tdb = ltdb_wrap_open(ltdb, path, 10000,
1361 tdb_flags, open_flags,
1362 ldb_get_create_perms(ldb), ldb);
1364 ldb_debug(ldb, LDB_DEBUG_ERROR,
1365 "Unable to open tdb '%s'", path);
1367 return LDB_ERR_OPERATIONS_ERROR;
1370 ltdb->sequence_number = 0;
1372 module = ldb_module_new(ldb, ldb, "ldb_tdb backend", <db_ops);
1375 return LDB_ERR_OPERATIONS_ERROR;
1377 ldb_module_set_private(module, ltdb);
1378 talloc_steal(module, ltdb);
1380 if (ltdb_cache_load(module) != 0) {
1381 talloc_free(module);
1383 return LDB_ERR_OPERATIONS_ERROR;
1390 const struct ldb_backend_ops ldb_tdb_backend_ops = {
1392 .connect_fn = ltdb_connect