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 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 50 _nscd_get_start_time() 51 { 52 return (start_time); 53 } 54 55 nscd_rc_t 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 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