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