xref: /illumos-gate/usr/src/cmd/nscd/nscd_init.c (revision 06e1a714)
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 <locale.h>
29 #include <unistd.h>
30 #include <string.h>
31 #include "nscd_common.h"
32 #include "nscd_config.h"
33 #include "nscd_log.h"
34 #include "nscd_switch.h"
35 #include "nscd_frontend.h"
36 
37 static char	*cfgfile_save = NULL;
38 
39 nscd_rc_t
40 _nscd_init(
41 	char			*cfgfile)
42 {
43 	char			*me = "nscd_init";
44 	nscd_rc_t		rc;
45 	nscd_cfg_error_t	*err;
46 
47 	/*
48 	 * allocate the space for tables
49 	 */
50 	rc = _nscd_alloc_nsw_config();
51 	rc = _nscd_alloc_service_state_table();
52 	rc = _nscd_alloc_nsw_state_base();
53 	rc = _nscd_alloc_nsw_be_info_db();
54 	rc = _nscd_alloc_getent_ctx_base();
55 	if (rc != NSCD_SUCCESS)
56 		return (rc);
57 
58 	/*
59 	 * allocate the space for local configuration
60 	 * and statistics
61 	 */
62 	rc = _nscd_alloc_switch_cfg();
63 	rc = _nscd_alloc_frontend_cfg();
64 	rc = _nscd_alloc_switch_stats();
65 	if (rc != NSCD_SUCCESS)
66 		return (rc);
67 
68 	/*
69 	 * Create and init the internal address database to keep
70 	 * track of the memory allocated by _nscd_alloc
71 	 */
72 	if (_nscd_create_int_addrDB() == NULL) {
73 		_NSCD_LOG(NSCD_LOG_INT_ADDR, NSCD_LOG_LEVEL_ERROR)
74 		(me, "_nscd_create_int_addrDB failed\n");
75 		return (NSCD_NO_MEMORY);
76 	}
77 
78 	/*
79 	 * Create and init the internal context database to keep
80 	 * track of the getent context currently being used
81 	 */
82 	if (_nscd_create_getent_ctxDB() == NULL) {
83 		_NSCD_LOG(NSCD_LOG_GETENT_CTX, NSCD_LOG_LEVEL_ERROR)
84 		(me, "_nscd_create_getent_ctx_addrDB failed\n");
85 		return (NSCD_NO_MEMORY);
86 	}
87 
88 	/*
89 	 * Create the backend info database for each possible source
90 	 */
91 	if ((rc = _nscd_init_all_nsw_be_info_db()) != NSCD_SUCCESS) {
92 		_NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_ERROR)
93 		(me, "_nscd_init_all_nsw_be_info_db failed (rc = %d)\n",
94 			rc);
95 		return (rc);
96 	}
97 
98 	/*
99 	 * Create the nscd_nsw_config_t for each possible nss database
100 	 */
101 	if ((rc = _nscd_init_all_nsw_config()) != NSCD_SUCCESS) {
102 		_NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_ERROR)
103 		(me, "_nscd_init_all_nsw_config failed (rc = %d)\n", rc);
104 		return (rc);
105 	}
106 
107 	/*
108 	 * populate the backend info databases
109 	 */
110 	if ((rc = _nscd_populate_nsw_backend_info()) != NSCD_SUCCESS) {
111 		_NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_ERROR)
112 		(me, "_nscd_init_all_nsw_be_info_db failed (rc = %d)\n", rc);
113 		return (rc);
114 	}
115 
116 	/*
117 	 * initialize config/stats management
118 	 */
119 	rc = _nscd_cfg_init(&err);
120 	if (rc != NSCD_SUCCESS) {
121 		if (err != NULL)
122 			_nscd_cfg_free_error(err);
123 		return (rc);
124 	}
125 
126 	/*
127 	 * read in the nsswitch configuration
128 	 */
129 	rc = _nscd_cfg_read_nsswitch_file("/etc/nsswitch.conf", &err);
130 	if (rc != NSCD_SUCCESS) {
131 		(void) printf(
132 		gettext("reading config file %s failed with rc = %d, %s\n"),
133 			"/etc/nsswitch.conf", rc, NSCD_ERR2MSG(err));
134 		if (err != NULL)
135 			_nscd_cfg_free_error(err);
136 
137 		_NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR)
138 	(me, "unable to read /etc/nsswitch.conf (rc = %d)\n", rc);
139 		return (rc);
140 	}
141 
142 	/*
143 	 * read in the nscd configuration
144 	 */
145 	if (cfgfile == NULL) {
146 		cfgfile = "/etc/nscd.conf";
147 		if (access(cfgfile, R_OK) != 0) {
148 			_NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR)
149 		(me, "unable to read /etc/nscd.conf (rc = %d)\n", rc);
150 
151 			return (NSCD_CFG_FILE_ACCESS_ERROR);
152 		}
153 	}
154 	rc = _nscd_cfg_read_file(cfgfile, &err);
155 	if (rc != NSCD_SUCCESS) {
156 		(void) printf(
157 		gettext("reading config file %s failed with rc = %d, %s\n"),
158 			cfgfile, rc, NSCD_ERR2MSG(err));
159 		if (err != NULL)
160 			_nscd_cfg_free_error(err);
161 
162 		_NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR)
163 	(me, "unable to read configuration from %s (rc = %d)\n",
164 			cfgfile, rc);
165 
166 		return (rc);
167 	}
168 	/*
169 	 * remember the name of the config file
170 	 * in case refresh is requested later
171 	 */
172 	if (cfgfile != NULL) {
173 		cfgfile_save = strdup(cfgfile);
174 		if (cfgfile == NULL)
175 			return (NSCD_NO_MEMORY);
176 	}
177 
178 	return (NSCD_SUCCESS);
179 }
180 
181 nscd_rc_t
182 _nscd_refresh()
183 {
184 	char			*me = "nscd_refresh";
185 	char			*cfgfile;
186 	nscd_rc_t		rc;
187 	nscd_cfg_error_t	*err;
188 	char			errmsg[1024];
189 
190 	/*
191 	 * re-read the nsswitch configuration
192 	 */
193 	rc = _nscd_cfg_read_nsswitch_file("/etc/nsswitch.conf", &err);
194 	if (rc != NSCD_SUCCESS) {
195 		(void) snprintf(errmsg, sizeof (errmsg),
196 		"unable to parse the config file %s (rc = %d), %s\n",
197 		"/etc/nsswitch.conf", rc, NSCD_ERR2MSG(err));
198 		goto error_exit;
199 	}
200 
201 	/*
202 	 * re-read the nscd configuration
203 	 */
204 	if (cfgfile_save == NULL)
205 		cfgfile = "/etc/nscd.conf";
206 	else
207 		cfgfile = cfgfile_save;
208 
209 	if (access(cfgfile, R_OK) != 0) {
210 		(void) snprintf(errmsg, sizeof (errmsg),
211 		"unable to read the config file %s (rc = %d), %s\n",
212 			cfgfile, NSCD_CFG_FILE_ACCESS_ERROR,
213 			strerror(errno));
214 
215 		goto error_exit;
216 	}
217 
218 	rc = _nscd_cfg_read_file(cfgfile, &err);
219 	if (rc != NSCD_SUCCESS) {
220 		(void) snprintf(errmsg, sizeof (errmsg),
221 		"unable to parse the config file %s (rc = %d), %s\n",
222 		cfgfile, rc, NSCD_ERR2MSG(err));
223 
224 		goto error_exit;
225 	}
226 
227 	_NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ALL)
228 	(me, "nsswitch/nscd configuration refreshed successfully\n");
229 
230 	return (NSCD_SUCCESS);
231 
232 	error_exit:
233 
234 	if (err != NULL)
235 		_nscd_cfg_free_error(err);
236 
237 	_NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR)
238 	(me, "%s\n", errmsg);
239 
240 	return (rc);
241 }
242