xref: /illumos-gate/usr/src/cmd/nscd/nscd_nswconfig.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 <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