From 12f689eef4394e8c2cf8efdded06d5b398d6e0a7 Mon Sep 17 00:00:00 2001
From: Andrew Tridgell <tridge@samba.org>
Date: Tue, 15 Sep 2009 10:00:24 -0700
Subject: s4-ldb: cope better with corruption of tdb records

When doing an indexed search if we hit a corrupt record we abandoned
the indexed search and did a full search. The problem was that we
might have sent some records to the caller already, which means the
caller ended up with duplicate records. Fix this by returning a search
error if indexing returns an error and we have given any records to
the caller.
---
 source4/lib/ldb/ldb_tdb/ldb_index.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

(limited to 'source4/lib/ldb/ldb_tdb/ldb_index.c')

diff --git a/source4/lib/ldb/ldb_tdb/ldb_index.c b/source4/lib/ldb/ldb_tdb/ldb_index.c
index 85fbfa0458..b959471d16 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_index.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_index.c
@@ -1037,7 +1037,8 @@ static int ltdb_index_dn(struct ldb_module *module,
   extracting just the given attributes
 */
 static int ltdb_index_filter(const struct dn_list *dn_list,
-			     struct ltdb_context *ac)
+			     struct ltdb_context *ac, 
+			     uint32_t *match_count)
 {
 	struct ldb_context *ldb;
 	struct ldb_message *msg;
@@ -1093,6 +1094,8 @@ static int ltdb_index_filter(const struct dn_list *dn_list,
 			ac->request_terminated = true;
 			return ret;
 		}
+
+		(*match_count)++;
 	}
 
 	return LDB_SUCCESS;
@@ -1103,7 +1106,7 @@ static int ltdb_index_filter(const struct dn_list *dn_list,
   returns -1 if an indexed search is not possible, in which
   case the caller should call ltdb_search_full()
 */
-int ltdb_search_indexed(struct ltdb_context *ac)
+int ltdb_search_indexed(struct ltdb_context *ac, uint32_t *match_count)
 {
 	struct ldb_context *ldb;
 	void *data = ldb_module_get_private(ac->module);
@@ -1166,7 +1169,7 @@ int ltdb_search_indexed(struct ltdb_context *ac)
 	if (ret == LDB_SUCCESS) {
 		/* we've got a candidate list - now filter by the full tree
 		   and extract the needed attributes */
-		ret = ltdb_index_filter(dn_list, ac);
+		ret = ltdb_index_filter(dn_list, ac, match_count);
 	}
 
 	talloc_free(dn_list);
@@ -1578,6 +1581,8 @@ static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *
 
 	ret = ltdb_unpack_data(module, &data, msg);
 	if (ret != 0) {
+		ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid data for index %s\n",
+			  ldb_dn_get_linearized(msg->dn));
 		talloc_free(msg);
 		return -1;
 	}
-- 
cgit