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
48 #include "ldb_includes.h"
54 map a tdb error code to a ldb error code
56 static int ltdb_err_map(enum TDB_ERROR tdb_code)
64 return LDB_ERR_OPERATIONS_ERROR;
66 return LDB_ERR_PROTOCOL_ERROR;
70 case TDB_ERR_LOCK_TIMEOUT:
71 return LDB_ERR_TIME_LIMIT_EXCEEDED;
73 return LDB_ERR_ENTRY_ALREADY_EXISTS;
75 return LDB_ERR_NO_SUCH_OBJECT;
77 return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
83 lock the database for read - use by ltdb_search and ltdb_sequence_number
85 int ltdb_lock_read(struct ldb_module *module)
87 struct ltdb_private *ltdb = (struct ltdb_private *)module->private_data;
88 if (ltdb->in_transaction == 0) {
89 return tdb_lockall_read(ltdb->tdb);
95 unlock the database after a ltdb_lock_read()
97 int ltdb_unlock_read(struct ldb_module *module)
99 struct ltdb_private *ltdb = (struct ltdb_private *)module->private_data;
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 = module->ldb;
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 int ltdb_check_special_dn(struct ldb_module *module,
165 const struct ldb_message *msg)
169 if (! ldb_dn_is_special(msg->dn) ||
170 ! ldb_dn_check_special(msg->dn, LTDB_ATTRIBUTES)) {
174 /* we have @ATTRIBUTES, let's check attributes are fine */
175 /* should we check that we deny multivalued attributes ? */
176 for (i = 0; i < msg->num_elements; i++) {
177 for (j = 0; j < msg->elements[i].num_values; j++) {
178 if (ltdb_check_at_attributes_values(&msg->elements[i].values[j]) != 0) {
179 ldb_set_errstring(module->ldb, "Invalid attribute value in an @ATTRIBUTES entry");
180 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
190 we've made a modification to a dn - possibly reindex and
191 update sequence number
193 static int ltdb_modified(struct ldb_module *module, struct ldb_dn *dn)
195 int ret = LDB_SUCCESS;
197 if (ldb_dn_is_special(dn) &&
198 (ldb_dn_check_special(dn, LTDB_INDEXLIST) ||
199 ldb_dn_check_special(dn, LTDB_ATTRIBUTES)) ) {
200 ret = ltdb_reindex(module);
203 if (ret == LDB_SUCCESS &&
204 !(ldb_dn_is_special(dn) &&
205 ldb_dn_check_special(dn, LTDB_BASEINFO)) ) {
206 ret = ltdb_increase_sequence_number(module);
213 store a record into the db
215 int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flgs)
217 struct ltdb_private *ltdb =
218 talloc_get_type(module->private_data, struct ltdb_private);
219 TDB_DATA tdb_key, tdb_data;
222 tdb_key = ltdb_key(module, msg->dn);
224 return LDB_ERR_OTHER;
227 ret = ltdb_pack_data(module, msg, &tdb_data);
229 talloc_free(tdb_key.dptr);
230 return LDB_ERR_OTHER;
233 ret = tdb_store(ltdb->tdb, tdb_key, tdb_data, flgs);
235 ret = ltdb_err_map(tdb_error(ltdb->tdb));
239 ret = ltdb_index_add(module, msg);
240 if (ret != LDB_SUCCESS) {
241 tdb_delete(ltdb->tdb, tdb_key);
245 talloc_free(tdb_key.dptr);
246 talloc_free(tdb_data.dptr);
252 static int ltdb_add_internal(struct ldb_module *module,
253 const struct ldb_message *msg)
257 ret = ltdb_check_special_dn(module, msg);
258 if (ret != LDB_SUCCESS) {
262 if (ltdb_cache_load(module) != 0) {
263 return LDB_ERR_OPERATIONS_ERROR;
266 ret = ltdb_store(module, msg, TDB_INSERT);
268 if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) {
269 ldb_asprintf_errstring(module->ldb,
270 "Entry %s already exists",
271 ldb_dn_get_linearized(msg->dn));
275 if (ret == LDB_SUCCESS) {
276 ret = ltdb_index_one(module, msg, 1);
277 if (ret != LDB_SUCCESS) {
281 ret = ltdb_modified(module, msg->dn);
282 if (ret != LDB_SUCCESS) {
291 add a record to the database
293 static int ltdb_add(struct ltdb_context *ctx)
295 struct ldb_module *module = ctx->module;
296 struct ldb_request *req = ctx->req;
299 req->handle->state = LDB_ASYNC_PENDING;
301 tret = ltdb_add_internal(module, req->op.add.message);
302 if (tret != LDB_SUCCESS) {
310 delete a record from the database, not updating indexes (used for deleting
313 int ltdb_delete_noindex(struct ldb_module *module, struct ldb_dn *dn)
315 struct ltdb_private *ltdb =
316 talloc_get_type(module->private_data, struct ltdb_private);
320 tdb_key = ltdb_key(module, dn);
322 return LDB_ERR_OTHER;
325 ret = tdb_delete(ltdb->tdb, tdb_key);
326 talloc_free(tdb_key.dptr);
329 ret = ltdb_err_map(tdb_error(ltdb->tdb));
335 static int ltdb_delete_internal(struct ldb_module *module, struct ldb_dn *dn)
337 struct ldb_message *msg;
340 msg = talloc(module, struct ldb_message);
342 return LDB_ERR_OPERATIONS_ERROR;
345 /* in case any attribute of the message was indexed, we need
346 to fetch the old record */
347 ret = ltdb_search_dn1(module, dn, msg);
348 if (ret != LDB_SUCCESS) {
349 /* not finding the old record is an error */
353 ret = ltdb_delete_noindex(module, dn);
354 if (ret != LDB_SUCCESS) {
358 /* remove one level attribute */
359 ret = ltdb_index_one(module, msg, 0);
360 if (ret != LDB_SUCCESS) {
364 /* remove any indexed attributes */
365 ret = ltdb_index_del(module, msg);
366 if (ret != LDB_SUCCESS) {
370 ret = ltdb_modified(module, dn);
371 if (ret != LDB_SUCCESS) {
381 delete a record from the database
383 static int ltdb_delete(struct ltdb_context *ctx)
385 struct ldb_module *module = ctx->module;
386 struct ldb_request *req = ctx->req;
389 req->handle->state = LDB_ASYNC_PENDING;
391 if (ltdb_cache_load(module) != 0) {
392 return LDB_ERR_OPERATIONS_ERROR;
395 tret = ltdb_delete_internal(module, req->op.del.dn);
396 if (tret != LDB_SUCCESS) {
404 find an element by attribute name. At the moment this does a linear search,
405 it should be re-coded to use a binary search once all places that modify
406 records guarantee sorted order
408 return the index of the first matching element if found, otherwise -1
410 static int find_element(const struct ldb_message *msg, const char *name)
413 for (i=0;i<msg->num_elements;i++) {
414 if (ldb_attr_cmp(msg->elements[i].name, name) == 0) {
423 add an element to an existing record. Assumes a elements array that we
424 can call re-alloc on, and assumed that we can re-use the data pointers from
425 the passed in additional values. Use with care!
427 returns 0 on success, -1 on failure (and sets errno)
429 static int msg_add_element(struct ldb_context *ldb,
430 struct ldb_message *msg,
431 struct ldb_message_element *el)
433 struct ldb_message_element *e2;
436 e2 = talloc_realloc(msg, msg->elements, struct ldb_message_element,
437 msg->num_elements+1);
445 e2 = &msg->elements[msg->num_elements];
448 e2->flags = el->flags;
450 if (el->num_values != 0) {
451 e2->values = talloc_array(msg->elements,
452 struct ldb_val, el->num_values);
458 for (i=0;i<el->num_values;i++) {
459 e2->values[i] = el->values[i];
461 e2->num_values = el->num_values;
469 delete all elements having a specified attribute name
471 static int msg_delete_attribute(struct ldb_module *module,
472 struct ldb_context *ldb,
473 struct ldb_message *msg, const char *name)
478 dn = ldb_dn_get_linearized(msg->dn);
483 for (i=0;i<msg->num_elements;i++) {
484 if (ldb_attr_cmp(msg->elements[i].name, name) == 0) {
485 for (j=0;j<msg->elements[i].num_values;j++) {
486 ltdb_index_del_value(module, dn,
487 &msg->elements[i], j);
489 talloc_free(msg->elements[i].values);
490 if (msg->num_elements > (i+1)) {
491 memmove(&msg->elements[i],
493 sizeof(struct ldb_message_element)*
494 (msg->num_elements - (i+1)));
498 msg->elements = talloc_realloc(msg, msg->elements,
499 struct ldb_message_element,
508 delete all elements matching an attribute name/value
510 return 0 on success, -1 on failure
512 static int msg_delete_element(struct ldb_module *module,
513 struct ldb_message *msg,
515 const struct ldb_val *val)
517 struct ldb_context *ldb = module->ldb;
520 struct ldb_message_element *el;
521 const struct ldb_schema_attribute *a;
523 found = find_element(msg, name);
528 el = &msg->elements[found];
530 a = ldb_schema_attribute_by_name(ldb, el->name);
532 for (i=0;i<el->num_values;i++) {
533 if (a->syntax->comparison_fn(ldb, ldb,
534 &el->values[i], val) == 0) {
535 if (i<el->num_values-1) {
536 memmove(&el->values[i], &el->values[i+1],
537 sizeof(el->values[i])*
538 (el->num_values-(i+1)));
541 if (el->num_values == 0) {
542 return msg_delete_attribute(module, ldb,
554 modify a record - internal interface
556 yuck - this is O(n^2). Luckily n is usually small so we probably
557 get away with it, but if we ever have really large attribute lists
558 then we'll need to look at this again
560 int ltdb_modify_internal(struct ldb_module *module,
561 const struct ldb_message *msg)
563 struct ldb_context *ldb = module->ldb;
564 struct ltdb_private *ltdb =
565 talloc_get_type(module->private_data, struct ltdb_private);
566 TDB_DATA tdb_key, tdb_data;
567 struct ldb_message *msg2;
571 tdb_key = ltdb_key(module, msg->dn);
573 return LDB_ERR_OTHER;
576 tdb_data = tdb_fetch(ltdb->tdb, tdb_key);
577 if (!tdb_data.dptr) {
578 talloc_free(tdb_key.dptr);
579 return ltdb_err_map(tdb_error(ltdb->tdb));
582 msg2 = talloc(tdb_key.dptr, struct ldb_message);
584 talloc_free(tdb_key.dptr);
585 return LDB_ERR_OTHER;
588 ret = ltdb_unpack_data(module, &tdb_data, msg2);
598 for (i=0;i<msg->num_elements;i++) {
599 struct ldb_message_element *el = &msg->elements[i];
600 struct ldb_message_element *el2;
601 struct ldb_val *vals;
604 switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) {
606 case LDB_FLAG_MOD_ADD:
607 /* add this element to the message. fail if it
609 idx = find_element(msg2, el->name);
612 if (msg_add_element(ldb, msg2, el) != 0) {
619 el2 = &msg2->elements[idx];
621 /* An attribute with this name already exists,
622 * add all values if they don't already exist
623 * (check both the other elements to be added,
624 * and those already in the db). */
626 for (j=0;j<el->num_values;j++) {
627 if (ldb_msg_find_val(el2, &el->values[j])) {
628 ldb_asprintf_errstring(module->ldb, "%s: value #%d already exists", el->name, j);
629 ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
632 if (ldb_msg_find_val(el, &el->values[j]) != &el->values[j]) {
633 ldb_asprintf_errstring(module->ldb, "%s: value #%d provided more than once", el->name, j);
634 ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
639 vals = talloc_realloc(msg2->elements, el2->values, struct ldb_val,
640 el2->num_values + el->num_values);
647 for (j=0;j<el->num_values;j++) {
648 vals[el2->num_values + j] =
649 ldb_val_dup(vals, &el->values[j]);
653 el2->num_values += el->num_values;
657 case LDB_FLAG_MOD_REPLACE:
658 /* replace all elements of this attribute name with the elements
659 listed. The attribute not existing is not an error */
660 msg_delete_attribute(module, ldb, msg2, el->name);
662 for (j=0;j<el->num_values;j++) {
663 if (ldb_msg_find_val(el, &el->values[j]) != &el->values[j]) {
664 ldb_asprintf_errstring(module->ldb, "%s: value #%d provided more than once", el->name, j);
665 ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
670 /* add the replacement element, if not empty */
671 if (el->num_values != 0 &&
672 msg_add_element(ldb, msg2, el) != 0) {
678 case LDB_FLAG_MOD_DELETE:
680 dn = ldb_dn_get_linearized(msg->dn);
686 /* we could be being asked to delete all
687 values or just some values */
688 if (msg->elements[i].num_values == 0) {
689 if (msg_delete_attribute(module, ldb, msg2,
690 msg->elements[i].name) != 0) {
691 ldb_asprintf_errstring(module->ldb, "No such attribute: %s for delete on %s", msg->elements[i].name, dn);
692 ret = LDB_ERR_NO_SUCH_ATTRIBUTE;
697 for (j=0;j<msg->elements[i].num_values;j++) {
698 if (msg_delete_element(module,
700 msg->elements[i].name,
701 &msg->elements[i].values[j]) != 0) {
702 ldb_asprintf_errstring(module->ldb, "No matching attribute value when deleting attribute: %s on %s", msg->elements[i].name, dn);
703 ret = LDB_ERR_NO_SUCH_ATTRIBUTE;
706 ret = ltdb_index_del_value(module, dn, &msg->elements[i], j);
707 if (ret != LDB_SUCCESS) {
713 ldb_asprintf_errstring(module->ldb,
714 "Invalid ldb_modify flags on %s: 0x%x",
715 msg->elements[i].name,
716 msg->elements[i].flags & LDB_FLAG_MOD_MASK);
717 ret = LDB_ERR_PROTOCOL_ERROR;
722 /* we've made all the mods
723 * save the modified record back into the database */
724 ret = ltdb_store(module, msg2, TDB_MODIFY);
725 if (ret != LDB_SUCCESS) {
729 ret = ltdb_modified(module, msg->dn);
730 if (ret != LDB_SUCCESS) {
734 talloc_free(tdb_key.dptr);
739 talloc_free(tdb_key.dptr);
747 static int ltdb_modify(struct ltdb_context *ctx)
749 struct ldb_module *module = ctx->module;
750 struct ldb_request *req = ctx->req;
753 req->handle->state = LDB_ASYNC_PENDING;
755 tret = ltdb_check_special_dn(module, req->op.mod.message);
756 if (tret != LDB_SUCCESS) {
760 if (ltdb_cache_load(module) != 0) {
761 return LDB_ERR_OPERATIONS_ERROR;
764 tret = ltdb_modify_internal(module, req->op.mod.message);
765 if (tret != LDB_SUCCESS) {
775 static int ltdb_rename(struct ltdb_context *ctx)
777 struct ldb_module *module = ctx->module;
778 struct ldb_request *req = ctx->req;
779 struct ldb_message *msg;
782 req->handle->state = LDB_ASYNC_PENDING;
784 if (ltdb_cache_load(ctx->module) != 0) {
785 return LDB_ERR_OPERATIONS_ERROR;
788 msg = talloc(ctx, struct ldb_message);
790 return LDB_ERR_OPERATIONS_ERROR;
793 /* in case any attribute of the message was indexed, we need
794 to fetch the old record */
795 tret = ltdb_search_dn1(module, req->op.rename.olddn, msg);
796 if (tret != LDB_SUCCESS) {
797 /* not finding the old record is an error */
801 msg->dn = ldb_dn_copy(msg, req->op.rename.newdn);
803 return LDB_ERR_OPERATIONS_ERROR;
806 if (ldb_dn_compare(req->op.rename.olddn, req->op.rename.newdn) == 0) {
807 /* The rename operation is apparently only changing case -
808 the DNs are the same. Delete the old DN before adding
809 the new one to avoid a TDB_ERR_EXISTS error.
811 The only drawback to this is that if the delete
812 succeeds but the add fails, we rely on the
813 transaction to roll this all back. */
814 tret = ltdb_delete_internal(module, req->op.rename.olddn);
815 if (tret != LDB_SUCCESS) {
819 tret = ltdb_add_internal(module, msg);
820 if (tret != LDB_SUCCESS) {
824 /* The rename operation is changing DNs. Try to add the new
825 DN first to avoid clobbering another DN not related to
826 this rename operation. */
827 tret = ltdb_add_internal(module, msg);
828 if (tret != LDB_SUCCESS) {
832 tret = ltdb_delete_internal(module, req->op.rename.olddn);
833 if (tret != LDB_SUCCESS) {
834 ltdb_delete_internal(module, req->op.rename.newdn);
835 return LDB_ERR_OPERATIONS_ERROR;
842 static int ltdb_start_trans(struct ldb_module *module)
844 struct ltdb_private *ltdb =
845 talloc_get_type(module->private_data, struct ltdb_private);
847 if (tdb_transaction_start(ltdb->tdb) != 0) {
848 return ltdb_err_map(tdb_error(ltdb->tdb));
851 ltdb->in_transaction++;
856 static int ltdb_end_trans(struct ldb_module *module)
858 struct ltdb_private *ltdb =
859 talloc_get_type(module->private_data, struct ltdb_private);
861 ltdb->in_transaction--;
863 if (tdb_transaction_commit(ltdb->tdb) != 0) {
864 return ltdb_err_map(tdb_error(ltdb->tdb));
870 static int ltdb_del_trans(struct ldb_module *module)
872 struct ltdb_private *ltdb =
873 talloc_get_type(module->private_data, struct ltdb_private);
875 ltdb->in_transaction--;
877 if (tdb_transaction_cancel(ltdb->tdb) != 0) {
878 return ltdb_err_map(tdb_error(ltdb->tdb));
885 return sequenceNumber from @BASEINFO
887 static int ltdb_sequence_number(struct ltdb_context *ctx,
888 struct ldb_extended **ext)
890 struct ldb_module *module = ctx->module;
891 struct ldb_request *req = ctx->req;
893 struct ldb_seqnum_request *seq;
894 struct ldb_seqnum_result *res;
895 struct ldb_message *msg = NULL;
900 seq = talloc_get_type(req->op.extended.data,
901 struct ldb_seqnum_request);
903 return LDB_ERR_OPERATIONS_ERROR;
906 req->handle->state = LDB_ASYNC_PENDING;
908 if (ltdb_lock_read(module) != 0) {
909 return LDB_ERR_OPERATIONS_ERROR;
912 res = talloc_zero(req, struct ldb_seqnum_result);
914 ret = LDB_ERR_OPERATIONS_ERROR;
917 tmp_ctx = talloc_new(req);
918 if (tmp_ctx == NULL) {
919 ret = LDB_ERR_OPERATIONS_ERROR;
923 dn = ldb_dn_new(tmp_ctx, module->ldb, LTDB_BASEINFO);
925 msg = talloc(tmp_ctx, struct ldb_message);
927 ret = LDB_ERR_OPERATIONS_ERROR;
931 ret = ltdb_search_dn1(module, dn, msg);
932 if (ret != LDB_SUCCESS) {
937 case LDB_SEQ_HIGHEST_SEQ:
938 res->seq_num = ldb_msg_find_attr_as_uint64(msg, LTDB_SEQUENCE_NUMBER, 0);
941 res->seq_num = ldb_msg_find_attr_as_uint64(msg, LTDB_SEQUENCE_NUMBER, 0);
944 case LDB_SEQ_HIGHEST_TIMESTAMP:
945 date = ldb_msg_find_attr_as_string(msg, LTDB_MOD_TIMESTAMP, NULL);
947 res->seq_num = ldb_string_to_time(date);
950 /* zero is as good as anything when we don't know */
955 *ext = talloc_zero(req, struct ldb_extended);
957 ret = LDB_ERR_OPERATIONS_ERROR;
960 (*ext)->oid = LDB_EXTENDED_SEQUENCE_NUMBER;
961 (*ext)->data = talloc_steal(*ext, res);
966 talloc_free(tmp_ctx);
967 ltdb_unlock_read(module);
971 void ltdb_request_done(struct ldb_request *req, int error)
973 struct ldb_reply *ares;
975 /* if we already returned an error just return */
976 if (req->handle->status != LDB_SUCCESS) {
980 ares = talloc_zero(req, struct ldb_reply);
982 ldb_oom(req->handle->ldb);
983 req->callback(req, NULL);
986 ares->type = LDB_REPLY_DONE;
989 req->callback(req, ares);
992 static void ltdb_timeout(struct event_context *ev,
993 struct timed_event *te,
997 struct ltdb_context *ctx;
998 ctx = talloc_get_type(private_data, struct ltdb_context);
1000 ltdb_request_done(ctx->req, LDB_ERR_TIME_LIMIT_EXCEEDED);
1003 static void ltdb_request_extended_done(struct ldb_request *req,
1004 struct ldb_extended *ext,
1007 struct ldb_reply *ares;
1009 /* if we already returned an error just return */
1010 if (req->handle->status != LDB_SUCCESS) {
1014 ares = talloc_zero(req, struct ldb_reply);
1016 ldb_oom(req->handle->ldb);
1017 req->callback(req, NULL);
1020 ares->type = LDB_REPLY_DONE;
1021 ares->response = ext;
1022 ares->error = error;
1024 req->callback(req, ares);
1027 static void ltdb_handle_extended(struct ltdb_context *ctx)
1029 struct ldb_extended *ext = NULL;
1032 if (strcmp(ctx->req->op.extended.oid,
1033 LDB_EXTENDED_SEQUENCE_NUMBER) == 0) {
1034 /* get sequence number */
1035 ret = ltdb_sequence_number(ctx, &ext);
1037 /* not recognized */
1038 ret = LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
1041 ltdb_request_extended_done(ctx->req, ext, ret);
1044 static void ltdb_callback(struct event_context *ev,
1045 struct timed_event *te,
1049 struct ltdb_context *ctx;
1052 ctx = talloc_get_type(private_data, struct ltdb_context);
1054 switch (ctx->req->operation) {
1056 ret = ltdb_search(ctx);
1059 ret = ltdb_add(ctx);
1062 ret = ltdb_modify(ctx);
1065 ret = ltdb_delete(ctx);
1068 ret = ltdb_rename(ctx);
1071 ltdb_handle_extended(ctx);
1074 /* no other op supported */
1075 ret = LDB_ERR_UNWILLING_TO_PERFORM;
1078 if (!ctx->callback_failed) {
1079 ltdb_request_done(ctx->req, ret);
1083 static int ltdb_handle_request(struct ldb_module *module,
1084 struct ldb_request *req)
1086 struct event_context *ev;
1087 struct ltdb_context *ac;
1088 struct timed_event *te;
1091 if (check_critical_controls(req->controls)) {
1092 return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
1095 if (req->starttime == 0 || req->timeout == 0) {
1096 ldb_set_errstring(module->ldb, "Invalid timeout settings");
1097 return LDB_ERR_TIME_LIMIT_EXCEEDED;
1100 ev = ldb_get_event_context(module->ldb);
1102 ac = talloc_zero(req, struct ltdb_context);
1104 ldb_set_errstring(module->ldb, "Out of Memory");
1105 return LDB_ERR_OPERATIONS_ERROR;
1108 ac->module = module;
1113 te = event_add_timed(ev, ac, tv, ltdb_callback, ac);
1115 return LDB_ERR_OPERATIONS_ERROR;
1119 tv.tv_sec = req->starttime + req->timeout;
1120 te = event_add_timed(ev, ac, tv, ltdb_timeout, ac);
1122 return LDB_ERR_OPERATIONS_ERROR;
1128 static const struct ldb_module_ops ltdb_ops = {
1130 .search = ltdb_handle_request,
1131 .add = ltdb_handle_request,
1132 .modify = ltdb_handle_request,
1133 .del = ltdb_handle_request,
1134 .rename = ltdb_handle_request,
1135 .extended = ltdb_handle_request,
1136 .start_transaction = ltdb_start_trans,
1137 .end_transaction = ltdb_end_trans,
1138 .del_transaction = ltdb_del_trans,
1142 connect to the database
1144 static int ltdb_connect(struct ldb_context *ldb, const char *url,
1145 unsigned int flags, const char *options[],
1146 struct ldb_module **module)
1149 int tdb_flags, open_flags;
1150 struct ltdb_private *ltdb;
1153 if (strchr(url, ':')) {
1154 if (strncmp(url, "tdb://", 6) != 0) {
1155 ldb_debug(ldb, LDB_DEBUG_ERROR,
1156 "Invalid tdb URL '%s'", url);
1164 tdb_flags = TDB_DEFAULT | TDB_SEQNUM;
1166 /* check for the 'nosync' option */
1167 if (flags & LDB_FLG_NOSYNC) {
1168 tdb_flags |= TDB_NOSYNC;
1171 /* and nommap option */
1172 if (flags & LDB_FLG_NOMMAP) {
1173 tdb_flags |= TDB_NOMMAP;
1176 if (flags & LDB_FLG_RDONLY) {
1177 open_flags = O_RDONLY;
1179 open_flags = O_CREAT | O_RDWR;
1182 ltdb = talloc_zero(ldb, struct ltdb_private);
1188 /* note that we use quite a large default hash size */
1189 ltdb->tdb = ltdb_wrap_open(ltdb, path, 10000,
1190 tdb_flags, open_flags,
1191 ldb->create_perms, ldb);
1193 ldb_debug(ldb, LDB_DEBUG_ERROR,
1194 "Unable to open tdb '%s'\n", path);
1199 ltdb->sequence_number = 0;
1201 *module = talloc(ldb, struct ldb_module);
1202 if ((*module) == NULL) {
1207 talloc_set_name_const(*module, "ldb_tdb backend");
1208 (*module)->ldb = ldb;
1209 (*module)->prev = (*module)->next = NULL;
1210 (*module)->private_data = ltdb;
1211 (*module)->ops = <db_ops;
1213 if (ltdb_cache_load(*module) != 0) {
1214 talloc_free(*module);
1222 const struct ldb_backend_ops ldb_tdb_backend_ops = {
1224 .connect_fn = ltdb_connect