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 <tri...@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 <tri...@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 <tri...@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 <tri...@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 <tri...@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 <tri...@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 <tri...@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

Reply via email to