summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/dsdb/repl/drepl_out_pull.c16
-rw-r--r--source4/dsdb/repl/drepl_service.c26
-rw-r--r--source4/rpc_server/drsuapi/dcesrv_drsuapi.c31
3 files changed, 68 insertions, 5 deletions
diff --git a/source4/dsdb/repl/drepl_out_pull.c b/source4/dsdb/repl/drepl_out_pull.c
index c66c5bbd19..54dbd29730 100644
--- a/source4/dsdb/repl/drepl_out_pull.c
+++ b/source4/dsdb/repl/drepl_out_pull.c
@@ -79,6 +79,22 @@ WERROR dreplsrv_schedule_pull_replication(struct dreplsrv_service *s, TALLOC_CTX
return WERR_OK;
}
+
+/* force an immediate of the specified partition by GUID */
+WERROR dreplsrv_schedule_partition_pull_by_guid(struct dreplsrv_service *s, TALLOC_CTX *mem_ctx,
+ struct GUID *guid)
+{
+ struct dreplsrv_partition *p;
+
+ for (p = s->partitions; p; p = p->next) {
+ if (GUID_compare(&p->nc.guid, guid) == 0) {
+ return dreplsrv_schedule_partition_pull(s, p, mem_ctx);
+ }
+ }
+
+ return WERR_NOT_FOUND;
+}
+
static void dreplsrv_pending_op_callback(struct dreplsrv_out_operation *op)
{
struct repsFromTo1 *rf = op->source_dsa->repsFrom1;
diff --git a/source4/dsdb/repl/drepl_service.c b/source4/dsdb/repl/drepl_service.c
index 27572af3df..eb49da3d41 100644
--- a/source4/dsdb/repl/drepl_service.c
+++ b/source4/dsdb/repl/drepl_service.c
@@ -106,6 +106,30 @@ static WERROR dreplsrv_connect_samdb(struct dreplsrv_service *service, struct lo
}
/*
+ DsReplicaSync messages from the DRSUAPI server are forwarded here
+ */
+static NTSTATUS drepl_replica_sync(struct irpc_message *msg,
+ struct drsuapi_DsReplicaSync *r)
+{
+ struct dreplsrv_service *service = talloc_get_type(msg->private_data,
+ struct dreplsrv_service);
+ WERROR werr;
+ struct GUID *guid = &r->in.req.req1.naming_context->guid;
+
+ werr = dreplsrv_schedule_partition_pull_by_guid(service, msg, guid);
+ if (W_ERROR_IS_OK(werr)) {
+ DEBUG(3,("drepl_replica_sync: forcing sync of partition %s\n",
+ GUID_string(msg, guid)));
+ dreplsrv_run_pending_ops(service);
+ } else {
+ DEBUG(3,("drepl_replica_sync: failed setup of sync of partition %s - %s\n",
+ GUID_string(msg, guid), win_errstr(werr)));
+ return NT_STATUS_INTERNAL_ERROR;
+ }
+ return NT_STATUS_OK;
+}
+
+/*
startup the dsdb replicator service task
*/
static void dreplsrv_task_init(struct task_server *task)
@@ -173,6 +197,8 @@ static void dreplsrv_task_init(struct task_server *task)
}
irpc_add_name(task->msg_ctx, "dreplsrv");
+
+ IRPC_REGISTER(task->msg_ctx, drsuapi, DRSUAPI_DSREPLICASYNC, drepl_replica_sync, service);
}
/*
diff --git a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c
index a9c7eb794a..73cc8cb1ef 100644
--- a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c
+++ b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c
@@ -29,6 +29,7 @@
#include "lib/ldb/include/ldb_errors.h"
#include "param/param.h"
#include "librpc/gen_ndr/ndr_drsblobs.h"
+#include "messaging/irpc.h"
/*
drsuapi_DsBind
@@ -228,12 +229,32 @@ static WERROR dcesrv_drsuapi_DsUnbind(struct dcesrv_call_state *dce_call, TALLOC
drsuapi_DsReplicaSync
*/
static WERROR dcesrv_drsuapi_DsReplicaSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
- struct drsuapi_DsReplicaSync *r)
+ struct drsuapi_DsReplicaSync *r)
{
- /* TODO: implement this call correct!
- * for now we just say yes,
- * because we have no output parameter
- */
+ struct server_id *repld;
+ struct irpc_request *ireq;
+
+ if (DEBUGLVL(4)) {
+ NDR_PRINT_IN_DEBUG(drsuapi_DsReplicaSync, r);
+ }
+
+ repld = irpc_servers_byname(dce_call->msg_ctx, mem_ctx, "dreplsrv");
+ if (repld == NULL || repld[0].id == 0) {
+ DEBUG(0,("DsReplicaSync: Unable to find dreplsrv task\n"));
+ return WERR_DS_DRA_INTERNAL_ERROR;
+ }
+
+ ireq = IRPC_CALL_SEND(dce_call->msg_ctx, repld[0],
+ drsuapi, DRSUAPI_DSREPLICASYNC,
+ r, mem_ctx);
+ if (ireq == NULL) {
+ DEBUG(0,("DsReplicaSync: Failed to forward request to dreplsrv task\n"));
+ return WERR_DS_DRA_INTERNAL_ERROR;
+ }
+
+ /* we are not interested in a reply */
+ talloc_free(ireq);
+
return WERR_OK;
}