Bug Summary

File:daemons/ipa-slapi-plugins/ipa-uuid/ipa_uuid.c
Warning:line 908, column 5
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_uuid.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-uuid -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_uuid.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 UUID 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 "uuid/uuid.h"
46#include <pthread.h>
47
48#include "util.h"
49
50#define IPAUUID_STR_SIZE36 36
51
52#define IPAUUID_PLUGIN_NAME"ipa-uuid-plugin" "ipa-uuid-plugin"
53#define IPAUUID_PLUGIN_VERSION0x00010000 0x00010000
54
55#define IPAUUID_DN"cn=IPA UUID,cn=plugins,cn=config" "cn=IPA UUID,cn=plugins,cn=config" /* temporary */
56
57#define IPA_PLUGIN_NAME"ipa-uuid-plugin" IPAUUID_PLUGIN_NAME"ipa-uuid-plugin"
58
59/**
60 * IPA UUID config types
61 */
62#define IPAUUID_ATTR"ipaUuidAttr" "ipaUuidAttr"
63#define IPAUUID_PREFIX"ipaUuidPrefix" "ipaUuidPrefix"
64#define IPAUUID_GENERATE"ipaUuidMagicRegen" "ipaUuidMagicRegen"
65#define IPAUUID_FILTER"ipaUuidFilter" "ipaUuidFilter"
66#define IPAUUID_SCOPE"ipaUuidScope" "ipaUuidScope"
67#define IPAUUID_EXCLUDE_SUBTREE"ipaUuidExcludeSubtree" "ipaUuidExcludeSubtree"
68#define IPAUUID_ENFORCE"ipaUuidEnforce" "ipaUuidEnforce"
69
70#define IPAUUID_FEATURE_DESC"IPA UUID" "IPA UUID"
71#define IPAUUID_PLUGIN_DESC"IPA UUID plugin" "IPA UUID plugin"
72#define IPAUUID_INT_PREOP_DESC"IPA UUID internal preop plugin" "IPA UUID internal preop plugin"
73#define IPAUUID_POSTOP_DESC"IPA UUID postop plugin" "IPA UUID postop plugin"
74
75static Slapi_PluginDesc pdesc = {
76 IPAUUID_FEATURE_DESC"IPA UUID",
77 "Red Hat, Inc.",
78 "1.0",
79 IPAUUID_PLUGIN_DESC"IPA UUID plugin"
80};
81
82/**
83 * linked list of config entries
84 */
85
86struct configEntry {
87 PRCList list;
88 char *dn;
89 char *attr;
90 char *prefix;
91 char *filter;
92 Slapi_Filter *slapi_filter;
93 char *generate;
94 char *scope;
95 char *exclude_subtree;
96 bool_Bool enforce;
97};
98
99static PRCList *ipauuid_global_config = NULL((void*)0);
100static pthread_rwlock_t g_ipauuid_cache_lock;
101
102static void *_PluginID = NULL((void*)0);
103static char *_PluginDN = NULL((void*)0);
104
105static int g_plugin_started = 0;
106
107
108/**
109 *
110 * management functions
111 *
112 */
113int ipauuid_init(Slapi_PBlock * pb);
114static int ipauuid_start(Slapi_PBlock * pb);
115static int ipauuid_close(Slapi_PBlock * pb);
116static int ipauuid_internal_preop_init(Slapi_PBlock *pb);
117static int ipauuid_postop_init(Slapi_PBlock * pb);
118
119/**
120 *
121 * Local operation functions
122 *
123 */
124static int ipauuid_load_plugin_config(void);
125static int ipauuid_parse_config_entry(Slapi_Entry * e, bool_Bool apply);
126static void ipauuid_delete_config(void);
127static void ipauuid_free_config_entry(struct configEntry ** entry);
128
129/**
130 *
131 * helpers
132 *
133 */
134static char *ipauuid_get_dn(Slapi_PBlock * pb);
135static int ipauuid_dn_is_config(char *dn);
136static int ipauuid_list_contains_attr(char **list, char *attr);
137
138/**
139 *
140 * the ops (where the real work is done)
141 *
142 */
143static int ipauuid_config_check_post_op(Slapi_PBlock * pb);
144static int ipauuid_pre_op(Slapi_PBlock * pb, int modtype);
145static int ipauuid_mod_pre_op(Slapi_PBlock * pb);
146static int ipauuid_add_pre_op(Slapi_PBlock * pb);
147
148/**
149 * debug functions - global, for the debugger
150 */
151void ipauuid_dump_config(void);
152void ipauuid_dump_config_entry(struct configEntry *);
153
154/**
155 *
156 * Deal with cache locking
157 *
158 */
159void ipauuid_read_lock(void)
160{
161 pthread_rwlock_rdlock(&g_ipauuid_cache_lock);
162}
163
164void ipauuid_write_lock(void)
165{
166 pthread_rwlock_wrlock(&g_ipauuid_cache_lock);
167}
168
169void ipauuid_unlock(void)
170{
171 pthread_rwlock_unlock(&g_ipauuid_cache_lock);
172}
173
174/**
175 *
176 * Get the plug-in version
177 *
178 */
179int ipauuid_version(void)
180{
181 return IPAUUID_PLUGIN_VERSION0x00010000;
182}
183
184/**
185 * Plugin identity mgmt
186 */
187void setPluginID(void *pluginID)
188{
189 _PluginID = pluginID;
190}
191
192void *getPluginID(void)
193{
194 return _PluginID;
195}
196
197void setPluginDN(char *pluginDN)
198{
199 _PluginDN = pluginDN;
200}
201
202char *getPluginDN(void)
203{
204 return _PluginDN;
205}
206
207/*
208 ipauuid_init
209 -------------
210 adds our callbacks to the list
211*/
212int
213ipauuid_init(Slapi_PBlock *pb)
214{
215 int status = EOK0;
216 char *plugin_identity = NULL((void*)0);
217
218 LOG_TRACE("--in-->\n")slapi_log_error(1, ((void *)((uintptr_t)(__func__))), "--in-->\n"
)
;
219
220 /**
221 * Store the plugin identity for later use.
222 * Used for internal operations
223 */
224
225 slapi_pblock_get(pb, SLAPI_PLUGIN_IDENTITY13, &plugin_identity);
226 PR_ASSERT(plugin_identity)((void) 0);
227 setPluginID(plugin_identity);
228
229 if (slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION8,
230 SLAPI_PLUGIN_VERSION_01"01") != 0 ||
231 slapi_pblock_set(pb, SLAPI_PLUGIN_START_FN212,
232 (void *) ipauuid_start) != 0 ||
233 slapi_pblock_set(pb, SLAPI_PLUGIN_CLOSE_FN210,
234 (void *) ipauuid_close) != 0 ||
235 slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION12,
236 (void *) &pdesc) != 0 ||
237 slapi_pblock_set(pb, SLAPI_PLUGIN_PRE_MODIFY_FN405,
238 (void *) ipauuid_mod_pre_op) != 0 ||
239 slapi_pblock_set(pb, SLAPI_PLUGIN_PRE_ADD_FN407,
240 (void *) ipauuid_add_pre_op) != 0 ||
241 /* internal preoperation */
242 slapi_register_plugin("internalpreoperation", /* op type */
243 1, /* Enabled */
244 "ipauuid_init", /* this function desc */
245 ipauuid_internal_preop_init, /* init func */
246 IPAUUID_INT_PREOP_DESC"IPA UUID internal preop plugin", /* plugin desc */
247 NULL((void*)0), /* ? */
248 plugin_identity /* access control */
249 ) ||
250 /* the config change checking post op */
251 slapi_register_plugin("postoperation", /* op type */
252 1, /* Enabled */
253 "ipauuid_init", /* this function desc */
254 ipauuid_postop_init, /* init func for post op */
255 IPAUUID_POSTOP_DESC"IPA UUID postop plugin", /* plugin desc */
256 NULL((void*)0), /* ? */
257 plugin_identity /* access control */
258 )
259 ) {
260 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_uuid.c", 260)
;
261 status = EFAIL-1;
262 }
263
264 LOG_TRACE("<--out--\n")slapi_log_error(1, ((void *)((uintptr_t)(__func__))), "<--out--\n"
)
;
265 return status;
266}
267
268static int
269ipauuid_internal_preop_init(Slapi_PBlock *pb)
270{
271 int status = EOK0;
272
273 if (slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION8,
274 SLAPI_PLUGIN_VERSION_01"01") != 0 ||
275 slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION12,
276 (void *) &pdesc) != 0 ||
277 slapi_pblock_set(pb, SLAPI_PLUGIN_INTERNAL_PRE_MODIFY_FN421,
278 (void *) ipauuid_mod_pre_op) != 0 ||
279 slapi_pblock_set(pb, SLAPI_PLUGIN_INTERNAL_PRE_ADD_FN420,
280 (void *) ipauuid_add_pre_op) != 0) {
281 status = EFAIL-1;
282 }
283
284 return status;
285}
286
287static int
288ipauuid_postop_init(Slapi_PBlock *pb)
289{
290 int status = EOK0;
291
292 if (slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION8,
293 SLAPI_PLUGIN_VERSION_01"01") != 0 ||
294 slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION12,
295 (void *) &pdesc) != 0 ||
296 slapi_pblock_set(pb, SLAPI_PLUGIN_POST_ADD_FN507,
297 (void *) ipauuid_config_check_post_op) != 0 ||
298 slapi_pblock_set(pb, SLAPI_PLUGIN_POST_MODRDN_FN506,
299 (void *) ipauuid_config_check_post_op) != 0 ||
300 slapi_pblock_set(pb, SLAPI_PLUGIN_POST_DELETE_FN508,
301 (void *) ipauuid_config_check_post_op) != 0 ||
302 slapi_pblock_set(pb, SLAPI_PLUGIN_POST_MODIFY_FN505,
303 (void *) ipauuid_config_check_post_op) != 0) {
304 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_uuid.c", 304)
;
305 status = EFAIL-1;
306 }
307
308 return status;
309}
310
311
312/*
313 ipauuid_start
314 --------------
315 Kicks off the config cache.
316 It is called after ipauuid_init.
317*/
318static int
319ipauuid_start(Slapi_PBlock * pb)
320{
321 char *plugindn = NULL((void*)0);
322
323 LOG_TRACE("--in-->\n")slapi_log_error(1, ((void *)((uintptr_t)(__func__))), "--in-->\n"
)
;
324
325 /* Check if we're already started */
326 if (g_plugin_started) {
327 goto done;
328 }
329
330 if (pthread_rwlock_init(&g_ipauuid_cache_lock, NULL((void*)0)) != 0) {
331 LOG_FATAL("lock creation failed\n")slapi_log_error(0, ((void *)((uintptr_t)(__func__))), "[file %s, line %d]: "
"lock creation failed\n", "ipa_uuid.c", 331)
;
332
333 return EFAIL-1;
334 }
335
336 /**
337 * Get the plug-in target dn from the system
338 * and store it for future use. This should avoid
339 * hardcoding of DN's in the code.
340 */
341 slapi_pblock_get(pb, SLAPI_TARGET_DN50, &plugindn);
342 if (NULL((void*)0) == plugindn || 0 == strlen(plugindn)) {
343 LOG("had to use hard coded config dn\n")slapi_log_error(14, "ipa-uuid-plugin", "had to use hard coded config dn\n"
)
;
344 plugindn = IPAUUID_DN"cn=IPA UUID,cn=plugins,cn=config";
345 } else {
346 LOG("config at %s\n", plugindn)slapi_log_error(14, "ipa-uuid-plugin", "config at %s\n", plugindn
)
;
347
348 }
349
350 setPluginDN(plugindn);
351
352 /*
353 * Load the config for our plug-in
354 */
355 ipauuid_global_config = (PRCList *)
356 slapi_ch_calloc(1, sizeof(struct configEntry));
357 PR_INIT_CLIST(ipauuid_global_config)do { (ipauuid_global_config)->next = (ipauuid_global_config
); (ipauuid_global_config)->prev = (ipauuid_global_config)
; } while (0)
;
358
359 if (ipauuid_load_plugin_config() != EOK0) {
360 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_uuid.c", 360)
;
361 return EFAIL-1;
362 }
363
364 g_plugin_started = 1;
365 LOG("ready for service\n")slapi_log_error(14, "ipa-uuid-plugin", "ready for service\n");
366 LOG_TRACE("<--out--\n")slapi_log_error(1, ((void *)((uintptr_t)(__func__))), "<--out--\n"
)
;
367
368done:
369 return EOK0;
370}
371
372/*
373 ipauuid_close
374 --------------
375 closes down the cache
376*/
377static int
378ipauuid_close(Slapi_PBlock * pb)
379{
380 LOG_TRACE( "--in-->\n")slapi_log_error(1, ((void *)((uintptr_t)(__func__))), "--in-->\n"
)
;
381
382 ipauuid_delete_config();
383
384 slapi_ch_free((void **)&ipauuid_global_config);
385
386 LOG_TRACE("<--out--\n")slapi_log_error(1, ((void *)((uintptr_t)(__func__))), "<--out--\n"
)
;
387
388 return EOK0;
389}
390
391/*
392 * config looks like this
393 * - cn=myplugin
394 * --- cn=posix
395 * ------ cn=accounts
396 * ------ cn=groups
397 * --- cn=samba
398 * --- cn=etc
399 * ------ cn=etc etc
400 */
401static int
402ipauuid_load_plugin_config()
403{
404 int status = EOK0;
405 int result;
406 int i;
407 Slapi_PBlock *search_pb;
408 Slapi_Entry **entries = NULL((void*)0);
409
410 LOG_TRACE("--in-->\n")slapi_log_error(1, ((void *)((uintptr_t)(__func__))), "--in-->\n"
)
;
411
412 ipauuid_write_lock();
413 ipauuid_delete_config();
414
415 search_pb = slapi_pblock_new();
416
417 slapi_search_internal_set_pb(search_pb, getPluginDN(),
418 LDAP_SCOPE_SUBTREE((ber_int_t) 0x0002), "objectclass=*",
419 NULL((void*)0), 0, NULL((void*)0), NULL((void*)0), getPluginID(), 0);
420 slapi_search_internal_pb(search_pb);
421 slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_RESULT15, &result);
422
423 if (LDAP_SUCCESS0x00 != result) {
424 status = EFAIL-1;
425 goto cleanup;
426 }
427
428 slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES16,
429 &entries);
430 if (NULL((void*)0) == entries || NULL((void*)0) == entries[0]) {
431 status = EOK0;
432 goto cleanup;
433 }
434
435 for (i = 0; (entries[i] != NULL((void*)0)); i++) {
436 /* We don't care about the status here because we may have
437 * some invalid config entries, but we just want to continue
438 * looking for valid ones. */
439 ipauuid_parse_config_entry(entries[i], true1);
440 }
441
442 cleanup:
443 slapi_free_search_results_internal(search_pb);
444 slapi_pblock_destroy(search_pb);
445 ipauuid_unlock();
446 LOG_TRACE("<--out--\n")slapi_log_error(1, ((void *)((uintptr_t)(__func__))), "<--out--\n"
)
;
447
448 return status;
449}
450
451/*
452 * ipauuid_parse_config_entry()
453 *
454 * Parses a single config entry. If apply is non-zero, then
455 * we will load and start using the new config. You can simply
456 * validate config without making any changes by setting apply
457 * to 0.
458 *
459 * Returns EOK if the entry is valid and EFAIL
460 * if it is invalid.
461 */
462static int
463ipauuid_parse_config_entry(Slapi_Entry * e, bool_Bool apply)
464{
465 char *value;
466 struct configEntry *entry = NULL((void*)0);
467 struct configEntry *config_entry;
468 PRCList *list;
469 int entry_added = 0;
470 int ret = EOK0;
471
472 LOG_TRACE("--in-->\n")slapi_log_error(1, ((void *)((uintptr_t)(__func__))), "--in-->\n"
)
;
473
474 /* If this is the main UUID plug-in config entry, just bail. */
475 if (strcasecmp(getPluginDN(), slapi_entry_get_ndn(e)) == 0) {
476 ret = EFAIL-1;
477 goto bail;
478 }
479
480 entry = (struct configEntry *)
481 slapi_ch_calloc(1, sizeof(struct configEntry));
482 if (NULL((void*)0) == entry) {
483 ret = EFAIL-1;
484 goto bail;
485 }
486
487 value = slapi_entry_get_ndn(e);
488 if (value) {
489 entry->dn = slapi_ch_strdup(value);
490 }
491 LOG_CONFIG("----------> dn [%s]\n", entry->dn)slapi_log_error(7, "ipa-uuid-plugin", "----------> dn [%s]\n"
, entry->dn)
;
492
493 entry->attr = slapi_entry_attr_get_charptr(e, IPAUUID_ATTR"ipaUuidAttr");
494 if (!entry->attr) {
495 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_uuid.c",
496, "ipaUuidAttr", entry->dn)
496 IPAUUID_ATTR, entry->dn)slapi_log_error(0, ((void *)((uintptr_t)(__func__))), "[file %s, line %d]: "
"The %s config setting is required for %s.\n", "ipa_uuid.c",
496, "ipaUuidAttr", entry->dn)
;
497 ret = EFAIL-1;
498 goto bail;
499 }
500 LOG_CONFIG("----------> %s [%s]\n", IPAUUID_ATTR, entry->attr)slapi_log_error(7, "ipa-uuid-plugin", "----------> %s [%s]\n"
, "ipaUuidAttr", entry->attr)
;
501
502 value = slapi_entry_attr_get_charptr(e, IPAUUID_PREFIX"ipaUuidPrefix");
503 if (value && value[0]) {
504 entry->prefix = value;
505 }
506 LOG_CONFIG("----------> %s [%s]\n", IPAUUID_PREFIX, entry->prefix)slapi_log_error(7, "ipa-uuid-plugin", "----------> %s [%s]\n"
, "ipaUuidPrefix", entry->prefix)
;
507
508 value = slapi_entry_attr_get_charptr(e, IPAUUID_GENERATE"ipaUuidMagicRegen");
509 if (value) {
510 entry->generate = value;
511 }
512 LOG_CONFIG("----------> %s [%s]\n", IPAUUID_GENERATE, entry->generate)slapi_log_error(7, "ipa-uuid-plugin", "----------> %s [%s]\n"
, "ipaUuidMagicRegen", entry->generate)
;
513
514 value = slapi_entry_attr_get_charptr(e, IPAUUID_FILTER"ipaUuidFilter");
515 if (value) {
516 entry->filter = value;
517 if (NULL((void*)0) == (entry->slapi_filter = slapi_str2filter(value))) {
518 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_uuid.c"
, 519, entry->dn, value)
519 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_uuid.c"
, 519, entry->dn, value)
;
520 ret = EFAIL-1;
521 goto bail;
522 }
523 } else {
524 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_uuid.c",
525, "ipaUuidFilter", entry->dn)
525 IPAUUID_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_uuid.c",
525, "ipaUuidFilter", entry->dn)
;
526 ret = EFAIL-1;
527 goto bail;
528 }
529 LOG_CONFIG("----------> %s [%s]\n", IPAUUID_FILTER, value)slapi_log_error(7, "ipa-uuid-plugin", "----------> %s [%s]\n"
, "ipaUuidFilter", value)
;
530
531 value = slapi_entry_attr_get_charptr(e, IPAUUID_SCOPE"ipaUuidScope");
532 if (value) {
533 entry->scope = value;
534 } else {
535 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_uuid.c"
, 536, "ipaUuidScope", entry->dn)
536 IPAUUID_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_uuid.c"
, 536, "ipaUuidScope", entry->dn)
;
537 ret = EFAIL-1;
538 goto bail;
539 }
540 LOG_CONFIG("----------> %s [%s]\n", IPAUUID_SCOPE, entry->scope)slapi_log_error(7, "ipa-uuid-plugin", "----------> %s [%s]\n"
, "ipaUuidScope", entry->scope)
;
541
542 value = slapi_entry_attr_get_charptr(e, IPAUUID_EXCLUDE_SUBTREE"ipaUuidExcludeSubtree");
543 entry->exclude_subtree = value;
544 LOG_CONFIG("----------> %s [%s]\n", IPAUUID_EXCLUDE_SUBTREE, entry->exclude_subtree)slapi_log_error(7, "ipa-uuid-plugin", "----------> %s [%s]\n"
, "ipaUuidExcludeSubtree", entry->exclude_subtree)
;
545
546 entry->enforce = slapi_entry_attr_get_bool(e, IPAUUID_ENFORCE"ipaUuidEnforce");
547 LOG_CONFIG("----------> %s [%s]\n",slapi_log_error(7, "ipa-uuid-plugin", "----------> %s [%s]\n"
, "ipaUuidEnforce", entry->enforce ? "True" : "False")
548 IPAUUID_ENFORCE, entry->enforce ? "True" : "False")slapi_log_error(7, "ipa-uuid-plugin", "----------> %s [%s]\n"
, "ipaUuidEnforce", entry->enforce ? "True" : "False")
;
549
550 /* If we were only called to validate config, we can
551 * just bail out before applying the config changes */
552 if (!apply) {
553 goto bail;
554 }
555
556 /**
557 * Finally add the entry to the list.
558 * We sort by scope dn length with longer
559 * dn's first - this allows the scope
560 * checking code to be simple and quick and
561 * cunningly linear.
562 */
563 if (!PR_CLIST_IS_EMPTY(ipauuid_global_config)((ipauuid_global_config)->next == (ipauuid_global_config))) {
564 list = PR_LIST_HEAD(ipauuid_global_config)(ipauuid_global_config)->next;
565 while (list != ipauuid_global_config) {
566 config_entry = (struct configEntry *) list;
567
568 if (slapi_dn_issuffix(entry->scope, config_entry->scope)) {
569 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)
;
570 LOG_CONFIG("store [%s] before [%s] \n",slapi_log_error(7, "ipa-uuid-plugin", "store [%s] before [%s] \n"
, entry->scope, config_entry->scope)
571 entry->scope, config_entry->scope)slapi_log_error(7, "ipa-uuid-plugin", "store [%s] before [%s] \n"
, entry->scope, config_entry->scope)
;
572 entry_added = 1;
573 break;
574 }
575
576 list = PR_NEXT_LINK(list)((list)->next);
577
578 if (ipauuid_global_config == list) {
579 /* add to tail */
580 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)
;
581 LOG_CONFIG("store [%s] at tail\n", entry->scope)slapi_log_error(7, "ipa-uuid-plugin", "store [%s] at tail\n",
entry->scope)
;
582 entry_added = 1;
583 break;
584 }
585 }
586 } else {
587 /* first entry */
588 PR_INSERT_LINK(&(entry->list), ipauuid_global_config)do { (&(entry->list))->next = (ipauuid_global_config
)->next; (&(entry->list))->prev = (ipauuid_global_config
); (ipauuid_global_config)->next->prev = (&(entry->
list)); (ipauuid_global_config)->next = (&(entry->list
)); } while (0)
;
589 LOG_CONFIG("store [%s] at head \n", entry->scope)slapi_log_error(7, "ipa-uuid-plugin", "store [%s] at head \n"
, entry->scope)
;
590 entry_added = 1;
591 }
592
593bail:
594 if (0 == entry_added) {
595 /* Don't log error if we weren't asked to apply config */
596 if (apply && (entry != NULL((void*)0))) {
597 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_uuid.c", 597, entry
->dn)
;
598 }
599 ipauuid_free_config_entry(&entry);
600 } else {
601 ret = EOK0;
602 }
603
604 LOG_TRACE("<--out--\n")slapi_log_error(1, ((void *)((uintptr_t)(__func__))), "<--out--\n"
)
;
605
606 return ret;
607}
608
609static void
610ipauuid_free_config_entry(struct configEntry **entry)
611{
612 struct configEntry *e;
613
614 if (!entry || !*entry) {
615 return;
616 }
617
618 e = *entry;
619
620 if (e->dn) {
621 LOG_CONFIG("freeing config entry [%s]\n", e->dn)slapi_log_error(7, "ipa-uuid-plugin", "freeing config entry [%s]\n"
, e->dn)
;
622 slapi_ch_free_string(&e->dn);
623 }
624
625 if (e->attr) {
626 slapi_ch_free_string(&e->attr);
627 }
628
629 if (e->prefix) {
630 slapi_ch_free_string(&e->prefix);
631 }
632
633 if (e->filter) {
634 slapi_ch_free_string(&e->filter);
635 }
636
637 if (e->slapi_filter) {
638 slapi_filter_free(e->slapi_filter, 1);
639 }
640
641 if (e->generate) {
642 slapi_ch_free_string(&e->generate);
643 }
644
645 if (e->scope) {
646 slapi_ch_free_string(&e->scope);
647 }
648
649 if (e->exclude_subtree) {
650 slapi_ch_free_string(&e->exclude_subtree);
651 }
652
653 slapi_ch_free((void **)entry);
654}
655
656static void
657ipauuid_delete_configEntry(PRCList *entry)
658{
659 PR_REMOVE_LINK(entry)do { (entry)->prev->next = (entry)->next; (entry)->
next->prev = (entry)->prev; } while (0)
;
660 ipauuid_free_config_entry((struct configEntry **) &entry);
661}
662
663static void
664ipauuid_delete_config()
665{
666 PRCList *list;
667
668 while (!PR_CLIST_IS_EMPTY(ipauuid_global_config)((ipauuid_global_config)->next == (ipauuid_global_config))) {
669 list = PR_LIST_HEAD(ipauuid_global_config)(ipauuid_global_config)->next;
670 ipauuid_delete_configEntry(list);
671 }
672
673 return;
674}
675
676/****************************************************
677 Helpers
678****************************************************/
679
680static char *ipauuid_get_dn(Slapi_PBlock * pb)
681{
682 char *dn = NULL((void*)0);
683
684 LOG_TRACE("--in-->\n")slapi_log_error(1, ((void *)((uintptr_t)(__func__))), "--in-->\n"
)
;
685
686 if (slapi_pblock_get(pb, SLAPI_TARGET_DN50, &dn)) {
687 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_uuid.c", 687)
;
688 }
689
690 LOG_TRACE("<--out--\n")slapi_log_error(1, ((void *)((uintptr_t)(__func__))), "<--out--\n"
)
;
691
692 return dn;
693}
694
695/* config check
696 matching config dn or a descendent reloads config
697*/
698static int ipauuid_dn_is_config(char *dn)
699{
700 int ret = 0;
701
702 LOG_TRACE("--in-->\n")slapi_log_error(1, ((void *)((uintptr_t)(__func__))), "--in-->\n"
)
;
703
704 if (slapi_dn_issuffix(dn, getPluginDN())) {
705 ret = 1;
706 }
707
708 LOG_TRACE("<--out--\n")slapi_log_error(1, ((void *)((uintptr_t)(__func__))), "<--out--\n"
)
;
709
710 return ret;
711}
712
713/****************************************************
714 Functions that actually do things other
715 than config and startup
716****************************************************/
717
718/*
719 * ipauuid_list_contains_attr()
720 *
721 * Checks if a attr is contained in a list of attrs.
722 * Returns 1 if the attr is found, 0 otherwise.
723 */
724static int
725ipauuid_list_contains_attr(char **list, char *attr)
726{
727 int ret = 0;
728 int i = 0;
729
730 if (list && attr) {
731 for (i = 0; list[i]; i++) {
732 if (slapi_attr_types_equivalent(attr, list[i])) {
733 ret = 1;
734 break;
735 }
736 }
737 }
738
739 return ret;
740}
741
742/* this function must be passed a preallocated buffer of 37 characters in the
743 * out parameter */
744static void ipauuid_generate_uuid(char *out)
745{
746 uuid_t uu;
747
748 uuid_generate_time(uu);
749 uuid_unparse_lower(uu, out);
750}
751
752/* for mods and adds:
753 where dn's are supplied, the closest in scope
754 is used as long as the type filter matches
755 and the attr value has not been generated yet.
756*/
757
758static int ipauuid_pre_op(Slapi_PBlock *pb, int modtype)
759{
760 char *dn = NULL((void*)0);
761 PRCList *list = NULL((void*)0);
762 struct configEntry *cfgentry = NULL((void*)0);
763 struct slapi_entry *e = NULL((void*)0);
764 Slapi_Entry *resulting_e = NULL((void*)0);
765 char *value = NULL((void*)0);
766 char **generated_attrs = NULL((void*)0);
767 Slapi_Mods *smods = NULL((void*)0);
768 Slapi_Mod *smod = NULL((void*)0);
769 Slapi_Mod *next_mod;
770 LDAPMod **mods;
771 bool_Bool free_entry = false0;
772 char *errstr = NULL((void*)0);
773 bool_Bool generate;
774 int ret = LDAP_SUCCESS0x00;
775 bool_Bool locked = false0;
776 bool_Bool set_attr;
777 int is_repl_op;
778 int is_config_dn;
779
780 LOG_TRACE("--in-->\n")slapi_log_error(1, ((void *)((uintptr_t)(__func__))), "--in-->\n"
)
;
781
782 /* Just bail if we aren't ready to service requests yet. */
783 if (!g_plugin_started) {
784 goto done;
785 }
786
787 dn = ipauuid_get_dn(pb);
788 if (!dn) {
789 goto done;
790 }
791
792 is_config_dn = ipauuid_dn_is_config(dn);
793
794 ret = slapi_pblock_get(pb, SLAPI_IS_REPLICATED_OPERATION142, &is_repl_op);
795 if (ret != 0) {
796 LOG_FATAL("slapi_pblock_get failed!?\n")slapi_log_error(0, ((void *)((uintptr_t)(__func__))), "[file %s, line %d]: "
"slapi_pblock_get failed!?\n", "ipa_uuid.c", 796)
;
797 ret = LDAP_OPERATIONS_ERROR0x01;
798 goto done;
799 }
800
801 /* pass through if this is a replicated operation */
802 if (is_repl_op && !is_config_dn) {
803 return 0;
804 }
805
806 if (modtype != LDAP_CHANGETYPE_ADD1 &&
807 modtype != LDAP_CHANGETYPE_MODIFY4) {
808 goto done;
809 }
810
811 if (LDAP_CHANGETYPE_ADD1 == modtype) {
812 slapi_pblock_get(pb, SLAPI_ADD_ENTRY60, &e);
813 } else {
814 /* xxxPAR: Ideally SLAPI_MODIFY_EXISTING_ENTRY should be
815 * available but it turns out that is only true if you are
816 * a dbm backend pre-op plugin - lucky dbm backend pre-op
817 * plugins.
818 * I think that is wrong since the entry is useful for filter
819 * tests and schema checks and this plugin shouldn't be limited
820 * to a single backend type, but I don't want that fight right
821 * now so we go get the entry here
822 *
823 slapi_pblock_get( pb, SLAPI_MODIFY_EXISTING_ENTRY, &e);
824 */
825 Slapi_DN *tmp_dn = slapi_sdn_new_dn_byref(dn);
826 if (tmp_dn) {
827 ret = slapi_search_internal_get_entry(tmp_dn, NULL((void*)0), &e, getPluginID());
828 slapi_sdn_free(&tmp_dn);
829
830 if (ret == LDAP_REFERRAL0x0a) {
831 /* we have a referral so nothing for us to do, but return
832 * success so we allow the MOD to proceed.
833 */
834 ret = LDAP_SUCCESS0x00;
835 free_entry = true1;
836 goto done;
837 }
838
839 if (ret) {
840 /* ok a client tried to modify an entry that doesn't exist.
841 * Nothing to see here, move along ... */
842 goto done;
843 }
844
845 free_entry = true1;
846 }
847
848 /* grab the mods - we'll put them back later with
849 * our modifications appended
850 */
851 slapi_pblock_get(pb, SLAPI_MODIFY_MODS90, &mods);
852 smods = slapi_mods_new();
853 slapi_mods_init_passin(smods, mods);
854
855 /* We need the resulting entry after the mods are applied to
856 * see if the entry is within the scope. */
857 if (e) {
858 resulting_e = slapi_entry_dup(e);
859 if (mods && (slapi_entry_apply_mods(resulting_e, mods) != LDAP_SUCCESS0x00)) {
860 /* The mods don't apply cleanly, so we just let this op go
861 * to let the main server handle it. */
862 goto done;
863 }
864 }
865 }
866
867 if (NULL((void*)0) == e) {
868 goto done;
869 }
870
871 if (is_config_dn) {
872 /* Validate config changes, but don't apply them.
873 * This allows us to reject invalid config changes
874 * here at the pre-op stage. Applying the config
875 * needs to be done at the post-op stage. */
876 Slapi_Entry *test_e = NULL((void*)0);
877
878 /* For a MOD, we need to check the resulting entry */
879 if (LDAP_CHANGETYPE_ADD1 == modtype) {
880 test_e = e;
881 } else {
882 test_e = resulting_e;
883 }
884
885 if (ipauuid_parse_config_entry(test_e, false0) != EOK0) {
886 /* Refuse the operation if config parsing failed. */
887 ret = LDAP_UNWILLING_TO_PERFORM0x35;
888 if (LDAP_CHANGETYPE_ADD1 == modtype) {
889 errstr = slapi_ch_smprintf("Not a valid IPA UUID "
890 "configuration entry.");
891 } else {
892 errstr = slapi_ch_smprintf("Changes result in an invalid "
893 "IPA UUID configuration.");
894 }
895 }
896
897 /* We're done, so just bail. */
898 goto done;
899 }
900
901 ipauuid_read_lock();
902 locked = true1;
903
904 if (PR_CLIST_IS_EMPTY(ipauuid_global_config)((ipauuid_global_config)->next == (ipauuid_global_config))) {
905 goto done;
906 }
907
908 list = PR_LIST_HEAD(ipauuid_global_config)(ipauuid_global_config)->next;
Value stored to 'list' is never read
909
910 for(list = PR_LIST_HEAD(ipauuid_global_config)(ipauuid_global_config)->next;
911 list != ipauuid_global_config;
912 list = PR_NEXT_LINK(list)((list)->next)) {
913 cfgentry = (struct configEntry *) list;
914 char *current_dn = NULL((void*)0);
915
916 generate = false0;
917 set_attr = false0;
918
919 /* Did we already service this attr? */
920 if (ipauuid_list_contains_attr(generated_attrs,
921 cfgentry->attr)) {
922 continue;
923 }
924 /* Current DN may have been reset by
925 * slapi_pblock_set(pb, SLAPI_ADD_TARGET,..) see below
926 * need to reread it
927 */
928 current_dn = ipauuid_get_dn(pb);
929
930 /* is the entry in scope? */
931 if (cfgentry->scope) {
932 if (!slapi_dn_issuffix(current_dn, cfgentry->scope)) {
933 continue;
934 }
935 }
936
937 if (cfgentry->exclude_subtree) {
938 if (slapi_dn_issuffix(current_dn, cfgentry->exclude_subtree)) {
939 continue;
940 }
941 }
942
943 /* does the entry match the filter? */
944 if (cfgentry->slapi_filter) {
945 Slapi_Entry *test_e = NULL((void*)0);
946
947 /* For a MOD operation, we need to check the filter
948 * against the resulting entry. */
949 if (LDAP_CHANGETYPE_ADD1 == modtype) {
950 test_e = e;
951 } else {
952 test_e = resulting_e;
953 }
954
955 ret = slapi_vattr_filter_test(pb, test_e,
956 cfgentry->slapi_filter, 0);
957 if (ret != LDAP_SUCCESS0x00) {
958 continue;
959 }
960 }
961
962 switch(modtype) {
963 case LDAP_CHANGETYPE_ADD1:
964 /* Generate the value if the magic value is set or if the
965 * attr is missing. */
966 value = slapi_entry_attr_get_charptr(e, cfgentry->attr);
967
968 if (!value ||
969 !slapi_UTF8CASECMP(cfgentry->generate, value)) {
970 generate = true1;
971 }
972
973 slapi_ch_free_string(&value);
974
975 /* always true on add if we match the scope */
976 set_attr = true1;
977 break;
978
979 case LDAP_CHANGETYPE_MODIFY4:
980 /* check mods for magic value */
981 next_mod = slapi_mod_new();
982 smod = slapi_mods_get_first_smod(smods, next_mod);
983 while (smod) {
984 char *attr = (char *)slapi_mod_get_type(smod);
985
986 /* See if the attr matches the configured attr. */
987 if (!slapi_attr_types_equivalent(cfgentry->attr, attr)) {
988 slapi_mod_done(next_mod);
989 smod = slapi_mods_get_next_smod(smods, next_mod);
990 continue;
991 }
992
993 /* ok we found the attr so that means we are going to set it */
994 set_attr = true1;
995
996 /* If all values are being deleted, we need to
997 * generate a new value. */
998 if (SLAPI_IS_MOD_DELETE(slapi_mod_get_operation(smod))(((slapi_mod_get_operation(smod)) & ~(0x0080)) == (0x0001
))
) {
999 int numvals = slapi_mod_get_num_values(smod);
1000
1001 if (numvals == 0) {
1002 generate = true1;
1003 } else {
1004 Slapi_Attr *sattr = NULL((void*)0);
1005 int e_numvals = 0;
1006
1007 if ((!slapi_entry_attr_find(e, attr, &sattr)) &&
1008 (NULL((void*)0) != sattr)) {
1009 slapi_attr_get_numvalues(sattr, &e_numvals);
1010 if (numvals >= e_numvals) {
1011 generate = true1;
1012 }
1013 }
1014 }
1015 } else {
1016 struct berval *bv;
1017
1018 /* If this attr is already slated for generation,
1019 * a previous mod in this same modify operation
1020 * either removed all values or set the magic value.
1021 * It's possible that this mod is adding a valid value,
1022 * which means we would not want to generate a new one.
1023 * It is safe to reset the flag since it will be
1024 * re-added here if necessary. */
1025 generate = false0;
1026
1027 /* This is either adding or replacing a value */
1028 bv = slapi_mod_get_first_value(smod);
1029 /* If we have a value, see if it's the magic value. */
1030 if (bv) {
1031 if (!slapi_UTF8CASECMP(bv->bv_val,
1032 cfgentry->generate)) {
1033 generate = true1;
1034
1035 /* also remove this mod, as we will add
1036 * it again later */
1037 slapi_mod_remove_value(next_mod);
1038 }
1039 } else {
1040 /* This is a replace with no new values, so we need
1041 * to generate a new value */
1042 generate = true1;
1043 }
1044 }
1045
1046 slapi_mod_done(next_mod);
1047 smod = slapi_mods_get_next_smod(smods, next_mod);
1048 }
1049
1050 slapi_mod_free(&next_mod);
1051 break;
1052
1053 default:
1054 /* never reached, just silence compiler */
1055 LOG_TRACE("File '%s' line %d: Got unexpected value of modtype:"slapi_log_error(1, ((void *)((uintptr_t)(__func__))), "File '%s' line %d: Got unexpected value of modtype:"
"%d\n", "ipa_uuid.c", 1056, modtype)
1056 "%d\n", __FILE__, __LINE__, modtype)slapi_log_error(1, ((void *)((uintptr_t)(__func__))), "File '%s' line %d: Got unexpected value of modtype:"
"%d\n", "ipa_uuid.c", 1056, modtype)
;
1057 break;
1058 }
1059
1060 /* We need to perform one last check for modify operations.
1061 * If an entry within the scope has not triggered generation yet,
1062 * we need to see if a value exists for the managed attr in the
1063 * resulting entry.
1064 * This will catch a modify operation that brings an entry into
1065 * scope for a managed range, but doesn't supply a value for the
1066 * managed attr. */
1067 if ((LDAP_CHANGETYPE_MODIFY4 == modtype) && !generate) {
1068 Slapi_Attr *attr = NULL((void*)0);
1069 if (slapi_entry_attr_find(resulting_e,
1070 cfgentry->attr, &attr) != 0) {
1071 generate = true1;
1072 set_attr = true1;
1073 }
1074 }
1075
1076 /* nothing to do keep looping */
1077 if (!set_attr) {
1078 continue;
1079 }
1080
1081 if (generate) {
1082 char *new_value;
1083
1084 /* create the value to add */
1085 value = slapi_ch_calloc(1, IPAUUID_STR_SIZE36 + 1);
1086 if (!value) {
1087 LOG_OOM()slapi_log_error(0, ((void *)((uintptr_t)(__func__))), "[file %s, line %d]: "
"Out of Memory!\n", "ipa_uuid.c", 1087)
;
1088 ret = LDAP_OPERATIONS_ERROR0x01;
1089 goto done;
1090 }
1091 ipauuid_generate_uuid(value);
1092
1093 if (cfgentry->prefix) {
1094 new_value = slapi_ch_smprintf("%s%s",
1095 cfgentry->prefix, value);
1096 } else {
1097 new_value = slapi_ch_smprintf("%s", value);
1098 }
1099
1100 /* do the mod */
1101 if (LDAP_CHANGETYPE_ADD1 == modtype) {
1102 Slapi_DN *sdn;
1103 Slapi_RDN *rdn;
1104 char *attr;
1105 char *nrdn;
1106
1107 /* add - set in entry */
1108 slapi_entry_attr_set_charptr(e, cfgentry->attr, new_value);
1109
1110 /* check to see if we need to change the RDN too */
1111 rdn = slapi_rdn_new();
1112 if (!rdn) {
1113 LOG_OOM()slapi_log_error(0, ((void *)((uintptr_t)(__func__))), "[file %s, line %d]: "
"Out of Memory!\n", "ipa_uuid.c", 1113)
;
1114 ret = LDAP_OPERATIONS_ERROR0x01;
1115 goto done;
1116 }
1117 sdn = slapi_sdn_new_dn_byval(current_dn);
1118 if (!sdn) {
1119 LOG_OOM()slapi_log_error(0, ((void *)((uintptr_t)(__func__))), "[file %s, line %d]: "
"Out of Memory!\n", "ipa_uuid.c", 1119)
;
1120 ret = LDAP_OPERATIONS_ERROR0x01;
1121 slapi_rdn_free(&rdn);
1122 goto done;
1123 }
1124 slapi_rdn_set_sdn(rdn, sdn);
1125 ret = slapi_rdn_contains_attr(rdn, cfgentry->attr, &attr);
1126 slapi_rdn_done(rdn);
1127 if (ret == 1) {
1128 /* no need to recheck if it is valid, it will be handled
1129 * later by checking the value in the entry */
1130 nrdn = slapi_ch_smprintf("%s=%s",
1131 cfgentry->attr, new_value);
1132 if (!nrdn) {
1133 LOG_OOM()slapi_log_error(0, ((void *)((uintptr_t)(__func__))), "[file %s, line %d]: "
"Out of Memory!\n", "ipa_uuid.c", 1133)
;
1134 ret = LDAP_OPERATIONS_ERROR0x01;
1135 slapi_rdn_free(&rdn);
1136 slapi_sdn_free(&sdn);
1137 goto done;
1138 }
1139
1140 slapi_rdn_set_dn(rdn, nrdn);
1141 slapi_ch_free_string(&nrdn);
1142 slapi_sdn_set_rdn(sdn, rdn);
1143 slapi_entry_set_sdn(e, sdn);
1144
1145 /* reset the target DN since we've changed it. */
1146 if (slapi_pblock_set(pb, SLAPI_ADD_TARGET50,
1147 (char*)slapi_sdn_get_ndn(slapi_entry_get_sdn_const(e)))) {
1148 LOG_FATAL("slapi_block_set failed!\n")slapi_log_error(0, ((void *)((uintptr_t)(__func__))), "[file %s, line %d]: "
"slapi_block_set failed!\n", "ipa_uuid.c", 1148)
;
1149 ret = LDAP_OPERATIONS_ERROR0x01;
1150 slapi_rdn_free(&rdn);
1151 slapi_sdn_free(&sdn);
1152 goto done;
1153 }
1154 }
1155 slapi_rdn_free(&rdn);
1156 slapi_sdn_free(&sdn);
1157
1158 } else {
1159 /* mod - add to mods */
1160 slapi_mods_add_string(smods, LDAP_MOD_REPLACE(0x0002),
1161 cfgentry->attr, new_value);
1162 }
1163
1164 /* Make sure we don't generate for this
1165 * attr again by keeping a list of attrs
1166 * we have generated for already.
1167 */
1168 slapi_ch_array_add(&generated_attrs,
1169 slapi_ch_strdup(cfgentry->attr));
1170
1171 /* free up */
1172 slapi_ch_free_string(&value);
1173 slapi_ch_free_string(&new_value);
1174
1175 } else {
1176 char *bindDN = NULL((void*)0);
1177 int is_root;
1178
1179 slapi_pblock_get(pb, SLAPI_CONN_DN143, &bindDN);
1180 is_root = slapi_dn_isroot(bindDN);
1181
1182 /* If not set to the magic value, check enforcement */
1183 if (cfgentry->enforce && is_root != 1) {
1184 /* only Directory Manager can set arbitrary values when
1185 * enforce is enabled. */
1186 errstr = slapi_ch_smprintf("Only the Directory Manager "
1187 "can set arbitrary values "
1188 "for %s\n", cfgentry->attr);
1189 ret = LDAP_INSUFFICIENT_ACCESS0x32;
1190 goto done;
1191 }
1192 }
1193 }
1194
1195 ret = LDAP_SUCCESS0x00;
1196
1197done:
1198 if (locked) {
1199 ipauuid_unlock();
1200 }
1201
1202 if (smods != NULL((void*)0)) {
1203 /* Put the updated mods back into place. */
1204 mods = slapi_mods_get_ldapmods_passout(smods);
1205 if (slapi_pblock_set(pb, SLAPI_MODIFY_MODS90, mods)) {
1206 LOG_FATAL("slapi_pblock_set failed!\n")slapi_log_error(0, ((void *)((uintptr_t)(__func__))), "[file %s, line %d]: "
"slapi_pblock_set failed!\n", "ipa_uuid.c", 1206)
;
1207 ret = LDAP_OPERATIONS_ERROR0x01;
1208 }
1209 slapi_mods_free(&smods);
1210 }
1211
1212 slapi_ch_array_free(generated_attrs);
1213 slapi_ch_free_string(&value);
1214
1215 if (free_entry && e) {
1216 slapi_entry_free(e);
1217 }
1218
1219 if (resulting_e) {
1220 slapi_entry_free(resulting_e);
1221 }
1222
1223 if (ret) {
1224 LOG("operation failure [%d]\n", ret)slapi_log_error(14, "ipa-uuid-plugin", "operation failure [%d]\n"
, ret)
;
1225 slapi_send_ldap_result(pb, ret, NULL((void*)0), errstr, 0, NULL((void*)0));
1226 slapi_ch_free((void **)&errstr);
1227 ret = EFAIL-1;
1228 }
1229
1230 LOG_TRACE("<--out--\n")slapi_log_error(1, ((void *)((uintptr_t)(__func__))), "<--out--\n"
)
;
1231
1232 return ret;
1233}
1234
1235static int ipauuid_add_pre_op(Slapi_PBlock * pb)
1236{
1237 return ipauuid_pre_op(pb, LDAP_CHANGETYPE_ADD1);
1238}
1239
1240static int ipauuid_mod_pre_op(Slapi_PBlock * pb)
1241{
1242 return ipauuid_pre_op(pb, LDAP_CHANGETYPE_MODIFY4);
1243}
1244
1245static int ipauuid_config_check_post_op(Slapi_PBlock * pb)
1246{
1247 char *dn;
1248
1249 LOG_TRACE("--in-->\n")slapi_log_error(1, ((void *)((uintptr_t)(__func__))), "--in-->\n"
)
;
1250
1251 if ((dn = ipauuid_get_dn(pb))) {
1252 if (ipauuid_dn_is_config(dn))
1253 ipauuid_load_plugin_config();
1254 }
1255
1256 LOG_TRACE("<--out--\n")slapi_log_error(1, ((void *)((uintptr_t)(__func__))), "<--out--\n"
)
;
1257
1258 return 0;
1259}
1260