The branch, master has been updated
       via  8d7a43f... s4-drs: fixed UDV and overlapping sync calls in DRS
       via  b65b887... s4-drs: fixed updating of uSNChanged in replmd_modify
      from  a2929a6... s3:build: remove redundant qnx block size definition

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


- Log -----------------------------------------------------------------
commit 8d7a43fed709b0ae4baaa861c30f2ee89a423dbb
Author: Andrew Tridgell <tri...@samba.org>
Date:   Thu Dec 3 09:19:55 2009 +1100

    s4-drs: fixed UDV and overlapping sync calls in DRS
    
    When windows abandons a DRS sync, it will sometimes re-use the same bind 
handle for
    a new sync. This means we need to check the DN of the sync and blank the 
getnc_state
    if the DN has changed.
    
    This also fixes the UDV to use the highest uSN for the partition, not for
    the whole SAM.

commit b65b88740c4920232a02f8e3c535e31656697246
Author: Andrew Tridgell <tri...@samba.org>
Date:   Wed Dec 2 17:14:40 2009 +1100

    s4-drs: fixed updating of uSNChanged in replmd_modify
    
    Updating of uSNChanged broke in a recent change

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

Summary of changes:
 source4/dsdb/samdb/ldb_modules/repl_meta_data.c |    5 +-
 source4/rpc_server/drsuapi/getncchanges.c       |   82 ++++++++++++-----------
 2 files changed, 44 insertions(+), 43 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 bfde2df..9ed70d9 100644
--- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
@@ -837,7 +837,6 @@ static int replmd_modify(struct ldb_module *module, struct 
ldb_request *req)
        struct ldb_message *msg;
        struct ldb_result *res;
        time_t t = time(NULL);
-       uint64_t seq_num = 0;
        int ret;
 
        /* do not manipulate our control entries */
@@ -900,13 +899,13 @@ static int replmd_modify(struct ldb_module *module, 
struct ldb_request *req)
 
        /* we only change whenChanged and uSNChanged if the seq_num
           has changed */
