From: Anatoliy Atanasov Date: Wed, 15 Sep 2010 07:17:55 +0000 (+0300) Subject: s4/fsmo: Handle infrastructure, pdc and rid extended ops X-Git-Url: http://git.samba.org/?p=kamenim%2Fsamba.git;a=commitdiff_plain;h=2eeba94c9cca41f72d6b95cb8eda585e33e21745 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 --- 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);