4 Copyright (C) Andrew Tridgell 2004
5 Copyright (C) Stefan Metzmacher 2004
6 Copyright (C) Simo Sorce 2006-2008
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
52 map a tdb error code to a ldb error code
54 static int ltdb_err_map(enum TDB_ERROR tdb_code)
62 return LDB_ERR_OPERATIONS_ERROR;
64 return LDB_ERR_PROTOCOL_ERROR;
68 case TDB_ERR_LOCK_TIMEOUT:
69 return LDB_ERR_TIME_LIMIT_EXCEEDED;
71 return LDB_ERR_ENTRY_ALREADY_EXISTS;
73 return LDB_ERR_NO_SUCH_OBJECT;
75 return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
81 lock the database for read - use by ltdb_search and ltdb_sequence_number
83 int ltdb_lock_read(struct ldb_module *module)
85 void *data = ldb_module_get_private(module);
86 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
87 if (ltdb->in_transaction == 0) {
88 return tdb_lockall_read(ltdb->tdb);
94 unlock the database after a ltdb_lock_read()
96 int ltdb_unlock_read(struct ldb_module *module)
98 void *data = ldb_module_get_private(module);
99 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
100 if (ltdb->in_transaction == 0) {
101 return tdb_unlockall_read(ltdb->tdb);
106 struct ldb_val ldb_dn_get_casefold_as_ldb_val(struct ldb_dn *dn) {
108 const char *casefold_dn = ldb_dn_get_casefold(dn);
109 val.data = (uint8_t *)((uintptr_t)casefold_dn);
110 val.length = strlen(casefold_dn);
114 struct ldb_val ldb_dn_alloc_casefold_as_ldb_val(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) {
116 const char *casefold_dn = ldb_dn_alloc_casefold(mem_ctx, dn);
117 val.data = (uint8_t *)((uintptr_t)casefold_dn);
118 val.length = strlen(casefold_dn);
123 form a TDB_DATA for a record key
126 This version takes the casefolded string form of the DN as an ldb_val
128 struct TDB_DATA ltdb_key_from_casefold_dn(TALLOC_CTX *mem_ctx,
129 struct ldb_val dn_folded)
133 key.dsize = dn_folded.length + 4;
134 key.dptr = talloc_size(mem_ctx, key.dsize);
139 memcpy(key.dptr, "DN=", 3);
140 memcpy(&key.dptr[3], dn_folded.data, key.dsize - 4);
142 key.dptr[key.dsize - 1] = '\0';
155 form a TDB_DATA for a record key
158 note that the key for a record can depend on whether the
159 dn refers to a case sensitive index record or not
161 struct TDB_DATA ltdb_key(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
164 struct ldb_val dn_folded;
167 most DNs are case insensitive. The exception is index DNs for
168 case sensitive attributes
170 there are 3 cases dealt with in this code:
172 1) if the dn doesn't start with @ then uppercase the attribute
173 names and the attributes values of case insensitive attributes
174 2) if the dn starts with @ then leave it alone -
175 the indexing code handles the rest
178 dn_folded = ldb_dn_get_casefold_as_ldb_val(dn);
179 if (!dn_folded.data) {
186 return ltdb_key_from_casefold_dn(mem_ctx, dn_folded);
190 check special dn's have valid attributes
191 currently only @ATTRIBUTES is checked
193 static int ltdb_check_special_dn(struct ldb_module *module,
194 const struct ldb_message *msg)
196 struct ldb_context *ldb = ldb_module_get_ctx(module);
199 if (! ldb_dn_is_special(msg->dn) ||
200 ! ldb_dn_check_special(msg->dn, LTDB_ATTRIBUTES)) {
204 /* we have @ATTRIBUTES, let's check attributes are fine */
205 /* should we check that we deny multivalued attributes ? */
206 for (i = 0; i < msg->num_elements; i++) {
207 for (j = 0; j < msg->elements[i].num_values; j++) {
208 if (ltdb_check_at_attributes_values(&msg->elements[i].values[j]) != 0) {
209 ldb_set_errstring(ldb, "Invalid attribute value in an @ATTRIBUTES entry");
210 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
220 we've made a modification to a dn - possibly reindex and
221 update sequence number
223 static int ltdb_modified(struct ldb_module *module, struct ldb_dn *dn)
225 int ret = LDB_SUCCESS;
227 if (ldb_dn_is_special(dn) &&
228 (ldb_dn_check_special(dn, LTDB_INDEXLIST) ||
229 ldb_dn_check_special(dn, LTDB_ATTRIBUTES)) ) {
230 ret = ltdb_reindex(module);
233 if (ret == LDB_SUCCESS &&
234 !(ldb_dn_is_special(dn) &&
235 ldb_dn_check_special(dn, LTDB_BASEINFO)) ) {
236 ret = ltdb_increase_sequence_number(module);
243 store a record into the db
245 int ltdb_store(struct ldb_module *module, TALLOC_CTX *mem_ctx,
246 const struct ldb_message *msg, int flgs)
248 void *data = ldb_module_get_private(module);
249 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
250 TDB_DATA tdb_key, tdb_data;
253 tdb_key = ltdb_key(mem_ctx, msg->dn);
255 return LDB_ERR_OTHER;
258 ret = ltdb_pack_data(module, msg, &tdb_data);
260 talloc_free(tdb_key.dptr);
261 return LDB_ERR_OTHER;
264 ret = tdb_store(ltdb->tdb, tdb_key, tdb_data, flgs);
266 ret = ltdb_err_map(tdb_error(ltdb->tdb));
270 ret = ltdb_index_add(module, mem_ctx, msg);
271 if (ret != LDB_SUCCESS) {
272 tdb_delete(ltdb->tdb, tdb_key);
276 talloc_free(tdb_key.dptr);
277 talloc_free(tdb_data.dptr);
283 static int ltdb_add_internal(struct ldb_module *module,
285 const struct ldb_message *msg)
287 struct ldb_context *ldb = ldb_module_get_ctx(module);
290 ret = ltdb_check_special_dn(module, msg);
291 if (ret != LDB_SUCCESS) {
295 if (ltdb_cache_load(module) != 0) {
296 return LDB_ERR_OPERATIONS_ERROR;
299 for (i=0;i<msg->num_elements;i++) {
300 struct ldb_message_element *el = &msg->elements[i];
301 const struct ldb_schema_attribute *a = ldb_schema_attribute_by_name(ldb, el->name);
303 if (el->num_values == 0) {
304 ldb_asprintf_errstring(ldb, "attribute %s on %s specified, but with 0 values (illegal)",
305 el->name, ldb_dn_get_linearized(msg->dn));
306 return LDB_ERR_CONSTRAINT_VIOLATION;
308 if (a && a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) {
309 if (el->num_values > 1) {
310 ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s speicified more than once",
311 el->name, ldb_dn_get_linearized(msg->dn));
312 return LDB_ERR_CONSTRAINT_VIOLATION;
317 ret = ltdb_store(module, mem_ctx, msg, TDB_INSERT);
319 if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) {
320 ldb_asprintf_errstring(ldb,
321 "Entry %s already exists",
322 ldb_dn_get_linearized(msg->dn));
326 if (ret == LDB_SUCCESS) {
327 ret = ltdb_index_one(module, mem_ctx, msg, 1);
328 if (ret != LDB_SUCCESS) {
332 ret = ltdb_modified(module, msg->dn);
333 if (ret != LDB_SUCCESS) {
342 add a record to the database
344 static int ltdb_add(struct ltdb_context *ctx)
346 struct ldb_module *module = ctx->module;
347 struct ldb_request *req = ctx->req;
350 ldb_request_set_state(req, LDB_ASYNC_PENDING);
352 tret = ltdb_add_internal(module, req, req->op.add.message);
353 if (tret != LDB_SUCCESS) {
361 delete a record from the database, not updating indexes (used for deleting
364 int ltdb_delete_noindex(struct ldb_module *module, TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
366 void *data = ldb_module_get_private(module);
367 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
371 tdb_key = ltdb_key(mem_ctx, dn);
373 return LDB_ERR_OTHER;
376 ret = tdb_delete(ltdb->tdb, tdb_key);
377 talloc_free(tdb_key.dptr);
380 ret = ltdb_err_map(tdb_error(ltdb->tdb));
386 static int ltdb_delete_internal(struct ldb_module *module, TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
388 struct ldb_message *msg;
391 msg = talloc(mem_ctx, struct ldb_message);
393 return LDB_ERR_OPERATIONS_ERROR;
396 /* in case any attribute of the message was indexed, we need
397 to fetch the old record */
398 ret = ltdb_search_dn1(module, dn, msg);
399 if (ret != LDB_SUCCESS) {
400 /* not finding the old record is an error */
404 ret = ltdb_delete_noindex(module, msg, dn);
405 if (ret != LDB_SUCCESS) {
409 /* remove one level attribute */
410 ret = ltdb_index_one(module, msg, msg, 0);
411 if (ret != LDB_SUCCESS) {
415 /* remove any indexed attributes */
416 ret = ltdb_index_del(module, msg, msg);
417 if (ret != LDB_SUCCESS) {
421 ret = ltdb_modified(module, dn);
422 if (ret != LDB_SUCCESS) {
432 delete a record from the database
434 static int ltdb_delete(struct ltdb_context *ctx)
436 struct ldb_module *module = ctx->module;
437 struct ldb_request *req = ctx->req;
440 ldb_request_set_state(req, LDB_ASYNC_PENDING);
442 if (ltdb_cache_load(module) != 0) {
443 return LDB_ERR_OPERATIONS_ERROR;
446 tret = ltdb_delete_internal(module, req, req->op.del.dn);
447 if (tret != LDB_SUCCESS) {
455 find an element by attribute name. At the moment this does a linear search,
456 it should be re-coded to use a binary search once all places that modify
457 records guarantee sorted order
459 return the index of the first matching element if found, otherwise -1
461 static int find_element(const struct ldb_message *msg, const char *name)
464 for (i=0;i<msg->num_elements;i++) {
465 if (ldb_attr_cmp(msg->elements[i].name, name) == 0) {
474 add an element to an existing record. Assumes a elements array that we
475 can call re-alloc on, and assumed that we can re-use the data pointers from
476 the passed in additional values. Use with care!
478 returns 0 on success, -1 on failure (and sets errno)
480 static int msg_add_element(struct ldb_context *ldb,
481 struct ldb_message *msg,
482 struct ldb_message_element *el)
484 struct ldb_message_element *e2;
487 e2 = talloc_realloc(msg, msg->elements, struct ldb_message_element,
488 msg->num_elements+1);
496 e2 = &msg->elements[msg->num_elements];
499 e2->flags = el->flags;
501 if (el->num_values != 0) {
502 e2->values = talloc_array(msg->elements,
503 struct ldb_val, el->num_values);
509 for (i=0;i<el->num_values;i++) {
510 e2->values[i] = el->values[i];
512 e2->num_values = el->num_values;
520 delete all elements having a specified attribute name
522 static int msg_delete_attribute(struct ldb_module *module,
523 struct ldb_message *msg, const char *name)
527 for (i=0;i<msg->num_elements;i++) {
528 if (ldb_attr_cmp(msg->elements[i].name, name) == 0) {
529 for (j=0;j<msg->elements[i].num_values;j++) {
530 ltdb_index_del_value(module, msg, msg->dn,
531 &msg->elements[i], j);
533 talloc_free(msg->elements[i].values);
534 if (msg->num_elements > (i+1)) {
535 memmove(&msg->elements[i],
537 sizeof(struct ldb_message_element)*
538 (msg->num_elements - (i+1)));
542 msg->elements = talloc_realloc(msg, msg->elements,
543 struct ldb_message_element,
552 delete all elements matching an attribute name/value
554 return 0 on success, -1 on failure
556 static int msg_delete_element(struct ldb_module *module,
557 struct ldb_message *msg,
559 const struct ldb_val *val)
561 struct ldb_context *ldb = ldb_module_get_ctx(module);
564 struct ldb_message_element *el;
565 const struct ldb_schema_attribute *a;
567 found = find_element(msg, name);
572 el = &msg->elements[found];
574 a = ldb_schema_attribute_by_name(ldb, el->name);
576 for (i=0;i<el->num_values;i++) {
577 if (a->syntax->comparison_fn(ldb, msg,
578 &el->values[i], val) == 0) {
579 if (i<el->num_values-1) {
580 memmove(&el->values[i], &el->values[i+1],
581 sizeof(el->values[i])*
582 (el->num_values-(i+1)));
585 if (el->num_values == 0) {
586 return msg_delete_attribute(module,
598 modify a record - internal interface
600 yuck - this is O(n^2). Luckily n is usually small so we probably
601 get away with it, but if we ever have really large attribute lists
602 then we'll need to look at this again
604 int ltdb_modify_internal(struct ldb_module *module,
606 const struct ldb_message *msg)
608 struct ldb_context *ldb = ldb_module_get_ctx(module);
609 void *data = ldb_module_get_private(module);
610 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
611 TDB_DATA tdb_key, tdb_data;
612 struct ldb_message *msg2;
615 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
617 return LDB_ERR_OPERATIONS_ERROR;
619 tdb_key = ltdb_key(tmp_ctx, msg->dn);
621 talloc_free(tmp_ctx);
622 return LDB_ERR_OTHER;
625 tdb_data = tdb_fetch(ltdb->tdb, tdb_key);
626 talloc_free(tdb_key.dptr);
628 if (!tdb_data.dptr) {
629 return ltdb_err_map(tdb_error(ltdb->tdb));
632 msg2 = talloc(tmp_ctx, struct ldb_message);
635 ret = LDB_ERR_OPERATIONS_ERROR;
639 ret = ltdb_unpack_data(module, &tdb_data, msg2);
647 for (i=0;i<msg->num_elements;i++) {
648 struct ldb_message_element *el = &msg->elements[i];
649 struct ldb_message_element *el2;
650 struct ldb_val *vals;
651 const struct ldb_schema_attribute *a = ldb_schema_attribute_by_name(ldb, el->name);
652 switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) {
654 case LDB_FLAG_MOD_ADD:
656 /* add this element to the message. fail if it
658 idx = find_element(msg2, el->name);
660 if (el->num_values == 0) {
661 ldb_asprintf_errstring(ldb, "attribute %s on %s speicified, but with 0 values (illigal)",
662 el->name, ldb_dn_get_linearized(msg->dn));
663 return LDB_ERR_CONSTRAINT_VIOLATION;
666 if (a && a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) {
667 if (el->num_values > 1) {
668 ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s speicified more than once",
669 el->name, ldb_dn_get_linearized(msg->dn));
670 return LDB_ERR_CONSTRAINT_VIOLATION;
673 if (msg_add_element(ldb, msg2, el) != 0) {
680 /* If this is an add, then if it already
681 * exists in the object, then we violoate the
682 * single-value rule */
683 if (a && a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) {
684 return LDB_ERR_CONSTRAINT_VIOLATION;
687 el2 = &msg2->elements[idx];
689 /* An attribute with this name already exists,
690 * add all values if they don't already exist
691 * (check both the other elements to be added,
692 * and those already in the db). */
694 for (j=0;j<el->num_values;j++) {
695 if (ldb_msg_find_val(el2, &el->values[j])) {
696 ldb_asprintf_errstring(ldb, "%s: value #%d already exists", el->name, j);
697 ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
700 if (ldb_msg_find_val(el, &el->values[j]) != &el->values[j]) {
701 ldb_asprintf_errstring(ldb, "%s: value #%d provided more than once", el->name, j);
702 ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
707 vals = talloc_realloc(msg2->elements, el2->values, struct ldb_val,
708 el2->num_values + el->num_values);
712 ret = LDB_ERR_OPERATIONS_ERROR;
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;
726 case LDB_FLAG_MOD_REPLACE:
727 if (a && a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) {
728 if (el->num_values > 1) {
729 ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s speicified more than once",
730 el->name, ldb_dn_get_linearized(msg->dn));
731 return LDB_ERR_CONSTRAINT_VIOLATION;
734 /* replace all elements of this attribute name with the elements
735 listed. The attribute not existing is not an error */
736 msg_delete_attribute(module, msg2, el->name);
738 for (j=0;j<el->num_values;j++) {
739 if (ldb_msg_find_val(el, &el->values[j]) != &el->values[j]) {
740 ldb_asprintf_errstring(ldb, "%s: value #%d provided more than once", el->name, j);
741 ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
746 /* add the replacement element, if not empty */
747 if (el->num_values != 0 &&
748 msg_add_element(ldb, msg2, el) != 0) {
754 case LDB_FLAG_MOD_DELETE:
756 /* we could be being asked to delete all
757 values or just some values */
758 if (msg->elements[i].num_values == 0) {
759 if (msg_delete_attribute(module, msg2,
760 msg->elements[i].name) != 0) {
761 const char *dn = ldb_dn_get_linearized(msg->dn);
762 ldb_asprintf_errstring(ldb, "No such attribute: %s for delete on %s", msg->elements[i].name, dn);
763 ret = LDB_ERR_NO_SUCH_ATTRIBUTE;
768 for (j=0;j<msg->elements[i].num_values;j++) {
769 if (msg_delete_element(module,
771 msg->elements[i].name,
772 &msg->elements[i].values[j]) != 0) {
773 const char *dn = ldb_dn_get_linearized(msg->dn);
774 ldb_asprintf_errstring(ldb, "No matching attribute value (%*.*s) when deleting attribute: %s on %s",
775 (int)msg->elements[i].values[j].length, (int)msg->elements[i].values[j].length,
776 (const char *)msg->elements[i].values[j].data,
777 msg->elements[i].name, dn);
778 ret = LDB_ERR_NO_SUCH_ATTRIBUTE;
781 ret = ltdb_index_del_value(module, tmp_ctx, msg->dn, &msg->elements[i], j);
782 if (ret != LDB_SUCCESS) {
788 ldb_asprintf_errstring(ldb,
789 "Invalid ldb_modify flags on %s: 0x%x",
790 msg->elements[i].name,
791 msg->elements[i].flags & LDB_FLAG_MOD_MASK);
792 ret = LDB_ERR_PROTOCOL_ERROR;
797 /* we've made all the mods
798 * save the modified record back into the database */
799 ret = ltdb_store(module, mem_ctx, msg2, TDB_MODIFY);
800 if (ret != LDB_SUCCESS) {
804 ret = ltdb_modified(module, msg->dn);
805 if (ret != LDB_SUCCESS) {
813 talloc_free(tmp_ctx);
821 static int ltdb_modify(struct ltdb_context *ctx)
823 struct ldb_module *module = ctx->module;
824 struct ldb_request *req = ctx->req;
827 ldb_request_set_state(req, LDB_ASYNC_PENDING);
829 tret = ltdb_check_special_dn(module, req->op.mod.message);
830 if (tret != LDB_SUCCESS) {
834 if (ltdb_cache_load(module) != 0) {
835 return LDB_ERR_OPERATIONS_ERROR;
838 tret = ltdb_modify_internal(module, req, req->op.mod.message);
839 if (tret != LDB_SUCCESS) {
849 static int ltdb_rename(struct ltdb_context *ctx)
851 struct ldb_module *module = ctx->module;
852 struct ldb_request *req = ctx->req;
853 struct ldb_message *msg;
856 ldb_request_set_state(req, LDB_ASYNC_PENDING);
858 if (ltdb_cache_load(ctx->module) != 0) {
859 return LDB_ERR_OPERATIONS_ERROR;
862 msg = talloc(ctx, struct ldb_message);
864 return LDB_ERR_OPERATIONS_ERROR;
867 /* in case any attribute of the message was indexed, we need
868 to fetch the old record */
869 tret = ltdb_search_dn1(module, req->op.rename.olddn, msg);
870 if (tret != LDB_SUCCESS) {
872 /* not finding the old record is an error */
876 msg->dn = ldb_dn_copy(msg, req->op.rename.newdn);
879 return LDB_ERR_OPERATIONS_ERROR;
882 /* Always delete first then add, to avoid conflicts with
883 * unique indexes. We rely on the transaction to make this
886 tret = ltdb_delete_internal(module, msg, req->op.rename.olddn);
887 if (tret != LDB_SUCCESS) {
892 tret = ltdb_add_internal(module, msg, msg);
894 if (tret != LDB_SUCCESS) {
901 static int ltdb_start_trans(struct ldb_module *module)
903 void *data = ldb_module_get_private(module);
904 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
906 if (tdb_transaction_start(ltdb->tdb) != 0) {
907 return ltdb_err_map(tdb_error(ltdb->tdb));
910 ltdb->in_transaction++;
912 ltdb_index_transaction_start(module);
917 static int ltdb_prepare_commit(struct ldb_module *module)
919 void *data = ldb_module_get_private(module);
920 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
922 if (ltdb->in_transaction != 1) {
926 if (ltdb_index_transaction_prepare_commit(module) != 0) {
927 tdb_transaction_cancel(ltdb->tdb);
928 ltdb->in_transaction--;
929 return ltdb_err_map(tdb_error(ltdb->tdb));
932 if (tdb_transaction_prepare_commit(ltdb->tdb) != 0) {
933 ltdb->in_transaction--;
934 return ltdb_err_map(tdb_error(ltdb->tdb));
937 ltdb->prepared_commit = true;
942 static int ltdb_end_trans(struct ldb_module *module)
944 void *data = ldb_module_get_private(module);
945 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
947 if (!ltdb->prepared_commit) {
948 int ret = ltdb_prepare_commit(module);
949 if (ret != LDB_SUCCESS) {
954 ltdb->in_transaction--;
955 ltdb->prepared_commit = false;
957 if (tdb_transaction_commit(ltdb->tdb) != 0) {
958 return ltdb_err_map(tdb_error(ltdb->tdb));
964 static int ltdb_del_trans(struct ldb_module *module)
966 void *data = ldb_module_get_private(module);
967 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
969 ltdb->in_transaction--;
971 if (ltdb_index_transaction_cancel(module) != 0) {
972 tdb_transaction_cancel(ltdb->tdb);
973 return ltdb_err_map(tdb_error(ltdb->tdb));
976 if (tdb_transaction_cancel(ltdb->tdb) != 0) {
977 return ltdb_err_map(tdb_error(ltdb->tdb));
984 return sequenceNumber from @BASEINFO
986 static int ltdb_sequence_number(struct ltdb_context *ctx,
987 struct ldb_extended **ext)
989 struct ldb_context *ldb;
990 struct ldb_module *module = ctx->module;
991 struct ldb_request *req = ctx->req;
993 struct ldb_seqnum_request *seq;
994 struct ldb_seqnum_result *res;
995 struct ldb_message *msg = NULL;
1000 ldb = ldb_module_get_ctx(module);
1002 seq = talloc_get_type(req->op.extended.data,
1003 struct ldb_seqnum_request);
1005 return LDB_ERR_OPERATIONS_ERROR;
1008 ldb_request_set_state(req, LDB_ASYNC_PENDING);
1010 if (ltdb_lock_read(module) != 0) {
1011 return LDB_ERR_OPERATIONS_ERROR;
1014 res = talloc_zero(req, struct ldb_seqnum_result);
1016 ret = LDB_ERR_OPERATIONS_ERROR;
1019 tmp_ctx = talloc_new(req);
1020 if (tmp_ctx == NULL) {
1021 ret = LDB_ERR_OPERATIONS_ERROR;
1025 dn = ldb_dn_new(tmp_ctx, ldb, LTDB_BASEINFO);
1027 msg = talloc(tmp_ctx, struct ldb_message);
1029 ret = LDB_ERR_OPERATIONS_ERROR;
1033 ret = ltdb_search_dn1(module, dn, msg);
1034 if (ret != LDB_SUCCESS) {
1038 switch (seq->type) {
1039 case LDB_SEQ_HIGHEST_SEQ:
1040 res->seq_num = ldb_msg_find_attr_as_uint64(msg, LTDB_SEQUENCE_NUMBER, 0);
1043 res->seq_num = ldb_msg_find_attr_as_uint64(msg, LTDB_SEQUENCE_NUMBER, 0);
1046 case LDB_SEQ_HIGHEST_TIMESTAMP:
1047 date = ldb_msg_find_attr_as_string(msg, LTDB_MOD_TIMESTAMP, NULL);
1049 res->seq_num = ldb_string_to_time(date);
1052 /* zero is as good as anything when we don't know */
1057 *ext = talloc_zero(req, struct ldb_extended);
1059 ret = LDB_ERR_OPERATIONS_ERROR;
1062 (*ext)->oid = LDB_EXTENDED_SEQUENCE_NUMBER;
1063 (*ext)->data = talloc_steal(*ext, res);
1068 talloc_free(tmp_ctx);
1069 ltdb_unlock_read(module);
1073 static void ltdb_request_done(struct ltdb_context *ctx, int error)
1075 struct ldb_context *ldb;
1076 struct ldb_request *req;
1077 struct ldb_reply *ares;
1079 ldb = ldb_module_get_ctx(ctx->module);
1082 /* if we already returned an error just return */
1083 if (ldb_request_get_status(req) != LDB_SUCCESS) {
1087 ares = talloc_zero(req, struct ldb_reply);
1090 req->callback(req, NULL);
1093 ares->type = LDB_REPLY_DONE;
1094 ares->error = error;
1096 req->callback(req, ares);
1099 static void ltdb_timeout(struct tevent_context *ev,
1100 struct tevent_timer *te,
1104 struct ltdb_context *ctx;
1105 ctx = talloc_get_type(private_data, struct ltdb_context);
1107 if (!ctx->request_terminated) {
1108 /* request is done now */
1109 ltdb_request_done(ctx, LDB_ERR_TIME_LIMIT_EXCEEDED);
1112 if (!ctx->request_terminated) {
1113 /* neutralize the spy */
1114 ctx->spy->ctx = NULL;
1119 static void ltdb_request_extended_done(struct ltdb_context *ctx,
1120 struct ldb_extended *ext,
1123 struct ldb_context *ldb;
1124 struct ldb_request *req;
1125 struct ldb_reply *ares;
1127 ldb = ldb_module_get_ctx(ctx->module);
1130 /* if we already returned an error just return */
1131 if (ldb_request_get_status(req) != LDB_SUCCESS) {
1135 ares = talloc_zero(req, struct ldb_reply);
1138 req->callback(req, NULL);
1141 ares->type = LDB_REPLY_DONE;
1142 ares->response = ext;
1143 ares->error = error;
1145 req->callback(req, ares);
1148 static void ltdb_handle_extended(struct ltdb_context *ctx)
1150 struct ldb_extended *ext = NULL;
1153 if (strcmp(ctx->req->op.extended.oid,
1154 LDB_EXTENDED_SEQUENCE_NUMBER) == 0) {
1155 /* get sequence number */
1156 ret = ltdb_sequence_number(ctx, &ext);
1158 /* not recognized */
1159 ret = LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
1162 ltdb_request_extended_done(ctx, ext, ret);
1165 static void ltdb_callback(struct tevent_context *ev,
1166 struct tevent_timer *te,
1170 struct ltdb_context *ctx;
1173 ctx = talloc_get_type(private_data, struct ltdb_context);
1175 if (ctx->request_terminated) {
1179 switch (ctx->req->operation) {
1181 ret = ltdb_search(ctx);
1184 ret = ltdb_add(ctx);
1187 ret = ltdb_modify(ctx);
1190 ret = ltdb_delete(ctx);
1193 ret = ltdb_rename(ctx);
1196 ltdb_handle_extended(ctx);
1199 /* no other op supported */
1200 ret = LDB_ERR_UNWILLING_TO_PERFORM;
1203 if (!ctx->request_terminated) {
1204 /* request is done now */
1205 ltdb_request_done(ctx, ret);
1209 if (!ctx->request_terminated) {
1210 /* neutralize the spy */
1211 ctx->spy->ctx = NULL;
1216 static int ltdb_request_destructor(void *ptr)
1218 struct ltdb_req_spy *spy = talloc_get_type(ptr, struct ltdb_req_spy);
1220 if (spy->ctx != NULL) {
1221 spy->ctx->request_terminated = true;
1227 static int ltdb_handle_request(struct ldb_module *module,
1228 struct ldb_request *req)
1230 struct ldb_context *ldb;
1231 struct tevent_context *ev;
1232 struct ltdb_context *ac;
1233 struct tevent_timer *te;
1236 if (check_critical_controls(req->controls)) {
1237 return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
1240 ldb = ldb_module_get_ctx(module);
1242 if (req->starttime == 0 || req->timeout == 0) {
1243 ldb_set_errstring(ldb, "Invalid timeout settings");
1244 return LDB_ERR_TIME_LIMIT_EXCEEDED;
1247 ev = ldb_get_event_context(ldb);
1249 ac = talloc_zero(ldb, struct ltdb_context);
1251 ldb_set_errstring(ldb, "Out of Memory");
1252 return LDB_ERR_OPERATIONS_ERROR;
1255 ac->module = module;
1260 te = tevent_add_timer(ev, ac, tv, ltdb_callback, ac);
1263 return LDB_ERR_OPERATIONS_ERROR;
1266 tv.tv_sec = req->starttime + req->timeout;
1267 ac->timeout_event = tevent_add_timer(ev, ac, tv, ltdb_timeout, ac);
1268 if (NULL == ac->timeout_event) {
1270 return LDB_ERR_OPERATIONS_ERROR;
1273 /* set a spy so that we do not try to use the request context
1274 * if it is freed before ltdb_callback fires */
1275 ac->spy = talloc(req, struct ltdb_req_spy);
1276 if (NULL == ac->spy) {
1278 return LDB_ERR_OPERATIONS_ERROR;
1282 talloc_set_destructor((TALLOC_CTX *)ac->spy, ltdb_request_destructor);
1287 static const struct ldb_module_ops ltdb_ops = {
1289 .search = ltdb_handle_request,
1290 .add = ltdb_handle_request,
1291 .modify = ltdb_handle_request,
1292 .del = ltdb_handle_request,
1293 .rename = ltdb_handle_request,
1294 .extended = ltdb_handle_request,
1295 .start_transaction = ltdb_start_trans,
1296 .end_transaction = ltdb_end_trans,
1297 .prepare_commit = ltdb_prepare_commit,
1298 .del_transaction = ltdb_del_trans,
1302 connect to the database
1304 static int ltdb_connect(struct ldb_context *ldb, const char *url,
1305 unsigned int flags, const char *options[],
1306 struct ldb_module **_module)
1308 struct ldb_module *module;
1310 int tdb_flags, open_flags;
1311 struct ltdb_private *ltdb;
1314 if (strchr(url, ':')) {
1315 if (strncmp(url, "tdb://", 6) != 0) {
1316 ldb_debug(ldb, LDB_DEBUG_ERROR,
1317 "Invalid tdb URL '%s'", url);
1325 tdb_flags = TDB_DEFAULT | TDB_SEQNUM;
1327 /* check for the 'nosync' option */
1328 if (flags & LDB_FLG_NOSYNC) {
1329 tdb_flags |= TDB_NOSYNC;
1332 /* and nommap option */
1333 if (flags & LDB_FLG_NOMMAP) {
1334 tdb_flags |= TDB_NOMMAP;
1337 if (flags & LDB_FLG_RDONLY) {
1338 open_flags = O_RDONLY;
1340 open_flags = O_CREAT | O_RDWR;
1343 ltdb = talloc_zero(ldb, struct ltdb_private);
1349 /* note that we use quite a large default hash size */
1350 ltdb->tdb = ltdb_wrap_open(ltdb, path, 10000,
1351 tdb_flags, open_flags,
1352 ldb_get_create_perms(ldb), ldb);
1354 ldb_debug(ldb, LDB_DEBUG_ERROR,
1355 "Unable to open tdb '%s'", path);
1360 ltdb->sequence_number = 0;
1362 module = ldb_module_new(ldb, ldb, "ldb_tdb backend", <db_ops);
1367 ldb_module_set_private(module, ltdb);
1369 if (ltdb_cache_load(module) != 0) {
1370 talloc_free(module);
1379 const struct ldb_backend_ops ldb_tdb_backend_ops = {
1381 .connect_fn = ltdb_connect