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