Bug Summary

File:daemons/ipa-slapi-plugins/topology/topology_util.c
Warning:line 1780, column 13
Value stored to 'rc' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name topology_util.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mthread-model posix -mframe-pointer=all -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/10.0.0 -D HAVE_CONFIG_H -I . -I ../../.. -I . -I ./../common -D PREFIX="/usr/local" -D BINDIR="/usr/local/bin" -D LIBDIR="/usr/local/lib" -D LIBEXECDIR="/usr/local/libexec" -D DATADIR="/usr/local/share" -D USE_OPENLDAP -I /usr/include/dirsrv -I /usr/include/nspr4 -I /usr/include/nspr4 -I /usr/include/nss3 -I /usr/include/nspr4 -D __STDC_WANT_LIB_EXT1__=1 -D _DEFAULT_SOURCE=1 -D _POSIX_C_SOURCE=200809L -D PIC -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/10.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdebug-compilation-dir /home/heimes/redhat/freeipa/daemons/ipa-slapi-plugins/topology -ferror-limit 19 -fmessage-length 0 -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fdiagnostics-show-option -analyzer-output=html -faddrsig -o /home/heimes/redhat/freeipa/report/2020-06-05-101548-295465-1 -x c topology_util.c
1#include "topology.h"
2
3
4int
5ipa_topo_util_modify(Slapi_DN *entrySDN, Slapi_Mods *smods)
6{
7 int rc = 0;
8 Slapi_PBlock *mod_pb;
9 LDAPMod **mods;
10
11 mod_pb = slapi_pblock_new();
12 slapi_pblock_init(mod_pb);
13
14 mods = (slapi_mods_get_ldapmods_passout(smods));
15 slapi_modify_internal_set_pb_ext(mod_pb, entrySDN, mods, NULL((void*)0), NULL((void*)0),
16 ipa_topo_get_plugin_id(), 0);
17 slapi_modify_internal_pb(mod_pb);
18 slapi_pblock_get(mod_pb, SLAPI_PLUGIN_INTOP_RESULT15, &rc);
19 slapi_pblock_destroy(mod_pb);
20 if (rc != 0)
21 {
22 slapi_log_error(SLAPI_LOG_FATAL0, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
23 "ipa_topo_util_modify: "
24 "failed to modify entry (%s): error %d\n", slapi_sdn_get_dn(entrySDN), rc);
25 }
26 return rc;
27
28}
29
30Slapi_Entry *
31ipa_topo_util_get_entry (char *dn)
32{
33 int rc = 0;
34 Slapi_Entry *res_entry = NULL((void*)0);
35 Slapi_Entry **entries;
36 Slapi_PBlock *pb = NULL((void*)0);
37
38 pb = slapi_pblock_new();
39
40 slapi_search_internal_set_pb(pb, dn, LDAP_SCOPE_BASE((ber_int_t) 0x0000),
41 "objectclass=*", NULL((void*)0), 0, NULL((void*)0), NULL((void*)0),
42 ipa_topo_get_plugin_id(), 0);
43 slapi_search_internal_pb(pb);
44 slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT15, &rc);
45 if (rc != 0)
46 {
47 slapi_log_error(SLAPI_LOG_FATAL0, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
48 "ipa_topo_util_get_entry: "
49 "unable to read entry (%s): error %d\n", dn, rc);
50 } else {
51 slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES16, &entries);
52 if (NULL((void*)0) == entries || NULL((void*)0) == entries[0]) {
53 slapi_log_error(SLAPI_LOG_FATAL0, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
54 "ipa_topo_util_get_entry: entry not found: %s\n", dn);
55 } else {
56 res_entry = slapi_entry_dup(entries[0]);
57 }
58 }
59 slapi_free_search_results_internal(pb);
60 slapi_pblock_destroy(pb);
61 return res_entry;
62}
63
64/*
65 * the plugin needs to determine if segments in the shared topology
66 * affect the instance it is running in. There are many ways to determine
67 * this "pluginhost":
68 * - get the machines hostname
69 * - define hostname in plugin conf
70 * - use nsslapd-localhost from cn=config
71 * - ...
72 * This first version will use the nsslapd-localhost
73 */
74char *
75ipa_topo_util_get_pluginhost(void)
76{
77 int rc = 0;
78 Slapi_Entry **entries;
79 Slapi_PBlock *pb = NULL((void*)0);
80 char *host = NULL((void*)0);
81 char *host_attrs[] = {"nsslapd-localhost", NULL((void*)0)};
82
83 pb = slapi_pblock_new();
84
85 slapi_search_internal_set_pb(pb, "cn=config", LDAP_SCOPE_BASE((ber_int_t) 0x0000),
86 "objectclass=*", host_attrs, 0, NULL((void*)0), NULL((void*)0),
87 ipa_topo_get_plugin_id(), 0);
88 slapi_search_internal_pb(pb);
89 slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT15, &rc);
90 if (rc != 0)
91 {
92 slapi_log_error(SLAPI_LOG_FATAL0, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
93 "ipa_topo_util_get_localhost: "
94 "unable to read server configuration: error %d\n", rc);
95 } else {
96 slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES16, &entries);
97 if (NULL((void*)0) == entries || NULL((void*)0) == entries[0]) {
98 slapi_log_error(SLAPI_LOG_FATAL0, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
99 "ipa_topo_util_get_localhost: server configuration missing\n");
100 } else {
101 host = slapi_entry_attr_get_charptr(entries[0], "nsslapd-localhost");
102 }
103 }
104
105 slapi_free_search_results_internal(pb);
106 slapi_pblock_destroy(pb);
107 return host;
108}
109
110void
111ipa_topo_util_check_plugin_active(void)
112{
113 if (ipa_topo_get_min_domain_level() <= ipa_topo_get_domain_level()) {
114 ipa_topo_set_plugin_active(1);
115 } else {
116 ipa_topo_set_plugin_active(0);
117 }
118}
119
120void
121ipa_topo_util_set_domain_level(void)
122{
123 int rc = 0;
124 Slapi_Entry **entries;
125 Slapi_PBlock *pb = NULL((void*)0);
126
127 pb = slapi_pblock_new();
128 slapi_search_internal_set_pb(pb, ipa_topo_get_domain_level_entry(),
129 LDAP_SCOPE_BASE((ber_int_t) 0x0000),
130 "objectclass=*", NULL((void*)0), 0, NULL((void*)0), NULL((void*)0),
131 ipa_topo_get_plugin_id(), 0);
132 slapi_search_internal_pb(pb);
133 slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT15, &rc);
134 if (rc != 0)
135 {
136 slapi_log_error(SLAPI_LOG_PLUGIN14, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
137 "ipa_topo_util_set_domain_level: "
138 "failed to lookup domain level entry: error %d\n", rc);
139 } else {
140 slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES16, &entries);
141 if (NULL((void*)0) == entries || NULL((void*)0) == entries[0]) {
142 slapi_log_error(SLAPI_LOG_PLUGIN14, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
143 "ipa_topo_util_set_domain_level: domain level"
144 " entry does not exist, use default domain level of 0\n");
145 ipa_topo_set_domain_level(NULL((void*)0));
146 } else {
147 char *domlevel = slapi_entry_attr_get_charptr(entries[0], "ipaDomainLevel");
148 ipa_topo_set_domain_level(domlevel);
149 slapi_ch_free_string(&domlevel);
150 }
151 }
152 slapi_free_search_results_internal(pb);
153 slapi_pblock_destroy(pb);
154}
155
156TopoReplica *
157ipa_topo_util_get_replica_conf(char *repl_root)
158{
159 int rc = 0;
160 Slapi_Entry **entries;
161 Slapi_PBlock *pb = NULL((void*)0);
162 char *filter;
163 TopoReplica *topoRepl = NULL((void*)0);
164
165 pb = slapi_pblock_new();
166 filter = slapi_ch_smprintf("(ipaReplTopoConfRoot=%s)",repl_root);
167 slapi_search_internal_set_pb(pb, ipa_topo_get_plugin_shared_topo(),
168 LDAP_SCOPE_ONELEVEL((ber_int_t) 0x0001),
169 filter, NULL((void*)0), 0, NULL((void*)0), NULL((void*)0),
170 ipa_topo_get_plugin_id(), 0);
171 slapi_search_internal_pb(pb);
172 slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT15, &rc);
173 if (rc != 0)
174 {
175 slapi_log_error(SLAPI_LOG_FATAL0, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
176 "ipa_topo_util_get_replica_conf: "
177 "no replica configuration found: error %d\n", rc);
178 } else {
179 slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES16, &entries);
180 if (NULL((void*)0) == entries || NULL((void*)0) == entries[0]) {
181 slapi_log_error(SLAPI_LOG_FATAL0, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
182 "ipa_topo_util_get_replica_conf: "
183 "server configuration missing\n");
184 } else {
185 topoRepl = ipa_topo_util_replica_init(entries[0]);
186 }
187 }
188 slapi_ch_free_string(&filter);
189 slapi_free_search_results_internal(pb);
190 slapi_pblock_destroy(pb);
191
192 if (0 == topoRepl) {
193 slapi_log_error(SLAPI_LOG_FATAL0, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
194 "ipa_topo_util_get_replica_conf: "
195 "cannot create replica\n");
196 } else if (0 != ipa_topo_cfg_replica_add(topoRepl)) {
197 slapi_log_error(SLAPI_LOG_FATAL0, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
198 "ipa_topo_util_get_replica_conf: "
199 "replica already exists\n");
200 ipa_topo_cfg_replica_free(topoRepl);
201 topoRepl = NULL((void*)0);
202 }
203
204 return topoRepl;
205}
206
207TopoReplicaSegmentList *
208ipa_topo_util_get_replica_segments(TopoReplica *replica)
209{
210 TopoReplicaSegment *repl_segment = NULL((void*)0);
211 int rc = 0;
212 Slapi_Entry **entries;
213 Slapi_PBlock *pb = NULL((void*)0);
214 char *filter;
215
216 pb = slapi_pblock_new();
217 filter = "objectclass=*";
218 slapi_search_internal_set_pb(pb, replica->shared_config_base,
219 LDAP_SCOPE_ONELEVEL((ber_int_t) 0x0001), filter, NULL((void*)0), 0, NULL((void*)0), NULL((void*)0),
220 ipa_topo_get_plugin_id(), 0);
221 slapi_search_internal_pb(pb);
222 slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT15, &rc);
223 if (rc != 0)
224 {
225 slapi_log_error(SLAPI_LOG_PLUGIN14, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
226 "ipa_topo_util_get_replica_segments: "
227 "no replica configuration found: error %d\n", rc);
228 } else {
229 slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES16, &entries);
230 if (NULL((void*)0) == entries || NULL((void*)0) == entries[0]) {
231 slapi_log_error(SLAPI_LOG_PLUGIN14, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
232 "ipa_topo_util_get_replica_segments: no segments found\n");
233 } else {
234 /* get number of segments and allocate */
235 int i = 0;
236 for (i=0;entries[i];i++) {
237 repl_segment = ipa_topo_util_segment_from_entry(replica, entries[i]);
238 ipa_topo_cfg_segment_add(replica, repl_segment);
239 }
240 }
241 }
242 slapi_free_search_results_internal(pb);
243 slapi_pblock_destroy(pb);
244 return replica->repl_segments;
245}
246
247int
248ipa_topo_util_setup_servers(void)
249{
250 int rc = 0;
251 Slapi_Entry **entries;
252 Slapi_PBlock *pb = NULL((void*)0);
253 char *filter;
254
255 pb = slapi_pblock_new();
256 filter = "objectclass=*";
257 slapi_search_internal_set_pb(pb,ipa_topo_get_plugin_shared_hosts(),
258 LDAP_SCOPE_ONELEVEL((ber_int_t) 0x0001),
259 filter, NULL((void*)0), 0, NULL((void*)0), NULL((void*)0),
260 ipa_topo_get_plugin_id(), 0);
261 slapi_search_internal_pb(pb);
262 slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT15, &rc);
263 if (rc == LDAP_NO_SUCH_OBJECT0x20) {
264 slapi_log_error(SLAPI_LOG_PLUGIN14, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
265 "ipa_topo_util_setup_servers: "
266 "search for servers failed (continuing): error %d\n", rc);
267 /* masters not yet configured, continue plugin startup */
268 rc = 0;
269 } else if (rc != 0) {
270 slapi_log_error(SLAPI_LOG_PLUGIN14, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
271 "ipa_topo_util_setup_servers: "
272 "search for servers failed: error %d\n", rc);
273 } else {
274 slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES16, &entries);
275 if (NULL((void*)0) == entries || NULL((void*)0) == entries[0]) {
276 slapi_log_error(SLAPI_LOG_PLUGIN14, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
277 "ipa_topo_util_setup_servers: no servers found\n");
278 } else {
279 int i = 0;
280 for (i=0;entries[i];i++) {
281 ipa_topo_util_init_hosts(entries[i]);
282 }
283 }
284 }
285 slapi_free_search_results_internal(pb);
286 slapi_pblock_destroy(pb);
287 return rc;
288
289}
290
291TopoReplicaAgmt *
292ipa_topo_util_agmt_from_entry(Slapi_Entry *entry, char *replRoot, char *fromHost,
293 char *toHost, char *direction)
294{
295 TopoReplicaAgmt *agmt = NULL((void*)0);
296 char **mattrs = NULL((void*)0);
297 char *mattr = NULL((void*)0);
298 char *mval = NULL((void*)0);
299 int i;
300
301 agmt = (TopoReplicaAgmt *) slapi_ch_calloc(1,sizeof(TopoReplicaAgmt));
302 agmt->origin = slapi_ch_strdup(fromHost);
303 agmt->target = slapi_ch_strdup(toHost);
304 agmt->repl_root = slapi_ch_strdup(replRoot);
305
306 /* use std agmt rdn, it may be updated when matching real agmt is found */
307 agmt->rdn = ipa_topo_agmt_std_rdn(toHost);
308
309 mattrs = ipa_topo_get_plugin_managed_attrs();
310 for (i=0; mattrs[i]; i++) {
311 mattr = slapi_ch_smprintf("%s;%s",mattrs[i],direction);
312 mval = slapi_entry_attr_get_charptr(entry,mattr);
313 slapi_ch_free_string(&mattr);
314 if (mval == 0) {
315 mval = slapi_entry_attr_get_charptr(entry,mattrs[i]);
316 }
317 if (mval) {
318 ipa_topo_util_set_segm_attr(agmt, mattrs[i], mval);
319 }
320 }
321 return agmt;
322}
323
324int
325ipa_topo_util_segm_dir(char *direction)
326{
327 int dir = -1;
328 if (strcasecmp(direction,SEGMENT_DIR_BOTH"both") == 0){
329 dir = SEGMENT_BIDIRECTIONAL0x03;
330 } else if (strcasecmp(direction,SEGMENT_DIR_LEFT_ORIGIN"left-right") == 0) {
331 dir = SEGMENT_LEFT_RIGHT0x01;
332 } else if (strcasecmp(direction,SEGMENT_DIR_RIGHT_ORIGIN"right-left") == 0) {
333 dir = SEGMENT_RIGHT_LEFT0x02;
334 }
335 return dir;
336}
337
338TopoReplicaSegment *
339ipa_topo_util_find_segment(TopoReplica *conf, Slapi_Entry *entry)
340{
341 char *leftHost;
342 char *rightHost;
343 char *direction;
344 TopoReplicaSegment *segment = NULL((void*)0);
345
346 leftHost = slapi_entry_attr_get_charptr(entry,"ipaReplTopoSegmentLeftNode");
347 rightHost = slapi_entry_attr_get_charptr(entry,"ipaReplTopoSegmentRightNode");
348 direction = slapi_entry_attr_get_charptr(entry,"ipaReplTopoSegmentDirection");
349
350 segment = ipa_topo_cfg_segment_find(conf->repl_root, leftHost, rightHost, ipa_topo_util_segm_dir(direction));
351
352 slapi_ch_free((void **)&leftHost);
353 slapi_ch_free((void **)&rightHost);
354 slapi_ch_free((void **)&direction);
355 return segment;
356}
357
358TopoReplicaSegment *
359ipa_topo_util_segment_from_entry(TopoReplica *conf, Slapi_Entry *entry)
360{
361 char *leftHost;
362 char *rightHost;
363 char *direction;
364 char *name;
365 char *state;
366
367 TopoReplicaSegment *segment = NULL((void*)0);
368 segment = (TopoReplicaSegment *) slapi_ch_calloc(1,sizeof(TopoReplicaSegment));
369 leftHost = slapi_entry_attr_get_charptr(entry,"ipaReplTopoSegmentLeftNode");
370 rightHost = slapi_entry_attr_get_charptr(entry,"ipaReplTopoSegmentRightNode");
371 direction = slapi_entry_attr_get_charptr(entry,"ipaReplTopoSegmentDirection");
372 name = slapi_entry_attr_get_charptr(entry,"cn");
373 if (strcasecmp(direction,SEGMENT_DIR_BOTH"both") == 0){
374 segment->direct = SEGMENT_BIDIRECTIONAL0x03;
375 segment->left = ipa_topo_util_agmt_from_entry(entry,conf->repl_root,
376 leftHost,rightHost, "left");
377 segment->right = ipa_topo_util_agmt_from_entry(entry,conf->repl_root,
378 rightHost,leftHost, "right");
379 } else if (strcasecmp(direction,SEGMENT_DIR_LEFT_ORIGIN"left-right") == 0) {
380 segment->direct = SEGMENT_LEFT_RIGHT0x01;
381 segment->left = ipa_topo_util_agmt_from_entry(entry,conf->repl_root,
382 leftHost,rightHost, "left");
383 } else if (strcasecmp(direction,SEGMENT_DIR_RIGHT_ORIGIN"right-left") == 0) {
384 segment->direct = SEGMENT_RIGHT_LEFT0x02;
385 segment->right = ipa_topo_util_agmt_from_entry(entry,conf->repl_root,
386 rightHost,leftHost, "right");
387 }
388 state = slapi_entry_attr_get_charptr(entry,"ipaReplTopoSegmentStatus");
389 if (state && 0 == strcasecmp(state, SEGMENT_OBSOLETE_STR"obsolete")) {
390 /* state obsolete was set during merge */
391 segment->state = SEGMENT_OBSOLETE0x04;
392 } else if (state && 0 == strcasecmp(state, SEGMENT_REMOVED_STR"removed")) {
393 /* state removed was set during host delete */
394 segment->state = SEGMENT_REMOVED0x06;
395 } else {
396 segment->state = 0;
397 }
398 segment->from = leftHost;
399 segment->to = rightHost;
400 segment->name = name;
401 slapi_ch_free((void **)&direction);
402 slapi_ch_free((void **)&state);
403
404 return segment;
405}
406
407TopoReplicaSegment *
408ipa_topo_util_segm_from_agmt(Slapi_Entry *repl_agmt)
409{
410 TopoReplicaSegment *segment = NULL((void*)0);
411 TopoReplicaAgmt *agmt = NULL((void*)0);
412 segment = (TopoReplicaSegment *) slapi_ch_calloc(1,sizeof(TopoReplicaSegment));
413 agmt = (TopoReplicaAgmt *) slapi_ch_calloc(1,sizeof(TopoReplicaAgmt));
414 segment->from = slapi_ch_strdup(ipa_topo_get_plugin_hostname());
415 segment->to = slapi_entry_attr_get_charptr(repl_agmt, "nsds5replicahost");
416 segment->direct = SEGMENT_LEFT_RIGHT0x01;
417 segment->state = SEGMENT_AUTOGEN0x05;
418 segment->name = slapi_ch_smprintf("%s-to-%s", segment->from, segment->to);
419 segment->left = agmt;
420 segment->right = NULL((void*)0);
421
422 agmt->origin = slapi_ch_strdup(segment->from);
423 agmt->target = slapi_ch_strdup(segment->to);
424 agmt->rdn = slapi_entry_attr_get_charptr(repl_agmt, "cn");
425 agmt->repl_timeout = slapi_entry_attr_get_charptr(repl_agmt, "nsds5replicatimeout");
426 agmt->repl_root = slapi_entry_attr_get_charptr(repl_agmt, "nsds5replicaroot");
427
428 agmt->repl_attrs = slapi_entry_attr_get_charptr(repl_agmt, "nsDS5ReplicatedAttributeList");
429 agmt->strip_attrs = slapi_entry_attr_get_charptr(repl_agmt, "nsds5ReplicaStripAttrs");
430 agmt->total_attrs = slapi_entry_attr_get_charptr(repl_agmt, "nsDS5ReplicatedAttributeListTotal");
431 agmt->repl_bind_dn = slapi_entry_attr_get_charptr(repl_agmt, "nsds5replicabinddn");
432 agmt->repl_bind_cred = slapi_entry_attr_get_charptr(repl_agmt, "nsds5replicacredentials");
433 agmt->repl_transport = slapi_entry_attr_get_charptr(repl_agmt, "nsds5replicatransportinfo");
434 agmt->repl_bind_method = slapi_entry_attr_get_charptr(repl_agmt, "nsds5replicabindmethod");
435
436 return segment;
437
438}
439
440TopoReplica *
441ipa_topo_util_get_conf_for_segment(Slapi_Entry *segment_entry)
442{
443 /* we have a segment entry and need to determine the corresponding
444 * replica conf, to get the replica root */
445 TopoReplica *tconf = NULL((void*)0);
446 char *parent = slapi_dn_parent(slapi_entry_get_dn_const(segment_entry));
447
448 Slapi_Entry *conf = ipa_topo_util_get_entry(parent);
449 if (conf) {
450 tconf = ipa_topo_util_conf_from_entry(conf);
451 slapi_entry_free(conf);
452 }
453
454 return tconf;
455}
456
457TopoReplica *
458ipa_topo_util_replica_init(Slapi_Entry *conf)
459{
460 TopoReplica *topoRepl = NULL((void*)0);
461 topoRepl = ipa_topo_cfg_replica_new();
462 if (topoRepl) {
463 topoRepl->shared_config_base = slapi_ch_strdup(slapi_entry_get_dn_const(conf));
464 topoRepl->repl_root = slapi_entry_attr_get_charptr(conf,"ipaReplTopoConfRoot");
465 topoRepl->repl_attrs = slapi_entry_attr_get_charptr(conf, "nsDS5ReplicatedAttributeList");
466 topoRepl->strip_attrs = slapi_entry_attr_get_charptr(conf, "nsds5ReplicaStripAttrs");
467 topoRepl->total_attrs = slapi_entry_attr_get_charptr(conf, "nsDS5ReplicatedAttributeListTotal");
468 }
469 return topoRepl;
470}
471
472TopoReplica *
473ipa_topo_util_conf_from_entry(Slapi_Entry *entry)
474{
475 TopoReplica *conf = NULL((void*)0);
476 char *repl_root = NULL((void*)0);
477
478 repl_root = slapi_entry_attr_get_charptr(entry,"ipaReplTopoConfRoot");
479 if (NULL((void*)0) == repl_root) return NULL((void*)0);
480
481 conf = ipa_topo_cfg_replica_find(repl_root, 1);
482 if (conf) {
483 slapi_ch_free((void **)&repl_root);
484 return conf;
485 } else {
486 conf = (TopoReplica *) slapi_ch_calloc(1,sizeof(TopoReplica));
487 conf->repl_root = repl_root;
488 /* TBD read defined managed attrs as defaults */
489 return conf;
490 }
491}
492void
493ipa_topo_util_segm_modify (TopoReplica *tconf,
494 TopoReplicaSegment *tsegm,
495 Slapi_Mods *smods)
496{
497 char *dn = NULL((void*)0);
498
499 dn = ipa_topo_segment_dn(tconf, tsegm->name);
500
501 if (dn == NULL((void*)0)) return;
502
503 if (slapi_mods_get_num_mods(smods) > 0) {
504 Slapi_DN *sdn = slapi_sdn_new_normdn_byref(dn);
505 ipa_topo_util_modify(sdn, smods);
506 slapi_sdn_free(&sdn);
507 }
508
509 slapi_ch_free_string(&dn);
510}
511
512void
513ipa_topo_util_remove_init_attr(TopoReplica *repl_conf, TopoReplicaAgmt *topo_agmt)
514{
515 TopoReplicaSegmentList *seglist = repl_conf->repl_segments;
516 TopoReplicaSegment *segment = NULL((void*)0);
517 char *dirattr = NULL((void*)0);
518
519 while (seglist) {
520 segment = seglist->segm;
521 if (segment->left == topo_agmt) {
522 dirattr = "nsds5beginreplicarefresh;left";
523 break;
524 } else if (segment->right == topo_agmt) {
525 dirattr = "nsds5beginreplicarefresh;right";
526 break;
527 } else {
528 segment = NULL((void*)0);
529 }
530 seglist = seglist->next;
531 }
532 if (segment) {
533 Slapi_Mods *smods = slapi_mods_new();
534 slapi_mods_add_string(smods, LDAP_MOD_DELETE(0x0001),
535 dirattr, "");
536 ipa_topo_util_segm_modify (repl_conf, segment, smods);
537 slapi_mods_free(&smods);
538 }
539}
540
541void
542ipa_topo_util_set_agmt_rdn(TopoReplicaAgmt *topo_agmt, Slapi_Entry *repl_agmt)
543{
544 const Slapi_DN *agmt_dn = slapi_entry_get_sdn_const(repl_agmt);
545 Slapi_RDN *agmt_rdn = slapi_rdn_new();
546 slapi_sdn_get_rdn(agmt_dn, agmt_rdn);
547 const char *agmt_rdn_str = slapi_rdn_get_rdn(agmt_rdn);
548 if (strcasecmp(agmt_rdn_str, topo_agmt->rdn)) {
549 slapi_ch_free_string(&topo_agmt->rdn);
550 topo_agmt->rdn = slapi_ch_strdup(agmt_rdn_str);
551 }
552 slapi_rdn_free(&agmt_rdn);
553}
554
555int
556ipa_topo_util_update_agmt_rdn(TopoReplica *conf, TopoReplicaAgmt *agmt,
557 char *toHost)
558{
559 int rc = 0;
560 Slapi_PBlock *pb = NULL((void*)0);
561 Slapi_Entry **entries = NULL((void*)0);
562 char *filter;
563
564 pb = slapi_pblock_new();
565 filter = slapi_ch_smprintf("(&(objectclass=nsds5replicationagreement)"
566 "(nsds5replicaroot=%s)(nsds5replicahost=%s))",
567 conf->repl_root, toHost);
568 slapi_search_internal_set_pb(pb, "cn=config", LDAP_SCOPE_SUB((ber_int_t) 0x0002),
569 filter, NULL((void*)0), 0, NULL((void*)0), NULL((void*)0),
570 ipa_topo_get_plugin_id(), 0);
571 slapi_search_internal_pb(pb);
572 slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT15, &rc);
573 if (rc == 0) {
574 slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES16, &entries);
575 }
576
577 if (NULL((void*)0) == entries || NULL((void*)0) == entries[0]) {
578 slapi_log_error(SLAPI_LOG_PLUGIN14, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
579 "ipa_topo_util_update_agmt_rdn: "
580 "no agreements found\n");
581 } else {
582 ipa_topo_util_set_agmt_rdn(agmt, entries[0]);
583 }
584
585 slapi_free_search_results_internal(pb);
586 slapi_ch_free_string(&filter);
587 slapi_pblock_destroy(pb);
588 return rc;
589}
590
591int
592ipa_topo_util_update_agmt_list(TopoReplica *conf, TopoReplicaSegmentList *repl_segments)
593{
594 int rc = 0;
595 int i;
596 int nentries;
597 Slapi_Entry **entries = NULL((void*)0);
598 Slapi_Entry *repl_agmt;
599 Slapi_PBlock *pb = NULL((void*)0);
600 char *filter;
601
602 /* find all replication agreements */
603
604 pb = slapi_pblock_new();
605 filter = slapi_ch_smprintf("(&(objectclass=nsds5replicationagreement)(nsds5replicaroot=%s))",
606 conf->repl_root);
607 slapi_search_internal_set_pb(pb, "cn=config", LDAP_SCOPE_SUB((ber_int_t) 0x0002),
608 filter, NULL((void*)0), 0, NULL((void*)0), NULL((void*)0),
609 ipa_topo_get_plugin_id(), 0);
610 slapi_search_internal_pb(pb);
611 slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT15, &rc);
612 if (rc != 0)
613 {
614 slapi_log_error(SLAPI_LOG_FATAL0, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
615 "ipa_topo_util_update_agmts_list: "
616 "cannot read replication agreeements: error %d\n", rc);
617 goto error_return;
618 } else {
619 slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES16, &entries);
620 if (NULL((void*)0) == entries || NULL((void*)0) == entries[0]) {
621 slapi_log_error(SLAPI_LOG_PLUGIN14, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
622 "ipa_topo_util_update_agmts_list: "
623 "no agreements found\n");
624 goto update_only;
625 }
626 }
627
628 /* for each agreement find segment */
629 nentries = 0;
630 repl_agmt = entries[0];
631 while (repl_agmt) {
632 char *targetHost;
633 TopoReplicaAgmt *topo_agmt;
634 TopoReplicaSegment *topo_segm;
635
636 slapi_log_error(SLAPI_LOG_PLUGIN14, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
637 "ipa_topo_util_update_agmts_list: processing agreement: %s\n",
638 slapi_entry_get_dn_const(repl_agmt));
639
640 targetHost = slapi_entry_attr_get_charptr(repl_agmt,"nsDS5ReplicaHost");
641 if(!targetHost){
642 slapi_log_error(SLAPI_LOG_PLUGIN14, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
643 "ipa_topo_util_update_agmts: "
644 "cannot read targethost: error %d\n", rc);
645 continue;
646 }
647 topo_agmt = ipa_topo_util_find_segment_agmt(conf->repl_segments,
648 ipa_topo_get_plugin_hostname(),
649 targetHost);
650 if (topo_agmt) {
651 /* compare rdns, use rdn of existing agreement */
652 ipa_topo_util_set_agmt_rdn(topo_agmt, repl_agmt);
653
654 /* update agreement params which are different in the segment*/
655 char *segm_attr_val;
656 char *agmt_attr_val;
657 Slapi_Mods *smods = slapi_mods_new();
658 char **mattrs = ipa_topo_get_plugin_managed_attrs();
659 for (i=0; mattrs[i]; i++) {
660 segm_attr_val = ipa_topo_util_get_segm_attr(topo_agmt,mattrs[i]);
661 if (segm_attr_val) {
662 if (0 == strcasecmp(mattrs[i], "nsds5BeginReplicaRefresh")) {
663 /* we have to remove this attr from the segment, this is
664 * processed on a server, which is the supplier side of
665 * an agreement.
666 */
667 ipa_topo_util_remove_init_attr(conf, topo_agmt);
668 continue;
669 }
670 agmt_attr_val = slapi_entry_attr_get_charptr(repl_agmt,mattrs[i]);
671 if (agmt_attr_val == NULL((void*)0) ||
672 strcasecmp(agmt_attr_val,segm_attr_val)) {
673 /* value does not exist in agmt or
674 * is different from segment: replace
675 */
676 slapi_mods_add_string(smods,
677 LDAP_MOD_REPLACE(0x0002),
678 mattrs[i],
679 segm_attr_val);
680 }
681
682 }
683 }
684 if (slapi_mods_get_num_mods(smods) > 0) {
685 ipa_topo_util_modify((Slapi_DN *)slapi_entry_get_sdn_const(repl_agmt),
686 smods);
687 }
688 slapi_mods_free(&smods);
689 } else {
690 if (ipa_topo_util_agmt_is_marked(repl_agmt)) {
691 /* agreement is marked and no segment exists, delete agreement */
692 ipa_topo_agmt_del_dn((char *)slapi_sdn_get_dn(slapi_entry_get_sdn_const(repl_agmt)));
693 } else {
694 /* generate segment from agreement */
695 topo_segm = ipa_topo_util_segm_from_agmt(repl_agmt);
696 rc = ipa_topo_util_segment_write(conf, topo_segm);
697 if ( rc != 0) {
698 slapi_log_error(SLAPI_LOG_PLUGIN14, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
699 "ipa_topo_util_update_agmts_list: "
700 "failed to write segment: error %d\n", rc);
701 }
702 rc = ipa_topo_util_agmt_mark(conf, repl_agmt, topo_segm);
703 if (rc != 0) {
704 slapi_log_error(SLAPI_LOG_PLUGIN14, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
705 "ipa_topo_util_update_agmt_list: "
706 "failed to mark agreement for host %s: error %d\n", targetHost, rc);
707 }
708 /* segment has been added in postop of segment write,
709 * prevent adding an agreement again
710 */
711 ipa_topo_cfg_segment_set_visited(conf, topo_segm);
712 }
713 }
714
715 repl_agmt = entries[++nentries];
716 }
717 slapi_free_search_results_internal(pb);
718
719update_only:
720 /* check if segments not covered by agreement exist
721 * add agreeement
722 */
723 ipa_topo_util_missing_agmts_add_list(conf, conf->repl_segments,
724 ipa_topo_get_plugin_hostname());
725
726error_return:
727 slapi_ch_free_string(&filter);
728 slapi_pblock_destroy(pb);
729 return rc;
730}
731
732TopoReplicaAgmt *
733ipa_topo_util_find_segment_agmt(TopoReplicaSegmentList *repl_segments,
734 char *fromHost, char *toHost)
735{
736 TopoReplicaAgmt *agmt = NULL((void*)0);
737 TopoReplicaAgmt *agmtfound = NULL((void*)0);
738 TopoReplicaSegmentList *segment = repl_segments;
739
740 while (segment) {
741 if (segment->visited) {
742 segment = segment->next;
743 continue;
744 }
745 agmt = segment->segm->left;
746 if (agmt && (0 == strcasecmp(agmt->origin, fromHost)) &&
747 (0 == strcasecmp(agmt->target, toHost))) {
748 agmtfound = agmt;
749 break;
750 }
751 agmt = segment->segm->right;
752 if (agmt && (0 == strcasecmp(agmt->origin, fromHost)) &&
753 (0 == strcasecmp(agmt->target, toHost))) {
754 agmtfound = agmt;
755 break;
756 }
757 segment = segment->next;
758 }
759 if (segment) {
760 segment->visited = 1;
761 }
762 return agmtfound;
763}
764
765void
766ipa_topo_util_missing_agmts_add_list(TopoReplica *repl_conf,
767 TopoReplicaSegmentList *repl_segments,
768 char *fromHost)
769{
770 TopoReplicaSegmentList *segment = repl_segments;
771
772 while (segment) {
773 if (segment->visited) {
774 segment->visited = 0;
775 segment = segment->next;
776 continue;
777 }
778 ipa_topo_util_missing_agmts_add(repl_conf, segment->segm, fromHost);
779 segment = segment->next;
780 }
781}
782
783void
784ipa_topo_util_missing_agmts_add(TopoReplica *repl_conf,
785 TopoReplicaSegment *segment,
786 char *fromHost)
787{
788 if (0 == strcasecmp(segment->from, fromHost)) {
789 if (segment->left) {
790 ipa_topo_agmt_new(segment->to,repl_conf, segment->left);
791 }
792 } else if (0 == strcasecmp(segment->to, fromHost)) {
793 if (segment->right) {
794 ipa_topo_agmt_new(segment->from,repl_conf, segment->right);
795 }
796 }
797}
798
799void
800ipa_topo_util_existing_agmts_del_list(TopoReplica *repl_conf,
801 TopoReplicaSegmentList *repl_segments,
802 char *fromHost)
803{
804 TopoReplicaSegmentList *segment = repl_segments;
805
806 while (segment) {
807 if (segment->visited) {
808 segment->visited = 0;
809 segment = segment->next;
810 continue;
811 }
812 ipa_topo_util_existing_agmts_del(repl_conf, segment->segm,fromHost);
813 segment = segment->next;
814 }
815}
816
817void
818ipa_topo_util_existing_agmts_del(TopoReplica *repl_conf,
819 TopoReplicaSegment *segment,
820 char *fromHost)
821{
822 if (0 == strcasecmp(segment->from, fromHost)) {
823 if (segment->left) {
824 ipa_topo_agmt_del(segment->to,repl_conf, segment->left);
825 }
826 } else if (0 == strcasecmp(segment->to, fromHost)) {
827 if (segment->right) {
828 ipa_topo_agmt_del(segment->from,repl_conf, segment->right);
829 }
830 }
831}
832
833void
834ipa_topo_util_existing_agmts_update_list(TopoReplica *repl_conf,
835 TopoReplicaSegmentList *repl_segments,
836 LDAPMod **mods ,char *fromHost)
837{
838 TopoReplicaSegmentList *segment = repl_segments;
839
840 while (segment) {
841 if (segment->visited) {
842 segment->visited = 0;
843 segment = segment->next;
844 continue;
845 }
846 ipa_topo_util_existing_agmts_update(repl_conf, segment->segm, mods, fromHost);
847 segment = segment->next;
848 }
849}
850
851void
852ipa_topo_util_existing_agmts_update(TopoReplica *repl_conf,
853 TopoReplicaSegment *segment,
854 LDAPMod **mods ,char *fromHost)
855{
856 TopoReplicaAgmt *l_agmt = NULL((void*)0);
857 TopoReplicaAgmt *r_agmt = NULL((void*)0);
858 l_agmt = segment->left;
859 r_agmt = segment->right;
860 if (l_agmt && r_agmt) {
861 if (0 == strcasecmp(l_agmt->origin, fromHost)) {
862 ipa_topo_agmt_mod(repl_conf, l_agmt, mods, "left");
863 } else if (0 == strcasecmp(r_agmt->origin, fromHost)) {
864 ipa_topo_agmt_mod(repl_conf, r_agmt, mods, "right");
865 }
866 }
867}
868
869void
870ipa_topo_util_segment_update(TopoReplica *repl_conf,
871 TopoReplicaSegment *segment,
872 LDAPMod **mods ,char *fromHost)
873{
874 int i;
875 for (i = 0; (mods != NULL((void*)0)) && (mods[i] != NULL((void*)0)); i++) {
876 switch (mods[i]->mod_op & ~LDAP_MOD_BVALUES(0x0080)) {
877 case LDAP_MOD_DELETE(0x0001):
878 break;
879 case LDAP_MOD_ADD(0x0000):
880 case LDAP_MOD_REPLACE(0x0002):
881 if (0 == strcasecmp(mods[i]->mod_type,"ipaReplTopoSegmentDirection")) {
882 if (0 == strcasecmp(mods[i]->mod_bvaluesmod_vals.modv_bvals[0]->bv_val,"both")) {
883 TopoReplicaSegment *ex_segm;
884 if (segment->direct == SEGMENT_LEFT_RIGHT0x01) {
885 ex_segm = ipa_topo_cfg_replica_segment_find(repl_conf, segment->from, segment->to,
886 SEGMENT_RIGHT_LEFT0x02, 1);
887 if (ex_segm) {
888 segment->right = ipa_topo_cfg_agmt_dup(ex_segm->left?ex_segm->left:ex_segm->right);
889 } else {
890 segment->right = ipa_topo_cfg_agmt_dup_reverse(segment->left);
891 if(0 == strcasecmp(fromHost,segment->right->origin)) {
892 ipa_topo_util_update_agmt_rdn(repl_conf, segment->right, segment->right->target);
893 }
894 }
895 } else if (segment->direct == SEGMENT_RIGHT_LEFT0x02) {
896 ex_segm = ipa_topo_cfg_replica_segment_find(repl_conf, segment->from, segment->to,
897 SEGMENT_LEFT_RIGHT0x01, 1);
898 if (ex_segm) {
899 segment->left = ipa_topo_cfg_agmt_dup(ex_segm->left?ex_segm->left:ex_segm->right);
900 } else {
901 segment->left = ipa_topo_cfg_agmt_dup_reverse(segment->right);
902 if(0 == strcasecmp(fromHost,segment->left->origin)) {
903 ipa_topo_util_update_agmt_rdn(repl_conf, segment->left, segment->left->target);
904 }
905 }
906 }
907 segment->direct = SEGMENT_BIDIRECTIONAL0x03;
908 } else {
909 /* only onedirectionl --> bidirectional handled so far */
910 slapi_log_error(SLAPI_LOG_FATAL0, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
911 "ipa_topo_util_segment_update: no downgrade of direction\n");
912 }
913 } else if (0 == strcasecmp(mods[i]->mod_type,"ipaReplTopoSegmentStatus")) {
914 if (0 == strcasecmp(mods[i]->mod_bvaluesmod_vals.modv_bvals[0]->bv_val,SEGMENT_OBSOLETE_STR"obsolete")) {
915 segment->state = SEGMENT_OBSOLETE0x04;
916 } else if (0 == strcasecmp(mods[i]->mod_bvaluesmod_vals.modv_bvals[0]->bv_val,SEGMENT_AUTOGEN_STR"autogen")) {
917 segment->state = SEGMENT_AUTOGEN0x05;
918 }
919 }
920 break;
921 }
922 }
923}
924
925char *
926ipa_topo_util_get_segm_attr(TopoReplicaAgmt *agmt, char *attr_type)
927{
928 char *attr = NULL((void*)0);
929 if (strcasecmp(attr_type, "nsds5ReplicaEnabled") == 0) {
930 attr = agmt->enabled;
931 } else if (strcasecmp(attr_type, "nsds5ReplicaStripAttrs") == 0){
932 attr = agmt->strip_attrs;
933 } else if (strcasecmp(attr_type, "nsds5ReplicatedAttributeList") == 0){
934 attr = agmt->repl_attrs;
935 } else if (strcasecmp(attr_type, "nsDS5ReplicatedAttributeListTotal") == 0) {
936 attr = agmt->total_attrs;
937 } else if (strcasecmp(attr_type, "nsds5BeginReplicaRefresh") == 0){
938 attr = agmt->repl_refresh;
939 } else if (strcasecmp(attr_type, "nsds5replicaTimeout") == 0) {
940 attr = agmt->repl_timeout;
941 } else if (strcasecmp(attr_type, "nsds5ReplicaEnabled") == 0) {
942 attr = agmt->enabled;
943 } else if (strcasecmp(attr_type, "nsds5replicaSessionPauseTime") == 0) {
944 attr = agmt->repl_pause;
945 } else if (strcasecmp(attr_type, "nsds5replicabinddn") == 0) {
946 attr = agmt->repl_bind_dn;
947 } else if (strcasecmp(attr_type, "nsds5replicacredentials") == 0) {
948 attr = agmt->repl_bind_cred;
949 } else if (strcasecmp(attr_type, "nsds5replicatransportinfo") == 0) {
950 attr = agmt->repl_transport;
951 } else if (strcasecmp(attr_type, "nsds5replicabindmethod") == 0) {
952 attr = agmt->repl_bind_method;
953 }
954 return attr;
955}
956
957void
958ipa_topo_util_set_segm_attr(TopoReplicaAgmt *agmt, char *attr_type, char *attr_val)
959{
960 if (strcasecmp(attr_type, "nsds5ReplicaEnabled") == 0) {
961 agmt->enabled = attr_val;
962 } else if (strcasecmp(attr_type, "nsds5ReplicaStripAttrs") == 0){
963 agmt->strip_attrs = attr_val;
964 } else if (strcasecmp(attr_type, "nsds5ReplicatedAttributeList") == 0){
965 agmt->repl_attrs = attr_val;
966 } else if (strcasecmp(attr_type, "nsDS5ReplicatedAttributeListTotal") == 0) {
967 agmt->total_attrs = attr_val;
968 } else if (strcasecmp(attr_type, "nsds5BeginReplicaRefresh") == 0){
969 agmt->repl_refresh = attr_val;
970 } else if (strcasecmp(attr_type, "nsds5replicaTimeout") == 0) {
971 agmt->repl_timeout = attr_val;
972 } else if (strcasecmp(attr_type, "nsds5ReplicaEnabled") == 0) {
973 agmt->enabled = attr_val;
974 } else if (strcasecmp(attr_type, "nsds5replicaSessionPauseTime") == 0) {
975 agmt->repl_pause = attr_val;
976 } else if (strcasecmp(attr_type, "nsds5replicabinddn") == 0) {
977 agmt->repl_bind_dn = attr_val;
978 } else if (strcasecmp(attr_type, "nsds5replicacredentials") == 0) {
979 agmt->repl_bind_cred = attr_val;
980 } else if (strcasecmp(attr_type, "nsds5replicatransportinfo") == 0) {
981 agmt->repl_transport = attr_val;
982 } else if (strcasecmp(attr_type, "nsds5replicabindmethod") == 0) {
983 agmt->repl_bind_method = attr_val;
984 }
985}
986
987/* check if the entry is a standard replication agreement (ignore winsync)
988 * and if the replication suffix is in the list of managed replication roots.
989 * This qualifies the entry as a candidate, further checks have to be done.
990 */
991int
992ipa_topo_util_entry_is_candidate(Slapi_Entry *e)
993{
994 char **ocs;
995 char *oc = NULL((void*)0);
996 char *repl_root;
997 char **shared_root;
998 int rc = 0;
999 int i;
1000
1001 ocs = slapi_entry_attr_get_charray(e,"objectclass");
1002
1003 for (i=0; ocs && ocs[i]; i++) {
1004 if (strcasecmp(ocs[i],"nsds5ReplicationAgreement") == 0) {
1005 oc = ocs[i];
1006 break;
1007 }
1008 }
1009
1010 if (oc) {
1011 repl_root = slapi_entry_attr_get_charptr(e,"nsDS5ReplicaRoot");
1012 shared_root = ipa_topo_get_plugin_replica_root();
1013 for (i=0; shared_root && shared_root[i]; i++) {
1014 if (strcasecmp(repl_root,shared_root[i]) == 0) {
1015 rc = 1;
1016 break;
1017 }
1018 }
1019 slapi_ch_free((void **) &repl_root);
1020 }
1021 slapi_ch_array_free(ocs);
1022 return rc;
1023}
1024
1025int
1026ipa_topo_util_target_is_managed(Slapi_Entry *e)
1027{
1028 char *targethost;
1029 char *repl_root;
1030 TopoReplica *replica;
1031 int ret = 0;
1032
1033 /* first check: is the entry managed alreday by the topology plugin */
1034 /* at the moment only replication agreements are managed */
1035 if (ipa_topo_util_agmt_is_marked(e)) return 1;
1036
1037 /* next check: is the replcation agreement targeting a meanged server
1038 * deny agreements to an managed server
1039 * allow other agreements
1040 */
1041 targethost = slapi_entry_attr_get_charptr(e,"nsDS5ReplicaHost");
1042 repl_root = slapi_entry_attr_get_charptr(e,"nsDS5ReplicaRoot");
1043 replica = ipa_topo_cfg_replica_find(repl_root,1);
1044 if (targethost && replica &&
1045 ipa_topo_cfg_host_find(replica, targethost, 1) &&
1046 ipa_topo_cfg_host_find(replica, ipa_topo_get_plugin_hostname(), 1)) {
1047 ret = 1;
1048 }
1049 slapi_ch_free_string(&targethost);
1050 slapi_ch_free_string(&repl_root);
1051
1052 return ret;
1053
1054}
1055
1056int ipa_topo_util_segment_is_managed(TopoReplica *tconf, TopoReplicaSegment *tsegm)
1057{
1058 int ret = 0;
1059
1060 if (ipa_topo_cfg_host_find(tconf, tsegm->from, 1) &&
1061 ipa_topo_cfg_host_find(tconf, tsegm->to, 1)) {
1062 ret = 1;
1063 }
1064 return ret;
1065}
1066
1067void
1068ipa_topo_util_segm_update (TopoReplica *tconf,
1069 TopoReplicaSegment *tsegm,
1070 int property)
1071{
1072 char *dn = NULL((void*)0);
1073 Slapi_Mods *smods;
1074
1075 dn = ipa_topo_segment_dn(tconf, tsegm->name);
1076
1077 if (dn == NULL((void*)0)) return;
1078
1079 /* apply mods to entry */
1080 smods = slapi_mods_new();
1081 switch (property) {
1082 case SEGMENT_BIDIRECTIONAL0x03:
1083 tsegm->direct = SEGMENT_BIDIRECTIONAL0x03;
1084 slapi_mods_add_string(smods, LDAP_MOD_REPLACE(0x0002),
1085 "ipaReplTopoSegmentDirection", "both");
1086 break;
1087 case SEGMENT_LEFT_RIGHT0x01:
1088 tsegm->direct = SEGMENT_LEFT_RIGHT0x01;
1089 slapi_mods_add_string(smods, LDAP_MOD_REPLACE(0x0002),
1090 "ipaReplTopoSegmentDirection", "left-right");
1091 break;
1092 case SEGMENT_RIGHT_LEFT0x02:
1093 tsegm->direct = SEGMENT_RIGHT_LEFT0x02;
1094 slapi_mods_add_string(smods, LDAP_MOD_REPLACE(0x0002),
1095 "ipaReplTopoSegmentDirection", "right-left");
1096 break;
1097 case SEGMENT_OBSOLETE0x04:
1098 tsegm->state = SEGMENT_OBSOLETE0x04;
1099 slapi_mods_add_string(smods, LDAP_MOD_REPLACE(0x0002),
1100 "ipaReplTopoSegmentStatus", SEGMENT_OBSOLETE_STR"obsolete");
1101 break;
1102 case SEGMENT_REMOVED0x06:
1103 tsegm->state = SEGMENT_OBSOLETE0x04;
1104 slapi_mods_add_string(smods, LDAP_MOD_REPLACE(0x0002),
1105 "ipaReplTopoSegmentStatus", SEGMENT_REMOVED_STR"removed");
1106 break;
1107 }
1108 if (slapi_mods_get_num_mods(smods) > 0) {
1109 Slapi_DN *sdn = slapi_sdn_new_normdn_byref(dn);
1110 ipa_topo_util_modify(sdn, smods);
1111 slapi_sdn_free(&sdn);
1112 }
1113
1114 slapi_mods_free(&smods);
1115 slapi_ch_free_string(&dn);
1116
1117}
1118
1119void
1120ipa_topo_util_segm_remove(TopoReplica *tconf,
1121 TopoReplicaSegment *tsegm)
1122{
1123 Slapi_PBlock *pb;
1124 char *dn = NULL((void*)0);
1125 int ret;
1126
1127 /* remove it from the database */
1128 dn = ipa_topo_segment_dn(tconf, tsegm->name);
1129 if (dn == NULL((void*)0)) return;
1130
1131 pb = slapi_pblock_new();
1132 slapi_delete_internal_set_pb(pb, dn, NULL((void*)0), NULL((void*)0),
1133 ipa_topo_get_plugin_id(), 0);
1134
1135 slapi_delete_internal_pb(pb);
1136 slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT15, &ret);
1137 slapi_pblock_destroy(pb);
1138
1139 slapi_ch_free_string(&dn);
1140
1141 /* removed from the internal data struct in the delete postop */
1142 /* ipa_topo_cfg_segment_del(tconf, tsegm); */
1143}
1144
1145/* for merging segments the result should be the same on any server
1146 * an deliberate decision is to compare hostnames to get a preference
1147 */
1148static int
1149ipa_topo_util_segm_order(TopoReplicaSegment *l, TopoReplicaSegment *r)
1150{
1151 return strcasecmp(l->from, r->from);
1152}
1153
1154void
1155ipa_topo_util_segment_do_merge(TopoReplica *tconf,
1156 TopoReplicaSegment *ex_segm, TopoReplicaSegment *tsegm)
1157{
1158 /* we are merging two one directional segments, tehy can have been created in
1159 * several ways and we need to find the agreeemnt to copy
1160 */
1161 if (NULL((void*)0) == tsegm->right) {
1162 if(ex_segm->left) {
1163 tsegm->right = ipa_topo_cfg_agmt_dup(ex_segm->left);
1164 } else {
1165 tsegm->right = ipa_topo_cfg_agmt_dup(ex_segm->right);
1166 }
1167 } else {
1168 if(ex_segm->left) {
1169 tsegm->left = ipa_topo_cfg_agmt_dup(ex_segm->left);
1170 } else {
1171 tsegm->left = ipa_topo_cfg_agmt_dup(ex_segm->right);
1172 }
1173 }
1174 ipa_topo_util_segm_update(tconf,ex_segm, SEGMENT_OBSOLETE0x04);
1175 ipa_topo_util_segm_remove(tconf, ex_segm);
1176 ipa_topo_util_segm_update(tconf,tsegm, SEGMENT_BIDIRECTIONAL0x03);
1177}
1178
1179
1180void
1181ipa_topo_util_segment_merge(TopoReplica *tconf,
1182 TopoReplicaSegment *tsegm)
1183{
1184 TopoReplicaSegment *ex_segm;
1185
1186 if (tsegm->direct == SEGMENT_BIDIRECTIONAL0x03) return;
1187
1188 if (strcasecmp(tsegm->from,ipa_topo_get_plugin_hostname()) &&
1189 strcasecmp(tsegm->to,ipa_topo_get_plugin_hostname())) {
1190 /* merging is only done on one of the endpoints of the segm */
1191 return;
1192 }
1193
1194 if (tsegm->direct == SEGMENT_LEFT_RIGHT0x01) {
1195 ex_segm = ipa_topo_cfg_replica_segment_find(tconf, tsegm->from, tsegm->to,
1196 SEGMENT_RIGHT_LEFT0x02, 1 /*lock*/);
1197 } else {
1198 ex_segm = ipa_topo_cfg_replica_segment_find(tconf, tsegm->from, tsegm->to,
1199 SEGMENT_LEFT_RIGHT0x01, 1 /*lock*/);
1200 }
1201 if (ex_segm == NULL((void*)0)) return;
1202
1203 /* to avoid conflicts merging has to be done only once and
1204 * so there is a preference which segment survives and on
1205 * which server it will be done
1206 */
1207 if (ipa_topo_util_segm_order(ex_segm, tsegm) > 0) {
1208 if (0 == strcasecmp(tsegm->from,ipa_topo_get_plugin_hostname())) {
1209 ipa_topo_util_segment_do_merge(tconf, ex_segm, tsegm);
1210 }
1211 } else {
1212 if (0 == strcasecmp(ex_segm->from,ipa_topo_get_plugin_hostname())) {
1213 ipa_topo_util_segment_do_merge(tconf, tsegm, ex_segm);
1214 }
1215 }
1216
1217}
1218int
1219ipa_topo_util_segment_write(TopoReplica *tconf, TopoReplicaSegment *tsegm)
1220{
1221 Slapi_Entry *e = NULL((void*)0);
1222 Slapi_PBlock *pb;
1223 char *dn = NULL((void*)0);
1224 Slapi_DN *sdn = NULL((void*)0);
1225 int ret = 0;
1226 /* Set up the new segment entry */
1227 dn = ipa_topo_segment_dn(tconf, tsegm->name);
1228 if (dn == NULL((void*)0)) return -1;
1229 sdn = slapi_sdn_new_normdn_byref(dn);
1230
1231 e = slapi_entry_alloc();
1232 /* the entry now owns the dup'd dn */
1233 slapi_entry_init_ext(e, sdn, NULL((void*)0)); /* sdn is copied into e */
1234 slapi_sdn_free(&sdn);
1235
1236 slapi_entry_add_string(e, SLAPI_ATTR_OBJECTCLASS"objectclass", "iparepltoposegment");
1237 slapi_entry_add_string(e, "cn",tsegm->name);
1238 slapi_entry_add_string(e, "iparepltoposegmentleftnode",tsegm->from);
1239 slapi_entry_add_string(e, "iparepltoposegmentrightnode",tsegm->to);
1240 slapi_entry_add_string(e, "iparepltoposegmentdirection", "left-right");
1241 /* write other attributes of the segment if present */
1242 if (tsegm->state == SEGMENT_AUTOGEN0x05) {
1243 slapi_entry_add_string(e, "iparepltoposegmentstatus", "autogen");
1244 }
1245
1246 pb = slapi_pblock_new();
1247 slapi_pblock_init(pb);
1248
1249 /* e will be consumed by slapi_add_internal() */
1250 slapi_add_entry_internal_set_pb(pb, e, NULL((void*)0), ipa_topo_get_plugin_id(), 0);
1251 slapi_add_internal_pb(pb);
1252 slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT15, &ret);
1253 slapi_pblock_destroy(pb);
1254
1255 return ret;
1256
1257}
1258/*
1259 * to distinguish replication agreements created by the topology plugin
1260 * and agreemens created by admins or legacy tools a "marker" objectclass is used.
1261 * Witheout extending the schema the description attribute is used and a
1262 * specific value is added:
1263 * - when a segment is created from an agreement an so put under control of
1264 * the plugin:
1265 * "ipaReplTopoManagedAgreementState: managed agreement - controlled by topology plugin"
1266 * - when an agreement is created from a segment:
1267 * "ipaReplTopoManagedAgreementState: managed agreement - generated by topology plugin"
1268 */
1269int
1270ipa_topo_util_agmt_mark(TopoReplica *tconf, Slapi_Entry *repl_agmt,
1271 TopoReplicaSegment *tsegm)
1272{
1273 int ret = 0;
1274
1275 Slapi_Mods *smods = slapi_mods_new();
1276 slapi_mods_add_string(smods, LDAP_MOD_ADD(0x0000), "objectclass",
1277 "ipaReplTopoManagedAgreement");
1278 slapi_mods_add_string(smods, LDAP_MOD_ADD(0x0000), "ipaReplTopoManagedAgreementState",
1279 "managed agreement - controlled by topology plugin");
1280 if (slapi_mods_get_num_mods(smods) > 0) {
1281 ret = ipa_topo_util_modify(
1282 (Slapi_DN *)slapi_entry_get_sdn_const(repl_agmt), smods);
1283 }
1284 slapi_mods_free(&smods);
1285
1286 return ret;
1287}
1288
1289int
1290ipa_topo_util_agmt_is_marked(Slapi_Entry *repl_agmt)
1291{
1292 int ret = 0;
1293 int i;
1294 char **descs;
1295
1296 descs = slapi_entry_attr_get_charray(repl_agmt, "objectclass");
1297 for (i=0; descs &&descs[i]; i++) {
1298 if (strcasecmp(descs[i],"ipaReplTopoManagedAgreement") == 0) {
1299 ret = 1;
1300 break;
1301 }
1302 }
1303 slapi_ch_array_free(descs);
1304 return ret;
1305}
1306
1307void
1308ipa_topo_util_update_segments_for_host(TopoReplica *conf, char *hostname)
1309{
1310 int rc = 0;
1311 int nentries;
1312 Slapi_Entry **entries;
1313 Slapi_Entry *repl_agmt;
1314 Slapi_PBlock *pb = NULL((void*)0);
1315 char *filter;
1316
1317 /* find all replication agreements to the new host entry
1318 * Since the host was not yet managed new segments ghave to be
1319 * created
1320 */
1321
1322 pb = slapi_pblock_new();
1323 filter = slapi_ch_smprintf("(&(objectclass=nsds5replicationagreement)(nsds5replicahost=%s)(nsds5replicaroot=%s))",
1324 hostname, conf->repl_root);
1325 slapi_search_internal_set_pb(pb, "cn=config", LDAP_SCOPE_SUB((ber_int_t) 0x0002),
1326 filter, NULL((void*)0), 0, NULL((void*)0), NULL((void*)0),
1327 ipa_topo_get_plugin_id(), 0);
1328 slapi_search_internal_pb(pb);
1329 slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT15, &rc);
1330 if (rc != 0)
1331 {
1332 slapi_log_error(SLAPI_LOG_PLUGIN14, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
1333 "ipa_topo_util_update_segments_for_host: "
1334 "no replication agreeements for host %s: error %d\n",
1335 hostname, rc);
1336 return;
1337 } else {
1338 slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES16, &entries);
1339 if (NULL((void*)0) == entries || NULL((void*)0) == entries[0]) {
1340 slapi_log_error(SLAPI_LOG_PLUGIN14, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
1341 "ipa_topo_util_update_segments_for_host: "
1342 "no agrements found\n");
1343 return;
1344 }
1345 }
1346
1347 /* for each agreement find segment */
1348 nentries = 0;
1349 repl_agmt = entries[0];
1350 while (repl_agmt) {
1351 TopoReplicaSegment *topo_segm = NULL((void*)0);
1352 TopoReplicaAgmt *topo_agmt = NULL((void*)0);
1353
1354 slapi_log_error(SLAPI_LOG_PLUGIN14, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
1355 "ipa_topo_util_update_segments_for_host: "
1356 "processing agreement: %s\n",
1357 slapi_entry_get_dn_const(repl_agmt));
1358
1359 /* generate segment from agreement */
1360 topo_segm = ipa_topo_util_segm_from_agmt(repl_agmt);
1361 rc = ipa_topo_util_segment_write(conf, topo_segm);
1362 if (rc != 0) {
1363 slapi_log_error(SLAPI_LOG_PLUGIN14, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
1364 "ipa_topo_util_update_segments_for_host: "
1365 "failed to write segment for host %s: error %d\n",
1366 hostname, rc);
1367 }
1368 rc = ipa_topo_util_agmt_mark(conf, repl_agmt, topo_segm);
1369 if (rc != 0) {
1370 slapi_log_error(SLAPI_LOG_PLUGIN14, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
1371 "ipa_topo_util_update_segments_for_host: "
1372 "failed to mark agreement for host %s: error %d\n",
1373 hostname, rc);
1374 }
1375 /* segment has been recreated and added during postp of segment_write
1376 * but the correct agreement rdn was lost, set it now */
1377 topo_agmt = ipa_topo_util_find_segment_agmt(conf->repl_segments,
1378 ipa_topo_get_plugin_hostname(),
1379 hostname);
1380 if (topo_agmt) {
1381 ipa_topo_util_set_agmt_rdn(topo_agmt, repl_agmt);
1382 }
1383 repl_agmt = entries[++nentries];
1384
1385 }
1386
1387 slapi_free_search_results_internal(pb);
1388 slapi_pblock_destroy(pb);
1389
1390}
1391
1392void
1393ipa_topo_util_disable_repl_from_host(char *repl_root, char *delhost)
1394{
1395 char *principal = ipa_topo_util_get_ldap_principal(repl_root, delhost);
1396 if (principal) {
1397 ipa_topo_util_disable_repl_for_principal(repl_root, principal);
1398 slapi_ch_free_string(&principal);
1399 } else {
1400 slapi_log_error(SLAPI_LOG_PLUGIN14, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
1401 "ipa_topo_util_disable_repl_from_host: "
1402 "failed to get ldap principal for host: %s \n",
1403 delhost);
1404 }
1405}
1406
1407void
1408ipa_topo_util_delete_segments_for_host(char *repl_root, char *delhost)
1409{
1410 TopoReplicaSegment *segm = NULL((void*)0);
1411 TopoReplica *tconf = ipa_topo_cfg_replica_find(repl_root, 1);
1412 int check_reverse = 1;
1413
1414 if (NULL((void*)0) == tconf) {
1415 slapi_log_error(SLAPI_LOG_PLUGIN14, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
1416 "ipa_topo_util_delete_segments_for_host: "
1417 "failed to get replica object for suffix: %s \n",
1418 repl_root);
1419 return;
1420 }
1421
1422 /* first check if a segment originating at localhost exists */
1423 segm = ipa_topo_cfg_segment_find(repl_root, ipa_topo_get_plugin_hostname(),
1424 delhost, SEGMENT_LEFT_RIGHT0x01);
1425 if (segm) {
1426 /* mark segment as removable, bypass connectivity check when replicated */
1427 if (segm->direct == SEGMENT_BIDIRECTIONAL0x03) check_reverse = 0;
1428 ipa_topo_util_segm_update(tconf,segm, SEGMENT_REMOVED0x06);
1429 /* delete segment */
1430 /* the replication agreement will be deleted in the postop_del*/
1431 ipa_topo_util_segm_remove(tconf, segm);
1432 }
1433 /* check if one directional segment in reverse direction exists */
1434 if (check_reverse) {
1435 segm = ipa_topo_cfg_segment_find(repl_root, delhost,
1436 ipa_topo_get_plugin_hostname(), SEGMENT_LEFT_RIGHT0x01);
1437 if (segm) {
1438 ipa_topo_util_segm_update(tconf,segm, SEGMENT_REMOVED0x06);
1439 /* mark and delete, no repl agmt on this server */
1440 ipa_topo_util_segm_remove(tconf, segm);
1441 }
1442 }
1443
1444 slapi_log_error(SLAPI_LOG_PLUGIN14, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
1445 "ipa_topo_util_delete_segments_for_host <-- done\n");
1446}
1447
1448void
1449ipa_topo_util_init_hosts(Slapi_Entry *hostentry)
1450{
1451 char *newhost;
1452 char **repl_root = NULL((void*)0);
1453 TopoReplica *replica = NULL((void*)0);
1454 int i;
1455
1456 newhost = slapi_entry_attr_get_charptr(hostentry,"cn");
1457 if (newhost == NULL((void*)0)) return;
1458
1459 repl_root = slapi_entry_attr_get_charray(hostentry,"ipaReplTopoManagedSuffix");
1460 if (repl_root == NULL((void*)0) || *repl_root == NULL((void*)0)) return;
1461
1462 for (i=0; repl_root[i];i++) {
1463 replica = ipa_topo_cfg_replica_find(repl_root[i], 1);
1464 if (replica == NULL((void*)0)) continue;
1465
1466 ipa_topo_cfg_host_add(replica, newhost);
1467 }
1468
1469 slapi_ch_array_free(repl_root);
1470 slapi_ch_free_string(&newhost);
1471 return;
1472}
1473
1474void
1475ipa_topo_util_add_managed_host(char *suffix, char *addhost)
1476{
1477 TopoReplica *conf = ipa_topo_cfg_replica_find(suffix,1);
1478 if (conf) {
1479 ipa_topo_cfg_host_add(conf, addhost);
1480 ipa_topo_util_update_segments_for_host(conf, addhost);
1481 }
1482}
1483
1484void
1485ipa_topo_util_add_host(Slapi_Entry *hostentry)
1486{
1487 char* addhost = NULL((void*)0);
1488 char **suffixes = NULL((void*)0);
1489 int i=0;
1490 addhost = slapi_entry_attr_get_charptr(hostentry,"cn");
1491 suffixes = slapi_entry_attr_get_charray(hostentry,"ipaReplTopoManagedSuffix");
1492 while (suffixes && suffixes[i]) {
1493 ipa_topo_util_add_managed_host(suffixes[i], addhost);
1494 i++;
1495 }
1496 slapi_ch_free_string(&addhost);
1497 slapi_ch_array_free(suffixes);
1498}
1499
1500
1501void
1502ipa_topo_util_update_host(Slapi_Entry *hostentry, LDAPMod **mods)
1503{
1504 char* modhost = NULL((void*)0);
1505 int i, j;
1506
1507 modhost = slapi_entry_attr_get_charptr(hostentry,"cn");
1508 for (i = 0; (mods != NULL((void*)0)) && (mods[i] != NULL((void*)0)); i++) {
1509 if (0 == strcasecmp(mods[i]->mod_type, "ipaReplTopoManagedSuffix")) {
1510 switch (mods[i]->mod_op & ~LDAP_MOD_BVALUES(0x0080)) {
1511 case LDAP_MOD_DELETE(0x0001):
1512 /* preop check ensures we have valuses */
1513 if (NULL((void*)0) == mods[i]->mod_bvaluesmod_vals.modv_bvals || NULL((void*)0) == mods[i]->mod_bvaluesmod_vals.modv_bvals[0]) {
1514 }
1515 break;
1516 case LDAP_MOD_ADD(0x0000):
1517 for (j = 0; mods[i]->mod_bvaluesmod_vals.modv_bvals[j] != NULL((void*)0); j++) {
1518 ipa_topo_util_add_managed_host(mods[i]->mod_bvaluesmod_vals.modv_bvals[j]->bv_val, modhost);
1519 }
1520 break;
1521 case LDAP_MOD_REPLACE(0x0002):
1522 break;
1523 }
1524 }
1525 }
1526 slapi_ch_free_string(&modhost);
1527}
1528
1529void
1530ipa_topo_util_delete_host(Slapi_Entry *hostentry)
1531{
1532 char* delhost = NULL((void*)0);
1533
1534 delhost = slapi_entry_attr_get_charptr(hostentry,"cn");
1535 /* if the deleted host is the current host, do not
1536 * delete the segments, deleting segments will trigger
1537 * removal of replication agreements and it cannot be
1538 * ensured that the deletion of the host will reach
1539 * other servers in the replica before.
1540 * So wait until the delete is received on the other
1541 * servers and the deletion of segments is received.
1542 */
1543 if (0 == strcasecmp(delhost,ipa_topo_get_plugin_hostname())) {
1544 return;
1545 } else {
1546 /* find all segments connecting the local master to the
1547 * deleted master.
1548 * - mark the segments as no longer managed
1549 * - delete the segments
1550 * - if the segment originates at the local host
1551 * remove the corresponding replication agreement
1552 */
1553 int i = 0;
1554 char **shared_root = ipa_topo_get_plugin_replica_root();
1555
1556 while (shared_root[i]) {
1557 ipa_topo_util_disable_repl_from_host(shared_root[i], delhost);
1558 ipa_topo_util_delete_segments_for_host(shared_root[i], delhost);
1559 i++;
1560 }
1561 }
1562
1563}
1564
1565int
1566ipa_topo_util_start(int delay)
1567{
1568 /* main routine to synchronize data in the shared tree and
1569 * config data. It will be called:
1570 * - at startup of the server
1571 * - if the domain level increases above the plugin version
1572 * and the plugin becomes active
1573 * - after a backup state change, eg after online initialization
1574 * when there is no guarantee that data in the shared tree
1575 * and plugin data still match.
1576 *
1577 * the parameter delay controls if the operation is performed
1578 * immediately or after some delay. This delay is necessary
1579 * during startup because the plugins only become active after
1580 * all plugins have been started and modifications would not be
1581 * logged in the changelog and replicated
1582 */
1583
1584 time_t now;
1585 int rc = 0;
1586 slapi_log_error(SLAPI_LOG_PLUGIN14, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
1587 "--> ipa_topo_util_start - deleay: %d\n",delay);
1588
1589 ipa_topo_init_shared_config();
1590
1591 /* initialize the config data from the shared tree and apply to
1592 * the managed data under cn=config
1593 */
1594 if (delay) {
1595 time(&now);
1596 if (!slapi_eq_once(ipa_topo_queue_apply_shared_config,NULL((void*)0),now +
1597 ipa_topo_get_plugin_startup_delay())) {
1598 slapi_log_error(SLAPI_LOG_FATAL0, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
1599 "unable to queue configuration update\n");
1600 return -1;
1601 }
1602 } else {
1603 rc = ipa_topo_apply_shared_config();
1604 }
1605 slapi_log_error(SLAPI_LOG_PLUGIN14, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
1606 "<-- ipa_topo_util_start\n");
1607 return rc;
1608}
1609
1610char *
1611ipa_topo_util_get_ldap_principal(char *repl_root, char *hostname)
1612{
1613 int rc = 0;
1614 Slapi_Entry **entries = NULL((void*)0);
1615 Slapi_PBlock *pb = NULL((void*)0);
1616 char *filter;
1617 char *dn = NULL((void*)0);
1618
1619 filter = slapi_ch_smprintf("krbprincipalname=ldap/%s*",hostname);
1620 pb = slapi_pblock_new();
1621
1622 slapi_search_internal_set_pb(pb, repl_root, LDAP_SCOPE_SUBTREE((ber_int_t) 0x0002),
1623 filter, NULL((void*)0), 0, NULL((void*)0), NULL((void*)0),
1624 ipa_topo_get_plugin_id(), 0);
1625 slapi_search_internal_pb(pb);
1626 slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT15, &rc);
1627 if (rc != 0)
1628 {
1629 slapi_log_error(SLAPI_LOG_PLUGIN14, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
1630 "ipa_topo_util_get_ldap_principal: "
1631 "unable to search for entry (%s): error %d\n", filter, rc);
1632 } else {
1633 slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES16, &entries);
1634 if (NULL((void*)0) == entries || NULL((void*)0) == entries[0]) {
1635 slapi_log_error(SLAPI_LOG_PLUGIN14, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
1636 "ipa_topo_util_get_ldap_principal: entry not found: (%s)\n", filter);
1637 } else {
1638 dn = slapi_ch_strdup(slapi_entry_get_dn(entries[0]));
1639 }
1640 }
1641 slapi_free_search_results_internal(pb);
1642 slapi_pblock_destroy(pb);
1643 slapi_ch_free_string(&filter);
1644 return dn;
1645}
1646
1647void
1648ipa_topo_util_disable_repl_for_principal(char *repl_root, char *principal)
1649{
1650 Slapi_DN *sdn;
1651 char *filter;
1652 Slapi_PBlock *pb;
1653 Slapi_Entry **entries;
1654 Slapi_Mods *smods;
1655 int ret;
1656
1657 /* to disable replication for a user/principal it ahs to be removed from the
1658 * allowed bind dns in the replica object and from the bind dn group
1659 */
1660
1661 slapi_log_error(SLAPI_LOG_PLUGIN14, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
1662 "--> ipa_topo_util_disable_repl_for_principal\n");
1663 /* find replica object */
1664 pb = slapi_pblock_new();
1665 filter = slapi_ch_smprintf("(&(objectclass=nsds5replica)(nsds5replicaroot=%s))", repl_root);
1666 slapi_search_internal_set_pb(pb, "cn=config", LDAP_SCOPE_SUB((ber_int_t) 0x0002),
1667 filter, NULL((void*)0), 0, NULL((void*)0), NULL((void*)0),
1668 ipa_topo_get_plugin_id(), 0);
1669 slapi_search_internal_pb(pb);
1670 slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT15, &ret);
1671 if (ret != 0) {
1672 sdn = NULL((void*)0);
1673 } else {
1674 slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES16, &entries);
1675 if (NULL((void*)0) == entries || NULL((void*)0) == entries[0]) {
1676 slapi_log_error(SLAPI_LOG_PLUGIN14, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
1677 "ipa_topo_agreement_dn: no replica found\n");
1678 sdn = NULL((void*)0);
1679 } else {
1680 sdn = slapi_sdn_dup(slapi_entry_get_sdn(entries[0]));
1681 }
1682 }
1683 slapi_free_search_results_internal(pb);
1684
1685 /* remove principal from binddns */
1686 smods = slapi_mods_new();
1687 slapi_mods_add_string(smods, LDAP_MOD_DELETE(0x0001),
1688 "nsds5replicabinddn", principal);
1689 ret = ipa_topo_util_modify(sdn, smods);
1690 slapi_sdn_free(&sdn);
1691
1692 /* find binddn group */
1693 slapi_pblock_init(pb);
1694
1695 slapi_search_internal_set_pb(pb, ipa_topo_get_plugin_shared_bindgroup(), LDAP_SCOPE_BASE((ber_int_t) 0x0000),
1696 "(objectclass=groupofnames)",
1697 NULL((void*)0), 0, NULL((void*)0), NULL((void*)0), ipa_topo_get_plugin_id(), 0);
1698 slapi_search_internal_pb(pb);
1699 slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT15, &ret);
1700 if (ret != 0) {
1701 sdn = NULL((void*)0);
1702 } else {
1703 slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES16, &entries);
1704 if (NULL((void*)0) == entries || NULL((void*)0) == entries[0]) {
1705 slapi_log_error(SLAPI_LOG_PLUGIN14, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
1706 "ipa_topo_agreement_dn: no replica found\n");
1707 sdn = NULL((void*)0);
1708 } else {
1709 sdn = slapi_sdn_dup(slapi_entry_get_sdn(entries[0]));
1710 }
1711 }
1712 slapi_free_search_results_internal(pb);
1713 slapi_pblock_destroy(pb);
1714
1715 /* delete principal as binddn group member */
1716 smods = slapi_mods_new();
1717 slapi_mods_add_string(smods, LDAP_MOD_DELETE(0x0001),
1718 "member", principal);
1719 ret = ipa_topo_util_modify(sdn, smods);
1720 slapi_mods_free(&smods);
1721 slapi_sdn_free(&sdn);
1722 slapi_log_error(SLAPI_LOG_PLUGIN14, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
1723 "<-- ipa_topo_util_disable_repl_for_principal\n");
1724}
1725
1726void
1727ipa_topo_util_reset_init(char *repl_root)
1728{
1729 TopoReplica *replica_config = NULL((void*)0);
1730 TopoReplicaSegmentList *seglist = NULL((void*)0);
1731 TopoReplicaSegment *segment = NULL((void*)0);
1732 char *localhost = ipa_topo_get_plugin_hostname();
1733 char *dirattr;
1734
1735 replica_config = ipa_topo_cfg_replica_find(repl_root, 1);
1736 if (replica_config) {
1737 seglist = ipa_topo_util_get_replica_segments(replica_config);
1738 } else {
1739 slapi_log_error(SLAPI_LOG_PLUGIN14, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
1740 "ipa_topo_util_reset_init: no replica found for: %s\n", repl_root);
1741 return;
1742 }
1743
1744 while (seglist) {
1745 /* this is executed after an online init completed, reset the init in segments
1746 * which target this server
1747 */
1748 segment = seglist->segm;
1749 if (segment->left && (0 == strcasecmp(localhost,segment->left->target))
1750 && ipa_topo_util_get_segm_attr(segment->left,"nsds5BeginReplicaRefresh")) {
1751 dirattr = "nsds5BeginReplicaRefresh;left";
1752 break;
1753 } else if (segment->right && (0 == strcasecmp(localhost,segment->right->target))
1754 && ipa_topo_util_get_segm_attr(segment->right,"nsds5BeginReplicaRefresh")) {
1755 dirattr = "nsds5BeginReplicaRefresh;right";
1756 break;
1757 } else {
1758 segment = NULL((void*)0);
1759 }
1760 seglist = seglist->next;
1761 }
1762 if (segment) {
1763 Slapi_Mods *smods = slapi_mods_new();
1764 slapi_mods_add_string(smods, LDAP_MOD_DELETE(0x0001),
1765 dirattr, "");
1766 ipa_topo_util_segm_modify (replica_config, segment, smods);
1767 slapi_mods_free(&smods);
1768 }
1769}
1770
1771void
1772ipa_topo_util_suffix_init(Slapi_Entry *config_entry)
1773{
1774 int rc = 0;
1775 TopoReplica *topoRepl = NULL((void*)0);
1776 char *repl_suffix = slapi_entry_attr_get_charptr(config_entry,"ipaReplTopoConfRoot");
1777 if (repl_suffix) {
1778 topoRepl = ipa_topo_util_replica_init(config_entry);
1779 if (topoRepl) {
1780 rc = ipa_topo_cfg_replica_add(topoRepl);
Value stored to 'rc' is never read
1781 rc = ipa_topo_apply_shared_replica_config(topoRepl);
1782 if (rc)
1783 slapi_log_error(SLAPI_LOG_PLUGIN14, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
1784 "ipa_topo_util_suffix_init: failed to init suffix %s\n", repl_suffix);
1785 }
1786 }
1787 slapi_ch_free_string(&repl_suffix);
1788}
1789
1790
1791void
1792ipa_topo_util_suffix_update(Slapi_Entry *config_post, Slapi_Entry *config_pre,
1793 LDAPMod **mods)
1794{
1795}
1796
1797#ifndef SLAPI_OP_FLAG_TOMBSTONE_ENTRY0x001000
1798#define SLAPI_OP_FLAG_TOMBSTONE_ENTRY0x001000 0x001000
1799#endif
1800
1801int
1802ipa_topo_util_is_tombstone_op(Slapi_PBlock *pb)
1803{
1804 Slapi_Operation *op;
1805
1806 slapi_pblock_get(pb, SLAPI_OPERATION132, &op);
1807 return slapi_operation_is_flag_set(op, SLAPI_OP_FLAG_TOMBSTONE_ENTRY0x001000);
1808}
1809int
1810ipa_topo_util_cleanruv_task(char *repl_root, int replicaID)
1811{
1812 Slapi_Entry *e = NULL((void*)0);
1813 Slapi_PBlock *pb;
1814 char *dn = NULL((void*)0);
1815 char *repl_rid;
1816 Slapi_DN *sdn = NULL((void*)0);
1817 int ret = 0;
1818 dn = slapi_ch_smprintf("cn=clean %d,cn=cleanallruv,cn=tasks,cn=config", replicaID);
1819 if (dn == NULL((void*)0)) return -1;
1820 sdn = slapi_sdn_new_normdn_byref(dn);
1821
1822 e = slapi_entry_alloc();
1823 /* the entry now owns the dup'd dn */
1824 slapi_entry_init_ext(e, sdn, NULL((void*)0)); /* sdn is copied into e */
1825 slapi_sdn_free(&sdn);
1826
1827 slapi_entry_add_string(e, SLAPI_ATTR_OBJECTCLASS"objectclass", "extensibleobject");
1828 slapi_entry_add_string(e, "replica-base-dn",repl_root);
1829 repl_rid = slapi_ch_smprintf("%d",replicaID);
1830 slapi_entry_add_string(e, "replica-id",repl_rid);
1831 slapi_entry_add_string(e, "replica-force-cleaning", "yes");
1832
1833 pb = slapi_pblock_new();
1834 slapi_pblock_init(pb);
1835
1836 /* e will be consumed by slapi_add_internal() */
1837 slapi_add_entry_internal_set_pb(pb, e, NULL((void*)0), ipa_topo_get_plugin_id(), 0);
1838 slapi_add_internal_pb(pb);
1839 slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT15, &ret);
1840 slapi_pblock_destroy(pb);
1841 slapi_ch_free_string(&repl_rid);
1842
1843 return ret;
1844
1845}
1846
1847void
1848ipa_topo_util_cleanruv_element(char *repl_root, char *hostname)
1849{
1850 Slapi_PBlock *pb = NULL((void*)0);
1851 char *filter = "(&(objectclass=nstombstone)(nsuniqueid=ffffffff-ffffffff-ffffffff-ffffffff))";
1852 int ret;
1853 Slapi_Entry **entries = NULL((void*)0);
1854
1855 /* find ruv object */
1856 pb = slapi_pblock_new();
1857 slapi_search_internal_set_pb(pb, repl_root, LDAP_SCOPE_SUB((ber_int_t) 0x0002),
1858 filter, NULL((void*)0), 0, NULL((void*)0), NULL((void*)0),
1859 ipa_topo_get_plugin_id(), 0);
1860 slapi_search_internal_pb(pb);
1861 slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT15, &ret);
1862 if (ret != 0) {
1863 slapi_log_error(SLAPI_LOG_FATAL0, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
1864 "ipa_topo_util_cleanruv: no RUV entry found\n");
1865 } else {
1866 slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES16, &entries);
1867 if (NULL((void*)0) == entries || NULL((void*)0) == entries[0]) {
1868 slapi_log_error(SLAPI_LOG_PLUGIN14, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
1869 "ipa_topo_util_cleanruv: no RUV entry found\n");
1870 } else {
1871 int i = 0;
1872 int rid = 0;
1873 int rc = 0;
1874 char **ruv_ele = slapi_entry_attr_get_charray(entries[0], "nsds50ruv");
1875 /* a ruv element has the form:
1876 * {replica <rid> ldap://<host>:<port>} <mincsn_str> <maxcsn_str>
1877 */
1878 char *urlstr = slapi_ch_smprintf("ldap://%s:",hostname);
1879 while (ruv_ele && ruv_ele[i]) {
1880 if (strstr(ruv_ele[i], urlstr)) {
1881 rid = atoi(ruv_ele[i]+strlen("{replica "));
1882 rc = ipa_topo_util_cleanruv_task(repl_root,rid);
1883 if (rc) {
1884 slapi_log_error(SLAPI_LOG_FATAL0, IPA_TOPO_PLUGIN_SUBSYSTEM"ipa-topology-plugin",
1885 "ipa_topo_util_cleanruv: failed to create cleanalltuv task\n");
1886 }
1887 break;
1888 }
1889 i++;
1890 }
1891 slapi_ch_array_free(ruv_ele);
1892 slapi_ch_free_string(&urlstr);
1893 }
1894 }
1895 slapi_free_search_results_internal(pb);
1896 slapi_pblock_destroy(pb);
1897}
1898
1899void
1900ipa_topo_util_cleanruv(Slapi_Entry *del_entry)
1901{
1902 char* delhost = NULL((void*)0);
1903 char **shared_root = ipa_topo_get_plugin_replica_root();
1904 int i = 0;
1905
1906 delhost = slapi_entry_attr_get_charptr(del_entry,"cn");
1907
1908 while (shared_root[i]) {
1909 ipa_topo_util_cleanruv_element(shared_root[i], delhost);
1910 i++;
1911 }
1912}