diff options
author | Anatoliy Atanasov <anatoliy.atanasov@postpath.com> | 2010-09-15 10:17:55 +0300 |
---|---|---|
committer | Anatoliy Atanasov <anatoliy.atanasov@postpath.com> | 2010-09-15 14:00:28 +0300 |
commit | 2eeba94c9cca41f72d6b95cb8eda585e33e21745 (patch) | |
tree | 02fe87797d6fc93baf8f4b57961b26a2140be363 | |
parent | 46087219357b13cf7c440ee6f4d536ff537bbd2d (diff) | |
download | samba-2eeba94c9cca41f72d6b95cb8eda585e33e21745.tar.gz samba-2eeba94c9cca41f72d6b95cb8eda585e33e21745.tar.bz2 samba-2eeba94c9cca41f72d6b95cb8eda585e33e21745.zip |
s4/fsmo: Handle infrastructure, pdc and rid extended ops
With this change we can transfer all roles back and forward, except
for the naming master. Also this commit fixes the naming of
fsmo_role_dn - used to point to the DN from which we read fSMORoleOwner
role_owner_dn - used to point to the NTDSDSA who owns the role
Now we always pass fsmo_role_dn, role_owner_dn to the extended operation
and to drepl_create_role_owner_source_dsa
Conflicts:
source4/dsdb/repl/drepl_ridalloc.c
-rw-r--r-- | source4/dsdb/repl/drepl_fsmo.c | 72 | ||||
-rw-r--r-- | source4/dsdb/repl/drepl_ridalloc.c | 26 |
2 files changed, 53 insertions, 45 deletions
diff --git a/source4/dsdb/repl/drepl_fsmo.c b/source4/dsdb/repl/drepl_fsmo.c index e69dc7e154..a389c39bf2 100644 --- a/source4/dsdb/repl/drepl_fsmo.c +++ b/source4/dsdb/repl/drepl_fsmo.c @@ -48,9 +48,9 @@ static void drepl_role_callback(struct dreplsrv_service *service, service->ncchanges_extended.in_progress = false; } -static bool fsmo_master_cmp(struct ldb_dn *ntds_dn, struct ldb_dn *fsmo_role_dn) +static bool fsmo_master_cmp(struct ldb_dn *ntds_dn, struct ldb_dn *role_owner_dn) { - if (ldb_dn_compare(ntds_dn, fsmo_role_dn) == 0) { + if (ldb_dn_compare(ntds_dn, role_owner_dn) == 0) { DEBUG(0,("\nWe are the FSMO master.\n")); return true; } @@ -68,6 +68,8 @@ WERROR dreplsrv_fsmo_role_check(struct dreplsrv_service *service, struct ldb_context *ldb = service->samdb; int ret; uint64_t alloc_pool = 0; + enum drsuapi_DsExtendedOperation extended_op = DRSUAPI_EXOP_NONE; + WERROR werr; if (service->ncchanges_extended.in_progress) { talloc_free(tmp_ctx); @@ -78,11 +80,11 @@ WERROR dreplsrv_fsmo_role_check(struct dreplsrv_service *service, if (!ntds_dn) { return WERR_DS_DRA_INTERNAL_ERROR; } - /* work out who is the current owner */ + switch (role) { case DREPL_NAMING_MASTER: - role_owner_dn = samdb_partitions_dn(ldb, tmp_ctx), - ret = samdb_reference_dn(ldb, tmp_ctx, role_owner_dn, "fSMORoleOwner", &fsmo_role_dn); + fsmo_role_dn = samdb_partitions_dn(ldb, tmp_ctx), + ret = samdb_reference_dn(ldb, tmp_ctx, fsmo_role_dn, "fSMORoleOwner", &role_owner_dn); if (ret != LDB_SUCCESS) { DEBUG(0,(__location__ ": Failed to find fSMORoleOwner in Naming Master object - %s", ldb_errstring(ldb))); @@ -91,70 +93,78 @@ WERROR dreplsrv_fsmo_role_check(struct dreplsrv_service *service, } break; case DREPL_INFRASTRUCTURE_MASTER: - role_owner_dn = samdb_infrastructure_dn(ldb, tmp_ctx); - ret = samdb_reference_dn(ldb, tmp_ctx, role_owner_dn, "fSMORoleOwner", &fsmo_role_dn); + fsmo_role_dn = samdb_infrastructure_dn(ldb, tmp_ctx); + ret = samdb_reference_dn(ldb, tmp_ctx, fsmo_role_dn, "fSMORoleOwner", &role_owner_dn); if (ret != LDB_SUCCESS) { DEBUG(0,(__location__ ": Failed to find fSMORoleOwner in Schema Master object - %s", ldb_errstring(ldb))); talloc_free(tmp_ctx); return WERR_DS_DRA_INTERNAL_ERROR; } + extended_op = DRSUAPI_EXOP_FSMO_REQ_ROLE; break; case DREPL_RID_MASTER: - ret = samdb_rid_manager_dn(ldb, tmp_ctx, &role_owner_dn); + ret = samdb_rid_manager_dn(ldb, tmp_ctx, &fsmo_role_dn); if (ret != LDB_SUCCESS) { DEBUG(0, (__location__ ": Failed to find RID Manager object - %s", ldb_errstring(ldb))); talloc_free(tmp_ctx); return WERR_DS_DRA_INTERNAL_ERROR; } - /* find the DN of the RID Manager */ - ret = samdb_reference_dn(ldb, tmp_ctx, role_owner_dn, "fSMORoleOwner", &fsmo_role_dn); + ret = samdb_reference_dn(ldb, tmp_ctx, fsmo_role_dn, "fSMORoleOwner", &role_owner_dn); if (ret != LDB_SUCCESS) { DEBUG(0,(__location__ ": Failed to find fSMORoleOwner in RID Manager object - %s", ldb_errstring(ldb))); talloc_free(tmp_ctx); return WERR_DS_DRA_INTERNAL_ERROR; } + extended_op = DRSUAPI_EXOP_FSMO_RID_REQ_ROLE; break; case DREPL_SCHEMA_MASTER: - role_owner_dn = ldb_get_schema_basedn(ldb); - ret = samdb_reference_dn(ldb, tmp_ctx, role_owner_dn, "fSMORoleOwner", &fsmo_role_dn); + fsmo_role_dn = ldb_get_schema_basedn(ldb); + ret = samdb_reference_dn(ldb, tmp_ctx, fsmo_role_dn, "fSMORoleOwner", &role_owner_dn); if (ret != LDB_SUCCESS) { DEBUG(0,(__location__ ": Failed to find fSMORoleOwner in Schema Master object - %s", ldb_errstring(ldb))); talloc_free(tmp_ctx); return WERR_DS_DRA_INTERNAL_ERROR; } - if (!fsmo_master_cmp(ntds_dn, fsmo_role_dn)) { - WERROR werr; - werr = drepl_request_extended_op(service, - role_owner_dn, - fsmo_role_dn, - DRSUAPI_EXOP_FSMO_REQ_ROLE, - alloc_pool, - drepl_role_callback); - if (W_ERROR_IS_OK(werr)) { - dreplsrv_run_pending_ops(service); - } else { - DEBUG(0,("%s: drepl_request_extended_op() failed with %s", - __FUNCTION__, win_errstr(werr))); - } - return werr; - } + extended_op = DRSUAPI_EXOP_FSMO_REQ_ROLE; break; case DREPL_PDC_MASTER: - role_owner_dn = ldb_get_default_basedn(ldb); - ret = samdb_reference_dn(ldb, tmp_ctx, role_owner_dn, "fSMORoleOwner", &fsmo_role_dn); + fsmo_role_dn = ldb_get_default_basedn(ldb); + ret = samdb_reference_dn(ldb, tmp_ctx, fsmo_role_dn, "fSMORoleOwner", &role_owner_dn); if (ret != LDB_SUCCESS) { DEBUG(0,(__location__ ": Failed to find fSMORoleOwner in Pd Master object - %s", ldb_errstring(ldb))); talloc_free(tmp_ctx); return WERR_DS_DRA_INTERNAL_ERROR; } + extended_op = DRSUAPI_EXOP_FSMO_REQ_PDC; break; default: return WERR_DS_DRA_INTERNAL_ERROR; } - return WERR_OK; + + if (fsmo_master_cmp(ntds_dn, role_owner_dn) || + (extended_op == DRSUAPI_EXOP_NONE)) { + DEBUG(0,("FSMO role check failed for DN %s and owner %s ", + ldb_dn_get_linearized(fsmo_role_dn), + ldb_dn_get_linearized(role_owner_dn))); + return WERR_OK; + } + + werr = drepl_request_extended_op(service, + fsmo_role_dn, + role_owner_dn, + extended_op, + alloc_pool, + drepl_role_callback); + if (W_ERROR_IS_OK(werr)) { + dreplsrv_run_pending_ops(service); + } else { + DEBUG(0,("%s: drepl_request_extended_op() failed with %s", + __FUNCTION__, win_errstr(werr))); + } + return werr; } diff --git a/source4/dsdb/repl/drepl_ridalloc.c b/source4/dsdb/repl/drepl_ridalloc.c index 1869af8a1a..44843166f7 100644 --- a/source4/dsdb/repl/drepl_ridalloc.c +++ b/source4/dsdb/repl/drepl_ridalloc.c @@ -36,7 +36,8 @@ */ WERROR drepl_create_role_owner_source_dsa(struct dreplsrv_service *service, - struct ldb_dn *role_owner_dn, struct ldb_dn *fsmo_role_dn) + struct ldb_dn *fsmo_role_dn, + struct ldb_dn *role_owner_dn) { struct dreplsrv_partition_source_dsa *sdsa; struct ldb_context *ldb = service->samdb; @@ -52,29 +53,29 @@ WERROR drepl_create_role_owner_source_dsa(struct dreplsrv_service *service, return WERR_NOMEM; } - sdsa->partition->dn = ldb_dn_copy(sdsa->partition, role_owner_dn); + sdsa->partition->dn = ldb_dn_copy(sdsa->partition, fsmo_role_dn); if (!sdsa->partition->dn) { talloc_free(sdsa); return WERR_NOMEM; } - sdsa->partition->nc.dn = ldb_dn_alloc_linearized(sdsa->partition, role_owner_dn); + sdsa->partition->nc.dn = ldb_dn_alloc_linearized(sdsa->partition, fsmo_role_dn); if (!sdsa->partition->nc.dn) { talloc_free(sdsa); return WERR_NOMEM; } - ret = dsdb_find_guid_by_dn(ldb, role_owner_dn, &sdsa->partition->nc.guid); + ret = dsdb_find_guid_by_dn(ldb, fsmo_role_dn, &sdsa->partition->nc.guid); if (ret != LDB_SUCCESS) { DEBUG(0,(__location__ ": Failed to find GUID for %s\n", - ldb_dn_get_linearized(role_owner_dn))); + ldb_dn_get_linearized(fsmo_role_dn))); talloc_free(sdsa); return WERR_DS_DRA_INTERNAL_ERROR; } sdsa->repsFrom1 = &sdsa->_repsFromBlob.ctr.ctr1; - ret = dsdb_find_guid_by_dn(ldb, fsmo_role_dn, &sdsa->repsFrom1->source_dsa_obj_guid); + ret = dsdb_find_guid_by_dn(ldb, role_owner_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(fsmo_role_dn))); + ldb_dn_get_linearized(role_owner_dn))); talloc_free(sdsa); return WERR_DS_DRA_INTERNAL_ERROR; } @@ -98,7 +99,7 @@ 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(role_owner_dn))); + ldb_dn_get_linearized(fsmo_role_dn))); talloc_free(sdsa); return werr; } @@ -111,23 +112,20 @@ WERROR drepl_create_role_owner_source_dsa(struct dreplsrv_service *service, schedule a getncchanges request to the role owner for an extended operation */ WERROR drepl_request_extended_op(struct dreplsrv_service *service, - struct ldb_dn *role_owner_dn, 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) { WERROR werr; - if (service->ncchanges_extended.role_owner_source_dsa == NULL) { - /* we need to establish a connection to the RID - Manager */ - werr = drepl_create_role_owner_source_dsa(service, role_owner_dn, fsmo_role_dn); + /* 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); } 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); |