diff options
Diffstat (limited to 'source3/libnet')
-rw-r--r-- | source3/libnet/libnet_dssync.c | 44 |
1 files changed, 42 insertions, 2 deletions
diff --git a/source3/libnet/libnet_dssync.c b/source3/libnet/libnet_dssync.c index 1bec903427..54bdbb7b22 100644 --- a/source3/libnet/libnet_dssync.c +++ b/source3/libnet/libnet_dssync.c @@ -374,6 +374,10 @@ static NTSTATUS libnet_dssync_process(TALLOC_CTX *mem_ctx, struct drsuapi_DsGetNCChangesCtr1 *ctr1 = NULL; struct drsuapi_DsGetNCChangesCtr6 *ctr6 = NULL; + struct replUpToDateVectorBlob *old_utdv = NULL; + struct drsuapi_DsReplicaCursorCtrEx cursors; + struct drsuapi_DsReplicaCursorCtrEx *pcursors = NULL; + struct replUpToDateVectorBlob new_utdv; int32_t out_level = 0; int y; uint32_t replica_flags = DRSUAPI_DS_REPLICA_NEIGHBOUR_WRITEABLE | @@ -389,7 +393,7 @@ static NTSTATUS libnet_dssync_process(TALLOC_CTX *mem_ctx, nc.guid = GUID_zero(); nc.sid = null_sid; - status = ctx->ops->startup(ctx, mem_ctx, NULL); + status = ctx->ops->startup(ctx, mem_ctx, &old_utdv); if (!NT_STATUS_IS_OK(status)) { ctx->error_message = talloc_asprintf(mem_ctx, "Failed to call startup operation: %s", @@ -397,6 +401,30 @@ static NTSTATUS libnet_dssync_process(TALLOC_CTX *mem_ctx, goto out; } + if (old_utdv) { + pcursors = &cursors; + ZERO_STRUCTP(pcursors); + + switch (old_utdv->version) { + case 1: + pcursors->count = old_utdv->ctr.ctr1.count; + pcursors->cursors = old_utdv->ctr.ctr1.cursors; + break; + case 2: + pcursors->count = old_utdv->ctr.ctr2.count; + pcursors->cursors = talloc_array(mem_ctx, + struct drsuapi_DsReplicaCursor, + pcursors->count); + for (y = 0; y < pcursors->count; y++) { + pcursors->cursors[y].source_dsa_invocation_id = + old_utdv->ctr.ctr2.cursors[y].source_dsa_invocation_id; + pcursors->cursors[y].highest_usn = + old_utdv->ctr.ctr2.cursors[y].highest_usn; + } + break; + } + } + if (ctx->remote_info28.supported_extensions & DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V8) { @@ -405,12 +433,14 @@ static NTSTATUS libnet_dssync_process(TALLOC_CTX *mem_ctx, req.req8.replica_flags = replica_flags; req.req8.max_object_count = 402; req.req8.max_ndr_size = 402116; + req.req8.uptodateness_vector = pcursors; } else { level = 5; req.req5.naming_context = &nc; req.req5.replica_flags = replica_flags; req.req5.max_object_count = 402; req.req5.max_ndr_size = 402116; + req.req5.uptodateness_vector = pcursors; } for (y=0; ;y++) { @@ -491,6 +521,11 @@ static NTSTATUS libnet_dssync_process(TALLOC_CTX *mem_ctx, if (!last_query) { continue; } + + ZERO_STRUCT(new_utdv); + new_utdv.version = 1; + new_utdv.ctr.ctr1.count = ctr1->uptodateness_vector->count; + new_utdv.ctr.ctr1.cursors = ctr1->uptodateness_vector->cursors; } if (level_out == 6) { @@ -532,9 +567,14 @@ static NTSTATUS libnet_dssync_process(TALLOC_CTX *mem_ctx, if (!last_query) { continue; } + + ZERO_STRUCT(new_utdv); + new_utdv.version = 2; + new_utdv.ctr.ctr2.count = ctr6->uptodateness_vector->count; + new_utdv.ctr.ctr2.cursors = ctr6->uptodateness_vector->cursors; } - status = ctx->ops->finish(ctx, mem_ctx, NULL); + status = ctx->ops->finish(ctx, mem_ctx, &new_utdv); if (!NT_STATUS_IS_OK(status)) { ctx->error_message = talloc_asprintf(mem_ctx, "Failed to call finishing operation: %s", |