mirror of
https://github.com/samba-team/samba.git
synced 2025-01-26 10:04:02 +03:00
s4-drs: calculate and send a uptodateness_vector with replication requests
This stops us getting objects changes twice if they came via an indirect path.
This commit is contained in:
parent
39730ac302
commit
7010fad4ea
@ -261,6 +261,7 @@ static void dreplsrv_op_pull_source_get_changes_trigger(struct tevent_req *req)
|
||||
struct dreplsrv_drsuapi_connection *drsuapi = state->op->source_dsa->conn->drsuapi;
|
||||
struct rpc_request *rreq;
|
||||
struct drsuapi_DsGetNCChanges *r;
|
||||
struct drsuapi_DsReplicaCursorCtrEx *uptodateness_vector;
|
||||
|
||||
r = talloc(state, struct drsuapi_DsGetNCChanges);
|
||||
if (tevent_req_nomem(r, req)) {
|
||||
@ -280,6 +281,12 @@ static void dreplsrv_op_pull_source_get_changes_trigger(struct tevent_req *req)
|
||||
return;
|
||||
}
|
||||
|
||||
if (partition->uptodatevector_ex.count == 0) {
|
||||
uptodateness_vector = NULL;
|
||||
} else {
|
||||
uptodateness_vector = &partition->uptodatevector_ex;
|
||||
}
|
||||
|
||||
r->in.bind_handle = &drsuapi->bind_handle;
|
||||
if (drsuapi->remote_info28.supported_extensions & DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V8) {
|
||||
r->in.level = 8;
|
||||
@ -287,7 +294,7 @@ static void dreplsrv_op_pull_source_get_changes_trigger(struct tevent_req *req)
|
||||
r->in.req->req8.source_dsa_invocation_id= rf1->source_dsa_invocation_id;
|
||||
r->in.req->req8.naming_context = &partition->nc;
|
||||
r->in.req->req8.highwatermark = rf1->highwatermark;
|
||||
r->in.req->req8.uptodateness_vector = NULL;/*&partition->uptodatevector_ex;*/
|
||||
r->in.req->req8.uptodateness_vector = uptodateness_vector;
|
||||
r->in.req->req8.replica_flags = rf1->replica_flags;
|
||||
r->in.req->req8.max_object_count = 133;
|
||||
r->in.req->req8.max_ndr_size = 1336811;
|
||||
@ -303,7 +310,7 @@ static void dreplsrv_op_pull_source_get_changes_trigger(struct tevent_req *req)
|
||||
r->in.req->req5.source_dsa_invocation_id= rf1->source_dsa_invocation_id;
|
||||
r->in.req->req5.naming_context = &partition->nc;
|
||||
r->in.req->req5.highwatermark = rf1->highwatermark;
|
||||
r->in.req->req5.uptodateness_vector = NULL;/*&partition->uptodatevector_ex;*/
|
||||
r->in.req->req5.uptodateness_vector = uptodateness_vector;
|
||||
r->in.req->req5.replica_flags = rf1->replica_flags;
|
||||
r->in.req->req5.max_object_count = 133;
|
||||
r->in.req->req5.max_ndr_size = 1336770;
|
||||
@ -311,6 +318,10 @@ static void dreplsrv_op_pull_source_get_changes_trigger(struct tevent_req *req)
|
||||
r->in.req->req5.fsmo_info = state->op->fsmo_info;
|
||||
}
|
||||
|
||||
#if 0
|
||||
NDR_PRINT_IN_DEBUG(drsuapi_DsGetNCChanges, r);
|
||||
#endif
|
||||
|
||||
rreq = dcerpc_drsuapi_DsGetNCChanges_send(drsuapi->pipe, r, r);
|
||||
if (tevent_req_nomem(rreq, req)) {
|
||||
return;
|
||||
|
@ -188,6 +188,65 @@ static WERROR dreplsrv_partition_add_source_dsa(struct dreplsrv_service *s,
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
convert from one udv format to the other
|
||||
*/
|
||||
static WERROR udv_convert(TALLOC_CTX *mem_ctx,
|
||||
const struct replUpToDateVectorCtr2 *udv,
|
||||
struct drsuapi_DsReplicaCursorCtrEx *udv_ex)
|
||||
{
|
||||
int i;
|
||||
|
||||
udv_ex->version = 2;
|
||||
udv_ex->reserved1 = 0;
|
||||
udv_ex->reserved2 = 0;
|
||||
udv_ex->count = udv->count;
|
||||
udv_ex->cursors = talloc_array(mem_ctx, struct drsuapi_DsReplicaCursor, udv->count);
|
||||
W_ERROR_HAVE_NO_MEMORY(udv_ex->cursors);
|
||||
|
||||
for (i=0; i<udv->count; i++) {
|
||||
udv_ex->cursors[i].source_dsa_invocation_id = udv->cursors[i].source_dsa_invocation_id;
|
||||
udv_ex->cursors[i].highest_usn = udv->cursors[i].highest_usn;
|
||||
}
|
||||
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
add our local UDV element for the partition
|
||||
*/
|
||||
static WERROR add_local_udv(struct dreplsrv_service *s,
|
||||
struct dreplsrv_partition *p,
|
||||
const struct GUID *our_invocation_id,
|
||||
struct drsuapi_DsReplicaCursorCtrEx *udv)
|
||||
{
|
||||
int ret;
|
||||
uint64_t highest_usn;
|
||||
int i;
|
||||
|
||||
ret = dsdb_load_partition_usn(s->samdb, p->dn, &highest_usn);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
/* nothing to add */
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
for (i=0; i<udv->count; i++) {
|
||||
if (GUID_equal(our_invocation_id, &udv->cursors[i].source_dsa_invocation_id)) {
|
||||
udv->cursors[i].highest_usn = highest_usn;
|
||||
return WERR_OK;
|
||||
}
|
||||
}
|
||||
|
||||
udv->cursors = talloc_realloc(p, udv->cursors, struct drsuapi_DsReplicaCursor, udv->count+1);
|
||||
W_ERROR_HAVE_NO_MEMORY(udv->cursors);
|
||||
|
||||
udv->cursors[udv->count].source_dsa_invocation_id = *our_invocation_id;
|
||||
udv->cursors[udv->count].highest_usn = highest_usn;
|
||||
udv->count++;
|
||||
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
static WERROR dreplsrv_refresh_partition(struct dreplsrv_service *s,
|
||||
struct dreplsrv_partition *p)
|
||||
{
|
||||
@ -232,6 +291,11 @@ static WERROR dreplsrv_refresh_partition(struct dreplsrv_service *s,
|
||||
talloc_free(nc_sid);
|
||||
}
|
||||
|
||||
talloc_free(p->uptodatevector.cursors);
|
||||
talloc_free(p->uptodatevector_ex.cursors);
|
||||
ZERO_STRUCT(p->uptodatevector);
|
||||
ZERO_STRUCT(p->uptodatevector_ex);
|
||||
|
||||
ouv_value = ldb_msg_find_ldb_val(r->msgs[0], "replUpToDateVector");
|
||||
if (ouv_value) {
|
||||
enum ndr_err_code ndr_err;
|
||||
@ -251,15 +315,15 @@ static WERROR dreplsrv_refresh_partition(struct dreplsrv_service *s,
|
||||
|
||||
p->uptodatevector.count = ouv.ctr.ctr2.count;
|
||||
p->uptodatevector.reserved = ouv.ctr.ctr2.reserved;
|
||||
talloc_free(p->uptodatevector.cursors);
|
||||
p->uptodatevector.cursors = talloc_steal(p, ouv.ctr.ctr2.cursors);
|
||||
|
||||
status = udv_convert(p, &p->uptodatevector, &p->uptodatevector_ex);
|
||||
W_ERROR_NOT_OK_RETURN(status);
|
||||
|
||||
status = add_local_udv(s, p, samdb_ntds_invocation_id(s->samdb), &p->uptodatevector_ex);
|
||||
W_ERROR_NOT_OK_RETURN(status);
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: add our own uptodatevector cursor
|
||||
*/
|
||||
|
||||
|
||||
orf_el = ldb_msg_find_element(r->msgs[0], "repsFrom");
|
||||
if (orf_el) {
|
||||
for (i=0; i < orf_el->num_values; i++) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user