1*cb5caa98Sdjl /* 2*cb5caa98Sdjl * CDDL HEADER START 3*cb5caa98Sdjl * 4*cb5caa98Sdjl * The contents of this file are subject to the terms of the 5*cb5caa98Sdjl * Common Development and Distribution License (the "License"). 6*cb5caa98Sdjl * You may not use this file except in compliance with the License. 7*cb5caa98Sdjl * 8*cb5caa98Sdjl * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*cb5caa98Sdjl * or http://www.opensolaris.org/os/licensing. 10*cb5caa98Sdjl * See the License for the specific language governing permissions 11*cb5caa98Sdjl * and limitations under the License. 12*cb5caa98Sdjl * 13*cb5caa98Sdjl * When distributing Covered Code, include this CDDL HEADER in each 14*cb5caa98Sdjl * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*cb5caa98Sdjl * If applicable, add the following below this CDDL HEADER, with the 16*cb5caa98Sdjl * fields enclosed by brackets "[]" replaced with your own identifying 17*cb5caa98Sdjl * information: Portions Copyright [yyyy] [name of copyright owner] 18*cb5caa98Sdjl * 19*cb5caa98Sdjl * CDDL HEADER END 20*cb5caa98Sdjl */ 21*cb5caa98Sdjl /* 22*cb5caa98Sdjl * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23*cb5caa98Sdjl * Use is subject to license terms. 24*cb5caa98Sdjl */ 25*cb5caa98Sdjl 26*cb5caa98Sdjl #pragma ident "%Z%%M% %I% %E% SMI" 27*cb5caa98Sdjl 28*cb5caa98Sdjl #include <stdlib.h> 29*cb5caa98Sdjl #include <libscf_priv.h> 30*cb5caa98Sdjl #include <string.h> 31*cb5caa98Sdjl #include <assert.h> 32*cb5caa98Sdjl #include "nscd_switch.h" 33*cb5caa98Sdjl #include "nscd_log.h" 34*cb5caa98Sdjl #include "nscd_db.h" 35*cb5caa98Sdjl 36*cb5caa98Sdjl /* 37*cb5caa98Sdjl * nscd database for each source. It contains backend 38*cb5caa98Sdjl * info (nscd_be_info_t) for each naming database. 39*cb5caa98Sdjl * Protected by nscd_src_backend_db_lock. 40*cb5caa98Sdjl */ 41*cb5caa98Sdjl nscd_db_t ***nscd_src_backend_db; 42*cb5caa98Sdjl static rwlock_t nscd_src_backend_db_lock = DEFAULTRWLOCK; 43*cb5caa98Sdjl 44*cb5caa98Sdjl /* 45*cb5caa98Sdjl * nsswitch config monitored by nscd. Protected by 46*cb5caa98Sdjl * readers/writer lock nscd_nsw_config_lock 47*cb5caa98Sdjl */ 48*cb5caa98Sdjl nscd_nsw_config_t ***nscd_nsw_config; 49*cb5caa98Sdjl static rwlock_t nscd_nsw_config_lock = DEFAULTRWLOCK; 50*cb5caa98Sdjl 51*cb5caa98Sdjl /* 52*cb5caa98Sdjl * nsswitch source index/name array 53*cb5caa98Sdjl * (allow 16 user-defined nsswitch sources/backends) 54*cb5caa98Sdjl */ 55*cb5caa98Sdjl #define NSCD_NUM_SRC_UDEF 16 56*cb5caa98Sdjl nscd_cfg_id_t *_nscd_cfg_nsw_src_all; 57*cb5caa98Sdjl int _nscd_cfg_num_nsw_src_all; 58*cb5caa98Sdjl 59*cb5caa98Sdjl static void 60*cb5caa98Sdjl free_nscd_nsw_config( 61*cb5caa98Sdjl nscd_acc_data_t *data) 62*cb5caa98Sdjl { 63*cb5caa98Sdjl 64*cb5caa98Sdjl nscd_nsw_config_t *nsw_cfg = *(nscd_nsw_config_t **)data; 65*cb5caa98Sdjl char *me = "free_nscd_nsw_config"; 66*cb5caa98Sdjl 67*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_DEBUG) 68*cb5caa98Sdjl (me, "freeing nscd nsw config %p \n", nsw_cfg); 69*cb5caa98Sdjl if (nsw_cfg == NULL) 70*cb5caa98Sdjl return; 71*cb5caa98Sdjl 72*cb5caa98Sdjl if (nsw_cfg->db_name != NULL) 73*cb5caa98Sdjl free(nsw_cfg->db_name); 74*cb5caa98Sdjl if (nsw_cfg->nsw_cfg_str != NULL) 75*cb5caa98Sdjl free(nsw_cfg->nsw_cfg_str); 76*cb5caa98Sdjl if (nsw_cfg->nsw_config != NULL) 77*cb5caa98Sdjl (void) __nsw_freeconfig_v1(nsw_cfg->nsw_config); 78*cb5caa98Sdjl if (nsw_cfg->src_idx != NULL) 79*cb5caa98Sdjl free(nsw_cfg->src_idx); 80*cb5caa98Sdjl 81*cb5caa98Sdjl free(nsw_cfg); 82*cb5caa98Sdjl } 83*cb5caa98Sdjl 84*cb5caa98Sdjl 85*cb5caa98Sdjl void 86*cb5caa98Sdjl _nscd_free_nsw_config( 87*cb5caa98Sdjl nscd_nsw_config_t *nswcfg) 88*cb5caa98Sdjl { 89*cb5caa98Sdjl free_nscd_nsw_config((nscd_acc_data_t *)&nswcfg); 90*cb5caa98Sdjl } 91*cb5caa98Sdjl 92*cb5caa98Sdjl void 93*cb5caa98Sdjl _nscd_free_all_nsw_config() 94*cb5caa98Sdjl { 95*cb5caa98Sdjl 96*cb5caa98Sdjl nscd_nsw_config_t **nsw_cfg; 97*cb5caa98Sdjl int i; 98*cb5caa98Sdjl char *me = "_nscd_free_all_nsw_config"; 99*cb5caa98Sdjl 100*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_DEBUG) 101*cb5caa98Sdjl (me, "freeing all nscd nsw config \n"); 102*cb5caa98Sdjl 103*cb5caa98Sdjl (void) rw_wrlock(&nscd_nsw_config_lock); 104*cb5caa98Sdjl for (i = 0; i < NSCD_NUM_DB; i++) { 105*cb5caa98Sdjl 106*cb5caa98Sdjl if ((nsw_cfg = nscd_nsw_config[i]) == NULL) 107*cb5caa98Sdjl continue; 108*cb5caa98Sdjl 109*cb5caa98Sdjl nscd_nsw_config[i] = (nscd_nsw_config_t **)_nscd_set( 110*cb5caa98Sdjl (nscd_acc_data_t *)nsw_cfg, NULL); 111*cb5caa98Sdjl } 112*cb5caa98Sdjl (void) rw_unlock(&nscd_nsw_config_lock); 113*cb5caa98Sdjl } 114*cb5caa98Sdjl 115*cb5caa98Sdjl 116*cb5caa98Sdjl static void 117*cb5caa98Sdjl free_nsw_backend_info_db(nscd_acc_data_t *data) 118*cb5caa98Sdjl { 119*cb5caa98Sdjl 120*cb5caa98Sdjl nscd_db_t *db = *(nscd_db_t **)data; 121*cb5caa98Sdjl char *me = "free_nsw_backend_info_db"; 122*cb5caa98Sdjl 123*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_DEBUG) 124*cb5caa98Sdjl (me, "freeing nsw backend info db %p\n", db); 125*cb5caa98Sdjl 126*cb5caa98Sdjl if (db == NULL) 127*cb5caa98Sdjl return; 128*cb5caa98Sdjl 129*cb5caa98Sdjl _nscd_free_db(db); 130*cb5caa98Sdjl 131*cb5caa98Sdjl } 132*cb5caa98Sdjl 133*cb5caa98Sdjl void 134*cb5caa98Sdjl _nscd_free_all_nsw_backend_info_db() 135*cb5caa98Sdjl { 136*cb5caa98Sdjl 137*cb5caa98Sdjl nscd_db_t **db; 138*cb5caa98Sdjl int i; 139*cb5caa98Sdjl char *me = " _nscd_free_all_nsw_backend_info_db"; 140*cb5caa98Sdjl 141*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_DEBUG) 142*cb5caa98Sdjl (me, "freeing all nsw backend info db\n"); 143*cb5caa98Sdjl 144*cb5caa98Sdjl (void) rw_wrlock(&nscd_src_backend_db_lock); 145*cb5caa98Sdjl for (i = 0; i < NSCD_NUM_SRC; i++) { 146*cb5caa98Sdjl 147*cb5caa98Sdjl if ((db = nscd_src_backend_db[i]) == NULL) 148*cb5caa98Sdjl continue; 149*cb5caa98Sdjl 150*cb5caa98Sdjl nscd_src_backend_db[i] = (nscd_db_t **)_nscd_set( 151*cb5caa98Sdjl (nscd_acc_data_t *)db, NULL); 152*cb5caa98Sdjl } 153*cb5caa98Sdjl (void) rw_unlock(&nscd_src_backend_db_lock); 154*cb5caa98Sdjl } 155*cb5caa98Sdjl 156*cb5caa98Sdjl /* 157*cb5caa98Sdjl * Populate the backend info db for the 'NSCD_NSW_SRC_NAME(srci)' 158*cb5caa98Sdjl * source. Create one entry for each source/database pair 159*cb5caa98Sdjl * (e.g., ldap:passwd, nis:hosts, etc). 160*cb5caa98Sdjl */ 161*cb5caa98Sdjl static nscd_rc_t 162*cb5caa98Sdjl _nscd_populate_nsw_backend_info_db(int srci) 163*cb5caa98Sdjl { 164*cb5caa98Sdjl nscd_be_info_t be_info, *bi; 165*cb5caa98Sdjl nss_backend_finder_t *bf; 166*cb5caa98Sdjl nscd_nsw_config_t *nsw_cfg; 167*cb5caa98Sdjl int i, size; 168*cb5caa98Sdjl nscd_db_entry_t *db_entry; 169*cb5caa98Sdjl char *src = NSCD_NSW_SRC_NAME(srci); 170*cb5caa98Sdjl const char *dbn; 171*cb5caa98Sdjl char *me = "_nscd_populate_nsw_backend_info_db"; 172*cb5caa98Sdjl 173*cb5caa98Sdjl for (i = 0; i < NSCD_NUM_DB; i++) { 174*cb5caa98Sdjl 175*cb5caa98Sdjl if (nscd_nsw_config[i] == NULL) 176*cb5caa98Sdjl continue; 177*cb5caa98Sdjl 178*cb5caa98Sdjl nsw_cfg = *nscd_nsw_config[i]; 179*cb5caa98Sdjl dbn = NSCD_NSW_DB_NAME(i); 180*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_DEBUG) 181*cb5caa98Sdjl (me, "adding backend info for <%s : %s>\n", src, dbn); 182*cb5caa98Sdjl 183*cb5caa98Sdjl (void) memset(&be_info, 0, sizeof (be_info)); 184*cb5caa98Sdjl 185*cb5caa98Sdjl for (bf = nsw_cfg->fe_params.finders; bf != 0; 186*cb5caa98Sdjl bf = bf->next) { 187*cb5caa98Sdjl nss_backend_constr_t c; 188*cb5caa98Sdjl 189*cb5caa98Sdjl c = (*bf->lookup)(bf->lookup_priv, dbn, src, 190*cb5caa98Sdjl &be_info.finder_priv); 191*cb5caa98Sdjl 192*cb5caa98Sdjl if (c != 0) { 193*cb5caa98Sdjl be_info.be_constr = c; 194*cb5caa98Sdjl be_info.finder = bf; 195*cb5caa98Sdjl break; 196*cb5caa98Sdjl } 197*cb5caa98Sdjl } 198*cb5caa98Sdjl if (be_info.be_constr == NULL) { 199*cb5caa98Sdjl /* 200*cb5caa98Sdjl * Couldn't find the backend anywhere. 201*cb5caa98Sdjl * This is fine, some backend just don't 202*cb5caa98Sdjl * support certain databases. 203*cb5caa98Sdjl */ 204*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 205*cb5caa98Sdjl (me, "unable to find backend info " 206*cb5caa98Sdjl "for <%s : %s>\n", src, dbn); 207*cb5caa98Sdjl } 208*cb5caa98Sdjl 209*cb5caa98Sdjl size = sizeof (nscd_be_info_t); 210*cb5caa98Sdjl 211*cb5caa98Sdjl db_entry = _nscd_alloc_db_entry(NSCD_DATA_BACKEND_INFO, 212*cb5caa98Sdjl dbn, size, 1, 1); 213*cb5caa98Sdjl 214*cb5caa98Sdjl if (db_entry == NULL) { 215*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 216*cb5caa98Sdjl (me, "unable to allocate db entry for " 217*cb5caa98Sdjl "<%s : %s>\n", src, dbn); 218*cb5caa98Sdjl return (NSCD_NO_MEMORY); 219*cb5caa98Sdjl } 220*cb5caa98Sdjl 221*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_DEBUG) 222*cb5caa98Sdjl (me, "adding be db entry %p for <%s : %s> to db %p: " 223*cb5caa98Sdjl "constr = %p\n", db_entry, src, dbn, 224*cb5caa98Sdjl *nscd_src_backend_db[srci], be_info.be_constr); 225*cb5caa98Sdjl 226*cb5caa98Sdjl bi = (nscd_be_info_t *)*(db_entry->data_array); 227*cb5caa98Sdjl *bi = be_info; 228*cb5caa98Sdjl 229*cb5caa98Sdjl (void) _nscd_rdlock((nscd_acc_data_t *) 230*cb5caa98Sdjl nscd_src_backend_db[srci]); 231*cb5caa98Sdjl (void) _nscd_add_db_entry(*nscd_src_backend_db[srci], 232*cb5caa98Sdjl dbn, db_entry, NSCD_ADD_DB_ENTRY_LAST); 233*cb5caa98Sdjl (void) _nscd_rw_unlock((nscd_acc_data_t *) 234*cb5caa98Sdjl nscd_src_backend_db[srci]); 235*cb5caa98Sdjl } 236*cb5caa98Sdjl 237*cb5caa98Sdjl return (NSCD_SUCCESS); 238*cb5caa98Sdjl } 239*cb5caa98Sdjl 240*cb5caa98Sdjl /* 241*cb5caa98Sdjl * create data structures (used by the switch engine) based 242*cb5caa98Sdjl * on the input switch policy configuration and database 243*cb5caa98Sdjl * name and indexes 244*cb5caa98Sdjl */ 245*cb5caa98Sdjl nscd_rc_t 246*cb5caa98Sdjl _nscd_create_sw_struct( 247*cb5caa98Sdjl int dbi, 248*cb5caa98Sdjl const char *dbn, 249*cb5caa98Sdjl const char *cfgstr, 250*cb5caa98Sdjl void *swcfgv1, 251*cb5caa98Sdjl nscd_nsw_params_t *params) 252*cb5caa98Sdjl { 253*cb5caa98Sdjl char *me = "_nscd_create_sw_struct"; 254*cb5caa98Sdjl nscd_rc_t rc = NSCD_SUCCESS; 255*cb5caa98Sdjl nscd_nsw_config_t *nsw_cfg = NULL; 256*cb5caa98Sdjl nscd_nsw_config_t **nsw_cfg_p = NULL; 257*cb5caa98Sdjl struct __nsw_switchconfig_v1 *swcfg = NULL; 258*cb5caa98Sdjl struct __nsw_lookup_v1 *lkp; 259*cb5caa98Sdjl enum __nsw_parse_err err; 260*cb5caa98Sdjl int maxsrc; 261*cb5caa98Sdjl int *src_idx_a = NULL; 262*cb5caa98Sdjl int j, k; 263*cb5caa98Sdjl 264*cb5caa98Sdjl /* 265*cb5caa98Sdjl * if the nsw config string has been parsed into 266*cb5caa98Sdjl * a struct __nsw_switchconfig_v1, use it. If not, 267*cb5caa98Sdjl * create the struct. 268*cb5caa98Sdjl */ 269*cb5caa98Sdjl if (swcfgv1 != NULL) 270*cb5caa98Sdjl swcfg = (struct __nsw_switchconfig_v1 *)swcfgv1; 271*cb5caa98Sdjl else { 272*cb5caa98Sdjl char *cstr; 273*cb5caa98Sdjl 274*cb5caa98Sdjl cstr = strdup(cfgstr); 275*cb5caa98Sdjl if (cstr == NULL) 276*cb5caa98Sdjl return (NSCD_NO_MEMORY); 277*cb5caa98Sdjl 278*cb5caa98Sdjl /* 279*cb5caa98Sdjl * parse the nsw config string and create 280*cb5caa98Sdjl * a struct __nsw_switchconfig_v1 281*cb5caa98Sdjl */ 282*cb5caa98Sdjl swcfg = _nsw_getoneconfig_v1(dbn, cstr, &err); 283*cb5caa98Sdjl free(cstr); 284*cb5caa98Sdjl if (swcfg == NULL) { 285*cb5caa98Sdjl rc = NSCD_CFG_SYNTAX_ERROR; 286*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 287*cb5caa98Sdjl (me, "error: unable to process nsw config string\n"); 288*cb5caa98Sdjl goto error_exit; 289*cb5caa98Sdjl } 290*cb5caa98Sdjl } 291*cb5caa98Sdjl 292*cb5caa98Sdjl /* allocate the space for a nscd_nsw_config_t */ 293*cb5caa98Sdjl nsw_cfg = calloc(1, sizeof (nscd_nsw_config_t)); 294*cb5caa98Sdjl if (nsw_cfg == NULL) { 295*cb5caa98Sdjl rc = NSCD_NO_MEMORY; 296*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 297*cb5caa98Sdjl (me, "error: unable to allocate an nscd_nsw_config_t\n"); 298*cb5caa98Sdjl goto error_exit; 299*cb5caa98Sdjl } 300*cb5caa98Sdjl 301*cb5caa98Sdjl /* need to know how many backends (sources) */ 302*cb5caa98Sdjl maxsrc = swcfg->num_lookups; 303*cb5caa98Sdjl nsw_cfg->max_src = maxsrc; 304*cb5caa98Sdjl 305*cb5caa98Sdjl /* 306*cb5caa98Sdjl * allocate an array to store the index for each 307*cb5caa98Sdjl * backend (source) 308*cb5caa98Sdjl */ 309*cb5caa98Sdjl src_idx_a = calloc(1, maxsrc * sizeof (int)); 310*cb5caa98Sdjl if (src_idx_a == NULL) { 311*cb5caa98Sdjl rc = NSCD_NO_MEMORY; 312*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 313*cb5caa98Sdjl (me, "error: unable to allocate an array for source index\n"); 314*cb5caa98Sdjl goto error_exit; 315*cb5caa98Sdjl } 316*cb5caa98Sdjl 317*cb5caa98Sdjl /* 318*cb5caa98Sdjl * set the index for each backend (source) 319*cb5caa98Sdjl */ 320*cb5caa98Sdjl lkp = swcfg->lookups; 321*cb5caa98Sdjl for (j = 0; j < maxsrc; j++) { 322*cb5caa98Sdjl char *usrc; 323*cb5caa98Sdjl 324*cb5caa98Sdjl for (k = 0; k < NSCD_NUM_SRC && 325*cb5caa98Sdjl NSCD_NSW_SRC_NAME(k) != NULL && 326*cb5caa98Sdjl strcmp(lkp->service_name, 327*cb5caa98Sdjl NSCD_NSW_SRC_NAME(k)) != 0; k++); 328*cb5caa98Sdjl 329*cb5caa98Sdjl if (k < NSCD_NUM_SRC && NSCD_NSW_SRC_NAME(k) == NULL) { 330*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_DEBUG) 331*cb5caa98Sdjl (me, "unknown nsw source name %s\n", 332*cb5caa98Sdjl lkp->service_name); 333*cb5caa98Sdjl usrc = strdup(lkp->service_name); 334*cb5caa98Sdjl if (usrc == NULL) { 335*cb5caa98Sdjl rc = NSCD_NO_MEMORY; 336*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, 337*cb5caa98Sdjl NSCD_LOG_LEVEL_ERROR) 338*cb5caa98Sdjl (me, "unable to strdup() source name\n"); 339*cb5caa98Sdjl goto error_exit; 340*cb5caa98Sdjl } 341*cb5caa98Sdjl NSCD_NSW_SRC_NAME(k) = usrc; 342*cb5caa98Sdjl 343*cb5caa98Sdjl rc = _nscd_populate_nsw_backend_info_db(k); 344*cb5caa98Sdjl if (rc != NSCD_SUCCESS) { 345*cb5caa98Sdjl free(usrc); 346*cb5caa98Sdjl NSCD_NSW_SRC_NAME(k) = NULL; 347*cb5caa98Sdjl goto error_exit; 348*cb5caa98Sdjl } 349*cb5caa98Sdjl } else if (NSCD_NSW_SRC_NAME(k) == NULL) { 350*cb5caa98Sdjl /* 351*cb5caa98Sdjl * number of user-defined source exceeded 352*cb5caa98Sdjl */ 353*cb5caa98Sdjl rc = NSCD_CFG_SYNTAX_ERROR; 354*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 355*cb5caa98Sdjl (me, "error: number of user_defined source exceeded\n"); 356*cb5caa98Sdjl 357*cb5caa98Sdjl goto error_exit; 358*cb5caa98Sdjl } 359*cb5caa98Sdjl 360*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_DEBUG) 361*cb5caa98Sdjl (me, "setting source index array [%d] = %d (%s)\n", 362*cb5caa98Sdjl j, k, lkp->service_name); 363*cb5caa98Sdjl 364*cb5caa98Sdjl src_idx_a[j] = k; 365*cb5caa98Sdjl 366*cb5caa98Sdjl lkp = lkp->next; 367*cb5caa98Sdjl if (lkp == NULL) break; 368*cb5caa98Sdjl 369*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_DEBUG) 370*cb5caa98Sdjl (me, "number of nsw sources = %d\n", nsw_cfg->max_src); 371*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_DEBUG) 372*cb5caa98Sdjl (me, "next nsw source is %s\n", lkp->service_name); 373*cb5caa98Sdjl } 374*cb5caa98Sdjl 375*cb5caa98Sdjl /* set it up to reference count the switch policy config */ 376*cb5caa98Sdjl nsw_cfg_p = (nscd_nsw_config_t **)_nscd_alloc( 377*cb5caa98Sdjl NSCD_DATA_NSW_CONFIG, 378*cb5caa98Sdjl sizeof (nscd_nsw_config_t **), 379*cb5caa98Sdjl free_nscd_nsw_config, 380*cb5caa98Sdjl NSCD_ALLOC_RWLOCK); 381*cb5caa98Sdjl 382*cb5caa98Sdjl if (nsw_cfg_p == NULL) { 383*cb5caa98Sdjl rc = NSCD_NO_MEMORY; 384*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 385*cb5caa98Sdjl (me, "unable to allocate a new nsw config DB\n"); 386*cb5caa98Sdjl goto error_exit; 387*cb5caa98Sdjl } 388*cb5caa98Sdjl *nsw_cfg_p = nsw_cfg; 389*cb5caa98Sdjl 390*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_DEBUG) 391*cb5caa98Sdjl (me, "new nsw config DB %p allocated\n", nsw_cfg_p); 392*cb5caa98Sdjl 393*cb5caa98Sdjl /* save all the data in the new nscd_nsw_config_t */ 394*cb5caa98Sdjl nsw_cfg->db_name = strdup(dbn); 395*cb5caa98Sdjl nsw_cfg->nsw_cfg_str = strdup(cfgstr); 396*cb5caa98Sdjl if (nsw_cfg->db_name == NULL || nsw_cfg->nsw_cfg_str == NULL) { 397*cb5caa98Sdjl rc = NSCD_NO_MEMORY; 398*cb5caa98Sdjl goto error_exit; 399*cb5caa98Sdjl } 400*cb5caa98Sdjl 401*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_DEBUG) 402*cb5caa98Sdjl (me, "switch policy \"%s\" for database is \"%s\"\n", 403*cb5caa98Sdjl nsw_cfg->db_name, nsw_cfg->nsw_cfg_str); 404*cb5caa98Sdjl 405*cb5caa98Sdjl nsw_cfg->nsw_config = swcfg; 406*cb5caa98Sdjl nsw_cfg->src_idx = src_idx_a; 407*cb5caa98Sdjl 408*cb5caa98Sdjl /* 409*cb5caa98Sdjl * set default frontend params and if necessary call initf() 410*cb5caa98Sdjl * to initialize or override 411*cb5caa98Sdjl */ 412*cb5caa98Sdjl nsw_cfg->fe_params.max_active_per_src = 10; 413*cb5caa98Sdjl nsw_cfg->fe_params.max_dormant_per_src = 1; 414*cb5caa98Sdjl nsw_cfg->fe_params.finders = nss_default_finders; 415*cb5caa98Sdjl if (params != NULL) { 416*cb5caa98Sdjl nsw_cfg->fe_params = params->p; 417*cb5caa98Sdjl 418*cb5caa98Sdjl if (params->p.flags & NSS_USE_DEFAULT_CONFIG) { 419*cb5caa98Sdjl params->nswcfg = nsw_cfg_p; 420*cb5caa98Sdjl /* 421*cb5caa98Sdjl * this nsw_cfg is not meant to last long, no need 422*cb5caa98Sdjl * to set up the nsw state and getent bases, just 423*cb5caa98Sdjl * exit with NSCD_SUCCESS 424*cb5caa98Sdjl */ 425*cb5caa98Sdjl nsw_cfg->nobase = 1; 426*cb5caa98Sdjl goto error_exit; 427*cb5caa98Sdjl } 428*cb5caa98Sdjl } else 429*cb5caa98Sdjl (void) (nscd_nss_db_initf[dbi])(&nsw_cfg->fe_params); 430*cb5caa98Sdjl 431*cb5caa98Sdjl /* 432*cb5caa98Sdjl * activate the new nscd_nsw_config_t, the old one 433*cb5caa98Sdjl * will either be deleted or left on the side (and be 434*cb5caa98Sdjl * deleted eventually) 435*cb5caa98Sdjl */ 436*cb5caa98Sdjl nscd_nsw_config[dbi] = (nscd_nsw_config_t **)_nscd_set( 437*cb5caa98Sdjl (nscd_acc_data_t *)nscd_nsw_config[dbi], 438*cb5caa98Sdjl (nscd_acc_data_t *)nsw_cfg_p); 439*cb5caa98Sdjl 440*cb5caa98Sdjl /* 441*cb5caa98Sdjl * also create a new nsw state base 442*cb5caa98Sdjl */ 443*cb5caa98Sdjl if ((rc = _nscd_init_nsw_state_base(dbi, 1)) != NSCD_SUCCESS) { 444*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 445*cb5caa98Sdjl (me, "unable to initialize a nsw state base(%d)\n", dbi); 446*cb5caa98Sdjl goto error_exit; 447*cb5caa98Sdjl } 448*cb5caa98Sdjl 449*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_DEBUG) 450*cb5caa98Sdjl (me, "new nsw state base(%d) %p created\n", dbi, 451*cb5caa98Sdjl nscd_nsw_state_base[dbi]); 452*cb5caa98Sdjl 453*cb5caa98Sdjl /* 454*cb5caa98Sdjl * also create a new getent context base 455*cb5caa98Sdjl */ 456*cb5caa98Sdjl if ((rc = _nscd_init_getent_ctx_base(dbi, 1)) != NSCD_SUCCESS) { 457*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 458*cb5caa98Sdjl (me, "unable to initialize a getent context base(%d)\n", dbi); 459*cb5caa98Sdjl goto error_exit; 460*cb5caa98Sdjl } 461*cb5caa98Sdjl 462*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_DEBUG) 463*cb5caa98Sdjl (me, "new getent context base(%d) %p created\n", dbi, 464*cb5caa98Sdjl nscd_getent_ctx_base[dbi]); 465*cb5caa98Sdjl 466*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_DEBUG) 467*cb5caa98Sdjl (me, "new nsw config created (database = %s, " 468*cb5caa98Sdjl "config = %s)\n", dbn, cfgstr); 469*cb5caa98Sdjl 470*cb5caa98Sdjl 471*cb5caa98Sdjl error_exit: 472*cb5caa98Sdjl 473*cb5caa98Sdjl if (rc != NSCD_SUCCESS) { 474*cb5caa98Sdjl 475*cb5caa98Sdjl if (swcfgv1 == NULL && swcfg != NULL) 476*cb5caa98Sdjl (void) __nsw_freeconfig_v1(swcfg); 477*cb5caa98Sdjl if (src_idx_a != NULL) 478*cb5caa98Sdjl free(src_idx_a); 479*cb5caa98Sdjl if (nsw_cfg_p) 480*cb5caa98Sdjl free(nsw_cfg_p); 481*cb5caa98Sdjl if (nsw_cfg != NULL) { 482*cb5caa98Sdjl if (nsw_cfg->db_name != NULL) 483*cb5caa98Sdjl free(nsw_cfg->db_name); 484*cb5caa98Sdjl if (nsw_cfg->nsw_cfg_str != NULL) 485*cb5caa98Sdjl free(nsw_cfg->nsw_cfg_str); 486*cb5caa98Sdjl free(nsw_cfg); 487*cb5caa98Sdjl } 488*cb5caa98Sdjl 489*cb5caa98Sdjl return (rc); 490*cb5caa98Sdjl } else 491*cb5caa98Sdjl return (NSCD_SUCCESS); 492*cb5caa98Sdjl } 493*cb5caa98Sdjl 494*cb5caa98Sdjl static nscd_rc_t 495*cb5caa98Sdjl create_nsw_config(int dbi) 496*cb5caa98Sdjl { 497*cb5caa98Sdjl 498*cb5caa98Sdjl nscd_nsw_config_t *nsw_cfg = NULL; 499*cb5caa98Sdjl nscd_nsw_config_t **nsw_cfg_p = NULL; 500*cb5caa98Sdjl char *me = "create_nsw_config"; 501*cb5caa98Sdjl 502*cb5caa98Sdjl /* 503*cb5caa98Sdjl * if pseudo-databases (initf function not defined), 504*cb5caa98Sdjl * don't bother now 505*cb5caa98Sdjl */ 506*cb5caa98Sdjl if (nscd_nss_db_initf[dbi] == NULL) 507*cb5caa98Sdjl return (NSCD_SUCCESS); 508*cb5caa98Sdjl 509*cb5caa98Sdjl /* allocate the space for a nscd_nsw_config_t */ 510*cb5caa98Sdjl nsw_cfg = calloc(1, sizeof (nscd_nsw_config_t)); 511*cb5caa98Sdjl if (nsw_cfg == NULL) { 512*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 513*cb5caa98Sdjl (me, "unable to allocate a nsw config structure\n"); 514*cb5caa98Sdjl return (NSCD_NO_MEMORY); 515*cb5caa98Sdjl } 516*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_DEBUG) 517*cb5caa98Sdjl (me, "nsw config structure %pallocated\n", nsw_cfg); 518*cb5caa98Sdjl 519*cb5caa98Sdjl nsw_cfg_p = (nscd_nsw_config_t **)_nscd_alloc( 520*cb5caa98Sdjl NSCD_DATA_NSW_CONFIG, 521*cb5caa98Sdjl sizeof (nscd_nsw_config_t **), 522*cb5caa98Sdjl free_nscd_nsw_config, 523*cb5caa98Sdjl NSCD_ALLOC_RWLOCK); 524*cb5caa98Sdjl 525*cb5caa98Sdjl if (nsw_cfg_p == NULL) { 526*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 527*cb5caa98Sdjl (me, "unable to allocate a pointer to nsw config structure\n"); 528*cb5caa98Sdjl return (NSCD_NO_MEMORY); 529*cb5caa98Sdjl } 530*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_DEBUG) 531*cb5caa98Sdjl (me, "nsw config pointer = %p\n", nsw_cfg_p); 532*cb5caa98Sdjl 533*cb5caa98Sdjl nsw_cfg->db_name = strdup(NSCD_NSW_DB_NAME(dbi)); 534*cb5caa98Sdjl if (nsw_cfg->db_name == NULL) { 535*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 536*cb5caa98Sdjl (me, "unable to strdup the db name\n"); 537*cb5caa98Sdjl return (NSCD_NO_MEMORY); 538*cb5caa98Sdjl } 539*cb5caa98Sdjl 540*cb5caa98Sdjl /* 541*cb5caa98Sdjl * set default frontend params and then call initf() 542*cb5caa98Sdjl * to initialize or override 543*cb5caa98Sdjl */ 544*cb5caa98Sdjl nsw_cfg->fe_params.max_active_per_src = 10; 545*cb5caa98Sdjl nsw_cfg->fe_params.max_dormant_per_src = 1; 546*cb5caa98Sdjl nsw_cfg->fe_params.finders = nss_default_finders; 547*cb5caa98Sdjl (void) (nscd_nss_db_initf[dbi])(&nsw_cfg->fe_params); 548*cb5caa98Sdjl 549*cb5caa98Sdjl /* 550*cb5caa98Sdjl * activate the new nscd_nsw_config_t 551*cb5caa98Sdjl */ 552*cb5caa98Sdjl *nsw_cfg_p = nsw_cfg; 553*cb5caa98Sdjl nscd_nsw_config[dbi] = (nscd_nsw_config_t **)_nscd_set( 554*cb5caa98Sdjl (nscd_acc_data_t *)nscd_nsw_config[dbi], 555*cb5caa98Sdjl (nscd_acc_data_t *)nsw_cfg_p); 556*cb5caa98Sdjl 557*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_DEBUG) 558*cb5caa98Sdjl (me, "nsw config %p activated\n", nsw_cfg); 559*cb5caa98Sdjl 560*cb5caa98Sdjl return (NSCD_SUCCESS); 561*cb5caa98Sdjl } 562*cb5caa98Sdjl 563*cb5caa98Sdjl nscd_rc_t 564*cb5caa98Sdjl _nscd_init_all_nsw_config(void) 565*cb5caa98Sdjl { 566*cb5caa98Sdjl nscd_rc_t rc; 567*cb5caa98Sdjl int i; 568*cb5caa98Sdjl char *me = "_nscd_init_all_nsw_config"; 569*cb5caa98Sdjl 570*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_DEBUG) 571*cb5caa98Sdjl (me, "initializing all nsw config\n"); 572*cb5caa98Sdjl 573*cb5caa98Sdjl for (i = 0; i < NSCD_NUM_DB; i++) { 574*cb5caa98Sdjl if ((rc = create_nsw_config(i)) != NSCD_SUCCESS) 575*cb5caa98Sdjl return (rc); 576*cb5caa98Sdjl } 577*cb5caa98Sdjl 578*cb5caa98Sdjl return (NSCD_SUCCESS); 579*cb5caa98Sdjl } 580*cb5caa98Sdjl 581*cb5caa98Sdjl static nscd_rc_t 582*cb5caa98Sdjl init_nsw_be_info_db(int srci) 583*cb5caa98Sdjl { 584*cb5caa98Sdjl nscd_db_t *ret, **db_p; 585*cb5caa98Sdjl char *me = "init_nsw_be_info_db"; 586*cb5caa98Sdjl 587*cb5caa98Sdjl ret = _nscd_alloc_db(NSCD_DB_SIZE_SMALL); 588*cb5caa98Sdjl 589*cb5caa98Sdjl if (ret == NULL) { 590*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 591*cb5caa98Sdjl (me, "unable to allocate a nsw be info database\n"); 592*cb5caa98Sdjl return (NSCD_NO_MEMORY); 593*cb5caa98Sdjl } 594*cb5caa98Sdjl 595*cb5caa98Sdjl /* set up to reference count the backend info db */ 596*cb5caa98Sdjl db_p = (nscd_db_t **) 597*cb5caa98Sdjl _nscd_alloc(NSCD_DATA_BACKEND_INFO_DB, 598*cb5caa98Sdjl sizeof (nscd_db_t **), 599*cb5caa98Sdjl free_nsw_backend_info_db, 600*cb5caa98Sdjl NSCD_ALLOC_RWLOCK); 601*cb5caa98Sdjl 602*cb5caa98Sdjl if (db_p == NULL) { 603*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 604*cb5caa98Sdjl (me, "unable to allocate the pointer to the nsw " 605*cb5caa98Sdjl "be info database\n"); 606*cb5caa98Sdjl return (NSCD_NO_MEMORY); 607*cb5caa98Sdjl } 608*cb5caa98Sdjl 609*cb5caa98Sdjl *db_p = ret; 610*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_DEBUG) 611*cb5caa98Sdjl (me, "backend database (db_p = %p, db = %p)\n", db_p, *db_p); 612*cb5caa98Sdjl 613*cb5caa98Sdjl nscd_src_backend_db[srci] = (nscd_db_t **)_nscd_set( 614*cb5caa98Sdjl (nscd_acc_data_t *)nscd_src_backend_db[srci], 615*cb5caa98Sdjl (nscd_acc_data_t *)db_p); 616*cb5caa98Sdjl 617*cb5caa98Sdjl return (NSCD_SUCCESS); 618*cb5caa98Sdjl } 619*cb5caa98Sdjl 620*cb5caa98Sdjl nscd_rc_t 621*cb5caa98Sdjl _nscd_init_all_nsw_be_info_db(void) 622*cb5caa98Sdjl { 623*cb5caa98Sdjl 624*cb5caa98Sdjl int i; 625*cb5caa98Sdjl nscd_rc_t rc; 626*cb5caa98Sdjl char *me = "_nscd_init_all_nsw_be_info_db"; 627*cb5caa98Sdjl 628*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_DEBUG) 629*cb5caa98Sdjl (me, "initializing all nsw be info databases\n"); 630*cb5caa98Sdjl 631*cb5caa98Sdjl for (i = 0; i < NSCD_NUM_SRC; i++) { 632*cb5caa98Sdjl if ((rc = init_nsw_be_info_db(i)) != NSCD_SUCCESS) 633*cb5caa98Sdjl return (rc); 634*cb5caa98Sdjl } 635*cb5caa98Sdjl 636*cb5caa98Sdjl return (NSCD_SUCCESS); 637*cb5caa98Sdjl } 638*cb5caa98Sdjl 639*cb5caa98Sdjl 640*cb5caa98Sdjl nscd_rc_t 641*cb5caa98Sdjl _nscd_alloc_nsw_config() 642*cb5caa98Sdjl { 643*cb5caa98Sdjl nscd_nsw_config = calloc(NSCD_NUM_DB, sizeof (nscd_nsw_config_t **)); 644*cb5caa98Sdjl if (nscd_nsw_config == NULL) 645*cb5caa98Sdjl return (NSCD_NO_MEMORY); 646*cb5caa98Sdjl 647*cb5caa98Sdjl return (NSCD_SUCCESS); 648*cb5caa98Sdjl } 649*cb5caa98Sdjl 650*cb5caa98Sdjl nscd_rc_t 651*cb5caa98Sdjl _nscd_alloc_nsw_be_info_db() 652*cb5caa98Sdjl { 653*cb5caa98Sdjl int i; 654*cb5caa98Sdjl 655*cb5caa98Sdjl _nscd_cfg_num_nsw_src_all = _nscd_cfg_num_nsw_src + NSCD_NUM_SRC_UDEF; 656*cb5caa98Sdjl nscd_src_backend_db = calloc(NSCD_NUM_SRC, sizeof (nscd_db_t **)); 657*cb5caa98Sdjl if (nscd_src_backend_db == NULL) 658*cb5caa98Sdjl return (NSCD_NO_MEMORY); 659*cb5caa98Sdjl 660*cb5caa98Sdjl /* also allocate/init the nsswitch source index/name array */ 661*cb5caa98Sdjl _nscd_cfg_nsw_src_all = (nscd_cfg_id_t *)calloc( 662*cb5caa98Sdjl _nscd_cfg_num_nsw_src_all + 1, sizeof (nscd_cfg_id_t)); 663*cb5caa98Sdjl for (i = 0; i < _nscd_cfg_num_nsw_src_all + 1; i++) 664*cb5caa98Sdjl (_nscd_cfg_nsw_src_all + i)->index = -1; 665*cb5caa98Sdjl 666*cb5caa98Sdjl (void) memcpy(_nscd_cfg_nsw_src_all, _nscd_cfg_nsw_src, 667*cb5caa98Sdjl _nscd_cfg_num_nsw_src * sizeof (nscd_cfg_id_t)); 668*cb5caa98Sdjl return (NSCD_SUCCESS); 669*cb5caa98Sdjl } 670*cb5caa98Sdjl 671*cb5caa98Sdjl nscd_rc_t 672*cb5caa98Sdjl _nscd_populate_nsw_backend_info() 673*cb5caa98Sdjl { 674*cb5caa98Sdjl int i; 675*cb5caa98Sdjl nscd_rc_t rc; 676*cb5caa98Sdjl 677*cb5caa98Sdjl for (i = 0; i < NSCD_NUM_SRC; i++) { 678*cb5caa98Sdjl if (NSCD_NSW_SRC_NAME(i) == NULL) 679*cb5caa98Sdjl continue; 680*cb5caa98Sdjl rc = _nscd_populate_nsw_backend_info_db(i); 681*cb5caa98Sdjl if (rc != NSCD_SUCCESS) 682*cb5caa98Sdjl return (rc); 683*cb5caa98Sdjl } 684*cb5caa98Sdjl 685*cb5caa98Sdjl return (NSCD_SUCCESS); 686*cb5caa98Sdjl } 687