s4-repl: check that a DsGetNCChanges is a continuation, and fix sorting
authorAndrew Tridgell <tridge@samba.org>
Tue, 13 Oct 2009 02:09:07 +0000 (13:09 +1100)
committerAndrew Tridgell <tridge@samba.org>
Tue, 13 Oct 2009 02:09:07 +0000 (13:09 +1100)
When we indicate that a getncchanges request is not complete, we set
the more_data flag to true in the response. The client usually then
asks for the next block of data. If the client decides it wants to
skip that replication and do a different replication then we need to
make sure that the next call is in fact a continuation of the existing
call, and not a new call.

This relies on returning the results sorted by uSNChanged, as the
client uses the tmp_highest_usn in each result to see if progress is
being made.

source4/rpc_server/drsuapi/drsutil.c
source4/rpc_server/drsuapi/getncchanges.c

index 1b4c28c4aba8b2022fabb35f69cc3f09438e2486..752861cc26272c4877a326f0f242183a0676f945 100644 (file)
@@ -98,7 +98,7 @@ int drsuapi_search_with_extended_dn(struct ldb_context *ldb,
                sort_control[0] = talloc(req, struct ldb_server_sort_control);
                sort_control[0]->attributeName = sort_attrib;
                sort_control[0]->orderingRule = NULL;
-               sort_control[0]->reverse = 1;
+               sort_control[0]->reverse = 0;
                sort_control[1] = NULL;
 
                ret = ldb_request_add_control(req, LDB_CONTROL_SERVER_SORT_OID, true, sort_control);
index 5713d41f84b63a5686f8f54c875e2361d0b87fe7..ae1b2e61ebfae679d569d8b60ea00cd6a2701d76 100644 (file)
@@ -411,7 +411,7 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_
                search_filter = talloc_asprintf(mem_ctx,
                                                "(uSNChanged>=%llu)",
                                                (unsigned long long)(getnc_state->min_usn+1));
-               
+       
                if (r->in.req->req8.replica_flags & DRSUAPI_DS_REPLICA_NEIGHBOUR_CRITICAL_ONLY) {
                        search_filter = talloc_asprintf(mem_ctx,
                                                        "(&%s(isCriticalSystemObject=TRUE))",
@@ -427,11 +427,24 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_
                         ldb_dn_get_linearized(getnc_state->ncRoot_dn), search_filter));
                ret = drsuapi_search_with_extended_dn(b_state->sam_ctx, getnc_state, &getnc_state->site_res,
                                                      getnc_state->ncRoot_dn, scope, attrs,
-                                                     "distinguishedName",
+                                                     "uSNChanged",
                                                      search_filter);
                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 */
@@ -525,7 +538,7 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_
                b_state->getncchanges_state = NULL;
        }
 
-       DEBUG(3,("DsGetNCChanges with uSNChanged >= %llu on %s gave %u objects\n", 
+       DEBUG(2,("DsGetNCChanges with uSNChanged >= %llu on %s gave %u objects\n", 
                 (unsigned long long)(r->in.req->req8.highwatermark.highest_usn+1),
                 ncRoot->dn, r->out.ctr->ctr6.object_count));