7a286c471efbab8562f7655a82931904703fffe0Dai Ngo/*
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo * CDDL HEADER START
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo *
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo * The contents of this file are subject to the terms of the
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo * Common Development and Distribution License (the "License").
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo * You may not use this file except in compliance with the License.
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo *
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo * or http://www.opensolaris.org/os/licensing.
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo * See the License for the specific language governing permissions
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo * and limitations under the License.
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo *
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo * When distributing Covered Code, include this CDDL HEADER in each
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo * If applicable, add the following below this CDDL HEADER, with the
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo * fields enclosed by brackets "[]" replaced with your own identifying
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo * information: Portions Copyright [yyyy] [name of copyright owner]
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo *
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo * CDDL HEADER END
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo */
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo/*
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo * Use is subject to license terms.
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo */
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo/*
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo * Reparsed daemon
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo */
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo#include <stdio.h>
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo#include <stdio_ext.h>
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo#include <stdlib.h>
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo#include <unistd.h>
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo#include <signal.h>
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo#include <sys/types.h>
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo#include <sys/stat.h>
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo#include <fcntl.h>
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo#include <memory.h>
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo#include <alloca.h>
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo#include <ucontext.h>
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo#include <errno.h>
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo#include <syslog.h>
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo#include <string.h>
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo#include <strings.h>
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo#include <door.h>
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo#include <wait.h>
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo#include <libintl.h>
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo#include <locale.h>
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo#include <sys/param.h>
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo#include <sys/systeminfo.h>
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo#include <sys/thread.h>
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo#include <rpc/xdr.h>
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo#include <priv.h>
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo#include <sys/fs_reparse.h>
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo#include <priv_utils.h>
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo#include <rpcsvc/daemon_utils.h>
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo#define REPARSED_CMD_OPTS "v"
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo#define DOOR_RESULT_BUFSZ (MAXPATHLEN + sizeof (reparsed_door_res_t))
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo#define SAFETY_BUFFER 8*1024
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngostatic char *MyName;
7a286c471efbab8562f7655a82931904703fffe0Dai Ngostatic int verbose = 0;
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngostatic int start_reparsed_svcs();
7a286c471efbab8562f7655a82931904703fffe0Dai Ngostatic void daemonize(void);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngostatic void reparsed_door_call_error(int error, int buflen);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngostatic void reparsed_doorfunc(void *cookie, char *argp, size_t arg_size,
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo door_desc_t *dp, uint_t n_desc);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngostatic void
7a286c471efbab8562f7655a82931904703fffe0Dai Ngousage()
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo{
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo syslog(LOG_ERR, "Usage: %s", MyName);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo syslog(LOG_ERR, "\t[-v]\t\tverbose error messages)");
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo exit(1);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo}
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngostatic void
7a286c471efbab8562f7655a82931904703fffe0Dai Ngowarn_hup(int i)
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo{
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo syslog(LOG_ERR, "SIGHUP received: ignored");
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo (void) signal(SIGHUP, warn_hup);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo}
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo/*
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo * Processing for daemonization
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo */
7a286c471efbab8562f7655a82931904703fffe0Dai Ngostatic void
7a286c471efbab8562f7655a82931904703fffe0Dai Ngodaemonize(void)
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo{
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo switch (fork()) {
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo case -1:
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo syslog(LOG_ERR, "reparsed: can't fork - errno %d", errno);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo exit(2);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo /* NOTREACHED */
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo case 0: /* child */
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo break;
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo default: /* parent */
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo _exit(0);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo }
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo (void) chdir("/");
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo /*
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo * Close stdin, stdout, and stderr.
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo * Open again to redirect input+output
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo */
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo (void) close(0);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo (void) close(1);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo (void) close(2);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo (void) open("/dev/null", O_RDONLY);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo (void) open("/dev/null", O_WRONLY);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo (void) dup(1);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo (void) setsid();
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo}
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngoint
7a286c471efbab8562f7655a82931904703fffe0Dai Ngomain(int argc, char *argv[])
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo{
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo pid_t pid;
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo int c, error;
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo struct rlimit rlset;
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo char *defval;
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo /*
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo * There is no check for non-global zone and Trusted Extensions.
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo * Reparsed works in both of these environments as long as the
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo * services that use reparsed are supported.
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo */
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo MyName = argv[0];
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo if (geteuid() != 0) {
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo syslog(LOG_ERR, "%s must be run as root", MyName);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo exit(1);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo }
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo while ((c = getopt(argc, argv, REPARSED_CMD_OPTS)) != EOF) {
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo switch (c) {
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo case 'v':
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo verbose++;
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo break;
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo default:
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo usage();
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo }
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo }
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo daemonize();
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo openlog(MyName, LOG_PID | LOG_NDELAY, LOG_DAEMON);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo (void) _create_daemon_lock(REPARSED, DAEMON_UID, DAEMON_GID);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo (void) enable_extended_FILE_stdio(-1, -1);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo switch (_enter_daemon_lock(REPARSED)) {
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo case 0:
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo break;
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo case -1:
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo syslog(LOG_ERR, "Error locking for %s", REPARSED);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo exit(2);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo default:
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo /* daemon was already running */
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo exit(0);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo }
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo (void) signal(SIGHUP, warn_hup);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo /*
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo * Make the process a privilege aware daemon.
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo * Only "basic" privileges are required.
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo *
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo */
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo if (__init_daemon_priv(PU_RESETGROUPS|PU_CLEARLIMITSET, 0, 0,
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo (char *)NULL) == -1) {
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo syslog(LOG_ERR, "should be run with sufficient privileges");
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo exit(3);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo }
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo /*
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo * Clear basic privileges not required by reparsed.
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo */
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo __fini_daemon_priv(PRIV_PROC_FORK, PRIV_PROC_EXEC, PRIV_PROC_SESSION,
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo PRIV_FILE_LINK_ANY, PRIV_PROC_INFO, (char *)NULL);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo return (start_reparsed_svcs());
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo}
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngostatic void
7a286c471efbab8562f7655a82931904703fffe0Dai Ngoreparsed_door_call_error(int error, int buflen)
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo{
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo reparsed_door_res_t rpd_res;
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo memset(&rpd_res, 0, sizeof (reparsed_door_res_t));
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo rpd_res.res_status = error;
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo rpd_res.res_len = buflen;
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo door_return((char *)&rpd_res, sizeof (reparsed_door_res_t), NULL, 0);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo (void) door_return(NULL, 0, NULL, 0);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo /* NOTREACHED */
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo}
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo/*
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo * reparsed_doorfunc
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo *
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo * argp: "service_type:service_data" string
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo * dp & n_desc: not used.
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo */
7a286c471efbab8562f7655a82931904703fffe0Dai Ngostatic void
7a286c471efbab8562f7655a82931904703fffe0Dai Ngoreparsed_doorfunc(void *cookie, char *argp, size_t arg_size,
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo door_desc_t *dp, uint_t n_desc)
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo{
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo int err;
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo size_t bufsz;
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo char *svc_type, *svc_data;
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo char *cp, *buf, *sbuf, res_buf[DOOR_RESULT_BUFSZ];
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo reparsed_door_res_t *resp;
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo if ((argp == NULL) || (arg_size == 0)) {
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo reparsed_door_call_error(EINVAL, 0);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo /* NOTREACHED */
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo }
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo if (verbose)
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo syslog(LOG_NOTICE, "reparsed_door: [%s, %d]", argp, arg_size);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo if ((svc_type = strdup(argp)) == NULL) {
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo reparsed_door_call_error(ENOMEM, 0);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo /* NOTREACHED */
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo }
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo /*
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo * Door argument string comes in "service_type:service_data" format.
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo * Need to break it into separate "service_type" and "service_data"
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo * string before passing them to reparse_deref() to process them.
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo */
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo if ((cp = strchr(svc_type, ':')) == NULL) {
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo free(svc_type);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo reparsed_door_call_error(EINVAL, 0);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo /* NOTREACHED */
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo }
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo *cp++ = '\0';
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo svc_data = cp;
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo /*
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo * Setup buffer for reparse_deref(). 'bufsz' is the actual
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo * buffer size to hold the result returned by reparse_deref().
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo */
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo resp = (reparsed_door_res_t *)res_buf;
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo buf = resp->res_data;
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo bufsz = sizeof (res_buf) - sizeof (reparsed_door_res_t);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo /*
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo * reparse_deref() calls the service type plugin library to process
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo * the service data. The plugin library function should understand
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo * the context of the service data and should be the one to XDR the
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo * results before returning it to the caller.
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo */
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo err = reparse_deref(svc_type, svc_data, buf, &bufsz);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo if (verbose)
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo syslog(LOG_NOTICE,
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo "reparsed_deref(svc_type: %s, data: %s, size: %d) -> %d",
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo svc_type, svc_data, bufsz, err);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo switch (err) {
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo case 0:
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo break;
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo case EOVERFLOW:
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo /*
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo * bufsz was returned with size needed by reparse_deref().
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo *
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo * We cannot use malloc() here because door_return() never
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo * returns, and memory allocated by malloc() would get leaked.
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo */
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo sbuf = alloca(bufsz + sizeof (reparsed_door_res_t));
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo if (sbuf == NULL || stack_inbounds(buf) == 0 ||
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo stack_inbounds(buf + sizeof (reparsed_door_res_t) +
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo SAFETY_BUFFER - 1) == 0) {
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo free(svc_type);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo reparsed_door_call_error(ENOMEM, 0);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo /* NOTREACHED */
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo }
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo resp = (reparsed_door_res_t *)sbuf;
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo if ((err = reparse_deref(svc_type, svc_data, resp->res_data,
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo &bufsz)) == 0)
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo break;
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo /* fall through */
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo default:
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo free(svc_type);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo reparsed_door_call_error(err, 0);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo /* NOTREACHED */
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo }
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo free(svc_type);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo if (verbose)
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo syslog(LOG_NOTICE, "reparsed_door_return <buf=%s> size=%d",
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo buf, bufsz);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo resp->res_status = 0;
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo resp->res_len = bufsz;
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo (void) door_return((char *)resp, bufsz + sizeof (reparsed_door_res_t),
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo NULL, 0);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo (void) door_return(NULL, 0, NULL, 0);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo /* NOTREACHED */
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo}
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngostatic int
7a286c471efbab8562f7655a82931904703fffe0Dai Ngostart_reparsed_svcs()
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo{
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo int doorfd;
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo int dfd;
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo if ((doorfd = door_create(reparsed_doorfunc, NULL,
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo DOOR_REFUSE_DESC|DOOR_NO_CANCEL)) == -1) {
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo syslog(LOG_ERR, "Unable to create door");
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo return (1);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo }
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo /*
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo * Create a file system path for the door
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo */
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo if ((dfd = open(REPARSED_DOOR, O_RDWR|O_CREAT|O_TRUNC,
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) == -1) {
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo syslog(LOG_ERR, "unable to open %s", REPARSED_DOOR);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo (void) close(doorfd);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo return (1);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo }
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo /*
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo * Clean up any stale associations
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo */
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo (void) fdetach(REPARSED_DOOR);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo /*
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo * Register in the kernel namespace for door_ki_open().
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo */
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo if (fattach(doorfd, REPARSED_DOOR) == -1) {
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo syslog(LOG_ERR, "Unable to fattach door %s", REPARSED_DOOR);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo (void) close(doorfd);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo (void) close(dfd);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo return (1);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo }
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo (void) close(dfd);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo /*
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo * Wait for incoming calls
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo */
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo /*CONSTCOND*/
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo while (1)
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo (void) pause();
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo syslog(LOG_ERR, "Door server exited");
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo return (10);
7a286c471efbab8562f7655a82931904703fffe0Dai Ngo}