xref: /titanic_41/usr/src/cmd/nscd/nscd_nswcfgst.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 <locale.h>
30*cb5caa98Sdjl #include <string.h>
31*cb5caa98Sdjl #include "nscd_config.h"
32*cb5caa98Sdjl #include "nscd_log.h"
33*cb5caa98Sdjl #include "nscd_switch.h"
34*cb5caa98Sdjl 
35*cb5caa98Sdjl /*
36*cb5caa98Sdjl  * Configuration data for the nscd switch functions.
37*cb5caa98Sdjl  */
38*cb5caa98Sdjl nscd_cfg_global_switch_t	nscd_switch_cfg_g;
39*cb5caa98Sdjl nscd_cfg_switch_t		*nscd_switch_cfg;
40*cb5caa98Sdjl 
41*cb5caa98Sdjl /*
42*cb5caa98Sdjl  * statistics of the nscd switch functions.
43*cb5caa98Sdjl  */
44*cb5caa98Sdjl nscd_cfg_stat_global_switch_t	nscd_switch_stats_g;
45*cb5caa98Sdjl nscd_cfg_stat_switch_t		*nscd_switch_stats;
46*cb5caa98Sdjl 
47*cb5caa98Sdjl /*
48*cb5caa98Sdjl  * cookie is set up by the verify function for passing to
49*cb5caa98Sdjl  * the notify function
50*cb5caa98Sdjl  */
51*cb5caa98Sdjl typedef struct {
52*cb5caa98Sdjl 	struct __nsw_switchconfig_v1	*cfg;
53*cb5caa98Sdjl 	char				*cfgstr;
54*cb5caa98Sdjl } nsw_cfg_cookie_t;
55*cb5caa98Sdjl 
56*cb5caa98Sdjl nscd_rc_t
57*cb5caa98Sdjl _nscd_alloc_switch_cfg()
58*cb5caa98Sdjl {
59*cb5caa98Sdjl 	nscd_switch_cfg  = calloc(NSCD_NUM_DB, sizeof (nscd_cfg_switch_t));
60*cb5caa98Sdjl 	if (nscd_switch_cfg == NULL)
61*cb5caa98Sdjl 		return (NSCD_NO_MEMORY);
62*cb5caa98Sdjl 
63*cb5caa98Sdjl 	return (NSCD_SUCCESS);
64*cb5caa98Sdjl }
65*cb5caa98Sdjl 
66*cb5caa98Sdjl nscd_rc_t
67*cb5caa98Sdjl _nscd_alloc_switch_stats()
68*cb5caa98Sdjl {
69*cb5caa98Sdjl 
70*cb5caa98Sdjl 	nscd_switch_stats = calloc(NSCD_NUM_DB,
71*cb5caa98Sdjl 		sizeof (nscd_cfg_stat_switch_t));
72*cb5caa98Sdjl 	if (nscd_switch_stats == NULL)
73*cb5caa98Sdjl 		return (NSCD_NO_MEMORY);
74*cb5caa98Sdjl 
75*cb5caa98Sdjl 	return (NSCD_SUCCESS);
76*cb5caa98Sdjl }
77*cb5caa98Sdjl 
78*cb5caa98Sdjl /* ARGSUSED */
79*cb5caa98Sdjl nscd_rc_t
80*cb5caa98Sdjl _nscd_cfg_switch_notify(
81*cb5caa98Sdjl 	void				*data,
82*cb5caa98Sdjl 	struct nscd_cfg_param_desc	*pdesc,
83*cb5caa98Sdjl 	nscd_cfg_id_t			*nswdb,
84*cb5caa98Sdjl 	nscd_cfg_flag_t			dflag,
85*cb5caa98Sdjl 	nscd_cfg_error_t		**errorp,
86*cb5caa98Sdjl 	void				*cookie)
87*cb5caa98Sdjl {
88*cb5caa98Sdjl 
89*cb5caa98Sdjl 	void				*dp;
90*cb5caa98Sdjl 	nscd_rc_t			rc;
91*cb5caa98Sdjl 	nsw_cfg_cookie_t		*ck = (nsw_cfg_cookie_t *)cookie;
92*cb5caa98Sdjl 
93*cb5caa98Sdjl 	if (_nscd_cfg_flag_is_set(dflag, NSCD_CFG_DFLAG_INIT) ||
94*cb5caa98Sdjl 		_nscd_cfg_flag_is_set(dflag, NSCD_CFG_DFLAG_GROUP)) {
95*cb5caa98Sdjl 		/*
96*cb5caa98Sdjl 		 * group data is received, copy in the
97*cb5caa98Sdjl 		 * entire strcture
98*cb5caa98Sdjl 		 */
99*cb5caa98Sdjl 		if (_nscd_cfg_flag_is_set(pdesc->pflag,
100*cb5caa98Sdjl 			NSCD_CFG_PFLAG_GLOBAL)) {
101*cb5caa98Sdjl 			nscd_switch_cfg_g = *(nscd_cfg_global_switch_t *)data;
102*cb5caa98Sdjl 		} else {
103*cb5caa98Sdjl 			nscd_switch_cfg[nswdb->index] =
104*cb5caa98Sdjl 				*(nscd_cfg_switch_t *)data;
105*cb5caa98Sdjl 
106*cb5caa98Sdjl 		}
107*cb5caa98Sdjl 	} else {
108*cb5caa98Sdjl 		/*
109*cb5caa98Sdjl 		 * individual paramater is received: copy in the
110*cb5caa98Sdjl 		 * parameter value except for nsw-config-string.
111*cb5caa98Sdjl 		 */
112*cb5caa98Sdjl 		if (_nscd_cfg_flag_is_set(pdesc->pflag,
113*cb5caa98Sdjl 			NSCD_CFG_PFLAG_GLOBAL)) {
114*cb5caa98Sdjl 			dp = (char *)&nscd_switch_cfg_g + pdesc->p_offset;
115*cb5caa98Sdjl 			(void) memcpy(dp, data, pdesc->p_size);
116*cb5caa98Sdjl 		} else {
117*cb5caa98Sdjl 			dp = (char *)&nscd_switch_cfg[nswdb->index] +
118*cb5caa98Sdjl 				pdesc->p_offset;
119*cb5caa98Sdjl 			if (pdesc->p_offset !=
120*cb5caa98Sdjl 				offsetof(nscd_cfg_switch_t, nsw_config_string))
121*cb5caa98Sdjl 				(void) memcpy(dp, data, pdesc->p_size);
122*cb5caa98Sdjl 		}
123*cb5caa98Sdjl 	}
124*cb5caa98Sdjl 
125*cb5caa98Sdjl 	/*
126*cb5caa98Sdjl 	 * cookie contains data for the switch policy config
127*cb5caa98Sdjl 	 */
128*cb5caa98Sdjl 	if (cookie != NULL) {
129*cb5caa98Sdjl 		rc = _nscd_create_sw_struct(nswdb->index, nswdb->name,
130*cb5caa98Sdjl 			ck->cfgstr, ck->cfg, NULL);
131*cb5caa98Sdjl 		if (rc != NSCD_SUCCESS) {
132*cb5caa98Sdjl 			(void) __nsw_freeconfig_v1(ck->cfg);
133*cb5caa98Sdjl 			free(ck);
134*cb5caa98Sdjl 			return (rc);
135*cb5caa98Sdjl 		}
136*cb5caa98Sdjl 		free(ck);
137*cb5caa98Sdjl 	}
138*cb5caa98Sdjl 
139*cb5caa98Sdjl 	if (_nscd_cfg_flag_is_not_set(dflag, NSCD_CFG_DFLAG_STATIC_DATA))
140*cb5caa98Sdjl 		free(data);
141*cb5caa98Sdjl 
142*cb5caa98Sdjl 	return (NSCD_SUCCESS);
143*cb5caa98Sdjl }
144*cb5caa98Sdjl 
145*cb5caa98Sdjl /* ARGSUSED */
146*cb5caa98Sdjl nscd_rc_t
147*cb5caa98Sdjl _nscd_cfg_switch_verify(
148*cb5caa98Sdjl 	void				*data,
149*cb5caa98Sdjl 	struct	nscd_cfg_param_desc	*pdesc,
150*cb5caa98Sdjl 	nscd_cfg_id_t			*nswdb,
151*cb5caa98Sdjl 	nscd_cfg_flag_t			dflag,
152*cb5caa98Sdjl 	nscd_cfg_error_t		**errorp,
153*cb5caa98Sdjl 	void				**cookie)
154*cb5caa98Sdjl {
155*cb5caa98Sdjl 	char				*me = "_nscd_cfg_switch_verify";
156*cb5caa98Sdjl 	nscd_cfg_switch_t		*cfg;
157*cb5caa98Sdjl 	char				*nswcfgstr;
158*cb5caa98Sdjl 	int				size;
159*cb5caa98Sdjl 	struct __nsw_switchconfig_v1	*switchcfg = NULL;
160*cb5caa98Sdjl 	enum __nsw_parse_err		err;
161*cb5caa98Sdjl 	nsw_cfg_cookie_t		*ck;
162*cb5caa98Sdjl 	char				buf[MAX_NSSWITCH_CONFIG_STRING_SZ];
163*cb5caa98Sdjl 	char				msg[NSCD_CFG_MAX_ERR_MSG_LEN];
164*cb5caa98Sdjl 
165*cb5caa98Sdjl 	/*
166*cb5caa98Sdjl 	 * global config data has nothing special to verify
167*cb5caa98Sdjl 	 */
168*cb5caa98Sdjl 	if (_nscd_cfg_flag_is_set(pdesc->pflag, NSCD_CFG_PFLAG_GLOBAL))
169*cb5caa98Sdjl 		return (NSCD_SUCCESS);
170*cb5caa98Sdjl 
171*cb5caa98Sdjl 	*cookie = NULL;
172*cb5caa98Sdjl 
173*cb5caa98Sdjl 	/*
174*cb5caa98Sdjl 	 * switch policy string is the one to parse and verify
175*cb5caa98Sdjl 	 */
176*cb5caa98Sdjl 
177*cb5caa98Sdjl 	if (_nscd_cfg_flag_is_set(dflag, NSCD_CFG_DFLAG_INIT) ||
178*cb5caa98Sdjl 		_nscd_cfg_flag_is_set(dflag, NSCD_CFG_DFLAG_GROUP)) {
179*cb5caa98Sdjl 
180*cb5caa98Sdjl 		/* get it from the group data */
181*cb5caa98Sdjl 		cfg = (nscd_cfg_switch_t *)data;
182*cb5caa98Sdjl 		nswcfgstr = cfg->nsw_config_string;
183*cb5caa98Sdjl 	} else {
184*cb5caa98Sdjl 		/* not group, and not the switch policy string, return */
185*cb5caa98Sdjl 		if (pdesc->p_offset != offsetof(nscd_cfg_switch_t,
186*cb5caa98Sdjl 			nsw_config_string))
187*cb5caa98Sdjl 		return (NSCD_SUCCESS);
188*cb5caa98Sdjl 
189*cb5caa98Sdjl 		/* the data itself is the string */
190*cb5caa98Sdjl 		nswcfgstr = (char *)data;
191*cb5caa98Sdjl 	}
192*cb5caa98Sdjl 
193*cb5caa98Sdjl 	/*
194*cb5caa98Sdjl 	 * convert the string into struct __nsw_switchconfig_v1
195*cb5caa98Sdjl 	 */
196*cb5caa98Sdjl 	size = MAX_NSSWITCH_CONFIG_STRING_SZ;
197*cb5caa98Sdjl 	if (strlcpy(buf, nswcfgstr, size) >= size) {
198*cb5caa98Sdjl 
199*cb5caa98Sdjl 		(void) snprintf(msg, sizeof (msg),
200*cb5caa98Sdjl 	gettext("switch policy string too long (\"%s : %s\" > %d)"),
201*cb5caa98Sdjl 			nswdb->name, nswcfgstr, size);
202*cb5caa98Sdjl 
203*cb5caa98Sdjl 		_NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR)
204*cb5caa98Sdjl 		(me, "%s\n", msg);
205*cb5caa98Sdjl 
206*cb5caa98Sdjl 		if (*errorp)
207*cb5caa98Sdjl 			*errorp = _nscd_cfg_make_error(
208*cb5caa98Sdjl 				NSCD_CFG_SYNTAX_ERROR, msg);
209*cb5caa98Sdjl 
210*cb5caa98Sdjl 		return (NSCD_CFG_SYNTAX_ERROR);
211*cb5caa98Sdjl 	}
212*cb5caa98Sdjl 	switchcfg = _nsw_getoneconfig_v1(nswdb->name, buf, &err);
213*cb5caa98Sdjl 	if (switchcfg == NULL) {
214*cb5caa98Sdjl 
215*cb5caa98Sdjl 		(void) snprintf(msg, sizeof (msg),
216*cb5caa98Sdjl 		gettext("syntax error: switch policy string (%s : %s) rc = %d"),
217*cb5caa98Sdjl 		nswdb->name, nswcfgstr, err);
218*cb5caa98Sdjl 
219*cb5caa98Sdjl 		_NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR)
220*cb5caa98Sdjl 		(me, "%s\n", msg);
221*cb5caa98Sdjl 
222*cb5caa98Sdjl 		if (*errorp)
223*cb5caa98Sdjl 			*errorp = _nscd_cfg_make_error(
224*cb5caa98Sdjl 				NSCD_CFG_SYNTAX_ERROR, msg);
225*cb5caa98Sdjl 
226*cb5caa98Sdjl 		return (NSCD_CFG_SYNTAX_ERROR);
227*cb5caa98Sdjl 	}
228*cb5caa98Sdjl 
229*cb5caa98Sdjl 	/* save the __nsw_switchconfig_v1 for the notify function */
230*cb5caa98Sdjl 	ck = calloc(1, sizeof (nsw_cfg_cookie_t));
231*cb5caa98Sdjl 	if (ck == NULL) {
232*cb5caa98Sdjl 		(void) __nsw_freeconfig_v1(switchcfg);
233*cb5caa98Sdjl 		return (NSCD_CFG_SYNTAX_ERROR);
234*cb5caa98Sdjl 	}
235*cb5caa98Sdjl 	ck->cfg = switchcfg;
236*cb5caa98Sdjl 	ck->cfgstr = nswcfgstr;
237*cb5caa98Sdjl 	*cookie = ck;
238*cb5caa98Sdjl 
239*cb5caa98Sdjl 	return (NSCD_SUCCESS);
240*cb5caa98Sdjl }
241*cb5caa98Sdjl 
242*cb5caa98Sdjl /* ARGSUSED */
243*cb5caa98Sdjl nscd_rc_t
244*cb5caa98Sdjl _nscd_cfg_switch_get_stat(
245*cb5caa98Sdjl 	void				**stat,
246*cb5caa98Sdjl 	struct nscd_cfg_stat_desc	*sdesc,
247*cb5caa98Sdjl 	nscd_cfg_id_t			*nswdb,
248*cb5caa98Sdjl 	nscd_cfg_flag_t			*dflag,
249*cb5caa98Sdjl 	void				(**free_stat)(void *stat),
250*cb5caa98Sdjl 	nscd_cfg_error_t		**errorp)
251*cb5caa98Sdjl {
252*cb5caa98Sdjl 
253*cb5caa98Sdjl 	if (_nscd_cfg_flag_is_set(sdesc->sflag, NSCD_CFG_SFLAG_GLOBAL)) {
254*cb5caa98Sdjl 		*stat = &NSCD_SW_STATS_G;
255*cb5caa98Sdjl 	} else
256*cb5caa98Sdjl 		*stat = &NSCD_SW_STATS(nswdb->index);
257*cb5caa98Sdjl 
258*cb5caa98Sdjl 	/* indicate the statistics are static, i.e., do not free */
259*cb5caa98Sdjl 	*dflag = _nscd_cfg_flag_set(*dflag, NSCD_CFG_DFLAG_STATIC_DATA);
260*cb5caa98Sdjl 
261*cb5caa98Sdjl 	return (NSCD_SUCCESS);
262*cb5caa98Sdjl }
263