[SCM] Samba Shared Repository - branch master updated - tevent-0-9-8-347-g10e25fc

Andrew Tridgell tridge at samba.org
Tue Sep 15 19:46:57 MDT 2009


The branch, master has been updated
       via  10e25fc5e90e9eaabedc2f3477ac1e8947c88c77 (commit)
       via  03d0005b250ebd7e632e5cd5cbb8e76fceb1bbee (commit)
       via  458dda1f15db3db674cf8846b3c08340378a29a8 (commit)
       via  654672008cb8c1293c7637718a84ac40a4476aa6 (commit)
       via  9e0b1a3a1f0ea9ca1b402aa60b8ddbe9ce0c9c10 (commit)
       via  bc3bbae6d28c79706b83b7e3f5457674b98d4a74 (commit)
       via  ff8ad222cd1ec26f0e29e409525e16d3b0f1b8c4 (commit)
       via  12f689eef4394e8c2cf8efdded06d5b398d6e0a7 (commit)
       via  00fb6705ffc937617e11c6da33b39bad7dda2ac3 (commit)
       via  089dc64cbb40fe270d44bed10cfb2ccfacff669a (commit)
      from  444a05c28df693a745809fef73ae583a78be7c8f (commit)

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


- Log -----------------------------------------------------------------
commit 10e25fc5e90e9eaabedc2f3477ac1e8947c88c77
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Sep 15 14:07:43 2009 -0700

    s4-ldb: ldap attribute names can contain a '.'
    
    When they are of the form of OIDs

commit 03d0005b250ebd7e632e5cd5cbb8e76fceb1bbee
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Sep 15 14:07:06 2009 -0700

    s4-ldb: expose ldb_transaction_prepare_commit() in ldb
    
    It is useful to be able to control the 2 phase commit from application
    code (s4 replication uses it)

commit 458dda1f15db3db674cf8846b3c08340378a29a8
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Sep 15 14:06:07 2009 -0700

    s4-repl: don't do double replication
    
    When we replicate from a remote DC, we need to note the new uSN that
    the local changes have resulted in, and modify the uSN that the notify
    task uses to determine if it should send a ReplicaSync message back to
    the remote DC. Otherwise we end up always triggering a ReplicaSync
    every time we replicate from another DC

commit 654672008cb8c1293c7637718a84ac40a4476aa6
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Sep 15 14:04:22 2009 -0700

    tdb: allow reads after prepare commit
    
    We previously only allowed a commit to happen after a prepare
    commit. It is in fact safe to allow reads between a prepare and a
    commit, and the s4 replication code can make use of that, so allow it.

commit 9e0b1a3a1f0ea9ca1b402aa60b8ddbe9ce0c9c10
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Sep 15 11:47:42 2009 -0700

    s4-drs: filter based on local_usn
    
    The getncchanges uSN is in our local space, so we must compare it to
    the local_usn in replPropertyMetaData

commit bc3bbae6d28c79706b83b7e3f5457674b98d4a74
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Sep 15 11:46:59 2009 -0700

    s4-repl: make sure we marshal the replPropertyMetaData after the last change
    
    we were setting local_usn after the marshall, so it wasn't going into
    the object

