freeipa/daemons/ipa-slapi-plugins/topology/topology_agmt.c
Ludwig Krispenz fcb9854dcb handle multiple managed suffixes
trigger topology updaet if suffix entry is added
    trigger topology update if managedSuffix is modified in host entry

Reviewed-by: Simo Sorce <simo@redhat.com>
Reviewed-By: Jan Cholasta <jcholast@redhat.com>
2015-10-15 14:24:33 +02:00

316 lines
10 KiB
C

#include "topology.h"
/* generate the dn for a topology segment by providing replroot and segment name */
char *
ipa_topo_segment_dn(TopoReplica *tconf, char *segname)
{
char *dn = NULL;
dn = slapi_ch_smprintf("cn=%s,%s", segname, tconf->shared_config_base);
return dn;
}
/* generate the rdn for a replication agreement by providing connected nodes */
char *
ipa_topo_agmt_gen_rdn(char *from, char *to)
{
char *agmt_rdn = slapi_ch_smprintf("cn=%s-to-%s", from, to);
return agmt_rdn;
}
/* generate the rdn for a replication agreement by providing target node */
char *
ipa_topo_agmt_std_rdn(char *to)
{
char *agmt_rdn = slapi_ch_smprintf("cn=meTo%s", to);
return agmt_rdn;
}
/* generate the dn for a replication agreement by providing replroot and host */
char *
ipa_topo_agreement_dn(TopoReplica *conf, TopoReplicaAgmt *agmt, char *rdn)
{
char *dn;
char *filter;
Slapi_PBlock *pb;
Slapi_Entry **entries;
int ret;
pb = slapi_pblock_new();
filter = slapi_ch_smprintf("(&(objectclass=nsds5replica)(nsds5replicaroot=%s))",
conf->repl_root);
slapi_search_internal_set_pb(pb, "cn=config", LDAP_SCOPE_SUB,
filter, NULL, 0, NULL, NULL,
ipa_topo_get_plugin_id(), 0);
slapi_search_internal_pb(pb);
slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &ret);
if (ret != 0) {
dn = NULL;
} else {
slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
if (NULL == entries || NULL == entries[0]) {
slapi_log_error(SLAPI_LOG_FATAL, IPA_TOPO_PLUGIN_SUBSYSTEM,
"ipa_topo_agreement_dn: no replica found\n");
dn = NULL;
} else if (rdn) {
dn = slapi_ch_smprintf("%s,%s", rdn,
slapi_entry_get_dn_const(entries[0]));
} else {
dn = slapi_ch_smprintf("cn=meTo%s,%s", agmt->target,
slapi_entry_get_dn_const(entries[0]));
}
}
slapi_free_search_results_internal(pb);
slapi_pblock_destroy(pb);
return dn;
}
int
ipa_topo_agmt_new(char *hostname, TopoReplica *conf, TopoReplicaAgmt *agmt)
{
int ret = 0;
if ((agmt->repl_bind_method == NULL) /* use GSSAPI as default */ ||
(strcasecmp(agmt->repl_bind_method,"SASL/GSSAPI") == 0)) {
ret = ipa_topo_agmt_setup(hostname, conf, agmt, 1);
} else {
ret = ipa_topo_agmt_setup(hostname, conf, agmt, 0);
}
return ret;
}
int ipa_topo_agmt_mod(TopoReplica *conf, TopoReplicaAgmt *agmt, LDAPMod **mods,
char *direction)
{
int ret;
Slapi_PBlock *pb;
char *dn = NULL;
Slapi_Entry **entries;
int i;
LDAPMod *tmp;
Slapi_Mods *smods = NULL;
dn = ipa_topo_agreement_dn(conf, agmt, agmt->rdn);
if (dn == NULL)
return 1;
pb = slapi_pblock_new();
slapi_search_internal_set_pb(pb, dn, LDAP_SCOPE_BASE,
"objectclass=*", NULL, 0, NULL, NULL,
ipa_topo_get_plugin_id(), 0);
slapi_search_internal_pb(pb);
slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &ret);
if (ret != 0) {
/* search failed */
slapi_log_error(SLAPI_LOG_FATAL, IPA_TOPO_PLUGIN_SUBSYSTEM,
"ipa_topo_agmt_mod: agreement not found: %s\n", dn);
goto done;
}
slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
if (NULL == entries || NULL == entries[0]) {
/* no entry */
ret = 1;
goto done;
}
/* apply mods to entry */
smods = slapi_mods_new();
for (i = 0; (mods != NULL) && (mods[i] != NULL); i++) {
char *type = ipa_topo_agmt_attr_is_managed(mods[i]->mod_type,direction);
if (type) {
tmp = mods[i];
switch (tmp->mod_op & ~LDAP_MOD_BVALUES) {
case LDAP_MOD_DELETE:
break;
case LDAP_MOD_ADD:
case LDAP_MOD_REPLACE:
slapi_mods_add_modbvps(smods, LDAP_MOD_REPLACE,
type, tmp->mod_bvalues);
break;
}
slapi_ch_free_string(&type);
}
}
if (slapi_mods_get_num_mods(smods) > 0) {
Slapi_DN *sdn = slapi_sdn_new_normdn_byref(dn);
ipa_topo_util_modify(sdn, smods);
slapi_sdn_free(&sdn);
} else {
slapi_ch_free_string(&dn);
}
slapi_mods_free(&smods);
done:
if (ret) slapi_ch_free_string(&dn);
slapi_free_search_results_internal(pb);
slapi_pblock_destroy(pb);
return ret;
}
int
ipa_topo_agmt_del(char *hostname, TopoReplica *conf, TopoReplicaAgmt *agmt)
{
char *dn = NULL;
int rc;
dn = ipa_topo_agreement_dn(conf, agmt, agmt->rdn);
slapi_log_error(SLAPI_LOG_FATAL, IPA_TOPO_PLUGIN_SUBSYSTEM,
"ipa_topo_agmt_del: %s\n", agmt->rdn?agmt->rdn:"RDN missing");
if (dn == NULL)
return (-1);
rc = ipa_topo_agmt_del_dn(dn);
slapi_ch_free_string(&dn);
return rc;
}
int
ipa_topo_agmt_del_dn(char *dn)
{
int ret = 0;
Slapi_PBlock *pb;
pb = slapi_pblock_new();
slapi_delete_internal_set_pb(pb, dn, NULL, NULL,
ipa_topo_get_plugin_id(), 0);
slapi_delete_internal_pb(pb);
slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &ret);
slapi_pblock_destroy(pb);
return ret;
}
int
ipa_topo_agmt_setup(char *hostname, TopoReplica *conf,
TopoReplicaAgmt *agmt, int isgssapi)
{
Slapi_Entry *e = NULL;
Slapi_PBlock *pb;
char *dn = NULL;
Slapi_DN *sdn = NULL;
char *cn;
char port[] = "389";
char *description;
int ret;
/* Set up the new replication agreement entry */
agmt->rdn = ipa_topo_agmt_gen_rdn(agmt->origin, agmt->target);
dn = ipa_topo_agreement_dn(conf, agmt, agmt->rdn);
if (dn == NULL)
return -1;
sdn = slapi_sdn_new_normdn_byref(dn);
e = slapi_entry_alloc();
/* the entry now owns the dup'd dn */
slapi_entry_init_ext(e, sdn, NULL); /* sdn is copied into e */
slapi_sdn_free(&sdn);
slapi_entry_add_string(e, SLAPI_ATTR_OBJECTCLASS, "nsds5replicationagreement");
slapi_entry_add_string(e, SLAPI_ATTR_OBJECTCLASS, "ipaReplTopoManagedAgreement");
cn = slapi_ch_smprintf("%s-to-%s", agmt->origin, agmt->target);
slapi_entry_add_string(e, "cn",cn);
slapi_ch_free_string(&cn);
slapi_entry_add_string(e, "nsds5replicahost",hostname);
slapi_entry_add_string(e, "nsds5replicaport",port);
slapi_entry_add_string(e, "nsds5replicatimeout",AGMT_TIMEOUT);
slapi_entry_add_string(e, "nsds5replicaroot",agmt->repl_root);
description = slapi_ch_smprintf("%s to %s", ipa_topo_get_plugin_hostname(), hostname);
slapi_entry_add_string(e, "description",description);
slapi_ch_free_string(&description);
slapi_entry_add_string(e, "ipaReplTopoManagedAgreementState",
"managed agreement - generated by topology plugin");
if (isgssapi) {
slapi_entry_add_string(e, "nsds5replicatransportinfo","LDAP");
slapi_entry_add_string(e, "nsds5replicabindmethod","SASL/GSSAPI");
} else {
slapi_entry_add_string(e, "nsds5replicabinddn",REPL_MAN_DN);
slapi_entry_add_string(e, "nsds5replicacredentials",REPL_MAN_PASSWD);
slapi_entry_add_string(e, "nsds5replicatransportinfo","TLS");
slapi_entry_add_string(e, "nsds5replicabindmethod","simple");
}
if (agmt->repl_attrs) {
slapi_entry_add_string(e, "nsDS5ReplicatedAttributeList",agmt->repl_attrs);
} else if (conf->repl_attrs) {
slapi_entry_add_string(e, "nsDS5ReplicatedAttributeList",conf->repl_attrs);
}
if (agmt->strip_attrs) {
slapi_entry_add_string(e, "nsds5ReplicaStripAttrs", agmt->strip_attrs);
} else if (conf->strip_attrs) {
slapi_entry_add_string(e, "nsds5ReplicaStripAttrs", conf->strip_attrs);
}
if (agmt->total_attrs) {
slapi_entry_add_string(e, "nsDS5ReplicatedAttributeListTotal",
agmt->total_attrs);
} else if (conf->total_attrs) {
slapi_entry_add_string(e, "nsDS5ReplicatedAttributeListTotal",
conf->total_attrs);
}
pb = slapi_pblock_new();
slapi_pblock_init(pb);
/* e will be consumed by slapi_add_internal() */
slapi_add_entry_internal_set_pb(pb, e, NULL, ipa_topo_get_plugin_id(), 0);
slapi_add_internal_pb(pb);
slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &ret);
slapi_pblock_destroy(pb);
return ret;
}
int
ipa_topo_agmt_initialize_replication(char *hostname,
TopoReplica *conf, TopoReplicaAgmt *agmt)
{
int ret = 0;
char *dn;
Slapi_Mods *smods = slapi_mods_new();
slapi_mods_add_string(smods, LDAP_MOD_REPLACE,
"nsds5ReplicaEnabled", "on");
slapi_mods_add_string(smods, LDAP_MOD_ADD,
"nsds5BeginReplicaRefresh", "start");
if (slapi_mods_get_num_mods(smods) > 0) {
dn = ipa_topo_agreement_dn(conf, agmt, agmt->rdn);
Slapi_DN *sdn = slapi_sdn_new_normdn_byref(dn);
ipa_topo_util_modify(sdn, smods);
slapi_sdn_free(&sdn);
}
slapi_mods_free(&smods);
return ret;
}
char *
ipa_topo_agmt_attr_is_managed(char *type, char *direction)
{
char *mtype = NULL;
char **mattrs = NULL;
char *subtype;
char *ctype = slapi_ch_strdup(type);
int i;
/* segment attrs have the form
* attrtype od attrtype;direction
* find the attrtype and return the corresponding
* repl agreeement attribute type
*/
subtype = strchr(ctype,';');
if (subtype) {
/* attr is handling specific direction,
* check if interested
*/
if (strstr(ctype,direction)) {
*subtype = '\0';
} else {
return NULL;
}
}
mattrs = ipa_topo_get_plugin_managed_attrs();
for (i=0; mattrs[i]; i++) {
if(0 == strcasecmp(mattrs[i], ctype)) {
mtype = slapi_ch_strdup(mattrs[i]);
break;
}
}
return mtype;
}