Beispiel #1
0
int
ipa_topo_pre_modrdn(Slapi_PBlock *pb)
{

    int result = SLAPI_PLUGIN_SUCCESS;

    slapi_log_error(SLAPI_LOG_PLUGIN, IPA_TOPO_PLUGIN_SUBSYSTEM,
                    "--> ipa_topo_pre_modrdn\n");

    if (0 == ipa_topo_get_plugin_active()) {
        slapi_log_error(SLAPI_LOG_PLUGIN, IPA_TOPO_PLUGIN_SUBSYSTEM,
                    "<-- ipa_topo_pre_modrdn - plugin not active\n");
        return 0;
    }

    if (ipa_topo_pre_ignore_op(pb)) return result;

    if (ipa_topo_check_entry_move(pb)){
        int rc = LDAP_UNWILLING_TO_PERFORM;
        char *errtxt;
        errtxt = slapi_ch_smprintf("Moving of a segment or config entry "
                                   "to another subtree is not allowed.\n");
        slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, errtxt);
        slapi_pblock_set(pb, SLAPI_RESULT_CODE, &rc);
        result = SLAPI_PLUGIN_FAILURE;
    }

    return result;

}
Beispiel #2
0
int ipa_topo_pre_add(Slapi_PBlock *pb)
{
    int result = SLAPI_PLUGIN_SUCCESS;
    char *errtxt  = NULL;

    slapi_log_error(SLAPI_LOG_PLUGIN, IPA_TOPO_PLUGIN_SUBSYSTEM,
                    "--> ipa_topo_pre_add\n");

    if (0 == ipa_topo_get_plugin_active()) {
        slapi_log_error(SLAPI_LOG_PLUGIN, IPA_TOPO_PLUGIN_SUBSYSTEM,
                    "<-- ipa_topo_pre_add - plugin not active\n");
        return 0;
    }

    if (ipa_topo_pre_ignore_op(pb)) return result;

    if (ipa_topo_is_entry_managed(pb)) {
        int rc = LDAP_UNWILLING_TO_PERFORM;
        errtxt = slapi_ch_smprintf("Entry is managed by topology plugin."
                                   " Adding of entry not allowed.\n");
        slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, errtxt);
        slapi_pblock_set(pb, SLAPI_RESULT_CODE, &rc);
        result = SLAPI_PLUGIN_FAILURE;
    } else if (ipa_topo_check_segment_is_valid(pb, &errtxt)) {
        int rc = LDAP_UNWILLING_TO_PERFORM;
        slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, errtxt);
        slapi_pblock_set(pb, SLAPI_RESULT_CODE, &rc);
        result = SLAPI_PLUGIN_FAILURE;
    }
    slapi_log_error(SLAPI_LOG_PLUGIN, IPA_TOPO_PLUGIN_SUBSYSTEM,
                    "<-- ipa_topo_pre_add\n");
    return result;
}
Beispiel #3
0
int
ipa_topo_pre_mod(Slapi_PBlock *pb)
{

    int result = SLAPI_PLUGIN_SUCCESS;
    char *errtxt = NULL;

    slapi_log_error(SLAPI_LOG_PLUGIN, IPA_TOPO_PLUGIN_SUBSYSTEM,
                    "--> ipa_topo_pre_mod\n");

    if (0 == ipa_topo_get_plugin_active()) {
        slapi_log_error(SLAPI_LOG_PLUGIN, IPA_TOPO_PLUGIN_SUBSYSTEM,
                    "<-- ipa_topo_pre_mod - plugin not active\n");
        return 0;
    }

    if (ipa_topo_pre_ignore_op(pb)) return result;

    if (ipa_topo_is_entry_managed(pb)){
        /* this means it is a replication agreement targeting a managed server
         * next check is if it tries to modify restricted attributes
         */
        if(ipa_topo_is_agmt_attr_restricted(pb)) {
            errtxt = slapi_ch_smprintf("Entry and attributes are managed by topology plugin."
                                       "No direct modifications allowed.\n");
        }
    } else if (ipa_topo_check_segment_updates(pb)) {
        /* some updates to segments are not supported */
        errtxt = slapi_ch_smprintf("Modification of connectivity and segment nodes "
                                   " is not supported.\n");
    } else if (ipa_topo_check_host_updates(pb)) {
        /* some updates to segments are not supported */
        errtxt = slapi_ch_smprintf("Modification of managed suffixes must explicitely "
                                   " list suffix.\n");
    }
    if (errtxt) {
        int rc = LDAP_UNWILLING_TO_PERFORM;
        slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, errtxt);
        slapi_pblock_set(pb, SLAPI_RESULT_CODE, &rc);
        result = SLAPI_PLUGIN_FAILURE;
    }
    slapi_log_error(SLAPI_LOG_PLUGIN, IPA_TOPO_PLUGIN_SUBSYSTEM,
                    "<-- ipa_topo_pre_mod\n");
    return result;
}
Beispiel #4
0
void
ipa_topo_be_state_change(void *handle, char *be_name,
                              int old_be_state, int new_be_state)
{
    Slapi_Backend *be=NULL;
    const char *be_suffix;

    /* check if different backends require different actions */
    be = slapi_be_select_by_instance_name(be_name);
    be_suffix = slapi_sdn_get_dn(slapi_be_getsuffix(be, 0));
    if (0 == ipa_topo_cfg_plugin_suffix_is_managed(be_suffix)) {
        /* nothing to do */
        return;
    }

    if (new_be_state == SLAPI_BE_STATE_ON) {
        /* backend came back online - check change in domain level */
        slapi_log_error(SLAPI_LOG_FATAL, IPA_TOPO_PLUGIN_SUBSYSTEM,
                        "ipa_topo_be_state_change - "
                        "backend %s is coming online; "
                        "checking domain level and init shared topology\n",
                        be_name);
        ipa_topo_util_set_domain_level();
        ipa_topo_util_check_plugin_active();
        if (ipa_topo_get_plugin_active()) {
            ipa_topo_set_post_init(1);
            ipa_topo_util_start(1);
        }
    } else if (new_be_state == SLAPI_BE_STATE_OFFLINE) {
        /* backend is about to be taken down - inactivate plugin */
        slapi_log_error(SLAPI_LOG_FATAL, IPA_TOPO_PLUGIN_SUBSYSTEM,
                        "ipa_topo_be_state_change"
                        "backend %s is going offline; inactivate plugin\n", be_name);
    } else if (new_be_state == SLAPI_BE_STATE_DELETE) {
        /* backend is about to be removed - disable replication */
        if (old_be_state == SLAPI_BE_STATE_ON) {
             slapi_log_error(SLAPI_LOG_FATAL, IPA_TOPO_PLUGIN_SUBSYSTEM,
                            "ipa_topo_be_state_change"
                            "backend %s is about to be deleted; inactivate plugin\n", be_name);
        }
    }
}
Beispiel #5
0
int
ipa_topo_pre_del(Slapi_PBlock *pb)
{
    int result = SLAPI_PLUGIN_SUCCESS;

    slapi_log_error(SLAPI_LOG_PLUGIN, IPA_TOPO_PLUGIN_SUBSYSTEM,
                    "--> ipa_topo_pre_del\n");

    if (0 == ipa_topo_get_plugin_active()) {
        slapi_log_error(SLAPI_LOG_PLUGIN, IPA_TOPO_PLUGIN_SUBSYSTEM,
                    "<-- ipa_topo_pre_del - plugin not active\n");
        return 0;
    }

    if (ipa_topo_pre_ignore_op(pb) ||
        ipa_topo_util_is_tombstone_op(pb)) return result;

    if (ipa_topo_is_entry_managed(pb)) {
        int rc = LDAP_UNWILLING_TO_PERFORM;
        char *errtxt;
        errtxt = slapi_ch_smprintf("Entry is managed by topology plugin."
                                   "Deletion not allowed.\n");
        slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, errtxt);
        slapi_pblock_set(pb, SLAPI_RESULT_CODE, &rc);
        result = SLAPI_PLUGIN_FAILURE;
    } else if (ipa_topo_check_topology_disconnect(pb)) {
        int rc = LDAP_UNWILLING_TO_PERFORM;
        char *errtxt;
        errtxt = slapi_ch_smprintf("Removal of Segment disconnects topology."
                                   "Deletion not allowed.\n");
        slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, errtxt);
        slapi_pblock_set(pb, SLAPI_RESULT_CODE, &rc);
        result = SLAPI_PLUGIN_FAILURE;
    }
    slapi_log_error(SLAPI_LOG_PLUGIN, IPA_TOPO_PLUGIN_SUBSYSTEM,
                    "<-- ipa_topo_pre_del\n");
    return result;
}
Beispiel #6
0
static int
ipa_topo_rootdse_search(Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* entryAfter,
                   int *returncode, char *returntext, void *arg)
{

    char *version = slapi_ch_smprintf("%d.%d", ipa_topo_get_plugin_version_major(),
                                               ipa_topo_get_plugin_version_minor());
    slapi_entry_attr_set_charptr(e, "ipaTopologyPluginVersion", version);
    if (ipa_topo_get_plugin_active()) {
        slapi_entry_attr_set_charptr(e, "ipaTopologyIsManaged", "on");
    } else {
        slapi_entry_attr_set_charptr(e, "ipaTopologyIsManaged", "off");
    }

    /* we expose temporarily the domain level in this function, should
     * finally be handled in a plugin managing the domain level
     */
    char *level = slapi_ch_smprintf("%d", ipa_topo_get_domain_level());
    slapi_entry_attr_set_charptr(e, "ipaDomainLevel", level);
    slapi_ch_free_string(&version);
    slapi_ch_free_string(&level);
    return SLAPI_DSE_CALLBACK_OK;
}
Beispiel #7
0
static int
ipa_topo_start(Slapi_PBlock * pb)
{
    int rc = 0;

    slapi_log_error(SLAPI_LOG_PLUGIN, IPA_TOPO_PLUGIN_SUBSYSTEM,
        "--> ipa_topo_start\n");

    /* expose info about the plugin via rootdse */
    rc = ipa_topo_rootdse_init(pb);

    /* register callback to handle state changes of backends,
     * required to check changes in domain level after online initialization
     */
    slapi_register_backend_state_change((void *)ipa_topo_be_state_change,
                                         ipa_topo_be_state_change);

    /* init plugin config data from the plugin entry in cn=config */
    rc = ipa_topo_init_plugin_config(pb);
    if (rc != 0) {
        slapi_log_error(SLAPI_LOG_FATAL, IPA_TOPO_PLUGIN_SUBSYSTEM,
                        "unable to get configuration\n");
        return (rc);
    }

    if (0 == ipa_topo_get_plugin_active()) {
        slapi_log_error(SLAPI_LOG_PLUGIN, IPA_TOPO_PLUGIN_SUBSYSTEM,
                        "plugin not activated, waiting for increase of domain level\n");
        return rc;
    }

    rc = ipa_topo_util_start(1);
    slapi_log_error(SLAPI_LOG_PLUGIN, IPA_TOPO_PLUGIN_SUBSYSTEM,
        "<-- ipa_topo_start\n");
    return (rc);
}
Beispiel #8
0
int
ipa_topo_post_add(Slapi_PBlock *pb)
{
    int result = SLAPI_PLUGIN_SUCCESS;
    int entry_type;
    Slapi_Entry *add_entry = NULL;

    slapi_log_error(SLAPI_LOG_PLUGIN, IPA_TOPO_PLUGIN_SUBSYSTEM,
                    "--> ipa_topo_post_add\n");

    /* 1. get entry  */
    slapi_pblock_get(pb,SLAPI_ENTRY_POST_OP,&add_entry);

    if (add_entry == NULL) {
        slapi_log_error(SLAPI_LOG_PLUGIN, IPA_TOPO_PLUGIN_SUBSYSTEM, "no entry\n");
        return 1;
    }
    /* 2. check if it is in scope and type
     * and if plugin is active
     */
    entry_type = ipa_topo_check_entry_type(add_entry);
    if (0 == ipa_topo_get_plugin_active() &&
        entry_type != TOPO_DOMLEVEL_ENTRY) {
        slapi_log_error(SLAPI_LOG_PLUGIN, IPA_TOPO_PLUGIN_SUBSYSTEM,
                    "<-- ipa_topo_post_add - plugin not active\n");
        return 0;
    }
    switch (entry_type) {
    case TOPO_CONFIG_ENTRY:
        /* initialize the shared topology data for a replica */
        break;
    case TOPO_SEGMENT_ENTRY: {
        TopoReplicaSegment *tsegm;
        TopoReplica *tconf = ipa_topo_util_get_conf_for_segment(add_entry);
        char *status;
        /* TBD check that one node is the current server and
         * that the other node is also managed by the
         * shared config.
         * If all checks pass create the replication agreement
         */
        tsegm =  ipa_topo_util_segment_from_entry(tconf, add_entry);
        status = slapi_entry_attr_get_charptr(add_entry, "ipaReplTopoSegmentStatus");
        if (status == NULL || strcasecmp(status,"autogen")) {
            ipa_topo_util_missing_agmts_add(tconf, tsegm,
                                            ipa_topo_get_plugin_hostname());
        }
        /* keep the new segment in tconf data */
        ipa_topo_cfg_segment_add(tconf, tsegm);
        /* TBD: do we know if the replica already has been initialized ?
         *        should the agreement be enabled ?
         *        For now assume everything is ok and enable
         */
        /* check if it is unidirectional and if other direction exists */
        ipa_topo_util_segment_merge(tconf, tsegm);
        slapi_ch_free_string(&status);
        break;
    }
    case TOPO_HOST_ENTRY: {
        /* add to list of managed hosts */
        ipa_topo_cfg_host_add(add_entry);
        /* we are adding a new master, there could be
         * a segment which so far was inactive since
         * the host was not managed
         */
        ipa_topo_util_update_segments_for_host(add_entry);
        break;
    }
    case TOPO_DOMLEVEL_ENTRY: {
        /* the domain level entry was just added
         * check and set the level, if plugin gets activated
         * do initialization.
         */
        char *domlevel = slapi_entry_attr_get_charptr(add_entry, "ipaDomainLevel");
        ipa_topo_set_domain_level(domlevel);
        ipa_topo_util_check_plugin_active();
        if (ipa_topo_get_plugin_active()) {
            ipa_topo_util_start(0);
        }
        slapi_ch_free_string(&domlevel);
        break;
    }
    case TOPO_IGNORE_ENTRY:
        break;
    }

    slapi_log_error(SLAPI_LOG_PLUGIN, IPA_TOPO_PLUGIN_SUBSYSTEM,
                    "<-- ipa_topo_post_add\n");
    return result;
}
Beispiel #9
0
int
ipa_topo_post_del(Slapi_PBlock *pb)
{
    int result = SLAPI_PLUGIN_SUCCESS;
    int entry_type;
    Slapi_Entry *del_entry = NULL;

    slapi_log_error(SLAPI_LOG_PLUGIN, IPA_TOPO_PLUGIN_SUBSYSTEM,
                    "--> ipa_topo_post_del\n");

    /* 1. get entry  */
    slapi_pblock_get(pb,SLAPI_ENTRY_PRE_OP,&del_entry);

    if (del_entry == NULL) {
        slapi_log_error(SLAPI_LOG_PLUGIN, IPA_TOPO_PLUGIN_SUBSYSTEM, "no entry\n");
        return 1;
    }
    /* 2. check if it is in scope */
    entry_type = ipa_topo_check_entry_type(del_entry);
    if (0 == ipa_topo_get_plugin_active() &&
        entry_type != TOPO_DOMLEVEL_ENTRY) {
        slapi_log_error(SLAPI_LOG_PLUGIN, IPA_TOPO_PLUGIN_SUBSYSTEM,
                    "<-- ipa_topo_post_del - plugin not active\n");
        return 0;
    }
    switch (entry_type) {
    case TOPO_CONFIG_ENTRY:
        break;
    case TOPO_SEGMENT_ENTRY: {
        /* check if corresponding agreement exists and delete */
        TopoReplica *tconf = ipa_topo_util_get_conf_for_segment(del_entry);
        TopoReplicaSegment *tsegm;
        char *status;
        tsegm = ipa_topo_util_find_segment(tconf, del_entry);
        if (tsegm == NULL) {
            slapi_log_error(SLAPI_LOG_FATAL, IPA_TOPO_PLUGIN_SUBSYSTEM,
                            "segment to be deleted does not exist\n");
            break;
        }
        status = slapi_entry_attr_get_charptr(del_entry, "ipaReplTopoSegmentStatus");
        if (status == NULL || strcasecmp(status, SEGMENT_OBSOLETE_STR)) {
            /* obsoleted segments are a result of merge, do not remove repl agmt */
            ipa_topo_util_existing_agmts_del(tconf, tsegm,
                                         ipa_topo_get_plugin_hostname());
        }
        /* also remove segment from local topo conf */
        ipa_topo_cfg_segment_del(tconf, tsegm);
        slapi_ch_free_string(&status);
        break;
        }
    case TOPO_DOMLEVEL_ENTRY: {
        /* the domain level entry was just deleted
         * this should not happen, but it is identical
         * to setting domlevel to 0
         * log an error and inactivate plugin
         */
        slapi_log_error(SLAPI_LOG_PLUGIN, IPA_TOPO_PLUGIN_SUBSYSTEM,
                       "postop_del: domainlevel entry deleted - "
                       "plugin will be inactivated \n");
        break;
    }
    case TOPO_HOST_ENTRY:
        /* deleting an host entry means that the host becomes
         * unmanaged, probably because a replica is removed.
         * remove all marked replication agreements connecting
         * this host.
         */
        ipa_topo_util_delete_host(del_entry);
        ipa_topo_cfg_host_del(del_entry);
        break;
    case TOPO_IGNORE_ENTRY:
        break;
    }

    slapi_log_error(SLAPI_LOG_PLUGIN, IPA_TOPO_PLUGIN_SUBSYSTEM,
                    "<-- ipa_topo_post_del\n");
    return result;
}
Beispiel #10
0
int
ipa_topo_post_mod(Slapi_PBlock *pb)
{
    int result = SLAPI_PLUGIN_SUCCESS;
    int entry_type;
    Slapi_Entry *mod_entry = NULL;

    slapi_log_error(SLAPI_LOG_PLUGIN, IPA_TOPO_PLUGIN_SUBSYSTEM,
                    "--> ipa_topo_post_mod\n");

    /* 1. get entry  */
    slapi_pblock_get(pb,SLAPI_ENTRY_POST_OP,&mod_entry);

    if (mod_entry == NULL) {
        slapi_log_error(SLAPI_LOG_PLUGIN, IPA_TOPO_PLUGIN_SUBSYSTEM, "no entry\n");
        return (1);
    }
    /* 2. check if it is in scope */
    entry_type = ipa_topo_check_entry_type(mod_entry);
    if (0 == ipa_topo_get_plugin_active() &&
        entry_type != TOPO_DOMLEVEL_ENTRY) {
        slapi_log_error(SLAPI_LOG_PLUGIN, IPA_TOPO_PLUGIN_SUBSYSTEM,
                    "<-- ipa_topo_post_mod - plugin not active\n");
        return 0;
    }

    switch (entry_type) {
    case TOPO_CONFIG_ENTRY:
        break;
    case TOPO_SEGMENT_ENTRY: {
        LDAPMod **mods;
        TopoReplica *tconf = ipa_topo_util_get_conf_for_segment(mod_entry);
        TopoReplicaSegment *tsegm;
        tsegm = ipa_topo_util_find_segment(tconf, mod_entry);
        if (tsegm == NULL) {
            slapi_log_error(SLAPI_LOG_FATAL, IPA_TOPO_PLUGIN_SUBSYSTEM,
                            "ipa_topo_post_mod - segment to be modified does not exist\n");
            break;
        }
        slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods);
        ipa_topo_util_segment_update(tconf, tsegm, mods,ipa_topo_get_plugin_hostname());
        ipa_topo_util_existing_agmts_update(tconf, tsegm, mods,
                                            ipa_topo_get_plugin_hostname());
        /* also update local segment in tconf */
        break;
        }
    case TOPO_DOMLEVEL_ENTRY: {
        /* the domain level entry was just modified
         * check and set the level, if plugin gets activated
         * do initialization.
         */
        char *domlevel = slapi_entry_attr_get_charptr(mod_entry, "ipaDomainLevel");
        int already_active = ipa_topo_get_plugin_active();
        ipa_topo_set_domain_level(domlevel);
        ipa_topo_util_check_plugin_active();
        if (!already_active && ipa_topo_get_plugin_active()) {
            ipa_topo_util_start(0);
        }
        slapi_ch_free_string(&domlevel);
        break;
    }
    case TOPO_HOST_ENTRY:
    case TOPO_IGNORE_ENTRY:
        break;
    }
    slapi_log_error(SLAPI_LOG_PLUGIN, IPA_TOPO_PLUGIN_SUBSYSTEM,
                    "<-- ipa_topo_post_mod\n");
    return result;
}