The branch, master has been updated
       via  3dd404abad878fa7e760ba50ce84fc80b82ea159 (commit)
       via  b9ce122ff27b6d80e74e5b5fa580cd1574e816d7 (commit)
      from  bd40feb1eb9e267cc8ef2e620c0e93956394fd0b (commit)

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


- Log -----------------------------------------------------------------
commit 3dd404abad878fa7e760ba50ce84fc80b82ea159
Author: Andrew Tridgell <tri...@samba.org>
Date:   Mon Sep 14 13:13:12 2009 -0700

    s4-repl: handle rename in repl_meta_data
    
    On a rename we need to update uSNChanged, and the max uSN for the
    partition

commit b9ce122ff27b6d80e74e5b5fa580cd1574e816d7
Author: Andrew Tridgell <tri...@samba.org>
Date:   Mon Sep 14 13:12:32 2009 -0700

    s4-drs: allow replication of renames
    
    a rename may have no attribute changes

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

Summary of changes:
 source4/dsdb/samdb/ldb_modules/repl_meta_data.c |   97 +++++++++++++++++++++++
 source4/rpc_server/drsuapi/getncchanges.c       |   13 ++--
 2 files changed, 104 insertions(+), 6 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c 
b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
index b9323b9..f9411fe 100644
--- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
@@ -932,6 +932,102 @@ static int replmd_modify(struct ldb_module *module, 
struct ldb_request *req)
        return ldb_next_request(module, down_req);
 }
 
+
+/*
+  handle a rename request
+
+  On a rename we need to do an extra ldb_modify which sets the
+  whenChanged and uSNChanged attributes
+ */
+static int replmd_rename(struct ldb_module *module, struct ldb_request *req)
+{
+       struct ldb_context *ldb;
+       int ret, i;
+       time_t t = time(NULL);
+       uint64_t seq_num = 0;
+       struct ldb_message *msg;
+       struct replmd_private *replmd_private = 
+               talloc_get_type(ldb_module_get_private(module), struct 
replmd_private);
+
+       /* do not manipulate our control entries */
+       if (ldb_dn_is_special(req->op.mod.message->dn)) {
+               return ldb_next_request(module, req);
+       }
+
+       ldb = ldb_module_get_ctx(module);
+
+       ldb_debug(ldb, LDB_DEBUG_TRACE, "replmd_rename\n");
+
+       /* Get a sequence number from the backend */
+       ret = ldb_sequence_number(ldb, LDB_SEQ_NEXT, &seq_num);
+       if (ret != LDB_SUCCESS) {
+               return ret;
+       }
+
+       msg = ldb_msg_new(req);
+       if (msg == NULL) {
+               ldb_oom(ldb);
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+
+       msg->dn = req->op.rename.olddn;
+
+       if (add_time_element(msg, "whenChanged", t) != LDB_SUCCESS) {
+               talloc_free(msg);
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+       msg->elements[0].flags = LDB_FLAG_MOD_REPLACE;
+
+       if (add_uint64_element(msg, "uSNChanged", seq_num) != LDB_SUCCESS) {
+               talloc_free(msg);
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+       msg->elements[1].flags = LDB_FLAG_MOD_REPLACE;
+
+       ret = ldb_modify(ldb, msg);
+       talloc_free(msg);
+       if (ret != LDB_SUCCESS) {
+               return ret;
+       }
+
+       ret = replmd_load_NCs(module);
+       if (ret != 0) {
+               return ret;
+       }
+
+       /* now update the highest uSNs of the partitions that are
+          affected. Note that two partitions could be changing */
+       for (i=0; i<replmd_private->num_ncs; i++) {
+               if (ldb_dn_compare_base(replmd_private->ncs[i].dn, 
+                                       req->op.rename.olddn) == 0) {
+                       break;
+               }
+       }
+       if (i == replmd_private->num_ncs) {
+               DEBUG(0,(__location__ ": rename olddn outside tree? %s\n",
+                        ldb_dn_get_linearized(req->op.rename.olddn)));
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+       replmd_private->ncs[i].mod_usn = seq_num;
+
+       for (i=0; i<replmd_private->num_ncs; i++) {
+               if (ldb_dn_compare_base(replmd_private->ncs[i].dn, 
+                                       req->op.rename.newdn) == 0) {
+                       break;
+               }
+       }
+       if (i == replmd_private->num_ncs) {
+               DEBUG(0,(__location__ ": rename newdn outside tree? %s\n",
+                        ldb_dn_get_linearized(req->op.rename.newdn)));
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+       replmd_private->ncs[i].mod_usn = seq_num;
+       
+       /* go on with the call chain */
+       return ldb_next_request(module, req);
+}
+
+
 static int replmd_replicated_request_error(struct replmd_replicated_request 
*ar, int ret)
 {
        return ret;
@@ -2171,6 +2267,7 @@ _PUBLIC_ const struct ldb_module_ops 
ldb_repl_meta_data_module_ops = {
        .init_context      = replmd_init,
        .add               = replmd_add,
        .modify            = replmd_modify,
+       .rename            = replmd_rename,
        .extended          = replmd_extended,
        .start_transaction = replmd_start_transaction,
        .prepare_commit    = replmd_prepare_commit,
diff --git a/source4/rpc_server/drsuapi/getncchanges.c 
b/source4/rpc_server/drsuapi/getncchanges.c
index 2754c8f..165e485 100644
--- a/source4/rpc_server/drsuapi/getncchanges.c
+++ b/source4/rpc_server/drsuapi/getncchanges.c
@@ -94,12 +94,13 @@ static WERROR get_nc_changes_build_object(struct 
drsuapi_DsReplicaObjectListItem
                attids[n] = md.ctr.ctr1.array[i].attid;
                n++;
        }
-       if (n == 0) {
-               /* nothing to send */
-               talloc_free(obj->meta_data_ctr);
-               obj->meta_data_ctr = NULL;
-               return WERR_OK;
-       }
+
+       /*
+         note that if n==0 we still need to send the change, as it
+         could be a rename, which changes the uSNChanged, but not any
+         of the replicated attributes
+        */
+
        obj->meta_data_ctr->count = n;
 
        obj->object.identifier = talloc(obj, struct 
drsuapi_DsReplicaObjectIdentifier);


-- 
Samba Shared Repository

Reply via email to