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));
64 /* compare two DN entries in a dn_list. Take account of possible
65 * differences in string termination */
66 static int dn_list_cmp(const struct ldb_val *v1, const struct ldb_val *v2)
68 if (v1->length > v2->length && v1->data[v2->length] != 0) {
71 if (v1->length < v2->length && v2->data[v1->length] != 0) {
74 return strncmp((char *)v1->data, (char *)v2->data, v1->length);
79 find a entry in a dn_list, using a ldb_val. Uses a case sensitive
80 comparison with the dn returns -1 if not found
82 static int ltdb_dn_list_find_val(const struct dn_list *list, const struct ldb_val *v)
85 for (i=0; i<list->count; i++) {
86 if (dn_list_cmp(&list->dn[i], v) == 0) return i;
92 find a entry in a dn_list. Uses a case sensitive comparison with the dn
93 returns -1 if not found
95 static int ltdb_dn_list_find_str(struct dn_list *list, const char *dn)
98 v.data = discard_const_p(unsigned char, dn);
99 v.length = strlen(dn);
100 return ltdb_dn_list_find_val(list, &v);
104 this is effectively a cast function, but with lots of paranoia
105 checks and also copes with CPUs that are fussy about pointer
108 static struct dn_list *ltdb_index_idxptr(struct ldb_module *module, TDB_DATA rec, bool check_parent)
110 struct dn_list *list;
111 if (rec.dsize != sizeof(void *)) {
112 ldb_asprintf_errstring(ldb_module_get_ctx(module),
113 "Bad data size for idxptr %u", (unsigned)rec.dsize);
116 /* note that we can't just use a cast here, as rec.dptr may
117 not be aligned sufficiently for a pointer. A cast would cause
118 platforms like some ARM CPUs to crash */
119 memcpy(&list, rec.dptr, sizeof(void *));
120 list = talloc_get_type(list, struct dn_list);
122 ldb_asprintf_errstring(ldb_module_get_ctx(module),
123 "Bad type '%s' for idxptr",
124 talloc_get_name(list));
127 if (check_parent && list->dn && talloc_parent(list->dn) != list) {
128 ldb_asprintf_errstring(ldb_module_get_ctx(module),
129 "Bad parent '%s' for idxptr",
130 talloc_get_name(talloc_parent(list->dn)));
137 return the @IDX list in an index entry for a dn as a
140 static int ltdb_dn_list_load(struct ldb_module *module,
141 struct ldb_dn *dn, struct dn_list *list)
143 struct ldb_message *msg;
145 struct ldb_message_element *el;
146 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
148 struct dn_list *list2;
154 /* see if we have any in-memory index entries */
155 if (ltdb->idxptr == NULL ||
156 ltdb->idxptr->itdb == NULL) {
160 key.dptr = discard_const_p(unsigned char, ldb_dn_get_linearized(dn));
161 key.dsize = strlen((char *)key.dptr);
163 rec = tdb_fetch(ltdb->idxptr->itdb, key);
164 if (rec.dptr == NULL) {
168 /* we've found an in-memory index entry */
169 list2 = ltdb_index_idxptr(module, rec, true);
172 return LDB_ERR_OPERATIONS_ERROR;
180 msg = ldb_msg_new(list);
182 return LDB_ERR_OPERATIONS_ERROR;
185 ret = ltdb_search_dn1(module, dn, msg,
186 LDB_UNPACK_DATA_FLAG_NO_DATA_ALLOC
187 |LDB_UNPACK_DATA_FLAG_NO_DN);
188 if (ret != LDB_SUCCESS) {
193 /* TODO: check indexing version number */
195 el = ldb_msg_find_element(msg, LTDB_IDX);
202 * we avoid copying the strings by stealing the list. We have
203 * to steal msg onto el->values (which looks odd) because we
204 * asked for the memory to be allocated on msg, not on each
205 * value with LDB_UNPACK_DATA_FLAG_NO_DATA_ALLOC above
207 talloc_steal(el->values, msg);
208 list->dn = talloc_steal(list, el->values);
209 list->count = el->num_values;
211 /* We don't need msg->elements any more */
212 talloc_free(msg->elements);
218 save a dn_list into a full @IDX style record
220 static int ltdb_dn_list_store_full(struct ldb_module *module, struct ldb_dn *dn,
221 struct dn_list *list)
223 struct ldb_message *msg;
226 if (list->count == 0) {
227 ret = ltdb_delete_noindex(module, dn);
228 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
234 msg = ldb_msg_new(module);
236 return ldb_module_oom(module);
239 ret = ldb_msg_add_fmt(msg, LTDB_IDXVERSION, "%u", LTDB_INDEXING_VERSION);
240 if (ret != LDB_SUCCESS) {
242 return ldb_module_oom(module);
246 if (list->count > 0) {
247 struct ldb_message_element *el;
249 ret = ldb_msg_add_empty(msg, LTDB_IDX, LDB_FLAG_MOD_ADD, &el);
250 if (ret != LDB_SUCCESS) {
252 return ldb_module_oom(module);
254 el->values = list->dn;
255 el->num_values = list->count;
258 ret = ltdb_store(module, msg, TDB_REPLACE);
264 save a dn_list into the database, in either @IDX or internal format
266 static int ltdb_dn_list_store(struct ldb_module *module, struct ldb_dn *dn,
267 struct dn_list *list)
269 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
272 struct dn_list *list2;
274 if (ltdb->idxptr == NULL) {
275 return ltdb_dn_list_store_full(module, dn, list);
278 if (ltdb->idxptr->itdb == NULL) {
279 ltdb->idxptr->itdb = tdb_open(NULL, 1000, TDB_INTERNAL, O_RDWR, 0);
280 if (ltdb->idxptr->itdb == NULL) {
281 return LDB_ERR_OPERATIONS_ERROR;
285 key.dptr = discard_const_p(unsigned char, ldb_dn_get_linearized(dn));
286 key.dsize = strlen((char *)key.dptr);
288 rec = tdb_fetch(ltdb->idxptr->itdb, key);
289 if (rec.dptr != NULL) {
290 list2 = ltdb_index_idxptr(module, rec, false);
293 return LDB_ERR_OPERATIONS_ERROR;
296 list2->dn = talloc_steal(list2, list->dn);
297 list2->count = list->count;
301 list2 = talloc(ltdb->idxptr, struct dn_list);
303 return LDB_ERR_OPERATIONS_ERROR;
305 list2->dn = talloc_steal(list2, list->dn);
306 list2->count = list->count;
308 rec.dptr = (uint8_t *)&list2;
309 rec.dsize = sizeof(void *);
311 ret = tdb_store(ltdb->idxptr->itdb, key, rec, TDB_INSERT);
313 return ltdb_err_map(tdb_error(ltdb->idxptr->itdb));
319 traverse function for storing the in-memory index entries on disk
321 static int ltdb_index_traverse_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state)
323 struct ldb_module *module = state;
324 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
326 struct ldb_context *ldb = ldb_module_get_ctx(module);
328 struct dn_list *list;
330 list = ltdb_index_idxptr(module, data, true);
332 ltdb->idxptr->error = LDB_ERR_OPERATIONS_ERROR;
337 v.length = strnlen((char *)key.dptr, key.dsize);
339 dn = ldb_dn_from_ldb_val(module, ldb, &v);
341 ldb_asprintf_errstring(ldb, "Failed to parse index key %*.*s as an LDB DN", (int)v.length, (int)v.length, (const char *)v.data);
342 ltdb->idxptr->error = LDB_ERR_OPERATIONS_ERROR;
346 ltdb->idxptr->error = ltdb_dn_list_store_full(module, dn, list);
348 if (ltdb->idxptr->error != 0) {
354 /* cleanup the idxptr mode when transaction commits */
355 int ltdb_index_transaction_commit(struct ldb_module *module)
357 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
360 struct ldb_context *ldb = ldb_module_get_ctx(module);
362 ldb_reset_err_string(ldb);
364 if (ltdb->idxptr->itdb) {
365 tdb_traverse(ltdb->idxptr->itdb, ltdb_index_traverse_store, module);
366 tdb_close(ltdb->idxptr->itdb);
369 ret = ltdb->idxptr->error;
370 if (ret != LDB_SUCCESS) {
371 if (!ldb_errstring(ldb)) {
372 ldb_set_errstring(ldb, ldb_strerror(ret));
374 ldb_asprintf_errstring(ldb, "Failed to store index records in transaction commit: %s", ldb_errstring(ldb));
377 talloc_free(ltdb->idxptr);
382 /* cleanup the idxptr mode when transaction cancels */
383 int ltdb_index_transaction_cancel(struct ldb_module *module)
385 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
386 if (ltdb->idxptr && ltdb->idxptr->itdb) {
387 tdb_close(ltdb->idxptr->itdb);
389 talloc_free(ltdb->idxptr);
396 return the dn key to be used for an index
397 the caller is responsible for freeing
399 static struct ldb_dn *ltdb_index_key(struct ldb_context *ldb,
400 const char *attr, const struct ldb_val *value,
401 const struct ldb_schema_attribute **ap)
405 const struct ldb_schema_attribute *a;
409 attr_folded = ldb_attr_casefold(ldb, attr);
414 a = ldb_schema_attribute_by_name(ldb, attr);
418 r = a->syntax->canonicalise_fn(ldb, ldb, value, &v);
419 if (r != LDB_SUCCESS) {
420 const char *errstr = ldb_errstring(ldb);
421 /* canonicalisation can be refused. For example,
422 a attribute that takes wildcards will refuse to canonicalise
423 if the value contains a wildcard */
424 ldb_asprintf_errstring(ldb, "Failed to create index key for attribute '%s':%s%s%s",
425 attr, ldb_strerror(r), (errstr?":":""), (errstr?errstr:""));
426 talloc_free(attr_folded);
429 if (ldb_should_b64_encode(ldb, &v)) {
430 char *vstr = ldb_base64_encode(ldb, (char *)v.data, v.length);
432 talloc_free(attr_folded);
435 ret = ldb_dn_new_fmt(ldb, ldb, "%s:%s::%s", LTDB_INDEX, attr_folded, vstr);
438 ret = ldb_dn_new_fmt(ldb, ldb, "%s:%s:%.*s", LTDB_INDEX, attr_folded, (int)v.length, (char *)v.data);
441 if (v.data != value->data) {
444 talloc_free(attr_folded);
450 see if a attribute value is in the list of indexed attributes
452 static bool ltdb_is_indexed(struct ldb_module *module,
453 struct ltdb_private *ltdb,
456 struct ldb_context *ldb = ldb_module_get_ctx(module);
458 struct ldb_message_element *el;
460 if (ldb->schema.index_handler_override) {
461 const struct ldb_schema_attribute *a
462 = ldb_schema_attribute_by_name(ldb, attr);
468 if (a->flags & LDB_ATTR_FLAG_INDEXED) {
475 if (!ltdb->cache->attribute_indexes) {
479 el = ldb_msg_find_element(ltdb->cache->indexlist, LTDB_IDXATTR);
484 /* TODO: this is too expensive! At least use a binary search */
485 for (i=0; i<el->num_values; i++) {
486 if (ldb_attr_cmp((char *)el->values[i].data, attr) == 0) {
494 in the following logic functions, the return value is treated as
497 LDB_SUCCESS: we found some matching index values
499 LDB_ERR_NO_SUCH_OBJECT: we know for sure that no object matches
501 LDB_ERR_OPERATIONS_ERROR: indexing could not answer the call,
502 we'll need a full search
506 return a list of dn's that might match a simple indexed search (an
507 equality search only)
509 static int ltdb_index_dn_simple(struct ldb_module *module,
510 struct ltdb_private *ltdb,
511 const struct ldb_parse_tree *tree,
512 struct dn_list *list)
514 struct ldb_context *ldb;
518 ldb = ldb_module_get_ctx(module);
523 /* if the attribute isn't in the list of indexed attributes then
524 this node needs a full search */
525 if (!ltdb_is_indexed(module, ltdb, tree->u.equality.attr)) {
526 return LDB_ERR_OPERATIONS_ERROR;
529 /* the attribute is indexed. Pull the list of DNs that match the
531 dn = ltdb_index_key(ldb, tree->u.equality.attr, &tree->u.equality.value, NULL);
532 if (!dn) return LDB_ERR_OPERATIONS_ERROR;
534 ret = ltdb_dn_list_load(module, dn, list);
540 static bool list_union(struct ldb_context *, struct dn_list *, const struct dn_list *);
543 return a list of dn's that might match a leaf indexed search
545 static int ltdb_index_dn_leaf(struct ldb_module *module,
546 struct ltdb_private *ltdb,
547 const struct ldb_parse_tree *tree,
548 struct dn_list *list)
550 if (ltdb->disallow_dn_filter &&
551 (ldb_attr_cmp(tree->u.equality.attr, "dn") == 0)) {
552 /* in AD mode we do not support "(dn=...)" search filters */
557 if (ldb_attr_dn(tree->u.equality.attr) == 0) {
558 list->dn = talloc_array(list, struct ldb_val, 1);
559 if (list->dn == NULL) {
560 ldb_module_oom(module);
561 return LDB_ERR_OPERATIONS_ERROR;
563 list->dn[0] = tree->u.equality.value;
567 return ltdb_index_dn_simple(module, ltdb, tree, list);
575 static bool list_intersect(struct ldb_context *ldb,
576 struct dn_list *list, const struct dn_list *list2)
578 struct dn_list *list3;
581 if (list->count == 0) {
585 if (list2->count == 0) {
592 /* the indexing code is allowed to return a longer list than
593 what really matches, as all results are filtered by the
594 full expression at the end - this shortcut avoids a lot of
595 work in some cases */
596 if (list->count < 2 && list2->count > 10) {
599 if (list2->count < 2 && list->count > 10) {
600 list->count = list2->count;
601 list->dn = list2->dn;
602 /* note that list2 may not be the parent of list2->dn,
603 as list2->dn may be owned by ltdb->idxptr. In that
604 case we expect this reparent call to fail, which is
606 talloc_reparent(list2, list, list2->dn);
610 list3 = talloc_zero(list, struct dn_list);
615 list3->dn = talloc_array(list3, struct ldb_val, list->count);
622 for (i=0;i<list->count;i++) {
623 if (ltdb_dn_list_find_val(list2, &list->dn[i]) != -1) {
624 list3->dn[list3->count] = list->dn[i];
629 list->dn = talloc_steal(list, list3->dn);
630 list->count = list3->count;
641 static bool list_union(struct ldb_context *ldb,
642 struct dn_list *list, const struct dn_list *list2)
646 if (list2->count == 0) {
651 if (list->count == 0) {
653 list->count = list2->count;
654 list->dn = list2->dn;
655 /* note that list2 may not be the parent of list2->dn,
656 as list2->dn may be owned by ltdb->idxptr. In that
657 case we expect this reparent call to fail, which is
659 talloc_reparent(list2, list, list2->dn);
663 dn3 = talloc_array(list, struct ldb_val, list->count + list2->count);
669 /* we allow for duplicates here, and get rid of them later */
670 memcpy(dn3, list->dn, sizeof(list->dn[0])*list->count);
671 memcpy(dn3+list->count, list2->dn, sizeof(list2->dn[0])*list2->count);
674 list->count += list2->count;
679 static int ltdb_index_dn(struct ldb_module *module,
680 struct ltdb_private *ltdb,
681 const struct ldb_parse_tree *tree,
682 struct dn_list *list);
686 process an OR list (a union)
688 static int ltdb_index_dn_or(struct ldb_module *module,
689 struct ltdb_private *ltdb,
690 const struct ldb_parse_tree *tree,
691 struct dn_list *list)
693 struct ldb_context *ldb;
696 ldb = ldb_module_get_ctx(module);
701 for (i=0; i<tree->u.list.num_elements; i++) {
702 struct dn_list *list2;
705 list2 = talloc_zero(list, struct dn_list);
707 return LDB_ERR_OPERATIONS_ERROR;
710 ret = ltdb_index_dn(module, ltdb,
711 tree->u.list.elements[i], list2);
713 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
719 if (ret != LDB_SUCCESS) {
725 if (!list_union(ldb, list, list2)) {
727 return LDB_ERR_OPERATIONS_ERROR;
731 if (list->count == 0) {
732 return LDB_ERR_NO_SUCH_OBJECT;
742 static int ltdb_index_dn_not(struct ldb_module *module,
743 struct ltdb_private *ltdb,
744 const struct ldb_parse_tree *tree,
745 struct dn_list *list)
747 /* the only way to do an indexed not would be if we could
748 negate the not via another not or if we knew the total
749 number of database elements so we could know that the
750 existing expression covered the whole database.
752 instead, we just give up, and rely on a full index scan
753 (unless an outer & manages to reduce the list)
755 return LDB_ERR_OPERATIONS_ERROR;
759 static bool ltdb_index_unique(struct ldb_context *ldb,
762 const struct ldb_schema_attribute *a;
763 a = ldb_schema_attribute_by_name(ldb, attr);
764 if (a->flags & LDB_ATTR_FLAG_UNIQUE_INDEX) {
771 process an AND expression (intersection)
773 static int ltdb_index_dn_and(struct ldb_module *module,
774 struct ltdb_private *ltdb,
775 const struct ldb_parse_tree *tree,
776 struct dn_list *list)
778 struct ldb_context *ldb;
782 ldb = ldb_module_get_ctx(module);
787 /* in the first pass we only look for unique simple
788 equality tests, in the hope of avoiding having to look
790 for (i=0; i<tree->u.list.num_elements; i++) {
791 const struct ldb_parse_tree *subtree = tree->u.list.elements[i];
794 if (subtree->operation != LDB_OP_EQUALITY ||
795 !ltdb_index_unique(ldb, subtree->u.equality.attr)) {
799 ret = ltdb_index_dn(module, ltdb, subtree, list);
800 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
802 return LDB_ERR_NO_SUCH_OBJECT;
804 if (ret == LDB_SUCCESS) {
805 /* a unique index match means we can
806 * stop. Note that we don't care if we return
807 * a few too many objects, due to later
813 /* now do a full intersection */
816 for (i=0; i<tree->u.list.num_elements; i++) {
817 const struct ldb_parse_tree *subtree = tree->u.list.elements[i];
818 struct dn_list *list2;
821 list2 = talloc_zero(list, struct dn_list);
823 return ldb_module_oom(module);
826 ret = ltdb_index_dn(module, ltdb, subtree, list2);
828 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
833 return LDB_ERR_NO_SUCH_OBJECT;
836 if (ret != LDB_SUCCESS) {
837 /* this didn't adding anything */
843 talloc_reparent(list2, list, list->dn);
844 list->dn = list2->dn;
845 list->count = list2->count;
847 } else if (!list_intersect(ldb, list, list2)) {
849 return LDB_ERR_OPERATIONS_ERROR;
852 if (list->count == 0) {
854 return LDB_ERR_NO_SUCH_OBJECT;
857 if (list->count < 2) {
858 /* it isn't worth loading the next part of the tree */
864 /* none of the attributes were indexed */
865 return LDB_ERR_OPERATIONS_ERROR;
872 return a list of matching objects using a one-level index
874 static int ltdb_index_dn_one(struct ldb_module *module,
875 struct ldb_dn *parent_dn,
876 struct dn_list *list)
878 struct ldb_context *ldb;
883 ldb = ldb_module_get_ctx(module);
885 /* work out the index key from the parent DN */
886 val.data = (uint8_t *)((uintptr_t)ldb_dn_get_casefold(parent_dn));
887 val.length = strlen((char *)val.data);
888 key = ltdb_index_key(ldb, LTDB_IDXONE, &val, NULL);
891 return LDB_ERR_OPERATIONS_ERROR;
894 ret = ltdb_dn_list_load(module, key, list);
896 if (ret != LDB_SUCCESS) {
900 if (list->count == 0) {
901 return LDB_ERR_NO_SUCH_OBJECT;
908 return a list of dn's that might match a indexed search or
909 an error. return LDB_ERR_NO_SUCH_OBJECT for no matches, or LDB_SUCCESS for matches
911 static int ltdb_index_dn(struct ldb_module *module,
912 struct ltdb_private *ltdb,
913 const struct ldb_parse_tree *tree,
914 struct dn_list *list)
916 int ret = LDB_ERR_OPERATIONS_ERROR;
918 switch (tree->operation) {
920 ret = ltdb_index_dn_and(module, ltdb, tree, list);
924 ret = ltdb_index_dn_or(module, ltdb, tree, list);
928 ret = ltdb_index_dn_not(module, ltdb, tree, list);
931 case LDB_OP_EQUALITY:
932 ret = ltdb_index_dn_leaf(module, ltdb, tree, list);
935 case LDB_OP_SUBSTRING:
940 case LDB_OP_EXTENDED:
941 /* we can't index with fancy bitops yet */
942 ret = LDB_ERR_OPERATIONS_ERROR;
950 filter a candidate dn_list from an indexed search into a set of results
951 extracting just the given attributes
953 static int ltdb_index_filter(const struct dn_list *dn_list,
954 struct ltdb_context *ac,
955 uint32_t *match_count)
957 struct ldb_context *ldb;
958 struct ldb_message *msg;
959 struct ldb_message *filtered_msg;
962 ldb = ldb_module_get_ctx(ac->module);
964 for (i = 0; i < dn_list->count; i++) {
969 msg = ldb_msg_new(ac);
971 return LDB_ERR_OPERATIONS_ERROR;
974 dn = ldb_dn_from_ldb_val(msg, ldb, &dn_list->dn[i]);
977 return LDB_ERR_OPERATIONS_ERROR;
980 ret = ltdb_search_dn1(ac->module, dn, msg,
981 LDB_UNPACK_DATA_FLAG_NO_DATA_ALLOC|
982 LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC);
984 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
985 /* the record has disappeared? yes, this can happen */
990 if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_OBJECT) {
991 /* an internal error */
993 return LDB_ERR_OPERATIONS_ERROR;
996 ret = ldb_match_msg_error(ldb, msg,
997 ac->tree, ac->base, ac->scope, &matched);
998 if (ret != LDB_SUCCESS) {
1007 /* filter the attributes that the user wants */
1008 ret = ltdb_filter_attrs(ac, msg, ac->attrs, &filtered_msg);
1013 return LDB_ERR_OPERATIONS_ERROR;
1016 ret = ldb_module_send_entry(ac->req, filtered_msg, NULL);
1017 if (ret != LDB_SUCCESS) {
1018 /* Regardless of success or failure, the msg
1019 * is the callbacks responsiblity, and should
1020 * not be talloc_free()'ed */
1021 ac->request_terminated = true;
1032 remove any duplicated entries in a indexed result
1034 static void ltdb_dn_list_remove_duplicates(struct dn_list *list)
1036 unsigned int i, new_count;
1038 if (list->count < 2) {
1042 TYPESAFE_QSORT(list->dn, list->count, dn_list_cmp);
1045 for (i=1; i<list->count; i++) {
1046 if (dn_list_cmp(&list->dn[i], &list->dn[new_count-1]) != 0) {
1047 if (new_count != i) {
1048 list->dn[new_count] = list->dn[i];
1054 list->count = new_count;
1058 search the database with a LDAP-like expression using indexes
1059 returns -1 if an indexed search is not possible, in which
1060 case the caller should call ltdb_search_full()
1062 int ltdb_search_indexed(struct ltdb_context *ac, uint32_t *match_count)
1064 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(ac->module), struct ltdb_private);
1065 struct dn_list *dn_list;
1068 /* see if indexing is enabled */
1069 if (!ltdb->cache->attribute_indexes &&
1070 !ltdb->cache->one_level_indexes &&
1071 ac->scope != LDB_SCOPE_BASE) {
1072 /* fallback to a full search */
1073 return LDB_ERR_OPERATIONS_ERROR;
1076 dn_list = talloc_zero(ac, struct dn_list);
1077 if (dn_list == NULL) {
1078 return ldb_module_oom(ac->module);
1081 switch (ac->scope) {
1082 case LDB_SCOPE_BASE:
1083 dn_list->dn = talloc_array(dn_list, struct ldb_val, 1);
1084 if (dn_list->dn == NULL) {
1085 talloc_free(dn_list);
1086 return ldb_module_oom(ac->module);
1088 dn_list->dn[0].data = discard_const_p(unsigned char, ldb_dn_get_linearized(ac->base));
1089 if (dn_list->dn[0].data == NULL) {
1090 talloc_free(dn_list);
1091 return ldb_module_oom(ac->module);
1093 dn_list->dn[0].length = strlen((char *)dn_list->dn[0].data);
1097 case LDB_SCOPE_ONELEVEL:
1098 if (!ltdb->cache->one_level_indexes) {
1099 talloc_free(dn_list);
1100 return LDB_ERR_OPERATIONS_ERROR;
1102 ret = ltdb_index_dn_one(ac->module, ac->base, dn_list);
1103 if (ret != LDB_SUCCESS) {
1104 talloc_free(dn_list);
1109 case LDB_SCOPE_SUBTREE:
1110 case LDB_SCOPE_DEFAULT:
1111 if (!ltdb->cache->attribute_indexes) {
1112 talloc_free(dn_list);
1113 return LDB_ERR_OPERATIONS_ERROR;
1115 ret = ltdb_index_dn(ac->module, ltdb, ac->tree, dn_list);
1116 if (ret != LDB_SUCCESS) {
1117 talloc_free(dn_list);
1120 ltdb_dn_list_remove_duplicates(dn_list);
1124 ret = ltdb_index_filter(dn_list, ac, match_count);
1125 talloc_free(dn_list);
1130 * @brief Add a DN in the index list of a given attribute name/value pair
1132 * This function will add the DN in the index list for the index for
1133 * the given attribute name and value.
1135 * @param[in] module A ldb_module structure
1137 * @param[in] dn The string representation of the DN as it
1138 * will be stored in the index entry
1140 * @param[in] el A ldb_message_element array, one of the entry
1141 * referred by the v_idx is the attribute name and
1142 * value pair which will be used to construct the
1145 * @param[in] v_idx The index of element in the el array to use
1147 * @return An ldb error code
1149 static int ltdb_index_add1(struct ldb_module *module, const char *dn,
1150 struct ldb_message_element *el, int v_idx,
1153 struct ldb_context *ldb;
1154 struct ldb_dn *dn_key;
1156 const struct ldb_schema_attribute *a;
1157 struct dn_list *list;
1160 ldb = ldb_module_get_ctx(module);
1162 list = talloc_zero(module, struct dn_list);
1164 return LDB_ERR_OPERATIONS_ERROR;
1167 dn_key = ltdb_index_key(ldb, el->name, &el->values[v_idx], &a);
1170 return LDB_ERR_OPERATIONS_ERROR;
1172 talloc_steal(list, dn_key);
1174 ret = ltdb_dn_list_load(module, dn_key, list);
1175 if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_OBJECT) {
1180 if (list->count > 0 &&
1181 a->flags & LDB_ATTR_FLAG_UNIQUE_INDEX) {
1183 * We do not want to print info about a possibly
1184 * confidential DN that the conflict was with in the
1185 * user-visible error string
1187 ldb_debug(ldb, LDB_DEBUG_WARNING,
1188 __location__ ": unique index violation on %s in %s, "
1189 "conficts with %*.*s in %s",
1191 (int)list->dn[0].length,
1192 (int)list->dn[0].length,
1194 ldb_dn_get_linearized(dn_key));
1195 ldb_asprintf_errstring(ldb, __location__ ": unique index violation on %s in %s",
1198 return LDB_ERR_ENTRY_ALREADY_EXISTS;
1201 /* If we are doing an ADD, then this can not already be in the index,
1202 as it was not already in the database, and this has already been
1203 checked because the store succeeded */
1205 if (ltdb_dn_list_find_str(list, dn) != -1) {
1211 /* overallocate the list a bit, to reduce the number of
1212 * realloc trigered copies */
1213 alloc_len = ((list->count+1)+7) & ~7;
1214 list->dn = talloc_realloc(list, list->dn, struct ldb_val, alloc_len);
1215 if (list->dn == NULL) {
1217 return LDB_ERR_OPERATIONS_ERROR;
1219 list->dn[list->count].data = (uint8_t *)talloc_strdup(list->dn, dn);
1220 list->dn[list->count].length = strlen(dn);
1223 ret = ltdb_dn_list_store(module, dn_key, list);
1231 add index entries for one elements in a message
1233 static int ltdb_index_add_el(struct ldb_module *module, const char *dn,
1234 struct ldb_message_element *el, bool is_new)
1237 for (i = 0; i < el->num_values; i++) {
1238 int ret = ltdb_index_add1(module, dn, el, i, is_new);
1239 if (ret != LDB_SUCCESS) {
1248 add index entries for all elements in a message
1250 static int ltdb_index_add_all(struct ldb_module *module, const char *dn,
1251 struct ldb_message_element *elements,
1252 unsigned int num_el,
1255 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
1262 if (!ltdb->cache->attribute_indexes) {
1263 /* no indexed fields */
1267 for (i = 0; i < num_el; i++) {
1269 if (!ltdb_is_indexed(module, ltdb, elements[i].name)) {
1272 ret = ltdb_index_add_el(module, dn, &elements[i], is_new);
1273 if (ret != LDB_SUCCESS) {
1274 struct ldb_context *ldb = ldb_module_get_ctx(module);
1275 ldb_asprintf_errstring(ldb,
1276 __location__ ": Failed to re-index %s in %s - %s",
1277 elements[i].name, dn, ldb_errstring(ldb));
1287 insert a one level index for a message
1289 static int ltdb_index_onelevel(struct ldb_module *module, const struct ldb_message *msg, int add)
1291 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
1292 struct ldb_message_element el;
1298 /* We index for ONE Level only if requested */
1299 if (!ltdb->cache->one_level_indexes) {
1303 pdn = ldb_dn_get_parent(module, msg->dn);
1305 return LDB_ERR_OPERATIONS_ERROR;
1308 dn = ldb_dn_get_linearized(msg->dn);
1311 return LDB_ERR_OPERATIONS_ERROR;
1314 val.data = (uint8_t *)((uintptr_t)ldb_dn_get_casefold(pdn));
1315 if (val.data == NULL) {
1317 return LDB_ERR_OPERATIONS_ERROR;
1320 val.length = strlen((char *)val.data);
1321 el.name = LTDB_IDXONE;
1326 ret = ltdb_index_add1(module, dn, &el, 0, add);
1327 } else { /* delete */
1328 ret = ltdb_index_del_value(module, msg->dn, &el, 0);
1337 add the index entries for a new element in a record
1338 The caller guarantees that these element values are not yet indexed
1340 int ltdb_index_add_element(struct ldb_module *module, struct ldb_dn *dn,
1341 struct ldb_message_element *el)
1343 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
1344 if (ldb_dn_is_special(dn)) {
1347 if (!ltdb_is_indexed(module, ltdb, el->name)) {
1350 return ltdb_index_add_el(module, ldb_dn_get_linearized(dn), el, true);
1354 add the index entries for a new record
1356 int ltdb_index_add_new(struct ldb_module *module, const struct ldb_message *msg)
1361 if (ldb_dn_is_special(msg->dn)) {
1365 dn = ldb_dn_get_linearized(msg->dn);
1367 return LDB_ERR_OPERATIONS_ERROR;
1370 ret = ltdb_index_add_all(module, dn, msg->elements, msg->num_elements,
1372 if (ret != LDB_SUCCESS) {
1376 return ltdb_index_onelevel(module, msg, 1);
1381 delete an index entry for one message element
1383 int ltdb_index_del_value(struct ldb_module *module, struct ldb_dn *dn,
1384 struct ldb_message_element *el, unsigned int v_idx)
1386 struct ldb_context *ldb;
1387 struct ldb_dn *dn_key;
1391 struct dn_list *list;
1393 ldb = ldb_module_get_ctx(module);
1395 dn_str = ldb_dn_get_linearized(dn);
1396 if (dn_str == NULL) {
1397 return LDB_ERR_OPERATIONS_ERROR;
1400 if (dn_str[0] == '@') {
1404 dn_key = ltdb_index_key(ldb, el->name, &el->values[v_idx], NULL);
1406 return LDB_ERR_OPERATIONS_ERROR;
1409 list = talloc_zero(dn_key, struct dn_list);
1411 talloc_free(dn_key);
1412 return LDB_ERR_OPERATIONS_ERROR;
1415 ret = ltdb_dn_list_load(module, dn_key, list);
1416 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
1417 /* it wasn't indexed. Did we have an earlier error? If we did then
1419 talloc_free(dn_key);
1423 if (ret != LDB_SUCCESS) {
1424 talloc_free(dn_key);
1428 i = ltdb_dn_list_find_str(list, dn_str);
1430 /* nothing to delete */
1431 talloc_free(dn_key);
1435 j = (unsigned int) i;
1436 if (j != list->count - 1) {
1437 memmove(&list->dn[j], &list->dn[j+1], sizeof(list->dn[0])*(list->count - (j+1)));
1440 if (list->count == 0) {
1441 talloc_free(list->dn);
1444 list->dn = talloc_realloc(list, list->dn, struct ldb_val, list->count);
1447 ret = ltdb_dn_list_store(module, dn_key, list);
1449 talloc_free(dn_key);
1455 delete the index entries for a element
1456 return -1 on failure
1458 int ltdb_index_del_element(struct ldb_module *module, struct ldb_dn *dn,
1459 struct ldb_message_element *el)
1461 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
1466 if (!ltdb->cache->attribute_indexes) {
1467 /* no indexed fields */
1471 dn_str = ldb_dn_get_linearized(dn);
1472 if (dn_str == NULL) {
1473 return LDB_ERR_OPERATIONS_ERROR;
1476 if (dn_str[0] == '@') {
1480 if (!ltdb_is_indexed(module, ltdb, el->name)) {
1483 for (i = 0; i < el->num_values; i++) {
1484 ret = ltdb_index_del_value(module, dn, el, i);
1485 if (ret != LDB_SUCCESS) {
1494 delete the index entries for a record
1495 return -1 on failure
1497 int ltdb_index_delete(struct ldb_module *module, const struct ldb_message *msg)
1499 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
1503 if (ldb_dn_is_special(msg->dn)) {
1507 ret = ltdb_index_onelevel(module, msg, 0);
1508 if (ret != LDB_SUCCESS) {
1512 if (!ltdb->cache->attribute_indexes) {
1513 /* no indexed fields */
1517 for (i = 0; i < msg->num_elements; i++) {
1518 ret = ltdb_index_del_element(module, msg->dn, &msg->elements[i]);
1519 if (ret != LDB_SUCCESS) {
1529 traversal function that deletes all @INDEX records
1531 static int delete_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state)
1533 struct ldb_module *module = state;
1534 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
1535 const char *dnstr = "DN=" LTDB_INDEX ":";
1536 struct dn_list list;
1541 if (strncmp((char *)key.dptr, dnstr, strlen(dnstr)) != 0) {
1544 /* we need to put a empty list in the internal tdb for this
1549 /* the offset of 3 is to remove the DN= prefix. */
1550 v.data = key.dptr + 3;
1551 v.length = strnlen((char *)key.dptr, key.dsize) - 3;
1553 dn = ldb_dn_from_ldb_val(ltdb, ldb_module_get_ctx(module), &v);
1554 ret = ltdb_dn_list_store(module, dn, &list);
1555 if (ret != LDB_SUCCESS) {
1556 ldb_asprintf_errstring(ldb_module_get_ctx(module),
1557 "Unable to store null index for %s\n",
1558 ldb_dn_get_linearized(dn));
1566 struct ltdb_reindex_context {
1567 struct ldb_module *module;
1572 traversal function that adds @INDEX records during a re index
1574 static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state)
1576 struct ldb_context *ldb;
1577 struct ltdb_reindex_context *ctx = (struct ltdb_reindex_context *)state;
1578 struct ldb_module *module = ctx->module;
1579 struct ldb_message *msg;
1580 unsigned int nb_elements_in_db;
1581 const struct ldb_val val = {
1583 .length = data.dsize,
1585 const char *dn = NULL;
1589 ldb = ldb_module_get_ctx(module);
1591 if (strncmp((char *)key.dptr, "DN=@", 4) == 0 ||
1592 strncmp((char *)key.dptr, "DN=", 3) != 0) {
1596 msg = ldb_msg_new(module);
1601 ret = ldb_unpack_data_only_attr_list_flags(ldb, &val,
1604 LDB_UNPACK_DATA_FLAG_NO_DATA_ALLOC,
1605 &nb_elements_in_db);
1607 ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid data for index %s\n",
1608 ldb_dn_get_linearized(msg->dn));
1613 /* check if the DN key has changed, perhaps due to the
1614 case insensitivity of an element changing */
1615 key2 = ltdb_key(module, msg->dn);
1616 if (key2.dptr == NULL) {
1617 /* probably a corrupt record ... darn */
1618 ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid DN in re_index: %s",
1619 ldb_dn_get_linearized(msg->dn));
1623 if (strcmp((char *)key2.dptr, (char *)key.dptr) != 0) {
1624 tdb_delete(tdb, key);
1625 tdb_store(tdb, key2, data, 0);
1627 talloc_free(key2.dptr);
1629 if (msg->dn == NULL) {
1630 dn = (char *)key.dptr + 3;
1632 dn = ldb_dn_get_linearized(msg->dn);
1635 ret = ltdb_index_onelevel(module, msg, 1);
1636 if (ret != LDB_SUCCESS) {
1637 ldb_debug(ldb, LDB_DEBUG_ERROR,
1638 "Adding special ONE LEVEL index failed (%s)!",
1639 ldb_dn_get_linearized(msg->dn));
1644 ret = ltdb_index_add_all(module, dn, msg->elements, msg->num_elements,
1647 if (ret != LDB_SUCCESS) {
1659 force a complete reindex of the database
1661 int ltdb_reindex(struct ldb_module *module)
1663 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
1665 struct ltdb_reindex_context ctx;
1667 if (ltdb_cache_reload(module) != 0) {
1668 return LDB_ERR_OPERATIONS_ERROR;
1672 * Ensure we read (and so remove) the entries from the real
1673 * DB, no values stored so far are any use as we want to do a
1676 ltdb_index_transaction_cancel(module);
1678 ret = ltdb_index_transaction_start(module);
1679 if (ret != LDB_SUCCESS) {
1683 /* first traverse the database deleting any @INDEX records by
1684 * putting NULL entries in the in-memory tdb
1686 ret = tdb_traverse(ltdb->tdb, delete_index, module);
1688 return LDB_ERR_OPERATIONS_ERROR;
1691 /* if we don't have indexes we have nothing todo */
1692 if (!ltdb->cache->attribute_indexes) {
1696 ctx.module = module;
1699 /* now traverse adding any indexes for normal LDB records */
1700 ret = tdb_traverse(ltdb->tdb, re_index, &ctx);
1702 struct ldb_context *ldb = ldb_module_get_ctx(module);
1703 ldb_asprintf_errstring(ldb, "reindexing traverse failed: %s", ldb_errstring(ldb));
1704 return LDB_ERR_OPERATIONS_ERROR;
1707 if (ctx.error != LDB_SUCCESS) {
1708 struct ldb_context *ldb = ldb_module_get_ctx(module);
1709 ldb_asprintf_errstring(ldb, "reindexing failed: %s", ldb_errstring(ldb));