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