summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
authorKamen Mazdrashki <kamenim@samba.org>2010-09-03 04:29:02 +0300
committerKamen Mazdrashki <kamenim@samba.org>2010-09-03 13:23:48 +0300
commit65b21c056217b03ad0e0aa321bc9d85e048d2ee6 (patch)
tree9a08fa73986e336018f004ed35f9d9bd52a3e671 /source4
parent715743b38dec1968dce843573a12947407d74324 (diff)
downloadsamba-65b21c056217b03ad0e0aa321bc9d85e048d2ee6.tar.gz
samba-65b21c056217b03ad0e0aa321bc9d85e048d2ee6.tar.bz2
samba-65b21c056217b03ad0e0aa321bc9d85e048d2ee6.zip
s4-dreplsrv: Refactor drepl_replica_sync() to behave as described in MS-DRSR
see: MS-DRSR - 4.1.23.2 Note: Synchronious replication not implemented yet.
Diffstat (limited to 'source4')
-rw-r--r--source4/dsdb/repl/drepl_service.c119
1 files changed, 111 insertions, 8 deletions
diff --git a/source4/dsdb/repl/drepl_service.c b/source4/dsdb/repl/drepl_service.c
index d118c45b6c..252ec5f693 100644
--- a/source4/dsdb/repl/drepl_service.c
+++ b/source4/dsdb/repl/drepl_service.c
@@ -103,28 +103,131 @@ static WERROR dreplsrv_connect_samdb(struct dreplsrv_service *service, struct lo
return WERR_OK;
}
+
/*
DsReplicaSync messages from the DRSUAPI server are forwarded here
*/
static NTSTATUS drepl_replica_sync(struct irpc_message *msg,
struct drsuapi_DsReplicaSync *r)
{
+ WERROR werr;
+ struct dreplsrv_partition *p;
+ struct dreplsrv_partition_source_dsa *dsa;
+ struct drsuapi_DsReplicaSyncRequest1 *req1;
+ struct drsuapi_DsReplicaObjectIdentifier *nc;
struct dreplsrv_service *service = talloc_get_type(msg->private_data,
struct dreplsrv_service);
- struct drsuapi_DsReplicaObjectIdentifier *nc = r->in.req->req1.naming_context;
- r->out.result = dreplsrv_schedule_partition_pull_by_nc(service, msg, nc);
- if (W_ERROR_IS_OK(r->out.result)) {
- DEBUG(3,("drepl_replica_sync: forcing sync of partition (%s, %s)\n",
+#define REPLICA_SYNC_FAIL(_werr) do {r->out.result = _werr; goto done;} while(0)
+
+ if (r->in.level != 1) {
+ DEBUG(0,("%s: Level %d is not supported yet.\n",
+ __FUNCTION__, r->in.level));
+ REPLICA_SYNC_FAIL(WERR_DS_DRA_INVALID_PARAMETER);
+ }
+
+ req1 = &r->in.req->req1;
+ nc = req1->naming_context;
+
+ /* Check input parameters */
+ if (!nc) {
+ REPLICA_SYNC_FAIL(WERR_DS_DRA_INVALID_PARAMETER);
+ }
+
+ /* Find Naming context to be synchronized */
+ werr = dreplsrv_partition_find_for_nc(service,
+ &nc->guid, &nc->sid, nc->dn,
+ &p);
+ if (!W_ERROR_IS_OK(werr)) {
+ DEBUG(0,("%s: failed to find NC for (%s, %s) - %s\n",
+ __FUNCTION__,
GUID_string(msg, &nc->guid),
- nc->dn));
- dreplsrv_run_pending_ops(service);
+ nc->dn,
+ win_errstr(werr)));
+ REPLICA_SYNC_FAIL(werr);
+ }
+
+ /* collect source DSAs to sync with */
+ if (req1->options & DRSUAPI_DRS_SYNC_ALL) {
+ for (dsa = p->sources; dsa; dsa = dsa->next) {
+ /* schedule replication item */
+ werr = dreplsrv_schedule_partition_pull_source(service, dsa,
+ DRSUAPI_EXOP_NONE, 0,
+ NULL, NULL);
+ if (!W_ERROR_IS_OK(werr)) {
+ DEBUG(0,("%s: failed setup of sync of partition (%s, %s, %s) - %s\n",
+ __FUNCTION__,
+ GUID_string(msg, &nc->guid),
+ nc->dn,
+ dsa->repsFrom1->other_info->dns_name,
+ win_errstr(werr)));
+ REPLICA_SYNC_FAIL(werr);
+ }
+ /* log we've scheduled replication item */
+ DEBUG(3,("%s: forcing sync of partition (%s, %s, %s)\n",
+ __FUNCTION__,
+ GUID_string(msg, &nc->guid),
+ nc->dn,
+ dsa->repsFrom1->other_info->dns_name));
+ }
} else {
- DEBUG(3,("drepl_replica_sync: failed setup of sync of partition (%s, %s) - %s\n",
+ if (req1->options & DRSUAPI_DRS_SYNC_BYNAME) {
+ /* client should pass at least valid string */
+ if (!req1->source_dsa_dns) {
+ REPLICA_SYNC_FAIL(WERR_DS_DRA_INVALID_PARAMETER);
+ }
+
+ werr = dreplsrv_partition_source_dsa_by_dns(p,
+ req1->source_dsa_dns,
+ &dsa);
+ } else {
+ /* client should pass at least some GUID */
+ if (GUID_all_zero(&req1->source_dsa_guid)) {
+ REPLICA_SYNC_FAIL(WERR_DS_DRA_INVALID_PARAMETER);
+ }
+
+ werr = dreplsrv_partition_source_dsa_by_guid(p,
+ &req1->source_dsa_guid,
+ &dsa);
+ }
+ if (!W_ERROR_IS_OK(werr)) {
+ DEBUG(0,("%s: Failed to locate source DSA %s for NC %s.\n",
+ __FUNCTION__,
+ (req1->options & DRSUAPI_DRS_SYNC_BYNAME)
+ ? req1->source_dsa_dns
+ : GUID_string(r, &req1->source_dsa_guid),
+ nc->dn));
+ REPLICA_SYNC_FAIL(WERR_DS_DRA_NO_REPLICA);
+ }
+
+ /* schedule replication item */
+ werr = dreplsrv_schedule_partition_pull_source(service, dsa,
+ DRSUAPI_EXOP_NONE, 0,
+ NULL, NULL);
+ if (!W_ERROR_IS_OK(werr)) {
+ DEBUG(0,("%s: failed setup of sync of partition (%s, %s, %s) - %s\n",
+ __FUNCTION__,
+ GUID_string(msg, &nc->guid),
+ nc->dn,
+ dsa->repsFrom1->other_info->dns_name,
+ win_errstr(werr)));
+ REPLICA_SYNC_FAIL(werr);
+ }
+ /* log we've scheduled replication item */
+ DEBUG(3,("%s: forcing sync of partition (%s, %s, %s)\n",
+ __FUNCTION__,
GUID_string(msg, &nc->guid),
nc->dn,
- win_errstr(r->out.result)));
+ dsa->repsFrom1->other_info->dns_name));
}
+
+ /* if we got here, everything is OK */
+ r->out.result = WERR_OK;
+
+ /* force execution of scheduled replications */
+ dreplsrv_run_pending_ops(service);
+
+done:
return NT_STATUS_OK;
}