#include "auth/auth.h"
#include "smbd/service.h"
#include "lib/events/events.h"
-#include "lib/messaging/irpc.h"
#include "dsdb/repl/drepl_service.h"
-#include "lib/ldb/include/ldb_errors.h"
+#include <ldb_errors.h>
#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"
/**
* Call-back data for _drepl_replica_sync_done_cb()
{
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;
const struct GUID *ntds_guid;
struct drsuapi_DsBindInfo28 *bind_info28;
- service->samdb = samdb_connect(service, service->task->event_ctx, lp_ctx, service->system_session_info);
+ service->samdb = samdb_connect(service, service->task->event_ctx, lp_ctx, service->system_session_info, 0);
if (!service->samdb) {
return WERR_DS_UNAVAILABLE;
}
}
service->ntds_guid = *ntds_guid;
+ if (samdb_rodc(service->samdb, &service->am_rodc) != LDB_SUCCESS) {
+ DEBUG(0,(__location__ ": Failed to determine RODC status\n"));
+ return WERR_DS_UNAVAILABLE;
+ }
+
bind_info28 = &service->bind_info28;
bind_info28->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_BASE;
bind_info28->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_ASYNC_REPLICATION;
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;
}
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)
{
}
/* 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)) {
struct dreplsrv_service);
#define REPLICA_SYNC_FAIL(_msg, _werr) do {\
- if (!W_ERROR_IS_OK(werr)) { \
+ if (!W_ERROR_IS_OK(_werr)) { \
DEBUG(0,(__location__ ": Failure - %s. werr = %s\n", \
_msg, win_errstr(_werr))); \
NDR_PRINT_IN_DEBUG(drsuapi_DsReplicaSync, r); \
} 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);
}
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);
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",
- WERR_DS_DRA_NO_REPLICA);
+ werr);
}
/* 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);
/* 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(service, 0);
done:
return NT_STATUS_OK;
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
}
+/*
+ DsReplicaAdd messages from the DRSUAPI server are forwarded here
+ */
+static NTSTATUS dreplsrv_replica_add(struct irpc_message *msg,
+ struct drsuapi_DsReplicaAdd *r)
+{
+ struct dreplsrv_service *service = talloc_get_type(msg->private_data,
+ struct dreplsrv_service);
+ return drepl_replica_add(service, r);
+}
+
+/*
+ DsReplicaDel messages from the DRSUAPI server are forwarded here
+ */
+static NTSTATUS dreplsrv_replica_del(struct irpc_message *msg,
+ struct drsuapi_DsReplicaDel *r)
+{
+ struct dreplsrv_service *service = talloc_get_type(msg->private_data,
+ struct dreplsrv_service);
+ return drepl_replica_del(service, r);
+}
+
+/*
+ DsReplicaMod messages from the DRSUAPI server are forwarded here
+ */
+static NTSTATUS dreplsrv_replica_mod(struct irpc_message *msg,
+ struct drsuapi_DsReplicaMod *r)
+{
+ struct dreplsrv_service *service = talloc_get_type(msg->private_data,
+ struct dreplsrv_service);
+ return drepl_replica_mod(service, r);
+}
+
+
/*
startup the dsdb replicator service task
*/
WERROR status;
struct dreplsrv_service *service;
uint32_t periodic_startup_interval;
- bool am_rodc;
- int ret;
switch (lpcfg_server_role(task->lp_ctx)) {
case ROLE_STANDALONE:
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;
}
}
/* if we are a RODC then we do not send DSReplicaSync*/
- ret = samdb_rodc(service->samdb, &am_rodc);
- if (ret == LDB_SUCCESS && !am_rodc) {
+ if (!service->am_rodc) {
service->notify.interval = lpcfg_parm_int(task->lp_ctx, NULL, "dreplsrv",
"notify_interval", 5); /* in seconds */
status = dreplsrv_notify_schedule(service, service->notify.interval);
IRPC_REGISTER(task->msg_ctx, irpc, DREPLSRV_REFRESH, dreplsrv_refresh, service);
IRPC_REGISTER(task->msg_ctx, drsuapi, DRSUAPI_DSREPLICASYNC, drepl_replica_sync, service);
+ IRPC_REGISTER(task->msg_ctx, drsuapi, DRSUAPI_DSREPLICAADD, dreplsrv_replica_add, service);
+ IRPC_REGISTER(task->msg_ctx, drsuapi, DRSUAPI_DSREPLICADEL, dreplsrv_replica_del, service);
+ 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);
}
/*