4 Copyright (C) Andrew Tridgell 2004-2009
6 ** NOTE! The following LGPL license applies to the ldb
7 ** library. This does NOT imply that all of Samba is released
10 This library is free software; you can redistribute it and/or
11 modify it under the terms of the GNU Lesser General Public
12 License as published by the Free Software Foundation; either
13 version 3 of the License, or (at your option) any later version.
15 This library is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 Lesser General Public License for more details.
20 You should have received a copy of the GNU Lesser General Public
21 License along with this library; if not, see <http://www.gnu.org/licenses/>.
27 * Component: ldb tdb backend - indexing
29 * Description: indexing routines for ldb tdb backend
31 * Author: Andrew Tridgell
35 #include "ldb_private.h"
43 struct tdb_context *itdb;
47 static int ltdb_write_index_dn_guid(struct ldb_module *module,
48 const struct ldb_message *msg,
50 static int ltdb_index_dn_base_dn(struct ldb_module *module,
51 struct ltdb_private *ltdb,
52 struct ldb_dn *base_dn,
53 struct dn_list *dn_list);
55 /* we put a @IDXVERSION attribute on index entries. This
56 allows us to tell if it was written by an older version
58 #define LTDB_INDEXING_VERSION 2
60 #define LTDB_GUID_INDEXING_VERSION 3
62 /* enable the idxptr mode when transactions start */
63 int ltdb_index_transaction_start(struct ldb_module *module)
65 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
66 ltdb->idxptr = talloc_zero(ltdb, struct ltdb_idxptr);
67 if (ltdb->idxptr == NULL) {
68 return ldb_oom(ldb_module_get_ctx(module));
75 see if two ldb_val structures contain exactly the same data
76 return -1 or 1 for a mismatch, 0 for match
78 static int ldb_val_equal_exact_for_qsort(const struct ldb_val *v1,
79 const struct ldb_val *v2)
81 if (v1->length > v2->length) {
84 if (v1->length < v2->length) {
87 return memcmp(v1->data, v2->data, v1->length);
92 find a entry in a dn_list, using a ldb_val. Uses a case sensitive
93 binary-safe comparison for the 'dn' returns -1 if not found
95 This is therefore safe when the value is a GUID in the future
97 static int ltdb_dn_list_find_val(struct ltdb_private *ltdb,
98 const struct dn_list *list,
99 const struct ldb_val *v)
102 for (i=0; i<list->count; i++) {
103 if (ldb_val_equal_exact(&list->dn[i], v) == 1) {
111 find a entry in a dn_list. Uses a case sensitive comparison with the dn
112 returns -1 if not found
114 static int ltdb_dn_list_find_msg(struct ltdb_private *ltdb,
115 struct dn_list *list,
116 const struct ldb_message *msg)
119 const struct ldb_val *key_val;
120 if (ltdb->cache->GUID_index_attribute == NULL) {
121 const char *dn_str = ldb_dn_get_linearized(msg->dn);
122 v.data = discard_const_p(unsigned char, dn_str);
123 v.length = strlen(dn_str);
125 key_val = ldb_msg_find_ldb_val(msg,
126 ltdb->cache->GUID_index_attribute);
127 if (key_val == NULL) {
132 return ltdb_dn_list_find_val(ltdb, list, &v);
136 this is effectively a cast function, but with lots of paranoia
137 checks and also copes with CPUs that are fussy about pointer
140 static struct dn_list *ltdb_index_idxptr(struct ldb_module *module, TDB_DATA rec, bool check_parent)
142 struct dn_list *list;
143 if (rec.dsize != sizeof(void *)) {
144 ldb_asprintf_errstring(ldb_module_get_ctx(module),
145 "Bad data size for idxptr %u", (unsigned)rec.dsize);
148 /* note that we can't just use a cast here, as rec.dptr may
149 not be aligned sufficiently for a pointer. A cast would cause
150 platforms like some ARM CPUs to crash */
151 memcpy(&list, rec.dptr, sizeof(void *));
152 list = talloc_get_type(list, struct dn_list);
154 ldb_asprintf_errstring(ldb_module_get_ctx(module),
155 "Bad type '%s' for idxptr",
156 talloc_get_name(list));
159 if (check_parent && list->dn && talloc_parent(list->dn) != list) {
160 ldb_asprintf_errstring(ldb_module_get_ctx(module),
161 "Bad parent '%s' for idxptr",
162 talloc_get_name(talloc_parent(list->dn)));
169 return the @IDX list in an index entry for a dn as a
172 static int ltdb_dn_list_load(struct ldb_module *module,
173 struct ltdb_private *ltdb,
174 struct ldb_dn *dn, struct dn_list *list)
176 struct ldb_message *msg;
178 struct ldb_message_element *el;
180 struct dn_list *list2;
186 /* see if we have any in-memory index entries */
187 if (ltdb->idxptr == NULL ||
188 ltdb->idxptr->itdb == NULL) {
192 key.dptr = discard_const_p(unsigned char, ldb_dn_get_linearized(dn));
193 key.dsize = strlen((char *)key.dptr);
195 rec = tdb_fetch(ltdb->idxptr->itdb, key);
196 if (rec.dptr == NULL) {
200 /* we've found an in-memory index entry */
201 list2 = ltdb_index_idxptr(module, rec, true);
204 return LDB_ERR_OPERATIONS_ERROR;
212 msg = ldb_msg_new(list);
214 return LDB_ERR_OPERATIONS_ERROR;
217 ret = ltdb_search_dn1(module, dn, msg,
218 LDB_UNPACK_DATA_FLAG_NO_DATA_ALLOC
219 |LDB_UNPACK_DATA_FLAG_NO_DN);
220 if (ret != LDB_SUCCESS) {
225 /* TODO: check indexing version number */
227 el = ldb_msg_find_element(msg, LTDB_IDX);
234 * we avoid copying the strings by stealing the list. We have
235 * to steal msg onto el->values (which looks odd) because we
236 * asked for the memory to be allocated on msg, not on each
237 * value with LDB_UNPACK_DATA_FLAG_NO_DATA_ALLOC above
239 if (ltdb->cache->GUID_index_attribute == NULL) {
240 talloc_steal(el->values, msg);
241 list->dn = talloc_steal(list, el->values);
242 list->count = el->num_values;
245 static const size_t GUID_val_size = 16;
246 if (el->num_values != 1) {
247 return LDB_ERR_OPERATIONS_ERROR;
250 if ((el->values[0].length % GUID_val_size) != 0) {
251 return LDB_ERR_OPERATIONS_ERROR;
254 list->count = el->values[0].length / GUID_val_size;
255 list->dn = talloc_array(list, struct ldb_val, list->count);
258 * The actual data is on msg, due to
259 * LDB_UNPACK_DATA_FLAG_NO_DATA_ALLOC
261 talloc_steal(list->dn, msg);
262 for (i = 0; i < list->count; i++) {
263 list->dn[i].data = &el->values[0].data[i * GUID_val_size];
264 list->dn[i].length = GUID_val_size;
268 /* We don't need msg->elements any more */
269 talloc_free(msg->elements);
273 int ltdb_key_dn_from_idx(struct ldb_module *module,
274 struct ltdb_private *ltdb,
279 struct ldb_context *ldb = ldb_module_get_ctx(module);
281 struct dn_list *list = talloc(mem_ctx, struct dn_list);
284 return LDB_ERR_OPERATIONS_ERROR;
287 ret = ltdb_index_dn_base_dn(module, ltdb, dn, list);
288 if (ret != LDB_SUCCESS) {
292 if (list->count == 0) {
293 return LDB_ERR_NO_SUCH_OBJECT;
295 if (list->count > 1) {
296 return LDB_ERR_CONSTRAINT_VIOLATION;
299 *tdb_key = ltdb_guid_to_key(module, ltdb,
300 mem_ctx, &list->dn[0]);
301 if (tdb_key->dptr == NULL) {
302 return LDB_ERR_OPERATIONS_ERROR;
311 save a dn_list into a full @IDX style record
313 static int ltdb_dn_list_store_full(struct ldb_module *module,
314 struct ltdb_private *ltdb,
316 struct dn_list *list)
318 struct ldb_message *msg;
321 msg = ldb_msg_new(module);
323 return ldb_module_oom(module);
328 if (list->count == 0) {
329 ret = ltdb_delete_noindex(module, msg);
330 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
337 if (ltdb->cache->GUID_index_attribute == NULL) {
338 ret = ldb_msg_add_fmt(msg, LTDB_IDXVERSION, "%u",
339 LTDB_INDEXING_VERSION);
340 if (ret != LDB_SUCCESS) {
342 return ldb_module_oom(module);
345 ret = ldb_msg_add_fmt(msg, LTDB_IDXVERSION, "%u",
346 LTDB_GUID_INDEXING_VERSION);
347 if (ret != LDB_SUCCESS) {
349 return ldb_module_oom(module);
353 if (list->count > 0) {
354 struct ldb_message_element *el;
356 ret = ldb_msg_add_empty(msg, LTDB_IDX, LDB_FLAG_MOD_ADD, &el);
357 if (ret != LDB_SUCCESS) {
359 return ldb_module_oom(module);
362 if (ltdb->cache->GUID_index_attribute == NULL) {
363 el->values = list->dn;
364 el->num_values = list->count;
368 el->values = talloc_array(msg,
370 if (el->values == NULL) {
372 return ldb_module_oom(module);
375 v.data = talloc_array_size(el->values,
378 if (v.data == NULL) {
380 return ldb_module_oom(module);
383 v.length = talloc_get_size(v.data);
385 for (i = 0; i < list->count; i++) {
386 if (list->dn[i].length !=
389 return ldb_module_operr(module);
391 memcpy(&v.data[LTDB_GUID_SIZE*i],
400 ret = ltdb_store(module, msg, TDB_REPLACE);
406 save a dn_list into the database, in either @IDX or internal format
408 static int ltdb_dn_list_store(struct ldb_module *module, struct ldb_dn *dn,
409 struct dn_list *list)
411 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
414 struct dn_list *list2;
416 if (ltdb->idxptr == NULL) {
417 return ltdb_dn_list_store_full(module, ltdb,
421 if (ltdb->idxptr->itdb == NULL) {
422 ltdb->idxptr->itdb = tdb_open(NULL, 1000, TDB_INTERNAL, O_RDWR, 0);
423 if (ltdb->idxptr->itdb == NULL) {
424 return LDB_ERR_OPERATIONS_ERROR;
428 key.dptr = discard_const_p(unsigned char, ldb_dn_get_linearized(dn));
429 key.dsize = strlen((char *)key.dptr);
431 rec = tdb_fetch(ltdb->idxptr->itdb, key);
432 if (rec.dptr != NULL) {
433 list2 = ltdb_index_idxptr(module, rec, false);
436 return LDB_ERR_OPERATIONS_ERROR;
439 list2->dn = talloc_steal(list2, list->dn);
440 list2->count = list->count;
444 list2 = talloc(ltdb->idxptr, struct dn_list);
446 return LDB_ERR_OPERATIONS_ERROR;
448 list2->dn = talloc_steal(list2, list->dn);
449 list2->count = list->count;
451 rec.dptr = (uint8_t *)&list2;
452 rec.dsize = sizeof(void *);
456 * This is not a store into the main DB, but into an in-memory
457 * TDB, so we don't need a guard on ltdb->read_only
459 ret = tdb_store(ltdb->idxptr->itdb, key, rec, TDB_INSERT);
461 return ltdb_err_map(tdb_error(ltdb->idxptr->itdb));
467 traverse function for storing the in-memory index entries on disk
469 static int ltdb_index_traverse_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state)
471 struct ldb_module *module = state;
472 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
474 struct ldb_context *ldb = ldb_module_get_ctx(module);
476 struct dn_list *list;
478 list = ltdb_index_idxptr(module, data, true);
480 ltdb->idxptr->error = LDB_ERR_OPERATIONS_ERROR;
485 v.length = strnlen((char *)key.dptr, key.dsize);
487 dn = ldb_dn_from_ldb_val(module, ldb, &v);
489 ldb_asprintf_errstring(ldb, "Failed to parse index key %*.*s as an LDB DN", (int)v.length, (int)v.length, (const char *)v.data);
490 ltdb->idxptr->error = LDB_ERR_OPERATIONS_ERROR;
494 ltdb->idxptr->error = ltdb_dn_list_store_full(module, ltdb,
497 if (ltdb->idxptr->error != 0) {
503 /* cleanup the idxptr mode when transaction commits */
504 int ltdb_index_transaction_commit(struct ldb_module *module)
506 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
509 struct ldb_context *ldb = ldb_module_get_ctx(module);
511 ldb_reset_err_string(ldb);
513 if (ltdb->idxptr->itdb) {
514 tdb_traverse(ltdb->idxptr->itdb, ltdb_index_traverse_store, module);
515 tdb_close(ltdb->idxptr->itdb);
518 ret = ltdb->idxptr->error;
519 if (ret != LDB_SUCCESS) {
520 if (!ldb_errstring(ldb)) {
521 ldb_set_errstring(ldb, ldb_strerror(ret));
523 ldb_asprintf_errstring(ldb, "Failed to store index records in transaction commit: %s", ldb_errstring(ldb));
526 talloc_free(ltdb->idxptr);
531 /* cleanup the idxptr mode when transaction cancels */
532 int ltdb_index_transaction_cancel(struct ldb_module *module)
534 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
535 if (ltdb->idxptr && ltdb->idxptr->itdb) {
536 tdb_close(ltdb->idxptr->itdb);
538 talloc_free(ltdb->idxptr);
545 return the dn key to be used for an index
546 the caller is responsible for freeing
548 static struct ldb_dn *ltdb_index_key(struct ldb_context *ldb,
549 const char *attr, const struct ldb_val *value,
550 const struct ldb_schema_attribute **ap)
554 const struct ldb_schema_attribute *a;
558 attr_folded = ldb_attr_casefold(ldb, attr);
563 a = ldb_schema_attribute_by_name(ldb, attr);
567 r = a->syntax->canonicalise_fn(ldb, ldb, value, &v);
568 if (r != LDB_SUCCESS) {
569 const char *errstr = ldb_errstring(ldb);
570 /* canonicalisation can be refused. For example,
571 a attribute that takes wildcards will refuse to canonicalise
572 if the value contains a wildcard */
573 ldb_asprintf_errstring(ldb, "Failed to create index key for attribute '%s':%s%s%s",
574 attr, ldb_strerror(r), (errstr?":":""), (errstr?errstr:""));
575 talloc_free(attr_folded);
578 if (ldb_should_b64_encode(ldb, &v)) {
579 char *vstr = ldb_base64_encode(ldb, (char *)v.data, v.length);
581 talloc_free(attr_folded);
584 ret = ldb_dn_new_fmt(ldb, ldb, "%s:%s::%s", LTDB_INDEX, attr_folded, vstr);
587 ret = ldb_dn_new_fmt(ldb, ldb, "%s:%s:%.*s", LTDB_INDEX, attr_folded, (int)v.length, (char *)v.data);
590 if (v.data != value->data) {
593 talloc_free(attr_folded);
599 see if a attribute value is in the list of indexed attributes
601 static bool ltdb_is_indexed(struct ldb_module *module,
602 struct ltdb_private *ltdb,
605 struct ldb_context *ldb = ldb_module_get_ctx(module);
607 struct ldb_message_element *el;
609 if (ldb->schema.index_handler_override) {
610 const struct ldb_schema_attribute *a
611 = ldb_schema_attribute_by_name(ldb, attr);
617 if (a->flags & LDB_ATTR_FLAG_INDEXED) {
624 if (!ltdb->cache->attribute_indexes) {
628 el = ldb_msg_find_element(ltdb->cache->indexlist, LTDB_IDXATTR);
633 /* TODO: this is too expensive! At least use a binary search */
634 for (i=0; i<el->num_values; i++) {
635 if (ldb_attr_cmp((char *)el->values[i].data, attr) == 0) {
643 in the following logic functions, the return value is treated as
646 LDB_SUCCESS: we found some matching index values
648 LDB_ERR_NO_SUCH_OBJECT: we know for sure that no object matches
650 LDB_ERR_OPERATIONS_ERROR: indexing could not answer the call,
651 we'll need a full search
655 return a list of dn's that might match a simple indexed search (an
656 equality search only)
658 static int ltdb_index_dn_simple(struct ldb_module *module,
659 struct ltdb_private *ltdb,
660 const struct ldb_parse_tree *tree,
661 struct dn_list *list)
663 struct ldb_context *ldb;
667 ldb = ldb_module_get_ctx(module);
672 /* if the attribute isn't in the list of indexed attributes then
673 this node needs a full search */
674 if (!ltdb_is_indexed(module, ltdb, tree->u.equality.attr)) {
675 return LDB_ERR_OPERATIONS_ERROR;
678 /* the attribute is indexed. Pull the list of DNs that match the
680 dn = ltdb_index_key(ldb, tree->u.equality.attr, &tree->u.equality.value, NULL);
681 if (!dn) return LDB_ERR_OPERATIONS_ERROR;
683 ret = ltdb_dn_list_load(module, ltdb, dn, list);
689 static bool list_union(struct ldb_context *, struct dn_list *, const struct dn_list *);
692 return a list of dn's that might match a leaf indexed search
694 static int ltdb_index_dn_leaf(struct ldb_module *module,
695 struct ltdb_private *ltdb,
696 const struct ldb_parse_tree *tree,
697 struct dn_list *list)
699 if (ltdb->disallow_dn_filter &&
700 (ldb_attr_cmp(tree->u.equality.attr, "dn") == 0)) {
701 /* in AD mode we do not support "(dn=...)" search filters */
706 if (ldb_attr_dn(tree->u.equality.attr) == 0) {
708 = ldb_dn_from_ldb_val(list,
709 ldb_module_get_ctx(module),
710 &tree->u.equality.value);
712 /* If we can't parse it, no match */
719 * Re-use the same code we use for a SCOPE_BASE
722 * We can't call TALLOC_FREE(dn) as this must belong
723 * to list for the memory to remain valid.
725 return ltdb_index_dn_base_dn(module, ltdb, dn, list);
727 return ltdb_index_dn_simple(module, ltdb, tree, list);
735 static bool list_intersect(struct ldb_context *ldb,
736 struct ltdb_private *ltdb,
737 struct dn_list *list, const struct dn_list *list2)
739 struct dn_list *list3;
742 if (list->count == 0) {
746 if (list2->count == 0) {
753 /* the indexing code is allowed to return a longer list than
754 what really matches, as all results are filtered by the
755 full expression at the end - this shortcut avoids a lot of
756 work in some cases */
757 if (list->count < 2 && list2->count > 10) {
760 if (list2->count < 2 && list->count > 10) {
761 list->count = list2->count;
762 list->dn = list2->dn;
763 /* note that list2 may not be the parent of list2->dn,
764 as list2->dn may be owned by ltdb->idxptr. In that
765 case we expect this reparent call to fail, which is
767 talloc_reparent(list2, list, list2->dn);
771 list3 = talloc_zero(list, struct dn_list);
776 list3->dn = talloc_array(list3, struct ldb_val, list->count);
783 for (i=0;i<list->count;i++) {
784 if (ltdb_dn_list_find_val(ltdb, list2,
785 &list->dn[i]) != -1) {
786 list3->dn[list3->count] = list->dn[i];
791 list->dn = talloc_steal(list, list3->dn);
792 list->count = list3->count;
803 static bool list_union(struct ldb_context *ldb,
804 struct dn_list *list, const struct dn_list *list2)
808 if (list2->count == 0) {
813 if (list->count == 0) {
815 list->count = list2->count;
816 list->dn = list2->dn;
817 /* note that list2 may not be the parent of list2->dn,
818 as list2->dn may be owned by ltdb->idxptr. In that
819 case we expect this reparent call to fail, which is
821 talloc_reparent(list2, list, list2->dn);
825 dn3 = talloc_array(list, struct ldb_val, list->count + list2->count);
831 /* we allow for duplicates here, and get rid of them later */
832 memcpy(dn3, list->dn, sizeof(list->dn[0])*list->count);
833 memcpy(dn3+list->count, list2->dn, sizeof(list2->dn[0])*list2->count);
836 list->count += list2->count;
841 static int ltdb_index_dn(struct ldb_module *module,
842 struct ltdb_private *ltdb,
843 const struct ldb_parse_tree *tree,
844 struct dn_list *list);
848 process an OR list (a union)
850 static int ltdb_index_dn_or(struct ldb_module *module,
851 struct ltdb_private *ltdb,
852 const struct ldb_parse_tree *tree,
853 struct dn_list *list)
855 struct ldb_context *ldb;
858 ldb = ldb_module_get_ctx(module);
863 for (i=0; i<tree->u.list.num_elements; i++) {
864 struct dn_list *list2;
867 list2 = talloc_zero(list, struct dn_list);
869 return LDB_ERR_OPERATIONS_ERROR;
872 ret = ltdb_index_dn(module, ltdb,
873 tree->u.list.elements[i], list2);
875 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
881 if (ret != LDB_SUCCESS) {
887 if (!list_union(ldb, list, list2)) {
889 return LDB_ERR_OPERATIONS_ERROR;
893 if (list->count == 0) {
894 return LDB_ERR_NO_SUCH_OBJECT;
904 static int ltdb_index_dn_not(struct ldb_module *module,
905 struct ltdb_private *ltdb,
906 const struct ldb_parse_tree *tree,
907 struct dn_list *list)
909 /* the only way to do an indexed not would be if we could
910 negate the not via another not or if we knew the total
911 number of database elements so we could know that the
912 existing expression covered the whole database.
914 instead, we just give up, and rely on a full index scan
915 (unless an outer & manages to reduce the list)
917 return LDB_ERR_OPERATIONS_ERROR;
921 static bool ltdb_index_unique(struct ldb_context *ldb,
924 const struct ldb_schema_attribute *a;
925 a = ldb_schema_attribute_by_name(ldb, attr);
926 if (a->flags & LDB_ATTR_FLAG_UNIQUE_INDEX) {
933 process an AND expression (intersection)
935 static int ltdb_index_dn_and(struct ldb_module *module,
936 struct ltdb_private *ltdb,
937 const struct ldb_parse_tree *tree,
938 struct dn_list *list)
940 struct ldb_context *ldb;
944 ldb = ldb_module_get_ctx(module);
949 /* in the first pass we only look for unique simple
950 equality tests, in the hope of avoiding having to look
952 for (i=0; i<tree->u.list.num_elements; i++) {
953 const struct ldb_parse_tree *subtree = tree->u.list.elements[i];
956 if (subtree->operation != LDB_OP_EQUALITY ||
957 !ltdb_index_unique(ldb, subtree->u.equality.attr)) {
961 ret = ltdb_index_dn(module, ltdb, subtree, list);
962 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
964 return LDB_ERR_NO_SUCH_OBJECT;
966 if (ret == LDB_SUCCESS) {
967 /* a unique index match means we can
968 * stop. Note that we don't care if we return
969 * a few too many objects, due to later
975 /* now do a full intersection */
978 for (i=0; i<tree->u.list.num_elements; i++) {
979 const struct ldb_parse_tree *subtree = tree->u.list.elements[i];
980 struct dn_list *list2;
983 list2 = talloc_zero(list, struct dn_list);
985 return ldb_module_oom(module);
988 ret = ltdb_index_dn(module, ltdb, subtree, list2);
990 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
995 return LDB_ERR_NO_SUCH_OBJECT;
998 if (ret != LDB_SUCCESS) {
999 /* this didn't adding anything */
1005 talloc_reparent(list2, list, list->dn);
1006 list->dn = list2->dn;
1007 list->count = list2->count;
1009 } else if (!list_intersect(ldb, ltdb,
1012 return LDB_ERR_OPERATIONS_ERROR;
1015 if (list->count == 0) {
1017 return LDB_ERR_NO_SUCH_OBJECT;
1020 if (list->count < 2) {
1021 /* it isn't worth loading the next part of the tree */
1027 /* none of the attributes were indexed */
1028 return LDB_ERR_OPERATIONS_ERROR;
1035 return a list of matching objects using a one-level index
1037 static int ltdb_index_dn_attr(struct ldb_module *module,
1038 struct ltdb_private *ltdb,
1041 struct dn_list *list)
1043 struct ldb_context *ldb;
1048 ldb = ldb_module_get_ctx(module);
1050 /* work out the index key from the parent DN */
1051 val.data = (uint8_t *)((uintptr_t)ldb_dn_get_casefold(dn));
1052 val.length = strlen((char *)val.data);
1053 key = ltdb_index_key(ldb, attr, &val, NULL);
1056 return LDB_ERR_OPERATIONS_ERROR;
1059 ret = ltdb_dn_list_load(module, ltdb, key, list);
1061 if (ret != LDB_SUCCESS) {
1065 if (list->count == 0) {
1066 return LDB_ERR_NO_SUCH_OBJECT;
1073 return a list of matching objects using a one-level index
1075 static int ltdb_index_dn_one(struct ldb_module *module,
1076 struct ltdb_private *ltdb,
1077 struct ldb_dn *parent_dn,
1078 struct dn_list *list)
1080 return ltdb_index_dn_attr(module, ltdb,
1081 LTDB_IDXONE, parent_dn, list);
1085 return a list of matching objects using the DN index
1087 static int ltdb_index_dn_base_dn(struct ldb_module *module,
1088 struct ltdb_private *ltdb,
1089 struct ldb_dn *base_dn,
1090 struct dn_list *dn_list)
1092 const struct ldb_val *guid_val = NULL;
1093 if (ltdb->cache->GUID_index_attribute == NULL) {
1094 dn_list->dn = talloc_array(dn_list, struct ldb_val, 1);
1095 if (dn_list->dn == NULL) {
1096 return ldb_module_oom(module);
1098 dn_list->dn[0].data = discard_const_p(unsigned char,
1099 ldb_dn_get_linearized(base_dn));
1100 if (dn_list->dn[0].data == NULL) {
1101 return ldb_module_oom(module);
1103 dn_list->dn[0].length = strlen((char *)dn_list->dn[0].data);
1109 if (ltdb->cache->GUID_index_dn_component != NULL) {
1110 guid_val = ldb_dn_get_extended_component(base_dn,
1111 ltdb->cache->GUID_index_dn_component);
1114 if (guid_val != NULL) {
1115 dn_list->dn = talloc_array(dn_list, struct ldb_val, 1);
1116 if (dn_list->dn == NULL) {
1117 return ldb_module_oom(module);
1119 dn_list->dn[0].data = guid_val->data;
1120 dn_list->dn[0].length = guid_val->length;
1126 return ltdb_index_dn_attr(module, ltdb,
1127 LTDB_IDXDN, base_dn, dn_list);
1131 return a list of dn's that might match a indexed search or
1132 an error. return LDB_ERR_NO_SUCH_OBJECT for no matches, or LDB_SUCCESS for matches
1134 static int ltdb_index_dn(struct ldb_module *module,
1135 struct ltdb_private *ltdb,
1136 const struct ldb_parse_tree *tree,
1137 struct dn_list *list)
1139 int ret = LDB_ERR_OPERATIONS_ERROR;
1141 switch (tree->operation) {
1143 ret = ltdb_index_dn_and(module, ltdb, tree, list);
1147 ret = ltdb_index_dn_or(module, ltdb, tree, list);
1151 ret = ltdb_index_dn_not(module, ltdb, tree, list);
1154 case LDB_OP_EQUALITY:
1155 ret = ltdb_index_dn_leaf(module, ltdb, tree, list);
1158 case LDB_OP_SUBSTRING:
1159 case LDB_OP_GREATER:
1161 case LDB_OP_PRESENT:
1163 case LDB_OP_EXTENDED:
1164 /* we can't index with fancy bitops yet */
1165 ret = LDB_ERR_OPERATIONS_ERROR;
1173 filter a candidate dn_list from an indexed search into a set of results
1174 extracting just the given attributes
1176 static int ltdb_index_filter(struct ltdb_private *ltdb,
1177 const struct dn_list *dn_list,
1178 struct ltdb_context *ac,
1179 uint32_t *match_count)
1181 struct ldb_context *ldb;
1182 struct ldb_message *msg;
1183 struct ldb_message *filtered_msg;
1186 ldb = ldb_module_get_ctx(ac->module);
1188 for (i = 0; i < dn_list->count; i++) {
1193 msg = ldb_msg_new(ac);
1195 return LDB_ERR_OPERATIONS_ERROR;
1198 dn = ldb_dn_from_ldb_val(msg, ldb, &dn_list->dn[i]);
1201 return LDB_ERR_OPERATIONS_ERROR;
1204 ret = ltdb_search_dn1(ac->module, dn, msg,
1205 LDB_UNPACK_DATA_FLAG_NO_DATA_ALLOC|
1206 LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC);
1208 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
1209 /* the record has disappeared? yes, this can happen */
1214 if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_OBJECT) {
1215 /* an internal error */
1217 return LDB_ERR_OPERATIONS_ERROR;
1220 ret = ldb_match_msg_error(ldb, msg,
1221 ac->tree, ac->base, ac->scope, &matched);
1222 if (ret != LDB_SUCCESS) {
1231 /* filter the attributes that the user wants */
1232 ret = ltdb_filter_attrs(ac, msg, ac->attrs, &filtered_msg);
1237 return LDB_ERR_OPERATIONS_ERROR;
1240 ret = ldb_module_send_entry(ac->req, filtered_msg, NULL);
1241 if (ret != LDB_SUCCESS) {
1242 /* Regardless of success or failure, the msg
1243 * is the callbacks responsiblity, and should
1244 * not be talloc_free()'ed */
1245 ac->request_terminated = true;
1256 remove any duplicated entries in a indexed result
1258 static void ltdb_dn_list_remove_duplicates(struct dn_list *list)
1260 unsigned int i, new_count;
1262 if (list->count < 2) {
1266 TYPESAFE_QSORT(list->dn, list->count,
1267 ldb_val_equal_exact_for_qsort);
1270 for (i=1; i<list->count; i++) {
1271 if (ldb_val_equal_exact(&list->dn[i],
1272 &list->dn[new_count-1]) == 0) {
1273 if (new_count != i) {
1274 list->dn[new_count] = list->dn[i];
1280 list->count = new_count;
1284 search the database with a LDAP-like expression using indexes
1285 returns -1 if an indexed search is not possible, in which
1286 case the caller should call ltdb_search_full()
1288 int ltdb_search_indexed(struct ltdb_context *ac, uint32_t *match_count)
1290 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(ac->module), struct ltdb_private);
1291 struct dn_list *dn_list;
1294 /* see if indexing is enabled */
1295 if (!ltdb->cache->attribute_indexes &&
1296 !ltdb->cache->one_level_indexes &&
1297 ac->scope != LDB_SCOPE_BASE) {
1298 /* fallback to a full search */
1299 return LDB_ERR_OPERATIONS_ERROR;
1302 dn_list = talloc_zero(ac, struct dn_list);
1303 if (dn_list == NULL) {
1304 return ldb_module_oom(ac->module);
1307 switch (ac->scope) {
1308 case LDB_SCOPE_BASE:
1309 ret = ltdb_index_dn_base_dn(ac->module, ltdb,
1311 if (ret != LDB_SUCCESS) {
1312 talloc_free(dn_list);
1317 case LDB_SCOPE_ONELEVEL:
1318 if (!ltdb->cache->one_level_indexes) {
1319 talloc_free(dn_list);
1320 return LDB_ERR_OPERATIONS_ERROR;
1322 ret = ltdb_index_dn_one(ac->module, ltdb, ac->base, dn_list);
1323 if (ret != LDB_SUCCESS) {
1324 talloc_free(dn_list);
1329 case LDB_SCOPE_SUBTREE:
1330 case LDB_SCOPE_DEFAULT:
1331 if (!ltdb->cache->attribute_indexes) {
1332 talloc_free(dn_list);
1333 return LDB_ERR_OPERATIONS_ERROR;
1335 ret = ltdb_index_dn(ac->module, ltdb, ac->tree, dn_list);
1336 if (ret != LDB_SUCCESS) {
1337 talloc_free(dn_list);
1340 ltdb_dn_list_remove_duplicates(dn_list);
1344 ret = ltdb_index_filter(ltdb, dn_list, ac, match_count);
1345 talloc_free(dn_list);
1350 * @brief Add a DN in the index list of a given attribute name/value pair
1352 * This function will add the DN in the index list for the index for
1353 * the given attribute name and value.
1355 * @param[in] module A ldb_module structure
1357 * @param[in] dn The string representation of the DN as it
1358 * will be stored in the index entry
1360 * @param[in] el A ldb_message_element array, one of the entry
1361 * referred by the v_idx is the attribute name and
1362 * value pair which will be used to construct the
1365 * @param[in] v_idx The index of element in the el array to use
1367 * @return An ldb error code
1369 static int ltdb_index_add1(struct ldb_module *module,
1370 struct ltdb_private *ltdb,
1371 const struct ldb_message *msg,
1372 struct ldb_message_element *el, int v_idx)
1374 struct ldb_context *ldb;
1375 struct ldb_dn *dn_key;
1377 const struct ldb_schema_attribute *a;
1378 struct dn_list *list;
1381 ldb = ldb_module_get_ctx(module);
1383 list = talloc_zero(module, struct dn_list);
1385 return LDB_ERR_OPERATIONS_ERROR;
1388 dn_key = ltdb_index_key(ldb, el->name, &el->values[v_idx], &a);
1391 return LDB_ERR_OPERATIONS_ERROR;
1393 talloc_steal(list, dn_key);
1395 ret = ltdb_dn_list_load(module, ltdb, dn_key, list);
1396 if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_OBJECT) {
1401 if (list->count > 0 &&
1402 a->flags & LDB_ATTR_FLAG_UNIQUE_INDEX) {
1404 * We do not want to print info about a possibly
1405 * confidential DN that the conflict was with in the
1406 * user-visible error string
1408 ldb_debug(ldb, LDB_DEBUG_WARNING,
1409 __location__ ": unique index violation on %s in %s, "
1410 "conficts with %*.*s in %s",
1411 el->name, ldb_dn_get_linearized(msg->dn),
1412 (int)list->dn[0].length,
1413 (int)list->dn[0].length,
1415 ldb_dn_get_linearized(dn_key));
1416 ldb_asprintf_errstring(ldb, __location__ ": unique index violation on %s in %s",
1418 ldb_dn_get_linearized(msg->dn));
1420 return LDB_ERR_ENTRY_ALREADY_EXISTS;
1423 /* overallocate the list a bit, to reduce the number of
1424 * realloc trigered copies */
1425 alloc_len = ((list->count+1)+7) & ~7;
1426 list->dn = talloc_realloc(list, list->dn, struct ldb_val, alloc_len);
1427 if (list->dn == NULL) {
1429 return LDB_ERR_OPERATIONS_ERROR;
1432 if (ltdb->cache->GUID_index_attribute == NULL) {
1433 const char *dn_str = ldb_dn_get_linearized(msg->dn);
1434 list->dn[list->count].data
1435 = (uint8_t *)talloc_strdup(list->dn, dn_str);
1436 if (list->dn[list->count].data == NULL) {
1438 return LDB_ERR_OPERATIONS_ERROR;
1440 list->dn[list->count].length = strlen(dn_str);
1442 const struct ldb_val *key_val;
1443 key_val = ldb_msg_find_ldb_val(msg,
1444 ltdb->cache->GUID_index_attribute);
1445 if (key_val == NULL) {
1447 return ldb_module_operr(module);
1450 if (key_val->length != LTDB_GUID_SIZE) {
1452 return ldb_module_operr(module);
1454 list->dn[list->count] = ldb_val_dup(list->dn, key_val);
1455 if (list->dn[list->count].data == NULL) {
1457 return ldb_module_operr(module);
1462 ret = ltdb_dn_list_store(module, dn_key, list);
1470 add index entries for one elements in a message
1472 static int ltdb_index_add_el(struct ldb_module *module,
1473 struct ltdb_private *ltdb,
1474 const struct ldb_message *msg,
1475 struct ldb_message_element *el)
1478 for (i = 0; i < el->num_values; i++) {
1479 int ret = ltdb_index_add1(module, ltdb,
1481 if (ret != LDB_SUCCESS) {
1490 add index entries for all elements in a message
1492 static int ltdb_index_add_all(struct ldb_module *module,
1493 struct ltdb_private *ltdb,
1494 const struct ldb_message *msg)
1496 struct ldb_message_element *elements = msg->elements;
1501 if (ldb_dn_is_special(msg->dn)) {
1505 dn_str = ldb_dn_get_linearized(msg->dn);
1506 if (dn_str == NULL) {
1507 return LDB_ERR_OPERATIONS_ERROR;
1510 ret = ltdb_write_index_dn_guid(module, msg, 1);
1511 if (ret != LDB_SUCCESS) {
1515 if (!ltdb->cache->attribute_indexes) {
1516 /* no indexed fields */
1520 for (i = 0; i < msg->num_elements; i++) {
1521 if (!ltdb_is_indexed(module, ltdb, elements[i].name)) {
1524 ret = ltdb_index_add_el(module, ltdb,
1526 if (ret != LDB_SUCCESS) {
1527 struct ldb_context *ldb = ldb_module_get_ctx(module);
1528 ldb_asprintf_errstring(ldb,
1529 __location__ ": Failed to re-index %s in %s - %s",
1530 elements[i].name, dn_str,
1531 ldb_errstring(ldb));
1541 insert a DN index for a message
1543 static int ltdb_modify_index_dn(struct ldb_module *module,
1544 struct ltdb_private *ltdb,
1545 const struct ldb_message *msg,
1547 const char *index, int add)
1549 struct ldb_message_element el;
1553 val.data = (uint8_t *)((uintptr_t)ldb_dn_get_casefold(dn));
1554 if (val.data == NULL) {
1555 return LDB_ERR_OPERATIONS_ERROR;
1558 val.length = strlen((char *)val.data);
1564 ret = ltdb_index_add1(module, ltdb, msg, &el, 0);
1565 } else { /* delete */
1566 ret = ltdb_index_del_value(module, ltdb, msg, &el, 0);
1569 if (ret != LDB_SUCCESS) {
1570 struct ldb_context *ldb = ldb_module_get_ctx(module);
1571 const char *dn_str = ldb_dn_get_linearized(dn);
1572 ldb_asprintf_errstring(ldb,
1574 ": Failed to modify %s "
1575 "against %s in %s - %s",
1577 ltdb->cache->GUID_index_attribute,
1578 dn_str, ldb_errstring(ldb));
1585 insert a one level index for a message
1587 static int ltdb_index_onelevel(struct ldb_module *module,
1588 const struct ldb_message *msg, int add)
1590 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module),
1591 struct ltdb_private);
1595 /* We index for ONE Level only if requested */
1596 if (!ltdb->cache->one_level_indexes) {
1600 pdn = ldb_dn_get_parent(module, msg->dn);
1602 return LDB_ERR_OPERATIONS_ERROR;
1604 ret = ltdb_modify_index_dn(module, ltdb,
1605 msg, pdn, LTDB_IDXONE, add);
1613 insert a one level index for a message
1615 static int ltdb_write_index_dn_guid(struct ldb_module *module,
1616 const struct ldb_message *msg,
1620 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module),
1621 struct ltdb_private);
1623 /* We index for DN only if using a GUID index */
1624 if (ltdb->cache->GUID_index_attribute == NULL) {
1628 ret = ltdb_modify_index_dn(module, ltdb, msg, msg->dn,
1631 if (ret == LDB_ERR_CONSTRAINT_VIOLATION) {
1632 ldb_asprintf_errstring(ldb_module_get_ctx(module),
1633 "Entry %s already exists",
1634 ldb_dn_get_linearized(msg->dn));
1635 ret = LDB_ERR_ENTRY_ALREADY_EXISTS;
1641 add the index entries for a new element in a record
1642 The caller guarantees that these element values are not yet indexed
1644 int ltdb_index_add_element(struct ldb_module *module,
1645 struct ltdb_private *ltdb,
1646 const struct ldb_message *msg,
1647 struct ldb_message_element *el)
1649 if (ldb_dn_is_special(msg->dn)) {
1652 if (!ltdb_is_indexed(module, ltdb, el->name)) {
1655 return ltdb_index_add_el(module, ltdb, msg, el);
1659 add the index entries for a new record
1661 int ltdb_index_add_new(struct ldb_module *module,
1662 struct ltdb_private *ltdb,
1663 const struct ldb_message *msg)
1667 if (ldb_dn_is_special(msg->dn)) {
1671 ret = ltdb_index_add_all(module, ltdb, msg);
1672 if (ret != LDB_SUCCESS) {
1676 return ltdb_index_onelevel(module, msg, 1);
1681 delete an index entry for one message element
1683 int ltdb_index_del_value(struct ldb_module *module,
1684 struct ltdb_private *ltdb,
1685 const struct ldb_message *msg,
1686 struct ldb_message_element *el, unsigned int v_idx)
1688 struct ldb_context *ldb;
1689 struct ldb_dn *dn_key;
1693 struct dn_list *list;
1694 struct ldb_dn *dn = msg->dn;
1696 ldb = ldb_module_get_ctx(module);
1698 dn_str = ldb_dn_get_linearized(dn);
1699 if (dn_str == NULL) {
1700 return LDB_ERR_OPERATIONS_ERROR;
1703 if (dn_str[0] == '@') {
1707 dn_key = ltdb_index_key(ldb, el->name, &el->values[v_idx], NULL);
1709 return LDB_ERR_OPERATIONS_ERROR;
1712 list = talloc_zero(dn_key, struct dn_list);
1714 talloc_free(dn_key);
1715 return LDB_ERR_OPERATIONS_ERROR;
1718 ret = ltdb_dn_list_load(module, ltdb, dn_key, list);
1719 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
1720 /* it wasn't indexed. Did we have an earlier error? If we did then
1722 talloc_free(dn_key);
1726 if (ret != LDB_SUCCESS) {
1727 talloc_free(dn_key);
1731 i = ltdb_dn_list_find_msg(ltdb, list, msg);
1733 /* nothing to delete */
1734 talloc_free(dn_key);
1738 j = (unsigned int) i;
1739 if (j != list->count - 1) {
1740 memmove(&list->dn[j], &list->dn[j+1], sizeof(list->dn[0])*(list->count - (j+1)));
1743 if (list->count == 0) {
1744 talloc_free(list->dn);
1747 list->dn = talloc_realloc(list, list->dn, struct ldb_val, list->count);
1750 ret = ltdb_dn_list_store(module, dn_key, list);
1752 talloc_free(dn_key);
1758 delete the index entries for a element
1759 return -1 on failure
1761 int ltdb_index_del_element(struct ldb_module *module,
1762 struct ltdb_private *ltdb,
1763 const struct ldb_message *msg,
1764 struct ldb_message_element *el)
1770 if (!ltdb->cache->attribute_indexes) {
1771 /* no indexed fields */
1775 dn_str = ldb_dn_get_linearized(msg->dn);
1776 if (dn_str == NULL) {
1777 return LDB_ERR_OPERATIONS_ERROR;
1780 if (dn_str[0] == '@') {
1784 if (!ltdb_is_indexed(module, ltdb, el->name)) {
1787 for (i = 0; i < el->num_values; i++) {
1788 ret = ltdb_index_del_value(module, ltdb, msg, el, i);
1789 if (ret != LDB_SUCCESS) {
1798 delete the index entries for a record
1799 return -1 on failure
1801 int ltdb_index_delete(struct ldb_module *module, const struct ldb_message *msg)
1803 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
1807 if (ldb_dn_is_special(msg->dn)) {
1811 ret = ltdb_index_onelevel(module, msg, 0);
1812 if (ret != LDB_SUCCESS) {
1816 ret = ltdb_write_index_dn_guid(module, msg, 0);
1817 if (ret != LDB_SUCCESS) {
1821 if (!ltdb->cache->attribute_indexes) {
1822 /* no indexed fields */
1826 for (i = 0; i < msg->num_elements; i++) {
1827 ret = ltdb_index_del_element(module, ltdb,
1828 msg, &msg->elements[i]);
1829 if (ret != LDB_SUCCESS) {
1839 traversal function that deletes all @INDEX records
1841 static int delete_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state)
1843 struct ldb_module *module = state;
1844 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
1845 const char *dnstr = "DN=" LTDB_INDEX ":";
1846 struct dn_list list;
1851 if (strncmp((char *)key.dptr, dnstr, strlen(dnstr)) != 0) {
1854 /* we need to put a empty list in the internal tdb for this
1859 /* the offset of 3 is to remove the DN= prefix. */
1860 v.data = key.dptr + 3;
1861 v.length = strnlen((char *)key.dptr, key.dsize) - 3;
1863 dn = ldb_dn_from_ldb_val(ltdb, ldb_module_get_ctx(module), &v);
1864 ret = ltdb_dn_list_store(module, dn, &list);
1865 if (ret != LDB_SUCCESS) {
1866 ldb_asprintf_errstring(ldb_module_get_ctx(module),
1867 "Unable to store null index for %s\n",
1868 ldb_dn_get_linearized(dn));
1876 struct ltdb_reindex_context {
1877 struct ldb_module *module;
1882 traversal function that adds @INDEX records during a re index
1884 static int re_key(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state)
1886 struct ldb_context *ldb;
1887 struct ltdb_reindex_context *ctx = (struct ltdb_reindex_context *)state;
1888 struct ldb_module *module = ctx->module;
1889 struct ldb_message *msg;
1890 unsigned int nb_elements_in_db;
1891 const struct ldb_val val = {
1893 .length = data.dsize,
1899 ldb = ldb_module_get_ctx(module);
1901 if (key.dsize > 4 &&
1902 memcmp(key.dptr, "DN=@", 4) == 0) {
1906 is_record = ltdb_key_is_record(key);
1907 if (is_record == false) {
1911 msg = ldb_msg_new(module);
1916 ret = ldb_unpack_data_only_attr_list_flags(ldb, &val,
1919 LDB_UNPACK_DATA_FLAG_NO_DATA_ALLOC,
1920 &nb_elements_in_db);
1922 ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid data for index %s\n",
1923 ldb_dn_get_linearized(msg->dn));
1929 if (msg->dn == NULL) {
1930 ldb_debug(ldb, LDB_DEBUG_ERROR,
1931 "Refusing to re-index as GUID "
1932 "key %*.*s with no DN\n",
1933 (int)key.dsize, (int)key.dsize,
1939 /* check if the DN key has changed, perhaps due to the case
1940 insensitivity of an element changing, or a change from DN
1942 key2 = ltdb_key_msg(module, msg);
1943 if (key2.dptr == NULL) {
1944 /* probably a corrupt record ... darn */
1945 ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid DN in re_index: %s",
1946 ldb_dn_get_linearized(msg->dn));
1950 if (key.dsize != key2.dsize ||
1951 (memcmp(key.dptr, key2.dptr, key.dsize) != 0)) {
1953 tdb_ret = tdb_delete(tdb, key);
1955 ldb_debug(ldb, LDB_DEBUG_ERROR,
1956 "Failed to delete %*.*s "
1957 "for rekey as %*.*s: %s",
1958 (int)key.dsize, (int)key.dsize,
1959 (const char *)key.dptr,
1960 (int)key2.dsize, (int)key2.dsize,
1961 (const char *)key.dptr,
1963 ctx->error = ltdb_err_map(tdb_error(tdb));
1966 tdb_ret = tdb_store(tdb, key2, data, 0);
1968 ldb_debug(ldb, LDB_DEBUG_ERROR,
1969 "Failed to rekey %*.*s as %*.*s: %s",
1970 (int)key.dsize, (int)key.dsize,
1971 (const char *)key.dptr,
1972 (int)key2.dsize, (int)key2.dsize,
1973 (const char *)key.dptr,
1975 ctx->error = ltdb_err_map(tdb_error(tdb));
1979 talloc_free(key2.dptr);
1987 traversal function that adds @INDEX records during a re index
1989 static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state)
1991 struct ldb_context *ldb;
1992 struct ltdb_reindex_context *ctx = (struct ltdb_reindex_context *)state;
1993 struct ldb_module *module = ctx->module;
1994 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module),
1995 struct ltdb_private);
1996 struct ldb_message *msg;
1997 unsigned int nb_elements_in_db;
1998 const struct ldb_val val = {
2000 .length = data.dsize,
2005 ldb = ldb_module_get_ctx(module);
2007 if (key.dsize > 4 &&
2008 memcmp(key.dptr, "DN=@", 4) == 0) {
2012 is_record = ltdb_key_is_record(key);
2013 if (is_record == false) {
2017 msg = ldb_msg_new(module);
2022 ret = ldb_unpack_data_only_attr_list_flags(ldb, &val,
2025 LDB_UNPACK_DATA_FLAG_NO_DATA_ALLOC,
2026 &nb_elements_in_db);
2028 ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid data for index %s\n",
2029 ldb_dn_get_linearized(msg->dn));
2035 if (msg->dn == NULL) {
2036 ldb_debug(ldb, LDB_DEBUG_ERROR,
2037 "Refusing to re-index as GUID "
2038 "key %*.*s with no DN\n",
2039 (int)key.dsize, (int)key.dsize,
2045 ret = ltdb_index_onelevel(module, msg, 1);
2046 if (ret != LDB_SUCCESS) {
2047 ldb_debug(ldb, LDB_DEBUG_ERROR,
2048 "Adding special ONE LEVEL index failed (%s)!",
2049 ldb_dn_get_linearized(msg->dn));
2054 ret = ltdb_index_add_all(module, ltdb, msg);
2056 if (ret != LDB_SUCCESS) {
2068 force a complete reindex of the database
2070 int ltdb_reindex(struct ldb_module *module)
2072 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
2074 struct ltdb_reindex_context ctx;
2077 * Only triggered after a modification, but make clear we do
2078 * not re-index a read-only DB
2080 if (ltdb->read_only) {
2081 return LDB_ERR_UNWILLING_TO_PERFORM;
2084 if (ltdb_cache_reload(module) != 0) {
2085 return LDB_ERR_OPERATIONS_ERROR;
2089 * Ensure we read (and so remove) the entries from the real
2090 * DB, no values stored so far are any use as we want to do a
2093 ltdb_index_transaction_cancel(module);
2095 ret = ltdb_index_transaction_start(module);
2096 if (ret != LDB_SUCCESS) {
2100 /* first traverse the database deleting any @INDEX records by
2101 * putting NULL entries in the in-memory tdb
2103 ret = tdb_traverse(ltdb->tdb, delete_index, module);
2105 struct ldb_context *ldb = ldb_module_get_ctx(module);
2106 ldb_asprintf_errstring(ldb, "index deletion traverse failed: %s",
2107 ldb_errstring(ldb));
2108 return LDB_ERR_OPERATIONS_ERROR;
2111 /* if we don't have indexes we have nothing todo */
2112 if (!ltdb->cache->attribute_indexes) {
2116 ctx.module = module;
2119 /* now traverse adding any indexes for normal LDB records */
2120 ret = tdb_traverse(ltdb->tdb, re_key, &ctx);
2122 struct ldb_context *ldb = ldb_module_get_ctx(module);
2123 ldb_asprintf_errstring(ldb, "key correction traverse failed: %s",
2124 ldb_errstring(ldb));
2125 return LDB_ERR_OPERATIONS_ERROR;
2128 if (ctx.error != LDB_SUCCESS) {
2129 struct ldb_context *ldb = ldb_module_get_ctx(module);
2130 ldb_asprintf_errstring(ldb, "reindexing failed: %s", ldb_errstring(ldb));
2136 /* now traverse adding any indexes for normal LDB records */
2137 ret = tdb_traverse(ltdb->tdb, re_index, &ctx);
2139 struct ldb_context *ldb = ldb_module_get_ctx(module);
2140 ldb_asprintf_errstring(ldb, "reindexing traverse failed: %s",
2141 ldb_errstring(ldb));
2142 return LDB_ERR_OPERATIONS_ERROR;
2145 if (ctx.error != LDB_SUCCESS) {
2146 struct ldb_context *ldb = ldb_module_get_ctx(module);
2147 ldb_asprintf_errstring(ldb, "reindexing failed: %s", ldb_errstring(ldb));