cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * CDDL HEADER START
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * The contents of this file are subject to the terms of the
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Common Development and Distribution License (the "License").
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * You may not use this file except in compliance with the License.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * or http://www.opensolaris.org/os/licensing.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * See the License for the specific language governing permissions
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * and limitations under the License.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * When distributing Covered Code, include this CDDL HEADER in each
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * If applicable, add the following below this CDDL HEADER, with the
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * fields enclosed by brackets "[]" replaced with your own identifying
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * information: Portions Copyright [yyyy] [name of copyright owner]
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * CDDL HEADER END
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cfed26cb92bcaf129a6022a551f26391e5841135Michen Chang * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Use is subject to license terms.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <locale.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <unistd.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <string.h>
e37190e5b4531a897e4191a30b8f41678b582e25michen#include <time.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include "nscd_common.h"
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include "nscd_config.h"
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include "nscd_log.h"
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include "nscd_switch.h"
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include "nscd_frontend.h"
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic char *cfgfile_save = NULL;
e37190e5b4531a897e4191a30b8f41678b582e25michenstatic mutex_t time_mutex = DEFAULTMUTEX;
e37190e5b4531a897e4191a30b8f41678b582e25michenstatic time_t start_time = 0;
e37190e5b4531a897e4191a30b8f41678b582e25michen
e37190e5b4531a897e4191a30b8f41678b582e25michenvoid
e37190e5b4531a897e4191a30b8f41678b582e25michen_nscd_set_start_time(int reset)
e37190e5b4531a897e4191a30b8f41678b582e25michen{
e37190e5b4531a897e4191a30b8f41678b582e25michen (void) mutex_lock(&time_mutex);
e37190e5b4531a897e4191a30b8f41678b582e25michen if (start_time == 0 || reset == 1)
e37190e5b4531a897e4191a30b8f41678b582e25michen start_time = time(NULL);
e37190e5b4531a897e4191a30b8f41678b582e25michen (void) mutex_unlock(&time_mutex);
e37190e5b4531a897e4191a30b8f41678b582e25michen}
e37190e5b4531a897e4191a30b8f41678b582e25michen
e37190e5b4531a897e4191a30b8f41678b582e25michentime_t
e37190e5b4531a897e4191a30b8f41678b582e25michen_nscd_get_start_time()
e37190e5b4531a897e4191a30b8f41678b582e25michen{
e37190e5b4531a897e4191a30b8f41678b582e25michen return (start_time);
e37190e5b4531a897e4191a30b8f41678b582e25michen}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlnscd_rc_t
cb5caa98562cf06753163f558cbcfe30b8f4673adjl_nscd_init(
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *cfgfile)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *me = "nscd_init";
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_rc_t rc;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_cfg_error_t *err;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
e37190e5b4531a897e4191a30b8f41678b582e25michen /*
e37190e5b4531a897e4191a30b8f41678b582e25michen * remember when main or forker nscd starts.
e37190e5b4531a897e4191a30b8f41678b582e25michen */
e37190e5b4531a897e4191a30b8f41678b582e25michen _nscd_set_start_time(0);
e37190e5b4531a897e4191a30b8f41678b582e25michen
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * allocate the space for tables
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
e37190e5b4531a897e4191a30b8f41678b582e25michen if ((rc = _nscd_alloc_nsw_config()) != NSCD_SUCCESS ||
e37190e5b4531a897e4191a30b8f41678b582e25michen (rc = _nscd_alloc_service_state_table()) != NSCD_SUCCESS ||
e37190e5b4531a897e4191a30b8f41678b582e25michen (rc = _nscd_alloc_nsw_state_base()) != NSCD_SUCCESS ||
e37190e5b4531a897e4191a30b8f41678b582e25michen (rc = _nscd_alloc_nsw_be_info_db()) != NSCD_SUCCESS ||
e37190e5b4531a897e4191a30b8f41678b582e25michen (rc = _nscd_alloc_getent_ctx_base()) != NSCD_SUCCESS)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (rc);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * allocate the space for local configuration
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * and statistics
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
e37190e5b4531a897e4191a30b8f41678b582e25michen if ((rc = _nscd_alloc_switch_cfg()) != NSCD_SUCCESS ||
e37190e5b4531a897e4191a30b8f41678b582e25michen (rc = _nscd_alloc_frontend_cfg()) != NSCD_SUCCESS ||
e37190e5b4531a897e4191a30b8f41678b582e25michen (rc = _nscd_alloc_switch_stats()) != NSCD_SUCCESS)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (rc);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Create and init the internal address database to keep
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * track of the memory allocated by _nscd_alloc
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (_nscd_create_int_addrDB() == NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_INT_ADDR, NSCD_LOG_LEVEL_ERROR)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "_nscd_create_int_addrDB failed\n");
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSCD_NO_MEMORY);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Create and init the internal context database to keep
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * track of the getent context currently being used
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (_nscd_create_getent_ctxDB() == NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_GETENT_CTX, NSCD_LOG_LEVEL_ERROR)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "_nscd_create_getent_ctx_addrDB failed\n");
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSCD_NO_MEMORY);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Create the backend info database for each possible source
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if ((rc = _nscd_init_all_nsw_be_info_db()) != NSCD_SUCCESS) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_ERROR)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "_nscd_init_all_nsw_be_info_db failed (rc = %d)\n",
80b80bf0416a7eb4be4215b2e192cafd03ca80b7michen rc);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (rc);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Create the nscd_nsw_config_t for each possible nss database
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if ((rc = _nscd_init_all_nsw_config()) != NSCD_SUCCESS) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_ERROR)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "_nscd_init_all_nsw_config failed (rc = %d)\n", rc);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (rc);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * initialize config/stats management
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl rc = _nscd_cfg_init(&err);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (rc != NSCD_SUCCESS) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (err != NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _nscd_cfg_free_error(err);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (rc);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * read in the nsswitch configuration
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl rc = _nscd_cfg_read_nsswitch_file("/etc/nsswitch.conf", &err);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (rc != NSCD_SUCCESS) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) printf(
cb5caa98562cf06753163f558cbcfe30b8f4673adjl gettext("reading config file %s failed with rc = %d, %s\n"),
80b80bf0416a7eb4be4215b2e192cafd03ca80b7michen "/etc/nsswitch.conf", rc, NSCD_ERR2MSG(err));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (err != NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _nscd_cfg_free_error(err);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "unable to read /etc/nsswitch.conf (rc = %d)\n", rc);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (rc);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
80b80bf0416a7eb4be4215b2e192cafd03ca80b7michen /*
80b80bf0416a7eb4be4215b2e192cafd03ca80b7michen * remember which version of /etc/nsswitch.conf that was read
80b80bf0416a7eb4be4215b2e192cafd03ca80b7michen */
80b80bf0416a7eb4be4215b2e192cafd03ca80b7michen _nscd_restart_if_cfgfile_changed();
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * read in the nscd configuration
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (cfgfile == NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl cfgfile = "/etc/nscd.conf";
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (access(cfgfile, R_OK) != 0) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "unable to read /etc/nscd.conf (rc = %d)\n", rc);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSCD_CFG_FILE_ACCESS_ERROR);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl rc = _nscd_cfg_read_file(cfgfile, &err);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (rc != NSCD_SUCCESS) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) printf(
cb5caa98562cf06753163f558cbcfe30b8f4673adjl gettext("reading config file %s failed with rc = %d, %s\n"),
80b80bf0416a7eb4be4215b2e192cafd03ca80b7michen cfgfile, rc, NSCD_ERR2MSG(err));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (err != NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _nscd_cfg_free_error(err);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR)
80b80bf0416a7eb4be4215b2e192cafd03ca80b7michen (me, "unable to read configuration from %s (rc = %d)\n",
80b80bf0416a7eb4be4215b2e192cafd03ca80b7michen cfgfile, rc);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (rc);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * remember the name of the config file
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * in case refresh is requested later
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (cfgfile != NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl cfgfile_save = strdup(cfgfile);
e37190e5b4531a897e4191a30b8f41678b582e25michen if (cfgfile_save == NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSCD_NO_MEMORY);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSCD_SUCCESS);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlnscd_rc_t
cb5caa98562cf06753163f558cbcfe30b8f4673adjl_nscd_refresh()
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *me = "nscd_refresh";
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *cfgfile;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_rc_t rc;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_cfg_error_t *err;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char errmsg[1024];
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * re-read the nscd configuration
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (cfgfile_save == NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl cfgfile = "/etc/nscd.conf";
cb5caa98562cf06753163f558cbcfe30b8f4673adjl else
cb5caa98562cf06753163f558cbcfe30b8f4673adjl cfgfile = cfgfile_save;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (access(cfgfile, R_OK) != 0) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) snprintf(errmsg, sizeof (errmsg),
cb5caa98562cf06753163f558cbcfe30b8f4673adjl "unable to read the config file %s (rc = %d), %s\n",
80b80bf0416a7eb4be4215b2e192cafd03ca80b7michen cfgfile, NSCD_CFG_FILE_ACCESS_ERROR,
80b80bf0416a7eb4be4215b2e192cafd03ca80b7michen strerror(errno));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl goto error_exit;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl rc = _nscd_cfg_read_file(cfgfile, &err);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (rc != NSCD_SUCCESS) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) snprintf(errmsg, sizeof (errmsg),
80b80bf0416a7eb4be4215b2e192cafd03ca80b7michen "unable to parse the config file %s (rc = %d), %s\n",
80b80bf0416a7eb4be4215b2e192cafd03ca80b7michen cfgfile, rc, NSCD_ERR2MSG(err));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl goto error_exit;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ALL)
cfed26cb92bcaf129a6022a551f26391e5841135Michen Chang (me, "nscd configuration refreshed successfully\n");
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSCD_SUCCESS);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl error_exit:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (err != NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _nscd_cfg_free_error(err);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_ERROR)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "%s\n", errmsg);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (rc);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}