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);
91 if (ltdb->in_transaction == 0) {
92 return tdb_lockall_read(ltdb->tdb);
98 unlock the database after a ltdb_lock_read()
100 int ltdb_unlock_read(struct ldb_module *module)
102 void *data = ldb_module_get_private(module);
103 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
104 if (ltdb->in_transaction == 0) {
105 return tdb_unlockall_read(ltdb->tdb);
112 form a TDB_DATA for a record key
115 note that the key for a record can depend on whether the
116 dn refers to a case sensitive index record or not
118 struct TDB_DATA ltdb_key(struct ldb_module *module, struct ldb_dn *dn)
120 struct ldb_context *ldb = ldb_module_get_ctx(module);
122 char *key_str = NULL;
123 const char *dn_folded = NULL;
126 most DNs are case insensitive. The exception is index DNs for
127 case sensitive attributes
129 there are 3 cases dealt with in this code:
131 1) if the dn doesn't start with @ then uppercase the attribute
132 names and the attributes values of case insensitive attributes
133 2) if the dn starts with @ then leave it alone -
134 the indexing code handles the rest
137 dn_folded = ldb_dn_get_casefold(dn);
142 key_str = talloc_strdup(ldb, "DN=");
147 key_str = talloc_strdup_append_buffer(key_str, dn_folded);
152 key.dptr = (uint8_t *)key_str;
153 key.dsize = strlen(key_str) + 1;
165 check special dn's have valid attributes
166 currently only @ATTRIBUTES is checked
168 static int ltdb_check_special_dn(struct ldb_module *module,
169 const struct ldb_message *msg)
171 struct ldb_context *ldb = ldb_module_get_ctx(module);
174 if (! ldb_dn_is_special(msg->dn) ||
175 ! ldb_dn_check_special(msg->dn, LTDB_ATTRIBUTES)) {
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 if (ldb_attr_cmp(msg->elements[i].name, "distinguishedName") == 0) continue;
184 for (j = 0; j < msg->elements[i].num_values; j++) {
185 if (ltdb_check_at_attributes_values(&msg->elements[i].values[j]) != 0) {
186 ldb_set_errstring(ldb, "Invalid attribute value in an @ATTRIBUTES entry");
187 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
197 we've made a modification to a dn - possibly reindex and
198 update sequence number
200 static int ltdb_modified(struct ldb_module *module, struct ldb_dn *dn)
202 int ret = LDB_SUCCESS;
203 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
205 /* only allow modifies inside a transaction, otherwise the
207 if (ltdb->in_transaction == 0) {
208 ldb_set_errstring(ldb_module_get_ctx(module), "ltdb modify without transaction");
209 return LDB_ERR_OPERATIONS_ERROR;
212 if (ldb_dn_is_special(dn) &&
213 (ldb_dn_check_special(dn, LTDB_INDEXLIST) ||
214 ldb_dn_check_special(dn, LTDB_ATTRIBUTES)) ) {
215 ret = ltdb_reindex(module);
218 /* If the modify was to a normal record, or any special except @BASEINFO, update the seq number */
219 if (ret == LDB_SUCCESS &&
220 !(ldb_dn_is_special(dn) &&
221 ldb_dn_check_special(dn, LTDB_BASEINFO)) ) {
222 ret = ltdb_increase_sequence_number(module);
225 /* If the modify was to @OPTIONS, reload the cache */
226 if (ldb_dn_is_special(dn) &&
227 (ldb_dn_check_special(dn, LTDB_OPTIONS)) ) {
228 ret = ltdb_cache_reload(module);
235 store a record into the db
237 int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flgs)
239 void *data = ldb_module_get_private(module);
240 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
241 TDB_DATA tdb_key, tdb_data;
242 int ret = LDB_SUCCESS;
244 tdb_key = ltdb_key(module, msg->dn);
245 if (tdb_key.dptr == NULL) {
246 return LDB_ERR_OTHER;
249 ret = ltdb_pack_data(module, msg, &tdb_data);
251 talloc_free(tdb_key.dptr);
252 return LDB_ERR_OTHER;
255 ret = tdb_store(ltdb->tdb, tdb_key, tdb_data, flgs);
257 ret = ltdb_err_map(tdb_error(ltdb->tdb));
262 talloc_free(tdb_key.dptr);
263 talloc_free(tdb_data.dptr);
269 static int ltdb_add_internal(struct ldb_module *module,
270 const struct ldb_message *msg)
272 struct ldb_context *ldb = ldb_module_get_ctx(module);
273 int ret = LDB_SUCCESS, i;
275 ret = ltdb_check_special_dn(module, msg);
276 if (ret != LDB_SUCCESS) {
280 if (ltdb_cache_load(module) != 0) {
281 return LDB_ERR_OPERATIONS_ERROR;
284 for (i=0;i<msg->num_elements;i++) {
285 struct ldb_message_element *el = &msg->elements[i];
286 const struct ldb_schema_attribute *a = ldb_schema_attribute_by_name(ldb, el->name);
288 if (el->num_values == 0) {
289 ldb_asprintf_errstring(ldb, "attribute %s on %s specified, but with 0 values (illegal)",
290 el->name, ldb_dn_get_linearized(msg->dn));
291 return LDB_ERR_CONSTRAINT_VIOLATION;
293 if (a && a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) {
294 if (el->num_values > 1) {
295 ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s specified more than once",
296 el->name, ldb_dn_get_linearized(msg->dn));
297 return LDB_ERR_CONSTRAINT_VIOLATION;
302 ret = ltdb_store(module, msg, TDB_INSERT);
303 if (ret != LDB_SUCCESS) {
304 if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) {
305 ldb_asprintf_errstring(ldb,
306 "Entry %s already exists",
307 ldb_dn_get_linearized(msg->dn));
312 ret = ltdb_index_add_new(module, msg);
313 if (ret != LDB_SUCCESS) {
317 ret = ltdb_modified(module, msg->dn);
323 add a record to the database
325 static int ltdb_add(struct ltdb_context *ctx)
327 struct ldb_module *module = ctx->module;
328 struct ldb_request *req = ctx->req;
329 int ret = LDB_SUCCESS;
331 ldb_request_set_state(req, LDB_ASYNC_PENDING);
333 if (ltdb_cache_load(module) != 0) {
334 return LDB_ERR_OPERATIONS_ERROR;
337 ret = ltdb_add_internal(module, req->op.add.message);
343 delete a record from the database, not updating indexes (used for deleting
346 int ltdb_delete_noindex(struct ldb_module *module, struct ldb_dn *dn)
348 void *data = ldb_module_get_private(module);
349 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
353 tdb_key = ltdb_key(module, dn);
355 return LDB_ERR_OTHER;
358 ret = tdb_delete(ltdb->tdb, tdb_key);
359 talloc_free(tdb_key.dptr);
362 ret = ltdb_err_map(tdb_error(ltdb->tdb));
368 static int ltdb_delete_internal(struct ldb_module *module, struct ldb_dn *dn)
370 struct ldb_message *msg;
371 int ret = LDB_SUCCESS;
373 msg = talloc(module, struct ldb_message);
375 return LDB_ERR_OPERATIONS_ERROR;
378 /* in case any attribute of the message was indexed, we need
379 to fetch the old record */
380 ret = ltdb_search_dn1(module, dn, msg);
381 if (ret != LDB_SUCCESS) {
382 /* not finding the old record is an error */
386 ret = ltdb_delete_noindex(module, dn);
387 if (ret != LDB_SUCCESS) {
391 /* remove any indexed attributes */
392 ret = ltdb_index_delete(module, msg);
393 if (ret != LDB_SUCCESS) {
397 ret = ltdb_modified(module, dn);
398 if (ret != LDB_SUCCESS) {
408 delete a record from the database
410 static int ltdb_delete(struct ltdb_context *ctx)
412 struct ldb_module *module = ctx->module;
413 struct ldb_request *req = ctx->req;
414 int ret = LDB_SUCCESS;
416 ldb_request_set_state(req, LDB_ASYNC_PENDING);
418 if (ltdb_cache_load(module) != 0) {
419 return LDB_ERR_OPERATIONS_ERROR;
422 ret = ltdb_delete_internal(module, req->op.del.dn);
428 find an element by attribute name. At the moment this does a linear search,
429 it should be re-coded to use a binary search once all places that modify
430 records guarantee sorted order
432 return the index of the first matching element if found, otherwise -1
434 static int find_element(const struct ldb_message *msg, const char *name)
437 for (i=0;i<msg->num_elements;i++) {
438 if (ldb_attr_cmp(msg->elements[i].name, name) == 0) {
447 add an element to an existing record. Assumes a elements array that we
448 can call re-alloc on, and assumed that we can re-use the data pointers from
449 the passed in additional values. Use with care!
451 returns 0 on success, -1 on failure (and sets errno)
453 static int ltdb_msg_add_element(struct ldb_context *ldb,
454 struct ldb_message *msg,
455 struct ldb_message_element *el)
457 struct ldb_message_element *e2;
460 if (el->num_values == 0) {
461 /* nothing to do here - we don't add empty elements */
465 e2 = talloc_realloc(msg, msg->elements, struct ldb_message_element,
466 msg->num_elements+1);
474 e2 = &msg->elements[msg->num_elements];
477 e2->flags = el->flags;
478 e2->values = talloc_array(msg->elements,
479 struct ldb_val, el->num_values);
484 for (i=0;i<el->num_values;i++) {
485 e2->values[i] = el->values[i];
487 e2->num_values = el->num_values;
495 delete all elements having a specified attribute name
497 static int msg_delete_attribute(struct ldb_module *module,
498 struct ldb_context *ldb,
499 struct ldb_message *msg, const char *name)
504 struct ldb_message_element *el;
506 dn = ldb_dn_get_linearized(msg->dn);
511 el = ldb_msg_find_element(msg, name);
515 i = el - msg->elements;
517 ret = ltdb_index_del_element(module, dn, el);
518 if (ret != LDB_SUCCESS) {
522 talloc_free(el->values);
523 if (msg->num_elements > (i+1)) {
524 memmove(el, el+1, sizeof(*el) * (msg->num_elements - (i+1)));
527 msg->elements = talloc_realloc(msg, msg->elements,
528 struct ldb_message_element,
534 delete all elements matching an attribute name/value
536 return 0 on success, -1 on failure
538 static int msg_delete_element(struct ldb_module *module,
539 struct ldb_message *msg,
541 const struct ldb_val *val)
543 struct ldb_context *ldb = ldb_module_get_ctx(module);
546 struct ldb_message_element *el;
547 const struct ldb_schema_attribute *a;
549 found = find_element(msg, name);
554 el = &msg->elements[found];
556 a = ldb_schema_attribute_by_name(ldb, el->name);
558 for (i=0;i<el->num_values;i++) {
559 if (a->syntax->comparison_fn(ldb, ldb,
560 &el->values[i], val) == 0) {
561 if (el->num_values == 1) {
562 return msg_delete_attribute(module, ldb, msg, name);
565 ret = ltdb_index_del_value(module, ldb_dn_get_linearized(msg->dn), el, i);
566 if (ret != LDB_SUCCESS) {
570 if (i<el->num_values-1) {
571 memmove(&el->values[i], &el->values[i+1],
572 sizeof(el->values[i])*
573 (el->num_values-(i+1)));
577 /* per definition we find in a canonicalised message an
578 attribute value only once. So we are finished here */
589 modify a record - internal interface
591 yuck - this is O(n^2). Luckily n is usually small so we probably
592 get away with it, but if we ever have really large attribute lists
593 then we'll need to look at this again
595 int ltdb_modify_internal(struct ldb_module *module,
596 const struct ldb_message *msg)
598 struct ldb_context *ldb = ldb_module_get_ctx(module);
599 void *data = ldb_module_get_private(module);
600 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
601 TDB_DATA tdb_key, tdb_data;
602 struct ldb_message *msg2;
604 int ret = LDB_SUCCESS, idx;
606 tdb_key = ltdb_key(module, msg->dn);
608 return LDB_ERR_OTHER;
611 tdb_data = tdb_fetch(ltdb->tdb, tdb_key);
612 if (!tdb_data.dptr) {
613 talloc_free(tdb_key.dptr);
614 return ltdb_err_map(tdb_error(ltdb->tdb));
617 msg2 = talloc(tdb_key.dptr, struct ldb_message);
624 ret = ltdb_unpack_data(module, &tdb_data, msg2);
635 for (i=0; i<msg->num_elements; i++) {
636 struct ldb_message_element *el = &msg->elements[i], *el2;
637 struct ldb_val *vals;
638 const struct ldb_schema_attribute *a = ldb_schema_attribute_by_name(ldb, el->name);
641 if (ldb_attr_cmp(el->name, "distinguishedName") == 0) {
642 ldb_asprintf_errstring(ldb, "it is not permitted to perform a modify on 'distinguishedName' (use rename instead): %s",
643 ldb_dn_get_linearized(msg->dn));
644 ret = LDB_ERR_CONSTRAINT_VIOLATION;
648 switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) {
649 case LDB_FLAG_MOD_ADD:
650 if (el->num_values == 0) {
651 ldb_asprintf_errstring(ldb, "attribute %s on %s specified, but with 0 values (illigal)",
652 el->name, ldb_dn_get_linearized(msg->dn));
653 ret = LDB_ERR_CONSTRAINT_VIOLATION;
657 if (a && a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) {
658 if (el->num_values > 1) {
659 ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s specified more than once",
660 el->name, ldb_dn_get_linearized(msg->dn));
661 ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
666 /* Checks if element already exists */
667 idx = find_element(msg2, el->name);
669 if (ltdb_msg_add_element(ldb, msg2, el) != 0) {
673 ret = ltdb_index_add_element(module, msg->dn, el);
674 if (ret != LDB_SUCCESS) {
678 /* We cannot add another value on a existing one
679 if the attribute is single-valued */
680 if (a && a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) {
681 ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s specified more than once",
682 el->name, ldb_dn_get_linearized(msg->dn));
683 ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
687 el2 = &(msg2->elements[idx]);
689 /* Check that values don't exist yet on multi-
690 valued attributes or aren't provided twice */
691 for (j=0; j<el->num_values; j++) {
692 if (ldb_msg_find_val(el2, &el->values[j]) != NULL) {
693 ldb_asprintf_errstring(ldb, "%s: value #%d already exists", el->name, j);
694 ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
697 if (ldb_msg_find_val(el, &el->values[j]) != &el->values[j]) {
698 ldb_asprintf_errstring(ldb, "%s: value #%d provided more than once", el->name, j);
699 ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
704 /* Now combine existing and new values to a new
706 vals = talloc_realloc(msg2->elements,
707 el2->values, struct ldb_val,
708 el2->num_values + el->num_values);
715 for (j=0; j<el->num_values; j++) {
716 vals[el2->num_values + j] =
717 ldb_val_dup(vals, &el->values[j]);
721 el2->num_values += el->num_values;
723 ret = ltdb_index_add_element(module, msg->dn, el);
724 if (ret != LDB_SUCCESS) {
731 case LDB_FLAG_MOD_REPLACE:
732 if (a && a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) {
733 if (el->num_values > 1) {
734 ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s specified more than once",
735 el->name, ldb_dn_get_linearized(msg->dn));
736 ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
741 /* TODO: This is O(n^2) - replace with more efficient check */
742 for (j=0; j<el->num_values; j++) {
743 if (ldb_msg_find_val(el, &el->values[j]) != &el->values[j]) {
744 ldb_asprintf_errstring(ldb, "%s: value #%d provided more than once", el->name, j);
745 ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
750 idx = find_element(msg2, el->name);
752 el2 = &(msg2->elements[idx]);
753 if (ldb_msg_element_compare(el, el2) == 0) {
754 /* we are replacing with the same values */
758 /* Delete the attribute if it exists in the DB */
759 ret = msg_delete_attribute(module, ldb, msg2, el->name);
760 if (ret != LDB_SUCCESS) {
765 /* Recreate it with the new values */
766 if (ltdb_msg_add_element(ldb, msg2, el) != 0) {
771 ret = ltdb_index_add_element(module, msg->dn, el);
772 if (ret != LDB_SUCCESS) {
778 case LDB_FLAG_MOD_DELETE:
779 dn = ldb_dn_get_linearized(msg->dn);
785 if (msg->elements[i].num_values == 0) {
786 /* Delete the whole attribute */
787 if (msg_delete_attribute(module, ldb, msg2,
788 msg->elements[i].name) != 0) {
789 ldb_asprintf_errstring(ldb, "No such attribute: %s for delete on %s",
790 msg->elements[i].name, dn);
791 ret = LDB_ERR_NO_SUCH_ATTRIBUTE;
795 /* Delete specified values from an attribute */
796 for (j=0; j < msg->elements[i].num_values; j++) {
797 if (msg_delete_element(module,
799 msg->elements[i].name,
800 &msg->elements[i].values[j]) != 0) {
801 ldb_asprintf_errstring(ldb, "No matching attribute value when deleting attribute: %s on %s",
802 msg->elements[i].name, dn);
803 ret = LDB_ERR_NO_SUCH_ATTRIBUTE;
810 ldb_asprintf_errstring(ldb,
811 "Invalid ldb_modify flags on %s: 0x%x",
812 msg->elements[i].name,
813 msg->elements[i].flags & LDB_FLAG_MOD_MASK);
814 ret = LDB_ERR_PROTOCOL_ERROR;
819 ret = ltdb_store(module, msg2, TDB_MODIFY);
820 if (ret != LDB_SUCCESS) {
824 ret = ltdb_modified(module, msg->dn);
825 if (ret != LDB_SUCCESS) {
830 talloc_free(tdb_key.dptr);
837 static int ltdb_modify(struct ltdb_context *ctx)
839 struct ldb_module *module = ctx->module;
840 struct ldb_request *req = ctx->req;
841 int ret = LDB_SUCCESS;
843 ret = ltdb_check_special_dn(module, req->op.mod.message);
844 if (ret != LDB_SUCCESS) {
848 ldb_request_set_state(req, LDB_ASYNC_PENDING);
850 if (ltdb_cache_load(module) != 0) {
851 return LDB_ERR_OPERATIONS_ERROR;
854 ret = ltdb_modify_internal(module, req->op.mod.message);
862 static int ltdb_rename(struct ltdb_context *ctx)
864 struct ldb_module *module = ctx->module;
865 struct ldb_request *req = ctx->req;
866 struct ldb_message *msg;
867 int ret = LDB_SUCCESS;
869 ldb_request_set_state(req, LDB_ASYNC_PENDING);
871 if (ltdb_cache_load(ctx->module) != 0) {
872 return LDB_ERR_OPERATIONS_ERROR;
875 msg = talloc(ctx, struct ldb_message);
877 return LDB_ERR_OPERATIONS_ERROR;
880 /* in case any attribute of the message was indexed, we need
881 to fetch the old record */
882 ret = ltdb_search_dn1(module, req->op.rename.olddn, msg);
883 if (ret != LDB_SUCCESS) {
884 /* not finding the old record is an error */
888 msg->dn = ldb_dn_copy(msg, req->op.rename.newdn);
889 if (msg->dn == NULL) {
890 return LDB_ERR_OPERATIONS_ERROR;
893 /* Always delete first then add, to avoid conflicts with
894 * unique indexes. We rely on the transaction to make this
897 ret = ltdb_delete_internal(module, req->op.rename.olddn);
898 if (ret != LDB_SUCCESS) {
902 ret = ltdb_add_internal(module, msg);
907 static int ltdb_start_trans(struct ldb_module *module)
909 void *data = ldb_module_get_private(module);
910 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
912 if (tdb_transaction_start(ltdb->tdb) != 0) {
913 return ltdb_err_map(tdb_error(ltdb->tdb));
916 ltdb->in_transaction++;
918 ltdb_index_transaction_start(module);
923 static int ltdb_prepare_commit(struct ldb_module *module)
925 void *data = ldb_module_get_private(module);
926 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
928 if (ltdb->in_transaction != 1) {
932 if (ltdb_index_transaction_commit(module) != 0) {
933 tdb_transaction_cancel(ltdb->tdb);
934 ltdb->in_transaction--;
935 return ltdb_err_map(tdb_error(ltdb->tdb));
938 if (tdb_transaction_prepare_commit(ltdb->tdb) != 0) {
939 ltdb->in_transaction--;
940 return ltdb_err_map(tdb_error(ltdb->tdb));
943 ltdb->prepared_commit = true;
948 static int ltdb_end_trans(struct ldb_module *module)
950 void *data = ldb_module_get_private(module);
951 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
953 if (!ltdb->prepared_commit) {
954 int ret = ltdb_prepare_commit(module);
955 if (ret != LDB_SUCCESS) {
960 ltdb->in_transaction--;
961 ltdb->prepared_commit = false;
963 if (tdb_transaction_commit(ltdb->tdb) != 0) {
964 return ltdb_err_map(tdb_error(ltdb->tdb));
970 static int ltdb_del_trans(struct ldb_module *module)
972 void *data = ldb_module_get_private(module);
973 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
975 ltdb->in_transaction--;
977 if (ltdb_index_transaction_cancel(module) != 0) {
978 tdb_transaction_cancel(ltdb->tdb);
979 return ltdb_err_map(tdb_error(ltdb->tdb));
982 if (tdb_transaction_cancel(ltdb->tdb) != 0) {
983 return ltdb_err_map(tdb_error(ltdb->tdb));
990 return sequenceNumber from @BASEINFO
992 static int ltdb_sequence_number(struct ltdb_context *ctx,
993 struct ldb_extended **ext)
995 struct ldb_context *ldb;
996 struct ldb_module *module = ctx->module;
997 struct ldb_request *req = ctx->req;
999 struct ldb_seqnum_request *seq;
1000 struct ldb_seqnum_result *res;
1001 struct ldb_message *msg = NULL;
1004 int ret = LDB_SUCCESS;
1006 ldb = ldb_module_get_ctx(module);
1008 seq = talloc_get_type(req->op.extended.data,
1009 struct ldb_seqnum_request);
1011 return LDB_ERR_OPERATIONS_ERROR;
1014 ldb_request_set_state(req, LDB_ASYNC_PENDING);
1016 if (ltdb_lock_read(module) != 0) {
1017 return LDB_ERR_OPERATIONS_ERROR;
1020 res = talloc_zero(req, struct ldb_seqnum_result);
1022 ret = LDB_ERR_OPERATIONS_ERROR;
1025 tmp_ctx = talloc_new(req);
1026 if (tmp_ctx == NULL) {
1027 ret = LDB_ERR_OPERATIONS_ERROR;
1031 dn = ldb_dn_new(tmp_ctx, ldb, LTDB_BASEINFO);
1033 msg = talloc(tmp_ctx, struct ldb_message);
1035 ret = LDB_ERR_OPERATIONS_ERROR;
1039 ret = ltdb_search_dn1(module, dn, msg);
1040 if (ret != LDB_SUCCESS) {
1044 switch (seq->type) {
1045 case LDB_SEQ_HIGHEST_SEQ:
1046 res->seq_num = ldb_msg_find_attr_as_uint64(msg, LTDB_SEQUENCE_NUMBER, 0);
1049 res->seq_num = ldb_msg_find_attr_as_uint64(msg, LTDB_SEQUENCE_NUMBER, 0);
1052 case LDB_SEQ_HIGHEST_TIMESTAMP:
1053 date = ldb_msg_find_attr_as_string(msg, LTDB_MOD_TIMESTAMP, NULL);
1055 res->seq_num = ldb_string_to_time(date);
1058 /* zero is as good as anything when we don't know */
1063 *ext = talloc_zero(req, struct ldb_extended);
1065 ret = LDB_ERR_OPERATIONS_ERROR;
1068 (*ext)->oid = LDB_EXTENDED_SEQUENCE_NUMBER;
1069 (*ext)->data = talloc_steal(*ext, res);
1072 talloc_free(tmp_ctx);
1073 ltdb_unlock_read(module);
1077 static void ltdb_request_done(struct ltdb_context *ctx, int error)
1079 struct ldb_context *ldb;
1080 struct ldb_request *req;
1081 struct ldb_reply *ares;
1083 ldb = ldb_module_get_ctx(ctx->module);
1086 /* if we already returned an error just return */
1087 if (ldb_request_get_status(req) != LDB_SUCCESS) {
1091 ares = talloc_zero(req, struct ldb_reply);
1094 req->callback(req, NULL);
1097 ares->type = LDB_REPLY_DONE;
1098 ares->error = error;
1100 req->callback(req, ares);
1103 static void ltdb_timeout(struct tevent_context *ev,
1104 struct tevent_timer *te,
1108 struct ltdb_context *ctx;
1109 ctx = talloc_get_type(private_data, struct ltdb_context);
1111 if (!ctx->request_terminated) {
1112 /* request is done now */
1113 ltdb_request_done(ctx, LDB_ERR_TIME_LIMIT_EXCEEDED);
1116 if (!ctx->request_terminated) {
1117 /* neutralize the spy */
1118 ctx->spy->ctx = NULL;
1123 static void ltdb_request_extended_done(struct ltdb_context *ctx,
1124 struct ldb_extended *ext,
1127 struct ldb_context *ldb;
1128 struct ldb_request *req;
1129 struct ldb_reply *ares;
1131 ldb = ldb_module_get_ctx(ctx->module);
1134 /* if we already returned an error just return */
1135 if (ldb_request_get_status(req) != LDB_SUCCESS) {
1139 ares = talloc_zero(req, struct ldb_reply);
1142 req->callback(req, NULL);
1145 ares->type = LDB_REPLY_DONE;
1146 ares->response = ext;
1147 ares->error = error;
1149 req->callback(req, ares);
1152 static void ltdb_handle_extended(struct ltdb_context *ctx)
1154 struct ldb_extended *ext = NULL;
1157 if (strcmp(ctx->req->op.extended.oid,
1158 LDB_EXTENDED_SEQUENCE_NUMBER) == 0) {
1159 /* get sequence number */
1160 ret = ltdb_sequence_number(ctx, &ext);
1162 /* not recognized */
1163 ret = LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
1166 ltdb_request_extended_done(ctx, ext, ret);
1169 static void ltdb_callback(struct tevent_context *ev,
1170 struct tevent_timer *te,
1174 struct ltdb_context *ctx;
1177 ctx = talloc_get_type(private_data, struct ltdb_context);
1179 if (ctx->request_terminated) {
1183 switch (ctx->req->operation) {
1185 ret = ltdb_search(ctx);
1188 ret = ltdb_add(ctx);
1191 ret = ltdb_modify(ctx);
1194 ret = ltdb_delete(ctx);
1197 ret = ltdb_rename(ctx);
1200 ltdb_handle_extended(ctx);
1203 /* no other op supported */
1204 ret = LDB_ERR_UNWILLING_TO_PERFORM;
1207 if (!ctx->request_terminated) {
1208 /* request is done now */
1209 ltdb_request_done(ctx, ret);
1213 if (!ctx->request_terminated) {
1214 /* neutralize the spy */
1215 ctx->spy->ctx = NULL;
1220 static int ltdb_request_destructor(void *ptr)
1222 struct ltdb_req_spy *spy = talloc_get_type(ptr, struct ltdb_req_spy);
1224 if (spy->ctx != NULL) {
1225 spy->ctx->request_terminated = true;
1231 static int ltdb_handle_request(struct ldb_module *module,
1232 struct ldb_request *req)
1234 struct ldb_context *ldb;
1235 struct tevent_context *ev;
1236 struct ltdb_context *ac;
1237 struct tevent_timer *te;
1240 if (check_critical_controls(req->controls)) {
1241 return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
1244 ldb = ldb_module_get_ctx(module);
1246 if (req->starttime == 0 || req->timeout == 0) {
1247 ldb_set_errstring(ldb, "Invalid timeout settings");
1248 return LDB_ERR_TIME_LIMIT_EXCEEDED;
1251 ev = ldb_get_event_context(ldb);
1253 ac = talloc_zero(ldb, struct ltdb_context);
1256 return LDB_ERR_OPERATIONS_ERROR;
1259 ac->module = module;
1264 te = tevent_add_timer(ev, ac, tv, ltdb_callback, ac);
1267 return LDB_ERR_OPERATIONS_ERROR;
1270 tv.tv_sec = req->starttime + req->timeout;
1271 ac->timeout_event = tevent_add_timer(ev, ac, tv, ltdb_timeout, ac);
1272 if (NULL == ac->timeout_event) {
1274 return LDB_ERR_OPERATIONS_ERROR;
1277 /* set a spy so that we do not try to use the request context
1278 * if it is freed before ltdb_callback fires */
1279 ac->spy = talloc(req, struct ltdb_req_spy);
1280 if (NULL == ac->spy) {
1282 return LDB_ERR_OPERATIONS_ERROR;
1286 talloc_set_destructor((TALLOC_CTX *)ac->spy, ltdb_request_destructor);
1291 static const struct ldb_module_ops ltdb_ops = {
1293 .search = ltdb_handle_request,
1294 .add = ltdb_handle_request,
1295 .modify = ltdb_handle_request,
1296 .del = ltdb_handle_request,
1297 .rename = ltdb_handle_request,
1298 .extended = ltdb_handle_request,
1299 .start_transaction = ltdb_start_trans,
1300 .end_transaction = ltdb_end_trans,
1301 .prepare_commit = ltdb_prepare_commit,
1302 .del_transaction = ltdb_del_trans,
1306 connect to the database
1308 static int ltdb_connect(struct ldb_context *ldb, const char *url,
1309 unsigned int flags, const char *options[],
1310 struct ldb_module **_module)
1312 struct ldb_module *module;
1314 int tdb_flags, open_flags;
1315 struct ltdb_private *ltdb;
1318 if (strchr(url, ':')) {
1319 if (strncmp(url, "tdb://", 6) != 0) {
1320 ldb_debug(ldb, LDB_DEBUG_ERROR,
1321 "Invalid tdb URL '%s'", url);
1329 tdb_flags = TDB_DEFAULT | TDB_SEQNUM;
1331 /* check for the 'nosync' option */
1332 if (flags & LDB_FLG_NOSYNC) {
1333 tdb_flags |= TDB_NOSYNC;
1336 /* and nommap option */
1337 if (flags & LDB_FLG_NOMMAP) {
1338 tdb_flags |= TDB_NOMMAP;
1341 if (flags & LDB_FLG_RDONLY) {
1342 open_flags = O_RDONLY;
1344 open_flags = O_CREAT | O_RDWR;
1347 ltdb = talloc_zero(ldb, struct ltdb_private);
1353 /* note that we use quite a large default hash size */
1354 ltdb->tdb = ltdb_wrap_open(ltdb, path, 10000,
1355 tdb_flags, open_flags,
1356 ldb_get_create_perms(ldb), ldb);
1358 ldb_debug(ldb, LDB_DEBUG_ERROR,
1359 "Unable to open tdb '%s'", path);
1364 ltdb->sequence_number = 0;
1366 module = ldb_module_new(ldb, ldb, "ldb_tdb backend", <db_ops);
1371 ldb_module_set_private(module, ltdb);
1372 talloc_steal(module, ltdb);
1374 if (ltdb_cache_load(module) != 0) {
1375 talloc_free(module);
1384 const struct ldb_backend_ops ldb_tdb_backend_ops = {
1386 .connect_fn = ltdb_connect