コード例 #1
0
ファイル: topology_pre.c プロジェクト: LiptonB/freeipa
int
ipa_topo_check_topology_disconnect(Slapi_PBlock *pb)
{
    int rc = 1;
    Slapi_Entry *del_entry;
    struct node_fanout *fanout = NULL;
    char *pi;

    /* we have to check if the operation is triggered by the
     * topology plugin itself - allow it
     */
    slapi_pblock_get(pb, SLAPI_PLUGIN_IDENTITY,&pi);
    if (pi && 0 == strcasecmp(pi, ipa_topo_get_plugin_id())) {
        return 0;
    }
    slapi_pblock_get(pb,SLAPI_DELETE_EXISTING_ENTRY,&del_entry);
    if (TOPO_SEGMENT_ENTRY != ipa_topo_check_entry_type(del_entry)) {
        return 0;
    } else {
        TopoReplica *tconf = ipa_topo_util_get_conf_for_segment(del_entry);
        if (tconf == NULL) {
            slapi_log_error(SLAPI_LOG_FATAL, IPA_TOPO_PLUGIN_SUBSYSTEM,
                            "topology not configured for segment\n");
            rc = 0; /* this segment is not controlled by the plugin */
            goto done;
        }
        TopoReplicaSegment *tsegm = NULL;
        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");
            goto done;
        }
        if (!ipa_topo_util_segment_is_managed(tconf,tsegm)) {
            /* not both endpoints are managed servers, delete is ok */
            rc = 0;
            goto done;
        }
        /* check if removal of segment would break connectivity */
        fanout = ipa_topo_connection_fanout(tconf, tsegm);
        if (fanout == NULL) goto done;

        if (ipa_topo_connection_exists(fanout, tsegm->from, tsegm->to) &&
            ipa_topo_connection_exists(fanout, tsegm->to, tsegm->from)) {
            rc = 0;
        }
        ipa_topo_connection_fanout_free(fanout);
    }

done:
    return rc;
}
コード例 #2
0
ファイル: topology_pre.c プロジェクト: LiptonB/freeipa
int
ipa_topo_check_host_updates(Slapi_PBlock *pb)
{
    int rc = 0;
    Slapi_Entry *mod_entry;
    char *pi;

    /* we have to check if the operation is triggered by the
     * topology plugin itself - allow it
     */
    slapi_pblock_get(pb, SLAPI_PLUGIN_IDENTITY,&pi);
    if (pi && 0 == strcasecmp(pi, ipa_topo_get_plugin_id())) {
        return 0;
    }
    slapi_pblock_get(pb,SLAPI_MODIFY_EXISTING_ENTRY,&mod_entry);
    if (TOPO_HOST_ENTRY == ipa_topo_check_entry_type(mod_entry) &&
        (ipa_topo_is_invalid_managed_suffix(pb))) {
        rc = 1;
    }
    return rc;
}
コード例 #3
0
ファイル: topology_pre.c プロジェクト: LiptonB/freeipa
int
ipa_topo_check_entry_move(Slapi_PBlock *pb)
{
    int rc = 0;
    int entry_type = TOPO_IGNORE_ENTRY;
    Slapi_Entry *modrdn_entry;
    slapi_pblock_get(pb,SLAPI_MODRDN_TARGET_ENTRY,&modrdn_entry);
    entry_type = ipa_topo_check_entry_type(modrdn_entry);
    switch (entry_type) {
    case TOPO_SEGMENT_ENTRY:
    case TOPO_CONFIG_ENTRY: {
        Slapi_DN *newsuperior = NULL;
        slapi_pblock_get(pb, SLAPI_MODRDN_NEWSUPERIOR_SDN, &newsuperior);
        if (newsuperior && slapi_sdn_get_dn(newsuperior)) rc = 1;
        break;
        }
    default:
        rc = 0;
        break;
    }
    return rc;
}
コード例 #4
0
ファイル: topology_pre.c プロジェクト: LiptonB/freeipa
int
ipa_topo_check_segment_is_valid(Slapi_PBlock *pb, char **errtxt)
{
    int rc = 0;
    Slapi_Entry *add_entry;
    char *pi;

    /* we have to check if the operation is triggered by the
     * topology plugin itself - allow it
     */
    slapi_pblock_get(pb, SLAPI_PLUGIN_IDENTITY,&pi);
    if (pi && 0 == strcasecmp(pi, ipa_topo_get_plugin_id())) {
        return 0;
    }
    slapi_pblock_get(pb,SLAPI_ADD_ENTRY,&add_entry);
    if (TOPO_SEGMENT_ENTRY != ipa_topo_check_entry_type(add_entry)) {
        return 0;
    } else {
        /* a new segment is added
         * verify that the segment does not yet exist
         */
        char *leftnode = slapi_entry_attr_get_charptr(add_entry,"ipaReplTopoSegmentLeftNode");
        char *rightnode = slapi_entry_attr_get_charptr(add_entry,"ipaReplTopoSegmentRightNode");
        char *dir = slapi_entry_attr_get_charptr(add_entry,"ipaReplTopoSegmentDirection");
        if (leftnode == NULL || rightnode == NULL || dir == NULL) {
                *errtxt = slapi_ch_smprintf("Segment definition is incomplete"
                                   ". Add rejected.\n");
            rc = 1;
        } else if (strcasecmp(dir,SEGMENT_DIR_BOTH) && strcasecmp(dir,SEGMENT_DIR_LEFT_ORIGIN) &&
            strcasecmp(dir,SEGMENT_DIR_RIGHT_ORIGIN)) {
                *errtxt = slapi_ch_smprintf("Segment has unsupported direction"
                                   ". Add rejected.\n");
                slapi_log_error(SLAPI_LOG_FATAL, IPA_TOPO_PLUGIN_SUBSYSTEM,
                                "segment has unknown direction: %s\n", dir);
                rc = 1;
        } else if (0 == strcasecmp(leftnode,rightnode)) {
                *errtxt = slapi_ch_smprintf("Segment is self referential"
                                   ". Add rejected.\n");
                slapi_log_error(SLAPI_LOG_FATAL, IPA_TOPO_PLUGIN_SUBSYSTEM,
                                "segment is self referential\n");
                rc = 1;
        } else {
            TopoReplicaSegment *tsegm = NULL;
            TopoReplica *tconf = ipa_topo_util_get_conf_for_segment(add_entry);
            if (tconf == NULL ) {
                *errtxt = slapi_ch_smprintf("Segment configuration suffix not found"
                                   ". Add rejected.\n");
                slapi_log_error(SLAPI_LOG_FATAL, IPA_TOPO_PLUGIN_SUBSYSTEM,
                                "topology not configured for segment\n");
                rc = 1;
            } else {
                tsegm = ipa_topo_util_find_segment(tconf, add_entry);
            }
            if (tsegm) {
                *errtxt = slapi_ch_smprintf("Segment already exists in topology"
                                   ". Add rejected.\n");
                slapi_log_error(SLAPI_LOG_FATAL, IPA_TOPO_PLUGIN_SUBSYSTEM,
                                "segment to be added does already exist\n");
                rc = 1;
            }
        }
        slapi_ch_free_string(&leftnode);
        slapi_ch_free_string(&rightnode);
        slapi_ch_free_string(&dir);
    }
    return rc;
}
コード例 #5
0
ファイル: topology_post.c プロジェクト: borland667/freeipa
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;
}
コード例 #6
0
ファイル: topology_post.c プロジェクト: borland667/freeipa
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;
}
コード例 #7
0
ファイル: topology_post.c プロジェクト: borland667/freeipa
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;
}