-       if (seq_num != 0) {
+       if (ac->seq_num != 0) {
                if (add_time_element(msg, "whenChanged", t) != LDB_SUCCESS) {
                        talloc_free(ac);
                        return ret;
                }
 
-               if (add_uint64_element(msg, "uSNChanged", seq_num) != 
LDB_SUCCESS) {
+               if (add_uint64_element(msg, "uSNChanged", ac->seq_num) != 
LDB_SUCCESS) {
                        talloc_free(ac);
                        return ret;
                }
diff --git a/source4/rpc_server/drsuapi/getncchanges.c 
b/source4/rpc_server/drsuapi/getncchanges.c
index 8155bef..c90c92a 100644
--- a/source4/rpc_server/drsuapi/getncchanges.c
+++ b/source4/rpc_server/drsuapi/getncchanges.c
@@ -132,6 +132,18 @@ static WERROR get_nc_changes_build_object(struct 
drsuapi_DsReplicaObjectListItem
 
        obj->meta_data_ctr = talloc(obj, struct drsuapi_DsReplicaMetaDataCtr);
        attids = talloc_array(obj, uint32_t, md.ctr.ctr1.count);
+
+       obj->object.identifier = talloc(obj, struct 
drsuapi_DsReplicaObjectIdentifier);
+       obj_dn = ldb_msg_find_attr_as_dn(sam_ctx, obj, msg, 
"distinguishedName");
+       obj->object.identifier->dn = ldb_dn_get_linearized(obj_dn);
+       obj->object.identifier->guid = samdb_result_guid(msg, "objectGUID");
+       sid = samdb_result_dom_sid(obj, msg, "objectSid");
+       if (sid) {
+               dom_sid_split_rid(NULL, sid, NULL, &rid);
+               obj->object.identifier->sid = *sid;
+       } else {
+               ZERO_STRUCT(obj->object.identifier->sid);
+       }
        
        obj->meta_data_ctr->meta_data = talloc_array(obj, struct 
drsuapi_DsReplicaMetaData, md.ctr.ctr1.count);
        for (n=i=0; i<md.ctr.ctr1.count; i++) {
@@ -159,18 +171,6 @@ static WERROR get_nc_changes_build_object(struct 
drsuapi_DsReplicaObjectListItem
 
        obj->meta_data_ctr->count = n;
 
-       obj->object.identifier = talloc(obj, struct 
drsuapi_DsReplicaObjectIdentifier);
-       obj_dn = ldb_msg_find_attr_as_dn(sam_ctx, obj, msg, 
"distinguishedName");
-       obj->object.identifier->dn = ldb_dn_get_linearized(obj_dn);
-       obj->object.identifier->guid = samdb_result_guid(msg, "objectGUID");
-       sid = samdb_result_dom_sid(obj, msg, "objectSid");
-       if (sid) {
-               dom_sid_split_rid(NULL, sid, NULL, &rid);
-               obj->object.identifier->sid = *sid;
-       } else {
-               ZERO_STRUCT(obj->object.identifier->sid);
-       }
-
        obj->object.flags = DRSUAPI_DS_REPLICA_OBJECT_FROM_MASTER;
        obj->object.attribute_ctr.num_attributes = obj->meta_data_ctr->count;
        obj->object.attribute_ctr.attributes = talloc_array(obj, struct 
drsuapi_DsReplicaAttribute,
@@ -193,7 +193,8 @@ static WERROR get_nc_changes_build_object(struct 
drsuapi_DsReplicaObjectListItem
 
                el = ldb_msg_find_element(msg, sa->lDAPDisplayName);
                if (el == NULL) {
-                       DEBUG(0,("No element '%s' for attributeID %u in 
message\n", 
+                       /* this happens for attributes that have been removed */
+                       DEBUG(5,("No element '%s' for attributeID %u in 
message\n",
                                 sa->lDAPDisplayName, attids[i]));
                        ZERO_STRUCT(obj->object.attribute_ctr.attributes[i]);
                        obj->object.attribute_ctr.attributes[i].attid = 
attids[i];
@@ -275,14 +276,13 @@ static WERROR load_udv(struct ldb_context *sam_ctx, 
TALLOC_CTX *mem_ctx,
  */
 static WERROR get_nc_changes_udv(struct ldb_context *sam_ctx,
                                 struct ldb_dn *ncRoot_dn,
-                                struct drsuapi_DsReplicaCursor2CtrEx *udv)
+                                struct drsuapi_DsReplicaCursor2CtrEx *udv,
+                                uint64_t highestUSN)
 {
        WERROR werr;
        struct drsuapi_DsReplicaCursor2 *tmp_cursor;
-       uint64_t highest_commited_usn;
        NTTIME now;
        time_t t = time(NULL);
-       int ret;
        struct replUpToDateVectorBlob ouv;
 
        werr = load_udv(sam_ctx, udv, ncRoot_dn, &ouv);
@@ -290,14 +290,9 @@ static WERROR get_nc_changes_udv(struct ldb_context 
*sam_ctx,
                return werr;
        }
        
-       ret = ldb_sequence_number(sam_ctx, LDB_SEQ_HIGHEST_SEQ, 
&highest_commited_usn);
-       if (ret != LDB_SUCCESS) {
-               return WERR_DS_DRA_INTERNAL_ERROR;
-       }
-
        tmp_cursor = talloc(udv, struct drsuapi_DsReplicaCursor2);
        tmp_cursor->source_dsa_invocation_id = 
*(samdb_ntds_invocation_id(sam_ctx));
-       tmp_cursor->highest_usn = highest_commited_usn;
+       tmp_cursor->highest_usn = highestUSN;
        unix_to_nt_time(&now, t);
        tmp_cursor->last_sync_success = now;
 
@@ -321,7 +316,8 @@ struct drsuapi_getncchanges_state {
        struct ldb_result *site_res;
        uint32_t num_sent;
        struct ldb_dn *ncRoot_dn;
-       uint32_t min_usn;
+       uint64_t min_usn;
+       uint64_t highest_usn;
 };
 
 /* 
@@ -386,6 +382,8 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct 
dcesrv_call_state *dce_call, TALLOC_
        req8 = &r->in.req->req8;
 
         /* Perform access checks. */
+       /* TODO: we need to support a sync on a specific non-root
+        * DN. We'll need to find the real partition root here */
        ncRoot = req8->naming_context;
        if (ncRoot == NULL) {
                DEBUG(0,(__location__ ": Request for DsGetNCChanges with no 
NC\n"));
@@ -413,6 +411,19 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct 
dcesrv_call_state *dce_call, TALLOC_
        }
 
        getnc_state = b_state->getncchanges_state;
+
+       /* see if a previous replication has been abandoned */
+       if (getnc_state) {
+               struct ldb_dn *new_dn = ldb_dn_new(getnc_state, 
b_state->sam_ctx, ncRoot->dn);
+               if (ldb_dn_compare(new_dn, getnc_state->ncRoot_dn) != 0) {
+                       DEBUG(0,(__location__ ": DsGetNCChanges 2nd replication 
on different DN %s %s\n",
+                                ldb_dn_get_linearized(new_dn),
+                                
ldb_dn_get_linearized(getnc_state->ncRoot_dn)));
+                       talloc_free(getnc_state);
+                       getnc_state = NULL;
+               }
+       }
+
        if (getnc_state == NULL) {
                getnc_state = talloc_zero(b_state, struct 
drsuapi_getncchanges_state);
                if (getnc_state == NULL) {
@@ -456,7 +467,6 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct 
dcesrv_call_state *dce_call, TALLOC_
                                                        search_filter);
                }
                
-               getnc_state->ncRoot_dn = ldb_dn_new(getnc_state, 
b_state->sam_ctx, ncRoot->dn);
                if (req8->replica_flags & 
DRSUAPI_DS_REPLICA_NEIGHBOUR_ASYNC_REP) {
                        scope = LDB_SCOPE_BASE;
                }
@@ -470,19 +480,6 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct 
dcesrv_call_state *dce_call, TALLOC_
                if (ret != LDB_SUCCESS) {
                        return WERR_DS_DRA_INTERNAL_ERROR;
                }
-       } else {
-               /* check that this request is for the same NC as the previous 
one */
-               struct ldb_dn *dn;
-               dn = ldb_dn_new(getnc_state, b_state->sam_ctx, ncRoot->dn);
-               if (!dn) {
-                       return WERR_NOMEM;
-               }
-               if (ldb_dn_compare(dn, getnc_state->ncRoot_dn) != 0) {
-                       DEBUG(0,(__location__ ": DsGetNCChanges 2nd replication 
on different DN %s %s\n",
-                                ldb_dn_get_linearized(dn),
-                                
ldb_dn_get_linearized(getnc_state->ncRoot_dn)));
-                       return WERR_DS_DRA_BAD_NC;
-               }
        }
 
        /* Prefix mapping */
@@ -529,6 +526,9 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct 
dcesrv_call_state *dce_call, TALLOC_
                if (uSN > r->out.ctr->ctr6.new_highwatermark.tmp_highest_usn) {
                        r->out.ctr->ctr6.new_highwatermark.tmp_highest_usn = 
uSN;
                }
+               if (uSN > getnc_state->highest_usn) {
+                       getnc_state->highest_usn = uSN;
+               }
 
                werr = get_nc_changes_build_object(obj, 
getnc_state->site_res->msgs[i], 
                                                   b_state->sam_ctx, 
getnc_state->ncRoot_dn, 
@@ -590,7 +590,8 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct 
dcesrv_call_state *dce_call, TALLOC_
                r->out.ctr->ctr6.new_highwatermark.highest_usn = 
r->out.ctr->ctr6.new_highwatermark.tmp_highest_usn;
 
                werr = get_nc_changes_udv(b_state->sam_ctx, 
getnc_state->ncRoot_dn, 
-                                         r->out.ctr->ctr6.uptodateness_vector);
+                                         r->out.ctr->ctr6.uptodateness_vector,
+                                         getnc_state->highest_usn);
                if (!W_ERROR_IS_OK(werr)) {
                        return werr;
                }
@@ -599,10 +600,11 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct 
dcesrv_call_state *dce_call, TALLOC_
                b_state->getncchanges_state = NULL;
        }
 
-       DEBUG(2,("DsGetNCChanges with uSNChanged >= %llu flags 0x%08x on %s 
gave %u objects\n", 
+       DEBUG(2,("DsGetNCChanges with uSNChanged >= %llu flags 0x%08x on %s 
gave %u objects (done %d/%d)\n",
                 (unsigned long long)(req8->highwatermark.highest_usn+1),
                 req8->replica_flags,
-                ncRoot->dn, r->out.ctr->ctr6.object_count));
+                ncRoot->dn, r->out.ctr->ctr6.object_count,
+                i, r->out.ctr->ctr6.more_data?getnc_state->site_res->count:i));
 
        return WERR_OK;
 }


-- 
Samba Shared Repository

Reply via email to