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 2007 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 * initialize config/stats management 130 */ 131 rc = _nscd_cfg_init(&err); 132 if (rc != NSCD_SUCCESS) { 133 if (err != NULL) 134 _nscd_cfg_free_error(err); 135 return (rc); 136 } 137 138 /* 139 * read in the nsswitch configuration 140 */ 141 rc = _nscd_cfg_read_nsswitch_file("/etc/nsswitch.conf", &err); 142 if (rc != NSCD_SUCCESS) { 143 (void) printf( 144 gettext("reading config file %s failed with rc = %d, %s\n"), 145 "/etc/nsswitch.conf", rc, NSCD_ERR2MSG(err)); 146 if (err != NULL) 147 _nscd_cfg_free_error(err); 148 149 _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR) 150 (me, "unable to read /etc/nsswitch.conf (rc = %d)\n", rc); 151 return (rc); 152 } 153 /* 154 * remember which version of /etc/nsswitch.conf that was read 155 */ 156 _nscd_restart_if_cfgfile_changed(); 157 158 /* 159 * read in the nscd configuration 160 */ 161 if (cfgfile == NULL) { 162 cfgfile = "/etc/nscd.conf"; 163 if (access(cfgfile, R_OK) != 0) { 164 _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR) 165 (me, "unable to read /etc/nscd.conf (rc = %d)\n", rc); 166 167 return (NSCD_CFG_FILE_ACCESS_ERROR); 168 } 169 } 170 rc = _nscd_cfg_read_file(cfgfile, &err); 171 if (rc != NSCD_SUCCESS) { 172 (void) printf( 173 gettext("reading config file %s failed with rc = %d, %s\n"), 174 cfgfile, rc, NSCD_ERR2MSG(err)); 175 if (err != NULL) 176 _nscd_cfg_free_error(err); 177 178 _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR) 179 (me, "unable to read configuration from %s (rc = %d)\n", 180 cfgfile, rc); 181 182 return (rc); 183 } 184 /* 185 * remember the name of the config file 186 * in case refresh is requested later 187 */ 188 if (cfgfile != NULL) { 189 cfgfile_save = strdup(cfgfile); 190 if (cfgfile_save == NULL) 191 return (NSCD_NO_MEMORY); 192 } 193 194 return (NSCD_SUCCESS); 195 } 196 197 nscd_rc_t 198 _nscd_refresh() 199 { 200 char *me = "nscd_refresh"; 201 char *cfgfile; 202 nscd_rc_t rc; 203 nscd_cfg_error_t *err; 204 char errmsg[1024]; 205 206 /* 207 * re-read the nsswitch configuration 208 */ 209 rc = _nscd_cfg_read_nsswitch_file("/etc/nsswitch.conf", &err); 210 if (rc != NSCD_SUCCESS) { 211 (void) snprintf(errmsg, sizeof (errmsg), 212 "unable to parse the config file %s (rc = %d), %s\n", 213 "/etc/nsswitch.conf", rc, NSCD_ERR2MSG(err)); 214 goto error_exit; 215 } 216 217 /* 218 * re-read the nscd configuration 219 */ 220 if (cfgfile_save == NULL) 221 cfgfile = "/etc/nscd.conf"; 222 else 223 cfgfile = cfgfile_save; 224 225 if (access(cfgfile, R_OK) != 0) { 226 (void) snprintf(errmsg, sizeof (errmsg), 227 "unable to read the config file %s (rc = %d), %s\n", 228 cfgfile, NSCD_CFG_FILE_ACCESS_ERROR, 229 strerror(errno)); 230 231 goto error_exit; 232 } 233 234 rc = _nscd_cfg_read_file(cfgfile, &err); 235 if (rc != NSCD_SUCCESS) { 236 (void) snprintf(errmsg, sizeof (errmsg), 237 "unable to parse the config file %s (rc = %d), %s\n", 238 cfgfile, rc, NSCD_ERR2MSG(err)); 239 240 goto error_exit; 241 } 242 243 _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ALL) 244 (me, "nsswitch/nscd configuration refreshed successfully\n"); 245 246 return (NSCD_SUCCESS); 247 248 error_exit: 249 250 if (err != NULL) 251 _nscd_cfg_free_error(err); 252 253 _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 254 (me, "%s\n", errmsg); 255 256 return (rc); 257 } 258