[SCM] Samba Shared Repository - branch master updated

Andrew Tridgell tridge at samba.org
Sat Oct 24 23:45:43 MDT 2009


The branch, master has been updated
       via  b55a5ad... s4-ldb: ensure DNs pass validity tests in indexing
       via  2eca02a... s4-ldb: fixed string length handling on index records
       via  c34e45a... s4-dsdb: ensure that new partitions inherit any transaction
       via  d4c0e8f... tdb: detect tdb store of identical records and skip
       via  dffb572... s4-ldb: don't allow modifies outside a transaction.
       via  5002cdd... s4-ldb: fixed re-index during a complex transaction
       via  e7d9f5e... s4-python: fixed annoyance where control-C doesn't kill our python scripts
      from  a07eb08... s4:dcesrv_samr: always use mem_ctx as initial parent for samr_*_state

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


- Log -----------------------------------------------------------------
commit b55a5adab99f535bb392662d54afbabed116a3b6
Author: Andrew Tridgell <tridge at samba.org>
Date:   Sun Oct 25 13:13:41 2009 +1100

    s4-ldb: ensure DNs pass validity tests in indexing

commit 2eca02a4080b68fbb2dacb659b1733224cfa462e
Author: Andrew Tridgell <tridge at samba.org>
Date:   Sun Oct 25 13:12:32 2009 +1100

    s4-ldb: fixed string length handling on index records

commit c34e45a8e2880eb06be6425fa6be15246db03197
Author: Andrew Tridgell <tridge at samba.org>
Date:   Fri Oct 23 22:46:09 2009 +1100

    s4-dsdb: ensure that new partitions inherit any transaction

commit d4c0e8fdf063f88032c32de7ece60d502b322089
Author: Andrew Tridgell <tridge at samba.org>
Date:   Fri Oct 23 22:45:03 2009 +1100

    tdb: detect tdb store of identical records and skip
    
    This can help with ldb where we rewrite the index records

commit dffb572ce0b350bf42549c882275b627d9b36e59
Author: Andrew Tridgell <tridge at samba.org>
Date:   Fri Oct 23 22:43:24 2009 +1100

    s4-ldb: don't allow modifies outside a transaction.

commit 5002cddcb0d9e539ded949bcc805c035e038362d
Author: Andrew Tridgell <tridge at samba.org>
Date:   Fri Oct 23 22:42:26 2009 +1100

    s4-ldb: fixed re-index during a complex transaction
    
    We may have modified index objects in the in-memory index tdb

commit e7d9f5eea52403f576b636a35fb9889ed82cbf0b
Author: Andrew Tridgell <tridge at samba.org>
Date:   Fri Oct 23 17:12:48 2009 +1100

    s4-python: fixed annoyance where control-C doesn't kill our python scripts
    
    We want our scripts to die immediately when a user hits
    control-C. Otherwise we not only annoy the hell out of the user, we
    also risk db corruption as the control-C could get delivered as an
    exception which gets mis-interpreted (eg. as a missing db object). We
    use transactions for all our databases, so the right thing to do in
    all our command line tools is to die immediately.

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

Summary of changes:
 lib/tdb/common/tdb.c                            |   20 ++++++++++
 source4/dsdb/samdb/ldb_modules/partition.c      |   15 +++++++
 source4/dsdb/samdb/ldb_modules/partition.h      |    1 +
 source4/dsdb/samdb/ldb_modules/partition_init.c |   21 +++++-----
 source4/lib/ldb/ldb_tdb/ldb_index.c             |   47 +++++++++++++++++-----
 source4/lib/ldb/ldb_tdb/ldb_tdb.c               |    8 ++++
 source4/scripting/python/pyglue.c               |   10 +++++
 7 files changed, 100 insertions(+), 22 deletions(-)


Changeset truncated at 500 lines:

diff --git a/lib/tdb/common/tdb.c b/lib/tdb/common/tdb.c
index 0389d3c..564c5fe 100644
--- a/lib/tdb/common/tdb.c
+++ b/lib/tdb/common/tdb.c
@@ -121,6 +121,7 @@ tdb_off_t tdb_find_lock_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t has
 	return rec_ptr;
 }
 
