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