1*cb5caa98Sdjl /* 2*cb5caa98Sdjl * CDDL HEADER START 3*cb5caa98Sdjl * 4*cb5caa98Sdjl * The contents of this file are subject to the terms of the 5*cb5caa98Sdjl * Common Development and Distribution License (the "License"). 6*cb5caa98Sdjl * You may not use this file except in compliance with the License. 7*cb5caa98Sdjl * 8*cb5caa98Sdjl * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*cb5caa98Sdjl * or http://www.opensolaris.org/os/licensing. 10*cb5caa98Sdjl * See the License for the specific language governing permissions 11*cb5caa98Sdjl * and limitations under the License. 12*cb5caa98Sdjl * 13*cb5caa98Sdjl * When distributing Covered Code, include this CDDL HEADER in each 14*cb5caa98Sdjl * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*cb5caa98Sdjl * If applicable, add the following below this CDDL HEADER, with the 16*cb5caa98Sdjl * fields enclosed by brackets "[]" replaced with your own identifying 17*cb5caa98Sdjl * information: Portions Copyright [yyyy] [name of copyright owner] 18*cb5caa98Sdjl * 19*cb5caa98Sdjl * CDDL HEADER END 20*cb5caa98Sdjl */ 21*cb5caa98Sdjl /* 22*cb5caa98Sdjl * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23*cb5caa98Sdjl * Use is subject to license terms. 24*cb5caa98Sdjl */ 25*cb5caa98Sdjl 26*cb5caa98Sdjl #pragma ident "%Z%%M% %I% %E% SMI" 27*cb5caa98Sdjl 28*cb5caa98Sdjl #include <stdio.h> 29*cb5caa98Sdjl #include <stdlib.h> 30*cb5caa98Sdjl #include <assert.h> 31*cb5caa98Sdjl #include <string.h> 32*cb5caa98Sdjl #include "nscd_switch.h" 33*cb5caa98Sdjl #include "nscd_log.h" 34*cb5caa98Sdjl 35*cb5caa98Sdjl /* 36*cb5caa98Sdjl * nscd_nsw_state_t list for each nss database. Protected 37*cb5caa98Sdjl * by the readers/writer lock nscd_nsw_state_base_lock. 38*cb5caa98Sdjl */ 39*cb5caa98Sdjl nscd_nsw_state_base_t **nscd_nsw_state_base; 40*cb5caa98Sdjl static rwlock_t nscd_nsw_state_base_lock = DEFAULTRWLOCK; 41*cb5caa98Sdjl 42*cb5caa98Sdjl static void 43*cb5caa98Sdjl _nscd_free_nsw_state( 44*cb5caa98Sdjl nscd_nsw_state_t *s) 45*cb5caa98Sdjl { 46*cb5caa98Sdjl 47*cb5caa98Sdjl int i; 48*cb5caa98Sdjl char *me = "_nscd_free_nsw_state"; 49*cb5caa98Sdjl 50*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) 51*cb5caa98Sdjl (me, "freeing nsw state = %p\n", s); 52*cb5caa98Sdjl 53*cb5caa98Sdjl if (s == NULL) 54*cb5caa98Sdjl return; 55*cb5caa98Sdjl 56*cb5caa98Sdjl if (s->nsw_cfg_p != NULL) 57*cb5caa98Sdjl /* 58*cb5caa98Sdjl * an nsw state without base does not reference 59*cb5caa98Sdjl * count the nsw config data (ie not using a 60*cb5caa98Sdjl * shared one), so the one created for it should 61*cb5caa98Sdjl * be freed 62*cb5caa98Sdjl */ 63*cb5caa98Sdjl if ((*s->nsw_cfg_p)->nobase != 1) 64*cb5caa98Sdjl _nscd_release((nscd_acc_data_t *)s->nsw_cfg_p); 65*cb5caa98Sdjl else 66*cb5caa98Sdjl _nscd_free_nsw_config(*s->nsw_cfg_p); 67*cb5caa98Sdjl 68*cb5caa98Sdjl if (s->be_db_pp != NULL) { 69*cb5caa98Sdjl for (i = 0; i < s->max_src; i++) { 70*cb5caa98Sdjl if (s->be_db_pp[i] == NULL) 71*cb5caa98Sdjl continue; 72*cb5caa98Sdjl _nscd_release((nscd_acc_data_t *)s->be_db_pp[i]); 73*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) 74*cb5caa98Sdjl (me, "release db be ptr %p\n", s->be_db_pp[i]); 75*cb5caa98Sdjl } 76*cb5caa98Sdjl free(s->be_db_pp); 77*cb5caa98Sdjl } 78*cb5caa98Sdjl 79*cb5caa98Sdjl if (s->be != NULL) { 80*cb5caa98Sdjl for (i = 0; i < s->max_src; i++) { 81*cb5caa98Sdjl if (s->be[i] == NULL) 82*cb5caa98Sdjl continue; 83*cb5caa98Sdjl if (s->getent == 1) 84*cb5caa98Sdjl (void) NSS_INVOKE_DBOP(s->be[i], 85*cb5caa98Sdjl NSS_DBOP_ENDENT, 0); 86*cb5caa98Sdjl (void) NSS_INVOKE_DBOP(s->be[i], 87*cb5caa98Sdjl NSS_DBOP_DESTRUCTOR, 0); 88*cb5caa98Sdjl } 89*cb5caa98Sdjl free(s->be); 90*cb5caa98Sdjl } 91*cb5caa98Sdjl 92*cb5caa98Sdjl s->base = NULL; 93*cb5caa98Sdjl 94*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) 95*cb5caa98Sdjl (me, "nsw state %p freed \n", s); 96*cb5caa98Sdjl 97*cb5caa98Sdjl free(s); 98*cb5caa98Sdjl } 99*cb5caa98Sdjl 100*cb5caa98Sdjl static void 101*cb5caa98Sdjl _nscd_free_nsw_state_base( 102*cb5caa98Sdjl nscd_acc_data_t *data) 103*cb5caa98Sdjl { 104*cb5caa98Sdjl nscd_nsw_state_base_t *base = (nscd_nsw_state_base_t *)data; 105*cb5caa98Sdjl nscd_nsw_state_t *s, *ts; 106*cb5caa98Sdjl int i; 107*cb5caa98Sdjl char *me = "_nscd_free_nsw_state_base"; 108*cb5caa98Sdjl 109*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE | NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_DEBUG) 110*cb5caa98Sdjl (me, "freeing db state base %p\n", base); 111*cb5caa98Sdjl 112*cb5caa98Sdjl if (base == NULL) 113*cb5caa98Sdjl return; 114*cb5caa98Sdjl 115*cb5caa98Sdjl for (i = 0; i < 2; i++) { 116*cb5caa98Sdjl if (i == 1) 117*cb5caa98Sdjl s = base->nsw_state.first; 118*cb5caa98Sdjl else 119*cb5caa98Sdjl s = base->nsw_state_thr.first; 120*cb5caa98Sdjl 121*cb5caa98Sdjl while (s != NULL) { 122*cb5caa98Sdjl ts = s->next; 123*cb5caa98Sdjl _nscd_free_nsw_state(s); 124*cb5caa98Sdjl s = ts; 125*cb5caa98Sdjl } 126*cb5caa98Sdjl } 127*cb5caa98Sdjl 128*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE | NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_DEBUG) 129*cb5caa98Sdjl (me, "nsw state base %p freed \n", base); 130*cb5caa98Sdjl } 131*cb5caa98Sdjl 132*cb5caa98Sdjl void 133*cb5caa98Sdjl _nscd_free_all_nsw_state_base() 134*cb5caa98Sdjl { 135*cb5caa98Sdjl nscd_nsw_state_base_t *base; 136*cb5caa98Sdjl int i; 137*cb5caa98Sdjl char *me = "_nscd_free_all_nsw_state_base"; 138*cb5caa98Sdjl 139*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE | NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_DEBUG) 140*cb5caa98Sdjl (me, "freeing all db state base\n"); 141*cb5caa98Sdjl 142*cb5caa98Sdjl (void) rw_wrlock(&nscd_nsw_state_base_lock); 143*cb5caa98Sdjl for (i = 0; i < NSCD_NUM_DB; i++) { 144*cb5caa98Sdjl 145*cb5caa98Sdjl base = nscd_nsw_state_base[i]; 146*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE | NSCD_LOG_CONFIG, 147*cb5caa98Sdjl NSCD_LOG_LEVEL_DEBUG) 148*cb5caa98Sdjl (me, "freeing db state base (%d) %p \n", i, base); 149*cb5caa98Sdjl 150*cb5caa98Sdjl if (base == NULL) 151*cb5caa98Sdjl continue; 152*cb5caa98Sdjl 153*cb5caa98Sdjl nscd_nsw_state_base[i] = (nscd_nsw_state_base_t *) 154*cb5caa98Sdjl _nscd_set((nscd_acc_data_t *)base, NULL); 155*cb5caa98Sdjl } 156*cb5caa98Sdjl (void) rw_unlock(&nscd_nsw_state_base_lock); 157*cb5caa98Sdjl } 158*cb5caa98Sdjl 159*cb5caa98Sdjl static nscd_nsw_state_t * 160*cb5caa98Sdjl _nscd_create_nsw_state( 161*cb5caa98Sdjl nscd_nsw_params_t *params) 162*cb5caa98Sdjl { 163*cb5caa98Sdjl nscd_nsw_state_t *s; 164*cb5caa98Sdjl nscd_nsw_config_t *nsw_cfg; 165*cb5caa98Sdjl nscd_db_t **be_db_p, *be_db; 166*cb5caa98Sdjl int i, nobe = 1; 167*cb5caa98Sdjl char *me = "_nscd_create_nsw_state"; 168*cb5caa98Sdjl 169*cb5caa98Sdjl 170*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) 171*cb5caa98Sdjl (me, "creating nsw state...\n"); 172*cb5caa98Sdjl 173*cb5caa98Sdjl s = calloc(1, sizeof (nscd_nsw_state_t)); 174*cb5caa98Sdjl if (s == NULL) { 175*cb5caa98Sdjl if ((*s->nsw_cfg_p)->nobase != 1) 176*cb5caa98Sdjl _nscd_release((nscd_acc_data_t *)params->nswcfg); 177*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_ERROR) 178*cb5caa98Sdjl (me, "not able to allocate a nsw state\n"); 179*cb5caa98Sdjl return (NULL); 180*cb5caa98Sdjl } else 181*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) 182*cb5caa98Sdjl (me, "nsw state %p allocated\n", s); 183*cb5caa98Sdjl 184*cb5caa98Sdjl s->dbi = params->dbi; 185*cb5caa98Sdjl s->next = NULL; 186*cb5caa98Sdjl 187*cb5caa98Sdjl nsw_cfg = *params->nswcfg; 188*cb5caa98Sdjl 189*cb5caa98Sdjl s->nsw_cfg_p = params->nswcfg; 190*cb5caa98Sdjl s->config = nsw_cfg->nsw_config; 191*cb5caa98Sdjl s->max_src = nsw_cfg->max_src; 192*cb5caa98Sdjl s->p = params->p; 193*cb5caa98Sdjl 194*cb5caa98Sdjl s->be = calloc(s->max_src, sizeof (nss_backend_t **)); 195*cb5caa98Sdjl if (s->be == NULL) { 196*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_ERROR) 197*cb5caa98Sdjl (me, "not able to allocate s->be\n"); 198*cb5caa98Sdjl 199*cb5caa98Sdjl _nscd_free_nsw_state(s); 200*cb5caa98Sdjl return (NULL); 201*cb5caa98Sdjl } else { 202*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) 203*cb5caa98Sdjl (me, "db be array %p allocated\n", s->be); 204*cb5caa98Sdjl } 205*cb5caa98Sdjl 206*cb5caa98Sdjl s->be_db_pp = calloc(s->max_src, sizeof (nscd_db_t ***)); 207*cb5caa98Sdjl if (s->be_db_pp == NULL) { 208*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_ERROR) 209*cb5caa98Sdjl (me, "not able to allocate s->be_db_pp\n"); 210*cb5caa98Sdjl _nscd_free_nsw_state(s); 211*cb5caa98Sdjl return (NULL); 212*cb5caa98Sdjl } else { 213*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) 214*cb5caa98Sdjl (me, "be_db_pp array %p allocated\n", s->be_db_pp); 215*cb5caa98Sdjl } 216*cb5caa98Sdjl 217*cb5caa98Sdjl /* create the source:database backends */ 218*cb5caa98Sdjl for (i = 0; i < s->max_src; i++) { 219*cb5caa98Sdjl nss_backend_t *be; 220*cb5caa98Sdjl int srci; 221*cb5caa98Sdjl char *srcn; 222*cb5caa98Sdjl const char *dbn; 223*cb5caa98Sdjl struct __nsw_lookup_v1 *lkp; 224*cb5caa98Sdjl const nscd_db_entry_t *dbe; 225*cb5caa98Sdjl nscd_be_info_t *be_info; 226*cb5caa98Sdjl 227*cb5caa98Sdjl if (i == 0) 228*cb5caa98Sdjl lkp = s->config->lookups; 229*cb5caa98Sdjl else 230*cb5caa98Sdjl lkp = lkp->next; 231*cb5caa98Sdjl if (lkp == NULL) { 232*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_ERROR) 233*cb5caa98Sdjl (me, "error: lkp is NULL\n"); 234*cb5caa98Sdjl _nscd_free_nsw_state(s); 235*cb5caa98Sdjl return (NULL); 236*cb5caa98Sdjl } 237*cb5caa98Sdjl 238*cb5caa98Sdjl srci = nsw_cfg->src_idx[i]; 239*cb5caa98Sdjl srcn = lkp->service_name; 240*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) 241*cb5caa98Sdjl (me, "source name = %s, index = %d\n", srcn, srci); 242*cb5caa98Sdjl 243*cb5caa98Sdjl be_db_p = (nscd_db_t **)_nscd_get( 244*cb5caa98Sdjl (nscd_acc_data_t *)nscd_src_backend_db[srci]); 245*cb5caa98Sdjl if (be_db_p == NULL) { 246*cb5caa98Sdjl _nscd_free_nsw_state(s); 247*cb5caa98Sdjl return (NULL); 248*cb5caa98Sdjl } 249*cb5caa98Sdjl be_db = *be_db_p; 250*cb5caa98Sdjl s->be_db_pp[i] = be_db_p; 251*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) 252*cb5caa98Sdjl (me, "be db ptr array %p referenced\n", be_db_p); 253*cb5caa98Sdjl 254*cb5caa98Sdjl be_info = NULL; 255*cb5caa98Sdjl be = NULL; 256*cb5caa98Sdjl dbn = params->p.name; 257*cb5caa98Sdjl dbe = _nscd_get_db_entry(be_db, NSCD_DATA_BACKEND_INFO, 258*cb5caa98Sdjl (const char *)dbn, NSCD_GET_FIRST_DB_ENTRY, 0); 259*cb5caa98Sdjl if (dbe != NULL) 260*cb5caa98Sdjl be_info = (nscd_be_info_t *)*(dbe->data_array); 261*cb5caa98Sdjl 262*cb5caa98Sdjl if (be_info == NULL || be_info->be_constr == NULL) { 263*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) 264*cb5caa98Sdjl (me, "no backend info or be_constr is NULL " 265*cb5caa98Sdjl "for <%s : %s>\n", NSCD_NSW_SRC_NAME(srci), 266*cb5caa98Sdjl dbn); 267*cb5caa98Sdjl } else 268*cb5caa98Sdjl be = (be_info->be_constr)(dbn, 269*cb5caa98Sdjl NSCD_NSW_SRC_NAME(srci), 0); 270*cb5caa98Sdjl 271*cb5caa98Sdjl if (be == NULL) { 272*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_ERROR) 273*cb5caa98Sdjl (me, "not able to init be for <%s : %s>\n", 274*cb5caa98Sdjl NSCD_NSW_SRC_NAME(srci), dbn); 275*cb5caa98Sdjl 276*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) 277*cb5caa98Sdjl (me, "releasing db be ptr %p\n", be_db_p); 278*cb5caa98Sdjl 279*cb5caa98Sdjl _nscd_release((nscd_acc_data_t *)be_db_p); 280*cb5caa98Sdjl s->be_db_pp[i] = NULL; 281*cb5caa98Sdjl 282*cb5caa98Sdjl continue; 283*cb5caa98Sdjl } 284*cb5caa98Sdjl 285*cb5caa98Sdjl s->be[i] = be; 286*cb5caa98Sdjl nobe = 0; 287*cb5caa98Sdjl } 288*cb5caa98Sdjl 289*cb5caa98Sdjl if (nobe == 1) { 290*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) 291*cb5caa98Sdjl (me, "NO backend found, returning NULL\n"); 292*cb5caa98Sdjl 293*cb5caa98Sdjl _nscd_free_nsw_state(s); 294*cb5caa98Sdjl return (NULL); 295*cb5caa98Sdjl } 296*cb5caa98Sdjl 297*cb5caa98Sdjl return (s); 298*cb5caa98Sdjl } 299*cb5caa98Sdjl 300*cb5caa98Sdjl static nscd_rc_t 301*cb5caa98Sdjl _get_nsw_state_int( 302*cb5caa98Sdjl nss_db_root_t *rootp, 303*cb5caa98Sdjl nscd_nsw_params_t *params, 304*cb5caa98Sdjl thread_t *tid) 305*cb5caa98Sdjl { 306*cb5caa98Sdjl 307*cb5caa98Sdjl nscd_nsw_state_t *ret = NULL; 308*cb5caa98Sdjl nscd_nsw_config_t **nswcfg; 309*cb5caa98Sdjl nscd_nsw_state_base_t *base; 310*cb5caa98Sdjl nscd_state_ctrl_t *ctrl_p; 311*cb5caa98Sdjl int thread_only = 0, wait_cond = 0; 312*cb5caa98Sdjl char *me = "_get_nsw_state_int"; 313*cb5caa98Sdjl int dbi; 314*cb5caa98Sdjl nscd_rc_t rc; 315*cb5caa98Sdjl 316*cb5caa98Sdjl dbi = params->dbi; 317*cb5caa98Sdjl 318*cb5caa98Sdjl /* 319*cb5caa98Sdjl * no nsw state will be reused, if asked to use 320*cb5caa98Sdjl * default config. So create the new structures 321*cb5caa98Sdjl * used by the switch engine and the new nsw state 322*cb5caa98Sdjl */ 323*cb5caa98Sdjl if (params->p.flags & NSS_USE_DEFAULT_CONFIG) { 324*cb5caa98Sdjl rc = _nscd_create_sw_struct(dbi, (char *)params->p.name, 325*cb5caa98Sdjl (char *)params->p.default_config, NULL, params); 326*cb5caa98Sdjl if (rc != NSCD_SUCCESS) 327*cb5caa98Sdjl return (rc); 328*cb5caa98Sdjl 329*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) 330*cb5caa98Sdjl (me, "no base nsw config created for %s (sources: %s)\n", 331*cb5caa98Sdjl params->p.name, params->p.default_config); 332*cb5caa98Sdjl 333*cb5caa98Sdjl ret = _nscd_create_nsw_state(params); 334*cb5caa98Sdjl if (ret == NULL) 335*cb5caa98Sdjl return (NSCD_CREATE_NSW_STATE_FAILED); 336*cb5caa98Sdjl rootp->s = (struct nss_db_state *)ret; 337*cb5caa98Sdjl return (NSCD_SUCCESS); 338*cb5caa98Sdjl } 339*cb5caa98Sdjl 340*cb5caa98Sdjl /* 341*cb5caa98Sdjl * if getting a nsw state for a request from the compat 342*cb5caa98Sdjl * backend, create the new switch structures if this 343*cb5caa98Sdjl * is the first time around for a passwd, shadow, group, 344*cb5caa98Sdjl * audit_user, or user_attr database 345*cb5caa98Sdjl */ 346*cb5caa98Sdjl if (params->compati != -1) { 347*cb5caa98Sdjl 348*cb5caa98Sdjl nscd_nsw_config_t **nswcfg1; 349*cb5caa98Sdjl int i = params->compati; 350*cb5caa98Sdjl 351*cb5caa98Sdjl nswcfg = (nscd_nsw_config_t **)_nscd_get( 352*cb5caa98Sdjl (nscd_acc_data_t *)nscd_nsw_config[i]); 353*cb5caa98Sdjl 354*cb5caa98Sdjl /* 355*cb5caa98Sdjl * if nsw data structures not created yet, get the 356*cb5caa98Sdjl * config string from the passwd_compat or 357*cb5caa98Sdjl * group_compat DB and create the structures 358*cb5caa98Sdjl */ 359*cb5caa98Sdjl if (nswcfg == NULL) { 360*cb5caa98Sdjl nswcfg1 = (nscd_nsw_config_t **)_nscd_get( 361*cb5caa98Sdjl (nscd_acc_data_t *)nscd_nsw_config[params->cfgdbi]); 362*cb5caa98Sdjl if (nswcfg1 == NULL) { 363*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, 364*cb5caa98Sdjl NSCD_LOG_LEVEL_ERROR) 365*cb5caa98Sdjl (me, "no nsw config for %s\n", 366*cb5caa98Sdjl params->p.name); 367*cb5caa98Sdjl return (NSCD_CREATE_NSW_STATE_FAILED); 368*cb5caa98Sdjl } 369*cb5caa98Sdjl 370*cb5caa98Sdjl rc = _nscd_create_sw_struct(i, params->p.name, 371*cb5caa98Sdjl (*nswcfg1)->nsw_cfg_str, NULL, params); 372*cb5caa98Sdjl _nscd_release((nscd_acc_data_t *)nswcfg1); 373*cb5caa98Sdjl if (rc != NSCD_SUCCESS) 374*cb5caa98Sdjl return (rc); 375*cb5caa98Sdjl 376*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, 377*cb5caa98Sdjl NSCD_LOG_LEVEL_DEBUG) 378*cb5caa98Sdjl (me, "nsw config created for %s (%s)\n", 379*cb5caa98Sdjl params->p.name, (*nswcfg1)->nsw_cfg_str); 380*cb5caa98Sdjl } else 381*cb5caa98Sdjl _nscd_release((nscd_acc_data_t *)nswcfg); 382*cb5caa98Sdjl } 383*cb5caa98Sdjl 384*cb5caa98Sdjl (void) rw_rdlock(&nscd_nsw_state_base_lock); 385*cb5caa98Sdjl base = nscd_nsw_state_base[dbi]; 386*cb5caa98Sdjl (void) rw_unlock(&nscd_nsw_state_base_lock); 387*cb5caa98Sdjl if (base == NULL) 388*cb5caa98Sdjl assert(base != NULL); 389*cb5caa98Sdjl 390*cb5caa98Sdjl /* 391*cb5caa98Sdjl * If list is not empty, return the first one on list. 392*cb5caa98Sdjl * Otherwise, create and return a new db state if the 393*cb5caa98Sdjl * limit is not reached. if reacehed, wait for the 'one 394*cb5caa98Sdjl * is available' signal. 395*cb5caa98Sdjl */ 396*cb5caa98Sdjl assert(base == (nscd_nsw_state_base_t *)_nscd_mutex_lock( 397*cb5caa98Sdjl (nscd_acc_data_t *)base)); 398*cb5caa98Sdjl 399*cb5caa98Sdjl if (tid == NULL) { 400*cb5caa98Sdjl ctrl_p = &base->nsw_state; 401*cb5caa98Sdjl } else { 402*cb5caa98Sdjl thread_only = 1; 403*cb5caa98Sdjl ctrl_p = &base->nsw_state_thr; 404*cb5caa98Sdjl 405*cb5caa98Sdjl _NSCD_LOG_IF(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) { 406*cb5caa98Sdjl _nscd_logit(me, "per thread nsw state info: \n"); 407*cb5caa98Sdjl _nscd_logit(me, "tid = %d\n", *tid); 408*cb5caa98Sdjl _nscd_logit(me, "tid in base = %d\n", base->tid); 409*cb5caa98Sdjl _nscd_logit(me, "number of free nsw_state = %d\n", 410*cb5caa98Sdjl ctrl_p->free); 411*cb5caa98Sdjl _nscd_logit(me, "number of nsw state allocated = %d\n", 412*cb5caa98Sdjl ctrl_p->allocated); 413*cb5caa98Sdjl _nscd_logit(me, "first nsw state on list = %p\n", 414*cb5caa98Sdjl ctrl_p->first); 415*cb5caa98Sdjl _nscd_logit(me, "number of waiter = %d\n", 416*cb5caa98Sdjl ctrl_p->waiter); 417*cb5caa98Sdjl } 418*cb5caa98Sdjl } 419*cb5caa98Sdjl 420*cb5caa98Sdjl if (ctrl_p->first == NULL && ctrl_p->allocated == ctrl_p->max) 421*cb5caa98Sdjl wait_cond = 1; 422*cb5caa98Sdjl else if (thread_only && base->used_by_thr && base->tid != *tid) 423*cb5caa98Sdjl wait_cond = 1; 424*cb5caa98Sdjl 425*cb5caa98Sdjl if (wait_cond) { 426*cb5caa98Sdjl 427*cb5caa98Sdjl ctrl_p->waiter++; 428*cb5caa98Sdjl 429*cb5caa98Sdjl while (wait_cond) { 430*cb5caa98Sdjl if (!thread_only) 431*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, 432*cb5caa98Sdjl NSCD_LOG_LEVEL_DEBUG) 433*cb5caa98Sdjl (me, "waiting for nsw state signal\n"); 434*cb5caa98Sdjl else 435*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, 436*cb5caa98Sdjl NSCD_LOG_LEVEL_DEBUG) 437*cb5caa98Sdjl (me, "waiting for per thread " 438*cb5caa98Sdjl "nsw state signal\n"); 439*cb5caa98Sdjl 440*cb5caa98Sdjl if (thread_only) { 441*cb5caa98Sdjl _nscd_cond_wait((nscd_acc_data_t *)base, 442*cb5caa98Sdjl &base->thr_cond); 443*cb5caa98Sdjl 444*cb5caa98Sdjl if (base->used_by_thr == 0 && 445*cb5caa98Sdjl ctrl_p->first != NULL) 446*cb5caa98Sdjl wait_cond = 0; 447*cb5caa98Sdjl } else { 448*cb5caa98Sdjl _nscd_cond_wait((nscd_acc_data_t *)base, NULL); 449*cb5caa98Sdjl 450*cb5caa98Sdjl if (ctrl_p->first != NULL) 451*cb5caa98Sdjl wait_cond = 0; 452*cb5caa98Sdjl } 453*cb5caa98Sdjl 454*cb5caa98Sdjl if (!thread_only) 455*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, 456*cb5caa98Sdjl NSCD_LOG_LEVEL_DEBUG) 457*cb5caa98Sdjl (me, "woke from cond wait ...wait_cond = %d\n", 458*cb5caa98Sdjl wait_cond); 459*cb5caa98Sdjl else 460*cb5caa98Sdjl 461*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, 462*cb5caa98Sdjl NSCD_LOG_LEVEL_DEBUG) 463*cb5caa98Sdjl (me, "woke from cond wait (per thread) " 464*cb5caa98Sdjl "...wait_cond = %d\n", wait_cond); 465*cb5caa98Sdjl 466*cb5caa98Sdjl } 467*cb5caa98Sdjl 468*cb5caa98Sdjl ctrl_p->waiter--; 469*cb5caa98Sdjl } 470*cb5caa98Sdjl 471*cb5caa98Sdjl if (ctrl_p->first == NULL) { 472*cb5caa98Sdjl int geti; 473*cb5caa98Sdjl 474*cb5caa98Sdjl /* 475*cb5caa98Sdjl * for lookup calls from the compat backend 476*cb5caa98Sdjl * uses the switch policy for passwd_compat 477*cb5caa98Sdjl * or group_compat 478*cb5caa98Sdjl */ 479*cb5caa98Sdjl if (params->compati != -1) 480*cb5caa98Sdjl geti = params->compati; 481*cb5caa98Sdjl else 482*cb5caa98Sdjl geti = params->dbi; 483*cb5caa98Sdjl 484*cb5caa98Sdjl params->nswcfg = (nscd_nsw_config_t **)_nscd_get( 485*cb5caa98Sdjl (nscd_acc_data_t *)nscd_nsw_config[geti]); 486*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) 487*cb5caa98Sdjl (me, "got a nsw config %p for index %d\n", 488*cb5caa98Sdjl params->nswcfg, geti); 489*cb5caa98Sdjl 490*cb5caa98Sdjl ctrl_p->first = _nscd_create_nsw_state(params); 491*cb5caa98Sdjl if (ctrl_p->first != NULL) { 492*cb5caa98Sdjl ctrl_p->first->base = base; 493*cb5caa98Sdjl 494*cb5caa98Sdjl if (tid == NULL) { 495*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, 496*cb5caa98Sdjl NSCD_LOG_LEVEL_DEBUG) 497*cb5caa98Sdjl (me, "got a new nsw_state %p\n", ctrl_p->first); 498*cb5caa98Sdjl } else { 499*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, 500*cb5caa98Sdjl NSCD_LOG_LEVEL_DEBUG) 501*cb5caa98Sdjl (me, "got a new per thread nsw_state %p\n", 502*cb5caa98Sdjl ctrl_p->first); 503*cb5caa98Sdjl } 504*cb5caa98Sdjl ctrl_p->allocated++; 505*cb5caa98Sdjl ctrl_p->free++; 506*cb5caa98Sdjl } else { 507*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_ERROR) 508*cb5caa98Sdjl (me, "error: unable to obtain a nsw state\n"); 509*cb5caa98Sdjl _nscd_mutex_unlock((nscd_acc_data_t *)base); 510*cb5caa98Sdjl return (NSCD_CREATE_NSW_STATE_FAILED); 511*cb5caa98Sdjl } 512*cb5caa98Sdjl } 513*cb5caa98Sdjl 514*cb5caa98Sdjl ret = ctrl_p->first; 515*cb5caa98Sdjl ctrl_p->first = ret->next; 516*cb5caa98Sdjl ret->next = NULL; 517*cb5caa98Sdjl ctrl_p->free--; 518*cb5caa98Sdjl if (thread_only) { 519*cb5caa98Sdjl base->tid = *tid; 520*cb5caa98Sdjl base->used_by_thr = 1; 521*cb5caa98Sdjl 522*cb5caa98Sdjl _NSCD_LOG_IF(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) { 523*cb5caa98Sdjl _nscd_logit(me, "\t\t\tgot a per thread nsw " 524*cb5caa98Sdjl "state %p: \n", ret); 525*cb5caa98Sdjl _nscd_logit(me, "tid = %d\n", *tid); 526*cb5caa98Sdjl _nscd_logit(me, "tid in base = %d\n", base->tid); 527*cb5caa98Sdjl _nscd_logit(me, "number of free nsw_state = %d\n", 528*cb5caa98Sdjl ctrl_p->free); 529*cb5caa98Sdjl _nscd_logit(me, "number od nsw state allocated = %d\n", 530*cb5caa98Sdjl ctrl_p->allocated); 531*cb5caa98Sdjl _nscd_logit(me, "first nsw state on list = %p\n", 532*cb5caa98Sdjl ctrl_p->first); 533*cb5caa98Sdjl _nscd_logit(me, "number of waiter = %d\n", 534*cb5caa98Sdjl ctrl_p->waiter); 535*cb5caa98Sdjl } 536*cb5caa98Sdjl } 537*cb5caa98Sdjl else 538*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) 539*cb5caa98Sdjl (me, "got old nsw state %p\n", ret); 540*cb5caa98Sdjl 541*cb5caa98Sdjl _nscd_mutex_unlock((nscd_acc_data_t *)base); 542*cb5caa98Sdjl 543*cb5caa98Sdjl rootp->s = (struct nss_db_state *)ret; 544*cb5caa98Sdjl 545*cb5caa98Sdjl return (NSCD_SUCCESS); 546*cb5caa98Sdjl } 547*cb5caa98Sdjl 548*cb5caa98Sdjl nscd_rc_t 549*cb5caa98Sdjl _nscd_get_nsw_state( 550*cb5caa98Sdjl nss_db_root_t *rootp, 551*cb5caa98Sdjl nscd_nsw_params_t *params) 552*cb5caa98Sdjl { 553*cb5caa98Sdjl return (_get_nsw_state_int(rootp, params, NULL)); 554*cb5caa98Sdjl } 555*cb5caa98Sdjl 556*cb5caa98Sdjl nscd_rc_t 557*cb5caa98Sdjl _nscd_get_nsw_state_thread( 558*cb5caa98Sdjl nss_db_root_t *rootp, 559*cb5caa98Sdjl nscd_nsw_params_t *params) 560*cb5caa98Sdjl { 561*cb5caa98Sdjl thread_t tid = thr_self(); 562*cb5caa98Sdjl return (_get_nsw_state_int(rootp, params, &tid)); 563*cb5caa98Sdjl } 564*cb5caa98Sdjl 565*cb5caa98Sdjl 566*cb5caa98Sdjl static void 567*cb5caa98Sdjl _put_nsw_state_int( 568*cb5caa98Sdjl nscd_nsw_state_t *s, 569*cb5caa98Sdjl thread_t *tid) 570*cb5caa98Sdjl { 571*cb5caa98Sdjl 572*cb5caa98Sdjl nscd_nsw_state_base_t *base; 573*cb5caa98Sdjl nscd_state_ctrl_t *ctrl_p; 574*cb5caa98Sdjl int thread_only = 0; 575*cb5caa98Sdjl char *me = "_put_nsw_state_int"; 576*cb5caa98Sdjl 577*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) 578*cb5caa98Sdjl (me, "put back a nsw state\n"); 579*cb5caa98Sdjl 580*cb5caa98Sdjl if (s == NULL) { 581*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) 582*cb5caa98Sdjl (me, "nsw state is NULL, nothing to put back\n"); 583*cb5caa98Sdjl return; 584*cb5caa98Sdjl } 585*cb5caa98Sdjl 586*cb5caa98Sdjl /* 587*cb5caa98Sdjl * no need to put back if the nsw state is not on any base 588*cb5caa98Sdjl * but need to free the resources used 589*cb5caa98Sdjl */ 590*cb5caa98Sdjl if ((*s->nsw_cfg_p)->nobase == 1) { 591*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) 592*cb5caa98Sdjl (me, "no base nsw state, freeing resources ...\n"); 593*cb5caa98Sdjl 594*cb5caa98Sdjl _nscd_free_nsw_state(s); 595*cb5caa98Sdjl return; 596*cb5caa98Sdjl } 597*cb5caa98Sdjl 598*cb5caa98Sdjl if (tid != NULL) 599*cb5caa98Sdjl thread_only = 1; 600*cb5caa98Sdjl 601*cb5caa98Sdjl base = s->base; 602*cb5caa98Sdjl 603*cb5caa98Sdjl if (_nscd_mutex_lock((nscd_acc_data_t *)base) == NULL) { 604*cb5caa98Sdjl /* base has been freed, free this db state */ 605*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) 606*cb5caa98Sdjl (me, "nsw state base has been freed, freeing %p\n", s); 607*cb5caa98Sdjl _nscd_free_nsw_state(s); 608*cb5caa98Sdjl return; 609*cb5caa98Sdjl } 610*cb5caa98Sdjl 611*cb5caa98Sdjl if (thread_only) 612*cb5caa98Sdjl ctrl_p = &base->nsw_state_thr; 613*cb5caa98Sdjl else 614*cb5caa98Sdjl ctrl_p = &base->nsw_state; 615*cb5caa98Sdjl 616*cb5caa98Sdjl _NSCD_LOG_IF(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) { 617*cb5caa98Sdjl _nscd_logit(me, "before returning the nsw state: \n"); 618*cb5caa98Sdjl _nscd_logit(me, "tid = %d\n", (tid == NULL) ? -1 : *tid); 619*cb5caa98Sdjl _nscd_logit(me, "tid in base = %d\n", base->tid); 620*cb5caa98Sdjl _nscd_logit(me, "number of free nsw_state = %d\n", 621*cb5caa98Sdjl ctrl_p->free); 622*cb5caa98Sdjl _nscd_logit(me, "number od nsw state allocated = %d\n", 623*cb5caa98Sdjl ctrl_p->allocated); 624*cb5caa98Sdjl _nscd_logit(me, "first nsw state on list = %p\n", 625*cb5caa98Sdjl ctrl_p->first); 626*cb5caa98Sdjl _nscd_logit(me, "number of waiter = %d\n", 627*cb5caa98Sdjl ctrl_p->waiter); 628*cb5caa98Sdjl } 629*cb5caa98Sdjl 630*cb5caa98Sdjl if (ctrl_p->first != NULL) { 631*cb5caa98Sdjl s->next = ctrl_p->first; 632*cb5caa98Sdjl ctrl_p->first = s; 633*cb5caa98Sdjl } else { 634*cb5caa98Sdjl ctrl_p->first = s; 635*cb5caa98Sdjl s->next = NULL; 636*cb5caa98Sdjl } 637*cb5caa98Sdjl ctrl_p->free++; 638*cb5caa98Sdjl 639*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) 640*cb5caa98Sdjl (me, "signaling waiter thread_only = %d..\n", thread_only); 641*cb5caa98Sdjl 642*cb5caa98Sdjl if (thread_only && ctrl_p->free == ctrl_p->allocated) { 643*cb5caa98Sdjl assert(ctrl_p->first != NULL); 644*cb5caa98Sdjl base->used_by_thr = 0; 645*cb5caa98Sdjl if (ctrl_p->waiter > 0) { 646*cb5caa98Sdjl (void) cond_signal(&base->thr_cond); 647*cb5caa98Sdjl } 648*cb5caa98Sdjl } 649*cb5caa98Sdjl 650*cb5caa98Sdjl if (!thread_only && ctrl_p->waiter > 0) { 651*cb5caa98Sdjl 652*cb5caa98Sdjl _nscd_cond_signal((nscd_acc_data_t *)base); 653*cb5caa98Sdjl } 654*cb5caa98Sdjl 655*cb5caa98Sdjl _NSCD_LOG_IF(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) { 656*cb5caa98Sdjl _nscd_logit(me, "after the nsw state is returned: \n"); 657*cb5caa98Sdjl _nscd_logit(me, "tid = %d\n", (tid == NULL) ? -1 : *tid); 658*cb5caa98Sdjl _nscd_logit(me, "tid in base = %d\n", base->tid); 659*cb5caa98Sdjl _nscd_logit(me, "number of free nsw_state = %d\n", 660*cb5caa98Sdjl ctrl_p->free); 661*cb5caa98Sdjl _nscd_logit(me, "number od nsw state allocated = %d\n", 662*cb5caa98Sdjl ctrl_p->allocated); 663*cb5caa98Sdjl _nscd_logit(me, "first nsw state on list = %p\n", 664*cb5caa98Sdjl ctrl_p->first); 665*cb5caa98Sdjl _nscd_logit(me, "tnumber of waiter = %d\n", 666*cb5caa98Sdjl ctrl_p->waiter); 667*cb5caa98Sdjl } 668*cb5caa98Sdjl 669*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) 670*cb5caa98Sdjl (me, "done putting back nsw state %p, thread_only = %d\n", 671*cb5caa98Sdjl s, thread_only); 672*cb5caa98Sdjl 673*cb5caa98Sdjl _nscd_mutex_unlock((nscd_acc_data_t *)base); 674*cb5caa98Sdjl 675*cb5caa98Sdjl } 676*cb5caa98Sdjl 677*cb5caa98Sdjl void 678*cb5caa98Sdjl _nscd_put_nsw_state( 679*cb5caa98Sdjl nscd_nsw_state_t *s) 680*cb5caa98Sdjl { 681*cb5caa98Sdjl _put_nsw_state_int(s, NULL); 682*cb5caa98Sdjl } 683*cb5caa98Sdjl 684*cb5caa98Sdjl void 685*cb5caa98Sdjl _nscd_put_nsw_state_thread( 686*cb5caa98Sdjl nscd_nsw_state_t *s) 687*cb5caa98Sdjl { 688*cb5caa98Sdjl thread_t tid = thr_self(); 689*cb5caa98Sdjl _put_nsw_state_int(s, &tid); 690*cb5caa98Sdjl } 691*cb5caa98Sdjl 692*cb5caa98Sdjl nscd_rc_t 693*cb5caa98Sdjl _nscd_init_nsw_state_base( 694*cb5caa98Sdjl int dbi, 695*cb5caa98Sdjl int lock) 696*cb5caa98Sdjl { 697*cb5caa98Sdjl nscd_nsw_state_base_t *base = NULL; 698*cb5caa98Sdjl char *me = "_nscd_init_nsw_state_base"; 699*cb5caa98Sdjl 700*cb5caa98Sdjl if (lock) 701*cb5caa98Sdjl (void) rw_rdlock(&nscd_nsw_state_base_lock); 702*cb5caa98Sdjl 703*cb5caa98Sdjl base = (nscd_nsw_state_base_t *)_nscd_alloc( 704*cb5caa98Sdjl NSCD_DATA_NSW_STATE_BASE, 705*cb5caa98Sdjl sizeof (nscd_nsw_state_base_t), 706*cb5caa98Sdjl _nscd_free_nsw_state_base, 707*cb5caa98Sdjl NSCD_ALLOC_MUTEX | NSCD_ALLOC_COND); 708*cb5caa98Sdjl 709*cb5caa98Sdjl if (base == NULL) { 710*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE | NSCD_LOG_CONFIG, 711*cb5caa98Sdjl NSCD_LOG_LEVEL_ERROR) 712*cb5caa98Sdjl (me, "not able to allocate a nsw state base\n"); 713*cb5caa98Sdjl if (lock) 714*cb5caa98Sdjl (void) rw_unlock(&nscd_nsw_state_base_lock); 715*cb5caa98Sdjl return (NSCD_NO_MEMORY); 716*cb5caa98Sdjl } 717*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE | NSCD_LOG_CONFIG, 718*cb5caa98Sdjl NSCD_LOG_LEVEL_DEBUG) 719*cb5caa98Sdjl (me, "nsw state base %p allocated\n", base); 720*cb5caa98Sdjl 721*cb5caa98Sdjl /* 722*cb5caa98Sdjl * initialize and activate the new nss_nsw_state base 723*cb5caa98Sdjl */ 724*cb5caa98Sdjl base->dbi = dbi; 725*cb5caa98Sdjl base->nsw_state.max = NSCD_SW_CFG(dbi).max_nsw_state_per_db; 726*cb5caa98Sdjl base->nsw_state_thr.max = NSCD_SW_CFG(dbi).max_nsw_state_per_thread; 727*cb5caa98Sdjl 728*cb5caa98Sdjl nscd_nsw_state_base[dbi] = (nscd_nsw_state_base_t *)_nscd_set( 729*cb5caa98Sdjl (nscd_acc_data_t *)nscd_nsw_state_base[dbi], 730*cb5caa98Sdjl (nscd_acc_data_t *)base); 731*cb5caa98Sdjl 732*cb5caa98Sdjl if (lock) 733*cb5caa98Sdjl (void) rw_unlock(&nscd_nsw_state_base_lock); 734*cb5caa98Sdjl 735*cb5caa98Sdjl return (NSCD_SUCCESS); 736*cb5caa98Sdjl } 737*cb5caa98Sdjl 738*cb5caa98Sdjl nscd_rc_t 739*cb5caa98Sdjl _nscd_init_all_nsw_state_base() 740*cb5caa98Sdjl { 741*cb5caa98Sdjl int i; 742*cb5caa98Sdjl nscd_rc_t rc; 743*cb5caa98Sdjl char *me = "_nscd_init_all_nsw_state_base"; 744*cb5caa98Sdjl 745*cb5caa98Sdjl (void) rw_rdlock(&nscd_nsw_state_base_lock); 746*cb5caa98Sdjl 747*cb5caa98Sdjl for (i = 0; i < NSCD_NUM_DB; i++) { 748*cb5caa98Sdjl 749*cb5caa98Sdjl rc = _nscd_init_nsw_state_base(i, 0); 750*cb5caa98Sdjl 751*cb5caa98Sdjl if (rc != NSCD_SUCCESS) { 752*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE | NSCD_LOG_CONFIG, 753*cb5caa98Sdjl NSCD_LOG_LEVEL_ERROR) 754*cb5caa98Sdjl (me, "not able to initialize a nsw db state " 755*cb5caa98Sdjl "base (%d)\n", i); 756*cb5caa98Sdjl 757*cb5caa98Sdjl (void) rw_unlock(&nscd_nsw_state_base_lock); 758*cb5caa98Sdjl return (rc); 759*cb5caa98Sdjl } 760*cb5caa98Sdjl } 761*cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE | NSCD_LOG_CONFIG, 762*cb5caa98Sdjl NSCD_LOG_LEVEL_DEBUG) 763*cb5caa98Sdjl (me, "all nsw state base initialized\n"); 764*cb5caa98Sdjl 765*cb5caa98Sdjl (void) rw_unlock(&nscd_nsw_state_base_lock); 766*cb5caa98Sdjl 767*cb5caa98Sdjl return (NSCD_SUCCESS); 768*cb5caa98Sdjl } 769*cb5caa98Sdjl 770*cb5caa98Sdjl nscd_rc_t 771*cb5caa98Sdjl _nscd_alloc_nsw_state_base() 772*cb5caa98Sdjl { 773*cb5caa98Sdjl 774*cb5caa98Sdjl (void) rw_rdlock(&nscd_nsw_state_base_lock); 775*cb5caa98Sdjl 776*cb5caa98Sdjl nscd_nsw_state_base = calloc(NSCD_NUM_DB, 777*cb5caa98Sdjl sizeof (nscd_nsw_state_base_t *)); 778*cb5caa98Sdjl if (nscd_nsw_state_base == NULL) { 779*cb5caa98Sdjl (void) rw_unlock(&nscd_nsw_state_base_lock); 780*cb5caa98Sdjl return (NSCD_NO_MEMORY); 781*cb5caa98Sdjl } 782*cb5caa98Sdjl 783*cb5caa98Sdjl (void) rw_rdlock(&nscd_nsw_state_base_lock); 784*cb5caa98Sdjl 785*cb5caa98Sdjl return (NSCD_SUCCESS); 786*cb5caa98Sdjl } 787