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