1cb5caa98Sdjl /* 2cb5caa98Sdjl * CDDL HEADER START 3cb5caa98Sdjl * 4cb5caa98Sdjl * The contents of this file are subject to the terms of the 5cb5caa98Sdjl * Common Development and Distribution License (the "License"). 6cb5caa98Sdjl * You may not use this file except in compliance with the License. 7cb5caa98Sdjl * 8cb5caa98Sdjl * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9cb5caa98Sdjl * or http://www.opensolaris.org/os/licensing. 10cb5caa98Sdjl * See the License for the specific language governing permissions 11cb5caa98Sdjl * and limitations under the License. 12cb5caa98Sdjl * 13cb5caa98Sdjl * When distributing Covered Code, include this CDDL HEADER in each 14cb5caa98Sdjl * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15cb5caa98Sdjl * If applicable, add the following below this CDDL HEADER, with the 16cb5caa98Sdjl * fields enclosed by brackets "[]" replaced with your own identifying 17cb5caa98Sdjl * information: Portions Copyright [yyyy] [name of copyright owner] 18cb5caa98Sdjl * 19cb5caa98Sdjl * CDDL HEADER END 20cb5caa98Sdjl */ 21cb5caa98Sdjl /* 22cb5caa98Sdjl * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23cb5caa98Sdjl * Use is subject to license terms. 24cb5caa98Sdjl */ 25cb5caa98Sdjl 26cb5caa98Sdjl #pragma ident "%Z%%M% %I% %E% SMI" 27cb5caa98Sdjl 28cb5caa98Sdjl #include <locale.h> 29cb5caa98Sdjl #include <unistd.h> 30cb5caa98Sdjl #include <string.h> 31*e37190e5Smichen #include <time.h> 32cb5caa98Sdjl #include "nscd_common.h" 33cb5caa98Sdjl #include "nscd_config.h" 34cb5caa98Sdjl #include "nscd_log.h" 35cb5caa98Sdjl #include "nscd_switch.h" 36cb5caa98Sdjl #include "nscd_frontend.h" 37cb5caa98Sdjl 38cb5caa98Sdjl static char *cfgfile_save = NULL; 39*e37190e5Smichen static mutex_t time_mutex = DEFAULTMUTEX; 40*e37190e5Smichen static time_t start_time = 0; 41*e37190e5Smichen 42*e37190e5Smichen void 43*e37190e5Smichen _nscd_set_start_time(int reset) 44*e37190e5Smichen { 45*e37190e5Smichen (void) mutex_lock(&time_mutex); 46*e37190e5Smichen if (start_time == 0 || reset == 1) 47*e37190e5Smichen start_time = time(NULL); 48*e37190e5Smichen (void) mutex_unlock(&time_mutex); 49*e37190e5Smichen } 50*e37190e5Smichen 51*e37190e5Smichen time_t 52*e37190e5Smichen _nscd_get_start_time() 53*e37190e5Smichen { 54*e37190e5Smichen return (start_time); 55*e37190e5Smichen } 56cb5caa98Sdjl 57cb5caa98Sdjl nscd_rc_t 58cb5caa98Sdjl _nscd_init( 59cb5caa98Sdjl char *cfgfile) 60cb5caa98Sdjl { 61cb5caa98Sdjl char *me = "nscd_init"; 62cb5caa98Sdjl nscd_rc_t rc; 63cb5caa98Sdjl nscd_cfg_error_t *err; 64cb5caa98Sdjl 65cb5caa98Sdjl /* 66*e37190e5Smichen * remember when main or forker nscd starts. 67*e37190e5Smichen */ 68*e37190e5Smichen _nscd_set_start_time(0); 69*e37190e5Smichen 70*e37190e5Smichen /* 71cb5caa98Sdjl * allocate the space for tables 72cb5caa98Sdjl */ 73*e37190e5Smichen if ((rc = _nscd_alloc_nsw_config()) != NSCD_SUCCESS || 74*e37190e5Smichen (rc = _nscd_alloc_service_state_table()) != NSCD_SUCCESS || 75*e37190e5Smichen (rc = _nscd_alloc_nsw_state_base()) != NSCD_SUCCESS || 76*e37190e5Smichen (rc = _nscd_alloc_nsw_be_info_db()) != NSCD_SUCCESS || 77*e37190e5Smichen (rc = _nscd_alloc_getent_ctx_base()) != NSCD_SUCCESS) 78cb5caa98Sdjl return (rc); 79cb5caa98Sdjl 80cb5caa98Sdjl /* 81cb5caa98Sdjl * allocate the space for local configuration 82cb5caa98Sdjl * and statistics 83cb5caa98Sdjl */ 84*e37190e5Smichen if ((rc = _nscd_alloc_switch_cfg()) != NSCD_SUCCESS || 85*e37190e5Smichen (rc = _nscd_alloc_frontend_cfg()) != NSCD_SUCCESS || 86*e37190e5Smichen (rc = _nscd_alloc_switch_stats()) != NSCD_SUCCESS) 87cb5caa98Sdjl return (rc); 88cb5caa98Sdjl 89cb5caa98Sdjl /* 90cb5caa98Sdjl * Create and init the internal address database to keep 91cb5caa98Sdjl * track of the memory allocated by _nscd_alloc 92cb5caa98Sdjl */ 93cb5caa98Sdjl if (_nscd_create_int_addrDB() == NULL) { 94cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_INT_ADDR, NSCD_LOG_LEVEL_ERROR) 95cb5caa98Sdjl (me, "_nscd_create_int_addrDB failed\n"); 96cb5caa98Sdjl return (NSCD_NO_MEMORY); 97cb5caa98Sdjl } 98cb5caa98Sdjl 99cb5caa98Sdjl /* 100cb5caa98Sdjl * Create and init the internal context database to keep 101cb5caa98Sdjl * track of the getent context currently being used 102cb5caa98Sdjl */ 103cb5caa98Sdjl if (_nscd_create_getent_ctxDB() == NULL) { 104cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_GETENT_CTX, NSCD_LOG_LEVEL_ERROR) 105cb5caa98Sdjl (me, "_nscd_create_getent_ctx_addrDB failed\n"); 106cb5caa98Sdjl return (NSCD_NO_MEMORY); 107cb5caa98Sdjl } 108cb5caa98Sdjl 109cb5caa98Sdjl /* 110cb5caa98Sdjl * Create the backend info database for each possible source 111cb5caa98Sdjl */ 112cb5caa98Sdjl if ((rc = _nscd_init_all_nsw_be_info_db()) != NSCD_SUCCESS) { 113cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_ERROR) 114cb5caa98Sdjl (me, "_nscd_init_all_nsw_be_info_db failed (rc = %d)\n", 115cb5caa98Sdjl rc); 116cb5caa98Sdjl return (rc); 117cb5caa98Sdjl } 118cb5caa98Sdjl 119cb5caa98Sdjl /* 120cb5caa98Sdjl * Create the nscd_nsw_config_t for each possible nss database 121cb5caa98Sdjl */ 122cb5caa98Sdjl if ((rc = _nscd_init_all_nsw_config()) != NSCD_SUCCESS) { 123cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_ERROR) 124cb5caa98Sdjl (me, "_nscd_init_all_nsw_config failed (rc = %d)\n", rc); 125cb5caa98Sdjl return (rc); 126cb5caa98Sdjl } 127cb5caa98Sdjl 128cb5caa98Sdjl /* 129cb5caa98Sdjl * populate the backend info databases 130cb5caa98Sdjl */ 131cb5caa98Sdjl if ((rc = _nscd_populate_nsw_backend_info()) != NSCD_SUCCESS) { 132cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_ERROR) 133cb5caa98Sdjl (me, "_nscd_init_all_nsw_be_info_db failed (rc = %d)\n", rc); 134cb5caa98Sdjl return (rc); 135cb5caa98Sdjl } 136cb5caa98Sdjl 137cb5caa98Sdjl /* 138cb5caa98Sdjl * initialize config/stats management 139cb5caa98Sdjl */ 140cb5caa98Sdjl rc = _nscd_cfg_init(&err); 141cb5caa98Sdjl if (rc != NSCD_SUCCESS) { 142cb5caa98Sdjl if (err != NULL) 143cb5caa98Sdjl _nscd_cfg_free_error(err); 144cb5caa98Sdjl return (rc); 145cb5caa98Sdjl } 146cb5caa98Sdjl 147cb5caa98Sdjl /* 148cb5caa98Sdjl * read in the nsswitch configuration 149cb5caa98Sdjl */ 150cb5caa98Sdjl rc = _nscd_cfg_read_nsswitch_file("/etc/nsswitch.conf", &err); 151cb5caa98Sdjl if (rc != NSCD_SUCCESS) { 152cb5caa98Sdjl (void) printf( 153cb5caa98Sdjl gettext("reading config file %s failed with rc = %d, %s\n"), 154cb5caa98Sdjl "/etc/nsswitch.conf", rc, NSCD_ERR2MSG(err)); 155cb5caa98Sdjl if (err != NULL) 156cb5caa98Sdjl _nscd_cfg_free_error(err); 157cb5caa98Sdjl 158cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR) 159cb5caa98Sdjl (me, "unable to read /etc/nsswitch.conf (rc = %d)\n", rc); 160cb5caa98Sdjl return (rc); 161cb5caa98Sdjl } 162cb5caa98Sdjl 163cb5caa98Sdjl /* 164cb5caa98Sdjl * read in the nscd configuration 165cb5caa98Sdjl */ 166cb5caa98Sdjl if (cfgfile == NULL) { 167cb5caa98Sdjl cfgfile = "/etc/nscd.conf"; 168cb5caa98Sdjl if (access(cfgfile, R_OK) != 0) { 169cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR) 170cb5caa98Sdjl (me, "unable to read /etc/nscd.conf (rc = %d)\n", rc); 171cb5caa98Sdjl 172cb5caa98Sdjl return (NSCD_CFG_FILE_ACCESS_ERROR); 173cb5caa98Sdjl } 174cb5caa98Sdjl } 175cb5caa98Sdjl rc = _nscd_cfg_read_file(cfgfile, &err); 176cb5caa98Sdjl if (rc != NSCD_SUCCESS) { 177cb5caa98Sdjl (void) printf( 178cb5caa98Sdjl gettext("reading config file %s failed with rc = %d, %s\n"), 179cb5caa98Sdjl cfgfile, rc, NSCD_ERR2MSG(err)); 180cb5caa98Sdjl if (err != NULL) 181cb5caa98Sdjl _nscd_cfg_free_error(err); 182cb5caa98Sdjl 183cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR) 184cb5caa98Sdjl (me, "unable to read configuration from %s (rc = %d)\n", 185cb5caa98Sdjl cfgfile, rc); 186cb5caa98Sdjl 187cb5caa98Sdjl return (rc); 188cb5caa98Sdjl } 189cb5caa98Sdjl /* 190cb5caa98Sdjl * remember the name of the config file 191cb5caa98Sdjl * in case refresh is requested later 192cb5caa98Sdjl */ 193cb5caa98Sdjl if (cfgfile != NULL) { 194cb5caa98Sdjl cfgfile_save = strdup(cfgfile); 195*e37190e5Smichen if (cfgfile_save == NULL) 196cb5caa98Sdjl return (NSCD_NO_MEMORY); 197cb5caa98Sdjl } 198cb5caa98Sdjl 199cb5caa98Sdjl return (NSCD_SUCCESS); 200cb5caa98Sdjl } 201cb5caa98Sdjl 202cb5caa98Sdjl nscd_rc_t 203cb5caa98Sdjl _nscd_refresh() 204cb5caa98Sdjl { 205cb5caa98Sdjl char *me = "nscd_refresh"; 206cb5caa98Sdjl char *cfgfile; 207cb5caa98Sdjl nscd_rc_t rc; 208cb5caa98Sdjl nscd_cfg_error_t *err; 209cb5caa98Sdjl char errmsg[1024]; 210cb5caa98Sdjl 211cb5caa98Sdjl /* 212cb5caa98Sdjl * re-read the nsswitch configuration 213cb5caa98Sdjl */ 214cb5caa98Sdjl rc = _nscd_cfg_read_nsswitch_file("/etc/nsswitch.conf", &err); 215cb5caa98Sdjl if (rc != NSCD_SUCCESS) { 216cb5caa98Sdjl (void) snprintf(errmsg, sizeof (errmsg), 217cb5caa98Sdjl "unable to parse the config file %s (rc = %d), %s\n", 218cb5caa98Sdjl "/etc/nsswitch.conf", rc, NSCD_ERR2MSG(err)); 219cb5caa98Sdjl goto error_exit; 220cb5caa98Sdjl } 221cb5caa98Sdjl 222cb5caa98Sdjl /* 223cb5caa98Sdjl * re-read the nscd configuration 224cb5caa98Sdjl */ 225cb5caa98Sdjl if (cfgfile_save == NULL) 226cb5caa98Sdjl cfgfile = "/etc/nscd.conf"; 227cb5caa98Sdjl else 228cb5caa98Sdjl cfgfile = cfgfile_save; 229cb5caa98Sdjl 230cb5caa98Sdjl if (access(cfgfile, R_OK) != 0) { 231cb5caa98Sdjl (void) snprintf(errmsg, sizeof (errmsg), 232cb5caa98Sdjl "unable to read the config file %s (rc = %d), %s\n", 233cb5caa98Sdjl cfgfile, NSCD_CFG_FILE_ACCESS_ERROR, 234cb5caa98Sdjl strerror(errno)); 235cb5caa98Sdjl 236cb5caa98Sdjl goto error_exit; 237cb5caa98Sdjl } 238cb5caa98Sdjl 239cb5caa98Sdjl rc = _nscd_cfg_read_file(cfgfile, &err); 240cb5caa98Sdjl if (rc != NSCD_SUCCESS) { 241cb5caa98Sdjl (void) snprintf(errmsg, sizeof (errmsg), 242cb5caa98Sdjl "unable to parse the config file %s (rc = %d), %s\n", 243cb5caa98Sdjl cfgfile, rc, NSCD_ERR2MSG(err)); 244cb5caa98Sdjl 245cb5caa98Sdjl goto error_exit; 246cb5caa98Sdjl } 247cb5caa98Sdjl 248cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ALL) 249cb5caa98Sdjl (me, "nsswitch/nscd configuration refreshed successfully\n"); 250cb5caa98Sdjl 251cb5caa98Sdjl return (NSCD_SUCCESS); 252cb5caa98Sdjl 253cb5caa98Sdjl error_exit: 254cb5caa98Sdjl 255cb5caa98Sdjl if (err != NULL) 256cb5caa98Sdjl _nscd_cfg_free_error(err); 257cb5caa98Sdjl 258cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR) 259cb5caa98Sdjl (me, "%s\n", errmsg); 260cb5caa98Sdjl 261cb5caa98Sdjl return (rc); 262cb5caa98Sdjl } 263