[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