+static TDB_DATA _tdb_fetch(struct tdb_context *tdb, TDB_DATA key);
 
 /* update an entry in place - this only works if the new data size
    is <= the old data size and the key exists.
@@ -135,6 +136,25 @@ static int tdb_update_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash,
 	if (!(rec_ptr = tdb_find(tdb, key, hash, &rec)))
 		return -1;
 
+	/* it could be an exact duplicate of what is there - this is
+	 * surprisingly common (eg. with a ldb re-index). */
+	if (rec.key_len == key.dsize && 
+	    rec.data_len == dbuf.dsize &&
+	    rec.full_hash == hash) {
+		TDB_DATA data = _tdb_fetch(tdb, key);
+		if (data.dsize == dbuf.dsize &&
+		    memcmp(data.dptr, dbuf.dptr, data.dsize) == 0) {
+			if (data.dptr) {
+				free(data.dptr);
+			}
+			return 0;
+		}
+		if (data.dptr) {
+			free(data.dptr);
+		}
+	}
+	 
+
 	/* must be long enough key, data and tailer */
 	if (rec.rec_len < key.dsize + dbuf.dsize + sizeof(tdb_off_t)) {
 		tdb->ecode = TDB_SUCCESS; /* Not really an error */
diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c
index 779b8b5..64015ed 100644
--- a/source4/dsdb/samdb/ldb_modules/partition.c
+++ b/source4/dsdb/samdb/ldb_modules/partition.c
@@ -690,6 +690,9 @@ static int partition_start_trans(struct ldb_module *module)
 			return ret;
 		}
 	}
+
+	data->in_transaction++;
+
 	return LDB_SUCCESS;
 }
 
@@ -737,6 +740,12 @@ static int partition_end_trans(struct ldb_module *module)
 		}
 	}
 
+	if (data->in_transaction == 0) {
+		DEBUG(0,("partition end transaction mismatch\n"));
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
+	data->in_transaction--;
+
 	return ldb_next_end_trans(module);
 }
 
@@ -756,6 +765,12 @@ static int partition_del_trans(struct ldb_module *module)
 		}
 	}	
 
