[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Sat Mar 3 08:59:02 UTC 2018


The branch, master has been updated
       via  4c0c888 ldb_tdb: Add tests for truncated index keys
       via  9a4fd23 ldb_tdb: Combine identical not GUID index and special DN cases
       via  ee74d4b ldb_tdb: Refuse to store a value in a unique index that is too long
       via  1d86a08 ldb_tdb: Do not give the warning of duplicate attributes in truncation
       via  0918068 ldb_tdb: Cope with key truncation
       via  5c1504b ldb_tdb: Do not fail in GUID index mode if there is a duplicate attribute
       via  0bfbcdb ldb_tdb: Add support for an option to restrict the key length
      from  ffb836f selftest: Impove test names for samba.wbinfo_simple

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 4c0c888b571d4c21ab267024178353925a8c087c
Author: Gary Lockyer <gary at catalyst.net.nz>
Date:   Wed Feb 21 15:12:40 2018 +1300

    ldb_tdb: Add tests for truncated index keys
    
    Tests for the index truncation code as well as the GUID index
    format in general.
    
    Covers truncation of both the DN and equality search keys.
    
    Signed-off-by: Gary Lockyer <gary at catalyst.net.nz>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    
    Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
    Autobuild-Date(master): Sat Mar  3 09:58:40 CET 2018 on sn-devel-144

commit 9a4fd23407da70a7b279a24fca8a6f037e66a477
Author: Gary Lockyer <gary at catalyst.net.nz>
Date:   Tue Feb 27 10:01:38 2018 +1300

    ldb_tdb: Combine identical not GUID index and special DN cases
    
    Fold together two identical cases to simplify the code.
    
    Signed-off-by: Gary Lockyer <gary at catalyst.net.nz>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit ee74d4bb8052bf22dcc3b30abb2493ac9a3237a4
Author: Gary Lockyer <gary at catalyst.net.nz>
Date:   Wed Feb 21 15:19:37 2018 +1300

    ldb_tdb: Refuse to store a value in a unique index that is too long
    
    Rather than add many special cases, over-long unique values are simply banned.
    
    Signed-off-by: Gary Lockyer <gary at catalyst.net.nz>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 1d86a0895aab42323e3455b33eb849198b0f7b49
Author: Gary Lockyer <gary at catalyst.net.nz>
Date:   Wed Feb 28 11:47:58 2018 +1300

    ldb_tdb: Do not give the warning of duplicate attributes in truncation
    
    In the truncation case a duplicate is perfectly expected.
    
    Signed-off-by: Gary Lockyer <gary at catalyst.net.nz>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 0918068997d7d8fdfe0c2e0cb1a9836479839fb6
Author: Gary Lockyer <gary at catalyst.net.nz>
Date:   Wed Feb 21 15:18:11 2018 +1300

    ldb_tdb: Cope with key truncation
    
    Modify the indexing code to handle a maximum key length, index keys
    greater than the maximum length will be truncated to the maximum length.
    And the unuque index code has been altered to handle multiple records
    for the same index key.
    
    Signed-off-by: Gary Lockyer <gary at catalyst.net.nz>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 5c1504b94d1417894176811f18c5d450de22cfd2
Author: Gary Lockyer <gary at catalyst.net.nz>
Date:   Wed Feb 28 11:47:22 2018 +1300

    ldb_tdb: Do not fail in GUID index mode if there is a duplicate attribute
    
    It is not the job of the index code to enforce this, but do give a
    a warning given it has been detected.
    
    However, now that we do allow it, we must never return the same
    object twice to the caller, so filter for it in ltdb_index_filter().
    
    The GUID list is sorted, which makes this cheap to handle, thankfully.
    
    Signed-off-by: Gary Lockyer <gary at catalyst.net.nz>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 0bfbcdb69155315415867cee34d5293b1ee125fa
Author: Gary Lockyer <gary at catalyst.net.nz>
Date:   Wed Feb 21 15:20:17 2018 +1300

    ldb_tdb: Add support for an option to restrict the key length
    
    Allow the setting of the maximum key length, this allows the testing of
    index key truncation code.  Index key truncation is required to allow
    the samba indexing scheme to be used with backends that enforce a
    maximum key length.
    
    This will allow emulation of a length-limited key DB for testing.
    
    This is a testing-only feature, as the index format changes
    based on this value.
    
    Signed-off-by: Gary Lockyer <gary at catalyst.net.nz>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 lib/ldb/ldb_tdb/ldb_index.c   |  412 ++++++++++++--
 lib/ldb/ldb_tdb/ldb_search.c  |   14 +-
 lib/ldb/ldb_tdb/ldb_tdb.c     |   13 +
 lib/ldb/ldb_tdb/ldb_tdb.h     |    7 +
 lib/ldb/tests/python/index.py | 1222 +++++++++++++++++++++++++++++++++++++++++
 lib/ldb/wscript               |    2 +-
 6 files changed, 1610 insertions(+), 60 deletions(-)
 create mode 100755 lib/ldb/tests/python/index.py


Changeset truncated at 500 lines:

diff --git a/lib/ldb/ldb_tdb/ldb_index.c b/lib/ldb/ldb_tdb/ldb_index.c
index 99fef23..17cb267 100644
--- a/lib/ldb/ldb_tdb/ldb_index.c
+++ b/lib/ldb/ldb_tdb/ldb_index.c
@@ -165,13 +165,19 @@ struct ltdb_idxptr {
 	int error;
 };
 
+enum key_truncation {
+	KEY_NOT_TRUNCATED,
+	KEY_TRUNCATED,
+};
+
 static int ltdb_write_index_dn_guid(struct ldb_module *module,
 				    const struct ldb_message *msg,
 				    int add);
 static int ltdb_index_dn_base_dn(struct ldb_module *module,
 				 struct ltdb_private *ltdb,
 				 struct ldb_dn *base_dn,
-				 struct dn_list *dn_list);
+				 struct dn_list *dn_list,
+				 enum key_truncation *truncation);
 
 static void ltdb_dn_list_sort(struct ltdb_private *ltdb,
 			      struct dn_list *list);
