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