1*cb5caa98Sdjl /* 2*cb5caa98Sdjl * CDDL HEADER START 3*cb5caa98Sdjl * 4*cb5caa98Sdjl * The contents of this file are subject to the terms of the 5*cb5caa98Sdjl * Common Development and Distribution License (the "License"). 6*cb5caa98Sdjl * You may not use this file except in compliance with the License. 7*cb5caa98Sdjl * 8*cb5caa98Sdjl * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*cb5caa98Sdjl * or http://www.opensolaris.org/os/licensing. 10*cb5caa98Sdjl * See the License for the specific language governing permissions 11*cb5caa98Sdjl * and limitations under the License. 12*cb5caa98Sdjl * 13*cb5caa98Sdjl * When distributing Covered Code, include this CDDL HEADER in each 14*cb5caa98Sdjl * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*cb5caa98Sdjl * If applicable, add the following below this CDDL HEADER, with the 16*cb5caa98Sdjl * fields enclosed by brackets "[]" replaced with your own identifying 17*cb5caa98Sdjl * information: Portions Copyright [yyyy] [name of copyright owner] 18*cb5caa98Sdjl * 19*cb5caa98Sdjl * CDDL HEADER END 20*cb5caa98Sdjl */ 21*cb5caa98Sdjl /* 22*cb5caa98Sdjl * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23*cb5caa98Sdjl * Use is subject to license terms. 24*cb5caa98Sdjl */ 25*cb5caa98Sdjl 26*cb5caa98Sdjl #pragma ident "%Z%%M% %I% %E% SMI" 27*cb5caa98Sdjl 28*cb5caa98Sdjl #include <stdio.h> 29*cb5caa98Sdjl #include <stdlib.h> 30*cb5caa98Sdjl #include <locale.h> /* gettext */ 31*cb5caa98Sdjl #include <dlfcn.h> 32*cb5caa98Sdjl #include <string.h> 33*cb5caa98Sdjl #include <sys/varargs.h> 34*cb5caa98Sdjl #include <errno.h> 35*cb5caa98Sdjl #include "nscd_db.h" 36*cb5caa98Sdjl #include "nscd_config.h" 37*cb5caa98Sdjl #include "nscd_cfgdef.h" 38*cb5caa98Sdjl #include "nscd_log.h" 39*cb5caa98Sdjl 40*cb5caa98Sdjl typedef struct { 41*cb5caa98Sdjl rwlock_t *global; 42*cb5caa98Sdjl rwlock_t *alldb; 43*cb5caa98Sdjl rwlock_t *nswdb; 44*cb5caa98Sdjl } nscd_cfg_lock_t; 45*cb5caa98Sdjl 46*cb5caa98Sdjl static rwlock_t cfg_paramDB_rwlock = DEFAULTRWLOCK; 47*cb5caa98Sdjl static nscd_db_t *cfg_paramDB = NULL; 48*cb5caa98Sdjl 49*cb5caa98Sdjl static nscd_cfg_global_data_t *nscd_cfg_global_current; 50*cb5caa98Sdjl static nscd_cfg_nsw_db_data_t *nscd_cfg_nsw_db_data_current; 51*cb5caa98Sdjl static nscd_cfg_nsw_db_data_t *nscd_cfg_nsw_alldb_current; 52*cb5caa98Sdjl static rwlock_t *nscd_cfg_global_rwlock; 53*cb5caa98Sdjl static rwlock_t *nscd_cfg_nsw_db_data_rwlock; 54*cb5caa98Sdjl static rwlock_t *nscd_cfg_nsw_alldb_rwlock; 55*cb5caa98Sdjl 56*cb5caa98Sdjl extern int _nscd_cfg_num_nsw_src_all; 57*cb5caa98Sdjl extern nscd_cfg_id_t *_nscd_cfg_nsw_src_all; 58*cb5caa98Sdjl 59*cb5caa98Sdjl nscd_cfg_error_t * 60*cb5caa98Sdjl _nscd_cfg_make_error( 61*cb5caa98Sdjl nscd_rc_t rc, 62*cb5caa98Sdjl char *msg) 63*cb5caa98Sdjl { 64*cb5caa98Sdjl 65*cb5caa98Sdjl nscd_cfg_error_t *ret; 66*cb5caa98Sdjl int size, msglen; 67*cb5caa98Sdjl 68*cb5caa98Sdjl msglen = (msg != NULL ? strlen(msg) + 1 : 0); 69*cb5caa98Sdjl 70*cb5caa98Sdjl size = sizeof (nscd_cfg_error_t) + msglen; 71*cb5caa98Sdjl 72*cb5caa98Sdjl ret = calloc(1, size); 73*cb5caa98Sdjl if (ret == NULL) 74*cb5caa98Sdjl return (NULL); 75*cb5caa98Sdjl 76*cb5caa98Sdjl ret->rc = rc; 77*cb5caa98Sdjl if (msg != NULL) { 78*cb5caa98Sdjl ret->msg = (char *)ret + 79*cb5caa98Sdjl sizeof (nscd_cfg_error_t); 80*cb5caa98Sdjl (void) memcpy(ret->msg, msg, msglen); 81*cb5caa98Sdjl } 82*cb5caa98Sdjl 83*cb5caa98Sdjl return (ret); 84*cb5caa98Sdjl } 85*cb5caa98Sdjl 86*cb5caa98Sdjl static nscd_rc_t 87*cb5caa98Sdjl _nscd_cfg_get_list( 88*cb5caa98Sdjl nscd_cfg_list_t **list, 89*cb5caa98Sdjl nscd_cfg_list_type_t type) 90*cb5caa98Sdjl { 91*cb5caa98Sdjl char *me = "_nscd_cfg_get_list"; 92*cb5caa98Sdjl int i, num, size; 93*cb5caa98Sdjl nscd_cfg_id_t *l; 94*cb5caa98Sdjl nscd_cfg_list_t *ret; 95*cb5caa98Sdjl nscd_cfg_param_desc_t *pl; 96*cb5caa98Sdjl nscd_cfg_stat_desc_t *sl; 97*cb5caa98Sdjl void *p; 98*cb5caa98Sdjl 99*cb5caa98Sdjl if (list == NULL) { 100*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 101*cb5caa98Sdjl (me, "invalid argument: list = %p\n", list); 102*cb5caa98Sdjl 103*cb5caa98Sdjl return (NSCD_INVALID_ARGUMENT); 104*cb5caa98Sdjl } 105*cb5caa98Sdjl *list = NULL; 106*cb5caa98Sdjl 107*cb5caa98Sdjl switch (type) { 108*cb5caa98Sdjl case NSCD_CFG_LIST_NSW_DB: 109*cb5caa98Sdjl 110*cb5caa98Sdjl num = _nscd_cfg_num_nsw_db; 111*cb5caa98Sdjl l = &_nscd_cfg_nsw_db[0]; 112*cb5caa98Sdjl break; 113*cb5caa98Sdjl 114*cb5caa98Sdjl case NSCD_CFG_LIST_NSW_SRC: 115*cb5caa98Sdjl 116*cb5caa98Sdjl num = _nscd_cfg_num_nsw_src_all; 117*cb5caa98Sdjl l = _nscd_cfg_nsw_src_all; 118*cb5caa98Sdjl break; 119*cb5caa98Sdjl 120*cb5caa98Sdjl case NSCD_CFG_LIST_PARAM: 121*cb5caa98Sdjl 122*cb5caa98Sdjl num = _nscd_cfg_num_param; 123*cb5caa98Sdjl pl = &_nscd_cfg_param_desc[0]; 124*cb5caa98Sdjl break; 125*cb5caa98Sdjl 126*cb5caa98Sdjl case NSCD_CFG_LIST_STAT: 127*cb5caa98Sdjl 128*cb5caa98Sdjl num = _nscd_cfg_num_stat; 129*cb5caa98Sdjl sl = &_nscd_cfg_stat_desc[0]; 130*cb5caa98Sdjl break; 131*cb5caa98Sdjl 132*cb5caa98Sdjl default: 133*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 134*cb5caa98Sdjl (me, "invalid argument: type (%d)\n", type); 135*cb5caa98Sdjl 136*cb5caa98Sdjl return (NSCD_INVALID_ARGUMENT); 137*cb5caa98Sdjl break; 138*cb5caa98Sdjl } 139*cb5caa98Sdjl 140*cb5caa98Sdjl size = sizeof (nscd_cfg_list_t) + sizeof (nscd_cfg_id_t *) * (num + 1); 141*cb5caa98Sdjl 142*cb5caa98Sdjl ret = calloc(1, size); 143*cb5caa98Sdjl if (ret == NULL) 144*cb5caa98Sdjl return (NSCD_NO_MEMORY); 145*cb5caa98Sdjl 146*cb5caa98Sdjl ret->num = num; 147*cb5caa98Sdjl p = (char *)ret + sizeof (nscd_cfg_list_t); 148*cb5caa98Sdjl ret->list = (nscd_cfg_id_t **)p; 149*cb5caa98Sdjl 150*cb5caa98Sdjl if (type == NSCD_CFG_LIST_PARAM) { 151*cb5caa98Sdjl for (i = 0; i <= num; i++) 152*cb5caa98Sdjl ret->list[i] = (nscd_cfg_id_t *)&pl[i]; 153*cb5caa98Sdjl } else if (type == NSCD_CFG_LIST_STAT) { 154*cb5caa98Sdjl for (i = 0; i <= num; i++) 155*cb5caa98Sdjl ret->list[i] = (nscd_cfg_id_t *)&sl[i]; 156*cb5caa98Sdjl } else { 157*cb5caa98Sdjl for (i = 0; i <= num; i++) 158*cb5caa98Sdjl ret->list[i] = &l[i]; 159*cb5caa98Sdjl } 160*cb5caa98Sdjl 161*cb5caa98Sdjl *list = ret; 162*cb5caa98Sdjl 163*cb5caa98Sdjl return (NSCD_SUCCESS); 164*cb5caa98Sdjl } 165*cb5caa98Sdjl 166*cb5caa98Sdjl nscd_rc_t 167*cb5caa98Sdjl _nscd_cfg_get_param_desc_list( 168*cb5caa98Sdjl nscd_cfg_param_desc_list_t **list) 169*cb5caa98Sdjl { 170*cb5caa98Sdjl return (_nscd_cfg_get_list((nscd_cfg_list_t **)list, 171*cb5caa98Sdjl NSCD_CFG_LIST_PARAM)); 172*cb5caa98Sdjl } 173*cb5caa98Sdjl 174*cb5caa98Sdjl /* find function pointer in the executable via dlopen(0) */ 175*cb5caa98Sdjl static nscd_rc_t 176*cb5caa98Sdjl _nscd_cfg_init_funcs( 177*cb5caa98Sdjl char *name, 178*cb5caa98Sdjl void **func_p, 179*cb5caa98Sdjl nscd_cfg_error_t **errorp) 180*cb5caa98Sdjl { 181*cb5caa98Sdjl char *me = "_nscd_cfg_init_funcs"; 182*cb5caa98Sdjl char msg[NSCD_CFG_MAX_ERR_MSG_LEN]; 183*cb5caa98Sdjl static void *handle = NULL; 184*cb5caa98Sdjl void *sym; 185*cb5caa98Sdjl nscd_rc_t rc = NSCD_SUCCESS; 186*cb5caa98Sdjl 187*cb5caa98Sdjl if (name == NULL && handle != NULL) { 188*cb5caa98Sdjl (void) dlclose(handle); 189*cb5caa98Sdjl return (rc); 190*cb5caa98Sdjl } 191*cb5caa98Sdjl if (name == NULL) 192*cb5caa98Sdjl return (rc); 193*cb5caa98Sdjl 194*cb5caa98Sdjl if (handle == NULL) { 195*cb5caa98Sdjl handle = dlopen((const char *)0, RTLD_LAZY); 196*cb5caa98Sdjl if (handle == NULL) { 197*cb5caa98Sdjl 198*cb5caa98Sdjl rc = NSCD_CFG_DLOPEN_ERROR; 199*cb5caa98Sdjl (void) snprintf(msg, sizeof (msg), 200*cb5caa98Sdjl gettext("unable to dlopen the nscd executable: %s"), 201*cb5caa98Sdjl dlerror()); 202*cb5caa98Sdjl goto error_exit; 203*cb5caa98Sdjl } 204*cb5caa98Sdjl } 205*cb5caa98Sdjl 206*cb5caa98Sdjl if (func_p) { 207*cb5caa98Sdjl if ((sym = dlsym(handle, name)) == NULL) { 208*cb5caa98Sdjl 209*cb5caa98Sdjl rc = NSCD_CFG_DLSYM_ERROR; 210*cb5caa98Sdjl (void) snprintf(msg, sizeof (msg), 211*cb5caa98Sdjl gettext("unable to get the address of a symbol in the nscd executable: %s"), 212*cb5caa98Sdjl dlerror()); 213*cb5caa98Sdjl goto error_exit; 214*cb5caa98Sdjl } else 215*cb5caa98Sdjl (void) memcpy(func_p, &sym, sizeof (void *)); 216*cb5caa98Sdjl } 217*cb5caa98Sdjl 218*cb5caa98Sdjl return (rc); 219*cb5caa98Sdjl 220*cb5caa98Sdjl error_exit: 221*cb5caa98Sdjl 222*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 223*cb5caa98Sdjl (me, "%s\n", msg); 224*cb5caa98Sdjl if (errorp != NULL) 225*cb5caa98Sdjl *errorp = _nscd_cfg_make_error(rc, msg); 226*cb5caa98Sdjl 227*cb5caa98Sdjl return (rc); 228*cb5caa98Sdjl } 229*cb5caa98Sdjl 230*cb5caa98Sdjl 231*cb5caa98Sdjl /* 232*cb5caa98Sdjl * FUNCTION: _nscd_cfg_create_paramDB 233*cb5caa98Sdjl * 234*cb5caa98Sdjl * Create the internal config parameter database 235*cb5caa98Sdjl */ 236*cb5caa98Sdjl static nscd_db_t * 237*cb5caa98Sdjl _nscd_cfg_create_paramDB() 238*cb5caa98Sdjl { 239*cb5caa98Sdjl 240*cb5caa98Sdjl nscd_db_t *ret; 241*cb5caa98Sdjl 242*cb5caa98Sdjl (void) rw_wrlock(&cfg_paramDB_rwlock); 243*cb5caa98Sdjl 244*cb5caa98Sdjl ret = _nscd_alloc_db(NSCD_DB_SIZE_MEDIUM); 245*cb5caa98Sdjl 246*cb5caa98Sdjl if (ret != NULL) 247*cb5caa98Sdjl cfg_paramDB = ret; 248*cb5caa98Sdjl 249*cb5caa98Sdjl (void) rw_unlock(&cfg_paramDB_rwlock); 250*cb5caa98Sdjl 251*cb5caa98Sdjl return (ret); 252*cb5caa98Sdjl } 253*cb5caa98Sdjl 254*cb5caa98Sdjl /* 255*cb5caa98Sdjl * FUNCTION: _nscd_cfg_add_index_entry 256*cb5caa98Sdjl * 257*cb5caa98Sdjl * Add a config index entry (a name to index mapping) 258*cb5caa98Sdjl * to the internal configuration database. 259*cb5caa98Sdjl */ 260*cb5caa98Sdjl static nscd_rc_t 261*cb5caa98Sdjl _nscd_cfg_add_index_entry( 262*cb5caa98Sdjl char *name, 263*cb5caa98Sdjl int index, 264*cb5caa98Sdjl nscd_cfg_list_type_t type) 265*cb5caa98Sdjl { 266*cb5caa98Sdjl int *idx; 267*cb5caa98Sdjl int size; 268*cb5caa98Sdjl int dbe_type; 269*cb5caa98Sdjl nscd_db_entry_t *db_entry; 270*cb5caa98Sdjl 271*cb5caa98Sdjl if (name == NULL) 272*cb5caa98Sdjl return (NSCD_INVALID_ARGUMENT); 273*cb5caa98Sdjl 274*cb5caa98Sdjl if (type == NSCD_CFG_LIST_NSW_DB) 275*cb5caa98Sdjl dbe_type = NSCD_DATA_CFG_NSW_DB_INDEX; 276*cb5caa98Sdjl else if (type == NSCD_CFG_LIST_NSW_SRC) 277*cb5caa98Sdjl dbe_type = NSCD_DATA_CFG_NSW_SRC_INDEX; 278*cb5caa98Sdjl else if (type == NSCD_CFG_LIST_PARAM) 279*cb5caa98Sdjl dbe_type = NSCD_DATA_CFG_PARAM_INDEX; 280*cb5caa98Sdjl else if (type == NSCD_CFG_LIST_STAT) 281*cb5caa98Sdjl dbe_type = NSCD_DATA_CFG_STAT_INDEX; 282*cb5caa98Sdjl 283*cb5caa98Sdjl size = sizeof (int); 284*cb5caa98Sdjl 285*cb5caa98Sdjl db_entry = _nscd_alloc_db_entry(dbe_type, (const char *)name, 286*cb5caa98Sdjl size, 1, 1); 287*cb5caa98Sdjl if (db_entry == NULL) 288*cb5caa98Sdjl return (NSCD_NO_MEMORY); 289*cb5caa98Sdjl 290*cb5caa98Sdjl idx = (int *)*(db_entry->data_array); 291*cb5caa98Sdjl *idx = index; 292*cb5caa98Sdjl 293*cb5caa98Sdjl (void) rw_wrlock(&cfg_paramDB_rwlock); 294*cb5caa98Sdjl (void) _nscd_add_db_entry(cfg_paramDB, name, db_entry, 295*cb5caa98Sdjl NSCD_ADD_DB_ENTRY_FIRST); 296*cb5caa98Sdjl (void) rw_unlock(&cfg_paramDB_rwlock); 297*cb5caa98Sdjl 298*cb5caa98Sdjl return (NSCD_SUCCESS); 299*cb5caa98Sdjl } 300*cb5caa98Sdjl 301*cb5caa98Sdjl /* 302*cb5caa98Sdjl * FUNCTION: _nscd_cfg_get_index 303*cb5caa98Sdjl * 304*cb5caa98Sdjl * Get the index of a config data item by searching the internal config 305*cb5caa98Sdjl * database. Do not free the returned data. 306*cb5caa98Sdjl */ 307*cb5caa98Sdjl static int 308*cb5caa98Sdjl _nscd_cfg_get_index( 309*cb5caa98Sdjl char *name, 310*cb5caa98Sdjl nscd_cfg_list_type_t type) 311*cb5caa98Sdjl { 312*cb5caa98Sdjl int index = -1, dbe_type; 313*cb5caa98Sdjl const nscd_db_entry_t *db_entry; 314*cb5caa98Sdjl 315*cb5caa98Sdjl if (name == NULL) 316*cb5caa98Sdjl return (-1); 317*cb5caa98Sdjl 318*cb5caa98Sdjl if (type == NSCD_CFG_LIST_NSW_DB) 319*cb5caa98Sdjl dbe_type = NSCD_DATA_CFG_NSW_DB_INDEX; 320*cb5caa98Sdjl else if (type == NSCD_CFG_LIST_NSW_SRC) 321*cb5caa98Sdjl dbe_type = NSCD_DATA_CFG_NSW_SRC_INDEX; 322*cb5caa98Sdjl else if (type == NSCD_CFG_LIST_PARAM) 323*cb5caa98Sdjl dbe_type = NSCD_DATA_CFG_PARAM_INDEX; 324*cb5caa98Sdjl else if (type == NSCD_CFG_LIST_STAT) 325*cb5caa98Sdjl dbe_type = NSCD_DATA_CFG_STAT_INDEX; 326*cb5caa98Sdjl else 327*cb5caa98Sdjl return (-1); 328*cb5caa98Sdjl 329*cb5caa98Sdjl db_entry = _nscd_get_db_entry(cfg_paramDB, dbe_type, 330*cb5caa98Sdjl (const char *)name, NSCD_GET_FIRST_DB_ENTRY, 0); 331*cb5caa98Sdjl 332*cb5caa98Sdjl if (db_entry != NULL) 333*cb5caa98Sdjl index = *(int *)*(db_entry->data_array); 334*cb5caa98Sdjl 335*cb5caa98Sdjl return (index); 336*cb5caa98Sdjl } 337*cb5caa98Sdjl 338*cb5caa98Sdjl static nscd_rc_t 339*cb5caa98Sdjl _nscd_cfg_verify_group_info( 340*cb5caa98Sdjl nscd_cfg_group_info_t *g_info, 341*cb5caa98Sdjl nscd_cfg_param_desc_t *gdesc) 342*cb5caa98Sdjl { 343*cb5caa98Sdjl 344*cb5caa98Sdjl char *me = "_nscd_cfg_verify_group_info"; 345*cb5caa98Sdjl void *vp; 346*cb5caa98Sdjl nscd_cfg_group_info_t *gi; 347*cb5caa98Sdjl 348*cb5caa98Sdjl if (_nscd_cfg_flag_is_set(gdesc->pflag, NSCD_CFG_PFLAG_GLOBAL)) { 349*cb5caa98Sdjl vp = (char *)&nscd_cfg_global_default + 350*cb5caa98Sdjl gdesc->g_offset; 351*cb5caa98Sdjl gi = (nscd_cfg_group_info_t *)vp; 352*cb5caa98Sdjl } else { 353*cb5caa98Sdjl vp = (char *)&nscd_cfg_nsw_db_data_default + 354*cb5caa98Sdjl gdesc->g_offset; 355*cb5caa98Sdjl gi = (nscd_cfg_group_info_t *)vp; 356*cb5caa98Sdjl 357*cb5caa98Sdjl } 358*cb5caa98Sdjl 359*cb5caa98Sdjl if (g_info->num_param == gi->num_param && 360*cb5caa98Sdjl _nscd_cfg_bitmap_is_equal(g_info->bitmap, gi->bitmap)) 361*cb5caa98Sdjl return (NSCD_SUCCESS); 362*cb5caa98Sdjl 363*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 364*cb5caa98Sdjl (me, "ERROR: group (%s) info mismatched: group info " 365*cb5caa98Sdjl "(%d, %#6.4x) not equal to that of default configuration data " 366*cb5caa98Sdjl "(%d, %#6.4x)\n", gdesc->id.name, g_info->num_param, 367*cb5caa98Sdjl _nscd_cfg_bitmap_value(g_info->bitmap), gi->num_param, 368*cb5caa98Sdjl _nscd_cfg_bitmap_value(gi->bitmap)); 369*cb5caa98Sdjl 370*cb5caa98Sdjl return (NSCD_CFG_PARAM_DESC_ERROR); 371*cb5caa98Sdjl 372*cb5caa98Sdjl } 373*cb5caa98Sdjl 374*cb5caa98Sdjl 375*cb5caa98Sdjl static nscd_rc_t 376*cb5caa98Sdjl _nscd_cfg_init_nsw() 377*cb5caa98Sdjl { 378*cb5caa98Sdjl char *me = "_nscd_cfg_init_nsw"; 379*cb5caa98Sdjl int i, j, idx, rc, num; 380*cb5caa98Sdjl nscd_cfg_id_t *id; 381*cb5caa98Sdjl nscd_cfg_list_type_t type[2] = { NSCD_CFG_LIST_NSW_DB, 382*cb5caa98Sdjl NSCD_CFG_LIST_NSW_SRC }; 383*cb5caa98Sdjl 384*cb5caa98Sdjl nscd_cfg_id_t *list[2] = { _nscd_cfg_nsw_db, NULL}; 385*cb5caa98Sdjl 386*cb5caa98Sdjl list[1] = _nscd_cfg_nsw_src_all; 387*cb5caa98Sdjl 388*cb5caa98Sdjl for (j = 0; j < 2; j++) { 389*cb5caa98Sdjl 390*cb5caa98Sdjl if (j == 0) 391*cb5caa98Sdjl num = _nscd_cfg_num_nsw_db + 1; 392*cb5caa98Sdjl else 393*cb5caa98Sdjl num = _nscd_cfg_num_nsw_src_all; 394*cb5caa98Sdjl 395*cb5caa98Sdjl for (i = 0; i < num; i++) { 396*cb5caa98Sdjl 397*cb5caa98Sdjl /* 398*cb5caa98Sdjl * _nscd_cfg_nsw_alldb is the id for the 399*cb5caa98Sdjl * special ALLDB (defaults for all db) 400*cb5caa98Sdjl */ 401*cb5caa98Sdjl if (j == 0 && i == _nscd_cfg_num_nsw_db) { 402*cb5caa98Sdjl id = &_nscd_cfg_nsw_alldb; 403*cb5caa98Sdjl idx = NSCD_CFG_NSW_ALLDB_INDEX; 404*cb5caa98Sdjl } else { 405*cb5caa98Sdjl id = &(list[j])[i]; 406*cb5caa98Sdjl id->index = idx = i; 407*cb5caa98Sdjl } 408*cb5caa98Sdjl 409*cb5caa98Sdjl if (id->name == NULL) 410*cb5caa98Sdjl continue; 411*cb5caa98Sdjl 412*cb5caa98Sdjl if ((rc = _nscd_cfg_add_index_entry(id->name, 413*cb5caa98Sdjl idx, type[j])) != NSCD_SUCCESS) { 414*cb5caa98Sdjl 415*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, 416*cb5caa98Sdjl NSCD_LOG_LEVEL_ERROR) 417*cb5caa98Sdjl (me, "unable to add index entry for " 418*cb5caa98Sdjl "nsswitch entry %s\n", id->name); 419*cb5caa98Sdjl 420*cb5caa98Sdjl _nscd_free_db(cfg_paramDB); 421*cb5caa98Sdjl return (rc); 422*cb5caa98Sdjl } 423*cb5caa98Sdjl } 424*cb5caa98Sdjl } 425*cb5caa98Sdjl 426*cb5caa98Sdjl return (NSCD_SUCCESS); 427*cb5caa98Sdjl } 428*cb5caa98Sdjl 429*cb5caa98Sdjl /* 430*cb5caa98Sdjl * get the address of a function in the nscd executable 431*cb5caa98Sdjl * and store it in where 'dest_p' points to 432*cb5caa98Sdjl */ 433*cb5caa98Sdjl static nscd_rc_t 434*cb5caa98Sdjl _nscd_cfg_get_funcp( 435*cb5caa98Sdjl char *name, 436*cb5caa98Sdjl void *dest_p, 437*cb5caa98Sdjl void **gfunc_a, 438*cb5caa98Sdjl nscd_cfg_error_t **errorp) 439*cb5caa98Sdjl { 440*cb5caa98Sdjl 441*cb5caa98Sdjl void *func; 442*cb5caa98Sdjl nscd_rc_t rc; 443*cb5caa98Sdjl 444*cb5caa98Sdjl if (gfunc_a != NULL) { 445*cb5caa98Sdjl 446*cb5caa98Sdjl if (strcmp(name, NSCD_CFG_FUNC_NAME_AS_GROUP) == 0) 447*cb5caa98Sdjl (void) memcpy(dest_p, gfunc_a, sizeof (void *)); 448*cb5caa98Sdjl 449*cb5caa98Sdjl return (NSCD_SUCCESS); 450*cb5caa98Sdjl } 451*cb5caa98Sdjl 452*cb5caa98Sdjl rc = _nscd_cfg_init_funcs(name, &func, errorp); 453*cb5caa98Sdjl if (rc != NSCD_SUCCESS) 454*cb5caa98Sdjl return (rc); 455*cb5caa98Sdjl (void) memcpy(dest_p, &func, sizeof (func)); 456*cb5caa98Sdjl 457*cb5caa98Sdjl return (NSCD_SUCCESS); 458*cb5caa98Sdjl } 459*cb5caa98Sdjl 460*cb5caa98Sdjl static nscd_rc_t 461*cb5caa98Sdjl _nscd_cfg_init_param() 462*cb5caa98Sdjl { 463*cb5caa98Sdjl char *me = "_nscd_cfg_init_param"; 464*cb5caa98Sdjl int i, gi, fn = 0; 465*cb5caa98Sdjl nscd_cfg_id_t *id; 466*cb5caa98Sdjl nscd_cfg_param_desc_t *desc, *gdesc = NULL; 467*cb5caa98Sdjl nscd_cfg_group_info_t g_info; 468*cb5caa98Sdjl nscd_cfg_list_type_t type = NSCD_CFG_LIST_PARAM; 469*cb5caa98Sdjl nscd_rc_t rc; 470*cb5caa98Sdjl void *nfunc, *vfunc; 471*cb5caa98Sdjl 472*cb5caa98Sdjl if (_nscd_cfg_create_paramDB() == NULL) 473*cb5caa98Sdjl return (NSCD_NO_MEMORY); 474*cb5caa98Sdjl 475*cb5caa98Sdjl desc = &_nscd_cfg_param_desc[0]; 476*cb5caa98Sdjl 477*cb5caa98Sdjl /* 478*cb5caa98Sdjl * need to loop to the last (+1) param description 479*cb5caa98Sdjl * which is a fake group and which marks the end 480*cb5caa98Sdjl * of list. It is used to signal the end of the 481*cb5caa98Sdjl * previous group so that the proper data will be 482*cb5caa98Sdjl * set for that group 483*cb5caa98Sdjl */ 484*cb5caa98Sdjl for (i = 0; i < _nscd_cfg_num_param + 1; i++, desc++) { 485*cb5caa98Sdjl 486*cb5caa98Sdjl id = (nscd_cfg_id_t *)desc; 487*cb5caa98Sdjl 488*cb5caa98Sdjl if (_nscd_cfg_flag_is_set(desc->pflag, 489*cb5caa98Sdjl NSCD_CFG_PFLAG_GROUP)) { 490*cb5caa98Sdjl 491*cb5caa98Sdjl if (gdesc != NULL) { 492*cb5caa98Sdjl g_info.num_param = fn; 493*cb5caa98Sdjl gdesc->p_fn = fn; 494*cb5caa98Sdjl 495*cb5caa98Sdjl if ((rc = _nscd_cfg_verify_group_info( 496*cb5caa98Sdjl &g_info, gdesc)) != NSCD_SUCCESS) 497*cb5caa98Sdjl return (rc); 498*cb5caa98Sdjl } 499*cb5caa98Sdjl 500*cb5caa98Sdjl gi = i; 501*cb5caa98Sdjl fn = 0; 502*cb5caa98Sdjl gdesc = desc; 503*cb5caa98Sdjl g_info.bitmap = NSCD_CFG_BITMAP_ZERO; 504*cb5caa98Sdjl nfunc = NULL; 505*cb5caa98Sdjl vfunc = NULL; 506*cb5caa98Sdjl 507*cb5caa98Sdjl /* 508*cb5caa98Sdjl * set the notify/verify functions 509*cb5caa98Sdjl */ 510*cb5caa98Sdjl if (gdesc->nfunc_name != NULL) { 511*cb5caa98Sdjl rc = _nscd_cfg_get_funcp(gdesc->nfunc_name, 512*cb5caa98Sdjl &gdesc->notify, NULL, NULL); 513*cb5caa98Sdjl if (rc != NULL) 514*cb5caa98Sdjl return (rc); 515*cb5caa98Sdjl nfunc = (void *)gdesc->notify; 516*cb5caa98Sdjl } 517*cb5caa98Sdjl if (gdesc->vfunc_name != NULL) { 518*cb5caa98Sdjl rc = _nscd_cfg_get_funcp(gdesc->vfunc_name, 519*cb5caa98Sdjl &gdesc->verify, NULL, NULL); 520*cb5caa98Sdjl if (rc != NULL) 521*cb5caa98Sdjl return (rc); 522*cb5caa98Sdjl vfunc = (void *)gdesc->verify; 523*cb5caa98Sdjl } 524*cb5caa98Sdjl } else { 525*cb5caa98Sdjl if (i == 0) { 526*cb5caa98Sdjl 527*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, 528*cb5caa98Sdjl NSCD_LOG_LEVEL_ERROR) 529*cb5caa98Sdjl (me, "ERROR: first parameter " 530*cb5caa98Sdjl "description is not for a group\n"); 531*cb5caa98Sdjl 532*cb5caa98Sdjl return (NSCD_CFG_PARAM_DESC_ERROR); 533*cb5caa98Sdjl } 534*cb5caa98Sdjl 535*cb5caa98Sdjl /* 536*cb5caa98Sdjl * set bitmap: the rightmost bit represents 537*cb5caa98Sdjl * the first member (index = 0) in the group, 538*cb5caa98Sdjl * the next bit is for the second member 539*cb5caa98Sdjl * (index = 1), and so on 540*cb5caa98Sdjl */ 541*cb5caa98Sdjl _nscd_cfg_bitmap_set_nth(g_info.bitmap, fn); 542*cb5caa98Sdjl 543*cb5caa98Sdjl desc->p_fn = fn++; 544*cb5caa98Sdjl 545*cb5caa98Sdjl /* 546*cb5caa98Sdjl * set the notify/verify functions 547*cb5caa98Sdjl */ 548*cb5caa98Sdjl if (desc->nfunc_name != NULL) { 549*cb5caa98Sdjl rc = _nscd_cfg_get_funcp(desc->nfunc_name, 550*cb5caa98Sdjl &desc->notify, &nfunc, NULL); 551*cb5caa98Sdjl if (rc != NULL) 552*cb5caa98Sdjl return (rc); 553*cb5caa98Sdjl } 554*cb5caa98Sdjl if (desc->vfunc_name != NULL) { 555*cb5caa98Sdjl rc = _nscd_cfg_get_funcp(desc->vfunc_name, 556*cb5caa98Sdjl &desc->verify, &vfunc, NULL); 557*cb5caa98Sdjl if (rc != NULL) 558*cb5caa98Sdjl return (rc); 559*cb5caa98Sdjl } 560*cb5caa98Sdjl } 561*cb5caa98Sdjl 562*cb5caa98Sdjl /* if end of list reached, we are done */ 563*cb5caa98Sdjl if (i == _nscd_cfg_num_param) 564*cb5caa98Sdjl break; 565*cb5caa98Sdjl 566*cb5caa98Sdjl desc->g_index = gi; 567*cb5caa98Sdjl 568*cb5caa98Sdjl id->index = i; 569*cb5caa98Sdjl 570*cb5caa98Sdjl if ((rc = _nscd_cfg_add_index_entry(id->name, 571*cb5caa98Sdjl i, type)) != NSCD_SUCCESS) { 572*cb5caa98Sdjl 573*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 574*cb5caa98Sdjl (me, "unable to add index entry for parameter " 575*cb5caa98Sdjl "%s\n", id->name); 576*cb5caa98Sdjl 577*cb5caa98Sdjl _nscd_free_db(cfg_paramDB); 578*cb5caa98Sdjl return (rc); 579*cb5caa98Sdjl } else { 580*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_DEBUG) 581*cb5caa98Sdjl (me, "index entry for parameter " 582*cb5caa98Sdjl "%s added\n", id->name); 583*cb5caa98Sdjl } 584*cb5caa98Sdjl } 585*cb5caa98Sdjl 586*cb5caa98Sdjl return (_nscd_cfg_init_nsw()); 587*cb5caa98Sdjl } 588*cb5caa98Sdjl 589*cb5caa98Sdjl static nscd_rc_t 590*cb5caa98Sdjl _nscd_cfg_init_stat() 591*cb5caa98Sdjl { 592*cb5caa98Sdjl char *me = "_nscd_cfg_init_stat"; 593*cb5caa98Sdjl int i, gi, fn = 0; 594*cb5caa98Sdjl nscd_cfg_id_t *id; 595*cb5caa98Sdjl nscd_cfg_stat_desc_t *desc, *gdesc = NULL; 596*cb5caa98Sdjl nscd_cfg_group_info_t g_info; 597*cb5caa98Sdjl nscd_cfg_list_type_t type = NSCD_CFG_LIST_STAT; 598*cb5caa98Sdjl nscd_rc_t rc; 599*cb5caa98Sdjl void *gsfunc; 600*cb5caa98Sdjl 601*cb5caa98Sdjl desc = &_nscd_cfg_stat_desc[0]; 602*cb5caa98Sdjl 603*cb5caa98Sdjl /* 604*cb5caa98Sdjl * need to loop to the last (+1) stat description 605*cb5caa98Sdjl * which is a fake group and which marks the end 606*cb5caa98Sdjl * of list. It is used to signal the end of the 607*cb5caa98Sdjl * previous group so that the proper data will be 608*cb5caa98Sdjl * set for that group 609*cb5caa98Sdjl */ 610*cb5caa98Sdjl for (i = 0; i < _nscd_cfg_num_stat + 1; i++, desc++) { 611*cb5caa98Sdjl 612*cb5caa98Sdjl id = (nscd_cfg_id_t *)desc; 613*cb5caa98Sdjl 614*cb5caa98Sdjl if (_nscd_cfg_flag_is_set(desc->sflag, 615*cb5caa98Sdjl NSCD_CFG_SFLAG_GROUP)) { 616*cb5caa98Sdjl 617*cb5caa98Sdjl if (gdesc != NULL) { 618*cb5caa98Sdjl g_info.num_param = fn; 619*cb5caa98Sdjl gdesc->s_fn = fn; 620*cb5caa98Sdjl 621*cb5caa98Sdjl if (g_info.num_param != 622*cb5caa98Sdjl gdesc->gi.num_param || 623*cb5caa98Sdjl !_nscd_cfg_bitmap_is_equal( 624*cb5caa98Sdjl g_info.bitmap, gdesc->gi.bitmap)) { 625*cb5caa98Sdjl 626*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, 627*cb5caa98Sdjl NSCD_LOG_LEVEL_ERROR) 628*cb5caa98Sdjl (me, "ERROR: group (%s) " 629*cb5caa98Sdjl "info mismatched: " 630*cb5caa98Sdjl "group info (%d, %#6.4x) not " 631*cb5caa98Sdjl "equal to the predefined one " 632*cb5caa98Sdjl "(%d, %#6.4x)\n", gdesc->id.name, 633*cb5caa98Sdjl g_info.num_param, 634*cb5caa98Sdjl _nscd_cfg_bitmap_value(g_info.bitmap), 635*cb5caa98Sdjl gdesc->gi.num_param, 636*cb5caa98Sdjl _nscd_cfg_bitmap_value( 637*cb5caa98Sdjl gdesc->gi.bitmap)); 638*cb5caa98Sdjl 639*cb5caa98Sdjl exit(1); 640*cb5caa98Sdjl return (NSCD_CFG_STAT_DESC_ERROR); 641*cb5caa98Sdjl } 642*cb5caa98Sdjl } 643*cb5caa98Sdjl 644*cb5caa98Sdjl gi = i; 645*cb5caa98Sdjl fn = 0; 646*cb5caa98Sdjl gdesc = desc; 647*cb5caa98Sdjl g_info.bitmap = NSCD_CFG_BITMAP_ZERO; 648*cb5caa98Sdjl gsfunc = NULL; 649*cb5caa98Sdjl 650*cb5caa98Sdjl /* 651*cb5caa98Sdjl * set the get_stat function 652*cb5caa98Sdjl */ 653*cb5caa98Sdjl if (gdesc->gsfunc_name != NULL) { 654*cb5caa98Sdjl rc = _nscd_cfg_get_funcp(gdesc->gsfunc_name, 655*cb5caa98Sdjl &gdesc->get_stat, NULL, NULL); 656*cb5caa98Sdjl if (rc != NULL) 657*cb5caa98Sdjl return (rc); 658*cb5caa98Sdjl gsfunc = (void *)gdesc->get_stat; 659*cb5caa98Sdjl } 660*cb5caa98Sdjl } else { 661*cb5caa98Sdjl if (i == 0) { 662*cb5caa98Sdjl 663*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, 664*cb5caa98Sdjl NSCD_LOG_LEVEL_ERROR) 665*cb5caa98Sdjl (me, "ERROR: first stat " 666*cb5caa98Sdjl "description is not for a group\n"); 667*cb5caa98Sdjl 668*cb5caa98Sdjl return (NSCD_CFG_STAT_DESC_ERROR); 669*cb5caa98Sdjl } 670*cb5caa98Sdjl 671*cb5caa98Sdjl /* 672*cb5caa98Sdjl * set bitmap: the rightmost bit represents 673*cb5caa98Sdjl * the first member (index = 0) in the group, 674*cb5caa98Sdjl * the next bit is for the second member 675*cb5caa98Sdjl * (index = 1), and so on 676*cb5caa98Sdjl */ 677*cb5caa98Sdjl _nscd_cfg_bitmap_set_nth(g_info.bitmap, fn); 678*cb5caa98Sdjl 679*cb5caa98Sdjl desc->s_fn = fn++; 680*cb5caa98Sdjl 681*cb5caa98Sdjl /* 682*cb5caa98Sdjl * set the get_stat function 683*cb5caa98Sdjl */ 684*cb5caa98Sdjl if (desc->gsfunc_name != NULL) { 685*cb5caa98Sdjl rc = _nscd_cfg_get_funcp(desc->gsfunc_name, 686*cb5caa98Sdjl &desc->get_stat, &gsfunc, NULL); 687*cb5caa98Sdjl if (rc != NULL) 688*cb5caa98Sdjl return (rc); 689*cb5caa98Sdjl } 690*cb5caa98Sdjl } 691*cb5caa98Sdjl 692*cb5caa98Sdjl /* if end of list reached, we are done */ 693*cb5caa98Sdjl if (i == _nscd_cfg_num_stat) 694*cb5caa98Sdjl break; 695*cb5caa98Sdjl 696*cb5caa98Sdjl desc->g_index = gi; 697*cb5caa98Sdjl 698*cb5caa98Sdjl id->index = i; 699*cb5caa98Sdjl 700*cb5caa98Sdjl if ((rc = _nscd_cfg_add_index_entry(id->name, 701*cb5caa98Sdjl i, type)) != NSCD_SUCCESS) { 702*cb5caa98Sdjl 703*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 704*cb5caa98Sdjl (me, "unable to add index entry for stat " 705*cb5caa98Sdjl "description %s\n", id->name); 706*cb5caa98Sdjl 707*cb5caa98Sdjl _nscd_free_db(cfg_paramDB); 708*cb5caa98Sdjl return (rc); 709*cb5caa98Sdjl } else { 710*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_DEBUG) 711*cb5caa98Sdjl (me, "index entry for stat description " 712*cb5caa98Sdjl "%s added\n", id->name); 713*cb5caa98Sdjl } 714*cb5caa98Sdjl } 715*cb5caa98Sdjl 716*cb5caa98Sdjl return (NSCD_SUCCESS); 717*cb5caa98Sdjl } 718*cb5caa98Sdjl 719*cb5caa98Sdjl static nscd_rc_t 720*cb5caa98Sdjl _nscd_cfg_copy_vlen_data( 721*cb5caa98Sdjl void *data, 722*cb5caa98Sdjl void **new_data_p, 723*cb5caa98Sdjl nscd_cfg_param_desc_t *desc, 724*cb5caa98Sdjl int *data_len, 725*cb5caa98Sdjl nscd_bool_t in) 726*cb5caa98Sdjl { 727*cb5caa98Sdjl int len, dlen; 728*cb5caa98Sdjl nscd_cfg_vlen_data_t *v = NULL; 729*cb5caa98Sdjl 730*cb5caa98Sdjl *new_data_p = NULL; 731*cb5caa98Sdjl *data_len = 0; 732*cb5caa98Sdjl 733*cb5caa98Sdjl /* it is OK if there is nothing to copy */ 734*cb5caa98Sdjl if (data == NULL) 735*cb5caa98Sdjl return (NSCD_SUCCESS); 736*cb5caa98Sdjl 737*cb5caa98Sdjl /* 738*cb5caa98Sdjl * if copy to the config store we need to allocate space 739*cb5caa98Sdjl * for the extra vlen header 740*cb5caa98Sdjl */ 741*cb5caa98Sdjl if (desc->type == NSCD_CFG_DATA_STRING) { 742*cb5caa98Sdjl len = dlen = strlen((char *)data) + 1; 743*cb5caa98Sdjl if (in == nscd_true) 744*cb5caa98Sdjl len += sizeof (nscd_cfg_vlen_data_t); 745*cb5caa98Sdjl } else { 746*cb5caa98Sdjl /* 747*cb5caa98Sdjl * should not be here, since for now 748*cb5caa98Sdjl * only string variable length data 749*cb5caa98Sdjl * is supported 750*cb5caa98Sdjl */ 751*cb5caa98Sdjl *new_data_p = NULL; 752*cb5caa98Sdjl return (NSCD_CFG_PARAM_DESC_ERROR); 753*cb5caa98Sdjl } 754*cb5caa98Sdjl 755*cb5caa98Sdjl v = calloc(1, len); 756*cb5caa98Sdjl if (v == NULL) { 757*cb5caa98Sdjl *new_data_p = NULL; 758*cb5caa98Sdjl return (NSCD_NO_MEMORY); 759*cb5caa98Sdjl } 760*cb5caa98Sdjl 761*cb5caa98Sdjl /* 762*cb5caa98Sdjl * if copy to the config store, set up 763*cb5caa98Sdjl * the extra vlen header in which the 764*cb5caa98Sdjl * pointer to, and length of, the real 765*cb5caa98Sdjl * data are kept. The pointer to the real 766*cb5caa98Sdjl * data, not the vlen header, is returned. 767*cb5caa98Sdjl */ 768*cb5caa98Sdjl if (in == nscd_true) { 769*cb5caa98Sdjl v->ptr = (char *)v + sizeof (nscd_cfg_vlen_data_t); 770*cb5caa98Sdjl v->len = dlen; 771*cb5caa98Sdjl (void) memcpy(v->ptr, data, dlen); 772*cb5caa98Sdjl *new_data_p = v->ptr; 773*cb5caa98Sdjl } else { 774*cb5caa98Sdjl (void) memcpy(v, data, dlen); 775*cb5caa98Sdjl *new_data_p = v; 776*cb5caa98Sdjl } 777*cb5caa98Sdjl *data_len = dlen; 778*cb5caa98Sdjl 779*cb5caa98Sdjl return (NSCD_SUCCESS); 780*cb5caa98Sdjl } 781*cb5caa98Sdjl 782*cb5caa98Sdjl static void 783*cb5caa98Sdjl _nscd_cfg_free_vlen_data_int( 784*cb5caa98Sdjl void *data) 785*cb5caa98Sdjl { 786*cb5caa98Sdjl nscd_cfg_vlen_data_t *v = NULL; 787*cb5caa98Sdjl void *p; 788*cb5caa98Sdjl 789*cb5caa98Sdjl if (data == NULL) 790*cb5caa98Sdjl return; 791*cb5caa98Sdjl 792*cb5caa98Sdjl p = (char *)data - sizeof (nscd_cfg_vlen_data_t); 793*cb5caa98Sdjl v = (nscd_cfg_vlen_data_t *)p; 794*cb5caa98Sdjl if (v->ptr == data) 795*cb5caa98Sdjl free(v); 796*cb5caa98Sdjl } 797*cb5caa98Sdjl 798*cb5caa98Sdjl static nscd_rc_t 799*cb5caa98Sdjl _nscd_cfg_set_vlen_data_int( 800*cb5caa98Sdjl void *src, 801*cb5caa98Sdjl void *dest, 802*cb5caa98Sdjl nscd_bool_t global) 803*cb5caa98Sdjl { 804*cb5caa98Sdjl int i, offset, dlen = 0; 805*cb5caa98Sdjl void *s, *d, *new; 806*cb5caa98Sdjl void *cptr; 807*cb5caa98Sdjl nscd_rc_t rc; 808*cb5caa98Sdjl nscd_cfg_param_desc_t *desc; 809*cb5caa98Sdjl 810*cb5caa98Sdjl desc = &_nscd_cfg_param_desc[0]; 811*cb5caa98Sdjl for (i = 0; i < _nscd_cfg_num_param; i++, desc++) { 812*cb5caa98Sdjl 813*cb5caa98Sdjl if (global == nscd_true && 814*cb5caa98Sdjl _nscd_cfg_flag_is_not_set(desc->pflag, 815*cb5caa98Sdjl NSCD_CFG_PFLAG_GLOBAL)) 816*cb5caa98Sdjl continue; 817*cb5caa98Sdjl else if (global != nscd_true && 818*cb5caa98Sdjl _nscd_cfg_flag_is_set(desc->pflag, 819*cb5caa98Sdjl NSCD_CFG_PFLAG_GLOBAL)) 820*cb5caa98Sdjl continue; 821*cb5caa98Sdjl 822*cb5caa98Sdjl if (_nscd_cfg_flag_is_set(desc->pflag, 823*cb5caa98Sdjl NSCD_CFG_PFLAG_VLEN_DATA)) { 824*cb5caa98Sdjl 825*cb5caa98Sdjl offset = desc->g_offset + desc->p_offset; 826*cb5caa98Sdjl 827*cb5caa98Sdjl s = (char *)src + offset; 828*cb5caa98Sdjl cptr = *(char **)s; 829*cb5caa98Sdjl 830*cb5caa98Sdjl rc = _nscd_cfg_copy_vlen_data(cptr, &new, 831*cb5caa98Sdjl desc, &dlen, nscd_true); 832*cb5caa98Sdjl if (rc != NSCD_SUCCESS) 833*cb5caa98Sdjl return (rc); 834*cb5caa98Sdjl 835*cb5caa98Sdjl d = (char *)dest + offset; 836*cb5caa98Sdjl /* free the old vlen data */ 837*cb5caa98Sdjl if (*(char **)d == NULL) 838*cb5caa98Sdjl _nscd_cfg_free_vlen_data_int(*(char **)d); 839*cb5caa98Sdjl 840*cb5caa98Sdjl *(char **)d = new; 841*cb5caa98Sdjl } 842*cb5caa98Sdjl } 843*cb5caa98Sdjl 844*cb5caa98Sdjl return (NSCD_SUCCESS); 845*cb5caa98Sdjl } 846*cb5caa98Sdjl 847*cb5caa98Sdjl static void * 848*cb5caa98Sdjl _nscd_cfg_locate_vlen_data( 849*cb5caa98Sdjl void *cfg_data, 850*cb5caa98Sdjl int *len) 851*cb5caa98Sdjl { 852*cb5caa98Sdjl void *ptr, *ret; 853*cb5caa98Sdjl 854*cb5caa98Sdjl ptr = *(char **)cfg_data; 855*cb5caa98Sdjl ret = ptr; 856*cb5caa98Sdjl if (ret == NULL) { 857*cb5caa98Sdjl *len = 0; 858*cb5caa98Sdjl return (NULL); 859*cb5caa98Sdjl } 860*cb5caa98Sdjl ptr = (char *)ptr - sizeof (nscd_cfg_vlen_data_t); 861*cb5caa98Sdjl *len = ((nscd_cfg_vlen_data_t *)ptr)->len; 862*cb5caa98Sdjl 863*cb5caa98Sdjl return (ret); 864*cb5caa98Sdjl } 865*cb5caa98Sdjl 866*cb5caa98Sdjl static void 867*cb5caa98Sdjl _nscd_cfg_lock( 868*cb5caa98Sdjl nscd_bool_t is_read, 869*cb5caa98Sdjl nscd_cfg_lock_t *cfglock) 870*cb5caa98Sdjl { 871*cb5caa98Sdjl 872*cb5caa98Sdjl int (*lockfunc)(rwlock_t *); 873*cb5caa98Sdjl 874*cb5caa98Sdjl if (cfglock == NULL) 875*cb5caa98Sdjl return; 876*cb5caa98Sdjl 877*cb5caa98Sdjl if (is_read == nscd_true) 878*cb5caa98Sdjl lockfunc = rw_rdlock; 879*cb5caa98Sdjl else 880*cb5caa98Sdjl lockfunc = rw_wrlock; 881*cb5caa98Sdjl 882*cb5caa98Sdjl if (cfglock->global != NULL) { 883*cb5caa98Sdjl 884*cb5caa98Sdjl (lockfunc)(cfglock->global); 885*cb5caa98Sdjl return; 886*cb5caa98Sdjl } 887*cb5caa98Sdjl 888*cb5caa98Sdjl if (cfglock->alldb != NULL) 889*cb5caa98Sdjl (lockfunc)(cfglock->alldb); 890*cb5caa98Sdjl 891*cb5caa98Sdjl if (cfglock->nswdb != NULL) 892*cb5caa98Sdjl (lockfunc)(cfglock->nswdb); 893*cb5caa98Sdjl } 894*cb5caa98Sdjl 895*cb5caa98Sdjl static void 896*cb5caa98Sdjl _nscd_cfg_unlock( 897*cb5caa98Sdjl nscd_cfg_lock_t *cfglock) 898*cb5caa98Sdjl { 899*cb5caa98Sdjl if (cfglock == NULL) 900*cb5caa98Sdjl return; 901*cb5caa98Sdjl 902*cb5caa98Sdjl if (cfglock->global != NULL) { 903*cb5caa98Sdjl 904*cb5caa98Sdjl (void) rw_unlock(cfglock->global); 905*cb5caa98Sdjl free(cfglock); 906*cb5caa98Sdjl return; 907*cb5caa98Sdjl } 908*cb5caa98Sdjl 909*cb5caa98Sdjl if (cfglock->nswdb != NULL) 910*cb5caa98Sdjl (void) rw_unlock(cfglock->nswdb); 911*cb5caa98Sdjl 912*cb5caa98Sdjl if (cfglock->alldb != NULL) 913*cb5caa98Sdjl (void) rw_unlock(cfglock->alldb); 914*cb5caa98Sdjl 915*cb5caa98Sdjl free(cfglock); 916*cb5caa98Sdjl } 917*cb5caa98Sdjl 918*cb5caa98Sdjl /* 919*cb5caa98Sdjl * If vlen_data_addr is given, it will be set to the 920*cb5caa98Sdjl * address of the pointer pointing to the vlen data. 921*cb5caa98Sdjl * 'cfglock' will be set to point to the reader/writer 922*cb5caa98Sdjl * lock(s) protecting the (group) configuration data. 923*cb5caa98Sdjl */ 924*cb5caa98Sdjl static nscd_rc_t 925*cb5caa98Sdjl _nscd_cfg_locate_cfg_data( 926*cb5caa98Sdjl void **cfg_data, 927*cb5caa98Sdjl nscd_bool_t is_read, 928*cb5caa98Sdjl nscd_cfg_param_desc_t *desc, 929*cb5caa98Sdjl nscd_cfg_id_t *nswdb, 930*cb5caa98Sdjl nscd_bool_t get_group, 931*cb5caa98Sdjl void **vlen_data_addr, 932*cb5caa98Sdjl int *len, 933*cb5caa98Sdjl nscd_cfg_lock_t **cfglock) 934*cb5caa98Sdjl { 935*cb5caa98Sdjl int offset; 936*cb5caa98Sdjl 937*cb5caa98Sdjl *cfg_data = NULL; 938*cb5caa98Sdjl if (len != NULL) 939*cb5caa98Sdjl *len = 0; 940*cb5caa98Sdjl if (vlen_data_addr != NULL) 941*cb5caa98Sdjl *vlen_data_addr = NULL; 942*cb5caa98Sdjl 943*cb5caa98Sdjl if (cfglock != NULL) { 944*cb5caa98Sdjl *cfglock = calloc(1, sizeof (nscd_cfg_lock_t)); 945*cb5caa98Sdjl if (*cfglock == NULL) 946*cb5caa98Sdjl return (NSCD_NO_MEMORY); 947*cb5caa98Sdjl } 948*cb5caa98Sdjl 949*cb5caa98Sdjl /* assume if nswdb is NULL, the param is a global one */ 950*cb5caa98Sdjl if (nswdb == NULL) { 951*cb5caa98Sdjl 952*cb5caa98Sdjl offset = desc->g_offset; 953*cb5caa98Sdjl if (get_group != nscd_true) 954*cb5caa98Sdjl offset += desc->p_offset; 955*cb5caa98Sdjl *cfg_data = (char *)nscd_cfg_global_current + offset; 956*cb5caa98Sdjl 957*cb5caa98Sdjl if (cfglock != NULL) 958*cb5caa98Sdjl (*cfglock)->global = nscd_cfg_global_rwlock; 959*cb5caa98Sdjl 960*cb5caa98Sdjl } else if (nswdb->index == NSCD_CFG_NSW_ALLDB_INDEX) { 961*cb5caa98Sdjl 962*cb5caa98Sdjl offset = desc->g_offset; 963*cb5caa98Sdjl if (get_group != nscd_true) 964*cb5caa98Sdjl offset += desc->p_offset; 965*cb5caa98Sdjl *cfg_data = (char *)nscd_cfg_nsw_alldb_current + 966*cb5caa98Sdjl offset; 967*cb5caa98Sdjl 968*cb5caa98Sdjl if (cfglock != NULL) 969*cb5caa98Sdjl (*cfglock)->alldb = nscd_cfg_nsw_alldb_rwlock; 970*cb5caa98Sdjl 971*cb5caa98Sdjl } else { 972*cb5caa98Sdjl 973*cb5caa98Sdjl offset = nswdb->index * 974*cb5caa98Sdjl (sizeof (nscd_cfg_nsw_db_data_t)) + desc->g_offset; 975*cb5caa98Sdjl if (get_group != nscd_true) 976*cb5caa98Sdjl offset += desc->p_offset; 977*cb5caa98Sdjl *cfg_data = (char *)nscd_cfg_nsw_db_data_current + 978*cb5caa98Sdjl offset; 979*cb5caa98Sdjl 980*cb5caa98Sdjl if (cfglock != NULL) { 981*cb5caa98Sdjl (*cfglock)->nswdb = 982*cb5caa98Sdjl &nscd_cfg_nsw_db_data_rwlock[nswdb->index]; 983*cb5caa98Sdjl 984*cb5caa98Sdjl (*cfglock)->alldb = nscd_cfg_nsw_alldb_rwlock; 985*cb5caa98Sdjl } 986*cb5caa98Sdjl } 987*cb5caa98Sdjl 988*cb5caa98Sdjl /* lock the config data */ 989*cb5caa98Sdjl if (cfglock != NULL) 990*cb5caa98Sdjl _nscd_cfg_lock(is_read, *cfglock); 991*cb5caa98Sdjl 992*cb5caa98Sdjl if (get_group != nscd_true && 993*cb5caa98Sdjl _nscd_cfg_flag_is_not_set(desc->pflag, 994*cb5caa98Sdjl NSCD_CFG_PFLAG_GROUP) && 995*cb5caa98Sdjl (_nscd_cfg_flag_is_set(desc->pflag, 996*cb5caa98Sdjl NSCD_CFG_PFLAG_VLEN_DATA))) { 997*cb5caa98Sdjl if (vlen_data_addr != NULL) 998*cb5caa98Sdjl *vlen_data_addr = *cfg_data; 999*cb5caa98Sdjl *cfg_data = _nscd_cfg_locate_vlen_data(*cfg_data, len); 1000*cb5caa98Sdjl return (NSCD_SUCCESS); 1001*cb5caa98Sdjl } 1002*cb5caa98Sdjl 1003*cb5caa98Sdjl if (len != NULL) { 1004*cb5caa98Sdjl if (get_group == nscd_true) 1005*cb5caa98Sdjl *len = desc->g_size; 1006*cb5caa98Sdjl else 1007*cb5caa98Sdjl *len = desc->p_size; 1008*cb5caa98Sdjl } 1009*cb5caa98Sdjl 1010*cb5caa98Sdjl return (NSCD_SUCCESS); 1011*cb5caa98Sdjl } 1012*cb5caa98Sdjl 1013*cb5caa98Sdjl /* 1014*cb5caa98Sdjl * perform the preliminary (range) check on 'data' based on the 1015*cb5caa98Sdjl * datatype (desc->datatype) of the config parameter 1016*cb5caa98Sdjl */ 1017*cb5caa98Sdjl nscd_rc_t 1018*cb5caa98Sdjl _nscd_cfg_prelim_check( 1019*cb5caa98Sdjl nscd_cfg_param_desc_t *desc, 1020*cb5caa98Sdjl void *data, 1021*cb5caa98Sdjl nscd_cfg_error_t **errorp) 1022*cb5caa98Sdjl { 1023*cb5caa98Sdjl 1024*cb5caa98Sdjl char *me = "_nscd_cfg_prelim_check"; 1025*cb5caa98Sdjl char msg[NSCD_CFG_MAX_ERR_MSG_LEN]; 1026*cb5caa98Sdjl nscd_cfg_str_check_t *sc; 1027*cb5caa98Sdjl nscd_cfg_int_check_t *ic; 1028*cb5caa98Sdjl nscd_cfg_bitmap_check_t *bmc; 1029*cb5caa98Sdjl nscd_rc_t rc = NSCD_CFG_PRELIM_CHECK_FAILED; 1030*cb5caa98Sdjl 1031*cb5caa98Sdjl if ((nscd_cfg_str_check_t *)desc->p_check == NULL) 1032*cb5caa98Sdjl return (NSCD_SUCCESS); 1033*cb5caa98Sdjl 1034*cb5caa98Sdjl switch (desc->type) { 1035*cb5caa98Sdjl 1036*cb5caa98Sdjl case NSCD_CFG_DATA_STRING: 1037*cb5caa98Sdjl 1038*cb5caa98Sdjl sc = (nscd_cfg_str_check_t *)desc->p_check; 1039*cb5caa98Sdjl if (sc->must_not_null == nscd_true && data == NULL) { 1040*cb5caa98Sdjl 1041*cb5caa98Sdjl if (errorp == NULL) 1042*cb5caa98Sdjl break; 1043*cb5caa98Sdjl 1044*cb5caa98Sdjl (void) snprintf(msg, sizeof (msg), 1045*cb5caa98Sdjl gettext("data must be specified for %s"), 1046*cb5caa98Sdjl desc->id.name); 1047*cb5caa98Sdjl 1048*cb5caa98Sdjl break; 1049*cb5caa98Sdjl } 1050*cb5caa98Sdjl 1051*cb5caa98Sdjl if (data == NULL) { 1052*cb5caa98Sdjl rc = NSCD_SUCCESS; 1053*cb5caa98Sdjl break; 1054*cb5caa98Sdjl } 1055*cb5caa98Sdjl 1056*cb5caa98Sdjl if (sc->maxlen != 0 && 1057*cb5caa98Sdjl strlen((char *)data) > sc->maxlen) { 1058*cb5caa98Sdjl 1059*cb5caa98Sdjl if (errorp == NULL) 1060*cb5caa98Sdjl break; 1061*cb5caa98Sdjl 1062*cb5caa98Sdjl (void) snprintf(msg, sizeof (msg), 1063*cb5caa98Sdjl gettext("length of data (%s) for %s larger than %d"), 1064*cb5caa98Sdjl (char *)data, desc->id.name, sc->maxlen); 1065*cb5caa98Sdjl break; 1066*cb5caa98Sdjl } 1067*cb5caa98Sdjl 1068*cb5caa98Sdjl rc = NSCD_SUCCESS; 1069*cb5caa98Sdjl 1070*cb5caa98Sdjl break; 1071*cb5caa98Sdjl 1072*cb5caa98Sdjl case NSCD_CFG_DATA_INTEGER: 1073*cb5caa98Sdjl 1074*cb5caa98Sdjl ic = (nscd_cfg_int_check_t *)desc->p_check; 1075*cb5caa98Sdjl if (*(int *)data > ic->max || 1076*cb5caa98Sdjl *(int *)data < ic->min) { 1077*cb5caa98Sdjl 1078*cb5caa98Sdjl if (errorp == NULL) 1079*cb5caa98Sdjl break; 1080*cb5caa98Sdjl 1081*cb5caa98Sdjl (void) snprintf(msg, sizeof (msg), 1082*cb5caa98Sdjl gettext("data (%d) for %s out of range (%d - %d)"), 1083*cb5caa98Sdjl *(int *)data, desc->id.name, 1084*cb5caa98Sdjl ic->min, ic->max); 1085*cb5caa98Sdjl 1086*cb5caa98Sdjl break; 1087*cb5caa98Sdjl } 1088*cb5caa98Sdjl 1089*cb5caa98Sdjl rc = NSCD_SUCCESS; 1090*cb5caa98Sdjl 1091*cb5caa98Sdjl break; 1092*cb5caa98Sdjl 1093*cb5caa98Sdjl case NSCD_CFG_DATA_BITMAP: 1094*cb5caa98Sdjl 1095*cb5caa98Sdjl bmc = (nscd_cfg_bitmap_check_t *)desc->p_check; 1096*cb5caa98Sdjl if (_nscd_cfg_bitmap_value(*(nscd_cfg_bitmap_t *)data) & 1097*cb5caa98Sdjl ~(bmc->valid_bits)) { 1098*cb5caa98Sdjl 1099*cb5caa98Sdjl if (errorp == NULL) 1100*cb5caa98Sdjl break; 1101*cb5caa98Sdjl 1102*cb5caa98Sdjl (void) snprintf(msg, sizeof (msg), 1103*cb5caa98Sdjl gettext("data (%#6.4x) for %s contain bit not in 0x%x"), 1104*cb5caa98Sdjl _nscd_cfg_bitmap_value( 1105*cb5caa98Sdjl *(nscd_cfg_bitmap_t *)data), 1106*cb5caa98Sdjl desc->id.name, 1107*cb5caa98Sdjl _nscd_cfg_bitmap_value(bmc->valid_bits)); 1108*cb5caa98Sdjl break; 1109*cb5caa98Sdjl } 1110*cb5caa98Sdjl 1111*cb5caa98Sdjl rc = NSCD_SUCCESS; 1112*cb5caa98Sdjl 1113*cb5caa98Sdjl break; 1114*cb5caa98Sdjl } 1115*cb5caa98Sdjl 1116*cb5caa98Sdjl if (rc != NSCD_SUCCESS && errorp != NULL) { 1117*cb5caa98Sdjl *errorp = _nscd_cfg_make_error(rc, msg); 1118*cb5caa98Sdjl 1119*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_DEBUG) 1120*cb5caa98Sdjl (me, "invalid argument: %s\n", (*errorp)->msg); 1121*cb5caa98Sdjl } 1122*cb5caa98Sdjl 1123*cb5caa98Sdjl return (rc); 1124*cb5caa98Sdjl } 1125*cb5caa98Sdjl 1126*cb5caa98Sdjl static nscd_rc_t 1127*cb5caa98Sdjl _nscd_cfg_notify_i( 1128*cb5caa98Sdjl nscd_cfg_param_desc_t *desc, 1129*cb5caa98Sdjl nscd_cfg_id_t *nswdb, 1130*cb5caa98Sdjl int *skip, 1131*cb5caa98Sdjl nscd_cfg_error_t **errorp) 1132*cb5caa98Sdjl { 1133*cb5caa98Sdjl 1134*cb5caa98Sdjl char *me = "_nscd_cfg_notify_i"; 1135*cb5caa98Sdjl int i, num, skip_bk; 1136*cb5caa98Sdjl void *cfg_data, *cdata; 1137*cb5caa98Sdjl void *cookie = NULL; 1138*cb5caa98Sdjl nscd_rc_t rc; 1139*cb5caa98Sdjl nscd_cfg_flag_t dflag, dflag1; 1140*cb5caa98Sdjl nscd_cfg_bitmap_t bitmap_c, bitmap_s, *bitmap_addr; 1141*cb5caa98Sdjl nscd_cfg_group_info_t *gi; 1142*cb5caa98Sdjl 1143*cb5caa98Sdjl if (errorp != NULL) 1144*cb5caa98Sdjl *errorp = NULL; 1145*cb5caa98Sdjl 1146*cb5caa98Sdjl if (skip == NULL) 1147*cb5caa98Sdjl skip = &skip_bk; 1148*cb5caa98Sdjl 1149*cb5caa98Sdjl *skip = 0; 1150*cb5caa98Sdjl 1151*cb5caa98Sdjl if (_nscd_cfg_flag_is_not_set(desc->pflag, 1152*cb5caa98Sdjl NSCD_CFG_PFLAG_GROUP)) { 1153*cb5caa98Sdjl 1154*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 1155*cb5caa98Sdjl (me, "ERROR: expect parameter description for group, " 1156*cb5caa98Sdjl "but receive parameter description is for %s\n", 1157*cb5caa98Sdjl desc->id.name); 1158*cb5caa98Sdjl 1159*cb5caa98Sdjl return (NSCD_CFG_PARAM_DESC_ERROR); 1160*cb5caa98Sdjl } 1161*cb5caa98Sdjl 1162*cb5caa98Sdjl /* 1163*cb5caa98Sdjl * Set data flag going with data to be sent to the 1164*cb5caa98Sdjl * verify/notify routines. Allowing the config flag 1165*cb5caa98Sdjl * be exipandable, set the bits one by one. 1166*cb5caa98Sdjl */ 1167*cb5caa98Sdjl dflag = NSCD_CFG_FLAG_ZERO; 1168*cb5caa98Sdjl dflag = _nscd_cfg_flag_set(dflag, NSCD_CFG_DFLAG_STATIC_DATA); 1169*cb5caa98Sdjl dflag = _nscd_cfg_flag_set(dflag, NSCD_CFG_DFLAG_INIT); 1170*cb5caa98Sdjl dflag = _nscd_cfg_flag_set(dflag, NSCD_CFG_DFLAG_GROUP); 1171*cb5caa98Sdjl if (_nscd_cfg_flag_is_set(desc->pflag, 1172*cb5caa98Sdjl NSCD_CFG_PFLAG_INIT_SET_ALL_DB)) 1173*cb5caa98Sdjl dflag = _nscd_cfg_flag_set(dflag, 1174*cb5caa98Sdjl NSCD_CFG_DFLAG_SET_ALL_DB); 1175*cb5caa98Sdjl 1176*cb5caa98Sdjl /* get to the group data in the config store */ 1177*cb5caa98Sdjl rc = _nscd_cfg_locate_cfg_data(&cfg_data, nscd_true, 1178*cb5caa98Sdjl desc, nswdb, nscd_true, NULL, NULL, NULL); 1179*cb5caa98Sdjl if (rc != NSCD_SUCCESS) 1180*cb5caa98Sdjl goto error; 1181*cb5caa98Sdjl 1182*cb5caa98Sdjl /* 1183*cb5caa98Sdjl * the static bitmap associated with the group 1184*cb5caa98Sdjl * may be replaced before sending to the components, 1185*cb5caa98Sdjl * so save the bitmap for later use 1186*cb5caa98Sdjl */ 1187*cb5caa98Sdjl gi = _nscd_cfg_get_gi(cfg_data); 1188*cb5caa98Sdjl bitmap_c = gi->bitmap; 1189*cb5caa98Sdjl bitmap_addr = &(gi->bitmap); 1190*cb5caa98Sdjl 1191*cb5caa98Sdjl /* 1192*cb5caa98Sdjl * the elements in this group will all be handled 1193*cb5caa98Sdjl * so the caller can skip them 1194*cb5caa98Sdjl */ 1195*cb5caa98Sdjl *skip = desc->p_fn; 1196*cb5caa98Sdjl 1197*cb5caa98Sdjl if (_nscd_cfg_flag_is_set(desc->pflag, 1198*cb5caa98Sdjl NSCD_CFG_PFLAG_INIT_SEND_WHOLE_GROUP)) 1199*cb5caa98Sdjl /* send the entire group just once */ 1200*cb5caa98Sdjl num = 1; 1201*cb5caa98Sdjl 1202*cb5caa98Sdjl else { /* send individual members one by one */ 1203*cb5caa98Sdjl 1204*cb5caa98Sdjl num = desc->p_fn; 1205*cb5caa98Sdjl 1206*cb5caa98Sdjl /* 1207*cb5caa98Sdjl * skip the first desc which is for the group 1208*cb5caa98Sdjl * and get to the desc for the first member 1209*cb5caa98Sdjl */ 1210*cb5caa98Sdjl desc++; 1211*cb5caa98Sdjl 1212*cb5caa98Sdjl dflag = _nscd_cfg_flag_unset(dflag, 1213*cb5caa98Sdjl NSCD_CFG_DFLAG_GROUP); 1214*cb5caa98Sdjl } 1215*cb5caa98Sdjl 1216*cb5caa98Sdjl dflag1 = dflag; 1217*cb5caa98Sdjl for (i = 0; i < num; i++, desc++) { 1218*cb5caa98Sdjl 1219*cb5caa98Sdjl dflag = dflag1; 1220*cb5caa98Sdjl 1221*cb5caa98Sdjl if (_nscd_cfg_flag_is_set(desc->pflag, 1222*cb5caa98Sdjl NSCD_CFG_PFLAG_SEND_BIT_SELECTED)) { 1223*cb5caa98Sdjl 1224*cb5caa98Sdjl /* set the bitmap to select just this member */ 1225*cb5caa98Sdjl bitmap_s = NSCD_CFG_BITMAP_ZERO; 1226*cb5caa98Sdjl _nscd_cfg_bitmap_set_nth(bitmap_s, i); 1227*cb5caa98Sdjl /* replace the bitmap in the cfg data */ 1228*cb5caa98Sdjl _nscd_cfg_bitmap_set(bitmap_addr, bitmap_s); 1229*cb5caa98Sdjl 1230*cb5caa98Sdjl /* 1231*cb5caa98Sdjl * send the whole group but with only one 1232*cb5caa98Sdjl * member selected 1233*cb5caa98Sdjl */ 1234*cb5caa98Sdjl cdata = cfg_data; 1235*cb5caa98Sdjl 1236*cb5caa98Sdjl dflag = _nscd_cfg_flag_set(dflag, 1237*cb5caa98Sdjl NSCD_CFG_DFLAG_GROUP); 1238*cb5caa98Sdjl dflag = _nscd_cfg_flag_set(dflag, 1239*cb5caa98Sdjl NSCD_CFG_DFLAG_BIT_SELECTED); 1240*cb5caa98Sdjl } else { 1241*cb5caa98Sdjl /* 1242*cb5caa98Sdjl * send param data or group data: 1243*cb5caa98Sdjl * param data - non-xero desc->p_offset 1244*cb5caa98Sdjl * group data - zero desc->p_offset 1245*cb5caa98Sdjl */ 1246*cb5caa98Sdjl cdata = (char *)cfg_data + desc->p_offset; 1247*cb5caa98Sdjl 1248*cb5caa98Sdjl /* 1249*cb5caa98Sdjl * if variable length data, need to send pointer 1250*cb5caa98Sdjl * to the data (not the address of the pointer) 1251*cb5caa98Sdjl */ 1252*cb5caa98Sdjl if (_nscd_cfg_flag_is_set(desc->pflag, 1253*cb5caa98Sdjl NSCD_CFG_PFLAG_VLEN_DATA)) 1254*cb5caa98Sdjl cdata = *(char **)cdata; 1255*cb5caa98Sdjl } 1256*cb5caa98Sdjl 1257*cb5caa98Sdjl if (desc->verify != NULL) { 1258*cb5caa98Sdjl dflag = _nscd_cfg_flag_set(dflag, 1259*cb5caa98Sdjl NSCD_CFG_DFLAG_VERIFY); 1260*cb5caa98Sdjl rc = desc->verify(cdata, desc, nswdb, 1261*cb5caa98Sdjl dflag, errorp, &cookie); 1262*cb5caa98Sdjl if (rc != NSCD_SUCCESS) 1263*cb5caa98Sdjl goto error; 1264*cb5caa98Sdjl } 1265*cb5caa98Sdjl 1266*cb5caa98Sdjl if (desc->notify != NULL) { 1267*cb5caa98Sdjl dflag = _nscd_cfg_flag_set(dflag, 1268*cb5caa98Sdjl NSCD_CFG_DFLAG_NOTIFY); 1269*cb5caa98Sdjl 1270*cb5caa98Sdjl rc = desc->notify(cfg_data, desc, nswdb, 1271*cb5caa98Sdjl dflag, errorp, cookie); 1272*cb5caa98Sdjl if (rc != NSCD_SUCCESS) 1273*cb5caa98Sdjl goto error; 1274*cb5caa98Sdjl } 1275*cb5caa98Sdjl } 1276*cb5caa98Sdjl 1277*cb5caa98Sdjl rc = NSCD_SUCCESS; 1278*cb5caa98Sdjl 1279*cb5caa98Sdjl /* restore the bitmap in the cfg data */ 1280*cb5caa98Sdjl _nscd_cfg_bitmap_set(bitmap_addr, bitmap_c); 1281*cb5caa98Sdjl 1282*cb5caa98Sdjl error: 1283*cb5caa98Sdjl 1284*cb5caa98Sdjl return (rc); 1285*cb5caa98Sdjl 1286*cb5caa98Sdjl } 1287*cb5caa98Sdjl 1288*cb5caa98Sdjl static nscd_rc_t 1289*cb5caa98Sdjl _nscd_cfg_notify_init( 1290*cb5caa98Sdjl nscd_cfg_error_t **errorp) 1291*cb5caa98Sdjl { 1292*cb5caa98Sdjl int i, j, skip; 1293*cb5caa98Sdjl nscd_rc_t rc; 1294*cb5caa98Sdjl nscd_cfg_id_t *nswdb = NULL; 1295*cb5caa98Sdjl nscd_cfg_param_desc_t *desc; 1296*cb5caa98Sdjl 1297*cb5caa98Sdjl if (errorp != NULL) 1298*cb5caa98Sdjl *errorp = NULL; 1299*cb5caa98Sdjl 1300*cb5caa98Sdjl for (i = 0; i < _nscd_cfg_num_param; i++) { 1301*cb5caa98Sdjl 1302*cb5caa98Sdjl desc = &_nscd_cfg_param_desc[i]; 1303*cb5caa98Sdjl 1304*cb5caa98Sdjl if (_nscd_cfg_flag_is_set(desc->pflag, 1305*cb5caa98Sdjl NSCD_CFG_PFLAG_GLOBAL)) { /* global cfg data */ 1306*cb5caa98Sdjl 1307*cb5caa98Sdjl rc = _nscd_cfg_notify_i(desc, NULL, &skip, errorp); 1308*cb5caa98Sdjl } else { 1309*cb5caa98Sdjl 1310*cb5caa98Sdjl /* 1311*cb5caa98Sdjl * if use defaults for all nsswitch database, 1312*cb5caa98Sdjl * send the config data to verify/notify once 1313*cb5caa98Sdjl */ 1314*cb5caa98Sdjl if (_nscd_cfg_flag_is_set(desc->pflag, 1315*cb5caa98Sdjl NSCD_CFG_PFLAG_INIT_SET_ALL_DB)) { 1316*cb5caa98Sdjl 1317*cb5caa98Sdjl nswdb = &_nscd_cfg_nsw_alldb; 1318*cb5caa98Sdjl 1319*cb5caa98Sdjl rc = _nscd_cfg_notify_i(desc, nswdb, 1320*cb5caa98Sdjl &skip, errorp); 1321*cb5caa98Sdjl } else { /* send data once for each nsw db */ 1322*cb5caa98Sdjl 1323*cb5caa98Sdjl for (j = 0; j < _nscd_cfg_num_nsw_db; 1324*cb5caa98Sdjl j++) { 1325*cb5caa98Sdjl 1326*cb5caa98Sdjl nswdb = &_nscd_cfg_nsw_db[j]; 1327*cb5caa98Sdjl 1328*cb5caa98Sdjl rc = _nscd_cfg_notify_i(desc, 1329*cb5caa98Sdjl nswdb, &skip, errorp); 1330*cb5caa98Sdjl } 1331*cb5caa98Sdjl } 1332*cb5caa98Sdjl } 1333*cb5caa98Sdjl 1334*cb5caa98Sdjl if (rc != NSCD_SUCCESS) 1335*cb5caa98Sdjl return (rc); 1336*cb5caa98Sdjl 1337*cb5caa98Sdjl i += skip; 1338*cb5caa98Sdjl } 1339*cb5caa98Sdjl 1340*cb5caa98Sdjl return (NSCD_SUCCESS); 1341*cb5caa98Sdjl } 1342*cb5caa98Sdjl 1343*cb5caa98Sdjl nscd_rc_t 1344*cb5caa98Sdjl _nscd_cfg_init( 1345*cb5caa98Sdjl nscd_cfg_error_t **errorp) 1346*cb5caa98Sdjl { 1347*cb5caa98Sdjl 1348*cb5caa98Sdjl int i, j, datalen; 1349*cb5caa98Sdjl int dbi = 0, dbj = 0; 1350*cb5caa98Sdjl char *dest, *src; 1351*cb5caa98Sdjl char *dbni = NULL, *dbnj = NULL; 1352*cb5caa98Sdjl nscd_rc_t rc; 1353*cb5caa98Sdjl nscd_cfg_nsw_spc_default_t *spc; 1354*cb5caa98Sdjl 1355*cb5caa98Sdjl if (errorp != NULL) 1356*cb5caa98Sdjl *errorp = NULL; 1357*cb5caa98Sdjl 1358*cb5caa98Sdjl rc = _nscd_cfg_init_param(); 1359*cb5caa98Sdjl if (rc != NSCD_SUCCESS) 1360*cb5caa98Sdjl return (rc); 1361*cb5caa98Sdjl 1362*cb5caa98Sdjl rc = _nscd_cfg_init_stat(); 1363*cb5caa98Sdjl if (rc != NSCD_SUCCESS) 1364*cb5caa98Sdjl return (rc); 1365*cb5caa98Sdjl 1366*cb5caa98Sdjl nscd_cfg_global_current = calloc(1, 1367*cb5caa98Sdjl sizeof (nscd_cfg_global_data_t)); 1368*cb5caa98Sdjl if (nscd_cfg_global_current == NULL) 1369*cb5caa98Sdjl return (NSCD_NO_MEMORY); 1370*cb5caa98Sdjl 1371*cb5caa98Sdjl nscd_cfg_nsw_alldb_current = calloc(1, 1372*cb5caa98Sdjl sizeof (nscd_cfg_nsw_db_data_t)); 1373*cb5caa98Sdjl if (nscd_cfg_nsw_alldb_current == NULL) 1374*cb5caa98Sdjl return (NSCD_NO_MEMORY); 1375*cb5caa98Sdjl 1376*cb5caa98Sdjl nscd_cfg_nsw_db_data_current = calloc(_nscd_cfg_num_nsw_db, 1377*cb5caa98Sdjl sizeof (nscd_cfg_nsw_db_data_t)); 1378*cb5caa98Sdjl if (nscd_cfg_nsw_db_data_current == NULL) 1379*cb5caa98Sdjl return (NSCD_NO_MEMORY); 1380*cb5caa98Sdjl 1381*cb5caa98Sdjl nscd_cfg_global_rwlock = calloc(1, sizeof (rwlock_t)); 1382*cb5caa98Sdjl if (nscd_cfg_global_rwlock == NULL) 1383*cb5caa98Sdjl return (NSCD_NO_MEMORY); 1384*cb5caa98Sdjl (void) rwlock_init(nscd_cfg_global_rwlock, NULL, NULL); 1385*cb5caa98Sdjl 1386*cb5caa98Sdjl *nscd_cfg_global_current = nscd_cfg_global_default; 1387*cb5caa98Sdjl 1388*cb5caa98Sdjl rc = _nscd_cfg_set_vlen_data_int(&nscd_cfg_global_default, 1389*cb5caa98Sdjl nscd_cfg_global_current, nscd_true); 1390*cb5caa98Sdjl if (rc != NSCD_SUCCESS) 1391*cb5caa98Sdjl return (rc); 1392*cb5caa98Sdjl 1393*cb5caa98Sdjl nscd_cfg_nsw_db_data_rwlock = calloc(_nscd_cfg_num_nsw_db, 1394*cb5caa98Sdjl sizeof (rwlock_t)); 1395*cb5caa98Sdjl if (nscd_cfg_nsw_db_data_rwlock == NULL) 1396*cb5caa98Sdjl return (NSCD_NO_MEMORY); 1397*cb5caa98Sdjl 1398*cb5caa98Sdjl /* set per switch db config to the default for all db's */ 1399*cb5caa98Sdjl for (i = 0; i < _nscd_cfg_num_nsw_db; i++) { 1400*cb5caa98Sdjl 1401*cb5caa98Sdjl nscd_cfg_nsw_db_data_current[i] = 1402*cb5caa98Sdjl nscd_cfg_nsw_db_data_default; 1403*cb5caa98Sdjl 1404*cb5caa98Sdjl (void) rwlock_init(&nscd_cfg_nsw_db_data_rwlock[i], 1405*cb5caa98Sdjl NULL, NULL); 1406*cb5caa98Sdjl } 1407*cb5caa98Sdjl 1408*cb5caa98Sdjl /* add db specific defaults */ 1409*cb5caa98Sdjl for (i = 0; i < _nscd_cfg_num_nsw_default; i++) { 1410*cb5caa98Sdjl 1411*cb5caa98Sdjl if (_nscd_cfg_nsw_spc_default[i].data == NULL) 1412*cb5caa98Sdjl continue; 1413*cb5caa98Sdjl 1414*cb5caa98Sdjl if (_nscd_cfg_nsw_spc_default[i].db != dbni) { 1415*cb5caa98Sdjl for (j = 0; j < _nscd_cfg_num_nsw_db; j++) { 1416*cb5caa98Sdjl 1417*cb5caa98Sdjl if (strcmp(_nscd_cfg_nsw_db[j].name, 1418*cb5caa98Sdjl _nscd_cfg_nsw_spc_default[i].db) != 0) 1419*cb5caa98Sdjl continue; 1420*cb5caa98Sdjl 1421*cb5caa98Sdjl dbi = _nscd_cfg_nsw_db[j].index; 1422*cb5caa98Sdjl dbni = _nscd_cfg_nsw_db[j].name; 1423*cb5caa98Sdjl break; 1424*cb5caa98Sdjl } 1425*cb5caa98Sdjl } 1426*cb5caa98Sdjl 1427*cb5caa98Sdjl dest = (char *)&nscd_cfg_nsw_db_data_current[dbi] + 1428*cb5caa98Sdjl _nscd_cfg_nsw_spc_default[i].group_off + 1429*cb5caa98Sdjl _nscd_cfg_nsw_spc_default[i].param_off; 1430*cb5caa98Sdjl 1431*cb5caa98Sdjl src = _nscd_cfg_nsw_spc_default[i].data; 1432*cb5caa98Sdjl datalen = _nscd_cfg_nsw_spc_default[i].data_len; 1433*cb5caa98Sdjl 1434*cb5caa98Sdjl (void) memcpy(dest, src, datalen); 1435*cb5caa98Sdjl } 1436*cb5caa98Sdjl 1437*cb5caa98Sdjl /* add db specific defaults via links */ 1438*cb5caa98Sdjl for (i = 0; i < _nscd_cfg_num_link_default; i++) { 1439*cb5caa98Sdjl 1440*cb5caa98Sdjl if (_nscd_cfg_nsw_link_default[i].data == NULL) 1441*cb5caa98Sdjl continue; 1442*cb5caa98Sdjl 1443*cb5caa98Sdjl spc = _nscd_cfg_nsw_link_default[i].data; 1444*cb5caa98Sdjl 1445*cb5caa98Sdjl if (_nscd_cfg_nsw_link_default[i].db != dbni) { 1446*cb5caa98Sdjl for (j = 0; j < _nscd_cfg_num_nsw_db; j++) { 1447*cb5caa98Sdjl 1448*cb5caa98Sdjl if (strcmp(_nscd_cfg_nsw_db[j].name, 1449*cb5caa98Sdjl _nscd_cfg_nsw_link_default[i].db) != 0) 1450*cb5caa98Sdjl continue; 1451*cb5caa98Sdjl 1452*cb5caa98Sdjl dbi = _nscd_cfg_nsw_db[j].index; 1453*cb5caa98Sdjl dbni = _nscd_cfg_nsw_db[j].name; 1454*cb5caa98Sdjl break; 1455*cb5caa98Sdjl } 1456*cb5caa98Sdjl } 1457*cb5caa98Sdjl 1458*cb5caa98Sdjl dest = (char *)&nscd_cfg_nsw_db_data_current[dbi] + 1459*cb5caa98Sdjl _nscd_cfg_nsw_link_default[i].group_off + 1460*cb5caa98Sdjl _nscd_cfg_nsw_link_default[i].param_off; 1461*cb5caa98Sdjl 1462*cb5caa98Sdjl if (_nscd_cfg_nsw_db[j].name != dbnj) { 1463*cb5caa98Sdjl for (j = 0; j < _nscd_cfg_num_nsw_db; j++) { 1464*cb5caa98Sdjl 1465*cb5caa98Sdjl if (strcmp(spc->db, 1466*cb5caa98Sdjl _nscd_cfg_nsw_db[j].name) != 0) 1467*cb5caa98Sdjl continue; 1468*cb5caa98Sdjl 1469*cb5caa98Sdjl dbnj = _nscd_cfg_nsw_db[j].name; 1470*cb5caa98Sdjl dbj = _nscd_cfg_nsw_db[j].index; 1471*cb5caa98Sdjl break; 1472*cb5caa98Sdjl } 1473*cb5caa98Sdjl } 1474*cb5caa98Sdjl 1475*cb5caa98Sdjl src = (char *)&nscd_cfg_nsw_db_data_current[dbj] + 1476*cb5caa98Sdjl spc->group_off + spc->param_off; 1477*cb5caa98Sdjl datalen = spc->data_len; 1478*cb5caa98Sdjl 1479*cb5caa98Sdjl (void) memcpy(dest, src, datalen); 1480*cb5caa98Sdjl } 1481*cb5caa98Sdjl 1482*cb5caa98Sdjl /* fix up variable length fields */ 1483*cb5caa98Sdjl for (i = 0; i < _nscd_cfg_num_nsw_db; i++) { 1484*cb5caa98Sdjl 1485*cb5caa98Sdjl rc = _nscd_cfg_set_vlen_data_int( 1486*cb5caa98Sdjl &nscd_cfg_nsw_db_data_current[i], 1487*cb5caa98Sdjl &nscd_cfg_nsw_db_data_current[i], nscd_false); 1488*cb5caa98Sdjl if (rc != NSCD_SUCCESS) 1489*cb5caa98Sdjl return (rc); 1490*cb5caa98Sdjl } 1491*cb5caa98Sdjl 1492*cb5caa98Sdjl nscd_cfg_nsw_alldb_rwlock = calloc(1, sizeof (rwlock_t)); 1493*cb5caa98Sdjl if (nscd_cfg_nsw_alldb_rwlock == NULL) 1494*cb5caa98Sdjl return (NSCD_NO_MEMORY); 1495*cb5caa98Sdjl 1496*cb5caa98Sdjl (void) rwlock_init(nscd_cfg_nsw_alldb_rwlock, NULL, NULL); 1497*cb5caa98Sdjl 1498*cb5caa98Sdjl rc = _nscd_cfg_set_vlen_data_int( 1499*cb5caa98Sdjl &nscd_cfg_nsw_db_data_default, 1500*cb5caa98Sdjl &nscd_cfg_nsw_alldb_current, nscd_false); 1501*cb5caa98Sdjl if (rc != NSCD_SUCCESS) 1502*cb5caa98Sdjl return (rc); 1503*cb5caa98Sdjl 1504*cb5caa98Sdjl /* 1505*cb5caa98Sdjl * notify and send the configuration data to 1506*cb5caa98Sdjl * the nscd components 1507*cb5caa98Sdjl */ 1508*cb5caa98Sdjl rc = _nscd_cfg_notify_init(errorp); 1509*cb5caa98Sdjl if (rc != NSCD_SUCCESS) 1510*cb5caa98Sdjl return (rc); 1511*cb5caa98Sdjl 1512*cb5caa98Sdjl return (NSCD_SUCCESS); 1513*cb5caa98Sdjl } 1514*cb5caa98Sdjl 1515*cb5caa98Sdjl static nscd_rc_t 1516*cb5caa98Sdjl _nscd_cfg_get_handle_common( 1517*cb5caa98Sdjl nscd_cfg_list_type_t type, 1518*cb5caa98Sdjl char *name, 1519*cb5caa98Sdjl char *nswdb_name, 1520*cb5caa98Sdjl nscd_cfg_handle_t **handle, 1521*cb5caa98Sdjl nscd_cfg_error_t **errorp) 1522*cb5caa98Sdjl { 1523*cb5caa98Sdjl 1524*cb5caa98Sdjl int i, is_global; 1525*cb5caa98Sdjl char *desc_str; 1526*cb5caa98Sdjl nscd_cfg_handle_t *h; 1527*cb5caa98Sdjl nscd_cfg_param_desc_t *pdesc; 1528*cb5caa98Sdjl nscd_cfg_stat_desc_t *sdesc; 1529*cb5caa98Sdjl char *me = "_nscd_cfg_get_handle_common"; 1530*cb5caa98Sdjl char msg[NSCD_CFG_MAX_ERR_MSG_LEN]; 1531*cb5caa98Sdjl nscd_rc_t rc = NSCD_INVALID_ARGUMENT; 1532*cb5caa98Sdjl 1533*cb5caa98Sdjl if (handle == NULL) { 1534*cb5caa98Sdjl 1535*cb5caa98Sdjl (void) snprintf(msg, sizeof (msg), 1536*cb5caa98Sdjl gettext("address of handle not specified")); 1537*cb5caa98Sdjl if (errorp) 1538*cb5caa98Sdjl *errorp = _nscd_cfg_make_error(rc, msg); 1539*cb5caa98Sdjl 1540*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_DEBUG) 1541*cb5caa98Sdjl (me, "invalid argument: %s\n", msg); 1542*cb5caa98Sdjl 1543*cb5caa98Sdjl return (rc); 1544*cb5caa98Sdjl } 1545*cb5caa98Sdjl 1546*cb5caa98Sdjl *handle = NULL; 1547*cb5caa98Sdjl 1548*cb5caa98Sdjl if (name == NULL) { 1549*cb5caa98Sdjl 1550*cb5caa98Sdjl (void) snprintf(msg, sizeof (msg), 1551*cb5caa98Sdjl gettext("name not specified")); 1552*cb5caa98Sdjl if (errorp) 1553*cb5caa98Sdjl *errorp = _nscd_cfg_make_error(rc, msg); 1554*cb5caa98Sdjl 1555*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_DEBUG) 1556*cb5caa98Sdjl (me, "invalid argument: %s\n"); 1557*cb5caa98Sdjl 1558*cb5caa98Sdjl return (rc); 1559*cb5caa98Sdjl } 1560*cb5caa98Sdjl 1561*cb5caa98Sdjl h = calloc(1, sizeof (nscd_cfg_handle_t)); 1562*cb5caa98Sdjl if (h == NULL) 1563*cb5caa98Sdjl return (NSCD_NO_MEMORY); 1564*cb5caa98Sdjl h->type = type; 1565*cb5caa98Sdjl 1566*cb5caa98Sdjl if (type == NSCD_CFG_LIST_PARAM) 1567*cb5caa98Sdjl desc_str = gettext("configuration parameter"); 1568*cb5caa98Sdjl else 1569*cb5caa98Sdjl desc_str = gettext("statistics"); 1570*cb5caa98Sdjl 1571*cb5caa98Sdjl /* get param or stat descriptor */ 1572*cb5caa98Sdjl i = _nscd_cfg_get_index(name, type); 1573*cb5caa98Sdjl if (i != -1) { 1574*cb5caa98Sdjl 1575*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_DEBUG) 1576*cb5caa98Sdjl (me, "%s: index of %s is %d\n", desc_str, name, i); 1577*cb5caa98Sdjl 1578*cb5caa98Sdjl if (type == NSCD_CFG_LIST_PARAM) { 1579*cb5caa98Sdjl pdesc = &_nscd_cfg_param_desc[i]; 1580*cb5caa98Sdjl (void) memcpy(&h->desc, &pdesc, sizeof (pdesc)); 1581*cb5caa98Sdjl is_global = _nscd_cfg_flag_is_set( 1582*cb5caa98Sdjl pdesc->pflag, NSCD_CFG_PFLAG_GLOBAL); 1583*cb5caa98Sdjl 1584*cb5caa98Sdjl /* hidden params are not exposed */ 1585*cb5caa98Sdjl if (_nscd_cfg_flag_is_set( 1586*cb5caa98Sdjl pdesc->pflag, NSCD_CFG_PFLAG_HIDDEN)) 1587*cb5caa98Sdjl i = -1; 1588*cb5caa98Sdjl 1589*cb5caa98Sdjl if (_nscd_cfg_flag_is_set(pdesc->pflag, 1590*cb5caa98Sdjl NSCD_CFG_PFLAG_OBSOLETE)) { 1591*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, 1592*cb5caa98Sdjl NSCD_LOG_LEVEL_WARNING) 1593*cb5caa98Sdjl (me, 1594*cb5caa98Sdjl gettext("%s: %s is obsolete and will be ignored\n"), 1595*cb5caa98Sdjl desc_str, name); 1596*cb5caa98Sdjl } 1597*cb5caa98Sdjl } else { 1598*cb5caa98Sdjl sdesc = &_nscd_cfg_stat_desc[i]; 1599*cb5caa98Sdjl (void) memcpy(&h->desc, &sdesc, sizeof (sdesc)); 1600*cb5caa98Sdjl is_global = _nscd_cfg_flag_is_set( 1601*cb5caa98Sdjl sdesc->sflag, NSCD_CFG_SFLAG_GLOBAL); 1602*cb5caa98Sdjl } 1603*cb5caa98Sdjl } 1604*cb5caa98Sdjl 1605*cb5caa98Sdjl if (i == -1) { 1606*cb5caa98Sdjl 1607*cb5caa98Sdjl (void) snprintf(msg, sizeof (msg), 1608*cb5caa98Sdjl gettext("%s: unknown name \"%s\""), desc_str, name); 1609*cb5caa98Sdjl if (errorp) 1610*cb5caa98Sdjl *errorp = _nscd_cfg_make_error(rc, msg); 1611*cb5caa98Sdjl 1612*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 1613*cb5caa98Sdjl (me, "%s\n", msg); 1614*cb5caa98Sdjl 1615*cb5caa98Sdjl free(h); 1616*cb5caa98Sdjl return (rc); 1617*cb5caa98Sdjl } 1618*cb5caa98Sdjl 1619*cb5caa98Sdjl /* 1620*cb5caa98Sdjl * if the param/stat is not a global one, we need to 1621*cb5caa98Sdjl * know which nsswitch database we are dealing with 1622*cb5caa98Sdjl */ 1623*cb5caa98Sdjl if (is_global == 0) { 1624*cb5caa98Sdjl if (nswdb_name == NULL) { 1625*cb5caa98Sdjl 1626*cb5caa98Sdjl (void) snprintf(msg, sizeof (msg), 1627*cb5caa98Sdjl gettext("%s: switch database name not specified"), 1628*cb5caa98Sdjl desc_str); 1629*cb5caa98Sdjl if (errorp) 1630*cb5caa98Sdjl *errorp = _nscd_cfg_make_error(rc, msg); 1631*cb5caa98Sdjl 1632*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 1633*cb5caa98Sdjl (me, "%s for non-global param or stat %s\n", 1634*cb5caa98Sdjl msg, name); 1635*cb5caa98Sdjl 1636*cb5caa98Sdjl free(h); 1637*cb5caa98Sdjl return (rc); 1638*cb5caa98Sdjl } 1639*cb5caa98Sdjl } else { 1640*cb5caa98Sdjl 1641*cb5caa98Sdjl if (nswdb_name != NULL) { 1642*cb5caa98Sdjl 1643*cb5caa98Sdjl (void) snprintf(msg, sizeof (msg), 1644*cb5caa98Sdjl gettext("%s: switch database specified for global data"), 1645*cb5caa98Sdjl desc_str); 1646*cb5caa98Sdjl if (errorp) 1647*cb5caa98Sdjl *errorp = _nscd_cfg_make_error(rc, msg); 1648*cb5caa98Sdjl 1649*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 1650*cb5caa98Sdjl (me, "%s %s\n", msg, name); 1651*cb5caa98Sdjl 1652*cb5caa98Sdjl free(h); 1653*cb5caa98Sdjl return (rc); 1654*cb5caa98Sdjl } 1655*cb5caa98Sdjl 1656*cb5caa98Sdjl *handle = h; 1657*cb5caa98Sdjl return (NSCD_SUCCESS); 1658*cb5caa98Sdjl } 1659*cb5caa98Sdjl 1660*cb5caa98Sdjl /* get nsw DB id */ 1661*cb5caa98Sdjl i = _nscd_cfg_get_index(nswdb_name, NSCD_CFG_LIST_NSW_DB); 1662*cb5caa98Sdjl if (i != -1) { 1663*cb5caa98Sdjl 1664*cb5caa98Sdjl if (i == NSCD_CFG_NSW_ALLDB_INDEX) 1665*cb5caa98Sdjl h->nswdb = &_nscd_cfg_nsw_alldb; 1666*cb5caa98Sdjl else 1667*cb5caa98Sdjl h->nswdb = &_nscd_cfg_nsw_db[i]; 1668*cb5caa98Sdjl 1669*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_DEBUG) 1670*cb5caa98Sdjl (me, "%s: index of %s is %d\n", 1671*cb5caa98Sdjl desc_str, nswdb_name, i); 1672*cb5caa98Sdjl } else { 1673*cb5caa98Sdjl 1674*cb5caa98Sdjl (void) snprintf(msg, sizeof (msg), 1675*cb5caa98Sdjl gettext("%s: unknown switch database name \"%s\""), 1676*cb5caa98Sdjl desc_str, nswdb_name); 1677*cb5caa98Sdjl if (errorp) 1678*cb5caa98Sdjl *errorp = _nscd_cfg_make_error(rc, msg); 1679*cb5caa98Sdjl 1680*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 1681*cb5caa98Sdjl (me, "%s\n", msg); 1682*cb5caa98Sdjl 1683*cb5caa98Sdjl free(h); 1684*cb5caa98Sdjl return (NSCD_CFG_UNSUPPORTED_SWITCH_DB); 1685*cb5caa98Sdjl } 1686*cb5caa98Sdjl 1687*cb5caa98Sdjl *handle = h; 1688*cb5caa98Sdjl 1689*cb5caa98Sdjl return (NSCD_SUCCESS); 1690*cb5caa98Sdjl } 1691*cb5caa98Sdjl 1692*cb5caa98Sdjl nscd_rc_t 1693*cb5caa98Sdjl _nscd_cfg_get_handle( 1694*cb5caa98Sdjl char *param_name, 1695*cb5caa98Sdjl char *nswdb_name, 1696*cb5caa98Sdjl nscd_cfg_handle_t **handle, 1697*cb5caa98Sdjl nscd_cfg_error_t **errorp) 1698*cb5caa98Sdjl { 1699*cb5caa98Sdjl 1700*cb5caa98Sdjl return (_nscd_cfg_get_handle_common(NSCD_CFG_LIST_PARAM, 1701*cb5caa98Sdjl param_name, nswdb_name, handle, errorp)); 1702*cb5caa98Sdjl } 1703*cb5caa98Sdjl 1704*cb5caa98Sdjl nscd_rc_t 1705*cb5caa98Sdjl _nscd_cfg_get_stat_handle( 1706*cb5caa98Sdjl char *stat_name, 1707*cb5caa98Sdjl char *nswdb_name, 1708*cb5caa98Sdjl nscd_cfg_handle_t **handle, 1709*cb5caa98Sdjl nscd_cfg_error_t **errorp) 1710*cb5caa98Sdjl { 1711*cb5caa98Sdjl 1712*cb5caa98Sdjl return (_nscd_cfg_get_handle_common(NSCD_CFG_LIST_STAT, 1713*cb5caa98Sdjl stat_name, nswdb_name, handle, errorp)); 1714*cb5caa98Sdjl } 1715*cb5caa98Sdjl 1716*cb5caa98Sdjl void 1717*cb5caa98Sdjl _nscd_cfg_free_handle( 1718*cb5caa98Sdjl nscd_cfg_handle_t *handle) 1719*cb5caa98Sdjl { 1720*cb5caa98Sdjl 1721*cb5caa98Sdjl free(handle); 1722*cb5caa98Sdjl 1723*cb5caa98Sdjl } 1724*cb5caa98Sdjl 1725*cb5caa98Sdjl static void 1726*cb5caa98Sdjl _nscd_cfg_free_vlen_data_group( 1727*cb5caa98Sdjl nscd_cfg_param_desc_t *gdesc, 1728*cb5caa98Sdjl void *group_data, 1729*cb5caa98Sdjl nscd_bool_t in) 1730*cb5caa98Sdjl { 1731*cb5caa98Sdjl int num; 1732*cb5caa98Sdjl void *dest, *ptr; 1733*cb5caa98Sdjl nscd_cfg_param_desc_t *desc; 1734*cb5caa98Sdjl 1735*cb5caa98Sdjl desc = gdesc; 1736*cb5caa98Sdjl 1737*cb5caa98Sdjl num = ((nscd_cfg_group_info_t *)group_data)->num_param; 1738*cb5caa98Sdjl 1739*cb5caa98Sdjl while (num-- > 0) { 1740*cb5caa98Sdjl 1741*cb5caa98Sdjl desc++; 1742*cb5caa98Sdjl 1743*cb5caa98Sdjl /* skip fixed length data */ 1744*cb5caa98Sdjl if (_nscd_cfg_flag_is_not_set(desc->pflag, 1745*cb5caa98Sdjl NSCD_CFG_PFLAG_VLEN_DATA)) 1746*cb5caa98Sdjl continue; 1747*cb5caa98Sdjl 1748*cb5caa98Sdjl dest = (char *)group_data + desc->p_offset; 1749*cb5caa98Sdjl ptr = *(char **)dest; 1750*cb5caa98Sdjl if (ptr == NULL) 1751*cb5caa98Sdjl continue; 1752*cb5caa98Sdjl if (in == nscd_true) 1753*cb5caa98Sdjl _nscd_cfg_free_vlen_data_int(ptr); 1754*cb5caa98Sdjl else 1755*cb5caa98Sdjl free(ptr); 1756*cb5caa98Sdjl } 1757*cb5caa98Sdjl } 1758*cb5caa98Sdjl 1759*cb5caa98Sdjl void 1760*cb5caa98Sdjl _nscd_cfg_free_param_data( 1761*cb5caa98Sdjl void *data) 1762*cb5caa98Sdjl { 1763*cb5caa98Sdjl 1764*cb5caa98Sdjl if (data == NULL) 1765*cb5caa98Sdjl return; 1766*cb5caa98Sdjl 1767*cb5caa98Sdjl free(data); 1768*cb5caa98Sdjl } 1769*cb5caa98Sdjl 1770*cb5caa98Sdjl void 1771*cb5caa98Sdjl _nscd_cfg_free_group_data( 1772*cb5caa98Sdjl nscd_cfg_handle_t *handle, 1773*cb5caa98Sdjl void *data) 1774*cb5caa98Sdjl { 1775*cb5caa98Sdjl 1776*cb5caa98Sdjl nscd_cfg_param_desc_t *desc; 1777*cb5caa98Sdjl nscd_cfg_group_info_t *gi; 1778*cb5caa98Sdjl 1779*cb5caa98Sdjl if (handle == NULL || data == NULL) 1780*cb5caa98Sdjl return; 1781*cb5caa98Sdjl 1782*cb5caa98Sdjl desc = _nscd_cfg_get_desc(handle); 1783*cb5caa98Sdjl gi = (nscd_cfg_group_info_t *)data; 1784*cb5caa98Sdjl if (desc->p_fn != gi->num_param) 1785*cb5caa98Sdjl return; 1786*cb5caa98Sdjl 1787*cb5caa98Sdjl _nscd_cfg_free_vlen_data_group(desc, data, nscd_false); 1788*cb5caa98Sdjl 1789*cb5caa98Sdjl free(data); 1790*cb5caa98Sdjl } 1791*cb5caa98Sdjl 1792*cb5caa98Sdjl void 1793*cb5caa98Sdjl _nscd_cfg_free_error( 1794*cb5caa98Sdjl nscd_cfg_error_t *error) 1795*cb5caa98Sdjl { 1796*cb5caa98Sdjl 1797*cb5caa98Sdjl if (error == NULL) 1798*cb5caa98Sdjl return; 1799*cb5caa98Sdjl 1800*cb5caa98Sdjl free(error); 1801*cb5caa98Sdjl } 1802*cb5caa98Sdjl 1803*cb5caa98Sdjl static nscd_rc_t 1804*cb5caa98Sdjl _nscd_cfg_copy_param_data( 1805*cb5caa98Sdjl nscd_cfg_param_desc_t *desc, 1806*cb5caa98Sdjl void *dest, 1807*cb5caa98Sdjl void *pdata, 1808*cb5caa98Sdjl nscd_bool_t in, 1809*cb5caa98Sdjl nscd_bool_t set_addr) 1810*cb5caa98Sdjl { 1811*cb5caa98Sdjl 1812*cb5caa98Sdjl char *me = "_nscd_cfg_copy_param_data"; 1813*cb5caa98Sdjl void *tmp; 1814*cb5caa98Sdjl int dlen; 1815*cb5caa98Sdjl nscd_rc_t rc = NSCD_SUCCESS; 1816*cb5caa98Sdjl 1817*cb5caa98Sdjl if (desc == NULL || dest == NULL) { 1818*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 1819*cb5caa98Sdjl (me, "input desc == %p, dest == %p\n", desc, dest); 1820*cb5caa98Sdjl return (NSCD_INVALID_ARGUMENT); 1821*cb5caa98Sdjl } 1822*cb5caa98Sdjl 1823*cb5caa98Sdjl /* fixed length data */ 1824*cb5caa98Sdjl if (_nscd_cfg_flag_is_not_set(desc->pflag, 1825*cb5caa98Sdjl NSCD_CFG_PFLAG_VLEN_DATA)) { 1826*cb5caa98Sdjl (void) memcpy(dest, pdata, desc->p_size); 1827*cb5caa98Sdjl goto done; 1828*cb5caa98Sdjl } 1829*cb5caa98Sdjl 1830*cb5caa98Sdjl 1831*cb5caa98Sdjl /* variable length data from this point on */ 1832*cb5caa98Sdjl 1833*cb5caa98Sdjl /* make a copy of the variable length data */ 1834*cb5caa98Sdjl rc = _nscd_cfg_copy_vlen_data(pdata, &tmp, desc, &dlen, in); 1835*cb5caa98Sdjl if (rc != NSCD_SUCCESS) 1836*cb5caa98Sdjl goto done; 1837*cb5caa98Sdjl 1838*cb5caa98Sdjl if (in == nscd_true) { /* data to internal */ 1839*cb5caa98Sdjl 1840*cb5caa98Sdjl /* free the variable length data in the config store */ 1841*cb5caa98Sdjl if (*(char **)dest != NULL) 1842*cb5caa98Sdjl _nscd_cfg_free_vlen_data_int(*(char **)dest); 1843*cb5caa98Sdjl } 1844*cb5caa98Sdjl 1845*cb5caa98Sdjl if (set_addr == nscd_true) { 1846*cb5caa98Sdjl /* 1847*cb5caa98Sdjl * set the addr of the vlen data 1848*cb5caa98Sdjl */ 1849*cb5caa98Sdjl *(char **)dest = tmp; 1850*cb5caa98Sdjl } else { 1851*cb5caa98Sdjl /* 1852*cb5caa98Sdjl * copy the data content (not address) 1853*cb5caa98Sdjl */ 1854*cb5caa98Sdjl (void) memcpy(dest, tmp, dlen); 1855*cb5caa98Sdjl } 1856*cb5caa98Sdjl 1857*cb5caa98Sdjl done: 1858*cb5caa98Sdjl 1859*cb5caa98Sdjl return (rc); 1860*cb5caa98Sdjl } 1861*cb5caa98Sdjl 1862*cb5caa98Sdjl static nscd_rc_t 1863*cb5caa98Sdjl _nscd_cfg_copy_group_data_in( 1864*cb5caa98Sdjl nscd_cfg_param_desc_t *gdesc, 1865*cb5caa98Sdjl nscd_cfg_group_info_t *gi, 1866*cb5caa98Sdjl void *group_dest, 1867*cb5caa98Sdjl void *group_src) 1868*cb5caa98Sdjl { 1869*cb5caa98Sdjl int i, num; 1870*cb5caa98Sdjl nscd_cfg_param_desc_t *desc; 1871*cb5caa98Sdjl void *src, *dest; 1872*cb5caa98Sdjl 1873*cb5caa98Sdjl i = 0; 1874*cb5caa98Sdjl num = gi->num_param; 1875*cb5caa98Sdjl desc = gdesc; 1876*cb5caa98Sdjl 1877*cb5caa98Sdjl while (num-- > 0) { 1878*cb5caa98Sdjl 1879*cb5caa98Sdjl desc++; 1880*cb5caa98Sdjl 1881*cb5caa98Sdjl /* if member not selected by bitmap, skip */ 1882*cb5caa98Sdjl if (_nscd_cfg_bitmap_is_not_set(gi->bitmap, i++)) 1883*cb5caa98Sdjl continue; 1884*cb5caa98Sdjl 1885*cb5caa98Sdjl src = (char *)group_src + desc->p_offset; 1886*cb5caa98Sdjl dest = (char *)group_dest + desc->p_offset; 1887*cb5caa98Sdjl 1888*cb5caa98Sdjl /* 1889*cb5caa98Sdjl * if variable length data, free and replace the old 1890*cb5caa98Sdjl * with the new 1891*cb5caa98Sdjl */ 1892*cb5caa98Sdjl if (_nscd_cfg_flag_is_set(desc->pflag, 1893*cb5caa98Sdjl NSCD_CFG_PFLAG_VLEN_DATA)) { 1894*cb5caa98Sdjl _nscd_cfg_free_vlen_data_int(*(char **)dest); 1895*cb5caa98Sdjl *(char **)dest = *(char **)src; 1896*cb5caa98Sdjl *(char **)src = NULL; 1897*cb5caa98Sdjl } else { 1898*cb5caa98Sdjl /* 1899*cb5caa98Sdjl * fixed length data, just copy it 1900*cb5caa98Sdjl */ 1901*cb5caa98Sdjl (void) memcpy(dest, src, desc->p_size); 1902*cb5caa98Sdjl } 1903*cb5caa98Sdjl } 1904*cb5caa98Sdjl 1905*cb5caa98Sdjl return (NSCD_SUCCESS); 1906*cb5caa98Sdjl } 1907*cb5caa98Sdjl 1908*cb5caa98Sdjl static nscd_rc_t 1909*cb5caa98Sdjl _nscd_cfg_copy_group_data_out( 1910*cb5caa98Sdjl nscd_cfg_param_desc_t *gdesc, 1911*cb5caa98Sdjl void *group_dest, 1912*cb5caa98Sdjl void *group_src) 1913*cb5caa98Sdjl { 1914*cb5caa98Sdjl 1915*cb5caa98Sdjl char *me = "_nscd_cfg_copy_group_data_out"; 1916*cb5caa98Sdjl void *src, *dest; 1917*cb5caa98Sdjl int dlen; 1918*cb5caa98Sdjl int num; 1919*cb5caa98Sdjl nscd_cfg_group_info_t *gi; 1920*cb5caa98Sdjl nscd_rc_t rc = NSCD_SUCCESS; 1921*cb5caa98Sdjl nscd_cfg_param_desc_t *desc; 1922*cb5caa98Sdjl 1923*cb5caa98Sdjl if (group_dest == NULL) { 1924*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 1925*cb5caa98Sdjl (me, "input group_dest = NULL\n"); 1926*cb5caa98Sdjl return (NSCD_INVALID_ARGUMENT); 1927*cb5caa98Sdjl } 1928*cb5caa98Sdjl 1929*cb5caa98Sdjl gi = _nscd_cfg_get_gi(group_src); 1930*cb5caa98Sdjl num = gi->num_param; 1931*cb5caa98Sdjl desc = gdesc; 1932*cb5caa98Sdjl 1933*cb5caa98Sdjl while (num-- > 0) { 1934*cb5caa98Sdjl 1935*cb5caa98Sdjl desc++; 1936*cb5caa98Sdjl 1937*cb5caa98Sdjl dest = (char *)group_dest + desc->p_offset; 1938*cb5caa98Sdjl src = (char *)group_src + desc->p_offset; 1939*cb5caa98Sdjl 1940*cb5caa98Sdjl /* 1941*cb5caa98Sdjl * if variable length data, get the real 1942*cb5caa98Sdjl * address and length of the data 1943*cb5caa98Sdjl */ 1944*cb5caa98Sdjl if (_nscd_cfg_flag_is_set(desc->pflag, 1945*cb5caa98Sdjl NSCD_CFG_PFLAG_VLEN_DATA)) { 1946*cb5caa98Sdjl src = _nscd_cfg_locate_vlen_data(src, &dlen); 1947*cb5caa98Sdjl if (dlen == NULL) 1948*cb5caa98Sdjl continue; 1949*cb5caa98Sdjl } 1950*cb5caa98Sdjl 1951*cb5caa98Sdjl /* 1952*cb5caa98Sdjl * The nscd_true asks _nscd_cfg_copy_param_data 1953*cb5caa98Sdjl * to set addr of the vlen data in 'dest' rather 1954*cb5caa98Sdjl * than copying the data content 1955*cb5caa98Sdjl */ 1956*cb5caa98Sdjl rc = _nscd_cfg_copy_param_data(desc, dest, src, 1957*cb5caa98Sdjl nscd_false, nscd_true); 1958*cb5caa98Sdjl if (rc != NSCD_SUCCESS) { 1959*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 1960*cb5caa98Sdjl (me, "unable to copy param data for %s\n", 1961*cb5caa98Sdjl desc->id.name); 1962*cb5caa98Sdjl 1963*cb5caa98Sdjl _nscd_cfg_free_vlen_data_group(gdesc, 1964*cb5caa98Sdjl group_dest, nscd_false); 1965*cb5caa98Sdjl 1966*cb5caa98Sdjl free(group_dest); 1967*cb5caa98Sdjl 1968*cb5caa98Sdjl return (rc); 1969*cb5caa98Sdjl } 1970*cb5caa98Sdjl } 1971*cb5caa98Sdjl 1972*cb5caa98Sdjl /* 1973*cb5caa98Sdjl * set group bitmap 1974*cb5caa98Sdjl */ 1975*cb5caa98Sdjl (void) memcpy(group_dest, group_src, 1976*cb5caa98Sdjl sizeof (nscd_cfg_group_info_t)); 1977*cb5caa98Sdjl 1978*cb5caa98Sdjl return (rc); 1979*cb5caa98Sdjl } 1980*cb5caa98Sdjl 1981*cb5caa98Sdjl 1982*cb5caa98Sdjl /* 1983*cb5caa98Sdjl * group_cfg is needed always; group_src may be NULL if 1984*cb5caa98Sdjl * param_index not zero and pdata not NULL; group_cfg and 1985*cb5caa98Sdjl * pdata should not be both non-NULL 1986*cb5caa98Sdjl */ 1987*cb5caa98Sdjl static nscd_rc_t 1988*cb5caa98Sdjl _nscd_cfg_copy_group_data_merge( 1989*cb5caa98Sdjl nscd_cfg_param_desc_t *gdesc, 1990*cb5caa98Sdjl void **group_dest, 1991*cb5caa98Sdjl void *group_src, 1992*cb5caa98Sdjl void *group_cfg, 1993*cb5caa98Sdjl int param_index, 1994*cb5caa98Sdjl void *pdata) 1995*cb5caa98Sdjl { 1996*cb5caa98Sdjl 1997*cb5caa98Sdjl char *me = "_nscd_cfg_copy_group_data_merge"; 1998*cb5caa98Sdjl void *src, *dest, *tmp_dest = NULL; 1999*cb5caa98Sdjl int num, i = 0; 2000*cb5caa98Sdjl nscd_cfg_group_info_t *gi; 2001*cb5caa98Sdjl nscd_rc_t rc = NSCD_SUCCESS; 2002*cb5caa98Sdjl nscd_cfg_param_desc_t *desc; 2003*cb5caa98Sdjl nscd_cfg_bitmap_t bitmap; 2004*cb5caa98Sdjl 2005*cb5caa98Sdjl if (group_dest == NULL) { 2006*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 2007*cb5caa98Sdjl (me, "input **group_dest == NULL\n"); 2008*cb5caa98Sdjl return (NSCD_INVALID_ARGUMENT); 2009*cb5caa98Sdjl } 2010*cb5caa98Sdjl 2011*cb5caa98Sdjl if (group_cfg == NULL) { 2012*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 2013*cb5caa98Sdjl (me, "input **group_cfg == NULL\n"); 2014*cb5caa98Sdjl return (NSCD_INVALID_ARGUMENT); 2015*cb5caa98Sdjl } 2016*cb5caa98Sdjl 2017*cb5caa98Sdjl if (param_index != NULL && pdata == NULL) { 2018*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 2019*cb5caa98Sdjl (me, "param_index != NULL but pdata == %p\n", pdata); 2020*cb5caa98Sdjl return (NSCD_INVALID_ARGUMENT); 2021*cb5caa98Sdjl } 2022*cb5caa98Sdjl 2023*cb5caa98Sdjl tmp_dest = calloc(1, gdesc->g_size); 2024*cb5caa98Sdjl if (tmp_dest == NULL) 2025*cb5caa98Sdjl return (NSCD_NO_MEMORY); 2026*cb5caa98Sdjl 2027*cb5caa98Sdjl if (group_src != NULL) 2028*cb5caa98Sdjl gi = _nscd_cfg_get_gi(group_src); 2029*cb5caa98Sdjl else { 2030*cb5caa98Sdjl gi = _nscd_cfg_get_gi(group_cfg); 2031*cb5caa98Sdjl bitmap = NSCD_CFG_BITMAP_ZERO; 2032*cb5caa98Sdjl } 2033*cb5caa98Sdjl 2034*cb5caa98Sdjl num = gi->num_param; 2035*cb5caa98Sdjl desc = gdesc; 2036*cb5caa98Sdjl 2037*cb5caa98Sdjl while (num-- > 0) { 2038*cb5caa98Sdjl 2039*cb5caa98Sdjl desc++; 2040*cb5caa98Sdjl 2041*cb5caa98Sdjl dest = (char *)tmp_dest + desc->p_offset; 2042*cb5caa98Sdjl 2043*cb5caa98Sdjl /* 2044*cb5caa98Sdjl * if member not selected by bitmap in group_src, 2045*cb5caa98Sdjl * get the member data in group_cfg 2046*cb5caa98Sdjl */ 2047*cb5caa98Sdjl if (_nscd_cfg_bitmap_is_not_set(gi->bitmap, i++) || 2048*cb5caa98Sdjl group_src == NULL) { 2049*cb5caa98Sdjl src = (char *)group_cfg + desc->p_offset; 2050*cb5caa98Sdjl } else 2051*cb5caa98Sdjl src = (char *)group_src + desc->p_offset; 2052*cb5caa98Sdjl 2053*cb5caa98Sdjl if (desc->id.index == param_index) { 2054*cb5caa98Sdjl 2055*cb5caa98Sdjl /* use the param data in pdata if provided */ 2056*cb5caa98Sdjl src = pdata; 2057*cb5caa98Sdjl _nscd_cfg_bitmap_set_nth(bitmap, i); 2058*cb5caa98Sdjl } 2059*cb5caa98Sdjl 2060*cb5caa98Sdjl /* 2061*cb5caa98Sdjl * if variable length data, get to the data 2062*cb5caa98Sdjl * instead of pointer to the data 2063*cb5caa98Sdjl */ 2064*cb5caa98Sdjl if (_nscd_cfg_flag_is_set(desc->pflag, 2065*cb5caa98Sdjl NSCD_CFG_PFLAG_VLEN_DATA)) 2066*cb5caa98Sdjl src = *(char **)src; 2067*cb5caa98Sdjl 2068*cb5caa98Sdjl /* 2069*cb5caa98Sdjl * nscd_true asks _nscd_cfg_copy_param_data to 2070*cb5caa98Sdjl * set addr of the vlen data in 'dest' rather 2071*cb5caa98Sdjl * than copying the data content 2072*cb5caa98Sdjl */ 2073*cb5caa98Sdjl rc = _nscd_cfg_copy_param_data(desc, dest, src, 2074*cb5caa98Sdjl nscd_true, nscd_true); 2075*cb5caa98Sdjl if (rc != NSCD_SUCCESS) { 2076*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 2077*cb5caa98Sdjl (me, "unable to copy param data for %s\n", 2078*cb5caa98Sdjl desc->id.name); 2079*cb5caa98Sdjl 2080*cb5caa98Sdjl _nscd_cfg_free_vlen_data_group(gdesc, 2081*cb5caa98Sdjl tmp_dest, nscd_true); 2082*cb5caa98Sdjl 2083*cb5caa98Sdjl free(tmp_dest); 2084*cb5caa98Sdjl 2085*cb5caa98Sdjl return (rc); 2086*cb5caa98Sdjl } 2087*cb5caa98Sdjl } 2088*cb5caa98Sdjl 2089*cb5caa98Sdjl *group_dest = tmp_dest; 2090*cb5caa98Sdjl 2091*cb5caa98Sdjl /* 2092*cb5caa98Sdjl * set bitmap: if input is group data, use the one 2093*cb5caa98Sdjl * given; if input is param data, use the one computed 2094*cb5caa98Sdjl * above 2095*cb5caa98Sdjl */ 2096*cb5caa98Sdjl if (group_src != NULL) 2097*cb5caa98Sdjl (void) memcpy(*group_dest, group_src, 2098*cb5caa98Sdjl sizeof (nscd_cfg_group_info_t)); 2099*cb5caa98Sdjl else { 2100*cb5caa98Sdjl gi = _nscd_cfg_get_gi(*group_dest); 2101*cb5caa98Sdjl _nscd_cfg_bitmap_set(&gi->bitmap, bitmap); 2102*cb5caa98Sdjl } 2103*cb5caa98Sdjl 2104*cb5caa98Sdjl return (rc); 2105*cb5caa98Sdjl } 2106*cb5caa98Sdjl 2107*cb5caa98Sdjl /* ARGSUSED */ 2108*cb5caa98Sdjl nscd_rc_t 2109*cb5caa98Sdjl _nscd_cfg_get( 2110*cb5caa98Sdjl nscd_cfg_handle_t *handle, 2111*cb5caa98Sdjl void **data, 2112*cb5caa98Sdjl int *data_len, 2113*cb5caa98Sdjl nscd_cfg_error_t **errorp) 2114*cb5caa98Sdjl { 2115*cb5caa98Sdjl char *me = "_nscd_cfg_get"; 2116*cb5caa98Sdjl int dlen; 2117*cb5caa98Sdjl nscd_rc_t rc = NSCD_SUCCESS; 2118*cb5caa98Sdjl nscd_cfg_id_t *nswdb; 2119*cb5caa98Sdjl nscd_cfg_param_desc_t *desc; 2120*cb5caa98Sdjl void *cfg_data, *ptr = NULL; 2121*cb5caa98Sdjl nscd_bool_t get_group = nscd_false; 2122*cb5caa98Sdjl nscd_bool_t out = nscd_false; 2123*cb5caa98Sdjl nscd_cfg_lock_t *lock = NULL; 2124*cb5caa98Sdjl 2125*cb5caa98Sdjl if (data_len != NULL) 2126*cb5caa98Sdjl *data_len = 0; 2127*cb5caa98Sdjl 2128*cb5caa98Sdjl if (data == NULL) { 2129*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 2130*cb5caa98Sdjl (me, "input data = %p\n", data); 2131*cb5caa98Sdjl return (NSCD_INVALID_ARGUMENT); 2132*cb5caa98Sdjl } 2133*cb5caa98Sdjl 2134*cb5caa98Sdjl *data = NULL; 2135*cb5caa98Sdjl 2136*cb5caa98Sdjl if (handle == NULL) { 2137*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 2138*cb5caa98Sdjl (me, "handle is NULL\n"); 2139*cb5caa98Sdjl return (NSCD_INVALID_ARGUMENT); 2140*cb5caa98Sdjl } 2141*cb5caa98Sdjl 2142*cb5caa98Sdjl nswdb = handle->nswdb; 2143*cb5caa98Sdjl desc = (nscd_cfg_param_desc_t *)handle->desc; 2144*cb5caa98Sdjl 2145*cb5caa98Sdjl if (_nscd_cfg_flag_is_set(desc->pflag, NSCD_CFG_PFLAG_GROUP)) 2146*cb5caa98Sdjl get_group = nscd_true; 2147*cb5caa98Sdjl 2148*cb5caa98Sdjl /* 2149*cb5caa98Sdjl * locate the current value of the param or group 2150*cb5caa98Sdjl * and lock the config data for reading 2151*cb5caa98Sdjl */ 2152*cb5caa98Sdjl rc = _nscd_cfg_locate_cfg_data(&cfg_data, nscd_true, desc, 2153*cb5caa98Sdjl nswdb, get_group, NULL, &dlen, &lock); 2154*cb5caa98Sdjl if (rc != NSCD_SUCCESS) { 2155*cb5caa98Sdjl 2156*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 2157*cb5caa98Sdjl (me, "unable to locate config data\n"); 2158*cb5caa98Sdjl return (rc); 2159*cb5caa98Sdjl 2160*cb5caa98Sdjl } else if (cfg_data == NULL) /* NULL vlen data */ 2161*cb5caa98Sdjl goto done; 2162*cb5caa98Sdjl 2163*cb5caa98Sdjl ptr = calloc(1, dlen); 2164*cb5caa98Sdjl if (ptr == NULL) { 2165*cb5caa98Sdjl rc = NSCD_NO_MEMORY; 2166*cb5caa98Sdjl goto error_exit; 2167*cb5caa98Sdjl } 2168*cb5caa98Sdjl 2169*cb5caa98Sdjl if (get_group == nscd_true) { 2170*cb5caa98Sdjl 2171*cb5caa98Sdjl rc = _nscd_cfg_copy_group_data_out(desc, ptr, cfg_data); 2172*cb5caa98Sdjl if (rc != NSCD_SUCCESS) { 2173*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 2174*cb5caa98Sdjl (me, "unable to copy group data %p: " 2175*cb5caa98Sdjl "error = %d\n", cfg_data, rc); 2176*cb5caa98Sdjl 2177*cb5caa98Sdjl goto error_exit; 2178*cb5caa98Sdjl } 2179*cb5caa98Sdjl } else { 2180*cb5caa98Sdjl /* 2181*cb5caa98Sdjl * nscd_false asks _nscd_cfg_copy_param_data to 2182*cb5caa98Sdjl * copy the data content rather than just setting 2183*cb5caa98Sdjl * the addr of the vlen data in 'ptr' 2184*cb5caa98Sdjl */ 2185*cb5caa98Sdjl rc = _nscd_cfg_copy_param_data(desc, ptr, cfg_data, 2186*cb5caa98Sdjl out, nscd_false); 2187*cb5caa98Sdjl 2188*cb5caa98Sdjl if (rc != NSCD_SUCCESS) { 2189*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 2190*cb5caa98Sdjl (me, "unable to copy param data %p: " 2191*cb5caa98Sdjl "error = %d\n", cfg_data, rc); 2192*cb5caa98Sdjl 2193*cb5caa98Sdjl goto error_exit; 2194*cb5caa98Sdjl } 2195*cb5caa98Sdjl } 2196*cb5caa98Sdjl 2197*cb5caa98Sdjl *data = ptr; 2198*cb5caa98Sdjl 2199*cb5caa98Sdjl done: 2200*cb5caa98Sdjl 2201*cb5caa98Sdjl if (data_len != NULL) 2202*cb5caa98Sdjl *data_len = dlen; 2203*cb5caa98Sdjl 2204*cb5caa98Sdjl _nscd_cfg_unlock(lock); 2205*cb5caa98Sdjl 2206*cb5caa98Sdjl return (NSCD_SUCCESS); 2207*cb5caa98Sdjl 2208*cb5caa98Sdjl error_exit: 2209*cb5caa98Sdjl 2210*cb5caa98Sdjl _nscd_cfg_unlock(lock); 2211*cb5caa98Sdjl if (ptr != NULL) 2212*cb5caa98Sdjl free(ptr); 2213*cb5caa98Sdjl 2214*cb5caa98Sdjl return (rc); 2215*cb5caa98Sdjl } 2216*cb5caa98Sdjl 2217*cb5caa98Sdjl /* 2218*cb5caa98Sdjl * three type of data: 2219*cb5caa98Sdjl * 1 - single param 2220*cb5caa98Sdjl * desc is that of the param 2221*cb5caa98Sdjl * 2 - single param to be sent in a group 2222*cb5caa98Sdjl * a single bit is set in the bitmap, 2223*cb5caa98Sdjl * desc is that of the group 2224*cb5caa98Sdjl * 3 - group data 2225*cb5caa98Sdjl * one of more bits are set in the bitmap, 2226*cb5caa98Sdjl * desc is that of the group 2227*cb5caa98Sdjl */ 2228*cb5caa98Sdjl static nscd_rc_t 2229*cb5caa98Sdjl _nscd_cfg_notify_s( 2230*cb5caa98Sdjl nscd_cfg_param_desc_t *desc, 2231*cb5caa98Sdjl nscd_cfg_id_t *nswdb, 2232*cb5caa98Sdjl void *data, 2233*cb5caa98Sdjl nscd_cfg_error_t **errorp) 2234*cb5caa98Sdjl { 2235*cb5caa98Sdjl int i, num, is_group = 0; 2236*cb5caa98Sdjl void *cookie = NULL; 2237*cb5caa98Sdjl void *cdata; 2238*cb5caa98Sdjl nscd_rc_t rc; 2239*cb5caa98Sdjl nscd_cfg_flag_t dflag, dflag1; 2240*cb5caa98Sdjl nscd_cfg_bitmap_t bitmap_s, bitmap_in, *bitmap_addr = NULL; 2241*cb5caa98Sdjl nscd_cfg_group_info_t *gi; 2242*cb5caa98Sdjl 2243*cb5caa98Sdjl if (errorp != NULL) 2244*cb5caa98Sdjl *errorp = NULL; 2245*cb5caa98Sdjl 2246*cb5caa98Sdjl /* 2247*cb5caa98Sdjl * Set data flag going with data to be sent to the 2248*cb5caa98Sdjl * verify/notify routines. To allow the config flag 2249*cb5caa98Sdjl * be exipandable, set the bits one by one. 2250*cb5caa98Sdjl */ 2251*cb5caa98Sdjl dflag = NSCD_CFG_FLAG_ZERO; 2252*cb5caa98Sdjl dflag = _nscd_cfg_flag_set(dflag, NSCD_CFG_DFLAG_STATIC_DATA); 2253*cb5caa98Sdjl if (_nscd_cfg_flag_is_set(desc->pflag, NSCD_CFG_PFLAG_GROUP)) { 2254*cb5caa98Sdjl dflag = _nscd_cfg_flag_set(dflag, NSCD_CFG_DFLAG_GROUP); 2255*cb5caa98Sdjl is_group = 1; 2256*cb5caa98Sdjl } 2257*cb5caa98Sdjl if (nswdb != NULL && 2258*cb5caa98Sdjl strcmp(NSCD_CFG_NSW_ALLDB, nswdb->name) == 0) 2259*cb5caa98Sdjl dflag = _nscd_cfg_flag_set(dflag, 2260*cb5caa98Sdjl NSCD_CFG_DFLAG_SET_ALL_DB); 2261*cb5caa98Sdjl 2262*cb5caa98Sdjl /* 2263*cb5caa98Sdjl * the bitmap in the input data may be replaced before 2264*cb5caa98Sdjl * sending to the components, so save the bitmap for 2265*cb5caa98Sdjl * later use 2266*cb5caa98Sdjl */ 2267*cb5caa98Sdjl if (is_group == 1) { 2268*cb5caa98Sdjl gi = _nscd_cfg_get_gi(data); 2269*cb5caa98Sdjl bitmap_in = gi->bitmap; 2270*cb5caa98Sdjl bitmap_addr = &(gi->bitmap); 2271*cb5caa98Sdjl 2272*cb5caa98Sdjl if (_nscd_cfg_flag_is_set(desc->pflag, 2273*cb5caa98Sdjl NSCD_CFG_PFLAG_INIT_SEND_WHOLE_GROUP)) 2274*cb5caa98Sdjl /* send the entire group just once */ 2275*cb5caa98Sdjl num = 1; 2276*cb5caa98Sdjl 2277*cb5caa98Sdjl else { /* send individual members one by one */ 2278*cb5caa98Sdjl 2279*cb5caa98Sdjl num = desc->p_fn; 2280*cb5caa98Sdjl 2281*cb5caa98Sdjl /* 2282*cb5caa98Sdjl * skip the first desc which is for the group 2283*cb5caa98Sdjl * and get to the desc for the first member 2284*cb5caa98Sdjl */ 2285*cb5caa98Sdjl desc++; 2286*cb5caa98Sdjl 2287*cb5caa98Sdjl dflag = _nscd_cfg_flag_unset(dflag, 2288*cb5caa98Sdjl NSCD_CFG_DFLAG_GROUP); 2289*cb5caa98Sdjl } 2290*cb5caa98Sdjl } else { 2291*cb5caa98Sdjl /* not group data, send the member once */ 2292*cb5caa98Sdjl num = 1; 2293*cb5caa98Sdjl } 2294*cb5caa98Sdjl 2295*cb5caa98Sdjl dflag1 = dflag; 2296*cb5caa98Sdjl for (i = 0; i < num; i++, desc++) { 2297*cb5caa98Sdjl 2298*cb5caa98Sdjl dflag = dflag1; 2299*cb5caa98Sdjl 2300*cb5caa98Sdjl if (is_group == 0) { 2301*cb5caa98Sdjl cdata = data; 2302*cb5caa98Sdjl goto verify_data; 2303*cb5caa98Sdjl } 2304*cb5caa98Sdjl 2305*cb5caa98Sdjl if (_nscd_cfg_flag_is_set(desc->pflag, 2306*cb5caa98Sdjl NSCD_CFG_PFLAG_SEND_BIT_SELECTED)) { 2307*cb5caa98Sdjl 2308*cb5caa98Sdjl /* set the bitmap to select just this member */ 2309*cb5caa98Sdjl bitmap_s = NSCD_CFG_BITMAP_ZERO; 2310*cb5caa98Sdjl _nscd_cfg_bitmap_set_nth(bitmap_s, i); 2311*cb5caa98Sdjl /* replace the bitmap in the input data */ 2312*cb5caa98Sdjl _nscd_cfg_bitmap_set(bitmap_addr, bitmap_s); 2313*cb5caa98Sdjl 2314*cb5caa98Sdjl /* 2315*cb5caa98Sdjl * send the whole group but with only one 2316*cb5caa98Sdjl * member selected 2317*cb5caa98Sdjl */ 2318*cb5caa98Sdjl cdata = data; 2319*cb5caa98Sdjl 2320*cb5caa98Sdjl dflag = _nscd_cfg_flag_set(dflag, 2321*cb5caa98Sdjl NSCD_CFG_DFLAG_GROUP); 2322*cb5caa98Sdjl dflag = _nscd_cfg_flag_set(dflag, 2323*cb5caa98Sdjl NSCD_CFG_DFLAG_BIT_SELECTED); 2324*cb5caa98Sdjl } else { 2325*cb5caa98Sdjl /* 2326*cb5caa98Sdjl * send param data or group data: 2327*cb5caa98Sdjl * param data - non-xero desc->p_offset 2328*cb5caa98Sdjl * group data - zero desc->p_offset 2329*cb5caa98Sdjl */ 2330*cb5caa98Sdjl cdata = (char *)data + desc->p_offset; 2331*cb5caa98Sdjl 2332*cb5caa98Sdjl /* 2333*cb5caa98Sdjl * if variable length data, need to send pointer 2334*cb5caa98Sdjl * to the data (not the address of the pointer) 2335*cb5caa98Sdjl */ 2336*cb5caa98Sdjl if (_nscd_cfg_flag_is_set(desc->pflag, 2337*cb5caa98Sdjl NSCD_CFG_PFLAG_VLEN_DATA)) 2338*cb5caa98Sdjl cdata = *(char **)cdata; 2339*cb5caa98Sdjl } 2340*cb5caa98Sdjl 2341*cb5caa98Sdjl verify_data: 2342*cb5caa98Sdjl 2343*cb5caa98Sdjl if (desc->verify != NULL) { 2344*cb5caa98Sdjl dflag = _nscd_cfg_flag_set(dflag, 2345*cb5caa98Sdjl NSCD_CFG_DFLAG_VERIFY); 2346*cb5caa98Sdjl rc = desc->verify(cdata, desc, nswdb, 2347*cb5caa98Sdjl dflag, errorp, &cookie); 2348*cb5caa98Sdjl if (rc != NSCD_SUCCESS) 2349*cb5caa98Sdjl goto error_exit; 2350*cb5caa98Sdjl } 2351*cb5caa98Sdjl 2352*cb5caa98Sdjl if (desc->notify != NULL) { 2353*cb5caa98Sdjl dflag = _nscd_cfg_flag_set(dflag, 2354*cb5caa98Sdjl NSCD_CFG_DFLAG_NOTIFY); 2355*cb5caa98Sdjl 2356*cb5caa98Sdjl rc = desc->notify(data, desc, nswdb, 2357*cb5caa98Sdjl dflag, errorp, cookie); 2358*cb5caa98Sdjl if (rc != NSCD_SUCCESS) 2359*cb5caa98Sdjl goto error_exit; 2360*cb5caa98Sdjl } 2361*cb5caa98Sdjl } 2362*cb5caa98Sdjl 2363*cb5caa98Sdjl rc = NSCD_SUCCESS; 2364*cb5caa98Sdjl 2365*cb5caa98Sdjl error_exit: 2366*cb5caa98Sdjl 2367*cb5caa98Sdjl /* restore the bitmap in the input data */ 2368*cb5caa98Sdjl if (bitmap_addr != NULL) 2369*cb5caa98Sdjl _nscd_cfg_bitmap_set(bitmap_addr, bitmap_in); 2370*cb5caa98Sdjl 2371*cb5caa98Sdjl return (rc); 2372*cb5caa98Sdjl } 2373*cb5caa98Sdjl 2374*cb5caa98Sdjl /* 2375*cb5caa98Sdjl * Convert string 'str' to data based on the data type in 'desc'. 2376*cb5caa98Sdjl * 'data' points to the buffer in which the converted data 2377*cb5caa98Sdjl * is placed. '*data_p' points to the buffer, or in the case 2378*cb5caa98Sdjl * of a string data type, points to the untoched string (i.e., 2379*cb5caa98Sdjl * 'str'). 2380*cb5caa98Sdjl */ 2381*cb5caa98Sdjl nscd_rc_t 2382*cb5caa98Sdjl _nscd_cfg_str_to_data( 2383*cb5caa98Sdjl nscd_cfg_param_desc_t *desc, 2384*cb5caa98Sdjl char *str, 2385*cb5caa98Sdjl void *data, 2386*cb5caa98Sdjl void **data_p, 2387*cb5caa98Sdjl nscd_cfg_error_t **errorp) 2388*cb5caa98Sdjl { 2389*cb5caa98Sdjl 2390*cb5caa98Sdjl char *me = "_nscd_cfg_str_to_data"; 2391*cb5caa98Sdjl char *c; 2392*cb5caa98Sdjl nscd_cfg_bitmap_t bitmap; 2393*cb5caa98Sdjl char msg[NSCD_CFG_MAX_ERR_MSG_LEN]; 2394*cb5caa98Sdjl nscd_rc_t rc = NSCD_CFG_DATA_CONVERSION_FAILED; 2395*cb5caa98Sdjl 2396*cb5caa98Sdjl if (desc == NULL || str == NULL || data == NULL) { 2397*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 2398*cb5caa98Sdjl (me, "ERROR: one of the following is NULL " 2399*cb5caa98Sdjl "desc = %p, str = %p, data = %p, data_p = %p\n", 2400*cb5caa98Sdjl desc, str, data, data_p); 2401*cb5caa98Sdjl 2402*cb5caa98Sdjl return (NSCD_INVALID_ARGUMENT); 2403*cb5caa98Sdjl } 2404*cb5caa98Sdjl *data_p = data; 2405*cb5caa98Sdjl 2406*cb5caa98Sdjl /* if description is that of a group, return error */ 2407*cb5caa98Sdjl if (_nscd_cfg_flag_is_set(desc->pflag, NSCD_CFG_PFLAG_GROUP)) { 2408*cb5caa98Sdjl 2409*cb5caa98Sdjl (void) snprintf(msg, sizeof (msg), 2410*cb5caa98Sdjl gettext("single data specified for group %s"), desc->id.name); 2411*cb5caa98Sdjl 2412*cb5caa98Sdjl if (errorp != NULL) 2413*cb5caa98Sdjl *errorp = _nscd_cfg_make_error(NSCD_INVALID_ARGUMENT, 2414*cb5caa98Sdjl msg); 2415*cb5caa98Sdjl 2416*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 2417*cb5caa98Sdjl (me, "ERROR: %s)\n", msg); 2418*cb5caa98Sdjl 2419*cb5caa98Sdjl return (NSCD_INVALID_ARGUMENT); 2420*cb5caa98Sdjl 2421*cb5caa98Sdjl } 2422*cb5caa98Sdjl 2423*cb5caa98Sdjl if (desc->type == NSCD_CFG_DATA_STRING) { 2424*cb5caa98Sdjl if (strcmp(str, NSCD_NULL) == 0) 2425*cb5caa98Sdjl *(char **)data_p = NULL; 2426*cb5caa98Sdjl else { 2427*cb5caa98Sdjl /* remove the " char if quoted string */ 2428*cb5caa98Sdjl if (str[0] == '"') { 2429*cb5caa98Sdjl c = str + strlen(str) - 1; 2430*cb5caa98Sdjl if (*c == '"') 2431*cb5caa98Sdjl *c = '\0'; 2432*cb5caa98Sdjl *(char **)data_p = str + 1; 2433*cb5caa98Sdjl } else 2434*cb5caa98Sdjl *(char **)data_p = str; 2435*cb5caa98Sdjl 2436*cb5caa98Sdjl } 2437*cb5caa98Sdjl return (NSCD_SUCCESS); 2438*cb5caa98Sdjl } 2439*cb5caa98Sdjl 2440*cb5caa98Sdjl if (str == NULL) { 2441*cb5caa98Sdjl 2442*cb5caa98Sdjl (void) snprintf(msg, sizeof (msg), 2443*cb5caa98Sdjl gettext("data must be specified for %s"), desc->id.name); 2444*cb5caa98Sdjl 2445*cb5caa98Sdjl if (errorp != NULL) 2446*cb5caa98Sdjl *errorp = _nscd_cfg_make_error(NSCD_INVALID_ARGUMENT, 2447*cb5caa98Sdjl msg); 2448*cb5caa98Sdjl 2449*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 2450*cb5caa98Sdjl (me, "ERROR: %s\n", msg); 2451*cb5caa98Sdjl 2452*cb5caa98Sdjl return (NSCD_INVALID_ARGUMENT); 2453*cb5caa98Sdjl 2454*cb5caa98Sdjl } 2455*cb5caa98Sdjl 2456*cb5caa98Sdjl switch (desc->type) { 2457*cb5caa98Sdjl 2458*cb5caa98Sdjl case NSCD_CFG_DATA_BOOLEAN: 2459*cb5caa98Sdjl 2460*cb5caa98Sdjl if (strcasecmp(str, "yes") == 0) 2461*cb5caa98Sdjl *(nscd_bool_t *)data = nscd_true; 2462*cb5caa98Sdjl else if (strcasecmp(str, "no") == 0) 2463*cb5caa98Sdjl *(nscd_bool_t *)data = nscd_false; 2464*cb5caa98Sdjl else { 2465*cb5caa98Sdjl 2466*cb5caa98Sdjl (void) snprintf(msg, sizeof (msg), 2467*cb5caa98Sdjl gettext("data (%s) must be 'yes' or 'no' for %s"), 2468*cb5caa98Sdjl str, desc->id.name); 2469*cb5caa98Sdjl 2470*cb5caa98Sdjl if (errorp != NULL) 2471*cb5caa98Sdjl *errorp = _nscd_cfg_make_error(NSCD_INVALID_ARGUMENT, 2472*cb5caa98Sdjl msg); 2473*cb5caa98Sdjl 2474*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 2475*cb5caa98Sdjl (me, "ERROR: %s\n", msg); 2476*cb5caa98Sdjl 2477*cb5caa98Sdjl return (NSCD_INVALID_ARGUMENT); 2478*cb5caa98Sdjl } 2479*cb5caa98Sdjl 2480*cb5caa98Sdjl break; 2481*cb5caa98Sdjl 2482*cb5caa98Sdjl case NSCD_CFG_DATA_INTEGER: 2483*cb5caa98Sdjl 2484*cb5caa98Sdjl errno = 0; 2485*cb5caa98Sdjl *(int *)data = (int)strtol(str, (char **)NULL, 10); 2486*cb5caa98Sdjl if (errno != NULL) { 2487*cb5caa98Sdjl 2488*cb5caa98Sdjl (void) snprintf(msg, sizeof (msg), 2489*cb5caa98Sdjl gettext("unable to convert data (%s) for %s"), 2490*cb5caa98Sdjl str, desc->id.name); 2491*cb5caa98Sdjl 2492*cb5caa98Sdjl if (errorp != NULL) 2493*cb5caa98Sdjl *errorp = _nscd_cfg_make_error(rc, msg); 2494*cb5caa98Sdjl 2495*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 2496*cb5caa98Sdjl (me, "ERROR: %s\n", msg); 2497*cb5caa98Sdjl 2498*cb5caa98Sdjl return (rc); 2499*cb5caa98Sdjl } 2500*cb5caa98Sdjl 2501*cb5caa98Sdjl break; 2502*cb5caa98Sdjl 2503*cb5caa98Sdjl case NSCD_CFG_DATA_BITMAP: 2504*cb5caa98Sdjl 2505*cb5caa98Sdjl errno = 0; 2506*cb5caa98Sdjl bitmap = (nscd_cfg_bitmap_t)strtol(str, (char **)NULL, 10); 2507*cb5caa98Sdjl if (errno != NULL) { 2508*cb5caa98Sdjl 2509*cb5caa98Sdjl (void) snprintf(msg, sizeof (msg), 2510*cb5caa98Sdjl gettext("unable to convert data (%s) for %s"), 2511*cb5caa98Sdjl str, desc->id.name); 2512*cb5caa98Sdjl 2513*cb5caa98Sdjl if (errorp != NULL) 2514*cb5caa98Sdjl *errorp = _nscd_cfg_make_error(rc, msg); 2515*cb5caa98Sdjl 2516*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 2517*cb5caa98Sdjl (me, "ERROR: %s\n", msg); 2518*cb5caa98Sdjl 2519*cb5caa98Sdjl return (rc); 2520*cb5caa98Sdjl } 2521*cb5caa98Sdjl 2522*cb5caa98Sdjl _nscd_cfg_bitmap_set(data, bitmap); 2523*cb5caa98Sdjl 2524*cb5caa98Sdjl break; 2525*cb5caa98Sdjl 2526*cb5caa98Sdjl } 2527*cb5caa98Sdjl 2528*cb5caa98Sdjl return (NSCD_SUCCESS); 2529*cb5caa98Sdjl } 2530*cb5caa98Sdjl 2531*cb5caa98Sdjl 2532*cb5caa98Sdjl nscd_rc_t 2533*cb5caa98Sdjl _nscd_cfg_set( 2534*cb5caa98Sdjl nscd_cfg_handle_t *handle, 2535*cb5caa98Sdjl void *data, 2536*cb5caa98Sdjl nscd_cfg_error_t **errorp) 2537*cb5caa98Sdjl { 2538*cb5caa98Sdjl char *me = "_nscd_cfg_set"; 2539*cb5caa98Sdjl int dlen; 2540*cb5caa98Sdjl nscd_cfg_id_t *nswdb; 2541*cb5caa98Sdjl nscd_cfg_param_desc_t *desc, *gdesc; 2542*cb5caa98Sdjl nscd_cfg_group_info_t *gi; 2543*cb5caa98Sdjl char *nswdb_name, *param_name; 2544*cb5caa98Sdjl void *pdata = NULL; 2545*cb5caa98Sdjl void *cfg_data, *vdata_addr = NULL; 2546*cb5caa98Sdjl nscd_bool_t get_group = 0; 2547*cb5caa98Sdjl nscd_bool_t in = nscd_true; 2548*cb5caa98Sdjl nscd_cfg_lock_t *lock = NULL; 2549*cb5caa98Sdjl nscd_rc_t rc = NSCD_SUCCESS; 2550*cb5caa98Sdjl 2551*cb5caa98Sdjl if (handle == NULL) { 2552*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 2553*cb5caa98Sdjl (me, "handle is NULL\n"); 2554*cb5caa98Sdjl return (NSCD_INVALID_ARGUMENT); 2555*cb5caa98Sdjl } 2556*cb5caa98Sdjl 2557*cb5caa98Sdjl nswdb = handle->nswdb; 2558*cb5caa98Sdjl desc = (nscd_cfg_param_desc_t *)handle->desc; 2559*cb5caa98Sdjl if (nswdb == NULL) 2560*cb5caa98Sdjl nswdb_name = "global"; 2561*cb5caa98Sdjl else 2562*cb5caa98Sdjl nswdb_name = nswdb->name; 2563*cb5caa98Sdjl param_name = desc->id.name; 2564*cb5caa98Sdjl 2565*cb5caa98Sdjl if (data == NULL && _nscd_cfg_flag_is_not_set(desc->pflag, 2566*cb5caa98Sdjl NSCD_CFG_PFLAG_VLEN_DATA)) { 2567*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 2568*cb5caa98Sdjl (me, "data == NULL\n"); 2569*cb5caa98Sdjl return (NSCD_INVALID_ARGUMENT); 2570*cb5caa98Sdjl } 2571*cb5caa98Sdjl 2572*cb5caa98Sdjl if (_nscd_cfg_flag_is_set(desc->pflag, 2573*cb5caa98Sdjl NSCD_CFG_PFLAG_UPDATE_SEND_WHOLE_GROUP) || 2574*cb5caa98Sdjl _nscd_cfg_flag_is_set(desc->pflag, NSCD_CFG_PFLAG_GROUP)) 2575*cb5caa98Sdjl get_group = nscd_true; 2576*cb5caa98Sdjl 2577*cb5caa98Sdjl /* 2578*cb5caa98Sdjl * locate the current value of the param or group 2579*cb5caa98Sdjl * and lock the config data for writing 2580*cb5caa98Sdjl */ 2581*cb5caa98Sdjl rc = _nscd_cfg_locate_cfg_data(&cfg_data, nscd_false, desc, 2582*cb5caa98Sdjl nswdb, get_group, &vdata_addr, &dlen, &lock); 2583*cb5caa98Sdjl if (rc != NSCD_SUCCESS) { 2584*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 2585*cb5caa98Sdjl (me, "unable to locate config data (rc = %d)\n", rc); 2586*cb5caa98Sdjl return (rc); 2587*cb5caa98Sdjl } 2588*cb5caa98Sdjl 2589*cb5caa98Sdjl if (_nscd_cfg_flag_is_set(desc->pflag, NSCD_CFG_PFLAG_GROUP) && 2590*cb5caa98Sdjl ((nscd_cfg_group_info_t *)cfg_data)->num_param != 2591*cb5caa98Sdjl ((nscd_cfg_group_info_t *)data)->num_param) { 2592*cb5caa98Sdjl 2593*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 2594*cb5caa98Sdjl (me, "number of parameters in group <%s : %s> not equal: " 2595*cb5caa98Sdjl "%d in input data, should be %d\n", 2596*cb5caa98Sdjl NSCD_STR_OR_GLOBAL(nswdb_name), 2597*cb5caa98Sdjl NSCD_STR_OR_NULL(param_name), 2598*cb5caa98Sdjl ((nscd_cfg_group_info_t *)data)->num_param, 2599*cb5caa98Sdjl ((nscd_cfg_group_info_t *)cfg_data)->num_param); 2600*cb5caa98Sdjl 2601*cb5caa98Sdjl rc = NSCD_INVALID_ARGUMENT; 2602*cb5caa98Sdjl goto error_exit; 2603*cb5caa98Sdjl } 2604*cb5caa98Sdjl 2605*cb5caa98Sdjl /* 2606*cb5caa98Sdjl * if variable length data, we want the address 2607*cb5caa98Sdjl * of the pointer pointing to the data 2608*cb5caa98Sdjl */ 2609*cb5caa98Sdjl if (vdata_addr != NULL) 2610*cb5caa98Sdjl cfg_data = vdata_addr; 2611*cb5caa98Sdjl 2612*cb5caa98Sdjl /* 2613*cb5caa98Sdjl * just copy in the specified data, if no need 2614*cb5caa98Sdjl * to verify the data or notify the associated 2615*cb5caa98Sdjl * component 2616*cb5caa98Sdjl */ 2617*cb5caa98Sdjl if (get_group == nscd_true) { 2618*cb5caa98Sdjl 2619*cb5caa98Sdjl gdesc = &_nscd_cfg_param_desc[desc->g_index]; 2620*cb5caa98Sdjl 2621*cb5caa98Sdjl rc = _nscd_cfg_copy_group_data_merge( 2622*cb5caa98Sdjl gdesc, &pdata, data, cfg_data, 2623*cb5caa98Sdjl desc->id.index, data); 2624*cb5caa98Sdjl 2625*cb5caa98Sdjl if (rc != NSCD_SUCCESS) { 2626*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 2627*cb5caa98Sdjl (me, "unable to copy group data <%s : %s>\n", 2628*cb5caa98Sdjl NSCD_STR_OR_GLOBAL(nswdb_name), 2629*cb5caa98Sdjl NSCD_STR_OR_NULL(param_name)); 2630*cb5caa98Sdjl 2631*cb5caa98Sdjl goto error_exit; 2632*cb5caa98Sdjl } 2633*cb5caa98Sdjl 2634*cb5caa98Sdjl rc = _nscd_cfg_notify_s(gdesc, nswdb, 2635*cb5caa98Sdjl pdata, errorp); 2636*cb5caa98Sdjl 2637*cb5caa98Sdjl } else 2638*cb5caa98Sdjl rc = _nscd_cfg_notify_s(desc, nswdb, data, 2639*cb5caa98Sdjl errorp); 2640*cb5caa98Sdjl 2641*cb5caa98Sdjl if (rc != NSCD_SUCCESS) { 2642*cb5caa98Sdjl 2643*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 2644*cb5caa98Sdjl (me, "verifying/notifying of new configuration " 2645*cb5caa98Sdjl "parameter <%s : %s> failed. %s\n", 2646*cb5caa98Sdjl NSCD_STR_OR_GLOBAL(nswdb_name), 2647*cb5caa98Sdjl param_name, (*errorp && (*errorp)->msg) ? 2648*cb5caa98Sdjl (*errorp)->msg : ""); 2649*cb5caa98Sdjl 2650*cb5caa98Sdjl goto error_exit; 2651*cb5caa98Sdjl } 2652*cb5caa98Sdjl 2653*cb5caa98Sdjl /* 2654*cb5caa98Sdjl * Move the new config into the config store 2655*cb5caa98Sdjl */ 2656*cb5caa98Sdjl rc = NSCD_CFG_SET_PARAM_FAILED; 2657*cb5caa98Sdjl if (_nscd_cfg_flag_is_set(desc->pflag, 2658*cb5caa98Sdjl NSCD_CFG_PFLAG_GROUP)) { 2659*cb5caa98Sdjl gi = _nscd_cfg_get_gi(pdata); 2660*cb5caa98Sdjl rc = _nscd_cfg_copy_group_data_in(gdesc, gi, 2661*cb5caa98Sdjl cfg_data, pdata); 2662*cb5caa98Sdjl } else { 2663*cb5caa98Sdjl /* 2664*cb5caa98Sdjl * nscd_true asks _nscd_cfg_copy_param_data to 2665*cb5caa98Sdjl * set addr of the vlen data in 'cfg_data' rather 2666*cb5caa98Sdjl * than copying the data content 2667*cb5caa98Sdjl */ 2668*cb5caa98Sdjl if (pdata != NULL) 2669*cb5caa98Sdjl _nscd_cfg_free_vlen_data_group(gdesc, 2670*cb5caa98Sdjl pdata, in); 2671*cb5caa98Sdjl 2672*cb5caa98Sdjl rc = _nscd_cfg_copy_param_data(desc, 2673*cb5caa98Sdjl cfg_data, data, in, nscd_true); 2674*cb5caa98Sdjl } 2675*cb5caa98Sdjl 2676*cb5caa98Sdjl if (rc != NSCD_SUCCESS) { 2677*cb5caa98Sdjl 2678*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 2679*cb5caa98Sdjl (me, "unable to make new param data <%s : %s> current\n", 2680*cb5caa98Sdjl NSCD_STR_OR_GLOBAL(nswdb_name), 2681*cb5caa98Sdjl NSCD_STR_OR_NULL(param_name)); 2682*cb5caa98Sdjl } 2683*cb5caa98Sdjl 2684*cb5caa98Sdjl error_exit: 2685*cb5caa98Sdjl 2686*cb5caa98Sdjl _nscd_cfg_unlock(lock); 2687*cb5caa98Sdjl 2688*cb5caa98Sdjl return (rc); 2689*cb5caa98Sdjl } 2690*cb5caa98Sdjl 2691*cb5caa98Sdjl nscd_rc_t 2692*cb5caa98Sdjl _nscd_cfg_set_linked( 2693*cb5caa98Sdjl nscd_cfg_handle_t *handle, 2694*cb5caa98Sdjl void *data, 2695*cb5caa98Sdjl nscd_cfg_error_t **errorp) 2696*cb5caa98Sdjl { 2697*cb5caa98Sdjl char *me = "_nscd_cfg_set_linked"; 2698*cb5caa98Sdjl nscd_cfg_id_t *nswdb; 2699*cb5caa98Sdjl nscd_cfg_handle_t *hl; 2700*cb5caa98Sdjl nscd_cfg_param_desc_t *desc; 2701*cb5caa98Sdjl char *nswdb_name, *param_name, *dbl; 2702*cb5caa98Sdjl nscd_rc_t rc = NSCD_SUCCESS; 2703*cb5caa98Sdjl nscd_cfg_nsw_spc_default_t *spc; 2704*cb5caa98Sdjl int i; 2705*cb5caa98Sdjl char msg[NSCD_CFG_MAX_ERR_MSG_LEN]; 2706*cb5caa98Sdjl 2707*cb5caa98Sdjl if (handle == NULL) { 2708*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 2709*cb5caa98Sdjl (me, "handle is NULL\n"); 2710*cb5caa98Sdjl return (NSCD_INVALID_ARGUMENT); 2711*cb5caa98Sdjl } 2712*cb5caa98Sdjl 2713*cb5caa98Sdjl nswdb = handle->nswdb; 2714*cb5caa98Sdjl desc = (nscd_cfg_param_desc_t *)handle->desc; 2715*cb5caa98Sdjl 2716*cb5caa98Sdjl /* 2717*cb5caa98Sdjl * no need to do the special linking thing, 2718*cb5caa98Sdjl * if a global param, or a group, or not a linked param 2719*cb5caa98Sdjl */ 2720*cb5caa98Sdjl if (nswdb == NULL || _nscd_cfg_flag_is_set(desc->pflag, 2721*cb5caa98Sdjl NSCD_CFG_PFLAG_GROUP) || 2722*cb5caa98Sdjl _nscd_cfg_flag_is_not_set(desc->pflag, 2723*cb5caa98Sdjl NSCD_CFG_PFLAG_LINKED)) 2724*cb5caa98Sdjl return (_nscd_cfg_set(handle, data, errorp)); 2725*cb5caa98Sdjl else 2726*cb5caa98Sdjl nswdb_name = nswdb->name; 2727*cb5caa98Sdjl param_name = desc->id.name; 2728*cb5caa98Sdjl 2729*cb5caa98Sdjl /* 2730*cb5caa98Sdjl * if a param is linked to another, it can not be 2731*cb5caa98Sdjl * changed directly 2732*cb5caa98Sdjl */ 2733*cb5caa98Sdjl for (i = 0; i < _nscd_cfg_num_link_default; i++) { 2734*cb5caa98Sdjl 2735*cb5caa98Sdjl if (_nscd_cfg_nsw_link_default[i].data == NULL) 2736*cb5caa98Sdjl continue; 2737*cb5caa98Sdjl 2738*cb5caa98Sdjl if (strcmp(_nscd_cfg_nsw_link_default[i].db, 2739*cb5caa98Sdjl nswdb_name) == 0 && 2740*cb5caa98Sdjl _nscd_cfg_nsw_link_default[i].group_off == 2741*cb5caa98Sdjl desc->g_offset && 2742*cb5caa98Sdjl _nscd_cfg_nsw_link_default[i].param_off == 2743*cb5caa98Sdjl desc->p_offset) { 2744*cb5caa98Sdjl 2745*cb5caa98Sdjl rc = NSCD_CFG_READ_ONLY; 2746*cb5caa98Sdjl 2747*cb5caa98Sdjl (void) snprintf(msg, sizeof (msg), 2748*cb5caa98Sdjl gettext("vaule of \'%s\' not changeable, change that of \'%s\' instead"), 2749*cb5caa98Sdjl nswdb->name, "passwd"); 2750*cb5caa98Sdjl 2751*cb5caa98Sdjl if (errorp != NULL) 2752*cb5caa98Sdjl *errorp = _nscd_cfg_make_error(rc, msg); 2753*cb5caa98Sdjl 2754*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 2755*cb5caa98Sdjl (me, "ERROR: %s\n", msg); 2756*cb5caa98Sdjl 2757*cb5caa98Sdjl return (rc); 2758*cb5caa98Sdjl } 2759*cb5caa98Sdjl } 2760*cb5caa98Sdjl 2761*cb5caa98Sdjl /* 2762*cb5caa98Sdjl * if a param is linked from another, it should be verify 2763*cb5caa98Sdjl * and changed first 2764*cb5caa98Sdjl */ 2765*cb5caa98Sdjl for (i = 0; i < _nscd_cfg_num_link_default; i++) { 2766*cb5caa98Sdjl 2767*cb5caa98Sdjl if (_nscd_cfg_nsw_link_default[i].data == NULL) 2768*cb5caa98Sdjl continue; 2769*cb5caa98Sdjl 2770*cb5caa98Sdjl spc = _nscd_cfg_nsw_link_default[i].data; 2771*cb5caa98Sdjl 2772*cb5caa98Sdjl if (strcmp(spc->db, nswdb_name) == 0 && 2773*cb5caa98Sdjl spc->group_off == desc->g_offset && 2774*cb5caa98Sdjl spc->param_off == desc->p_offset) { 2775*cb5caa98Sdjl 2776*cb5caa98Sdjl rc = _nscd_cfg_set(handle, data, errorp); 2777*cb5caa98Sdjl if (rc != NSCD_SUCCESS) 2778*cb5caa98Sdjl return (rc); 2779*cb5caa98Sdjl break; 2780*cb5caa98Sdjl } 2781*cb5caa98Sdjl } 2782*cb5caa98Sdjl 2783*cb5caa98Sdjl /* 2784*cb5caa98Sdjl * then change all those linked to the one that has been changed 2785*cb5caa98Sdjl */ 2786*cb5caa98Sdjl for (i = 0; i < _nscd_cfg_num_link_default; i++) { 2787*cb5caa98Sdjl 2788*cb5caa98Sdjl if (_nscd_cfg_nsw_link_default[i].data == NULL) 2789*cb5caa98Sdjl continue; 2790*cb5caa98Sdjl 2791*cb5caa98Sdjl spc = _nscd_cfg_nsw_link_default[i].data; 2792*cb5caa98Sdjl 2793*cb5caa98Sdjl if (strcmp(spc->db, nswdb_name) == 0 && 2794*cb5caa98Sdjl spc->group_off == desc->g_offset && 2795*cb5caa98Sdjl spc->param_off == desc->p_offset && 2796*cb5caa98Sdjl _nscd_cfg_nsw_link_default[i].group_off == 2797*cb5caa98Sdjl desc->g_offset && 2798*cb5caa98Sdjl _nscd_cfg_nsw_link_default[i].param_off == 2799*cb5caa98Sdjl desc->p_offset) { 2800*cb5caa98Sdjl 2801*cb5caa98Sdjl dbl = _nscd_cfg_nsw_link_default[i].db; 2802*cb5caa98Sdjl 2803*cb5caa98Sdjl rc = _nscd_cfg_get_handle(param_name, dbl, 2804*cb5caa98Sdjl &hl, errorp); 2805*cb5caa98Sdjl rc = _nscd_cfg_set(hl, data, errorp); 2806*cb5caa98Sdjl _nscd_cfg_free_handle(hl); 2807*cb5caa98Sdjl if (rc != NSCD_SUCCESS) 2808*cb5caa98Sdjl return (rc); 2809*cb5caa98Sdjl } 2810*cb5caa98Sdjl } 2811*cb5caa98Sdjl 2812*cb5caa98Sdjl return (_nscd_cfg_set(handle, data, errorp)); 2813*cb5caa98Sdjl } 2814*cb5caa98Sdjl 2815*cb5caa98Sdjl /* 2816*cb5caa98Sdjl * Return a list of space-separated database names that 2817*cb5caa98Sdjl * have at least one of the input sources appeared in the 2818*cb5caa98Sdjl * configured nsswitch policy string of the databases. 2819*cb5caa98Sdjl * The return string should be freed by the caller. 2820*cb5caa98Sdjl * 2821*cb5caa98Sdjl * For compat sources (compat_group and compat_passwd), 2822*cb5caa98Sdjl * "group" will be returned, if the policy string for 2823*cb5caa98Sdjl * compat_group contains one of the input sources. Same 2824*cb5caa98Sdjl * for compat_passwd and passwd. 2825*cb5caa98Sdjl */ 2826*cb5caa98Sdjl char * 2827*cb5caa98Sdjl _nscd_srcs_in_db_nsw_policy( 2828*cb5caa98Sdjl int num_src, 2829*cb5caa98Sdjl char **srcs) 2830*cb5caa98Sdjl { 2831*cb5caa98Sdjl uint8_t i, j, n = 0, nc = 0; 2832*cb5caa98Sdjl uint8_t compat_grp = 0, compat_pwd = 0; 2833*cb5caa98Sdjl uint8_t *db; 2834*cb5caa98Sdjl uint8_t *db_compat; 2835*cb5caa98Sdjl int dlen = 0; 2836*cb5caa98Sdjl nscd_cfg_nsw_db_data_t *dbcfg; 2837*cb5caa98Sdjl nscd_cfg_switch_t *sw; 2838*cb5caa98Sdjl char *outstr = NULL; 2839*cb5caa98Sdjl char *dbname; 2840*cb5caa98Sdjl 2841*cb5caa98Sdjl db = (uint8_t *)calloc(_nscd_cfg_num_nsw_db, sizeof (uint8_t)); 2842*cb5caa98Sdjl if (db == NULL) 2843*cb5caa98Sdjl return (NULL); 2844*cb5caa98Sdjl 2845*cb5caa98Sdjl db_compat = (uint8_t *)calloc(_nscd_cfg_num_nsw_db, 2846*cb5caa98Sdjl sizeof (uint8_t)); 2847*cb5caa98Sdjl if (db_compat == NULL) { 2848*cb5caa98Sdjl free(db); 2849*cb5caa98Sdjl return (NULL); 2850*cb5caa98Sdjl } 2851*cb5caa98Sdjl 2852*cb5caa98Sdjl for (i = 0; i < _nscd_cfg_num_nsw_db; i++) { 2853*cb5caa98Sdjl 2854*cb5caa98Sdjl (void) rw_rdlock(&nscd_cfg_nsw_db_data_rwlock[i]); 2855*cb5caa98Sdjl 2856*cb5caa98Sdjl dbcfg = &nscd_cfg_nsw_db_data_current[i]; 2857*cb5caa98Sdjl sw = &dbcfg->sw; 2858*cb5caa98Sdjl if (sw->nsw_config_string == NULL) 2859*cb5caa98Sdjl continue; 2860*cb5caa98Sdjl 2861*cb5caa98Sdjl dbname = _nscd_cfg_nsw_db[i].name; 2862*cb5caa98Sdjl for (j = 0; j < num_src; j++) { 2863*cb5caa98Sdjl if (strstr(sw->nsw_config_string, srcs[j]) != 2864*cb5caa98Sdjl NULL) { 2865*cb5caa98Sdjl db[n++] = i; 2866*cb5caa98Sdjl dlen += strlen(dbname) + 1; 2867*cb5caa98Sdjl } else if (strcmp(sw->nsw_config_string, 2868*cb5caa98Sdjl "compat") == 0) { 2869*cb5caa98Sdjl if (strcmp(dbname, "passwd") == 0) { 2870*cb5caa98Sdjl compat_pwd = 1; 2871*cb5caa98Sdjl dlen += 7; 2872*cb5caa98Sdjl } else if (strcmp(dbname, "group") == 0) { 2873*cb5caa98Sdjl compat_grp = 1; 2874*cb5caa98Sdjl dlen += 6; 2875*cb5caa98Sdjl } else { 2876*cb5caa98Sdjl db_compat[nc++] = i; 2877*cb5caa98Sdjl dlen += strlen(dbname) + 1; 2878*cb5caa98Sdjl 2879*cb5caa98Sdjl } 2880*cb5caa98Sdjl } 2881*cb5caa98Sdjl } 2882*cb5caa98Sdjl (void) rw_unlock(&nscd_cfg_nsw_db_data_rwlock[i]); 2883*cb5caa98Sdjl } 2884*cb5caa98Sdjl 2885*cb5caa98Sdjl if (dlen != NULL) 2886*cb5caa98Sdjl outstr = (char *)calloc(1, dlen); 2887*cb5caa98Sdjl if (outstr == NULL) { 2888*cb5caa98Sdjl free(db_compat); 2889*cb5caa98Sdjl free(db); 2890*cb5caa98Sdjl return (NULL); 2891*cb5caa98Sdjl } 2892*cb5caa98Sdjl 2893*cb5caa98Sdjl for (j = 0; j < n; j++) { 2894*cb5caa98Sdjl dbname = _nscd_cfg_nsw_db[db[j]].name; 2895*cb5caa98Sdjl if (strstr(dbname, "group_compat") != NULL) { 2896*cb5caa98Sdjl if (compat_grp == 1) 2897*cb5caa98Sdjl dbname = "group"; 2898*cb5caa98Sdjl else 2899*cb5caa98Sdjl continue; 2900*cb5caa98Sdjl } else if (strstr(dbname, "passwd_compat") != NULL) { 2901*cb5caa98Sdjl if (compat_pwd == 1) 2902*cb5caa98Sdjl dbname = "passwd"; 2903*cb5caa98Sdjl else 2904*cb5caa98Sdjl continue; 2905*cb5caa98Sdjl } 2906*cb5caa98Sdjl 2907*cb5caa98Sdjl (void) strlcat(outstr, dbname, dlen); 2908*cb5caa98Sdjl (void) strlcat(outstr, ",", dlen); 2909*cb5caa98Sdjl } 2910*cb5caa98Sdjl 2911*cb5caa98Sdjl for (j = 0; j < nc; j++) { 2912*cb5caa98Sdjl dbname = _nscd_cfg_nsw_db[db_compat[j]].name; 2913*cb5caa98Sdjl if (compat_pwd == 1) { 2914*cb5caa98Sdjl (void) strlcat(outstr, dbname, dlen); 2915*cb5caa98Sdjl (void) strlcat(outstr, " ", dlen); 2916*cb5caa98Sdjl } 2917*cb5caa98Sdjl } 2918*cb5caa98Sdjl 2919*cb5caa98Sdjl free(db); 2920*cb5caa98Sdjl free(db_compat); 2921*cb5caa98Sdjl return (outstr); 2922*cb5caa98Sdjl 2923*cb5caa98Sdjl } 2924