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 static 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;
204 if (ldb_dn_is_special(dn) &&
205 (ldb_dn_check_special(dn, LTDB_INDEXLIST) ||
206 ldb_dn_check_special(dn, LTDB_ATTRIBUTES)) ) {
207 ret = ltdb_reindex(module);
210 /* If the modify was to a normal record, or any special except @BASEINFO, update the seq number */
211 if (ret == LDB_SUCCESS &&
212 !(ldb_dn_is_special(dn) &&
213 ldb_dn_check_special(dn, LTDB_BASEINFO)) ) {
214 ret = ltdb_increase_sequence_number(module);
217 /* If the modify was to @OPTIONS, reload the cache */
218 if (ldb_dn_is_special(dn) &&
219 (ldb_dn_check_special(dn, LTDB_OPTIONS)) ) {
220 ret = ltdb_cache_reload(module);
227 store a record into the db
229 int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flgs)
231 void *data = ldb_module_get_private(module);
232 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
233 TDB_DATA tdb_key, tdb_data;
234 int ret = LDB_SUCCESS;
236 tdb_key = ltdb_key(module, msg->dn);
237 if (tdb_key.dptr == NULL) {
238 return LDB_ERR_OTHER;
241 ret = ltdb_pack_data(module, msg, &tdb_data);
243 talloc_free(tdb_key.dptr);
244 return LDB_ERR_OTHER;
247 ret = tdb_store(ltdb->tdb, tdb_key, tdb_data, flgs);
249 ret = ltdb_err_map(tdb_error(ltdb->tdb));
253 ret = ltdb_index_add(module, msg);
254 if (ret != LDB_SUCCESS) {
255 tdb_delete(ltdb->tdb, tdb_key);
259 talloc_free(tdb_key.dptr);
260 talloc_free(tdb_data.dptr);
266 static int ltdb_add_internal(struct ldb_module *module,
267 const struct ldb_message *msg)
269 struct ldb_context *ldb = ldb_module_get_ctx(module);
270 int ret = LDB_SUCCESS, i;
272 ret = ltdb_check_special_dn(module, msg);
273 if (ret != LDB_SUCCESS) {
277 if (ltdb_cache_load(module) != 0) {
278 return LDB_ERR_OPERATIONS_ERROR;
281 for (i=0;i<msg->num_elements;i++) {
282 struct ldb_message_element *el = &msg->elements[i];
283 const struct ldb_schema_attribute *a = ldb_schema_attribute_by_name(ldb, el->name);
285 if (el->num_values == 0) {
286 ldb_asprintf_errstring(ldb, "attribute %s on %s specified, but with 0 values (illegal)",
287 el->name, ldb_dn_get_linearized(msg->dn));
288 return LDB_ERR_CONSTRAINT_VIOLATION;
290 if (a && a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) {
291 if (el->num_values > 1) {
292 ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s specified more than once",
293 el->name, ldb_dn_get_linearized(msg->dn));
294 return LDB_ERR_CONSTRAINT_VIOLATION;
299 ret = ltdb_store(module, msg, TDB_INSERT);
300 if (ret != LDB_SUCCESS) {
301 if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) {
302 ldb_asprintf_errstring(ldb,
303 "Entry %s already exists",
304 ldb_dn_get_linearized(msg->dn));
309 ret = ltdb_index_one(module, msg, 1);
310 if (ret != LDB_SUCCESS) {
314 ret = ltdb_modified(module, msg->dn);
320 add a record to the database
322 static int ltdb_add(struct ltdb_context *ctx)
324 struct ldb_module *module = ctx->module;
325 struct ldb_request *req = ctx->req;
326 int ret = LDB_SUCCESS;
328 ldb_request_set_state(req, LDB_ASYNC_PENDING);
330 if (ltdb_cache_load(module) != 0) {
331 return LDB_ERR_OPERATIONS_ERROR;
334 ret = ltdb_add_internal(module, req->op.add.message);
340 delete a record from the database, not updating indexes (used for deleting
343 int ltdb_delete_noindex(struct ldb_module *module, struct ldb_dn *dn)
345 void *data = ldb_module_get_private(module);
346 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
350 tdb_key = ltdb_key(module, dn);
352 return LDB_ERR_OTHER;
355 ret = tdb_delete(ltdb->tdb, tdb_key);
356 talloc_free(tdb_key.dptr);
359 ret = ltdb_err_map(tdb_error(ltdb->tdb));
365 static int ltdb_delete_internal(struct ldb_module *module, struct ldb_dn *dn)
367 struct ldb_message *msg;
368 int ret = LDB_SUCCESS;
370 msg = talloc(module, struct ldb_message);
372 return LDB_ERR_OPERATIONS_ERROR;
375 /* in case any attribute of the message was indexed, we need
376 to fetch the old record */
377 ret = ltdb_search_dn1(module, dn, msg);
378 if (ret != LDB_SUCCESS) {
379 /* not finding the old record is an error */
383 ret = ltdb_delete_noindex(module, dn);
384 if (ret != LDB_SUCCESS) {
388 /* remove one level attribute */
389 ret = ltdb_index_one(module, msg, 0);
390 if (ret != LDB_SUCCESS) {
394 /* remove any indexed attributes */
395 ret = ltdb_index_del(module, msg);
396 if (ret != LDB_SUCCESS) {
400 ret = ltdb_modified(module, dn);
401 if (ret != LDB_SUCCESS) {
411 delete a record from the database
413 static int ltdb_delete(struct ltdb_context *ctx)
415 struct ldb_module *module = ctx->module;
416 struct ldb_request *req = ctx->req;
417 int ret = LDB_SUCCESS;
419 ldb_request_set_state(req, LDB_ASYNC_PENDING);
421 if (ltdb_cache_load(module) != 0) {
422 return LDB_ERR_OPERATIONS_ERROR;
425 ret = ltdb_delete_internal(module, req->op.del.dn);
431 find an element by attribute name. At the moment this does a linear search,
432 it should be re-coded to use a binary search once all places that modify
433 records guarantee sorted order
435 return the index of the first matching element if found, otherwise -1
437 static int find_element(const struct ldb_message *msg, const char *name)
440 for (i=0;i<msg->num_elements;i++) {
441 if (ldb_attr_cmp(msg->elements[i].name, name) == 0) {
450 add an element to an existing record. Assumes a elements array that we
451 can call re-alloc on, and assumed that we can re-use the data pointers from
452 the passed in additional values. Use with care!
454 returns 0 on success, -1 on failure (and sets errno)
456 static int msg_add_element(struct ldb_context *ldb,
457 struct ldb_message *msg,
458 struct ldb_message_element *el)
460 struct ldb_message_element *e2;
463 if (el->num_values == 0) {
464 /* nothing to do here - we don't add empty elements */
468 e2 = talloc_realloc(msg, msg->elements, struct ldb_message_element,
469 msg->num_elements+1);
477 e2 = &msg->elements[msg->num_elements];
480 e2->flags = el->flags;
481 e2->values = talloc_array(msg->elements,
482 struct ldb_val, el->num_values);
487 for (i=0;i<el->num_values;i++) {
488 e2->values[i] = el->values[i];
490 e2->num_values = el->num_values;
498 delete all elements having a specified attribute name
500 static int msg_delete_attribute(struct ldb_module *module,
501 struct ldb_context *ldb,
502 struct ldb_message *msg, const char *name)
507 dn = ldb_dn_get_linearized(msg->dn);
512 for (i=0;i<msg->num_elements;i++) {
513 if (ldb_attr_cmp(msg->elements[i].name, name) == 0) {
514 for (j=0;j<msg->elements[i].num_values;j++) {
515 ltdb_index_del_value(module, dn,
516 &msg->elements[i], j);
518 talloc_free(msg->elements[i].values);
519 if (msg->num_elements > (i+1)) {
520 memmove(&msg->elements[i],
522 sizeof(struct ldb_message_element)*
523 (msg->num_elements - (i+1)));
527 msg->elements = talloc_realloc(msg, msg->elements,
528 struct ldb_message_element,
531 /* per definition we find in a canonicalised message an
532 attribute only once. So we are finished here. */
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,
549 const struct ldb_val *val)
551 struct ldb_context *ldb = ldb_module_get_ctx(module);
554 struct ldb_message_element *el;
555 const struct ldb_schema_attribute *a;
557 found = find_element(msg, name);
562 el = &msg->elements[found];
564 a = ldb_schema_attribute_by_name(ldb, el->name);
566 for (i=0;i<el->num_values;i++) {
567 if (a->syntax->comparison_fn(ldb, ldb,
568 &el->values[i], val) == 0) {
569 if (i<el->num_values-1) {
570 memmove(&el->values[i], &el->values[i+1],
571 sizeof(el->values[i])*
572 (el->num_values-(i+1)));
575 if (el->num_values == 0) {
576 return msg_delete_attribute(module, ldb,
580 /* per definition we find in a canonicalised message an
581 attribute value only once. So we are finished here */
592 modify a record - internal interface
594 yuck - this is O(n^2). Luckily n is usually small so we probably
595 get away with it, but if we ever have really large attribute lists
596 then we'll need to look at this again
598 int ltdb_modify_internal(struct ldb_module *module,
599 const struct ldb_message *msg)
601 struct ldb_context *ldb = ldb_module_get_ctx(module);
602 void *data = ldb_module_get_private(module);
603 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
604 TDB_DATA tdb_key, tdb_data;
605 struct ldb_message *msg2;
607 int ret = LDB_SUCCESS, idx;
609 tdb_key = ltdb_key(module, msg->dn);
611 return LDB_ERR_OTHER;
614 tdb_data = tdb_fetch(ltdb->tdb, tdb_key);
615 if (!tdb_data.dptr) {
616 talloc_free(tdb_key.dptr);
617 return ltdb_err_map(tdb_error(ltdb->tdb));
620 msg2 = talloc(tdb_key.dptr, struct ldb_message);
627 ret = ltdb_unpack_data(module, &tdb_data, msg2);
638 for (i=0; i<msg->num_elements; i++) {
639 struct ldb_message_element *el = &msg->elements[i], *el2;
640 struct ldb_val *vals;
641 const struct ldb_schema_attribute *a = ldb_schema_attribute_by_name(ldb, el->name);
644 if (ldb_attr_cmp(el->name, "distinguishedName") == 0) {
645 ldb_asprintf_errstring(ldb, "it is not permitted to perform a modify on 'distinguishedName' (use rename instead): %s",
646 ldb_dn_get_linearized(msg->dn));
647 ret = LDB_ERR_CONSTRAINT_VIOLATION;
651 switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) {
652 case LDB_FLAG_MOD_ADD:
653 if (el->num_values == 0) {
654 ldb_asprintf_errstring(ldb, "attribute %s on %s specified, but with 0 values (illigal)",
655 el->name, ldb_dn_get_linearized(msg->dn));
656 ret = LDB_ERR_CONSTRAINT_VIOLATION;
660 if (a && a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) {
661 if (el->num_values > 1) {
662 ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s specified more than once",
663 el->name, ldb_dn_get_linearized(msg->dn));
664 ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
669 /* Checks if element already exists */
670 idx = find_element(msg2, el->name);
672 if (msg_add_element(ldb, msg2, el) != 0) {
677 /* We cannot add another value on a existing one
678 if the attribute is single-valued */
679 if (a && a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) {
680 ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s specified more than once",
681 el->name, ldb_dn_get_linearized(msg->dn));
682 ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
686 el2 = &(msg2->elements[idx]);
688 /* Check that values don't exist yet on multi-
689 valued attributes or aren't provided twice */
690 for (j=0; j<el->num_values; j++) {
691 if (ldb_msg_find_val(el2, &el->values[j]) != NULL) {
692 ldb_asprintf_errstring(ldb, "%s: value #%d already exists", el->name, j);
693 ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
696 if (ldb_msg_find_val(el, &el->values[j]) != &el->values[j]) {
697 ldb_asprintf_errstring(ldb, "%s: value #%d provided more than once", el->name, j);
698 ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
703 /* Now combine existing and new values to a new
705 vals = talloc_realloc(msg2->elements,
706 el2->values, struct ldb_val,
707 el2->num_values + el->num_values);
714 for (j=0; j<el->num_values; j++) {
715 vals[el2->num_values + j] =
716 ldb_val_dup(vals, &el->values[j]);
720 el2->num_values += el->num_values;
725 case LDB_FLAG_MOD_REPLACE:
726 if (a && a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) {
727 if (el->num_values > 1) {
728 ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s specified more than once",
729 el->name, ldb_dn_get_linearized(msg->dn));
730 ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
735 for (j=0; j<el->num_values; j++) {
736 if (ldb_msg_find_val(el, &el->values[j]) != &el->values[j]) {
737 ldb_asprintf_errstring(ldb, "%s: value #%d provided more than once", el->name, j);
738 ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
743 /* Delete the attribute if it exists in the DB */
744 msg_delete_attribute(module, ldb, msg2, el->name);
746 /* Recreate it with the new values */
747 if (msg_add_element(ldb, msg2, el) != 0) {
754 case LDB_FLAG_MOD_DELETE:
755 dn = ldb_dn_get_linearized(msg->dn);
761 if (msg->elements[i].num_values == 0) {
762 /* Delete the whole attribute */
763 if (msg_delete_attribute(module, ldb, msg2,
764 msg->elements[i].name) != 0) {
765 ldb_asprintf_errstring(ldb, "No such attribute: %s for delete on %s",
766 msg->elements[i].name, dn);
767 ret = LDB_ERR_NO_SUCH_ATTRIBUTE;
771 /* Delete specified values from an attribute */
772 for (j=0; j < msg->elements[i].num_values; j++) {
773 if (msg_delete_element(module,
775 msg->elements[i].name,
776 &msg->elements[i].values[j]) != 0) {
777 ldb_asprintf_errstring(ldb, "No matching attribute value when deleting attribute: %s on %s",
778 msg->elements[i].name, dn);
779 ret = LDB_ERR_NO_SUCH_ATTRIBUTE;
783 ret = ltdb_index_del_value(module, dn,
784 &msg->elements[i], j);
785 if (ret != LDB_SUCCESS) {
793 ldb_asprintf_errstring(ldb,
794 "Invalid ldb_modify flags on %s: 0x%x",
795 msg->elements[i].name,
796 msg->elements[i].flags & LDB_FLAG_MOD_MASK);
797 ret = LDB_ERR_PROTOCOL_ERROR;
802 ret = ltdb_store(module, msg2, TDB_MODIFY);
803 if (ret != LDB_SUCCESS) {
807 ret = ltdb_modified(module, msg->dn);
808 if (ret != LDB_SUCCESS) {
813 talloc_free(tdb_key.dptr);
820 static int ltdb_modify(struct ltdb_context *ctx)
822 struct ldb_module *module = ctx->module;
823 struct ldb_request *req = ctx->req;
824 int ret = LDB_SUCCESS;
826 ret = ltdb_check_special_dn(module, req->op.mod.message);
827 if (ret != LDB_SUCCESS) {
831 ldb_request_set_state(req, LDB_ASYNC_PENDING);
833 if (ltdb_cache_load(module) != 0) {
834 return LDB_ERR_OPERATIONS_ERROR;
837 ret = ltdb_modify_internal(module, req->op.mod.message);
845 static int ltdb_rename(struct ltdb_context *ctx)
847 struct ldb_module *module = ctx->module;
848 struct ldb_request *req = ctx->req;
849 struct ldb_message *msg;
850 int ret = LDB_SUCCESS;
852 ldb_request_set_state(req, LDB_ASYNC_PENDING);
854 if (ltdb_cache_load(ctx->module) != 0) {
855 return LDB_ERR_OPERATIONS_ERROR;
858 msg = talloc(ctx, struct ldb_message);
860 return LDB_ERR_OPERATIONS_ERROR;
863 /* in case any attribute of the message was indexed, we need
864 to fetch the old record */
865 ret = ltdb_search_dn1(module, req->op.rename.olddn, msg);
866 if (ret != LDB_SUCCESS) {
867 /* not finding the old record is an error */
871 msg->dn = ldb_dn_copy(msg, req->op.rename.newdn);
872 if (msg->dn == NULL) {
873 return LDB_ERR_OPERATIONS_ERROR;
876 /* Always delete first then add, to avoid conflicts with
877 * unique indexes. We rely on the transaction to make this
880 ret = ltdb_delete_internal(module, req->op.rename.olddn);
881 if (ret != LDB_SUCCESS) {
885 ret = ltdb_add_internal(module, msg);
890 static int ltdb_start_trans(struct ldb_module *module)
892 void *data = ldb_module_get_private(module);
893 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
895 if (tdb_transaction_start(ltdb->tdb) != 0) {
896 return ltdb_err_map(tdb_error(ltdb->tdb));
899 ltdb->in_transaction++;
901 ltdb_index_transaction_start(module);
906 static int ltdb_prepare_commit(struct ldb_module *module)
908 void *data = ldb_module_get_private(module);
909 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
911 if (ltdb->in_transaction != 1) {
915 if (ltdb_index_transaction_commit(module) != 0) {
916 tdb_transaction_cancel(ltdb->tdb);
917 ltdb->in_transaction--;
918 return ltdb_err_map(tdb_error(ltdb->tdb));
921 if (tdb_transaction_prepare_commit(ltdb->tdb) != 0) {
922 ltdb->in_transaction--;
923 return ltdb_err_map(tdb_error(ltdb->tdb));
926 ltdb->prepared_commit = true;
931 static int ltdb_end_trans(struct ldb_module *module)
933 void *data = ldb_module_get_private(module);
934 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
936 if (!ltdb->prepared_commit) {
937 int ret = ltdb_prepare_commit(module);
938 if (ret != LDB_SUCCESS) {
943 ltdb->in_transaction--;
944 ltdb->prepared_commit = false;
946 if (tdb_transaction_commit(ltdb->tdb) != 0) {
947 return ltdb_err_map(tdb_error(ltdb->tdb));
953 static int ltdb_del_trans(struct ldb_module *module)
955 void *data = ldb_module_get_private(module);
956 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
958 ltdb->in_transaction--;
960 if (ltdb_index_transaction_cancel(module) != 0) {
961 tdb_transaction_cancel(ltdb->tdb);
962 return ltdb_err_map(tdb_error(ltdb->tdb));
965 if (tdb_transaction_cancel(ltdb->tdb) != 0) {
966 return ltdb_err_map(tdb_error(ltdb->tdb));
973 return sequenceNumber from @BASEINFO
975 static int ltdb_sequence_number(struct ltdb_context *ctx,
976 struct ldb_extended **ext)
978 struct ldb_context *ldb;
979 struct ldb_module *module = ctx->module;
980 struct ldb_request *req = ctx->req;
982 struct ldb_seqnum_request *seq;
983 struct ldb_seqnum_result *res;
984 struct ldb_message *msg = NULL;
987 int ret = LDB_SUCCESS;
989 ldb = ldb_module_get_ctx(module);
991 seq = talloc_get_type(req->op.extended.data,
992 struct ldb_seqnum_request);
994 return LDB_ERR_OPERATIONS_ERROR;
997 ldb_request_set_state(req, LDB_ASYNC_PENDING);
999 if (ltdb_lock_read(module) != 0) {
1000 return LDB_ERR_OPERATIONS_ERROR;
1003 res = talloc_zero(req, struct ldb_seqnum_result);
1005 ret = LDB_ERR_OPERATIONS_ERROR;
1008 tmp_ctx = talloc_new(req);
1009 if (tmp_ctx == NULL) {
1010 ret = LDB_ERR_OPERATIONS_ERROR;
1014 dn = ldb_dn_new(tmp_ctx, ldb, LTDB_BASEINFO);
1016 msg = talloc(tmp_ctx, struct ldb_message);
1018 ret = LDB_ERR_OPERATIONS_ERROR;
1022 ret = ltdb_search_dn1(module, dn, msg);
1023 if (ret != LDB_SUCCESS) {
1027 switch (seq->type) {
1028 case LDB_SEQ_HIGHEST_SEQ:
1029 res->seq_num = ldb_msg_find_attr_as_uint64(msg, LTDB_SEQUENCE_NUMBER, 0);
1032 res->seq_num = ldb_msg_find_attr_as_uint64(msg, LTDB_SEQUENCE_NUMBER, 0);
1035 case LDB_SEQ_HIGHEST_TIMESTAMP:
1036 date = ldb_msg_find_attr_as_string(msg, LTDB_MOD_TIMESTAMP, NULL);
1038 res->seq_num = ldb_string_to_time(date);
1041 /* zero is as good as anything when we don't know */
1046 *ext = talloc_zero(req, struct ldb_extended);
1048 ret = LDB_ERR_OPERATIONS_ERROR;
1051 (*ext)->oid = LDB_EXTENDED_SEQUENCE_NUMBER;
1052 (*ext)->data = talloc_steal(*ext, res);
1055 talloc_free(tmp_ctx);
1056 ltdb_unlock_read(module);
1060 static void ltdb_request_done(struct ltdb_context *ctx, int error)
1062 struct ldb_context *ldb;
1063 struct ldb_request *req;
1064 struct ldb_reply *ares;
1066 ldb = ldb_module_get_ctx(ctx->module);
1069 /* if we already returned an error just return */
1070 if (ldb_request_get_status(req) != LDB_SUCCESS) {
1074 ares = talloc_zero(req, struct ldb_reply);
1077 req->callback(req, NULL);
1080 ares->type = LDB_REPLY_DONE;
1081 ares->error = error;
1083 req->callback(req, ares);
1086 static void ltdb_timeout(struct tevent_context *ev,
1087 struct tevent_timer *te,
1091 struct ltdb_context *ctx;
1092 ctx = talloc_get_type(private_data, struct ltdb_context);
1094 if (!ctx->request_terminated) {
1095 /* request is done now */
1096 ltdb_request_done(ctx, LDB_ERR_TIME_LIMIT_EXCEEDED);
1099 if (!ctx->request_terminated) {
1100 /* neutralize the spy */
1101 ctx->spy->ctx = NULL;
1106 static void ltdb_request_extended_done(struct ltdb_context *ctx,
1107 struct ldb_extended *ext,
1110 struct ldb_context *ldb;
1111 struct ldb_request *req;
1112 struct ldb_reply *ares;
1114 ldb = ldb_module_get_ctx(ctx->module);
1117 /* if we already returned an error just return */
1118 if (ldb_request_get_status(req) != LDB_SUCCESS) {
1122 ares = talloc_zero(req, struct ldb_reply);
1125 req->callback(req, NULL);
1128 ares->type = LDB_REPLY_DONE;
1129 ares->response = ext;
1130 ares->error = error;
1132 req->callback(req, ares);
1135 static void ltdb_handle_extended(struct ltdb_context *ctx)
1137 struct ldb_extended *ext = NULL;
1140 if (strcmp(ctx->req->op.extended.oid,
1141 LDB_EXTENDED_SEQUENCE_NUMBER) == 0) {
1142 /* get sequence number */
1143 ret = ltdb_sequence_number(ctx, &ext);
1145 /* not recognized */
1146 ret = LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
1149 ltdb_request_extended_done(ctx, ext, ret);
1152 static void ltdb_callback(struct tevent_context *ev,
1153 struct tevent_timer *te,
1157 struct ltdb_context *ctx;
1160 ctx = talloc_get_type(private_data, struct ltdb_context);
1162 if (ctx->request_terminated) {
1166 switch (ctx->req->operation) {
1168 ret = ltdb_search(ctx);
1171 ret = ltdb_add(ctx);
1174 ret = ltdb_modify(ctx);
1177 ret = ltdb_delete(ctx);
1180 ret = ltdb_rename(ctx);
1183 ltdb_handle_extended(ctx);
1186 /* no other op supported */
1187 ret = LDB_ERR_UNWILLING_TO_PERFORM;
1190 if (!ctx->request_terminated) {
1191 /* request is done now */
1192 ltdb_request_done(ctx, ret);
1196 if (!ctx->request_terminated) {
1197 /* neutralize the spy */
1198 ctx->spy->ctx = NULL;
1203 static int ltdb_request_destructor(void *ptr)
1205 struct ltdb_req_spy *spy = talloc_get_type(ptr, struct ltdb_req_spy);
1207 if (spy->ctx != NULL) {
1208 spy->ctx->request_terminated = true;
1214 static int ltdb_handle_request(struct ldb_module *module,
1215 struct ldb_request *req)
1217 struct ldb_context *ldb;
1218 struct tevent_context *ev;
1219 struct ltdb_context *ac;
1220 struct tevent_timer *te;
1223 if (check_critical_controls(req->controls)) {
1224 return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
1227 ldb = ldb_module_get_ctx(module);
1229 if (req->starttime == 0 || req->timeout == 0) {
1230 ldb_set_errstring(ldb, "Invalid timeout settings");
1231 return LDB_ERR_TIME_LIMIT_EXCEEDED;
1234 ev = ldb_get_event_context(ldb);
1236 ac = talloc_zero(ldb, struct ltdb_context);
1239 return LDB_ERR_OPERATIONS_ERROR;
1242 ac->module = module;
1247 te = tevent_add_timer(ev, ac, tv, ltdb_callback, ac);
1250 return LDB_ERR_OPERATIONS_ERROR;
1253 tv.tv_sec = req->starttime + req->timeout;
1254 ac->timeout_event = tevent_add_timer(ev, ac, tv, ltdb_timeout, ac);
1255 if (NULL == ac->timeout_event) {
1257 return LDB_ERR_OPERATIONS_ERROR;
1260 /* set a spy so that we do not try to use the request context
1261 * if it is freed before ltdb_callback fires */
1262 ac->spy = talloc(req, struct ltdb_req_spy);
1263 if (NULL == ac->spy) {
1265 return LDB_ERR_OPERATIONS_ERROR;
1269 talloc_set_destructor((TALLOC_CTX *)ac->spy, ltdb_request_destructor);
1274 static const struct ldb_module_ops ltdb_ops = {
1276 .search = ltdb_handle_request,
1277 .add = ltdb_handle_request,
1278 .modify = ltdb_handle_request,
1279 .del = ltdb_handle_request,
1280 .rename = ltdb_handle_request,
1281 .extended = ltdb_handle_request,
1282 .start_transaction = ltdb_start_trans,
1283 .end_transaction = ltdb_end_trans,
1284 .prepare_commit = ltdb_prepare_commit,
1285 .del_transaction = ltdb_del_trans,
1289 connect to the database
1291 static int ltdb_connect(struct ldb_context *ldb, const char *url,
1292 unsigned int flags, const char *options[],
1293 struct ldb_module **_module)
1295 struct ldb_module *module;
1297 int tdb_flags, open_flags;
1298 struct ltdb_private *ltdb;
1301 if (strchr(url, ':')) {
1302 if (strncmp(url, "tdb://", 6) != 0) {
1303 ldb_debug(ldb, LDB_DEBUG_ERROR,
1304 "Invalid tdb URL '%s'", url);
1312 tdb_flags = TDB_DEFAULT | TDB_SEQNUM;
1314 /* check for the 'nosync' option */
1315 if (flags & LDB_FLG_NOSYNC) {
1316 tdb_flags |= TDB_NOSYNC;
1319 /* and nommap option */
1320 if (flags & LDB_FLG_NOMMAP) {
1321 tdb_flags |= TDB_NOMMAP;
1324 if (flags & LDB_FLG_RDONLY) {
1325 open_flags = O_RDONLY;
1327 open_flags = O_CREAT | O_RDWR;
1330 ltdb = talloc_zero(ldb, struct ltdb_private);
1336 /* note that we use quite a large default hash size */
1337 ltdb->tdb = ltdb_wrap_open(ltdb, path, 10000,
1338 tdb_flags, open_flags,
1339 ldb_get_create_perms(ldb), ldb);
1341 ldb_debug(ldb, LDB_DEBUG_ERROR,
1342 "Unable to open tdb '%s'", path);
1347 ltdb->sequence_number = 0;
1349 module = ldb_module_new(ldb, ldb, "ldb_tdb backend", <db_ops);
1354 ldb_module_set_private(module, ltdb);
1356 if (ltdb_cache_load(module) != 0) {
1357 talloc_free(module);
1366 const struct ldb_backend_ops ldb_tdb_backend_ops = {
1368 .connect_fn = ltdb_connect