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/*
b57459abfba36eb3068cfe44c6921168b4c4f774Julian Pullen * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Use is subject to license terms.
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik * Copyright 2012 Milan Jurik. All rights reserved.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <stdlib.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <alloca.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <signal.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <sys/stat.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <unistd.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <pthread.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <time.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <errno.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <door.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <zone.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <resolv.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <sys/socket.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <net/route.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <string.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <net/if.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <sys/stat.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <fcntl.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include "nscd_common.h"
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include "nscd_door.h"
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include "nscd_config.h"
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include "nscd_switch.h"
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include "nscd_log.h"
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include "nscd_selfcred.h"
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include "nscd_frontend.h"
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include "nscd_admin.h"
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void rts_mon(void);
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void keep_open_dns_socket(void);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlextern nsc_ctx_t *cache_ctx_p[];
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Current active Configuration data for the frontend component
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic nscd_cfg_global_frontend_t frontend_cfg_g;
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic nscd_cfg_frontend_t *frontend_cfg;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic int max_servers = 0;
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic int max_servers_set = 0;
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic int per_user_is_on = 1;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic char *main_execname;
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic char **main_argv;
cb5caa98562cf06753163f558cbcfe30b8f4673adjlextern int _whoami;
cb5caa98562cf06753163f558cbcfe30b8f4673adjlextern long activity;
cb5caa98562cf06753163f558cbcfe30b8f4673adjlextern mutex_t activity_lock;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic sema_t common_sema;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic thread_key_t lookup_state_key;
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic mutex_t create_lock = DEFAULTMUTEX;
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic int num_servers = 0;
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic thread_key_t server_key;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Bind a TSD value to a server thread. This enables the destructor to
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * be called if/when this thread exits. This would be a programming
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * error, but better safe than sorry.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*ARGSUSED*/
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void *
cb5caa98562cf06753163f558cbcfe30b8f4673adjlserver_tsd_bind(void *arg)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl static void *value = 0;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* disable cancellation to avoid hangs if server threads disappear */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) thr_setspecific(server_key, value);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) door_return(NULL, 0, NULL, 0);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* make lint happy */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Server threads are created here.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*ARGSUSED*/
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void
cb5caa98562cf06753163f558cbcfe30b8f4673adjlserver_create(door_info_t *dip)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_lock(&create_lock);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (++num_servers > max_servers) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl num_servers--;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_unlock(&create_lock);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_unlock(&create_lock);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) thr_create(NULL, 0, server_tsd_bind, NULL,
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen THR_BOUND|THR_DETACHED, NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Server thread are destroyed here
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*ARGSUSED*/
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void
cb5caa98562cf06753163f558cbcfe30b8f4673adjlserver_destroy(void *arg)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_lock(&create_lock);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl num_servers--;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_unlock(&create_lock);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * get clearance
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlint
cb5caa98562cf06753163f558cbcfe30b8f4673adjl_nscd_get_clearance(sema_t *sema) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (sema_trywait(&common_sema) == 0) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) thr_setspecific(lookup_state_key, NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (0);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (sema_trywait(sema) == 0) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) thr_setspecific(lookup_state_key, (void*)1);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (0);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (1);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * release clearance
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlint
cb5caa98562cf06753163f558cbcfe30b8f4673adjl_nscd_release_clearance(sema_t *sema) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int which;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) thr_getspecific(lookup_state_key, (void**)&which);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (which == 0) /* from common pool */ {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) sema_post(&common_sema);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (0);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) sema_post(sema);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (1);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void
cb5caa98562cf06753163f558cbcfe30b8f4673adjldozip(void)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* not much here */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm/*
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm * _nscd_restart_if_cfgfile_changed()
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm * Restart if modification times of nsswitch.conf or resolv.conf have changed.
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm *
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm * If nsswitch.conf has changed then it is possible that sources for
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm * various backends have changed and therefore the current cached
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm * data may not be consistent with the new data sources. By
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm * restarting the cache will be cleared and the new configuration will
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm * be used.
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm *
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm * The check for resolv.conf is made as only the first call to
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm * res_gethostbyname() or res_getaddrbyname() causes a call to
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm * res_ninit() to occur which in turn parses resolv.conf. Therefore
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm * to benefit from changes to resolv.conf nscd must be restarted when
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm * resolv.conf is updated, removed or created. If res_getXbyY calls
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm * are removed from NSS then this check could be removed.
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm *
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm */
80b80bf0416a7eb4be4215b2e192cafd03ca80b7michenvoid
80b80bf0416a7eb4be4215b2e192cafd03ca80b7michen_nscd_restart_if_cfgfile_changed()
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
80b80bf0416a7eb4be4215b2e192cafd03ca80b7michen static mutex_t nsswitch_lock = DEFAULTMUTEX;
80b80bf0416a7eb4be4215b2e192cafd03ca80b7michen static timestruc_t last_nsswitch_check = { 0 };
80b80bf0416a7eb4be4215b2e192cafd03ca80b7michen static timestruc_t last_nsswitch_modified = { 0 };
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm static timestruc_t last_resolv_modified = { -1, 0 };
86f95553514ce565ce5afbc1786980b5bbd4f96amichen static mutex_t restarting_lock = DEFAULTMUTEX;
86f95553514ce565ce5afbc1786980b5bbd4f96amichen static int restarting = 0;
86f95553514ce565ce5afbc1786980b5bbd4f96amichen int restart = 0;
80b80bf0416a7eb4be4215b2e192cafd03ca80b7michen time_t now = time(NULL);
80b80bf0416a7eb4be4215b2e192cafd03ca80b7michen char *me = "_nscd_restart_if_cfgfile_changed";
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm#define FLAG_RESTART_REQUIRED if (restarting == 0) {\
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm (void) mutex_lock(&restarting_lock);\
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm if (restarting == 0) {\
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm restarting = 1;\
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm restart = 1;\
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm }\
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm (void) mutex_unlock(&restarting_lock);\
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm }
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm
86f95553514ce565ce5afbc1786980b5bbd4f96amichen if (restarting == 1)
86f95553514ce565ce5afbc1786980b5bbd4f96amichen return;
86f95553514ce565ce5afbc1786980b5bbd4f96amichen
80b80bf0416a7eb4be4215b2e192cafd03ca80b7michen if (now - last_nsswitch_check.tv_sec < _NSC_FILE_CHECK_TIME)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_lock(&nsswitch_lock);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
80b80bf0416a7eb4be4215b2e192cafd03ca80b7michen if (now - last_nsswitch_check.tv_sec >= _NSC_FILE_CHECK_TIME) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl struct stat nss_buf;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl struct stat res_buf;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
80b80bf0416a7eb4be4215b2e192cafd03ca80b7michen last_nsswitch_check.tv_sec = now;
80b80bf0416a7eb4be4215b2e192cafd03ca80b7michen last_nsswitch_check.tv_nsec = 0;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_unlock(&nsswitch_lock); /* let others continue */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (stat("/etc/nsswitch.conf", &nss_buf) < 0) {
80b80bf0416a7eb4be4215b2e192cafd03ca80b7michen return;
80b80bf0416a7eb4be4215b2e192cafd03ca80b7michen } else if (last_nsswitch_modified.tv_sec == 0) {
80b80bf0416a7eb4be4215b2e192cafd03ca80b7michen last_nsswitch_modified = nss_buf.st_mtim;
80b80bf0416a7eb4be4215b2e192cafd03ca80b7michen }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
80b80bf0416a7eb4be4215b2e192cafd03ca80b7michen if (last_nsswitch_modified.tv_sec < nss_buf.st_mtim.tv_sec ||
80b80bf0416a7eb4be4215b2e192cafd03ca80b7michen (last_nsswitch_modified.tv_sec == nss_buf.st_mtim.tv_sec &&
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm last_nsswitch_modified.tv_nsec < nss_buf.st_mtim.tv_nsec)) {
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm FLAG_RESTART_REQUIRED;
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm }
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm if (restart == 0) {
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm if (stat("/etc/resolv.conf", &res_buf) < 0) {
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm /* Unable to stat file, were we previously? */
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm if (last_resolv_modified.tv_sec > 0) {
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm /* Yes, it must have been removed. */
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm FLAG_RESTART_REQUIRED;
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm } else if (last_resolv_modified.tv_sec == -1) {
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm /* No, then we've never seen it. */
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm last_resolv_modified.tv_sec = 0;
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm }
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm } else if (last_resolv_modified.tv_sec == -1) {
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm /* We've just started and file is present. */
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm last_resolv_modified = res_buf.st_mtim;
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm } else if (last_resolv_modified.tv_sec == 0) {
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm /* Wasn't there at start-up. */
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm FLAG_RESTART_REQUIRED;
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm } else if (last_resolv_modified.tv_sec <
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm res_buf.st_mtim.tv_sec ||
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm (last_resolv_modified.tv_sec ==
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm res_buf.st_mtim.tv_sec &&
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm last_resolv_modified.tv_nsec <
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm res_buf.st_mtim.tv_nsec)) {
940a40ea49c831201b0a8119547eb48e9a0ed2f8sm FLAG_RESTART_REQUIRED;
86f95553514ce565ce5afbc1786980b5bbd4f96amichen }
86f95553514ce565ce5afbc1786980b5bbd4f96amichen }
86f95553514ce565ce5afbc1786980b5bbd4f96amichen
86f95553514ce565ce5afbc1786980b5bbd4f96amichen if (restart == 1) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *fmri;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * if in self cred mode, kill the forker and
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * child nscds
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (_nscd_is_self_cred_on(0, NULL)) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _nscd_kill_forker();
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _nscd_kill_all_children();
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * time for restart
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_INFO)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "nscd restart due to %s or %s change\n",
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen "/etc/nsswitch.conf", "resolv.conf");
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * try to restart under smf
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if ((fmri = getenv("SMF_FMRI")) == NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* not running under smf - reexec */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) execv(main_execname, main_argv);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl exit(1); /* just in case */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (smf_restart_instance(fmri) == 0)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) sleep(10); /* wait a bit */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl exit(1); /* give up waiting for resurrection */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl } else
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen (void) mutex_unlock(&nsswitch_lock);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjluid_t
cb5caa98562cf06753163f558cbcfe30b8f4673adjl_nscd_get_client_euid()
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ucred_t *uc = NULL;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl uid_t id;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *me = "get_client_euid";
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (door_ucred(&uc) != 0) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_DEBUG)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "door_ucred: %s\n", strerror(errno));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return ((uid_t)-1);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl id = ucred_geteuid(uc);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ucred_free(uc);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (id);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen/*
b57459abfba36eb3068cfe44c6921168b4c4f774Julian Pullen * Check to see if the door client's euid is 0 or if it has required_priv
6392794b28bef963aa5ad05c3da79435fd0a5a0bMichen Chang * privilege. Return 0 if yes, -1 otherwise.
b57459abfba36eb3068cfe44c6921168b4c4f774Julian Pullen * Supported values for required_priv are:
b57459abfba36eb3068cfe44c6921168b4c4f774Julian Pullen * - NSCD_ALL_PRIV: for all zones privileges
b57459abfba36eb3068cfe44c6921168b4c4f774Julian Pullen * - NSCD_READ_PRIV: for PRIV_FILE_DAC_READ privilege
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen */
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michenint
b57459abfba36eb3068cfe44c6921168b4c4f774Julian Pullen_nscd_check_client_priv(int required_priv)
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen{
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen int rc = 0;
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen ucred_t *uc = NULL;
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen const priv_set_t *eset;
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen char *me = "_nscd_check_client_read_priv";
b57459abfba36eb3068cfe44c6921168b4c4f774Julian Pullen priv_set_t *zs; /* zone */
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen if (door_ucred(&uc) != 0) {
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR)
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen (me, "door_ucred: %s\n", strerror(errno));
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen return (-1);
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen }
6392794b28bef963aa5ad05c3da79435fd0a5a0bMichen Chang
6392794b28bef963aa5ad05c3da79435fd0a5a0bMichen Chang if (ucred_geteuid(uc) == 0) {
6392794b28bef963aa5ad05c3da79435fd0a5a0bMichen Chang ucred_free(uc);
6392794b28bef963aa5ad05c3da79435fd0a5a0bMichen Chang return (0);
6392794b28bef963aa5ad05c3da79435fd0a5a0bMichen Chang }
6392794b28bef963aa5ad05c3da79435fd0a5a0bMichen Chang
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen eset = ucred_getprivset(uc, PRIV_EFFECTIVE);
b57459abfba36eb3068cfe44c6921168b4c4f774Julian Pullen switch (required_priv) {
b57459abfba36eb3068cfe44c6921168b4c4f774Julian Pullen case NSCD_ALL_PRIV:
b57459abfba36eb3068cfe44c6921168b4c4f774Julian Pullen zs = priv_str_to_set("zone", ",", NULL);
b57459abfba36eb3068cfe44c6921168b4c4f774Julian Pullen if (!priv_isequalset(eset, zs)) {
b57459abfba36eb3068cfe44c6921168b4c4f774Julian Pullen _NSCD_LOG(NSCD_LOG_FRONT_END,
b57459abfba36eb3068cfe44c6921168b4c4f774Julian Pullen NSCD_LOG_LEVEL_ERROR)
b57459abfba36eb3068cfe44c6921168b4c4f774Julian Pullen (me, "missing all zones privileges\n");
b57459abfba36eb3068cfe44c6921168b4c4f774Julian Pullen rc = -1;
b57459abfba36eb3068cfe44c6921168b4c4f774Julian Pullen }
b57459abfba36eb3068cfe44c6921168b4c4f774Julian Pullen priv_freeset(zs);
b57459abfba36eb3068cfe44c6921168b4c4f774Julian Pullen break;
b57459abfba36eb3068cfe44c6921168b4c4f774Julian Pullen case NSCD_READ_PRIV:
b57459abfba36eb3068cfe44c6921168b4c4f774Julian Pullen if (!priv_ismember(eset, PRIV_FILE_DAC_READ))
b57459abfba36eb3068cfe44c6921168b4c4f774Julian Pullen rc = -1;
b57459abfba36eb3068cfe44c6921168b4c4f774Julian Pullen break;
b57459abfba36eb3068cfe44c6921168b4c4f774Julian Pullen default:
b57459abfba36eb3068cfe44c6921168b4c4f774Julian Pullen _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR)
b57459abfba36eb3068cfe44c6921168b4c4f774Julian Pullen (me, "unknown required_priv: %d\n", required_priv);
b57459abfba36eb3068cfe44c6921168b4c4f774Julian Pullen rc = -1;
b57459abfba36eb3068cfe44c6921168b4c4f774Julian Pullen break;
b57459abfba36eb3068cfe44c6921168b4c4f774Julian Pullen }
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen ucred_free(uc);
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen return (rc);
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen}
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void
cb5caa98562cf06753163f558cbcfe30b8f4673adjlN2N_check_priv(
cb5caa98562cf06753163f558cbcfe30b8f4673adjl void *buf,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *dc_str)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nss_pheader_t *phdr = (nss_pheader_t *)buf;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ucred_t *uc = NULL;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl const priv_set_t *eset;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl zoneid_t zoneid;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int errnum;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *me = "N2N_check_priv";
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (door_ucred(&uc) != 0) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl errnum = errno;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_DEBUG)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "door_ucred: %s\n", strerror(errno));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik NSCD_SET_STATUS(phdr, NSS_ERROR, errnum);
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik return;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl eset = ucred_getprivset(uc, PRIV_EFFECTIVE);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl zoneid = ucred_getzoneid(uc);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if ((zoneid != GLOBAL_ZONEID && zoneid != getzoneid()) ||
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen eset != NULL ? !priv_ismember(eset, PRIV_SYS_ADMIN) :
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen ucred_geteuid(uc) != 0) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ALERT)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "%s call failed(cred): caller pid %d, uid %d, "
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen "euid %d, zoneid %d\n", dc_str, ucred_getpid(uc),
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen ucred_getruid(uc), ucred_geteuid(uc), zoneid);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ucred_free(uc);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik NSCD_SET_STATUS(phdr, NSS_ERROR, EACCES);
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik return;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_DEBUG)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "nscd received %s cmd from pid %d, uid %d, "
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen "euid %d, zoneid %d\n", dc_str, ucred_getpid(uc),
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen ucred_getruid(uc), ucred_geteuid(uc), zoneid);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ucred_free(uc);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik NSCD_SET_STATUS_SUCCESS(phdr);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
e37190e5b4531a897e4191a30b8f41678b582e25michenvoid
e37190e5b4531a897e4191a30b8f41678b582e25michen_nscd_APP_check_cred(
cb5caa98562cf06753163f558cbcfe30b8f4673adjl void *buf,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl pid_t *pidp,
e37190e5b4531a897e4191a30b8f41678b582e25michen char *dc_str,
e37190e5b4531a897e4191a30b8f41678b582e25michen int log_comp,
e37190e5b4531a897e4191a30b8f41678b582e25michen int log_level)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nss_pheader_t *phdr = (nss_pheader_t *)buf;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ucred_t *uc = NULL;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl uid_t ruid;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl uid_t euid;
e37190e5b4531a897e4191a30b8f41678b582e25michen pid_t pid;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int errnum;
e37190e5b4531a897e4191a30b8f41678b582e25michen char *me = "_nscd_APP_check_cred";
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (door_ucred(&uc) != 0) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl errnum = errno;
e37190e5b4531a897e4191a30b8f41678b582e25michen _NSCD_LOG(log_comp, NSCD_LOG_LEVEL_ERROR)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "door_ucred: %s\n", strerror(errno));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik NSCD_SET_STATUS(phdr, NSS_ERROR, errnum);
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik return;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
e37190e5b4531a897e4191a30b8f41678b582e25michen NSCD_SET_STATUS_SUCCESS(phdr);
e37190e5b4531a897e4191a30b8f41678b582e25michen pid = ucred_getpid(uc);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (NSS_PACKED_CRED_CHECK(buf, ruid = ucred_getruid(uc),
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen euid = ucred_geteuid(uc))) {
e37190e5b4531a897e4191a30b8f41678b582e25michen if (pidp != NULL) {
e37190e5b4531a897e4191a30b8f41678b582e25michen if (*pidp == (pid_t)-1)
e37190e5b4531a897e4191a30b8f41678b582e25michen *pidp = pid;
e37190e5b4531a897e4191a30b8f41678b582e25michen else if (*pidp != pid) {
e37190e5b4531a897e4191a30b8f41678b582e25michen NSCD_SET_STATUS(phdr, NSS_ERROR, EACCES);
e37190e5b4531a897e4191a30b8f41678b582e25michen }
e37190e5b4531a897e4191a30b8f41678b582e25michen }
e37190e5b4531a897e4191a30b8f41678b582e25michen } else {
e37190e5b4531a897e4191a30b8f41678b582e25michen NSCD_SET_STATUS(phdr, NSS_ERROR, EACCES);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ucred_free(uc);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
e37190e5b4531a897e4191a30b8f41678b582e25michen if (NSCD_STATUS_IS_NOT_OK(phdr)) {
e37190e5b4531a897e4191a30b8f41678b582e25michen _NSCD_LOG(log_comp, log_level)
e37190e5b4531a897e4191a30b8f41678b582e25michen (me, "%s call failed: caller pid %d (input pid = %d), ruid %d, "
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen "euid %d, header ruid %d, header euid %d\n", dc_str,
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen pid, (pidp != NULL) ? *pidp : -1, ruid, euid,
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen ((nss_pheader_t *)(buf))->p_ruid,
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen ((nss_pheader_t *)(buf))->p_euid);
e37190e5b4531a897e4191a30b8f41678b582e25michen }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen/* log error and return -1 when an invalid packed buffer header is found */
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichenstatic int
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichenpheader_error(nss_pheader_t *phdr, uint32_t call_number)
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen{
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen char *call_num_str;
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen switch (call_number) {
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen case NSCD_SEARCH:
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen call_num_str = "NSCD_SEARCH";
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen break;
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen case NSCD_SETENT:
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen call_num_str = "NSCD_SETENT";
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen break;
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen case NSCD_GETENT:
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen call_num_str = "NSCD_GETENT";
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen break;
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen case NSCD_ENDENT:
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen call_num_str = "NSCD_ENDENT";
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen break;
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen case NSCD_PUT:
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen call_num_str = "NSCD_PUT";
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen break;
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen case NSCD_GETHINTS:
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen call_num_str = "NSCD_GETHINTS";
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen break;
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen default:
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen call_num_str = "UNKNOWN";
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen break;
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen }
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ALERT)
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen ("pheader_error", "call number %s: invalid packed buffer header\n",
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen call_num_str);
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen NSCD_SET_STATUS(phdr, NSS_ERROR, EINVAL);
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen return (-1);
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen}
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen/*
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * Validate the header of a getXbyY or setent/getent/endent request.
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * Return 0 if good, -1 otherwise.
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen *
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * A valid header looks like the following (size is arg_size, does
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * not include the output area):
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * +----------------------------------+ --
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * | nss_pheader_t (header fixed part)| ^
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * | | |
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * | pbufsiz, dbd,off, key_off, | len = sizeof(nss_pheader_t)
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * | data_off .... | |
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * | | v
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * +----------------------------------+ <----- dbd_off
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * | dbd (database description) | ^
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * | nss_dbd_t + up to 3 strings | |
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * | length = sizeof(nss_dbd_t) + | len = key_off - dbd_off
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * | length of 3 strings + | |
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * | length of padding | |
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * | (total length in multiple of 4) | v
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * +----------------------------------+ <----- key_off
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * | lookup key | ^
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * | nss_XbyY_key_t, content varies, | |
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * | based on database and lookup op | len = data_off - key_off
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * | length = data_off - key_off | |
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * | including padding, multiple of 4 | v
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * +----------------------------------+ <----- data_off (= arg_size)
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * | | ^
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * | area to hold results | |
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * | | len = data_len (= pbufsiz -
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * | | | data_off)
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * | | v
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * +----------------------------------+ <----- pbufsiz
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen */
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichenstatic int
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichenvalidate_pheader(
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen void *argp,
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen size_t arg_size,
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen uint32_t call_number)
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen{
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen nss_pheader_t *phdr = (nss_pheader_t *)(void *)argp;
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen nssuint_t l1, l2;
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen /*
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * current version is NSCD_HEADER_REV, length of the fixed part
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * of the header must match the size of nss_pheader_t
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen */
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen if (phdr->p_version != NSCD_HEADER_REV ||
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen phdr->dbd_off != sizeof (nss_pheader_t))
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen return (pheader_error(phdr, call_number));
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen /*
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * buffer size and offsets must be in multiple of 4
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen */
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen if ((arg_size & 3) || (phdr->dbd_off & 3) || (phdr->key_off & 3) ||
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen (phdr->data_off & 3))
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen return (pheader_error(phdr, call_number));
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen /*
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * the input arg_size is the length of the request header
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * and should be less than NSCD_PHDR_MAXLEN
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen */
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen if (phdr->data_off != arg_size || arg_size > NSCD_PHDR_MAXLEN)
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen return (pheader_error(phdr, call_number));
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen /* get length of the dbd area */
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen l1 = phdr->key_off - phdr-> dbd_off;
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen /*
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * dbd area may contain padding, so length of dbd should
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * not be less than the length of the actual data
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen */
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen if (l1 < phdr->dbd_len)
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen return (pheader_error(phdr, call_number));
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen /* get length of the key area */
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen l2 = phdr->data_off - phdr->key_off;
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen /*
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * key area may contain padding, so length of key area should
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * not be less than the length of the actual data
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen */
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen if (l2 < phdr->key_len)
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen return (pheader_error(phdr, call_number));
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen /*
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * length of fixed part + lengths of dbd and key area = length of
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * the request header
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen */
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen if (sizeof (nss_pheader_t) + l1 + l2 != phdr->data_off)
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen return (pheader_error(phdr, call_number));
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen /* header length + data length = buffer length */
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen if (phdr->data_off + phdr->data_len != phdr->pbufsiz)
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen return (pheader_error(phdr, call_number));
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen return (0);
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen}
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen/* log error and return -1 when an invalid nscd to nscd buffer is found */
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichenstatic int
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichenN2Nbuf_error(nss_pheader_t *phdr, uint32_t call_number)
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen{
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen char *call_num_str;
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen switch (call_number) {
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen case NSCD_PING:
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen call_num_str = "NSCD_PING";
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen break;
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen case NSCD_IMHERE:
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen call_num_str = "NSCD_IMHERE";
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen break;
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen case NSCD_PULSE:
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen call_num_str = "NSCD_PULSE";
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen break;
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen case NSCD_FORK:
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen call_num_str = "NSCD_FORK";
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen break;
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen case NSCD_KILL:
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen call_num_str = "NSCD_KILL";
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen break;
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen case NSCD_REFRESH:
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen call_num_str = "NSCD_REFRESH";
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen break;
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen case NSCD_GETPUADMIN:
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen call_num_str = "NSCD_GETPUADMIN";
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen break;
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen case NSCD_GETADMIN:
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen call_num_str = "NSCD_GETADMIN";
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen break;
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen case NSCD_SETADMIN:
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen call_num_str = "NSCD_SETADMIN";
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen break;
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen case NSCD_KILLSERVER:
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen call_num_str = "NSCD_KILLSERVER";
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen break;
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen default:
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen call_num_str = "UNKNOWN";
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen break;
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen }
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ALERT)
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen ("N2Nbuf_error", "call number %s: invalid N2N buffer\n", call_num_str);
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen NSCD_SET_N2N_STATUS(phdr, NSS_NSCD_PRIV, 0,
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen NSCD_DOOR_BUFFER_CHECK_FAILED);
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen return (-1);
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen}
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen/*
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * Validate the buffer of an nscd to nscd request.
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * Return 0 if good, -1 otherwise.
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen *
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * A valid buffer looks like the following (size is arg_size):
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * +----------------------------------+ --
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * | nss_pheader_t (header fixed part)| ^
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * | | |
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * | pbufsiz, dbd,off, key_off, | len = sizeof(nss_pheader_t)
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * | data_off .... | |
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * | | v
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * +----------------------------------+ <---dbd_off = key_off = data_off
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * | | ^
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * | input data/output data | |
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * | OR no data | len = data_len (= pbufsiz -
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * | | | data_off)
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * | | | len could be zero
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * | | v
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * +----------------------------------+ <--- pbufsiz
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen */
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichenstatic int
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichenvalidate_N2Nbuf(
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen void *argp,
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen size_t arg_size,
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen uint32_t call_number)
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen{
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen nss_pheader_t *phdr = (nss_pheader_t *)(void *)argp;
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen /*
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * current version is NSCD_HEADER_REV, length of the fixed part
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * of the header must match the size of nss_pheader_t
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen */
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen if (phdr->p_version != NSCD_HEADER_REV ||
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen phdr->dbd_off != sizeof (nss_pheader_t))
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen return (N2Nbuf_error(phdr, call_number));
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen /*
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * There are no dbd and key data, so the dbd, key, data
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * offsets should be equal
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen */
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen if (phdr->dbd_off != phdr->key_off ||
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen phdr->dbd_off != phdr->data_off)
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen return (N2Nbuf_error(phdr, call_number));
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen /*
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * the input arg_size is the buffer length and should
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * be less or equal than NSCD_N2NBUF_MAXLEN
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen */
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen if (phdr->pbufsiz != arg_size || arg_size > NSCD_N2NBUF_MAXLEN)
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen return (N2Nbuf_error(phdr, call_number));
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen /* header length + data length = buffer length */
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen if (phdr->data_off + phdr->data_len != phdr->pbufsiz)
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen return (N2Nbuf_error(phdr, call_number));
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen return (0);
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen}
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void
cb5caa98562cf06753163f558cbcfe30b8f4673adjllookup(char *argp, size_t arg_size)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nsc_lookup_args_t largs;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char space[NSCD_LOOKUP_BUFSIZE];
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nss_pheader_t *phdr = (nss_pheader_t *)(void *)argp;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl NSCD_ALLOC_LOOKUP_BUFFER(argp, arg_size, phdr, space,
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen sizeof (space));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen /*
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * make sure the first couple bytes of the data area is null,
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * so that bad strings in the packed header stop here
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen */
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen (void) memset((char *)phdr + phdr->data_off, 0, 16);
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) memset(&largs, 0, sizeof (largs));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl largs.buffer = argp;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl largs.bufsize = arg_size;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nsc_lookup(&largs, 0);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * only the PUN needs to keep track of the
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * activity count to determine when to
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * terminate itself
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (_whoami == NSCD_CHILD) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_lock(&activity_lock);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ++activity;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_unlock(&activity_lock);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl NSCD_SET_RETURN_ARG(phdr, arg_size);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) door_return(argp, arg_size, NULL, 0);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void
cb5caa98562cf06753163f558cbcfe30b8f4673adjlgetent(char *argp, size_t arg_size)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char space[NSCD_LOOKUP_BUFSIZE];
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nss_pheader_t *phdr = (nss_pheader_t *)(void *)argp;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen NSCD_ALLOC_LOOKUP_BUFFER(argp, arg_size, phdr, space, sizeof (space));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nss_pgetent(argp, arg_size);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl NSCD_SET_RETURN_ARG(phdr, arg_size);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) door_return(argp, arg_size, NULL, 0);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic int
cb5caa98562cf06753163f558cbcfe30b8f4673adjlis_db_per_user(void *buf, char *dblist)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nss_pheader_t *phdr = (nss_pheader_t *)buf;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nss_dbd_t *pdbd;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *dbname, *dbn;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int len;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* copy db name into a temp buffer */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl pdbd = (nss_dbd_t *)((void *)((char *)buf + phdr->dbd_off));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl dbname = (char *)pdbd + pdbd->o_name;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl len = strlen(dbname);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl dbn = alloca(len + 2);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) memcpy(dbn, dbname, len);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* check if <dbname> + ',' can be found in the dblist string */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl dbn[len] = ',';
cb5caa98562cf06753163f558cbcfe30b8f4673adjl dbn[len + 1] = '\0';
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (strstr(dblist, dbn) != NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (1);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * check if <dbname> can be found in the last part
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * of the dblist string
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl dbn[len] = '\0';
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (strstr(dblist, dbn) != NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (1);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (0);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Check to see if all conditions are met for processing per-user
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * requests. Returns 1 if yes, -1 if backend is not configured,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * 0 otherwise.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic int
cb5caa98562cf06753163f558cbcfe30b8f4673adjlneed_per_user_door(void *buf, int whoami, uid_t uid, char **dblist)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nss_pheader_t *phdr = (nss_pheader_t *)buf;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl NSCD_SET_STATUS_SUCCESS(phdr);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* if already a per-user nscd, no need to get per-user door */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (whoami == NSCD_CHILD)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (0);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* forker shouldn't be asked */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (whoami == NSCD_FORKER) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl NSCD_SET_STATUS(phdr, NSS_ERROR, ENOTSUP);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (0);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* if door client is root, no need for a per-user door */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (uid == 0)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (0);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * if per-user lookup is not configured, no per-user
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * door available
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (_nscd_is_self_cred_on(0, dblist) == 0)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (-1);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * if per-user lookup is not configured for the db,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * don't bother
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (is_db_per_user(phdr, *dblist) == 0)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (0);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (1);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void
cb5caa98562cf06753163f558cbcfe30b8f4673adjlif_selfcred_return_per_user_door(char *argp, size_t arg_size,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl door_desc_t *dp, int whoami)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nss_pheader_t *phdr = (nss_pheader_t *)((void *)argp);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *dblist;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int door = -1;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int rc = 0;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl door_desc_t desc;
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen char *space;
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen int len;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * check to see if self-cred is configured and
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * need to return an alternate PUN door
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (per_user_is_on == 1) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl rc = need_per_user_door(argp, whoami,
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen _nscd_get_client_euid(), &dblist);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (rc == -1)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl per_user_is_on = 0;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (rc <= 0) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * self-cred not configured, and no error detected,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * return to continue the door call processing
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (NSCD_STATUS_IS_OK(phdr))
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl else
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * configured but error detected,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * stop the door call processing
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) door_return(argp, phdr->data_off, NULL, 0);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* get the alternate PUN door */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _nscd_proc_alt_get(argp, &door);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (NSCD_GET_STATUS(phdr) != NSS_ALTRETRY) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) door_return(argp, phdr->data_off, NULL, 0);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* return the alternate door descriptor */
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen len = strlen(dblist) + 1;
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen space = alloca(arg_size + len);
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen phdr->data_len = len;
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen (void) memcpy(space, phdr, arg_size);
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen (void) strncpy((char *)space + arg_size, dblist, len);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl dp = &desc;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl dp->d_attributes = DOOR_DESCRIPTOR;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl dp->d_data.d_desc.d_descriptor = door;
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen arg_size += len;
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen (void) door_return(space, arg_size, dp, 1);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*ARGSUSED*/
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void
cb5caa98562cf06753163f558cbcfe30b8f4673adjlswitcher(void *cookie, char *argp, size_t arg_size,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl door_desc_t *dp, uint_t n_desc)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int iam;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl pid_t ent_pid = -1;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nss_pheader_t *phdr = (nss_pheader_t *)((void *)argp);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl void *uptr;
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen int len;
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen size_t buflen;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int callnum;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *me = "switcher";
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_DEBUG)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "switcher ...\n");
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (argp == DOOR_UNREF_DATA) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) printf("Door Slam... exiting\n");
cb5caa98562cf06753163f558cbcfe30b8f4673adjl exit(0);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (argp == NULL) { /* empty door call */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) door_return(NULL, 0, 0, 0); /* return the favor */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * need to restart if main nscd and config file(s) changed
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (_whoami == NSCD_MAIN)
80b80bf0416a7eb4be4215b2e192cafd03ca80b7michen _nscd_restart_if_cfgfile_changed();
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if ((phdr->nsc_callnumber & NSCDV2CATMASK) == NSCD_CALLCAT_APP) {
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen /* make sure the packed buffer header is good */
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen if (validate_pheader(argp, arg_size,
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen phdr->nsc_callnumber) == -1)
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen (void) door_return(argp, arg_size, NULL, 0);
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen
cb5caa98562cf06753163f558cbcfe30b8f4673adjl switch (phdr->nsc_callnumber) {
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case NSCD_SEARCH:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* if a fallback to main nscd, skip per-user setup */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (phdr->p_status != NSS_ALTRETRY)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if_selfcred_return_per_user_door(argp, arg_size,
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen dp, _whoami);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl lookup(argp, arg_size);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case NSCD_SETENT:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
e37190e5b4531a897e4191a30b8f41678b582e25michen _nscd_APP_check_cred(argp, &ent_pid, "NSCD_SETENT",
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ALERT);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (NSCD_STATUS_IS_OK(phdr)) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if_selfcred_return_per_user_door(argp, arg_size,
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen dp, _whoami);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nss_psetent(argp, arg_size, ent_pid);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case NSCD_GETENT:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl getent(argp, arg_size);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case NSCD_ENDENT:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nss_pendent(argp, arg_size);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case NSCD_PUT:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "door call NSCD_PUT not supported yet\n");
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl NSCD_SET_STATUS(phdr, NSS_ERROR, ENOTSUP);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case NSCD_GETHINTS:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "door call NSCD_GETHINTS not supported yet\n");
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl NSCD_SET_STATUS(phdr, NSS_ERROR, ENOTSUP);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl default:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "Unknown name service door call op %x\n",
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen phdr->nsc_callnumber);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl NSCD_SET_STATUS(phdr, NSS_ERROR, EINVAL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) door_return(argp, arg_size, NULL, 0);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl iam = NSCD_MAIN;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl callnum = phdr->nsc_callnumber & ~NSCD_WHOAMI;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (callnum == NSCD_IMHERE ||
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen callnum == NSCD_PULSE || callnum == NSCD_FORK)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl iam = phdr->nsc_callnumber & NSCD_WHOAMI;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl else
cb5caa98562cf06753163f558cbcfe30b8f4673adjl callnum = phdr->nsc_callnumber;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* nscd -> nscd v2 calls */
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen /* make sure the buffer is good */
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen if (validate_N2Nbuf(argp, arg_size, callnum) == -1)
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen (void) door_return(argp, arg_size, NULL, 0);
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen
cb5caa98562cf06753163f558cbcfe30b8f4673adjl switch (callnum) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case NSCD_PING:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl NSCD_SET_STATUS_SUCCESS(phdr);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case NSCD_IMHERE:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _nscd_proc_iamhere(argp, dp, n_desc, iam);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case NSCD_PULSE:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl N2N_check_priv(argp, "NSCD_PULSE");
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (NSCD_STATUS_IS_OK(phdr))
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _nscd_proc_pulse(argp, iam);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case NSCD_FORK:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl N2N_check_priv(argp, "NSCD_FORK");
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (NSCD_STATUS_IS_OK(phdr))
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _nscd_proc_fork(argp, iam);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case NSCD_KILL:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl N2N_check_priv(argp, "NSCD_KILL");
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (NSCD_STATUS_IS_OK(phdr))
cb5caa98562cf06753163f558cbcfe30b8f4673adjl exit(0);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case NSCD_REFRESH:
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen N2N_check_priv(argp, "NSCD_REFRESH");
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen if (NSCD_STATUS_IS_OK(phdr)) {
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen if (_nscd_refresh() != NSCD_SUCCESS)
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen exit(1);
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen NSCD_SET_STATUS_SUCCESS(phdr);
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case NSCD_GETPUADMIN:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (_nscd_is_self_cred_on(0, NULL)) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _nscd_peruser_getadmin(argp, sizeof (nscd_admin_t));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl } else {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl NSCD_SET_N2N_STATUS(phdr, NSS_NSCD_PRIV, 0,
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen NSCD_SELF_CRED_NOT_CONFIGURED);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case NSCD_GETADMIN:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl len = _nscd_door_getadmin((void *)argp);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (len == 0)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* size of door buffer not big enough, allocate one */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl NSCD_ALLOC_DOORBUF(NSCD_GETADMIN, len, uptr, buflen);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* copy packed header */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *(nss_pheader_t *)uptr = *(nss_pheader_t *)((void *)argp);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* set new buffer size */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ((nss_pheader_t *)uptr)->pbufsiz = buflen;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* try one more time */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) _nscd_door_getadmin((void *)uptr);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) door_return(uptr, buflen, NULL, 0);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case NSCD_SETADMIN:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl N2N_check_priv(argp, "NSCD_SETADMIN");
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (NSCD_STATUS_IS_OK(phdr))
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _nscd_door_setadmin(argp);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case NSCD_KILLSERVER:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl N2N_check_priv(argp, "NSCD_KILLSERVER");
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (NSCD_STATUS_IS_OK(phdr)) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* also kill the forker nscd if one is running */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _nscd_kill_forker();
cb5caa98562cf06753163f558cbcfe30b8f4673adjl exit(0);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl default:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "Unknown name service door call op %d\n",
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen phdr->nsc_callnumber);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl NSCD_SET_STATUS(phdr, NSS_ERROR, EINVAL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) door_return(argp, arg_size, NULL, 0);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) door_return(argp, arg_size, NULL, 0);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlint
cb5caa98562cf06753163f558cbcfe30b8f4673adjl_nscd_setup_server(char *execname, char **argv)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int fd;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int errnum;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int bind_failed = 0;
80b80bf0416a7eb4be4215b2e192cafd03ca80b7michen mode_t old_mask;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl struct stat buf;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl sigset_t myset;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl struct sigaction action;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *me = "_nscd_setup_server";
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl main_execname = execname;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl main_argv = argv;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
82714199c1609fb4cb7d0f524cc6a6436eea4d25sdussud /* Any nscd process is to ignore SIGPIPE */
82714199c1609fb4cb7d0f524cc6a6436eea4d25sdussud if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
82714199c1609fb4cb7d0f524cc6a6436eea4d25sdussud errnum = errno;
82714199c1609fb4cb7d0f524cc6a6436eea4d25sdussud _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR)
82714199c1609fb4cb7d0f524cc6a6436eea4d25sdussud (me, "signal (SIGPIPE): %s\n", strerror(errnum));
82714199c1609fb4cb7d0f524cc6a6436eea4d25sdussud return (-1);
82714199c1609fb4cb7d0f524cc6a6436eea4d25sdussud }
82714199c1609fb4cb7d0f524cc6a6436eea4d25sdussud
cb5caa98562cf06753163f558cbcfe30b8f4673adjl keep_open_dns_socket();
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * the max number of server threads should be fixed now, so
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * set flag to indicate that no in-flight change is allowed
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl max_servers_set = 1;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) thr_keycreate(&lookup_state_key, NULL);
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen (void) sema_init(&common_sema, frontend_cfg_g.common_worker_threads,
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen USYNC_THREAD, 0);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* Establish server thread pool */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) door_server_create(server_create);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (thr_keycreate(&server_key, server_destroy) != 0) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl errnum = errno;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "thr_keycreate (server thread): %s\n",
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen strerror(errnum));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (-1);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* Create a door */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if ((fd = door_create(switcher, NAME_SERVICE_DOOR_COOKIE,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl DOOR_UNREF | DOOR_NO_CANCEL)) < 0) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl errnum = errno;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "door_create: %s\n", strerror(errnum));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (-1);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* if not main nscd, no more setup to do */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (_whoami != NSCD_MAIN)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (fd);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* bind to file system */
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen if (is_system_labeled() && (getzoneid() == GLOBAL_ZONEID)) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (stat(TSOL_NAME_SERVICE_DOOR, &buf) < 0) {
80b80bf0416a7eb4be4215b2e192cafd03ca80b7michen int newfd;
80b80bf0416a7eb4be4215b2e192cafd03ca80b7michen
80b80bf0416a7eb4be4215b2e192cafd03ca80b7michen /* make sure the door will be readable by all */
80b80bf0416a7eb4be4215b2e192cafd03ca80b7michen old_mask = umask(0);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if ((newfd = creat(TSOL_NAME_SERVICE_DOOR, 0444)) < 0) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl errnum = errno;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_FRONT_END,
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen NSCD_LOG_LEVEL_ERROR)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "Cannot create %s: %s\n",
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen TSOL_NAME_SERVICE_DOOR,
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen strerror(errnum));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl bind_failed = 1;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
80b80bf0416a7eb4be4215b2e192cafd03ca80b7michen /* rstore the old file mode creation mask */
80b80bf0416a7eb4be4215b2e192cafd03ca80b7michen (void) umask(old_mask);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) close(newfd);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (symlink(TSOL_NAME_SERVICE_DOOR, NAME_SERVICE_DOOR) != 0) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (errno != EEXIST) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl errnum = errno;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_FRONT_END,
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen NSCD_LOG_LEVEL_ERROR)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "Cannot symlink %s: %s\n",
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen NAME_SERVICE_DOOR, strerror(errnum));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl bind_failed = 1;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl } else if (stat(NAME_SERVICE_DOOR, &buf) < 0) {
80b80bf0416a7eb4be4215b2e192cafd03ca80b7michen int newfd;
80b80bf0416a7eb4be4215b2e192cafd03ca80b7michen
80b80bf0416a7eb4be4215b2e192cafd03ca80b7michen /* make sure the door will be readable by all */
80b80bf0416a7eb4be4215b2e192cafd03ca80b7michen old_mask = umask(0);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if ((newfd = creat(NAME_SERVICE_DOOR, 0444)) < 0) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl errnum = errno;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "Cannot create %s: %s\n", NAME_SERVICE_DOOR,
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen strerror(errnum));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl bind_failed = 1;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
80b80bf0416a7eb4be4215b2e192cafd03ca80b7michen /* rstore the old file mode creation mask */
80b80bf0416a7eb4be4215b2e192cafd03ca80b7michen (void) umask(old_mask);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) close(newfd);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (bind_failed == 1) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) door_revoke(fd);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (-1);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (fattach(fd, NAME_SERVICE_DOOR) < 0) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if ((errno != EBUSY) ||
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen (fdetach(NAME_SERVICE_DOOR) < 0) ||
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen (fattach(fd, NAME_SERVICE_DOOR) < 0)) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl errnum = errno;
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "fattach: %s\n", strerror(errnum));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) door_revoke(fd);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (-1);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * kick off routing socket monitor thread
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (thr_create(NULL, NULL,
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen (void *(*)(void *))rts_mon, 0, 0, NULL) != 0) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl errnum = errno;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "thr_create (routing socket monitor): %s\n",
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen strerror(errnum));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) door_revoke(fd);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (-1);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * set up signal handler for SIGHUP
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl action.sa_handler = dozip;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl action.sa_flags = 0;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) sigemptyset(&action.sa_mask);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) sigemptyset(&myset);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) sigaddset(&myset, SIGHUP);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (sigaction(SIGHUP, &action, NULL) < 0) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl errnum = errno;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "sigaction (SIGHUP): %s\n", strerror(errnum));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) door_revoke(fd);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (-1);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (fd);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlint
cb5caa98562cf06753163f558cbcfe30b8f4673adjl_nscd_setup_child_server(int did)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int errnum;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int fd;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_rc_t rc;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *me = "_nscd_setup_child_server";
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* Re-establish our own server thread pool */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) door_server_create(server_create);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (thr_keycreate(&server_key, server_destroy) != 0) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl errnum = errno;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_DEBUG)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "thr_keycreate failed: %s", strerror(errnum));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (-1);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Create a new door.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Keep DOOR_REFUSE_DESC (self-cred nscds don't fork)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) close(did);
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen if ((fd = door_create(switcher, NAME_SERVICE_DOOR_COOKIE,
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen DOOR_REFUSE_DESC|DOOR_UNREF|DOOR_NO_CANCEL)) < 0) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl errnum = errno;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_DEBUG)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "door_create failed: %s", strerror(errnum));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (-1);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * kick off routing socket monitor thread
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (thr_create(NULL, NULL,
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen (void *(*)(void *))rts_mon, 0, 0, NULL) != 0) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl errnum = errno;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "thr_create (routing socket monitor): %s\n",
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen strerror(errnum));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) door_revoke(fd);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (-1);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * start monitoring the states of the name service clients
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl rc = _nscd_init_smf_monitor();
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (rc != NSCD_SUCCESS) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "unable to start the SMF monitor (rc = %d)\n", rc);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) door_revoke(fd);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (-1);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (fd);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlnscd_rc_t
cb5caa98562cf06753163f558cbcfe30b8f4673adjl_nscd_alloc_frontend_cfg()
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl frontend_cfg = calloc(NSCD_NUM_DB, sizeof (nscd_cfg_frontend_t));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (frontend_cfg == NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSCD_NO_MEMORY);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSCD_SUCCESS);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/* ARGSUSED */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlnscd_rc_t
cb5caa98562cf06753163f558cbcfe30b8f4673adjl_nscd_cfg_frontend_notify(
cb5caa98562cf06753163f558cbcfe30b8f4673adjl void *data,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl struct nscd_cfg_param_desc *pdesc,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_cfg_id_t *nswdb,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_cfg_flag_t dflag,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_cfg_error_t **errorp,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl void *cookie)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl void *dp;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * At init time, the whole group of config params are received.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * At update time, group or individual parameter value could
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * be received.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (_nscd_cfg_flag_is_set(dflag, NSCD_CFG_DFLAG_INIT) ||
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen _nscd_cfg_flag_is_set(dflag, NSCD_CFG_DFLAG_GROUP)) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * group data is received, copy in the
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * entire strcture
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen if (_nscd_cfg_flag_is_set(pdesc->pflag, NSCD_CFG_PFLAG_GLOBAL))
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen frontend_cfg_g = *(nscd_cfg_global_frontend_t *)data;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl else
cb5caa98562cf06753163f558cbcfe30b8f4673adjl frontend_cfg[nswdb->index] =
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen *(nscd_cfg_frontend_t *)data;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl } else {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * individual paramater is received: copy in the
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * parameter value.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen if (_nscd_cfg_flag_is_set(pdesc->pflag, NSCD_CFG_PFLAG_GLOBAL))
cb5caa98562cf06753163f558cbcfe30b8f4673adjl dp = (char *)&frontend_cfg_g + pdesc->p_offset;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl else
cb5caa98562cf06753163f558cbcfe30b8f4673adjl dp = (char *)&frontend_cfg[nswdb->index] +
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen pdesc->p_offset;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) memcpy(dp, data, pdesc->p_size);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSCD_SUCCESS);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/* ARGSUSED */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlnscd_rc_t
cb5caa98562cf06753163f558cbcfe30b8f4673adjl_nscd_cfg_frontend_verify(
cb5caa98562cf06753163f558cbcfe30b8f4673adjl void *data,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl struct nscd_cfg_param_desc *pdesc,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_cfg_id_t *nswdb,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_cfg_flag_t dflag,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_cfg_error_t **errorp,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl void **cookie)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *me = "_nscd_cfg_frontend_verify";
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * if max. number of server threads is set and in effect,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * don't allow changing of the frontend configuration
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (max_servers_set) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_INFO)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "changing of the frontend configuration not allowed now");
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSCD_CFG_CHANGE_NOT_ALLOWED);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSCD_SUCCESS);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/* ARGSUSED */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlnscd_rc_t
cb5caa98562cf06753163f558cbcfe30b8f4673adjl_nscd_cfg_frontend_get_stat(
cb5caa98562cf06753163f558cbcfe30b8f4673adjl void **stat,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl struct nscd_cfg_stat_desc *sdesc,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_cfg_id_t *nswdb,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_cfg_flag_t *dflag,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl void (**free_stat)(void *stat),
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_cfg_error_t **errorp)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSCD_SUCCESS);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlvoid
cb5caa98562cf06753163f558cbcfe30b8f4673adjl_nscd_init_cache_sema(sema_t *sema, char *cache_name)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int i, j;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *dbn;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (max_servers == 0)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl max_servers = frontend_cfg_g.common_worker_threads +
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen frontend_cfg_g.cache_hit_threads;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl for (i = 0; i < NSCD_NUM_DB; i++) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl dbn = NSCD_NSW_DB_NAME(i);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (strcasecmp(dbn, cache_name) == 0) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl j = frontend_cfg[i].worker_thread_per_nsw_db;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) sema_init(sema, j, USYNC_THREAD, 0);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl max_servers += j;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Monitor the routing socket. Address lists stored in the ipnodes
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * cache are sorted based on destination address selection rules,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * so when things change that could affect that sorting (interfaces
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * go up or down, flags change, etc.), we clear that cache so the
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * list will be re-ordered the next time the hostname is resolved.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void
cb5caa98562cf06753163f558cbcfe30b8f4673adjlrts_mon(void)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int rt_sock, rdlen, idx;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl union {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl struct {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl struct rt_msghdr rtm;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl struct sockaddr_storage addrs[RTA_NUMBITS];
cb5caa98562cf06753163f558cbcfe30b8f4673adjl } r;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl struct if_msghdr ifm;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl struct ifa_msghdr ifam;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl } mbuf;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl struct ifa_msghdr *ifam = &mbuf.ifam;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *me = "rts_mon";
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl rt_sock = socket(PF_ROUTE, SOCK_RAW, 0);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (rt_sock < 0) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "Failed to open routing socket: %s\n", strerror(errno));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl thr_exit(0);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl for (;;) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl rdlen = read(rt_sock, &mbuf, sizeof (mbuf));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (rdlen <= 0) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (rdlen == 0 || (errno != EINTR && errno != EAGAIN)) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_FRONT_END,
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen NSCD_LOG_LEVEL_ERROR)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "routing socket read: %s\n",
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen strerror(errno));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl thr_exit(0);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl continue;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (ifam->ifam_version != RTM_VERSION) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_FRONT_END,
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen NSCD_LOG_LEVEL_ERROR)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "rx unknown version (%d) on "
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen "routing socket.\n",
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen ifam->ifam_version);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl continue;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl switch (ifam->ifam_type) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case RTM_NEWADDR:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case RTM_DELADDR:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* if no ipnodes cache, then nothing to do */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl idx = get_cache_idx("ipnodes");
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (cache_ctx_p[idx] == NULL ||
bf1e3bee1b13b3a914f0dd817a04f6e0ce8e0691michen cache_ctx_p[idx]->reaper_on != nscd_true)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nsc_invalidate(cache_ctx_p[idx], NULL, NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case RTM_ADD:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case RTM_DELETE:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case RTM_CHANGE:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case RTM_GET:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case RTM_LOSING:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case RTM_REDIRECT:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case RTM_MISS:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case RTM_LOCK:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case RTM_OLDADD:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case RTM_OLDDEL:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case RTM_RESOLVE:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case RTM_IFINFO:
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou case RTM_CHGADDR:
1cb875ae88fb9463b368e725c2444776595895cbCathy Zhou case RTM_FREEADDR:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl default:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "rx unknown msg type (%d) on routing socket.\n",
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ifam->ifam_type);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void
cb5caa98562cf06753163f558cbcfe30b8f4673adjlkeep_open_dns_socket(void)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _res.options |= RES_STAYOPEN; /* just keep this udp socket open */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}