xref: /illumos-gate/usr/src/cmd/nscd/nscd_nswcfgst.c (revision 2a8bcb4e)
1cb5caa98Sdjl /*
2cb5caa98Sdjl  * CDDL HEADER START
3cb5caa98Sdjl  *
4cb5caa98Sdjl  * The contents of this file are subject to the terms of the
5cb5caa98Sdjl  * Common Development and Distribution License (the "License").
6cb5caa98Sdjl  * You may not use this file except in compliance with the License.
7cb5caa98Sdjl  *
8cb5caa98Sdjl  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9cb5caa98Sdjl  * or http://www.opensolaris.org/os/licensing.
10cb5caa98Sdjl  * See the License for the specific language governing permissions
11cb5caa98Sdjl  * and limitations under the License.
12cb5caa98Sdjl  *
13cb5caa98Sdjl  * When distributing Covered Code, include this CDDL HEADER in each
14cb5caa98Sdjl  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15cb5caa98Sdjl  * If applicable, add the following below this CDDL HEADER, with the
16cb5caa98Sdjl  * fields enclosed by brackets "[]" replaced with your own identifying
17cb5caa98Sdjl  * information: Portions Copyright [yyyy] [name of copyright owner]
18cb5caa98Sdjl  *
19cb5caa98Sdjl  * CDDL HEADER END
20cb5caa98Sdjl  */
21cb5caa98Sdjl /*
22cb5caa98Sdjl  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23cb5caa98Sdjl  * Use is subject to license terms.
24cb5caa98Sdjl  */
25cb5caa98Sdjl 
26cb5caa98Sdjl #include <stdlib.h>
27cb5caa98Sdjl #include <locale.h>
28cb5caa98Sdjl #include <string.h>
29cb5caa98Sdjl #include "nscd_config.h"
30cb5caa98Sdjl #include "nscd_log.h"
31cb5caa98Sdjl #include "nscd_switch.h"
32cb5caa98Sdjl 
33cb5caa98Sdjl /*
34cb5caa98Sdjl  * Configuration data for the nscd switch functions.
35cb5caa98Sdjl  */
36cb5caa98Sdjl nscd_cfg_global_switch_t	nscd_switch_cfg_g;
37cb5caa98Sdjl nscd_cfg_switch_t		*nscd_switch_cfg;
38cb5caa98Sdjl 
39cb5caa98Sdjl /*
40cb5caa98Sdjl  * statistics of the nscd switch functions.
41cb5caa98Sdjl  */
42cb5caa98Sdjl nscd_cfg_stat_global_switch_t	nscd_switch_stats_g;
43cb5caa98Sdjl nscd_cfg_stat_switch_t		*nscd_switch_stats;
44cb5caa98Sdjl 
45cb5caa98Sdjl /*
46cb5caa98Sdjl  * cookie is set up by the verify function for passing to
47cb5caa98Sdjl  * the notify function
48cb5caa98Sdjl  */
49cb5caa98Sdjl typedef struct {
50cb5caa98Sdjl 	struct __nsw_switchconfig_v1	*cfg;
51cb5caa98Sdjl 	char				*cfgstr;
52cb5caa98Sdjl } nsw_cfg_cookie_t;
53cb5caa98Sdjl 
54cb5caa98Sdjl nscd_rc_t
_nscd_alloc_switch_cfg()55cb5caa98Sdjl _nscd_alloc_switch_cfg()
56cb5caa98Sdjl {
57cb5caa98Sdjl 	nscd_switch_cfg  = calloc(NSCD_NUM_DB, sizeof (nscd_cfg_switch_t));
58cb5caa98Sdjl 	if (nscd_switch_cfg == NULL)
59cb5caa98Sdjl 		return (NSCD_NO_MEMORY);
60cb5caa98Sdjl 
61cb5caa98Sdjl 	return (NSCD_SUCCESS);
62cb5caa98Sdjl }
63cb5caa98Sdjl 
64cb5caa98Sdjl nscd_rc_t
_nscd_alloc_switch_stats()65cb5caa98Sdjl _nscd_alloc_switch_stats()
66cb5caa98Sdjl {
67cb5caa98Sdjl 
68cb5caa98Sdjl 	nscd_switch_stats = calloc(NSCD_NUM_DB,
69cb5caa98Sdjl 		sizeof (nscd_cfg_stat_switch_t));
70cb5caa98Sdjl 	if (nscd_switch_stats == NULL)
71cb5caa98Sdjl 		return (NSCD_NO_MEMORY);
72cb5caa98Sdjl 
73cb5caa98Sdjl 	return (NSCD_SUCCESS);
74cb5caa98Sdjl }
75cb5caa98Sdjl 
76cb5caa98Sdjl /* ARGSUSED */
77cb5caa98Sdjl nscd_rc_t
_nscd_cfg_switch_notify(void * data,struct nscd_cfg_param_desc * pdesc,nscd_cfg_id_t * nswdb,nscd_cfg_flag_t dflag,nscd_cfg_error_t ** errorp,void * cookie)78cb5caa98Sdjl _nscd_cfg_switch_notify(
79cb5caa98Sdjl 	void				*data,
80cb5caa98Sdjl 	struct nscd_cfg_param_desc	*pdesc,
81cb5caa98Sdjl 	nscd_cfg_id_t			*nswdb,
82cb5caa98Sdjl 	nscd_cfg_flag_t			dflag,
83cb5caa98Sdjl 	nscd_cfg_error_t		**errorp,
84cb5caa98Sdjl 	void				*cookie)
85cb5caa98Sdjl {
86cb5caa98Sdjl 
87cb5caa98Sdjl 	void				*dp;
88cb5caa98Sdjl 	nscd_rc_t			rc;
89cb5caa98Sdjl 	nsw_cfg_cookie_t		*ck = (nsw_cfg_cookie_t *)cookie;
90cb5caa98Sdjl 
91cb5caa98Sdjl 	if (_nscd_cfg_flag_is_set(dflag, NSCD_CFG_DFLAG_INIT) ||
92cb5caa98Sdjl 		_nscd_cfg_flag_is_set(dflag, NSCD_CFG_DFLAG_GROUP)) {
93cb5caa98Sdjl 		/*
94cb5caa98Sdjl 		 * group data is received, copy in the
95cb5caa98Sdjl 		 * entire strcture
96cb5caa98Sdjl 		 */
97cb5caa98Sdjl 		if (_nscd_cfg_flag_is_set(pdesc->pflag,
98cb5caa98Sdjl 			NSCD_CFG_PFLAG_GLOBAL)) {
99cb5caa98Sdjl 			nscd_switch_cfg_g = *(nscd_cfg_global_switch_t *)data;
100cb5caa98Sdjl 		} else {
101cb5caa98Sdjl 			nscd_switch_cfg[nswdb->index] =
102cb5caa98Sdjl 				*(nscd_cfg_switch_t *)data;
103cb5caa98Sdjl 
104cb5caa98Sdjl 		}
105cb5caa98Sdjl 	} else {
106cb5caa98Sdjl 		/*
107cb5caa98Sdjl 		 * individual paramater is received: copy in the
108cb5caa98Sdjl 		 * parameter value except for nsw-config-string.
109cb5caa98Sdjl 		 */
110cb5caa98Sdjl 		if (_nscd_cfg_flag_is_set(pdesc->pflag,
111cb5caa98Sdjl 			NSCD_CFG_PFLAG_GLOBAL)) {
112cb5caa98Sdjl 			dp = (char *)&nscd_switch_cfg_g + pdesc->p_offset;
113cb5caa98Sdjl 			(void) memcpy(dp, data, pdesc->p_size);
114cb5caa98Sdjl 		} else {
115cb5caa98Sdjl 			dp = (char *)&nscd_switch_cfg[nswdb->index] +
116cb5caa98Sdjl 				pdesc->p_offset;
117cb5caa98Sdjl 			if (pdesc->p_offset !=
118cb5caa98Sdjl 				offsetof(nscd_cfg_switch_t, nsw_config_string))
119cb5caa98Sdjl 				(void) memcpy(dp, data, pdesc->p_size);
120cb5caa98Sdjl 		}
121cb5caa98Sdjl 	}
122cb5caa98Sdjl 
123cb5caa98Sdjl 	/*
124cb5caa98Sdjl 	 * cookie contains data for the switch policy config
125cb5caa98Sdjl 	 */
126cb5caa98Sdjl 	if (cookie != NULL) {
127*ad0e80f7Smichen 		rc = _nscd_create_sw_struct(nswdb->index, -1, nswdb->name,
128cb5caa98Sdjl 			ck->cfgstr, ck->cfg, NULL);
129cb5caa98Sdjl 		if (rc != NSCD_SUCCESS) {
130cb5caa98Sdjl 			(void) __nsw_freeconfig_v1(ck->cfg);
131cb5caa98Sdjl 			free(ck);
132cb5caa98Sdjl 			return (rc);
133cb5caa98Sdjl 		}
134cb5caa98Sdjl 		free(ck);
135cb5caa98Sdjl 	}
136cb5caa98Sdjl 
137cb5caa98Sdjl 	if (_nscd_cfg_flag_is_not_set(dflag, NSCD_CFG_DFLAG_STATIC_DATA))
138cb5caa98Sdjl 		free(data);
139cb5caa98Sdjl 
140cb5caa98Sdjl 	return (NSCD_SUCCESS);
141cb5caa98Sdjl }
142cb5caa98Sdjl 
143cb5caa98Sdjl /* ARGSUSED */
144cb5caa98Sdjl nscd_rc_t
_nscd_cfg_switch_verify(void * data,struct nscd_cfg_param_desc * pdesc,nscd_cfg_id_t * nswdb,nscd_cfg_flag_t dflag,nscd_cfg_error_t ** errorp,void ** cookie)145cb5caa98Sdjl _nscd_cfg_switch_verify(
146cb5caa98Sdjl 	void				*data,
147cb5caa98Sdjl 	struct	nscd_cfg_param_desc	*pdesc,
148cb5caa98Sdjl 	nscd_cfg_id_t			*nswdb,
149cb5caa98Sdjl 	nscd_cfg_flag_t			dflag,
150cb5caa98Sdjl 	nscd_cfg_error_t		**errorp,
151cb5caa98Sdjl 	void				**cookie)
152cb5caa98Sdjl {
153cb5caa98Sdjl 	char				*me = "_nscd_cfg_switch_verify";
154cb5caa98Sdjl 	nscd_cfg_switch_t		*cfg;
155cb5caa98Sdjl 	char				*nswcfgstr;
156cb5caa98Sdjl 	int				size;
157cb5caa98Sdjl 	struct __nsw_switchconfig_v1	*switchcfg = NULL;
158cb5caa98Sdjl 	enum __nsw_parse_err		err;
159cb5caa98Sdjl 	nsw_cfg_cookie_t		*ck;
160cb5caa98Sdjl 	char				buf[MAX_NSSWITCH_CONFIG_STRING_SZ];
161cb5caa98Sdjl 	char				msg[NSCD_CFG_MAX_ERR_MSG_LEN];
162cb5caa98Sdjl 
163cb5caa98Sdjl 	/*
164cb5caa98Sdjl 	 * global config data has nothing special to verify
165cb5caa98Sdjl 	 */
166cb5caa98Sdjl 	if (_nscd_cfg_flag_is_set(pdesc->pflag, NSCD_CFG_PFLAG_GLOBAL))
167cb5caa98Sdjl 		return (NSCD_SUCCESS);
168cb5caa98Sdjl 
169cb5caa98Sdjl 	*cookie = NULL;
170cb5caa98Sdjl 
171cb5caa98Sdjl 	/*
172cb5caa98Sdjl 	 * switch policy string is the one to parse and verify
173cb5caa98Sdjl 	 */
174cb5caa98Sdjl 
175cb5caa98Sdjl 	if (_nscd_cfg_flag_is_set(dflag, NSCD_CFG_DFLAG_INIT) ||
176cb5caa98Sdjl 		_nscd_cfg_flag_is_set(dflag, NSCD_CFG_DFLAG_GROUP)) {
177cb5caa98Sdjl 
178cb5caa98Sdjl 		/* get it from the group data */
179cb5caa98Sdjl 		cfg = (nscd_cfg_switch_t *)data;
180cb5caa98Sdjl 		nswcfgstr = cfg->nsw_config_string;
181cb5caa98Sdjl 	} else {
182cb5caa98Sdjl 		/* not group, and not the switch policy string, return */
183cb5caa98Sdjl 		if (pdesc->p_offset != offsetof(nscd_cfg_switch_t,
184cb5caa98Sdjl 			nsw_config_string))
185cb5caa98Sdjl 		return (NSCD_SUCCESS);
186cb5caa98Sdjl 
187cb5caa98Sdjl 		/* the data itself is the string */
188cb5caa98Sdjl 		nswcfgstr = (char *)data;
189cb5caa98Sdjl 	}
190cb5caa98Sdjl 
191cb5caa98Sdjl 	/*
192cb5caa98Sdjl 	 * convert the string into struct __nsw_switchconfig_v1
193cb5caa98Sdjl 	 */
194cb5caa98Sdjl 	size = MAX_NSSWITCH_CONFIG_STRING_SZ;
195cb5caa98Sdjl 	if (strlcpy(buf, nswcfgstr, size) >= size) {
196cb5caa98Sdjl 
197cb5caa98Sdjl 		(void) snprintf(msg, sizeof (msg),
198cb5caa98Sdjl 	gettext("switch policy string too long (\"%s : %s\" > %d)"),
199cb5caa98Sdjl 			nswdb->name, nswcfgstr, size);
200cb5caa98Sdjl 
201cb5caa98Sdjl 		_NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR)
202cb5caa98Sdjl 		(me, "%s\n", msg);
203cb5caa98Sdjl 
204cb5caa98Sdjl 		if (*errorp)
205cb5caa98Sdjl 			*errorp = _nscd_cfg_make_error(
206cb5caa98Sdjl 				NSCD_CFG_SYNTAX_ERROR, msg);
207cb5caa98Sdjl 
208cb5caa98Sdjl 		return (NSCD_CFG_SYNTAX_ERROR);
209cb5caa98Sdjl 	}
210cb5caa98Sdjl 	switchcfg = _nsw_getoneconfig_v1(nswdb->name, buf, &err);
211cb5caa98Sdjl 	if (switchcfg == NULL) {
212cb5caa98Sdjl 
213cb5caa98Sdjl 		(void) snprintf(msg, sizeof (msg),
214cb5caa98Sdjl 		gettext("syntax error: switch policy string (%s : %s) rc = %d"),
215cb5caa98Sdjl 		nswdb->name, nswcfgstr, err);
216cb5caa98Sdjl 
217cb5caa98Sdjl 		_NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR)
218cb5caa98Sdjl 		(me, "%s\n", msg);
219cb5caa98Sdjl 
220cb5caa98Sdjl 		if (*errorp)
221cb5caa98Sdjl 			*errorp = _nscd_cfg_make_error(
222cb5caa98Sdjl 				NSCD_CFG_SYNTAX_ERROR, msg);
223cb5caa98Sdjl 
224cb5caa98Sdjl 		return (NSCD_CFG_SYNTAX_ERROR);
225cb5caa98Sdjl 	}
226cb5caa98Sdjl 
227cb5caa98Sdjl 	/* save the __nsw_switchconfig_v1 for the notify function */
228cb5caa98Sdjl 	ck = calloc(1, sizeof (nsw_cfg_cookie_t));
229cb5caa98Sdjl 	if (ck == NULL) {
230cb5caa98Sdjl 		(void) __nsw_freeconfig_v1(switchcfg);
231cb5caa98Sdjl 		return (NSCD_CFG_SYNTAX_ERROR);
232cb5caa98Sdjl 	}
233cb5caa98Sdjl 	ck->cfg = switchcfg;
234cb5caa98Sdjl 	ck->cfgstr = nswcfgstr;
235cb5caa98Sdjl 	*cookie = ck;
236cb5caa98Sdjl 
237cb5caa98Sdjl 	return (NSCD_SUCCESS);
238cb5caa98Sdjl }
239cb5caa98Sdjl 
240cb5caa98Sdjl /* ARGSUSED */
241cb5caa98Sdjl nscd_rc_t
_nscd_cfg_switch_get_stat(void ** stat,struct nscd_cfg_stat_desc * sdesc,nscd_cfg_id_t * nswdb,nscd_cfg_flag_t * dflag,void (** free_stat)(void * stat),nscd_cfg_error_t ** errorp)242cb5caa98Sdjl _nscd_cfg_switch_get_stat(
243cb5caa98Sdjl 	void				**stat,
244cb5caa98Sdjl 	struct nscd_cfg_stat_desc	*sdesc,
245cb5caa98Sdjl 	nscd_cfg_id_t			*nswdb,
246cb5caa98Sdjl 	nscd_cfg_flag_t			*dflag,
247cb5caa98Sdjl 	void				(**free_stat)(void *stat),
248cb5caa98Sdjl 	nscd_cfg_error_t		**errorp)
249cb5caa98Sdjl {
250cb5caa98Sdjl 
251cb5caa98Sdjl 	if (_nscd_cfg_flag_is_set(sdesc->sflag, NSCD_CFG_SFLAG_GLOBAL)) {
252cb5caa98Sdjl 		*stat = &NSCD_SW_STATS_G;
253cb5caa98Sdjl 	} else
254cb5caa98Sdjl 		*stat = &NSCD_SW_STATS(nswdb->index);
255cb5caa98Sdjl 
256cb5caa98Sdjl 	/* indicate the statistics are static, i.e., do not free */
257cb5caa98Sdjl 	*dflag = _nscd_cfg_flag_set(*dflag, NSCD_CFG_DFLAG_STATIC_DATA);
258cb5caa98Sdjl 
259cb5caa98Sdjl 	return (NSCD_SUCCESS);
260cb5caa98Sdjl }
261