Bug Summary

File:daemons/ipa-slapi-plugins/ipa-modrdn/ipa_modrdn.c
Warning:line 733, column 9
Value stored to 'list' 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 ipa_modrdn.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/ipa-modrdn -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 ipa_modrdn.c
1/** BEGIN COPYRIGHT BLOCK
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation, either version 3 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 *
15 * Additional permission under GPLv3 section 7:
16 *
17 * In the following paragraph, "GPL" means the GNU General Public
18 * License, version 3 or any later version, and "Non-GPL Code" means
19 * code that is governed neither by the GPL nor a license
20 * compatible with the GPL.
21 *
22 * You may link the code of this Program with Non-GPL Code and convey
23 * linked combinations including the two, provided that such Non-GPL
24 * Code only links to the code of this Program through those well
25 * defined interfaces identified in the file named EXCEPTION found in
26 * the source code files (the "Approved Interfaces"). The files of
27 * Non-GPL Code may instantiate templates or use macros or inline
28 * functions from the Approved Interfaces without causing the resulting
29 * work to be covered by the GPL. Only the copyright holders of this
30 * Program may make changes or additions to the list of Approved
31 * Interfaces.
32 *
33 * Copyright (C) 2010 Red Hat, Inc.
34 * All rights reserved.
35 * END COPYRIGHT BLOCK **/
36
37/**
38 * IPA MODRDN plug-in
39 */
40#include <string.h>
41#include <stdbool.h>
42#include "slapi-plugin.h"
43#include "nspr.h"
44#include "prclist.h"
45#include <pthread.h>
46
47#include "util.h"
48
49#define IPA_PLUGIN_NAME"ipa-modrdn-plugin" "ipa-modrdn-plugin"
50#define IPAMODRDN_PLUGIN_VERSION0x00010000 0x00010000
51
52#define IPAMODRDN_DN"cn=IPA MODRDN,cn=plugins,cn=config" "cn=IPA MODRDN,cn=plugins,cn=config" /* temporary */
53
54/**
55 * IPA MODRDN config types
56 */
57#define IPAMODRDN_SATTR"ipaModRDNsourceAttr" "ipaModRDNsourceAttr"
58#define IPAMODRDN_TATTR"ipaModRDNtargetAttr" "ipaModRDNtargetAttr"
59#define IPAMODRDN_PREFIX"ipaModRDNprefix" "ipaModRDNprefix"
60#define IPAMODRDN_SUFFIX"ipaModRDNsuffix" "ipaModRDNsuffix"
61#define IPAMODRDN_FILTER"ipaModRDNfilter" "ipaModRDNfilter"
62#define IPAMODRDN_SCOPE"ipaModRDNscope" "ipaModRDNscope"
63
64#define IPAMODRDN_FEATURE_DESC"IPA MODRDN" "IPA MODRDN"
65#define IPAMODRDN_PLUGIN_DESC"IPA MODRDN plugin" "IPA MODRDN plugin"
66#define IPAMODRDN_POSTOP_DESC"IPA MODRDN postop plugin" "IPA MODRDN postop plugin"
67
68static Slapi_PluginDesc pdesc = {
69 IPAMODRDN_FEATURE_DESC"IPA MODRDN",
70 "Red Hat, Inc.",
71 "1.0",
72 IPAMODRDN_PLUGIN_DESC"IPA MODRDN plugin"
73};
74
75/**
76 * linked list of config entries
77 */
78
79struct configEntry {
80 PRCList list;
81 char *dn;
82 char *sattr;
83 char *tattr;
84 char *prefix;
85 char *suffix;
86 char *filter;
87 Slapi_Filter *slapi_filter;
88 char *scope;
89};
90
91static PRCList *ipamodrdn_global_config = NULL((void*)0);
92static pthread_rwlock_t g_ipamodrdn_cache_lock;
93
94static void *_PluginID = NULL((void*)0);
95static char *_PluginDN = NULL((void*)0);
96
97static int g_plugin_started = 0;
98
99
100/**
101 *
102 * management functions
103 *
104 */
105int ipamodrdn_init(Slapi_PBlock * pb);
106static int ipamodrdn_start(Slapi_PBlock * pb);
107static int ipamodrdn_close(Slapi_PBlock * pb);
108
109/**
110 *
111 * Local operation functions
112 *
113 */
114static int ipamodrdn_load_plugin_config(void);
115static int ipamodrdn_parse_config_entry(Slapi_Entry * e, bool_Bool apply);
116static void ipamodrdn_delete_config(void);
117static void ipamodrdn_free_config_entry(struct configEntry ** entry);
118
119/**
120 *
121 * helpers
122 *
123 */
124static char *ipamodrdn_get_dn(Slapi_PBlock * pb);
125static int ipamodrdn_dn_is_config(char *dn);
126
127/**
128 *
129 * the ops (where the real work is done)
130 *
131 */
132static int ipamodrdn_config_check_post_op(Slapi_PBlock * pb);
133static int ipamodrdn_post_op(Slapi_PBlock * pb);
134
135/**
136 * debug functions - global, for the debugger
137 */
138void ipamodrdn_dump_config(void);
139void ipamodrdn_dump_config_entry(struct configEntry *);
140
141/**
142 *
143 * Deal with cache locking
144 *
145 */
146void ipamodrdn_read_lock(void)
147{
148 pthread_rwlock_rdlock(&g_ipamodrdn_cache_lock);
149}
150
151void ipamodrdn_write_lock(void)
152{
153 pthread_rwlock_wrlock(&g_ipamodrdn_cache_lock);
154}
155
156void ipamodrdn_unlock(void)
157{
158 pthread_rwlock_unlock(&g_ipamodrdn_cache_lock);
159}
160
161/**
162 *
163 * Get the plug-in version
164 *
165 */
166int ipamodrdn_version(void)
167{
168 return IPAMODRDN_PLUGIN_VERSION0x00010000;
169}
170
171/**
172 * Plugin identity mgmt
173 */
174void setPluginID(void *pluginID)
175{
176 _PluginID = pluginID;
177}
178
179void *getPluginID(void)
180{
181 return _PluginID;
182}
183
184void setPluginDN(char *pluginDN)
185{
186 _PluginDN = pluginDN;
187}
188
189char *getPluginDN(void)
190{
191 return _PluginDN;
192}
193
194/*
195 ipamodrdn_init
196 -------------
197 adds our callbacks to the list
198*/
199int
200ipamodrdn_init(Slapi_PBlock *pb)
201{
202 int status = EOK0;
203 char *plugin_identity = NULL((void*)0);
204 Slapi_Entry *plugin_entry = NULL((void*)0);
205 char *plugin_type = NULL((void*)0);
206 int delfn = SLAPI_PLUGIN_POST_DELETE_FN508;
207 int mdnfn = SLAPI_PLUGIN_POST_MODRDN_FN506;
208 int modfn = SLAPI_PLUGIN_POST_MODIFY_FN505;
209 int addfn = SLAPI_PLUGIN_POST_ADD_FN507;
210
211 LOG_TRACE("--in-->\n")slapi_log_error(1, ((void *)((uintptr_t)(__func__))), "--in-->\n"
)
;
212
213 /**
214 * Store the plugin identity for later use.
215 * Used for internal operations
216 */
217
218 slapi_pblock_get(pb, SLAPI_PLUGIN_IDENTITY13, &plugin_identity);
219 PR_ASSERT(plugin_identity)((void) 0);
220 setPluginID(plugin_identity);
221
222 if ((slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_ENTRY52, &plugin_entry) == 0) &&
223 plugin_entry &&
224 (plugin_type = slapi_entry_attr_get_charptr(plugin_entry, "nsslapd-plugintype")) &&
225 plugin_type && strstr(plugin_type, "betxn"))
226 {
227 addfn = SLAPI_PLUGIN_BE_TXN_POST_ADD_FN560;
228 mdnfn = SLAPI_PLUGIN_BE_TXN_POST_MODRDN_FN562;
229 delfn = SLAPI_PLUGIN_BE_TXN_POST_DELETE_FN563;
230 modfn = SLAPI_PLUGIN_BE_TXN_POST_MODIFY_FN561;
231 }
232 slapi_ch_free_string(&plugin_type);
233
234 if (slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION8,
235 SLAPI_PLUGIN_VERSION_01"01") != 0 ||
236 slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION12,
237 (void *) &pdesc) != 0 ||
238 slapi_pblock_set(pb, SLAPI_PLUGIN_START_FN212,
239 (void *) ipamodrdn_start) != 0 ||
240 slapi_pblock_set(pb, SLAPI_PLUGIN_CLOSE_FN210,
241 (void *) ipamodrdn_close) != 0 ||
242 slapi_pblock_set(pb, addfn,
243 (void *) ipamodrdn_config_check_post_op) != 0 ||
244 slapi_pblock_set(pb, mdnfn,
245 (void *) ipamodrdn_post_op) != 0 ||
246 slapi_pblock_set(pb, delfn,
247 (void *) ipamodrdn_config_check_post_op) != 0 ||
248 slapi_pblock_set(pb, modfn,
249 (void *) ipamodrdn_config_check_post_op) != 0) {
250 LOG_FATAL("failed to register plugin\n")slapi_log_error(0, ((void *)((uintptr_t)(__func__))), "[file %s, line %d]: "
"failed to register plugin\n", "ipa_modrdn.c", 250)
;
251 status = EFAIL-1;
252 }
253
254 LOG_TRACE("<--out--\n")slapi_log_error(1, ((void *)((uintptr_t)(__func__))), "<--out--\n"
)
;
255 return status;
256}
257
258
259/*
260 ipamodrdn_start
261 --------------
262 Kicks off the config cache.
263 It is called after ipamodrdn_init.
264*/
265static int
266ipamodrdn_start(Slapi_PBlock * pb)
267{
268 char *plugindn = NULL((void*)0);
269
270 LOG_TRACE("--in-->\n")slapi_log_error(1, ((void *)((uintptr_t)(__func__))), "--in-->\n"
)
;
271
272 /* Check if we're already started */
273 if (g_plugin_started) {
274 goto done;
275 }
276
277 if (pthread_rwlock_init(&g_ipamodrdn_cache_lock, NULL((void*)0)) != 0) {
278 LOG_FATAL("lock creation failed\n")slapi_log_error(0, ((void *)((uintptr_t)(__func__))), "[file %s, line %d]: "
"lock creation failed\n", "ipa_modrdn.c", 278)
;
279
280 return EFAIL-1;
281 }
282
283 /**
284 * Get the plug-in target dn from the system
285 * and store it for future use. This should avoid
286 * hardcoding of DN's in the code.
287 */
288 slapi_pblock_get(pb, SLAPI_TARGET_DN50, &plugindn);
289 if (NULL((void*)0) == plugindn || 0 == strlen(plugindn)) {
290 LOG("had to use hard coded config dn\n")slapi_log_error(14, "ipa-modrdn-plugin", "had to use hard coded config dn\n"
)
;
291 plugindn = IPAMODRDN_DN"cn=IPA MODRDN,cn=plugins,cn=config";
292 } else {
293 LOG("config at %s\n", plugindn)slapi_log_error(14, "ipa-modrdn-plugin", "config at %s\n", plugindn
)
;
294
295 }
296
297 setPluginDN(plugindn);
298
299 /*
300 * Load the config for our plug-in
301 */
302 ipamodrdn_global_config = (PRCList *)
303 slapi_ch_calloc(1, sizeof(struct configEntry));
304 PR_INIT_CLIST(ipamodrdn_global_config)do { (ipamodrdn_global_config)->next = (ipamodrdn_global_config
); (ipamodrdn_global_config)->prev = (ipamodrdn_global_config
); } while (0)
;
305
306 if (ipamodrdn_load_plugin_config() != EOK0) {
307 LOG_FATAL("unable to load plug-in configuration\n")slapi_log_error(0, ((void *)((uintptr_t)(__func__))), "[file %s, line %d]: "
"unable to load plug-in configuration\n", "ipa_modrdn.c", 307
)
;
308 return EFAIL-1;
309 }
310
311 g_plugin_started = 1;
312 LOG("ready for service\n")slapi_log_error(14, "ipa-modrdn-plugin", "ready for service\n"
)
;
313 LOG_TRACE("<--out--\n")slapi_log_error(1, ((void *)((uintptr_t)(__func__))), "<--out--\n"
)
;
314
315done:
316 return EOK0;
317}
318
319/*
320 ipamodrdn_close
321 --------------
322 closes down the cache
323*/
324static int
325ipamodrdn_close(Slapi_PBlock * pb)
326{
327 LOG_TRACE( "--in-->\n")slapi_log_error(1, ((void *)((uintptr_t)(__func__))), "--in-->\n"
)
;
328
329 ipamodrdn_delete_config();
330
331 slapi_ch_free((void **)&ipamodrdn_global_config);
332
333 LOG_TRACE("<--out--\n")slapi_log_error(1, ((void *)((uintptr_t)(__func__))), "<--out--\n"
)
;
334
335 return EOK0;
336}
337
338/*
339 * config looks like this
340 * - cn=myplugin
341 * --- cn=posix
342 * ------ cn=accounts
343 * ------ cn=groups
344 * --- cn=samba
345 * --- cn=etc
346 * ------ cn=etc etc
347 */
348static int
349ipamodrdn_load_plugin_config(void)
350{
351 int status = EOK0;
352 int result;
353 int i;
354 Slapi_PBlock *search_pb;
355 Slapi_Entry **entries = NULL((void*)0);
356
357 LOG_TRACE("--in-->\n")slapi_log_error(1, ((void *)((uintptr_t)(__func__))), "--in-->\n"
)
;
358
359 ipamodrdn_write_lock();
360 ipamodrdn_delete_config();
361
362 search_pb = slapi_pblock_new();
363
364 slapi_search_internal_set_pb(search_pb, getPluginDN(),
365 LDAP_SCOPE_SUBTREE((ber_int_t) 0x0002), "objectclass=*",
366 NULL((void*)0), 0, NULL((void*)0), NULL((void*)0), getPluginID(), 0);
367 slapi_search_internal_pb(search_pb);
368 slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_RESULT15, &result);
369
370 if (LDAP_SUCCESS0x00 != result) {
371 status = EFAIL-1;
372 goto cleanup;
373 }
374
375 slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES16,
376 &entries);
377 if (NULL((void*)0) == entries || NULL((void*)0) == entries[0]) {
378 status = EOK0;
379 goto cleanup;
380 }
381
382 for (i = 0; (entries[i] != NULL((void*)0)); i++) {
383 /* We don't care about the status here because we may have
384 * some invalid config entries, but we just want to continue
385 * looking for valid ones. */
386 ipamodrdn_parse_config_entry(entries[i], true1);
387 }
388
389 cleanup:
390 slapi_free_search_results_internal(search_pb);
391 slapi_pblock_destroy(search_pb);
392 ipamodrdn_unlock();
393 LOG_TRACE("<--out--\n")slapi_log_error(1, ((void *)((uintptr_t)(__func__))), "<--out--\n"
)
;
394
395 return status;
396}
397
398/*
399 * ipamodrdn_parse_config_entry()
400 *
401 * Parses a single config entry. If apply is non-zero, then
402 * we will load and start using the new config. You can simply
403 * validate config without making any changes by setting apply
404 * to 0.
405 *
406 * Returns EOK if the entry is valid and EFAIL
407 * if it is invalid.
408 */
409static int
410ipamodrdn_parse_config_entry(Slapi_Entry * e, bool_Bool apply)
411{
412 char *value;
413 struct configEntry *entry = NULL((void*)0);
414 struct configEntry *config_entry;
415 PRCList *list;
416 int entry_added = 0;
417 int ret = EOK0;
418
419 LOG_TRACE("--in-->\n")slapi_log_error(1, ((void *)((uintptr_t)(__func__))), "--in-->\n"
)
;
420
421 /* If this is the main MODRDN plug-in config entry, just bail. */
422 if (strcasecmp(getPluginDN(), slapi_entry_get_ndn(e)) == 0) {
423 ret = EFAIL-1;
424 goto bail;
425 }
426
427 entry = (struct configEntry *)
428 slapi_ch_calloc(1, sizeof(struct configEntry));
429 if (NULL((void*)0) == entry) {
430 ret = EFAIL-1;
431 goto bail;
432 }
433
434 value = slapi_entry_get_ndn(e);
435 if (value) {
436 entry->dn = slapi_ch_strdup(value);
437 }
438
439 LOG_CONFIG("----------> dn [%s]\n", entry->dn)slapi_log_error(7, "ipa-modrdn-plugin", "----------> dn [%s]\n"
, entry->dn)
;
440
441 entry->sattr = slapi_entry_attr_get_charptr(e, IPAMODRDN_SATTR"ipaModRDNsourceAttr");
442 if (!entry->sattr) {
443 LOG_FATAL("The %s config setting is required for %s.\n",slapi_log_error(0, ((void *)((uintptr_t)(__func__))), "[file %s, line %d]: "
"The %s config setting is required for %s.\n", "ipa_modrdn.c"
, 444, "ipaModRDNsourceAttr", entry->dn)
444 IPAMODRDN_SATTR, entry->dn)slapi_log_error(0, ((void *)((uintptr_t)(__func__))), "[file %s, line %d]: "
"The %s config setting is required for %s.\n", "ipa_modrdn.c"
, 444, "ipaModRDNsourceAttr", entry->dn)
;
445 ret = EFAIL-1;
446 goto bail;
447 }
448 LOG_CONFIG("----------> %s [%s]\n", IPAMODRDN_SATTR, entry->sattr)slapi_log_error(7, "ipa-modrdn-plugin", "----------> %s [%s]\n"
, "ipaModRDNsourceAttr", entry->sattr)
;
449
450 entry->tattr = slapi_entry_attr_get_charptr(e, IPAMODRDN_TATTR"ipaModRDNtargetAttr");
451 if (!entry->tattr) {
452 LOG_FATAL("The %s config setting is required for %s.\n",slapi_log_error(0, ((void *)((uintptr_t)(__func__))), "[file %s, line %d]: "
"The %s config setting is required for %s.\n", "ipa_modrdn.c"
, 453, "ipaModRDNtargetAttr", entry->dn)
453 IPAMODRDN_TATTR, entry->dn)slapi_log_error(0, ((void *)((uintptr_t)(__func__))), "[file %s, line %d]: "
"The %s config setting is required for %s.\n", "ipa_modrdn.c"
, 453, "ipaModRDNtargetAttr", entry->dn)
;
454 ret = EFAIL-1;
455 goto bail;
456 }
457 LOG_CONFIG("----------> %s [%s]\n", IPAMODRDN_TATTR, entry->tattr)slapi_log_error(7, "ipa-modrdn-plugin", "----------> %s [%s]\n"
, "ipaModRDNtargetAttr", entry->tattr)
;
458
459 value = slapi_entry_attr_get_charptr(e, IPAMODRDN_PREFIX"ipaModRDNprefix");
460 if (value && value[0]) {
461 entry->prefix = value;
462 } else {
463 entry->prefix = slapi_ch_strdup("");
464 }
465 LOG_CONFIG("----------> %s [%s]\n", IPAMODRDN_PREFIX, entry->prefix)slapi_log_error(7, "ipa-modrdn-plugin", "----------> %s [%s]\n"
, "ipaModRDNprefix", entry->prefix)
;
466
467 value = slapi_entry_attr_get_charptr(e, IPAMODRDN_SUFFIX"ipaModRDNsuffix");
468 if (value && value[0]) {
469 entry->suffix = value;
470 } else {
471 entry->suffix = slapi_ch_strdup("");
472 }
473 LOG_CONFIG("----------> %s [%s]\n", IPAMODRDN_SUFFIX, entry->suffix)slapi_log_error(7, "ipa-modrdn-plugin", "----------> %s [%s]\n"
, "ipaModRDNsuffix", entry->suffix)
;
474
475 value = slapi_entry_attr_get_charptr(e, IPAMODRDN_FILTER"ipaModRDNfilter");
476 if (value) {
477 entry->filter = value;
478 if (NULL((void*)0) == (entry->slapi_filter = slapi_str2filter(value))) {
479 LOG_FATAL("Error: Invalid search filter in entry [%s]: [%s]\n",slapi_log_error(0, ((void *)((uintptr_t)(__func__))), "[file %s, line %d]: "
"Error: Invalid search filter in entry [%s]: [%s]\n", "ipa_modrdn.c"
, 480, entry->dn, value)
480 entry->dn, value)slapi_log_error(0, ((void *)((uintptr_t)(__func__))), "[file %s, line %d]: "
"Error: Invalid search filter in entry [%s]: [%s]\n", "ipa_modrdn.c"
, 480, entry->dn, value)
;
481 ret = EFAIL-1;
482 goto bail;
483 }
484 } else {
485 LOG_FATAL("The %s config setting is required for %s.\n",slapi_log_error(0, ((void *)((uintptr_t)(__func__))), "[file %s, line %d]: "
"The %s config setting is required for %s.\n", "ipa_modrdn.c"
, 486, "ipaModRDNfilter", entry->dn)
486 IPAMODRDN_FILTER, entry->dn)slapi_log_error(0, ((void *)((uintptr_t)(__func__))), "[file %s, line %d]: "
"The %s config setting is required for %s.\n", "ipa_modrdn.c"
, 486, "ipaModRDNfilter", entry->dn)
;
487 ret = EFAIL-1;
488 goto bail;
489 }
490 LOG_CONFIG("----------> %s [%s]\n", IPAMODRDN_FILTER, value)slapi_log_error(7, "ipa-modrdn-plugin", "----------> %s [%s]\n"
, "ipaModRDNfilter", value)
;
491
492 value = slapi_entry_attr_get_charptr(e, IPAMODRDN_SCOPE"ipaModRDNscope");
493 if (value) {
494 entry->scope = value;
495 } else {
496 LOG_FATAL("The %s config config setting is required for %s.\n",slapi_log_error(0, ((void *)((uintptr_t)(__func__))), "[file %s, line %d]: "
"The %s config config setting is required for %s.\n", "ipa_modrdn.c"
, 497, "ipaModRDNscope", entry->dn)
497 IPAMODRDN_SCOPE, entry->dn)slapi_log_error(0, ((void *)((uintptr_t)(__func__))), "[file %s, line %d]: "
"The %s config config setting is required for %s.\n", "ipa_modrdn.c"
, 497, "ipaModRDNscope", entry->dn)
;
498 ret = EFAIL-1;
499 goto bail;
500 }
501 LOG_CONFIG("----------> %s [%s]\n", IPAMODRDN_SCOPE, entry->scope)slapi_log_error(7, "ipa-modrdn-plugin", "----------> %s [%s]\n"
, "ipaModRDNscope", entry->scope)
;
502
503 /* If we were only called to validate config, we can
504 * just bail out before applying the config changes */
505 if (!apply) {
506 goto bail;
507 }
508
509 /**
510 * Finally add the entry to the list.
511 * We sort by scope dn length with longer
512 * dn's first - this allows the scope
513 * checking code to be simple and quick and
514 * cunningly linear.
515 */
516 if (!PR_CLIST_IS_EMPTY(ipamodrdn_global_config)((ipamodrdn_global_config)->next == (ipamodrdn_global_config
))
) {
517 list = PR_LIST_HEAD(ipamodrdn_global_config)(ipamodrdn_global_config)->next;
518 while (list != ipamodrdn_global_config) {
519 config_entry = (struct configEntry *) list;
520
521 if (slapi_dn_issuffix(entry->scope, config_entry->scope)) {
522 PR_INSERT_BEFORE(&(entry->list), list)do { (&(entry->list))->next = (list); (&(entry->
list))->prev = (list)->prev; (list)->prev->next =
(&(entry->list)); (list)->prev = (&(entry->
list)); } while (0)
;
523 LOG_CONFIG("store [%s] before [%s] \n",slapi_log_error(7, "ipa-modrdn-plugin", "store [%s] before [%s] \n"
, entry->scope, config_entry->scope)
524 entry->scope, config_entry->scope)slapi_log_error(7, "ipa-modrdn-plugin", "store [%s] before [%s] \n"
, entry->scope, config_entry->scope)
;
525 entry_added = 1;
526 break;
527 }
528
529 list = PR_NEXT_LINK(list)((list)->next);
530
531 if (ipamodrdn_global_config == list) {
532 /* add to tail */
533 PR_INSERT_BEFORE(&(entry->list), list)do { (&(entry->list))->next = (list); (&(entry->
list))->prev = (list)->prev; (list)->prev->next =
(&(entry->list)); (list)->prev = (&(entry->
list)); } while (0)
;
534 LOG_CONFIG("store [%s] at tail\n", entry->scope)slapi_log_error(7, "ipa-modrdn-plugin", "store [%s] at tail\n"
, entry->scope)
;
535 entry_added = 1;
536 break;
537 }
538 }
539 } else {
540 /* first entry */
541 PR_INSERT_LINK(&(entry->list), ipamodrdn_global_config)do { (&(entry->list))->next = (ipamodrdn_global_config
)->next; (&(entry->list))->prev = (ipamodrdn_global_config
); (ipamodrdn_global_config)->next->prev = (&(entry
->list)); (ipamodrdn_global_config)->next = (&(entry
->list)); } while (0)
;
542 LOG_CONFIG("store [%s] at head \n", entry->scope)slapi_log_error(7, "ipa-modrdn-plugin", "store [%s] at head \n"
, entry->scope)
;
543 entry_added = 1;
544 }
545
546bail:
547 if (0 == entry_added) {
548 /* Don't log error if we weren't asked to apply config */
549 if (apply && (entry != NULL((void*)0))) {
550 LOG_FATAL("Invalid config entry [%s] skipped\n", entry->dn)slapi_log_error(0, ((void *)((uintptr_t)(__func__))), "[file %s, line %d]: "
"Invalid config entry [%s] skipped\n", "ipa_modrdn.c", 550, entry
->dn)
;
551 }
552 ipamodrdn_free_config_entry(&entry);
553 } else {
554 ret = EOK0;
555 }
556
557 LOG_TRACE("<--out--\n")slapi_log_error(1, ((void *)((uintptr_t)(__func__))), "<--out--\n"
)
;
558
559 return ret;
560}
561
562static void
563ipamodrdn_free_config_entry(struct configEntry **entry)
564{
565 struct configEntry *e;
566
567 if (!entry || !*entry) {
568 return;
569 }
570
571 e = *entry;
572
573 if (e->dn) {
574 LOG_CONFIG("freeing config entry [%s]\n", e->dn)slapi_log_error(7, "ipa-modrdn-plugin", "freeing config entry [%s]\n"
, e->dn)
;
575 }
576 slapi_ch_free_string(&e->dn);
577 slapi_ch_free_string(&e->sattr);
578 slapi_ch_free_string(&e->tattr);
579 slapi_ch_free_string(&e->prefix);
580 slapi_ch_free_string(&e->suffix);
581 slapi_ch_free_string(&e->filter);
582 slapi_filter_free(e->slapi_filter, 1);
583 slapi_ch_free_string(&e->scope);
584 slapi_ch_free((void **)entry);
585}
586
587static void
588ipamodrdn_delete_configEntry(PRCList *entry)
589{
590 PR_REMOVE_LINK(entry)do { (entry)->prev->next = (entry)->next; (entry)->
next->prev = (entry)->prev; } while (0)
;
591 ipamodrdn_free_config_entry((struct configEntry **) &entry);
592}
593
594static void
595ipamodrdn_delete_config(void)
596{
597 PRCList *list;
598
599 while (!PR_CLIST_IS_EMPTY(ipamodrdn_global_config)((ipamodrdn_global_config)->next == (ipamodrdn_global_config
))
) {
600 list = PR_LIST_HEAD(ipamodrdn_global_config)(ipamodrdn_global_config)->next;
601 ipamodrdn_delete_configEntry(list);
602 }
603
604 return;
605}
606
607/****************************************************
608 Helpers
609****************************************************/
610
611static char *ipamodrdn_get_dn(Slapi_PBlock * pb)
612{
613 char *dn = NULL((void*)0);
614
615 LOG_TRACE("--in-->\n")slapi_log_error(1, ((void *)((uintptr_t)(__func__))), "--in-->\n"
)
;
616
617 if (slapi_pblock_get(pb, SLAPI_TARGET_DN50, &dn)) {
618 LOG_FATAL("failed to get dn of changed entry")slapi_log_error(0, ((void *)((uintptr_t)(__func__))), "[file %s, line %d]: "
"failed to get dn of changed entry", "ipa_modrdn.c", 618)
;
619 }
620
621 LOG_TRACE("<--out--\n")slapi_log_error(1, ((void *)((uintptr_t)(__func__))), "<--out--\n"
)
;
622
623 return dn;
624}
625
626/* config check
627 matching config dn or a descendent reloads config
628*/
629static int ipamodrdn_dn_is_config(char *dn)
630{
631 int ret = 0;
632
633 LOG_TRACE("--in-->\n")slapi_log_error(1, ((void *)((uintptr_t)(__func__))), "--in-->\n"
)
;
634
635 if (slapi_dn_issuffix(dn, getPluginDN())) {
636 ret = 1;
637 }
638
639 LOG_TRACE("<--out--\n")slapi_log_error(1, ((void *)((uintptr_t)(__func__))), "<--out--\n"
)
;
640
641 return ret;
642}
643
644/****************************************************
645 Functions that actually do things other
646 than config and startup
647****************************************************/
648
649static int
650ipamodrdn_change_attr(struct configEntry *cfgentry,
651 char *targetdn, const char *value)
652{
653 Slapi_PBlock *mod_pb = slapi_pblock_new();
654 LDAPMod mod;
655 LDAPMod *mods[2];
656 char *val[2] = { NULL((void*)0) };
657 int ret;
658
659 val[0] = slapi_ch_smprintf("%s%s%s",
660 cfgentry->prefix, value, cfgentry->suffix);
661 if (!val[0]) {
662 LOG_OOM()slapi_log_error(0, ((void *)((uintptr_t)(__func__))), "[file %s, line %d]: "
"Out of Memory!\n", "ipa_modrdn.c", 662)
;
663 ret = EFAIL-1;
664 goto done;
665 }
666 val[1] = 0;
667
668 mod.mod_op = LDAP_MOD_REPLACE(0x0002);
669 mod.mod_type = cfgentry->tattr;
670 mod.mod_valuesmod_vals.modv_strvals = val;
671
672 mods[0] = &mod;
673 mods[1] = 0;
674
675 LOG("Setting %s to %s in entry (%s)\n", cfgentry->tattr, value, targetdn)slapi_log_error(14, "ipa-modrdn-plugin", "Setting %s to %s in entry (%s)\n"
, cfgentry->tattr, value, targetdn)
;
676
677 /* Perform the modify operation. */
678 slapi_modify_internal_set_pb(mod_pb, targetdn, mods,
679 0, 0, getPluginID(), 0);
680 slapi_modify_internal_pb(mod_pb);
681 slapi_pblock_get(mod_pb, SLAPI_PLUGIN_INTOP_RESULT15, &ret);
682 if (ret != LDAP_SUCCESS0x00) {
683 LOG_FATAL("Failed to change attribute with error %d\n", ret)slapi_log_error(0, ((void *)((uintptr_t)(__func__))), "[file %s, line %d]: "
"Failed to change attribute with error %d\n", "ipa_modrdn.c"
, 683, ret)
;
684 ret = EFAIL-1;
685 }
686 ret = EOK0;
687
688done:
689 if (val[0]) slapi_ch_free_string(&(val[0]));
690 slapi_pblock_destroy(mod_pb);
691 return ret;
692}
693
694
695
696
697/* for mods and adds:
698 where dn's are supplied, the closest in scope
699 is used as long as the type filter matches
700 and the attr value has not been generated yet.
701*/
702
703static int ipamodrdn_post_op(Slapi_PBlock *pb)
704{
705 char *dn = NULL((void*)0);
706 PRCList *list = NULL((void*)0);
707 struct configEntry *cfgentry = NULL((void*)0);
708 struct slapi_entry *e = NULL((void*)0);
709 Slapi_Attr *sattr = NULL((void*)0);
710 Slapi_Attr *tattr = NULL((void*)0);
711 int ret = LDAP_SUCCESS0x00;
712
713 LOG_TRACE("--in-->\n")slapi_log_error(1, ((void *)((uintptr_t)(__func__))), "--in-->\n"
)
;
714
715 /* Just bail if we aren't ready to service requests yet. */
716 if (!g_plugin_started) {
717 goto done;
718 }
719
720 slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP53, &e);
721 if (NULL((void*)0) == e) {
722 goto done;
723 }
724
725 dn = slapi_entry_get_ndn(e);
726 if (NULL((void*)0) == dn) {
727 goto done;
728 }
729
730 ipamodrdn_read_lock();
731
732 if (!PR_CLIST_IS_EMPTY(ipamodrdn_global_config)((ipamodrdn_global_config)->next == (ipamodrdn_global_config
))
) {
733 list = PR_LIST_HEAD(ipamodrdn_global_config)(ipamodrdn_global_config)->next;
Value stored to 'list' is never read
734
735 for(list = PR_LIST_HEAD(ipamodrdn_global_config)(ipamodrdn_global_config)->next;
736 list != ipamodrdn_global_config;
737 list = PR_NEXT_LINK(list)((list)->next)) {
738 cfgentry = (struct configEntry *) list;
739
740 /* is the entry in scope? */
741 if (cfgentry->scope) {
742 if (!slapi_dn_issuffix(dn, cfgentry->scope)) {
743 continue;
744 }
745 }
746
747 /* does the entry match the filter? */
748 if (cfgentry->slapi_filter) {
749 ret = slapi_vattr_filter_test(pb, e,
750 cfgentry->slapi_filter, 0);
751 if (ret != LDAP_SUCCESS0x00) {
752 continue;
753 }
754 }
755
756 if (slapi_entry_attr_find(e, cfgentry->sattr, &sattr) != 0) {
757 LOG_TRACE("Source attr %s not found for %s\n",slapi_log_error(1, ((void *)((uintptr_t)(__func__))), "Source attr %s not found for %s\n"
, cfgentry->sattr, dn)
758 cfgentry->sattr, dn)slapi_log_error(1, ((void *)((uintptr_t)(__func__))), "Source attr %s not found for %s\n"
, cfgentry->sattr, dn)
;
759 continue;
760 }
761 if (slapi_entry_attr_find(e, cfgentry->tattr, &tattr) != 0) {
762 LOG_TRACE("Target attr %s not found for %s\n",slapi_log_error(1, ((void *)((uintptr_t)(__func__))), "Target attr %s not found for %s\n"
, cfgentry->tattr, dn)
763 cfgentry->tattr, dn)slapi_log_error(1, ((void *)((uintptr_t)(__func__))), "Target attr %s not found for %s\n"
, cfgentry->tattr, dn)
;
764 } else {
765 Slapi_Value *val;
766 const char *strval;
767
768 ret = slapi_attr_first_value(sattr, &val);
769 if (ret == -1 || !val) {
770 LOG_FATAL("Source attr %s is empty\n", cfgentry->sattr)slapi_log_error(0, ((void *)((uintptr_t)(__func__))), "[file %s, line %d]: "
"Source attr %s is empty\n", "ipa_modrdn.c", 770, cfgentry->
sattr)
;
771 continue;
772 }
773 strval = slapi_value_get_string(val);
774
775 ret = ipamodrdn_change_attr(cfgentry, dn, strval);
776 if (ret != EOK0) {
777 LOG_FATAL("Failed to set target attr %s for %s\n",slapi_log_error(0, ((void *)((uintptr_t)(__func__))), "[file %s, line %d]: "
"Failed to set target attr %s for %s\n", "ipa_modrdn.c", 778
, cfgentry->tattr, dn)
778 cfgentry->tattr, dn)slapi_log_error(0, ((void *)((uintptr_t)(__func__))), "[file %s, line %d]: "
"Failed to set target attr %s for %s\n", "ipa_modrdn.c", 778
, cfgentry->tattr, dn)
;
779 }
780 }
781 }
782 }
783
784 ipamodrdn_unlock();
785
786 ret = LDAP_SUCCESS0x00;
787
788done:
789 if (ret) {
790 LOG("operation failure [%d]\n", ret)slapi_log_error(14, "ipa-modrdn-plugin", "operation failure [%d]\n"
, ret)
;
791 ret = EFAIL-1;
792 }
793
794 LOG_TRACE("<--out--\n")slapi_log_error(1, ((void *)((uintptr_t)(__func__))), "<--out--\n"
)
;
795
796 return ret;
797}
798
799static int ipamodrdn_config_check_post_op(Slapi_PBlock * pb)
800{
801 char *dn;
802
803 LOG_TRACE("--in-->\n")slapi_log_error(1, ((void *)((uintptr_t)(__func__))), "--in-->\n"
)
;
804
805 if ((dn = ipamodrdn_get_dn(pb))) {
806 if (ipamodrdn_dn_is_config(dn)) {
807 ipamodrdn_load_plugin_config();
808 }
809 }
810
811 LOG_TRACE("<--out--\n")slapi_log_error(1, ((void *)((uintptr_t)(__func__))), "<--out--\n"
)
;
812
813 return 0;
814}