13b31921jamie/*- 27551d83pfg * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 37551d83pfg * 48d425bfjamie * Copyright (c) 2011 James Gritton. 53b31921jamie * All rights reserved. 63b31921jamie * 73b31921jamie * Redistribution and use in source and binary forms, with or without 83b31921jamie * modification, are permitted provided that the following conditions 93b31921jamie * are met: 103b31921jamie * 1. Redistributions of source code must retain the above copyright 113b31921jamie * notice, this list of conditions and the following disclaimer. 123b31921jamie * 2. Redistributions in binary form must reproduce the above copyright 133b31921jamie * notice, this list of conditions and the following disclaimer in the 143b31921jamie * documentation and/or other materials provided with the distribution. 153b31921jamie * 163b31921jamie * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 173b31921jamie * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 183b31921jamie * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 193b31921jamie * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 203b31921jamie * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 213b31921jamie * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 223b31921jamie * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 233b31921jamie * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 243b31921jamie * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 253b31921jamie * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 263b31921jamie * SUCH DAMAGE. 273b31921jamie * 283b31921jamie * $FreeBSD$ 293b31921jamie */ 303b31921jamie 313b31921jamie#include <sys/param.h> 323b31921jamie#include <sys/types.h> 333b31921jamie#include <sys/jail.h> 343b31921jamie#include <sys/queue.h> 353b31921jamie#include <sys/time.h> 363b31921jamie 373b31921jamie#include <jail.h> 383b31921jamie 393b31921jamie#define CONF_FILE "/etc/jail.conf" 403b31921jamie 413b31921jamie#define DEP_FROM 0 423b31921jamie#define DEP_TO 1 433b31921jamie 443b31921jamie#define DF_SEEN 0x01 /* Dependency has been followed */ 453b31921jamie#define DF_LIGHT 0x02 /* Implied dependency on jail existence only */ 4621a3003eadler#define DF_NOFAIL 0x04 /* Don't propagate failed jails */ 473b31921jamie 483b31921jamie#define PF_VAR 0x01 /* This is a variable, not a true parameter */ 493b31921jamie#define PF_APPEND 0x02 /* Append to existing parameter list */ 503b31921jamie#define PF_BAD 0x04 /* Unable to resolve parameter value */ 513b31921jamie#define PF_INTERNAL 0x08 /* Internal parameter, not passed to kernel */ 523b31921jamie#define PF_BOOL 0x10 /* Boolean parameter */ 533b31921jamie#define PF_INT 0x20 /* Integer parameter */ 54235aefejamie#define PF_CONV 0x40 /* Parameter duplicated in converted form */ 5582d5811jamie#define PF_REV 0x80 /* Run commands in reverse order on stopping */ 566a6f426hrs#define PF_IMMUTABLE 0x100 /* Immutable parameter */ 573b31921jamie 583b31921jamie#define JF_START 0x0001 /* -c */ 593b31921jamie#define JF_SET 0x0002 /* -m */ 603b31921jamie#define JF_STOP 0x0004 /* -r */ 613b31921jamie#define JF_DEPEND 0x0008 /* Operation required by dependency */ 623b31921jamie#define JF_WILD 0x0010 /* Not specified on the command line */ 633b31921jamie#define JF_FAILED 0x0020 /* Operation failed */ 6494aa5f7jamie#define JF_PARAMS 0x0040 /* Parameters checked and imported */ 6594aa5f7jamie#define JF_RDTUN 0x0080 /* Create-only parameter check has been done */ 66bf5da84jamie#define JF_PERSIST 0x0100 /* Jail is temporarily persistent */ 67bf5da84jamie#define JF_TIMEOUT 0x0200 /* A command (or process kill) timed out */ 68bf5da84jamie#define JF_SLEEPQ 0x0400 /* Waiting on a command and/or timeout */ 690e8a4f4jamie#define JF_FROM_RUNQ 0x0800 /* Has already been on the run queue */ 707e81b08eugen#define JF_SHOW 0x1000 /* -e Exhibit list of configured jails */ 713b31921jamie 723b31921jamie#define JF_OP_MASK (JF_START | JF_SET | JF_STOP) 733b31921jamie#define JF_RESTART (JF_START | JF_STOP) 743b31921jamie#define JF_START_SET (JF_START | JF_SET) 753b31921jamie#define JF_SET_RESTART (JF_SET | JF_STOP) 763b31921jamie#define JF_START_SET_RESTART (JF_START | JF_SET | JF_STOP) 773b31921jamie#define JF_DO_STOP(js) (((js) & (JF_SET | JF_STOP)) == JF_STOP) 783b31921jamie 793b31921jamieenum intparam { 8018b00cejamie IP__NULL = 0, /* Null command */ 8118b00cejamie IP_ALLOW_DYING, /* Allow making changes to a dying jail */ 823b31921jamie IP_COMMAND, /* Command run inside jail at creation */ 833b31921jamie IP_DEPEND, /* Jail starts after (stops before) another */ 843b31921jamie IP_EXEC_CLEAN, /* Run commands in a clean environment */ 853b31921jamie IP_EXEC_CONSOLELOG, /* Redirect optput for commands run in jail */ 863b31921jamie IP_EXEC_FIB, /* Run jailed commands with this FIB */ 873b31921jamie IP_EXEC_JAIL_USER, /* Run jailed commands as this user */ 883b31921jamie IP_EXEC_POSTSTART, /* Commands run outside jail after creating */ 893b31921jamie IP_EXEC_POSTSTOP, /* Commands run outside jail after removing */ 909fcd25bfreqlabs IP_EXEC_PREPARE, /* Commands run outside jail before addrs and mounting */ 913b31921jamie IP_EXEC_PRESTART, /* Commands run outside jail before creating */ 923b31921jamie IP_EXEC_PRESTOP, /* Commands run outside jail before removing */ 939fcd25bfreqlabs IP_EXEC_RELEASE, /* Commands run outside jail after addrs and unmounted */ 9442ccecbnetchild IP_EXEC_CREATED, /* Commands run outside jail right after it was started */ 953b31921jamie IP_EXEC_START, /* Commands run inside jail on creation */ 963b31921jamie IP_EXEC_STOP, /* Commands run inside jail on removal */ 973b31921jamie IP_EXEC_SYSTEM_JAIL_USER,/* Get jail_user from system passwd file */ 983b31921jamie IP_EXEC_SYSTEM_USER, /* Run non-jailed commands as this user */ 993b31921jamie IP_EXEC_TIMEOUT, /* Time to wait for a command to complete */ 1006811668jamie#if defined(INET) || defined(INET6) 1013b31921jamie IP_INTERFACE, /* Add IP addresses to this interface */ 1023b31921jamie IP_IP_HOSTNAME, /* Get jail IP address(es) from hostname */ 1036811668jamie#endif 1043b31921jamie IP_MOUNT, /* Mount points in fstab(5) form */ 1053b31921jamie IP_MOUNT_DEVFS, /* Mount /dev under prison root */ 106513bdd9hrs IP_MOUNT_FDESCFS, /* Mount /dev/fd under prison root */ 1076064614jamie IP_MOUNT_PROCFS, /* Mount /proc under prison root */ 108235aefejamie IP_MOUNT_FSTAB, /* A standard fstab(5) file */ 1093b31921jamie IP_STOP_TIMEOUT, /* Time to wait after sending SIGTERM */ 110235aefejamie IP_VNET_INTERFACE, /* Assign interface(s) to vnet jail */ 1116811668jamie#ifdef INET 1123b31921jamie IP__IP4_IFADDR, /* Copy of ip4.addr with interface/netmask */ 1136811668jamie#endif 1143b31921jamie#ifdef INET6 1153b31921jamie IP__IP6_IFADDR, /* Copy of ip6.addr with interface/prefixlen */ 1163b31921jamie#endif 1178576789jamie IP__MOUNT_FROM_FSTAB, /* Line from mount.fstab file */ 118bf5da84jamie IP__OP, /* Placeholder for requested operation */ 119235aefejamie KP_ALLOW_CHFLAGS, 120235aefejamie KP_ALLOW_MOUNT, 121235aefejamie KP_ALLOW_RAW_SOCKETS, 122235aefejamie KP_ALLOW_SET_HOSTNAME, 123235aefejamie KP_ALLOW_SOCKET_AF, 124235aefejamie KP_ALLOW_SYSVIPC, 1256fe59c6jamie KP_DEVFS_RULESET, 126235aefejamie KP_HOST_HOSTNAME, 1276811668jamie#ifdef INET 1283b31921jamie KP_IP4_ADDR, 1296811668jamie#endif 1303b31921jamie#ifdef INET6 1313b31921jamie KP_IP6_ADDR, 1323b31921jamie#endif 1333b31921jamie KP_JID, 1343b31921jamie KP_NAME, 1353b31921jamie KP_PATH, 1363b31921jamie KP_PERSIST, 137235aefejamie KP_SECURELEVEL, 1383b31921jamie KP_VNET, 1393b31921jamie IP_NPARAM 1403b31921jamie}; 1413b31921jamie 1423b31921jamieSTAILQ_HEAD(cfvars, cfvar); 1433b31921jamie 1443b31921jamiestruct cfvar { 1453b31921jamie STAILQ_ENTRY(cfvar) tq; 1463b31921jamie char *name; 1473b31921jamie size_t pos; 1483b31921jamie}; 1493b31921jamie 1500e5ec9djamieTAILQ_HEAD(cfstrings, cfstring); 1513b31921jamie 1523b31921jamiestruct cfstring { 1530e5ec9djamie TAILQ_ENTRY(cfstring) tq; 1543b31921jamie char *s; 1553b31921jamie size_t len; 1563b31921jamie struct cfvars vars; 1573b31921jamie}; 1583b31921jamie 1593b31921jamieTAILQ_HEAD(cfparams, cfparam); 1603b31921jamie 1613b31921jamiestruct cfparam { 1623b31921jamie TAILQ_ENTRY(cfparam) tq; 1633b31921jamie char *name; 1643b31921jamie struct cfstrings val; 1653b31921jamie unsigned flags; 1663b31921jamie int gen; 1673b31921jamie}; 1683b31921jamie 1693b31921jamieTAILQ_HEAD(cfjails, cfjail); 1703b31921jamieSTAILQ_HEAD(cfdepends, cfdepend); 1713b31921jamie 1723b31921jamiestruct cfjail { 1733b31921jamie TAILQ_ENTRY(cfjail) tq; 1743b31921jamie char *name; 1753b31921jamie char *comline; 1763b31921jamie struct cfparams params; 1773b31921jamie struct cfdepends dep[2]; 1783b31921jamie struct cfjails *queue; 1793b31921jamie struct cfparam *intparams[IP_NPARAM]; 1803b31921jamie struct cfstring *comstring; 1813b31921jamie struct jailparam *jp; 1823b31921jamie struct timespec timeout; 183bf5da84jamie const enum intparam *comparam; 1843b31921jamie unsigned flags; 1853b31921jamie int jid; 1863b31921jamie int seq; 1873b31921jamie int pstatus; 1883b31921jamie int ndeps; 1893b31921jamie int njp; 1903b31921jamie int nprocs; 1913b31921jamie}; 1923b31921jamie 1933b31921jamiestruct cfdepend { 1943b31921jamie STAILQ_ENTRY(cfdepend) tq[2]; 1953b31921jamie struct cfjail *j[2]; 1963b31921jamie unsigned flags; 1973b31921jamie}; 1983b31921jamie 1993b31921jamieextern void *emalloc(size_t); 2003b31921jamieextern void *erealloc(void *, size_t); 2013b31921jamieextern char *estrdup(const char *); 202b3870a1jamieextern int create_jail(struct cfjail *j); 2033b31921jamieextern void failed(struct cfjail *j); 2043b31921jamieextern void jail_note(const struct cfjail *j, const char *fmt, ...); 2053b31921jamieextern void jail_warnx(const struct cfjail *j, const char *fmt, ...); 2063b31921jamie 207bf5da84jamieextern int next_command(struct cfjail *j); 2083a156b8jamieextern int finish_command(struct cfjail *j); 2093b31921jamieextern struct cfjail *next_proc(int nonblock); 2103b31921jamie 2113b31921jamieextern void load_config(void); 2123b31921jamieextern struct cfjail *add_jail(void); 2133b31921jamieextern void add_param(struct cfjail *j, const struct cfparam *p, 214235aefejamie enum intparam ipnum, const char *value); 2153b31921jamieextern int bool_param(const struct cfparam *p); 2163b31921jamieextern int int_param(const struct cfparam *p, int *ip); 2173b31921jamieextern const char *string_param(const struct cfparam *p); 21894aa5f7jamieextern int check_intparams(struct cfjail *j); 2193b31921jamieextern int import_params(struct cfjail *j); 2203b31921jamieextern int equalopts(const char *opt1, const char *opt2); 2213b31921jamieextern int wild_jail_name(const char *wname); 2223b31921jamieextern int wild_jail_match(const char *jname, const char *wname); 2233b31921jamie 2243b31921jamieextern void dep_setup(int docf); 2253b31921jamieextern int dep_check(struct cfjail *j); 2263b31921jamieextern void dep_done(struct cfjail *j, unsigned flags); 2273b31921jamieextern void dep_reset(struct cfjail *j); 2283b31921jamieextern struct cfjail *next_jail(void); 229a85d762jamieextern int start_state(const char *target, int docf, unsigned state, 230a85d762jamie int running); 2313b31921jamieextern void requeue(struct cfjail *j, struct cfjails *queue); 2320e8a4f4jamieextern void requeue_head(struct cfjail *j, struct cfjails *queue); 2333b31921jamie 2343b31921jamieextern void yyerror(const char *); 2353b31921jamieextern int yylex(void); 2363b31921jamie 2373b31921jamieextern struct cfjails cfjails; 2383b31921jamieextern struct cfjails ready; 2393a156b8jamieextern struct cfjails depend; 2403b31921jamieextern const char *cfname; 2415ddbe53jamieextern int iflag; 242b3870a1jamieextern int note_remove; 2433a156b8jamieextern int paralimit; 2443b31921jamieextern int verbose; 245