vs_main.c revision 911106dfb16696472af8c1b7b4c554a829354fa8
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
911106dfb16696472af8c1b7b4c554a829354fa8jm * CDDL HEADER START
911106dfb16696472af8c1b7b4c554a829354fa8jm *
911106dfb16696472af8c1b7b4c554a829354fa8jm * The contents of this file are subject to the terms of the
911106dfb16696472af8c1b7b4c554a829354fa8jm * Common Development and Distribution License (the "License").
911106dfb16696472af8c1b7b4c554a829354fa8jm * You may not use this file except in compliance with the License.
911106dfb16696472af8c1b7b4c554a829354fa8jm *
911106dfb16696472af8c1b7b4c554a829354fa8jm * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
911106dfb16696472af8c1b7b4c554a829354fa8jm * or http://www.opensolaris.org/os/licensing.
911106dfb16696472af8c1b7b4c554a829354fa8jm * See the License for the specific language governing permissions
911106dfb16696472af8c1b7b4c554a829354fa8jm * and limitations under the License.
911106dfb16696472af8c1b7b4c554a829354fa8jm *
911106dfb16696472af8c1b7b4c554a829354fa8jm * When distributing Covered Code, include this CDDL HEADER in each
911106dfb16696472af8c1b7b4c554a829354fa8jm * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
911106dfb16696472af8c1b7b4c554a829354fa8jm * If applicable, add the following below this CDDL HEADER, with the
911106dfb16696472af8c1b7b4c554a829354fa8jm * fields enclosed by brackets "[]" replaced with your own identifying
911106dfb16696472af8c1b7b4c554a829354fa8jm * information: Portions Copyright [yyyy] [name of copyright owner]
911106dfb16696472af8c1b7b4c554a829354fa8jm *
911106dfb16696472af8c1b7b4c554a829354fa8jm * CDDL HEADER END
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
911106dfb16696472af8c1b7b4c554a829354fa8jm * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
911106dfb16696472af8c1b7b4c554a829354fa8jm * Use is subject to license terms.
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm#pragma ident "%Z%%M% %I% %E% SMI"
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
911106dfb16696472af8c1b7b4c554a829354fa8jm * vscand Daemon Program
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm#include <stdio.h>
911106dfb16696472af8c1b7b4c554a829354fa8jm#include <sys/stat.h>
911106dfb16696472af8c1b7b4c554a829354fa8jm#include <sys/filio.h>
911106dfb16696472af8c1b7b4c554a829354fa8jm#include <sys/types.h>
911106dfb16696472af8c1b7b4c554a829354fa8jm#include <sys/socket.h>
911106dfb16696472af8c1b7b4c554a829354fa8jm#include <sys/ioctl.h>
911106dfb16696472af8c1b7b4c554a829354fa8jm#include <sys/param.h>
911106dfb16696472af8c1b7b4c554a829354fa8jm#include <zone.h>
911106dfb16696472af8c1b7b4c554a829354fa8jm#include <tsol/label.h>
911106dfb16696472af8c1b7b4c554a829354fa8jm#include <string.h>
911106dfb16696472af8c1b7b4c554a829354fa8jm#include <stdlib.h>
911106dfb16696472af8c1b7b4c554a829354fa8jm#include <fcntl.h>
911106dfb16696472af8c1b7b4c554a829354fa8jm#include <wait.h>
911106dfb16696472af8c1b7b4c554a829354fa8jm#include <unistd.h>
911106dfb16696472af8c1b7b4c554a829354fa8jm#include <getopt.h>
911106dfb16696472af8c1b7b4c554a829354fa8jm#include <stdarg.h>
911106dfb16696472af8c1b7b4c554a829354fa8jm#include <libscf.h>
911106dfb16696472af8c1b7b4c554a829354fa8jm#include <signal.h>
911106dfb16696472af8c1b7b4c554a829354fa8jm#include <libintl.h>
911106dfb16696472af8c1b7b4c554a829354fa8jm#include <netinet/in.h>
911106dfb16696472af8c1b7b4c554a829354fa8jm#include <arpa/inet.h>
911106dfb16696472af8c1b7b4c554a829354fa8jm#include <ctype.h>
911106dfb16696472af8c1b7b4c554a829354fa8jm#include <pthread.h>
911106dfb16696472af8c1b7b4c554a829354fa8jm#include <syslog.h>
911106dfb16696472af8c1b7b4c554a829354fa8jm#include <locale.h>
911106dfb16696472af8c1b7b4c554a829354fa8jm#include <pwd.h>
911106dfb16696472af8c1b7b4c554a829354fa8jm#include <grp.h>
911106dfb16696472af8c1b7b4c554a829354fa8jm#include <priv_utils.h>
911106dfb16696472af8c1b7b4c554a829354fa8jm#include "vs_incl.h"
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic int vscand_fg = 0; /* daemon by default */
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic vs_daemon_state_t vscand_state = VS_STATE_INIT;
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic int vscand_sigval = 0;
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic int vscand_kdrv_fd = -1;
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic pthread_mutex_t vscand_cfg_mutex = PTHREAD_MUTEX_INITIALIZER;
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/* virus log path */
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic char vscand_vlog[MAXPATHLEN];
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/* user and group ids - default to 0 */
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic uid_t root_uid = 0, daemon_uid = 0;
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic gid_t sys_gid = 0;
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/* local function prototypes */
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic void vscand_sig_handler(int);
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic int vscand_parse_args(int, char **);
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic void vscand_get_uid_gid();
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic int vscand_init_file(char *, uid_t, gid_t, mode_t);
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic void vscand_usage(char *);
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic int vscand_daemonize_init(void);
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic void vscand_daemonize_fini(int, int);
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic int vscand_init(void);
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic void vscand_fini(void);
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic int vscand_configure(void);
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic int vscand_kernel_bind(void);
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic void vscand_kernel_unbind(void);
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic int vscand_kernel_enable(int);
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic void vscand_kernel_disable(void);
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic int vscand_kernel_config(vs_config_t *);
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic void vscand_error(const char *);
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic int vscand_get_viruslog(void);
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
911106dfb16696472af8c1b7b4c554a829354fa8jm * Enable libumem debugging by default on DEBUG builds.
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jm#ifdef DEBUG
911106dfb16696472af8c1b7b4c554a829354fa8jmconst char *
911106dfb16696472af8c1b7b4c554a829354fa8jm_umem_debug_init(void)
911106dfb16696472af8c1b7b4c554a829354fa8jm{
911106dfb16696472af8c1b7b4c554a829354fa8jm return ("default,verbose"); /* $UMEM_DEBUG setting */
911106dfb16696472af8c1b7b4c554a829354fa8jm}
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jmconst char *
911106dfb16696472af8c1b7b4c554a829354fa8jm_umem_logging_init(void)
911106dfb16696472af8c1b7b4c554a829354fa8jm{
911106dfb16696472af8c1b7b4c554a829354fa8jm return ("fail,contents"); /* $UMEM_LOGGING setting */
911106dfb16696472af8c1b7b4c554a829354fa8jm}
911106dfb16696472af8c1b7b4c554a829354fa8jm#endif
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_sig_handler
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic void
911106dfb16696472af8c1b7b4c554a829354fa8jmvscand_sig_handler(int sig)
911106dfb16696472af8c1b7b4c554a829354fa8jm{
911106dfb16696472af8c1b7b4c554a829354fa8jm if (vscand_sigval == 0)
911106dfb16696472af8c1b7b4c554a829354fa8jm vscand_sigval = sig;
911106dfb16696472af8c1b7b4c554a829354fa8jm}
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
911106dfb16696472af8c1b7b4c554a829354fa8jm * main
911106dfb16696472af8c1b7b4c554a829354fa8jm *
911106dfb16696472af8c1b7b4c554a829354fa8jm * main must return SMF return code (see smf_method (5)) if vscand
911106dfb16696472af8c1b7b4c554a829354fa8jm * is invoked directly by smf (see manifest: vscan.xml)
911106dfb16696472af8c1b7b4c554a829354fa8jm * Exit codes: SMF_EXIT_ERR_CONFIG - error
911106dfb16696472af8c1b7b4c554a829354fa8jm * SMF_EXIT_ERR_FATAL - fatal error
911106dfb16696472af8c1b7b4c554a829354fa8jm * SMF_EXIT_OK - success
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jmint
911106dfb16696472af8c1b7b4c554a829354fa8jmmain(int argc, char **argv)
911106dfb16696472af8c1b7b4c554a829354fa8jm{
911106dfb16696472af8c1b7b4c554a829354fa8jm int err_stat = 0, pfd = -1;
911106dfb16696472af8c1b7b4c554a829354fa8jm sigset_t set;
911106dfb16696472af8c1b7b4c554a829354fa8jm struct sigaction act;
911106dfb16696472af8c1b7b4c554a829354fa8jm mode_t log_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
911106dfb16696472af8c1b7b4c554a829354fa8jm mode_t door_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) setlocale(LC_ALL, "");
911106dfb16696472af8c1b7b4c554a829354fa8jm openlog("vscand", 0, LOG_DAEMON);
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm /* check if running in global zone; other zones not supported */
911106dfb16696472af8c1b7b4c554a829354fa8jm if (getzoneid() != GLOBAL_ZONEID) {
911106dfb16696472af8c1b7b4c554a829354fa8jm vscand_error(gettext("non-global zone not supported"));
911106dfb16696472af8c1b7b4c554a829354fa8jm exit(SMF_EXIT_ERR_FATAL);
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm /* check for a Trusted Solaris environment; not supported */
911106dfb16696472af8c1b7b4c554a829354fa8jm if (is_system_labeled()) {
911106dfb16696472af8c1b7b4c554a829354fa8jm vscand_error(gettext("Trusted Extensions not supported"));
911106dfb16696472af8c1b7b4c554a829354fa8jm exit(SMF_EXIT_ERR_FATAL);
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm /* Parse arguments */
911106dfb16696472af8c1b7b4c554a829354fa8jm if (vscand_parse_args(argc, argv) != 0)
911106dfb16696472af8c1b7b4c554a829354fa8jm exit(SMF_EXIT_ERR_CONFIG);
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm vscand_get_uid_gid();
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm /*
911106dfb16696472af8c1b7b4c554a829354fa8jm * Initializetion of virus log and statistic door file
911106dfb16696472af8c1b7b4c554a829354fa8jm * MUST be done BEFORE vscand_daemonize_init resets uid/gid.
911106dfb16696472af8c1b7b4c554a829354fa8jm * Only root can create the files in /var/log and /var/run.
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jm if ((vscand_get_viruslog() != 0) ||
911106dfb16696472af8c1b7b4c554a829354fa8jm (vscand_vlog[0] == '\0') ||
911106dfb16696472af8c1b7b4c554a829354fa8jm (vscand_init_file(vscand_vlog, root_uid, sys_gid, log_mode) != 0)) {
911106dfb16696472af8c1b7b4c554a829354fa8jm *vscand_vlog = 0;
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) unlink(VS_STATS_DOOR_NAME);
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) vscand_init_file(VS_STATS_DOOR_NAME,
911106dfb16696472af8c1b7b4c554a829354fa8jm daemon_uid, sys_gid, door_mode);
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm /*
911106dfb16696472af8c1b7b4c554a829354fa8jm * Once we're done setting our global state up, set up signal handlers
911106dfb16696472af8c1b7b4c554a829354fa8jm * for ensuring orderly termination on SIGTERM. If we are starting in
911106dfb16696472af8c1b7b4c554a829354fa8jm * the foreground, we also use the same handler for SIGINT and SIGHUP.
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) sigfillset(&set);
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) sigdelset(&set, SIGABRT); /* always unblocked for ASSERT() */
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) sigfillset(&act.sa_mask);
911106dfb16696472af8c1b7b4c554a829354fa8jm act.sa_handler = vscand_sig_handler;
911106dfb16696472af8c1b7b4c554a829354fa8jm act.sa_flags = 0;
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) sigaction(SIGTERM, &act, NULL);
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) sigaction(SIGHUP, &act, NULL); /* Refresh config */
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) sigaction(SIGINT, &act, NULL);
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) sigaction(SIGUSR1, &act, NULL);
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) sigdelset(&set, SIGTERM);
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) sigdelset(&set, SIGHUP);
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) sigdelset(&set, SIGINT);
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) sigdelset(&set, SIGUSR1);
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm if (vscand_fg) {
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) sigdelset(&set, SIGTSTP);
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) sigdelset(&set, SIGTTIN);
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) sigdelset(&set, SIGTTOU);
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm if (vscand_init() != 0) {
911106dfb16696472af8c1b7b4c554a829354fa8jm vscand_error(gettext("failed to initialize service"));
911106dfb16696472af8c1b7b4c554a829354fa8jm exit(SMF_EXIT_ERR_CONFIG);
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm } else {
911106dfb16696472af8c1b7b4c554a829354fa8jm /*
911106dfb16696472af8c1b7b4c554a829354fa8jm * "pfd" is a pipe descriptor -- any fatal errors
911106dfb16696472af8c1b7b4c554a829354fa8jm * during subsequent initialization of the child
911106dfb16696472af8c1b7b4c554a829354fa8jm * process should be written to this pipe and the
911106dfb16696472af8c1b7b4c554a829354fa8jm * parent will report this error as the exit status.
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jm pfd = vscand_daemonize_init();
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm if (vscand_init() != 0) {
911106dfb16696472af8c1b7b4c554a829354fa8jm vscand_error(gettext("failed to initialize service"));
911106dfb16696472af8c1b7b4c554a829354fa8jm exit(SMF_EXIT_ERR_CONFIG);
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm vscand_daemonize_fini(pfd, err_stat);
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm vscand_state = VS_STATE_RUNNING;
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm /* Wait here until shutdown */
911106dfb16696472af8c1b7b4c554a829354fa8jm while (vscand_state == VS_STATE_RUNNING) {
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) sigsuspend(&set);
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm switch (vscand_sigval) {
911106dfb16696472af8c1b7b4c554a829354fa8jm case 0:
911106dfb16696472af8c1b7b4c554a829354fa8jm case SIGUSR1:
911106dfb16696472af8c1b7b4c554a829354fa8jm break;
911106dfb16696472af8c1b7b4c554a829354fa8jm case SIGHUP:
911106dfb16696472af8c1b7b4c554a829354fa8jm if (vscand_configure() != 0)
911106dfb16696472af8c1b7b4c554a829354fa8jm vscand_state = VS_STATE_SHUTDOWN;
911106dfb16696472af8c1b7b4c554a829354fa8jm break;
911106dfb16696472af8c1b7b4c554a829354fa8jm default:
911106dfb16696472af8c1b7b4c554a829354fa8jm vscand_state = VS_STATE_SHUTDOWN;
911106dfb16696472af8c1b7b4c554a829354fa8jm break;
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm vscand_sigval = 0;
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm vscand_fini();
911106dfb16696472af8c1b7b4c554a829354fa8jm return (SMF_EXIT_OK);
911106dfb16696472af8c1b7b4c554a829354fa8jm}
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
911106dfb16696472af8c1b7b4c554a829354fa8jm * vscand_parse_args -
911106dfb16696472af8c1b7b4c554a829354fa8jm * Routine to parse the arguments to the daemon program
911106dfb16696472af8c1b7b4c554a829354fa8jm * 'f' argument runs process in the foreground instead of as a daemon
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jmint
911106dfb16696472af8c1b7b4c554a829354fa8jmvscand_parse_args(int argc, char **argv)
911106dfb16696472af8c1b7b4c554a829354fa8jm{
911106dfb16696472af8c1b7b4c554a829354fa8jm int optchar;
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm while ((optchar = getopt(argc, argv, "f?")) != EOF) {
911106dfb16696472af8c1b7b4c554a829354fa8jm switch (optchar) {
911106dfb16696472af8c1b7b4c554a829354fa8jm case 'f':
911106dfb16696472af8c1b7b4c554a829354fa8jm vscand_fg = 1;
911106dfb16696472af8c1b7b4c554a829354fa8jm break;
911106dfb16696472af8c1b7b4c554a829354fa8jm default:
911106dfb16696472af8c1b7b4c554a829354fa8jm vscand_usage(argv[0]);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm return (0);
911106dfb16696472af8c1b7b4c554a829354fa8jm}
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
911106dfb16696472af8c1b7b4c554a829354fa8jm * vscand_usage
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic void
911106dfb16696472af8c1b7b4c554a829354fa8jmvscand_usage(char *progname)
911106dfb16696472af8c1b7b4c554a829354fa8jm{
911106dfb16696472af8c1b7b4c554a829354fa8jm char buf[128];
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) snprintf(buf, sizeof (buf), "%s %s [-f]",
911106dfb16696472af8c1b7b4c554a829354fa8jm gettext("Usage"), progname);
911106dfb16696472af8c1b7b4c554a829354fa8jm vscand_error(buf);
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) snprintf(buf, sizeof (buf), "\t-f %s\n",
911106dfb16696472af8c1b7b4c554a829354fa8jm gettext("run program in foreground"));
911106dfb16696472af8c1b7b4c554a829354fa8jm vscand_error(buf);
911106dfb16696472af8c1b7b4c554a829354fa8jm}
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
911106dfb16696472af8c1b7b4c554a829354fa8jm * vscand_get_uid_gid
911106dfb16696472af8c1b7b4c554a829354fa8jm *
911106dfb16696472af8c1b7b4c554a829354fa8jm * failure to access a uid/gid results in the default (0) being used.
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic void
911106dfb16696472af8c1b7b4c554a829354fa8jmvscand_get_uid_gid()
911106dfb16696472af8c1b7b4c554a829354fa8jm{
911106dfb16696472af8c1b7b4c554a829354fa8jm struct passwd *pwd;
911106dfb16696472af8c1b7b4c554a829354fa8jm struct group *grp;
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm if ((pwd = getpwnam("root")) != NULL)
911106dfb16696472af8c1b7b4c554a829354fa8jm root_uid = pwd->pw_uid;
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm if ((pwd = getpwnam("daemon")) != NULL)
911106dfb16696472af8c1b7b4c554a829354fa8jm daemon_uid = pwd->pw_uid;
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm if ((grp = getgrnam("sys")) != NULL)
911106dfb16696472af8c1b7b4c554a829354fa8jm sys_gid = grp->gr_gid;
911106dfb16696472af8c1b7b4c554a829354fa8jm}
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
911106dfb16696472af8c1b7b4c554a829354fa8jm * vscand_daemonize_init
911106dfb16696472af8c1b7b4c554a829354fa8jm *
911106dfb16696472af8c1b7b4c554a829354fa8jm * This function will fork off a child process, from which
911106dfb16696472af8c1b7b4c554a829354fa8jm * only the child will return.
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic int
911106dfb16696472af8c1b7b4c554a829354fa8jmvscand_daemonize_init(void)
911106dfb16696472af8c1b7b4c554a829354fa8jm{
911106dfb16696472af8c1b7b4c554a829354fa8jm int status, pfds[2];
911106dfb16696472af8c1b7b4c554a829354fa8jm sigset_t set, oset;
911106dfb16696472af8c1b7b4c554a829354fa8jm pid_t pid;
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm /*
911106dfb16696472af8c1b7b4c554a829354fa8jm * Reset process owner/group to daemon/sys. Root ownership is only
911106dfb16696472af8c1b7b4c554a829354fa8jm * required to initialize virus log file in /var/log
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jm if (__init_daemon_priv(PU_RESETGROUPS | PU_LIMITPRIVS,
911106dfb16696472af8c1b7b4c554a829354fa8jm daemon_uid, sys_gid,
911106dfb16696472af8c1b7b4c554a829354fa8jm PRIV_PROC_AUDIT, PRIV_FILE_DAC_SEARCH, PRIV_FILE_DAC_READ,
911106dfb16696472af8c1b7b4c554a829354fa8jm PRIV_FILE_FLAG_SET, NULL) != 0) {
911106dfb16696472af8c1b7b4c554a829354fa8jm vscand_error(gettext("failed to initialize privileges"));
911106dfb16696472af8c1b7b4c554a829354fa8jm _exit(SMF_EXIT_ERR_FATAL);
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm /*
911106dfb16696472af8c1b7b4c554a829354fa8jm * Block all signals prior to the fork and leave them blocked in the
911106dfb16696472af8c1b7b4c554a829354fa8jm * parent so we don't get in a situation where the parent gets SIGINT
911106dfb16696472af8c1b7b4c554a829354fa8jm * and returns non-zero exit status and the child is actually running.
911106dfb16696472af8c1b7b4c554a829354fa8jm * In the child, restore the signal mask once we've done our setsid().
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) sigfillset(&set);
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) sigdelset(&set, SIGABRT);
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) sigprocmask(SIG_BLOCK, &set, &oset);
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm if (pipe(pfds) == -1) {
911106dfb16696472af8c1b7b4c554a829354fa8jm vscand_error(gettext("failed to create pipe for daemonize"));
911106dfb16696472af8c1b7b4c554a829354fa8jm _exit(SMF_EXIT_ERR_FATAL);
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm if ((pid = fork()) == -1) {
911106dfb16696472af8c1b7b4c554a829354fa8jm vscand_error(gettext("failed to fork for daemonize"));
911106dfb16696472af8c1b7b4c554a829354fa8jm _exit(SMF_EXIT_ERR_FATAL);
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm /*
911106dfb16696472af8c1b7b4c554a829354fa8jm * If we're the parent process, wait for either the child to send us
911106dfb16696472af8c1b7b4c554a829354fa8jm * the appropriate exit status over the pipe or for the read to fail
911106dfb16696472af8c1b7b4c554a829354fa8jm * (presumably with 0 for EOF if our child terminated abnormally).
911106dfb16696472af8c1b7b4c554a829354fa8jm * If the read fails, exit with either the child's exit status if it
911106dfb16696472af8c1b7b4c554a829354fa8jm * exited or with SMF_EXIT_ERR_FATAL if it died from a fatal signal.
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jm if (pid != 0) {
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) close(pfds[1]);
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm if (read(pfds[0], &status, sizeof (status)) == sizeof (status))
911106dfb16696472af8c1b7b4c554a829354fa8jm _exit(status);
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm if (waitpid(pid, &status, 0) == pid && WIFEXITED(status))
911106dfb16696472af8c1b7b4c554a829354fa8jm _exit(WEXITSTATUS(status));
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm vscand_error(gettext("failed to daemonize"));
911106dfb16696472af8c1b7b4c554a829354fa8jm _exit(SMF_EXIT_ERR_FATAL);
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) setsid();
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) sigprocmask(SIG_SETMASK, &oset, NULL);
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) chdir("/");
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) umask(022);
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) close(pfds[0]);
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm return (pfds[1]);
911106dfb16696472af8c1b7b4c554a829354fa8jm}
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
911106dfb16696472af8c1b7b4c554a829354fa8jm * vscand_daemonize_fini
911106dfb16696472af8c1b7b4c554a829354fa8jm * Now that we're running, if a pipe fd was specified, write an exit
911106dfb16696472af8c1b7b4c554a829354fa8jm * status to it to indicate that our parent process can safely detach.
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic void
911106dfb16696472af8c1b7b4c554a829354fa8jmvscand_daemonize_fini(int fd, int err_status)
911106dfb16696472af8c1b7b4c554a829354fa8jm{
911106dfb16696472af8c1b7b4c554a829354fa8jm if (fd >= 0)
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) write(fd, &err_status, sizeof (err_status));
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) close(fd);
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm /* Restore standard file descriptors */
911106dfb16696472af8c1b7b4c554a829354fa8jm if ((fd = open("/dev/null", O_RDWR)) >= 0) {
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) fcntl(fd, F_DUP2FD, STDIN_FILENO);
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) fcntl(fd, F_DUP2FD, STDOUT_FILENO);
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) fcntl(fd, F_DUP2FD, STDERR_FILENO);
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) close(fd);
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm /* clear basic privileges not required by vscand */
911106dfb16696472af8c1b7b4c554a829354fa8jm __fini_daemon_priv(PRIV_PROC_FORK, PRIV_PROC_EXEC, PRIV_PROC_SESSION,
911106dfb16696472af8c1b7b4c554a829354fa8jm PRIV_FILE_LINK_ANY, PRIV_PROC_INFO, (char *)NULL);
911106dfb16696472af8c1b7b4c554a829354fa8jm}
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
911106dfb16696472af8c1b7b4c554a829354fa8jm * vscand_init_file
911106dfb16696472af8c1b7b4c554a829354fa8jm *
911106dfb16696472af8c1b7b4c554a829354fa8jm * create specified file and set its uid, gid and mode
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic int
911106dfb16696472af8c1b7b4c554a829354fa8jmvscand_init_file(char *filepath, uid_t uid, gid_t gid, mode_t mode)
911106dfb16696472af8c1b7b4c554a829354fa8jm{
911106dfb16696472af8c1b7b4c554a829354fa8jm int fd, rc = 0;
911106dfb16696472af8c1b7b4c554a829354fa8jm struct stat stat_buf;
911106dfb16696472af8c1b7b4c554a829354fa8jm char buf[MAXPATHLEN];
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm if ((fd = open(filepath, O_RDONLY | O_CREAT, mode)) == -1)
911106dfb16696472af8c1b7b4c554a829354fa8jm rc = -1;
911106dfb16696472af8c1b7b4c554a829354fa8jm else {
911106dfb16696472af8c1b7b4c554a829354fa8jm if (fstat(fd, &stat_buf) != 0)
911106dfb16696472af8c1b7b4c554a829354fa8jm rc = -1;
911106dfb16696472af8c1b7b4c554a829354fa8jm else {
911106dfb16696472af8c1b7b4c554a829354fa8jm if (stat_buf.st_mode != mode) {
911106dfb16696472af8c1b7b4c554a829354fa8jm if (fchmod(fd, mode) != 0)
911106dfb16696472af8c1b7b4c554a829354fa8jm rc = -1;
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm if ((stat_buf.st_uid != uid) ||
911106dfb16696472af8c1b7b4c554a829354fa8jm (stat_buf.st_gid != gid)) {
911106dfb16696472af8c1b7b4c554a829354fa8jm if (fchown(fd, uid, gid) != 0)
911106dfb16696472af8c1b7b4c554a829354fa8jm rc = -1;
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) close(fd);
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm if (rc == -1) {
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) snprintf(buf, MAXPATHLEN, "%s %s",
911106dfb16696472af8c1b7b4c554a829354fa8jm gettext("Failed to initialize"), filepath);
911106dfb16696472af8c1b7b4c554a829354fa8jm vscand_error(buf);
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm return (rc);
911106dfb16696472af8c1b7b4c554a829354fa8jm}
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
911106dfb16696472af8c1b7b4c554a829354fa8jm * vscand_init
911106dfb16696472af8c1b7b4c554a829354fa8jm *
911106dfb16696472af8c1b7b4c554a829354fa8jm * There are some requirements on the order in which the daemon
911106dfb16696472af8c1b7b4c554a829354fa8jm * initialization functions are called.
911106dfb16696472af8c1b7b4c554a829354fa8jm *
911106dfb16696472af8c1b7b4c554a829354fa8jm * - vscand_kernel_bind - bind to kernel module
911106dfb16696472af8c1b7b4c554a829354fa8jm * - vs_eng_init populates vs_icap data and thus vs_icap_init MUST be
911106dfb16696472af8c1b7b4c554a829354fa8jm * called before vs_eng_init
911106dfb16696472af8c1b7b4c554a829354fa8jm * - vscand_configure - load the configuration
911106dfb16696472af8c1b7b4c554a829354fa8jm * - vs_door_init - start vscan door server
911106dfb16696472af8c1b7b4c554a829354fa8jm * - vscand_kernel_enable - enable scan requests from kernel
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic int
911106dfb16696472af8c1b7b4c554a829354fa8jmvscand_init(void)
911106dfb16696472af8c1b7b4c554a829354fa8jm{
911106dfb16696472af8c1b7b4c554a829354fa8jm int door_fd = -1;
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm if (vscand_kernel_bind() < 0)
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm if (vs_stats_init() != 0)
911106dfb16696472af8c1b7b4c554a829354fa8jm vscand_error(
911106dfb16696472af8c1b7b4c554a829354fa8jm gettext("failed to initialize statistics interface"));
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm vs_svc_init();
911106dfb16696472af8c1b7b4c554a829354fa8jm vs_icap_init();
911106dfb16696472af8c1b7b4c554a829354fa8jm vs_eng_init();
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm if (vscand_configure() != 0) {
911106dfb16696472af8c1b7b4c554a829354fa8jm vscand_error(gettext("failed to initialize configuration"));
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm if (((door_fd = vs_door_init()) < 0) ||
911106dfb16696472af8c1b7b4c554a829354fa8jm (vscand_kernel_enable(door_fd) < 0)) {
911106dfb16696472af8c1b7b4c554a829354fa8jm vscand_fini();
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm return (0);
911106dfb16696472af8c1b7b4c554a829354fa8jm}
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
911106dfb16696472af8c1b7b4c554a829354fa8jm * vscand_fini
911106dfb16696472af8c1b7b4c554a829354fa8jm *
911106dfb16696472af8c1b7b4c554a829354fa8jm * vscand_kernel_disable - should be called first to ensure that no
911106dfb16696472af8c1b7b4c554a829354fa8jm * more scan requests are initiated from the kernel module
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_door_fini - shouldn't be called until after the in-progress
911106dfb16696472af8c1b7b4c554a829354fa8jm * scans complete (vs_eng_fini waits for in progress scans)
911106dfb16696472af8c1b7b4c554a829354fa8jm * vscand_kernel_unbind - should be called last to tell the kernel module
911106dfb16696472af8c1b7b4c554a829354fa8jm * that vscand is shutdown.
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic void
911106dfb16696472af8c1b7b4c554a829354fa8jmvscand_fini(void)
911106dfb16696472af8c1b7b4c554a829354fa8jm{
911106dfb16696472af8c1b7b4c554a829354fa8jm vscand_kernel_disable();
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm vs_svc_fini();
911106dfb16696472af8c1b7b4c554a829354fa8jm vs_eng_fini();
911106dfb16696472af8c1b7b4c554a829354fa8jm vs_icap_fini();
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm vs_door_fini();
911106dfb16696472af8c1b7b4c554a829354fa8jm vs_stats_fini();
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm vscand_kernel_unbind();
911106dfb16696472af8c1b7b4c554a829354fa8jm}
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
911106dfb16696472af8c1b7b4c554a829354fa8jm * vscand_configure
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic int
911106dfb16696472af8c1b7b4c554a829354fa8jmvscand_configure(void)
911106dfb16696472af8c1b7b4c554a829354fa8jm{
911106dfb16696472af8c1b7b4c554a829354fa8jm uint32_t len;
911106dfb16696472af8c1b7b4c554a829354fa8jm vs_config_t kconfig;
911106dfb16696472af8c1b7b4c554a829354fa8jm vs_props_all_t config;
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) pthread_mutex_lock(&vscand_cfg_mutex);
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) memset(&config, 0, sizeof (vs_props_all_t));
911106dfb16696472af8c1b7b4c554a829354fa8jm if (vs_props_get_all(&config) != VS_ERR_NONE) {
911106dfb16696472af8c1b7b4c554a829354fa8jm vscand_error(gettext("configuration data error"));
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) pthread_mutex_unlock(&vscand_cfg_mutex);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) memset(&kconfig, 0, sizeof (vs_config_t));
911106dfb16696472af8c1b7b4c554a829354fa8jm len = sizeof (kconfig.vsc_types);
911106dfb16696472af8c1b7b4c554a829354fa8jm if (vs_parse_types(config.va_props.vp_types,
911106dfb16696472af8c1b7b4c554a829354fa8jm kconfig.vsc_types, &len) != 0) {
911106dfb16696472af8c1b7b4c554a829354fa8jm vscand_error(gettext("configuration data error - types"));
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) pthread_mutex_unlock(&vscand_cfg_mutex);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm kconfig.vsc_types_len = len;
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm /* Convert the maxfsize string from the configuration into bytes */
911106dfb16696472af8c1b7b4c554a829354fa8jm if (vs_strtonum(config.va_props.vp_maxsize,
911106dfb16696472af8c1b7b4c554a829354fa8jm &kconfig.vsc_max_size) != 0) {
911106dfb16696472af8c1b7b4c554a829354fa8jm vscand_error(gettext("configuration data error - max-size"));
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) pthread_mutex_unlock(&vscand_cfg_mutex);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm kconfig.vsc_allow = config.va_props.vp_maxsize_action ? 1LL : 0LL;
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm /* Send configuration update to kernel */
911106dfb16696472af8c1b7b4c554a829354fa8jm if (vscand_kernel_config(&kconfig) != 0) {
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) pthread_mutex_unlock(&vscand_cfg_mutex);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm /* Tell vs_eng things have changed. */
911106dfb16696472af8c1b7b4c554a829354fa8jm vs_eng_config(&config);
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm /* Tell vs_stats things have changed */
911106dfb16696472af8c1b7b4c554a829354fa8jm vs_stats_config(&config);
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) pthread_mutex_unlock(&vscand_cfg_mutex);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (0);
911106dfb16696472af8c1b7b4c554a829354fa8jm}
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
911106dfb16696472af8c1b7b4c554a829354fa8jm * vscand_get_state
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jmvs_daemon_state_t
911106dfb16696472af8c1b7b4c554a829354fa8jmvscand_get_state(void)
911106dfb16696472af8c1b7b4c554a829354fa8jm{
911106dfb16696472af8c1b7b4c554a829354fa8jm return (vscand_state);
911106dfb16696472af8c1b7b4c554a829354fa8jm}
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
911106dfb16696472af8c1b7b4c554a829354fa8jm * vscand_get_viruslog
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic int
911106dfb16696472af8c1b7b4c554a829354fa8jmvscand_get_viruslog()
911106dfb16696472af8c1b7b4c554a829354fa8jm{
911106dfb16696472af8c1b7b4c554a829354fa8jm vs_props_t props;
911106dfb16696472af8c1b7b4c554a829354fa8jm uint64_t propids;
911106dfb16696472af8c1b7b4c554a829354fa8jm int rc;
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm propids = VS_PROPID_VLOG;
911106dfb16696472af8c1b7b4c554a829354fa8jm if ((rc = vs_props_get(&props, propids)) != VS_ERR_NONE) {
911106dfb16696472af8c1b7b4c554a829354fa8jm vscand_error(vs_strerror(rc));
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) strlcpy(vscand_vlog, props.vp_vlog, sizeof (vscand_vlog));
911106dfb16696472af8c1b7b4c554a829354fa8jm return (0);
911106dfb16696472af8c1b7b4c554a829354fa8jm}
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
911106dfb16696472af8c1b7b4c554a829354fa8jm * vscand_viruslog
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jmchar *
911106dfb16696472af8c1b7b4c554a829354fa8jmvscand_viruslog(void)
911106dfb16696472af8c1b7b4c554a829354fa8jm{
911106dfb16696472af8c1b7b4c554a829354fa8jm if (vscand_vlog[0] == '\0')
911106dfb16696472af8c1b7b4c554a829354fa8jm return (NULL);
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm return (vscand_vlog);
911106dfb16696472af8c1b7b4c554a829354fa8jm}
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
911106dfb16696472af8c1b7b4c554a829354fa8jm * vscand_kernel_bind
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic int
911106dfb16696472af8c1b7b4c554a829354fa8jmvscand_kernel_bind(void)
911106dfb16696472af8c1b7b4c554a829354fa8jm{
911106dfb16696472af8c1b7b4c554a829354fa8jm char devname[MAXPATHLEN];
911106dfb16696472af8c1b7b4c554a829354fa8jm int inst = 0;
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) snprintf(devname, MAXPATHLEN, "%s%d", VS_DRV_PATH, inst);
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm if ((vscand_kdrv_fd = open(devname, O_RDONLY)) < 0) {
911106dfb16696472af8c1b7b4c554a829354fa8jm vscand_error(gettext("failed to bind to kernel"));
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm return (0);
911106dfb16696472af8c1b7b4c554a829354fa8jm}
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
911106dfb16696472af8c1b7b4c554a829354fa8jm * vscand_kernel_unbind
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic void
911106dfb16696472af8c1b7b4c554a829354fa8jmvscand_kernel_unbind(void)
911106dfb16696472af8c1b7b4c554a829354fa8jm{
911106dfb16696472af8c1b7b4c554a829354fa8jm if (vscand_kdrv_fd >= 0)
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) close(vscand_kdrv_fd);
911106dfb16696472af8c1b7b4c554a829354fa8jm}
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
911106dfb16696472af8c1b7b4c554a829354fa8jm * vscand_kernel_enable
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic int
911106dfb16696472af8c1b7b4c554a829354fa8jmvscand_kernel_enable(int door_fd)
911106dfb16696472af8c1b7b4c554a829354fa8jm{
911106dfb16696472af8c1b7b4c554a829354fa8jm if (ioctl(vscand_kdrv_fd, VS_DRV_IOCTL_ENABLE, door_fd) < 0) {
911106dfb16696472af8c1b7b4c554a829354fa8jm vscand_error(gettext("failed to bind to kernel"));
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) close(vscand_kdrv_fd);
911106dfb16696472af8c1b7b4c554a829354fa8jm vscand_kdrv_fd = -1;
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm return (0);
911106dfb16696472af8c1b7b4c554a829354fa8jm}
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
911106dfb16696472af8c1b7b4c554a829354fa8jm * vscand_kernel_disable
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic void
911106dfb16696472af8c1b7b4c554a829354fa8jmvscand_kernel_disable()
911106dfb16696472af8c1b7b4c554a829354fa8jm{
911106dfb16696472af8c1b7b4c554a829354fa8jm if (vscand_kdrv_fd >= 0)
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) ioctl(vscand_kdrv_fd, VS_DRV_IOCTL_DISABLE);
911106dfb16696472af8c1b7b4c554a829354fa8jm}
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
911106dfb16696472af8c1b7b4c554a829354fa8jm * vscand_kernel_config
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jmint
911106dfb16696472af8c1b7b4c554a829354fa8jmvscand_kernel_config(vs_config_t *conf)
911106dfb16696472af8c1b7b4c554a829354fa8jm{
911106dfb16696472af8c1b7b4c554a829354fa8jm if (vscand_kdrv_fd < 0)
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm if (ioctl(vscand_kdrv_fd, VS_DRV_IOCTL_CONFIG, conf) < 0) {
911106dfb16696472af8c1b7b4c554a829354fa8jm vscand_error(gettext("failed to send config to kernel"));
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm return (0);
911106dfb16696472af8c1b7b4c554a829354fa8jm}
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
911106dfb16696472af8c1b7b4c554a829354fa8jm * vscand_error
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic void
911106dfb16696472af8c1b7b4c554a829354fa8jmvscand_error(const char *errmsg)
911106dfb16696472af8c1b7b4c554a829354fa8jm{
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) fprintf(stderr, "vscand: %s", errmsg);
911106dfb16696472af8c1b7b4c554a829354fa8jm syslog(LOG_ERR, "%s\n", errmsg);
911106dfb16696472af8c1b7b4c554a829354fa8jm}