struct tevent_context *ev;
struct dreplsrv_out_operation *op;
void *ndr_struct_ptr;
+ /*
+ * Used when we have to re-try with a different NC, eg for
+ * EXOP retry or to get a current schema first
+ */
+ struct dreplsrv_partition_source_dsa *source_dsa_retry;
+ enum drsuapi_DsExtendedOperation extended_op_retry;
+ bool retry_started;
};
static void dreplsrv_op_pull_source_connect_done(struct tevent_req *subreq);
dsdb_repl_flags,
state, &objects);
- if (W_ERROR_EQUAL(status, WERR_DS_DRA_SCHEMA_MISMATCH)
- && state->op->source_dsa_retry == NULL) {
+ if (W_ERROR_EQUAL(status, WERR_DS_DRA_SCHEMA_MISMATCH)) {
struct dreplsrv_partition *p;
+ if (state->retry_started) {
+ nt_status = werror_to_ntstatus(WERR_BAD_NET_RESP);
+ DEBUG(0,("Failed to convert objects after retry: %s/%s\n",
+ win_errstr(status), nt_errstr(nt_status)));
+ tevent_req_nterror(req, nt_status);
+ return;
+ }
+
/*
* Change info sync or extended operation into a fetch
* of the schema partition, so we get all the schema
if (state->op->extended_op == DRSUAPI_EXOP_REPL_SECRET) {
- state->op->extended_op_retry = state->op->extended_op;
+ state->extended_op_retry = state->op->extended_op;
} else {
- state->op->extended_op_retry = DRSUAPI_EXOP_NONE;
+ state->extended_op_retry = DRSUAPI_EXOP_NONE;
}
state->op->extended_op = DRSUAPI_EXOP_NONE;
if (ldb_dn_compare(nc_root, partition->dn) == 0) {
- state->op->source_dsa_retry = state->op->source_dsa;
+ state->source_dsa_retry = state->op->source_dsa;
} else {
status = dreplsrv_partition_find_for_nc(service,
NULL, NULL,
}
status = dreplsrv_partition_source_dsa_by_guid(p,
&state->op->source_dsa->repsFrom1->source_dsa_obj_guid,
- &state->op->source_dsa_retry);
+ &state->source_dsa_retry);
if (!W_ERROR_IS_OK(status)) {
struct GUID_txt_buf str;
}
DEBUG(4,("Wrong schema when applying reply GetNCChanges, retrying\n"));
+ state->retry_started = true;
dreplsrv_op_pull_source_get_changes_trigger(req);
return;
* pulling the schema, then go back and do the original
* operation once we are done.
*/
- if (state->op->source_dsa_retry != NULL) {
- state->op->source_dsa = state->op->source_dsa_retry;
- state->op->extended_op = state->op->extended_op_retry;
- state->op->source_dsa_retry = NULL;
+ if (state->source_dsa_retry != NULL) {
+ state->op->source_dsa = state->source_dsa_retry;
+ state->op->extended_op = state->extended_op_retry;
+ state->source_dsa_retry = NULL;
dreplsrv_op_pull_source_get_changes_trigger(req);
return;
}