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 /* we put a @IDXVERSION attribute on index entries. This
48 allows us to tell if it was written by an older version
50 #define LTDB_INDEXING_VERSION 2
52 /* enable the idxptr mode when transactions start */
53 int ltdb_index_transaction_start(struct ldb_module *module)
55 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
56 ltdb->idxptr = talloc_zero(ltdb, struct ltdb_idxptr);
57 if (ltdb->idxptr == NULL) {
58 return ldb_oom(ldb_module_get_ctx(module));
65 see if two ldb_val structures contain exactly the same data
66 return -1 or 1 for a mismatch, 0 for match
68 static int ldb_val_equal_exact_for_qsort(const struct ldb_val *v1,
69 const struct ldb_val *v2)
71 if (v1->length > v2->length) {
74 if (v1->length < v2->length) {
77 return memcmp(v1->data, v2->data, v1->length);
82 find a entry in a dn_list, using a ldb_val. Uses a case sensitive
83 binary-safe comparison for the 'dn' returns -1 if not found
85 This is therefore safe when the value is a GUID in the future
87 static int ltdb_dn_list_find_val(struct ltdb_private *ltdb,
88 const struct dn_list *list,
89 const struct ldb_val *v)
92 for (i=0; i<list->count; i++) {
93 if (ldb_val_equal_exact(&list->dn[i], v) == 1) {
101 find a entry in a dn_list. Uses a case sensitive comparison with the dn
102 returns -1 if not found
104 static int ltdb_dn_list_find_str(struct ltdb_private *ltdb,
105 struct dn_list *list,
109 v.data = discard_const_p(unsigned char, dn);
110 v.length = strlen(dn);
111 return ltdb_dn_list_find_val(ltdb, list, &v);
115 this is effectively a cast function, but with lots of paranoia
116 checks and also copes with CPUs that are fussy about pointer
119 static struct dn_list *ltdb_index_idxptr(struct ldb_module *module, TDB_DATA rec, bool check_parent)
121 struct dn_list *list;
122 if (rec.dsize != sizeof(void *)) {
123 ldb_asprintf_errstring(ldb_module_get_ctx(module),
124 "Bad data size for idxptr %u", (unsigned)rec.dsize);
127 /* note that we can't just use a cast here, as rec.dptr may
128 not be aligned sufficiently for a pointer. A cast would cause
129 platforms like some ARM CPUs to crash */
130 memcpy(&list, rec.dptr, sizeof(void *));
131 list = talloc_get_type(list, struct dn_list);
133 ldb_asprintf_errstring(ldb_module_get_ctx(module),
134 "Bad type '%s' for idxptr",
135 talloc_get_name(list));
138 if (check_parent && list->dn && talloc_parent(list->dn) != list) {
139 ldb_asprintf_errstring(ldb_module_get_ctx(module),
140 "Bad parent '%s' for idxptr",
141 talloc_get_name(talloc_parent(list->dn)));
148 return the @IDX list in an index entry for a dn as a
151 static int ltdb_dn_list_load(struct ldb_module *module,
152 struct ldb_dn *dn, struct dn_list *list)
154 struct ldb_message *msg;
156 struct ldb_message_element *el;
157 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
159 struct dn_list *list2;
165 /* see if we have any in-memory index entries */
166 if (ltdb->idxptr == NULL ||
167 ltdb->idxptr->itdb == NULL) {
171 key.dptr = discard_const_p(unsigned char, ldb_dn_get_linearized(dn));
172 key.dsize = strlen((char *)key.dptr);
174 rec = tdb_fetch(ltdb->idxptr->itdb, key);
175 if (rec.dptr == NULL) {
179 /* we've found an in-memory index entry */
180 list2 = ltdb_index_idxptr(module, rec, true);
183 return LDB_ERR_OPERATIONS_ERROR;
191 msg = ldb_msg_new(list);
193 return LDB_ERR_OPERATIONS_ERROR;
196 ret = ltdb_search_dn1(module, dn, msg,
197 LDB_UNPACK_DATA_FLAG_NO_DATA_ALLOC
198 |LDB_UNPACK_DATA_FLAG_NO_DN);
199 if (ret != LDB_SUCCESS) {
204 /* TODO: check indexing version number */
206 el = ldb_msg_find_element(msg, LTDB_IDX);
213 * we avoid copying the strings by stealing the list. We have
214 * to steal msg onto el->values (which looks odd) because we
215 * asked for the memory to be allocated on msg, not on each
216 * value with LDB_UNPACK_DATA_FLAG_NO_DATA_ALLOC above
218 if (ltdb->cache->GUID_index_attribute == NULL) {
219 talloc_steal(el->values, msg);
220 list->dn = talloc_steal(list, el->values);
221 list->count = el->num_values;
224 static const size_t GUID_val_size = 16;
225 if (el->num_values != 1) {
226 return LDB_ERR_OPERATIONS_ERROR;
229 if ((el->values[0].length % GUID_val_size) != 0) {
230 return LDB_ERR_OPERATIONS_ERROR;
233 list->count = el->values[0].length / GUID_val_size;
234 list->dn = talloc_array(list, struct ldb_val, list->count);
237 * The actual data is on msg, due to
238 * LDB_UNPACK_DATA_FLAG_NO_DATA_ALLOC
240 talloc_steal(list->dn, msg);
241 for (i = 0; i < list->count; i++) {
242 list->dn[i].data = &el->values[0].data[i * GUID_val_size];
243 list->dn[i].length = GUID_val_size;
247 /* We don't need msg->elements any more */
248 talloc_free(msg->elements);
254 save a dn_list into a full @IDX style record
256 static int ltdb_dn_list_store_full(struct ldb_module *module,
257 struct ltdb_private *ltdb,
259 struct dn_list *list)
261 struct ldb_message *msg;
264 if (list->count == 0) {
265 ret = ltdb_delete_noindex(module, dn);
266 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
272 msg = ldb_msg_new(module);
274 return ldb_module_oom(module);
277 ret = ldb_msg_add_fmt(msg, LTDB_IDXVERSION, "%u", LTDB_INDEXING_VERSION);
278 if (ret != LDB_SUCCESS) {
280 return ldb_module_oom(module);
284 if (list->count > 0) {
285 struct ldb_message_element *el;
287 ret = ldb_msg_add_empty(msg, LTDB_IDX, LDB_FLAG_MOD_ADD, &el);
288 if (ret != LDB_SUCCESS) {
290 return ldb_module_oom(module);
293 if (ltdb->cache->GUID_index_attribute == NULL) {
294 el->values = list->dn;
295 el->num_values = list->count;
299 el->values = talloc_array(msg,
301 if (el->values == NULL) {
303 return ldb_module_oom(module);
306 v.data = talloc_array_size(el->values,
309 if (v.data == NULL) {
311 return ldb_module_oom(module);
314 v.length = talloc_get_size(v.data);
316 for (i = 0; i < list->count; i++) {
317 if (list->dn[i].length !=
320 return ldb_module_operr(module);
322 memcpy(&v.data[LTDB_GUID_SIZE*i],
331 ret = ltdb_store(module, msg, TDB_REPLACE);
337 save a dn_list into the database, in either @IDX or internal format
339 static int ltdb_dn_list_store(struct ldb_module *module, struct ldb_dn *dn,
340 struct dn_list *list)
342 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
345 struct dn_list *list2;
347 if (ltdb->idxptr == NULL) {
348 return ltdb_dn_list_store_full(module, ltdb,
352 if (ltdb->idxptr->itdb == NULL) {
353 ltdb->idxptr->itdb = tdb_open(NULL, 1000, TDB_INTERNAL, O_RDWR, 0);
354 if (ltdb->idxptr->itdb == NULL) {
355 return LDB_ERR_OPERATIONS_ERROR;
359 key.dptr = discard_const_p(unsigned char, ldb_dn_get_linearized(dn));
360 key.dsize = strlen((char *)key.dptr);
362 rec = tdb_fetch(ltdb->idxptr->itdb, key);
363 if (rec.dptr != NULL) {
364 list2 = ltdb_index_idxptr(module, rec, false);
367 return LDB_ERR_OPERATIONS_ERROR;
370 list2->dn = talloc_steal(list2, list->dn);
371 list2->count = list->count;
375 list2 = talloc(ltdb->idxptr, struct dn_list);
377 return LDB_ERR_OPERATIONS_ERROR;
379 list2->dn = talloc_steal(list2, list->dn);
380 list2->count = list->count;
382 rec.dptr = (uint8_t *)&list2;
383 rec.dsize = sizeof(void *);
387 * This is not a store into the main DB, but into an in-memory
388 * TDB, so we don't need a guard on ltdb->read_only
390 ret = tdb_store(ltdb->idxptr->itdb, key, rec, TDB_INSERT);
392 return ltdb_err_map(tdb_error(ltdb->idxptr->itdb));
398 traverse function for storing the in-memory index entries on disk
400 static int ltdb_index_traverse_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state)
402 struct ldb_module *module = state;
403 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
405 struct ldb_context *ldb = ldb_module_get_ctx(module);
407 struct dn_list *list;
409 list = ltdb_index_idxptr(module, data, true);
411 ltdb->idxptr->error = LDB_ERR_OPERATIONS_ERROR;
416 v.length = strnlen((char *)key.dptr, key.dsize);
418 dn = ldb_dn_from_ldb_val(module, ldb, &v);
420 ldb_asprintf_errstring(ldb, "Failed to parse index key %*.*s as an LDB DN", (int)v.length, (int)v.length, (const char *)v.data);
421 ltdb->idxptr->error = LDB_ERR_OPERATIONS_ERROR;
425 ltdb->idxptr->error = ltdb_dn_list_store_full(module, ltdb,
428 if (ltdb->idxptr->error != 0) {
434 /* cleanup the idxptr mode when transaction commits */
435 int ltdb_index_transaction_commit(struct ldb_module *module)
437 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
440 struct ldb_context *ldb = ldb_module_get_ctx(module);
442 ldb_reset_err_string(ldb);
444 if (ltdb->idxptr->itdb) {
445 tdb_traverse(ltdb->idxptr->itdb, ltdb_index_traverse_store, module);
446 tdb_close(ltdb->idxptr->itdb);
449 ret = ltdb->idxptr->error;
450 if (ret != LDB_SUCCESS) {
451 if (!ldb_errstring(ldb)) {
452 ldb_set_errstring(ldb, ldb_strerror(ret));
454 ldb_asprintf_errstring(ldb, "Failed to store index records in transaction commit: %s", ldb_errstring(ldb));
457 talloc_free(ltdb->idxptr);
462 /* cleanup the idxptr mode when transaction cancels */
463 int ltdb_index_transaction_cancel(struct ldb_module *module)
465 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
466 if (ltdb->idxptr && ltdb->idxptr->itdb) {
467 tdb_close(ltdb->idxptr->itdb);
469 talloc_free(ltdb->idxptr);
476 return the dn key to be used for an index
477 the caller is responsible for freeing
479 static struct ldb_dn *ltdb_index_key(struct ldb_context *ldb,
480 const char *attr, const struct ldb_val *value,
481 const struct ldb_schema_attribute **ap)
485 const struct ldb_schema_attribute *a;
489 attr_folded = ldb_attr_casefold(ldb, attr);
494 a = ldb_schema_attribute_by_name(ldb, attr);
498 r = a->syntax->canonicalise_fn(ldb, ldb, value, &v);
499 if (r != LDB_SUCCESS) {
500 const char *errstr = ldb_errstring(ldb);
501 /* canonicalisation can be refused. For example,
502 a attribute that takes wildcards will refuse to canonicalise
503 if the value contains a wildcard */
504 ldb_asprintf_errstring(ldb, "Failed to create index key for attribute '%s':%s%s%s",
505 attr, ldb_strerror(r), (errstr?":":""), (errstr?errstr:""));
506 talloc_free(attr_folded);
509 if (ldb_should_b64_encode(ldb, &v)) {
510 char *vstr = ldb_base64_encode(ldb, (char *)v.data, v.length);
512 talloc_free(attr_folded);
515 ret = ldb_dn_new_fmt(ldb, ldb, "%s:%s::%s", LTDB_INDEX, attr_folded, vstr);
518 ret = ldb_dn_new_fmt(ldb, ldb, "%s:%s:%.*s", LTDB_INDEX, attr_folded, (int)v.length, (char *)v.data);
521 if (v.data != value->data) {
524 talloc_free(attr_folded);
530 see if a attribute value is in the list of indexed attributes
532 static bool ltdb_is_indexed(struct ldb_module *module,
533 struct ltdb_private *ltdb,
536 struct ldb_context *ldb = ldb_module_get_ctx(module);
538 struct ldb_message_element *el;
540 if (ldb->schema.index_handler_override) {
541 const struct ldb_schema_attribute *a
542 = ldb_schema_attribute_by_name(ldb, attr);
548 if (a->flags & LDB_ATTR_FLAG_INDEXED) {
555 if (!ltdb->cache->attribute_indexes) {
559 el = ldb_msg_find_element(ltdb->cache->indexlist, LTDB_IDXATTR);
564 /* TODO: this is too expensive! At least use a binary search */
565 for (i=0; i<el->num_values; i++) {
566 if (ldb_attr_cmp((char *)el->values[i].data, attr) == 0) {
574 in the following logic functions, the return value is treated as
577 LDB_SUCCESS: we found some matching index values
579 LDB_ERR_NO_SUCH_OBJECT: we know for sure that no object matches
581 LDB_ERR_OPERATIONS_ERROR: indexing could not answer the call,
582 we'll need a full search
586 return a list of dn's that might match a simple indexed search (an
587 equality search only)
589 static int ltdb_index_dn_simple(struct ldb_module *module,
590 struct ltdb_private *ltdb,
591 const struct ldb_parse_tree *tree,
592 struct dn_list *list)
594 struct ldb_context *ldb;
598 ldb = ldb_module_get_ctx(module);
603 /* if the attribute isn't in the list of indexed attributes then
604 this node needs a full search */
605 if (!ltdb_is_indexed(module, ltdb, tree->u.equality.attr)) {
606 return LDB_ERR_OPERATIONS_ERROR;
609 /* the attribute is indexed. Pull the list of DNs that match the
611 dn = ltdb_index_key(ldb, tree->u.equality.attr, &tree->u.equality.value, NULL);
612 if (!dn) return LDB_ERR_OPERATIONS_ERROR;
614 ret = ltdb_dn_list_load(module, dn, list);
620 static bool list_union(struct ldb_context *, struct dn_list *, const struct dn_list *);
623 return a list of dn's that might match a leaf indexed search
625 static int ltdb_index_dn_leaf(struct ldb_module *module,
626 struct ltdb_private *ltdb,
627 const struct ldb_parse_tree *tree,
628 struct dn_list *list)
630 if (ltdb->disallow_dn_filter &&
631 (ldb_attr_cmp(tree->u.equality.attr, "dn") == 0)) {
632 /* in AD mode we do not support "(dn=...)" search filters */
637 if (ldb_attr_dn(tree->u.equality.attr) == 0) {
638 list->dn = talloc_array(list, struct ldb_val, 1);
639 if (list->dn == NULL) {
640 ldb_module_oom(module);
641 return LDB_ERR_OPERATIONS_ERROR;
643 list->dn[0] = tree->u.equality.value;
647 return ltdb_index_dn_simple(module, ltdb, tree, list);
655 static bool list_intersect(struct ldb_context *ldb,
656 struct ltdb_private *ltdb,
657 struct dn_list *list, const struct dn_list *list2)
659 struct dn_list *list3;
662 if (list->count == 0) {
666 if (list2->count == 0) {
673 /* the indexing code is allowed to return a longer list than
674 what really matches, as all results are filtered by the
675 full expression at the end - this shortcut avoids a lot of
676 work in some cases */
677 if (list->count < 2 && list2->count > 10) {
680 if (list2->count < 2 && list->count > 10) {
681 list->count = list2->count;
682 list->dn = list2->dn;
683 /* note that list2 may not be the parent of list2->dn,
684 as list2->dn may be owned by ltdb->idxptr. In that
685 case we expect this reparent call to fail, which is
687 talloc_reparent(list2, list, list2->dn);
691 list3 = talloc_zero(list, struct dn_list);
696 list3->dn = talloc_array(list3, struct ldb_val, list->count);
703 for (i=0;i<list->count;i++) {
704 if (ltdb_dn_list_find_val(ltdb, list2,
705 &list->dn[i]) != -1) {
706 list3->dn[list3->count] = list->dn[i];
711 list->dn = talloc_steal(list, list3->dn);
712 list->count = list3->count;
723 static bool list_union(struct ldb_context *ldb,
724 struct dn_list *list, const struct dn_list *list2)
728 if (list2->count == 0) {
733 if (list->count == 0) {
735 list->count = list2->count;
736 list->dn = list2->dn;
737 /* note that list2 may not be the parent of list2->dn,
738 as list2->dn may be owned by ltdb->idxptr. In that
739 case we expect this reparent call to fail, which is
741 talloc_reparent(list2, list, list2->dn);
745 dn3 = talloc_array(list, struct ldb_val, list->count + list2->count);
751 /* we allow for duplicates here, and get rid of them later */
752 memcpy(dn3, list->dn, sizeof(list->dn[0])*list->count);
753 memcpy(dn3+list->count, list2->dn, sizeof(list2->dn[0])*list2->count);
756 list->count += list2->count;
761 static int ltdb_index_dn(struct ldb_module *module,
762 struct ltdb_private *ltdb,
763 const struct ldb_parse_tree *tree,
764 struct dn_list *list);
768 process an OR list (a union)
770 static int ltdb_index_dn_or(struct ldb_module *module,
771 struct ltdb_private *ltdb,
772 const struct ldb_parse_tree *tree,
773 struct dn_list *list)
775 struct ldb_context *ldb;
778 ldb = ldb_module_get_ctx(module);
783 for (i=0; i<tree->u.list.num_elements; i++) {
784 struct dn_list *list2;
787 list2 = talloc_zero(list, struct dn_list);
789 return LDB_ERR_OPERATIONS_ERROR;
792 ret = ltdb_index_dn(module, ltdb,
793 tree->u.list.elements[i], list2);
795 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
801 if (ret != LDB_SUCCESS) {
807 if (!list_union(ldb, list, list2)) {
809 return LDB_ERR_OPERATIONS_ERROR;
813 if (list->count == 0) {
814 return LDB_ERR_NO_SUCH_OBJECT;
824 static int ltdb_index_dn_not(struct ldb_module *module,
825 struct ltdb_private *ltdb,
826 const struct ldb_parse_tree *tree,
827 struct dn_list *list)
829 /* the only way to do an indexed not would be if we could
830 negate the not via another not or if we knew the total
831 number of database elements so we could know that the
832 existing expression covered the whole database.
834 instead, we just give up, and rely on a full index scan
835 (unless an outer & manages to reduce the list)
837 return LDB_ERR_OPERATIONS_ERROR;
841 static bool ltdb_index_unique(struct ldb_context *ldb,
844 const struct ldb_schema_attribute *a;
845 a = ldb_schema_attribute_by_name(ldb, attr);
846 if (a->flags & LDB_ATTR_FLAG_UNIQUE_INDEX) {
853 process an AND expression (intersection)
855 static int ltdb_index_dn_and(struct ldb_module *module,
856 struct ltdb_private *ltdb,
857 const struct ldb_parse_tree *tree,
858 struct dn_list *list)
860 struct ldb_context *ldb;
864 ldb = ldb_module_get_ctx(module);
869 /* in the first pass we only look for unique simple
870 equality tests, in the hope of avoiding having to look
872 for (i=0; i<tree->u.list.num_elements; i++) {
873 const struct ldb_parse_tree *subtree = tree->u.list.elements[i];
876 if (subtree->operation != LDB_OP_EQUALITY ||
877 !ltdb_index_unique(ldb, subtree->u.equality.attr)) {
881 ret = ltdb_index_dn(module, ltdb, subtree, list);
882 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
884 return LDB_ERR_NO_SUCH_OBJECT;
886 if (ret == LDB_SUCCESS) {
887 /* a unique index match means we can
888 * stop. Note that we don't care if we return
889 * a few too many objects, due to later
895 /* now do a full intersection */
898 for (i=0; i<tree->u.list.num_elements; i++) {
899 const struct ldb_parse_tree *subtree = tree->u.list.elements[i];
900 struct dn_list *list2;
903 list2 = talloc_zero(list, struct dn_list);
905 return ldb_module_oom(module);
908 ret = ltdb_index_dn(module, ltdb, subtree, list2);
910 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
915 return LDB_ERR_NO_SUCH_OBJECT;
918 if (ret != LDB_SUCCESS) {
919 /* this didn't adding anything */
925 talloc_reparent(list2, list, list->dn);
926 list->dn = list2->dn;
927 list->count = list2->count;
929 } else if (!list_intersect(ldb, ltdb,
932 return LDB_ERR_OPERATIONS_ERROR;
935 if (list->count == 0) {
937 return LDB_ERR_NO_SUCH_OBJECT;
940 if (list->count < 2) {
941 /* it isn't worth loading the next part of the tree */
947 /* none of the attributes were indexed */
948 return LDB_ERR_OPERATIONS_ERROR;
955 return a list of matching objects using a one-level index
957 static int ltdb_index_dn_one(struct ldb_module *module,
958 struct ldb_dn *parent_dn,
959 struct dn_list *list)
961 struct ldb_context *ldb;
966 ldb = ldb_module_get_ctx(module);
968 /* work out the index key from the parent DN */
969 val.data = (uint8_t *)((uintptr_t)ldb_dn_get_casefold(parent_dn));
970 val.length = strlen((char *)val.data);
971 key = ltdb_index_key(ldb, LTDB_IDXONE, &val, NULL);
974 return LDB_ERR_OPERATIONS_ERROR;
977 ret = ltdb_dn_list_load(module, key, list);
979 if (ret != LDB_SUCCESS) {
983 if (list->count == 0) {
984 return LDB_ERR_NO_SUCH_OBJECT;
991 return a list of dn's that might match a indexed search or
992 an error. return LDB_ERR_NO_SUCH_OBJECT for no matches, or LDB_SUCCESS for matches
994 static int ltdb_index_dn(struct ldb_module *module,
995 struct ltdb_private *ltdb,
996 const struct ldb_parse_tree *tree,
997 struct dn_list *list)
999 int ret = LDB_ERR_OPERATIONS_ERROR;
1001 switch (tree->operation) {
1003 ret = ltdb_index_dn_and(module, ltdb, tree, list);
1007 ret = ltdb_index_dn_or(module, ltdb, tree, list);
1011 ret = ltdb_index_dn_not(module, ltdb, tree, list);
1014 case LDB_OP_EQUALITY:
1015 ret = ltdb_index_dn_leaf(module, ltdb, tree, list);
1018 case LDB_OP_SUBSTRING:
1019 case LDB_OP_GREATER:
1021 case LDB_OP_PRESENT:
1023 case LDB_OP_EXTENDED:
1024 /* we can't index with fancy bitops yet */
1025 ret = LDB_ERR_OPERATIONS_ERROR;
1033 filter a candidate dn_list from an indexed search into a set of results
1034 extracting just the given attributes
1036 static int ltdb_index_filter(struct ltdb_private *ltdb,
1037 const struct dn_list *dn_list,
1038 struct ltdb_context *ac,
1039 uint32_t *match_count)
1041 struct ldb_context *ldb;
1042 struct ldb_message *msg;
1043 struct ldb_message *filtered_msg;
1046 ldb = ldb_module_get_ctx(ac->module);
1048 for (i = 0; i < dn_list->count; i++) {
1053 msg = ldb_msg_new(ac);
1055 return LDB_ERR_OPERATIONS_ERROR;
1058 dn = ldb_dn_from_ldb_val(msg, ldb, &dn_list->dn[i]);
1061 return LDB_ERR_OPERATIONS_ERROR;
1064 ret = ltdb_search_dn1(ac->module, dn, msg,
1065 LDB_UNPACK_DATA_FLAG_NO_DATA_ALLOC|
1066 LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC);
1068 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
1069 /* the record has disappeared? yes, this can happen */
1074 if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_OBJECT) {
1075 /* an internal error */
1077 return LDB_ERR_OPERATIONS_ERROR;
1080 ret = ldb_match_msg_error(ldb, msg,
1081 ac->tree, ac->base, ac->scope, &matched);
1082 if (ret != LDB_SUCCESS) {
1091 /* filter the attributes that the user wants */
1092 ret = ltdb_filter_attrs(ac, msg, ac->attrs, &filtered_msg);
1097 return LDB_ERR_OPERATIONS_ERROR;
1100 ret = ldb_module_send_entry(ac->req, filtered_msg, NULL);
1101 if (ret != LDB_SUCCESS) {
1102 /* Regardless of success or failure, the msg
1103 * is the callbacks responsiblity, and should
1104 * not be talloc_free()'ed */
1105 ac->request_terminated = true;
1116 remove any duplicated entries in a indexed result
1118 static void ltdb_dn_list_remove_duplicates(struct dn_list *list)
1120 unsigned int i, new_count;
1122 if (list->count < 2) {
1126 TYPESAFE_QSORT(list->dn, list->count,
1127 ldb_val_equal_exact_for_qsort);
1130 for (i=1; i<list->count; i++) {
1131 if (ldb_val_equal_exact(&list->dn[i],
1132 &list->dn[new_count-1]) == 0) {
1133 if (new_count != i) {
1134 list->dn[new_count] = list->dn[i];
1140 list->count = new_count;
1144 search the database with a LDAP-like expression using indexes
1145 returns -1 if an indexed search is not possible, in which
1146 case the caller should call ltdb_search_full()
1148 int ltdb_search_indexed(struct ltdb_context *ac, uint32_t *match_count)
1150 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(ac->module), struct ltdb_private);
1151 struct dn_list *dn_list;
1154 /* see if indexing is enabled */
1155 if (!ltdb->cache->attribute_indexes &&
1156 !ltdb->cache->one_level_indexes &&
1157 ac->scope != LDB_SCOPE_BASE) {
1158 /* fallback to a full search */
1159 return LDB_ERR_OPERATIONS_ERROR;
1162 dn_list = talloc_zero(ac, struct dn_list);
1163 if (dn_list == NULL) {
1164 return ldb_module_oom(ac->module);
1167 switch (ac->scope) {
1168 case LDB_SCOPE_BASE:
1169 dn_list->dn = talloc_array(dn_list, struct ldb_val, 1);
1170 if (dn_list->dn == NULL) {
1171 talloc_free(dn_list);
1172 return ldb_module_oom(ac->module);
1174 dn_list->dn[0].data = discard_const_p(unsigned char, ldb_dn_get_linearized(ac->base));
1175 if (dn_list->dn[0].data == NULL) {
1176 talloc_free(dn_list);
1177 return ldb_module_oom(ac->module);
1179 dn_list->dn[0].length = strlen((char *)dn_list->dn[0].data);
1183 case LDB_SCOPE_ONELEVEL:
1184 if (!ltdb->cache->one_level_indexes) {
1185 talloc_free(dn_list);
1186 return LDB_ERR_OPERATIONS_ERROR;
1188 ret = ltdb_index_dn_one(ac->module, ac->base, dn_list);
1189 if (ret != LDB_SUCCESS) {
1190 talloc_free(dn_list);
1195 case LDB_SCOPE_SUBTREE:
1196 case LDB_SCOPE_DEFAULT:
1197 if (!ltdb->cache->attribute_indexes) {
1198 talloc_free(dn_list);
1199 return LDB_ERR_OPERATIONS_ERROR;
1201 ret = ltdb_index_dn(ac->module, ltdb, ac->tree, dn_list);
1202 if (ret != LDB_SUCCESS) {
1203 talloc_free(dn_list);
1206 ltdb_dn_list_remove_duplicates(dn_list);
1210 ret = ltdb_index_filter(ltdb, dn_list, ac, match_count);
1211 talloc_free(dn_list);
1216 * @brief Add a DN in the index list of a given attribute name/value pair
1218 * This function will add the DN in the index list for the index for
1219 * the given attribute name and value.
1221 * @param[in] module A ldb_module structure
1223 * @param[in] dn The string representation of the DN as it
1224 * will be stored in the index entry
1226 * @param[in] el A ldb_message_element array, one of the entry
1227 * referred by the v_idx is the attribute name and
1228 * value pair which will be used to construct the
1231 * @param[in] v_idx The index of element in the el array to use
1233 * @return An ldb error code
1235 static int ltdb_index_add1(struct ldb_module *module,
1236 struct ltdb_private *ltdb,
1238 struct ldb_message_element *el, int v_idx)
1240 struct ldb_context *ldb;
1241 struct ldb_dn *dn_key;
1243 const struct ldb_schema_attribute *a;
1244 struct dn_list *list;
1247 ldb = ldb_module_get_ctx(module);
1249 list = talloc_zero(module, struct dn_list);
1251 return LDB_ERR_OPERATIONS_ERROR;
1254 dn_key = ltdb_index_key(ldb, el->name, &el->values[v_idx], &a);
1257 return LDB_ERR_OPERATIONS_ERROR;
1259 talloc_steal(list, dn_key);
1261 ret = ltdb_dn_list_load(module, dn_key, list);
1262 if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_OBJECT) {
1267 if (list->count > 0 &&
1268 a->flags & LDB_ATTR_FLAG_UNIQUE_INDEX) {
1270 * We do not want to print info about a possibly
1271 * confidential DN that the conflict was with in the
1272 * user-visible error string
1274 ldb_debug(ldb, LDB_DEBUG_WARNING,
1275 __location__ ": unique index violation on %s in %s, "
1276 "conficts with %*.*s in %s",
1278 (int)list->dn[0].length,
1279 (int)list->dn[0].length,
1281 ldb_dn_get_linearized(dn_key));
1282 ldb_asprintf_errstring(ldb, __location__ ": unique index violation on %s in %s",
1285 return LDB_ERR_ENTRY_ALREADY_EXISTS;
1288 /* overallocate the list a bit, to reduce the number of
1289 * realloc trigered copies */
1290 alloc_len = ((list->count+1)+7) & ~7;
1291 list->dn = talloc_realloc(list, list->dn, struct ldb_val, alloc_len);
1292 if (list->dn == NULL) {
1294 return LDB_ERR_OPERATIONS_ERROR;
1297 list->dn[list->count].data
1298 = (uint8_t *)talloc_strdup(list->dn, dn);
1299 if (list->dn[list->count].data == NULL) {
1301 return LDB_ERR_OPERATIONS_ERROR;
1303 list->dn[list->count].length = strlen(dn);
1306 ret = ltdb_dn_list_store(module, dn_key, list);
1314 add index entries for one elements in a message
1316 static int ltdb_index_add_el(struct ldb_module *module,
1317 struct ltdb_private *ltdb,
1319 struct ldb_message_element *el)
1322 for (i = 0; i < el->num_values; i++) {
1323 int ret = ltdb_index_add1(module, ltdb,
1325 if (ret != LDB_SUCCESS) {
1334 add index entries for all elements in a message
1336 static int ltdb_index_add_all(struct ldb_module *module,
1337 struct ltdb_private *ltdb,
1339 struct ldb_message_element *elements,
1340 unsigned int num_el)
1348 if (!ltdb->cache->attribute_indexes) {
1349 /* no indexed fields */
1353 for (i = 0; i < num_el; i++) {
1355 if (!ltdb_is_indexed(module, ltdb, elements[i].name)) {
1358 ret = ltdb_index_add_el(module, ltdb, dn, &elements[i]);
1359 if (ret != LDB_SUCCESS) {
1360 struct ldb_context *ldb = ldb_module_get_ctx(module);
1361 ldb_asprintf_errstring(ldb,
1362 __location__ ": Failed to re-index %s in %s - %s",
1363 elements[i].name, dn, ldb_errstring(ldb));
1373 insert a one level index for a message
1375 static int ltdb_index_onelevel(struct ldb_module *module,
1376 const struct ldb_message *msg, int add)
1378 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module),
1379 struct ltdb_private);
1380 struct ldb_message_element el;
1386 /* We index for ONE Level only if requested */
1387 if (!ltdb->cache->one_level_indexes) {
1391 pdn = ldb_dn_get_parent(module, msg->dn);
1393 return LDB_ERR_OPERATIONS_ERROR;
1396 dn = ldb_dn_get_linearized(msg->dn);
1399 return LDB_ERR_OPERATIONS_ERROR;
1402 val.data = (uint8_t *)((uintptr_t)ldb_dn_get_casefold(pdn));
1403 if (val.data == NULL) {
1405 return LDB_ERR_OPERATIONS_ERROR;
1408 val.length = strlen((char *)val.data);
1409 el.name = LTDB_IDXONE;
1414 ret = ltdb_index_add1(module, ltdb, dn, &el, 0);
1415 } else { /* delete */
1416 ret = ltdb_index_del_value(module, ltdb, msg->dn, &el, 0);
1425 add the index entries for a new element in a record
1426 The caller guarantees that these element values are not yet indexed
1428 int ltdb_index_add_element(struct ldb_module *module,
1429 struct ltdb_private *ltdb,
1431 struct ldb_message_element *el)
1433 if (ldb_dn_is_special(dn)) {
1436 if (!ltdb_is_indexed(module, ltdb, el->name)) {
1439 return ltdb_index_add_el(module, ltdb,
1440 ldb_dn_get_linearized(dn), el);
1444 add the index entries for a new record
1446 int ltdb_index_add_new(struct ldb_module *module,
1447 struct ltdb_private *ltdb,
1448 const struct ldb_message *msg)
1453 if (ldb_dn_is_special(msg->dn)) {
1457 dn = ldb_dn_get_linearized(msg->dn);
1459 return LDB_ERR_OPERATIONS_ERROR;
1462 ret = ltdb_index_add_all(module, ltdb, dn, msg->elements,
1464 if (ret != LDB_SUCCESS) {
1468 return ltdb_index_onelevel(module, msg, 1);
1473 delete an index entry for one message element
1475 int ltdb_index_del_value(struct ldb_module *module,
1476 struct ltdb_private *ltdb,
1478 struct ldb_message_element *el, unsigned int v_idx)
1480 struct ldb_context *ldb;
1481 struct ldb_dn *dn_key;
1485 struct dn_list *list;
1487 ldb = ldb_module_get_ctx(module);
1489 dn_str = ldb_dn_get_linearized(dn);
1490 if (dn_str == NULL) {
1491 return LDB_ERR_OPERATIONS_ERROR;
1494 if (dn_str[0] == '@') {
1498 dn_key = ltdb_index_key(ldb, el->name, &el->values[v_idx], NULL);
1500 return LDB_ERR_OPERATIONS_ERROR;
1503 list = talloc_zero(dn_key, struct dn_list);
1505 talloc_free(dn_key);
1506 return LDB_ERR_OPERATIONS_ERROR;
1509 ret = ltdb_dn_list_load(module, dn_key, list);
1510 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
1511 /* it wasn't indexed. Did we have an earlier error? If we did then
1513 talloc_free(dn_key);
1517 if (ret != LDB_SUCCESS) {
1518 talloc_free(dn_key);
1522 i = ltdb_dn_list_find_str(ltdb, list, dn_str);
1524 /* nothing to delete */
1525 talloc_free(dn_key);
1529 j = (unsigned int) i;
1530 if (j != list->count - 1) {
1531 memmove(&list->dn[j], &list->dn[j+1], sizeof(list->dn[0])*(list->count - (j+1)));
1534 if (list->count == 0) {
1535 talloc_free(list->dn);
1538 list->dn = talloc_realloc(list, list->dn, struct ldb_val, list->count);
1541 ret = ltdb_dn_list_store(module, dn_key, list);
1543 talloc_free(dn_key);
1549 delete the index entries for a element
1550 return -1 on failure
1552 int ltdb_index_del_element(struct ldb_module *module,
1553 struct ltdb_private *ltdb,
1555 struct ldb_message_element *el)
1561 if (!ltdb->cache->attribute_indexes) {
1562 /* no indexed fields */
1566 dn_str = ldb_dn_get_linearized(dn);
1567 if (dn_str == NULL) {
1568 return LDB_ERR_OPERATIONS_ERROR;
1571 if (dn_str[0] == '@') {
1575 if (!ltdb_is_indexed(module, ltdb, el->name)) {
1578 for (i = 0; i < el->num_values; i++) {
1579 ret = ltdb_index_del_value(module, ltdb, dn, el, i);
1580 if (ret != LDB_SUCCESS) {
1589 delete the index entries for a record
1590 return -1 on failure
1592 int ltdb_index_delete(struct ldb_module *module, const struct ldb_message *msg)
1594 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
1598 if (ldb_dn_is_special(msg->dn)) {
1602 ret = ltdb_index_onelevel(module, msg, 0);
1603 if (ret != LDB_SUCCESS) {
1607 if (!ltdb->cache->attribute_indexes) {
1608 /* no indexed fields */
1612 for (i = 0; i < msg->num_elements; i++) {
1613 ret = ltdb_index_del_element(module, ltdb,
1614 msg->dn, &msg->elements[i]);
1615 if (ret != LDB_SUCCESS) {
1625 traversal function that deletes all @INDEX records
1627 static int delete_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state)
1629 struct ldb_module *module = state;
1630 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
1631 const char *dnstr = "DN=" LTDB_INDEX ":";
1632 struct dn_list list;
1637 if (strncmp((char *)key.dptr, dnstr, strlen(dnstr)) != 0) {
1640 /* we need to put a empty list in the internal tdb for this
1645 /* the offset of 3 is to remove the DN= prefix. */
1646 v.data = key.dptr + 3;
1647 v.length = strnlen((char *)key.dptr, key.dsize) - 3;
1649 dn = ldb_dn_from_ldb_val(ltdb, ldb_module_get_ctx(module), &v);
1650 ret = ltdb_dn_list_store(module, dn, &list);
1651 if (ret != LDB_SUCCESS) {
1652 ldb_asprintf_errstring(ldb_module_get_ctx(module),
1653 "Unable to store null index for %s\n",
1654 ldb_dn_get_linearized(dn));
1662 struct ltdb_reindex_context {
1663 struct ldb_module *module;
1668 traversal function that adds @INDEX records during a re index
1670 static int re_key(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state)
1672 struct ldb_context *ldb;
1673 struct ltdb_reindex_context *ctx = (struct ltdb_reindex_context *)state;
1674 struct ldb_module *module = ctx->module;
1675 struct ldb_message *msg;
1676 unsigned int nb_elements_in_db;
1677 const struct ldb_val val = {
1679 .length = data.dsize,
1685 ldb = ldb_module_get_ctx(module);
1687 if (key.dsize > 4 &&
1688 memcmp(key.dptr, "DN=@", 4) == 0) {
1692 is_record = ltdb_key_is_record(key);
1693 if (is_record == false) {
1697 msg = ldb_msg_new(module);
1702 ret = ldb_unpack_data_only_attr_list_flags(ldb, &val,
1705 LDB_UNPACK_DATA_FLAG_NO_DATA_ALLOC,
1706 &nb_elements_in_db);
1708 ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid data for index %s\n",
1709 ldb_dn_get_linearized(msg->dn));
1715 if (msg->dn == NULL) {
1716 ldb_debug(ldb, LDB_DEBUG_ERROR,
1717 "Refusing to re-index as GUID "
1718 "key %*.*s with no DN\n",
1719 (int)key.dsize, (int)key.dsize,
1725 /* check if the DN key has changed, perhaps due to the case
1726 insensitivity of an element changing, or a change from DN
1728 key2 = ltdb_key_msg(module, msg);
1729 if (key2.dptr == NULL) {
1730 /* probably a corrupt record ... darn */
1731 ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid DN in re_index: %s",
1732 ldb_dn_get_linearized(msg->dn));
1736 if (key.dsize != key2.dsize ||
1737 (memcmp(key.dptr, key2.dptr, key.dsize) != 0)) {
1739 tdb_ret = tdb_delete(tdb, key);
1741 ldb_debug(ldb, LDB_DEBUG_ERROR,
1742 "Failed to delete %*.*s "
1743 "for rekey as %*.*s: %s",
1744 (int)key.dsize, (int)key.dsize,
1745 (const char *)key.dptr,
1746 (int)key2.dsize, (int)key2.dsize,
1747 (const char *)key.dptr,
1749 ctx->error = ltdb_err_map(tdb_error(tdb));
1752 tdb_ret = tdb_store(tdb, key2, data, 0);
1754 ldb_debug(ldb, LDB_DEBUG_ERROR,
1755 "Failed to rekey %*.*s as %*.*s: %s",
1756 (int)key.dsize, (int)key.dsize,
1757 (const char *)key.dptr,
1758 (int)key2.dsize, (int)key2.dsize,
1759 (const char *)key.dptr,
1761 ctx->error = ltdb_err_map(tdb_error(tdb));
1765 talloc_free(key2.dptr);
1773 traversal function that adds @INDEX records during a re index
1775 static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state)
1777 struct ldb_context *ldb;
1778 struct ltdb_reindex_context *ctx = (struct ltdb_reindex_context *)state;
1779 struct ldb_module *module = ctx->module;
1780 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module),
1781 struct ltdb_private);
1782 struct ldb_message *msg;
1783 const char *dn = NULL;
1784 unsigned int nb_elements_in_db;
1785 const struct ldb_val val = {
1787 .length = data.dsize,
1792 ldb = ldb_module_get_ctx(module);
1794 if (key.dsize > 4 &&
1795 memcmp(key.dptr, "DN=@", 4) == 0) {
1799 is_record = ltdb_key_is_record(key);
1800 if (is_record == false) {
1804 msg = ldb_msg_new(module);
1809 ret = ldb_unpack_data_only_attr_list_flags(ldb, &val,
1812 LDB_UNPACK_DATA_FLAG_NO_DATA_ALLOC,
1813 &nb_elements_in_db);
1815 ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid data for index %s\n",
1816 ldb_dn_get_linearized(msg->dn));
1822 if (msg->dn == NULL) {
1823 ldb_debug(ldb, LDB_DEBUG_ERROR,
1824 "Refusing to re-index as GUID "
1825 "key %*.*s with no DN\n",
1826 (int)key.dsize, (int)key.dsize,
1831 dn = ldb_dn_get_linearized(msg->dn);
1834 ret = ltdb_index_onelevel(module, msg, 1);
1835 if (ret != LDB_SUCCESS) {
1836 ldb_debug(ldb, LDB_DEBUG_ERROR,
1837 "Adding special ONE LEVEL index failed (%s)!",
1838 ldb_dn_get_linearized(msg->dn));
1843 ret = ltdb_index_add_all(module, ltdb, dn,
1844 msg->elements, msg->num_elements);
1846 if (ret != LDB_SUCCESS) {
1858 force a complete reindex of the database
1860 int ltdb_reindex(struct ldb_module *module)
1862 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
1864 struct ltdb_reindex_context ctx;
1867 * Only triggered after a modification, but make clear we do
1868 * not re-index a read-only DB
1870 if (ltdb->read_only) {
1871 return LDB_ERR_UNWILLING_TO_PERFORM;
1874 if (ltdb_cache_reload(module) != 0) {
1875 return LDB_ERR_OPERATIONS_ERROR;
1879 * Ensure we read (and so remove) the entries from the real
1880 * DB, no values stored so far are any use as we want to do a
1883 ltdb_index_transaction_cancel(module);
1885 ret = ltdb_index_transaction_start(module);
1886 if (ret != LDB_SUCCESS) {
1890 /* first traverse the database deleting any @INDEX records by
1891 * putting NULL entries in the in-memory tdb
1893 ret = tdb_traverse(ltdb->tdb, delete_index, module);
1895 struct ldb_context *ldb = ldb_module_get_ctx(module);
1896 ldb_asprintf_errstring(ldb, "index deletion traverse failed: %s",
1897 ldb_errstring(ldb));
1898 return LDB_ERR_OPERATIONS_ERROR;
1901 /* if we don't have indexes we have nothing todo */
1902 if (!ltdb->cache->attribute_indexes) {
1906 ctx.module = module;
1909 /* now traverse adding any indexes for normal LDB records */
1910 ret = tdb_traverse(ltdb->tdb, re_key, &ctx);
1912 struct ldb_context *ldb = ldb_module_get_ctx(module);
1913 ldb_asprintf_errstring(ldb, "key correction traverse failed: %s",
1914 ldb_errstring(ldb));
1915 return LDB_ERR_OPERATIONS_ERROR;
1918 if (ctx.error != LDB_SUCCESS) {
1919 struct ldb_context *ldb = ldb_module_get_ctx(module);
1920 ldb_asprintf_errstring(ldb, "reindexing failed: %s", ldb_errstring(ldb));
1926 /* now traverse adding any indexes for normal LDB records */
1927 ret = tdb_traverse(ltdb->tdb, re_index, &ctx);
1929 struct ldb_context *ldb = ldb_module_get_ctx(module);
1930 ldb_asprintf_errstring(ldb, "reindexing traverse failed: %s",
1931 ldb_errstring(ldb));
1932 return LDB_ERR_OPERATIONS_ERROR;
1935 if (ctx.error != LDB_SUCCESS) {
1936 struct ldb_context *ldb = ldb_module_get_ctx(module);
1937 ldb_asprintf_errstring(ldb, "reindexing failed: %s", ldb_errstring(ldb));