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
_nscd_set_start_time(int reset)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
_nscd_get_start_time()50 _nscd_get_start_time()
51 {
52 return (start_time);
53 }
54
55 nscd_rc_t
_nscd_init(char * cfgfile)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
_nscd_refresh()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