4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 * Copyright 2012 Milan Jurik. All rights reserved.
29 #include <locale.h> /* gettext */
32 #include <sys/varargs.h>
35 #include "nscd_config.h"
36 #include "nscd_cfgdef.h"
45 static rwlock_t cfg_paramDB_rwlock
= DEFAULTRWLOCK
;
46 static nscd_db_t
*cfg_paramDB
= NULL
;
48 static nscd_cfg_global_data_t
*nscd_cfg_global_current
;
49 static nscd_cfg_nsw_db_data_t
*nscd_cfg_nsw_db_data_current
;
50 static nscd_cfg_nsw_db_data_t
*nscd_cfg_nsw_alldb_current
;
51 static rwlock_t
*nscd_cfg_global_rwlock
;
52 static rwlock_t
*nscd_cfg_nsw_db_data_rwlock
;
53 static rwlock_t
*nscd_cfg_nsw_alldb_rwlock
;
55 extern int _nscd_cfg_num_nsw_src_all
;
56 extern nscd_cfg_id_t
*_nscd_cfg_nsw_src_all
;
64 nscd_cfg_error_t
*ret
;
67 msglen
= (msg
!= NULL
? strlen(msg
) + 1 : 0);
69 size
= sizeof (nscd_cfg_error_t
) + msglen
;
71 ret
= calloc(1, size
);
77 ret
->msg
= (char *)ret
+
78 sizeof (nscd_cfg_error_t
);
79 (void) memcpy(ret
->msg
, msg
, msglen
);
87 nscd_cfg_list_t
**list
,
88 nscd_cfg_list_type_t type
)
90 char *me
= "_nscd_cfg_get_list";
94 nscd_cfg_param_desc_t
*pl
;
95 nscd_cfg_stat_desc_t
*sl
;
99 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
100 (me
, "invalid argument: list = %p\n", list
);
102 return (NSCD_INVALID_ARGUMENT
);
107 case NSCD_CFG_LIST_NSW_DB
:
109 num
= _nscd_cfg_num_nsw_db
;
110 l
= &_nscd_cfg_nsw_db
[0];
113 case NSCD_CFG_LIST_NSW_SRC
:
115 num
= _nscd_cfg_num_nsw_src_all
;
116 l
= _nscd_cfg_nsw_src_all
;
119 case NSCD_CFG_LIST_PARAM
:
121 num
= _nscd_cfg_num_param
;
122 pl
= &_nscd_cfg_param_desc
[0];
125 case NSCD_CFG_LIST_STAT
:
127 num
= _nscd_cfg_num_stat
;
128 sl
= &_nscd_cfg_stat_desc
[0];
132 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
133 (me
, "invalid argument: type (%d)\n", type
);
135 return (NSCD_INVALID_ARGUMENT
);
138 size
= sizeof (nscd_cfg_list_t
) + sizeof (nscd_cfg_id_t
*) * (num
+ 1);
140 ret
= calloc(1, size
);
142 return (NSCD_NO_MEMORY
);
145 p
= (char *)ret
+ sizeof (nscd_cfg_list_t
);
146 ret
->list
= (nscd_cfg_id_t
**)p
;
148 if (type
== NSCD_CFG_LIST_PARAM
) {
149 for (i
= 0; i
<= num
; i
++)
150 ret
->list
[i
] = (nscd_cfg_id_t
*)&pl
[i
];
151 } else if (type
== NSCD_CFG_LIST_STAT
) {
152 for (i
= 0; i
<= num
; i
++)
153 ret
->list
[i
] = (nscd_cfg_id_t
*)&sl
[i
];
155 for (i
= 0; i
<= num
; i
++)
156 ret
->list
[i
] = &l
[i
];
161 return (NSCD_SUCCESS
);
165 _nscd_cfg_get_param_desc_list(
166 nscd_cfg_param_desc_list_t
**list
)
168 return (_nscd_cfg_get_list((nscd_cfg_list_t
**)list
,
169 NSCD_CFG_LIST_PARAM
));
173 * FUNCTION: _nscd_cfg_create_paramDB
175 * Create the internal config parameter database
178 _nscd_cfg_create_paramDB()
183 (void) rw_wrlock(&cfg_paramDB_rwlock
);
185 ret
= _nscd_alloc_db(NSCD_DB_SIZE_MEDIUM
);
190 (void) rw_unlock(&cfg_paramDB_rwlock
);
196 * FUNCTION: _nscd_cfg_add_index_entry
198 * Add a config index entry (a name to index mapping)
199 * to the internal configuration database.
202 _nscd_cfg_add_index_entry(
205 nscd_cfg_list_type_t type
)
210 nscd_db_entry_t
*db_entry
;
213 return (NSCD_INVALID_ARGUMENT
);
215 if (type
== NSCD_CFG_LIST_NSW_DB
)
216 dbe_type
= NSCD_DATA_CFG_NSW_DB_INDEX
;
217 else if (type
== NSCD_CFG_LIST_NSW_SRC
)
218 dbe_type
= NSCD_DATA_CFG_NSW_SRC_INDEX
;
219 else if (type
== NSCD_CFG_LIST_PARAM
)
220 dbe_type
= NSCD_DATA_CFG_PARAM_INDEX
;
221 else if (type
== NSCD_CFG_LIST_STAT
)
222 dbe_type
= NSCD_DATA_CFG_STAT_INDEX
;
226 db_entry
= _nscd_alloc_db_entry(dbe_type
, (const char *)name
,
228 if (db_entry
== NULL
)
229 return (NSCD_NO_MEMORY
);
231 idx
= (int *)*(db_entry
->data_array
);
234 (void) rw_wrlock(&cfg_paramDB_rwlock
);
235 (void) _nscd_add_db_entry(cfg_paramDB
, name
, db_entry
,
236 NSCD_ADD_DB_ENTRY_FIRST
);
237 (void) rw_unlock(&cfg_paramDB_rwlock
);
239 return (NSCD_SUCCESS
);
243 * FUNCTION: _nscd_cfg_get_index
245 * Get the index of a config data item by searching the internal config
246 * database. Do not free the returned data.
251 nscd_cfg_list_type_t type
)
253 int index
= -1, dbe_type
;
254 const nscd_db_entry_t
*db_entry
;
259 if (type
== NSCD_CFG_LIST_NSW_DB
)
260 dbe_type
= NSCD_DATA_CFG_NSW_DB_INDEX
;
261 else if (type
== NSCD_CFG_LIST_NSW_SRC
)
262 dbe_type
= NSCD_DATA_CFG_NSW_SRC_INDEX
;
263 else if (type
== NSCD_CFG_LIST_PARAM
)
264 dbe_type
= NSCD_DATA_CFG_PARAM_INDEX
;
265 else if (type
== NSCD_CFG_LIST_STAT
)
266 dbe_type
= NSCD_DATA_CFG_STAT_INDEX
;
270 db_entry
= _nscd_get_db_entry(cfg_paramDB
, dbe_type
,
271 (const char *)name
, NSCD_GET_FIRST_DB_ENTRY
, 0);
273 if (db_entry
!= NULL
)
274 index
= *(int *)*(db_entry
->data_array
);
280 _nscd_cfg_verify_group_info(
281 nscd_cfg_group_info_t
*g_info
,
282 nscd_cfg_param_desc_t
*gdesc
)
285 char *me
= "_nscd_cfg_verify_group_info";
287 nscd_cfg_group_info_t
*gi
;
289 if (_nscd_cfg_flag_is_set(gdesc
->pflag
, NSCD_CFG_PFLAG_GLOBAL
)) {
290 vp
= (char *)&nscd_cfg_global_default
+
292 gi
= (nscd_cfg_group_info_t
*)vp
;
294 vp
= (char *)&nscd_cfg_nsw_db_data_default
+
296 gi
= (nscd_cfg_group_info_t
*)vp
;
300 if (g_info
->num_param
== gi
->num_param
&&
301 _nscd_cfg_bitmap_is_equal(g_info
->bitmap
, gi
->bitmap
))
302 return (NSCD_SUCCESS
);
304 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
305 (me
, "ERROR: group (%s) info mismatched: group info "
306 "(%d, %#6.4x) not equal to that of default configuration data "
307 "(%d, %#6.4x)\n", gdesc
->id
.name
, g_info
->num_param
,
308 _nscd_cfg_bitmap_value(g_info
->bitmap
), gi
->num_param
,
309 _nscd_cfg_bitmap_value(gi
->bitmap
));
311 return (NSCD_CFG_PARAM_DESC_ERROR
);
319 char *me
= "_nscd_cfg_init_nsw";
320 int i
, j
, idx
, rc
, num
;
322 nscd_cfg_list_type_t type
[2] = { NSCD_CFG_LIST_NSW_DB
,
323 NSCD_CFG_LIST_NSW_SRC
};
325 nscd_cfg_id_t
*list
[2] = { _nscd_cfg_nsw_db
, NULL
};
327 list
[1] = _nscd_cfg_nsw_src_all
;
329 for (j
= 0; j
< 2; j
++) {
332 num
= _nscd_cfg_num_nsw_db
+ 1;
334 num
= _nscd_cfg_num_nsw_src_all
;
336 for (i
= 0; i
< num
; i
++) {
339 * _nscd_cfg_nsw_alldb is the id for the
340 * special ALLDB (defaults for all db)
342 if (j
== 0 && i
== _nscd_cfg_num_nsw_db
) {
343 id
= &_nscd_cfg_nsw_alldb
;
344 idx
= NSCD_CFG_NSW_ALLDB_INDEX
;
350 if (id
->name
== NULL
)
353 if ((rc
= _nscd_cfg_add_index_entry(id
->name
,
354 idx
, type
[j
])) != NSCD_SUCCESS
) {
356 _NSCD_LOG(NSCD_LOG_CONFIG
,
357 NSCD_LOG_LEVEL_ERROR
)
358 (me
, "unable to add index entry for "
359 "nsswitch entry %s\n", id
->name
);
361 _nscd_free_db(cfg_paramDB
);
367 return (NSCD_SUCCESS
);
371 _nscd_cfg_init_param()
373 char *me
= "_nscd_cfg_init_param";
376 nscd_cfg_param_desc_t
*desc
, *gdesc
= NULL
;
377 nscd_cfg_group_info_t g_info
;
378 nscd_cfg_list_type_t type
= NSCD_CFG_LIST_PARAM
;
382 if (_nscd_cfg_create_paramDB() == NULL
)
383 return (NSCD_NO_MEMORY
);
385 desc
= &_nscd_cfg_param_desc
[0];
388 * need to loop to the last (+1) param description
389 * which is a fake group and which marks the end
390 * of list. It is used to signal the end of the
391 * previous group so that the proper data will be
394 for (i
= 0; i
< _nscd_cfg_num_param
+ 1; i
++, desc
++) {
396 id
= (nscd_cfg_id_t
*)desc
;
398 if (_nscd_cfg_flag_is_set(desc
->pflag
,
399 NSCD_CFG_PFLAG_GROUP
)) {
402 g_info
.num_param
= fn
;
405 if ((rc
= _nscd_cfg_verify_group_info(
406 &g_info
, gdesc
)) != NSCD_SUCCESS
)
413 g_info
.bitmap
= NSCD_CFG_BITMAP_ZERO
;
416 * set the notify/verify functions
418 nfunc
= (void *)gdesc
->notify
;
419 vfunc
= (void *)gdesc
->verify
;
423 _NSCD_LOG(NSCD_LOG_CONFIG
,
424 NSCD_LOG_LEVEL_ERROR
)
425 (me
, "ERROR: first parameter "
426 "description is not for a group\n");
428 return (NSCD_CFG_PARAM_DESC_ERROR
);
432 * set bitmap: the rightmost bit represents
433 * the first member (index = 0) in the group,
434 * the next bit is for the second member
435 * (index = 1), and so on
437 _nscd_cfg_bitmap_set_nth(g_info
.bitmap
, fn
);
442 * set the notify/verify functions
444 if (desc
->notify
== NSCD_CFG_FUNC_NOTIFY_AS_GROUP
) {
445 (void) memcpy(&desc
->notify
, &nfunc
,
448 if (desc
->verify
== NSCD_CFG_FUNC_VERIFY_AS_GROUP
) {
449 (void) memcpy(&desc
->verify
, &vfunc
,
454 /* if end of list reached, we are done */
455 if (i
== _nscd_cfg_num_param
)
462 if ((rc
= _nscd_cfg_add_index_entry(id
->name
,
463 i
, type
)) != NSCD_SUCCESS
) {
465 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
466 (me
, "unable to add index entry for parameter "
469 _nscd_free_db(cfg_paramDB
);
472 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_DEBUG
)
473 (me
, "index entry for parameter "
474 "%s added\n", id
->name
);
478 return (_nscd_cfg_init_nsw());
482 _nscd_cfg_init_stat()
484 char *me
= "_nscd_cfg_init_stat";
487 nscd_cfg_stat_desc_t
*desc
, *gdesc
= NULL
;
488 nscd_cfg_group_info_t g_info
;
489 nscd_cfg_list_type_t type
= NSCD_CFG_LIST_STAT
;
493 desc
= &_nscd_cfg_stat_desc
[0];
496 * need to loop to the last (+1) stat description
497 * which is a fake group and which marks the end
498 * of list. It is used to signal the end of the
499 * previous group so that the proper data will be
502 for (i
= 0; i
< _nscd_cfg_num_stat
+ 1; i
++, desc
++) {
504 id
= (nscd_cfg_id_t
*)desc
;
506 if (_nscd_cfg_flag_is_set(desc
->sflag
,
507 NSCD_CFG_SFLAG_GROUP
)) {
510 g_info
.num_param
= fn
;
513 if (g_info
.num_param
!=
514 gdesc
->gi
.num_param
||
515 !_nscd_cfg_bitmap_is_equal(
516 g_info
.bitmap
, gdesc
->gi
.bitmap
)) {
518 _NSCD_LOG(NSCD_LOG_CONFIG
,
519 NSCD_LOG_LEVEL_ERROR
)
520 (me
, "ERROR: group (%s) "
522 "group info (%d, %#6.4x) not "
523 "equal to the predefined one "
524 "(%d, %#6.4x)\n", gdesc
->id
.name
,
526 _nscd_cfg_bitmap_value(
529 _nscd_cfg_bitmap_value(
533 return (NSCD_CFG_STAT_DESC_ERROR
);
540 g_info
.bitmap
= NSCD_CFG_BITMAP_ZERO
;
543 * set the get_stat function
545 gsfunc
= (void *)gdesc
->get_stat
;
549 _NSCD_LOG(NSCD_LOG_CONFIG
,
550 NSCD_LOG_LEVEL_ERROR
)
551 (me
, "ERROR: first stat "
552 "description is not for a group\n");
554 return (NSCD_CFG_STAT_DESC_ERROR
);
558 * set bitmap: the rightmost bit represents
559 * the first member (index = 0) in the group,
560 * the next bit is for the second member
561 * (index = 1), and so on
563 _nscd_cfg_bitmap_set_nth(g_info
.bitmap
, fn
);
568 * set the get_stat function
570 if (desc
->get_stat
== NSCD_CFG_FUNC_GET_STAT_AS_GROUP
) {
571 (void) memcpy(&desc
->get_stat
, &gsfunc
,
576 /* if end of list reached, we are done */
577 if (i
== _nscd_cfg_num_stat
)
584 if ((rc
= _nscd_cfg_add_index_entry(id
->name
,
585 i
, type
)) != NSCD_SUCCESS
) {
587 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
588 (me
, "unable to add index entry for stat "
589 "description %s\n", id
->name
);
591 _nscd_free_db(cfg_paramDB
);
594 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_DEBUG
)
595 (me
, "index entry for stat description "
596 "%s added\n", id
->name
);
600 return (NSCD_SUCCESS
);
604 _nscd_cfg_copy_vlen_data(
607 nscd_cfg_param_desc_t
*desc
,
612 nscd_cfg_vlen_data_t
*v
= NULL
;
617 /* it is OK if there is nothing to copy */
619 return (NSCD_SUCCESS
);
622 * if copy to the config store we need to allocate space
623 * for the extra vlen header
625 if (desc
->type
== NSCD_CFG_DATA_STRING
) {
626 len
= dlen
= strlen((char *)data
) + 1;
628 len
+= sizeof (nscd_cfg_vlen_data_t
);
631 * should not be here, since for now
632 * only string variable length data
636 return (NSCD_CFG_PARAM_DESC_ERROR
);
642 return (NSCD_NO_MEMORY
);
646 * if copy to the config store, set up
647 * the extra vlen header in which the
648 * pointer to, and length of, the real
649 * data are kept. The pointer to the real
650 * data, not the vlen header, is returned.
652 if (in
== nscd_true
) {
653 v
->ptr
= (char *)v
+ sizeof (nscd_cfg_vlen_data_t
);
655 (void) memcpy(v
->ptr
, data
, dlen
);
656 *new_data_p
= v
->ptr
;
658 (void) memcpy(v
, data
, dlen
);
663 return (NSCD_SUCCESS
);
667 _nscd_cfg_free_vlen_data_int(
670 nscd_cfg_vlen_data_t
*v
= NULL
;
676 p
= (char *)data
- sizeof (nscd_cfg_vlen_data_t
);
677 v
= (nscd_cfg_vlen_data_t
*)p
;
683 _nscd_cfg_set_vlen_data_int(
688 int i
, offset
, dlen
= 0;
692 nscd_cfg_param_desc_t
*desc
;
694 desc
= &_nscd_cfg_param_desc
[0];
695 for (i
= 0; i
< _nscd_cfg_num_param
; i
++, desc
++) {
697 if (global
== nscd_true
&&
698 _nscd_cfg_flag_is_not_set(desc
->pflag
,
699 NSCD_CFG_PFLAG_GLOBAL
))
701 else if (global
!= nscd_true
&&
702 _nscd_cfg_flag_is_set(desc
->pflag
,
703 NSCD_CFG_PFLAG_GLOBAL
))
706 if (_nscd_cfg_flag_is_set(desc
->pflag
,
707 NSCD_CFG_PFLAG_VLEN_DATA
)) {
709 offset
= desc
->g_offset
+ desc
->p_offset
;
711 s
= (char *)src
+ offset
;
714 rc
= _nscd_cfg_copy_vlen_data(cptr
, &new,
715 desc
, &dlen
, nscd_true
);
716 if (rc
!= NSCD_SUCCESS
)
719 d
= (char *)dest
+ offset
;
720 /* free the old vlen data */
721 if (*(char **)d
== NULL
)
722 _nscd_cfg_free_vlen_data_int(*(char **)d
);
728 return (NSCD_SUCCESS
);
732 _nscd_cfg_locate_vlen_data(
738 ptr
= *(char **)cfg_data
;
744 ptr
= (char *)ptr
- sizeof (nscd_cfg_vlen_data_t
);
745 *len
= ((nscd_cfg_vlen_data_t
*)ptr
)->len
;
753 nscd_cfg_lock_t
*cfglock
)
756 int (*lockfunc
)(rwlock_t
*);
761 if (is_read
== nscd_true
)
762 lockfunc
= rw_rdlock
;
764 lockfunc
= rw_wrlock
;
766 if (cfglock
->global
!= NULL
) {
768 (lockfunc
)(cfglock
->global
);
772 if (cfglock
->alldb
!= NULL
)
773 (lockfunc
)(cfglock
->alldb
);
775 if (cfglock
->nswdb
!= NULL
)
776 (lockfunc
)(cfglock
->nswdb
);
781 nscd_cfg_lock_t
*cfglock
)
786 if (cfglock
->global
!= NULL
) {
788 (void) rw_unlock(cfglock
->global
);
793 if (cfglock
->nswdb
!= NULL
)
794 (void) rw_unlock(cfglock
->nswdb
);
796 if (cfglock
->alldb
!= NULL
)
797 (void) rw_unlock(cfglock
->alldb
);
803 * If vlen_data_addr is given, it will be set to the
804 * address of the pointer pointing to the vlen data.
805 * 'cfglock' will be set to point to the reader/writer
806 * lock(s) protecting the (group) configuration data.
809 _nscd_cfg_locate_cfg_data(
812 nscd_cfg_param_desc_t
*desc
,
813 nscd_cfg_id_t
*nswdb
,
814 nscd_bool_t get_group
,
815 void **vlen_data_addr
,
817 nscd_cfg_lock_t
**cfglock
)
824 if (vlen_data_addr
!= NULL
)
825 *vlen_data_addr
= NULL
;
827 if (cfglock
!= NULL
) {
828 *cfglock
= calloc(1, sizeof (nscd_cfg_lock_t
));
829 if (*cfglock
== NULL
)
830 return (NSCD_NO_MEMORY
);
833 /* assume if nswdb is NULL, the param is a global one */
836 offset
= desc
->g_offset
;
837 if (get_group
!= nscd_true
)
838 offset
+= desc
->p_offset
;
839 *cfg_data
= (char *)nscd_cfg_global_current
+ offset
;
842 (*cfglock
)->global
= nscd_cfg_global_rwlock
;
844 } else if (nswdb
->index
== NSCD_CFG_NSW_ALLDB_INDEX
) {
846 offset
= desc
->g_offset
;
847 if (get_group
!= nscd_true
)
848 offset
+= desc
->p_offset
;
849 *cfg_data
= (char *)nscd_cfg_nsw_alldb_current
+
853 (*cfglock
)->alldb
= nscd_cfg_nsw_alldb_rwlock
;
857 offset
= nswdb
->index
*
858 (sizeof (nscd_cfg_nsw_db_data_t
)) + desc
->g_offset
;
859 if (get_group
!= nscd_true
)
860 offset
+= desc
->p_offset
;
861 *cfg_data
= (char *)nscd_cfg_nsw_db_data_current
+
864 if (cfglock
!= NULL
) {
866 &nscd_cfg_nsw_db_data_rwlock
[nswdb
->index
];
868 (*cfglock
)->alldb
= nscd_cfg_nsw_alldb_rwlock
;
872 /* lock the config data */
874 _nscd_cfg_lock(is_read
, *cfglock
);
876 if (get_group
!= nscd_true
&&
877 _nscd_cfg_flag_is_not_set(desc
->pflag
,
878 NSCD_CFG_PFLAG_GROUP
) &&
879 (_nscd_cfg_flag_is_set(desc
->pflag
,
880 NSCD_CFG_PFLAG_VLEN_DATA
))) {
881 if (vlen_data_addr
!= NULL
)
882 *vlen_data_addr
= *cfg_data
;
883 *cfg_data
= _nscd_cfg_locate_vlen_data(*cfg_data
, len
);
884 return (NSCD_SUCCESS
);
888 if (get_group
== nscd_true
)
894 return (NSCD_SUCCESS
);
898 * perform the preliminary (range) check on 'data' based on the
899 * datatype (desc->datatype) of the config parameter
902 _nscd_cfg_prelim_check(
903 nscd_cfg_param_desc_t
*desc
,
905 nscd_cfg_error_t
**errorp
)
908 char *me
= "_nscd_cfg_prelim_check";
909 char msg
[NSCD_CFG_MAX_ERR_MSG_LEN
];
910 nscd_cfg_str_check_t
*sc
;
911 nscd_cfg_int_check_t
*ic
;
912 nscd_cfg_bitmap_check_t
*bmc
;
913 nscd_rc_t rc
= NSCD_CFG_PRELIM_CHECK_FAILED
;
915 if ((nscd_cfg_str_check_t
*)desc
->p_check
== NULL
)
916 return (NSCD_SUCCESS
);
918 switch (desc
->type
) {
920 case NSCD_CFG_DATA_STRING
:
922 sc
= (nscd_cfg_str_check_t
*)desc
->p_check
;
923 if (sc
->must_not_null
== nscd_true
&& data
== NULL
) {
928 (void) snprintf(msg
, sizeof (msg
),
929 gettext("data must be specified for %s"),
940 if (sc
->maxlen
!= 0 &&
941 strlen((char *)data
) > sc
->maxlen
) {
946 (void) snprintf(msg
, sizeof (msg
),
947 gettext("length of data (%s) for %s larger "
949 (char *)data
, desc
->id
.name
, sc
->maxlen
);
957 case NSCD_CFG_DATA_INTEGER
:
959 ic
= (nscd_cfg_int_check_t
*)desc
->p_check
;
960 if (*(int *)data
> ic
->max
||
961 *(int *)data
< ic
->min
) {
966 (void) snprintf(msg
, sizeof (msg
),
967 gettext("data (%d) for %s out of range "
969 *(int *)data
, desc
->id
.name
,
979 case NSCD_CFG_DATA_BITMAP
:
981 bmc
= (nscd_cfg_bitmap_check_t
*)desc
->p_check
;
982 if (_nscd_cfg_bitmap_value(*(nscd_cfg_bitmap_t
*)data
) &
983 ~(bmc
->valid_bits
)) {
988 (void) snprintf(msg
, sizeof (msg
),
989 gettext("data (%#6.4x) for %s contain bit "
991 _nscd_cfg_bitmap_value(
992 *(nscd_cfg_bitmap_t
*)data
),
994 _nscd_cfg_bitmap_value(bmc
->valid_bits
));
1003 if (rc
!= NSCD_SUCCESS
&& errorp
!= NULL
) {
1004 *errorp
= _nscd_cfg_make_error(rc
, msg
);
1006 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_DEBUG
)
1007 (me
, "invalid argument: %s\n", (*errorp
)->msg
);
1015 nscd_cfg_param_desc_t
*desc
,
1016 nscd_cfg_id_t
*nswdb
,
1018 nscd_cfg_error_t
**errorp
)
1021 char *me
= "_nscd_cfg_notify_i";
1022 int i
, num
, skip_bk
;
1023 void *cfg_data
, *cdata
;
1024 void *cookie
= NULL
;
1026 nscd_cfg_flag_t dflag
, dflag1
;
1027 nscd_cfg_bitmap_t bitmap_c
, bitmap_s
, *bitmap_addr
;
1028 nscd_cfg_group_info_t
*gi
;
1038 if (_nscd_cfg_flag_is_not_set(desc
->pflag
,
1039 NSCD_CFG_PFLAG_GROUP
)) {
1041 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
1042 (me
, "ERROR: expect parameter description for group, "
1043 "but receive parameter description is for %s\n",
1046 return (NSCD_CFG_PARAM_DESC_ERROR
);
1050 * Set data flag going with data to be sent to the
1051 * verify/notify routines. Allowing the config flag
1052 * be exipandable, set the bits one by one.
1054 dflag
= NSCD_CFG_FLAG_ZERO
;
1055 dflag
= _nscd_cfg_flag_set(dflag
, NSCD_CFG_DFLAG_STATIC_DATA
);
1056 dflag
= _nscd_cfg_flag_set(dflag
, NSCD_CFG_DFLAG_INIT
);
1057 dflag
= _nscd_cfg_flag_set(dflag
, NSCD_CFG_DFLAG_GROUP
);
1058 if (_nscd_cfg_flag_is_set(desc
->pflag
,
1059 NSCD_CFG_PFLAG_INIT_SET_ALL_DB
))
1060 dflag
= _nscd_cfg_flag_set(dflag
,
1061 NSCD_CFG_DFLAG_SET_ALL_DB
);
1063 /* get to the group data in the config store */
1064 rc
= _nscd_cfg_locate_cfg_data(&cfg_data
, nscd_true
,
1065 desc
, nswdb
, nscd_true
, NULL
, NULL
, NULL
);
1066 if (rc
!= NSCD_SUCCESS
)
1070 * the static bitmap associated with the group
1071 * may be replaced before sending to the components,
1072 * so save the bitmap for later use
1074 gi
= _nscd_cfg_get_gi(cfg_data
);
1075 bitmap_c
= gi
->bitmap
;
1076 bitmap_addr
= &(gi
->bitmap
);
1079 * the elements in this group will all be handled
1080 * so the caller can skip them
1084 if (_nscd_cfg_flag_is_set(desc
->pflag
,
1085 NSCD_CFG_PFLAG_INIT_SEND_WHOLE_GROUP
))
1086 /* send the entire group just once */
1089 else { /* send individual members one by one */
1094 * skip the first desc which is for the group
1095 * and get to the desc for the first member
1099 dflag
= _nscd_cfg_flag_unset(dflag
,
1100 NSCD_CFG_DFLAG_GROUP
);
1104 for (i
= 0; i
< num
; i
++, desc
++) {
1108 if (_nscd_cfg_flag_is_set(desc
->pflag
,
1109 NSCD_CFG_PFLAG_SEND_BIT_SELECTED
)) {
1111 /* set the bitmap to select just this member */
1112 bitmap_s
= NSCD_CFG_BITMAP_ZERO
;
1113 _nscd_cfg_bitmap_set_nth(bitmap_s
, i
);
1114 /* replace the bitmap in the cfg data */
1115 _nscd_cfg_bitmap_set(bitmap_addr
, bitmap_s
);
1118 * send the whole group but with only one
1123 dflag
= _nscd_cfg_flag_set(dflag
,
1124 NSCD_CFG_DFLAG_GROUP
);
1125 dflag
= _nscd_cfg_flag_set(dflag
,
1126 NSCD_CFG_DFLAG_BIT_SELECTED
);
1129 * send param data or group data:
1130 * param data - non-xero desc->p_offset
1131 * group data - zero desc->p_offset
1133 cdata
= (char *)cfg_data
+ desc
->p_offset
;
1136 * if variable length data, need to send pointer
1137 * to the data (not the address of the pointer)
1139 if (_nscd_cfg_flag_is_set(desc
->pflag
,
1140 NSCD_CFG_PFLAG_VLEN_DATA
))
1141 cdata
= *(char **)cdata
;
1144 if (desc
->verify
!= NULL
) {
1145 dflag
= _nscd_cfg_flag_set(dflag
,
1146 NSCD_CFG_DFLAG_VERIFY
);
1147 rc
= desc
->verify(cdata
, desc
, nswdb
,
1148 dflag
, errorp
, &cookie
);
1149 if (rc
!= NSCD_SUCCESS
)
1153 if (desc
->notify
!= NULL
) {
1154 dflag
= _nscd_cfg_flag_set(dflag
,
1155 NSCD_CFG_DFLAG_NOTIFY
);
1157 rc
= desc
->notify(cfg_data
, desc
, nswdb
,
1158 dflag
, errorp
, cookie
);
1159 if (rc
!= NSCD_SUCCESS
)
1166 /* restore the bitmap in the cfg data */
1167 _nscd_cfg_bitmap_set(bitmap_addr
, bitmap_c
);
1176 _nscd_cfg_notify_init(
1177 nscd_cfg_error_t
**errorp
)
1181 nscd_cfg_id_t
*nswdb
= NULL
;
1182 nscd_cfg_param_desc_t
*desc
;
1187 for (i
= 0; i
< _nscd_cfg_num_param
; i
++) {
1189 desc
= &_nscd_cfg_param_desc
[i
];
1191 if (_nscd_cfg_flag_is_set(desc
->pflag
,
1192 NSCD_CFG_PFLAG_GLOBAL
)) { /* global cfg data */
1194 rc
= _nscd_cfg_notify_i(desc
, NULL
, &skip
, errorp
);
1198 * if use defaults for all nsswitch database,
1199 * send the config data to verify/notify once
1201 if (_nscd_cfg_flag_is_set(desc
->pflag
,
1202 NSCD_CFG_PFLAG_INIT_SET_ALL_DB
)) {
1204 nswdb
= &_nscd_cfg_nsw_alldb
;
1206 rc
= _nscd_cfg_notify_i(desc
, nswdb
,
1208 } else { /* send data once for each nsw db */
1210 for (j
= 0; j
< _nscd_cfg_num_nsw_db
; j
++) {
1212 nswdb
= &_nscd_cfg_nsw_db
[j
];
1214 rc
= _nscd_cfg_notify_i(desc
,
1215 nswdb
, &skip
, errorp
);
1217 if (rc
!= NSCD_SUCCESS
)
1223 if (rc
!= NSCD_SUCCESS
)
1229 return (NSCD_SUCCESS
);
1234 nscd_cfg_error_t
**errorp
)
1238 int dbi
= 0, dbj
= 0;
1240 char *dbni
= NULL
, *dbnj
= NULL
;
1242 nscd_cfg_nsw_spc_default_t
*spc
;
1247 rc
= _nscd_cfg_init_param();
1248 if (rc
!= NSCD_SUCCESS
)
1251 rc
= _nscd_cfg_init_stat();
1252 if (rc
!= NSCD_SUCCESS
)
1255 nscd_cfg_global_current
= calloc(1,
1256 sizeof (nscd_cfg_global_data_t
));
1257 if (nscd_cfg_global_current
== NULL
)
1258 return (NSCD_NO_MEMORY
);
1260 nscd_cfg_nsw_alldb_current
= calloc(1,
1261 sizeof (nscd_cfg_nsw_db_data_t
));
1262 if (nscd_cfg_nsw_alldb_current
== NULL
)
1263 return (NSCD_NO_MEMORY
);
1265 nscd_cfg_nsw_db_data_current
= calloc(_nscd_cfg_num_nsw_db
,
1266 sizeof (nscd_cfg_nsw_db_data_t
));
1267 if (nscd_cfg_nsw_db_data_current
== NULL
)
1268 return (NSCD_NO_MEMORY
);
1270 nscd_cfg_global_rwlock
= calloc(1, sizeof (rwlock_t
));
1271 if (nscd_cfg_global_rwlock
== NULL
)
1272 return (NSCD_NO_MEMORY
);
1273 (void) rwlock_init(nscd_cfg_global_rwlock
, NULL
, NULL
);
1275 *nscd_cfg_global_current
= nscd_cfg_global_default
;
1277 rc
= _nscd_cfg_set_vlen_data_int(&nscd_cfg_global_default
,
1278 nscd_cfg_global_current
, nscd_true
);
1279 if (rc
!= NSCD_SUCCESS
)
1282 nscd_cfg_nsw_db_data_rwlock
= calloc(_nscd_cfg_num_nsw_db
,
1284 if (nscd_cfg_nsw_db_data_rwlock
== NULL
)
1285 return (NSCD_NO_MEMORY
);
1287 /* set per switch db config to the default for all db's */
1288 for (i
= 0; i
< _nscd_cfg_num_nsw_db
; i
++) {
1290 nscd_cfg_nsw_db_data_current
[i
] =
1291 nscd_cfg_nsw_db_data_default
;
1293 (void) rwlock_init(&nscd_cfg_nsw_db_data_rwlock
[i
],
1297 /* add db specific defaults */
1298 for (i
= 0; i
< _nscd_cfg_num_nsw_default
; i
++) {
1300 if (_nscd_cfg_nsw_spc_default
[i
].data
== NULL
)
1303 if (_nscd_cfg_nsw_spc_default
[i
].db
!= dbni
) {
1304 for (j
= 0; j
< _nscd_cfg_num_nsw_db
; j
++) {
1306 if (strcmp(_nscd_cfg_nsw_db
[j
].name
,
1307 _nscd_cfg_nsw_spc_default
[i
].db
) != 0)
1310 dbi
= _nscd_cfg_nsw_db
[j
].index
;
1311 dbni
= _nscd_cfg_nsw_db
[j
].name
;
1316 dest
= (char *)&nscd_cfg_nsw_db_data_current
[dbi
] +
1317 _nscd_cfg_nsw_spc_default
[i
].group_off
+
1318 _nscd_cfg_nsw_spc_default
[i
].param_off
;
1320 src
= _nscd_cfg_nsw_spc_default
[i
].data
;
1321 datalen
= _nscd_cfg_nsw_spc_default
[i
].data_len
;
1323 (void) memcpy(dest
, src
, datalen
);
1326 /* add db specific defaults via links */
1327 for (i
= 0; i
< _nscd_cfg_num_link_default
; i
++) {
1329 if (_nscd_cfg_nsw_link_default
[i
].data
== NULL
)
1332 spc
= _nscd_cfg_nsw_link_default
[i
].data
;
1334 if (_nscd_cfg_nsw_link_default
[i
].db
!= dbni
) {
1335 for (j
= 0; j
< _nscd_cfg_num_nsw_db
; j
++) {
1337 if (strcmp(_nscd_cfg_nsw_db
[j
].name
,
1338 _nscd_cfg_nsw_link_default
[i
].db
) != 0)
1341 dbi
= _nscd_cfg_nsw_db
[j
].index
;
1342 dbni
= _nscd_cfg_nsw_db
[j
].name
;
1347 dest
= (char *)&nscd_cfg_nsw_db_data_current
[dbi
] +
1348 _nscd_cfg_nsw_link_default
[i
].group_off
+
1349 _nscd_cfg_nsw_link_default
[i
].param_off
;
1351 if (_nscd_cfg_nsw_db
[j
].name
!= dbnj
) {
1352 for (j
= 0; j
< _nscd_cfg_num_nsw_db
; j
++) {
1355 _nscd_cfg_nsw_db
[j
].name
) != 0)
1358 dbnj
= _nscd_cfg_nsw_db
[j
].name
;
1359 dbj
= _nscd_cfg_nsw_db
[j
].index
;
1364 src
= (char *)&nscd_cfg_nsw_db_data_current
[dbj
] +
1365 spc
->group_off
+ spc
->param_off
;
1366 datalen
= spc
->data_len
;
1368 (void) memcpy(dest
, src
, datalen
);
1371 /* fix up variable length fields */
1372 for (i
= 0; i
< _nscd_cfg_num_nsw_db
; i
++) {
1374 rc
= _nscd_cfg_set_vlen_data_int(
1375 &nscd_cfg_nsw_db_data_current
[i
],
1376 &nscd_cfg_nsw_db_data_current
[i
], nscd_false
);
1377 if (rc
!= NSCD_SUCCESS
)
1381 nscd_cfg_nsw_alldb_rwlock
= calloc(1, sizeof (rwlock_t
));
1382 if (nscd_cfg_nsw_alldb_rwlock
== NULL
)
1383 return (NSCD_NO_MEMORY
);
1385 (void) rwlock_init(nscd_cfg_nsw_alldb_rwlock
, NULL
, NULL
);
1387 rc
= _nscd_cfg_set_vlen_data_int(
1388 &nscd_cfg_nsw_db_data_default
,
1389 nscd_cfg_nsw_alldb_current
, nscd_false
);
1390 if (rc
!= NSCD_SUCCESS
)
1394 * notify and send the configuration data to
1395 * the nscd components
1397 rc
= _nscd_cfg_notify_init(errorp
);
1398 if (rc
!= NSCD_SUCCESS
)
1401 return (NSCD_SUCCESS
);
1405 _nscd_cfg_get_handle_common(
1406 nscd_cfg_list_type_t type
,
1409 nscd_cfg_handle_t
**handle
,
1410 nscd_cfg_error_t
**errorp
)
1415 nscd_cfg_handle_t
*h
;
1416 nscd_cfg_param_desc_t
*pdesc
;
1417 nscd_cfg_stat_desc_t
*sdesc
;
1418 char *me
= "_nscd_cfg_get_handle_common";
1419 char msg
[NSCD_CFG_MAX_ERR_MSG_LEN
];
1420 nscd_rc_t rc
= NSCD_INVALID_ARGUMENT
;
1422 if (handle
== NULL
) {
1424 (void) snprintf(msg
, sizeof (msg
),
1425 gettext("address of handle not specified"));
1427 *errorp
= _nscd_cfg_make_error(rc
, msg
);
1429 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_DEBUG
)
1430 (me
, "invalid argument: %s\n", msg
);
1439 (void) snprintf(msg
, sizeof (msg
),
1440 gettext("name not specified"));
1442 *errorp
= _nscd_cfg_make_error(rc
, msg
);
1444 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_DEBUG
)
1445 (me
, "invalid argument: %s\n");
1450 h
= calloc(1, sizeof (nscd_cfg_handle_t
));
1452 return (NSCD_NO_MEMORY
);
1455 if (type
== NSCD_CFG_LIST_PARAM
)
1456 desc_str
= gettext("configuration parameter");
1458 desc_str
= gettext("statistics");
1460 /* get param or stat descriptor */
1461 i
= _nscd_cfg_get_index(name
, type
);
1464 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_DEBUG
)
1465 (me
, "%s: index of %s is %d\n", desc_str
, name
, i
);
1467 if (type
== NSCD_CFG_LIST_PARAM
) {
1468 pdesc
= &_nscd_cfg_param_desc
[i
];
1469 (void) memcpy(&h
->desc
, &pdesc
, sizeof (pdesc
));
1470 is_global
= _nscd_cfg_flag_is_set(
1471 pdesc
->pflag
, NSCD_CFG_PFLAG_GLOBAL
);
1473 /* hidden params are not exposed */
1474 if (_nscd_cfg_flag_is_set(
1475 pdesc
->pflag
, NSCD_CFG_PFLAG_HIDDEN
))
1478 if (_nscd_cfg_flag_is_set(pdesc
->pflag
,
1479 NSCD_CFG_PFLAG_OBSOLETE
)) {
1480 _NSCD_LOG(NSCD_LOG_CONFIG
,
1481 NSCD_LOG_LEVEL_WARNING
)
1482 (me
, gettext("%s: %s is obsolete and "
1483 "will be ignored\n"),
1487 sdesc
= &_nscd_cfg_stat_desc
[i
];
1488 (void) memcpy(&h
->desc
, &sdesc
, sizeof (sdesc
));
1489 is_global
= _nscd_cfg_flag_is_set(
1490 sdesc
->sflag
, NSCD_CFG_SFLAG_GLOBAL
);
1496 (void) snprintf(msg
, sizeof (msg
),
1497 gettext("%s: unknown name \"%s\""), desc_str
, name
);
1499 *errorp
= _nscd_cfg_make_error(rc
, msg
);
1501 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
1509 * if the param/stat is not a global one, we need to
1510 * know which nsswitch database we are dealing with
1512 if (is_global
== 0) {
1513 if (nswdb_name
== NULL
) {
1515 (void) snprintf(msg
, sizeof (msg
),
1516 gettext("%s: switch database name not specified"),
1519 *errorp
= _nscd_cfg_make_error(rc
, msg
);
1521 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
1522 (me
, "%s for non-global param or stat %s\n",
1530 if (nswdb_name
!= NULL
) {
1532 (void) snprintf(msg
, sizeof (msg
),
1533 gettext("%s: switch database specified for "
1534 "global data"), desc_str
);
1536 *errorp
= _nscd_cfg_make_error(rc
, msg
);
1538 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
1539 (me
, "%s %s\n", msg
, name
);
1546 return (NSCD_SUCCESS
);
1550 i
= _nscd_cfg_get_index(nswdb_name
, NSCD_CFG_LIST_NSW_DB
);
1553 if (i
== NSCD_CFG_NSW_ALLDB_INDEX
)
1554 h
->nswdb
= &_nscd_cfg_nsw_alldb
;
1556 h
->nswdb
= &_nscd_cfg_nsw_db
[i
];
1558 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_DEBUG
)
1559 (me
, "%s: index of %s is %d\n",
1560 desc_str
, nswdb_name
, i
);
1563 (void) snprintf(msg
, sizeof (msg
),
1564 gettext("%s: unknown switch database name \"%s\""),
1565 desc_str
, nswdb_name
);
1567 *errorp
= _nscd_cfg_make_error(rc
, msg
);
1569 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
1573 return (NSCD_CFG_UNSUPPORTED_SWITCH_DB
);
1578 return (NSCD_SUCCESS
);
1582 _nscd_cfg_get_handle(
1585 nscd_cfg_handle_t
**handle
,
1586 nscd_cfg_error_t
**errorp
)
1589 return (_nscd_cfg_get_handle_common(NSCD_CFG_LIST_PARAM
,
1590 param_name
, nswdb_name
, handle
, errorp
));
1594 _nscd_cfg_get_stat_handle(
1597 nscd_cfg_handle_t
**handle
,
1598 nscd_cfg_error_t
**errorp
)
1601 return (_nscd_cfg_get_handle_common(NSCD_CFG_LIST_STAT
,
1602 stat_name
, nswdb_name
, handle
, errorp
));
1606 _nscd_cfg_free_handle(
1607 nscd_cfg_handle_t
*handle
)
1615 _nscd_cfg_free_vlen_data_group(
1616 nscd_cfg_param_desc_t
*gdesc
,
1622 nscd_cfg_param_desc_t
*desc
;
1626 num
= ((nscd_cfg_group_info_t
*)group_data
)->num_param
;
1632 /* skip fixed length data */
1633 if (_nscd_cfg_flag_is_not_set(desc
->pflag
,
1634 NSCD_CFG_PFLAG_VLEN_DATA
))
1637 dest
= (char *)group_data
+ desc
->p_offset
;
1638 ptr
= *(char **)dest
;
1641 if (in
== nscd_true
)
1642 _nscd_cfg_free_vlen_data_int(ptr
);
1649 _nscd_cfg_free_param_data(
1660 _nscd_cfg_free_group_data(
1661 nscd_cfg_handle_t
*handle
,
1665 nscd_cfg_param_desc_t
*desc
;
1666 nscd_cfg_group_info_t
*gi
;
1668 if (handle
== NULL
|| data
== NULL
)
1671 desc
= _nscd_cfg_get_desc(handle
);
1672 gi
= (nscd_cfg_group_info_t
*)data
;
1673 if (desc
->p_fn
!= gi
->num_param
)
1676 _nscd_cfg_free_vlen_data_group(desc
, data
, nscd_false
);
1682 _nscd_cfg_free_error(
1683 nscd_cfg_error_t
*error
)
1693 _nscd_cfg_copy_param_data(
1694 nscd_cfg_param_desc_t
*desc
,
1698 nscd_bool_t set_addr
)
1701 char *me
= "_nscd_cfg_copy_param_data";
1704 nscd_rc_t rc
= NSCD_SUCCESS
;
1706 if (desc
== NULL
|| dest
== NULL
) {
1707 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
1708 (me
, "input desc == %p, dest == %p\n", desc
, dest
);
1709 return (NSCD_INVALID_ARGUMENT
);
1712 /* fixed length data */
1713 if (_nscd_cfg_flag_is_not_set(desc
->pflag
,
1714 NSCD_CFG_PFLAG_VLEN_DATA
)) {
1715 (void) memcpy(dest
, pdata
, desc
->p_size
);
1720 /* variable length data from this point on */
1722 /* make a copy of the variable length data */
1723 rc
= _nscd_cfg_copy_vlen_data(pdata
, &tmp
, desc
, &dlen
, in
);
1724 if (rc
!= NSCD_SUCCESS
)
1727 if (in
== nscd_true
) { /* data to internal */
1729 /* free the variable length data in the config store */
1730 if (*(char **)dest
!= NULL
)
1731 _nscd_cfg_free_vlen_data_int(*(char **)dest
);
1734 if (set_addr
== nscd_true
) {
1736 * set the addr of the vlen data
1738 *(char **)dest
= tmp
;
1741 * copy the data content (not address)
1743 (void) memcpy(dest
, tmp
, dlen
);
1752 _nscd_cfg_copy_group_data_in(
1753 nscd_cfg_param_desc_t
*gdesc
,
1754 nscd_cfg_group_info_t
*gi
,
1759 nscd_cfg_param_desc_t
*desc
;
1763 num
= gi
->num_param
;
1770 /* if member not selected by bitmap, skip */
1771 if (_nscd_cfg_bitmap_is_not_set(gi
->bitmap
, i
++))
1774 src
= (char *)group_src
+ desc
->p_offset
;
1775 dest
= (char *)group_dest
+ desc
->p_offset
;
1778 * if variable length data, free and replace the old
1781 if (_nscd_cfg_flag_is_set(desc
->pflag
,
1782 NSCD_CFG_PFLAG_VLEN_DATA
)) {
1783 _nscd_cfg_free_vlen_data_int(*(char **)dest
);
1784 *(char **)dest
= *(char **)src
;
1785 *(char **)src
= NULL
;
1788 * fixed length data, just copy it
1790 (void) memcpy(dest
, src
, desc
->p_size
);
1794 return (NSCD_SUCCESS
);
1798 _nscd_cfg_copy_group_data_out(
1799 nscd_cfg_param_desc_t
*gdesc
,
1804 char *me
= "_nscd_cfg_copy_group_data_out";
1808 nscd_cfg_group_info_t
*gi
;
1809 nscd_rc_t rc
= NSCD_SUCCESS
;
1810 nscd_cfg_param_desc_t
*desc
;
1812 if (group_dest
== NULL
) {
1813 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
1814 (me
, "input group_dest = NULL\n");
1815 return (NSCD_INVALID_ARGUMENT
);
1818 gi
= _nscd_cfg_get_gi(group_src
);
1819 num
= gi
->num_param
;
1826 dest
= (char *)group_dest
+ desc
->p_offset
;
1827 src
= (char *)group_src
+ desc
->p_offset
;
1830 * if variable length data, get the real
1831 * address and length of the data
1833 if (_nscd_cfg_flag_is_set(desc
->pflag
,
1834 NSCD_CFG_PFLAG_VLEN_DATA
)) {
1835 src
= _nscd_cfg_locate_vlen_data(src
, &dlen
);
1841 * The nscd_true asks _nscd_cfg_copy_param_data
1842 * to set addr of the vlen data in 'dest' rather
1843 * than copying the data content
1845 rc
= _nscd_cfg_copy_param_data(desc
, dest
, src
,
1846 nscd_false
, nscd_true
);
1847 if (rc
!= NSCD_SUCCESS
) {
1848 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
1849 (me
, "unable to copy param data for %s\n",
1852 _nscd_cfg_free_vlen_data_group(gdesc
,
1853 group_dest
, nscd_false
);
1864 (void) memcpy(group_dest
, group_src
,
1865 sizeof (nscd_cfg_group_info_t
));
1872 * group_cfg is needed always; group_src may be NULL if
1873 * param_index not zero and pdata not NULL; group_cfg and
1874 * pdata should not be both non-NULL
1877 _nscd_cfg_copy_group_data_merge(
1878 nscd_cfg_param_desc_t
*gdesc
,
1886 char *me
= "_nscd_cfg_copy_group_data_merge";
1887 void *src
, *dest
, *tmp_dest
= NULL
;
1889 nscd_cfg_group_info_t
*gi
;
1890 nscd_rc_t rc
= NSCD_SUCCESS
;
1891 nscd_cfg_param_desc_t
*desc
;
1892 nscd_cfg_bitmap_t bitmap
;
1894 if (group_dest
== NULL
) {
1895 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
1896 (me
, "input **group_dest == NULL\n");
1897 return (NSCD_INVALID_ARGUMENT
);
1900 if (group_cfg
== NULL
) {
1901 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
1902 (me
, "input **group_cfg == NULL\n");
1903 return (NSCD_INVALID_ARGUMENT
);
1906 if (param_index
!= NULL
&& pdata
== NULL
) {
1907 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
1908 (me
, "param_index != NULL but pdata == %p\n", pdata
);
1909 return (NSCD_INVALID_ARGUMENT
);
1912 tmp_dest
= calloc(1, gdesc
->g_size
);
1913 if (tmp_dest
== NULL
)
1914 return (NSCD_NO_MEMORY
);
1916 if (group_src
!= NULL
)
1917 gi
= _nscd_cfg_get_gi(group_src
);
1919 gi
= _nscd_cfg_get_gi(group_cfg
);
1920 bitmap
= NSCD_CFG_BITMAP_ZERO
;
1923 num
= gi
->num_param
;
1930 dest
= (char *)tmp_dest
+ desc
->p_offset
;
1933 * if member not selected by bitmap in group_src,
1934 * get the member data in group_cfg
1936 if (_nscd_cfg_bitmap_is_not_set(gi
->bitmap
, i
++) ||
1937 group_src
== NULL
) {
1938 src
= (char *)group_cfg
+ desc
->p_offset
;
1940 src
= (char *)group_src
+ desc
->p_offset
;
1942 if (desc
->id
.index
== param_index
) {
1944 /* use the param data in pdata if provided */
1946 _nscd_cfg_bitmap_set_nth(bitmap
, i
);
1950 * if variable length data, get to the data
1951 * instead of pointer to the data
1953 if (_nscd_cfg_flag_is_set(desc
->pflag
,
1954 NSCD_CFG_PFLAG_VLEN_DATA
))
1955 src
= *(char **)src
;
1958 * nscd_true asks _nscd_cfg_copy_param_data to
1959 * set addr of the vlen data in 'dest' rather
1960 * than copying the data content
1962 rc
= _nscd_cfg_copy_param_data(desc
, dest
, src
,
1963 nscd_true
, nscd_true
);
1964 if (rc
!= NSCD_SUCCESS
) {
1965 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
1966 (me
, "unable to copy param data for %s\n",
1969 _nscd_cfg_free_vlen_data_group(gdesc
,
1970 tmp_dest
, nscd_true
);
1978 *group_dest
= tmp_dest
;
1981 * set bitmap: if input is group data, use the one
1982 * given; if input is param data, use the one computed
1985 if (group_src
!= NULL
)
1986 (void) memcpy(*group_dest
, group_src
,
1987 sizeof (nscd_cfg_group_info_t
));
1989 gi
= _nscd_cfg_get_gi(*group_dest
);
1990 _nscd_cfg_bitmap_set(&gi
->bitmap
, bitmap
);
1999 nscd_cfg_handle_t
*handle
,
2002 nscd_cfg_error_t
**errorp
)
2004 char *me
= "_nscd_cfg_get";
2006 nscd_rc_t rc
= NSCD_SUCCESS
;
2007 nscd_cfg_id_t
*nswdb
;
2008 nscd_cfg_param_desc_t
*desc
;
2009 void *cfg_data
, *ptr
= NULL
;
2010 nscd_bool_t get_group
= nscd_false
;
2011 nscd_bool_t out
= nscd_false
;
2012 nscd_cfg_lock_t
*lock
= NULL
;
2014 if (data_len
!= NULL
)
2018 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
2019 (me
, "input data = %p\n", data
);
2020 return (NSCD_INVALID_ARGUMENT
);
2025 if (handle
== NULL
) {
2026 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
2027 (me
, "handle is NULL\n");
2028 return (NSCD_INVALID_ARGUMENT
);
2031 nswdb
= handle
->nswdb
;
2032 desc
= (nscd_cfg_param_desc_t
*)handle
->desc
;
2034 if (_nscd_cfg_flag_is_set(desc
->pflag
, NSCD_CFG_PFLAG_GROUP
))
2035 get_group
= nscd_true
;
2038 * locate the current value of the param or group
2039 * and lock the config data for reading
2041 rc
= _nscd_cfg_locate_cfg_data(&cfg_data
, nscd_true
, desc
,
2042 nswdb
, get_group
, NULL
, &dlen
, &lock
);
2043 if (rc
!= NSCD_SUCCESS
) {
2045 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
2046 (me
, "unable to locate config data\n");
2049 } else if (cfg_data
== NULL
) /* NULL vlen data */
2052 ptr
= calloc(1, dlen
);
2054 rc
= NSCD_NO_MEMORY
;
2058 if (get_group
== nscd_true
) {
2060 rc
= _nscd_cfg_copy_group_data_out(desc
, ptr
, cfg_data
);
2061 if (rc
!= NSCD_SUCCESS
) {
2062 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
2063 (me
, "unable to copy group data %p: "
2064 "error = %d\n", cfg_data
, rc
);
2070 * nscd_false asks _nscd_cfg_copy_param_data to
2071 * copy the data content rather than just setting
2072 * the addr of the vlen data in 'ptr'
2074 rc
= _nscd_cfg_copy_param_data(desc
, ptr
, cfg_data
,
2077 if (rc
!= NSCD_SUCCESS
) {
2078 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
2079 (me
, "unable to copy param data %p: "
2080 "error = %d\n", cfg_data
, rc
);
2090 if (data_len
!= NULL
)
2093 _nscd_cfg_unlock(lock
);
2095 return (NSCD_SUCCESS
);
2099 _nscd_cfg_unlock(lock
);
2107 * three type of data:
2109 * desc is that of the param
2110 * 2 - single param to be sent in a group
2111 * a single bit is set in the bitmap,
2112 * desc is that of the group
2114 * one of more bits are set in the bitmap,
2115 * desc is that of the group
2119 nscd_cfg_param_desc_t
*desc
,
2120 nscd_cfg_id_t
*nswdb
,
2122 nscd_cfg_error_t
**errorp
)
2124 int i
, num
, is_group
= 0;
2125 void *cookie
= NULL
;
2128 nscd_cfg_flag_t dflag
, dflag1
;
2129 nscd_cfg_bitmap_t bitmap_s
, bitmap_in
, *bitmap_addr
= NULL
;
2130 nscd_cfg_group_info_t
*gi
;
2136 * Set data flag going with data to be sent to the
2137 * verify/notify routines. To allow the config flag
2138 * be exipandable, set the bits one by one.
2140 dflag
= NSCD_CFG_FLAG_ZERO
;
2141 dflag
= _nscd_cfg_flag_set(dflag
, NSCD_CFG_DFLAG_STATIC_DATA
);
2142 if (_nscd_cfg_flag_is_set(desc
->pflag
, NSCD_CFG_PFLAG_GROUP
)) {
2143 dflag
= _nscd_cfg_flag_set(dflag
, NSCD_CFG_DFLAG_GROUP
);
2146 if (nswdb
!= NULL
&&
2147 strcmp(NSCD_CFG_NSW_ALLDB
, nswdb
->name
) == 0)
2148 dflag
= _nscd_cfg_flag_set(dflag
,
2149 NSCD_CFG_DFLAG_SET_ALL_DB
);
2152 * the bitmap in the input data may be replaced before
2153 * sending to the components, so save the bitmap for
2156 if (is_group
== 1) {
2157 gi
= _nscd_cfg_get_gi(data
);
2158 bitmap_in
= gi
->bitmap
;
2159 bitmap_addr
= &(gi
->bitmap
);
2161 if (_nscd_cfg_flag_is_set(desc
->pflag
,
2162 NSCD_CFG_PFLAG_INIT_SEND_WHOLE_GROUP
))
2163 /* send the entire group just once */
2166 else { /* send individual members one by one */
2171 * skip the first desc which is for the group
2172 * and get to the desc for the first member
2176 dflag
= _nscd_cfg_flag_unset(dflag
,
2177 NSCD_CFG_DFLAG_GROUP
);
2180 /* not group data, send the member once */
2185 for (i
= 0; i
< num
; i
++, desc
++) {
2189 if (is_group
== 0) {
2194 if (_nscd_cfg_flag_is_set(desc
->pflag
,
2195 NSCD_CFG_PFLAG_SEND_BIT_SELECTED
)) {
2197 /* set the bitmap to select just this member */
2198 bitmap_s
= NSCD_CFG_BITMAP_ZERO
;
2199 _nscd_cfg_bitmap_set_nth(bitmap_s
, i
);
2200 /* replace the bitmap in the input data */
2201 _nscd_cfg_bitmap_set(bitmap_addr
, bitmap_s
);
2204 * send the whole group but with only one
2209 dflag
= _nscd_cfg_flag_set(dflag
,
2210 NSCD_CFG_DFLAG_GROUP
);
2211 dflag
= _nscd_cfg_flag_set(dflag
,
2212 NSCD_CFG_DFLAG_BIT_SELECTED
);
2215 * send param data or group data:
2216 * param data - non-xero desc->p_offset
2217 * group data - zero desc->p_offset
2219 cdata
= (char *)data
+ desc
->p_offset
;
2222 * if variable length data, need to send pointer
2223 * to the data (not the address of the pointer)
2225 if (_nscd_cfg_flag_is_set(desc
->pflag
,
2226 NSCD_CFG_PFLAG_VLEN_DATA
))
2227 cdata
= *(char **)cdata
;
2232 if (desc
->verify
!= NULL
) {
2233 dflag
= _nscd_cfg_flag_set(dflag
,
2234 NSCD_CFG_DFLAG_VERIFY
);
2235 rc
= desc
->verify(cdata
, desc
, nswdb
,
2236 dflag
, errorp
, &cookie
);
2237 if (rc
!= NSCD_SUCCESS
)
2241 if (desc
->notify
!= NULL
) {
2242 dflag
= _nscd_cfg_flag_set(dflag
,
2243 NSCD_CFG_DFLAG_NOTIFY
);
2245 rc
= desc
->notify(data
, desc
, nswdb
,
2246 dflag
, errorp
, cookie
);
2247 if (rc
!= NSCD_SUCCESS
)
2256 /* restore the bitmap in the input data */
2257 if (bitmap_addr
!= NULL
)
2258 _nscd_cfg_bitmap_set(bitmap_addr
, bitmap_in
);
2264 * Convert string 'str' to data based on the data type in 'desc'.
2265 * 'data' points to the buffer in which the converted data
2266 * is placed. '*data_p' points to the buffer, or in the case
2267 * of a string data type, points to the untoched string (i.e.,
2271 _nscd_cfg_str_to_data(
2272 nscd_cfg_param_desc_t
*desc
,
2276 nscd_cfg_error_t
**errorp
)
2279 char *me
= "_nscd_cfg_str_to_data";
2281 nscd_cfg_bitmap_t bitmap
;
2282 char msg
[NSCD_CFG_MAX_ERR_MSG_LEN
];
2283 nscd_rc_t rc
= NSCD_CFG_DATA_CONVERSION_FAILED
;
2285 if (desc
== NULL
|| str
== NULL
|| data
== NULL
) {
2286 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
2287 (me
, "ERROR: one of the following is NULL "
2288 "desc = %p, str = %p, data = %p, data_p = %p\n",
2289 desc
, str
, data
, data_p
);
2291 return (NSCD_INVALID_ARGUMENT
);
2295 /* if description is that of a group, return error */
2296 if (_nscd_cfg_flag_is_set(desc
->pflag
, NSCD_CFG_PFLAG_GROUP
)) {
2298 (void) snprintf(msg
, sizeof (msg
),
2299 gettext("single data specified for group %s"), desc
->id
.name
);
2302 *errorp
= _nscd_cfg_make_error(NSCD_INVALID_ARGUMENT
,
2305 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
2306 (me
, "ERROR: %s)\n", msg
);
2308 return (NSCD_INVALID_ARGUMENT
);
2312 if (desc
->type
== NSCD_CFG_DATA_STRING
) {
2313 if (strcmp(str
, NSCD_NULL
) == 0)
2314 *(char **)data_p
= NULL
;
2316 /* remove the " char if quoted string */
2317 if (str
[0] == '"') {
2318 c
= str
+ strlen(str
) - 1;
2321 *(char **)data_p
= str
+ 1;
2323 *(char **)data_p
= str
;
2326 return (NSCD_SUCCESS
);
2331 (void) snprintf(msg
, sizeof (msg
),
2332 gettext("data must be specified for %s"), desc
->id
.name
);
2335 *errorp
= _nscd_cfg_make_error(NSCD_INVALID_ARGUMENT
,
2338 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
2339 (me
, "ERROR: %s\n", msg
);
2341 return (NSCD_INVALID_ARGUMENT
);
2345 switch (desc
->type
) {
2347 case NSCD_CFG_DATA_BOOLEAN
:
2349 if (strcasecmp(str
, "yes") == 0)
2350 *(nscd_bool_t
*)data
= nscd_true
;
2351 else if (strcasecmp(str
, "no") == 0)
2352 *(nscd_bool_t
*)data
= nscd_false
;
2355 (void) snprintf(msg
, sizeof (msg
),
2356 gettext("data (%s) must be 'yes' or 'no' for %s"),
2357 str
, desc
->id
.name
);
2360 *errorp
= _nscd_cfg_make_error(NSCD_INVALID_ARGUMENT
,
2363 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
2364 (me
, "ERROR: %s\n", msg
);
2366 return (NSCD_INVALID_ARGUMENT
);
2371 case NSCD_CFG_DATA_INTEGER
:
2374 *(int *)data
= (int)strtol(str
, (char **)NULL
, 10);
2375 if (errno
!= NULL
) {
2377 (void) snprintf(msg
, sizeof (msg
),
2378 gettext("unable to convert data (%s) for %s"),
2379 str
, desc
->id
.name
);
2382 *errorp
= _nscd_cfg_make_error(rc
, msg
);
2384 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
2385 (me
, "ERROR: %s\n", msg
);
2392 case NSCD_CFG_DATA_BITMAP
:
2395 bitmap
= (nscd_cfg_bitmap_t
)strtol(str
, (char **)NULL
, 10);
2396 if (errno
!= NULL
) {
2398 (void) snprintf(msg
, sizeof (msg
),
2399 gettext("unable to convert data (%s) for %s"),
2400 str
, desc
->id
.name
);
2403 *errorp
= _nscd_cfg_make_error(rc
, msg
);
2405 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
2406 (me
, "ERROR: %s\n", msg
);
2411 _nscd_cfg_bitmap_set(data
, bitmap
);
2417 return (NSCD_SUCCESS
);
2423 nscd_cfg_handle_t
*handle
,
2425 nscd_cfg_error_t
**errorp
)
2427 char *me
= "_nscd_cfg_set";
2429 nscd_cfg_id_t
*nswdb
;
2430 nscd_cfg_param_desc_t
*desc
, *gdesc
;
2431 nscd_cfg_group_info_t
*gi
;
2432 char *nswdb_name
, *param_name
;
2434 void *cfg_data
, *vdata_addr
= NULL
;
2435 nscd_bool_t get_group
= 0;
2436 nscd_bool_t in
= nscd_true
;
2437 nscd_cfg_lock_t
*lock
= NULL
;
2438 nscd_rc_t rc
= NSCD_SUCCESS
;
2440 if (handle
== NULL
) {
2441 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
2442 (me
, "handle is NULL\n");
2443 return (NSCD_INVALID_ARGUMENT
);
2446 nswdb
= handle
->nswdb
;
2447 desc
= (nscd_cfg_param_desc_t
*)handle
->desc
;
2449 nswdb_name
= "global";
2451 nswdb_name
= nswdb
->name
;
2452 param_name
= desc
->id
.name
;
2454 if (data
== NULL
&& _nscd_cfg_flag_is_not_set(desc
->pflag
,
2455 NSCD_CFG_PFLAG_VLEN_DATA
)) {
2456 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
2457 (me
, "data == NULL\n");
2458 return (NSCD_INVALID_ARGUMENT
);
2461 if (_nscd_cfg_flag_is_set(desc
->pflag
,
2462 NSCD_CFG_PFLAG_UPDATE_SEND_WHOLE_GROUP
) ||
2463 _nscd_cfg_flag_is_set(desc
->pflag
, NSCD_CFG_PFLAG_GROUP
))
2464 get_group
= nscd_true
;
2467 * locate the current value of the param or group
2468 * and lock the config data for writing
2470 rc
= _nscd_cfg_locate_cfg_data(&cfg_data
, nscd_false
, desc
,
2471 nswdb
, get_group
, &vdata_addr
, &dlen
, &lock
);
2472 if (rc
!= NSCD_SUCCESS
) {
2473 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
2474 (me
, "unable to locate config data (rc = %d)\n", rc
);
2478 if (_nscd_cfg_flag_is_set(desc
->pflag
, NSCD_CFG_PFLAG_GROUP
) &&
2479 ((nscd_cfg_group_info_t
*)cfg_data
)->num_param
!=
2480 ((nscd_cfg_group_info_t
*)data
)->num_param
) {
2482 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
2483 (me
, "number of parameters in group <%s : %s> not equal: "
2484 "%d in input data, should be %d\n",
2485 NSCD_STR_OR_GLOBAL(nswdb_name
),
2486 NSCD_STR_OR_NULL(param_name
),
2487 ((nscd_cfg_group_info_t
*)data
)->num_param
,
2488 ((nscd_cfg_group_info_t
*)cfg_data
)->num_param
);
2490 rc
= NSCD_INVALID_ARGUMENT
;
2495 * if variable length data, we want the address
2496 * of the pointer pointing to the data
2498 if (vdata_addr
!= NULL
)
2499 cfg_data
= vdata_addr
;
2502 * just copy in the specified data, if no need
2503 * to verify the data or notify the associated
2506 if (get_group
== nscd_true
) {
2508 gdesc
= &_nscd_cfg_param_desc
[desc
->g_index
];
2510 rc
= _nscd_cfg_copy_group_data_merge(
2511 gdesc
, &pdata
, data
, cfg_data
,
2512 desc
->id
.index
, data
);
2514 if (rc
!= NSCD_SUCCESS
) {
2515 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
2516 (me
, "unable to copy group data <%s : %s>\n",
2517 NSCD_STR_OR_GLOBAL(nswdb_name
),
2518 NSCD_STR_OR_NULL(param_name
));
2523 rc
= _nscd_cfg_notify_s(gdesc
, nswdb
,
2527 rc
= _nscd_cfg_notify_s(desc
, nswdb
, data
,
2530 if (rc
!= NSCD_SUCCESS
) {
2532 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
2533 (me
, "verifying/notifying of new configuration "
2534 "parameter <%s : %s> failed. %s\n",
2535 NSCD_STR_OR_GLOBAL(nswdb_name
),
2536 param_name
, (*errorp
&& (*errorp
)->msg
) ?
2537 (*errorp
)->msg
: "");
2543 * Move the new config into the config store
2545 rc
= NSCD_CFG_SET_PARAM_FAILED
;
2546 if (_nscd_cfg_flag_is_set(desc
->pflag
,
2547 NSCD_CFG_PFLAG_GROUP
)) {
2548 gi
= _nscd_cfg_get_gi(pdata
);
2549 rc
= _nscd_cfg_copy_group_data_in(gdesc
, gi
,
2553 * nscd_true asks _nscd_cfg_copy_param_data to
2554 * set addr of the vlen data in 'cfg_data' rather
2555 * than copying the data content
2558 _nscd_cfg_free_vlen_data_group(gdesc
,
2561 rc
= _nscd_cfg_copy_param_data(desc
,
2562 cfg_data
, data
, in
, nscd_true
);
2565 if (rc
!= NSCD_SUCCESS
) {
2567 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
2568 (me
, "unable to make new param data <%s : %s> current\n",
2569 NSCD_STR_OR_GLOBAL(nswdb_name
),
2570 NSCD_STR_OR_NULL(param_name
));
2575 _nscd_cfg_unlock(lock
);
2581 _nscd_cfg_set_linked(
2582 nscd_cfg_handle_t
*handle
,
2584 nscd_cfg_error_t
**errorp
)
2586 char *me
= "_nscd_cfg_set_linked";
2587 nscd_cfg_id_t
*nswdb
;
2588 nscd_cfg_handle_t
*hl
;
2589 nscd_cfg_param_desc_t
*desc
;
2590 char *nswdb_name
, *param_name
, *dbl
;
2591 nscd_rc_t rc
= NSCD_SUCCESS
;
2592 nscd_cfg_nsw_spc_default_t
*spc
;
2594 char msg
[NSCD_CFG_MAX_ERR_MSG_LEN
];
2596 if (handle
== NULL
) {
2597 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
2598 (me
, "handle is NULL\n");
2599 return (NSCD_INVALID_ARGUMENT
);
2602 nswdb
= handle
->nswdb
;
2603 desc
= (nscd_cfg_param_desc_t
*)handle
->desc
;
2606 * no need to do the special linking thing,
2607 * if a global param, or a group, or not a linked param
2609 if (nswdb
== NULL
|| _nscd_cfg_flag_is_set(desc
->pflag
,
2610 NSCD_CFG_PFLAG_GROUP
) ||
2611 _nscd_cfg_flag_is_not_set(desc
->pflag
,
2612 NSCD_CFG_PFLAG_LINKED
))
2613 return (_nscd_cfg_set(handle
, data
, errorp
));
2615 nswdb_name
= nswdb
->name
;
2616 param_name
= desc
->id
.name
;
2619 * if a param is linked to another, it can not be
2622 for (i
= 0; i
< _nscd_cfg_num_link_default
; i
++) {
2624 if (_nscd_cfg_nsw_link_default
[i
].data
== NULL
)
2627 if (strcmp(_nscd_cfg_nsw_link_default
[i
].db
,
2629 _nscd_cfg_nsw_link_default
[i
].group_off
==
2631 _nscd_cfg_nsw_link_default
[i
].param_off
==
2634 rc
= NSCD_CFG_READ_ONLY
;
2636 (void) snprintf(msg
, sizeof (msg
),
2637 gettext("value of \'%s\' not changeable, "
2638 "change that of \'%s\' instead"),
2639 nswdb
->name
, "passwd");
2642 *errorp
= _nscd_cfg_make_error(rc
, msg
);
2644 _NSCD_LOG(NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_ERROR
)
2645 (me
, "ERROR: %s\n", msg
);
2652 * if a param is linked from another, it should be verify
2655 for (i
= 0; i
< _nscd_cfg_num_link_default
; i
++) {
2657 if (_nscd_cfg_nsw_link_default
[i
].data
== NULL
)
2660 spc
= _nscd_cfg_nsw_link_default
[i
].data
;
2662 if (strcmp(spc
->db
, nswdb_name
) == 0 &&
2663 spc
->group_off
== desc
->g_offset
&&
2664 spc
->param_off
== desc
->p_offset
) {
2666 rc
= _nscd_cfg_set(handle
, data
, errorp
);
2667 if (rc
!= NSCD_SUCCESS
)
2674 * then change all those linked to the one that has been changed
2676 for (i
= 0; i
< _nscd_cfg_num_link_default
; i
++) {
2678 if (_nscd_cfg_nsw_link_default
[i
].data
== NULL
)
2681 spc
= _nscd_cfg_nsw_link_default
[i
].data
;
2683 if (strcmp(spc
->db
, nswdb_name
) == 0 &&
2684 spc
->group_off
== desc
->g_offset
&&
2685 spc
->param_off
== desc
->p_offset
&&
2686 _nscd_cfg_nsw_link_default
[i
].group_off
==
2688 _nscd_cfg_nsw_link_default
[i
].param_off
==
2691 dbl
= _nscd_cfg_nsw_link_default
[i
].db
;
2693 rc
= _nscd_cfg_get_handle(param_name
, dbl
,
2695 if (rc
!= NSCD_SUCCESS
)
2697 rc
= _nscd_cfg_set(hl
, data
, errorp
);
2698 _nscd_cfg_free_handle(hl
);
2699 if (rc
!= NSCD_SUCCESS
)
2704 return (_nscd_cfg_set(handle
, data
, errorp
));
2708 * Return a list of comma-separated database names that
2709 * have at least one of the input sources (the srcs array)
2710 * appears in their configured nsswitch policy string.
2711 * That is, if srcs contains "ldap" and "passwd: files ldap"
2712 * "group: files ldap" are in /etc/nsswitch.conf, then
2713 * "passwd,group" will be returned. The return string
2714 * should be freed by the caller.
2716 * For compat nsswitch configuration, "group" and/or
2717 * "passwd,user_attr,shadow,audit_user" (not "group_compat"
2718 * or "passwd_compat") will be returned. Note that the
2719 * user_attr, shadow, and audit_user databases share the
2720 * same policy with the passwd database.
2722 * For example, if srcs has "ldap" and in /etc/nsswitch.conf,
2725 * passwd_compat: ldap
2727 * group_compat: ldap
2729 * then "netgroup,passwd,group,user_attr,shadow,audit_user"
2733 _nscd_srcs_in_db_nsw_policy(
2737 uint8_t i
, j
, n
= 0, nc
= 0;
2738 uint8_t compat_grp
= 0, compat_pwd
= 0;
2742 nscd_cfg_nsw_db_data_t
*dbcfg
;
2743 nscd_cfg_switch_t
*sw
;
2744 char *outstr
= NULL
;
2747 db
= (uint8_t *)calloc(_nscd_cfg_num_nsw_db
, sizeof (uint8_t));
2751 db_compat
= (uint8_t *)calloc(_nscd_cfg_num_nsw_db
,
2753 if (db_compat
== NULL
) {
2758 for (i
= 0; i
< _nscd_cfg_num_nsw_db
; i
++) {
2760 (void) rw_rdlock(&nscd_cfg_nsw_db_data_rwlock
[i
]);
2762 dbcfg
= &nscd_cfg_nsw_db_data_current
[i
];
2764 if (sw
->nsw_config_string
== NULL
) {
2765 (void) rw_unlock(&nscd_cfg_nsw_db_data_rwlock
[i
]);
2769 dbname
= _nscd_cfg_nsw_db
[i
].name
;
2770 for (j
= 0; j
< num_src
; j
++) {
2771 if (strstr(sw
->nsw_config_string
, srcs
[j
]) !=
2774 dlen
+= strlen(dbname
) + 1;
2775 } else if (strcmp(sw
->nsw_config_string
,
2777 if (strcmp(dbname
, "passwd") == 0) {
2780 } else if (strcmp(dbname
, "group") == 0) {
2784 db_compat
[nc
++] = i
;
2785 dlen
+= strlen(dbname
) + 1;
2790 (void) rw_unlock(&nscd_cfg_nsw_db_data_rwlock
[i
]);
2794 outstr
= (char *)calloc(1, dlen
);
2795 if (outstr
== NULL
) {
2801 for (j
= 0; j
< n
; j
++) {
2802 dbname
= _nscd_cfg_nsw_db
[db
[j
]].name
;
2803 if (strstr(dbname
, "group_compat") != NULL
) {
2804 if (compat_grp
== 1)
2808 } else if (strstr(dbname
, "passwd_compat") != NULL
) {
2809 if (compat_pwd
== 1)
2815 (void) strlcat(outstr
, dbname
, dlen
);
2816 (void) strlcat(outstr
, ",", dlen
);
2819 for (j
= 0; j
< nc
; j
++) {
2820 dbname
= _nscd_cfg_nsw_db
[db_compat
[j
]].name
;
2821 if (compat_pwd
== 1) {
2822 (void) strlcat(outstr
, dbname
, dlen
);
2823 (void) strlcat(outstr
, ",", dlen
);
2827 /* remove the last comma */
2828 i
= strlen(outstr
) - 1;
2829 if (outstr
[i
] == ',')