mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2024-12-28 01:41:14 -06:00
3f70c9aed7
when a suffix becomes managed for a host, the host needs to be added to the managed servers, otherwise connectivity check would fail Reviewed-By: Thierry Bordaz <tbordaz@redhat.com>
290 lines
10 KiB
C
290 lines
10 KiB
C
#include "topology.h"
|
|
|
|
/*
|
|
* detect if the plugin should handle this entry and return the entry type
|
|
*/
|
|
int
|
|
ipa_topo_check_entry_type(Slapi_Entry *entry)
|
|
{
|
|
int ret = TOPO_IGNORE_ENTRY;
|
|
Slapi_DN *add_dn = NULL;
|
|
char **ocs;
|
|
|
|
add_dn = slapi_entry_get_sdn(entry);
|
|
if (slapi_sdn_issuffix(add_dn,ipa_topo_get_plugin_shared_topo_dn())) {
|
|
/* check if it is a toplogy or a segment */
|
|
/* check if segment's left or right node is the local server*/
|
|
int i;
|
|
ocs = slapi_entry_attr_get_charray(entry,"objectclass");
|
|
|
|
for (i=0; ocs && ocs[i]; i++) {
|
|
if (strcasecmp(ocs[i],"ipaReplTopoConf") == 0) {
|
|
ret = TOPO_CONFIG_ENTRY;
|
|
break;
|
|
} else if (strcasecmp(ocs[i],"ipaReplTopoSegment") == 0) {
|
|
ret = TOPO_SEGMENT_ENTRY;
|
|
break;
|
|
}
|
|
}
|
|
} else if (slapi_sdn_isparent(ipa_topo_get_plugin_shared_hosts_dn(),add_dn)) {
|
|
ret = TOPO_HOST_ENTRY;
|
|
} else if (slapi_sdn_issuffix(add_dn,ipa_topo_get_domain_level_entry_dn())) {
|
|
ret = TOPO_DOMLEVEL_ENTRY;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
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 */
|
|
ipa_topo_util_suffix_init(add_entry);
|
|
break;
|
|
case TOPO_SEGMENT_ENTRY: {
|
|
TopoReplicaSegment *tsegm = NULL;
|
|
TopoReplica *tconf = ipa_topo_util_get_conf_for_segment(add_entry);
|
|
char *status;
|
|
if (tconf == NULL) {
|
|
slapi_log_error(SLAPI_LOG_FATAL, IPA_TOPO_PLUGIN_SUBSYSTEM,
|
|
"ipa_topo_post_add - config area for segment not found\n");
|
|
break;
|
|
}
|
|
/* 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: {
|
|
/* we are adding a new master, there could be
|
|
* a segment which so far was inactive since
|
|
* the host was not managed
|
|
*/
|
|
/* It will also add to list of managed hosts */
|
|
ipa_topo_util_add_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;
|
|
}
|
|
int
|
|
ipa_topo_post_mod(Slapi_PBlock *pb)
|
|
{
|
|
int result = SLAPI_PLUGIN_SUCCESS;
|
|
int entry_type;
|
|
Slapi_Entry *mod_entry = NULL;
|
|
Slapi_Entry *pre_entry = NULL;
|
|
LDAPMod **mods;
|
|
|
|
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);
|
|
slapi_pblock_get(pb,SLAPI_ENTRY_PRE_OP,&pre_entry);
|
|
slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods);
|
|
|
|
if (mod_entry == NULL || pre_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:
|
|
ipa_topo_util_suffix_update(mod_entry, pre_entry, mods);
|
|
break;
|
|
case TOPO_SEGMENT_ENTRY: {
|
|
TopoReplica *tconf = ipa_topo_util_get_conf_for_segment(mod_entry);
|
|
TopoReplicaSegment *tsegm = NULL;
|
|
if (tconf) tsegm = ipa_topo_util_find_segment(tconf, pre_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;
|
|
}
|
|
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: {
|
|
/* check i host needs to be added to the managed hosts
|
|
* and if segments need to be created */
|
|
ipa_topo_util_update_host(mod_entry, mods);
|
|
break;
|
|
}
|
|
case TOPO_IGNORE_ENTRY:
|
|
break;
|
|
}
|
|
slapi_log_error(SLAPI_LOG_PLUGIN, IPA_TOPO_PLUGIN_SUBSYSTEM,
|
|
"<-- ipa_topo_post_mod\n");
|
|
return result;
|
|
}
|
|
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");
|
|
|
|
/* 0. prevent operation on tombstones */
|
|
if (ipa_topo_util_is_tombstone_op(pb)) return 0;
|
|
|
|
/* 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 = NULL;
|
|
char *status;
|
|
if (tconf) 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);
|
|
ipa_topo_util_cleanruv(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;
|
|
}
|