xref: /titanic_51/usr/src/cmd/nscd/nscd_init.c (revision e37190e5b4531a897e4191a30b8f41678b582e25)
1cb5caa98Sdjl /*
2cb5caa98Sdjl  * CDDL HEADER START
3cb5caa98Sdjl  *
4cb5caa98Sdjl  * The contents of this file are subject to the terms of the
5cb5caa98Sdjl  * Common Development and Distribution License (the "License").
6cb5caa98Sdjl  * You may not use this file except in compliance with the License.
7cb5caa98Sdjl  *
8cb5caa98Sdjl  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9cb5caa98Sdjl  * or http://www.opensolaris.org/os/licensing.
10cb5caa98Sdjl  * See the License for the specific language governing permissions
11cb5caa98Sdjl  * and limitations under the License.
12cb5caa98Sdjl  *
13cb5caa98Sdjl  * When distributing Covered Code, include this CDDL HEADER in each
14cb5caa98Sdjl  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15cb5caa98Sdjl  * If applicable, add the following below this CDDL HEADER, with the
16cb5caa98Sdjl  * fields enclosed by brackets "[]" replaced with your own identifying
17cb5caa98Sdjl  * information: Portions Copyright [yyyy] [name of copyright owner]
18cb5caa98Sdjl  *
19cb5caa98Sdjl  * CDDL HEADER END
20cb5caa98Sdjl  */
21cb5caa98Sdjl /*
22cb5caa98Sdjl  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23cb5caa98Sdjl  * Use is subject to license terms.
24cb5caa98Sdjl  */
25cb5caa98Sdjl 
26cb5caa98Sdjl #pragma ident	"%Z%%M%	%I%	%E% SMI"
27cb5caa98Sdjl 
28cb5caa98Sdjl #include <locale.h>
29cb5caa98Sdjl #include <unistd.h>
30cb5caa98Sdjl #include <string.h>
31*e37190e5Smichen #include <time.h>
32cb5caa98Sdjl #include "nscd_common.h"
33cb5caa98Sdjl #include "nscd_config.h"
34cb5caa98Sdjl #include "nscd_log.h"
35cb5caa98Sdjl #include "nscd_switch.h"
36cb5caa98Sdjl #include "nscd_frontend.h"
37cb5caa98Sdjl 
38cb5caa98Sdjl static char	*cfgfile_save = NULL;
39*e37190e5Smichen static mutex_t	time_mutex = DEFAULTMUTEX;
40*e37190e5Smichen static time_t	start_time = 0;
41*e37190e5Smichen 
42*e37190e5Smichen void
43*e37190e5Smichen _nscd_set_start_time(int reset)
44*e37190e5Smichen {
45*e37190e5Smichen 	(void) mutex_lock(&time_mutex);
46*e37190e5Smichen 	if (start_time == 0 || reset == 1)
47*e37190e5Smichen 		start_time = time(NULL);
48*e37190e5Smichen 	(void) mutex_unlock(&time_mutex);
49*e37190e5Smichen }
50*e37190e5Smichen 
51*e37190e5Smichen time_t
52*e37190e5Smichen _nscd_get_start_time()
53*e37190e5Smichen {
54*e37190e5Smichen 	return (start_time);
55*e37190e5Smichen }
56cb5caa98Sdjl 
57cb5caa98Sdjl nscd_rc_t
58cb5caa98Sdjl _nscd_init(
59cb5caa98Sdjl 	char			*cfgfile)
60cb5caa98Sdjl {
61cb5caa98Sdjl 	char			*me = "nscd_init";
62cb5caa98Sdjl 	nscd_rc_t		rc;
63cb5caa98Sdjl 	nscd_cfg_error_t	*err;
64cb5caa98Sdjl 
65cb5caa98Sdjl 	/*
66*e37190e5Smichen 	 * remember when main or forker nscd starts.
67*e37190e5Smichen 	 */
68*e37190e5Smichen 	_nscd_set_start_time(0);
69*e37190e5Smichen 
70*e37190e5Smichen 	/*
71cb5caa98Sdjl 	 * allocate the space for tables
72cb5caa98Sdjl 	 */
73*e37190e5Smichen 	if ((rc = _nscd_alloc_nsw_config()) != NSCD_SUCCESS ||
74*e37190e5Smichen 	    (rc = _nscd_alloc_service_state_table()) != NSCD_SUCCESS ||
75*e37190e5Smichen 	    (rc = _nscd_alloc_nsw_state_base()) != NSCD_SUCCESS ||
76*e37190e5Smichen 	    (rc = _nscd_alloc_nsw_be_info_db()) != NSCD_SUCCESS ||
77*e37190e5Smichen 	    (rc = _nscd_alloc_getent_ctx_base()) != NSCD_SUCCESS)
78cb5caa98Sdjl 		return (rc);
79cb5caa98Sdjl 
80cb5caa98Sdjl 	/*
81cb5caa98Sdjl 	 * allocate the space for local configuration
82cb5caa98Sdjl 	 * and statistics
83cb5caa98Sdjl 	 */
84*e37190e5Smichen 	if ((rc = _nscd_alloc_switch_cfg()) != NSCD_SUCCESS ||
85*e37190e5Smichen 	    (rc = _nscd_alloc_frontend_cfg()) != NSCD_SUCCESS ||
86*e37190e5Smichen 	    (rc = _nscd_alloc_switch_stats()) != NSCD_SUCCESS)
87cb5caa98Sdjl 		return (rc);
88cb5caa98Sdjl 
89cb5caa98Sdjl 	/*
90cb5caa98Sdjl 	 * Create and init the internal address database to keep
91cb5caa98Sdjl 	 * track of the memory allocated by _nscd_alloc
92cb5caa98Sdjl 	 */
93cb5caa98Sdjl 	if (_nscd_create_int_addrDB() == NULL) {
94cb5caa98Sdjl 		_NSCD_LOG(NSCD_LOG_INT_ADDR, NSCD_LOG_LEVEL_ERROR)
95cb5caa98Sdjl 		(me, "_nscd_create_int_addrDB failed\n");
96cb5caa98Sdjl 		return (NSCD_NO_MEMORY);
97cb5caa98Sdjl 	}
98cb5caa98Sdjl 
99cb5caa98Sdjl 	/*
100cb5caa98Sdjl 	 * Create and init the internal context database to keep
101cb5caa98Sdjl 	 * track of the getent context currently being used
102cb5caa98Sdjl 	 */
103cb5caa98Sdjl 	if (_nscd_create_getent_ctxDB() == NULL) {
104cb5caa98Sdjl 		_NSCD_LOG(NSCD_LOG_GETENT_CTX, NSCD_LOG_LEVEL_ERROR)
105cb5caa98Sdjl 		(me, "_nscd_create_getent_ctx_addrDB failed\n");
106cb5caa98Sdjl 		return (NSCD_NO_MEMORY);
107cb5caa98Sdjl 	}
108cb5caa98Sdjl 
109cb5caa98Sdjl 	/*
110cb5caa98Sdjl 	 * Create the backend info database for each possible source
111cb5caa98Sdjl 	 */
112cb5caa98Sdjl 	if ((rc = _nscd_init_all_nsw_be_info_db()) != NSCD_SUCCESS) {
113cb5caa98Sdjl 		_NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_ERROR)
114cb5caa98Sdjl 		(me, "_nscd_init_all_nsw_be_info_db failed (rc = %d)\n",
115cb5caa98Sdjl 			rc);
116cb5caa98Sdjl 		return (rc);
117cb5caa98Sdjl 	}
118cb5caa98Sdjl 
119cb5caa98Sdjl 	/*
120cb5caa98Sdjl 	 * Create the nscd_nsw_config_t for each possible nss database
121cb5caa98Sdjl 	 */
122cb5caa98Sdjl 	if ((rc = _nscd_init_all_nsw_config()) != NSCD_SUCCESS) {
123cb5caa98Sdjl 		_NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_ERROR)
124cb5caa98Sdjl 		(me, "_nscd_init_all_nsw_config failed (rc = %d)\n", rc);
125cb5caa98Sdjl 		return (rc);
126cb5caa98Sdjl 	}
127cb5caa98Sdjl 
128cb5caa98Sdjl 	/*
129cb5caa98Sdjl 	 * populate the backend info databases
130cb5caa98Sdjl 	 */
131cb5caa98Sdjl 	if ((rc = _nscd_populate_nsw_backend_info()) != NSCD_SUCCESS) {
132cb5caa98Sdjl 		_NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_ERROR)
133cb5caa98Sdjl 		(me, "_nscd_init_all_nsw_be_info_db failed (rc = %d)\n", rc);
134cb5caa98Sdjl 		return (rc);
135cb5caa98Sdjl 	}
136cb5caa98Sdjl 
137cb5caa98Sdjl 	/*
138cb5caa98Sdjl 	 * initialize config/stats management
139cb5caa98Sdjl 	 */
140cb5caa98Sdjl 	rc = _nscd_cfg_init(&err);
141cb5caa98Sdjl 	if (rc != NSCD_SUCCESS) {
142cb5caa98Sdjl 		if (err != NULL)
143cb5caa98Sdjl 			_nscd_cfg_free_error(err);
144cb5caa98Sdjl 		return (rc);
145cb5caa98Sdjl 	}
146cb5caa98Sdjl 
147cb5caa98Sdjl 	/*
148cb5caa98Sdjl 	 * read in the nsswitch configuration
149cb5caa98Sdjl 	 */
150cb5caa98Sdjl 	rc = _nscd_cfg_read_nsswitch_file("/etc/nsswitch.conf", &err);
151cb5caa98Sdjl 	if (rc != NSCD_SUCCESS) {
152cb5caa98Sdjl 		(void) printf(
153cb5caa98Sdjl 		gettext("reading config file %s failed with rc = %d, %s\n"),
154cb5caa98Sdjl 			"/etc/nsswitch.conf", rc, NSCD_ERR2MSG(err));
155cb5caa98Sdjl 		if (err != NULL)
156cb5caa98Sdjl 			_nscd_cfg_free_error(err);
157cb5caa98Sdjl 
158cb5caa98Sdjl 		_NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR)
159cb5caa98Sdjl 	(me, "unable to read /etc/nsswitch.conf (rc = %d)\n", rc);
160cb5caa98Sdjl 		return (rc);
161cb5caa98Sdjl 	}
162cb5caa98Sdjl 
163cb5caa98Sdjl 	/*
164cb5caa98Sdjl 	 * read in the nscd configuration
165cb5caa98Sdjl 	 */
166cb5caa98Sdjl 	if (cfgfile == NULL) {
167cb5caa98Sdjl 		cfgfile = "/etc/nscd.conf";
168cb5caa98Sdjl 		if (access(cfgfile, R_OK) != 0) {
169cb5caa98Sdjl 			_NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR)
170cb5caa98Sdjl 		(me, "unable to read /etc/nscd.conf (rc = %d)\n", rc);
171cb5caa98Sdjl 
172cb5caa98Sdjl 			return (NSCD_CFG_FILE_ACCESS_ERROR);
173cb5caa98Sdjl 		}
174cb5caa98Sdjl 	}
175cb5caa98Sdjl 	rc = _nscd_cfg_read_file(cfgfile, &err);
176cb5caa98Sdjl 	if (rc != NSCD_SUCCESS) {
177cb5caa98Sdjl 		(void) printf(
178cb5caa98Sdjl 		gettext("reading config file %s failed with rc = %d, %s\n"),
179cb5caa98Sdjl 			cfgfile, rc, NSCD_ERR2MSG(err));
180cb5caa98Sdjl 		if (err != NULL)
181cb5caa98Sdjl 			_nscd_cfg_free_error(err);
182cb5caa98Sdjl 
183cb5caa98Sdjl 		_NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR)
184cb5caa98Sdjl 	(me, "unable to read configuration from %s (rc = %d)\n",
185cb5caa98Sdjl 			cfgfile, rc);
186cb5caa98Sdjl 
187cb5caa98Sdjl 		return (rc);
188cb5caa98Sdjl 	}
189cb5caa98Sdjl 	/*
190cb5caa98Sdjl 	 * remember the name of the config file
191cb5caa98Sdjl 	 * in case refresh is requested later
192cb5caa98Sdjl 	 */
193cb5caa98Sdjl 	if (cfgfile != NULL) {
194cb5caa98Sdjl 		cfgfile_save = strdup(cfgfile);
195*e37190e5Smichen 		if (cfgfile_save == NULL)
196cb5caa98Sdjl 			return (NSCD_NO_MEMORY);
197cb5caa98Sdjl 	}
198cb5caa98Sdjl 
199cb5caa98Sdjl 	return (NSCD_SUCCESS);
200cb5caa98Sdjl }
201cb5caa98Sdjl 
202cb5caa98Sdjl nscd_rc_t
203cb5caa98Sdjl _nscd_refresh()
204cb5caa98Sdjl {
205cb5caa98Sdjl 	char			*me = "nscd_refresh";
206cb5caa98Sdjl 	char			*cfgfile;
207cb5caa98Sdjl 	nscd_rc_t		rc;
208cb5caa98Sdjl 	nscd_cfg_error_t	*err;
209cb5caa98Sdjl 	char			errmsg[1024];
210cb5caa98Sdjl 
211cb5caa98Sdjl 	/*
212cb5caa98Sdjl 	 * re-read the nsswitch configuration
213cb5caa98Sdjl 	 */
214cb5caa98Sdjl 	rc = _nscd_cfg_read_nsswitch_file("/etc/nsswitch.conf", &err);
215cb5caa98Sdjl 	if (rc != NSCD_SUCCESS) {
216cb5caa98Sdjl 		(void) snprintf(errmsg, sizeof (errmsg),
217cb5caa98Sdjl 		"unable to parse the config file %s (rc = %d), %s\n",
218cb5caa98Sdjl 		"/etc/nsswitch.conf", rc, NSCD_ERR2MSG(err));
219cb5caa98Sdjl 		goto error_exit;
220cb5caa98Sdjl 	}
221cb5caa98Sdjl 
222cb5caa98Sdjl 	/*
223cb5caa98Sdjl 	 * re-read the nscd configuration
224cb5caa98Sdjl 	 */
225cb5caa98Sdjl 	if (cfgfile_save == NULL)
226cb5caa98Sdjl 		cfgfile = "/etc/nscd.conf";
227cb5caa98Sdjl 	else
228cb5caa98Sdjl 		cfgfile = cfgfile_save;
229cb5caa98Sdjl 
230cb5caa98Sdjl 	if (access(cfgfile, R_OK) != 0) {
231cb5caa98Sdjl 		(void) snprintf(errmsg, sizeof (errmsg),
232cb5caa98Sdjl 		"unable to read the config file %s (rc = %d), %s\n",
233cb5caa98Sdjl 			cfgfile, NSCD_CFG_FILE_ACCESS_ERROR,
234cb5caa98Sdjl 			strerror(errno));
235cb5caa98Sdjl 
236cb5caa98Sdjl 		goto error_exit;
237cb5caa98Sdjl 	}
238cb5caa98Sdjl 
239cb5caa98Sdjl 	rc = _nscd_cfg_read_file(cfgfile, &err);
240cb5caa98Sdjl 	if (rc != NSCD_SUCCESS) {
241cb5caa98Sdjl 		(void) snprintf(errmsg, sizeof (errmsg),
242cb5caa98Sdjl 		"unable to parse the config file %s (rc = %d), %s\n",
243cb5caa98Sdjl 		cfgfile, rc, NSCD_ERR2MSG(err));
244cb5caa98Sdjl 
245cb5caa98Sdjl 		goto error_exit;
246cb5caa98Sdjl 	}
247cb5caa98Sdjl 
248cb5caa98Sdjl 	_NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ALL)
249cb5caa98Sdjl 	(me, "nsswitch/nscd configuration refreshed successfully\n");
250cb5caa98Sdjl 
251cb5caa98Sdjl 	return (NSCD_SUCCESS);
252cb5caa98Sdjl 
253cb5caa98Sdjl 	error_exit:
254cb5caa98Sdjl 
255cb5caa98Sdjl 	if (err != NULL)
256cb5caa98Sdjl 		_nscd_cfg_free_error(err);
257cb5caa98Sdjl 
258cb5caa98Sdjl 	_NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR)
259cb5caa98Sdjl 	(me, "%s\n", errmsg);
260cb5caa98Sdjl 
261cb5caa98Sdjl 	return (rc);
262cb5caa98Sdjl }
263