commit ff8ad222cd1ec26f0e29e409525e16d3b0f1b8c4
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Sep 15 10:01:26 2009 -0700

    s4-dsdb: use DLIST_ADD() not DLIST_ADD_END()
    
    Using DLIST_ADD_END() to construct a long list is very inefficient (it
    is O(n^2). These lists are not ordered, so using DLIST_ADD() is much
    better.

commit 12f689eef4394e8c2cf8efdded06d5b398d6e0a7
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Sep 15 10:00:24 2009 -0700

    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.

commit 00fb6705ffc937617e11c6da33b39bad7dda2ac3
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Sep 15 09:43:27 2009 -0700

    talloc: when we enable NULL tracking, reparent the autofree context
    
    If NULL tracking is enabled after the autofree context is initialised
    then autofree ends up separate from the null_context. This means that
    talloc_report_full() doesn't report the autofree context. Fix this by
    reparenting the autofree context when we create the null_context.

commit 089dc64cbb40fe270d44bed10cfb2ccfacff669a
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Sep 15 09:23:14 2009 -0700

    s4-repl: add a debug to make it easier to monitor replication

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

Summary of changes:
 lib/talloc/talloc.c                             |    3 +
 lib/tdb/common/transaction.c                    |    8 ---
 source4/dsdb/repl/drepl_out_helpers.c           |    3 +-
 source4/dsdb/repl/replicated_objects.c          |   40 +++++++++++-
 source4/dsdb/samdb/ldb_modules/repl_meta_data.c |   20 +++---
 source4/dsdb/schema/schema_init.c               |    4 +-
 source4/dsdb/schema/schema_set.c                |    4 +-
 source4/lib/ldb/common/ldb.c                    |   78 +++++++++++++++++------
 source4/lib/ldb/common/ldb_parse.c              |    3 +-
 source4/lib/ldb/include/ldb.h                   |    5 ++
 source4/lib/ldb/include/ldb_private.h           |    2 +
 source4/lib/ldb/ldb_tdb/ldb_index.c             |   11 +++-
 source4/lib/ldb/ldb_tdb/ldb_pack.c              |    4 +
 source4/lib/ldb/ldb_tdb/ldb_search.c            |   18 +++++-
 source4/lib/ldb/ldb_tdb/ldb_tdb.h               |    2 +-
 source4/libnet/libnet_vampire.c                 |    6 +-
 source4/rpc_server/drsuapi/getncchanges.c       |    2 +-
 source4/torture/libnet/libnet_BecomeDC.c        |    6 +-
 18 files changed, 163 insertions(+), 56 deletions(-)


Changeset truncated at 500 lines:

diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c
index 2709741..478767c 100644
--- a/lib/talloc/talloc.c
+++ b/lib/talloc/talloc.c
@@ -1468,6 +1468,9 @@ void talloc_enable_null_tracking(void)
 {
 	if (null_context == NULL) {
 		null_context = _talloc_named_const(NULL, 0, "null_context");
+		if (autofree_context != NULL) {
+			talloc_reparent(NULL, null_context, autofree_context);
+		}
 	}
 }
 
diff --git a/lib/tdb/common/transaction.c b/lib/tdb/common/transaction.c
index e97fe67..67a0358 100644
--- a/lib/tdb/common/transaction.c
+++ b/lib/tdb/common/transaction.c
@@ -137,14 +137,6 @@ static int transaction_read(struct tdb_context *tdb, tdb_off_t off, void *buf,
 {
 	uint32_t blk;
 
-	/* Only a commit is allowed on a prepared transaction */
-	if (tdb->transaction->prepared) {
-		tdb->ecode = TDB_ERR_EINVAL;
-		TDB_LOG((tdb, TDB_DEBUG_FATAL, "transaction_read: transaction already prepared, read not allowed\n"));
-		tdb->transaction->transaction_error = 1;
-		return -1;
-	}
-
 	/* break it down into block sized ops */
 	while (len + (off % tdb->transaction->block_size) > tdb->transaction->block_size) {
 		tdb_len_t len2 = tdb->transaction->block_size - (off % tdb->transaction->block_size);
diff --git a/source4/dsdb/repl/drepl_out_helpers.c b/source4/dsdb/repl/drepl_out_helpers.c
index 168aacd..5c63c11 100644
--- a/source4/dsdb/repl/drepl_out_helpers.c
+++ b/source4/dsdb/repl/drepl_out_helpers.c
@@ -414,7 +414,8 @@ static void dreplsrv_op_pull_source_apply_changes_send(struct dreplsrv_op_pull_s
 							 &rf1,
 							 uptodateness_vector,
 							 &drsuapi->gensec_skey,
-							 st, NULL);
+							 st, NULL, 
+							 &st->op->source_dsa->notify_uSN);
 	if (!W_ERROR_IS_OK(status)) {
 		DEBUG(0,("Failed to commit objects: %s\n", win_errstr(status)));
 		composite_error(c, werror_to_ntstatus(status));
diff --git a/source4/dsdb/repl/replicated_objects.c b/source4/dsdb/repl/replicated_objects.c
index fb6d4c1..5ae622e 100644
--- a/source4/dsdb/repl/replicated_objects.c
+++ b/source4/dsdb/repl/replicated_objects.c
@@ -212,7 +212,8 @@ WERROR dsdb_extended_replicated_objects_commit(struct ldb_context *ldb,
 					       const struct drsuapi_DsReplicaCursor2CtrEx *uptodateness_vector,
 					       const DATA_BLOB *gensec_skey,
 					       TALLOC_CTX *mem_ctx,
-					       struct dsdb_extended_replicated_objects **_out)
+					       struct dsdb_extended_replicated_objects **_out,
+					       uint64_t *notify_uSN)
 {
 	WERROR status;
 	const struct dsdb_schema *schema;
@@ -221,6 +222,7 @@ WERROR dsdb_extended_replicated_objects_commit(struct ldb_context *ldb,
 	const struct drsuapi_DsReplicaObjectListItemEx *cur;
 	uint32_t i;
 	int ret;
+	uint64_t seq_num1, seq_num2;
 
 	schema = dsdb_get_schema(ldb);
 	if (!schema) {
@@ -280,6 +282,14 @@ WERROR dsdb_extended_replicated_objects_commit(struct ldb_context *ldb,
 		return WERR_FOOBAR;
 	}
 
+	ret = dsdb_load_partition_usn(ldb, out->partition_dn, &seq_num1);
+	if (ret != LDB_SUCCESS) {
+		DEBUG(0,(__location__ " Failed to load partition uSN\n"));
+		talloc_free(out);
+		ldb_transaction_cancel(ldb);
+		return WERR_FOOBAR;		
+	}
+
 	ret = ldb_extended(ldb, DSDB_EXTENDED_REPLICATED_OBJECTS_OID, out, &ext_res);
 	if (ret != LDB_SUCCESS) {
 		DEBUG(0,("Failed to apply records: %s: %s\n",
@@ -290,6 +300,28 @@ WERROR dsdb_extended_replicated_objects_commit(struct ldb_context *ldb,
 	}
 	talloc_free(ext_res);
 
+	ret = ldb_transaction_prepare_commit(ldb);
+	if (ret != LDB_SUCCESS) {
+		DEBUG(0,(__location__ " Failed to prepare commit of transaction\n"));
+		talloc_free(out);
+		return WERR_FOOBAR;
+	}
+
+	ret = dsdb_load_partition_usn(ldb, out->partition_dn, &seq_num2);
+	if (ret != LDB_SUCCESS) {
+		DEBUG(0,(__location__ " Failed to load partition uSN\n"));
+		talloc_free(out);
+		ldb_transaction_cancel(ldb);
+		return WERR_FOOBAR;		
+	}
+
+	/* if this replication partner didn't need to be notified
+	   before this transaction then it still doesn't need to be
+	   notified, as the changes came from this server */	
+	if (seq_num2 > seq_num1 && seq_num1 <= *notify_uSN) {
+		*notify_uSN = seq_num2;
+	}
+
 	ret = ldb_transaction_commit(ldb);
 	if (ret != LDB_SUCCESS) {
 		DEBUG(0,(__location__ " Failed to commit transaction\n"));
@@ -297,6 +329,12 @@ WERROR dsdb_extended_replicated_objects_commit(struct ldb_context *ldb,
 		return WERR_FOOBAR;
 	}
 
+
+	DEBUG(2,("Replicated %u objects (%u linked attributes) for %s\n",
+		 out->num_objects, out->linked_attributes_count,
+		 ldb_dn_get_linearized(out->partition_dn)));
+		 
+
 	if (_out) {
 		*_out = out;
 	} else {
diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
index f9411fe..2670352 100644
--- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
@@ -1352,16 +1352,6 @@ static int replmd_replicated_apply_merge(struct replmd_replicated_request *ar)
 		replmd_replPropertyMetaDataCtr1_sort(&nmd.ctr.ctr1, &rdn_p->attid);
 	}
 
-	/* create the meta data value */
-	ndr_err = ndr_push_struct_blob(&nmd_value, msg, 
-				       lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")),
-				       &nmd,
-				       (ndr_push_flags_fn_t)ndr_push_replPropertyMetaDataBlob);
-	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-		NTSTATUS nt_status = ndr_map_error2ntstatus(ndr_err);
-		return replmd_replicated_request_werror(ar, ntstatus_to_werror(nt_status));
-	}
-
 	/*
 	 * check if some replicated attributes left, otherwise skip the ldb_modify() call
 	 */
@@ -1385,6 +1375,16 @@ static int replmd_replicated_apply_merge(struct replmd_replicated_request *ar)
 		nmd.ctr.ctr1.array[i].local_usn = seq_num;
 	}
 
+	/* create the meta data value */
+	ndr_err = ndr_push_struct_blob(&nmd_value, msg, 
+				       lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")),
+				       &nmd,
+				       (ndr_push_flags_fn_t)ndr_push_replPropertyMetaDataBlob);
+	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+		NTSTATUS nt_status = ndr_map_error2ntstatus(ndr_err);
+		return replmd_replicated_request_werror(ar, ntstatus_to_werror(nt_status));
+	}
+
 	/*
 	 * when we know that we'll modify the record, add the whenChanged, uSNChanged
 	 * and replPopertyMetaData attributes
diff --git a/source4/dsdb/schema/schema_init.c b/source4/dsdb/schema/schema_init.c
index 3b701ad..9f7d967 100644
--- a/source4/dsdb/schema/schema_init.c
+++ b/source4/dsdb/schema/schema_init.c
@@ -967,7 +967,7 @@ int dsdb_schema_from_ldb_results(TALLOC_CTX *mem_ctx, struct ldb_context *ldb,
 			return LDB_ERR_CONSTRAINT_VIOLATION;
 		}
 
-		DLIST_ADD_END(schema->attributes, sa, struct dsdb_attribute *);
+		DLIST_ADD(schema->attributes, sa);
 	}
 
 	for (i=0; i < objectclass_res->count; i++) {
@@ -988,7 +988,7 @@ int dsdb_schema_from_ldb_results(TALLOC_CTX *mem_ctx, struct ldb_context *ldb,
 			return LDB_ERR_CONSTRAINT_VIOLATION;
 		}
 
-		DLIST_ADD_END(schema->classes, sc, struct dsdb_class *);
+		DLIST_ADD(schema->classes, sc);
 	}
 
 	schema->fsmo.master_dn = ldb_msg_find_attr_as_dn(ldb, schema, schema_res->msgs[0], "fSMORoleOwner");
diff --git a/source4/dsdb/schema/schema_set.c b/source4/dsdb/schema/schema_set.c
index 6745bde..6f09f63 100644
--- a/source4/dsdb/schema/schema_set.c
+++ b/source4/dsdb/schema/schema_set.c
@@ -555,7 +555,7 @@ WERROR dsdb_set_schema_from_ldif(struct ldb_context *ldb, const char *pf, const
 				goto failed;
 			}
 
-			DLIST_ADD_END(schema->attributes, sa, struct dsdb_attribute *);
+			DLIST_ADD(schema->attributes, sa);
 		} else if (is_sc) {
 			struct dsdb_class *sc;
 
@@ -569,7 +569,7 @@ WERROR dsdb_set_schema_from_ldif(struct ldb_context *ldb, const char *pf, const
 				goto failed;
 			}
 
-			DLIST_ADD_END(schema->classes, sc, struct dsdb_class *);
+			DLIST_ADD(schema->classes, sc);
 		}
 	}
 
diff --git a/source4/lib/ldb/common/ldb.c b/source4/lib/ldb/common/ldb.c
index 6939cef..613451a 100644
--- a/source4/lib/ldb/common/ldb.c
+++ b/source4/lib/ldb/common/ldb.c
@@ -316,6 +316,7 @@ int ldb_transaction_start(struct ldb_context *ldb)
 
 	/* start a new transaction */
 	ldb->transaction_active++;
+	ldb->prepare_commit_done = false;
 
 	FIRST_OP(ldb, start_transaction);
 
@@ -335,6 +336,57 @@ int ldb_transaction_start(struct ldb_context *ldb)
 }
 
 /*
+  prepare for transaction commit (first phase of two phase commit)
+*/
+int ldb_transaction_prepare_commit(struct ldb_context *ldb)
+{
+	struct ldb_module *module;
+	int status;
+
+	if (ldb->prepare_commit_done) {
+		return LDB_SUCCESS;
+	}
+
+	/* commit only when all nested transactions are complete */
+	if (ldb->transaction_active > 1) {
+		return LDB_SUCCESS;
+	}
+
+	ldb->prepare_commit_done = true;
+
+	if (ldb->transaction_active < 0) {
+		ldb_debug(ldb, LDB_DEBUG_FATAL,
+			  "prepare commit called but no ldb transactions are active!");
+		ldb->transaction_active = 0;
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
+
+	/* call prepare transaction if available */
+	FIRST_OP_NOERR(ldb, prepare_commit);
+	if (module == NULL) {
+		return LDB_SUCCESS;
+	}
+
+	status = module->ops->prepare_commit(module);
+	if (status != LDB_SUCCESS) {
+		/* if a module fails the prepare then we need
+		   to call the end transaction for everyone */
+		FIRST_OP(ldb, end_transaction);
+		module->ops->end_transaction(module);
+		if (ldb->err_string == NULL) {
+			/* no error string was setup by the backend */
+			ldb_asprintf_errstring(ldb,
+					       "ldb transaction prepare commit: %s (%d)",
+					       ldb_strerror(status),
+					       status);
+		}
+	}
+
+	return status;
+}
+
+
+/*
   commit a transaction
 */
 int ldb_transaction_commit(struct ldb_context *ldb)
@@ -342,6 +394,10 @@ int ldb_transaction_commit(struct ldb_context *ldb)
 	struct ldb_module *module;
 	int status;
 
+	status = ldb_transaction_prepare_commit(ldb);
+	if (status != LDB_SUCCESS) {
+		return status;
+	}
 
 	ldb->transaction_active--;
 
@@ -361,27 +417,6 @@ int ldb_transaction_commit(struct ldb_context *ldb)
 		return LDB_ERR_OPERATIONS_ERROR;
 	}
 
-	/* call prepare transaction if available */
-	FIRST_OP_NOERR(ldb, prepare_commit);
-	if (module != NULL) {
-		status = module->ops->prepare_commit(module);
-		if (status != LDB_SUCCESS) {
-			/* if a module fails the prepare then we need
-			   to call the end transaction for everyone */
-			/* preserve err string */
-			FIRST_OP(ldb, end_transaction);
-			module->ops->end_transaction(module);
-			if (ldb->err_string == NULL) {
-				/* no error string was setup by the backend */
-				ldb_asprintf_errstring(ldb,
-						       "ldb transaction prepare commit: %s (%d)",
-						       ldb_strerror(status),
-						       status);
-			}
-			return status;
-		}
-	}
-
 	ldb_reset_err_string(ldb);
 
 	FIRST_OP(ldb, end_transaction);
@@ -401,6 +436,7 @@ int ldb_transaction_commit(struct ldb_context *ldb)
 	return status;
 }
 
+
 /*
   cancel a transaction
 */
diff --git a/source4/lib/ldb/common/ldb_parse.c b/source4/lib/ldb/common/ldb_parse.c
index 654a635..0fab002 100644
--- a/source4/lib/ldb/common/ldb_parse.c
+++ b/source4/lib/ldb/common/ldb_parse.c
@@ -267,7 +267,8 @@ static enum ldb_parse_op ldb_parse_filtertype(void *mem_ctx, char **type, char *
 		p++;
 	}
 
-	while ((isascii(*p) && isalnum((unsigned char)*p)) || (*p == '-')) { /* attribute names can only be alphanums */
+	while ((isascii(*p) && isalnum((unsigned char)*p)) || (*p == '-') || (*p == '.')) { 
+		/* attribute names can only be alphanums */
 		p++;
 	}
 
diff --git a/source4/lib/ldb/include/ldb.h b/source4/lib/ldb/include/ldb.h
index 04b0a22..2c89031 100644
--- a/source4/lib/ldb/include/ldb.h
+++ b/source4/lib/ldb/include/ldb.h
@@ -1284,6 +1284,11 @@ int ldb_sequence_number(struct ldb_context *ldb, enum ldb_sequence_type type, ui
 int ldb_transaction_start(struct ldb_context *ldb);
 
 /**
+   first phase of two phase commit
+ */
+int ldb_transaction_prepare_commit(struct ldb_context *ldb);
+
+/**
   commit a transaction
 */
 int ldb_transaction_commit(struct ldb_context *ldb);
diff --git a/source4/lib/ldb/include/ldb_private.h b/source4/lib/ldb/include/ldb_private.h
index c12f334..1fb3109 100644
--- a/source4/lib/ldb/include/ldb_private.h
+++ b/source4/lib/ldb/include/ldb_private.h
@@ -114,6 +114,8 @@ struct ldb_context {
 	char *modules_dir;
 
 	struct tevent_context *ev_ctx;
+
+	bool prepare_commit_done;
 };
 
 /* The following definitions come from lib/ldb/common/ldb.c  */
diff --git a/source4/lib/ldb/ldb_tdb/ldb_index.c b/source4/lib/ldb/ldb_tdb/ldb_index.c
index 85fbfa0..b959471 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;
 	}
diff --git a/source4/lib/ldb/ldb_tdb/ldb_pack.c b/source4/lib/ldb/ldb_tdb/ldb_pack.c
index 5640e70..e7aeb47 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_pack.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_pack.c
@@ -236,6 +236,10 @@ int ltdb_unpack_data(struct ldb_module *module,
 			errno = EIO;
 			goto failed;
 		}
+		if (len == 0) {
+			errno = EIO;
+			goto failed;
+		}
 		message->elements[i].flags = 0;
 		message->elements[i].name = talloc_strndup(message->elements, (char *)p, len);
 		if (message->elements[i].name == NULL) {
diff --git a/source4/lib/ldb/ldb_tdb/ldb_search.c b/source4/lib/ldb/ldb_tdb/ldb_search.c
index b307c5f..a6647cc 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_search.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_search.c
@@ -265,6 +265,9 @@ int ltdb_search_dn1(struct ldb_module *module, struct ldb_dn *dn, struct ldb_mes
 	ret = ltdb_unpack_data(module, &tdb_data, msg);
 	free(tdb_data.dptr);
 	if (ret == -1) {
+		struct ldb_context *ldb = ldb_module_get_ctx(module);
+		ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid data for index %s\n",
+			  ldb_dn_get_linearized(msg->dn));
 		return LDB_ERR_OPERATIONS_ERROR;		
 	}
 
@@ -535,7 +538,9 @@ int ltdb_search(struct ltdb_context *ctx)
 	ctx->attrs = req->op.search.attrs;
 
 	if (ret == LDB_SUCCESS) {
-		ret = ltdb_search_indexed(ctx);
+		uint32_t match_count = 0;
+
+		ret = ltdb_search_indexed(ctx, &match_count);
 		if (ret == LDB_ERR_NO_SUCH_OBJECT) {
 			/* Not in the index, therefore OK! */
 			ret = LDB_SUCCESS;
@@ -553,6 +558,17 @@ int ltdb_search(struct ltdb_context *ctx)
 			printf("FULL SEARCH: %s\n", expression);
 			talloc_free(expression);
 #endif
+			if (match_count != 0) {
+				/* the indexing code gave an error
+				 * after having returned at least one
+				 * entry. This means the indexes are
+				 * corrupt or a database record is
+				 * corrupt. We cannot continue with a
+				 * full search or we may return
+				 * duplicate entries
+				 */
+				return LDB_ERR_OPERATIONS_ERROR;
+			}
 			ret = ltdb_search_full(ctx);
 			if (ret != LDB_SUCCESS) {
 				ldb_set_errstring(ldb, "Indexed and full searches both failed!\n");
diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.h b/source4/lib/ldb/ldb_tdb/ldb_tdb.h
index 75034dc..c8c1dad 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_tdb.h
+++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.h
@@ -82,7 +82,7 @@ int ltdb_check_at_attributes_values(const struct ldb_val *value);
 
 struct ldb_parse_tree;
 
-int ltdb_search_indexed(struct ltdb_context *ctx);
+int ltdb_search_indexed(struct ltdb_context *ctx, uint32_t *);
 int ltdb_index_add(struct ldb_module *module, const struct ldb_message *msg);
 int ltdb_index_del(struct ldb_module *module, const struct ldb_message *msg);
 int ltdb_index_one(struct ldb_module *module, const struct ldb_message *msg, int add);
diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c
index 5e516af..327a64d 100644
--- a/source4/libnet/libnet_vampire.c
+++ b/source4/libnet/libnet_vampire.c
@@ -168,6 +168,7 @@ static NTSTATUS vampire_apply_schema(struct vampire_state *s,
 	uint32_t i;
 	int ret;
 	bool ok;
+	uint64_t seq_num;
 
 	DEBUG(0,("Analyze and apply schema objects\n"));


-- 
Samba Shared Repository


More information about the samba-cvs mailing list