xref: /titanic_52/usr/src/cmd/nscd/nscd_nswstate.c (revision cb5caa98562cf06753163f558cbcfe30b8f4673a)
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