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);
108 form a TDB_DATA for a record key
111 note that the key for a record can depend on whether the
112 dn refers to a case sensitive index record or not
114 struct TDB_DATA ltdb_key(struct ldb_module *module, struct ldb_dn *dn)
116 struct ldb_context *ldb = ldb_module_get_ctx(module);
118 char *key_str = NULL;
119 const char *dn_folded = NULL;
122 most DNs are case insensitive. The exception is index DNs for
123 case sensitive attributes
125 there are 3 cases dealt with in this code:
127 1) if the dn doesn't start with @ then uppercase the attribute
128 names and the attributes values of case insensitive attributes
129 2) if the dn starts with @ then leave it alone -
130 the indexing code handles the rest
133 dn_folded = ldb_dn_get_casefold(dn);
138 key_str = talloc_strdup(ldb, "DN=");
143 key_str = talloc_strdup_append_buffer(key_str, dn_folded);
148 key.dptr = (uint8_t *)key_str;
149 key.dsize = strlen(key_str) + 1;
161 check special dn's have valid attributes
162 currently only @ATTRIBUTES is checked
164 static int ltdb_check_special_dn(struct ldb_module *module,
165 const struct ldb_message *msg)
167 struct ldb_context *ldb = ldb_module_get_ctx(module);
170 if (! ldb_dn_is_special(msg->dn) ||
171 ! ldb_dn_check_special(msg->dn, LTDB_ATTRIBUTES)) {
175 /* we have @ATTRIBUTES, let's check attributes are fine */
176 /* should we check that we deny multivalued attributes ? */
177 for (i = 0; i < msg->num_elements; i++) {
178 for (j = 0; j < msg->elements[i].num_values; j++) {
179 if (ltdb_check_at_attributes_values(&msg->elements[i].values[j]) != 0) {
180 ldb_set_errstring(ldb, "Invalid attribute value in an @ATTRIBUTES entry");
181 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
191 we've made a modification to a dn - possibly reindex and
192 update sequence number
194 static int ltdb_modified(struct ldb_module *module, struct ldb_dn *dn)
196 int ret = LDB_SUCCESS;
198 if (ldb_dn_is_special(dn) &&
199 (ldb_dn_check_special(dn, LTDB_INDEXLIST) ||
200 ldb_dn_check_special(dn, LTDB_ATTRIBUTES)) ) {
201 ret = ltdb_reindex(module);
204 if (ret == LDB_SUCCESS &&
205 !(ldb_dn_is_special(dn) &&
206 ldb_dn_check_special(dn, LTDB_BASEINFO)) ) {
207 ret = ltdb_increase_sequence_number(module);
214 store a record into the db
216 int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flgs)
218 void *data = ldb_module_get_private(module);
219 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
220 TDB_DATA tdb_key, tdb_data;
223 tdb_key = ltdb_key(module, msg->dn);
225 return LDB_ERR_OTHER;
228 ret = ltdb_pack_data(module, msg, &tdb_data);
230 talloc_free(tdb_key.dptr);
231 return LDB_ERR_OTHER;
234 ret = tdb_store(ltdb->tdb, tdb_key, tdb_data, flgs);
236 ret = ltdb_err_map(tdb_error(ltdb->tdb));
240 ret = ltdb_index_add(module, msg);
241 if (ret != LDB_SUCCESS) {
242 tdb_delete(ltdb->tdb, tdb_key);
246 talloc_free(tdb_key.dptr);
247 talloc_free(tdb_data.dptr);
253 static int ltdb_add_internal(struct ldb_module *module,
254 const struct ldb_message *msg)
256 struct ldb_context *ldb = ldb_module_get_ctx(module);
259 ret = ltdb_check_special_dn(module, msg);
260 if (ret != LDB_SUCCESS) {
264 if (ltdb_cache_load(module) != 0) {
265 return LDB_ERR_OPERATIONS_ERROR;
268 ret = ltdb_store(module, msg, TDB_INSERT);
270 if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) {
271 ldb_asprintf_errstring(ldb,
272 "Entry %s already exists",
273 ldb_dn_get_linearized(msg->dn));
277 if (ret == LDB_SUCCESS) {
278 ret = ltdb_index_one(module, msg, 1);
279 if (ret != LDB_SUCCESS) {
283 ret = ltdb_modified(module, msg->dn);
284 if (ret != LDB_SUCCESS) {
293 add a record to the database
295 static int ltdb_add(struct ltdb_context *ctx)
297 struct ldb_module *module = ctx->module;
298 struct ldb_request *req = ctx->req;
301 ldb_request_set_state(req, LDB_ASYNC_PENDING);
303 tret = ltdb_add_internal(module, req->op.add.message);
304 if (tret != LDB_SUCCESS) {
312 delete a record from the database, not updating indexes (used for deleting
315 int ltdb_delete_noindex(struct ldb_module *module, struct ldb_dn *dn)
317 void *data = ldb_module_get_private(module);
318 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
322 tdb_key = ltdb_key(module, dn);
324 return LDB_ERR_OTHER;
327 ret = tdb_delete(ltdb->tdb, tdb_key);
328 talloc_free(tdb_key.dptr);
331 ret = ltdb_err_map(tdb_error(ltdb->tdb));
337 static int ltdb_delete_internal(struct ldb_module *module, struct ldb_dn *dn)
339 struct ldb_message *msg;
342 msg = talloc(module, struct ldb_message);
344 return LDB_ERR_OPERATIONS_ERROR;
347 /* in case any attribute of the message was indexed, we need
348 to fetch the old record */
349 ret = ltdb_search_dn1(module, dn, msg);
350 if (ret != LDB_SUCCESS) {
351 /* not finding the old record is an error */
355 ret = ltdb_delete_noindex(module, dn);
356 if (ret != LDB_SUCCESS) {
360 /* remove one level attribute */
361 ret = ltdb_index_one(module, msg, 0);
362 if (ret != LDB_SUCCESS) {
366 /* remove any indexed attributes */
367 ret = ltdb_index_del(module, msg);
368 if (ret != LDB_SUCCESS) {
372 ret = ltdb_modified(module, dn);
373 if (ret != LDB_SUCCESS) {
383 delete a record from the database
385 static int ltdb_delete(struct ltdb_context *ctx)
387 struct ldb_module *module = ctx->module;
388 struct ldb_request *req = ctx->req;
391 ldb_request_set_state(req, LDB_ASYNC_PENDING);
393 if (ltdb_cache_load(module) != 0) {
394 return LDB_ERR_OPERATIONS_ERROR;
397 tret = ltdb_delete_internal(module, req->op.del.dn);
398 if (tret != LDB_SUCCESS) {
406 find an element by attribute name. At the moment this does a linear search,
407 it should be re-coded to use a binary search once all places that modify
408 records guarantee sorted order
410 return the index of the first matching element if found, otherwise -1
412 static int find_element(const struct ldb_message *msg, const char *name)
415 for (i=0;i<msg->num_elements;i++) {
416 if (ldb_attr_cmp(msg->elements[i].name, name) == 0) {
425 add an element to an existing record. Assumes a elements array that we
426 can call re-alloc on, and assumed that we can re-use the data pointers from
427 the passed in additional values. Use with care!
429 returns 0 on success, -1 on failure (and sets errno)
431 static int msg_add_element(struct ldb_context *ldb,
432 struct ldb_message *msg,
433 struct ldb_message_element *el)
435 struct ldb_message_element *e2;
438 e2 = talloc_realloc(msg, msg->elements, struct ldb_message_element,
439 msg->num_elements+1);
447 e2 = &msg->elements[msg->num_elements];
450 e2->flags = el->flags;
452 if (el->num_values != 0) {
453 e2->values = talloc_array(msg->elements,
454 struct ldb_val, el->num_values);
460 for (i=0;i<el->num_values;i++) {
461 e2->values[i] = el->values[i];
463 e2->num_values = el->num_values;
471 delete all elements having a specified attribute name
473 static int msg_delete_attribute(struct ldb_module *module,
474 struct ldb_context *ldb,
475 struct ldb_message *msg, const char *name)
480 dn = ldb_dn_get_linearized(msg->dn);
485 for (i=0;i<msg->num_elements;i++) {
486 if (ldb_attr_cmp(msg->elements[i].name, name) == 0) {
487 for (j=0;j<msg->elements[i].num_values;j++) {
488 ltdb_index_del_value(module, dn,
489 &msg->elements[i], j);
491 talloc_free(msg->elements[i].values);
492 if (msg->num_elements > (i+1)) {
493 memmove(&msg->elements[i],
495 sizeof(struct ldb_message_element)*
496 (msg->num_elements - (i+1)));
500 msg->elements = talloc_realloc(msg, msg->elements,
501 struct ldb_message_element,
510 delete all elements matching an attribute name/value
512 return 0 on success, -1 on failure
514 static int msg_delete_element(struct ldb_module *module,
515 struct ldb_message *msg,
517 const struct ldb_val *val)
519 struct ldb_context *ldb = ldb_module_get_ctx(module);
522 struct ldb_message_element *el;
523 const struct ldb_schema_attribute *a;
525 found = find_element(msg, name);
530 el = &msg->elements[found];
532 a = ldb_schema_attribute_by_name(ldb, el->name);
534 for (i=0;i<el->num_values;i++) {
535 if (a->syntax->comparison_fn(ldb, ldb,
536 &el->values[i], val) == 0) {
537 if (i<el->num_values-1) {
538 memmove(&el->values[i], &el->values[i+1],
539 sizeof(el->values[i])*
540 (el->num_values-(i+1)));
543 if (el->num_values == 0) {
544 return msg_delete_attribute(module, ldb,
556 modify a record - internal interface
558 yuck - this is O(n^2). Luckily n is usually small so we probably
559 get away with it, but if we ever have really large attribute lists
560 then we'll need to look at this again
562 int ltdb_modify_internal(struct ldb_module *module,
563 const struct ldb_message *msg)
565 struct ldb_context *ldb = ldb_module_get_ctx(module);
566 void *data = ldb_module_get_private(module);
567 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
568 TDB_DATA tdb_key, tdb_data;
569 struct ldb_message *msg2;
573 tdb_key = ltdb_key(module, msg->dn);
575 return LDB_ERR_OTHER;
578 tdb_data = tdb_fetch(ltdb->tdb, tdb_key);
579 if (!tdb_data.dptr) {
580 talloc_free(tdb_key.dptr);
581 return ltdb_err_map(tdb_error(ltdb->tdb));
584 msg2 = talloc(tdb_key.dptr, struct ldb_message);
586 talloc_free(tdb_key.dptr);
587 return LDB_ERR_OTHER;
590 ret = ltdb_unpack_data(module, &tdb_data, msg2);
600 for (i=0;i<msg->num_elements;i++) {
601 struct ldb_message_element *el = &msg->elements[i];
602 struct ldb_message_element *el2;
603 struct ldb_val *vals;
606 switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) {
608 case LDB_FLAG_MOD_ADD:
609 /* add this element to the message. fail if it
611 idx = find_element(msg2, el->name);
614 if (msg_add_element(ldb, msg2, el) != 0) {
621 el2 = &msg2->elements[idx];
623 /* An attribute with this name already exists,
624 * add all values if they don't already exist
625 * (check both the other elements to be added,
626 * and those already in the db). */
628 for (j=0;j<el->num_values;j++) {
629 if (ldb_msg_find_val(el2, &el->values[j])) {
630 ldb_asprintf_errstring(ldb, "%s: value #%d already exists", el->name, j);
631 ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
634 if (ldb_msg_find_val(el, &el->values[j]) != &el->values[j]) {
635 ldb_asprintf_errstring(ldb, "%s: value #%d provided more than once", el->name, j);
636 ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
641 vals = talloc_realloc(msg2->elements, el2->values, struct ldb_val,
642 el2->num_values + el->num_values);
649 for (j=0;j<el->num_values;j++) {
650 vals[el2->num_values + j] =
651 ldb_val_dup(vals, &el->values[j]);
655 el2->num_values += el->num_values;
659 case LDB_FLAG_MOD_REPLACE:
660 /* replace all elements of this attribute name with the elements
661 listed. The attribute not existing is not an error */
662 msg_delete_attribute(module, ldb, msg2, el->name);
664 for (j=0;j<el->num_values;j++) {
665 if (ldb_msg_find_val(el, &el->values[j]) != &el->values[j]) {
666 ldb_asprintf_errstring(ldb, "%s: value #%d provided more than once", el->name, j);
667 ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
672 /* add the replacement element, if not empty */
673 if (el->num_values != 0 &&
674 msg_add_element(ldb, msg2, el) != 0) {
680 case LDB_FLAG_MOD_DELETE:
682 dn = ldb_dn_get_linearized(msg->dn);
688 /* we could be being asked to delete all
689 values or just some values */
690 if (msg->elements[i].num_values == 0) {
691 if (msg_delete_attribute(module, ldb, msg2,
692 msg->elements[i].name) != 0) {
693 ldb_asprintf_errstring(ldb, "No such attribute: %s for delete on %s", msg->elements[i].name, dn);
694 ret = LDB_ERR_NO_SUCH_ATTRIBUTE;
699 for (j=0;j<msg->elements[i].num_values;j++) {
700 if (msg_delete_element(module,
702 msg->elements[i].name,
703 &msg->elements[i].values[j]) != 0) {
704 ldb_asprintf_errstring(ldb, "No matching attribute value when deleting attribute: %s on %s", msg->elements[i].name, dn);
705 ret = LDB_ERR_NO_SUCH_ATTRIBUTE;
708 ret = ltdb_index_del_value(module, dn, &msg->elements[i], j);
709 if (ret != LDB_SUCCESS) {
715 ldb_asprintf_errstring(ldb,
716 "Invalid ldb_modify flags on %s: 0x%x",
717 msg->elements[i].name,
718 msg->elements[i].flags & LDB_FLAG_MOD_MASK);
719 ret = LDB_ERR_PROTOCOL_ERROR;
724 /* we've made all the mods
725 * save the modified record back into the database */
726 ret = ltdb_store(module, msg2, TDB_MODIFY);
727 if (ret != LDB_SUCCESS) {
731 ret = ltdb_modified(module, msg->dn);
732 if (ret != LDB_SUCCESS) {
736 talloc_free(tdb_key.dptr);
741 talloc_free(tdb_key.dptr);
749 static int ltdb_modify(struct ltdb_context *ctx)
751 struct ldb_module *module = ctx->module;
752 struct ldb_request *req = ctx->req;
755 ldb_request_set_state(req, LDB_ASYNC_PENDING);
757 tret = ltdb_check_special_dn(module, req->op.mod.message);
758 if (tret != LDB_SUCCESS) {
762 if (ltdb_cache_load(module) != 0) {
763 return LDB_ERR_OPERATIONS_ERROR;
766 tret = ltdb_modify_internal(module, req->op.mod.message);
767 if (tret != LDB_SUCCESS) {
777 static int ltdb_rename(struct ltdb_context *ctx)
779 struct ldb_module *module = ctx->module;
780 struct ldb_request *req = ctx->req;
781 struct ldb_message *msg;
784 ldb_request_set_state(req, LDB_ASYNC_PENDING);
786 if (ltdb_cache_load(ctx->module) != 0) {
787 return LDB_ERR_OPERATIONS_ERROR;
790 msg = talloc(ctx, struct ldb_message);
792 return LDB_ERR_OPERATIONS_ERROR;
795 /* in case any attribute of the message was indexed, we need
796 to fetch the old record */
797 tret = ltdb_search_dn1(module, req->op.rename.olddn, msg);
798 if (tret != LDB_SUCCESS) {
799 /* not finding the old record is an error */
803 msg->dn = ldb_dn_copy(msg, req->op.rename.newdn);
805 return LDB_ERR_OPERATIONS_ERROR;
808 if (ldb_dn_compare(req->op.rename.olddn, req->op.rename.newdn) == 0) {
809 /* The rename operation is apparently only changing case -
810 the DNs are the same. Delete the old DN before adding
811 the new one to avoid a TDB_ERR_EXISTS error.
813 The only drawback to this is that if the delete
814 succeeds but the add fails, we rely on the
815 transaction to roll this all back. */
816 tret = ltdb_delete_internal(module, req->op.rename.olddn);
817 if (tret != LDB_SUCCESS) {
821 tret = ltdb_add_internal(module, msg);
822 if (tret != LDB_SUCCESS) {
826 /* The rename operation is changing DNs. Try to add the new
827 DN first to avoid clobbering another DN not related to
828 this rename operation. */
829 tret = ltdb_add_internal(module, msg);
830 if (tret != LDB_SUCCESS) {
834 tret = ltdb_delete_internal(module, req->op.rename.olddn);
835 if (tret != LDB_SUCCESS) {
836 ltdb_delete_internal(module, req->op.rename.newdn);
837 return LDB_ERR_OPERATIONS_ERROR;
844 static int ltdb_start_trans(struct ldb_module *module)
846 void *data = ldb_module_get_private(module);
847 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
849 if (tdb_transaction_start(ltdb->tdb) != 0) {
850 return ltdb_err_map(tdb_error(ltdb->tdb));
853 ltdb->in_transaction++;
855 ltdb_index_transaction_start(module);
860 static int ltdb_prepare_commit(struct ldb_module *module)
862 void *data = ldb_module_get_private(module);
863 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
865 if (ltdb->in_transaction != 1) {
869 if (ltdb_index_transaction_commit(module) != 0) {
870 tdb_transaction_cancel(ltdb->tdb);
871 ltdb->in_transaction--;
872 return ltdb_err_map(tdb_error(ltdb->tdb));
875 if (tdb_transaction_prepare_commit(ltdb->tdb) != 0) {
876 ltdb->in_transaction--;
877 return ltdb_err_map(tdb_error(ltdb->tdb));
880 ltdb->prepared_commit = true;
885 static int ltdb_end_trans(struct ldb_module *module)
887 void *data = ldb_module_get_private(module);
888 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
890 if (!ltdb->prepared_commit) {
891 int ret = ltdb_prepare_commit(module);
892 if (ret != LDB_SUCCESS) {
897 ltdb->in_transaction--;
898 ltdb->prepared_commit = false;
900 if (tdb_transaction_commit(ltdb->tdb) != 0) {
901 return ltdb_err_map(tdb_error(ltdb->tdb));
907 static int ltdb_del_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 ltdb->in_transaction--;
914 if (ltdb_index_transaction_cancel(module) != 0) {
915 tdb_transaction_cancel(ltdb->tdb);
916 return ltdb_err_map(tdb_error(ltdb->tdb));
919 if (tdb_transaction_cancel(ltdb->tdb) != 0) {
920 return ltdb_err_map(tdb_error(ltdb->tdb));
927 return sequenceNumber from @BASEINFO
929 static int ltdb_sequence_number(struct ltdb_context *ctx,
930 struct ldb_extended **ext)
932 struct ldb_context *ldb;
933 struct ldb_module *module = ctx->module;
934 struct ldb_request *req = ctx->req;
936 struct ldb_seqnum_request *seq;
937 struct ldb_seqnum_result *res;
938 struct ldb_message *msg = NULL;
943 ldb = ldb_module_get_ctx(module);
945 seq = talloc_get_type(req->op.extended.data,
946 struct ldb_seqnum_request);
948 return LDB_ERR_OPERATIONS_ERROR;
951 ldb_request_set_state(req, LDB_ASYNC_PENDING);
953 if (ltdb_lock_read(module) != 0) {
954 return LDB_ERR_OPERATIONS_ERROR;
957 res = talloc_zero(req, struct ldb_seqnum_result);
959 ret = LDB_ERR_OPERATIONS_ERROR;
962 tmp_ctx = talloc_new(req);
963 if (tmp_ctx == NULL) {
964 ret = LDB_ERR_OPERATIONS_ERROR;
968 dn = ldb_dn_new(tmp_ctx, ldb, LTDB_BASEINFO);
970 msg = talloc(tmp_ctx, struct ldb_message);
972 ret = LDB_ERR_OPERATIONS_ERROR;
976 ret = ltdb_search_dn1(module, dn, msg);
977 if (ret != LDB_SUCCESS) {
982 case LDB_SEQ_HIGHEST_SEQ:
983 res->seq_num = ldb_msg_find_attr_as_uint64(msg, LTDB_SEQUENCE_NUMBER, 0);
986 res->seq_num = ldb_msg_find_attr_as_uint64(msg, LTDB_SEQUENCE_NUMBER, 0);
989 case LDB_SEQ_HIGHEST_TIMESTAMP:
990 date = ldb_msg_find_attr_as_string(msg, LTDB_MOD_TIMESTAMP, NULL);
992 res->seq_num = ldb_string_to_time(date);
995 /* zero is as good as anything when we don't know */
1000 *ext = talloc_zero(req, struct ldb_extended);
1002 ret = LDB_ERR_OPERATIONS_ERROR;
1005 (*ext)->oid = LDB_EXTENDED_SEQUENCE_NUMBER;
1006 (*ext)->data = talloc_steal(*ext, res);
1011 talloc_free(tmp_ctx);
1012 ltdb_unlock_read(module);
1016 static void ltdb_request_done(struct ltdb_context *ctx, int error)
1018 struct ldb_context *ldb;
1019 struct ldb_request *req;
1020 struct ldb_reply *ares;
1022 ldb = ldb_module_get_ctx(ctx->module);
1025 /* if we already returned an error just return */
1026 if (ldb_request_get_status(req) != LDB_SUCCESS) {
1030 ares = talloc_zero(req, struct ldb_reply);
1033 req->callback(req, NULL);
1036 ares->type = LDB_REPLY_DONE;
1037 ares->error = error;
1039 req->callback(req, ares);
1042 static void ltdb_timeout(struct tevent_context *ev,
1043 struct tevent_timer *te,
1047 struct ltdb_context *ctx;
1048 ctx = talloc_get_type(private_data, struct ltdb_context);
1050 if (!ctx->request_terminated) {
1051 /* request is done now */
1052 ltdb_request_done(ctx, LDB_ERR_TIME_LIMIT_EXCEEDED);
1055 if (!ctx->request_terminated) {
1056 /* neutralize the spy */
1057 ctx->spy->ctx = NULL;
1062 static void ltdb_request_extended_done(struct ltdb_context *ctx,
1063 struct ldb_extended *ext,
1066 struct ldb_context *ldb;
1067 struct ldb_request *req;
1068 struct ldb_reply *ares;
1070 ldb = ldb_module_get_ctx(ctx->module);
1073 /* if we already returned an error just return */
1074 if (ldb_request_get_status(req) != LDB_SUCCESS) {
1078 ares = talloc_zero(req, struct ldb_reply);
1081 req->callback(req, NULL);
1084 ares->type = LDB_REPLY_DONE;
1085 ares->response = ext;
1086 ares->error = error;
1088 req->callback(req, ares);
1091 static void ltdb_handle_extended(struct ltdb_context *ctx)
1093 struct ldb_extended *ext = NULL;
1096 if (strcmp(ctx->req->op.extended.oid,
1097 LDB_EXTENDED_SEQUENCE_NUMBER) == 0) {
1098 /* get sequence number */
1099 ret = ltdb_sequence_number(ctx, &ext);
1101 /* not recognized */
1102 ret = LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
1105 ltdb_request_extended_done(ctx, ext, ret);
1108 static void ltdb_callback(struct tevent_context *ev,
1109 struct tevent_timer *te,
1113 struct ltdb_context *ctx;
1116 ctx = talloc_get_type(private_data, struct ltdb_context);
1118 if (ctx->request_terminated) {
1122 switch (ctx->req->operation) {
1124 ret = ltdb_search(ctx);
1127 ret = ltdb_add(ctx);
1130 ret = ltdb_modify(ctx);
1133 ret = ltdb_delete(ctx);
1136 ret = ltdb_rename(ctx);
1139 ltdb_handle_extended(ctx);
1142 /* no other op supported */
1143 ret = LDB_ERR_UNWILLING_TO_PERFORM;
1146 if (!ctx->request_terminated) {
1147 /* request is done now */
1148 ltdb_request_done(ctx, ret);
1152 if (!ctx->request_terminated) {
1153 /* neutralize the spy */
1154 ctx->spy->ctx = NULL;
1159 static int ltdb_request_destructor(void *ptr)
1161 struct ltdb_req_spy *spy = talloc_get_type(ptr, struct ltdb_req_spy);
1163 if (spy->ctx != NULL) {
1164 spy->ctx->request_terminated = true;
1170 static int ltdb_handle_request(struct ldb_module *module,
1171 struct ldb_request *req)
1173 struct ldb_context *ldb;
1174 struct tevent_context *ev;
1175 struct ltdb_context *ac;
1176 struct tevent_timer *te;
1179 if (check_critical_controls(req->controls)) {
1180 return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
1183 ldb = ldb_module_get_ctx(module);
1185 if (req->starttime == 0 || req->timeout == 0) {
1186 ldb_set_errstring(ldb, "Invalid timeout settings");
1187 return LDB_ERR_TIME_LIMIT_EXCEEDED;
1190 ev = ldb_get_event_context(ldb);
1192 ac = talloc_zero(ldb, struct ltdb_context);
1194 ldb_set_errstring(ldb, "Out of Memory");
1195 return LDB_ERR_OPERATIONS_ERROR;
1198 ac->module = module;
1203 te = tevent_add_timer(ev, ac, tv, ltdb_callback, ac);
1206 return LDB_ERR_OPERATIONS_ERROR;
1209 tv.tv_sec = req->starttime + req->timeout;
1210 ac->timeout_event = tevent_add_timer(ev, ac, tv, ltdb_timeout, ac);
1211 if (NULL == ac->timeout_event) {
1213 return LDB_ERR_OPERATIONS_ERROR;
1216 /* set a spy so that we do not try to use the request context
1217 * if it is freed before ltdb_callback fires */
1218 ac->spy = talloc(req, struct ltdb_req_spy);
1219 if (NULL == ac->spy) {
1221 return LDB_ERR_OPERATIONS_ERROR;
1225 talloc_set_destructor((TALLOC_CTX *)ac->spy, ltdb_request_destructor);
1230 static const struct ldb_module_ops ltdb_ops = {
1232 .search = ltdb_handle_request,
1233 .add = ltdb_handle_request,
1234 .modify = ltdb_handle_request,
1235 .del = ltdb_handle_request,
1236 .rename = ltdb_handle_request,
1237 .extended = ltdb_handle_request,
1238 .start_transaction = ltdb_start_trans,
1239 .end_transaction = ltdb_end_trans,
1240 .prepare_commit = ltdb_prepare_commit,
1241 .del_transaction = ltdb_del_trans,
1245 connect to the database
1247 static int ltdb_connect(struct ldb_context *ldb, const char *url,
1248 unsigned int flags, const char *options[],
1249 struct ldb_module **_module)
1251 struct ldb_module *module;
1253 int tdb_flags, open_flags;
1254 struct ltdb_private *ltdb;
1257 if (strchr(url, ':')) {
1258 if (strncmp(url, "tdb://", 6) != 0) {
1259 ldb_debug(ldb, LDB_DEBUG_ERROR,
1260 "Invalid tdb URL '%s'", url);
1268 tdb_flags = TDB_DEFAULT | TDB_SEQNUM;
1270 /* check for the 'nosync' option */
1271 if (flags & LDB_FLG_NOSYNC) {
1272 tdb_flags |= TDB_NOSYNC;
1275 /* and nommap option */
1276 if (flags & LDB_FLG_NOMMAP) {
1277 tdb_flags |= TDB_NOMMAP;
1280 if (flags & LDB_FLG_RDONLY) {
1281 open_flags = O_RDONLY;
1283 open_flags = O_CREAT | O_RDWR;
1286 ltdb = talloc_zero(ldb, struct ltdb_private);
1292 /* note that we use quite a large default hash size */
1293 ltdb->tdb = ltdb_wrap_open(ltdb, path, 10000,
1294 tdb_flags, open_flags,
1295 ldb_get_create_perms(ldb), ldb);
1297 ldb_debug(ldb, LDB_DEBUG_ERROR,
1298 "Unable to open tdb '%s'\n", path);
1303 ltdb->sequence_number = 0;
1305 module = ldb_module_new(ldb, ldb, "ldb_tdb backend", <db_ops);
1310 ldb_module_set_private(module, ltdb);
1312 if (ltdb_cache_load(module) != 0) {
1313 talloc_free(module);
1322 const struct ldb_backend_ops ldb_tdb_backend_ops = {
1324 .connect_fn = ltdb_connect