+	if (data->in_transaction == 0) {
+		DEBUG(0,("partition del transaction mismatch\n"));
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
+	data->in_transaction--;
+
 	ret = ldb_next_del_trans(module);
 	if (ret != LDB_SUCCESS) {
 		final_ret = ret;
diff --git a/source4/dsdb/samdb/ldb_modules/partition.h b/source4/dsdb/samdb/ldb_modules/partition.h
index 3572f17..dda0b86 100644
--- a/source4/dsdb/samdb/ldb_modules/partition.h
+++ b/source4/dsdb/samdb/ldb_modules/partition.h
@@ -45,6 +45,7 @@ struct partition_private_data {
 	const char *ldapBackend;
 
 	uint64_t metadata_seq;
+	uint32_t in_transaction;
 };
 
 #define PARTITION_FIND_OP_NOERROR(module, op) do { \
diff --git a/source4/dsdb/samdb/ldb_modules/partition_init.c b/source4/dsdb/samdb/ldb_modules/partition_init.c
index 28eab9b..5967bc8 100644
--- a/source4/dsdb/samdb/ldb_modules/partition_init.c
+++ b/source4/dsdb/samdb/ldb_modules/partition_init.c
@@ -282,6 +282,16 @@ static int new_partition_from_dn(struct ldb_context *ldb, struct partition_priva
 
 	talloc_steal((*partition), (*partition)->module);
 
+	/* if we were in a transaction then we need to start a
+	   transaction on this new partition, otherwise we'll get a
+	   transaction mismatch when we end the transaction */
+	if (data->in_transaction) {
+		struct ldb_module *next = (*partition)->module;
+		PARTITION_FIND_OP(next, start_transaction);
+
+		ret = next->ops->start_transaction(next);
+	}
+
 	return ret;
 }
 
@@ -698,17 +708,6 @@ int partition_create(struct ldb_module *module, struct ldb_request *req)
 		if (ret != LDB_SUCCESS) {
 			return ret;
 		}
-		
-		/* Start a transaction on the DB (as it won't be in one being brand new) */
-		{
-			struct ldb_module *next = partition->module;
-			PARTITION_FIND_OP(next, start_transaction);
-			
-			ret = next->ops->start_transaction(next);
-			if (ret != LDB_SUCCESS) {
-				return ret;
-			}
-		}
 	}
 	
 	ret = new_partition_set_replicated_metadata(ldb, module, last_req, data, partition);
diff --git a/source4/lib/ldb/ldb_tdb/ldb_index.c b/source4/lib/ldb/ldb_tdb/ldb_index.c
index 0d560fe..252154f 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_index.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_index.c
@@ -40,7 +40,6 @@ struct dn_list {
 
 struct ltdb_idxptr {
 	struct tdb_context *itdb;
-	bool repack;
 	int error;
 };
 
@@ -313,7 +312,7 @@ static int ltdb_index_traverse_store(struct tdb_context *tdb, TDB_DATA key, TDB_
 	}
 
 	v.data = key.dptr;
-	v.length = key.dsize;
+	v.length = strnlen((char *)key.dptr, key.dsize);
 
 	dn = ldb_dn_from_ldb_val(module, ldb, &v);
 	if (dn == NULL) {
@@ -402,6 +401,10 @@ static struct ldb_dn *ltdb_index_key(struct ldb_context *ldb,
 	if (ldb_should_b64_encode(ldb, &v)) {
 		char *vstr = ldb_base64_encode(ldb, (char *)v.data, v.length);
 		if (!vstr) return NULL;
+		/* remove trailing '=' to make it a valid DN */
+		if (vstr[strlen(vstr)-1] == '=') {
+			vstr[strlen(vstr)-1] = 0;
+		}
 		ret = ldb_dn_new_fmt(ldb, ldb, "%s:%s::%s", LTDB_INDEX, attr_folded, vstr);
 		talloc_free(vstr);
 	} else {
@@ -1402,10 +1405,34 @@ int ltdb_index_delete(struct ldb_module *module, const struct ldb_message *msg)
 */
 static int delete_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state)
 {
-	const char *dn = "DN=" LTDB_INDEX ":";
-	if (strncmp((char *)key.dptr, dn, strlen(dn)) == 0) {
-		return tdb_delete(tdb, key);
+	struct ldb_module *module = state;
+	struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
+	const char *dnstr = "DN=" LTDB_INDEX ":";
+	struct dn_list list;
+	struct ldb_dn *dn;
+	struct ldb_val v;
+	int ret;
+
+	if (strncmp((char *)key.dptr, dnstr, strlen(dnstr)) != 0) {
+		return 0;
+	}
+	/* we need to put a empty list in the internal tdb for this
+	 * index entry */
+	list.dn = NULL;
+	list.count = 0;
+	v.data = key.dptr;
+	v.length = strnlen((char *)key.dptr, key.dsize);
+
+	dn = ldb_dn_from_ldb_val(ltdb, ldb_module_get_ctx(module), &v);
+	ret = ltdb_dn_list_store(module, dn, &list);
+	if (ret != LDB_SUCCESS) {
+		ldb_asprintf_errstring(ldb_module_get_ctx(module), 
+				       "Unable to store null index for %s\n",
+				       ldb_dn_get_linearized(dn));
+		talloc_free(dn);
+		return -1;
 	}
+	talloc_free(dn);
 	return 0;
 }
 
@@ -1493,8 +1520,10 @@ int ltdb_reindex(struct ldb_module *module)
 		return LDB_ERR_OPERATIONS_ERROR;
 	}
 
-	/* first traverse the database deleting any @INDEX records */
-	ret = tdb_traverse(ltdb->tdb, delete_index, NULL);
+	/* first traverse the database deleting any @INDEX records by
+	 * putting NULL entries in the in-memory tdb
+	 */
+	ret = tdb_traverse(ltdb->tdb, delete_index, module);
 	if (ret == -1) {
 		return LDB_ERR_OPERATIONS_ERROR;
 	}
@@ -1510,9 +1539,5 @@ int ltdb_reindex(struct ldb_module *module)
 		return LDB_ERR_OPERATIONS_ERROR;
 	}
 
-	if (ltdb->idxptr) {
-		ltdb->idxptr->repack = true;
-	}
-
 	return LDB_SUCCESS;
 }
diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.c b/source4/lib/ldb/ldb_tdb/ldb_tdb.c
index 01153fe..d617586 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_tdb.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.c
@@ -200,6 +200,14 @@ static int ltdb_check_special_dn(struct ldb_module *module,
 static int ltdb_modified(struct ldb_module *module, struct ldb_dn *dn)
 {
 	int ret = LDB_SUCCESS;
+	struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);
+
+	/* only allow modifies inside a transaction, otherwise the
+	 * ldb is unsafe */
+	if (ltdb->in_transaction == 0) {
+		ldb_set_errstring(ldb_module_get_ctx(module), "ltdb modify without transaction");
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
 
 	if (ldb_dn_is_special(dn) &&
 	    (ldb_dn_check_special(dn, LTDB_INDEXLIST) ||
diff --git a/source4/scripting/python/pyglue.c b/source4/scripting/python/pyglue.c
index 71203d3..2f7023e 100644
--- a/source4/scripting/python/pyglue.c
+++ b/source4/scripting/python/pyglue.c
@@ -549,5 +549,15 @@ void initglue(void)
 	PyModule_AddObject(m, "DS_DC_FUNCTION_2003", PyInt_FromLong(DS_DC_FUNCTION_2003));
 	PyModule_AddObject(m, "DS_DC_FUNCTION_2008", PyInt_FromLong(DS_DC_FUNCTION_2008));
 	PyModule_AddObject(m, "DS_DC_FUNCTION_2008_R2", PyInt_FromLong(DS_DC_FUNCTION_2008_R2));
+
+	/* one of the most annoying things about python scripts is
+ 	   that they don't die when you hit control-C. This fixes that
+ 	   sillyness. As we do all database operations using
+ 	   transactions, this is also safe. In fact, not dying
+ 	   immediately is unsafe as we could end up treating the
+ 	   control-C exception as a different error and try to modify
+ 	   as database incorrectly 
+	*/
+	signal(SIGINT, SIG_DFL);
 }
 


-- 
Samba Shared Repository


More information about the samba-cvs mailing list