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