@@ -183,6 +189,13 @@ static void ltdb_dn_list_sort(struct ltdb_private *ltdb,
 
 #define LTDB_GUID_INDEXING_VERSION 3
 
+static unsigned ltdb_max_key_length(struct ltdb_private *ltdb) {
+	if (ltdb->max_key_length == 0){
+		return UINT_MAX;
+	}
+	return ltdb->max_key_length;
+}
+
 /* enable the idxptr mode when transactions start */
 int ltdb_index_transaction_start(struct ldb_module *module)
 {
@@ -423,7 +436,7 @@ normal_index:
 			return LDB_ERR_OPERATIONS_ERROR;
 		}
 
-		if (el->num_values != 1) {
+		if (el->num_values == 0) {
 			return LDB_ERR_OPERATIONS_ERROR;
 		}
 
@@ -459,13 +472,16 @@ int ltdb_key_dn_from_idx(struct ldb_module *module,
 {
 	struct ldb_context *ldb = ldb_module_get_ctx(module);
 	int ret;
+	int index = 0;
+	enum key_truncation truncation = KEY_NOT_TRUNCATED;
 	struct dn_list *list = talloc(mem_ctx, struct dn_list);
 	if (list == NULL) {
 		ldb_oom(ldb);
 		return LDB_ERR_OPERATIONS_ERROR;
 	}
 
-	ret = ltdb_index_dn_base_dn(module, ltdb, dn, list);
+
+	ret = ltdb_index_dn_base_dn(module, ltdb, dn, list, &truncation);
 	if (ret != LDB_SUCCESS) {
 		TALLOC_FREE(list);
 		return ret;
@@ -475,7 +491,8 @@ int ltdb_key_dn_from_idx(struct ldb_module *module,
 		TALLOC_FREE(list);
 		return LDB_ERR_NO_SUCH_OBJECT;
 	}
-	if (list->count > 1) {
+
+	if (list->count > 1 && truncation == KEY_NOT_TRUNCATED)  {
 		const char *dn_str = ldb_dn_get_linearized(dn);
 		ldb_asprintf_errstring(ldb_module_get_ctx(module),
 				       __location__
@@ -488,9 +505,81 @@ int ltdb_key_dn_from_idx(struct ldb_module *module,
 		return LDB_ERR_CONSTRAINT_VIOLATION;
 	}
 
+	if (list->count > 0 && truncation == KEY_TRUNCATED)  {
+		/*
+		 * DN key has been truncated, need to inspect the actual
+		 * records to locate the actual DN
+		 */
+		int i;
+		index = -1;
+		for (i=0; i < list->count; i++) {
+			uint8_t guid_key[LTDB_GUID_KEY_SIZE];
+			TDB_DATA key = {
+				.dptr = guid_key,
+				.dsize = sizeof(guid_key)
+			};
+			const int flags = LDB_UNPACK_DATA_FLAG_NO_ATTRS;
+			struct ldb_message *rec = ldb_msg_new(ldb);
+			if (rec == NULL) {
+				return LDB_ERR_OPERATIONS_ERROR;
+			}
+
+			ret = ltdb_idx_to_key(module, ltdb,
+					      ldb, &list->dn[i],
+					      &key);
+			if (ret != LDB_SUCCESS) {
+				TALLOC_FREE(list);
+				TALLOC_FREE(rec);
+				return ret;
+			}
+
+			ret = ltdb_search_key(module, ltdb, key,
+					      rec, flags);
+			if (key.dptr != guid_key) {
+				TALLOC_FREE(key.dptr);
+			}
+			if (ret == LDB_ERR_NO_SUCH_OBJECT) {
+				/*
+				 * the record has disappeared?
+				 * yes, this can happen
+				 */
+				TALLOC_FREE(rec);
+				continue;
+			}
+
+			if (ret != LDB_SUCCESS) {
+				/* an internal error */
+				TALLOC_FREE(rec);
+				TALLOC_FREE(list);
+				return LDB_ERR_OPERATIONS_ERROR;
+			}
+
+			/*
+			 * We found the actual DN that we wanted from in the
+			 * multiple values that matched the index
+			 * (due to truncation), so return that.
+			 *
+			 */
+			if (ldb_dn_compare(dn, rec->dn) == 0) {
+				index = i;
+				TALLOC_FREE(rec);
+				break;
+			}
+		}
+
+		/*
+		 * We matched the index but the actual DN we wanted
+		 * was not here.
+		 */
+		if (index == -1) {
+			TALLOC_FREE(list);
+			return LDB_ERR_NO_SUCH_OBJECT;
+		}
+	}
+
 	/* The tdb_key memory is allocated by the caller */
 	ret = ltdb_guid_to_key(module, ltdb,
-			       &list->dn[0], tdb_key);
+			       &list->dn[index], tdb_key);
 	TALLOC_FREE(list);
 
 	if (ret != LDB_SUCCESS) {
@@ -743,7 +832,8 @@ int ltdb_index_transaction_cancel(struct ldb_module *module)
 static struct ldb_dn *ltdb_index_key(struct ldb_context *ldb,
 				     struct ltdb_private *ltdb,
 				     const char *attr, const struct ldb_val *value,
-				     const struct ldb_schema_attribute **ap)
+				     const struct ldb_schema_attribute **ap,
+				     enum key_truncation *truncation)
 {
 	struct ldb_dn *ret;
 	struct ldb_val v;
@@ -752,6 +842,11 @@ static struct ldb_dn *ltdb_index_key(struct ldb_context *ldb,
 	const char *attr_for_dn = NULL;
 	int r;
 	bool should_b64_encode;
+	unsigned max_key_length = ltdb_max_key_length(ltdb);
+	unsigned key_len = 0;
+	unsigned attr_len = 0;
+	unsigned indx_len = 0;
+	unsigned frmt_len = 0;
 
 	if (attr[0] == '@') {
 		attr_for_dn = attr;
@@ -788,6 +883,8 @@ static struct ldb_dn *ltdb_index_key(struct ldb_context *ldb,
 			return NULL;
 		}
 	}
+	attr_len = strlen(attr_for_dn);
+	indx_len = strlen(LTDB_INDEX);
 
 	/*
 	 * We do not base 64 encode a DN in a key, it has already been
@@ -812,18 +909,59 @@ static struct ldb_dn *ltdb_index_key(struct ldb_context *ldb,
 	}
 
 	if (should_b64_encode) {
+		unsigned vstr_len = 0;
 		char *vstr = ldb_base64_encode(ldb, (char *)v.data, v.length);
 		if (!vstr) {
 			talloc_free(attr_folded);
 			return NULL;
 		}
-		ret = ldb_dn_new_fmt(ldb, ldb, "%s:%s::%s", LTDB_INDEX,
-				     attr_for_dn, vstr);
+		vstr_len = strlen(vstr);
+		key_len = 3 + indx_len + attr_len + vstr_len;
+		if (key_len > max_key_length) {
+			unsigned excess = key_len - max_key_length;
+			frmt_len = vstr_len - excess;
+			*truncation = KEY_TRUNCATED;
+			/*
+			* Truncated keys are placed in a separate key space
+			* from the non truncated keys
+			* Note: the double hash "##" is not a typo and
+			* indicates that the following value is base64 encoded
+			*/
+			ret = ldb_dn_new_fmt(ldb, ldb, "%s#%s##%.*s",
+					     LTDB_INDEX, attr_for_dn,
+					     frmt_len, vstr);
+		} else {
+			frmt_len = vstr_len;
+			*truncation = KEY_NOT_TRUNCATED;
+			/*
+			 * Note: the double colon "::" is not a typo and
+			 * indicates that the following value is base64 encoded
+			 */
+			ret = ldb_dn_new_fmt(ldb, ldb, "%s:%s::%.*s",
+					     LTDB_INDEX, attr_for_dn,
+					     frmt_len, vstr);
+		}
 		talloc_free(vstr);
 	} else {
-		ret = ldb_dn_new_fmt(ldb, ldb, "%s:%s:%.*s", LTDB_INDEX,
-				     attr_for_dn,
-				     (int)v.length, (char *)v.data);
+		key_len = 2 + indx_len + attr_len + (int)v.length;
+		if (key_len > max_key_length) {
+			unsigned excess = key_len - max_key_length;
+			frmt_len = v.length - excess;
+			*truncation = KEY_TRUNCATED;
+			/*
+			 * Truncated keys are placed in a separate key space
+			 * from the non truncated keys
+			 */
+			ret = ldb_dn_new_fmt(ldb, ldb, "%s#%s#%.*s",
+					     LTDB_INDEX, attr_for_dn,
+					     frmt_len, (char *)v.data);
+		} else {
+			frmt_len = v.length;
+			*truncation = KEY_NOT_TRUNCATED;
+			ret = ldb_dn_new_fmt(ldb, ldb, "%s:%s:%.*s",
+					     LTDB_INDEX, attr_for_dn,
+					     frmt_len, (char *)v.data);
+		}
 	}
 
 	if (v.data != value->data) {
@@ -908,6 +1046,7 @@ static int ltdb_index_dn_simple(struct ldb_module *module,
 	struct ldb_context *ldb;
 	struct ldb_dn *dn;
 	int ret;
+	enum key_truncation truncation = KEY_NOT_TRUNCATED;
 
 	ldb = ldb_module_get_ctx(module);
 
@@ -924,7 +1063,12 @@ static int ltdb_index_dn_simple(struct ldb_module *module,
 	   search criterion */
 	dn = ltdb_index_key(ldb, ltdb,
 			    tree->u.equality.attr,
-			    &tree->u.equality.value, NULL);
+			    &tree->u.equality.value, NULL, &truncation);
+	/*
+	 * We ignore truncation here and allow multi-valued matches
+	 * as ltdb_search_indexed will filter out the wrong one in
+	 * ltdb_index_filter() which calls ldb_match_message().
+	 */
 	if (!dn) return LDB_ERR_OPERATIONS_ERROR;
 
 	ret = ltdb_dn_list_load(module, ltdb, dn, list);
@@ -959,6 +1103,7 @@ static int ltdb_index_dn_leaf(struct ldb_module *module,
 		return LDB_SUCCESS;
 	}
 	if (ldb_attr_dn(tree->u.equality.attr) == 0) {
+		enum key_truncation truncation = KEY_NOT_TRUNCATED;
 		struct ldb_dn *dn
 			= ldb_dn_from_ldb_val(list,
 					      ldb_module_get_ctx(module),
@@ -977,7 +1122,13 @@ static int ltdb_index_dn_leaf(struct ldb_module *module,
 		 * We can't call TALLOC_FREE(dn) as this must belong
 		 * to list for the memory to remain valid.
 		 */
-		return ltdb_index_dn_base_dn(module, ltdb, dn, list);
+		return ltdb_index_dn_base_dn(module, ltdb, dn, list,
+					     &truncation);
+		/*
+		 * We ignore truncation here and allow multi-valued matches
+		 * as ltdb_search_indexed will filter out the wrong one in
+		 * ltdb_index_filter() which calls ldb_match_message().
+		 */
 
 	} else if ((ltdb->cache->GUID_index_attribute != NULL) &&
 		   (ldb_attr_cmp(tree->u.equality.attr,
@@ -1380,7 +1531,8 @@ static int ltdb_index_dn_attr(struct ldb_module *module,
 			      struct ltdb_private *ltdb,
 			      const char *attr,
 			      struct ldb_dn *dn,
-			      struct dn_list *list)
+			      struct dn_list *list,
+			      enum key_truncation *truncation)
 {
 	struct ldb_context *ldb;
 	struct ldb_dn *key;
@@ -1392,7 +1544,7 @@ static int ltdb_index_dn_attr(struct ldb_module *module,
 	/* work out the index key from the parent DN */
 	val.data = (uint8_t *)((uintptr_t)ldb_dn_get_casefold(dn));
 	val.length = strlen((char *)val.data);
-	key = ltdb_index_key(ldb, ltdb, attr, &val, NULL);
+	key = ltdb_index_key(ldb, ltdb, attr, &val, NULL, truncation);
 	if (!key) {
 		ldb_oom(ldb);
 		return LDB_ERR_OPERATIONS_ERROR;
@@ -1417,12 +1569,14 @@ static int ltdb_index_dn_attr(struct ldb_module *module,
 static int ltdb_index_dn_one(struct ldb_module *module,
 			     struct ltdb_private *ltdb,
 			     struct ldb_dn *parent_dn,
-			     struct dn_list *list)
+			     struct dn_list *list,
+			     enum key_truncation *truncation)
 {
 	/* Ensure we do not shortcut on intersection for this list */
 	list->strict = true;
 	return ltdb_index_dn_attr(module, ltdb,
-				  LTDB_IDXONE, parent_dn, list);
+				  LTDB_IDXONE, parent_dn, list, truncation);
+
 }
 
 /*
@@ -1431,7 +1585,8 @@ static int ltdb_index_dn_one(struct ldb_module *module,
 static int ltdb_index_dn_base_dn(struct ldb_module *module,
 				 struct ltdb_private *ltdb,
 				 struct ldb_dn *base_dn,
-				 struct dn_list *dn_list)
+				 struct dn_list *dn_list,
+				 enum key_truncation *truncation)
 {
 	const struct ldb_val *guid_val = NULL;
 	if (ltdb->cache->GUID_index_attribute == NULL) {
@@ -1468,7 +1623,7 @@ static int ltdb_index_dn_base_dn(struct ldb_module *module,
 	}
 
 	return ltdb_index_dn_attr(module, ltdb,
-				  LTDB_IDXDN, base_dn, dn_list);
+				  LTDB_IDXDN, base_dn, dn_list, truncation);
 }
 
 /*
@@ -1520,12 +1675,14 @@ static int ltdb_index_dn(struct ldb_module *module,
 static int ltdb_index_filter(struct ltdb_private *ltdb,
 			     const struct dn_list *dn_list,
 			     struct ltdb_context *ac,
-			     uint32_t *match_count)
+			     uint32_t *match_count,
+			     enum key_truncation scope_one_truncation)
 {
 	struct ldb_context *ldb;
 	struct ldb_message *msg;
 	struct ldb_message *filtered_msg;
 	unsigned int i;
+	uint8_t previous_guid_key[LTDB_GUID_KEY_SIZE] = {};
 
 	ldb = ldb_module_get_ctx(ac->module);
 
@@ -1538,11 +1695,6 @@ static int ltdb_index_filter(struct ltdb_private *ltdb,
 		int ret;
 		bool matched;
 
-		msg = ldb_msg_new(ac);
-		if (!msg) {
-			return LDB_ERR_OPERATIONS_ERROR;
-		}
-
 		ret = ltdb_idx_to_key(ac->module, ltdb,
 				      ac, &dn_list->dn[i],
 				      &tdb_key);
@@ -1550,6 +1702,33 @@ static int ltdb_index_filter(struct ltdb_private *ltdb,
 			return ret;
 		}
 
+		if (ltdb->cache->GUID_index_attribute != NULL) {
+			/*
+			 * If we are in GUID index mode, then the dn_list is
+			 * sorted.  If we got a duplicate, forget about it, as
+			 * otherwise we would send the same entry back more
+			 * than once.
+			 *
+			 * This is needed in the truncated DN case, or if a
+			 * duplicate was forced in via
+			 * LDB_FLAG_INTERNAL_DISABLE_SINGLE_VALUE_CHECK
+			 */
+
+			if (memcmp(previous_guid_key, tdb_key.dptr,
+				   sizeof(previous_guid_key)) == 0) {
+				continue;
+			}
+
+			memcpy(previous_guid_key, tdb_key.dptr,
+			       sizeof(previous_guid_key));
+		}
+
+		msg = ldb_msg_new(ac);
+		if (!msg) {
+			return LDB_ERR_OPERATIONS_ERROR;
+		}
+
+
 		ret = ltdb_search_key(ac->module, ltdb,
 				      tdb_key, msg,
 				      LDB_UNPACK_DATA_FLAG_NO_DATA_ALLOC|
@@ -1569,10 +1748,15 @@ static int ltdb_index_filter(struct ltdb_private *ltdb,
 			return LDB_ERR_OPERATIONS_ERROR;
 		}
 
-		/* We trust the index for SCOPE_ONELEVEL and SCOPE_BASE */
-		if ((ac->scope == LDB_SCOPE_ONELEVEL
-		     && ltdb->cache->one_level_indexes)
-		    || ac->scope == LDB_SCOPE_BASE) {
+		/*
+		 * We trust the index for LDB_SCOPE_ONELEVEL
+		 * unless the index key has been truncated.
+		 *
+		 * LDB_SCOPE_BASE is not passed in by our only caller.
+		 */
+		if (ac->scope == LDB_SCOPE_ONELEVEL
+		    && ltdb->cache->one_level_indexes
+		    && scope_one_truncation == KEY_NOT_TRUNCATED) {
 			ret = ldb_match_message(ldb, msg, ac->tree,
 						ac->scope, &matched);
 		} else {
@@ -1645,6 +1829,7 @@ int ltdb_search_indexed(struct ltdb_context *ac, uint32_t *match_count)
 	struct dn_list *dn_list;
 	int ret;
 	enum ldb_scope index_scope;
+	enum key_truncation scope_one_truncation = KEY_NOT_TRUNCATED;
 
 	/* see if indexing is enabled */
 	if (!ltdb->cache->attribute_indexes &&
@@ -1674,17 +1859,10 @@ int ltdb_search_indexed(struct ltdb_context *ac, uint32_t *match_count)
 	switch (index_scope) {
 	case LDB_SCOPE_BASE:
 		/*
-		 * If we ever start to also load the index values for
-		 * the tree, we must ensure we strictly intersect with
-		 * this list, as we trust the BASE index
+		 * The only caller will have filtered the operation out
+		 * so we should never get here
 		 */
-		ret = ltdb_index_dn_base_dn(ac->module, ltdb,
-					    ac->base, dn_list);
-		if (ret != LDB_SUCCESS) {
-			talloc_free(dn_list);
-			return ret;
-		}
-		break;
+		ldb_operr(ldb);
 
 	case LDB_SCOPE_ONELEVEL:
 		/*
@@ -1692,7 +1870,8 @@ int ltdb_search_indexed(struct ltdb_context *ac, uint32_t *match_count)
 		 * the tree, we must ensure we strictly intersect with
 		 * this list, as we trust the ONELEVEL index
 		 */
-		ret = ltdb_index_dn_one(ac->module, ltdb, ac->base, dn_list);
+		ret = ltdb_index_dn_one(ac->module, ltdb, ac->base, dn_list,
+				        &scope_one_truncation);
 		if (ret != LDB_SUCCESS) {
 			talloc_free(dn_list);
 			return ret;
@@ -1761,7 +1940,19 @@ int ltdb_search_indexed(struct ltdb_context *ac, uint32_t *match_count)
 		break;
 	}
 
-	ret = ltdb_index_filter(ltdb, dn_list, ac, match_count);
+	/*
+	 * It is critical that this function do the re-filter even
+	 * on things found by the index as the index can over-match
+	 * in cases of truncation (as well as when it decides it is
+	 * not worth further filtering)
+	 *
+	 * If this changes, then the index code above would need to
+	 * pass up a flag to say if any index was truncated during
+	 * processing as the truncation here refers only to the
+	 * SCOPE_ONELEVEL index.
+	 */
+	ret = ltdb_index_filter(ltdb, dn_list, ac, match_count,
+				scope_one_truncation);
 	talloc_free(dn_list);
 	return ret;
 }
@@ -1797,6 +1988,8 @@ static int ltdb_index_add1(struct ldb_module *module,
 	const struct ldb_schema_attribute *a;
 	struct dn_list *list;


-- 
Samba Shared Repository



More information about the samba-cvs mailing list