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