s4/fsmo: Handle infrastructure, pdc and rid extended ops
authorAnatoliy Atanasov <anatoliy.atanasov@postpath.com>
Wed, 15 Sep 2010 07:17:55 +0000 (10:17 +0300)
committerAnatoliy Atanasov <anatoliy.atanasov@postpath.com>
Wed, 15 Sep 2010 11:00:28 +0000 (14:00 +0300)
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

source4/dsdb/repl/drepl_fsmo.c
source4/dsdb/repl/drepl_ridalloc.c

index e69dc7e15454694ffd856484b004bd0bc458db86..a389c39bf2bc084560df6166159466d7bbdef3c4 100644 (file)
@@ -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;
 }
index 1869af8a1a66a9452eb20eb94d02897a47329d75..44843166f76d723c31bf875ee1c1ed7ac972bb95 100644 (file)
@@ -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);