s4-repl: added a workaround for WERR_DS_DRA_NO_REPLICA DsReplicaSync errors
authorAndrew Tridgell <tridge@samba.org>
Tue, 27 Apr 2010 02:17:08 +0000 (12:17 +1000)
committerAndrew Tridgell <tridge@samba.org>
Tue, 27 Apr 2010 05:24:40 +0000 (15:24 +1000)
The 0xc0002104/WERR_DS_DRA_NO_REPLICA seems to be spurious, and can be
avoided by setting DRSUAPI_DRS_SYNC_ALL in the DsReplicaSync request.

We need to investigate this further, and find out from MS why this is
sometimes being sent, even when the target DC has the right repsFrom
entries

source4/dsdb/repl/drepl_notify.c
source4/dsdb/repl/drepl_service.h

index 00075e8ca89417008e40811c9565cfaa55f08fb1..0145b2767abc2c3188dc544bd4b4b92391ea51f9 100644 (file)
@@ -120,6 +120,10 @@ static void dreplsrv_op_notify_replica_sync_trigger(struct tevent_req *req)
                DRSUAPI_DRS_ASYNC_OP |
                DRSUAPI_DRS_UPDATE_NOTIFICATION |
                DRSUAPI_DRS_WRIT_REP;
+       if (state->op->service->syncall_workaround) {
+               DEBUG(3,("sending DsReplicaSync with SYNC_ALL workaround\n"));
+               r->in.req->req1.options |= DRSUAPI_DRS_SYNC_ALL;
+       }
 
        if (state->op->is_urgent) {
                r->in.req->req1.options |= DRSUAPI_DRS_SYNC_URGENT;
@@ -127,6 +131,10 @@ static void dreplsrv_op_notify_replica_sync_trigger(struct tevent_req *req)
 
        state->ndr_struct_ptr = r;
 
+       if (DEBUGLVL(10)) {
+               NDR_PRINT_IN_DEBUG(drsuapi_DsReplicaSync, r);
+       }
+
        subreq = dcerpc_drsuapi_DsReplicaSync_r_send(state,
                                                     state->ev,
                                                     drsuapi->drsuapi_handle,
@@ -185,10 +193,17 @@ static void dreplsrv_notify_op_callback(struct tevent_req *subreq)
        status = dreplsrv_op_notify_recv(subreq);
        TALLOC_FREE(subreq);
        if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(0,("dreplsrv_notify: Failed to send DsReplicaSync to %s for %s - %s\n",
+               WERROR werr;
+               werr = ntstatus_to_werror(status);
+
+               DEBUG(0,("dreplsrv_notify: Failed to send DsReplicaSync to %s for %s - %s : %s\n",
                         op->source_dsa->repsFrom1->other_info->dns_name,
                         ldb_dn_get_linearized(op->source_dsa->partition->dn),
-                        nt_errstr(status)));
+                        nt_errstr(status), win_errstr(werr)));
+               if (W_ERROR_EQUAL(werr, WERR_DS_DRA_NO_REPLICA)) {
+                       DEBUG(0,("Enabling SYNC_ALL workaround\n"));
+                       op->service->syncall_workaround = true;
+               }
        } else {
                DEBUG(2,("dreplsrv_notify: DsReplicaSync OK for %s\n",
                         op->source_dsa->repsFrom1->other_info->dns_name));
index 7813f92cbe8fc8cf427b4a35c26eb658ceaae39c..88be76912867791871d7ea0b8e21bfacd9cfff5e 100644 (file)
@@ -213,6 +213,8 @@ struct dreplsrv_service {
                bool in_progress;
                struct dreplsrv_partition_source_dsa *rid_manager_source_dsa;
        } ridalloc;
+
+       bool syncall_workaround;
 };
 
 #include "dsdb/repl/drepl_out_helpers.h"