X-Git-Url: http://git.samba.org/?a=blobdiff_plain;f=source4%2Fdsdb%2Frepl%2Fdrepl_service.c;h=0951a0f0cc0f1c52d62824c0a7753d2be859ba1f;hb=51289a6f9bf25189386dd3f66b5b547f02348508;hp=a85750b3c1eff51a6e8037a11045d1fabeae0bca;hpb=736d36a9487336ca8bc47fba4c7565f9d37e06c5;p=samba.git diff --git a/source4/dsdb/repl/drepl_service.c b/source4/dsdb/repl/drepl_service.c index a85750b3c1e..0951a0f0cc0 100644 --- a/source4/dsdb/repl/drepl_service.c +++ b/source4/dsdb/repl/drepl_service.c @@ -26,13 +26,17 @@ #include "smbd/service.h" #include "lib/events/events.h" #include "dsdb/repl/drepl_service.h" -#include "lib/ldb/include/ldb_errors.h" +#include #include "../lib/util/dlinklist.h" #include "librpc/gen_ndr/ndr_misc.h" #include "librpc/gen_ndr/ndr_drsuapi.h" #include "librpc/gen_ndr/ndr_drsblobs.h" #include "librpc/gen_ndr/ndr_irpc.h" #include "param/param.h" +#include "libds/common/roles.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_DRS_REPL /** * Call-back data for _drepl_replica_sync_done_cb() @@ -53,7 +57,7 @@ static WERROR dreplsrv_init_creds(struct dreplsrv_service *service) { service->system_session_info = system_session(service->task->lp_ctx); if (service->system_session_info == NULL) { - return WERR_NOMEM; + return WERR_NOT_ENOUGH_MEMORY; } return WERR_OK; @@ -145,7 +149,7 @@ static void _drepl_replica_sync_done_cb(struct dreplsrv_service *service, struct drsuapi_DsReplicaSync *r = data->r; /* store last bad result */ - if (W_ERROR_IS_OK(werr)) { + if (!W_ERROR_IS_OK(werr)) { data->werr_last_failure = werr; } @@ -170,6 +174,7 @@ static void _drepl_replica_sync_done_cb(struct dreplsrv_service *service, static WERROR _drepl_schedule_replication(struct dreplsrv_service *service, struct dreplsrv_partition_source_dsa *dsa, struct drsuapi_DsReplicaObjectIdentifier *nc, + uint32_t rep_options, struct drepl_replica_sync_cb_data *data, TALLOC_CTX *mem_ctx) { @@ -181,7 +186,7 @@ static WERROR _drepl_schedule_replication(struct dreplsrv_service *service, } /* schedule replication item */ - werr = dreplsrv_schedule_partition_pull_source(service, dsa, + werr = dreplsrv_schedule_partition_pull_source(service, dsa, rep_options, DRSUAPI_EXOP_NONE, 0, fn_callback, data); if (!W_ERROR_IS_OK(werr)) { @@ -264,7 +269,7 @@ static NTSTATUS drepl_replica_sync(struct irpc_message *msg, } else { cb_data = talloc_zero(msg, struct drepl_replica_sync_cb_data); if (!cb_data) { - REPLICA_SYNC_FAIL("Not enought memory", + REPLICA_SYNC_FAIL("Not enough memory", WERR_DS_DRA_INTERNAL_ERROR); } @@ -277,7 +282,8 @@ static NTSTATUS drepl_replica_sync(struct irpc_message *msg, if (req1->options & DRSUAPI_DRS_SYNC_ALL) { for (dsa = p->sources; dsa; dsa = dsa->next) { /* schedule replication item */ - werr = _drepl_schedule_replication(service, dsa, nc, cb_data, msg); + werr = _drepl_schedule_replication(service, dsa, nc, + req1->options, cb_data, msg); if (!W_ERROR_IS_OK(werr)) { REPLICA_SYNC_FAIL("_drepl_schedule_replication() failed", werr); @@ -304,6 +310,16 @@ static NTSTATUS drepl_replica_sync(struct irpc_message *msg, werr = dreplsrv_partition_source_dsa_by_guid(p, &req1->source_dsa_guid, &dsa); + if (W_ERROR_EQUAL(werr, WERR_DS_DRA_NO_REPLICA)) { + /* we don't have this source setup as + a replication partner. Create a + temporary dsa structure for this + replication */ + werr = dreplsrv_partition_source_dsa_temporary(p, + msg, + &req1->source_dsa_guid, + &dsa); + } } if (!W_ERROR_IS_OK(werr)) { REPLICA_SYNC_FAIL("Failed to locate source DSA for given NC", @@ -311,7 +327,8 @@ static NTSTATUS drepl_replica_sync(struct irpc_message *msg, } /* schedule replication item */ - werr = _drepl_schedule_replication(service, dsa, nc, cb_data, msg); + werr = _drepl_schedule_replication(service, dsa, nc, + req1->options, cb_data, msg); if (!W_ERROR_IS_OK(werr)) { REPLICA_SYNC_FAIL("_drepl_schedule_replication() failed", werr); @@ -321,8 +338,11 @@ static NTSTATUS drepl_replica_sync(struct irpc_message *msg, /* if we got here, everything is OK */ r->out.result = WERR_OK; - /* force execution of scheduled replications */ - dreplsrv_run_pending_ops(service); + /* + * schedule replication event to force + * replication as soon as possible + */ + dreplsrv_pendingops_schedule_pull_now(service); done: return NT_STATUS_OK; @@ -346,15 +366,6 @@ static NTSTATUS dreplsrv_refresh(struct irpc_message *msg, return NT_STATUS_OK; } -static NTSTATUS drepl_take_FSMO_role(struct irpc_message *msg, - struct drepl_takeFSMORole *r) -{ - struct dreplsrv_service *service = talloc_get_type(msg->private_data, - struct dreplsrv_service); - r->out.result = dreplsrv_fsmo_role_check(service, r->in.role); - return NT_STATUS_OK; -} - /** * Called when the auth code wants us to try and replicate * a users secrets @@ -427,7 +438,7 @@ static void dreplsrv_task_init(struct task_server *task) task_server_terminate(task, "dreplsrv: no DSDB replication required in domain member configuration", false); return; - case ROLE_DOMAIN_CONTROLLER: + case ROLE_ACTIVE_DIRECTORY_DC: /* Yes, we want DSDB replication */ break; } @@ -478,6 +489,15 @@ static void dreplsrv_task_init(struct task_server *task) return; } + service->pending.im = tevent_create_immediate(service); + if (service->pending.im == NULL) { + task_server_terminate(task, + "dreplsrv: Failed to create immediate " + "task for future DsReplicaSync\n", + true); + return; + } + /* if we are a RODC then we do not send DSReplicaSync*/ if (!service->am_rodc) { service->notify.interval = lpcfg_parm_int(task->lp_ctx, NULL, "dreplsrv", @@ -500,13 +520,13 @@ static void dreplsrv_task_init(struct task_server *task) IRPC_REGISTER(task->msg_ctx, drsuapi, DRSUAPI_DSREPLICAMOD, dreplsrv_replica_mod, service); IRPC_REGISTER(task->msg_ctx, irpc, DREPL_TAKEFSMOROLE, drepl_take_FSMO_role, service); IRPC_REGISTER(task->msg_ctx, irpc, DREPL_TRIGGER_REPL_SECRET, drepl_trigger_repl_secret, service); - messaging_register(task->msg_ctx, service, MSG_DREPL_ALLOCATE_RID, dreplsrv_allocate_rid); + imessaging_register(task->msg_ctx, service, MSG_DREPL_ALLOCATE_RID, dreplsrv_allocate_rid); } /* register ourselves as a available server */ -NTSTATUS server_service_drepl_init(void) +NTSTATUS server_service_drepl_init(TALLOC_CTX *ctx) { - return register_server_service("drepl", dreplsrv_task_init); + return register_server_service(ctx, "drepl", dreplsrv_task_init); }