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