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