summaryrefslogtreecommitdiff
path: root/source4/dsdb
diff options
context:
space:
mode:
Diffstat (limited to 'source4/dsdb')
-rw-r--r--source4/dsdb/repl/drepl_fsmo.c13
-rw-r--r--source4/dsdb/repl/drepl_ridalloc.c91
-rw-r--r--source4/dsdb/repl/drepl_service.h6
3 files changed, 70 insertions, 40 deletions
diff --git a/source4/dsdb/repl/drepl_fsmo.c b/source4/dsdb/repl/drepl_fsmo.c
index a389c39bf2..63b831669a 100644
--- a/source4/dsdb/repl/drepl_fsmo.c
+++ b/source4/dsdb/repl/drepl_fsmo.c
@@ -43,9 +43,7 @@ static void drepl_role_callback(struct dreplsrv_service *service,
} else {
DEBUG(0,(__location__ ": Successful role transfer\n"));
}
- talloc_free(service->ncchanges_extended.role_owner_source_dsa);
- service->ncchanges_extended.role_owner_source_dsa = NULL;
- service->ncchanges_extended.in_progress = false;
+ service->role_transfer_in_progress = false;
}
static bool fsmo_master_cmp(struct ldb_dn *ntds_dn, struct ldb_dn *role_owner_dn)
@@ -67,13 +65,14 @@ WERROR dreplsrv_fsmo_role_check(struct dreplsrv_service *service,
TALLOC_CTX *tmp_ctx = talloc_new(service);
struct ldb_context *ldb = service->samdb;
int ret;
- uint64_t alloc_pool = 0;
+ uint64_t fsmo_info = 0;
enum drsuapi_DsExtendedOperation extended_op = DRSUAPI_EXOP_NONE;
WERROR werr;
- if (service->ncchanges_extended.in_progress) {
+ if (service->role_transfer_in_progress) {
talloc_free(tmp_ctx);
- return WERR_OK;
+ /* should we allow these in parallel? */
+ return WERR_DS_DRA_REPL_PENDING;
}
ntds_dn = samdb_ntds_settings_dn(ldb);
@@ -158,7 +157,7 @@ WERROR dreplsrv_fsmo_role_check(struct dreplsrv_service *service,
fsmo_role_dn,
role_owner_dn,
extended_op,
- alloc_pool,
+ fsmo_info,
drepl_role_callback);
if (W_ERROR_IS_OK(werr)) {
dreplsrv_run_pending_ops(service);
diff --git a/source4/dsdb/repl/drepl_ridalloc.c b/source4/dsdb/repl/drepl_ridalloc.c
index 44843166f7..cc41db1360 100644
--- a/source4/dsdb/repl/drepl_ridalloc.c
+++ b/source4/dsdb/repl/drepl_ridalloc.c
@@ -33,11 +33,14 @@
/*
create the role owner source dsa structure
- */
+ nc_dn: the DN of the subtree being replicated
+ source_dsa_dn: the DN of the server that we are replicating from
+ */
WERROR drepl_create_role_owner_source_dsa(struct dreplsrv_service *service,
- struct ldb_dn *fsmo_role_dn,
- struct ldb_dn *role_owner_dn)
+ struct ldb_dn *nc_dn,
+ struct ldb_dn *source_dsa_dn,
+ struct dreplsrv_partition_source_dsa **_sdsa)
{
struct dreplsrv_partition_source_dsa *sdsa;
struct ldb_context *ldb = service->samdb;
@@ -53,29 +56,29 @@ WERROR drepl_create_role_owner_source_dsa(struct dreplsrv_service *service,
return WERR_NOMEM;
}
- sdsa->partition->dn = ldb_dn_copy(sdsa->partition, fsmo_role_dn);
+ sdsa->partition->dn = ldb_dn_copy(sdsa->partition, nc_dn);
if (!sdsa->partition->dn) {
talloc_free(sdsa);
return WERR_NOMEM;
}
- sdsa->partition->nc.dn = ldb_dn_alloc_linearized(sdsa->partition, fsmo_role_dn);
+ sdsa->partition->nc.dn = ldb_dn_alloc_linearized(sdsa->partition, nc_dn);
if (!sdsa->partition->nc.dn) {
talloc_free(sdsa);
return WERR_NOMEM;
}
- ret = dsdb_find_guid_by_dn(ldb, fsmo_role_dn, &sdsa->partition->nc.guid);
+ ret = dsdb_find_guid_by_dn(ldb, nc_dn, &sdsa->partition->nc.guid);
if (ret != LDB_SUCCESS) {
DEBUG(0,(__location__ ": Failed to find GUID for %s\n",
- ldb_dn_get_linearized(fsmo_role_dn)));
+ ldb_dn_get_linearized(nc_dn)));
talloc_free(sdsa);
return WERR_DS_DRA_INTERNAL_ERROR;
}
sdsa->repsFrom1 = &sdsa->_repsFromBlob.ctr.ctr1;
- ret = dsdb_find_guid_by_dn(ldb, role_owner_dn, &sdsa->repsFrom1->source_dsa_obj_guid);
+ ret = dsdb_find_guid_by_dn(ldb, source_dsa_dn, &sdsa->repsFrom1->source_dsa_obj_guid);
if (ret != LDB_SUCCESS) {
DEBUG(0,(__location__ ": Failed to find objectGUID for %s\n",
- ldb_dn_get_linearized(role_owner_dn)));
+ ldb_dn_get_linearized(source_dsa_dn)));
talloc_free(sdsa);
return WERR_DS_DRA_INTERNAL_ERROR;
}
@@ -99,15 +102,35 @@ WERROR drepl_create_role_owner_source_dsa(struct dreplsrv_service *service,
werr = dreplsrv_out_connection_attach(service, sdsa->repsFrom1, &sdsa->conn);
if (!W_ERROR_IS_OK(werr)) {
DEBUG(0,(__location__ ": Failed to attach connection to %s\n",
- ldb_dn_get_linearized(fsmo_role_dn)));
+ ldb_dn_get_linearized(nc_dn)));
talloc_free(sdsa);
return werr;
}
- service->ncchanges_extended.role_owner_source_dsa = sdsa;
+ *_sdsa = sdsa;
return WERR_OK;
}
+struct extended_op_data {
+ dreplsrv_fsmo_callback_t callback;
+ void *callback_data;
+ struct dreplsrv_partition_source_dsa *sdsa;
+};
+
+/*
+ called when an extended op finishes
+ */
+static void extended_op_callback(struct dreplsrv_service *service,
+ WERROR err,
+ enum drsuapi_DsExtendedError exop_error,
+ void *cb_data)
+{
+ struct extended_op_data *data = talloc_get_type_abort(cb_data, struct extended_op_data);
+ talloc_free(data->sdsa);
+ data->callback(service, err, exop_error, data->callback_data);
+ talloc_free(data);
+}
+
/*
schedule a getncchanges request to the role owner for an extended operation
*/
@@ -115,20 +138,31 @@ WERROR drepl_request_extended_op(struct dreplsrv_service *service,
struct ldb_dn *fsmo_role_dn,
struct ldb_dn *role_owner_dn,
enum drsuapi_DsExtendedOperation extended_op,
- uint64_t alloc_pool,
- dreplsrv_fsmo_callback_t callback)
+ uint64_t fsmo_info,
+ dreplsrv_fsmo_callback_t callback,
+ void *callback_data)
{
WERROR werr;
- if (service->ncchanges_extended.role_owner_source_dsa == NULL) {
- /* we need to establish a connection to the role owner */
- werr = drepl_create_role_owner_source_dsa(service, fsmo_role_dn, role_owner_dn);
- W_ERROR_NOT_OK_RETURN(werr);
- }
+ struct extended_op_data *data;
+ struct dreplsrv_partition_source_dsa *sdsa;
+
+ werr = drepl_create_role_owner_source_dsa(service, role_owner_dn, fsmo_role_dn, &sdsa);
+ W_ERROR_NOT_OK_RETURN(werr);
+
+ data = talloc(service, struct extended_op_data);
+ W_ERROR_HAVE_NO_MEMORY(data);
- service->ncchanges_extended.in_progress = true;
- werr = dreplsrv_schedule_partition_pull_source(service, service->ncchanges_extended.role_owner_source_dsa,
- extended_op, alloc_pool,
- callback, NULL);
+ data->callback = callback;
+ data->callback_data = callback_data;
+ data->sdsa = sdsa;
+
+ werr = dreplsrv_schedule_partition_pull_source(service, sdsa,
+ extended_op, fsmo_info,
+ extended_op_callback, data);
+ if (!W_ERROR_IS_OK(werr)) {
+ talloc_free(sdsa);
+ talloc_free(data);
+ }
return werr;
}
@@ -147,11 +181,7 @@ static void drepl_new_rid_pool_callback(struct dreplsrv_service *service,
DEBUG(3,(__location__ ": RID Manager completed RID allocation OK\n"));
}
- /* don't keep the connection open to the RID Manager */
- talloc_free(service->ncchanges_extended.role_owner_source_dsa);
- service->ncchanges_extended.role_owner_source_dsa = NULL;
-
- service->ncchanges_extended.in_progress = false;
+ service->rid_alloc_in_progress = false;
}
/*
@@ -167,7 +197,10 @@ static WERROR drepl_request_new_rid_pool(struct dreplsrv_service *service,
fsmo_role_dn,
DRSUAPI_EXOP_FSMO_RID_ALLOC,
alloc_pool,
- drepl_new_rid_pool_callback);
+ drepl_new_rid_pool_callback, NULL);
+ if (W_ERROR_IS_OK(werr)) {
+ service->rid_alloc_in_progress = true;
+ }
return werr;
}
@@ -271,7 +304,7 @@ WERROR dreplsrv_ridalloc_check_rid_pool(struct dreplsrv_service *service)
int ret;
uint64_t alloc_pool;
- if (service->ncchanges_extended.in_progress) {
+ if (service->rid_alloc_in_progress) {
talloc_free(tmp_ctx);
return WERR_OK;
}
diff --git a/source4/dsdb/repl/drepl_service.h b/source4/dsdb/repl/drepl_service.h
index dba9a37bae..fac555c2e3 100644
--- a/source4/dsdb/repl/drepl_service.h
+++ b/source4/dsdb/repl/drepl_service.h
@@ -216,10 +216,8 @@ struct dreplsrv_service {
struct dreplsrv_notify_operation *n_current;
} ops;
- struct {
- bool in_progress;
- struct dreplsrv_partition_source_dsa *role_owner_source_dsa;
- } ncchanges_extended;
+ bool rid_alloc_in_progress;
+ bool role_transfer_in_progress;
bool syncall_workaround;
};