diff options
Diffstat (limited to 'libexec/rc')
196 files changed, 21246 insertions, 0 deletions
diff --git a/libexec/rc/Makefile b/libexec/rc/Makefile new file mode 100644 index 000000000000..e82b582462d0 --- /dev/null +++ b/libexec/rc/Makefile @@ -0,0 +1,31 @@ +.include <src.opts.mk> + +CONFGROUPS= CONFETC CONFETCEXEC CONFETCDEFAULTS +CONFETCDIR= /etc +CONFETC= network.subr rc rc.initdiskless rc.subr rc.shutdown rc.bsdextended +CONFETCPACKAGE= rc + +.if ${MK_IPFW} != "no" +CONFETC+= rc.firewall +.endif +CONFETCMODE= 644 +CONFETCEXEC= netstart pccard_ether rc.resume rc.suspend +CONFETCEXECDIR= /etc +CONFETCEXECMODE= 755 +CONFETCEXECPACKAGE= rc +CONFETCDEFAULTSDIR= /etc/defaults +CONFETCDEFAULTS= rc.conf +CONFETCDEFAULTSPACKAGE= rc + +FILESGROUPS= LIBEXEC_SCRIPTS +LIBEXEC_SCRIPTS= debug.sh hooks.sh safe_eval.sh +LIBEXEC_SCRIPTSDIR= /libexec +LIBEXEC_SCRIPTSMODE= 755 +LIBEXEC_SCRIPTSPACKAGE= rc + +SUBDIR+= rc.d + +HAS_TESTS= +SUBDIR.${MK_TESTS}+= tests + +.include <bsd.prog.mk> diff --git a/libexec/rc/debug.sh b/libexec/rc/debug.sh new file mode 100755 index 000000000000..739c81a709f6 --- /dev/null +++ b/libexec/rc/debug.sh @@ -0,0 +1,451 @@ +: +# NAME: +# debug.sh - selectively debug scripts +# +# SYNOPSIS: +# $_DEBUG_SH . debug.sh +# DebugOn [-eo] "tag" ... +# DebugOff [-eo] [rc="rc"] "tag" ... +# Debugging +# DebugAdd "tag" +# DebugEcho ... +# DebugLog ... +# DebugShell "tag" ... +# DebugTrace ... +# Debug "tag" ... +# +# $DEBUG_SKIP echo skipped when Debug "tag" is true. +# $DEBUG_DO echo only done when Debug "tag" is true. +# +# DESCRIPTION: +# debug.sh provides the following functions to facilitate +# flexible run-time tracing of complicated shell scripts. +# +# DebugOn turns tracing on if any "tag" is found in "DEBUG_SH". +# It turns tracing off if "!tag" is found in "DEBUG_SH". +# It also sets "DEBUG_ON" to the "tag" that caused tracing to be +# enabled, or "DEBUG_OFF" if we matched "!tag". +# If '-e' option given returns 1 if no "tag" matched. +# If the '-o' flag is given, tracing is turned off unless there +# was a matched "tag", useful for functions too noisy to tace. +# +# Further; when we set "DEBUG_ON" if we find +# "$DEBUG_ON:debug_add:tag" in "DEBUG_SH" we will +# add the new "tag" to "DEBUG_SH" so it only has effect after that +# point. +# +# DebugOff turns tracing on if any "tag" matches "DEBUG_OFF" or +# off if any "tag" matches "DEBUG_ON". This allows nested +# functions to not interfere with each other. +# +# DebugOff accepts but ignores the '-e' and '-o' options. +# The optional "rc" value will be returned rather than the +# default of 0. Thus if DebugOff is the last operation in a +# function, "rc" will be the return code of that function. +# +# DebugAdd allows adding a "tag" to "DEBUG_SH" to influence +# later events, possibly in a child process. +# +# DebugEcho is just shorthand for: +#.nf +# $DEBUG_DO echo "$@" +#.fi +# +# Debugging returns true if tracing is enabled. +# It is useful for bounding complex debug actions, rather than +# using lots of "DEBUG_DO" lines. +# +# DebugShell runs an interactive shell if any "tag" is found in +# "DEBUG_INTERACTIVE", and there is a tty available. +# The shell used is defined by "DEBUG_SHELL" or "SHELL" and +# defaults to '/bin/sh'. +# +# Debug calls DebugOn and if that does not turn tracing on, it +# calls DebugOff to turn it off. +# +# The variables "DEBUG_SKIP" and "DEBUG_DO" are set so as to +# enable/disable code that should be skipped/run when debugging +# is turned on. "DEBUGGING" is the same as "DEBUG_SKIP" for +# backwards compatability. +# +# The use of $_DEBUG_SH is to prevent multiple inclusion, though +# it does no harm in this case. +# +# BUGS: +# Does not work with some versions of ksh. +# If a function turns tracing on, ksh turns it off when the +# function returns - useless. +# PD ksh works ok ;-) +# +# AUTHOR: +# Simon J. Gerraty <sjg@crufty.net> + +# RCSid: +# $Id: debug.sh,v 1.47 2025/08/07 21:59:54 sjg Exp $ +# +# @(#) Copyright (c) 1994-2024 Simon J. Gerraty +# +# SPDX-License-Identifier: BSD-2-Clause +# +# Please send copies of changes and bug-fixes to: +# sjg@crufty.net +# + +_DEBUG_SH=: + +Myname=${Myname:-`basename $0 .sh`} + +DEBUGGING= +DEBUG_DO=: +DEBUG_SKIP= +export DEBUGGING DEBUG_DO DEBUG_SKIP + +# have is handy +if test -z "$_HAVE_SH"; then + _HAVE_SH=: + + ## + # have that does not rely on return code of type + # + have() { + case `(type "$1") 2>&1` in + *" found") return 1;; + esac + return 0 + } +fi + +# does local *actually* work? +local_works() { + local _fu +} + +if local_works > /dev/null 2>&1; then + _local=local +else + _local=: +fi +# for backwards compatability +local=$_local + +if test -z "$isPOSIX_SHELL"; then + if (echo ${PATH%:*}) > /dev/null 2>&1; then + # true should be a builtin, : certainly is + isPOSIX_SHELL=: + else + isPOSIX_SHELL=false + false() { + return 1 + } + fi +fi + +is_posix_shell() { + $isPOSIX_SHELL + return +} + + +## +# _debugAdd match +# +# Called from _debugOn when $match also appears in $DEBUG_SH with +# a suffix of :debug_add:tag we will add tag to DEBUG_SH +# +_debugAdd() { + eval $_local tag + + for tag in `IFS=,; echo $DEBUG_SH` + do + : tag=$tag + case "$tag" in + $1:debug_add:*) + if is_posix_shell; then + tag=${tag#$1:debug_add:} + else + tag=`expr $tag : '.*:debug_add:\(.*\)'` + fi + case ",$DEBUG_SH," in + *,$tag,*) ;; + *) set -x + : _debugAdd $1 + DEBUG_SH=$DEBUG_SH,$tag + set +x + ;; + esac + ;; + esac + done + export DEBUG_SH +} + + +## +# _debugOn match first +# +# Actually turn on tracing, set $DEBUG_ON=$match +# +# Check if $DEBUG_SH contains $match:debug_add:* and call _debugAdd +# to add the suffix to DEBUG_SH. This useful when we only want +# to trace some script when run under specific circumstances. +# +# If we have included hooks.sh $_HOOKS_SH will be set +# and if $first (the first arg to DebugOn) is suitable as a variable +# name we will run ${first}_debugOn_hooks. +# +# We disable tracing for hooks_run itself but functions can trace +# if they want based on DEBUG_DO +# +_debugOn() { + DEBUG_OFF= + DEBUG_DO= + DEBUG_SKIP=: + DEBUG_X=-x + # do this firt to reduce noise + case ",$DEBUG_SH," in + *,$1:debug_add:*) _debugAdd $1;; + *,$2:debug_add:*) _debugAdd $2;; + esac + set -x + DEBUG_ON=$1 + case "$_HOOKS_SH,$2" in + ,*|:,|:,*[${CASE_CLASS_NEG:-!}A-Za-z0-9_]*) ;; + *) # avoid noise from hooks_run + set +x + hooks_run ${2}_debugOn_hooks + set -x + ;; + esac +} + +## +# _debugOff match $DEBUG_ON $first +# +# Actually turn off tracing, set $DEBUG_OFF=$match +# +# If we have included hooks.sh $_HOOKS_SH will be set +# and if $first (the first arg to DebugOff) is suitable as a variable +# name we will run ${first}_debugOff_hooks. +# +# We do hooks_run after turning off tracing, but before resetting +# DEBUG_DO so functions can trace if they want +# +_debugOff() { + DEBUG_OFF=$1 + set +x + case "$_HOOKS_SH,$3" in + ,*|:,|:,*[${CASE_CLASS_NEG:-!}A-Za-z0-9_]*) ;; + *) hooks_run ${3}_debugOff_hooks;; + esac + set +x # just to be sure + DEBUG_ON=$2 + DEBUG_DO=: + DEBUG_SKIP= + DEBUG_X= +} + +## +# DebugAdd tag +# +# Add tag to DEBUG_SH +# +DebugAdd() { + DEBUG_SH=${DEBUG_SH:+$DEBUG_SH,}$1 + export DEBUG_SH +} + +## +# DebugEcho message +# +# Output message if we are debugging +# +DebugEcho() { + $DEBUG_DO echo "$@" +} + +## +# Debugging +# +# return 0 if we are debugging. +# +Debugging() { + test "$DEBUG_SKIP" +} + +## +# DebugLog message +# +# Outout message with timestamp if we are debugging +# +DebugLog() { + $DEBUG_SKIP return 0 + echo `date '+@ %s [%Y-%m-%d %H:%M:%S %Z]'` "$@" +} + +## +# DebugTrace message +# +# Something hard to miss when wading through huge -x output +# +DebugTrace() { + $DEBUG_SKIP return 0 + set +x + echo "@ ==================== [ $DEBUG_ON ] ====================" + DebugLog "$@" + echo "@ ==================== [ $DEBUG_ON ] ====================" + set -x +} + +## +# DebugOn [-e] [-o] match ... +# +# Turn on debugging if any $match is found in $DEBUG_SH. +# +DebugOn() { + eval ${local:-:} _e _match _off _rc + _rc=0 # avoid problems with set -e + _off=: + while : + do + case "$1" in + -e) _rc=1; shift;; # caller ok with return 1 + -o) _off=; shift;; # off unless we have a match + *) break;; + esac + done + case ",${DEBUG_SH:-$DEBUG}," in + ,,) return $_rc;; + *,[Dd]ebug,*) ;; + *) $DEBUG_DO set +x;; # reduce the noise + esac + _match= + # if debugging is off because of a !e + # don't add 'all' to the On list. + case "$_off$DEBUG_OFF" in + :) _e=all;; + *) _e=;; + esac + for _e in ${*:-$Myname} $_e + do + : $_e in ,${DEBUG_SH:-$DEBUG}, + case ",${DEBUG_SH:-$DEBUG}," in + *,!$_e,*|*,!$Myname:$_e,*) + # only turn it off if it was on + _rc=0 + $DEBUG_DO _debugOff $_e $DEBUG_ON $1 + break + ;; + *,$_e,*|*,$Myname:$_e,*) + # only turn it on if it was off + _rc=0 + _match=$_e + $DEBUG_SKIP _debugOn $_e $1 + break + ;; + esac + done + if test -z "$_off$_match"; then + # off unless explicit match, but + # only turn it off if it was on + $DEBUG_DO _debugOff $_e $DEBUG_ON $1 + fi + DEBUGGING=$DEBUG_SKIP # backwards compatability + $DEBUG_DO set -x # back on if needed + $DEBUG_DO set -x # make sure we see it in trace + return $_rc +} + +## +# DebugOff [-e] [-o] [rc=$?] match ... +# +# Only turn debugging off if one of our args was the reason it +# was turned on. +# +# We normally return 0, but caller can pass rc=$? as first arg +# so that we preserve the status of last statement. +# +# The options '-e' and '-o' are ignored, they just make it easier to +# keep DebugOn and DebugOff lines in sync. +# +DebugOff() { + eval ${local:-:} _e _rc + case ",${DEBUG_SH:-$DEBUG}," in + *,[Dd]ebug,*) ;; + *) $DEBUG_DO set +x;; # reduce the noise + esac + _rc=0 # always happy + while : + do + case "$1" in + -[eo]) shift;; # ignore it + rc=*) eval "_$1"; shift;; + *) break;; + esac + done + for _e in $* + do + : $_e==$DEBUG_OFF DEBUG_OFF + case "$DEBUG_OFF" in + "") break;; + $_e) _debugOn $DEBUG_ON $1; return $_rc;; + esac + done + for _e in $* + do + : $_e==$DEBUG_ON DEBUG_ON + case "$DEBUG_ON" in + "") break;; + $_e) _debugOff "" "" $1; return $_rc;; + esac + done + DEBUGGING=$DEBUG_SKIP # backwards compatability + $DEBUG_DO set -x # back on if needed + $DEBUG_DO set -x # make sure we see it in trace + return $_rc +} + +_TTY=${_TTY:-`test -t 0 && tty`}; export _TTY + +# override this if you like +_debugShell() { + test "x$_TTY" != x || return 0 + { + echo DebugShell "$@" + echo "Type 'exit' to continue..." + } > $_TTY + ${DEBUG_SHELL:-${SHELL:-/bin/sh}} < $_TTY > $_TTY 2>&1 +} + +# Run an interactive shell if appropriate +# Note: you can use $DEBUG_SKIP DebugShell ... to skip unless debugOn +DebugShell() { + eval ${local:-:} _e + case "$_TTY%${DEBUG_INTERACTIVE}" in + *%|%*) return 0;; # no tty or no spec + esac + for _e in ${*:-$Myname} all + do + case ",${DEBUG_INTERACTIVE}," in + *,!$_e,*|*,!$Myname:$_e,*) + return 0 + ;; + *,$_e,*|*,$Myname:$_e,*) + # Provide clues as to why/where + _debugShell "$_e: $@" + return $? + ;; + esac + done + return 0 +} + +# For backwards compatability +Debug() { + case "${DEBUG_SH:-$DEBUG}" in + "") ;; + *) DEBUG_ON=${DEBUG_ON:-_Debug} + DebugOn -e $* || DebugOff $DEBUG_LAST + DEBUGGING=$DEBUG_SKIP + ;; + esac +} diff --git a/libexec/rc/hooks.sh b/libexec/rc/hooks.sh new file mode 100755 index 000000000000..af4aff3d6bc5 --- /dev/null +++ b/libexec/rc/hooks.sh @@ -0,0 +1,274 @@ +: +# NAME: +# hooks.sh - provide hooks for customization +# +# SYNOPSIS: +# hooks_add_all HOOKS [--first] func [...] +# hooks_add_once HOOKS [--first] func [...] +# hooks_add_default_set {all,once} +# hooks_add HOOKS func [...] +# hooks_get [--lifo] HOOKS +# hooks_run [--lifo] HOOKS ["args"] +# hooks_run_all [--lifo] HOOKS ["args"] +# hooks_has HOOKS func +# +# add_hooks HOOKS [--first] func [...] +# run_hooks HOOKS [LIFO] ["args"] +# run_hooks_all HOOKS [LIFO] ["args"] +# +# DESCRIPTION: +# The functions add_hooks and run_hooks are retained for +# backwards compatibility. They are aliases for hooks_add and +# hooks_run. +# +# hooks_add_all simply adds the "func"s to the list "HOOKS". +# +# If the first arg is '--first' "func"s are added to the start +# of the list. +# +# hooks_add_once does the same but only if "func" is not in "HOOKS". +# hooks_add uses one of the above based on "option", '--all' (default) +# or '--once'. +# +# hooks_add_default_set sets the default behavior of hooks_add +# +# hooks_get simply returns the named list of functions. +# +# hooks_has indicates whether "func" in in "HOOKS". +# +# hooks_run runs each "func" in $HOOKS and stops if any of them +# return a bad status. +# +# hooks_run_all does the same but does not stop on error. +# +# If run_hooks or run_hooks_all is given a flag of '--lifo' or +# 2nd argument of LIFO the hooks are run in the reverse order of +# calls to hooks_add. +# Any "args" specified are passed to each hook function. +# + +# RCSid: +# $Id: hooks.sh,v 1.26 2025/08/07 21:59:54 sjg Exp $ +# +# @(#)Copyright (c) 2000-2024 Simon J. Gerraty +# +# SPDX-License-Identifier: BSD-2-Clause +# +# Please send copies of changes and bug-fixes to: +# sjg@crufty.net +# + +# avoid multiple inclusion +_HOOKS_SH=: + +# does local *actually* work? +local_works() { + local _fu +} + +if local_works > /dev/null 2>&1; then + _local=local +else + _local=: +fi +# for backwards compatability +local=$_local + + +## +# hooks_add_all list func ... +# +# add "func"s to "list" regardless +# +hooks_add_all() { + eval $_local __h + __h=$1; shift + case "$1" in + --first) + shift + eval "$__h=\"$* \$$__h\"" + ;; + *) eval "$__h=\"\$$__h $*\"";; + esac +} + +## +# hooks_add_once list func ... +# +# add "func"s to "list" if not already there +# +hooks_add_once() { + eval $_local __h __hh __first + __h=$1; shift + case "$1" in + --first) shift; __first=:;; + *) __first=;; + esac + eval "__hh=\$$__h" + while [ $# -gt 0 ] + do + : __hh="$__hh" 1="$1" + case "$__first $__hh " in + *" $1 "*) ;; # dupe + :*) __hh="$1 $__hh";; + *) __hh="$__hh $1";; + esac + shift + done + eval "$__h=\"$__hh\"" +} + +## +# hooks_add_default_set [--]{all,once} +# +# change the default method of hooks_add +# +hooks_add_default_set() { + case "$1" in + once|--once) HOOKS_ADD_DEFAULT=once;; + *) HOOKS_ADD_DEFAULT=all;; + esac +} + +## +# hooks_add [--{all,once}] list func ... +# +# add "func"s to "list" +# +# If '--once' use hooks_add_once, +# default is hooks_add_all. +# +hooks_add() { + case "$1" in + --all) shift; hooks_add_all "$@";; + --once) shift; hooks_add_once "$@";; + *) hooks_add_${HOOKS_ADD_DEFAULT:-all} "$@";; + esac +} + +## +# hooks_get [--lifo] list [LIFO] +# +# return $list +# +hooks_get() { + eval $_local __h __h2 e __l + case "$1" in + --lifo) __l=LIFO; shift;; + esac + eval "__h=\$$1" + case "$__l$2" in + LIFO*) + __h2="$__h" + __h= + for e in $__h2 + do + __h="$e $__h" + done + ;; + esac + echo "$__h" +} + +## +# hooks_has list func +# +# is func in $list ? +# +hooks_has() { + eval $_local __h + eval "__h=\$$1" + case " $__h " in + *" $1 "*) return 0;; + esac + return 1 +} + +## +# hooks_run [--all] [--lifo] list [LIFO] [args] +# +# pass "args" to each function in "list" +# Without '--all'; if any return non-zero return that immediately +# +hooks_run() { + eval $_local __a e __h __hl __h2 __l + __a=return + __l= + + while : + do + case "$1" in + --all) __a=:; shift;; + --lifo) __l=$1; shift;; + *) break;; + esac + done + __hl=$1; shift + case "$1" in + LIFO) __l=--lifo; shift;; + esac + __h=`hooks_get $__l $__hl` + for e in $__h + do + $e "$@" || $__a $? + done +} + +## +# hooks_run_all [--lifo] list [LIFO] [args] +# +# pass "args" to each function in "list" +# +hooks_run_all() { + hooks_run --all "$@" +} + +## +# add_hooks,run_hooks[_all] aliases +# +add_hooks() { + hooks_add "$@" +} + +run_hooks() { + hooks_run "$@" +} + +run_hooks_all() { + hooks_run --all "$@" +} + + +case /$0 in +*/hooks.sh) + # simple unit-test + list=HOOKS + flags= + while : + do + : 1=$1 + case "$1" in + HOOKS|*hooks) list=$1; shift;; + --*) flags="$flags $1"; shift;; + *) break;; + esac + done + for f in "$@" + do + : f=$f + case "$f" in + LIFO) ;; + false|true) ;; + *) eval "$f() { echo This is $f; }";; + esac + done + echo hooks_add $flags $list "$@" + hooks_add $flags $list "$@" + echo hooks_run $list + hooks_run $list + echo hooks_run --all --lifo $list + hooks_run --all --lifo $list + echo hooks_run $list LIFO + hooks_run $list LIFO + ;; +esac diff --git a/libexec/rc/netstart b/libexec/rc/netstart new file mode 100755 index 000000000000..430a578a73ea --- /dev/null +++ b/libexec/rc/netstart @@ -0,0 +1,52 @@ +#!/bin/sh - +# +# Copyright (c) 1993 The FreeBSD Project +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. + +# This file is NOT called by any of the other scripts - it has been +# obsoleted by /etc/rc.d/* and is provided here only for user +# convenience (if you're sitting in single user mode and wish to start +# the network by hand, this script will do it for you). +# + +_start=quietstart + +/etc/rc.d/devd ${_start} +/etc/rc.d/hostid ${_start} +/etc/rc.d/hostname ${_start} +/etc/rc.d/ipmon ${_start} +/etc/rc.d/ipfilter ${_start} +/etc/rc.d/ipnat ${_start} +/etc/rc.d/ipfs ${_start} +/etc/rc.d/netif ${_start} +/etc/rc.d/ipsec ${_start} +/etc/rc.d/ppp ${_start} +/etc/rc.d/ipfw ${_start} +/etc/rc.d/routing ${_start} +/etc/rc.d/route6d ${_start} +/etc/rc.d/routed ${_start} +/etc/rc.d/rtsold ${_start} +/etc/rc.d/nisdomain ${_start} + +exit 0 diff --git a/libexec/rc/network.subr b/libexec/rc/network.subr new file mode 100644 index 000000000000..5e4f2c1f39a0 --- /dev/null +++ b/libexec/rc/network.subr @@ -0,0 +1,1790 @@ +# +# Copyright (c) 2003 The FreeBSD Project. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# +IFCONFIG_CMD="/sbin/ifconfig" +: ${netif_ipexpand_max:=2048} + +# +# Subroutines commonly used from network startup scripts. +# Requires that rc.conf be loaded first. +# + +# ifn_start ifn +# Bring up and configure an interface. If some configuration is +# applied, print the interface configuration. +# +ifn_start() +{ + local ifn cfg + ifn="$1" + cfg=1 + + [ -z "$ifn" ] && err 1 "ifn_start called without an interface" + + ifscript_up ${ifn} && cfg=0 + ifconfig_up ${ifn} && cfg=0 + if ! noafif $ifn; then + afexists inet6 && ipv6_up ${ifn} && cfg=0 + afexists inet && ipv4_up ${ifn} && cfg=0 + fi + childif_create ${ifn} && cfg=0 + + return $cfg +} + +# ifn_stop ifn +# Shutdown and de-configure an interface. If action is taken, +# print the interface name. +# +ifn_stop() +{ + local ifn cfg + ifn="$1" + cfg=1 + + [ -z "$ifn" ] && err 1 "ifn_stop called without an interface" + + if ! noafif $ifn; then + afexists inet && ipv4_down ${ifn} && cfg=0 + afexists inet6 && ipv6_down ${ifn} && cfg=0 + fi + ifconfig_down ${ifn} && cfg=0 + ifscript_down ${ifn} && cfg=0 + childif_destroy ${ifn} && cfg=0 + + return $cfg +} + +# ifn_vnetup ifn +# Move ifn to the specified vnet jail. +# +ifn_vnetup() +{ + + ifn_vnet0 $1 vnet +} + +# ifn_vnetdown ifn +# Reclaim ifn from the specified vnet jail. +# +ifn_vnetdown() +{ + + ifn_vnet0 $1 -vnet +} + +# ifn_vnet0 ifn action +# Helper function for ifn_vnetup and ifn_vnetdown. +# +ifn_vnet0() +{ + local _ifn _cfg _action _vnet + _ifn="$1" + _action="$2" + _cfg=1 + + if _vnet=$(vnetif $_ifn); then + ${IFCONFIG_CMD} $_ifn $_action $_vnet && _cfg=0 + fi + + return $_cfg +} + +# ifconfig_up if +# Evaluate ifconfig(8) arguments for interface $if and +# run ifconfig(8) with those arguments. It returns 0 if +# arguments were found and executed or 1 if the interface +# had no arguments. Pseudo arguments DHCP and WPA are handled +# here. +# +ifconfig_up() +{ + local _cfg _ifconfig_descr _ipv6_opts ifconfig_args + _cfg=1 + + # Make sure lo0 always comes up. + if [ "$1" = "lo0" ]; then + _cfg=0 + fi + + # inet6 specific + if ! noafif $1 && afexists inet6; then + if checkyesno ipv6_activate_all_interfaces; then + _ipv6_opts="-ifdisabled" + fi + + # backward compatibility: $ipv6_enable + case $ipv6_enable in + [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) + case $1 in + bridge[0-9]*) + # No accept_rtadv by default on if_bridge(4) + # to avoid a conflict with the member + # interfaces. + ;; + *) + if ! checkyesno ipv6_gateway_enable; then + _ipv6_opts="${_ipv6_opts} accept_rtadv" + fi + ;; + esac + ;; + esac + + case $ipv6_cpe_wanif in + $1) + _ipv6_opts="${_ipv6_opts} -no_radr accept_rtadv" + ;; + esac + + if [ -n "${_ipv6_opts}" ]; then + ${IFCONFIG_CMD} $1 inet6 ${_ipv6_opts} + fi + fi + + # ifconfig_IF + ifconfig_args=`ifconfig_getargs $1` + if [ -n "${ifconfig_args}" ]; then + eval ${IFCONFIG_CMD} $1 ${ifconfig_args} + _cfg=0 + fi + + # inet6 specific + if ! noafif $1 && afexists inet6; then + # ifconfig_IF_ipv6 + ifconfig_args=`ifconfig_getargs $1 ipv6` + if [ -n "${ifconfig_args}" ]; then + # backward compatibility: inet6 keyword + case "${ifconfig_args}" in + :*|[0-9a-fA-F]*:*) + warn "\$ifconfig_$1_ipv6 needs leading" \ + "\"inet6\" keyword for an IPv6 address." + ifconfig_args="inet6 ${ifconfig_args}" + ;; + esac + ${IFCONFIG_CMD} $1 inet6 -ifdisabled + eval ${IFCONFIG_CMD} $1 ${ifconfig_args} + _cfg=0 + fi + + # $ipv6_prefix_IF will be handled in + # ipv6_prefix_hostid_addr_common(). + ifconfig_args=`get_if_var $1 ipv6_prefix_IF` + if [ -n "${ifconfig_args}" ]; then + ${IFCONFIG_CMD} $1 inet6 -ifdisabled + _cfg=0 + fi + + # backward compatibility: $ipv6_ifconfig_IF + ifconfig_args=`get_if_var $1 ipv6_ifconfig_IF` + if [ -n "${ifconfig_args}" ]; then + warn "\$ipv6_ifconfig_$1 is obsolete." \ + " Use ifconfig_$1_ipv6 instead." + ${IFCONFIG_CMD} $1 inet6 -ifdisabled + eval ${IFCONFIG_CMD} $1 inet6 ${ifconfig_args} + _cfg=0 + fi + fi + + ifalias $1 link alias + ifalias $1 ether alias + + _ifconfig_descr=`get_if_var $1 ifconfig_IF_descr` + if [ -n "${_ifconfig_descr}" ]; then + ${IFCONFIG_CMD} $1 description "${_ifconfig_descr}" + fi + + if wpaif $1; then + /etc/rc.d/wpa_supplicant start $1 + _cfg=0 # XXX: not sure this should count + elif hostapif $1; then + /etc/rc.d/hostapd start $1 + _cfg=0 + elif [ ${_cfg} -eq 0 ]; then + ${IFCONFIG_CMD} $1 up + fi + + if ! noafif $1 && afexists inet6; then + ipv6_accept_rtadv_up $1 && _cfg=0 + fi + + if dhcpif $1; then + if [ $_cfg -ne 0 ] ; then + ${IFCONFIG_CMD} $1 up + fi + if syncdhcpif $1; then + /etc/rc.d/dhclient start $1 + fi + _cfg=0 + fi + + return $_cfg +} + +# ifconfig_down if +# returns 1 if wpa_supplicant or dhclient was stopped or +# the interface exists. +# +ifconfig_down() +{ + local _cfg + _cfg=1 + + if wpaif $1; then + /etc/rc.d/wpa_supplicant stop $1 + _cfg=0 + elif hostapif $1; then + /etc/rc.d/hostapd stop $1 + _cfg=0 + elif dhcpif $1; then + /etc/rc.d/dhclient stop $1 + _cfg=0 + fi + + if ifexists $1; then + ${IFCONFIG_CMD} $1 down + _cfg=0 + fi + + return $_cfg +} + +# get_if_var if var [default] +# Return the value of the pseudo-hash corresponding to $if where +# $var is a string containg the sub-string "IF" which will be +# replaced with $if after the characters defined in _punct are +# replaced with '_'. If the variable is unset, replace it with +# $default if given. +get_if_var() +{ + local _if _punct _punct_c _var _default prefix suffix + + if [ $# -ne 2 -a $# -ne 3 ]; then + err 3 'USAGE: get_if_var name var [default]' + fi + + _if=$1 + _punct=".-/+" + ltr ${_if} "${_punct}" '_' _if + _var=$2 + _default=$3 + + prefix=${_var%%IF*} + suffix=${_var##*IF} + eval echo \${${prefix}${_if}${suffix}-${_default}} +} + +# _ifconfig_getargs if [af] +# Prints the arguments for the supplied interface to stdout. +# Returns 1 if empty. In general, ifconfig_getargs should be used +# outside this file. +_ifconfig_getargs() +{ + local _ifn _af + _ifn=$1 + _af=${2+_$2} + + if [ -z "$_ifn" ]; then + return 1 + fi + + get_if_var $_ifn ifconfig_IF$_af "$ifconfig_DEFAULT" +} + +# ifconfig_getargs if [af] +# Takes the result from _ifconfig_getargs and removes pseudo +# args such as DHCP and WPA. +ifconfig_getargs() +{ + local _tmpargs _arg _args _vnet + _tmpargs=`_ifconfig_getargs $1 $2` + if [ $? -eq 1 ]; then + return 1 + fi + _args= + _vnet=0 + + for _arg in $_tmpargs; do + case $_arg:$_vnet in + [Dd][Hh][Cc][Pp]:0) ;; + [Nn][Oo][Aa][Uu][Tt][Oo]:0) ;; + [Nn][Oo][Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]:0) ;; + [Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]:0) ;; + [Ww][Pp][Aa]:0) ;; + [Hh][Oo][Ss][Tt][Aa][Pp]:0) ;; + vnet:0) _vnet=1 ;; + *:1) _vnet=0 ;; + *:0) + _args="$_args $_arg" + ;; + esac + done + + echo $_args +} + +# autoif +# Returns 0 if the interface should be automatically configured at +# boot time and 1 otherwise. +autoif() +{ + local _tmpargs _arg + _tmpargs=`_ifconfig_getargs $1` + + for _arg in $_tmpargs; do + case $_arg in + [Nn][Oo][Aa][Uu][Tt][Oo]) + return 1 + ;; + esac + done + + return 0 +} + +# dhcpif if +# Returns 0 if the interface is a DHCP interface and 1 otherwise. +dhcpif() +{ + local _tmpargs _arg + _tmpargs=`_ifconfig_getargs $1` + + case $1 in + lo[0-9]*|\ + stf[0-9]*|\ + lp[0-9]*|\ + sl[0-9]*) + return 1 + ;; + esac + if noafif $1; then + return 1 + fi + + for _arg in $_tmpargs; do + case $_arg in + [Dd][Hh][Cc][Pp]) + return 0 + ;; + [Nn][Oo][Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) + return 0 + ;; + [Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) + return 0 + ;; + esac + done + + return 1 +} + +# syncdhcpif +# Returns 0 if the interface should be configured synchronously and +# 1 otherwise. +syncdhcpif() +{ + local _tmpargs _arg + _tmpargs=`_ifconfig_getargs $1` + + if noafif $1; then + return 1 + fi + + for _arg in $_tmpargs; do + case $_arg in + [Nn][Oo][Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) + return 1 + ;; + [Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) + return 0 + ;; + esac + done + + checkyesno synchronous_dhclient +} + +# wpaif if +# Returns 0 if the interface is a WPA interface and 1 otherwise. +wpaif() +{ + local _tmpargs _arg + _tmpargs=`_ifconfig_getargs $1` + + for _arg in $_tmpargs; do + case $_arg in + [Ww][Pp][Aa]) + return 0 + ;; + esac + done + + return 1 +} + +# hostapif if +# Returns 0 if the interface is a HOSTAP interface and 1 otherwise. +hostapif() +{ + local _tmpargs _arg + _tmpargs=`_ifconfig_getargs $1` + + for _arg in $_tmpargs; do + case $_arg in + [Hh][Oo][Ss][Tt][Aa][Pp]) + return 0 + ;; + esac + done + + return 1 +} + +# vnetif if +# Returns 0 and echo jail if "vnet" keyword is specified on the +# interface, and 1 otherwise. +vnetif() +{ + local _tmpargs _arg _vnet + _tmpargs=`_ifconfig_getargs $1` + + _vnet=0 + for _arg in $_tmpargs; do + case $_arg:$_vnet in + vnet:0) _vnet=1 ;; + *:1) echo $_arg; return 0 ;; + esac + done + + return 1 +} + +# afexists af +# Returns 0 if the address family is enabled in the kernel +# 1 otherwise. +afexists() +{ + local _af + _af=$1 + + case ${_af} in + inet|inet6) + check_kern_features ${_af} + ;; + link|ether) + return 0 + ;; + *) + err 1 "afexists(): Unsupported address family: $_af" + ;; + esac +} + +# noafif if +# Returns 0 if the interface has no af configuration and 1 otherwise. +noafif() +{ + local _if + _if=$1 + + case $_if in + pflog[0-9]*|\ + pfsync[0-9]*|\ + usbus[0-9]*|\ + an[0-9]*|\ + ath[0-9]*|\ + ipw[0-9]*|\ + ipfw[0-9]*|\ + iwi[0-9]*|\ + iwn[0-9]*|\ + ral[0-9]*|\ + wi[0-9]*|\ + wl[0-9]*|\ + wpi[0-9]*) + return 0 + ;; + esac + + return 1 +} + +# ipv6if if +# Returns 0 if the interface should be configured for IPv6 and +# 1 otherwise. +ipv6if() +{ + local _if _tmpargs i + _if=$1 + + if ! afexists inet6; then + return 1 + fi + + # lo0 is always IPv6-enabled + case $_if in + lo0) + return 0 + ;; + esac + + case "${ipv6_network_interfaces}" in + $_if|"$_if "*|*" $_if"|*" $_if "*|[Aa][Uu][Tt][Oo]) + # True if $ifconfig_IF_ipv6 is defined. + _tmpargs=`_ifconfig_getargs $_if ipv6` + if [ -n "${_tmpargs}" ]; then + return 0 + fi + + # True if $ipv6_prefix_IF is defined. + _tmpargs=`get_if_var $_if ipv6_prefix_IF` + if [ -n "${_tmpargs}" ]; then + return 0 + fi + + # backward compatibility: True if $ipv6_ifconfig_IF is defined. + _tmpargs=`get_if_var $_if ipv6_ifconfig_IF` + if [ -n "${_tmpargs}" ]; then + return 0 + fi + ;; + esac + + return 1 +} + +# ipv6_autoconfif if +# Returns 0 if the interface should be configured for IPv6 with +# Stateless Address Configuration; 1 otherwise. +ipv6_autoconfif() +{ + local _if _tmpargs _arg + _if=$1 + + case $_if in + lo[0-9]*|\ + stf[0-9]*|\ + lp[0-9]*|\ + sl[0-9]*) + return 1 + ;; + esac + if noafif $_if; then + return 1 + fi + if ! ipv6if $_if; then + return 1 + fi + if checkyesno ipv6_gateway_enable; then + return 1 + fi + _tmpargs=`get_if_var $_if ipv6_prefix_IF` + if [ -n "${_tmpargs}" ]; then + return 1 + fi + # backward compatibility: $ipv6_enable + case $ipv6_enable in + [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) + if checkyesno ipv6_gateway_enable; then + return 1 + fi + case $1 in + bridge[0-9]*) + # No accept_rtadv by default on if_bridge(4) + # to avoid a conflict with the member + # interfaces. + return 1 + ;; + *) + return 0 + ;; + esac + ;; + esac + + _tmpargs=`_ifconfig_getargs $_if ipv6` + for _arg in $_tmpargs; do + case $_arg in + accept_rtadv) + return 0 + ;; + esac + done + + # backward compatibility: $ipv6_ifconfig_IF + _tmpargs=`get_if_var $_if ipv6_ifconfig_IF` + for _arg in $_tmpargs; do + case $_arg in + accept_rtadv) + return 0 + ;; + esac + done + + return 1 +} + +# ifexists if +# Returns 0 if the interface exists and 1 otherwise. +ifexists() +{ + [ -z "$1" ] && return 1 + ${IFCONFIG_CMD} -n $1 > /dev/null 2>&1 +} + +# ifisup if +# Returns 0 if the interface exists and UP, +# returns 1 if the interface exists and not UP, +# returns 2 otherwise. +ifisup() +{ + local _if + + [ -z "$1" ] && return 2 + _if="$1" + + set -- $(${IFCONFIG_CMD} -n ${_if} 2>/dev/null) + case "$1$2" in + ${_if}:*'<UP'[,\>]*) return 0 ;; + ${_if}:*) return 1 ;; + esac + + return 2 +} + +# ipv4_up if +# add IPv4 addresses to the interface $if +ipv4_up() +{ + local _if _ret + _if=$1 + _ret=1 + + # Add 127.0.0.1/8 to lo0 unless otherwise specified. + if [ "${_if}" = "lo0" ]; then + ifconfig_args=`get_if_var ${_if} ifconfig_IF` + if [ -z "${ifconfig_args}" ]; then + ${IFCONFIG_CMD} ${_if} inet 127.0.0.1/8 alias + fi + fi + ifalias ${_if} inet alias && _ret=0 + + return $_ret +} + +# ipv6_up if +# add IPv6 addresses to the interface $if +ipv6_up() +{ + local _if _ret + _if=$1 + _ret=1 + + if ! ipv6if $_if; then + return 0 + fi + + ifalias ${_if} inet6 alias && _ret=0 + ipv6_prefix_hostid_addr_common ${_if} alias && _ret=0 + + return $_ret +} + +# ipv4_down if +# remove IPv4 addresses from the interface $if +ipv4_down() +{ + local _if _ifs _ret inetList oldifs _inet + _if=$1 + _ifs="^" + _ret=1 + + ifalias ${_if} inet -alias && _ret=0 + + inetList="`${IFCONFIG_CMD} ${_if} | grep 'inet ' | tr "\n\t" "$_ifs"`" + + oldifs="$IFS" + IFS="$_ifs" + for _inet in $inetList ; do + # get rid of extraneous line + case $_inet in + inet[[:space:]]*) ;; + *) continue ;; + esac + + _inet=`expr "$_inet" : '.*\(inet \([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}\).*'` + + IFS="$oldifs" + ${IFCONFIG_CMD} ${_if} ${_inet} delete + IFS="$_ifs" + _ret=0 + done + IFS="$oldifs" + + return $_ret +} + +# ipv6_down if +# remove IPv6 addresses from the interface $if +ipv6_down() +{ + local _if _ifs _ret inetList oldifs _inet6 + _if=$1 + _ifs="^" + _ret=1 + + if ! ipv6if $_if; then + return 0 + fi + + ipv6_accept_rtadv_down ${_if} && _ret=0 + ipv6_prefix_hostid_addr_common ${_if} -alias && _ret=0 + ifalias ${_if} inet6 -alias && _ret=0 + + inetList="`${IFCONFIG_CMD} ${_if} | grep 'inet6 ' | tr "\n\t" "$_ifs"`" + + oldifs="$IFS" + IFS="$_ifs" + for _inet6 in $inetList ; do + # get rid of extraneous line + case $_inet6 in + inet6[[:space:]]*) ;; + *) continue ;; + esac + + _inet6=`expr "$_inet6" : '.*\(inet6 \([0-9a-f:]*\)\).*'` + + IFS="$oldifs" + ${IFCONFIG_CMD} ${_if} ${_inet6} -alias + IFS="$_ifs" + _ret=0 + done + IFS="$oldifs" + + return $_ret +} + +# ifalias if af action +# Configure or remove aliases for network interface $if. +# It returns 0 if at least one alias was configured or +# removed, or 1 if there were none. +# +ifalias() +{ + local _ret + _ret=1 + + afexists $2 || return $_ret + + case "$2" in + inet|inet6|link|ether) + ifalias_af_common $1 $2 $3 && _ret=0 + ;; + esac + + return $_ret +} + +# ifalias_expand_addr af action addr +# Expand address range ("N-M") specification in addr. +# "addr" must not include an address-family keyword. +# The results will include an address-family keyword. +# +ifalias_expand_addr() +{ + local _af _action + + _af=$1 + _action=$2 + shift 2 + + afexists $_af || return + ifalias_expand_addr_$_af $_action $* +} + +# ifalias_expand_addr_inet action addr +# Helper function for ifalias_expand_addr(). Handles IPv4. +# +ifalias_expand_addr_inet() +{ + local _action _arg _cidr _cidr_addr _exargs + local _ipaddr _plen _range _iphead _iptail _iplow _iphigh _ipcount + local _retstr _c + _action=$1 + _arg=$2 + shift 2 + _exargs=$* + _retstr= + + case $_action:$_arg:$_exargs in + *:*--*) return ;; # invalid + tmp:*[0-9]-[0-9]*:*) # to be expanded + _action="alias" + ;; + *:*[0-9]-[0-9]*:*) # to be expanded + ;; + tmp:*:*netmask*) # already expanded w/ netmask option + echo ${_arg%/[0-9]*} $_exargs && return + ;; + tmp:*:*) # already expanded w/o netmask option + echo $_arg $_exargs && return + ;; + *:*:*netmask*) # already expanded w/ netmask option + echo inet ${_arg%/[0-9]*} $_exargs && return + ;; + *:*:*) # already expanded w/o netmask option + echo inet $_arg $_exargs && return + ;; + esac + + for _cidr in $_arg; do + _ipaddr=${_cidr%%/*} + _plen=${_cidr##*/} + # When subnet prefix length is not specified, use /32. + case $_plen in + $_ipaddr) _plen=32 ;; # "/" character not found + esac + + OIFS=$IFS + IFS=. set -- $_ipaddr + _range= + _iphead= + _iptail= + for _c in $@; do + case $_range:$_c in + :[0-9]*-[0-9]*) + _range=$_c + ;; + :*) + _iphead="${_iphead}${_iphead:+.}${_c}" + ;; + *:*) + _iptail="${_iptail}${_iptail:+.}${_c}" + ;; + esac + done + IFS=$OIFS + _iplow=${_range%-*} + _iphigh=${_range#*-} + + # clear netmask when removing aliases + if [ "$_action" = "-alias" ]; then + _plen="" + fi + + _ipcount=$_iplow + while [ "$_ipcount" -le "$_iphigh" ]; do + _retstr="${_retstr} ${_iphead}${_iphead:+.}${_ipcount}${_iptail:+.}${_iptail}${_plen:+/}${_plen}" + if [ $_ipcount -gt $(($_iplow + $netif_ipexpand_max)) ]; then + warn "Range specification is too large (${_iphead}${_iphead:+.}${_iplow}${_iptail:+.}${_iptail}-${_iphead}${_iphead:+.}${_iphigh}${_iptail:+.}${_iptail}). ${_iphead}${_iphead:+.}${_iplow}${_iptail:+.}${_iptail}-${_iphead}${_iphead:+.}${_ipcount}${_iptail:+.}${_iptail} was processed. Increase \$netif_ipexpand_max in rc.conf." + break + else + _ipcount=$(($_ipcount + 1)) + fi + # Forcibly set /32 for remaining aliases. + _plen=32 + done + done + + for _c in $_retstr; do + ifalias_expand_addr_inet $_action $_c $_exargs + done +} + +# ifalias_expand_addr_inet6 action addr +# Helper function for ifalias_expand_addr(). Handles IPv6. +# +ifalias_expand_addr_inet6() +{ + local _action _arg _cidr _cidr_addr _exargs + local _ipaddr _plen _ipleft _ipright _iplow _iphigh _ipcount + local _ipv4part + local _retstr _c + _action=$1 + _arg=$2 + shift 2 + _exargs=$* + _retstr= + + case $_action:$_arg:$_exargs in + *:*--*:*) return ;; # invalid + tmp:*[0-9a-zA-Z]-[0-9a-zA-Z]*:*)# to be expanded + _action="alias" + ;; + *:*[0-9a-zA-Z]-[0-9a-zA-Z]*:*) # to be expanded + ;; + tmp:*:*prefixlen*) # already expanded w/ prefixlen option + echo ${_arg%/[0-9]*} $_exargs && return + ;; + tmp:*:*) # already expanded w/o prefixlen option + echo $_arg $_exargs && return + ;; + *:*:*prefixlen*) # already expanded w/ prefixlen option + echo inet6 ${_arg%/[0-9]*} $_exargs && return + ;; + *:*:*) # already expanded w/o prefixlen option + echo inet6 $_arg $_exargs && return + ;; + esac + + for _cidr in $_arg; do + _ipaddr="${_cidr%%/*}" + _plen="${_cidr##*/}" + + case $_action:$_ipaddr:$_cidr in + -alias:*:*) unset _plen ;; + *:$_cidr:$_ipaddr) unset _plen ;; + esac + + if [ "${_ipaddr%:*.*.*.*}" = "$_ipaddr" ]; then + # Handle !v4mapped && !v4compat addresses. + + # The default prefix length is 64. + case $_ipaddr:$_cidr in + $_cidr:$_ipaddr) _plen="64" ;; + esac + _ipleft=${_ipaddr%-*} + _ipright=${_ipaddr#*-} + _iplow=${_ipleft##*:} + _iphigh=${_ipright%%:*} + _ipleft=${_ipleft%:*} + _ipright=${_ipright#*:} + + if [ "$_iphigh" = "$_ipright" ]; then + unset _ipright + else + _ipright=:$_ipright + fi + + if [ -n "$_iplow" -a -n "$_iphigh" ]; then + _iplow=$((0x$_iplow)) + _iphigh=$((0x$_iphigh)) + _ipcount=$_iplow + while [ $_ipcount -le $_iphigh ]; do + _r=`printf "%s:%04x%s%s" \ + $_ipleft $_ipcount $_ipright \ + ${_plen:+/}$_plen` + _retstr="$_retstr $_r" + if [ $_ipcount -gt $(($_iplow + $netif_ipexpand_max)) ] + then + warn "Range specification is too large $(printf '(%s:%x%s-%s:%x%s)' "$_ipleft" "$_iplow" "$_ipright" "$_ipleft" "$_iphigh" "$_ipright"). $(printf '%s:%x%s-%s:%x%s' "$_ipleft" "$_iplow" "$_ipright" "$_ipleft" "$_ipcount" "$_ipright") was processed. Increase \$netif_ipexpand_max in rc.conf." + break + else + _ipcount=$(($_ipcount + 1)) + fi + done + else + _retstr="${_ipaddr}${_plen:+/}${_plen}" + fi + + for _c in $_retstr; do + ifalias_expand_addr_inet6 $_action $_c $_exargs + done + else + # v4mapped/v4compat should handle as an IPv4 alias + _ipv4part=${_ipaddr##*:} + + # Adjust prefix length if any. If not, set the + # default prefix length as 32. + case $_ipaddr:$_cidr in + $_cidr:$_ipaddr) _plen=32 ;; + *) _plen=$(($_plen - 96)) ;; + esac + + _retstr=`ifalias_expand_addr_inet \ + tmp ${_ipv4part}${_plen:+/}${_plen}` + for _c in $_retstr; do + ifalias_expand_addr_inet $_action $_c $_exargs + done + fi + done +} + +# ifalias_af_common_handler if af action args +# Helper function for ifalias_af_common(). +# +ifalias_af_common_handler() +{ + local _ret _if _af _action _args _c _tmpargs + + _ret=1 + _if=$1 + _af=$2 + _action=$3 + shift 3 + _args=$* + + case $_args in + ${_af}[[:space:]]*) ;; + *) return ;; + esac + + # link(ether) does not support address removal. + case $_af:$_action in + link:-alias|ether:-alias) return ;; + esac + + _tmpargs= + for _c in $_args; do + case $_c in + ${_af}) + case $_tmpargs in + ${_af}[[:space:]]*[0-9a-fA-F]-*) + ifalias_af_common_handler $_if $_af $_action \ + `ifalias_expand_addr $_af $_action ${_tmpargs#${_af}[[:space:]]}` + ;; + ${_af}[[:space:]]*) + ${IFCONFIG_CMD} $_if $_tmpargs $_action && _ret=0 + ;; + esac + _tmpargs=$_af + ;; + *) + _tmpargs="$_tmpargs $_c" + ;; + esac + done + # Process the last component if any. + if [ -n "${_tmpargs}" ]; then + case $_tmpargs in + ${_af}[[:space:]]pass[[:space:]]*) + ${IFCONFIG_CMD} $_if $_tmpargs $_action && _ret=0 + ;; + ${_af}[[:space:]]*[0-9a-fA-F]-*) + ifalias_af_common_handler $_if $_af $_action \ + `ifalias_expand_addr $_af $_action ${_tmpargs#${_af}[[:space:]]}` + ;; + ${_af}[[:space:]]*) + ${IFCONFIG_CMD} $_if $_tmpargs $_action && _ret=0 + ;; + esac + fi + + return $_ret +} + +# ifalias_af_common if af action +# Helper function for ifalias(). +# +ifalias_af_common() +{ + local _ret _if _af _action alias ifconfig_args _aliasn _c _tmpargs _iaf + local _vif _punct=".-/+" + + _ret=1 + _aliasn= + _if=$1 + _af=$2 + _action=$3 + + # Normalize $_if before using it in a pattern to list_vars() + ltr "$_if" "$_punct" "_" _vif + + # ifconfig_IF_aliasN which starts with $_af + for alias in `list_vars ifconfig_${_vif}_alias[0-9]\* | + sort_lite -nk1.$((9+${#_vif}+7))` + do + eval ifconfig_args=\"\$$alias\" + _iaf= + case $ifconfig_args in + inet[[:space:]]*) _iaf=inet ;; + inet6[[:space:]]*) _iaf=inet6 ;; + link[[:space:]]*) _iaf=link ;; + ether[[:space:]]*) _iaf=ether ;; + esac + + case ${_af}:${_action}:${_iaf}:"${ifconfig_args}" in + ${_af}:*:${_af}:*) + _aliasn="$_aliasn $ifconfig_args" + ;; + ${_af}:*:"":"") + break + ;; + inet:alias:"":*) + _aliasn="$_aliasn inet $ifconfig_args" + warn "\$${alias} needs leading" \ + "\"inet\" keyword for an IPv4 address." + esac + done + + # backward compatibility: ipv6_ifconfig_IF_aliasN. + case $_af in + inet6) + for alias in `list_vars ipv6_ifconfig_${_vif}_alias[0-9]\* | + sort_lite -nk1.$((14+${#_vif}+7))` + do + eval ifconfig_args=\"\$$alias\" + case ${_action}:"${ifconfig_args}" in + *:"") + break + ;; + alias:*) + _aliasn="${_aliasn} inet6 ${ifconfig_args}" + warn "\$${alias} is obsolete. " \ + "Use ifconfig_${_vif}_aliasN instead." + ;; + esac + done + esac + + # backward compatibility: ipv4_addrs_IF. + for _tmpargs in `get_if_var $_if ipv4_addrs_IF`; do + _aliasn="$_aliasn inet $_tmpargs" + done + + # Handle ifconfig_IF_aliases, ifconfig_IF_aliasN, and the others. + _tmpargs= + for _c in `get_if_var $_if ifconfig_IF_aliases` $_aliasn; do + case $_c in + inet|inet6|link|ether) + case $_tmpargs in + ${_af}[[:space:]]*) + eval ifalias_af_common_handler $_if $_af $_action $_tmpargs && _ret=0 + ;; + esac + _tmpargs=$_c + ;; + *) + _tmpargs="$_tmpargs $_c" + esac + done + # Process the last component + case $_tmpargs in + ${_af}[[:space:]]*) + ifalias_af_common_handler $_if $_af $_action $_tmpargs && _ret=0 + ;; + esac + + return $_ret +} + +# ipv6_prefix_hostid_addr_common if action +# Add or remove IPv6 prefix + hostid addr on the interface $if +# +ipv6_prefix_hostid_addr_common() +{ + local _if _action prefix j + _if=$1 + _action=$2 + prefix=`get_if_var ${_if} ipv6_prefix_IF` + + if [ -n "${prefix}" ]; then + for j in ${prefix}; do + # The default prefixlen is 64. + plen=${j#*/} + case $j:$plen in + $plen:$j) plen=64 ;; + *) j=${j%/*} ;; + esac + + # Normalize the last part by removing ":" + j=${j%::*} + j=${j%:} + ${IFCONFIG_CMD} ${_if} inet6 $j:: \ + prefixlen $plen eui64 ${_action} + + # if I am a router, add subnet router + # anycast address (RFC 2373). + if checkyesno ipv6_gateway_enable; then + ${IFCONFIG_CMD} ${_if} inet6 $j:: \ + prefixlen $plen ${_action} anycast + fi + done + fi +} + +# ipv6_accept_rtadv_up if +# Enable accepting Router Advertisement and send Router +# Solicitation message +ipv6_accept_rtadv_up() +{ + if ipv6_autoconfif $1; then + ${IFCONFIG_CMD} $1 inet6 accept_rtadv up + if [ -x /sbin/rtsol ]; then + /sbin/rtsol ${rtsol_flags} $1 + fi + return 0 + fi + return 1 +} + +# ipv6_accept_rtadv_down if +# Disable accepting Router Advertisement +ipv6_accept_rtadv_down() +{ + if ipv6_autoconfif $1; then + ${IFCONFIG_CMD} $1 inet6 -accept_rtadv + fi +} + +# ifscript_up if +# Evaluate a startup script for the $if interface. +# It returns 0 if a script was found and processed or +# 1 if no script was found. +# +ifscript_up() +{ + if [ -r /etc/start_if.$1 ]; then + . /etc/start_if.$1 + return 0 + else + return 1 + fi +} + +# ifscript_down if +# Evaluate a shutdown script for the $if interface. +# It returns 0 if a script was found and processed or +# 1 if no script was found. +# +ifscript_down() +{ + if [ -r /etc/stop_if.$1 ]; then + . /etc/stop_if.$1 + return 0 + else + return 1 + fi +} + +# wlan_up +# Create IEEE802.11 interfaces. +# +wlan_up() +{ + local _list _iflist parent child_wlans child create_args debug_flags + _list= + _iflist=$* + + # Parse wlans_$parent="$child ..." + for parent in `set | sed -nE 's/wlans_([a-z]+[a-z0-9]+[0-9]+)=.*/\1/p'`; do + child_wlans=`get_if_var $parent wlans_IF` + for child in ${child_wlans}; do + create_args="wlandev $parent `get_if_var $child create_args_IF`" + debug_flags="`get_if_var $child wlandebug_IF`" + case $_iflist in + ""|$child|$child[[:space:]]*|*[[:space:]]$child[[:space:]]*|*[[:space:]]$child) ;; + *) continue ;; + esac + # Skip if ${child} already exists. + if ${IFCONFIG_CMD} $child > /dev/null 2>&1; then + continue + fi + if expr $child : 'wlan[0-9][0-9]*$' >/dev/null 2>&1; then + ${IFCONFIG_CMD} $child create ${create_args} && cfg=0 + else + ${IFCONFIG_CMD} wlan create ${create_args} name $child && cfg=0 + fi + if [ $? -eq 0 ]; then + _list="$_list $child" + fi + if [ -n "${debug_flags}" ]; then + wlandebug -i $child ${debug_flags} + fi + done + done + if [ -n "${_list# }" ]; then + echo "Created wlan(4) interfaces: ${_list# }." + fi + debug "Created wlan(4)s: ${_list# }" +} + +# wlan_down +# Destroy IEEE802.11 interfaces. +# +wlan_down() +{ + local _list _iflist parent child_wlans child + _list= + _iflist=$* + + # Parse wlans_$parent="$child ..." + for parent in `set | sed -nE 's/wlans_([a-z]+[a-z0-9]+[0-9]+)=.*/\1/p'`; do + child_wlans=`get_if_var $parent wlans_IF` + for child in ${child_wlans}; do + case $_iflist in + ""|$child|$child[[:space:]]*|*[[:space:]]$child[[:space:]]*|*[[:space:]]$child) ;; + *) continue ;; + esac + # Skip if ${child} doesn't exists. + if ! ${IFCONFIG_CMD} $child > /dev/null 2>&1; then + continue + fi + ${IFCONFIG_CMD} -n ${child} destroy + if [ $? -eq 0 ]; then + _list="$_list $child" + fi + done + done + if [ -n "${_list# }" ]; then + echo "Destroyed wlan(4) interfaces: ${_list# }." + fi + debug "Destroyed wlan(4)s: ${_list# }" +} + +# clone_up +# Create cloneable interfaces. +# +clone_up() +{ + local _list ifn ifopt _iflist _inet6 _n tmpargs + _list= + _iflist=$* + + # create_args_IF + for ifn in ${cloned_interfaces}; do + # Parse ifn:ifopt. + OIFS=$IFS; IFS=:; set -- $ifn; ifn=$1; ifopt=$2; IFS=$OIFS + case $_iflist in + ""|$ifn|$ifn[[:space:]]*|*[[:space:]]$ifn[[:space:]]*|*[[:space:]]$ifn) ;; + *) continue ;; + esac + case $ifn in + epair[0-9]*) + # epair(4) uses epair[0-9] for creation and + # epair[0-9][ab] for configuration. + # + # Skip if ${ifn}a or ${ifn}b already exist. + if ${IFCONFIG_CMD} ${ifn}a > /dev/null 2>&1; then + continue + elif ${IFCONFIG_CMD} ${ifn}b > /dev/null 2>&1; then + continue + fi + ${IFCONFIG_CMD} ${ifn} create \ + `get_if_var ${ifn} create_args_IF` + if [ $? -eq 0 ]; then + _list="$_list ${ifn}a ${ifn}b" + fi + ;; + *) + # Skip if ${ifn} already exists. + if ${IFCONFIG_CMD} $ifn > /dev/null 2>&1; then + continue + fi + ${IFCONFIG_CMD} ${ifn} create \ + `get_if_var ${ifn} create_args_IF` + if [ $? -eq 0 ]; then + _list="$_list $ifn" + fi + esac + done + for ifn in ${gif_interfaces}; do + # Parse ifn:ifopt. + OIFS=$IFS; IFS=:; set -- $ifn; ifn=$1; ifopt=$2; IFS=$OIFS + case $_iflist in + ""|$ifn|$ifn[[:space:]]*|*[[:space:]]$ifn[[:space:]]*|*[[:space:]]$ifn) ;; + *) continue ;; + esac + # Skip if ifn already exists. + if ${IFCONFIG_CMD} $ifn > /dev/null 2>&1; then + continue + fi + case $ifn in + gif[0-9]*) + ${IFCONFIG_CMD} $ifn create + ;; + *) + _n=$(${IFCONFIG_CMD} gif create) + ${IFCONFIG_CMD} $_n name $ifn + ;; + esac + if [ $? -eq 0 ]; then + _list="$_list $ifn" + tmpargs=$(get_if_var $ifn gifconfig_IF) + _inet6='' + case "$tmpargs" in + '') + ;; + inet6[[:space:]]*) + tmpargs=${tmpargs#inet6} + _inet6=inet6 + # FALLTHROUGH + ;& + *) + ${IFCONFIG_CMD} $ifn $_inet6 tunnel $tmpargs + ;; + esac + fi + done + if [ -n "${_list# }" ]; then + echo "Created clone interfaces: ${_list# }." + fi + debug "Cloned: ${_list# }" +} + +# clone_down +# Destroy cloned interfaces. Destroyed interfaces are echoed to +# standard output. +# +clone_down() +{ + local _list ifn _difn ifopt _iflist _sticky + _list= + _iflist=$* + + : ${cloned_interfaces_sticky:=NO} + if checkyesno cloned_interfaces_sticky; then + _sticky=1 + else + _sticky=0 + fi + for ifn in ${cloned_interfaces} ${gif_interfaces}; do + # Parse ifn:ifopt. + OIFS=$IFS; IFS=:; set -- $ifn; ifn=$1; ifopt=$2; IFS=$OIFS + case $ifopt:$_sticky in + sticky:*) continue ;; # :sticky => not destroy + nosticky:*) ;; # :nosticky => destroy + *:1) continue ;; # global sticky knob == 1 + esac + case $_iflist in + ""|$ifn|$ifn[[:space:]]*|*[[:space:]]$ifn[[:space:]]*|*[[:space:]]$ifn) ;; + *) continue ;; + esac + case $ifn in + epair[0-9]*) + # Note: epair(4) uses epair[0-9] for removal and + # epair[0-9][ab] for configuration. + # + # Skip if both of ${ifn}a and ${ifn}b do not exist. + if ${IFCONFIG_CMD} ${ifn}a > /dev/null 2>&1; then + _difn=${ifn}a + elif ${IFCONFIG_CMD} ${ifn}b > /dev/null 2>&1; then + _difn=${ifn}b + else + continue + fi + ${IFCONFIG_CMD} -n $_difn destroy + if [ $? -eq 0 ]; then + _list="$_list ${ifn}a ${ifn}b" + fi + ;; + *) + # Skip if ifn does not exist. + if ! ${IFCONFIG_CMD} $ifn > /dev/null 2>&1; then + continue + fi + ${IFCONFIG_CMD} -n ${ifn} destroy + if [ $? -eq 0 ]; then + _list="$_list $ifn" + fi + ;; + esac + done + if [ -n "${_list# }" ]; then + echo "Destroyed clone interfaces: ${_list# }." + fi + debug "Destroyed clones: ${_list# }" +} + +# childif_create +# Create and configure child interfaces. Return 0 if child +# interfaces are created. +# +childif_create() +{ + local cfg child child_vlans create_args debug_flags ifn i + cfg=1 + ifn=$1 + + # Create vlan interfaces + child_vlans=`get_if_var $ifn vlans_IF` + + if [ -n "${child_vlans}" ]; then + load_kld if_vlan + fi + + for child in ${child_vlans}; do + if expr $child : '[1-9][0-9]*$' >/dev/null 2>&1; then + child="${ifn}.${child}" + create_args=`get_if_var $child create_args_IF` + ${IFCONFIG_CMD} $child create ${create_args} && cfg=0 + else + create_args="vlandev $ifn `get_if_var $child create_args_IF`" + if expr $child : 'vlan[0-9][0-9]*$' >/dev/null 2>&1; then + ${IFCONFIG_CMD} $child create ${create_args} && cfg=0 + else + i=`${IFCONFIG_CMD} vlan create ${create_args}` + ${IFCONFIG_CMD} $i name $child && cfg=0 + fi + fi + if autoif $child; then + ifn_start $child + fi + done + + return ${cfg} +} + +# childif_destroy +# Destroy child interfaces. +# +childif_destroy() +{ + local cfg child child_vlans ifn + cfg=1 + + child_vlans=`get_if_var $ifn vlans_IF` + for child in ${child_vlans}; do + if expr $child : '[1-9][0-9]*$' >/dev/null 2>&1; then + child="${ifn}.${child}" + fi + if ! ifexists $child; then + continue + fi + ${IFCONFIG_CMD} -n $child destroy && cfg=0 + done + + return ${cfg} +} + +# ng_mkpeer +# Create netgraph nodes. +# +ng_mkpeer() +{ + ngctl -f - 2> /dev/null <<EOF +mkpeer $* +msg dummy nodeinfo +EOF +} + +# ng_create_one +# Create netgraph nodes. +# +ng_create_one() +{ + local t + + ng_mkpeer $* | while read line; do + t=`expr "${line}" : '.* name="\([a-z]*[0-9]*\)" .*'` + if [ -n "${t}" ]; then + echo ${t} + return + fi + done +} + +# ifnet_rename [ifname] +# Rename interfaces if ifconfig_IF_name is defined. +# +ifnet_rename() +{ + local _if _ifname + + # ifconfig_IF_name + for _if in ${*:-$(${IFCONFIG_CMD} -l)}; do + _ifname=`get_if_var $_if ifconfig_IF_name` + if [ ! -z "$_ifname" ]; then + ${IFCONFIG_CMD} $_if name $_ifname + fi + done + + return 0 +} + +# list_net_interfaces type +# List all network interfaces. The type of interface returned +# can be controlled by the type argument. The type +# argument can be any of the following: +# nodhcp - all interfaces, excluding DHCP configured interfaces +# dhcp - list only DHCP configured interfaces +# noautoconf - all interfaces, excluding IPv6 Stateless +# Address Autoconf configured interfaces +# autoconf - list only IPv6 Stateless Address Autoconf +# configured interfaces +# If no argument is specified all network interfaces are output. +# Note that the list will include cloned interfaces if applicable. +# Cloned interfaces must already exist to have a chance to appear +# in the list if ${network_interfaces} is set to `auto'. +# +list_net_interfaces() +{ + local type _tmplist _list _autolist _lo _if + type=$1 + + # Get a list of ALL the interfaces and make lo0 first if it's there. + # + _tmplist= + case ${network_interfaces} in + [Aa][Uu][Tt][Oo]) + _autolist="`${IFCONFIG_CMD} -l`" + _lo= + for _if in ${_autolist} ; do + if autoif $_if; then + if [ "$_if" = "lo0" ]; then + _lo="lo0 " + else + _tmplist="${_tmplist} ${_if}" + fi + fi + done + _tmplist="${_lo}${_tmplist# }" + ;; + *) + for _if in ${network_interfaces} ${cloned_interfaces}; do + # epair(4) uses epair[0-9] for creation and + # epair[0-9][ab] for configuration. + case $_if in + epair[0-9]*) + _tmplist="$_tmplist ${_if}a ${_if}b" + ;; + *) + _tmplist="$_tmplist $_if" + ;; + esac + done + # + # lo0 is effectively mandatory, so help prevent foot-shooting + # + case "$_tmplist" in + lo0|'lo0 '*|*' lo0'|*' lo0 '*) + # This is fine, do nothing + _tmplist="${_tmplist# }" + ;; + *) + _tmplist="lo0 ${_tmplist# }" + ;; + esac + ;; + esac + + _list= + case "$type" in + nodhcp) + for _if in ${_tmplist} ; do + if ! dhcpif $_if && \ + [ -n "`_ifconfig_getargs $_if`" ]; then + _list="${_list# } ${_if}" + fi + done + ;; + dhcp) + for _if in ${_tmplist} ; do + if dhcpif $_if; then + _list="${_list# } ${_if}" + fi + done + ;; + noautoconf) + for _if in ${_tmplist} ; do + if ! ipv6_autoconfif $_if && \ + [ -n "`_ifconfig_getargs $_if ipv6`" ]; then + _list="${_list# } ${_if}" + fi + done + ;; + autoconf) + for _if in ${_tmplist} ; do + if ipv6_autoconfif $_if; then + _list="${_list# } ${_if}" + fi + done + ;; + *) + _list=${_tmplist} + ;; + esac + + echo $_list + + return 0 +} + +# get_default_if -address_family +# Get the interface of the default route for the given address family. +# The -address_family argument must be suitable passing to route(8). +# +get_default_if() +{ + local routeget oldifs defif line + defif= + oldifs="$IFS" + IFS=" +" + for line in `route -n get $1 default 2>/dev/null`; do + case $line in + *interface:*) + defif=${line##*: } + ;; + esac + done + IFS=${oldifs} + + echo $defif +} + +# hexdigit arg +# Echo decimal number $arg (single digit) in hexadecimal format. +hexdigit() +{ + printf '%x\n' "$1" +} + +# hexprint arg +# Echo decimal number $arg (multiple digits) in hexadecimal format. +hexprint() +{ + printf '%x\n' "$1" +} + +is_wired_interface() +{ + local media + + case `${IFCONFIG_CMD} $1 2>/dev/null` in + *media:?Ethernet*) media=Ethernet ;; + esac + + test "$media" = "Ethernet" +} + +# network6_getladdr if [flag] +# Echo link-local address from $if if any. +# If flag is defined, tentative ones will be excluded. +network6_getladdr() +{ + local _if _flag proto addr rest + _if=$1 + _flag=$2 + + ${IFCONFIG_CMD} $_if inet6 2>/dev/null | while read proto addr rest; do + case "${proto}/${addr}/${_flag}/${rest}" in + inet6/fe80::*//*) + echo ${addr} + ;; + inet6/fe80:://*tentative*) # w/o flag + sleep `${SYSCTL_N} net.inet6.ip6.dad_count` + network6_getladdr $_if $_flags + ;; + inet6/fe80::/*/*tentative*) # w/ flag + echo ${addr} + ;; + *) + continue + ;; + esac + + return + done +} diff --git a/libexec/rc/pccard_ether b/libexec/rc/pccard_ether new file mode 100755 index 000000000000..957983e55a8e --- /dev/null +++ b/libexec/rc/pccard_ether @@ -0,0 +1,147 @@ +#!/bin/sh - +# +# +# pccard_ether interfacename [start|stop|restart] +# +# example: pccard_ether fxp0 start +# + +. /etc/rc.subr +. /etc/network.subr + +name="pccard_ether" +start_precmd="checkauto" +start_cmd="pccard_ether_start" +stop_precmd="checkauto" +stop_cmd="pccard_ether_stop" +restart_precmd="checkauto" +restart_cmd="pccard_ether_restart" +startchildren_cmd="pccard_ether_startchildren" +stopchildren_cmd="pccard_ether_stopchildren" +extra_commands="startchildren stopchildren" + +setup_routes() +{ + # Add default route into $static_routes + case ${defaultrouter} in + [Nn][Oo] | '') + ;; + *) + static_routes="default ${static_routes}" + route_default="default ${defaultrouter}" + ;; + esac + + # Add private route for this interface into $static_routes + eval ifx_routes=\$static_routes_${ifn} + if [ -n "${ifx_routes}" ]; then + static_routes="${ifx_routes} ${static_routes}" + fi + + # Set up any static routes if specified + if [ -n "${static_routes}" ]; then + for i in ${static_routes}; do + eval route_args=\$route_${i} + route add ${route_args} + done + fi +} + +remove_routes() +{ + # Delete static route if specified + eval ifx_routes=\$static_routes_${ifn} + if [ -n "${ifx_routes}" ]; then + for i in ${ifx_routes}; do + eval route_args=\$route_${i} + route delete ${route_args} + done + fi +} + +checkauto() +{ + if [ -z "$rc_force" ]; then + # Ignore interfaces with the NOAUTO keyword + autoif $ifn || exit 0 + fi +} + +pccard_ether_start() +{ + ifisup $ifn + case $? in + 0) # Interface is already up, so ignore it. + if [ -z "$rc_force"]; then + exit 0 + fi + ;; + 2) # Interface does not exist. + exit 1 + ;; + esac + + /etc/rc.d/netif quietstart $ifn + + # Do route configuration if needed. + # XXX: should probably do this by calling rc.d/routing. + if [ -n "`ifconfig_getargs $ifn`" ]; then + if ! dhcpif $ifn; then + setup_routes + fi + fi + + # XXX: IPv6 setup should be done in some way. +} + +pccard_ether_stop() +{ + if [ -n "`ifconfig_getargs $ifn`" ]; then + if ! dhcpif $ifn; then + remove_routes + fi + fi + + /etc/rc.d/netif quietstop $ifn + + # clean ARP table + ifexists $ifn && arp -d -i $ifn -a +} + +pccard_ether_restart() +{ + # Hand implemented because the default implementation runs + # the equivalent of "$0 start; $0 stop" and this script + # doesn't support that syntax + pccard_ether_stop + pccard_ether_start +} + +pccard_ether_startchildren() +{ + for child in `get_if_var $ifn wlans_IF`; do + if ifexists $child; then + continue + fi + /etc/rc.d/netif quietstart $child + done +} + +pccard_ether_stopchildren() +{ + for child in `get_if_var $ifn wlans_IF`; do + /etc/rc.d/netif quietstop $child + done +} + +ifn=$1 +shift +if [ -z "$*" ]; then + args="start" +else + args=$* +fi + +load_rc_config pccard_ether +load_rc_config network +run_rc_command $args diff --git a/libexec/rc/rc b/libexec/rc/rc new file mode 100644 index 000000000000..db3c3e20ab44 --- /dev/null +++ b/libexec/rc/rc @@ -0,0 +1,152 @@ +#!/bin/sh +# +# Copyright (c) 2000-2004 The FreeBSD Project +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. + +# System startup script run by init on autoboot +# or after single-user. +# Output and error are redirected to console by init, +# and the console is the controlling terminal. + +# Note that almost all of the user-configurable behavior is no longer in +# this file, but rather in /etc/defaults/rc.conf. Please check that file +# first before contemplating any changes here. If you do need to change +# this file for some reason, we would like to know about it. + +stty status '^T' 2> /dev/null + +# Set shell to ignore SIGINT (2), but not children; +# shell catches SIGQUIT (3) and returns to single user. +# +trap : 2 +trap "echo 'Boot interrupted'; exit 1" 3 + +HOME=/ +PATH=/sbin:/bin:/usr/sbin:/usr/bin +export HOME PATH + +if [ "$1" = autoboot ]; then + autoboot=yes + _boot="faststart" + rc_fast=yes # run_rc_command(): do fast booting +else + autoboot=no + _boot="quietstart" +fi + +_localbase=`/sbin/sysctl -n user.localbase 2> /dev/null` + +dlv=`/sbin/sysctl -n vfs.nfs.diskless_valid 2> /dev/null` +if [ ${dlv:=0} -ne 0 -o -f /etc/diskless ]; then + sh /etc/rc.initdiskless +fi + +# Run these after determining whether we are booting diskless in order +# to minimize the number of files that are needed on a diskless system, +# and to make the configuration file variables available to rc itself. +# +# -o verify has no effect if mac_veriexec is not active +set -o verify +. /etc/rc.subr +set +o verify +load_rc_config $rc_config_xtra + +if have DebugOn; then + # allow DEBUG_SH to be set from loader prompt + export DEBUG_SH=${DEBUG_SH:-$(kenv -q DEBUG_SH)} +fi + +# If we receive a SIGALRM, re-source /etc/rc.conf; this allows rc.d +# scripts to perform "boot-time configuration" including enabling and +# disabling rc.d scripts which appear later in the boot order. +trap "_rc_conf_loaded=false; load_rc_config" ALRM + +skip="-s nostart" +if check_jail jailed; then + skip="$skip -s nojail" + if ! check_jail vnet; then + skip="$skip -s nojailvnet" + fi +fi + +# If the firstboot sentinel doesn't exist, we want to skip firstboot scripts. +if ! [ -e ${firstboot_sentinel} ]; then + skip_firstboot="-s firstboot" +fi + +# Do a first pass to get everything up to $early_late_divider so that +# we can do a second pass that includes $local_startup directories +# +unset system_rc +find_system_scripts +files=`rcorder ${skip} ${skip_firstboot} ${system_rc} 2>/dev/null` +run_rc_scripts --break ${early_late_divider} ${rc_early_flags} $files + +unset files local_rc system_rc + +# Now that disks are mounted, for each dir in $local_startup +# search for init scripts that use the new rc.d semantics. +# +case ${local_startup} in +[Nn][Oo] | '') ;; +*) find_local_scripts_new ;; +esac + +# The firstboot sentinel might be on a newly mounted filesystem; look for it +# again and unset skip_firstboot if we find it. +if [ -e ${firstboot_sentinel} ]; then + skip_firstboot="" +fi + +find_system_scripts +files=`rcorder ${skip} ${skip_firstboot} ${system_rc} ${local_rc} 2>/dev/null` +run_rc_scripts ${rc_late_flags} $files +unset files local_rc system_rc + +# allow for more complicated setups +if have run_rc_scripts_final; then + run_rc_scripts_final +fi + +# Remove the firstboot sentinel, and reboot if it was requested. +# Be a bit paranoid about removing it to handle the common failure +# modes since the consequence of failure can be big. +# Note: this assumes firstboot_sentinel is on / when we have +# a read-only /, or that it is on media that's writable. +if [ -e ${firstboot_sentinel} ]; then + checkyesno root_rw_mount || mount -uw / + chflags -R 0 ${firstboot_sentinel} + rm -rf ${firstboot_sentinel} + if [ -e ${firstboot_sentinel}-reboot ]; then + chflags -R 0 ${firstboot_sentinel}-reboot + rm -rf ${firstboot_sentinel}-reboot + checkyesno root_rw_mount || mount -ur / + kill -INT 1 + fi + checkyesno root_rw_mount || mount -ur / +fi + +echo '' +date +exit 0 diff --git a/libexec/rc/rc.bsdextended b/libexec/rc/rc.bsdextended new file mode 100644 index 000000000000..01222f1e78b4 --- /dev/null +++ b/libexec/rc/rc.bsdextended @@ -0,0 +1,137 @@ +#!/bin/sh +# +# Copyright (c) 2004 Tom Rhodes +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# + +#### +# Sample startup policy for the mac_bsdextended(4) security module. +# +# Suck in the system configuration variables. +#### +if [ -z "${source_rc_confs_defined}" ]; then + if [ -r /etc/defaults/rc.conf ]; then + . /etc/defaults/rc.conf + source_rc_confs + elif [ -r /etc/rc.conf ]; then + . /etc/rc.conf + fi +fi + +#### +# Set ugidfw(8) to CMD: +#### +CMD=/usr/sbin/ugidfw + +#### +# WARNING: recommended reading is the handbook's MAC +# chapter and the ugidfw(8) manual page. You can +# lock yourself out of the system very quickly by setting +# incorrect values here. These are only examples. +#### + +#### +# Build a generic list of rules here, these should be +# modified before using this script. +# +# For apache to read user files, the ruleadd must give +# it permissions by default. +#### +#${CMD} add subject uid 80 object not uid 80 mode rxws; +#${CMD} add subject gid 80 object not gid 80 mode rxws; + +#### +# majordomo compat: +#${CMD} add subject uid 54 object not uid 54 mode rxws; +#${CMD} add subject gid 26 object gid 54 mode rxws; + +#### +# This is for root: +${CMD} add subject uid 0 object not uid 0 mode arxws; +${CMD} add subject gid 0 object not gid 0 mode arxws; + +#### +# And for majordomo: +#${CMD} add subject uid 54 object not uid 54 mode rxws; +#${CMD} add subject gid 54 object not gid 54 mode rxws; + +#### +# And for bin: +${CMD} add subject uid 3 object not uid 3 mode rxws; +${CMD} add subject gid 7 object not gid 7 mode rxws; + +#### +# And for mail/pop: +#${CMD} add subject uid 68 object not uid 68 mode rxws; +#${CMD} add subject gid 6 object not gid 6 mode arxws; + +#### +# And for smmsp: +${CMD} add subject uid 25 object not uid 25 mode rxws; +${CMD} add subject gid 25 object not gid 25 mode rxws; + +#### +# And for mailnull: +${CMD} add subject uid 26 object not uid 26 mode rxws; +${CMD} add subject gid 26 object not gid 26 mode rxws; + +#### +# For cyrus: +#${CMD} add subject uid 60 object not uid 60 mode rxws; +#${CMD} add subject gid 60 object not gid 60 mode rxws; + +#### +# For stunnel: +#${CMD} add subject uid 1018 object not uid 1018 mode rxws; +#${CMD} add subject gid 1018 object not gid 1018 mode rxws; + +#### +# For the nobody account: +${CMD} add subject uid 65534 object not uid 65534 mode rxws; +${CMD} add subject gid 65534 object not gid 65534 mode rxws; + +#### +# NOTICE: The next script adds a rule to allow +# access their mailbox which is owned by GID `6'. +# Removing this will give mailbox lock issues. +for x in `awk -F: '($3 >= 1001) && ($3 != 65534) { print $1 }' /etc/passwd`; + do ${CMD} add subject uid $x object gid 6 mode arwxs; +done; + +#### +# Use some script to get a list of users and +# add all users to mode n for all other users. This +# will isolate all users from other user home directories while +# permitting them to use commands and browse the system. +for x in `awk -F: '($3 >= 1001) && ($3 != 65534) { print $1 }' /etc/passwd`; + do ${CMD} add subject not uid $x object uid $x mode n; +done; + +### +# Do the same thing but only for group ids in place of +# user IDs. +for x in `awk -F: '($3 >= 1001) && ($3 != 65534) { print $3 }' /etc/passwd`; + do ${CMD} add subject not gid $x object uid $x mode n; +done; diff --git a/libexec/rc/rc.conf b/libexec/rc/rc.conf new file mode 100644 index 000000000000..b7cce777c4f6 --- /dev/null +++ b/libexec/rc/rc.conf @@ -0,0 +1,793 @@ +#!/bin/sh + +# This is rc.conf - a file full of useful variables that you can set +# to change the default startup behavior of your system. You should +# not edit this file! Put any overrides into one of the ${rc_conf_files} +# instead and you will be able to update these defaults later without +# spamming your local configuration information. +# +# The ${rc_conf_files} files should only contain values which override +# values set in this file. This eases the upgrade path when defaults +# are changed and new features are added. +# +# All arguments must be in double or single quotes. +# +# For a more detailed explanation of all the rc.conf variables, please +# refer to the rc.conf(5) manual page. +# + +############################################################## +### Important initial Boot-time options #################### +############################################################## + +# Set default value of _localbase if not previously set +: ${_localbase:="$(/sbin/sysctl -n user.localbase 2> /dev/null)"} +: ${_localbase:="/usr/local"} + +# rc_debug can't be set here without interferring with rc.subr's setting it +# when the kenv variable rc.debug is set. +#rc_debug="NO" # Set to YES to enable debugging output from rc.d +rc_info="NO" # Enables display of informational messages at boot. +rc_startmsgs="YES" # Show "Starting foo:" messages at boot +rcshutdown_timeout="90" # Seconds to wait before terminating rc.shutdown +precious_machine="NO" # Set to YES to get some guards against mis-directed + # shutdown(8) commands +early_late_divider="FILESYSTEMS" # Script that separates early/late + # stages of the boot process. Make sure you know + # the ramifications if you change this. + # See rc.conf(5) for more details. +always_force_depends="NO" # Set to check that indicated dependencies are + # running during boot (can increase boot time). + +apm_enable="NO" # Set to YES to enable APM BIOS functions (or NO). +apmd_enable="NO" # Run apmd to handle APM event from userland. +apmd_flags="" # Flags to apmd (if enabled). +ddb_enable="NO" # Set to YES to load ddb scripts at boot. +ddb_config="/etc/ddb.conf" # ddb(8) config file. +devd_enable="YES" # Run devd, to trigger programs on device tree changes. +devd_flags="" # Additional flags for devd(8). +devmatch_enable="YES" # Demand load kernel modules based on device ids. +devmatch_blocklist="" # List of modules (w/o .ko) to exclude from devmatch. +#kld_list="" # Kernel modules to load after local disks are mounted +kldxref_enable="YES" # Build linker.hints files with kldxref(8). +kldxref_clobber="NO" # Overwrite old linker.hints at boot. +kldxref_module_path="" # Override kern.module_path. A ';'-delimited list. +powerd_enable="NO" # Run powerd to lower our power usage. +powerd_flags="" # Flags to powerd (if enabled). +tmpmfs="AUTO" # Set to YES to always create an mfs /tmp, NO to never +tmpsize="20m" # Size of mfs /tmp if created +tmpmfs_flags="-S" # Extra mdmfs options for the mfs /tmp +utx_enable="YES" # Enable user accounting +varmfs="AUTO" # Set to YES to always create an mfs /var, NO to never +varsize="32m" # Size of mfs /var if created +varmfs_flags="-S" # Extra mount options for the mfs /var +mfs_type="auto" # "md", "tmpfs", "auto" to prefer tmpfs with md as fallback +populate_var="AUTO" # Set to YES to always (re)populate /var, NO to never +cleanvar_enable="YES" # Clean the /var directory +var_run_enable="YES" # Save/restore /var/run structure at shutdown/reboot +var_run_autosave="YES" # Only restore /var/run structure at shutdown/reboot + # The user is expected to issue service var_run save to + # manually save the /var/run mtree +var_run_mtree="/var/db/mtree/BSD.var-run.mtree" + # Where to save /var/run mtree +local_startup="${_localbase}/etc/rc.d" # startup script dirs. +script_name_sep=" " # Change if your startup scripts' names contain spaces +rc_conf_files="/etc/rc.conf /etc/rc.conf.local" + +# ZFS support +zfs_enable="NO" # Set to YES to automatically mount ZFS file systems +zfskeys_enable="NO" # Set YES to autoload ZFS encryption keys +zfs_bootonce_activate="NO" # Set YES to make successful bootonce BE permanent +zpool_reguid="" # Set to zpools for which the GUID should be replaced + # upon first boot. +zpool_upgrade="" # Set to zpools for which the version should be upgraded + # upon first boot. + +# ZFSD support +zfsd_enable="NO" # Set to YES to automatically start the ZFS fault + # management daemon. + +gptboot_enable="YES" # GPT boot success/failure reporting. + +# GELI disk encryption configuration. +geli_devices="" # List of devices to automatically attach in addition to + # GELI devices listed in /etc/fstab. +geli_groups="" # List of groups containing devices to automatically + # attach with the same keyfiles and passphrase +geli_tries="" # Number of times to attempt attaching geli device. + # If empty, kern.geom.eli.tries will be used. +geli_default_flags="" # Default flags for geli(8). +geli_autodetach="YES" # Automatically detach on last close. + # Providers are marked as such when all file systems are + # mounted. +# Example use. +#geli_devices="da1 mirror/home" +#geli_da1_flags="-p -k /etc/geli/da1.keys" +#geli_da1_autodetach="NO" +#geli_mirror_home_flags="-k /etc/geli/home.keys" +#geli_groups="storage backup" +#geli_storage_flags="-k /etc/geli/storage.keys" +#geli_storage_devices="ada0 ada1" +#geli_backup_flags="-j /etc/geli/backup.passfile -k /etc/geli/backup.keys" +#geli_backup_devices="ada2 ada3" + +root_rw_mount="YES" # Set to NO to inhibit remounting root read-write. +root_hold_delay="30" # Time to wait for root mount hold release. +fsck_flags="-p" # May be changed to -f (or -f -y) to force a full fsck +fsck_y_enable="NO" # Set to YES to do fsck -y if the initial preen fails. +fsck_y_flags="-T ffs:-R -T ufs:-R" # Additional flags for fsck -y +background_fsck="YES" # Attempt to run fsck in the background where possible. +background_fsck_delay="60" # Time to wait (seconds) before starting the fsck. +growfs_enable="NO" # Set to YES to attempt to grow the root filesystem on boot +growfs_swap_size="" # Set to 0 to disable growfs swap, "" to default size, + # size in bytes to specify swap size. +netfs_types="nfs:NFS smbfs:SMB" # Net filesystems. +extra_netfs_types="NO" # List of network extra filesystem types for delayed + # mount at startup (or NO). + +############################################################## +### Network configuration sub-section ###################### +############################################################## + +### Basic network and firewall/security options: ### +hostname="" # Set this! +hostid_enable="YES" # Set host UUID. +hostid_file="/etc/hostid" # File with hostuuid. +hostid_uuidgen_flags="-r" # Flags to uuidgen. +machine_id_file="/etc/machine-id" # File with machine-id. +nisdomainname="NO" # Set to NIS domain if using NIS (or NO). +dhclient_program="/sbin/dhclient" # Path to dhcp client program. +dhclient_flags="" # Extra flags to pass to dhcp client. +#dhclient_flags_em0="" # Extra dhclient flags for em0 only +background_dhclient="NO" # Start dhcp client in the background. +#background_dhclient_em0="YES" # Start dhcp client on em0 in the background. +dhclient_arpwait="YES" # Wait for ARP resolution +synchronous_dhclient="NO" # Start dhclient directly on configured + # interfaces during startup. +defaultroute_delay="30" # Time to wait for a default route on a DHCP interface. +defaultroute_carrier_delay="5" # Time to wait for carrier while waiting for a default route. +netif_enable="YES" # Set to YES to initialize network interfaces +netif_ipexpand_max="2048" # Maximum number of IP addrs in a range spec. +wpa_supplicant_program="/usr/sbin/wpa_supplicant" +wpa_supplicant_flags="-s" # Extra flags to pass to wpa_supplicant +wpa_supplicant_conf_file="/etc/wpa_supplicant.conf" +# +firewall_enable="NO" # Set to YES to enable firewall functionality +firewall_script="/etc/rc.firewall" # Which script to run to set up the firewall +firewall_type="UNKNOWN" # Firewall type (see /etc/rc.firewall) +firewall_quiet="NO" # Set to YES to suppress rule display +firewall_logging="NO" # Set to YES to enable events logging +firewall_logif="NO" # Set to YES to create logging-pseudo interface +firewall_flags="" # Flags passed to ipfw when type is a file +firewall_coscripts="" # List of executables/scripts to run after + # firewall starts/stops +firewall_client_net="192.0.2.0/24" # IPv4 Network address for "client" + # firewall. +#firewall_client_net_ipv6="2001:db8:2:1::/64" # IPv6 network prefix for + # "client" firewall. +firewall_simple_iif="em1" # Inside network interface for "simple" + # firewall. +firewall_simple_inet="192.0.2.16/28" # Inside network address for "simple" + # firewall. +firewall_simple_oif="em0" # Outside network interface for "simple" + # firewall. +firewall_simple_onet="192.0.2.0/28" # Outside network address for "simple" + # firewall. +#firewall_simple_iif_ipv6="em1" # Inside IPv6 network interface for "simple" + # firewall. +#firewall_simple_inet_ipv6="2001:db8:2:800::/56" # Inside IPv6 network prefix + # for "simple" firewall. +#firewall_simple_oif_ipv6="em0" # Outside IPv6 network interface for "simple" + # firewall. +#firewall_simple_onet_ipv6="2001:db8:2:0::/56" # Outside IPv6 network prefix + # for "simple" firewall. +firewall_myservices="" # List of ports/protocols on which this host + # offers services for "workstation" firewall. +firewall_allowservices="" # List of IPs which have access to + # $firewall_myservices for "workstation" + # firewall. +firewall_trusted="" # List of IPs which have full access to this + # host for "workstation" firewall. +firewall_logdeny="NO" # Set to YES to log default denied incoming + # packets for "workstation" firewall. +firewall_nologports="135-139,445 1026,1027 1433,1434" # List of TCP/UDP ports + # for which denied incoming packets are not + # logged for "workstation" firewall. +firewall_nat_enable="NO" # Enable kernel NAT (if firewall_enable == YES) +firewall_nat_interface="" # Public interface or IPaddress to use +firewall_nat_flags="" # Additional configuration parameters +firewall_nat64_enable="NO" # Enable kernel NAT64 module. +firewall_nptv6_enable="NO" # Enable kernel NPTv6 module. +firewall_pmod_enable="NO" # Enable kernel protocols modification module. +dummynet_enable="NO" # Load the dummynet(4) module +ipfw_netflow_enable="NO" # Enable netflow logging via ng_netflow +ip_portrange_first="NO" # Set first dynamically allocated port +ip_portrange_last="NO" # Set last dynamically allocated port +ike_enable="NO" # Enable IKE daemon (usually racoon or isakmpd) +ike_program="${_localbase}/sbin/isakmpd" # Path to IKE daemon +ike_flags="" # Additional flags for IKE daemon +ipsec_enable="NO" # Set to YES to run setkey on ipsec_file +ipsec_file="/etc/ipsec.conf" # Name of config file for setkey +natd_program="/sbin/natd" # path to natd, if you want a different one. +natd_enable="NO" # Enable natd (if firewall_enable == YES). +natd_interface="" # Public interface or IPaddress to use. +natd_flags="" # Additional flags for natd. +ipfilter_enable="NO" # Set to YES to enable ipfilter functionality +ipfilter_program="/sbin/ipf" # where the ipfilter program lives +ipfilter_rules="/etc/ipf.rules" # rules definition file for ipfilter, see + # /usr/src/share/examples/ipfilter for examples +ipfilter_flags="" # additional flags for ipfilter +ipfilter_optionlist="" # optionlist for ipf(8) -T +ippool_enable="NO" # Set to YES to enable ip filter pools +ippool_program="/sbin/ippool" # where the ippool program lives +ippool_rules="/etc/ippool.tables" # rules definition file for ippool +ippool_flags="" # additional flags for ippool +ipnat_enable="NO" # Set to YES to enable ipnat functionality +ipnat_program="/sbin/ipnat" # where the ipnat program lives +ipnat_rules="/etc/ipnat.rules" # rules definition file for ipnat +ipnat_flags="" # additional flags for ipnat +ipmon_enable="NO" # Set to YES for ipmon; needs ipfilter or ipnat +ipmon_program="/sbin/ipmon" # where the ipfilter monitor program lives +ipmon_flags="-Ds" # typically "-Ds" or "-D /var/log/ipflog" +ipfs_enable="NO" # Set to YES to enable saving and restoring + # of state tables at shutdown and boot +ipfs_program="/sbin/ipfs" # where the ipfs program lives +ipfs_flags="" # additional flags for ipfs +pf_enable="NO" # Set to YES to enable packet filter (pf) +pf_rules="/etc/pf.conf" # rules definition file for pf (nonexistent + # by default) +pf_program="/sbin/pfctl" # where the pfctl program lives +pf_flags="" # additional flags for pfctl +pf_fallback_rules_enable="NO" # fallback if loading ruleset fails +pf_fallback_rules="block drop log all" # rules to load on pf ruleset failure +#pf_fallback_rules="block drop log all +#pass quick on em4" # multi-rule +pf_fallback_rules_file="/etc/pf-fallback.conf" # rules file on ruleset failure +pflog_enable="NO" # Set to YES to enable packet filter logging +pflog_logfile="/var/log/pflog" # where pflogd should store the logfile +pflog_program="/sbin/pflogd" # where the pflogd program lives +pflog_flags="" # additional flags for pflogd +dnctl_enable="NO" +dnctl_program="/sbin/dnctl" +dnctl_rules="/etc/dnctl.conf" +ftpproxy_enable="NO" # Set to YES to enable ftp-proxy(8) for pf +ftpproxy_flags="" # additional flags for ftp-proxy(8) +pfsync_enable="NO" # Expose pf state to other hosts for syncing +pfsync_syncdev="" # Interface for pfsync to work through +pfsync_syncpeer="" # IP address of pfsync peer host +pfsync_ifconfig="" # Additional options to ifconfig(8) for pfsync +tcp_extensions="YES" # Set to NO to turn off RFC1323 extensions. +log_in_vain="0" # >=1 to log connects to ports w/o listeners. +tcp_keepalive="YES" # Enable stale TCP connection timeout (or NO). +tcp_drop_synfin="NO" # Set to YES to drop TCP packets with SYN+FIN + # NOTE: this violates the TCP specification +icmp_drop_redirect="auto" # Set to YES to ignore ICMP REDIRECT packets +icmp_log_redirect="NO" # Set to YES to log ICMP REDIRECT packets +network_interfaces="auto" # List of network interfaces (or "auto"). +cloned_interfaces="" # List of cloned network interfaces to create. +#cloned_interfaces="gif0 gif1 gif2 gif3" # Pre-cloning GENERIC config. +#ifconfig_lo0="inet 127.0.0.1/8" # default loopback device configuration. +#ifconfig_lo0_alias0="inet 127.0.0.254/32" # Sample alias entry. +#ifconfig_em0_ipv6="inet6 2001:db8:1::1 prefixlen 64" # Sample IPv6 addr entry +#ifconfig_em0_alias0="inet6 2001:db8:2::1 prefixlen 64" # Sample IPv6 alias +#ifconfig_em0_name="net0" # Change interface name from em0 to net0. +#vlans_em0="101 vlan0" # vlan(4) interfaces for em0 device +#create_args_vlan0="vlan 102" # vlan tag for vlan0 device +#wlans_ath0="wlan0" # wlan(4) interfaces for ath0 device +#wlandebug_wlan0="scan+auth+assoc" # Set debug flags with wlandebug(8) +#ipv4_addrs_em0="192.168.0.1/24 192.168.1.1-5/28" # example IPv4 address entry. +# +#autobridge_interfaces="bridge0" # List of bridges to check +#autobridge_bridge0="tap* vlan0" # Interface glob to automatically add to the bridge + +# User ppp configuration. +ppp_enable="NO" # Start user-ppp (or NO). +ppp_program="/usr/sbin/ppp" # Path to user-ppp program. +ppp_mode="auto" # Choice of "auto", "ddial", "direct" or "dedicated". + # For details see man page for ppp(8). Default is auto. +ppp_nat="YES" # Use PPP's internal network address translation or NO. +ppp_profile="papchap" # Which profile to use from /etc/ppp/ppp.conf. +ppp_user="root" # Which user to run ppp as + +# Start multiple instances of ppp at boot time +#ppp_profile="profile1 profile2 profile3" # Which profiles to use +#ppp_profile1_mode="ddial" # Override ppp mode for profile1 +#ppp_profile2_nat="NO" # Override nat mode for profile2 +# profile3 uses default ppp_mode and ppp_nat + +### Network daemon (miscellaneous) ### +hostapd_program="/usr/sbin/hostapd" +hostapd_enable="NO" # Run hostap daemon. +syslogd_enable="YES" # Run syslog daemon (or NO). +syslogd_program="/usr/sbin/syslogd" # path to syslogd, if you want a different one. +syslogd_flags="-s" # Flags to syslogd (if enabled). +syslogd_oomprotect="YES" # Don't kill syslogd when swap space is exhausted. +altlog_proglist="" # List of chrooted applicatioins in /var +inetd_enable="NO" # Run the network daemon dispatcher (YES/NO). +inetd_program="/usr/sbin/inetd" # path to inetd, if you want a different one. +inetd_flags="-wW -C 60" # Optional flags to inetd +iscsid_enable="NO" # iSCSI initiator daemon. +iscsictl_enable="NO" # iSCSI initiator autostart. +iscsictl_flags="-Aa" # Optional flags to iscsictl. +hastd_enable="NO" # Run the HAST daemon (YES/NO). +hastd_program="/sbin/hastd" # path to hastd, if you want a different one. +hastd_flags="" # Optional flags to hastd. +ggated_enable="NO" # Run the ggate daemon (YES/NO). +ggated_config="/etc/gg.exports" # ggated(8) exports file. +ggated_flags="" # Extra parameters like which port to bind to. +ctld_enable="NO" # CAM Target Layer / iSCSI target daemon. +local_unbound_enable="NO" # Local caching DNS resolver +local_unbound_oomprotect="YES" # Don't kill local_unbound when swap space is exhausted. +local_unbound_tls="NO" # Use DNS over TLS +blacklistd_enable="NO" # Renamed to blocklistd_enable. +blacklistd_flags="" # Renamed to blocklistd_flags. +blocklistd_enable="NO" # Run blocklistd daemon (YES/NO). +blocklistd_flags="" # Optional flags for blocklistd(8). +resolv_enable="YES" # Enable resolv / resolvconf + +# +# kerberos. Do not run the admin daemons on slave servers +# +kdc_enable="NO" # Run a kerberos 5 KDC (or NO). +kdc_program="" # path to kerberos 5 KDC +kdc_flags="" # Additional flags to the kerberos 5 KDC +kdc_restart="NO" # Auto restart kdc on abnormal termination +kdc_restart_delay="" # Auto restart delay seconds +kadmind_enable="NO" # Run kadmind (or NO) +kadmind_program="/usr/libexec/kadmind" # path to kadmind +kpasswdd_enable="NO" # Run kpasswdd (or NO) +kpasswdd_program="/usr/libexec/kpasswdd" # path to kpasswdd +kfd_enable="NO" # Run kfd (or NO) +kfd_program="/usr/libexec/kfd" # path to kerberos 5 kfd daemon +kfd_flags="" +ipropd_master_enable="NO" # Run Heimdal incremental propagation daemon + # (master daemon). +ipropd_master_program="/usr/libexec/ipropd-master" +ipropd_master_flags="" # Flags to ipropd-master. +ipropd_master_keytab="/etc/krb5.keytab" # keytab for ipropd-master. +ipropd_master_slaves="" # slave node names used for /var/heimdal/slaves. +ipropd_slave_enable="NO" # Run Heimdal incremental propagation daemon + # (slave daemon). +ipropd_slave_program="/usr/libexec/ipropd-slave" +ipropd_slave_flags="" # Flags to ipropd-slave. +ipropd_slave_keytab="/etc/krb5.keytab" # keytab for ipropd-slave. +ipropd_slave_master="" # master node name. + +gssd_enable="NO" # Run the gssd daemon (or NO). +gssd_program="/usr/sbin/gssd" # Path to gssd. +gssd_flags="" # Flags for gssd. + +rwhod_enable="NO" # Run the rwho daemon (or NO). +rwhod_flags="" # Flags for rwhod +rarpd_enable="NO" # Run rarpd (or NO). +rarpd_flags="-a" # Flags to rarpd. +bootparamd_enable="NO" # Run bootparamd (or NO). +bootparamd_flags="" # Flags to bootparamd +pppoed_enable="NO" # Run the PPP over Ethernet daemon. +pppoed_provider="*" # Provider and ppp(8) config file entry. +pppoed_flags="-P /var/run/pppoed.pid" # Flags to pppoed (if enabled). +pppoed_interface="em0" # The interface that pppoed runs on. +sshd_enable="NO" # Enable sshd +sshd_oomprotect="YES" # Don't kill sshd when swap space is exhausted. +sshd_program="/usr/sbin/sshd" # path to sshd, if you want a different one. +sshd_flags="" # Additional flags for sshd. + +### Network daemon (NFS): All need rpcbind_enable="YES" ### +autofs_enable="NO" # Run autofs daemons. +automount_flags="" # Flags to automount(8) (if autofs enabled). +automountd_flags="" # Flags to automountd(8) (if autofs enabled). +autounmountd_flags="" # Flags to autounmountd(8) (if autofs enabled). +nfs_client_enable="NO" # This host is an NFS client (or NO). +nfs_access_cache="60" # Client cache timeout in seconds +nfs_server_enable="NO" # This host is an NFS server (or NO). +nfs_server_flags="-u -t" # Flags to nfsd (if enabled). +nfs_server_managegids="NO" # The NFS server maps gids for AUTH_SYS (or NO). +nfs_server_maxio="131072" # Maximum I/O size for the nfsd. +mountd_enable="NO" # Run mountd (or NO). +mountd_flags="-r -S" # Flags to mountd (if NFS server enabled). +weak_mountd_authentication="NO" # Allow non-root mount requests to be served. +nfs_reserved_port_only="YES" # Provide NFS only on secure port (or NO). +nfs_bufpackets="" # bufspace (in packets) for client +rpc_lockd_enable="NO" # Run NFS rpc.lockd needed for client/server. +rpc_lockd_flags="" # Flags to rpc.lockd (if enabled). +rpc_statd_enable="NO" # Run NFS rpc.statd needed for client/server. +rpc_statd_flags="" # Flags to rpc.statd (if enabled). +rpcbind_enable="NO" # Run the portmapper service (YES/NO). +rpcbind_program="/usr/sbin/rpcbind" # path to rpcbind, if you want a different one. +rpcbind_flags="" # Flags to rpcbind (if enabled). +rpc_ypupdated_enable="NO" # Run if NIS master and SecureRPC (or NO). +nfsv4_server_enable="NO" # Enable support for NFSv4 +nfsv4_server_only="NO" # Set NFS server to NFSv4 only +nfscbd_enable="NO" # NFSv4 client side callback daemon +nfscbd_flags="" # Flags for nfscbd +nfsuserd_enable="NO" # NFSv4 user/group name mapping daemon +nfsuserd_flags="" # Flags for nfsuserd +tlsclntd_enable="NO" # Run rpc.tlsclntd needed for NFS-over-TLS mount +tlsclntd_flags="" # Flags for rpc.tlsclntd +tlsservd_enable="NO" # Run rpc.tlsservd needed for NFS-over-TLS nfsd +tlsservd_flags="" # Flags for rpc.tlsservd + +### Network Time Services options: ### +ntpdate_enable="NO" # Run ntpdate to sync time on boot (or NO). +ntpdate_program="/usr/sbin/ntpdate" # path to ntpdate, if you want a different one. +ntpdate_flags="-b" # Flags to ntpdate (if enabled). +ntpdate_config="/etc/ntp.conf" # ntpdate(8) configuration file +ntpdate_hosts="" # Whitespace-separated list of ntpdate(8) servers. +ntpd_enable="NO" # Run ntpd Network Time Protocol (or NO). +ntpd_program="/usr/sbin/ntpd" # path to ntpd, if you want a different one. +ntpd_config="/etc/ntp.conf" # ntpd(8) configuration file +ntpd_sync_on_start="NO" # Sync time on ntpd startup, even if offset is high +ntpd_flags="" # Additional flags to ntpd +ntp_src_leapfile="/etc/ntp/leap-seconds" + # Initial source for ntpd leapfile +ntp_db_leapfile="/var/db/ntpd.leap-seconds.list" + # Canonical place to get the leap seconds from +ntp_leapfile_sources="https://hpiers.obspm.fr/iers/bul/bulc/ntp/leap-seconds.list https://data.iana.org/time-zones/tzdb/leap-seconds.list" + # Source from which to fetch leapfile +ntp_leapfile_fetch_opts="-mq" # Options to use for ntp leapfile fetch, + # e.g. --no-verify-peer +ntp_leapfile_expiry_days=30 # Check for new leapfile 30 days prior to + # expiry. +ntp_leapfile_fetch_verbose="NO" # Be verbose during NTP leapfile fetch + +# Network Information Services (NIS) options: All need rpcbind_enable="YES" ### +nis_client_enable="NO" # We're an NIS client (or NO). +nis_client_flags="" # Flags to ypbind (if enabled). +nis_ypset_enable="NO" # Run ypset at boot time (or NO). +nis_ypset_flags="" # Flags to ypset (if enabled). +nis_server_enable="NO" # We're an NIS server (or NO). +nis_server_flags="" # Flags to ypserv (if enabled). +nis_ypxfrd_enable="NO" # Run rpc.ypxfrd at boot time (or NO). +nis_ypxfrd_flags="" # Flags to rpc.ypxfrd (if enabled). +nis_yppasswdd_enable="NO" # Run rpc.yppasswdd at boot time (or NO). +nis_yppasswdd_flags="" # Flags to rpc.yppasswdd (if enabled). +nis_ypldap_enable="NO" # Run ypldap at boot time (or NO). +nis_ypldap_flags="" # Flags to ypldap (if enabled). + +### SNMP daemon ### +# Be sure to understand the security implications of running SNMP v1/v2 +# in your network. +bsnmpd_enable="NO" # Run the SNMP daemon (or NO). +bsnmpd_flags="" # Flags for bsnmpd. + +### Network routing options: ### +defaultrouter="NO" # Set to default gateway (or NO). +#defaultrouter_fibN="192.0.2.1" # Use this form to set a gateway for FIB N +static_arp_pairs="" # Set to static ARP list (or leave empty). +static_ndp_pairs="" # Set to static NDP list (or leave empty). +static_routes="" # Set to static route list (or leave empty). +gateway_enable="NO" # Set to YES if this host will be a gateway. +routed_enable="NO" # Set to YES to enable a routing daemon. +routed_program="/sbin/routed" # Name of routing daemon to use if enabled. +routed_flags="-q" # Flags for routing daemon. +arpproxy_all="NO" # replaces obsolete kernel option ARP_PROXYALL. +forward_sourceroute="NO" # do source routing (only if gateway_enable is set to "YES") +accept_sourceroute="NO" # accept source routed packets to us + +### Bluetooth ### +hcsecd_enable="NO" # Enable hcsecd(8) (or NO) +hcsecd_config="/etc/bluetooth/hcsecd.conf" # hcsecd(8) configuration file + +sdpd_enable="NO" # Enable sdpd(8) (or NO) +sdpd_control="/var/run/sdp" # sdpd(8) control socket +sdpd_groupname="nobody" # set spdp(8) user/group to run as after +sdpd_username="nobody" # it initializes + +bthidd_enable="NO" # Enable bthidd(8) (or NO) +bthidd_config="/etc/bluetooth/bthidd.conf" # bthidd(8) configuration file +bthidd_hids="/var/db/bthidd.hids" # bthidd(8) known HID devices file +bthidd_evdev_support="AUTO" # AUTO depends on EVDEV_SUPPORT kernel option + +rfcomm_pppd_server_enable="NO" # Enable rfcomm_pppd(8) in server mode (or NO) +rfcomm_pppd_server_profile="one two" # Profile to use from /etc/ppp/ppp.conf +# +#rfcomm_pppd_server_one_bdaddr="" # Override local bdaddr for 'one' +rfcomm_pppd_server_one_channel="1" # Override local channel for 'one' +#rfcomm_pppd_server_one_register_sp="NO" # Override SP and DUN register +#rfcomm_pppd_server_one_register_dun="NO" # for 'one' +# +#rfcomm_pppd_server_two_bdaddr="" # Override local bdaddr for 'two' +rfcomm_pppd_server_two_channel="3" # Override local channel for 'two' +#rfcomm_pppd_server_two_register_sp="NO" # Override SP and DUN register +#rfcomm_pppd_server_two_register_dun="NO" # for 'two' + +ubthidhci_enable="NO" # Switch an USB BT controller present on +#ubthidhci_busnum="3" # bus 3 and addr 2 from HID mode to HCI mode. +#ubthidhci_addr="2" # Check usbconfig list to find the correct + # numbers for your system. + +### Network link/usability verification options +netwait_enable="NO" # Enable rc.d/netwait (or NO) +#netwait_ip="" # Wait for ping response from any IP in this list. +netwait_timeout="60" # Total number of seconds to perform pings. +#netwait_if="" # Wait for active link on each intf in this list. +netwait_if_timeout="30" # Total number of seconds to monitor link state. +netwait_dad="NO" # Wait for DAD to complete +netwait_dad_timeout="" # Total number of seconds to wait for DAD, zero + # or unset to autodetect + +### Miscellaneous network options: ### +icmp_bmcastecho="NO" # respond to broadcast ping packets + +### IPv6 options: ### +ipv6_network_interfaces="auto" # List of IPv6 network interfaces + # (or "auto" or "none"). +ipv6_activate_all_interfaces="NO" # If NO, interfaces which have no + # corresponding $ifconfig_IF_ipv6 is + # marked as IFDISABLED for security + # reason. +ipv6_defaultrouter="NO" # Set to IPv6 default gateway (or NO). +#ipv6_defaultrouter="2002:c058:6301::" # Use this for 6to4 (RFC 3068) +#ipv6_defaultrouter_fibN="2001:db8::" # Use this form to set a gateway for FIB N +ipv6_static_routes="" # Set to static route list (or leave empty). +#ipv6_static_routes="xxx" # An example to set fec0:0000:0000:0006::/64 + # route toward loopback interface. +#ipv6_route_xxx="fec0:0000:0000:0006:: -prefixlen 64 ::1" +ipv6_gateway_enable="NO" # Set to YES if this host will be a gateway. +ipv6_cpe_wanif="NO" # Set to the upstream interface name if this + # node will work as a router to forward IPv6 + # packets not explicitly addressed to itself. +ipv6_privacy="NO" # Use privacy address on RA-receiving IFs + # (RFC 4941) + +route6d_enable="NO" # Set to YES to enable an IPv6 routing daemon. +route6d_program="/usr/sbin/route6d" # Name of IPv6 routing daemon. +route6d_flags="" # Flags to IPv6 routing daemon. +#route6d_flags="-l" # Example for route6d with only IPv6 site local + # addrs. +#route6d_flags="-q" # If you want to run a routing daemon on an end + # node, you should stop advertisement. +#ipv6_network_interfaces="em0 em1" # Examples for router + # or static configuration for end node. + # Choose correct prefix value. +#ipv6_prefix_em0="fec0:0000:0000:0001 fec0:0000:0000:0002" # Examples for rtr. +#ipv6_prefix_em1="fec0:0000:0000:0003 fec0:0000:0000:0004" # Examples for rtr. +ipv6_default_interface="NO" # Default output interface for scoped addrs. + # This works only with + # ipv6_gateway_enable="NO". +rtsol_flags="-i" # Flags to IPv6 router solicitation. +rtsold_enable="NO" # Set to YES to enable an IPv6 router + # solicitation daemon. +rtsold_flags="-a -i" # Flags to an IPv6 router solicitation + # daemon. +rtadvd_enable="NO" # Set to YES to enable an IPv6 router + # advertisement daemon. If set to YES, + # this router becomes a possible candidate + # IPv6 default router for local subnets. +rtadvd_flags="" # Flags to the IPv6 router advertisement daemon. +rtadvd_interfaces="" # Interfaces rtadvd sends RA packets. +stf_interface_ipv4addr="" # Local IPv4 addr for 6to4 IPv6 over IPv4 + # tunneling interface. Specify this entry + # to enable 6to4 interface. +stf_interface_ipv4plen="0" # Prefix length for 6to4 IPv4 addr, + # to limit peer addr range. Effective value + # is 0-31. +stf_interface_ipv6_ifid="0:0:0:1" # IPv6 interface id for stf0. + # If you like, you can set "AUTO" for this. +stf_interface_ipv6_slaid="0000" # IPv6 Site Level Aggregator for stf0 +ipv6_ipv4mapping="NO" # Set to "YES" to enable IPv4 mapped IPv6 addr + # communication. (like ::ffff:a.b.c.d) +ip6addrctl_enable="YES" # Set to YES to enable default address selection +ip6addrctl_verbose="NO" # Set to YES to enable verbose configuration messages +ip6addrctl_policy="AUTO" # A pre-defined address selection policy + # (ipv4_prefer, ipv6_prefer, or AUTO) + +############################################################## +### System console options ################################# +############################################################## + +keyboard="" # keyboard device to use (default /dev/kbd0). +keymap="NO" # keymap in /usr/share/{syscons,vt}/keymaps/* (or NO). +keyrate="NO" # keyboard rate to: slow, normal, fast (or NO). +keybell="NO" # See kbdcontrol(1) for options. Use "off" to disable. +keychange="NO" # function keys default values (or NO). +cursor="NO" # cursor type {normal|blink|destructive} (or NO). +scrnmap="NO" # screen map in /usr/share/syscons/scrnmaps/* (or NO). +font8x16="NO" # font 8x16 from /usr/share/{syscons,vt}/fonts/* (or NO). +font8x14="NO" # font 8x14 from /usr/share/{syscons,vt}/fonts/* (or NO). +font8x8="NO" # font 8x8 from /usr/share/{syscons,vt}/fonts/* (or NO). +blanktime="300" # blank time (in seconds) or "NO" to turn it off. +saver="NO" # screen saver: Uses /boot/kernel/${saver}_saver.ko +moused_nondefault_enable="YES" # Treat non-default mice as enabled unless + # specifically overridden in rc.conf(5). +moused_enable="NO" # Run the mouse daemon. +moused_type="evdev" # See man page for rc.conf(5) for available settings. +moused_port="/dev/psm0" # Set to your mouse port. +moused_flags="" # Any additional flags to moused. +mousechar_start="NO" # if 0xd0-0xd3 default range is occupied in your + # language code table, specify alternative range + # start like mousechar_start=3, see vidcontrol(1) +msconvd_enable="NO" # Run the mouse protocol conversion daemon. +msconvd_type="auto" # See rc.conf(5) man page for available moused_type-s. +msconvd_ports="" # List of msconvd ports. +msconvd_flags="" # Any additional flags to msconvd. +allscreens_flags="" # Set this vidcontrol mode for all virtual screens +allscreens_kbdflags="" # Set this kbdcontrol mode for all virtual screens + +############################################################## +### Mail Transfer Agent (MTA) options ###################### +############################################################## + +# Settings for /etc/rc.d/sendmail: +sendmail_enable="NONE" # Run the sendmail inbound daemon (YES/NO/NONE). + # If NONE, don't start any sendmail processes. +sendmail_pidfile="/var/run/sendmail.pid" # sendmail pid file +sendmail_procname="/usr/sbin/sendmail" # sendmail process name +sendmail_flags="-L sm-mta -bd -q30m" # Flags to sendmail (as a server) +sendmail_cert_create="YES" # Create a server certificate if none (YES/NO) +#sendmail_cert_cn="CN" # CN of the generate certificate +sendmail_submit_enable="YES" # Start a localhost-only MTA for mail submission +sendmail_submit_flags="-L sm-mta -bd -q30m -ODaemonPortOptions=Addr=localhost" + # Flags for localhost-only MTA +sendmail_outbound_enable="YES" # Dequeue stuck mail (YES/NO). +sendmail_outbound_flags="-L sm-queue -q30m" # Flags to sendmail (outbound only) +sendmail_msp_queue_enable="YES" # Dequeue stuck clientmqueue mail (YES/NO). +sendmail_msp_queue_flags="-L sm-msp-queue -Ac -q30m" + # Flags for sendmail_msp_queue daemon. +sendmail_rebuild_aliases="NO" # Run newaliases if necessary (YES/NO). + + +############################################################## +### Miscellaneous administrative options ################### +############################################################## + +auditd_enable="NO" # Run the audit daemon. +auditd_program="/usr/sbin/auditd" # Path to the audit daemon. +auditd_flags="" # Which options to pass to the audit daemon. +auditdistd_enable="NO" # Run the audit daemon. +auditdistd_program="/usr/sbin/auditdistd" # Path to the auditdistd daemon. +auditdistd_flags="" # Which options to pass to the auditdistd daemon. +cron_enable="YES" # Run the periodic job daemon. +cron_program="/usr/sbin/cron" # Which cron executable to run (if enabled). +cron_dst="YES" # Handle DST transitions intelligently (YES/NO) +cron_flags="" # Which options to pass to the cron daemon. +cfumass_enable="NO" # Create default LUN for cfumass(4). +cfumass_dir="/var/cfumass" # File to LUN's contents. +cfumass_image="/var/tmp/cfumass.img" # LUN's backing file path. +lpd_enable="NO" # Run the line printer daemon. +lpd_program="/usr/sbin/lpd" # path to lpd, if you want a different one. +lpd_flags="" # Flags to lpd (if enabled). +nscd_enable="NO" # Run the nsswitch caching daemon. +chkprintcap_enable="NO" # Run chkprintcap(8) before running lpd. +chkprintcap_flags="-d" # Create missing directories by default. +dumpdev="AUTO" # Device to crashdump to (device name, AUTO, or NO); + # this should be commented out here + # for stable branches to respect kenv. +dumpon_flags="" # Options to pass to dumpon(8), followed by dumpdev. +dumpdir="/var/crash" # Directory where crash dumps are to be stored +savecore_enable="YES" # Extract core from dump devices if any +savecore_flags="-m 10" # Used if dumpdev is enabled above, and present. + # By default, only the 10 most recent kernel dumps + # are saved. +service_delete_empty="NO" # Have 'service delete' remove empty rc.conf.d files. +crashinfo_enable="YES" # Automatically generate crash dump summary. +crashinfo_program="/usr/sbin/crashinfo" # Script to generate crash dump summary. +quota_enable="NO" # turn on quotas on startup (or NO). +check_quotas="YES" # Check quotas on startup (or NO). +quotaon_flags="-a" # Turn quotas on for all file systems (if enabled) +quotaoff_flags="-a" # Turn quotas off for all file systems at shutdown +quotacheck_flags="-a" # Check all file system quotas (if enabled) +accounting_enable="NO" # Turn on process accounting (or NO). +firstboot_sentinel="/firstboot" # Scripts with "firstboot" keyword are run if + # this file exists. Should be on a R/W filesystem so + # the file can be deleted after the boot completes. +sysvipc_enable="NO" # Load System V IPC primitives at startup (or NO). +linux_enable="NO" # Linux binary compatibility loaded at startup (or NO). +linux_mounts_enable="YES" # If linux_enable is set to YES, mount Linux-specific + # filesystems at startup. +clear_tmp_enable="NO" # Clear /tmp at startup. +clear_tmp_X="YES" # Clear and recreate X11-related directories in /tmp +ldconfig_insecure="NO" # Set to YES to disable ldconfig security checks +ldconfig_paths="/usr/lib/compat ${_localbase}/lib ${_localbase}/lib/compat/pkg" + # shared library search paths +ldconfig32_paths="/usr/lib32/compat" + # 32-bit compatibility shared library search paths +ldconfig_local_dirs="${_localbase}/libdata/ldconfig" + # Local directories with ldconfig configuration files. +ldconfig_local32_dirs="${_localbase}/libdata/ldconfig32" + # Local directories with 32-bit compatibility ldconfig + # configuration files. +kern_securelevel_enable="NO" # kernel security level (see security(7)) +kern_securelevel="-1" # range: -1..3 ; `-1' is the most insecure + # Note that setting securelevel to 0 will result + # in the system booting with securelevel set to 1, as + # init(8) will raise the level when rc(8) completes. +update_motd="YES" # update version info in /var/run/motd (or NO) +entropy_boot_file="/boot/entropy" # Set to NO to disable very early + # (used at early boot time) entropy caching through reboots. +entropy_file="/entropy" # Set to NO to disable late (used when going multi-user) + # entropy through reboots. + # /var/db/entropy-file is preferred if / is not avail. +entropy_dir="/var/db/entropy" # Set to NO to disable caching entropy via cron. +entropy_save_sz="4096" # Size of the entropy cache files. +entropy_save_num="8" # Number of entropy cache files to save. +harvest_mask="4607" # Entropy device harvests all but the very invasive sources. + # (See 'sysctl kern.random.harvest' and random(4)) +osrelease_enable="YES" # Update /var/run/os-release on boot (or NO). +osrelease_file="/var/run/os-release" # File to update for os-release. +osrelease_perms="444" # Default permission for os-release file. +dmesg_enable="YES" # Save dmesg(8) to /var/run/dmesg.boot +watchdogd_enable="NO" # Start the software watchdog daemon +watchdogd_flags="" # Flags to watchdogd (if enabled) +watchdogd_timeout="" # watchdogd timeout, overrides -t in watchdogd_flags +watchdogd_shutdown_timeout="" # Timeout to use after watchdogd is stopped. + # Has effect only for system shutdown. + # Overrides -x in watchdogd_flags. +devfs_rulesets="/etc/defaults/devfs.rules /etc/devfs.rules" # Files containing + # devfs(8) rules. +devfs_system_ruleset="" # The name (NOT number) of a ruleset to apply to /dev +devfs_set_rulesets="" # A list of /mount/dev=ruleset_name settings to + # apply (must be mounted already, i.e. fstab(5)) +devfs_load_rulesets="YES" # Enable to always load the default rulesets +performance_cx_lowest="NONE" # Online CPU idle state +performance_cpu_freq="NONE" # Online CPU frequency +economy_cx_lowest="Cmax" # Offline CPU idle state +economy_cpu_freq="NONE" # Offline CPU frequency +virecover_enable="YES" # Perform housekeeping for the vi(1) editor +ugidfw_enable="NO" # Load mac_bsdextended(4) rules on boot +bsdextended_script="/etc/rc.bsdextended" # Default mac_bsdextended(4) + # ruleset file. +newsyslog_enable="YES" # Run newsyslog at startup. +newsyslog_flags="-CN" # Newsyslog flags to create marked files +mixer_enable="YES" # Run the sound mixer. +opensm_enable="NO" # Opensm(8) for infiniband devices defaults to off +nuageinit_enable="NO" # Run nuageinit at startup + +# rctl(8) requires kernel options RACCT and RCTL +rctl_enable="YES" # Load rctl(8) rules on boot +rctl_rules="/etc/rctl.conf" # rctl(8) ruleset. See rctl.conf(5). + +iovctl_files="" # Config files for iovctl(8) + +############################################################## +### Jail Configuration (see rc.conf(5) manual page) ########## +############################################################## +jail_enable="NO" # Set to NO to disable starting of any jails +jail_conf="/etc/jail.conf" # Configuration file for jail(8) +jail_confwarn="YES" # Prevent warning about obsolete per-jail configuration +jail_parallel_start="NO" # Start jails in the background +jail_list="" # Space separated list of names of jails +jail_reverse_stop="NO" # Stop jails in reverse order + +############################################################## +### Define source_rc_confs, the mechanism used by /etc/rc.* ## +### scripts to source rc_conf_files overrides safely. ## +############################################################## + +if [ -z "${source_rc_confs_defined}" ]; then + source_rc_confs_defined=yes + source_rc_confs() { + local i sourced_files + for i in ${rc_conf_files}; do + case ${sourced_files} in + *:$i:*) + ;; + *) + sourced_files="${sourced_files}:$i:" + if [ -r $i ]; then + . $i + fi + ;; + esac + done + # Re-do process to pick up [possibly] redefined $rc_conf_files + for i in ${rc_conf_files}; do + case ${sourced_files} in + *:$i:*) + ;; + *) + sourced_files="${sourced_files}:$i:" + if [ -r $i ]; then + . $i + fi + ;; + esac + done + } +fi + +# Allow vendors to override FreeBSD defaults in /etc/default/rc.conf +# without the need to carefully manage /etc/rc.conf. +if [ -r /etc/defaults/vendor.conf ]; then + . /etc/defaults/vendor.conf +fi diff --git a/libexec/rc/rc.d/DAEMON b/libexec/rc/rc.d/DAEMON new file mode 100755 index 000000000000..f31fddb55d7e --- /dev/null +++ b/libexec/rc/rc.d/DAEMON @@ -0,0 +1,9 @@ +#!/bin/sh +# +# + +# PROVIDE: DAEMON +# REQUIRE: NETWORKING SERVERS + +# This is a dummy dependency, to ensure that general purpose daemons +# are run _after_ the above are. diff --git a/libexec/rc/rc.d/FILESYSTEMS b/libexec/rc/rc.d/FILESYSTEMS new file mode 100755 index 000000000000..1bf52077be8e --- /dev/null +++ b/libexec/rc/rc.d/FILESYSTEMS @@ -0,0 +1,11 @@ +#!/bin/sh +# +# + +# PROVIDE: FILESYSTEMS +# REQUIRE: root mountcritlocal cleanvar tmp + +# This is a dummy dependency, for services which require filesystems +# to be mounted before starting. It also serves as the default early / +# late divider; after this point, rc.d directories are rescanned to +# catch scripts from other filesystems than /. diff --git a/libexec/rc/rc.d/LOGIN b/libexec/rc/rc.d/LOGIN new file mode 100755 index 000000000000..7f95980e11ec --- /dev/null +++ b/libexec/rc/rc.d/LOGIN @@ -0,0 +1,12 @@ +#!/bin/sh +# +# + +# PROVIDE: LOGIN +# REQUIRE: DAEMON + +# This is a dummy dependency to ensure user services such as xdm, +# inetd, cron and kerberos are started after everything else, in case +# the administrator has increased the system security level and +# wants to delay user logins until the system is (almost) fully +# operational. diff --git a/libexec/rc/rc.d/Makefile b/libexec/rc/rc.d/Makefile new file mode 100644 index 000000000000..3b7f45e8f101 --- /dev/null +++ b/libexec/rc/rc.d/Makefile @@ -0,0 +1,384 @@ +.include <src.opts.mk> + +CONFDIR= /etc/rc.d +CONFGROUPS= CONFS +CONFSPACKAGE= rc + +# Files which are always installed and go in the -rc package. +CONFS= DAEMON \ + FILESYSTEMS \ + LOGIN \ + NETWORKING \ + SERVERS \ + adjkerntz \ + bgfsck \ + bridge \ + cfumass \ + cleanvar \ + cleartmp \ + ddb \ + defaultroute \ + devfs \ + dmesg \ + dumpon \ + fsck \ + growfs \ + growfs_fstab \ + hostid \ + hostid_save \ + hostname \ + iovctl \ + ip6addrctl \ + ipsec \ + kld \ + kldxref \ + ldconfig \ + linux \ + local \ + localpkg \ + mixer \ + motd \ + mountcritlocal \ + mountcritremote \ + mountlate \ + mdconfig \ + mdconfig2 \ + msgs \ + netif \ + netoptions \ + netwait \ + noshutdown \ + os-release \ + pwcheck \ + quota \ + random \ + rarpd \ + rctl \ + root \ + routing \ + rpcbind \ + rtadvd \ + rtsold \ + savecore \ + securelevel \ + serial \ + static_arp \ + static_ndp \ + stf \ + swap \ + swaplate \ + sysctl \ + sysctl_lastload \ + sysvipc \ + tmp \ + ugidfw \ + var \ + var_run \ + watchdogd + +# Groups for files which don't go in -rc, or which depend on src.conf knobs. + +.if ${MK_ACCT} != "no" || ${MK_UTMPX} != "no" +CONFGROUPS+= ACCT +ACCTPACKAGE= acct +.if ${MK_ACCT} != "no" +ACCT= accounting +.endif +.if ${MK_UTMPX} != "no" +ACCT+= utx +.endif +.endif + +CONFGROUPS.${MK_ACPI}+= ACPI +ACPIPACKAGE= acpi +ACPI= power_profile + +CONFGROUPS.${MK_APM}+= APM +APMPACKAGE= apm +APM= apm +.if ${MACHINE} == "i386" +APM+= apmd +.endif + +CONFGROUPS.${MK_AUDIT}+= AUDIT +AUDITPACKAGE= audit +AUDIT= auditd \ + auditdistd + +CONFGROUPS.${MK_AUTOFS}+= AUTOFS +AUTOFSPACKAGE= autofs +AUTOFS= automount \ + automountd \ + autounmountd + +CONFGROUPS.${MK_BLOCKLIST}+= BLOCKLIST +BLOCKLISTPACKAGE= blocklist +BLOCKLIST= blacklistd \ + blocklistd + +CONFGROUPS.${MK_BLUETOOTH}+= BLUETOOTH +BLUETOOTHPACKAGE= bluetooth +BLUETOOTH= bluetooth \ + bthidd \ + hcsecd \ + rfcomm_pppd_server \ + sdpd \ + ubthidhci + +CONFGROUPS.${MK_BOOTPARAMD}+= BOOTPARAMD +BOOTPARAMD= bootparams + +CONFGROUPS.${MK_BSNMP}+= BSNMP +BSNMPPACKAGE= bsnmp +BSNMP= bsnmpd + +CONFGROUPS.${MK_CCD}+= CCD +CCDPACKAGE= ccdconfig +CCD= ccd + +CONFGROUPS+= DEVD +DEVDPACKAGE= devd +DEVD= devd + +CONFGROUPS+= DEVMATCH +DEVMATCHPACKAGE= devmatch +DEVMATCH= devmatch + +CONFGROUPS+= DHCLIENT +DHCLIENTPACKAGE= dhclient +DHCLIENT= dhclient + +CONFGROUPS+= CRON +CRONPACKAGE= cron +CRON= cron + +CONFGROUPS+= CTL +CTLPACKAGE= ctl +CTL= ctld + +CONFGROUPS+= GEOM +GEOMPACKAGE= geom +GEOM= geli \ + geli2 \ + gptboot + +CONFGROUPS+= GGATED +GGATEDPACKAGE= ggate +GGATED= ggated + +CONFGROUPS.${MK_KERBEROS_SUPPORT}+=GSSD +GSSDPACKAGE= gssd +GSSD= gssd + +CONFGROUPS.${MK_HAST}+= HAST +HASTPACKAGE= hast +HAST= hastd + +CONFGROUPS.${MK_INETD}+= INETD +INETDPACKAGE= inetd +INETD= inetd + +CONFGROUPS.${MK_IPFILTER}+= IPF +IPFPACKAGE= ipf +IPF= ipfilter \ + ipfs \ + ipmon \ + ipnat \ + ippool + +CONFGROUPS.${MK_IPFW}+= IPFW +IPFWPACKAGE= ipfw +IPFW= ipfw \ + dnctl +.if ${MK_NETGRAPH} != "no" +IPFW+= ipfw_netflow +.endif + +CONFGROUPS.${MK_ISCSI}+= ISCSI +ISCSIPACKAGE= iscsi +ISCSI= iscsictl \ + iscsid + +# natd is only built when ipfw is built +CONFGROUPS.${MK_IPFW}+= NATD +NATDPACKAGE= natd +NATD= natd + +CONFGROUPS.${MK_JAIL}+= JAIL +JAILPACKAGE= jail +JAIL= jail + +CONFGROUPS.${MK_LPR}+= LP +LPPACKAGE= lp +LP= lpd + +CONFGROUPS+= NEWSYSLOG +NEWSYSLOGPACKAGE= newsyslog +NEWSYSLOG= newsyslog + +CONFGROUPS+= NFS +NFSPACKAGE= nfs +NFS= lockd \ + mountd \ + nfscbd \ + nfsclient \ + nfsd \ + nfsuserd \ + statd + +CONFGROUPS.${MK_NIS}+= NIS +NISPACKAGE= yp +NIS= ypbind \ + ypldap \ + yppasswdd \ + ypserv \ + ypset \ + ypupdated \ + ypxfrd \ + nisdomain + +CONFGROUPS.${MK_NS_CACHING}+= NSCD +NSCD= nscd + +CONFGROUPS.${MK_NTP}+= NTP +NTPPACKAGE= ntp +NTP= ntpd \ + ntpdate + +CONFGROUPS.${MK_NUAGEINIT}+= NUAGEINIT +NUAGEINITPACKAGE= nuageinit +NUAGEINIT= nuageinit \ + nuageinit_post_net \ + nuageinit_user_data_script + +CONFGROUPS.${MK_OFED_EXTRA}+= OPENSM +OPENSM= opensm + +CONFGROUPS.${MK_PF}+= PF +PFPACKAGE= pf +PF= pf \ + pflog \ + pfsync \ + ftp-proxy + +CONFGROUPS+= POWERD +POWERDPACKAGE= powerd +POWERD= powerd + +CONFGROUPS.${MK_PPP}+= PPP +PPPPACKAGE= ppp +PPP= ppp + +CONFGROUPS+= PPPOED +PPPOEDPACKAGE= ppp +PPPOED= pppoed + +CONFGROUPS+= SYSLOGD +SYSLOGDPACKAGE= syslogd +SYSLOGD= syslogd + +CONFGROUPS+= RCMDS +RCMDSPACKAGE= rcmds +RCMDS= rwho + +CONFGROUPS+= RESOLVCONF +RESOLVCONFPACKAGE= resolvconf +RESOLVCONF= resolv + +CONFGROUPS.${MK_SENDMAIL}+= SENDMAIL +SENDMAILPACKAGE= sendmail +SENDMAIL= sendmail + +CONFGROUPS.${MK_OPENSSH}+= SSH +SSHPACKAGE= ssh +SSH= sshd + +CONFGROUPS.${MK_UNBOUND}+= UNBOUND +UNBOUNDPACKAGE= local-unbound +UNBOUND= local_unbound + +CONFGROUPS.${MK_VI}+= VI +VIPACKAGE= vi +VI= virecover + +CONFGROUPS.${MK_CUSE}+= VOSS +VOSSPACKAGE= sound +VOSS= virtual_oss + +CONFGROUPS.${MK_WIRELESS}+= HOSTAPD +HOSTAPDPACKAGE= hostapd +HOSTAPD= hostapd + +CONFGROUPS.${MK_WIRELESS}+= WPA +WPAPACKAGE= wpa +WPA= wpa_supplicant + +CONFGROUPS.${MK_ZFS}+= ZFS +ZFSPACKAGE= zfs +ZFS= zfs \ + zfsbe \ + zfsd \ + zfskeys \ + zpool \ + zpoolreguid \ + zpoolupgrade \ + zvol + +CONFGROUPS.${MK_LEGACY_CONSOLE}+=SYSCONS +SYSCONSPACKAGE= console-tools +SYSCONS= moused \ + msconvd \ + syscons + +.if ${MK_KERBEROS} != "no" +.if ${MK_MITKRB5} == "no" + +# Heimdal rc scripts +CONFGROUPS+= HEIMDAL +HEIMDAL= ipropd_master \ + ipropd_slave \ + kadmind \ + kdc \ + kfd \ + kpasswdd +HEIMDALPACKAGE= kerberos + +DIRS+= VAR_HEMIDAL +VAR_HEMIDAL= /var/heimdal +VAR_HEMIDAL_MODE= 700 + +.else # ${MK_MITKRB5} != "no" + +# MIT KRB5 rc scripts +CONFGROUPS+= KRB5 +KRB5= kadmind \ + kdc +KRB5PACKAGE= kerberos-kdc + +.endif # ${MK_MITKRB5} +.endif # ${MK_KERBEROS} + +.if ${MK_OPENSSL} != "no" && ${MK_OPENSSL_KTLS} != "no" +CONFGROUPS+= KTLS +KTLS= tlsclntd \ + tlsservd +.endif + +.if ${MK_INET6} != "no" || ${MK_ROUTED} != "no" +CONFGROUPS+= RIP +RIPPACKAGE= rip + +.if ${MK_INET6} != "no" +RIP+= route6d +.endif +.if ${MK_ROUTED} != "no" +RIP+= routed +.endif +.endif + +.for fg in ${CONFGROUPS} ${CONFGROUPS.yes} +${fg}MODE?= ${BINMODE} +${fg}PACKAGE?= rc +.endfor + +.include <bsd.prog.mk> diff --git a/libexec/rc/rc.d/NETWORKING b/libexec/rc/rc.d/NETWORKING new file mode 100755 index 000000000000..402e20927a4c --- /dev/null +++ b/libexec/rc/rc.d/NETWORKING @@ -0,0 +1,11 @@ +#!/bin/sh +# +# + +# PROVIDE: NETWORKING NETWORK +# REQUIRE: netif netwait netoptions routing ppp ipfw stf +# REQUIRE: defaultroute route6d resolv bridge +# REQUIRE: static_arp static_ndp + +# This is a dummy dependency, for services which require networking +# to be operational before starting. diff --git a/libexec/rc/rc.d/SERVERS b/libexec/rc/rc.d/SERVERS new file mode 100755 index 000000000000..0bcaec08c3e6 --- /dev/null +++ b/libexec/rc/rc.d/SERVERS @@ -0,0 +1,9 @@ +#!/bin/sh +# +# + +# PROVIDE: SERVERS +# REQUIRE: mountcritremote sysvipc linux ldconfig savecore watchdogd + +# This is a dummy dependency, for early-start servers relying on +# some basic configuration. diff --git a/libexec/rc/rc.d/accounting b/libexec/rc/rc.d/accounting new file mode 100755 index 000000000000..1e0ece84fb15 --- /dev/null +++ b/libexec/rc/rc.d/accounting @@ -0,0 +1,83 @@ +#!/bin/sh +# +# + +# PROVIDE: accounting +# REQUIRE: mountcritremote +# BEFORE: DAEMON +# KEYWORD: nojail + +. /etc/rc.subr + +name="accounting" +rcvar="accounting_enable" +accounting_command="/usr/sbin/accton" +accounting_file="/var/account/acct" + +extra_commands="rotate_log" + +start_cmd="accounting_start" +stop_cmd="accounting_stop" +rotate_log_cmd="accounting_rotate_log" + +create_accounting_file() +{ + install -o root -g wheel -m 0640 /dev/null "${accounting_file}" +} + +accounting_start() +{ + local _dir + + _dir="${accounting_file%/*}" + if [ ! -d "$_dir" ]; then + if ! mkdir -p -m 0750 "$_dir"; then + err 1 "Could not create $_dir." + fi + fi + + if [ ! -e "$accounting_file" ]; then + echo -n "Creating accounting file ${accounting_file}" + create_accounting_file + echo '.' + fi + + echo "Turning on accounting." + ${accounting_command} ${accounting_file} +} + +accounting_stop() +{ + echo "Turning off accounting." + ${accounting_command} +} + +accounting_rotate_log() +{ + # Note that this function must handle being called as "onerotate_log" + # (by the periodic scripts) when accounting is disabled, and handle + # being called multiple times (by an admin making mistakes) without + # anything having actually rotated the old .0 file out of the way. + + if [ -e "${accounting_file}.0" ]; then + err 1 "Cannot rotate accounting log, ${accounting_file}.0 already exists." + fi + + if [ ! -e "${accounting_file}" ]; then + err 1 "Cannot rotate accounting log, ${accounting_file} does not exist." + fi + + mv ${accounting_file} ${accounting_file}.0 + + if checkyesno accounting_enable; then + create_accounting_file + ${accounting_command} "${accounting_file}" + fi +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: jail can't manipulate accounting +accounting_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/adjkerntz b/libexec/rc/rc.d/adjkerntz new file mode 100755 index 000000000000..339f8add7201 --- /dev/null +++ b/libexec/rc/rc.d/adjkerntz @@ -0,0 +1,21 @@ +#!/bin/sh +# +# + +# PROVIDE: adjkerntz +# REQUIRE: FILESYSTEMS +# BEFORE: netif +# KEYWORD: nojail + +. /etc/rc.subr + +name="adjkerntz" +start_cmd="adjkerntz -i" +stop_cmd=":" + +load_rc_config $name + +# doesn't make sense to run in a svcj: jail can't modify kerntz +adjkerntz_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/apm b/libexec/rc/rc.d/apm new file mode 100755 index 000000000000..3187f41c3a50 --- /dev/null +++ b/libexec/rc/rc.d/apm @@ -0,0 +1,50 @@ +#!/bin/sh +# +# + +# PROVIDE: apm +# REQUIRE: DAEMON +# BEFORE: LOGIN +# KEYWORD: nojail + +. /etc/rc.subr + +name="apm" +desc="Advanced power management" +rcvar="apm_enable" +start_precmd="apm_precmd" +command="/usr/sbin/${name}" +start_cmd="${command} -e enable" +stop_cmd="${command} -e disable" +status_cmd="apm_status" + +apm_precmd() +{ + case `${SYSCTL_N} hw.machine_arch` in + i386) + return 0 + ;; + esac + return 1 +} + +apm_status() +{ + case `${command} -s` in + 1) + echo "APM is enabled." + return 0 + ;; + 0) + echo "APM is disabled" + ;; + esac + return 1 +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: nojail keyword +apm_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/apmd b/libexec/rc/rc.d/apmd new file mode 100755 index 000000000000..aeb5042342d6 --- /dev/null +++ b/libexec/rc/rc.d/apmd @@ -0,0 +1,41 @@ +#!/bin/sh +# +# + +# PROVIDE: apmd +# REQUIRE: DAEMON apm +# BEFORE: LOGIN +# KEYWORD: nojail shutdown + +. /etc/rc.subr + +name="apmd" +desc="Advanced power management daemon" +rcvar="apmd_enable" +command="/usr/sbin/${name}" +start_precmd="apmd_prestart" + +apmd_prestart() +{ + case `${SYSCTL_N} hw.machine_arch` in + i386) + force_depend apm || return 1 + + # Warn user about acpi apm compatibility support which + # does not work with apmd. + if [ ! -e /dev/apmctl ]; then + warn "/dev/apmctl not found; kernel is missing apm(4)" + fi + ;; + *) + return 1 + ;; + esac +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: nojail keyword +apmd_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/auditd b/libexec/rc/rc.d/auditd new file mode 100755 index 000000000000..caea2587a2e9 --- /dev/null +++ b/libexec/rc/rc.d/auditd @@ -0,0 +1,39 @@ +#!/bin/sh +# +# +# Start up for the Audit daemon. +# + +# PROVIDE: auditd +# REQUIRE: syslogd +# BEFORE: DAEMON +# KEYWORD: nojail shutdown + +. /etc/rc.subr + +name="auditd" +desc="Audit daemon" +stop_cmd="auditd_stop" +command="/usr/sbin/${name}" +pidfile="/var/run/${name}.pid" +rcvar="auditd_enable" +command_args="${auditd_flags}" +required_files="/etc/security/audit_class /etc/security/audit_control + /etc/security/audit_event /etc/security/audit_user + /etc/security/audit_warn" + +auditd_stop() +{ + + /usr/sbin/audit -t + if [ -n "$rc_pid" ]; then + wait_for_pids $rc_pid + fi +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: nojail keyword +auditd_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/auditdistd b/libexec/rc/rc.d/auditdistd new file mode 100755 index 000000000000..0814c2a4d2c7 --- /dev/null +++ b/libexec/rc/rc.d/auditdistd @@ -0,0 +1,23 @@ +#!/bin/sh +# +# + +# PROVIDE: auditdistd +# REQUIRE: auditd +# BEFORE: DAEMON +# KEYWORD: nojail shutdown + +. /etc/rc.subr + +name="auditdistd" +desc="Audit trail files distribution daemon" +rcvar="${name}_enable" +pidfile="/var/run/${name}.pid" +command="/usr/sbin/${name}" +required_files="/etc/security/${name}.conf" +extra_commands="reload" + +: ${auditdistd_svcj_options:="net_basic"} + +load_rc_config $name +run_rc_command "$1" diff --git a/libexec/rc/rc.d/automount b/libexec/rc/rc.d/automount new file mode 100755 index 000000000000..19f367837189 --- /dev/null +++ b/libexec/rc/rc.d/automount @@ -0,0 +1,35 @@ +#!/bin/sh +# +# + +# PROVIDE: automount +# REQUIRE: nfsclient automountd +# BEFORE: DAEMON +# KEYWORD: nojail shutdown + +. /etc/rc.subr + +name="automount" +rcvar="autofs_enable" +start_cmd="automount_start" +stop_cmd="automount_stop" +required_modules="autofs" + +automount_start() +{ + + /usr/sbin/automount ${automount_flags} +} + +automount_stop() +{ + + /sbin/umount -At autofs +} + +load_rc_config $name + +# mounting shall not be performed in a svcj +automount_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/automountd b/libexec/rc/rc.d/automountd new file mode 100755 index 000000000000..b809e9dfc8ad --- /dev/null +++ b/libexec/rc/rc.d/automountd @@ -0,0 +1,24 @@ +#!/bin/sh +# +# + +# PROVIDE: automountd +# REQUIRE: rpcbind ypset nfsclient FILESYSTEMS ldconfig +# BEFORE: DAEMON +# KEYWORD: nojail + +. /etc/rc.subr + +name="automountd" +desc="daemon handling autofs mount requests" +rcvar="autofs_enable" +pidfile="/var/run/${name}.pid" +command="/usr/sbin/${name}" +required_modules="autofs" + +load_rc_config $name + +# mounting shall not be performed in a svcj +automountd_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/autounmountd b/libexec/rc/rc.d/autounmountd new file mode 100755 index 000000000000..1d8b3bfa354f --- /dev/null +++ b/libexec/rc/rc.d/autounmountd @@ -0,0 +1,23 @@ +#!/bin/sh +# +# + +# PROVIDE: autounmountd +# REQUIRE: FILESYSTEMS +# BEFORE: DAEMON +# KEYWORD: nojail + +. /etc/rc.subr + +name="autounmountd" +desc="daemon unmounting automounted filesystems" +rcvar="autofs_enable" +pidfile="/var/run/${name}.pid" +command="/usr/sbin/${name}" + +load_rc_config $name + +# doesn't make sense to run in a svcj: nojail keyword +autounmountd_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/bgfsck b/libexec/rc/rc.d/bgfsck new file mode 100755 index 000000000000..dd5c330c3d11 --- /dev/null +++ b/libexec/rc/rc.d/bgfsck @@ -0,0 +1,53 @@ +#!/bin/sh +# +# + +# PROVIDE: bgfsck +# REQUIRE: cron devfs syslogd +# KEYWORD: nojail + +. /etc/rc.subr + +name="background_fsck" +desc="Run fsck in background" +rcvar="background_fsck" +start_cmd="bgfsck_start" +start_precmd="bgfsck_start_precmd" +stop_cmd=":" + +bgfsck_start_precmd() +{ + if [ $($ID -u) != 0 ]; then + err 1 "Must be root." + fi +} + +bgfsck_start() +{ + : ${background_fsck_delay=0} + if [ -n "${rc_force}" ]; then + background_fsck_delay=0 + fi + if [ ${background_fsck_delay} -lt 0 ]; then + warn "Background file system checks delayed indefinitely" + return 0 + fi + + bgfsck_msg='Starting background file system checks' + if [ "${background_fsck_delay}" -gt 0 ]; then + bgfsck_msg="${bgfsck_msg} in ${background_fsck_delay} seconds" + fi + if [ -z "${rc_force}" ]; then + startmsg "${bgfsck_msg}." + fi + + (sleep ${background_fsck_delay}; nice -4 fsck -B -p) 2>&1 | \ + logger -p daemon.notice -t fsck & +} + +load_rc_config $name + +# doesn't make sense to run in a svcj +bgfsck_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/blacklistd b/libexec/rc/rc.d/blacklistd new file mode 100755 index 000000000000..9157e258f43f --- /dev/null +++ b/libexec/rc/rc.d/blacklistd @@ -0,0 +1,54 @@ +#!/bin/sh +# +# Copyright (c) 2016 The FreeBSD Foundation +# +# This software was developed by Kurt Lidl under sponsorship from the +# FreeBSD Foundation. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# + +# PROVIDE: blacklistd +# REQUIRE: netif pf + +. /etc/rc.subr + +name="blacklistd" +desc="The blacklist daemon has been renamed to blocklist" +rcvar="blacklistd_enable" +command="/usr/sbin/${name}" +required_files="/etc/blacklistd.conf" +start_precmd="blacklistd_prestart" + +# no svcj options needed +: ${blacklistd_svcj_options:=""} + +blacklistd_prestart() +{ + echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" + echo "@ WARNING: blacklistd has been renamed to blocklistd @" + echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" +} + +load_rc_config $name +run_rc_command "$1" diff --git a/libexec/rc/rc.d/blocklistd b/libexec/rc/rc.d/blocklistd new file mode 100644 index 000000000000..24cbae77fd40 --- /dev/null +++ b/libexec/rc/rc.d/blocklistd @@ -0,0 +1,46 @@ +#!/bin/sh +# +# Copyright (c) 2016 The FreeBSD Foundation +# +# This software was developed by Kurt Lidl under sponsorship from the +# FreeBSD Foundation. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# + +# PROVIDE: blocklistd +# REQUIRE: netif pf + +. /etc/rc.subr + +name="blocklistd" +desc="System blocklist daemon" +rcvar="blocklistd_enable" +command="/usr/sbin/${name}" +required_files="/etc/blocklistd.conf" + +# no svcj options needed +: ${blocklistd_svcj_options:=""} + +load_rc_config $name +run_rc_command "$1" diff --git a/libexec/rc/rc.d/bluetooth b/libexec/rc/rc.d/bluetooth new file mode 100755 index 000000000000..193fd969967f --- /dev/null +++ b/libexec/rc/rc.d/bluetooth @@ -0,0 +1,333 @@ +#!/bin/sh +# +# Copyright (c) 2005 Maksim Yevmenkin <m_evmenkin@yahoo.com> +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +# PROVIDE: bluetooth +# REQUIRE: DAEMON +# KEYWORD: nojail nostart + +. /etc/rc.subr + +name="bluetooth" +desc="Bluetooth setup script" +rcvar= +start_cmd="bluetooth_start" +stop_cmd="bluetooth_stop" +required_modules="ng_bluetooth ng_hci ng_l2cap ng_btsocket" + +############################################################################## +# Read and parse Bluetooth device configuration file +############################################################################## + +bluetooth_read_conf() +{ + local _err _file _line _namespace + + _file=$1 + _namespace=$2 + _err=0 + + if [ ! -e $_file ]; then + return 0 + fi + + if [ ! -f $_file -o ! -r $_file ]; then + err 1 "Bluetooth configuration file $_file is not a file or not readable" + fi + + while read _line + do + case "$_line" in + \#*) + continue + ;; + + *) + if [ -z "$_line" ]; then + continue; + fi + + + if expr "$_line" : "[a-zA-Z0-9_]*=" > /dev/null 2>&1; then + eval "${_namespace}${_line}" + else + warn "Unable to parse line \"$_line\" in $_file" + _err=1 + fi + ;; + esac + done < $_file + + return $_err +} + +############################################################################## +# Setup Bluetooth stack. Create and connect nodes +############################################################################## + +bluetooth_setup_stack() +{ + dev=$1 + shift + hook=$1 + shift + + # Setup HCI + ngctl mkpeer ${dev}: hci ${hook} drv \ + > /dev/null 2>&1 || return 1 + + ngctl name ${dev}:${hook} ${dev}hci \ + > /dev/null 2>&1 || return 1 + + ngctl msg ${dev}hci: set_debug ${bluetooth_device_hci_debug_level} \ + > /dev/null 2>&1 || return 1 + + # Setup L2CAP + ngctl mkpeer ${dev}hci: l2cap acl hci \ + > /dev/null 2>&1 || return 1 + + ngctl name ${dev}hci:acl ${dev}l2cap \ + > /dev/null 2>&1 || return 1 + + ngctl msg ${dev}l2cap: set_debug ${bluetooth_device_l2cap_debug_level} \ + > /dev/null 2>&1 || return 1 + + # Connect HCI node to the Bluetooth sockets layer + ngctl connect ${dev}hci: btsock_hci_raw: raw ${dev}raw \ + > /dev/null 2>&1 || return 1 + + # Connect L2CAP node to Bluetooth sockets layer + ngctl connect ${dev}l2cap: btsock_l2c_raw: ctl ${dev}ctl \ + > /dev/null 2>&1 || return 1 + + ngctl connect ${dev}l2cap: btsock_l2c: l2c ${dev}l2c \ + > /dev/null 2>&1 || return 1 + + # Initilalize HCI node + for loop in 1 2 3 + do + ${hccontrol} -n ${dev}hci reset \ + > /dev/null 2>&1 && break + if [ ${loop} -eq 3 ] + then + warn Reset failed three times, giving up. + return 1 + fi + warn Reset failed, retrying. + done + + ${hccontrol} -n ${dev}hci read_bd_addr \ + > /dev/null 2>&1 || return 1 + + ${hccontrol} -n ${dev}hci read_local_supported_features \ + > /dev/null 2>&1 || return 1 + + ${hccontrol} -n ${dev}hci read_buffer_size \ + > /dev/null 2>&1 || return 1 + + if checkyesno bluetooth_device_discoverable; then + if checkyesno bluetooth_device_connectable; then + ${hccontrol} -n ${dev}hci write_scan_enable 3 \ + > /dev/null 2>&1 || return 1 + else + ${hccontrol} -n ${dev}hci write_scan_enable 1 \ + > /dev/null 2>&1 || return 1 + fi + else + if checkyesno bluetooth_device_connectable; then + ${hccontrol} -n ${dev}hci write_scan_enable 2 \ + > /dev/null 2>&1 || return 1 + else + ${hccontrol} -n ${dev}hci write_scan_enable 0 \ + > /dev/null 2>&1 || return 1 + fi + fi + + + ${hccontrol} -n ${dev}hci write_class_of_device ${bluetooth_device_class} \ + > /dev/null 2>&1 || return 1 + + if checkyesno bluetooth_device_authentication_enable; then + ${hccontrol} -n ${dev}hci write_authentication_enable 1 \ + > /dev/null 2>&1 || return 1 + else + ${hccontrol} -n ${dev}hci write_authentication_enable 0 \ + > /dev/null 2>&1 || return 1 + fi + + case "${bluetooth_device_encryption_mode}" in + [Nn][Oo][Nn][Ee]|0) + ${hccontrol} -n ${dev}hci write_encryption_mode 0 \ + > /dev/null 2>&1 || return 1 + ;; + + [Pp][2][Pp]|1) + ${hccontrol} -n ${dev}hci write_encryption_mode 1 \ + > /dev/null 2>&1 || return 1 + ;; + + [Al][Ll][Ll]|2) + ${hccontrol} -n ${dev}hci write_encryption_mode 2 \ + > /dev/null 2>&1 || return 1 + ;; + + *) + warn "Unsupported encryption mode ${bluetooth_device_encryption_mode} for device ${dev}" + return 1 + ;; + esac + + if checkyesno bluetooth_device_role_switch; then + ${hccontrol} -n ${dev}hci write_node_role_switch 1 \ + > /dev/null 2>&1 || return 1 + else + ${hccontrol} -n ${dev}hci write_node_role_switch 0 \ + > /dev/null 2>&1 || return 1 + fi + + ${hccontrol} -n ${dev}hci change_local_name "${bluetooth_device_local_name}" \ + > /dev/null 2>&1 || return 1 + + ${hccontrol} -n ${dev}hci initialize \ + > /dev/null 2>&1 || return 1 + + return 0 +} + +############################################################################## +# Shutdown Bluetooth stack. Destroy all nodes +############################################################################## + +bluetooth_shutdown_stack() +{ + dev=$1 + + ngctl shutdown ${dev}hci: > /dev/null 2>&1 + ngctl shutdown ${dev}l2cap: > /dev/null 2>&1 + + return 0 +} + +############################################################################## +# bluetooth_start() +############################################################################## + +bluetooth_start() +{ + local _file + + dev=$1 + + # Try to figure out device type by looking at device name + case "${dev}" in + # USB Bluetooth adapters + ubt*) + hook="hook" + + # Obtain unit number from device. + unit=`expr ${dev} : 'ubt\([0-9]\{1,\}\)'` + if [ -z "${unit}" ]; then + err 1 "Unable to get ubt unit number: ${dev}" + fi + ;; + + # Unknown + *) + err 1 "Unsupported device: ${dev}" + ;; + esac + + # Be backward compatible and setup reasonable defaults + bluetooth_device_authentication_enable="0" + bluetooth_device_class="ff:01:0c" + bluetooth_device_connectable="1" + bluetooth_device_discoverable="0" + bluetooth_device_encryption_mode="0" + bluetooth_device_hci_debug_level="3" + bluetooth_device_l2cap_debug_level="3" + bluetooth_device_local_name="`/usr/bin/uname -n` (${dev})" + bluetooth_device_role_switch="1" + + # Load default device configuration parameters + _file="/etc/defaults/bluetooth.device.conf" + + if ! bluetooth_read_conf $_file bluetooth_device_ ; then + err 1 "Unable to read default Bluetooth configuration from $_file" + fi + + # Load device specific overrides + _file="/etc/bluetooth/$dev.conf" + + if ! bluetooth_read_conf $_file bluetooth_device_ ; then + err 1 "Unable to read Bluetooth device configuration from $_file" + fi + + # Setup stack + if ! bluetooth_setup_stack ${dev} ${hook} ; then + bluetooth_shutdown_stack $dev + err 1 "Unable to setup Bluetooth stack for device ${dev}" + fi + + return 0 +} + +############################################################################## +# bluetooth_stop() +############################################################################## + +bluetooth_stop() +{ + dev=$1 + + # Try to figure out device type by looking at device name + case "${dev}" in + # USB Bluetooth adapters + ubt*) + ;; + + # Unknown + *) + err 1 "Unsupported device: ${dev}" + ;; + esac + + bluetooth_shutdown_stack ${dev} + + return 0 +} + +############################################################################## +# Start here +############################################################################## + +load_rc_config $name +hccontrol="${bluetooth_hccontrol:-/usr/sbin/hccontrol}" + +# doesn't make sense to run in a svcj: nojail keyword +bluetooth_svcj="NO" + +run_rc_command $* + diff --git a/libexec/rc/rc.d/bootparams b/libexec/rc/rc.d/bootparams new file mode 100755 index 000000000000..1d435d4ee480 --- /dev/null +++ b/libexec/rc/rc.d/bootparams @@ -0,0 +1,21 @@ +#!/bin/sh +# +# + +# PROVIDE: bootparams +# REQUIRE: rpcbind DAEMON +# BEFORE: LOGIN +# KEYWORD: nojail + +. /etc/rc.subr + +name="bootparamd" +desc="Boot parameter daemon" +rcvar="bootparamd_enable" +required_files="/etc/bootparams" +command="/usr/sbin/${name}" + +: ${bootparamd_svcj_options:="net_basic"} + +load_rc_config $name +run_rc_command "$1" diff --git a/libexec/rc/rc.d/bridge b/libexec/rc/rc.d/bridge new file mode 100755 index 000000000000..98d9212593e5 --- /dev/null +++ b/libexec/rc/rc.d/bridge @@ -0,0 +1,97 @@ +#!/bin/sh +# +# Copyright (c) 2006 The FreeBSD Project. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE PROJECT ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE PROJECT BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# + +# PROVIDE: bridge +# REQUIRE: netif ppp stf +# KEYWORD: nojailvnet + +. /etc/rc.subr +. /etc/network.subr + +name="bridge" +desc="Network bridge setup" +start_cmd="bridge_start" +stop_cmd="bridge_stop" +cmd="" + +glob_int() { + case "$1" in + $2 ) true ;; + * ) false ;; + esac +} + +bridge_test() { + bridge=$1 + iface=$2 + + eval interfaces=\$autobridge_${bridge} + if [ -n "${interfaces}" ]; then + for i in ${interfaces}; do + if glob_int $iface $i ; then + ifconfig $bridge $cmd $iface > /dev/null 2>&1 + return + fi + done + fi +} + +autobridge() +{ + if [ -n "${autobridge_interfaces}" ]; then + if [ -z "$iflist" ]; then + # We're operating as a general network start routine. + iflist="`list_net_interfaces`" + fi + + for br in ${autobridge_interfaces}; do + for i in $iflist; do + bridge_test $br $i + done + done + fi +} + +bridge_start() +{ + cmd="addm" + autobridge +} + +bridge_stop() +{ + cmd="deletem" + autobridge +} + +iflist=$2 + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +bridge_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/bsnmpd b/libexec/rc/rc.d/bsnmpd new file mode 100755 index 000000000000..60f4f5e86617 --- /dev/null +++ b/libexec/rc/rc.d/bsnmpd @@ -0,0 +1,21 @@ +#!/bin/sh +# +# + +# PROVIDE: bsnmpd +# REQUIRE: NETWORKING syslogd +# KEYWORD: nojailvnet shutdown + +. /etc/rc.subr + +name="bsnmpd" +desc="Simple and extensible SNMP daemon" +rcvar="bsnmpd_enable" +command="/usr/sbin/${name}" + +: ${bsnmpd_svcj_options:="net_basic"} + +load_rc_config $name +pidfile="${bsnmpd_pidfile:-/var/run/snmpd.pid}" +command_args="-p ${pidfile}" +run_rc_command "$1" diff --git a/libexec/rc/rc.d/bthidd b/libexec/rc/rc.d/bthidd new file mode 100755 index 000000000000..4b230406c4d5 --- /dev/null +++ b/libexec/rc/rc.d/bthidd @@ -0,0 +1,56 @@ +#!/bin/sh +# +# + +# PROVIDE: bthidd +# REQUIRE: DAEMON hcsecd +# BEFORE: LOGIN +# KEYWORD: nojail shutdown + +. /etc/rc.subr + +name="bthidd" +desc="Bluetooth HID daemon" +rcvar="bthidd_enable" +command="/usr/sbin/${name}" +pidfile="/var/run/${name}.pid" +start_precmd="bthidd_prestart" + +evdev_enabled() +{ + case ${bthidd_evdev_support} in + [Aa][Uu][Tt][Oo]) + check_kern_features evdev_support + return $? + ;; + *) + checkyesno bthidd_evdev_support + return $? + ;; + esac +} + +bthidd_prestart() +{ + if evdev_enabled; then + load_kld -m uinput uinput + fi + load_kld -m kbdmux kbdmux + load_kld -m vkbd vkbd + load_kld -m ng_btsocket ng_btsocket + return 0 +} + +load_rc_config $name +config="${bthidd_config:-/etc/bluetooth/${name}.conf}" +hids="${bthidd_hids:-/var/db/${name}.hids}" +command_args="-c ${config} -H ${hids} -p ${pidfile}" +if evdev_enabled; then + command_args="$command_args -u" +fi +required_files="${config}" + +# doesn't make sense to run in a svcj: nojail keyword +bthidd_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/ccd b/libexec/rc/rc.d/ccd new file mode 100755 index 000000000000..5f2427e4beb0 --- /dev/null +++ b/libexec/rc/rc.d/ccd @@ -0,0 +1,28 @@ +#!/bin/sh +# +# + +# PROVIDE: disks +# KEYWORD: nojail + +. /etc/rc.subr + +name="ccd" +desc="Concatenated disks setup" +start_cmd="ccd_start" +stop_cmd=":" + +ccd_start() +{ + if [ -f /etc/ccd.conf ]; then + echo "Configuring CCD devices." + ccdconfig -C + fi +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: nojail keyword +ccd_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/cfumass b/libexec/rc/rc.d/cfumass new file mode 100755 index 000000000000..7d1117d7c388 --- /dev/null +++ b/libexec/rc/rc.d/cfumass @@ -0,0 +1,152 @@ +#!/bin/sh +# +# + +# PROVIDE: cfumass +# REQUIRE: var +# KEYWORD: nojail + +. /etc/rc.subr + +name="cfumass" +desc="Configure the LUN for device mode USB mass storage" +rcvar="cfumass_enable" + +start_cmd="${name}_start" +stop_cmd="${name}_stop" + +extra_commands="reload" +reload_cmd="${name}_start" + +: ${cfumass_dir:=/var/cfumass} +: ${cfumass_image:=/var/tmp/cfumass.img} +: ${cfumass_vendor:="FreeBSD"} +: ${cfumass_product:="cfumass(4)"} + +remove_luns() +{ + local _lun _luns + + _luns=`ctladm devlist -b block -v | awk ' + + $1 ~ /^[0-9]+$/ { + lun = $1 + } + + $1 == "file='"${cfumass_image}"'" { + print lun + }'` + + for _lun in ${_luns}; do + ctladm remove -b block -l "${_lun}" > /dev/null + done +} + +cfumass_start() +{ + local err _files _template _new_template + + if [ ! -d "${cfumass_dir}" ]; then + warn "${cfumass_dir} does not exist" + return 1 + fi + + _files=`find "${cfumass_dir}" -newer "${cfumass_image}" -print 2> /dev/null` + if [ ! -e "${cfumass_image}" -o -n "${_files}" ]; then + # The image doesn't exist or is out of date. + makefs -t cd9660 -o label="${cfumass_vendor}" \ + -o rockridge "${cfumass_image}" "${cfumass_dir}" + err=$? + if [ "${err}" -ne 0 ]; then + warn "unable to create ${cfumass_image}" + return "${err}" + fi + fi + + remove_luns + + ctladm create -b block -o file="${cfumass_image}" -o readonly=on \ + -o vendor="${cfumass_vendor}" -o product="${cfumass_product}" \ + -S 0 > /dev/null + err=$? + if [ "${err}" -ne 0 ]; then + warn "unable to create CTL LUN" + return "${err}" + fi + + load_kld -e cfumass cfumass + + # If the template is already switched to Mass Storage, then reset + # it to -1 to force the host to reenumerate it; otherwise it might + # not notice the new LUN. + _template=`sysctl -n hw.usb.template` + if [ "${_template}" -eq 0 ]; then + sysctl hw.usb.template=-1 > /dev/null + err=$? + if [ "${err}" -ne 0 ]; then + warn "unable to set hw.usb.template sysctl" + return "${err}" + fi + fi + + # Set the template number based on the current one. + _template=`sysctl -n hw.usb.template` + case "${_template}" in + -1) + _new_template="0" + ;; + 8) + _new_template="10" + ;; + *) + warn "hw.usb.template sysctl set to neither -1 nor 8; not changing" + _new_template="" + ;; + esac + + if [ -n "${_new_template}" ]; then + sysctl hw.usb.template="${_new_template}" > /dev/null + err=$? + if [ "${err}" -ne 0 ]; then + warn "unable to set hw.usb.template sysctl to ${_new_template}" + return "${err}" + fi + fi +} + +cfumass_stop() +{ + local err _template _new_template + + remove_luns + + _template=`sysctl -n hw.usb.template` + case "${_template}" in + 0) + _new_template="-1" + ;; + 10) + _new_template="8" + ;; + *) + warn "hw.usb.template sysctl set to neither 0 nor 10; not changing" + _new_template="" + ;; + esac + + if [ -n "${_new_template}" ]; then + sysctl hw.usb.template="${_new_template}" > /dev/null + err=$? + if [ "${err}" -ne 0 ]; then + warn "unable to set hw.usb.template sysctl to ${_new_template}" + return "${err}" + fi + fi +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: nojail keyword +cfumass_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/cleanvar b/libexec/rc/rc.d/cleanvar new file mode 100755 index 000000000000..dce5baa6875b --- /dev/null +++ b/libexec/rc/rc.d/cleanvar @@ -0,0 +1,50 @@ +#!/bin/sh +# +# + +# PROVIDE: cleanvar +# REQUIRE: var + +. /etc/rc.subr + +name="cleanvar" +desc="Purge /var directory" +rcvar="cleanvar_enable" + +start_precmd="${name}_prestart" +start_cmd="${name}_start" +stop_cmd=":" + +extra_commands="reload" +reload_cmd="${name}_start" + +cleanvar_prestart() +{ + # These files must be removed only the first time this script is run + # on boot. + # + rm -f /var/run/clean_var /var/spool/lock/clean_var +} + +cleanvar_start() +{ + if [ -d /var/run -a ! -f /var/run/clean_var ]; then + # Skip over logging sockets + find -x /var/run \( -type f -or -type s ! -name log -and ! -name logpriv \) -delete + >/var/run/clean_var + fi + if [ -d /var/spool/lock -a ! -f /var/spool/lock/clean_var ]; then + find -x /var/spool/lock -type f -delete + >/var/spool/lock/clean_var + fi + if [ -d /var/spool/uucp/.Temp ]; then + find -x /var/spool/uucp/.Temp -delete + fi +} + +load_rc_config $name + +# doesn't make sense to run in a svcj +cleanvar_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/cleartmp b/libexec/rc/rc.d/cleartmp new file mode 100755 index 000000000000..c4dfb5367dcb --- /dev/null +++ b/libexec/rc/rc.d/cleartmp @@ -0,0 +1,64 @@ +#!/bin/sh +# +# + +# PROVIDE: cleartmp +# REQUIRE: mountcritremote tmp +# BEFORE: DAEMON + +. /etc/rc.subr + +name="cleartmp" +desc="Purge /tmp directory" +# Disguise rcvar for the start method to run irrespective of its setting. +rcvar1="clear_tmp_enable" +start_cmd="${name}_start" +stop_cmd=":" + +cleartmp_start() +{ + # Make /tmp location variable for easier debugging. + local tmp="/tmp" + + # X related directories to create in /tmp. + local x11_socket_dirs="${tmp}/.X11-unix ${tmp}/.XIM-unix \ + ${tmp}/.ICE-unix ${tmp}/.font-unix" + + if checkyesno ${rcvar1}; then + startmsg "Clearing ${tmp}." + + # This is not needed for mfs, but doesn't hurt anything. + # Things to note: + # + The dot in ${tmp}/. is important. + # + Put -prune before -exec so find never descends + # into a directory that was already passed to rm -rf. + # + "--" in rm arguments isn't strictly necessary, but + # it can prevent foot-shooting in future. + # + /tmp/lost+found is preserved, but its contents are removed. + # + lost+found and quota.* in subdirectories are removed. + # + .sujournal and .snap are preserved. + find -x ${tmp}/. ! -name . \ + ! \( -name .sujournal -type f -user root \) \ + ! \( -name .snap -type d -user root \) \ + ! \( -name lost+found -type d -user root \) \ + ! \( \( -name quota.user -or -name quota.group \) \ + -type f -user root \) \ + -prune -exec rm -rf -- {} + + elif checkyesno clear_tmp_X; then + # Remove X lock files, since they will prevent you from + # restarting X. Remove other X related directories. + startmsg "Clearing ${tmp} (X related)." + rm -rf ${tmp}/.X[0-9]-lock ${x11_socket_dirs} + fi + if checkyesno clear_tmp_X; then + # Create X related directories with proper permissions. + mkdir -m 1777 ${x11_socket_dirs} + fi +} + +load_rc_config $name + +# doesn't make sense to run in a svcj +cleartmp_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/cron b/libexec/rc/rc.d/cron new file mode 100755 index 000000000000..584db590d835 --- /dev/null +++ b/libexec/rc/rc.d/cron @@ -0,0 +1,28 @@ +#!/bin/sh +# +# + +# PROVIDE: cron +# REQUIRE: LOGIN FILESYSTEMS +# BEFORE: securelevel +# KEYWORD: shutdown + +. /etc/rc.subr + +name="cron" +desc="Daemon to execute scheduled commands" +rcvar="cron_enable" +command="/usr/sbin/${name}" +pidfile="/var/run/${name}.pid" + +load_rc_config $name + +# doesn't make sense to run in a svcj: in the generic case it may need +# access to more than a jails allows +cron_svcj="NO" + +if checkyesno cron_dst +then + cron_flags="$cron_flags -s" +fi +run_rc_command "$1" diff --git a/libexec/rc/rc.d/ctld b/libexec/rc/rc.d/ctld new file mode 100755 index 000000000000..c91d7a9be921 --- /dev/null +++ b/libexec/rc/rc.d/ctld @@ -0,0 +1,26 @@ +#!/bin/sh +# +# + +# PROVIDE: ctld +# REQUIRE: FILESYSTEMS NETWORKING +# BEFORE: DAEMON +# KEYWORD: nojail + +. /etc/rc.subr + +name="ctld" +desc="CAM Target Layer / iSCSI target daemon" +rcvar="ctld_enable" +pidfile="/var/run/${name}.pid" +command="/usr/sbin/${name}" +required_files="/etc/ctl.conf" +required_modules="ctl" +extra_commands="reload" + +load_rc_config $name + +# doesn't make sense to run in a svcj: nojail keyword +ctld_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/ddb b/libexec/rc/rc.d/ddb new file mode 100755 index 000000000000..08a7d345c326 --- /dev/null +++ b/libexec/rc/rc.d/ddb @@ -0,0 +1,41 @@ +#!/bin/sh +# +# + +# PROVIDE: ddb +# REQUIRE: dumpon +# BEFORE: disks +# KEYWORD: nojail + +. /etc/rc.subr + +name="ddb" +desc="DDB kernel debugger" +rcvar="ddb_enable" +command="/sbin/${name}" +start_precmd="ddb_prestart" +start_cmd="ddb_start" +stop_cmd=":" + +ddb_prestart() +{ + # Silently exit if ddb is not enabled + if [ -z "`sysctl -Nq debug.ddb.scripting.scripts`" ]; then + return 1 + fi +} + +ddb_start() +{ + ${command} ${command_args} +} + +load_rc_config $name + +required_files="${ddb_config}" +command_args="${ddb_config}" + +# doesn't make sense to run in a svcj: privileged operation +ddb_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/defaultroute b/libexec/rc/rc.d/defaultroute new file mode 100755 index 000000000000..b96f91d36118 --- /dev/null +++ b/libexec/rc/rc.d/defaultroute @@ -0,0 +1,77 @@ +#!/bin/sh +# +# Wait for the default route to be up if DHCP is in use +# +# + +# PROVIDE: defaultroute +# REQUIRE: devd netif stf +# KEYWORD: nojailvnet + +. /etc/rc.subr +. /etc/network.subr + +name="defaultroute" +desc="Setup default router" +start_cmd="defaultroute_start" +stop_cmd=":" + +# Does any interface have a carrier? +defaultroute_carrier() +{ + local carrier nocarrier + + carrier=1 + for _if in ${dhcp_interfaces}; do + output=`/sbin/ifconfig ${_if}` + nocarrier=`expr "${output}" : '.*[[:blank:]]status: \(no carrier\)'` + [ -z "${nocarrier}" ] && carrier=0 + done + return ${carrier} +} + +defaultroute_start() +{ + local nl waited + + afexists inet || return 0 + + # Return without waiting if we don't have dhcp interfaces or + # if none of the dhcp interfaces is plugged in. + dhcp_interfaces=`list_net_interfaces dhcp` + [ -z "${dhcp_interfaces}" ] && return + + # Wait for a default route + waited=0 + while [ ${waited} -lt ${defaultroute_delay} ]; do + defif=`get_default_if -inet` + if [ -n "${defif}" ]; then + if [ ${waited} -ne 0 ]; then + echo -n "($defif)" + nl=1 + fi + break + fi + if [ ${waited} -eq 0 ]; then + echo -n "Waiting ${defaultroute_delay}s for the default route interface: " + else + echo -n . + fi + if [ ${waited} -eq ${defaultroute_carrier_delay} ] && ! defaultroute_carrier; then + echo -n "(no carrier)" + break + fi + nl=1 + sleep 1 + waited=$(($waited + 1)) + done + + [ -n "$nl" ] && echo +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +defaultroute_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/devd b/libexec/rc/rc.d/devd new file mode 100755 index 000000000000..98f2068c2075 --- /dev/null +++ b/libexec/rc/rc.d/devd @@ -0,0 +1,44 @@ +#!/bin/sh +# +# + +# PROVIDE: devd +# REQUIRE: netif ldconfig +# BEFORE: NETWORKING mountcritremote +# KEYWORD: nojail shutdown + +. /etc/rc.subr + +name="devd" +desc="Device state change daemon" +rcvar="devd_enable" +command="/sbin/${name}" + +devd_offcmd=devd_off +start_precmd=find_pidfile +stop_precmd=find_pidfile + +find_pidfile() +{ + if get_pidfile_from_conf pid-file /etc/devd.conf; then + pidfile="$_pidfile_from_conf" + else + pidfile="/var/run/${name}.pid" + fi +} + +devd_off() +{ + # If devd is disabled, turn it off in the kernel to avoid unnecessary + # memory usage. + if ! checkyesno ${rcvar}; then + $SYSCTL hw.bus.devctl_queue=0 + fi +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: executing potential privileged operations +devd_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/devfs b/libexec/rc/rc.d/devfs new file mode 100755 index 000000000000..9987d35f6ad3 --- /dev/null +++ b/libexec/rc/rc.d/devfs @@ -0,0 +1,75 @@ +#!/bin/sh +# +# + +# PROVIDE: devfs +# REQUIRE: mountcritremote +# BEFORE: SERVERS securelevel +# KEYWORD: nojail + +. /etc/rc.subr + +name="devfs" +desc="Device filesystem" +start_cmd='devfs_start' +stop_cmd=':' + +devfs_start() +{ + if [ -n "$devfs_system_ruleset" -o -n "$devfs_set_rulesets" ] || + checkyesno devfs_load_rulesets; then + devfs_init_rulesets + if [ -n "$devfs_system_ruleset" ]; then + devfs_set_ruleset $devfs_system_ruleset /dev + devfs_apply_ruleset $devfs_system_ruleset /dev + fi + if [ -n "$devfs_set_rulesets" ]; then + local _dir_set + local _dir + local _set + for _dir_set in $devfs_set_rulesets; do + _dir=${_dir_set%=*} + _set=${_dir_set#*=} + devfs_set_ruleset $_set $_dir + devfs_apply_ruleset $_set $_dir + done + fi + fi + read_devfs_conf +} + +read_devfs_conf() +{ + if [ -r /etc/devfs.conf ]; then + cd /dev + while read action devicelist parameter; do + case "${action}" in + l*) for device in ${devicelist}; do + if [ ! -e ${parameter} ]; then + ln -fs ${device} ${parameter} + fi + done + ;; + o*) for device in ${devicelist}; do + if [ -c ${device} ]; then + chown ${parameter} ${device} + fi + done + ;; + p*) for device in ${devicelist}; do + if [ -c ${device} ]; then + chmod ${parameter} ${device} + fi + done + ;; + esac + done < /etc/devfs.conf + fi +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: may need more permissions +devfs_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/devmatch b/libexec/rc/rc.d/devmatch new file mode 100755 index 000000000000..7a8726de5677 --- /dev/null +++ b/libexec/rc/rc.d/devmatch @@ -0,0 +1,88 @@ +#!/bin/sh + +# Copyright (c) 2018 M. Warner Losh <imp@FreeBSD.org> +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# +# PROVIDE: devmatch +# REQUIRE: kld +# BEFORE: netif +# KEYWORD: nojail + +. /etc/rc.subr + +name="devmatch" +desc="Use devmatch(8) to load kernel modules" +rcvar="${name}_enable" + +start_cmd="${name}_start" +stop_cmd=':' +one_nomatch="$2" + +devmatch_start() +{ + local x m list boot_safe + + boot_safe=$(kenv -q boot_safe || echo "NO") + checkyesno boot_safe && return + + if [ -n "$one_nomatch" ]; then + list=$(devmatch -p "${one_nomatch}" | sort -u) + else + sysctl hw.bus.devctl_nomatch_enabled=1 > /dev/null + list=$(devmatch | sort -u) + fi + + [ -n "$list" ] || return + + # While kldload can accept multiple modules on the line at once, we loop + # here in case there's some weird error with one of them. We also + # optimize against the false positives or drivers that have symbolic + # links that confuse devmatch by running it -n. Finally, we filter out + # all items in the devmatch_blocklist. + # + # We strip all the .ko suffixes off so that one may specify modules + # with or without .ko. Prior version documented it was without, while + # the code required it, so accept both now. devmatch produces module + # names with .ko + + devctl freeze + x=$(echo "#${devmatch_blocklist:-${devmatch_blacklist}}#$(kenv -q devmatch_blocklist)#" | \ + sed -e "s/ /#/g;s/\.ko#/#/g") + for m in ${list}; do + m="${m%.ko}" + case "${x}" in + *"#${m}#"*) continue ;; + esac + kldstat -q -n ${m} || \ + (echo "Autoloading module: ${m}"; kldload -n ${m}) + done + devctl thaw +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: privileged operations +devmatch_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/dhclient b/libexec/rc/rc.d/dhclient new file mode 100755 index 000000000000..1cd770031d71 --- /dev/null +++ b/libexec/rc/rc.d/dhclient @@ -0,0 +1,76 @@ +#!/bin/sh +# +# + +# PROVIDE: dhclient +# KEYWORD: nojailvnet nostart + +. /etc/rc.subr +. /etc/network.subr + +ifn="$2" + +name="dhclient" +desc="Dynamic Host Configuration Protocol (DHCP) client" +rcvar= +pidfile="/var/run/dhclient/${name}.${ifn}.pid" +start_precmd="dhclient_prestart" +stop_precmd="dhclient_pre_check" + +# rc_force check can only be done at the run_rc_command +# time, so we're testing it in the pre* hooks. +dhclient_pre_check() +{ + if [ -z "${rc_force}" ] && ! dhcpif $ifn; then + local msg + msg="'$ifn' is not a DHCP-enabled interface" + if [ -z "${rc_quiet}" ]; then + echo "$msg" + else + debug "$msg" + fi + exit 1 + fi +} + +dhclient_prestart() +{ + dhclient_pre_check + + # Interface-specific flags (see rc.subr for $flags setting) + specific=$(get_if_var $ifn dhclient_flags_IF) + if [ -z "$flags" -a -n "$specific" ]; then + rc_flags=$specific + fi + + background_dhclient=$(get_if_var $ifn background_dhclient_IF $background_dhclient) + if checkyesno background_dhclient; then + rc_flags="${rc_flags} -b" + fi + + dhclient_arpwait=$(get_if_var $ifn dhclient_arpwait_IF $dhclient_arpwait) + if ! checkyesno dhclient_arpwait; then + rc_flags="${rc_flags} -n" + fi + + # /var/run/dhclient is not guaranteed to exist, + # e.g. if /var/run is a tmpfs + install -d -o root -g wheel -m 755 ${pidfile%/*} + + rc_flags="${rc_flags} ${ifn}" +} + +load_rc_config $name +load_rc_config network + +# dhclient_prestart is not compatible with svcj +dhclient_svcj="NO" + +if [ -z $ifn ] ; then + # only complain if a command was specified but no interface + if [ -n "$1" ] ; then + err 1 "$0: no interface specified" + fi +fi + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/dmesg b/libexec/rc/rc.d/dmesg new file mode 100755 index 000000000000..51e35d5d4e80 --- /dev/null +++ b/libexec/rc/rc.d/dmesg @@ -0,0 +1,30 @@ +#!/bin/sh +# +# + +# PROVIDE: dmesg +# REQUIRE: mountcritremote FILESYSTEMS +# BEFORE: DAEMON +# KEYWORD: nojail + +. /etc/rc.subr + +name="dmesg" +desc="Save kernel boot messages to disk" +rcvar="dmesg_enable" +dmesg_file="/var/run/dmesg.boot" +start_cmd="do_dmesg" +stop_cmd=":" + +do_dmesg() +{ + rm -f ${dmesg_file} + ( umask 022 ; /sbin/dmesg $rc_flags > ${dmesg_file} ) +} + +load_rc_config $name + +# doesn't make sense to run in a svcj +dmesg_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/dnctl b/libexec/rc/rc.d/dnctl new file mode 100755 index 000000000000..9067d278088e --- /dev/null +++ b/libexec/rc/rc.d/dnctl @@ -0,0 +1,29 @@ +#!/bin/sh +# +# + +# PROVIDE: dnctl +# BEFORE: pf ipfw +# KEYWORD: nojailvnet + +. /etc/rc.subr + +name="dnctl" +desc="Dummynet packet queuing and scheduling" +rcvar="${name}_enable" +load_rc_config $name +start_cmd="${name}_start" +required_files="$dnctl_rules" +required_modules="dummynet" + +# doesn't make sense to run in a svcj: config setting +dnctl_svcj="NO" + +dnctl_start() +{ + startmsg -n "Enabling ${name}" + $dnctl_program "$dnctl_rules" + startmsg '.' +} + +run_rc_command $* diff --git a/libexec/rc/rc.d/dumpon b/libexec/rc/rc.d/dumpon new file mode 100755 index 000000000000..0dfcdb266b20 --- /dev/null +++ b/libexec/rc/rc.d/dumpon @@ -0,0 +1,104 @@ +#!/bin/sh +# +# + +# PROVIDE: dumpon +# BEFORE: disks +# KEYWORD: nojail + +. /etc/rc.subr + +name="dumpon" +desc="Dump kernel corefiles from swap to disk" +start_cmd="dumpon_start" +stop_cmd="dumpon_stop" + +dumpon_try() +{ + local flags + + flags=${dumpon_flags} + if [ -n "${dumppubkey}" ]; then + warn "The dumppubkey variable is deprecated. Use dumpon_flags." + flags="${flags} -k ${dumppubkey}" + fi + /sbin/dumpon ${flags} "${1}" + if [ $? -eq 0 ]; then + # Make a symlink in devfs for savecore + ln -fs "${1}" /dev/dumpdev + return 0 + fi + warn "unable to specify $1 as a dump device" + return 1 +} + +dumpon_warn_unencrypted() +{ + if [ -n "${dumppubkey}" ]; then + return + fi + for flag in ${dumpon_flags}; do + if [ $flag = -k ]; then + return + fi + done + warn "Kernel dumps will be written to the swap partition without encryption." +} + +dumpon_start() +{ + # Enable dumpdev so that savecore can see it. Enable it + # early so a crash early in the boot process can be caught. + # + case ${dumpdev} in + [Nn][Oo]) + ;; + [Aa][Uu][Tt][Oo] | '') + root_hold_wait + dev=$(/bin/kenv -q dumpdev) + if [ -n "${dev}" ] ; then + dumpon_try "${dev}" + return $? + fi + if [ -z ${dumpdev} ] ; then + return + fi + while read dev mp type more ; do + [ "${type}" = "swap" ] || continue + case ${dev} in + *.bde|*.eli) + dumpon_warn_unencrypted + dev=${dev%.*} + ;; + esac + [ -c "${dev}" ] || continue + dumpon_try "${dev}" 2>/dev/null && return 0 + done </etc/fstab + echo "No suitable dump device was found." 1>&2 + return 1 + ;; + *) + root_hold_wait + dumpon_try "${dumpdev}" + ;; + esac +} + +dumpon_stop() +{ + case ${dumpdev} in + [Nn][Oo]) + ;; + *) + rm -f /dev/dumpdev + /sbin/dumpon -v off + ;; + esac +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +dumpon_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/fsck b/libexec/rc/rc.d/fsck new file mode 100755 index 000000000000..e755f055dbe6 --- /dev/null +++ b/libexec/rc/rc.d/fsck @@ -0,0 +1,98 @@ +#!/bin/sh +# +# + +# PROVIDE: fsck +# REQUIRE: swap +# KEYWORD: nojail + +. /etc/rc.subr + +name="fsck" +desc="Run file system checks" +start_cmd="fsck_start" +stop_cmd=":" + +fsck_start() +{ + if [ "$autoboot" = no ]; then + echo "Fast boot: skipping disk checks." + elif [ ! -r /etc/fstab ]; then + echo "Warning! No /etc/fstab: skipping disk checks." + elif [ "$autoboot" = yes ]; then + # During fsck ignore SIGQUIT + trap : 3 + + startmsg "Starting file system checks:" + # Background fsck can only be run with -p + if checkyesno background_fsck; then + fsck -F -p + else + fsck ${fsck_flags} + fi + + err=$? + if [ ${err} -eq 3 ]; then + echo "Warning! Some of the devices might not be" \ + "available; retrying" + root_hold_wait + startmsg "Restarting file system checks:" + # Background fsck can only be run with -p + if checkyesno background_fsck; then + fsck -F -p + else + fsck ${fsck_flags} + fi + err=$? + fi + + case ${err} in + 0) + ;; + 2) + stop_boot + ;; + 4) + echo "Rebooting..." + reboot + echo "Reboot failed; help!" + stop_boot + ;; + 8|16) + if checkyesno fsck_y_enable; then + echo "File system preen failed, trying fsck -y ${fsck_y_flags}" + fsck -y ${fsck_y_flags} + case $? in + 0) + ;; + *) + echo "Automatic file system check failed; help!" + stop_boot + ;; + esac + else + echo "Automatic file system check failed; help!" + stop_boot + fi + ;; + 12) + echo "Boot interrupted." + stop_boot + ;; + 130) + stop_boot + ;; + *) + echo "Unknown error ${err}; help!" + stop_boot + ;; + esac + fi +} + +load_rc_config $name + +# doesn't make sense to run in a svcj +fsck_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/ftp-proxy b/libexec/rc/rc.d/ftp-proxy new file mode 100755 index 000000000000..c77dd36cd60b --- /dev/null +++ b/libexec/rc/rc.d/ftp-proxy @@ -0,0 +1,77 @@ +#!/bin/sh +# +# + +# PROVIDE: ftp-proxy +# REQUIRE: DAEMON pf +# KEYWORD: shutdown + +. /etc/rc.subr + +name="ftpproxy" +desc="Internet File Transfer Protocol proxy daemon" +rcvar="ftpproxy_enable" +command="/usr/sbin/ftp-proxy" + +: ${ftpproxy_svcj_options:="net_basic"} + +load_rc_config $name + +# +# manage_pid argument +# Create or remove a pidfile manually, for daemons that can't be bothered +# to do it themselves. Takes one argument, which is the argument provided +# to the rc script. The pidfile will be named /var/run/<$name>.pid, +# unless $pidfile is defined. +# +# The method used to determine the pid is rather hacky; grep ps output to +# find '$procname|$command', then grep for ${name}_flags. If at all +# possible, use another method if at all possible, to avoid that dirty- +# code feeling. +# +manage_pid() { + local search_string ps_pid + case $1 in + *start) + cmd_string=`basename ${procname:-${command}}` + eval flag_string=\"\$${name}_flags\" + # Determine the pid. + ps_pid=`ps ax -o pid= -o command= | grep $cmd_string | grep -e "$flag_string" | grep -v grep | awk '{ print $1 }'` + # Write the pidfile depending on $pidfile status. + echo $ps_pid > ${pidfile:-"/var/run/$name.pid"} + ;; + stop) + rm $pidfile + ;; + esac +} + +# Allow ftp-proxy to start up in two different ways. The typical behavior +# is to start up one instance of ftp-proxy by setting ftpproxy_enable and +# ftpproxy_flags. The alternate behavior allows multiple instances of ftp- +# proxy to be started, allowing different types of proxy behavior. To use the +# new behavior, a list of instances must be defined, and a list of flags for +# each instance. For example, if we want to start two instances of ftp-proxy, +# foo and bar, we would set the following vars. +# ftpproxy_enable="YES" +# ftpproxy_instances="foo bar" +# ftpproxy_foo="<arguments for foo>" +# ftpproxy_bar="<arguments for bar>" +# +# Starting more than one ftp-proxy? +if [ "$ftpproxy_instances" ] && [ -n "${ftpproxy_instances}" ]; then + # Iterate through instance list. + for i in $ftpproxy_instances; do + #eval ftpproxy_${i}_flags=\$ftpproxy_${i} + #eval name=ftpproxy_${i} + # Set flags for this instance. + eval ftpproxy_flags=\$ftpproxy_${i} + # Define a unique pid file name. + pidfile="/var/run/ftp-proxy.$i.pid" + run_rc_command "$1" + manage_pid $1 + done +else + # Traditional single-instance behavior + run_rc_command "$1" +fi diff --git a/libexec/rc/rc.d/geli b/libexec/rc/rc.d/geli new file mode 100755 index 000000000000..5fc5ded54ec3 --- /dev/null +++ b/libexec/rc/rc.d/geli @@ -0,0 +1,128 @@ +#!/bin/sh +# +# Copyright (c) 2005 Pawel Jakub Dawidek <pjd@FreeBSD.org> +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# + +# PROVIDE: disks +# KEYWORD: nojail + +. /etc/rc.subr + +name="geli" +desc="GELI disk encryption" +start_precmd='[ -n "$(geli_make_list)" -o -n "${geli_groups}" ]' +start_cmd="geli_start" +stop_cmd="geli_stop" +required_modules="geom_eli:g_eli" + +geli_start() +{ + devices=`geli_make_list` + + if [ -z "${geli_tries}" ]; then + if [ -n "${geli_attach_attempts}" ]; then + geli_tries=${geli_attach_attempts} + else + geli_tries=`${SYSCTL_N} kern.geom.eli.tries` + fi + fi + + for provider in ${devices}; do + provider_=`ltr ${provider} '/-' '_'` + + eval "flags=\${geli_${provider_}_flags}" + if [ -z "${flags}" ]; then + flags=${geli_default_flags} + fi + if [ -e "/dev/${provider}" -a ! -e "/dev/${provider}.eli" ]; then + echo "Configuring Disk Encryption for ${provider}." + count=1 + while [ ${count} -le ${geli_tries} ]; do + geli attach ${flags} ${provider} + if [ -e "/dev/${provider}.eli" ]; then + break + fi + echo "Attach failed; attempt ${count} of ${geli_tries}." + count=$((count+1)) + done + fi + done + + for group in ${geli_groups}; do + group_=`ltr ${group} '/-' '_'` + + eval "flags=\${geli_${group_}_flags}" + if [ -z "${flags}" ]; then + flags=${geli_default_flags} + fi + + eval "providers=\${geli_${group_}_devices}" + if [ -z "${providers}" ]; then + echo "No devices listed in geli group ${group}." + continue + fi + + if [ -e "/dev/${providers%% *}" -a ! -e "/dev/${providers%% *}.eli" ]; then + echo "Configuring Disk Encryption for geli group ${group}, containing ${providers}." + count=1 + while [ ${count} -le ${geli_tries} ]; do + geli attach ${flags} ${providers} + if [ -e "/dev/${providers%% *}.eli" ]; then + break + fi + echo "Attach failed; attempt ${count} of ${geli_tries}." + count=$((count+1)) + done + fi + done +} + +geli_stop() +{ + devices=`geli_make_list` + + for group in ${geli_groups}; do + group_=`ltr ${group} '/-' '_'` + + eval "providers=\${geli_${group_}_devices}" + + devices="${devices} ${providers}" + done + + for provider in ${devices}; do + if [ -e "/dev/${provider}.eli" ]; then + umount "/dev/${provider}.eli" 2>/dev/null + geli detach "${provider}" + fi + done +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +geli_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/geli2 b/libexec/rc/rc.d/geli2 new file mode 100755 index 000000000000..cedd48a312ee --- /dev/null +++ b/libexec/rc/rc.d/geli2 @@ -0,0 +1,62 @@ +#!/bin/sh +# +# Copyright (c) 2005 Pawel Jakub Dawidek <pjd@FreeBSD.org> +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# + +# PROVIDE: geli2 +# REQUIRE: FILESYSTEMS +# KEYWORD: nojail + +. /etc/rc.subr + +name="geli2" +desc="GELI disk encryption" +start_cmd="geli2_start" +stop_cmd=":" + +geli2_start() +{ + devices=`geli_make_list` + + for provider in ${devices}; do + provider_=`ltr ${provider} '/-' '_'` + + eval "autodetach=\${geli_${provider_}_autodetach}" + if [ -z "${autodetach}" ]; then + autodetach=${geli_autodetach} + fi + if checkyesno autodetach && [ -e "/dev/${provider}.eli" ]; then + geli detach -l ${provider} + fi + done +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +geli2_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/ggated b/libexec/rc/rc.d/ggated new file mode 100755 index 000000000000..846019acb055 --- /dev/null +++ b/libexec/rc/rc.d/ggated @@ -0,0 +1,22 @@ +#!/bin/sh + +# PROVIDE: ggated +# REQUIRE: NETWORKING + +. /etc/rc.subr + +name="ggated" +desc="GEOM Gate network daemon" +rcvar="ggated_enable" +command="/sbin/${name}" +pidfile="/var/run/${name}.pid" + +load_rc_config $name +required_files="${ggated_config}" + +# XXX?: doesn't make sense to run in a svcj: low-level access +ggated_svcj="NO" + +command_args="${ggated_config}" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/gptboot b/libexec/rc/rc.d/gptboot new file mode 100755 index 000000000000..188f1bb77557 --- /dev/null +++ b/libexec/rc/rc.d/gptboot @@ -0,0 +1,80 @@ +#!/bin/sh +# +# Copyright (c) 2010 Pawel Jakub Dawidek <pjd@FreeBSD.org> +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# + +# PROVIDE: gptboot +# REQUIRE: mountcritremote +# KEYWORD: nojail + +. /etc/rc.subr + +name="gptboot" +rcvar="gptboot_enable" +start_cmd="gptboot_report" + +gptboot_report() +{ + gpart show | \ + egrep '(^=>| freebsd-ufs .*(\[|,)(bootfailed|bootonce)(,|\]))' | \ + sed 's/^=>//' | \ + egrep -v '(\[|,)bootme(,|\])' | \ + while read start size pos type attrs rest; do + case "${pos}" in + [0-9]*) + if [ -n "${disk}" ]; then + part="${disk}p${pos}" + echo "${attrs}" | egrep -q '(\[|,)bootfailed(,|\])' + bootfailed=$? + echo "${attrs}" | egrep -q '(\[|,)bootonce(,|\])' + bootonce=$? + if [ ${bootfailed} -eq 0 ]; then + logger -t gptboot -p local0.notice "Boot from ${part} failed." + gpart unset -a bootfailed -i ${pos} ${disk} >/dev/null + elif [ ${bootonce} -eq 0 ]; then + # We want to log success after all failures. + echo -n "Boot from ${part} succeeded." + gpart unset -a bootonce -i ${pos} ${disk} >/dev/null + fi + fi + ;; + *) + if [ "${type}" = "GPT" ]; then + disk="${pos}" + else + disk="" + fi + ;; + esac + done | logger -t gptboot -p local0.notice +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +gptboot_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/growfs b/libexec/rc/rc.d/growfs new file mode 100755 index 000000000000..86bf199a8611 --- /dev/null +++ b/libexec/rc/rc.d/growfs @@ -0,0 +1,313 @@ +#!/bin/sh +# +# Copyright 2022 Michael J. Karels +# Copyright 2014 John-Mark Gurney +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# + +# PROVIDE: growfs +# REQUIRE: fsck +# BEFORE: root +# KEYWORD: firstboot + +# Grow root partition to fill available space, optionally adding a swap +# partition at the end. This allows us to distribute an image and +# have it work on essentially any size drive. + +# Note that this uses awk(1), and thus will not work if /usr is on a separate +# filesystem. We need to run early, because there might be not enough free +# space on rootfs for the boot to succeed, and on images we ship - which are +# the primary purpose of this script - there is no separate /usr anyway. + +. /etc/rc.subr + +name="growfs" +desc="Grow root partition to fill device" +start_cmd="growfs_start" +stop_cmd=":" +rcvar="growfs_enable" + +growfs_get_diskdev() +{ + local _search=${1} + sysctl -b kern.geom.conftxt | + while read x1 _type _dev line + do + if [ "${_type}" = "DISK" -a -n "$(echo ${_search} | grep ${_dev})" ]; then + echo -n ${_dev} + break + fi + done +} + +# Compute upper bound on swap partition size (if added), based on physmem +# and vm.swap_maxpages / 2 (the limit that elicits a warning). +# Rule for swap size based on memory size: +# up to 4 GB twice memory size +# 4 GB - 8 GB 8 GB +# over 8 GB memory size +growfs_swap_max() +{ + memsize=$(sysctl -n hw.physmem) + memsizeMB=$(($memsize / (1024 * 1024))) + + if [ $memsizeMB -lt 4096 ] + then + swapmax=$(($memsize * 2)) + elif [ $memsizeMB -lt 8192 ] + then + swapmax=$((8192 * 1024 * 1024)) + else + swapmax=$memsize + fi + + pagesize=$(sysctl -n hw.pagesize) + vm_swap_max=$(($(sysctl -n vm.swap_maxpages) / 2 * $pagesize)) + + if [ $swapmax -gt $vm_swap_max ] + then + swapmax=$vm_swap_max + fi + echo -n "$swapmax" +} + +# Find newly-added swap partition on parent device ($1). +growfs_last_swap() +{ + swapdev=$(gpart list $1 | awk ' + $2 == "Name:" { dev = $3 } + $1 == "type:" && $2 == "freebsd-swap" { swapdev = dev } + END { print swapdev } + ') + echo -n $swapdev +} + +growfs_start() +{ + verbose=0 + echo "Growing root partition to fill device" + FSTYPE=$(mount -p | awk '{ if ( $2 == "/") { print $3 }}') + FSDEV=$(mount -p | awk '{ if ( $2 == "/") { print $1 }}') + case "$FSTYPE" in + ufs) + rootdev=${FSDEV#/dev/} + ;; + zfs) + pool=${FSDEV%%/*} + rootdev=$(zpool list -v $pool | awk 'END { print $1 }') + ;; + *) + echo "Don't know how to grow root filesystem type: $FSTYPE" + return + esac + if [ x"$rootdev" = x"${rootdev%/*}" ]; then + # raw device + rawdev="$rootdev" + else + rawdev=$(glabel status | awk -v rootdev=$rootdev 'index(rootdev, $1) { print $3; }') + if [ x"$rawdev" = x"" ]; then + echo "Can't figure out device for: $rootdev" + return + fi + fi + + if [ x"diskid" = x"${rootdev%/*}" ]; then + search=$rootdev + else + search=$rawdev + fi + + diskdev=$(growfs_get_diskdev ${search}) + if [ -z "${diskdev}" ]; then + diskdev=${rootdev} + fi + + # Check kenv for growfs_swap_size; if not present, + # check $growfs_swap_size from /etc/rc.conf. + # A value of 0 suppresses swap addition, + # "" (or unset) specifies the default; + # other values indicate the size in bytes. + # If default, check whether swap is already in fstab; + # if so, don't add another. + addswap=1 + swapsize="$(kenv -q growfs_swap_size 2>/dev/null)" + case "$swapsize" in + "0") addswap=0 + ;; + "") case "$growfs_swap_size" in + "0") addswap=0 + ;; + "") + if ! awk ' + /^#/ { next } + $3 == "swap" { exit 1 } + ' < /etc/fstab + then + addswap=0 + fi + ;; + *) swapsize="$growfs_swap_size" + ;; + esac + ;; + *) ;; + esac + + swaplim=$(growfs_swap_max) + + [ $verbose -eq 1 ] && { + echo "diskdev is $diskdev" + echo "search is $search" + echo "swapsize is $swapsize" + echo "swaplim is $swaplim" + } + + sysctl -b kern.geom.conftxt | awk ' +{ + verbose = 0 + lvl=$1 + device[lvl] = $3 + type[lvl] = $2 + idx[lvl] = $7 + offset[lvl] = $9 + parttype[lvl] = $13 + size[lvl] = $4 + if (verbose) print lvl, type[lvl], $3 + if (type[lvl] == "DISK") { + disksize = size[lvl] + if (verbose) + print "disksize ", disksize + # Do not add swap on disks under 15 GB (decimal) by default. + if (addswap == 1 && (size[lvl] > 15000000000 || swapsize > 0)) + doing_swap = 1 + else + doing_swap = 0 + } else if (type[lvl] == "PART" && $11 == "freebsd-swap" && \ + int(swapsize) == 0) { + # This finds swap only if it precedes root, e.g. preceding disk. + addswap = 0 + doing_swap = 0 + print "swap device exists, not adding swap" + } + if (dev == $3) { + for (i = 1; i <= lvl; i++) { + # resize + if (type[i] == "PART") { + pdev = device[i - 1] + if (verbose) + print i, pdev, addswap, disksize, \ + doing_swap + swapcmd = "" + # Allow swap if current root is < 40% of disk. + if (parttype[i] != "MBR" && doing_swap == 1 && \ + (size[i] / disksize < 0.4 || \ + swapsize > 0)) { + print "Adding swap partition" + if (int(swapsize) == 0) { + swapsize = int(disksize / 10) + if (swapsize > swaplim) + swapsize = swaplim + } + sector = $5 + swapsize /= sector + if (verbose) + print "swapsize sectors", + swapsize + align = 4 * 1024 * 1024 / sector + + # Estimate offset for swap; let + # gpart compute actual start and size. + # Assume expansion all goes into this + # partition for MBR case. + if (parttype[i - 1] == "MBR") { + if (verbose) + print "sz ", size[i - 1], \ + " off ", offset[i - 1] + expand = size[0] - \ + (size[i - 1] + offset[i - 1]) + } else { + if (verbose) + print "sz ", size[i], \ + " off ", offset[i] + expand = size[0] - \ + (size[i] + offset[i]) + } + if (verbose) + print "expand ", expand, \ + " sz ", size[i] + swapbase = (expand + size[i]) / sector + swapbase -= swapsize + align + swapcmd = "gpart add -t freebsd-swap -a " align " -b " int(swapbase) " " pdev " && kenv growfs_swap_pdev=" pdev " >/dev/null; " + if (verbose) + swapcmd = "set -x; gpart show; " swapcmd + } + cmd[i] = swapcmd "gpart resize -i " idx[i] " " pdev + if (parttype[i] == "GPT") + cmd[i] = "gpart recover " pdev " ; " cmd[i] + } else if (type[i] == "LABEL") { + continue + } else { + print "unhandled type: " type[i] + exit 1 + } + } + for (i = 1; i <= lvl; i++) { + if (cmd[i]) + system(cmd[i]) + } + exit 0 + } +}' dev="$search" addswap="$addswap" swapsize="$swapsize" swaplim="$swaplim" + gpart commit "$diskdev" 2> /dev/null + case "$FSTYPE" in + ufs) + growfs -y /dev/"$rootdev" + ;; + zfs) + zpool online -e $pool $rootdev + ;; + esac + + # Get parent device of swap partition if one was added; + # if so, find swap device and label it. + pdev=$(kenv -q growfs_swap_pdev) + if [ -n "$pdev" ] + then + dev=$(growfs_last_swap "$pdev") + if [ -z "$dev" ] + then + echo "Swap partition not found on $pdev" + exit 0 + fi + glabel label -v growfs_swap $dev + fi +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +growfs_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/growfs_fstab b/libexec/rc/rc.d/growfs_fstab new file mode 100755 index 000000000000..8b7cea3a63e5 --- /dev/null +++ b/libexec/rc/rc.d/growfs_fstab @@ -0,0 +1,65 @@ +#!/bin/sh +# +# Copyright 2022 Michael J. Karels +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# + +# PROVIDE: growfs_fstab +# REQUIRE: growfs root +# KEYWORD: firstboot + +# If the growfs script added a swap partition, then add a swap entry +# to /etc/fstab if none exists, and add as dumpdev. + +. /etc/rc.subr + +name="growfs_fstab" +desc="Add new swap partition to /etc/fstab" +start_cmd="growfs_fstab_start" +stop_cmd=":" +rcvar="growfs_enable" + +growfs_fstab_start() +{ + if kenv -q growfs_swap_pdev >/dev/null + then + if awk ' + /^#/ { next } + $3 == "swap" { exit 1 } + ' < /etc/fstab + then + printf "/dev/label/growfs_swap\tnone\t\tswap\tsw\t\t0\t0\n" >>/etc/fstab + printf '# Set dumpdev to "AUTO" to enable crash dumps, "NO" to disable\n' >>/etc/rc.conf + printf 'dumpdev="AUTO"\n' >>/etc/rc.conf + dumpon $dumpon_flags /dev/label/growfs_swap + fi + fi +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +growfs_fstab_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/gssd b/libexec/rc/rc.d/gssd new file mode 100755 index 000000000000..7ab3c181eeb1 --- /dev/null +++ b/libexec/rc/rc.d/gssd @@ -0,0 +1,19 @@ +#!/bin/sh +# +# + +# PROVIDE: gssd +# REQUIRE: root mountcritlocal NETWORKING kdc +# BEFORE: mountcritremote +# KEYWORD: nojailvnet shutdown + +. /etc/rc.subr + +name=gssd +desc="Generic Security Services Daemon" +rcvar=gssd_enable + +: ${gssd_svcj_options:="net_basic nfsd"} + +load_rc_config $name +run_rc_command "$1" diff --git a/libexec/rc/rc.d/hastd b/libexec/rc/rc.d/hastd new file mode 100755 index 000000000000..37df43d26c7d --- /dev/null +++ b/libexec/rc/rc.d/hastd @@ -0,0 +1,33 @@ +#!/bin/sh +# +# + +# PROVIDE: hastd +# REQUIRE: NETWORKING syslogd +# BEFORE: DAEMON +# KEYWORD: nojail shutdown + +. /etc/rc.subr + +name="hastd" +desc="Highly Available Storage daemon" +rcvar="hastd_enable" +pidfile="/var/run/${name}.pid" +command="/sbin/${name}" +hastctl="/sbin/hastctl" +required_files="/etc/hast.conf" +stop_precmd="hastd_stop_precmd" +required_modules="geom_gate:g_gate" +extra_commands="reload" + +hastd_stop_precmd() +{ + ${hastctl} role init all +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: nojail keyword +hastd_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/hcsecd b/libexec/rc/rc.d/hcsecd new file mode 100755 index 000000000000..8827e53777f3 --- /dev/null +++ b/libexec/rc/rc.d/hcsecd @@ -0,0 +1,27 @@ +#!/bin/sh +# +# + +# PROVIDE: hcsecd +# REQUIRE: DAEMON +# BEFORE: LOGIN +# KEYWORD: nojail shutdown + +. /etc/rc.subr + +name="hcsecd" +desc="Control link keys and PIN codes for Bluetooth devices" +rcvar="hcsecd_enable" +command="/usr/sbin/${name}" +pidfile="/var/run/${name}.pid" +required_modules="ng_btsocket" + +load_rc_config $name +config="${hcsecd_config:-/etc/bluetooth/${name}.conf}" +command_args="-f ${config}" +required_files="${config}" + +# doesn't make sense to run in a svcj: nojail keyword +hcsecd_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/hostapd b/libexec/rc/rc.d/hostapd new file mode 100755 index 000000000000..264cb4ef476b --- /dev/null +++ b/libexec/rc/rc.d/hostapd @@ -0,0 +1,45 @@ +#!/bin/sh +# +# + +# PROVIDE: hostapd +# REQUIRE: mountcritremote +# KEYWORD: nojail shutdown + +. /etc/rc.subr + +name="hostapd" +desc="Authenticator for IEEE 802.11 networks" +command=${hostapd_program} +start_postcmd="hostapd_poststart" + +hostapd_poststart() { + if [ -n "$ifn" ]; then + ifconfig ${ifn} down + sleep 2 + ifconfig ${ifn} up + fi +} + +ifn="$2" +if [ -z "$ifn" ]; then + rcvar="hostapd_enable" + conf_file="/etc/${name}.conf" + pidfile="/var/run/${name}.pid" +else + rcvar= + conf_file="/etc/${name}-${ifn}.conf" + pidfile="/var/run/${name}-${ifn}.pid" +fi + +command_args="-P ${pidfile} -B ${conf_file}" +required_files="${conf_file}" +required_modules="wlan_xauth wlan_wep wlan_tkip wlan_ccmp wlan_gcmp" +extra_commands="reload" + +load_rc_config ${name} + +# doesn't make sense to run in a svcj: nojail keyword +hostapd_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/hostid b/libexec/rc/rc.d/hostid new file mode 100755 index 000000000000..bde88d7e6be5 --- /dev/null +++ b/libexec/rc/rc.d/hostid @@ -0,0 +1,165 @@ +#!/bin/sh +# +# Copyright (c) 2007 Pawel Jakub Dawidek <pjd@FreeBSD.org> +# Copyright (c) 2015 Xin LI <delphij@FreeBSD.org> +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# + +# PROVIDE: hostid +# REQUIRE: sysctl +# KEYWORD: nojail + +. /etc/rc.subr + +name="hostid" +desc="Generate a unique host ID" +start_cmd="hostid_start" +stop_cmd=":" +reset_cmd="hostid_reset" +extra_commands="reset" +rcvar="hostid_enable" + +hostid_set() +{ + uuid=$1 + # Generate hostid based on hostuuid - take first four bytes from md5(uuid). + id=`echo -n $uuid | /sbin/md5` + id="0x${id%????????????????????????}" + + # Set both kern.hostuuid and kern.hostid. + # + startmsg "Setting hostuuid: ${uuid}." + ${SYSCTL} kern.hostuuid="${uuid}" >/dev/null + startmsg "Setting hostid: ${id}." + ${SYSCTL} kern.hostid=${id} >/dev/null +} + +valid_hostid() +{ + uuid=$1 + + x="[0-9a-f]" + y=$x$x$x$x + + # Check against a blacklist before + # accepting the UUID. + case "${uuid}" in + 00000000-0000-0000-0000-000000000000) + ;; + 00020003-0004-0005-0006-000700080009) + ;; + 03000200-0400-0500-0006-000700080009) + ;; + 07090201-0103-0301-0807-060504030201) + ;; + 11111111-1111-1111-1111-111111111111) + ;; + 11111111-2222-3333-4444-555555555555) + ;; + 12345678-1234-5678-90ab-cddeefaabbcc) + ;; + 4c4c4544-0000-2010-8020-80c04f202020) + ;; + 58585858-5858-5858-5858-585858585858) + ;; + 890e2d14-cacd-45d1-ae66-bc80e8bfeb0f) + ;; + 8e275844-178f-44a8-aceb-a7d7e5178c63) + ;; + dc698397-fa54-4cf2-82c8-b1b5307a6a7f) + ;; + fefefefe-fefe-fefe-fefe-fefefefefefe) + ;; + *-ffff-ffff-ffff-ffffffffffff) + ;; + $y$y-$y-$y-$y-$y$y$y) + return 0 + ;; + esac + + return 1 +} + +hostid_hardware() +{ + uuid=`kenv -q smbios.system.uuid` + + if valid_hostid $uuid; then + echo "${uuid}" + elif [ "$uuid" ]; then + echo "INVALID" + fi +} + +hostid_generate() +{ + # First look for UUID in hardware. + uuid=`hostid_hardware` + + # Warn about invalid UUIDs + if [ "${uuid}" = "INVALID" ]; then + warn "hostid: unable to figure out a UUID from DMI data, generating a new one" + sleep 2 + uuid="" + fi + + # Generate a random UUID if invalid or not found + if [ -z "${uuid}" ]; then + # If not found, fall back to software-generated UUID. + uuid=`uuidgen ${hostid_uuidgen_flags}` + fi + hostid_set $uuid +} + +hostid_reset() +{ + hostid_generate + # Store newly generated UUID in ${hostid_file}. + echo $uuid > ${hostid_file} + if [ $? -ne 0 ]; then + warn "could not store hostuuid in ${hostid_file}." + fi +} + +hostid_start() +{ + # If ${hostid_file} already exists, we take UUID from there. + if [ -r ${hostid_file} ]; then + read saved_hostid < ${hostid_file} + if valid_hostid ${saved_hostid}; then + hostid_set ${saved_hostid} + exit 0 + fi + fi + + # No hostid file, generate UUID. + hostid_generate +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +hostid_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/hostid_save b/libexec/rc/rc.d/hostid_save new file mode 100755 index 000000000000..b9727d24bc57 --- /dev/null +++ b/libexec/rc/rc.d/hostid_save @@ -0,0 +1,51 @@ +#!/bin/sh +# +# + +# PROVIDE: hostid_save +# REQUIRE: hostid root +# KEYWORD: nojail + +. /etc/rc.subr + +name="hostid_save" +desc="Save unique host ID to disk" +start_cmd="hostid_save" +stop_cmd=":" +rcvar="hostid_enable" + +hostid_machine_id() +{ + local IFS + + IFS=- + set -- ${current_hostid} + IFS= + current_machine_id=$* +} + +hostid_save() +{ + current_hostid=`$SYSCTL_N kern.hostuuid` + + read saved_hostid 2>/dev/null < ${hostid_file} + if [ "${saved_hostid}" != "${current_hostid}" ]; then + echo "${current_hostid}" > ${hostid_file} || + warn "could not store hostuuid in ${hostid_file}." + fi + + hostid_machine_id + + read saved_machine_id 2>/dev/null < ${machine_id_file} + if [ "${saved_machine_id}" != "${current_machine_id}" ]; then + echo "${current_machine_id}" > ${machine_id_file} || + warn "could not store hostuuid in ${machine_id_file}." + fi +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +hostid_save_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/hostname b/libexec/rc/rc.d/hostname new file mode 100755 index 000000000000..0bc31ccd787e --- /dev/null +++ b/libexec/rc/rc.d/hostname @@ -0,0 +1,84 @@ +#!/bin/sh +# +# Copyright (c) 2003 The FreeBSD Project. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# + +# PROVIDE: hostname +# REQUIRE: FILESYSTEMS +# BEFORE: netif + +. /etc/rc.subr +. /etc/network.subr + +name="hostname" +desc="Set the system\'s hostname" +start_cmd="hostname_start" +stop_cmd=":" + +hostname_start() +{ + # If we are not inside a jail, set the host name. + # If we are inside a jail, set the host name if it is permitted. + # + if check_jail jailed; then + if ! check_jail set_hostname_allowed; then + return + fi + else + # If we're not in a jail and rc.conf doesn't specify a + # hostname, see if we can get one from kenv. + # + if [ -z "${hostname}" -a \ + -n "`/bin/kenv dhcp.host-name 2> /dev/null`" ]; then + hostname=`/bin/kenv dhcp.host-name` + fi + fi + + # Have we got a hostname yet? + # + if [ -z "${hostname}" ]; then + # Null hostname is probably OK if DHCP is in use, + # or when hostname is already set (common for jails). + # + if [ -z "`list_net_interfaces dhcp`" -a \ + -z "`/bin/hostname`" ]; then + warn "\$hostname is not set -- see rc.conf(5)." + fi + return + fi + + # All right, it is safe to invoke hostname(1) now. + # + startmsg -n "Setting hostname: ${hostname}" + /bin/hostname "${hostname}" + startmsg '.' +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +hostname_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/inetd b/libexec/rc/rc.d/inetd new file mode 100755 index 000000000000..81cc18d95be2 --- /dev/null +++ b/libexec/rc/rc.d/inetd @@ -0,0 +1,22 @@ +#!/bin/sh +# +# + +# PROVIDE: inetd +# REQUIRE: DAEMON LOGIN FILESYSTEMS +# KEYWORD: shutdown + +. /etc/rc.subr + +name="inetd" +desc="Internet \"super-server\"" +rcvar="inetd_enable" +command="/usr/sbin/${name}" +pidfile="/var/run/${name}.pid" +required_files="/etc/${name}.conf" +extra_commands="reload" + +: ${inetd_svcj_options:="net_basic"} + +load_rc_config $name +run_rc_command "$1" diff --git a/libexec/rc/rc.d/iovctl b/libexec/rc/rc.d/iovctl new file mode 100755 index 000000000000..70dc783aafb0 --- /dev/null +++ b/libexec/rc/rc.d/iovctl @@ -0,0 +1,42 @@ +#!/bin/sh +# +# + +# PROVIDE: iovctl +# REQUIRE: FILESYSTEMS sysctl kld + +. /etc/rc.subr + +name="iovctl" +command="/usr/sbin/iovctl" +start_cmd="iovctl_start" +stop_cmd="iovctl_stop" + +run_iovctl() +{ + local _f flag + + flag=$1 + for _f in ${iovctl_files} ; do + if [ -r ${_f} ]; then + ${command} ${flag} -f ${_f} > /dev/null + fi + done +} + +iovctl_start() +{ + run_iovctl -C +} + +iovctl_stop() +{ + run_iovctl -D +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +iovctl_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/ip6addrctl b/libexec/rc/rc.d/ip6addrctl new file mode 100755 index 000000000000..eac1d2729e78 --- /dev/null +++ b/libexec/rc/rc.d/ip6addrctl @@ -0,0 +1,127 @@ +#!/bin/sh +# +# + +# PROVIDE: ip6addrctl +# REQUIRE: FILESYSTEMS +# BEFORE: netif +# KEYWORD: nojailvnet + +. /etc/rc.subr +. /etc/network.subr + +name="ip6addrctl" +desc="configure address selection policy for IPv6 and IPv4" +rcvar="ip6addrctl_enable" +start_cmd="ip6addrctl_start" +stop_cmd="ip6addrctl_stop" +extra_commands="status prefer_ipv6 prefer_ipv4" +status_cmd="ip6addrctl" +prefer_ipv6_cmd="ip6addrctl_prefer_ipv6" +prefer_ipv4_cmd="ip6addrctl_prefer_ipv4" +config_file="/etc/ip6addrctl.conf" + +set_rcvar_obsolete ipv6_enable ipv6_activate_all_interfaces +set_rcvar_obsolete ipv6_prefer ip6addrctl_policy + +IP6ADDRCTL_CMD="/usr/sbin/ip6addrctl" + +ip6addrctl_prefer_ipv6() +{ + afexists inet6 || return 0 + + ${IP6ADDRCTL_CMD} flush >/dev/null 2>&1 + cat <<EOT | ${IP6ADDRCTL_CMD} install /dev/stdin + ::1/128 50 0 + ::/0 40 1 + ::ffff:0:0/96 35 4 + 2002::/16 30 2 + 2001::/32 5 5 + fc00::/7 3 13 + ::/96 1 3 + fec0::/10 1 11 + 3ffe::/16 1 12 +EOT +} + +ip6addrctl_prefer_ipv4() +{ + afexists inet6 || return 0 + + ${IP6ADDRCTL_CMD} flush >/dev/null 2>&1 + cat <<EOT | ${IP6ADDRCTL_CMD} install /dev/stdin + ::1/128 50 0 + ::/0 40 1 + ::ffff:0:0/96 100 4 + 2002::/16 30 2 + 2001::/32 5 5 + fc00::/7 3 13 + ::/96 1 3 + fec0::/10 1 11 + 3ffe::/16 1 12 +EOT +} + +ip6addrctl_start() +{ + afexists inet6 || return 0 + + # install the policy of the address selection algorithm. + case "${ip6addrctl_policy}" in + [Aa][Uu][Tt][Oo]) + if [ -r "${config_file}" -a -s "${config_file}" ]; then + ${IP6ADDRCTL_CMD} flush >/dev/null 2>&1 + ${IP6ADDRCTL_CMD} install "${config_file}" + else + if checkyesno ipv6_activate_all_interfaces; then + ip6addrctl_prefer_ipv6 + elif [ -n "$(list_vars ifconfig_\*_ipv6)" ]; then + ip6addrctl_prefer_ipv6 + else + ip6addrctl_prefer_ipv4 + fi + fi + ;; + ipv4_prefer) + ip6addrctl_prefer_ipv4 + ;; + ipv6_prefer) + ip6addrctl_prefer_ipv6 + ;; + [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) + # Backward compatibility when ipv6_prefer=YES + ip6addrctl_prefer_ipv6 + ;; + [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0) + # Backward compatibility when ipv6_prefer=NO + ip6addrctl_prefer_ipv4 + ;; + [Nn][Oo][Nn][Ee]) + ${IP6ADDRCTL_CMD} flush >/dev/null 2>&1 + ;; + *) + warn "\$ip6addrctl_policy is invalid: ${ip6addrctl_policy}. " \ + " \"ipv4_prefer\" is used instead." + ip6addrctl_prefer_ipv4 + ;; + esac + + if checkyesno ip6addrctl_verbose; then + echo 'Address selection policy table for IPv4 and IPv6:' + ${IP6ADDRCTL_CMD} + fi +} + +ip6addrctl_stop() +{ + afexists inet6 || return 0 + + ip6addrctl flush >/dev/null 2>&1 +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +ipv6addrctl_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/ipfilter b/libexec/rc/rc.d/ipfilter new file mode 100755 index 000000000000..9b64fcff0c7a --- /dev/null +++ b/libexec/rc/rc.d/ipfilter @@ -0,0 +1,88 @@ +#!/bin/sh +# +# + +# PROVIDE: ipfilter +# REQUIRE: FILESYSTEMS +# BEFORE: ipmon ipnat netif netwait securelevel +# KEYWORD: nojailvnet + +. /etc/rc.subr + +name="ipfilter" +desc="IP packet filter" +rcvar="ipfilter_enable" +load_rc_config $name +stop_precmd="test -f ${ipfilter_rules}" + +# doesn't make sense to run in a svcj: config setting +ipfilter_svcj="NO" + +start_precmd="$stop_precmd" +start_cmd="ipfilter_start" +stop_cmd="ipfilter_stop" +reload_precmd="$stop_precmd" +reload_cmd="ipfilter_reload" +resync_precmd="$stop_precmd" +resync_cmd="ipfilter_resync" +status_precmd="$stop_precmd" +status_cmd="ipfilter_status" +extra_commands="reload resync" +required_modules="ipl:ipfilter" + +ipfilter_start() +{ + echo "Enabling ipfilter." + if [ -n "${ifilter_optionlist}" ]; then + if ${ipfilter_program:-/sbin/ipf} -V | grep -q 'Running: yes'; then + ${ipfilter_program:-/sbin/ipf} -D + fi + ${ipfilter_program:-/sbin/ipf} -T "${ipfilter_optionlist}" + ${ipfilter_program:-/sbin/ipf} -E + elif ! ${ipfilter_program:-/sbin/ipf} -V | grep -q 'Running: yes'; then + ${ipfilter_program:-/sbin/ipf} -E + fi + ${ipfilter_program:-/sbin/ipf} -Fa + if [ -r "${ipfilter_rules}" ]; then + ${ipfilter_program:-/sbin/ipf} \ + -f "${ipfilter_rules}" ${ipfilter_flags} + fi +} + +ipfilter_stop() +{ + if ${ipfilter_program:-/sbin/ipf} -V | grep -q 'Running: yes'; then + echo "Saving firewall state tables" + ${ipfs_program:-/sbin/ipfs} -W ${ipfs_flags} + echo "Disabling ipfilter." + ${ipfilter_program:-/sbin/ipf} -D + fi +} + +ipfilter_reload() +{ + echo "Reloading ipfilter rules." + + ${ipfilter_program:-/sbin/ipf} -I -Fa + if [ -r "${ipfilter_rules}" ]; then + ${ipfilter_program:-/sbin/ipf} -I \ + -f "${ipfilter_rules}" ${ipfilter_flags} + if [ $? -ne 0 ]; then + err 1 'Load of rules into alternate set failed; aborting reload' + fi + fi + ${ipfilter_program:-/sbin/ipf} -s + +} + +ipfilter_resync() +{ + ${ipfilter_program:-/sbin/ipf} -y ${ipfilter_flags} +} + +ipfilter_status() +{ + ${ipfilter_program:-/sbin/ipf} -V +} + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/ipfs b/libexec/rc/rc.d/ipfs new file mode 100755 index 000000000000..2ec4ad3b1d00 --- /dev/null +++ b/libexec/rc/rc.d/ipfs @@ -0,0 +1,56 @@ +#!/bin/sh +# +# + +# PROVIDE: ipfs +# REQUIRE: ipnat +# BEFORE: netif +# KEYWORD: nojail shutdown + +. /etc/rc.subr + +name="ipfs" +desc="Saves and restores information for NAT and state tables" +rcvar="ipfs_enable" +start_cmd="ipfs_start" +stop_cmd="ipfs_stop" +start_precmd="ipfs_prestart" + +ipfs_prestart() +{ + # Do not continue if either ipnat or ipfilter is not enabled or + # if the ipfilter module is not loaded. + # + if ! checkyesno ipfilter_enable -o ! checkyesno ipnat_enable ; then + err 1 "${name} requires either ipfilter or ipnat enabled" + fi + if ! ${ipfilter_program:-/sbin/ipf} -V | grep -q 'Running: yes' >/dev/null 2>&1; then + err 1 "ipfilter module is not loaded" + fi + return 0 +} + +ipfs_start() +{ + if [ -r /var/db/ipf/ipstate.ipf -a -r /var/db/ipf/ipnat.ipf ]; then + ${ipfs_program} -R ${rc_flags} + rm -f /var/db/ipf/ipstate.ipf /var/db/ipf/ipnat.ipf + fi +} + +ipfs_stop() +{ + if [ ! -d /var/db/ipf ]; then + mkdir /var/db/ipf + chmod 700 /var/db/ipf + chown root:wheel /var/db/ipf + fi + ${ipfs_program} -W ${rc_flags} +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +ipfs_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/ipfw b/libexec/rc/rc.d/ipfw new file mode 100755 index 000000000000..6d6f7577828f --- /dev/null +++ b/libexec/rc/rc.d/ipfw @@ -0,0 +1,169 @@ +#!/bin/sh +# +# + +# PROVIDE: ipfw +# REQUIRE: ppp +# KEYWORD: nojailvnet + +. /etc/rc.subr +. /etc/network.subr + +name="ipfw" +desc="Firewall, traffic shaper, packet scheduler, in-kernel NAT" +rcvar="firewall_enable" +start_cmd="ipfw_start" +start_precmd="ipfw_prestart" +start_postcmd="ipfw_poststart" +stop_cmd="ipfw_stop" +status_cmd="ipfw_status" +required_modules="ipfw" +extra_commands="status" + +set_rcvar_obsolete ipv6_firewall_enable + +ipfw_prestart() +{ + if checkyesno dummynet_enable; then + required_modules="$required_modules dummynet" + fi + if checkyesno natd_enable; then + required_modules="$required_modules ipdivert" + fi + if checkyesno firewall_nat_enable; then + required_modules="$required_modules ipfw_nat" + fi + if checkyesno firewall_nat64_enable; then + required_modules="$required_modules ipfw_nat64" + fi + if checkyesno firewall_nptv6_enable; then + required_modules="$required_modules ipfw_nptv6" + fi + if checkyesno firewall_pmod_enable; then + required_modules="$required_modules ipfw_pmod" + fi +} + +ipfw_start() +{ + local _firewall_type _module _sysctl_reload + + if [ -n "${1}" ]; then + _firewall_type=$1 + else + _firewall_type=${firewall_type} + fi + + _sysctl_reload=no + for _module in ${required_modules} + do + if kldstat -qn ${_module}; then + _sysctl_reload=yes + break + fi + done + + if [ ${_sysctl_reload} = yes ]; then + /etc/rc.d/sysctl reload + fi + + # set the firewall rules script if none was specified + [ -z "${firewall_script}" ] && firewall_script=/etc/rc.firewall + + if [ -r "${firewall_script}" ]; then + /bin/sh "${firewall_script}" "${_firewall_type}" + echo 'Firewall rules loaded.' + elif [ "`ipfw list 65535`" = "65535 deny ip from any to any" ]; then + echo 'Warning: kernel has firewall functionality, but' \ + 'firewall rules are not enabled.' + echo ' All ip services are disabled.' + fi + + # Firewall logging + # + if checkyesno firewall_logging; then + echo 'Firewall logging enabled.' + ${SYSCTL} net.inet.ip.fw.verbose=1 >/dev/null + fi + if checkyesno firewall_logif; then + if ! ifconfig ipfw0 >/dev/null 2>&1; then + ifconfig ipfw0 create + echo 'Firewall logging pseudo-interface (ipfw0)' \ + 'created.' + else + echo 'Firewall logging pseudo-interface (ipfw0)' \ + 'already created.' + fi + fi +} + +ipfw_poststart() +{ + local _coscript + + # Start firewall coscripts + # + for _coscript in ${firewall_coscripts} ; do + if [ -f "${_coscript}" ]; then + ${_coscript} quietstart + fi + done + + # Enable the firewall + # + if ! ${SYSCTL} net.inet.ip.fw.enable=1 >/dev/null 2>&1; then + warn "failed to enable IPv4 firewall" + fi + if afexists inet6; then + if ! ${SYSCTL} net.inet6.ip6.fw.enable=1 >/dev/null 2>&1 + then + warn "failed to enable IPv6 firewall" + fi + fi +} + +ipfw_stop() +{ + local _coscript + + # Disable the firewall + # + ${SYSCTL} net.inet.ip.fw.enable=0 >/dev/null + if afexists inet6; then + ${SYSCTL} net.inet6.ip6.fw.enable=0 >/dev/null + fi + + # Stop firewall coscripts + # + for _coscript in `reverse_list ${firewall_coscripts}` ; do + if [ -f "${_coscript}" ]; then + ${_coscript} quietstop + fi + done +} + +ipfw_status() +{ + status=$(sysctl -i -n net.inet.ip.fw.enable) + : ${status:=0} + if afexists inet6; then + status6=$(sysctl -i -n net.inet6.ip6.fw.enable) + : ${status6:=0} + status=$((${status} + ${status6})) + fi + if [ ${status} -eq 0 ]; then + echo "ipfw is not enabled" + exit 1 + else + echo "ipfw is enabled" + exit 0 + fi +} + +load_rc_config $name +firewall_coscripts="/etc/rc.d/natd ${firewall_coscripts}" + +# doesn't make sense to run in a svcj: config setting +ipfw_svcj="NO" + +run_rc_command $* diff --git a/libexec/rc/rc.d/ipfw_netflow b/libexec/rc/rc.d/ipfw_netflow new file mode 100755 index 000000000000..129488ce60d0 --- /dev/null +++ b/libexec/rc/rc.d/ipfw_netflow @@ -0,0 +1,79 @@ +#!/bin/sh +# +# + +# PROVIDE: ipfw_netflow +# REQUIRE: ipfw +# KEYWORD: nojailvnet + +. /etc/rc.subr +. /etc/network.subr + +name="ipfw_netflow" +desc="firewall, ipfw, netflow" +rcvar="${name}_enable" +start_cmd="${name}_start" +stop_cmd="${name}_stop" +start_precmd="${name}_test" +status_cmd="${name}_status" +required_modules="ipfw ng_netflow ng_ipfw" +extra_commands="status" + +: ${ipfw_netflow_hook:=9995} +: ${ipfw_netflow_rule:=01000} +: ${ipfw_netflow_ip:=127.0.0.1} +: ${ipfw_netflow_port:=9995} +: ${ipfw_netflow_version:=} + +ipfw_netflow_test() +{ + if [ "${ipfw_netflow_version}" != "" ] && [ "${ipfw_netflow_version}" != 9 ]; then + err 1 "Unknown netflow version \'${ipfw_netflow_version}\'" + fi + case "${ipfw_netflow_hook}" in + [!0-9]*) + err 1 "Bad value \"${ipfw_netflow_hook}\": Hook must be numerical" + esac + case "${ipfw_netflow_rule}" in + [!0-9]*) + err 1 "Bad value \"${ipfw_netflow_rule}\": Rule number must be numerical" + esac +} + +ipfw_netflow_is_running() +{ + ngctl show netflow: > /dev/null 2>&1 && return 0 || return 1 +} + +ipfw_netflow_status() +{ + ipfw_netflow_is_running && echo "ipfw_netflow is active" || echo "ipfw_netflow is not active" +} + +ipfw_netflow_start() +{ + ipfw_netflow_is_running && err 1 "ipfw_netflow is already active" + ipfw add ${ipfw_netflow_rule} ngtee ${ipfw_netflow_hook} ip from any to any ${ipfw_netflow_fib:+fib ${ipfw_netflow_fib}} + ngctl -f - <<-EOF + mkpeer ipfw: netflow ${ipfw_netflow_hook} iface0 + name ipfw:${ipfw_netflow_hook} netflow + mkpeer netflow: ksocket export${ipfw_netflow_version} inet/dgram/udp + msg netflow: setdlt {iface=0 dlt=12} + name netflow:export${ipfw_netflow_version} netflow_export + msg netflow:export${ipfw_netflow_version} connect inet/${ipfw_netflow_ip}:${ipfw_netflow_port} +EOF +} + +ipfw_netflow_stop() +{ + ipfw_netflow_is_running || err 1 "ipfw_netflow is not active" + ngctl shutdown netflow: + ipfw delete ${ipfw_netflow_rule} +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +ipfw_netflow_svcj="NO" + +run_rc_command $* diff --git a/libexec/rc/rc.d/ipmon b/libexec/rc/rc.d/ipmon new file mode 100755 index 000000000000..3ef0c895ad16 --- /dev/null +++ b/libexec/rc/rc.d/ipmon @@ -0,0 +1,36 @@ +#!/bin/sh +# +# + +# PROVIDE: ipmon +# REQUIRE: FILESYSTEMS hostname sysctl +# BEFORE: SERVERS +# KEYWORD: nojailvnet + +. /etc/rc.subr + +name="ipmon" +desc="Monitors /dev/ipl for logged packets" +rcvar="ipmon_enable" +command="/sbin/${name}" +start_precmd="ipmon_precmd" + +# no svcj options needed +: ${ipmon_svcj_options:=""} + +ipmon_precmd() +{ + # Continue only if ipfilter or ipnat is enabled and the + # ipfilter module is loaded. + # + if ! checkyesno ipfilter_enable && ! checkyesno ipnat_enable && ! checkyesno rc_force ; then + err 1 "${name} requires either ipfilter or ipnat enabled" + fi + if ! ${ipfilter_program:-/sbin/ipf} -V | grep -q 'Running: yes' >/dev/null 2>&1; then + err 1 "ipfilter module is not loaded" + fi + return 0 +} + +load_rc_config $name +run_rc_command "$1" diff --git a/libexec/rc/rc.d/ipnat b/libexec/rc/rc.d/ipnat new file mode 100755 index 000000000000..56fe443686b1 --- /dev/null +++ b/libexec/rc/rc.d/ipnat @@ -0,0 +1,30 @@ +#!/bin/sh +# +# + +# PROVIDE: ipnat +# KEYWORD: nojailvnet + +. /etc/rc.subr + +name="ipnat" +desc="user interface to the NAT subsystem" +rcvar="ipnat_enable" +load_rc_config $name +start_cmd="ipnat_start" +stop_cmd="${ipnat_program} -F -C" +reload_cmd="${ipnat_program} -F -C -f ${ipnat_rules}" +extra_commands="reload" +required_files="${ipnat_rules}" +required_modules="ipl:ipfilter" + +# doesn't make sense to run in a svcj: config setting +ipnat_svcj="NO" + +ipnat_start() +{ + echo "Installing NAT rules." + ${ipnat_program} -CF -f ${ipnat_rules} ${ipnat_flags} +} + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/ippool b/libexec/rc/rc.d/ippool new file mode 100755 index 000000000000..0db8bbe98f61 --- /dev/null +++ b/libexec/rc/rc.d/ippool @@ -0,0 +1,40 @@ +#!/bin/sh +# +# + +# PROVIDE: ippool +# REQUIRE: FILESYSTEMS +# BEFORE: ipfilter +# KEYWORD: nojailvnet + +. /etc/rc.subr + +name="ippool" +desc="user interface to the IPFilter pools" +rcvar="ippool_enable" +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +ippool_svcj="NO" + +start_precmd="ippool_start_precmd" +stop_cmd="${ippool_program} -F" +reload_cmd="ippool_reload" +extra_commands="reload" +required_files="${ippool_rules}" +required_modules="ipl:ipfilter" + +ippool_start_precmd() +{ + rc_flags="-f ${ippool_rules} ${rc_flags}" +} + +ippool_reload() +{ + echo "Reloading IP Pools." + ${stop_cmd} + ${start_cmd} +} + + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/ipropd_master b/libexec/rc/rc.d/ipropd_master new file mode 100755 index 000000000000..a3ca498afe6c --- /dev/null +++ b/libexec/rc/rc.d/ipropd_master @@ -0,0 +1,43 @@ +#!/bin/sh +# +# + +# PROVIDE: ipropd_master +# REQUIRE: kdc +# KEYWORD: shutdown + +. /etc/rc.subr + +name=ipropd_master +rcvar=${name}_enable +required_files="$ipropd_master_keytab" +start_precmd=${name}_start_precmd +start_postcmd=${name}_start_postcmd + +: ${ipropd_master_svcj_options:="net_basic"} + +ipropd_master_start_precmd() +{ + + if [ -z "$ipropd_master_slaves" ]; then + warn "\$ipropd_master_slaves is empty." + return 1 + fi + for _slave in $ipropd_master_slaves; do + echo $_slave + done > /var/heimdal/slaves || return 1 +} +ipropd_master_start_postcmd() +{ + + echo "${name}: slave nodes: $ipropd_master_slaves" +} + +load_rc_config $name + +command_args="$command_args \ + --keytab=\"$ipropd_master_keytab\" \ + --detach \ +" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/ipropd_slave b/libexec/rc/rc.d/ipropd_slave new file mode 100755 index 000000000000..1735cff3de86 --- /dev/null +++ b/libexec/rc/rc.d/ipropd_slave @@ -0,0 +1,35 @@ +#!/bin/sh +# +# + +# PROVIDE: ipropd_slave +# REQUIRE: kdc +# KEYWORD: shutdown + +. /etc/rc.subr + +name=ipropd_slave +rcvar=${name}_enable +required_files="$ipropd_slave_keytab" +start_precmd=${name}_start_precmd + +: ${ipropd_slave_svcj_options:="net_basic"} + +ipropd_slave_start_precmd() +{ + + if [ -z "$ipropd_slave_master" ]; then + warn "\$ipropd_slave_master is empty." + return 1 + fi +} + +load_rc_config $name + +command_args=" \ + command_args \ + --keytab=\"$ipropd_slave_keytab\" \ + --detach \ + $ipropd_slave_master" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/ipsec b/libexec/rc/rc.d/ipsec new file mode 100755 index 000000000000..0e7ad213ce67 --- /dev/null +++ b/libexec/rc/rc.d/ipsec @@ -0,0 +1,64 @@ +#!/bin/sh +# +# + +# PROVIDE: ipsec +# REQUIRE: FILESYSTEMS +# BEFORE: DAEMON mountcritremote +# KEYWORD: nojailvnet + +. /etc/rc.subr + +name="ipsec" +desc="Internet Protocol Security protocol" +rcvar="ipsec_enable" +start_precmd="ipsec_prestart" +start_cmd="ipsec_start" +stop_precmd="test -f $ipsec_file" +stop_cmd="ipsec_stop" +reload_cmd="ipsec_reload" +extra_commands="reload" +ipsec_program="/sbin/setkey" +required_modules="ipsec" +# ipsec_file is set by rc.conf + +ipsec_prestart() +{ + if [ ! -f "$ipsec_file" ]; then + warn "$ipsec_file not readable; ipsec start aborted." + stop_boot + return 1 + fi + return 0 +} + +ipsec_start() +{ + echo "Installing ipsec manual keys/policies." + ${ipsec_program} -f $ipsec_file +} + +ipsec_stop() +{ + echo "Clearing ipsec manual keys/policies." + + # Still not 100% sure if we would like to do this. + # It is very questionable to do this during shutdown session + # since it can hang any of the remaining IPv4/v6 sessions. + # + ${ipsec_program} -F + ${ipsec_program} -FP +} + +ipsec_reload() +{ + echo "Reloading ipsec manual keys/policies." + ${ipsec_program} -f "$ipsec_file" +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +ipsec_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/iscsictl b/libexec/rc/rc.d/iscsictl new file mode 100755 index 000000000000..247954e0d4f1 --- /dev/null +++ b/libexec/rc/rc.d/iscsictl @@ -0,0 +1,24 @@ +#!/bin/sh +# +# + +# PROVIDE: iscsictl +# REQUIRE: NETWORKING iscsid +# BEFORE: DAEMON +# KEYWORD: nojail + +. /etc/rc.subr + +name="iscsictl" +desc="iSCSI initiator management utility" +rcvar="iscsictl_enable" +command="/usr/bin/${name}" +command_args="${iscsictl_flags}" +required_modules="iscsi" + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +iscsictl_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/iscsid b/libexec/rc/rc.d/iscsid new file mode 100755 index 000000000000..e2418e8baaa1 --- /dev/null +++ b/libexec/rc/rc.d/iscsid @@ -0,0 +1,24 @@ +#!/bin/sh +# +# + +# PROVIDE: iscsid +# REQUIRE: NETWORKING +# BEFORE: DAEMON +# KEYWORD: nojail + +. /etc/rc.subr + +name="iscsid" +desc="iSCSI initiator daemon" +rcvar="iscsid_enable" +pidfile="/var/run/${name}.pid" +command="/usr/sbin/${name}" +required_modules="iscsi" + +load_rc_config $name + +# doesn't make sense to run in a svcj: nojail keyword +iscsid_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/jail b/libexec/rc/rc.d/jail new file mode 100755 index 000000000000..f059363e1e8d --- /dev/null +++ b/libexec/rc/rc.d/jail @@ -0,0 +1,616 @@ +#!/bin/sh +# +# + +# PROVIDE: jail +# REQUIRE: LOGIN FILESYSTEMS +# BEFORE: securelevel +# KEYWORD: shutdown + +. /etc/rc.subr + +name="jail" +desc="Manage system jails" +rcvar="jail_enable" + +start_cmd="jail_start" +start_postcmd="jail_warn" +stop_cmd="jail_stop" +config_cmd="jail_config" +console_cmd="jail_console" +status_cmd="jail_status" +extra_commands="config console status" +: ${jail_program:=/usr/sbin/jail} +: ${jail_consolecmd:=/usr/bin/login -f root} +: ${jail_jexec:=/usr/sbin/jexec} +: ${jail_jls:=/usr/sbin/jls} + +need_dad_wait= + +# extract_var jv name param num defval +# Extract value from ${jail_$jv_$name} or ${jail_$name} and +# set it to $param. If not defined, $defval is used. +# When $num is [0-9]*, ${jail_$jv_$name$num} are looked up and +# $param is set by using +=. $num=0 is optional (params may start at 1). +# When $num is YN or NY, the value is interpreted as boolean. +# When $num is @, the value is interpreted as an array separted by IFS. +extract_var() +{ + local i _jv _name _param _num _def _name1 _name2 + _jv=$1 + _name=$2 + _param=$3 + _num=$4 + _def=$5 + + case $_num in + YN) + _name1=jail_${_jv}_${_name} + _name2=jail_${_name} + eval $_name1=\"\${$_name1:-\${$_name2:-$_def}}\" + if checkyesno $_name1; then + echo " $_param = 1;" + else + echo " $_param = 0;" + fi + ;; + NY) + _name1=jail_${_jv}_${_name} + _name2=jail_${_name} + eval $_name1=\"\${$_name1:-\${$_name2:-$_def}}\" + if checkyesno $_name1; then + echo " $_param = 0;" + else + echo " $_param = 1;" + fi + ;; + [0-9]*) + i=$_num + while : ; do + _name1=jail_${_jv}_${_name}${i} + _name2=jail_${_name}${i} + eval _tmpargs=\"\${$_name1:-\${$_name2:-$_def}}\" + if [ -n "$_tmpargs" ]; then + echo " $_param += \"$_tmpargs\";" + elif [ $i != 0 ]; then + break; + fi + i=$(($i + 1)) + done + ;; + @) + _name1=jail_${_jv}_${_name} + _name2=jail_${_name} + eval _tmpargs=\"\${$_name1:-\${$_name2:-$_def}}\" + set -- $_tmpargs + if [ $# -gt 0 ]; then + echo -n " $_param = " + while [ $# -gt 1 ]; do + echo -n "\"$1\", " + shift + done + echo "\"$1\";" + fi + ;; + *) + _name1=jail_${_jv}_${_name} + _name2=jail_${_name} + eval _tmpargs=\"\${$_name1:-\${$_name2:-$_def}}\" + if [ -n "$_tmpargs" ]; then + echo " $_param = \"$_tmpargs\";" + fi + ;; + esac +} + +# parse_options _j _jv +# Parse options and create a temporary configuration file if necessary. +# +parse_options() +{ + local _j _jv _p + _j=$1 + _jv=$2 + + _confwarn=0 + if [ -z "$_j" ]; then + warn "parse_options: you must specify a jail" + return + fi + eval _jconf=\"\${jail_${_jv}_conf:-/etc/jail.${_j}.conf}\" + eval _rootdir=\"\$jail_${_jv}_rootdir\" + eval _jconfdir=\"/etc/jail.conf.d/${_j}.conf\" + eval _hostname=\"\$jail_${_jv}_hostname\" + if [ -z "$_rootdir" -o \ + -z "$_hostname" ]; then + if [ -r "$_jconf" ]; then + _conf="$_jconf" + return 0 + elif [ -r "$_jconfdir" ] && ! egrep -q \ + '^\s*\.include\s*["'\'']?/etc/jail.conf.d/' "$jail_conf" \ + 2>/dev/null; then + _conf="$_jconfdir" + return 0 + elif [ -r "$jail_conf" ]; then + _conf="$jail_conf" + return 0 + else + warn "Invalid configuration for $_j " \ + "(no jail.conf, no hostname, or no path). " \ + "Jail $_j was ignored." + fi + return 1 + fi + eval _ip=\"\$jail_${_jv}_ip\" + if [ -z "$_ip" ] && ! check_kern_features vimage; then + warn "no ipaddress specified and no vimage support. " \ + "Jail $_j was ignored." + return 1 + fi + _conf=/var/run/jail.${_j}.conf + # + # To relieve confusion, show a warning message. + # + : ${jail_confwarn:=YES} + checkyesno jail_confwarn && _confwarn=1 + if [ -r "$jail_conf" -o -r "$_jconf" ]; then + if ! checkyesno jail_parallel_start; then + warn "$_conf is created and used for jail $_j." + fi + fi + /usr/bin/install -m 0644 -o root -g wheel /dev/null $_conf || return 1 + + eval : \${jail_${_jv}_flags:=${jail_flags}} + eval _exec=\"\$jail_${_jv}_exec\" + eval _exec_start=\"\$jail_${_jv}_exec_start\" + eval _exec_stop=\"\$jail_${_jv}_exec_stop\" + if [ -n "${_exec}" ]; then + # simple/backward-compatible execution + _exec_start="${_exec}" + _exec_stop="" + else + # flexible execution + if [ -z "${_exec_start}" ]; then + _exec_start="/bin/sh /etc/rc" + if [ -z "${_exec_stop}" ]; then + _exec_stop="/bin/sh /etc/rc.shutdown jail" + fi + fi + fi + eval _interface=\"\${jail_${_jv}_interface:-${jail_interface}}\" + eval _parameters=\"\${jail_${_jv}_parameters:-${jail_parameters}}\" + eval _fstab=\"\${jail_${_jv}_fstab:-${jail_fstab:-/etc/fstab.$_j}}\" + ( + date +"# Generated by rc.d/jail at %Y-%m-%d %H:%M:%S" + echo "$_j {" + extract_var $_jv hostname host.hostname - "" + extract_var $_jv rootdir path - "" + if [ -n "$_ip" ]; then + extract_var $_jv interface interface - "" + jail_handle_ips_option $_ip $_interface + alias=0 + while : ; do + eval _x=\"\$jail_${_jv}_ip_multi${alias}\" + [ -z "$_x" ] && break + + jail_handle_ips_option $_x $_interface + alias=$(($alias + 1)) + done + case $need_dad_wait in + 1) + # Sleep to let DAD complete before + # starting services. + echo " exec.start += \"sleep " \ + $(($(${SYSCTL_N} net.inet6.ip6.dad_count) + 1)) \ + "\";" + ;; + esac + # These are applicable only to non-vimage jails. + extract_var $_jv fib exec.fib - "" + extract_var $_jv socket_unixiproute_only \ + allow.raw_sockets NY YES + else + echo " vnet;" + extract_var $_jv vnet_interface vnet.interface @ "" + fi + + echo " exec.clean;" + echo " exec.system_user = \"root\";" + echo " exec.jail_user = \"root\";" + extract_var $_jv exec_prestart exec.prestart 0 "" + extract_var $_jv exec_poststart exec.poststart 0 "" + extract_var $_jv exec_prestop exec.prestop 0 "" + extract_var $_jv exec_poststop exec.poststop 0 "" + + echo " exec.start += \"$_exec_start\";" + extract_var $_jv exec_afterstart exec.start 0 "" + echo " exec.stop = \"$_exec_stop\";" + + extract_var $_jv consolelog exec.consolelog - \ + /var/log/jail_${_j}_console.log + + if [ -r $_fstab ]; then + echo " mount.fstab = \"$_fstab\";" + fi + + eval : \${jail_${_jv}_devfs_enable:=${jail_devfs_enable:-NO}} + if checkyesno jail_${_jv}_devfs_enable; then + echo " mount.devfs;" + eval _ruleset=\${jail_${_jv}_devfs_ruleset:-${jail_devfs_ruleset}} + case $_ruleset in + "") ;; + [0-9]*) echo " devfs_ruleset = \"$_ruleset\";" ;; + devfsrules_jail) + # XXX: This is the default value, + # Let jail(8) to use the default because + # mount(8) only accepts an integer. + # This should accept a ruleset name. + ;; + *) warn "devfs_ruleset must be an integer." ;; + esac + fi + eval : \${jail_${_jv}_fdescfs_enable:=${jail_fdescfs_enable:-NO}} + if checkyesno jail_${_jv}_fdescfs_enable; then + echo " mount.fdescfs;" + fi + eval : \${jail_${_jv}_procfs_enable:=${jail_procfs_enable:-NO}} + if checkyesno jail_${_jv}_procfs_enable; then + echo " mount.procfs;" + fi + + eval : \${jail_${_jv}_mount_enable:=${jail_mount_enable:-NO}} + if checkyesno jail_${_jv}_mount_enable; then + echo " allow.mount;" + fi + + extract_var $_jv set_hostname_allow allow.set_hostname YN NO + extract_var $_jv sysvipc_allow allow.sysvipc YN NO + extract_var $_jv enforce_statfs enforce_statfs - 2 + extract_var $_jv osreldate osreldate + extract_var $_jv osrelease osrelease + + _zfs_dataset="$(eval echo \$jail_${_jv}_zfs_dataset)" + if [ -n "$_zfs_dataset" ]; then + for ds in $_zfs_dataset; do + echo " zfs.dataset += ${ds};" + done + fi + for _p in $_parameters; do + echo " ${_p%\;};" + done + echo "}" + ) >> $_conf + + return 0 +} + +# jail_extract_address argument iface +# The second argument is the string from one of the _ip +# or the _multi variables. In case of a comma separated list +# only one argument must be passed in at a time. +# The function alters the _type, _iface, _addr and _mask variables. +# +jail_extract_address() +{ + local _i _interface + _i=$1 + _interface=$2 + + if [ -z "${_i}" ]; then + warn "jail_extract_address: called without input" + return + fi + + # Check if we have an interface prefix given and split into + # iFace and rest. + case "${_i}" in + *\|*) # ifN|.. prefix there + _iface=${_i%%|*} + _r=${_i##*|} + ;; + *) _iface="" + _r=${_i} + ;; + esac + + # In case the IP has no interface given, check if we have a global one. + _iface=${_iface:-${_interface}} + + # Set address, cut off any prefix/netmask/prefixlen. + _addr=${_r} + _addr=${_addr%%[/ ]*} + + # Theoretically we can return here if interface is not set, + # as we only care about the _mask if we call ifconfig. + # This is not done because we may want to santize IP addresses + # based on _type later, and optionally change the type as well. + + # Extract the prefix/netmask/prefixlen part by cutting off the address. + _mask=${_r} + _mask=`expr -- "${_mask}" : "${_addr}\(.*\)"` + + # Identify type {inet,inet6}. + case "${_addr}" in + *\.*\.*\.*) _type="inet" ;; + *:*) _type="inet6" ;; + *) warn "jail_extract_address: type not identified" + ;; + esac + + # Handle the special /netmask instead of /prefix or + # "netmask xxx" case for legacy IP. + # We do NOT support shortend class-full netmasks. + if [ "${_type}" = "inet" ]; then + case "${_mask}" in + /*\.*\.*\.*) _mask=" netmask ${_mask#/}" ;; + *) ;; + esac + + # In case _mask is still not set use /32. + _mask=${_mask:-/32} + + elif [ "${_type}" = "inet6" ]; then + # In case _mask is not set for IPv6, use /128. + _mask=${_mask:-/128} + fi +} + +# jail_handle_ips_option input iface +# Handle a single argument imput which can be a comma separated +# list of addresses (theoretically with an option interface and +# prefix/netmask/prefixlen). +# +jail_handle_ips_option() +{ + local _x _type _i _defif + _x=$1 + _defif=$2 + + if [ -z "${_x}" ]; then + # No IP given. This can happen for the primary address + # of each address family. + return + fi + + # Loop, in case we find a comma separated list, we need to handle + # each argument on its own. + while [ ${#_x} -gt 0 ]; do + case "${_x}" in + *,*) # Extract the first argument and strip it off the list. + _i=`expr -- "${_x}" : '^\([^,]*\)'` + _x=`expr -- "${_x}" : "^[^,]*,\(.*\)"` + ;; + *) _i=${_x} + _x="" + ;; + esac + + _type="" + _addr="" + _mask="" + _iface="" + jail_extract_address $_i $_defif + + # make sure we got an address. + case $_addr in + "") continue ;; + *) ;; + esac + + # Append address to list of addresses for the jail command. + case $_type in + inet) + echo " ip4.addr += \"${_iface:+${_iface}|}${_addr}${_mask}\";" + ;; + inet6) + echo " ip6.addr += \"${_iface:+${_iface}|}${_addr}${_mask}\";" + need_dad_wait=1 + ;; + esac + done +} + +jail_config() +{ + local _j _jv + + case $1 in + _ALL) return ;; + esac + for _j in $@; do + _j=$(echo $_j | tr /. _) + _jv=$(echo -n $_j | tr -c '[:alnum:]' _) + if parse_options $_j $_jv; then + echo "$_j: parameters are in $_conf." + fi + done +} + +jail_console() +{ + local _j _jv _cmd + + # One argument that is not _ALL. + case $#:$1 in + 0:*|1:_ALL) err 3 "Specify a jail name." ;; + 1:*) ;; + esac + _j=$(echo $1 | tr /. _) + _jv=$(echo -n $1 | tr -c '[:alnum:]' _) + shift + case $# in + 0) eval _cmd=\${jail_${_jv}_consolecmd:-$jail_consolecmd} ;; + *) _cmd=$@ ;; + esac + $jail_jexec $_j $_cmd +} + +jail_status() +{ + + $jail_jls -N +} + +jail_start() +{ + local _j _jv _jid _id _name + + if [ $# = 0 ]; then + return + fi + startmsg -n 'Starting jails:' + case $1 in + _ALL) + command=$jail_program + rc_flags=$jail_flags + command_args="-f $jail_conf -c" + if ! checkyesno jail_parallel_start; then + command_args="$command_args -p1" + fi + _tmp=`mktemp -t jail` || exit 3 + if $command $rc_flags $command_args >> $_tmp 2>&1; then + $jail_jls jid name | while read _id _name; do + startmsg -n " $_name" + echo $_id > /var/run/jail_${_name}.id + done + else + cat $_tmp + fi + rm -f $_tmp + startmsg '.' + return + ;; + esac + if checkyesno jail_parallel_start; then + # + # Start jails in parallel and then check jail id when + # jail_parallel_start is YES. + # + for _j in $@; do + _j=$(echo $_j | tr /. _) + _jv=$(echo -n $_j | tr -c '[:alnum:]' _) + parse_options $_j $_jv || continue + + eval rc_flags=\${jail_${_jv}_flags:-$jail_flags} + eval command=\${jail_${_jv}_program:-$jail_program} + command_args="-i -f $_conf -c $_j" + ( + _tmp=`mktemp -t jail_${_j}` || exit 3 + if $command $rc_flags $command_args \ + >> $_tmp 2>&1 </dev/null; then + startmsg -n " ${_hostname:-${_j}}" + _jid=$($jail_jls -j $_j jid) + echo $_jid > /var/run/jail_${_j}.id + else + startmsg " cannot start jail " \ + "\"${_hostname:-${_j}}\": " + cat $_tmp + fi + rm -f $_tmp + ) & + done + wait + else + # + # Start jails one-by-one when jail_parallel_start is NO. + # + for _j in $@; do + _j=$(echo $_j | tr /. _) + _jv=$(echo -n $_j | tr -c '[:alnum:]' _) + parse_options $_j $_jv || continue + + eval rc_flags=\${jail_${_jv}_flags:-$jail_flags} + eval command=\${jail_${_jv}_program:-$jail_program} + command_args="-i -f $_conf -c $_j" + _tmp=`mktemp -t jail` || exit 3 + if $command $rc_flags $command_args \ + >> $_tmp 2>&1 </dev/null; then + startmsg -n " ${_hostname:-${_j}}" + _jid=$($jail_jls -j $_j jid) + echo $_jid > /var/run/jail_${_j}.id + else + startmsg " cannot start jail " \ + "\"${_hostname:-${_j}}\": " + cat $_tmp + fi + rm -f $_tmp + done + fi + startmsg '.' +} + +jail_stop() +{ + local _j _jv + + if [ $# = 0 ]; then + return + fi + echo -n 'Stopping jails:' + case $1 in + _ALL) + command=$jail_program + rc_flags=$jail_flags + command_args="-f $jail_conf -r" + if checkyesno jail_reverse_stop; then + $jail_jls name | tail -r + else + $jail_jls name + fi | while read _j; do + echo -n " $_j" + _tmp=`mktemp -t jail` || exit 3 + $command $rc_flags $command_args $_j >> $_tmp 2>&1 + if $jail_jls -j $_j > /dev/null 2>&1; then + cat $_tmp + else + rm -f /var/run/jail_${_j}.id + fi + rm -f $_tmp + done + echo '.' + return + ;; + esac + checkyesno jail_reverse_stop && set -- $(reverse_list $@) + for _j in $@; do + _j=$(echo $_j | tr /. _) + _jv=$(echo -n $_j | tr -c '[:alnum:]' _) + parse_options $_j $_jv || continue + if ! $jail_jls -j $_j > /dev/null 2>&1; then + continue + fi + eval command=\${jail_${_jv}_program:-$jail_program} + echo -n " ${_hostname:-${_j}}" + _tmp=`mktemp -t jail` || exit 3 + $command -q -f $_conf -r $_j >> $_tmp 2>&1 + if $jail_jls -j $_j > /dev/null 2>&1; then + cat $_tmp + else + rm -f /var/run/jail_${_j}.id + fi + rm -f $_tmp + done + echo '.' +} + +jail_warn() +{ + + # To relieve confusion, show a warning message. + case $_confwarn in + 1) warn "Per-jail configuration via jail_* variables " \ + "is obsolete. Please consider migrating to $jail_conf." + ;; + esac +} + +load_rc_config $name + +# doesn't make sense to run in a svcj +jail_svcj="NO" + +case $# in +1) run_rc_command $@ ${jail_list:-_ALL} ;; +*) jail_reverse_stop="no" + run_rc_command $@ ;; +esac diff --git a/libexec/rc/rc.d/kadmind b/libexec/rc/rc.d/kadmind new file mode 100755 index 000000000000..0cee49630480 --- /dev/null +++ b/libexec/rc/rc.d/kadmind @@ -0,0 +1,24 @@ +#!/bin/sh +# +# + +# PROVIDE: kadmind +# REQUIRE: kdc +# KEYWORD: shutdown + +. /etc/rc.subr + +name=kadmind +desc="Server for administrative access to Kerberos database" +rcvar=${name}_enable +required_vars=kdc_enable +command_args="$command_args &" + +: ${kadmind_svcj_options:="net_basic"} + +set_rcvar_obsolete kadmind5_server_enable kadmind_enable +set_rcvar_obsolete kadmind5_server kadmind_program +set_rcvar_obsolete kerberos5_server_enable kdc_enable + +load_rc_config $name +run_rc_command "$1" diff --git a/libexec/rc/rc.d/kdc b/libexec/rc/rc.d/kdc new file mode 100755 index 000000000000..204b08f1e99c --- /dev/null +++ b/libexec/rc/rc.d/kdc @@ -0,0 +1,67 @@ +#!/bin/sh +# +# + +# PROVIDE: kdc +# REQUIRE: NETWORKING +# BEFORE: SERVERS +# KEYWORD: shutdown + +. /etc/rc.subr + +name=kdc +desc="Kerberos 5 server" +rcvar=${name}_enable +: ${kdc_restart:="NO"} +: ${kdc_restart_delay:=""} +: ${kdc_svcj_options:="net_basic"} + +set_rcvar_obsolete kerberos5_server_enable kdc_enable +set_rcvar_obsolete kerberos5_server kdc_program +set_rcvar_obsolete kerberos5_server_flags kdc_flags + +default_kdc_programs='/usr/libexec/kdc /usr/libexec/kdc /usr/libexec/krb5kdc /usr/local/sbin/krb5kdc' + +load_rc_config $name + +# XXX Remove the following block of code when Heimdal is removed +if [ -z "${kdc_program}" ]; then + for i in ${default_kdc_programs}; do + if [ -x "${i}" ]; then + kdc_program=${i} + break + fi + done +fi + +command="${kdc_program}" + +if [ "${kdc_program}" = /usr/libexec/kdc -o \ + "${kdc_program}" = /usr/local/libexec/kdc ]; then + detach="--detach" + flavor=heimdal +else + flavor=mit + unset detach +fi + +case ${kdc_restart} in +[Yy][Ee][Ss]) + if [ "$flavor" = mit ]; then + detach=-n + else + unset detach + fi + case ${kdc_restart_delay} in + "") unset daemon_restart_delay;; + *) daemon_restart_delay="-R ${kdc_restart_delay}";; + esac + command_args="-r ${daemon_restart_delay} ${kdc_program} ${detach} ${command_args}" + kdc_program=/usr/sbin/daemon + ;; +*) + command_args="${detach} ${command_args}" + ;; +esac + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/kfd b/libexec/rc/rc.d/kfd new file mode 100755 index 000000000000..23ad790abab5 --- /dev/null +++ b/libexec/rc/rc.d/kfd @@ -0,0 +1,19 @@ +#!/bin/sh +# +# + +# PROVIDE: kfd +# REQUIRE: NETWORKING +# KEYWORD: shutdown + +. /etc/rc.subr + +name=kfd +desc="Receive forwarded tickets" +rcvar=${name}_enable +command_args="$command_args -i &" + +: ${kfd_svcj_options:="net_basic"} + +load_rc_config $name +run_rc_command "$1" diff --git a/libexec/rc/rc.d/kld b/libexec/rc/rc.d/kld new file mode 100755 index 000000000000..37b14255abb9 --- /dev/null +++ b/libexec/rc/rc.d/kld @@ -0,0 +1,58 @@ +#!/bin/sh + +# Copyright (c) 2011 Douglas Barton +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# +# PROVIDE: kld +# REQUIRE: kldxref +# KEYWORD: nojail + +. /etc/rc.subr + +name="kld" +desc="Load kernel modules" + +start_cmd="${name}_start" +stop_cmd=':' + +kld_start() +{ + [ -n "$kld_list" ] || return + [ -z "$(kenv -q kld_disable 2>/dev/null)" ] || return + + local _kld + + echo 'Loading kernel modules:' $kld_list + for _kld in $kld_list ; do + load_kld -e ${_kld}.ko $_kld + done +} + +load_rc_config $name + +# doesn't make sense to run in a svcj +kld_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/kldxref b/libexec/rc/rc.d/kldxref new file mode 100755 index 000000000000..d6aa02d778d9 --- /dev/null +++ b/libexec/rc/rc.d/kldxref @@ -0,0 +1,40 @@ +#!/bin/sh +# +# + +# PROVIDE: kldxref +# REQUIRE: mountcritlocal +# BEFORE: netif +# KEYWORD: nojail + +. /etc/rc.subr + +rcvar="kldxref_enable" +name="kldxref" +desc="Generate hints for the kernel loader" +stop_cmd=":" +start_cmd="kldxref_start" + +kldxref_start() { + if [ -n "$kldxref_module_path" ]; then + MODULE_PATHS="$kldxref_module_path" + else + MODULE_PATHS=`sysctl -n kern.module_path` + fi + IFS=';' + for MODULE_DIR in $MODULE_PATHS; do + if checkyesno kldxref_clobber || + [ ! -f "$MODULE_DIR/linker.hints" ] && + [ `echo ${MODULE_DIR}/*.ko` != "${MODULE_DIR}/*.ko" ]; then + echo "Building $MODULE_DIR/linker.hints" + kldxref "$MODULE_DIR" + fi + done +} + +load_rc_config $name + +# doesn't make sense to run in a svcj +kldxref_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/kpasswdd b/libexec/rc/rc.d/kpasswdd new file mode 100755 index 000000000000..7e2562769640 --- /dev/null +++ b/libexec/rc/rc.d/kpasswdd @@ -0,0 +1,24 @@ +#!/bin/sh +# +# + +# PROVIDE: kpasswdd +# REQUIRE: kdc +# KEYWORD: shutdown + +. /etc/rc.subr + +name=kpasswdd +desc="Kerberos 5 password changing" +rcvar=${name}_enable +required_vars=kdc_enable +command_args="$command_args &" + +: ${kpasswdd_svcj_options:="net_basic"} + +set_rcvar_obsolete kpasswdd_server_enable kpasswdd_enable +set_rcvar_obsolete kpasswdd_server kpasswdd_program +set_rcvar_obsolete kerberos5_server_enable kdc_enable + +load_rc_config $name +run_rc_command "$1" diff --git a/libexec/rc/rc.d/ldconfig b/libexec/rc/rc.d/ldconfig new file mode 100755 index 000000000000..494228e96501 --- /dev/null +++ b/libexec/rc/rc.d/ldconfig @@ -0,0 +1,79 @@ +#!/bin/sh +# +# + +# PROVIDE: ldconfig +# REQUIRE: FILESYSTEMS +# BEFORE: DAEMON + +. /etc/rc.subr + +name="ldconfig" +desc="Configure the shared library cache" +ldconfig_command="/sbin/ldconfig" +start_cmd="ldconfig_start" +stop_cmd=":" + +ldconfig_paths() +{ + local _dirs _files _ii _ldpaths _paths + + _dirs="${1}" + _paths="${2}" + _ldpaths="${3}" + + for _ii in ${_dirs}; do + if [ -d "${_ii}" ]; then + _files=`find ${_ii} -type f` + if [ -n "${_files}" ]; then + _paths="${_paths} `cat ${_files} | sort -u`" + fi + fi + done + for _ii in ${_paths}; do + if [ -r "${_ii}" ]; then + _ldpaths="${_ldpaths} ${_ii}" + fi + done + + echo "${_ldpaths}" +} + +ldconfig_start() +{ + local _files _ins + + _ins= + ldconfig=${ldconfig_command} + checkyesno ldconfig_insecure && _ins="-i" + if [ -x "${ldconfig_command}" ]; then + _LDC=$(/libexec/ld-elf.so.1 -v | sed -n -e '/^Default lib path /s///p' | tr : ' ') + _LDC=$(ldconfig_paths "${ldconfig_local_dirs}" \ + "${ldconfig_paths} /etc/ld-elf.so.conf" "$_LDC") + startmsg 'ELF ldconfig path:' ${_LDC} + ${ldconfig} -elf ${_ins} ${_LDC} + + if check_kern_features compat_freebsd32; then + _LDC="" + if [ -x /libexec/ld-elf32.so.1 ]; then + for x in $(/libexec/ld-elf32.so.1 -v | sed -n -e '/^Default lib path /s///p' | tr : ' '); do + if [ -d "${x}" ]; then + _LDC="${_LDC} ${x}" + fi + done + fi + _LDC=$(ldconfig_paths "${ldconfig_local32_dirs}" \ + "${ldconfig32_paths}" "$_LDC") + startmsg '32-bit compatibility ldconfig path:' ${_LDC} + ${ldconfig} -32 ${_ins} ${_LDC} + fi + + fi +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +ldconfig_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/linux b/libexec/rc/rc.d/linux new file mode 100755 index 000000000000..d419920acaca --- /dev/null +++ b/libexec/rc/rc.d/linux @@ -0,0 +1,88 @@ +#!/bin/sh +# +# + +# PROVIDE: linux +# REQUIRE: kldxref zfs +# KEYWORD: nojail + +. /etc/rc.subr + +name="linux" +desc="Enable Linux ABI" +rcvar="linux_enable" +start_cmd="${name}_start" +stop_cmd=":" + +linux_mount() { + local _fs _mount_point + _fs="$1" + _mount_point="$2" + shift 2 + if ! mount | grep -q "^$_fs on $_mount_point ("; then + mkdir -p "$_mount_point" + mount "$@" -t "$_fs" "$_fs" "$_mount_point" + fi +} + +linux_start() +{ + local _emul_path _tmpdir + + case `sysctl -n hw.machine_arch` in + aarch64) + load_kld -e 'linux64elf' linux64 + ;; + amd64) + load_kld -e 'linuxelf' linux + load_kld -e 'linux64elf' linux64 + ;; + i386) + load_kld -e 'linuxelf' linux + ;; + esac + + _emul_path="$(sysctl -n compat.linux.emul_path)" + + if [ -x ${_emul_path}/sbin/ldconfigDisabled ]; then + _tmpdir=`mktemp -d -t linux-ldconfig` + ${_emul_path}/sbin/ldconfig -C ${_tmpdir}/ld.so.cache + if ! cmp -s ${_tmpdir}/ld.so.cache ${_emul_path}/etc/ld.so.cache; then + cat ${_tmpdir}/ld.so.cache > ${_emul_path}/etc/ld.so.cache + fi + rm -rf ${_tmpdir} + fi + + # Linux uses the pre-pts(4) tty naming scheme. + load_kld pty + + # Explicitly load the filesystem modules; they are usually required, + # even with linux_mounts_enable="NO". + load_kld fdescfs + load_kld linprocfs + load_kld linsysfs + + # Handle unbranded ELF executables by defaulting to ELFOSABI_LINUX. + if [ `sysctl -ni kern.elf64.fallback_brand` -eq "-1" ]; then + sysctl kern.elf64.fallback_brand=3 > /dev/null + fi + + if [ `sysctl -ni kern.elf32.fallback_brand` -eq "-1" ]; then + sysctl kern.elf32.fallback_brand=3 > /dev/null + fi + + if checkyesno linux_mounts_enable; then + linux_mount linprocfs "${_emul_path}/proc" -o nocover + linux_mount linsysfs "${_emul_path}/sys" -o nocover + linux_mount devfs "${_emul_path}/dev" -o nocover + linux_mount fdescfs "${_emul_path}/dev/fd" -o nocover,linrdlnk + linux_mount tmpfs "${_emul_path}/dev/shm" -o nocover,mode=1777 + fi +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: kernel modules and FS-mounting +linux_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/local b/libexec/rc/rc.d/local new file mode 100755 index 000000000000..c3f5e037563e --- /dev/null +++ b/libexec/rc/rc.d/local @@ -0,0 +1,40 @@ +#!/bin/sh +# +# + +# PROVIDE: local +# REQUIRE: DAEMON +# BEFORE: LOGIN +# KEYWORD: shutdown + +. /etc/rc.subr + +name="local" +desc="Run /etc/rc.local and /etc/rc.shutdown.local" +start_cmd="local_start" +stop_cmd="local_stop" + +local_start() +{ + if [ -f /etc/rc.local ]; then + startmsg -n 'Starting local daemons:' + . /etc/rc.local + startmsg '.' + fi +} + +local_stop() +{ + if [ -f /etc/rc.shutdown.local ]; then + echo -n 'Shutting down local daemons:' + . /etc/rc.shutdown.local + echo '.' + fi +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: it may contain everything +local_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/local_unbound b/libexec/rc/rc.d/local_unbound new file mode 100755 index 000000000000..94f01810b303 --- /dev/null +++ b/libexec/rc/rc.d/local_unbound @@ -0,0 +1,123 @@ +#!/bin/sh +# +# + +# PROVIDE: local_unbound +# REQUIRE: FILESYSTEMS defaultroute netwait resolv +# BEFORE: NETWORKING +# KEYWORD: shutdown + +. /etc/rc.subr + +name="local_unbound" +desc="Local caching forwarding resolver" +rcvar="local_unbound_enable" + +command="/usr/sbin/local-unbound" +extra_commands="anchor configtest reload setup" +start_precmd="local_unbound_prestart" +start_postcmd="local_unbound_poststart" +reload_precmd="local_unbound_configtest" +anchor_cmd="local_unbound_anchor" +configtest_cmd="local_unbound_configtest" +setup_cmd="local_unbound_setup" +pidfile="/var/run/${name}.pid" + +load_rc_config $name + +: ${local_unbound_workdir:=/var/unbound} +: ${local_unbound_config:=${local_unbound_workdir}/unbound.conf} +: ${local_unbound_flags:="-c ${local_unbound_config}"} +: ${local_unbound_forwardconf:=${local_unbound_workdir}/forward.conf} +: ${local_unbound_controlconf:=${local_unbound_workdir}/control.conf} +: ${local_unbound_anchor:=${local_unbound_workdir}/root.key} +: ${local_unbound_forwarders:=} +: ${local_unbound_tls:=} +: ${local_unbound_pidfile:=${pidfile}} +pidfile=${local_unbound_pidfile} +: ${local_unbound_svcj_options:="net_basic"} + +do_as_unbound() +{ + echo "$@" | su -m unbound +} + +# +# Retrieve or update the DNSSEC root anchor +# +local_unbound_anchor() +{ + do_as_unbound ${command}-anchor -a ${local_unbound_anchor} + # we can't trust the exit code - check if the file exists + [ -f ${local_unbound_anchor} ] +} + +# +# Check the unbound configuration file +# +local_unbound_configtest() +{ + do_as_unbound ${command}-checkconf ${local_unbound_config} +} + +# +# Create the unbound configuration file and update resolv.conf to +# point to unbound. +# +local_unbound_setup() +{ + local tls_flag + if checkyesno local_unbound_tls ; then + tls_flag="-t" + fi + echo "Performing initial setup." + ${command}-setup -n \ + -u unbound \ + -w ${local_unbound_workdir} \ + -c ${local_unbound_config} \ + -f ${local_unbound_forwardconf} \ + -o ${local_unbound_controlconf} \ + -a ${local_unbound_anchor} \ + ${tls_flag} \ + ${local_unbound_forwarders} +} + +# +# Before starting, check that the configuration file and root anchor +# exist. If not, attempt to generate them. +# +local_unbound_prestart() +{ + # Create configuration file + if [ ! -f ${local_unbound_config} ] ; then + run_rc_command setup + fi + + # Retrieve DNSSEC root key + if [ ! -s ${local_unbound_anchor} ] ; then + run_rc_command anchor + fi +} + +# +# After starting, wait for Unbound to report that it is ready to avoid +# race conditions with services which require functioning DNS. +# +local_unbound_poststart() +{ + local retry=5 + + echo -n "Waiting for nameserver to start..." + until "${command}-control" -c "${local_unbound_config}" status | grep -q "is running" ; do + if [ $((retry -= 1)) -eq 0 ] ; then + echo " giving up" + return 1 + fi + echo -n "." + sleep 1 + done + echo " good" +} + +load_rc_config $name +run_rc_command "$1" diff --git a/libexec/rc/rc.d/localpkg b/libexec/rc/rc.d/localpkg new file mode 100755 index 000000000000..12fb9e0fd927 --- /dev/null +++ b/libexec/rc/rc.d/localpkg @@ -0,0 +1,83 @@ +#!/bin/sh +# +# + +# PROVIDE: localpkg +# REQUIRE: sysvipc linux +# BEFORE: securelevel +# KEYWORD: shutdown + +. /etc/rc.subr + +name="localpkg" +desc="Run local init scripts" +start_cmd="pkg_start" +stop_cmd="pkg_stop" + +pkg_start() +{ + local initdone + + # For each dir in $local_startup, search for init scripts matching *.sh + # + case ${local_startup} in + [Nn][Oo] | '') + ;; + *) + initdone= + find_local_scripts_old + for script in ${zlist} ${slist}; do + if [ -z "${initdone}" -a -f "${script}" ]; then + echo -n 'Local package initialization:' + initdone=yes + fi + if [ -x "${script}" ]; then + (set -T + trap 'exit 1' 2 + ${script} start) + elif [ -f "${script}" -o -L "${script}" ]; then + echo -n " (skipping ${script}, not executable)" + fi + done + [ -n "${initdone}" ] && echo '.' + ;; + esac +} + +pkg_stop() +{ + local initdone + + case ${local_startup} in + [Nn][Oo] | '') + ;; + *) + initdone= + find_local_scripts_old + for script in `reverse_list ${slist} ${zlist}`; do + if [ -z "${initdone}" -a -f "${script}" ]; then + echo -n 'Shutting down local packages:' + initdone=yes + fi + if [ -x "${script}" ]; then + if [ `sysctl -n debug.bootverbose` -eq 1 ]; then + echo "==>" ${script} + fi + (set -T + trap 'exit 1' 2 + ${script} stop) + elif [ -f "${script}" -o -L "${script}" ]; then + echo -n " (skipping ${script##*/}, not executable)" + fi + done + [ -n "${initdone}" ] && echo '.' + ;; + esac +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: other rc.d scripts need to decide on their own +localpkg_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/lockd b/libexec/rc/rc.d/lockd new file mode 100755 index 000000000000..9c804751031a --- /dev/null +++ b/libexec/rc/rc.d/lockd @@ -0,0 +1,34 @@ +#!/bin/sh +# +# FreeBSD History: src/etc/rc.d/nfslocking,v 1.11 2004/10/07 13:55:26 mtm +# + +# PROVIDE: lockd +# REQUIRE: nfsclient rpcbind statd +# BEFORE: DAEMON +# KEYWORD: nojail shutdown + +. /etc/rc.subr + +name="lockd" +desc="NFS file locking daemon" +rcvar=rpc_lockd_enable +command="/usr/sbin/rpc.${name}" +start_precmd='lockd_precmd' + +: ${lockd_svcj_options:="net_basic"} + +# Make sure that we are either an NFS client or server, and that we get +# the correct flags from rc.conf(5). +# +lockd_precmd() +{ + force_depend rpcbind || return 1 + force_depend statd rpc_statd || return 1 +} + +load_rc_config $name + +rc_flags=${rpc_lockd_flags} + +run_rc_command $1 diff --git a/libexec/rc/rc.d/lpd b/libexec/rc/rc.d/lpd new file mode 100755 index 000000000000..0c169bef99a5 --- /dev/null +++ b/libexec/rc/rc.d/lpd @@ -0,0 +1,29 @@ +#!/bin/sh +# +# + +# PROVIDE: lpd +# REQUIRE: DAEMON +# BEFORE: LOGIN +# KEYWORD: shutdown + +. /etc/rc.subr + +name="lpd" +desc="Line printer spooler daemon" +rcvar="lpd_enable" +command="/usr/sbin/${name}" +required_files="/etc/printcap" +start_precmd="chkprintcap" + +: ${lpd_svcj_options:="net_basic"} + +chkprintcap() +{ + if checkyesno chkprintcap_enable ; then + /usr/sbin/chkprintcap ${chkprintcap_flags} + fi +} + +load_rc_config $name +run_rc_command "$1" diff --git a/libexec/rc/rc.d/mdconfig b/libexec/rc/rc.d/mdconfig new file mode 100755 index 000000000000..4df14017334b --- /dev/null +++ b/libexec/rc/rc.d/mdconfig @@ -0,0 +1,199 @@ +#!/bin/sh +# +# Copyright (c) 2006 The FreeBSD Project +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# + +# PROVIDE: mdconfig +# REQUIRE: swap root + +. /etc/rc.subr + +name="mdconfig" +desc="Create and control memory disks" +stop_cmd="mdconfig_stop" +start_cmd="mdconfig_start" +start_precmd='[ -n "${_mdconfig_list}" ]' +required_modules="geom_md:g_md" + +is_readonly() +{ + local _mp _ret + + _mp=$1 + _ret=`mount | while read _line; do + case ${_line} in + *" ${_mp} "*read-only*) + echo "yes" + ;; + + *) + ;; + esac; + done` + + if [ -n "${_ret}" ]; then + return 0 + else + return 1 + fi +} + +init_variables() +{ + local _i + + _fs="" + _mp="" + _dev="/dev/${_md}" + eval _config=\$mdconfig_${_md} + eval _newfs=\$mdconfig_${_md}_newfs + + _type=${_config##*-t\ } + _type=${_type%%\ *} + if [ -z "${_type}" ]; then + err 1 "You need to specify \"-t <type>\" in mdconfig_${_md}" + fi + + if [ "${_type}" = "vnode" ]; then + _file=${_config##*-f\ } + _file=${_file%%\ *} + if [ -z "${_file}" ]; then + err 2 "You need to specify \"-f <file>\" in mdconfig_${_md} for vnode devices" + fi + if [ "${_file}" != "${_file%.uzip}" ]; then + _dev="/dev/${_md}.uzip" + fi + for _i in `df ${_file} 2>/dev/null`; do _fs=${_i}; done + fi + + # Debugging help. + debug "${_md} config: ${_config}" + debug "${_md} type: ${_type}" + debug "${_md} dev: ${_dev}" + debug "${_md} file: ${_file}" + debug "${_md} fs: ${_fs}" + debug "${_md} newfs flags: ${_newfs}" +} + +mdconfig_start() +{ + local _md _mp _config _type _dev _file _fs _newfs _fsck_cmd + + for _md in ${_mdconfig_list}; do + init_variables ${_md} + # Create md(4) devices of types swap, malloc and vnode if the + # file is on the root partition. + if [ "${_type}" != "vnode" -o "${_fs}" = "/" ]; then + if [ "${_type}" = "vnode" ]; then + if is_readonly ${_fs}; then + warn "${_fs} is mounted read-only, skipping ${_md}." + continue + fi + if [ "${_file}" != "${_file%.uzip}" ]; then + load_kld -m g_uzip geom_uzip || return 3 + # sleep a bit to allow creation of /dev/mdX.uzip + sleep 2 + fi + fi + if mdconfig -l -u ${_md} >/dev/null 2>&1; then + err 3 "${_md} already exists" + fi + echo "Creating ${_md} device (${_type})." + if ! mdconfig -a ${_config} -u ${_md}; then + echo "Creating ${_md} device failed, moving on." + continue + fi + # Skip fsck for uzip devices. + if [ "${_type}" = "vnode" ]; then + if [ "${_file}" != "${_file%.uzip}" ]; then + _fsck_cmd=":" + elif checkyesno background_fsck; then + _fsck_cmd="fsck -F" + else + _fsck_cmd="fsck" + fi + if ! eval ${_fsck_cmd} -p ${_dev} >/dev/null; then + echo "Fsck failed on ${_dev}, not mounting the filesystem." + continue + + fi + else + newfs ${_newfs} ${_dev} >/dev/null + fi + if mount -d ${_dev} 2>&1 >/dev/null; then + echo "Mounting ${_dev}." + mount ${_dev} + fi + fi + done +} + +mdconfig_stop() +{ + local _md _mp _config _type _dev _file _fs _newfs _i + + for _md in ${_mdconfig_list}; do + init_variables ${_md} + if [ "${_type}" != "vnode" -o "${_fs}" = "/" ]; then + for _i in `df ${_dev} 2>/dev/null`; do _mp=${_i}; done + if [ -z "${_mp}" -o "${_mp}" != "${_mp%%%}" ]; then + echo "Device ${_dev} isn't mounted." + else + echo "Umounting ${_dev}." + umount ${_dev} + fi + if mdconfig -l -u ${_md} >/dev/null 2>&1; then + echo "Destroying ${_md}." + mdconfig -d -u ${_md} + fi + fi + done +} + +_mdconfig_cmd="$1" +if [ $# -gt 0 ]; then + shift +fi +[ -n "$*" ] && _mdconfig_list="$*" + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +mdconfig_svcj="NO" + +if [ -z "${_mdconfig_list}" ]; then + for _mdconfig_config in `list_vars mdconfig_md[0-9]\* | + sort_lite -nk1.12` + do + _mdconfig_unit=${_mdconfig_config#mdconfig_md} + [ "${_mdconfig_unit#*[!0-9]}" = "$_mdconfig_unit" ] || + continue + _mdconfig_list="$_mdconfig_list md$_mdconfig_unit" + done + _mdconfig_list="${_mdconfig_list# }" +fi + +run_rc_command "${_mdconfig_cmd}" diff --git a/libexec/rc/rc.d/mdconfig2 b/libexec/rc/rc.d/mdconfig2 new file mode 100755 index 000000000000..716e71cd2a32 --- /dev/null +++ b/libexec/rc/rc.d/mdconfig2 @@ -0,0 +1,229 @@ +#!/bin/sh +# +# Copyright (c) 2006 The FreeBSD Project +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# + +# PROVIDE: mdconfig2 +# REQUIRE: mountcritremote +# BEFORE: SERVERS + +. /etc/rc.subr + +name="mdconfig2" +desc="Create and control memory disks" +stop_cmd="mdconfig2_stop" +start_cmd="mdconfig2_start" +start_precmd='[ -n "${_mdconfig2_list}" ]' +required_modules="geom_md:g_md" + +is_readonly() +{ + local _mp _ret + + _mp=$1 + _ret=`mount | while read _line; do + case ${_line} in + *" ${_mp} "*read-only*) + echo "yes" + ;; + + *) + ;; + esac; + done` + + if [ -n "${_ret}" ]; then + return 0 + else + return 1 + fi +} + +init_variables() +{ + local _i + + _fs="" + _mp="" + _mounted="no" + _dev="/dev/${_md}" + eval _config=\$mdconfig_${_md} + eval _owner=\$mdconfig_${_md}_owner + eval _perms=\$mdconfig_${_md}_perms + eval _files=\$mdconfig_${_md}_files + eval _populate=\$mdconfig_${_md}_cmd + + _type=${_config##*-t\ } + _type=${_type%%\ *} + if [ -z "${_type}" ]; then + err 1 "You need to specify \"-t <type>\" in mdconfig_${_md}" + fi + + if [ "${_type}" = "vnode" ]; then + _file=${_config##*-f\ } + _file=${_file%%\ *} + if [ -z "${_file}" ]; then + err 2 "You need to specify \"-f <file>\" in mdconfig_${_md} for vnode devices" + fi + + if [ "${_file}" != "${_file%.uzip}" ]; then + _dev="/dev/${_md}.uzip" + fi + for _i in `df ${_file} 2>/dev/null`; do _fs=${_i}; done + fi + + # Debugging help. + debug "${_md} config: ${_config}" + debug "${_md} type: ${_type}" + debug "${_md} dev: ${_dev}" + debug "${_md} file: ${_file}" + debug "${_md} fs: ${_fs}" + debug "${_md} owner: ${_owner}" + debug "${_md} perms: ${_perms}" + debug "${_md} files: ${_files}" + debug "${_md} populate cmd: ${_populate}" +} + +mdconfig2_start() +{ + local _md _fs _mp _mounted _dev _config _type _file _owner _perms _files _populate _fsck_cmd _i + + for _md in ${_mdconfig2_list}; do + init_variables ${_md} + if [ ! -r ${_file} ]; then + err 3 "${_file} doesn't exist" + continue + fi + # First pass: create md(4) vnode devices from files stored on + # non-root partition. Swap and malloc md(4) devices have already + # been created. + if [ "${_type}" = "vnode" -a "${_fs}" != "/" ]; then + if [ "${_file}" != "${_file%.uzip}" ]; then + load_kld -m g_uzip geom_uzip || return 3 + fi + if is_readonly ${_fs}; then + warn "${_fs} is mounted read-only, skipping ${_md}." + continue + fi + if mdconfig -l -u ${_md} >/dev/null 2>&1; then + err 3 "${_md} already exists" + fi + echo "Creating ${_md} device (${_type})." + if ! mdconfig -a ${_config} -u ${_md}; then + echo "Creating ${_md} device failed, moving on." + continue + fi + # Skip fsck for uzip devices. + if [ "${_file}" != "${_file%.uzip}" ]; then + _fsck_cmd=":" + elif checkyesno background_fsck; then + _fsck_cmd="fsck -F" + else + _fsck_cmd="fsck" + fi + if ! eval ${_fsck_cmd} -p ${_dev} >/dev/null; then + echo "Fsck failed on ${_dev}, not mounting the filesystem." + continue + fi + if mount -d ${_dev} >/dev/null 2>&1; then + echo "Mounting ${_dev}." + mount ${_dev} + fi + fi + + for _i in `df ${_dev} 2>/dev/null`; do _mp=${_i}; done + if [ ! -z "${_mp}" -a "${_mp}" = "${_mp%%%}" ]; then + _mounted="yes" + fi + + if checkyesno _mounted; then + # Second pass: change permissions and ownership. + [ -z "${_owner}" ] || chown -f ${_owner} ${_dev} ${_mp} + [ -z "${_perms}" ] || chmod -f ${_perms} ${_dev} ${_mp} + + # Third pass: populate with foreign files. + if [ -n "${_files}" -o -n "${_populate}" ]; then + echo "Populating ${_dev}." + fi + if [ -n "${_files}" ]; then + cp -Rp ${_files} ${_mp} + fi + if [ -n "${_populate}" ]; then + eval ${_populate} + fi + fi + done +} + +mdconfig2_stop() +{ + local _md _fs _mp _mounted _dev _config _type _file _owner _perms _files _populate + + for _md in ${_mdconfig2_list}; do + init_variables ${_md} + if [ "${_type}" = "vnode" ]; then + for i in `df ${_dev} 2>/dev/null`; do _mp=$i; done + if [ ! -r "${_file}" -o "${_fs}" = "/" ]; then + continue + fi + if [ -z "${_mp}" -o "${_mp}" != "${_mp%%%}" ]; then + echo "Device ${_dev} isn't mounted." + else + echo "Umounting ${_dev}." + umount ${_dev} + fi + if mdconfig -l -u ${_md} >/dev/null 2>&1; then + echo "Destroying ${_md}." + mdconfig -d -u ${_md} + fi + fi + done +} + +_mdconfig2_cmd="$1" +if [ $# -gt 0 ]; then + shift +fi +[ -n "$*" ] && _mdconfig2_list="$*" + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +mdconfig2_svcj="NO" + +if [ -z "${_mdconfig2_list}" ]; then + for _mdconfig2_config in `list_vars mdconfig_md[0-9]\* | + sort_lite -nk1.12` + do + _mdconfig2_unit=${_mdconfig2_config#mdconfig_md} + [ "${_mdconfig2_unit#*[!0-9]}" = "$_mdconfig2_unit" ] || + continue + _mdconfig2_list="$_mdconfig2_list md$_mdconfig2_unit" + done + _mdconfig2_list="${_mdconfig2_list# }" +fi + +run_rc_command "${_mdconfig2_cmd}" diff --git a/libexec/rc/rc.d/mixer b/libexec/rc/rc.d/mixer new file mode 100755 index 000000000000..7527e16918d2 --- /dev/null +++ b/libexec/rc/rc.d/mixer @@ -0,0 +1,107 @@ +#!/bin/sh - +# +# Copyright (c) 2004 The FreeBSD Project +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# + +# PROVIDE: mixer +# REQUIRE: FILESYSTEMS +# KEYWORD: nojail shutdown + +. /etc/rc.subr + +name="mixer" +desc="Save and restore soundcard mixer values" +rcvar="mixer_enable" +stop_cmd="mixer_stop" +start_cmd="mixer_start" +reload_cmd="mixer_start" +extra_commands="reload" + +# +# List current mixer devices to stdout. +# +list_mixers() +{ + ( cd /dev ; ls mixer* 2>/dev/null ) +} + +# +# Save state of an individual mixer specified as $1 +# +mixer_save() +{ + local dev + + dev="/dev/${1}" + if [ -r ${dev} ]; then + /usr/sbin/mixer -f ${dev} -o > /var/db/${1}-state 2>/dev/null + fi +} + +# +# Restore the state of an individual mixer specified as $1 +# +mixer_restore() +{ + local file dev + + dev="/dev/${1}" + file="/var/db/${1}-state" + if [ -r ${dev} -a -r ${file} ]; then + /usr/sbin/mixer -f ${dev} `cat ${file}` > /dev/null + fi +} + +# +# Restore state of all mixers +# +mixer_start() +{ + local mixer + + for mixer in `list_mixers`; do + mixer_restore ${mixer} + done +} + +# +# Save the state of all mixers +# +mixer_stop() +{ + local mixer + + for mixer in `list_mixers`; do + mixer_save ${mixer} + done +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +mixer_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/motd b/libexec/rc/rc.d/motd new file mode 100755 index 000000000000..7858aef2c3fe --- /dev/null +++ b/libexec/rc/rc.d/motd @@ -0,0 +1,62 @@ +#!/bin/sh +# +# + +# PROVIDE: motd +# REQUIRE: mountcritremote FILESYSTEMS +# BEFORE: LOGIN + +. /etc/rc.subr + +name="motd" +desc="Update /var/run/motd" +rcvar="update_motd" +start_cmd="motd_start" +stop_cmd=":" + +COMPAT_MOTD="/etc/motd" +TARGET="/var/run/motd" +TEMPLATE="/etc/motd.template" +PERMS="644" + +motd_start() +{ + # Update kernel info in /var/run/motd + # Must be done *before* interactive logins are possible + # to prevent possible race conditions. + # + startmsg -n 'Updating motd:' + if [ ! -f "${TEMPLATE}" ]; then + # Create missing template from existing regular motd file, if + # one exists. + if [ -f "${COMPAT_MOTD}" ]; then + sed '1{/^FreeBSD.*/{d;};};' "${COMPAT_MOTD}" > "${TEMPLATE}" + chmod $PERMS "${TEMPLATE}" + rm -f "${COMPAT_MOTD}" + else + # Otherwise, create an empty template file. + install -c -o root -g wheel -m ${PERMS} /dev/null "${TEMPLATE}" + fi + fi + # Provide compatibility symlink: + if [ ! -h "${COMPAT_MOTD}" ]; then + ln -sF "${TARGET}" "${COMPAT_MOTD}" + fi + + T=`mktemp -t motd` + uname -v | sed -e 's,^\([^#]*\) #\(.* [1-2][0-9][0-9][0-9]\).*/\([^\]*\)$,\1 (\3) #\2,' \ + -e 's,^\([^ ]*\) \([^ ]*\) \([^ ]*\) \([^ ]*\)$,\1 \2 (\4) \3,' > ${T} + cat "${TEMPLATE}" >> ${T} + + install -C -o root -g wheel -m "${PERMS}" "$T" "${TARGET}" + rm -f "$T" + + startmsg '.' +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +motd_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/mountcritlocal b/libexec/rc/rc.d/mountcritlocal new file mode 100755 index 000000000000..5b80d4bfbb50 --- /dev/null +++ b/libexec/rc/rc.d/mountcritlocal @@ -0,0 +1,76 @@ +#!/bin/sh +# +# + +# PROVIDE: mountcritlocal +# REQUIRE: root hostid_save mdconfig +# KEYWORD: nojail shutdown + +. /etc/rc.subr + +name="mountcritlocal" +desc="Mount critical local filesystems" +start_cmd="mountcritlocal_start" +stop_cmd=sync + +mountcritlocal_start() +{ + local err holders waited + + # Set up the list of network filesystem types for which mounting + # should be delayed until after network initialization. + case ${extra_netfs_types} in + [Nn][Oo]) + ;; + *) + netfs_types="${netfs_types} ${extra_netfs_types}" + ;; + esac + + while read a b vfstype rest; do + if [ "$vfstype" = "zfs" -a "${a#\#}" = "$a" ]; then + # zpool is needed for legacy ZFS + echo 'Importing zpools for legacy ZFS' + /etc/rc.d/zpool start + break + fi + done < /etc/fstab + + # Mount everything except nfs filesystems. + startmsg -n 'Mounting local filesystems:' + mount_excludes='no' + for i in ${netfs_types}; do + fstype=${i%:*} + mount_excludes="${mount_excludes}${fstype}," + done + mount_excludes=${mount_excludes%,} + + mount -a -t ${mount_excludes} + err=$? + if [ ${err} -ne 0 ]; then + echo 'Mounting /etc/fstab filesystems failed,' \ + 'will retry after root mount hold release' + root_hold_wait + mount -a -t ${mount_excludes} + err=$? + fi + + startmsg '.' + + case ${err} in + 0) + ;; + *) + echo 'Mounting /etc/fstab filesystems failed,' \ + 'startup aborted' + stop_boot true + ;; + esac +} + +load_rc_config $name + +# mounting shall not be performed in a svcj +mountcritlocal_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/mountcritremote b/libexec/rc/rc.d/mountcritremote new file mode 100755 index 000000000000..99becaefb10f --- /dev/null +++ b/libexec/rc/rc.d/mountcritremote @@ -0,0 +1,93 @@ +#!/bin/sh +# +# + +# PROVIDE: mountcritremote +# REQUIRE: NETWORKING FILESYSTEMS ipsec netwait nfscbd +# KEYWORD: nojail + +. /etc/rc.subr + +name="mountcritremote" +desc="Mount critical remote filesystems" +stop_cmd=":" +start_cmd="mountcritremote_start" +start_precmd="mountcritremote_precmd" + +# Mount NFS filesystems if present in /etc/fstab +# +# XXX When the vfsload() issues with nfsclient support and related sysctls +# have been resolved, this block can be removed, and the condition that +# skips nfs in the following block (for "other network filesystems") can +# be removed. +# +mountcritremote_precmd() +{ + case "`mount -d -a -t nfs 2> /dev/null`" in + *mount_nfs*) + # Handle absent nfs client support + load_kld -m nfs nfscl || return 1 + ;; + esac + return 0 +} + +mountcritremote_start() +{ + local mounted_remote_filesystem=false + + # Mount nfs filesystems. + # + case "`/sbin/mount -d -a -t nfs`" in + '') + ;; + *) + mounted_remote_filesystem=true + echo -n 'Mounting NFS filesystems:' + mount -a -t nfs + echo '.' + ;; + esac + + # Mount other network filesystems if present in /etc/fstab. + case ${extra_netfs_types} in + [Nn][Oo]) + ;; + *) + netfs_types="${netfs_types} ${extra_netfs_types}" + ;; + esac + + for i in ${netfs_types}; do + fstype=${i%:*} + fsdecr=${i#*:} + + [ "${fstype}" = "nfs" ] && continue + + case "`mount -d -a -t ${fstype}`" in + *mount_${fstype}*) + mounted_remote_filesystem=true + echo -n "Mounting ${fsdecr} filesystems:" + mount -a -t ${fstype} + echo '.' + ;; + esac + done + + if $mounted_remote_filesystem; then + # Cleanup /var again just in case it's a network mount. + /etc/rc.d/cleanvar quietreload + rm -f /var/run/clean_var /var/spool/lock/clean_var + + # Regenerate the ldconfig hints in case there are additional + # library paths on remote file systems + /etc/rc.d/ldconfig quietstart + fi +} + +load_rc_config $name + +# mounting shall not be performed in a svcj +mountcritremote_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/mountd b/libexec/rc/rc.d/mountd new file mode 100755 index 000000000000..dfd2431f9c35 --- /dev/null +++ b/libexec/rc/rc.d/mountd @@ -0,0 +1,79 @@ +#!/bin/sh +# +# + +# PROVIDE: mountd +# REQUIRE: NETWORKING rpcbind quota mountlate +# KEYWORD: nojailvnet shutdown + +. /etc/rc.subr + +name="mountd" +desc="Service remote NFS mount requests" +rcvar="mountd_enable" +command="/usr/sbin/${name}" +pidfile="/var/run/${name}.pid" +required_files="/etc/exports" +start_precmd="mountd_precmd" +extra_commands="reload" + +: ${mountd_svcj_options:="net_basic nfsd"} + +mountd_precmd() +{ + + # Load the modules now, so that the vfs.nfsd sysctl + # oids are available. + load_kld nfsd || return 1 + + # Do not force rpcbind to be running for an NFSv4 only server. + # + if checkyesno nfsv4_server_only; then + echo 'NFSv4 only server' + sysctl vfs.nfsd.server_min_nfsvers=4 > /dev/null + sysctl vfs.nfsd.server_max_nfsvers=4 > /dev/null + rc_flags="${rc_flags} -R" + else + force_depend rpcbind || return 1 + if checkyesno nfsv4_server_enable; then + sysctl vfs.nfsd.server_max_nfsvers=4 > /dev/null + else + sysctl vfs.nfsd.server_max_nfsvers=3 > /dev/null + fi + fi + + # mountd flags will differ depending on rc.conf settings + # + if checkyesno nfs_server_enable || checkyesno nfsv4_server_only; then + if checkyesno weak_mountd_authentication; then + if checkyesno nfsv4_server_only; then + echo -n 'weak_mountd_authentication ' + echo -n 'incompatible with nfsv4_server_only, ' + echo 'ignored' + else + rc_flags="${rc_flags} -n" + fi + fi + else + if checkyesno mountd_enable; then + checkyesno weak_mountd_authentication && rc_flags="-n" + fi + fi + + if checkyesno zfs_enable; then + rc_flags="${rc_flags} /etc/exports /etc/zfs/exports" + fi + + rm -f /var/db/mountdtab + ( umask 022 ; > /var/db/mountdtab ) || + err 1 'Cannot create /var/db/mountdtab' +} + +load_rc_config $name +load_rc_config nfsd +load_rc_config zfs + +# precmd is not compatible with svcj +mountd_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/mountlate b/libexec/rc/rc.d/mountlate new file mode 100755 index 000000000000..87ea9edccb74 --- /dev/null +++ b/libexec/rc/rc.d/mountlate @@ -0,0 +1,51 @@ +#!/bin/sh +# +# + +# PROVIDE: mountlate +# REQUIRE: DAEMON +# BEFORE: LOGIN +# KEYWORD: nojail + +. /etc/rc.subr + +name="mountlate" +desc="Mount filesystems with \"late\" option from /etc/fstab" +start_cmd="mountlate_start" +stop_cmd=":" + +mountlate_start() +{ + local err latefs + + # Mount "late" filesystems. + # + err=0 + echo -n 'Mounting late filesystems:' + mount -a -L + err=$? + echo '.' + + case ${err} in + 0) + ;; + *) + echo 'Mounting /etc/fstab filesystems failed,' \ + 'startup aborted' + stop_boot true + ;; + esac + + # If we booted a special kernel remove the record + # so we will boot the default kernel next time. + if [ -x /sbin/nextboot ]; then + /sbin/nextboot -D + fi +} + +load_rc_config $name + +# mounting shall not be performed in a svcj +mountlate_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/moused b/libexec/rc/rc.d/moused new file mode 100755 index 000000000000..e267ae5b3cd8 --- /dev/null +++ b/libexec/rc/rc.d/moused @@ -0,0 +1,82 @@ +#!/bin/sh +# +# + +# PROVIDE: moused +# REQUIRE: DAEMON FILESYSTEMS +# KEYWORD: nojail shutdown + +. /etc/rc.subr + +name="moused" +desc="Mouse daemon" +rcvar="moused_enable" +command="/usr/sbin/${name}" +start_cmd="moused_start" +pidprefix="/var/run/moused" +pidfile="${pidprefix}.pid" +pidarg= +typearg= +load_rc_config $name + +# doesn't make sense to run in a svcj: nojail keyword +# XXX: How does moused communiacte with the kernel? +# XXX: Does the kernel prevent this communcation in jails? +moused_svcj="NO" + +# Set the pid file and variable name. The second argument, if it exists, is +# expected to be the mouse device. +# +if [ -n "$2" ]; then + ms=`basename $2` + eval moused_${ms}_enable=\${moused_${ms}_enable-${moused_nondefault_enable}} + rcvar="moused_${ms}_enable" + pidfile="${pidprefix}.${ms}.pid" + pidarg="-I $pidfile" +fi + +moused_start() +{ + local ms myflags myport mytype + + # Set the mouse device and get any related variables. If + # a moused device has been specified on the commandline, then + # rc.conf(5) variables defined for that device take precedence + # over the generic moused_* variables. The only exception is + # the moused_port variable, which if not defined sets it to the + # passed in device name. + # + if [ -n "$1" ]; then + ms=`basename $1` + eval myflags=\${moused_${ms}_flags-$moused_flags} + eval myport=\${moused_${ms}_port-/dev/$1} + eval mytype=\${moused_${ms}_type-$moused_type} + if [ -n "$mytype" ] && check_kern_features evdev_support; then + typearg="-t ${mytype}" + fi + else + ms="default" + myflags="$moused_flags" + myport="$moused_port" + fi + + startmsg -n "Starting ${ms} moused" + /usr/sbin/moused ${myflags} -p ${myport} ${typearg} ${pidarg} + startmsg '.' + + mousechar_arg= + case ${mousechar_start} in + [Nn][Oo] | '') + ;; + *) + mousechar_arg="-M ${mousechar_start}" + ;; + esac + + for ttyv in /dev/ttyv* ; do + [ "$ttyv" = '/dev/ttyv*' ] && break + vidcontrol < ${ttyv} ${mousechar_arg} -m on + done +} + +run_rc_command $* diff --git a/libexec/rc/rc.d/msconvd b/libexec/rc/rc.d/msconvd new file mode 100755 index 000000000000..c2a96bf2eb68 --- /dev/null +++ b/libexec/rc/rc.d/msconvd @@ -0,0 +1,61 @@ +#!/bin/sh +# +# + +# PROVIDE: msconvd +# REQUIRE: DAEMON FILESYSTEMS +# KEYWORD: nojail shutdown + +. /etc/rc.subr + +name="msconvd" +desc="Mouse protocol conversion daemon" +command="/usr/sbin/${name}" +start_cmd="msconvd_start" +pidprefix="/var/run/msconvd" +load_rc_config $name + +: ${msconvd_enable="NO"} +: ${msconvd_type="auto"} + +# doesn't make sense to run in a svcj: nojail keyword +# XXX: How does msconvd communiacte with the kernel? +# XXX: Does the kernel prevent this communcation in jails? +msconvd_svcj="NO" + +# Set the pid file and variable name. The second argument, if it exists, is +# expected to be the mouse device. +# +if [ -n "$2" ]; then + eval msconvd_$2_enable=\${msconvd_$2_enable-${msconvd_enable}} + rcvar="msconvd_$2_enable" + pidfile="${pidprefix}.$2.pid" +else + for ms in ${msconvd_ports}; do + /etc/rc.d/msconvd $1 ${ms} + done + exit 0 +fi + +msconvd_start() +{ + local ms myflags myport mytype + + # Set the mouse device and get any related variables. If + # a msconvd device has been specified on the commandline, then + # rc.conf(5) variables defined for that device take precedence + # over the generic msconvd_* variables. The only exception is + # the msconvd_port variable, which if not defined sets it to + # the passed in device name. + # + ms=$1 + eval myflags=\${msconvd_${ms}_flags-$msconvd_flags} + eval myport=\${msconvd_${ms}_port-/dev/${ms}} + eval mytype=\${msconvd_${ms}_type-$msconvd_type} + + startmsg -n "Starting ${ms} ${name}" + ${command} ${myflags} -p ${myport} -t ${mytype} -I ${pidfile} + startmsg '.' +} + +run_rc_command $* diff --git a/libexec/rc/rc.d/msgs b/libexec/rc/rc.d/msgs new file mode 100755 index 000000000000..424d545f884d --- /dev/null +++ b/libexec/rc/rc.d/msgs @@ -0,0 +1,29 @@ +#!/bin/sh +# +# + +# PROVIDE: msgs +# REQUIRE: LOGIN + +. /etc/rc.subr + +name="msgs" +desc="Make a bounds file for msgs(1)" +start_cmd="msgs_start" +stop_cmd=":" + +msgs_start() +{ + # Make a bounds file for msgs(1) if there isn't one already + # + if [ -d /var/msgs -a ! -f /var/msgs/bounds -a ! -L /var/msgs/bounds ]; then + echo 0 > /var/msgs/bounds + fi +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +msgs_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/natd b/libexec/rc/rc.d/natd new file mode 100755 index 000000000000..1c8c1cb50a96 --- /dev/null +++ b/libexec/rc/rc.d/natd @@ -0,0 +1,47 @@ +#!/bin/sh +# +# + +# PROVIDE: natd +# KEYWORD: nostart nojailvnet + +. /etc/rc.subr +. /etc/network.subr + +name="natd" +desc="Network Address Translation daemon" +rcvar="natd_enable" +command="/sbin/${name}" +pidfile="/var/run/${name}.pid" +start_precmd="natd_precmd" +required_modules="ipdivert" + +natd_precmd() +{ + if [ -n "${natd_interface}" ]; then + dhcp_list="`list_net_interfaces dhcp`" + for ifn in ${dhcp_list}; do + case "${natd_interface}" in + ${ifn}) + rc_flags="$rc_flags -dynamic" + ;; + esac + done + + if echo "${natd_interface}" | \ + grep -q -E '^[0-9]+(\.[0-9]+){0,3}$'; then + rc_flags="$rc_flags -a ${natd_interface}" + else + rc_flags="$rc_flags -n ${natd_interface}" + fi + fi + + return 0 +} + +load_rc_config $name + +# precmd is not compatible with svcj +natd_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/netif b/libexec/rc/rc.d/netif new file mode 100755 index 000000000000..8c033acaf828 --- /dev/null +++ b/libexec/rc/rc.d/netif @@ -0,0 +1,275 @@ +#!/bin/sh +# +# Copyright (c) 2003 The FreeBSD Project. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE PROJECT ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE PROJECT BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# + +# PROVIDE: netif +# REQUIRE: FILESYSTEMS iovctl serial sysctl +# REQUIRE: hostid +# KEYWORD: nojailvnet + +. /etc/rc.subr +. /etc/network.subr + +name="netif" +desc="Network interface setup" +rcvar="${name}_enable" +start_cmd="netif_start" +stop_cmd="netif_stop" +wlanup_cmd="wlan_up" +wlandown_cmd="wlan_down" +cloneup_cmd="clone_up" +clonedown_cmd="clone_down" +clear_cmd="doclear" +vnetup_cmd="vnet_up" +vnetdown_cmd="vnet_down" +extra_commands="cloneup clonedown clear vnetup vnetdown" +cmdifn= + +set_rcvar_obsolete ipv6_enable ipv6_activate_all_interfaces +set_rcvar_obsolete ipv6_prefer + +netif_start() +{ + local _if + + # Set the list of interfaces to work on. + # + cmdifn=$* + + if [ -z "$cmdifn" ]; then + # + # We're operating as a general network start routine. + # + + # disable SIGINT (Ctrl-c) when running at startup + trap : 2 + fi + + # Create IEEE802.11 interface + wlan_up $cmdifn + + # Create cloned interfaces + clone_up $cmdifn + + # Rename interfaces. + ifnet_rename $cmdifn + + # Configure the interface(s). + netif_common ifn_start $cmdifn + + if [ -f /etc/rc.d/ipfilter ] ; then + # Resync ipfilter + /etc/rc.d/ipfilter quietresync + fi + if [ -f /etc/rc.d/bridge -a -n "$cmdifn" ] ; then + /etc/rc.d/bridge start $cmdifn + fi + if [ -f /etc/rc.d/routing -a -n "$cmdifn" ] ; then + for _if in $cmdifn; do + /etc/rc.d/routing static any $_if + done + fi +} + +netif_stop() +{ + _clone_down=1 + _wlan_down=1 + netif_stop0 $* +} + +doclear() +{ + _clone_down= + _wlan_down= + netif_stop0 $* +} + +netif_stop0() +{ + local _if + + # Set the list of interfaces to work on. + # + cmdifn=$* + + # Deconfigure the interface(s) + netif_common ifn_stop $cmdifn + + # Destroy wlan interfaces + if [ -n "$_wlan_down" ]; then + wlan_down $cmdifn + fi + + # Destroy cloned interfaces + if [ -n "$_clone_down" ]; then + clone_down $cmdifn + fi + + if [ -f /etc/rc.d/routing -a -n "$cmdifn" ] ; then + for _if in $cmdifn; do + /etc/rc.d/routing stop any $_if + done + fi +} + +vnet_up() +{ + cmdifn=$* + + netif_common ifn_vnetup $cmdifn +} + +vnet_down() +{ + cmdifn=$* + + netif_common ifn_vnetdown $cmdifn +} + +# netif_common routine +# Common configuration subroutine for network interfaces. This +# routine takes all the preparatory steps needed for configuring +# an interface and then calls $routine. +netif_common() +{ + local _cooked_list _tmp_list _fail _func _ok _str _cmdifn + + _func= + + if [ -z "$1" ]; then + err 1 "netif_common(): No function name specified." + else + _func="$1" + shift + fi + + # Set the scope of the command (all interfaces or just one). + # + _cooked_list= + _tmp_list= + _cmdifn=$* + if [ -n "$_cmdifn" ]; then + # Don't check that the interface(s) exist. We need to run + # the down code even when the interface doesn't exist to + # kill off wpa_supplicant. + # XXXBED: is this really true or does wpa_supplicant die? + # if so, we should get rid of the devd entry + _cooked_list="$_cmdifn" + else + _cooked_list="`list_net_interfaces`" + fi + + # Expand epair[0-9] to epair[0-9][ab]. + for ifn in $_cooked_list; do + case ${ifn#epair} in + [0-9]*[ab]) ;; # Skip epair[0-9]*[ab]. + [0-9]*) + for _str in $_cooked_list; do + case $_str in + $ifn) _tmp_list="$_tmp_list ${ifn}a ${ifn}b" ;; + *) _tmp_list="$_tmp_list ${ifn}" ;; + esac + done + _cooked_list=${_tmp_list# } + ;; + esac + done + + _dadwait= + _fail= + _ok= + for ifn in ${_cooked_list# }; do + # Skip if ifn does not exist. + case $_func in + ifn_stop) + if ! ${IFCONFIG_CMD} $ifn > /dev/null 2>&1; then + warn "$ifn does not exist. Skipped." + _fail="${_fail} ${ifn}" + continue + fi + ;; + esac + if ${_func} ${ifn} $2; then + _ok="${_ok} ${ifn}" + if ipv6if ${ifn} && [ "${ifn}" != "lo0" ]; then + _dadwait=1 + fi + else + _fail="${_fail} ${ifn}" + fi + done + + # inet6 address configuration needs sleep for DAD. + case ${_func}:${_dadwait} in + ifn_start:1|ifn_vnetup:1|ifn_vnetdown:1) + sleep `${SYSCTL_N} net.inet6.ip6.dad_count` + sleep 1 + ;; + esac + + _str= + if [ -n "${_ok}" ]; then + case ${_func} in + ifn_start) + _str='Starting' + ;; + ifn_stop) + _str='Stopping' + ;; + ifn_vnetup) + _str='Moving' + ;; + ifn_vnetdown) + _str='Reclaiming' + ;; + esac + startmsg "${_str} Network:${_ok}." + case ${_func} in + ifn_vnetup) + # Clear _ok not to do "ifconfig $ifn" + # because $ifn is no longer in the current vnet. + _ok= + ;; + esac + if check_startmsgs; then + for ifn in ${_ok}; do + /sbin/ifconfig ${ifn} + done + fi + fi + + debug "The following interfaces were not configured: $_fail" +} + +# Load the old "network" config file also for compatibility. +# This is needed for mfsBSD at least. +load_rc_config network +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +netif_svcj="NO" + +run_rc_command $* diff --git a/libexec/rc/rc.d/netoptions b/libexec/rc/rc.d/netoptions new file mode 100755 index 000000000000..0f329a5385cf --- /dev/null +++ b/libexec/rc/rc.d/netoptions @@ -0,0 +1,129 @@ +#!/bin/sh +# +# + +# PROVIDE: netoptions +# REQUIRE: FILESYSTEMS +# BEFORE: netif +# KEYWORD: nojailvnet + +. /etc/rc.subr +. /etc/network.subr + +name="netoptions" +desc="Network options setup" +start_cmd="netoptions_start" +stop_cmd=: + +_netoptions_initdone= +netoptions_init() +{ + if [ -z "${_netoptions_initdone}" ]; then + echo -n 'Additional TCP/IP options:' + _netoptions_initdone=yes + fi +} + +netoptions_start() +{ + local _af + + for _af in inet inet6; do + afexists ${_af} && eval netoptions_${_af} + done + [ -n "${_netoptions_initdone}" ] && echo '.' +} + +netoptions_inet() +{ + case ${log_in_vain} in + [12]) + netoptions_init + echo -n " log_in_vain=${log_in_vain}" + ${SYSCTL} net.inet.tcp.log_in_vain=${log_in_vain} >/dev/null + ${SYSCTL} net.inet.udp.log_in_vain=${log_in_vain} >/dev/null + ;; + *) + ${SYSCTL} net.inet.tcp.log_in_vain=0 >/dev/null + ${SYSCTL} net.inet.udp.log_in_vain=0 >/dev/null + ;; + esac + + if checkyesno tcp_extensions; then + ${SYSCTL} net.inet.tcp.rfc1323=1 >/dev/null + else + netoptions_init + echo -n " rfc1323 extensions=${tcp_extensions}" + ${SYSCTL} net.inet.tcp.rfc1323=0 >/dev/null + fi + + if checkyesno tcp_keepalive; then + ${SYSCTL} net.inet.tcp.always_keepalive=1 >/dev/null + else + netoptions_init + echo -n " TCP keepalive=${tcp_keepalive}" + ${SYSCTL} net.inet.tcp.always_keepalive=0 >/dev/null + fi + + if checkyesno tcp_drop_synfin; then + netoptions_init + echo -n " drop SYN+FIN packets=${tcp_drop_synfin}" + ${SYSCTL} net.inet.tcp.drop_synfin=1 >/dev/null + else + ${SYSCTL} net.inet.tcp.drop_synfin=0 >/dev/null + fi + + case ${ip_portrange_first} in + [0-9]*) + netoptions_init + echo -n " ip_portrange_first=$ip_portrange_first" + ${SYSCTL} net.inet.ip.portrange.first=$ip_portrange_first >/dev/null + ;; + esac + + case ${ip_portrange_last} in + [0-9]*) + netoptions_init + echo -n " ip_portrange_last=$ip_portrange_last" + ${SYSCTL} net.inet.ip.portrange.last=$ip_portrange_last >/dev/null + ;; + esac +} + +netoptions_inet6() +{ + if checkyesno ipv6_ipv4mapping; then + netoptions_init + echo -n " ipv4-mapped-ipv6=${ipv6_ipv4mapping}" + ${SYSCTL} net.inet6.ip6.v6only=0 >/dev/null + else + ${SYSCTL} net.inet6.ip6.v6only=1 >/dev/null + fi + + if checkyesno ipv6_privacy; then + netoptions_init + echo -n " IPv6 Privacy Addresses" + ${SYSCTL} net.inet6.ip6.use_tempaddr=1 >/dev/null + ${SYSCTL} net.inet6.ip6.prefer_tempaddr=1 >/dev/null + fi + + case $ipv6_cpe_wanif in + ""|[Nn][Oo]|[Nn][Oo][Nn][Ee]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0) + ${SYSCTL} net.inet6.ip6.no_radr=0 >/dev/null + ${SYSCTL} net.inet6.ip6.rfc6204w3=0 >/dev/null + ;; + *) + netoptions_init + echo -n " IPv6 CPE WANIF=${ipv6_cpe_wanif}" + ${SYSCTL} net.inet6.ip6.no_radr=1 >/dev/null + ${SYSCTL} net.inet6.ip6.rfc6204w3=1 >/dev/null + ;; + esac +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +netoptions_svcj="NO" + +run_rc_command $1 diff --git a/libexec/rc/rc.d/netwait b/libexec/rc/rc.d/netwait new file mode 100755 index 000000000000..05874552cf1c --- /dev/null +++ b/libexec/rc/rc.d/netwait @@ -0,0 +1,156 @@ +#!/bin/sh +# +# PROVIDE: netwait +# REQUIRE: devd ipfw pf routing +# +# The netwait script helps handle three situations: +# - Systems with USB or other late-attaching network hardware which +# is initialized by devd events. The script waits for all the +# interfaces named in the netwait_if list to appear. +# - Systems with IPv6 addresses, especially jails, where we need to +# wait for DAD to complete before starting daemons, as they will +# otherwise fail to bind to IN6ADDR_ANY. +# - Systems with statically-configured IP addresses in rc.conf(5). +# The IP addresses in the netwait_ip list are pinged. The script +# waits for any single IP in the list to respond to the ping. If your +# system uses DHCP, you should probably use synchronous_dhclient="YES" +# in your /etc/rc.conf instead of netwait_ip. +# Either or both of the wait lists can be used (at least one must be +# non-empty if netwait is enabled). + +. /etc/rc.subr + +name="netwait" +desc="Wait for network devices or the network being up" +rcvar="netwait_enable" + +start_cmd="${name}_start" +stop_cmd=":" + +netwait_start() +{ + local ip rc count output link wait_if got_if any_error + + if [ -z "${netwait_if}" ] && [ -z "${netwait_ip}" ] && + ! checkyesno netwait_dad ; then + err 1 "Nothing to wait for" + fi + + if ! [ "${netwait_if_timeout:=0}" -ge 1 ]; then + err 1 "netwait_if_timeout must be >= 1" + fi + if ! check_kern_features inet6; then + netwait_dad="NO" + elif ! [ "${netwait_dad_timeout:=0}" -ge 1 ]; then + netwait_dad_timeout=$(($(sysctl -n net.inet6.ip6.dad_count)+1)) + fi + if ! [ "${netwait_timeout:=0}" -ge 1 ]; then + err 1 "netwait_timeout must be >= 1" + fi + + any_error=false + + if [ -n "${netwait_if}" ]; then + for wait_if in ${netwait_if}; do + echo -n "Waiting for ${wait_if}" + link="" + got_if=false + count=1 + # Handle SIGINT (Ctrl-C); force abort of while loop + trap break SIGINT + while [ ${count} -le ${netwait_if_timeout} ]; do + if output=`/sbin/ifconfig ${wait_if} 2>/dev/null`; then + if ! ${got_if}; then + echo -n ", interface present" + got_if=true + fi + link=`expr "${output}" : '.*[[:blank:]]status: \(no carrier\)'` + if [ -z "${link}" ]; then + echo ', got link.' + break + fi + fi + sleep 1 + count=$((count+1)) + done + # Restore default SIGINT handler + trap - SIGINT + if ! ${got_if}; then + echo ", wait failed: interface never appeared." + any_error=true + elif [ -n "${link}" ]; then + echo ", wait failed: interface still has no link." + any_error=true + fi + done + fi + + if checkyesno netwait_dad; then + got_dad=false + # Handle SIGINT (Ctrl-C); force abort of while loop + trap break SIGINT + + echo -n "Waiting for DAD to complete" + count=1 + while [ ${count} -le ${netwait_dad_timeout} ]; do + if ! ifconfig | grep -q 'inet6.*tentative'; then + echo ', done.' + got_dad=true + break + fi + sleep 1 + count=$((count+1)) + done + + # Restore default SIGINT handler + trap - SIGINT + + if ! ${got_dad}; then + echo ', timed out.' + any_error=true + fi + fi + + if [ -n "${netwait_ip}" ]; then + got_ip=false + # Handle SIGINT (Ctrl-C); force abort of for loop + trap break SIGINT + + for ip in ${netwait_ip}; do + echo -n "Waiting for ${ip} to respond to ICMP ping" + + count=1 + while [ ${count} -le ${netwait_timeout} ]; do + /sbin/ping -t 1 -c 1 -o ${ip} >/dev/null 2>&1 + rc=$? + + if [ $rc -eq 0 ]; then + echo ', got response.' + got_ip=false + break 2 + fi + count=$((count+1)) + done + echo ', failed: No response from host.' + done + + # Restore default SIGINT handler + trap - SIGINT + + if ! ${got_ip}; then + any_error=true + fi + fi + + if ${any_error}; then + warn "Continuing with startup, but be aware you may not have " + warn "a fully functional networking layer at this point." + fi +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +netwait_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/newsyslog b/libexec/rc/rc.d/newsyslog new file mode 100755 index 000000000000..9b959bfabe85 --- /dev/null +++ b/libexec/rc/rc.d/newsyslog @@ -0,0 +1,30 @@ +#!/bin/sh +# +# + +# PROVIDE: newsyslog +# REQUIRE: FILESYSTEMS mountcritremote + +. /etc/rc.subr + +name="newsyslog" +desc="Logfile rotation" +rcvar="newsyslog_enable" +required_files="/etc/newsyslog.conf" +command="/usr/sbin/${name}" +start_cmd="newsyslog_start" +stop_cmd=":" + +newsyslog_start() +{ + startmsg -n 'Creating and/or trimming log files' + ${command} ${rc_flags} + startmsg '.' +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: needs to send signals outside the svcj +newsyslog_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/nfscbd b/libexec/rc/rc.d/nfscbd new file mode 100755 index 000000000000..450de46e0855 --- /dev/null +++ b/libexec/rc/rc.d/nfscbd @@ -0,0 +1,21 @@ +#!/bin/sh +# +# + +# PROVIDE: nfscbd +# REQUIRE: NETWORKING nfsuserd +# KEYWORD: nojail shutdown + +. /etc/rc.subr + +name="nfscbd" +desc="NFSv4 client side callback daemon" +rcvar="nfscbd_enable" +command="/usr/sbin/${name}" +sig_stop="USR1" + +: ${nfscbd_svcj_options:="net_basic"} + +load_rc_config $name + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/nfsclient b/libexec/rc/rc.d/nfsclient new file mode 100755 index 000000000000..857cfa02036f --- /dev/null +++ b/libexec/rc/rc.d/nfsclient @@ -0,0 +1,53 @@ +#!/bin/sh +# +# + +# PROVIDE: nfsclient +# REQUIRE: NETWORKING mountcritremote rpcbind +# KEYWORD: nojail shutdown + +. /etc/rc.subr + +name="nfsclient" +desc="NFS client setup" +rcvar="nfs_client_enable" +start_cmd="nfsclient_start" +stop_cmd="unmount_all" +required_modules="nfscl:nfs" + +nfsclient_start() +{ + # + # Set some nfs client related sysctls + # + + if [ -n "${nfs_access_cache}" ]; then + startmsg "NFS access cache time=${nfs_access_cache}" + if ! sysctl vfs.nfs.access_cache_timeout=${nfs_access_cache} >/dev/null; then + warn "failed to set access cache timeout" + fi + fi + if [ -n "${nfs_bufpackets}" ]; then + if ! sysctl vfs.nfs.bufpackets=${nfs_bufpackets} > /dev/null; then + warn "failed to set vfs.nfs.bufpackets" + fi + fi + + unmount_all +} + +unmount_all() +{ + # If /var/db/mounttab exists, some nfs-server has not been + # successfully notified about a previous client shutdown. + # If there is no /var/db/mounttab, we do nothing. + if [ -f /var/db/mounttab ]; then + rpc.umntall -k + fi +} +load_rc_config $name + +# no unmounting in svcj +nfsclient_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/nfsd b/libexec/rc/rc.d/nfsd new file mode 100755 index 000000000000..364c2a3b6bd3 --- /dev/null +++ b/libexec/rc/rc.d/nfsd @@ -0,0 +1,68 @@ +#!/bin/sh +# +# + +# PROVIDE: nfsd +# REQUIRE: mountcritremote mountd hostname gssd nfsuserd +# KEYWORD: nojailvnet shutdown + +. /etc/rc.subr + +name="nfsd" +desc="Remote NFS server" +rcvar="nfs_server_enable" +command="/usr/sbin/${name}" +nfs_server_vhost="" + +: ${nfsd_svcj_options:="net_basic nfsd"} + +load_rc_config $name +# precmd is not compatible with svcj +nfsd_svcj="NO" +start_precmd="nfsd_precmd" +sig_stop="USR1" + +nfsd_precmd() +{ + local _vhost + rc_flags="${nfs_server_flags}" + + # Load the modules now, so that the vfs.nfsd sysctl + # oids are available. + load_kld nfsd || return 1 + + if [ -n "${nfs_server_maxio}" ] && ! check_jail jailed; then + if ! sysctl vfs.nfsd.srvmaxio=${nfs_server_maxio} >/dev/null; then + warn "Failed to set server max I/O" + fi + fi + + if checkyesno nfs_reserved_port_only; then + echo 'NFS on reserved port only=YES' + sysctl vfs.nfsd.nfs_privport=1 > /dev/null + else + sysctl vfs.nfsd.nfs_privport=0 > /dev/null + fi + + if checkyesno nfs_server_managegids; then + force_depend nfsuserd || err 1 "Cannot run nfsuserd" + fi + + if checkyesno nfsv4_server_enable; then + sysctl vfs.nfsd.server_max_nfsvers=4 > /dev/null + elif ! checkyesno nfsv4_server_only; then + echo 'NFSv4 is disabled' + sysctl vfs.nfsd.server_max_nfsvers=3 > /dev/null + fi + + if ! checkyesno nfsv4_server_only; then + force_depend rpcbind || return 1 + fi + + force_depend mountd || return 1 + if [ -n "${nfs_server_vhost}" ]; then + command_args="-V \"${nfs_server_vhost}\"" + fi +} + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/nfsuserd b/libexec/rc/rc.d/nfsuserd new file mode 100755 index 000000000000..3ef88dcc6dfc --- /dev/null +++ b/libexec/rc/rc.d/nfsuserd @@ -0,0 +1,32 @@ +#!/bin/sh +# +# + +# PROVIDE: nfsuserd +# REQUIRE: NETWORKING +# KEYWORD: nojailvnet shutdown + +. /etc/rc.subr + +name="nfsuserd" +desc="Load user and group information into the kernel for NFSv4 services and support manage-gids for all NFS versions" +rcvar="nfsuserd_enable" +command="/usr/sbin/${name}" +sig_stop="USR1" + +: ${nfsuserd_svcj_options:="net_basic nfsd"} + +load_rc_config $name +# precmd is not compatible with svcj +nfsuserd_svcj="NO" +start_precmd="nfsuserd_precmd" + +nfsuserd_precmd() +{ + if checkyesno nfs_server_managegids; then + rc_flags="-manage-gids ${nfsuserd_flags}" + fi + return 0 +} + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/nisdomain b/libexec/rc/rc.d/nisdomain new file mode 100755 index 000000000000..9616d7be39ac --- /dev/null +++ b/libexec/rc/rc.d/nisdomain @@ -0,0 +1,58 @@ +#!/bin/sh +# +# Copyright (c) 1993 - 2003 The FreeBSD Project. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# + +# PROVIDE: nisdomain +# REQUIRE: SERVERS rpcbind +# BEFORE: ypset ypbind ypserv ypxfrd + +. /etc/rc.subr + +name="nisdomain" +desc="Set NIS domain name" +start_cmd="nisdomain_start" +stop_cmd=":" + +nisdomain_start() +{ + # Set the domainname if we're using NIS + # + case ${nisdomainname} in + [Nn][Oo]|'') + ;; + *) + domainname ${nisdomainname} + echo "Setting NIS domain: `/bin/domainname`." + ;; + esac +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +nisdomain_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/noshutdown b/libexec/rc/rc.d/noshutdown new file mode 100755 index 000000000000..54924310a6c7 --- /dev/null +++ b/libexec/rc/rc.d/noshutdown @@ -0,0 +1,31 @@ +#!/bin/sh +# +# + +# PROVIDE: noshutdown +# REQUIRE: var +# BEFORE: LOGIN + +. /etc/rc.subr + +name="noshutdown" +desc="Disable shutdown(8) for precious machines" +rcvar="precious_machine" +start_cmd="noshutdown_start" +stop_cmd="noshutdown_stop" + +: ${noshutdown_file:="/var/run/noshutdown"} + +noshutdown_start() +{ + touch $noshutdown_file +} + +noshutdown_stop() +{ + rm -f $noshutdown_file +} + +load_rc_config $name + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/nscd b/libexec/rc/rc.d/nscd new file mode 100755 index 000000000000..611d2d8ddb8f --- /dev/null +++ b/libexec/rc/rc.d/nscd @@ -0,0 +1,56 @@ +#!/bin/sh +# +# + +# PROVIDE: nscd +# REQUIRE: DAEMON +# BEFORE: LOGIN +# KEYWORD: shutdown + +# +# Add the following lines to /etc/rc.conf to enable nscd: +# +# nscd_enable="YES" +# +# See nscd(8) for flags +# + +. /etc/rc.subr + +name="nscd" +desc="Name-service caching daemon" +rcvar="nscd_enable" + +# no svcj options needed +: ${nscd_svcj_options:=""} + +command=/usr/sbin/nscd +extra_commands="flush" +flush_cmd="${command} -I all" + +# usage: _nscd_set_option <option name> <default value> +# +_nscd_set_option() { + local _optname _defoptval _nscd_opt_val _cached_opt_val + _optname=$1 + _defoptval=$2 + + _nscd_opt_val=$(eval "echo \$nscd_${_optname}") + _cached_opt_val=$(eval "echo \$cached_${_optname}") + + if [ -n "$_cached_opt_val" -a "$_nscd_opt_val" != "$_defoptval" ]; then + warn "You should use nscd_${_optname} instead of" \ + "cached_${_optname}" + setvar "nscd_${_optname}" "$_cached_opt_val" + else + setvar "nscd_${_optname}" "${_nscd_opt_val:-$_defoptval}" + fi +} + + +load_rc_config $name +_nscd_set_option "enable" "NO" +_nscd_set_option "pidfile" "/var/run/nscd.pid" +_nscd_set_option "flags" "" +run_rc_command "$1" + diff --git a/libexec/rc/rc.d/ntpd b/libexec/rc/rc.d/ntpd new file mode 100755 index 000000000000..e7e42da8acc7 --- /dev/null +++ b/libexec/rc/rc.d/ntpd @@ -0,0 +1,250 @@ +#!/bin/sh +# +# + +# PROVIDE: ntpd +# REQUIRE: DAEMON ntpdate FILESYSTEMS devfs +# BEFORE: LOGIN +# KEYWORD: nojail resume shutdown + +. /etc/rc.subr + +name="ntpd" +desc="Network Time Protocol daemon" +rcvar="ntpd_enable" +command="/usr/sbin/${name}" +extra_commands="fetch needfetch resume" +fetch_cmd="ntpd_fetch_leapfile" +needfetch_cmd="ntpd_needfetch_leapfile" +resume_cmd="ntpd_resume" +start_precmd="ntpd_precmd" + +_ntp_tmp_leapfile="/var/run/ntpd.leap-seconds.list" +_ntp_default_dir="/var/db/ntp" +_ntp_default_driftfile="${_ntp_default_dir}/ntpd.drift" +_ntp_old_driftfile="/var/db/ntpd.drift" + +pidfile="${_ntp_default_dir}/${name}.pid" + +load_rc_config $name + +# doesn't make sense to run in a svcj: nojail keyword +ntpd_svcj="NO" + +leapfile_is_disabled() { + # Return true (0) if automatic leapfile handling is disabled. + case "$ntp_db_leapfile" in + [Nn][Oo] | [Nn][Oo][Nn][Ee] ) + return 0;; + * ) + return 1;; + esac +} + +can_run_nonroot() +{ + # If the admin set what uid to use, we don't change it. + if [ -n "${ntpd_user}" ]; then + return 1 + fi + + # If the admin set any command line options involving files, we + # may not be able to access them as user ntpd. + case "${rc_flags}" in + *-f* | *--driftfile* | *-i* | *--jaildir* | \ + *-k* | *--keyfile* | *-l* | *--logfile* | \ + *-p* | *--pidfile* | *-s* | *--statsdir* ) + return 1;; + esac + + # If the admin set any options in ntp.conf involving files, + # we may not be able to access them as user ntpd. + local fileopts="^[ \t]*crypto|^[ \t]*driftfile|^[ \t]*key|^[ \t]*logfile|^[ \t]*statsdir" + grep -E -q "${fileopts}" "${ntpd_config}" && return 1 + + # Try to set up the MAC ntpd policy so ntpd can run with reduced + # privileges. Detect whether MAC is compiled into the kernel, load + # the policy module if not already present, then check whether the + # policy has been disabled via tunable or sysctl. + [ -n "$(sysctl -qn security.mac.version)" ] || return 1 + sysctl -qn security.mac.ntpd >/dev/null || kldload -qn mac_ntpd || return 1 + [ "$(sysctl -qn security.mac.ntpd.enabled)" == "1" ] || return 1 + + # On older existing systems, the ntp dir may by owned by root, change + # it to ntpd to give the daemon create/write access to the driftfile. + if [ "$(stat -f %u ${_ntp_default_dir})" = "0" ]; then + chown ntpd:ntpd "${_ntp_default_dir}" || return 1 + chmod 0755 "${_ntp_default_dir}" || return 1 + logger -s -t "rc.d/ntpd" -p daemon.notice \ + "${_ntp_default_dir} updated to owner ntpd:ntpd, mode 0755" + fi + + # If the driftfile exists in the standard location for older existing + # systems, move it into the ntp dir and fix the ownership if we can. + if [ -f "${_ntp_old_driftfile}" ] && [ ! -L "${_ntp_old_driftfile}" ]; then + mv "${_ntp_old_driftfile}" "${_ntp_default_driftfile}" && + chown ntpd:ntpd "${_ntp_default_driftfile}" || return 1 + logger -s -t "rc.d/ntpd" -p daemon.notice \ + "${_ntp_default_driftfile} updated to owner ntpd:ntpd" + logger -s -t "rc.d/ntpd" -p daemon.notice \ + "${_ntp_old_driftfile} moved to ${_ntp_default_driftfile}" + fi +} + +ntpd_precmd() +{ + local driftopt + + # If we can run as a non-root user, switch uid to ntpd and use the + # new default location for the driftfile inside the ntpd-owned dir. + # Otherwise, figure out what to do about the driftfile option. If set + # by the admin, we don't add the option. If the file exists in the old + # default location we use that, else we use the new default location. + if can_run_nonroot; then + _user="ntpd" + driftopt="-f ${_ntp_default_driftfile}" + elif grep -q "^[ \t]*driftfile" "${ntpd_config}" || + [ -n "${rc_flags}" ] && + ( [ -z "${rc_flags##*-f*}" ] || + [ -z "${rc_flags##*--driftfile*}" ] ); then + driftopt="" # admin set the option, we don't need to add it. + elif [ -f "${_ntp_old_driftfile}" ]; then + driftopt="-f ${_ntp_old_driftfile}" + else + driftopt="-f ${_ntp_default_driftfile}" + fi + + # Set command_args based on the various config vars. + command_args="-p ${pidfile} -c ${ntpd_config} ${driftopt}" + if checkyesno ntpd_sync_on_start; then + command_args="${command_args} -g" + fi + + # Make sure the leapfile is ready to use, unless leapfile + # handling is disabled. + if leapfile_is_disabled; then + return + fi + + ntpd_init_leapfile + if [ ! -f "${ntp_db_leapfile}" ]; then + ntpd_fetch_leapfile + fi +} + +current_ntp_ts() { + # Seconds between 1900-01-01 and 1970-01-01 + # echo $(((70*365+17)*86400)) + ntp_to_unix=2208988800 + + echo $(($(date -u +%s)+$ntp_to_unix)) +} + +get_ntp_leapfile_ver() { + # Leapfile update date (version number). + expr "$(awk '$1 == "#$" { print $2 }' "$1" 2>/dev/null)" : \ + '^\([1-9][0-9]*\)$' \| 0 +} + +get_ntp_leapfile_expiry() { + # Leapfile expiry date. + expr "$(awk '$1 == "#@" { print $2 }' "$1" 2>/dev/null)" : \ + '^\([1-9][0-9]*\)$' \| 0 +} + +ntpd_init_leapfile() { + + if leapfile_is_disabled; then + return + fi + + # Refresh working leapfile with an invalid hash due to + # FreeBSD id header. Ntpd will ignore leapfiles with a + # mismatch hash. The file must be the virgin file from + # the source. + if [ ! -f $ntp_db_leapfile ]; then + cp -p $ntp_src_leapfile $ntp_db_leapfile + fi +} + +ntpd_needfetch_leapfile() { + local rc verbose + + if leapfile_is_disabled; then + # Return code 1: ntp leapfile fetch not needed + return 1 + fi + + if checkyesno ntp_leapfile_fetch_verbose; then + verbose=echo + else + verbose=: + fi + + ntp_ver_no_src=$(get_ntp_leapfile_ver $ntp_src_leapfile) + ntp_expiry_src=$(get_ntp_leapfile_expiry $ntp_src_leapfile) + ntp_ver_no_db=$(get_ntp_leapfile_ver $ntp_db_leapfile) + ntp_expiry_db=$(get_ntp_leapfile_expiry $ntp_db_leapfile) + $verbose ntp_src_leapfile version is $ntp_ver_no_src expires $ntp_expiry_src + $verbose ntp_db_leapfile version is $ntp_ver_no_db expires $ntp_expiry_db + + if [ "$ntp_ver_no_src" -gt "$ntp_ver_no_db" -o \ + "$ntp_ver_no_src" -eq "$ntp_ver_no_db" -a \ + "$ntp_expiry_src" -gt "$ntp_expiry_db" ]; then + $verbose replacing $ntp_db_leapfile with $ntp_src_leapfile + cp -p $ntp_src_leapfile $ntp_db_leapfile + ntp_ver_no_db=$ntp_ver_no_src + else + $verbose not replacing $ntp_db_leapfile with $ntp_src_leapfile + fi + ntp_leapfile_expiry_seconds=$((ntp_leapfile_expiry_days*86400)) + ntp_leap_expiry=$(get_ntp_leapfile_expiry $ntp_db_leapfile) + ntp_leap_fetch_date=$((ntp_leap_expiry-ntp_leapfile_expiry_seconds)) + if [ $(current_ntp_ts) -ge $ntp_leap_fetch_date ]; then + $verbose Within ntp leapfile expiry limit, initiating fetch + # Return code 0: ntp leapfile fetch needed + return 0 + fi + # Return code 1: ntp leapfile fetch not needed + return 1 +} + +ntpd_fetch_leapfile() { + + if leapfile_is_disabled; then + return + fi + + if checkyesno ntp_leapfile_fetch_verbose; then + verbose=echo + else + verbose=: + fi + + if ntpd_needfetch_leapfile ; then + for url in $ntp_leapfile_sources ; do + $verbose fetching $url + # Circumvent umask 027 and 077 in login.conf(5) + umask 022 + fetch $ntp_leapfile_fetch_opts -o $_ntp_tmp_leapfile $url && break + done + ntp_ver_no_tmp=$(get_ntp_leapfile_ver $_ntp_tmp_leapfile) + ntp_expiry_tmp=$(get_ntp_leapfile_expiry $_ntp_tmp_leapfile) + if [ "$ntp_expiry_tmp" -gt "$ntp_expiry_db" -o \ + "$ntp_expiry_tmp" -eq "$ntp_expiry_db" -a \ + "$ntp_ver_no_tmp" -gt "$ntp_ver_no_db" ]; then + $verbose using $url as $ntp_db_leapfile + mv -f $_ntp_tmp_leapfile $ntp_db_leapfile || + $verbose "warning: cannot replace $ntp_db_leapfile (read-only fs?)" + else + $verbose using existing $ntp_db_leapfile + fi + fi +} + +ntpd_resume() +{ + run_rc_command restart +} + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/ntpdate b/libexec/rc/rc.d/ntpdate new file mode 100755 index 000000000000..cb948d739227 --- /dev/null +++ b/libexec/rc/rc.d/ntpdate @@ -0,0 +1,38 @@ +#!/bin/sh +# +# + +# PROVIDE: ntpdate +# REQUIRE: NETWORKING syslogd +# KEYWORD: nojail + +. /etc/rc.subr + +name="ntpdate" +desc="Set the date and time via NTP" +rcvar="ntpdate_enable" +stop_cmd=":" +start_cmd="ntpdate_start" + +ntpdate_start() +{ + if [ -z "$ntpdate_hosts" -a -f "$ntpdate_config" ]; then + ntpdate_hosts=`awk ' + /^server[ \t]*127.127/ {next} + /^(server|peer|pool)/ { + if ($2 ~/^-/) {print $3} + else {print $2}} + ' < "$ntpdate_config"` + fi + if [ -n "$ntpdate_hosts" -o -n "$rc_flags" ]; then + echo "Setting date via ntp." + ${ntpdate_program:-ntpdate} $rc_flags $ntpdate_hosts + fi +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: privileged operations +ntpdate_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/nuageinit b/libexec/rc/rc.d/nuageinit new file mode 100755 index 000000000000..c901971488bd --- /dev/null +++ b/libexec/rc/rc.d/nuageinit @@ -0,0 +1,96 @@ +#!/bin/sh +# + +# PROVIDE: nuageinit +# REQUIRE: mountcritlocal zfs devmatch +# BEFORE: NETWORKING +# KEYWORD: firstboot + +. /etc/rc.subr + +name="nuageinit" +desc="Limited Cloud Init configuration" +start_cmd="nuageinit_start" +stop_cmd=":" +rcvar="nuageinit_enable" + +fetch_openstack() +{ + cd /media/nuageinit/openstack/latest + for file in meta_data.json network_data.json user_data; do + fetch http://169.254.169.254/openstack/latest/$file || : + done + if [ -f user_data ]; then + chmod 755 user_data + fi + cd - +} + +nuageinit_start() +{ + local citype + # detect cloud init provider + # according to the specification, the config drive + # is either formatted in vfat or iso9660 and labeled + # config-2 + for f in iso9660 msdosfs; do + drive="/dev/$f/[cC][oO][nN][fF][iI][gG]-2" + if [ -e $drive ]; then + citype=config-2 + break + fi + drive="/dev/$f/[cC][iI][dD][aA][tT][aA]" + if [ -e $drive ]; then + citype=nocloud + break + fi + unset drive + done + if [ -n "$drive" ]; then + mkdir -p /media/nuageinit + fs=$(fstyp $drive 2> /dev/null) + mount -t $fs $drive /media/nuageinit + else + product=$(kenv smbios.system.product) + case "$product" in + OpenStack*) + mkdir -p /media/nuageinit/openstack/latest + ifaces=$(ifconfig -l ether) + set -- $ifaces + dhclient -p /tmp/ephemeraldhcp.pid $1 + fetch_openstack + pkill -F /tmp/ephemeraldhcp.pid + citype=config-2 + ;; + *) + # try to detect networked based instance + err 1 "Impossible to find a cloud init provider" + ;; + esac + fi + # according to the specification, the content is either + # in the openstack or ec2 directory + case "$citype" in + config-2) + for d in openstack ec2; do + dir=/media/nuageinit/$d/latest + if [ -d $dir ]; then + /usr/libexec/nuageinit $dir $citype 2>&1 | tee -a /var/log/nuageinit.log + break + fi + done + ;; + nocloud) + /usr/libexec/nuageinit /media/nuageinit $citype 2>&1 | tee -a /var/log/nuageinit.log + ;; + esac + if [ -n "$drive" ]; then + umount /media/nuageinit + rmdir /media/nuageinit + else + rm -rf /media/nuageinit + fi +} + +load_rc_config $name +run_rc_command "$1" diff --git a/libexec/rc/rc.d/nuageinit_post_net b/libexec/rc/rc.d/nuageinit_post_net new file mode 100755 index 000000000000..6d2591a603af --- /dev/null +++ b/libexec/rc/rc.d/nuageinit_post_net @@ -0,0 +1,25 @@ +#!/bin/sh +# + +# PROVIDE: nuageinit_post_net +# REQUIRE: NETWORKING devfs +# BEFORE: SERVERS +# KEYWORD: firstboot + +. /etc/rc.subr + +name="nuageinit_post_net" +desc="Post Network Cloud Init configuration" +start_cmd="execute_post_net" +stop_cmd=":" +rcvar="nuageinit_enable" + +execute_post_net() +{ + test -f /var/cache/nuageinit/user_data -o -f /var/cache/nuageinit/user-data || return + /usr/libexec/nuageinit /var/cache/nuageinit/ postnet | tee -a /var/log/nuageinit.log +} + +# Share the same config as nuageinit +load_rc_config nuageinit +run_rc_command "$1" diff --git a/libexec/rc/rc.d/nuageinit_user_data_script b/libexec/rc/rc.d/nuageinit_user_data_script new file mode 100755 index 000000000000..decb6bf1483e --- /dev/null +++ b/libexec/rc/rc.d/nuageinit_user_data_script @@ -0,0 +1,29 @@ +#!/bin/sh +# + +# PROVIDE: nuageinit_user_data_script +# REQUIRE: local +# KEYWORD: firstboot + +. /etc/rc.subr + +name="nuageinit_user_data_script" +desc="Execute user data script provided by cloudinit" +start_cmd="execute_user_data_script" +stop_cmd=":" +rcvar="nuageinit_enable" + +execute_user_data_script() +{ + if [ -x /var/cache/nuageinit/runcmds ]; then + echo "Executing 'runcmd'" | tee -a /var/log/nuageinit.log + /var/cache/nuageinit/runcmds 2>&1 | tee -a /var/log/nuageinit.log + fi + test -x /var/cache/nuageinit/user_data || return + echo "Executing user_data script" | tee -a /var/log/nuageinit.log + /var/cache/nuageinit/user_data 2>&1 | tee -a /var/log/nuageinit.log +} + +# Share the same config as nuageinit +load_rc_config nuageinit +run_rc_command "$1" diff --git a/libexec/rc/rc.d/opensm b/libexec/rc/rc.d/opensm new file mode 100755 index 000000000000..650345d81c12 --- /dev/null +++ b/libexec/rc/rc.d/opensm @@ -0,0 +1,29 @@ +#!/bin/sh +# +# + +# PROVIDE: opensm +# BEFORE: netif +# REQUIRE: FILESYSTEMS + +. /etc/rc.subr + +name="opensm" +start_cmd="opensm_start" +rcvar="opensm_enable" + +: ${opensm_svcj_options:="net_basic"} + +command=/usr/bin/opensm +command_args="-B" + +opensm_start() +{ + for guid in `ibstat | grep "Port GUID" | cut -d ':' -f2`; do + [ -z "${rc_quiet}" ] && echo "Starting ${guid} opensm." + ${command} ${command_args} -g ${guid} >> /dev/null + done +} + +load_rc_config $name +run_rc_command $* diff --git a/libexec/rc/rc.d/os-release b/libexec/rc/rc.d/os-release new file mode 100755 index 000000000000..0f8ee71e06b4 --- /dev/null +++ b/libexec/rc/rc.d/os-release @@ -0,0 +1,48 @@ +#!/bin/sh +# +# + +# PROVIDE: os-release +# REQUIRE: mountcritremote FILESYSTEMS +# BEFORE: LOGIN + +. /etc/rc.subr + +: ${osrelease_file:=/var/run/os-release} +: ${osrelease_perms:=444} +name="osrelease" +desc="Update ${osrelease_file}" +rcvar="osrelease_enable" +start_cmd="osrelease_start" +stop_cmd=":" + +osrelease_start() +{ + local _version _version_id + + startmsg -n "Updating ${osrelease_file} " + _version=$(freebsd-version -u) + _version_id=${_version%%[^0-9.]*} + t=$(mktemp -t os-release) + cat > "$t" <<-__EOF__ + NAME=FreeBSD + VERSION="$_version" + VERSION_ID="$_version_id" + ID=freebsd + ANSI_COLOR="0;31" + PRETTY_NAME="FreeBSD $_version" + CPE_NAME="cpe:/o:freebsd:freebsd:$_version_id" + HOME_URL="https://FreeBSD.org/" + BUG_REPORT_URL="https://bugs.FreeBSD.org/" +__EOF__ + install -C -o root -g wheel -m ${osrelease_perms} "$t" "${osrelease_file}" + rm -f "$t" + startmsg 'done.' +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +osrelease_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/pf b/libexec/rc/rc.d/pf new file mode 100755 index 000000000000..46fb085e5175 --- /dev/null +++ b/libexec/rc/rc.d/pf @@ -0,0 +1,94 @@ +#!/bin/sh +# +# + +# PROVIDE: pf +# REQUIRE: FILESYSTEMS netif pflog pfsync routing +# KEYWORD: nojailvnet + +. /etc/rc.subr + +name="pf" +desc="Packet filter" +rcvar="pf_enable" +load_rc_config $name +start_cmd="pf_start" +stop_cmd="pf_stop" +check_cmd="pf_check" +reload_cmd="pf_reload" +resync_cmd="pf_resync" +status_cmd="pf_status" +extra_commands="check reload resync" +required_files="$pf_rules" +required_modules="pf" + +# doesn't make sense to run in a svcj: config setting +pf_svcj="NO" + +pf_fallback() +{ + warn "Unable to load $pf_rules." + + if ! checkyesno pf_fallback_rules_enable; then + return + fi + + if [ -f $pf_fallback_rules_file ]; then + warn "Loading fallback rules file: $pf_fallback_rules_file" + $pf_program -f "$pf_fallback_rules_file" $pf_flags + else + warn "Loading fallback rules: $pf_fallback_rules" + echo "$pf_fallback_rules" | $pf_program -f - $pf_flags + fi +} + +pf_start() +{ + startmsg -n 'Enabling pf' + $pf_program -F all > /dev/null 2>&1 + $pf_program -f "$pf_rules" $pf_flags || pf_fallback + if ! $pf_program -s info | grep -q "Enabled" ; then + $pf_program -eq + fi + startmsg '.' +} + +pf_stop() +{ + if $pf_program -s info | grep -q "Enabled" ; then + echo -n 'Disabling pf' + $pf_program -dq + echo '.' + fi +} + +pf_check() +{ + echo "Checking pf rules." + $pf_program -n -f "$pf_rules" $pf_flags +} + +pf_reload() +{ + echo "Reloading pf rules." + pf_resync +} + +pf_resync() +{ + $pf_program -n -f "$pf_rules" $pf_flags || return 1 + $pf_program -f "$pf_rules" $pf_flags +} + +pf_status() +{ + if ! [ -c /dev/pf ] ; then + echo "pf.ko is not loaded" + return 1 + else + $pf_program -s info + $pf_program -s Running >/dev/null + fi +} + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/pflog b/libexec/rc/rc.d/pflog new file mode 100755 index 000000000000..b47252a23e0f --- /dev/null +++ b/libexec/rc/rc.d/pflog @@ -0,0 +1,111 @@ +#!/bin/sh +# +# + +# PROVIDE: pflog +# REQUIRE: FILESYSTEMS netif +# KEYWORD: nojailvnet + +. /etc/rc.subr + +name="pflog" +desc="Packet filter logging interface" +rcvar="pflog_enable" +command="/sbin/pflogd" +pidfile="/var/run/pflogd.pid" +start_precmd="pflog_prestart" +stop_postcmd="pflog_poststop" +extra_commands="reload resync" + +# no svcj options needed +: ${pflog_svcj_options:=""} + +# for backward compatibility +resync_cmd="pflog_resync" + +pflog_prestart() +{ + load_kld pflog || return 1 + + # create pflog_dev interface if needed + if ! ifconfig $pflog_dev > /dev/null 2>&1; then + if ! ifconfig $pflog_dev create; then + warn "could not create $pflog_dev." + return 1 + fi + fi + + # set pflog_dev interface to up state + if ! ifconfig $pflog_dev up; then + warn "could not bring up $pflog_dev." + return 1 + fi + + # -p flag requires stripping pidfile's leading /var/run and trailing .pid + pidfile=$(echo $pidfile | sed -e 's|/var/run/||' -e 's|.pid$||') + + # prepare the command line for pflogd + rc_flags="-p $pidfile -f $pflog_logfile -i $pflog_dev $rc_flags" + + # report we're ready to run pflogd + return 0 +} + +pflog_poststop() +{ + if ! ifconfig $pflog_dev down; then + warn "could not bring down $pflog_dev." + return 1 + fi + + if [ "$pflog_instances" ] && [ -n "$pflog_instances" ]; then + rm $pidfile + fi + + return 0 +} + +# for backward compatibility +pflog_resync() +{ + run_rc_command reload +} + +load_rc_config $name + +# precmd is not compatible with svcj +pflog_svcj="NO" + +# Check if spawning multiple pflogd and told what to spawn +if [ -n "$2" ]; then + # Set required variables + eval pflog_dev=\$pflog_${2}_dev + eval pflog_logfile=\$pflog_${2}_logfile + eval pflog_flags=\$pflog_${2}_flags + # Check that required vars have non-zero length, warn if not. + if [ -z $pflog_dev ]; then + warn "pflog_dev not set" + continue + fi + if [ -z $pflog_logfile ]; then + warn "pflog_logfile not set" + continue + fi + + # Provide a unique pidfile name for pflogd -p <pidfile> flag + pidfile="/var/run/pflogd.$2.pid" + + # Override service name and execute command + name=$pflog_dev + run_rc_command "$1" +# Check if spawning multiple pflogd and not told what to spawn +elif [ "$pflog_instances" ] && [ -n "$pflog_instances" ]; then + # Interate through requested instances. + for i in $pflog_instances; do + /etc/rc.d/pflog $1 $i + done +else + # Typical case, spawn single instance only. + pflog_dev=${pflog_dev:-"pflog0"} + run_rc_command "$1" +fi diff --git a/libexec/rc/rc.d/pfsync b/libexec/rc/rc.d/pfsync new file mode 100755 index 000000000000..e2ba9c17cd45 --- /dev/null +++ b/libexec/rc/rc.d/pfsync @@ -0,0 +1,52 @@ +#!/bin/sh +# +# + +# PROVIDE: pfsync +# REQUIRE: FILESYSTEMS netif +# KEYWORD: nojailvnet + +. /etc/rc.subr + +name="pfsync" +desc="Packet filter state table sychronisation interface" +rcvar="pfsync_enable" +start_precmd="pfsync_prestart" +start_cmd="pfsync_start" +stop_cmd="pfsync_stop" +required_modules="pf pfsync" + +pfsync_prestart() +{ + case "$pfsync_syncdev" in + '') + warn "pfsync_syncdev is not set." + return 1 + ;; + esac + return 0 +} + +pfsync_start() +{ + local _syncpeer + + echo "Enabling pfsync." + if [ -n "${pfsync_syncpeer}" ]; then + _syncpeer="syncpeer ${pfsync_syncpeer}" + fi + ifconfig pfsync0 $_syncpeer syncdev $pfsync_syncdev $pfsync_ifconfig up +} + +pfsync_stop() +{ + echo "Disabling pfsync." + ifconfig pfsync0 -syncdev -syncpeer down +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +pfsync_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/power_profile b/libexec/rc/rc.d/power_profile new file mode 100755 index 000000000000..7e187bf0a67c --- /dev/null +++ b/libexec/rc/rc.d/power_profile @@ -0,0 +1,99 @@ +#!/bin/sh +# +# Modify the power profile based on AC line state. This script is +# usually called from devd(8). +# +# Arguments: 0x00 (AC offline, economy) or 0x01 (AC online, performance) +# +# + +# PROVIDE: power_profile +# REQUIRE: FILESYSTEMS syslogd +# KEYWORD: nojail nostart + +. /etc/rc.subr + +name="power_profile" +desc="Modify the power profile based on AC line state" +stop_cmd=':' +LOGGER="logger -t power_profile -p daemon.notice" + +# Set a given sysctl node to a value. +# +# Variables: +# $node: sysctl node to set with the new value +# $value: HIGH for the highest performance value, LOW for the best +# economy value, or the value itself. +# $highest_value: maximum value for this sysctl, when $value is "HIGH" +# $lowest_value: minimum value for this sysctl, when $value is "LOW" +# +sysctl_set() +{ + # Check if the node exists + if [ -z "$(sysctl -n ${node} 2> /dev/null)" ]; then + return + fi + + # Get the new value, checking for special types HIGH or LOW + case ${value} in + [Hh][Ii][Gg][Hh]) + value=${highest_value} + ;; + [Ll][Oo][Ww]) + value=${lowest_value} + ;; + [Nn][Oo][Nn][Ee]) + return + ;; + *) + ;; + esac + + # Set the desired value + if [ -n "${value}" ]; then + if ! sysctl ${node}=${value} > /dev/null 2>&1; then + warn "unable to set ${node}=${value}" + fi + fi +} + +if [ $# -ne 1 ]; then + err 1 "Usage: $0 [0x00|0x01]" +fi +load_rc_config $name + +# doesn't make sense to run in a svcj: privileged operations +power_profile_svcj="NO" + +# Find the next state (performance or economy). +state=$1 +case ${state} in +0x01 | '') + ${LOGGER} "changed to 'performance'" + profile="performance" + ;; +0x00) + ${LOGGER} "changed to 'economy'" + profile="economy" + ;; +*) + echo "Usage: $0 [0x00|0x01]" + exit 1 +esac + +# Set the various sysctls based on the profile's values. +node="hw.acpi.cpu.cx_lowest" +highest_value="C1" +lowest_value="Cmax" +eval value=\$${profile}_cx_lowest +sysctl_set + +node="dev.cpu.0.freq" +highest_value="`(sysctl -n dev.cpu.0.freq_levels | \ + awk '{ split($0, a, "[/ ]"); print a[1] }' -) 2> /dev/null`" +lowest_value="`(sysctl -n dev.cpu.0.freq_levels | \ + awk '{ split($0, a, "[/ ]"); print a[length(a) - 1] }' -) 2> /dev/null`" +eval value=\$${profile}_cpu_freq +sysctl_set + +exit 0 diff --git a/libexec/rc/rc.d/powerd b/libexec/rc/rc.d/powerd new file mode 100755 index 000000000000..8ebc9cc2dc7f --- /dev/null +++ b/libexec/rc/rc.d/powerd @@ -0,0 +1,22 @@ +#!/bin/sh +# +# + +# PROVIDE: powerd +# REQUIRE: DAEMON +# BEFORE: LOGIN +# KEYWORD: nojail shutdown + +. /etc/rc.subr + +name="powerd" +desc="Modify the power profile based on AC line state" +rcvar="powerd_enable" +command="/usr/sbin/${name}" + +load_rc_config $name + +# doesn't make sense to run in a svcj: privileged operations +powerd_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/ppp b/libexec/rc/rc.d/ppp new file mode 100755 index 000000000000..6f41d67f8940 --- /dev/null +++ b/libexec/rc/rc.d/ppp @@ -0,0 +1,138 @@ +#!/bin/sh +# +# + +# PROVIDE: ppp +# REQUIRE: netif +# KEYWORD: nojail + +. /etc/rc.subr + +name="ppp" +desc="Point to Point Protocol" +rcvar="ppp_enable" +command="/usr/sbin/${name}" +start_cmd="ppp_start" +stop_cmd="ppp_stop" +start_postcmd="ppp_poststart" + +ppp_start_profile() +{ + local _ppp_profile _ppp_mode _ppp_nat _ppp_unit + local _ppp_profile_cleaned _punct _punct_c + + _ppp_profile=$1 + _ppp_profile_cleaned=$1 + _punct=". - / +" + for _punct_c in $_punct; do + _ppp_profile_cleaned=`ltr ${_ppp_profile_cleaned} ${_punct_c} '_'` + done + + # Check for ppp profile mode override. + # + eval _ppp_mode=\$ppp_${_ppp_profile_cleaned}_mode + if [ -z "$_ppp_mode" ]; then + _ppp_mode=$ppp_mode + fi + + # Check for ppp profile nat override. + # + eval _ppp_nat=\$ppp_${_ppp_profile_cleaned}_nat + if [ -z "$_ppp_nat" ]; then + _ppp_nat=$ppp_nat + fi + + # Establish ppp mode. + # + if [ "${_ppp_mode}" != "ddial" -a "${_ppp_mode}" != "direct" \ + -a "${_ppp_mode}" != "dedicated" \ + -a "${_ppp_mode}" != "background" ]; then + _ppp_mode="auto" + fi + + rc_flags="-quiet -${_ppp_mode}" + + # Switch on NAT mode? + # + case ${_ppp_nat} in + [Yy][Ee][Ss]) + rc_flags="$rc_flags -nat" + ;; + esac + + # Check for hard wired unit + eval _ppp_unit=\$ppp_${_ppp_profile_cleaned}_unit + if [ -n "${_ppp_unit}" ]; then + _ppp_unit="-unit${_ppp_unit}" + fi + rc_flags="$rc_flags $_ppp_unit" + + # Run! + # + su -m $ppp_user -c "$command ${rc_flags} ${_ppp_profile}" +} + +ppp_start() +{ + local _ppp_profile _p + + _ppp_profile=$* + if [ -z "${_ppp_profile}" ]; then + _ppp_profile=$ppp_profile + fi + + startmsg -n "Starting PPP profile:" + + for _p in $_ppp_profile; do + startmsg -n " $_p" + ppp_start_profile $_p + done + + startmsg "." +} + +ppp_poststart() +{ + # Re-Sync ipfilter and pf so they pick up any new network interfaces + # + if [ -f /etc/rc.d/ipfilter ]; then + /etc/rc.d/ipfilter quietresync + fi + if [ -f /etc/rc.d/pf ]; then + /etc/rc.d/pf quietresync + fi +} + +ppp_stop_profile() { + local _ppp_profile + + _ppp_profile=$1 + + /bin/pkill -f "^${command}.*[[:space:]]${_ppp_profile}\$" || \ + echo -n "(not running)" +} + +ppp_stop() { + local _ppp_profile _p + + _ppp_profile=$* + if [ -z "${_ppp_profile}" ]; then + _ppp_profile=$ppp_profile + fi + + echo -n "Stopping PPP profile:" + + for _p in $_ppp_profile; do + echo -n " $_p" + ppp_stop_profile $_p + done + + echo "." +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: nojail keyword +ppp_svcj="NO" + +run_rc_command $* diff --git a/libexec/rc/rc.d/pppoed b/libexec/rc/rc.d/pppoed new file mode 100755 index 000000000000..5c64862c6a49 --- /dev/null +++ b/libexec/rc/rc.d/pppoed @@ -0,0 +1,37 @@ +#!/bin/sh +# +# + +# PROVIDE: pppoed +# REQUIRE: NETWORKING +# BEFORE: DAEMON +# KEYWORD: nojail + +. /etc/rc.subr + +name="pppoed" +desc="Handle incoming PPP over Ethernet connections" +rcvar="pppoed_enable" +start_cmd="pppoed_start" +# XXX stop_cmd will not be straightforward +stop_cmd=":" + +pppoed_start() +{ + local _opts + + if [ -n "${pppoed_provider}" ]; then + pppoed_flags="${pppoed_flags} -p ${pppoed_provider}" + fi + startmsg 'Starting pppoed' + _opts=$-; set -f + /usr/libexec/pppoed ${pppoed_flags} ${pppoed_interface} + set +f; set -${_opts} +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: nojail keyword +pppoed_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/pwcheck b/libexec/rc/rc.d/pwcheck new file mode 100755 index 000000000000..db42fdd0d37e --- /dev/null +++ b/libexec/rc/rc.d/pwcheck @@ -0,0 +1,31 @@ +#!/bin/sh +# +# + +# PROVIDE: pwcheck +# REQUIRE: mountcritremote syslogd +# BEFORE: DAEMON + +. /etc/rc.subr + +name="pwcheck" +desc="Check password file correctness" +start_cmd="pwcheck_start" +stop_cmd=":" + +pwcheck_start() +{ + # check the password temp/lock file + # + if [ -f /etc/ptmp ]; then + logger -s -p auth.err \ + "password file may be incorrect -- /etc/ptmp exists" + fi +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +pwcheck_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/quota b/libexec/rc/rc.d/quota new file mode 100755 index 000000000000..9a3a3d50739c --- /dev/null +++ b/libexec/rc/rc.d/quota @@ -0,0 +1,37 @@ +#!/bin/sh +# +# + +# Enable/Check the quotas (must be after ypbind if using NIS) + +# PROVIDE: quota +# REQUIRE: mountcritremote ypset +# BEFORE: DAEMON +# KEYWORD: nojail + +. /etc/rc.subr + +name="quota" +desc="Enable/check the quotas" +rcvar="quota_enable" +load_rc_config $name +start_cmd="quota_start" +stop_cmd="/usr/sbin/quotaoff ${quotaoff_flags}" + +# doesn't make sense to run in a svcj: config setting +quota_svcj="NO" + +quota_start() +{ + if checkyesno check_quotas; then + echo -n 'Checking quotas:' + quotacheck ${quotacheck_flags} + echo ' done.' + fi + + echo -n 'Enabling quotas:' + quotaon ${quotaon_flags} + echo ' done.' +} + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/random b/libexec/rc/rc.d/random new file mode 100755 index 000000000000..c34f0d1f86b4 --- /dev/null +++ b/libexec/rc/rc.d/random @@ -0,0 +1,158 @@ +#!/bin/sh +# +# + +# PROVIDE: random +# REQUIRE: FILESYSTEMS +# BEFORE: netif +# KEYWORD: nojail shutdown + +. /etc/rc.subr + +name="random" +desc="Harvest and save entropy for random device" +start_cmd="random_start" +stop_cmd="random_stop" + +extra_commands="saveseed" +saveseed_cmd="${name}_stop" + +save_dev_random() +{ + oumask=`umask` + umask 077 + for f ; do + debug "saving entropy to $f" + dd if=/dev/random of="$f" bs=4096 count=1 status=none && + ( chflags nodump "$f" 2>/dev/null || : ) && + chmod 600 "$f" && + fsync "$f" "$(dirname "$f")" + done + umask ${oumask} +} + +feed_dev_random() +{ + for f ; do + if [ -f "$f" -a -r "$f" -a -s "$f" ] ; then + if dd if="$f" of=/dev/random bs=4096 2>/dev/null ; then + debug "entropy read from $f" + rm -f "$f" + fi + fi + done +} + +random_start() +{ + + if [ -n "${harvest_mask}" ]; then + echo -n 'Setting up harvesting: ' + ${SYSCTL} kern.random.harvest.mask=${harvest_mask} > /dev/null + ${SYSCTL_N} kern.random.harvest.mask_symbolic + fi + + echo -n 'Feeding entropy: ' + + if [ ! -w /dev/random ] ; then + warn "/dev/random is not writeable" + return 1 + fi + + # Reseed /dev/random with previously stored entropy. + case ${entropy_dir:=/var/db/entropy} in + [Nn][Oo]) + ;; + *) + if [ -d "${entropy_dir}" ] ; then + feed_dev_random "${entropy_dir}"/* + fi + ;; + esac + + case ${entropy_file:=/entropy} in + [Nn][Oo]) + ;; + *) + feed_dev_random "${entropy_file}" /var/db/entropy-file + save_dev_random "${entropy_file}" + ;; + esac + + case ${entropy_boot_file:=/boot/entropy} in + [Nn][Oo]) + ;; + *) + save_dev_random "${entropy_boot_file}" + ;; + esac + + echo '.' +} + +random_stop() +{ + # Write some entropy so when the machine reboots /dev/random + # can be reseeded + # + case ${entropy_file:=/entropy} in + [Nn][Oo]) + ;; + *) + echo -n 'Writing entropy file: ' + rm -f ${entropy_file} 2> /dev/null + oumask=`umask` + umask 077 + if touch ${entropy_file} 2> /dev/null; then + entropy_file_confirmed="${entropy_file}" + else + # Try this as a reasonable alternative for read-only + # roots, diskless workstations, etc. + rm -f /var/db/entropy-file 2> /dev/null + if touch /var/db/entropy-file 2> /dev/null; then + entropy_file_confirmed=/var/db/entropy-file + fi + fi + case ${entropy_file_confirmed} in + '') + warn 'write failed (read-only fs?)' + ;; + *) + save_dev_random "${entropy_file_confirmed}" + echo '.' + ;; + esac + umask ${oumask} + ;; + esac + case ${entropy_boot_file:=/boot/entropy} in + [Nn][Oo]) + ;; + *) + echo -n 'Writing early boot entropy file: ' + rm -f ${entropy_boot_file} 2> /dev/null + oumask=`umask` + umask 077 + if touch ${entropy_boot_file} 2> /dev/null; then + entropy_boot_file_confirmed="${entropy_boot_file}" + fi + case ${entropy_boot_file_confirmed} in + '') + warn 'write failed (read-only fs?)' + ;; + *) + save_dev_random "${entropy_boot_file_confirmed}" + echo '.' + ;; + esac + umask ${oumask} + ;; + esac +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +random_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/rarpd b/libexec/rc/rc.d/rarpd new file mode 100755 index 000000000000..2618565ae0d1 --- /dev/null +++ b/libexec/rc/rc.d/rarpd @@ -0,0 +1,23 @@ +#!/bin/sh +# +# + +# PROVIDE: rarpd +# REQUIRE: DAEMON FILESYSTEMS +# BEFORE: LOGIN +# KEYWORD: nojailvnet + +. /etc/rc.subr + +name="rarpd" +desc="Reverse ARP daemon" +rcvar="rarpd_enable" +command="/usr/sbin/${name}" +required_files="/etc/ethers" + +: ${rarpd_svcj_options:="net_basic"} + +load_rc_config $name +pidfile="${rarpd_pidfile:-/var/run/${name}.pid}" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/rctl b/libexec/rc/rc.d/rctl new file mode 100755 index 000000000000..96c148e78bcd --- /dev/null +++ b/libexec/rc/rc.d/rctl @@ -0,0 +1,45 @@ +#!/bin/sh +# +# + +# PROVIDE: rctl +# REQUIRE: FILESYSTEMS +# BEFORE: LOGIN +# KEYWORD: nojail + +. /etc/rc.subr + +name="rctl" +desc="Manage resource limits" +rcvar="rctl_enable" +start_cmd="rctl_start" +stop_cmd="rctl_stop" + +rctl_start() +{ + if [ -f ${rctl_rules} ]; then + while read var comments + do + case ${var} in + \#*|'') + ;; + *) + echo "${var}" + ;; + esac + done < ${rctl_rules} | xargs rctl -a + fi +} + +rctl_stop() +{ + + rctl -r : +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +rctl_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/resolv b/libexec/rc/rc.d/resolv new file mode 100755 index 000000000000..a46c7ba314e9 --- /dev/null +++ b/libexec/rc/rc.d/resolv @@ -0,0 +1,66 @@ +#!/bin/sh +# +# Copyright (c) 1999 Matt Dillon +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# + +# PROVIDE: resolv +# REQUIRE: netif FILESYSTEMS +# KEYWORD: nojail + +. /etc/rc.subr + +name="resolv" +rcvar="resolv_enable" +desc="Create /etc/resolv.conf from kenv" +start_cmd="${name}_start" +stop_cmd=':' + +# if the info is available via dhcp/kenv +# build the resolv.conf +# +resolv_start() +{ + if [ -n "`/bin/kenv dhcp.domain-name-servers 2> /dev/null`" ]; then + interface="`/bin/kenv boot.netif.name`" + ( + if [ -n "`/bin/kenv dhcp.domain-name 2> /dev/null`" ]; then + echo domain `/bin/kenv dhcp.domain-name` + fi + + set -- `/bin/kenv dhcp.domain-name-servers` + for ns in `IFS=','; echo $*`; do + echo nameserver $ns + done + ) | /sbin/resolvconf -a ${interface}:dhcp4 + fi +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +resolv_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/rfcomm_pppd_server b/libexec/rc/rc.d/rfcomm_pppd_server new file mode 100755 index 000000000000..810c1adc8e91 --- /dev/null +++ b/libexec/rc/rc.d/rfcomm_pppd_server @@ -0,0 +1,126 @@ +#!/bin/sh +# +# + +# PROVIDE: rfcomm_pppd_server +# REQUIRE: DAEMON sdpd +# BEFORE: LOGIN +# KEYWORD: nojail + +. /etc/rc.subr + +name="rfcomm_pppd_server" +desc="RFCOMM PPP daemon" +rcvar="rfcomm_pppd_server_enable" +command="/usr/sbin/rfcomm_pppd" +start_cmd="rfcomm_pppd_server_start" +stop_cmd="rfcomm_pppd_server_stop" +required_modules="ng_btsocket" + +rfcomm_pppd_server_start_profile() +{ + local _profile _profile_cleaned _punct _punct_c + local _bdaddr _channel _x + + _profile=$1 + _profile_cleaned=$1 + + _punct=". - / +" + for _punct_c in ${_punct} ; do + _profile_cleaned=`ltr ${_profile_cleaned} ${_punct_c} '_'` + done + + rc_flags="" + + # Check for RFCOMM PPP profile bdaddr override + # + eval _bdaddr=\$rfcomm_pppd_server_${_profile_cleaned}_bdaddr + if [ -n "${_bdaddr}" ]; then + rc_flags="${rc_flags} -a ${_bdaddr}" + fi + + # Check for RFCOMM PPP profile channel override + # + eval _channel=\$rfcomm_pppd_server_${_profile_cleaned}_channel + if [ -z "${_channel}" ]; then + _channel=1 + fi + rc_flags="${rc_flags} -C ${_channel}" + + # Check for RFCOMM PPP profile register SP override + # + eval _x=\$rfcomm_pppd_server_${_profile_cleaned}_register_sp + if [ -n "${_x}" ]; then + if checkyesno "rfcomm_pppd_server_${_profile_cleaned}_register_sp" ; then + rc_flags="${rc_flags} -S" + fi + fi + + # Check for RFCOMM PPP profile register DUN override + # + eval _x=\$rfcomm_pppd_server_${_profile_cleaned}_register_dun + if [ -n "${_x}" ]; then + if checkyesno "rfcomm_pppd_server_${_profile_cleaned}_register_dun" ; then + rc_flags="${rc_flags} -D" + fi + fi + + # Run! + # + $command -s ${rc_flags} -l ${_profile} +} + +rfcomm_pppd_server_stop_profile() +{ + local _profile + + _profile=$1 + + /bin/pkill -f "^${command}.*[[:space:]]${_profile}\$" || \ + echo -n "(not running)" +} + +rfcomm_pppd_server_start() +{ + local _profile _p + + _profile=$* + if [ -z "${_profile}" ]; then + _profile=${rfcomm_pppd_server_profile} + fi + + startmsg -n "Starting RFCOMM PPP profile:" + + for _p in ${_profile} ; do + startmsg -n " ${_p}" + rfcomm_pppd_server_start_profile ${_p} + done + + startmsg "." +} + +rfcomm_pppd_server_stop() +{ + local _profile _p + + _profile=$* + if [ -z "${_profile}" ]; then + _profile=${rfcomm_pppd_server_profile} + fi + + echo -n "Stopping RFCOMM PPP profile:" + + for _p in ${_profile} ; do + echo -n " ${_p}" + rfcomm_pppd_server_stop_profile ${_p} + done + + echo "." +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: nojail keyword +rfcomm_pppd_server_svcj="NO" + +run_rc_command $* diff --git a/libexec/rc/rc.d/root b/libexec/rc/rc.d/root new file mode 100755 index 000000000000..e1dad6270e7d --- /dev/null +++ b/libexec/rc/rc.d/root @@ -0,0 +1,46 @@ +#!/bin/sh +# +# + +# PROVIDE: root +# REQUIRE: fsck +# KEYWORD: nojail + +. /etc/rc.subr + +name="root" +desc="Mount root filesystem read/write" +start_cmd="root_start" +stop_cmd=":" + +root_start() +{ + # root normally must be read/write, but if this is a BOOTP NFS + # diskless boot it does not have to be. + # + case ${root_rw_mount} in + [Nn][Oo] | '') + ;; + *) + if ! mount -uw /; then + echo 'Mounting root filesystem rw failed, startup aborted' + stop_boot true + fi + ;; + esac + + umount -a >/dev/null 2>&1 + + # If we booted a special kernel remove the record + # so we will boot the default kernel next time. + if [ -x /sbin/nextboot ]; then + /sbin/nextboot -D > /dev/null 2>&1 + fi +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: mounting / config setting +root_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/route6d b/libexec/rc/rc.d/route6d new file mode 100755 index 000000000000..873efdeb123c --- /dev/null +++ b/libexec/rc/rc.d/route6d @@ -0,0 +1,22 @@ +#!/bin/sh +# +# + +# PROVIDE: route6d +# REQUIRE: netif routing +# KEYWORD: nojailvnet + +. /etc/rc.subr + +name="route6d" +desc="RIP6 routing daemon" +rcvar="route6d_enable" + +: ${route6d_svcj_options:="net_basic"} + +set_rcvar_obsolete ipv6_router_enable route6d_enable +set_rcvar_obsolete ipv6_router route6d_program +set_rcvar_obsolete ipv6_router_flags route6d_flags + +load_rc_config $name +run_rc_command "$1" diff --git a/libexec/rc/rc.d/routed b/libexec/rc/rc.d/routed new file mode 100755 index 000000000000..9338cf034edd --- /dev/null +++ b/libexec/rc/rc.d/routed @@ -0,0 +1,23 @@ +#!/bin/sh +# +# + +# PROVIDE: routed dynamicrouting +# REQUIRE: netif routing +# BEFORE: NETWORKING +# KEYWORD: nojailvnet + +. /etc/rc.subr + +name="routed" +desc="Network RIP and router discovery routing daemon" +rcvar="routed_enable" + +: ${routed_svcj_options:="net_basic"} + +set_rcvar_obsolete router_enable routed_enable +set_rcvar_obsolete router routed_program +set_rcvar_obsolete router_flags routed_flags + +load_rc_config $name +run_rc_command "$1" diff --git a/libexec/rc/rc.d/routing b/libexec/rc/rc.d/routing new file mode 100755 index 000000000000..dd75604125a3 --- /dev/null +++ b/libexec/rc/rc.d/routing @@ -0,0 +1,442 @@ +#!/bin/sh +# +# Configure routing and miscellaneous network tunables +# +# + +# PROVIDE: routing +# REQUIRE: netif ppp stf +# KEYWORD: nojailvnet + +. /etc/rc.subr +. /etc/network.subr + +name="routing" +desc="Routing setup" +start_cmd="routing_start doall" +stop_cmd="routing_stop" +extra_commands="options static" +static_cmd="routing_start static" +options_cmd="routing_start options" + +ROUTE_CMD="/sbin/route" + +routing_start() +{ + local _cmd _af _if _a _ret + _cmd=$1 + _af=$2 + _if=$3 + _ret=0 + + case $_if in + ""|[Aa][Ll][Ll]|[Aa][Nn][Yy]) _if="" ;; + esac + + case $_af in + ""|[Aa][Ll][Ll]|[Aa][Nn][Yy]) + for _a in inet inet6; do + afexists $_a || continue + setroutes $_cmd $_a $_if || _ret=1 + done + ;; + *) + if afexists $_af; then + setroutes $_cmd $_af $_if || _ret=1 + else + err 1 "Unsupported address family: $_af." + fi + ;; + esac + + return $_ret +} + +routing_stop() +{ + local _af _if _a + _af=$1 + _if=$2 + + case $_if in + ""|[Aa][Ll][Ll]|[Aa][Nn][Yy]) _if="" ;; + esac + + case $_af in + ""|[Aa][Ll][Ll]|[Aa][Nn][Yy]) + for _a in inet inet6; do + afexists $_a || continue + eval static_${_a} delete $_if + # When $_if is specified, do not flush routes. + if ! [ -n "$_if" ]; then + eval routing_stop_${_a} + fi + done + ;; + *) + if afexists $_af; then + eval static_${_af} delete $_if + # When $_if is specified, do not flush routes. + if ! [ -n "$_if" ]; then + eval routing_stop_${_af} + fi + else + err 1 "Unsupported address family: $_af." + fi + ;; + esac +} + +setroutes() +{ + local _ret + _ret=0 + case $1 in + static) + static_$2 add $3 + _ret=$? + ;; + options) + options_$2 + ;; + doall) + static_$2 add $3 + _ret=$? + options_$2 + ;; + esac + return $_ret +} + +routing_stop_inet() +{ + ${ROUTE_CMD} -n flush -inet +} + +routing_stop_inet6() +{ + local i + + ${ROUTE_CMD} -n flush -inet6 + for i in `list_net_interfaces`; do + if ipv6if $i; then + ifconfig $i inet6 -defaultif + fi + done +} + +get_fibmod() +{ + local _fibs + + _fibs=$((`${SYSCTL_N} net.fibs` - 1)) + if [ ${_fibs} -gt 0 ]; then + echo "-fib 0-${_fibs}" + else + echo + fi +} + +static_inet() +{ + local _action _if _skip _fibmod _fibs + _action=$1 + _if=$2 + + _fibmod=`get_fibmod` + _fibs=$((`${SYSCTL_N} net.fibs` - 1)) + + # Provide loopback route in all routing tables. This has to come + # first so that any following routes can be added. + static_routes="_loopback ${static_routes}" + route__loopback="-inet 127.0.0.1 -iface lo0 ${_fibmod}" + + # Add default route. + case ${defaultrouter} in + [Nn][Oo] | '') + ;; + *) + static_routes="${static_routes} _default" + route__default="default ${defaultrouter}" + ;; + esac + + # Add default routes for fibs + if [ ${_fibs} -gt 0 ]; then + for _fibnum in `jot ${_fibs}` ; do + eval _fib_gw=\${defaultrouter_fib${_fibnum}} + case ${_fib_gw} in + [Nn][Oo] | '') + ;; + *) + static_routes="${static_routes} _default_fib${_fibnum}" + eval route__default_fib${_fibnum}="'default ${_fib_gw} -fib ${_fibnum}'" + ;; + esac + done + fi + + + # Install configured routes. + if [ -n "${static_routes}" ]; then + for i in ${static_routes}; do + _skip=0 + if [ -n "$_if" ]; then + case $i in + *:$_if) ;; + *) _skip=1 ;; + esac + fi + if [ $_skip = 0 ]; then + route_args=`get_if_var ${i%:*} route_IF` + if [ -n "$route_args" ]; then + ${ROUTE_CMD} ${_action} ${route_args} + else + warn "route_${i%:*} not found." + fi + fi + done + fi +} + +static_inet6() +{ + local _action _if _skip fibmod _fibs + _action=$1 + _if=$2 + + fibmod=`get_fibmod` + _fibs=$((`${SYSCTL_N} net.fibs` - 1)) + + # Add pre-defined static routes first. + ipv6_static_routes="_v4mapped _v4compat ${ipv6_static_routes}" + ipv6_static_routes="_lla _llma ${ipv6_static_routes}" + ipv6_static_routes="_loopback ${ipv6_static_routes}" + + # disallow "internal" addresses to appear on the wire + ipv6_route__v4mapped="::ffff:0.0.0.0 -prefixlen 96 ::1 -reject ${fibmod}" + ipv6_route__v4compat="::0.0.0.0 -prefixlen 96 ::1 -reject ${fibmod}" + + # Create a loopback route in every fib + ipv6_route__loopback="::1 -prefixlen 128 -iface lo0 ${fibmod}" + + # Disallow link-local unicast packets without outgoing scope + # identifiers. However, if you set "ipv6_default_interface", + # for the host case, you will allow to omit the identifiers. + # Under this configuration, the packets will go to the default + # interface. + ipv6_route__lla="fe80:: -prefixlen 10 ::1 -reject ${fibmod}" + ipv6_route__llma="ff02:: -prefixlen 16 ::1 -reject ${fibmod}" + + # Add default route. + case ${ipv6_defaultrouter} in + [Nn][Oo] | '') + ;; + *) + ipv6_static_routes="${ipv6_static_routes} _default" + ipv6_route__default="default ${ipv6_defaultrouter}" + ;; + esac + + # Add default routes for fibs + if [ ${_fibs} -gt 0 ]; then + for _fibnum in `jot ${_fibs}` ; do + eval _fib_gw=\${ipv6_defaultrouter_fib${_fibnum}} + case ${_fib_gw} in + [Nn][Oo] | '') + ;; + *) + ipv6_static_routes="${ipv6_static_routes} _default_fib${_fibnum}" + eval ipv6_route__default_fib${_fibnum}="'default ${_fib_gw} -fib ${_fibnum}'" + ;; + esac + done + fi + + + # Install configured routes. + if [ -n "${ipv6_static_routes}" ]; then + for i in ${ipv6_static_routes}; do + _skip=0 + if [ -n "$_if" ]; then + case $i in + *:$_if) ;; + *) _skip=1 ;; + esac + fi + if [ $_skip = 0 ]; then + ipv6_route_args=`get_if_var ${i%:*} ipv6_route_IF` + if [ -n "$ipv6_route_args" ]; then + ${ROUTE_CMD} ${_action} \ + -inet6 ${ipv6_route_args} + else + warn "route_${i%:*} not found" + fi + fi + done + fi + + # Install the "default interface" to kernel, which will be used + # as the default route when there's no router. + + # Disable installing the default interface when we act + # as router to avoid conflict between the default + # router list and the manual configured default route. + if checkyesno ipv6_gateway_enable; then + return + fi + + case "${ipv6_default_interface}" in + [Nn][Oo] | [Nn][Oo][Nn][Ee]) + return + ;; + [Aa][Uu][Tt][Oo] | "") + for i in ${ipv6_network_interfaces}; do + case $i in + [Nn][Oo][Nn][Ee]) + return + ;; + lo0) + continue + ;; + esac + laddr=`network6_getladdr $i exclude_tentative` + case ${laddr} in + '') + ;; + *) + ipv6_default_interface=$i + break + ;; + esac + done + ;; + esac + + ifconfig ${ipv6_default_interface} inet6 defaultif + ${SYSCTL} net.inet6.ip6.use_defaultzone=1 > /dev/null +} + +ropts_init() +{ + if [ -z "${_ropts_initdone}" ]; then + echo -n "Additional $1 routing options:" + _ropts_initdone=yes + fi +} + +_check_dynamicrouting() +{ + local skip file name rcvar + + # copied from /etc/rc + skip="-s nostart" + if check_jail jailed; then + skip="$skip -s nojail" + fi + [ -n "$local_startup" ] && find_local_scripts_new + [ -n "$system_rc" ] && find_system_scripts + + for file in $( rcorder ${skip} ${system_rc} ${local_rc} 2>/dev/null | + xargs grep -lE '^# PROVIDE:.*\<dynamicrouting\>' ); do + (set -- enabled; . $file) && return 0; + done + + return 1 +} + +options_inet() +{ + local _icmp_drop_redirect + + _ropts_initdone= + if checkyesno icmp_bmcastecho; then + ropts_init inet + echo -n ' broadcast ping responses=YES' + ${SYSCTL} net.inet.icmp.bmcastecho=1 > /dev/null + else + ${SYSCTL} net.inet.icmp.bmcastecho=0 > /dev/null + fi + + _icmp_drop_redirect="${icmp_drop_redirect}" + case "${_icmp_drop_redirect}" in + [Aa][Uu][Tt][Oo] | "") + if _check_dynamicrouting; then + _icmp_drop_redirect="yes" + else + _icmp_drop_redirect="no" + fi + ;; + esac + if checkyesno _icmp_drop_redirect; then + ropts_init inet + echo -n ' ignore ICMP redirect=YES' + ${SYSCTL} net.inet.icmp.drop_redirect=1 > /dev/null + else + ${SYSCTL} net.inet.icmp.drop_redirect=0 > /dev/null + fi + + if checkyesno icmp_log_redirect; then + ropts_init inet + echo -n ' log ICMP redirect=YES' + ${SYSCTL} net.inet.icmp.log_redirect=1 > /dev/null + else + ${SYSCTL} net.inet.icmp.log_redirect=0 > /dev/null + fi + + if checkyesno gateway_enable; then + ropts_init inet + echo -n ' gateway=YES' + ${SYSCTL} net.inet.ip.forwarding=1 > /dev/null + else + ${SYSCTL} net.inet.ip.forwarding=0 > /dev/null + fi + + if checkyesno forward_sourceroute; then + ropts_init inet + echo -n ' do source routing=YES' + ${SYSCTL} net.inet.ip.sourceroute=1 > /dev/null + else + ${SYSCTL} net.inet.ip.sourceroute=0 > /dev/null + fi + + if checkyesno accept_sourceroute; then + ropts_init inet + echo -n ' accept source routing=YES' + ${SYSCTL} net.inet.ip.accept_sourceroute=1 > /dev/null + else + ${SYSCTL} net.inet.ip.accept_sourceroute=0 > /dev/null + fi + + if checkyesno arpproxy_all; then + ropts_init inet + echo -n ' ARP proxyall=YES' + ${SYSCTL} net.link.ether.inet.proxyall=1 > /dev/null + else + ${SYSCTL} net.link.ether.inet.proxyall=0 > /dev/null + fi + + [ -n "${_ropts_initdone}" ] && echo '.' +} + +options_inet6() +{ + _ropts_initdone= + + if checkyesno ipv6_gateway_enable; then + ropts_init inet6 + echo -n ' gateway=YES' + ${SYSCTL} net.inet6.ip6.forwarding=1 > /dev/null + else + ${SYSCTL} net.inet6.ip6.forwarding=0 > /dev/null + fi + + [ -n "${_ropts_initdone}" ] && echo '.' +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +routing_svcj="NO" + +run_rc_command "$@" diff --git a/libexec/rc/rc.d/rpcbind b/libexec/rc/rc.d/rpcbind new file mode 100755 index 000000000000..c393df666219 --- /dev/null +++ b/libexec/rc/rc.d/rpcbind @@ -0,0 +1,21 @@ +#!/bin/sh +# +# + +# PROVIDE: rpcbind +# REQUIRE: NETWORKING ntpdate syslogd +# KEYWORD: shutdown + +. /etc/rc.subr + +name="rpcbind" +desc="Universal addresses to RPC program number mapper" +rcvar="rpcbind_enable" +command="/usr/sbin/${name}" + +: ${rpcbind_svcj_options:="net_basic"} + +stop_postcmd='/bin/rm -f /var/run/rpcbind.*' + +load_rc_config $name +run_rc_command "$1" diff --git a/libexec/rc/rc.d/rtadvd b/libexec/rc/rc.d/rtadvd new file mode 100755 index 000000000000..99fec22604aa --- /dev/null +++ b/libexec/rc/rc.d/rtadvd @@ -0,0 +1,77 @@ +#!/bin/sh +# +# + +# PROVIDE: rtadvd +# REQUIRE: DAEMON +# BEFORE: LOGIN +# KEYWORD: nojailvnet shutdown + +. /etc/rc.subr +. /etc/network.subr + +name="rtadvd" +desc="Router advertisement daemon" +rcvar="rtadvd_enable" +command="/usr/sbin/${name}" +extra_commands="reload" +reload_cmd="rtadvd_reload" +start_precmd="rtadvd_precmd" + +: ${rtadvd_svcj_options:="net_basic"} + +rtadvd_precmd() +{ + # This should be enabled with a great care. + # You may want to fine-tune /etc/rtadvd.conf. + # + # And if you wish your rtadvd to receive and process + # router renumbering messages, specify your Router Renumbering + # security policy by -R option. + # + # See `man 3 ipsec_set_policy` for IPsec policy specification + # details. + # (CAUTION: This enables your routers prefix renumbering + # from another machine, so if you enable this, do it with + # enough care.) + # + # If specific interfaces haven't been specified, + # get a list of interfaces and enable it on them + # + case ${rtadvd_interfaces} in + [Aa][Uu][Tt][Oo]|'') + command_args= + for i in `list_net_interfaces`; do + case $i in + lo0) continue ;; + esac + if ipv6if $i; then + command_args="${command_args} ${i}" + fi + done + ;; + [Nn][Oo][Nn][Ee]) + ;; + *) + command_args="${rtadvd_interfaces}" + ;; + esac + + # Enable Router Renumbering, unicast case + # (use correct src/dst addr) + # rtadvd -R "in ipsec ah/transport/fec0:0:0:1::1-fec0:0:0:10::1/require" ${ipv6_network_interfaces} + # Enable Router Renumbering, multicast case + # (use correct src addr) + # rtadvd -R "in ipsec ah/transport/ff05::2-fec0:0:0:10::1/require" ${ipv6_network_interfaces} + return 0 +} + +rtadvd_reload() { + /usr/sbin/rtadvctl reload +} + +load_rc_config $name + +# precmd is not compatible with svcj +rtadvd_svcj="NO" +run_rc_command "$1" diff --git a/libexec/rc/rc.d/rtsold b/libexec/rc/rc.d/rtsold new file mode 100755 index 000000000000..5578af5a367f --- /dev/null +++ b/libexec/rc/rc.d/rtsold @@ -0,0 +1,28 @@ +#!/bin/sh +# +# + +# PROVIDE: rtsold +# REQUIRE: netif +# BEFORE: NETWORKING +# KEYWORD: nojailvnet shutdown + +. /etc/rc.subr + +name="rtsold" +desc="Router solicitation daemon" +rcvar="rtsold_enable" +command="/usr/sbin/${name}" +pidfile="/var/run/${name}.pid" +start_postcmd="rtsold_poststart" + +: ${rtsold_svcj_options:="net_basic"} + +rtsold_poststart() +{ + # wait for DAD + sleep $(($(${SYSCTL_N} net.inet6.ip6.dad_count) + 1)) +} + +load_rc_config $name +run_rc_command "$1" diff --git a/libexec/rc/rc.d/rwho b/libexec/rc/rc.d/rwho new file mode 100755 index 000000000000..f35bcda30ebf --- /dev/null +++ b/libexec/rc/rc.d/rwho @@ -0,0 +1,20 @@ +#!/bin/sh +# +# + +# PROVIDE: rwho +# REQUIRE: DAEMON +# BEFORE: LOGIN +# KEYWORD: shutdown + +. /etc/rc.subr + +name="rwhod" +desc="System status server" +rcvar="rwhod_enable" +command="/usr/sbin/${name}" + +: ${rwhod_svcj_options:="net_basic"} + +load_rc_config $name +run_rc_command "$1" diff --git a/libexec/rc/rc.d/savecore b/libexec/rc/rc.d/savecore new file mode 100755 index 000000000000..889476591dac --- /dev/null +++ b/libexec/rc/rc.d/savecore @@ -0,0 +1,85 @@ +#!/bin/sh +# +# + +# PROVIDE: savecore +# REQUIRE: dumpon ddb syslogd +# KEYWORD: nojail + +. /etc/rc.subr + +name="savecore" +rcvar="savecore_enable" +desc="Save a core dump of the operating system" +start_cmd="savecore_start" +start_precmd="savecore_prestart" +stop_cmd=":" + +savecore_prestart() +{ + # Quit if we have no dump device + case ${dumpdev} in + [Nn][Oo]) + debug 'No dump device. Quitting.' + return 1 + ;; + [Aa][Uu][Tt][Oo] | '') + if [ ! -L /dev/dumpdev ]; then + return 1 + fi + dumpdev=`/bin/realpath /dev/dumpdev` + ;; + esac + + # If there is no crash directory set it now + case ${dumpdir} in + '') + dumpdir='/var/crash' + ;; + [Nn][Oo]) + dumpdir='NO' + ;; + esac + + if [ ! -c "${dumpdev}" ]; then + warn "Dump device does not exist. Savecore not run." + return 1 + fi + + if [ ! -d "${dumpdir}" ]; then + warn "Dump directory does not exist. Savecore not run." + return 1 + fi + return 0 +} + +savecore_start() +{ + local dev + + case "${dumpdev}" in + [Aa][Uu][Tt][Oo]) + dev= + ;; + *) + dev="${dumpdev}" + ;; + esac + + if savecore -C "${dev}" >/dev/null; then + savecore ${savecore_flags} ${dumpdir} ${dumpdev} + if checkyesno crashinfo_enable; then + ${crashinfo_program} -b -d ${dumpdir} + fi + sync + else + startmsg 'No core dumps found.' + fi +} + +load_rc_config $name + +# doesn't make sense to run in a svcj +savecore_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/sdpd b/libexec/rc/rc.d/sdpd new file mode 100755 index 000000000000..a7bf51ecdc75 --- /dev/null +++ b/libexec/rc/rc.d/sdpd @@ -0,0 +1,27 @@ +#!/bin/sh +# +# + +# PROVIDE: sdpd +# REQUIRE: DAEMON +# BEFORE: LOGIN +# KEYWORD: nojail shutdown + +. /etc/rc.subr + +name="sdpd" +desc="Bluetooth Service Discovery Protocol daemon " +command="/usr/sbin/${name}" +rcvar="sdpd_enable" +required_modules="ng_btsocket" + +load_rc_config $name +control="${sdpd_control:-/var/run/sdp}" +group="${sdpd_groupname:-nobody}" +user="${sdpd_username:-nobody}" +command_args="-c ${control} -g ${group} -u ${user}" + +# doesn't make sense to run in a svcj: nojail keyword +sdpd_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/securelevel b/libexec/rc/rc.d/securelevel new file mode 100755 index 000000000000..e5c5a410cf62 --- /dev/null +++ b/libexec/rc/rc.d/securelevel @@ -0,0 +1,29 @@ +#!/bin/sh +# +# + +# PROVIDE: securelevel +# REQUIRE: adjkerntz ipfw pf sysctl_lastload + +. /etc/rc.subr + +name="securelevel" +desc="Securelevel configuration" +rcvar='kern_securelevel_enable' +start_cmd="securelevel_start" +stop_cmd=":" + +securelevel_start() +{ + if [ ${kern_securelevel} -ge 0 ]; then + echo 'Raising kernel security level: ' + ${SYSCTL} kern.securelevel=${kern_securelevel} + fi +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +securelevel_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/sendmail b/libexec/rc/rc.d/sendmail new file mode 100755 index 000000000000..a9d37f3f7d69 --- /dev/null +++ b/libexec/rc/rc.d/sendmail @@ -0,0 +1,229 @@ +#!/bin/sh +# +# + +# PROVIDE: mail +# REQUIRE: LOGIN FILESYSTEMS +# KEYWORD: shutdown +# +# We make mail start late, so that things like .forward's are not processed +# until the system is fully operational. + +# XXX - Get together with sendmail mantainer to figure out how to +# better handle SENDMAIL_ENABLE and 3rd party MTAs. +# +. /etc/rc.subr + +name="sendmail" +desc="Electronic mail transport agent" +rcvar="sendmail_enable" +required_files="/etc/mail/${name}.cf" +start_precmd="sendmail_precmd" + +: ${sendmail_svcj_options:="net_basic"} + +load_rc_config $name +command=${sendmail_program:-/usr/sbin/${name}} +pidfile=${sendmail_pidfile:-/var/run/${name}.pid} +procname=${sendmail_procname:-/usr/sbin/${name}} + +CERTDIR=/etc/mail/certs + +case ${sendmail_enable} in +[Nn][Oo][Nn][Ee]) + sendmail_enable="NO" + sendmail_submit_enable="NO" + sendmail_outbound_enable="NO" + sendmail_msp_queue_enable="NO" + ;; +esac + +# If sendmail_enable=yes, don't need submit or outbound daemon +if checkyesno sendmail_enable; then + sendmail_submit_enable="NO" + sendmail_outbound_enable="NO" + _sendmail_run=true +fi + +# If sendmail_submit_enable=yes, don't need outbound daemon +if checkyesno sendmail_submit_enable; then + name="sendmail_submit" + rcvar="sendmail_submit_enable" + sendmail_outbound_enable="NO" + _sendmail_run=true +fi + +if checkyesno sendmail_outbound_enable; then + name="sendmail_outbound" + rcvar="sendmail_outbound_enable" + _sendmail_run=true +fi + +if checkyesno sendmail_msp_queue_enable; then + _sendmail_msp_queue_run=true +else + # Make sure run_rc_command is called at least once. + _sendmail_run=true +fi + +sendmail_cert_create() +{ + cnname="${sendmail_cert_cn:-`hostname`}" + cnname="${cnname:-amnesiac}" + + # based upon: + # http://www.sendmail.org/~ca/email/other/cagreg.html + CAdir=`mktemp -d` && + certpass=`(date; ps ax ; hostname) | md5 -q` + + # make certificate authority + ( cd "$CAdir" && + chmod 700 "$CAdir" && + mkdir certs crl newcerts && + echo "01" > serial && + :> index.txt && + + cat <<-OPENSSL_CNF > openssl.cnf && + RANDFILE = $CAdir/.rnd + [ ca ] + default_ca = CA_default + [ CA_default ] + dir = . + certs = \$dir/certs # Where the issued certs are kept + crl_dir = \$dir/crl # Where the issued crl are kept + database = \$dir/index.txt # database index file. + new_certs_dir = \$dir/newcerts # default place for new certs. + certificate = \$dir/cacert.pem # The CA certificate + serial = \$dir/serial # The current serial number + crlnumber = \$dir/crlnumber # the current crl number + crl = \$dir/crl.pem # The current CRL + private_key = \$dir/cakey.pem + x509_extensions = usr_cert # The extensions to add to the cert + name_opt = ca_default # Subject Name options + cert_opt = ca_default # Certificate field options + default_days = 365 # how long to certify for + default_crl_days= 30 # how long before next CRL + default_md = default # use public key default MD + preserve = no # keep passed DN ordering + policy = policy_anything + [ policy_anything ] + countryName = optional + stateOrProvinceName = optional + localityName = optional + organizationName = optional + organizationalUnitName = optional + commonName = supplied + emailAddress = optional + [ req ] + default_bits = 2048 + default_keyfile = privkey.pem + distinguished_name = req_distinguished_name + attributes = req_attributes + x509_extensions = v3_ca # The extensions to add to the self signed cert + string_mask = utf8only + prompt = no + [ req_distinguished_name ] + countryName = XX + stateOrProvinceName = Some-state + localityName = Some-city + 0.organizationName = Some-org + CN = $cnname + [ req_attributes ] + challengePassword = foobar + unstructuredName = An optional company name + [ usr_cert ] + basicConstraints=CA:FALSE + nsComment = "OpenSSL Generated Certificate" + subjectKeyIdentifier=hash + authorityKeyIdentifier=keyid,issuer + [ v3_req ] + basicConstraints = CA:FALSE + keyUsage = nonRepudiation, digitalSignature, keyEncipherment + [ v3_ca ] + subjectKeyIdentifier=hash + authorityKeyIdentifier=keyid:always,issuer + basicConstraints = CA:true + OPENSSL_CNF + + # though we use a password, the key is discarded and never used + openssl req -batch -passout pass:"$certpass" -new -x509 \ + -keyout cakey.pem -out cacert.pem -days 3650 \ + -config openssl.cnf -newkey rsa:2048 >/dev/null 2>&1 && + + # make new certificate + openssl req -batch -nodes -new -x509 -keyout newkey.pem \ + -out newreq.pem -days 365 -config openssl.cnf \ + -newkey rsa:2048 >/dev/null 2>&1 && + + # sign certificate + openssl x509 -x509toreq -in newreq.pem -signkey newkey.pem \ + -out tmp.pem >/dev/null 2>&1 && + openssl ca -notext -config openssl.cnf \ + -out newcert.pem -keyfile cakey.pem -cert cacert.pem \ + -key "$certpass" -batch -infiles tmp.pem >/dev/null 2>&1 && + + mkdir -p "$CERTDIR" && + chmod 0755 "$CERTDIR" && + chmod 644 newcert.pem cacert.pem && + chmod 600 newkey.pem && + cp -p newcert.pem "$CERTDIR"/host.cert && + cp -p cacert.pem "$CERTDIR"/cacert.pem && + cp -p newkey.pem "$CERTDIR"/host.key && + ln -s cacert.pem "$CERTDIR"/`openssl x509 -hash -noout \ + -in cacert.pem`.0) + + retVal="$?" + rm -rf "$CAdir" + + return "$retVal" +} + +sendmail_precmd() +{ + # check modifications on /etc/mail/aliases + if checkyesno sendmail_rebuild_aliases; then + if [ -f "/etc/mail/aliases.db" ]; then + if [ "/etc/mail/aliases" -nt "/etc/mail/aliases.db" ]; then + echo \ + "${name}: /etc/mail/aliases newer than /etc/mail/aliases.db, regenerating" + /usr/bin/newaliases + fi + else + echo \ + "${name}: /etc/mail/aliases.db not present, generating" + /usr/bin/newaliases + fi + fi + + if checkyesno sendmail_cert_create && [ ! \( \ + -f "$CERTDIR/host.cert" -o -f "$CERTDIR/host.key" -o \ + -f "$CERTDIR/cacert.pem" \) ]; then + if ! openssl version >/dev/null 2>&1; then + warn "OpenSSL not available, but sendmail_cert_create is YES." + else + info Creating certificate for sendmail. + sendmail_cert_create + fi + fi + + if [ ! -f /var/log/sendmail.st ]; then + /usr/bin/install -m 640 -o root -g wheel /dev/null /var/log/sendmail.st + fi +} + +if ${_sendmail_run:-false}; then + run_rc_command "$1" +fi +_ret=$? + +if ${_sendmail_msp_queue_run:-false}; then + name="sendmail_msp_queue" + rcvar="sendmail_msp_queue_enable" + pidfile="${sendmail_msp_queue_pidfile:-/var/spool/clientmqueue/sm-client.pid}" + required_files="/etc/mail/submit.cf" + _rc_restart_done=false + run_rc_command "$1" + _ret=$(( _ret > $? ? _ret : $? )) +fi + +(exit "$_ret") diff --git a/libexec/rc/rc.d/serial b/libexec/rc/rc.d/serial new file mode 100755 index 000000000000..f8ddc7ff30d4 --- /dev/null +++ b/libexec/rc/rc.d/serial @@ -0,0 +1,158 @@ +#!/bin/sh +# +# Copyright (c) 1996 Andrey A. Chernov +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# + +# PROVIDE: serial +# REQUIRE: root +# KEYWORD: nojail + +# Change some defaults for serial devices. +# Standard defaults are: +# dtrwait 300 drainwait `sysctl -n kern.drainwait` +# initial cflag from <sys/ttydefaults.h> = cread cs8 hupcl +# initial iflag, lflag and oflag all 0 +# speed 115200 +# special chars from <sys/ttydefaults.h> +# nothing locked +# except for serial consoles the initial iflag, lflag and oflag are from +# <sys/ttydefaults.h> and clocal is locked on. + +default() { + # Reset everything changed by the other functions to initial defaults. + + dc=$1; shift # device name character + drainwait=`sysctl -n kern.tty_drainwait` + + for i in $* + do + comcontrol /dev/tty${dc}${i} dtrwait 300 drainwait $drainwait + stty < /dev/tty${dc}${i}.init -clocal crtscts hupcl 115200 reprint ^R + stty < /dev/tty${dc}${i}.lock -clocal -crtscts -hupcl 0 + stty < /dev/cua${dc}${i}.init -clocal crtscts hupcl 115200 reprint ^R + stty < /dev/cua${dc}${i}.lock -clocal -crtscts -hupcl 0 + done +} + +maybe() { + # Special settings. + + dc=$1; shift + + for i in $* + do + # Don't use ^R; it breaks bash's ^R when typed ahead. + stty < /dev/tty${dc}${i}.init reprint undef + stty < /dev/cua${dc}${i}.init reprint undef + # Lock clocal off on dialin device for security. + stty < /dev/tty${dc}${i}.lock clocal + # Lock the speeds to use old binaries that don't support them. + # Any legal speed works to lock the initial speed. + stty < /dev/tty${dc}${i}.lock 300 + stty < /dev/cua${dc}${i}.lock 300 + done +} + +modem() { + # Modem that supports CTS and perhaps RTS handshaking. + + dc=$1; shift + + for i in $* + do + # may depend on modem + comcontrol /dev/tty${dc}${i} drainwait 180 + # Lock crtscts on. + # Speed reasonable for V42bis. + stty < /dev/tty${dc}${i}.init crtscts 115200 + stty < /dev/tty${dc}${i}.lock crtscts + stty < /dev/cua${dc}${i}.init crtscts 115200 + stty < /dev/cua${dc}${i}.lock crtscts + done +} + +mouse() { + # Mouse on either callin or callout port. + + dc=$1; shift + + for i in $* + do + # Lock clocal on, hupcl off. + # Standard speed for Microsoft mouse. + stty < /dev/tty${dc}${i}.init clocal -hupcl 1200 + stty < /dev/tty${dc}${i}.lock clocal hupcl + stty < /dev/cua${dc}${i}.init clocal -hupcl 1200 + stty < /dev/cua${dc}${i}.lock clocal hupcl + done +} + +terminal() { + # Terminal that supports CTS and perhaps RTS handshaking + # with the cable or terminal arranged so that DCD is on + # at least while the terminal is on. + # Also works for bidirectional communications to another pc + # provided at most one side runs getty. + # Same as modem() except we want a faster speed and no dtrwait. + + dc=$1; shift + + modem ${dc} $* + for i in $* + do + comcontrol /dev/tty${dc}${i} dtrwait 0 + stty < /dev/tty${dc}${i}.init 115200 + stty < /dev/cua${dc}${i}.init 115200 + done +} + +3wire() { + # 3-wire serial terminals. These don't supply carrier, so + # clocal needs to be set, and crtscts needs to be unset. + + dc=$1; shift + + terminal ${dc} $* + for i in $* + do + stty < /dev/tty${dc}${i}.init clocal -crtscts + stty < /dev/cua${dc}${i}.init clocal -crtscts + done +} + +# Don't use anything from this file unless you have some buggy programs +# that require it. + +# Edit the functions and the examples to suit your system. +# $1 is the device identifier, and the remainder of the line +# lists the device numbers. + +# Initialize assorted 8250-16550 (uart) ports. +# maybe u 0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q r s t u v +# mouse u 2 +# modem u 1 +# terminal u 0 +# 3wire u 0 diff --git a/libexec/rc/rc.d/sshd b/libexec/rc/rc.d/sshd new file mode 100755 index 000000000000..1d2c89cc88a8 --- /dev/null +++ b/libexec/rc/rc.d/sshd @@ -0,0 +1,87 @@ +#!/bin/sh +# +# + +# PROVIDE: sshd +# REQUIRE: LOGIN FILESYSTEMS +# KEYWORD: shutdown + +. /etc/rc.subr + +name="sshd" +desc="Secure Shell Daemon" +rcvar="sshd_enable" +command="/usr/sbin/${name}" +keygen_cmd="sshd_keygen" +start_precmd="sshd_precmd" +reload_precmd="sshd_configtest" +restart_precmd="sshd_configtest" +configtest_cmd="sshd_configtest" +pidfile="/var/run/${name}.pid" +extra_commands="configtest keygen reload" + +: ${sshd_rsa_enable:="yes"} +: ${sshd_ecdsa_enable:="yes"} +: ${sshd_ed25519_enable:="yes"} + +# sshd in a jail would not see other jails. As such exclude it from +# svcj_all_enable="YES" by setting sshd_svcj to NO. This allows to +# enable it in rc.conf. +: ${sshd_svcj:="NO"} +: ${sshd_svcj_options:="net_basic"} + +sshd_keygen_alg() +{ + local alg=$1 + local ALG="$(echo $alg | tr a-z A-Z)" + local keyfile + + if ! checkyesno "sshd_${alg}_enable" ; then + return 0 + fi + + case $alg in + rsa|ecdsa|ed25519) + keyfile="/etc/ssh/ssh_host_${alg}_key" + ;; + *) + return 1 + ;; + esac + + if [ -f "${keyfile}" ] ; then + info "$ALG host key exists." + return 0 + fi + + if [ ! -x /usr/bin/ssh-keygen ] ; then + warn "/usr/bin/ssh-keygen does not exist." + return 1 + fi + + echo "Generating $ALG host key." + /usr/bin/ssh-keygen -q -t $alg -f "$keyfile" -N "" + /usr/bin/ssh-keygen -l -f "$keyfile.pub" +} + +sshd_keygen() +{ + sshd_keygen_alg rsa + sshd_keygen_alg ecdsa + sshd_keygen_alg ed25519 +} + +sshd_configtest() +{ + echo "Performing sanity check on ${name} configuration." + eval ${command} ${sshd_flags} -t +} + +sshd_precmd() +{ + run_rc_command keygen + run_rc_command configtest +} + +load_rc_config $name +run_rc_command "$1" diff --git a/libexec/rc/rc.d/statd b/libexec/rc/rc.d/statd new file mode 100755 index 000000000000..3f2678af2940 --- /dev/null +++ b/libexec/rc/rc.d/statd @@ -0,0 +1,33 @@ +#!/bin/sh +# +# FreeBSD History: src/etc/rc.d/nfslocking,v 1.11 2004/10/07 13:55:26 mtm Exp +# + +# PROVIDE: statd +# REQUIRE: nfsclient rpcbind +# BEFORE: DAEMON +# KEYWORD: nojail shutdown + +. /etc/rc.subr + +name="statd" +desc="host status monitoring daemon" +rcvar=rpc_statd_enable +command="/usr/sbin/rpc.${name}" +start_precmd='statd_precmd' + +: ${statd_svcj_options:="net_basic"} + +# Make sure that we are either an NFS client or server, and that we get +# the correct flags from rc.conf(5). +# +statd_precmd() +{ + force_depend rpcbind || return 1 +} + +load_rc_config $name + +rc_flags=${rpc_statd_flags} + +run_rc_command $1 diff --git a/libexec/rc/rc.d/static_arp b/libexec/rc/rc.d/static_arp new file mode 100755 index 000000000000..42db3c2c8fff --- /dev/null +++ b/libexec/rc/rc.d/static_arp @@ -0,0 +1,77 @@ +#!/bin/sh +# +# Copyright (c) 2009 Xin LI <delphij@FreeBSD.org> +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# Configure static ARP table +# +# + +# PROVIDE: static_arp +# REQUIRE: netif +# KEYWORD: nojailvnet + +. /etc/rc.subr +. /etc/network.subr + +name="static_arp" +desc="Static ARP Configuration" +start_cmd="static_arp_start" +stop_cmd="static_arp_stop" + +static_arp_start() +{ + local e arp_args + + if [ -n "${static_arp_pairs}" ]; then + echo -n 'Binding static ARP pair(s):' + for e in ${static_arp_pairs}; do + echo -n " ${e}" + eval arp_args=\$static_arp_${e} + arp -S ${arp_args} >/dev/null 2>&1 + done + echo '.' + fi +} + +static_arp_stop() +{ + local e arp_args + + if [ -n "${static_arp_pairs}" ]; then + echo -n 'Unbinding static ARP pair(s):' + for e in ${static_arp_pairs}; do + echo -n " ${e}" + eval arp_args=\$static_arp_${e} + arp -d ${arp_args%%[ ]*} > /dev/null 2>&1 + done + echo '.' + fi +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +statc_arp_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/static_ndp b/libexec/rc/rc.d/static_ndp new file mode 100755 index 000000000000..e66c4a0080c3 --- /dev/null +++ b/libexec/rc/rc.d/static_ndp @@ -0,0 +1,76 @@ +#!/bin/sh +# +# Copyright (c) 2011 Xin LI <delphij@FreeBSD.org> +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# Configure static NDP table +# +# + +# PROVIDE: static_ndp +# REQUIRE: netif +# KEYWORD: nojailvnet + +. /etc/rc.subr +. /etc/network.subr + +name="static_ndp" +start_cmd="static_ndp_start" +stop_cmd="static_ndp_stop" + +static_ndp_start() +{ + local e ndp_args + + if [ -n "${static_ndp_pairs}" ]; then + echo -n 'Binding static NDP pair(s):' + for e in ${static_ndp_pairs}; do + echo -n " ${e}" + eval ndp_args=\$static_ndp_${e} + ndp -s ${ndp_args} >/dev/null 2>&1 + done + echo '.' + fi +} + +static_ndp_stop() +{ + local e ndp_args + + if [ -n "${static_ndp_pairs}" ]; then + echo -n 'Unbinding static NDP pair(s):' + for e in ${static_ndp_pairs}; do + echo -n " ${e}" + eval ndp_args=\$static_ndp_${e} + ndp -d ${ndp_args%%[ ]*} > /dev/null 2>&1 + done + echo '.' + fi +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +static_ndp_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/stf b/libexec/rc/rc.d/stf new file mode 100755 index 000000000000..94a585693982 --- /dev/null +++ b/libexec/rc/rc.d/stf @@ -0,0 +1,82 @@ +#!/bin/sh +# + +# PROVIDE: stf +# REQUIRE: netif +# KEYWORD: nojail + +. /etc/rc.subr +. /etc/network.subr + +name="stf" +desc="6to4 tunnel interface" +start_cmd="stf_up" +stop_cmd="stf_down" + +stf_up() +{ + case ${stf_interface_ipv4addr} in + [Nn][Oo] | '') + ;; + *) + # assign IPv6 addr and interface route for 6to4 interface + stf_prefixlen=$((16+${stf_interface_ipv4plen:-0})) + OIFS="$IFS" + IFS=".$IFS" + set ${stf_interface_ipv4addr} + IFS="$OIFS" + hexfrag1=`hexprint $(($1*256 + $2))` + hexfrag2=`hexprint $(($3*256 + $4))` + ipv4_in_hexformat="${hexfrag1}:${hexfrag2}" + case ${stf_interface_ipv6_ifid} in + [Aa][Uu][Tt][Oo] | '') + for i in ${ipv6_network_interfaces}; do + laddr=`network6_getladdr ${i}` + case ${laddr} in + '') + ;; + *) + break + ;; + esac + done + stf_interface_ipv6_ifid=`expr "${laddr}" : \ + 'fe80::\(.*\)%\(.*\)'` + case ${stf_interface_ipv6_ifid} in + '') + stf_interface_ipv6_ifid=0:0:0:1 + ;; + esac + ;; + esac + echo "Configuring 6to4 tunnel interface: stf0." + ifconfig stf0 create >/dev/null 2>&1 + ifconfig stf0 inet6 2002:${ipv4_in_hexformat}:${stf_interface_ipv6_slaid:-0}:${stf_interface_ipv6_ifid} \ + prefixlen ${stf_prefixlen} + check_startmsgs && /sbin/ifconfig stf0 + + # disallow packets to malicious 6to4 prefix + route add -inet6 2002:e000:: -prefixlen 20 ::1 -reject + route add -inet6 2002:7f00:: -prefixlen 24 ::1 -reject + route add -inet6 2002:0000:: -prefixlen 24 ::1 -reject + route add -inet6 2002:ff00:: -prefixlen 24 ::1 -reject + ;; + esac +} + +stf_down() +{ + echo "Removing 6to4 tunnel interface: stf0." + ifconfig stf0 destroy + route delete -inet6 2002:e000:: -prefixlen 20 ::1 + route delete -inet6 2002:7f00:: -prefixlen 24 ::1 + route delete -inet6 2002:0000:: -prefixlen 24 ::1 + route delete -inet6 2002:ff00:: -prefixlen 24 ::1 +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +stf_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/swap b/libexec/rc/rc.d/swap new file mode 100755 index 000000000000..f7663fc422bf --- /dev/null +++ b/libexec/rc/rc.d/swap @@ -0,0 +1,21 @@ +#!/bin/sh +# +# + +# PROVIDE: swap +# REQUIRE: disks +# KEYWORD: nojail shutdown + +. /etc/rc.subr + +name="swap" +desc="Setup swap space" +start_cmd='/sbin/swapon -aq' +stop_cmd=':' + +load_rc_config $name + +# doesn't make sense to run in a svcj: privileged operations +swap_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/swaplate b/libexec/rc/rc.d/swaplate new file mode 100755 index 000000000000..da86cb2bf686 --- /dev/null +++ b/libexec/rc/rc.d/swaplate @@ -0,0 +1,21 @@ +#!/bin/sh +# +# + +# PROVIDE: swaplate +# REQUIRE: mountlate +# KEYWORD: nojail shutdown + +. /etc/rc.subr + +name="swaplate" +desc="Setup late swap space" +start_cmd='/sbin/swapon -aLq' +stop_cmd='/sbin/swapoff -aLq' + +load_rc_config swap + +# doesn't make sense to run in a svcj: privileged operations +swaplate_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/syscons b/libexec/rc/rc.d/syscons new file mode 100755 index 000000000000..b01b648ace6e --- /dev/null +++ b/libexec/rc/rc.d/syscons @@ -0,0 +1,406 @@ +#!/bin/sh - +# +# Copyright (c) 2000 The FreeBSD Project +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# + +# PROVIDE: syscons +# REQUIRE: LOGIN +# KEYWORD: nojail + +. /etc/rc.subr + +name="syscons" +desc="Configure the system console" +extra_commands="setkeyboard" +setkeyboard_cmd="syscons_setkeyboard" +start_precmd="syscons_precmd" +start_cmd="syscons_start" +stop_cmd=":" + +# stdin must be redirected because it might be for a serial console +# +kbddev=/dev/ttyv0 +viddev=/dev/ttyv0 + +_sc_config= +_sc_console= +_sc_initdone= +_sc_keymap_msg= +_sc_bootmethod= +sc_init() +{ + local bootmethod + + if [ -z "${_sc_initdone}" ]; then + if [ -z "${_sc_console}" ]; then + if [ x`sysctl -n kern.vty` = x"vt" ]; then + _sc_console="vt" + else + _sc_console="syscons" + fi + _sc_config="${_sc_console}" + fi + if [ -z "${_sc_bootmethod}" ]; then + bootmethod=$(sysctl -qn machdep.bootmethod) + case ${bootmethod} in + UEFI) + _sc_bootmethod="uefi" + ;; + BIOS) + _sc_bootmethod="bios" + ;; + PVH) + _sc_bootmethod="pvh" + ;; + *) + _sc_bootmethod="uefi" # Default to UEFI + ;; + esac + fi + echo -n "Configuring ${_sc_config}:" + _sc_initdone=yes + fi +} + +# syscons to vt migration helper +lookup_keymap_for_vt() +{ + keymap=`basename $1 .kbd` + case $keymap in +hy.armscii-8) echo am;; +be.iso.acc) echo be.acc;; +be.iso) echo be;; +bg.bds.ctrlcaps) echo bg.bds;; +bg.phonetic.ctrlcaps) echo bg.phonetic;; +br275.iso.acc) echo br;; +br275.*) echo br.noacc;; +by.*) echo by;; +fr_CA.iso.acc) echo ca-fr;; +swissgerman.macbook.acc) echo ch.macbook.acc;; +swissgerman.iso.acc) echo ch.acc;; +swissgerman.*) echo ch;; +swissfrench.iso.acc) echo ch-fr.acc;; +swissfrench.*) echo ch-fr;; +ce.iso2) echo centraleuropean.qwerty;; +colemak.iso15.acc) echo colemak.acc;; +cs.*|cz.*) echo cz;; +german.iso.acc) echo de.acc;; +german.*) echo de;; +danish.iso.acc) echo dk.acc;; +danish.iso.macbook) echo dk.macbook;; +danish.*) echo dk;; +estonian.*) echo ee;; +spanish.dvorak) echo es.dvorak;; +spanish.iso*.acc) echo es.acc;; +spanish.iso) echo es;; +finnish.*) echo fi;; +fr.macbook.acc) echo fr.macbook;; +fr.iso.acc) echo fr.acc;; +fr.iso) echo fr;; +el.iso07) echo gr;; +gr.us101.acc) echo gr.101.acc;; +hr.iso) echo hr;; +hu.iso2.101keys) echo hu.101;; +hu.iso2.102keys) echo hu.102;; +iw.iso8) echo il;; +icelandic.iso.acc) echo is.acc;; +icelandic.iso) echo is;; +it.iso) echo it;; +jp.106x) echo jp.capsctrl;; +jp.106) echo jp;; +kk.pt154.io) echo kz.io;; +kk.pt154.kst) echo kz.kst;; +latinamerican.iso.acc) echo latinamerican.acc;; +lt.iso4) echo lt;; +norwegian.iso) echo no;; +norwegian.dvorak) echo no.dvorak;; +dutch.iso.acc) echo nl;; +eee_nordic) echo nordic.asus-eee;; +pl_PL.dvorak) echo pl.dvorak;; +pl_PL.ISO8859-2) echo pl;; +pt.iso.acc) echo pt.acc;; +pt.iso) echo pt;; +ru.koi8-r.shift) echo ru.shift;; +ru.koi8-r.win) echo ru.win;; +ru.*) echo ru;; +swedish.*) echo se;; +si.iso) echo si;; +sk.iso2) echo sk;; +tr.iso9.q) echo tr;; +ua.koi8-u.shift.alt) echo ua.shift.alt;; +ua.*) echo ua;; +uk.*-ctrl) echo uk.capsctrl;; +uk.dvorak) echo uk.dvorak;; +uk.*) echo uk;; +us.iso.acc) echo us.acc;; +us.pc-ctrl) echo us.ctrl;; +us.iso) echo us;; + esac +} + +kbdcontrol_load_keymap() +{ + errmsg=`kbdcontrol < ${kbddev} -l ${keymap} 2>&1` + if [ -n "${errmsg}" -a "${_sc_console}" = "vt" ]; then + _sc_keymap_msg="${errmsg}" + keymap_vt=`lookup_keymap_for_vt ${keymap}` + if [ -n "${keymap_vt}" ]; then + errmsg=`kbdcontrol < ${kbddev} -l ${keymap_vt} 2>&1` + if [ -z "${errmsg}" ]; then + _sc_keymap_msg="New keymap: In /etc/rc.conf replace 'keymap=${keymap}' by 'keymap=${keymap_vt}'" + fi + else + _sc_keymap_msg="No replacement found for keymap '${keymap}'. +You may try to convert your keymap file using 'convert-keymap.pl', which is +part of the system sources and located in /usr/src/tools/tools/vt/keymaps/" + fi + fi +} + +# helper +syscons_configure_keyboard() +{ + # keymap + # + case ${keymap} in + NO | '') + ;; + *) + sc_init + echo -n ' keymap'; kbdcontrol_load_keymap + ;; + esac + + # keyrate + # + case ${keyrate} in + [Nn][Oo] | '') + ;; + *) + sc_init + echo -n ' keyrate'; kbdcontrol < ${kbddev} -r ${keyrate} + ;; + esac + + # keybell + # + case ${keybell} in + [Nn][Oo] | '') + ;; + *) + sc_init + echo -n ' keybell'; kbdcontrol < ${kbddev} -b ${keybell} + ;; + esac + + # change function keys + # + case ${keychange} in + [Nn][Oo] | '') + ;; + *) + sc_init + echo -n ' keychange' + set -- ${keychange} + while [ $# -gt 0 ]; do + kbdcontrol <${kbddev} -f "$1" "$2" + shift; shift + done + ;; + esac + + # set this keyboard mode for all virtual terminals + # + if [ -n "${allscreens_kbdflags}" ]; then + sc_init + echo -n ' allscreens_kbd' + for ttyv in /dev/ttyv*; do + [ "$ttyv" = '/dev/ttyv*' ] && break + kbdcontrol ${allscreens_kbdflags} < ${ttyv} > ${ttyv} 2>&1 + done + fi +} + +syscons_setkeyboard() +{ + kbd=$1 + + if [ -z "${kbd}" ]; then + return 1 + fi + + # Check if the kbdmux(4) is the current active keyboard + kbdcontrol -i < ${kbddev} | grep kbdmux > /dev/null 2>&1 + if [ $? -ne 0 ]; then + kbdcontrol -k ${kbd} < ${kbddev} > /dev/null 2>&1 + fi + + _sc_config="keyboard" + syscons_configure_keyboard + + # Terminate keyboard configuration line and reset global variables. + # + if [ -n "${_sc_initdone}" ]; then + echo '.' + _sc_config="${_sc_console}" + _sc_initdone= + fi +} + +syscons_precmd() +{ + if [ ! -c $kbddev ] + then + return 1 + fi + return 0 +} + +syscons_bios_start() +{ + # cursor type + # + case ${cursor} in + [Nn][Oo] | '') + ;; + *) + sc_init + echo -n ' cursor'; vidcontrol < ${viddev} -c ${cursor} + ;; + esac + + # screen mapping + # + case ${scrnmap} in + [Nn][Oo] | '') + ;; + *) + sc_init + echo -n ' scrnmap'; vidcontrol < ${viddev} -l ${scrnmap} + ;; + esac + + # blank time + # + case ${blanktime} in + [Nn][Oo] | '') + ;; + *) + sc_init + echo -n ' blanktime'; vidcontrol < ${viddev} -t ${blanktime} + ;; + esac + + # screen saver + # + case ${saver} in + [Nn][Oo] | '') + ;; + *) + sc_init + echo -n ' screensaver' + for i in `kldstat | awk '$5 ~ "_saver\.ko$" { print $5 }'`; do + kldunload ${i} + done + load_kld -e _saver ${saver}_saver + ;; + esac +} + +syscons_start() +{ + # keyboard + # + if [ -n "${keyboard}" ]; then + syscons_setkeyboard ${keyboard} + fi + + syscons_configure_keyboard + + if [ "${_sc_bootmethod}" = "bios" ]; then + syscons_bios_start + fi + + # font 8x16 + # + case ${font8x16} in + [Nn][Oo] | '') + ;; + *) + sc_init + echo -n ' font8x16'; vidcontrol < ${viddev} -f 8x16 ${font8x16} + ;; + esac + + # font 8x14 + # + case ${font8x14} in + [Nn][Oo] | '') + ;; + *) + sc_init + echo -n ' font8x14'; vidcontrol < ${viddev} -f 8x14 ${font8x14} + ;; + esac + + # font 8x8 + # + case ${font8x8} in + [Nn][Oo] | '') + ;; + *) + sc_init + echo -n ' font8x8'; vidcontrol < ${viddev} -f 8x8 ${font8x8} + ;; + esac + + # set this mode for all virtual screens + # + if [ -n "${allscreens_flags}" ]; then + sc_init + echo -n ' allscreens' + for ttyv in /dev/ttyv*; do + [ "$ttyv" = '/dev/ttyv*' ] && break + vidcontrol ${allscreens_flags} < ${ttyv} > ${ttyv} 2>&1 + done + fi + + [ -n "${_sc_initdone}" ] && echo '.' + if [ -n "${_sc_keymap_msg}" ]; then + echo + echo "WARNING:" + echo "${_sc_keymap_msg}." + echo + fi +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +syscons_svcj="NO" + +run_rc_command $* + diff --git a/libexec/rc/rc.d/sysctl b/libexec/rc/rc.d/sysctl new file mode 100755 index 000000000000..0ca753b530af --- /dev/null +++ b/libexec/rc/rc.d/sysctl @@ -0,0 +1,41 @@ +#!/bin/sh +# +# + +# PROVIDE: sysctl + +. /etc/rc.subr + +name="sysctl" +desc="Set sysctl variables from /etc/sysctl.conf and /etc/sysctl.conf.local" +command="/sbin/sysctl" +stop_cmd=":" +start_cmd="sysctl_start" +reload_cmd="sysctl_start last" +lastload_cmd="sysctl_start last" +extra_commands="reload lastload" + +sysctl_start() +{ + case $1 in + last) + command_args="-f" + ;; + *) + command_args="-i -f" + ;; + esac + + for _f in /etc/sysctl.conf /etc/sysctl.conf.local; do + if [ -r ${_f} ]; then + ${command} ${command_args} ${_f} > /dev/null + fi + done +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +sysctl_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/sysctl_lastload b/libexec/rc/rc.d/sysctl_lastload new file mode 100755 index 000000000000..6d97561ed2c0 --- /dev/null +++ b/libexec/rc/rc.d/sysctl_lastload @@ -0,0 +1,21 @@ +#!/bin/sh +# +# + +# PROVIDE: sysctl_lastload +# REQUIRE: LOGIN +# BEFORE: jail + +. /etc/rc.subr + +name="sysctl_lastload" +desc="Last chance to set sysctl variables that failed the first time." +start_cmd="/etc/rc.d/sysctl lastload" +stop_cmd=":" + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +sysctl_lastload_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/syslogd b/libexec/rc/rc.d/syslogd new file mode 100755 index 000000000000..8d0ff952a6b2 --- /dev/null +++ b/libexec/rc/rc.d/syslogd @@ -0,0 +1,75 @@ +#!/bin/sh +# +# + +# netif is required for lo0 because syslogd tries to open a local socket +# +# PROVIDE: syslogd +# REQUIRE: mountcritremote FILESYSTEMS newsyslog netif +# BEFORE: SERVERS + +. /etc/rc.subr + +name="syslogd" +desc="System log daemon" +rcvar="syslogd_enable" +pidfile="/var/run/syslog.pid" +command="/usr/sbin/${name}" +required_files="/etc/syslog.conf" +start_precmd="syslogd_precmd" +extra_commands="reload" + +sockfile="/var/run/syslogd.sockets" +evalargs="rc_flags=\"\`set_socketlist\` \$rc_flags\"" + +: ${syslogd_svcj_options:="net_basic"} + +syslogd_precmd() +{ + local _l _ldir + + # Transitional symlink for old binaries + # + if [ ! -L /dev/log ] && ! check_jail jailed; then + ln -sf /var/run/log /dev/log + fi + rm -f /var/run/log + + # Create default list of syslog sockets to watch + # + ( umask 022 ; > $sockfile ) + + # If running named(8) or ntpd(8) chrooted, added appropriate + # syslog socket to list of sockets to watch. + # + for _l in $altlog_proglist; do + eval _ldir=\$${_l}_chrootdir + if checkyesno ${_l}_enable && [ -n "$_ldir" ]; then + echo "${_ldir}/var/run/log" >> $sockfile + fi + done + + # If other sockets have been provided, change run_rc_command()'s + # internal copy of $syslogd_flags to force use of specific + # syslogd sockets. + # + if [ -s $sockfile ]; then + echo "/var/run/log" >> $sockfile + eval $evalargs + fi + + return 0 +} + +set_socketlist() +{ + local _s _socketargs + + _socketargs= + for _s in `cat $sockfile | tr '\n' ' '` ; do + _socketargs="-l $_s $_socketargs" + done + echo $_socketargs +} +load_rc_config $name +run_rc_command "$1" diff --git a/libexec/rc/rc.d/sysvipc b/libexec/rc/rc.d/sysvipc new file mode 100755 index 000000000000..ce38db598641 --- /dev/null +++ b/libexec/rc/rc.d/sysvipc @@ -0,0 +1,29 @@ +#!/bin/sh +# +# + +# PROVIDE: sysvipc +# REQUIRE: kldxref +# KEYWORD: nojail + +. /etc/rc.subr + +name="sysvipc" +desc="Load SysV IPC modules" +rcvar="sysvipc_enable" +start_cmd="${name}_start" +stop_cmd=":" + +sysvipc_start() +{ + load_kld sysvmsg + load_kld sysvsem + load_kld sysvshm +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: privileged operations +sysvipc_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/tlsclntd b/libexec/rc/rc.d/tlsclntd new file mode 100755 index 000000000000..5688c7ff53a2 --- /dev/null +++ b/libexec/rc/rc.d/tlsclntd @@ -0,0 +1,22 @@ +#!/bin/sh +# +# + +# PROVIDE: tlsclntd +# REQUIRE: NETWORKING root mountcritlocal sysctl +# BEFORE: nfscbd +# KEYWORD: nojail shutdown + +. /etc/rc.subr + +name="tlsclntd" +desc="NFS over TLS client side daemon" +rcvar="tlsclntd_enable" +command="/usr/sbin/rpc.${name}" +pidfile="/var/run/rpc.${name}.pid" + +: ${tlsclntd_svcj_options:="net_basic"} + +load_rc_config $name + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/tlsservd b/libexec/rc/rc.d/tlsservd new file mode 100755 index 000000000000..989e17996043 --- /dev/null +++ b/libexec/rc/rc.d/tlsservd @@ -0,0 +1,26 @@ +#!/bin/sh +# +# + +# PROVIDE: tlsservd +# REQUIRE: NETWORKING root mountcritlocal sysctl +# BEFORE: nfsd +# KEYWORD: nojailvnet shutdown + +. /etc/rc.subr + +name="tlsservd" +desc="NFS over TLS server side daemon" +rcvar="tlsservd_enable" +command="/usr/sbin/rpc.${name}" + +: ${tlsservd_svcj_options:="net_basic nfsd"} + +pidfile="/var/run/rpc.${name}.pid" +required_files="/etc/rpc.tlsservd/cert.pem /etc/rpc.tlsservd/certkey.pem" +extra_commands="reload" + + +load_rc_config $name + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/tmp b/libexec/rc/rc.d/tmp new file mode 100755 index 000000000000..cc970816e45c --- /dev/null +++ b/libexec/rc/rc.d/tmp @@ -0,0 +1,81 @@ +#!/bin/sh +# +# Copyright (c) 1999 Matt Dillon +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# + +# PROVIDE: tmp +# REQUIRE: mountcritlocal + +. /etc/rc.subr + +name="tmp" +desc="Configure tmpfs" +stop_cmd=':' + +load_rc_config $name + +# doesn't make sense to run in a svcj: mounting +tmp_svcj="NO" + +mount_tmpmfs() +{ + while read line; do + case $line in + /dev/md[0-9]*\ /tmp) + return;; + esac + done <<*EOF +$(df /tmp) +*EOF + mount_md ${tmpsize} /tmp "${tmpmfs_flags}" + chmod 01777 /tmp +} + +# If we do not have a writable /tmp, create a memory +# filesystem for /tmp. If /tmp is a symlink (e.g. to /var/tmp, +# then it should already be writable). +# +case "${tmpmfs}" in +[Aa][Uu][Tt][Oo]) + _tmpdir=/tmp/.diskless.$(dd if=/dev/random bs=32 count=1 status=none | sha256) + if mkdir -m 0700 ${_tmpdir}; then + rmdir ${_tmpdir} + else + if [ -h /tmp ]; then + echo "*** /tmp is a symlink to a non-writable area!" + echo "dropping into shell, ^D to continue anyway." + /bin/sh + else + mount_tmpmfs + fi + fi + ;; +*) + if checkyesno tmpmfs; then + mount_tmpmfs + fi + ;; +esac diff --git a/libexec/rc/rc.d/ubthidhci b/libexec/rc/rc.d/ubthidhci new file mode 100755 index 000000000000..9792a0e3530d --- /dev/null +++ b/libexec/rc/rc.d/ubthidhci @@ -0,0 +1,43 @@ +#!/bin/sh +# +# + +# PROVIDE: ubthidhci +# REQUIRE: DAEMON +# BEFORE: bluetooth +# KEYWORD: nojail shutdown + +. /etc/rc.subr + +name="ubthidhci" +rcvar="ubthidhci_enable" +command="/usr/sbin/usbconfig" +start_precmd="ubthidhci_prestart" + +ubthidhci_prestart() +{ + + if [ -z ${ubthidhci_busnum} ]; then + warn ubthidhci_busnum is not set + return 1 + fi + if [ -z ${ubthidhci_addr} ]; then + warn ubthidhci_addr is not set + return 1 + fi +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: nojail keyword +ubthidhci_svcj="NO" + +# +# We discard the output because: +# 1) we don't want it to show up during boot; and +# 2) the request usually returns an error, but that doesn't mean it failed +# +# NB: 0x40 is UT_VENDOR +command_args="-u ${ubthidhci_busnum} -a ${ubthidhci_addr} do_request 0x40 0 0 0 0 > /dev/null 2>&1" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/ugidfw b/libexec/rc/rc.d/ugidfw new file mode 100755 index 000000000000..13b20c45ee29 --- /dev/null +++ b/libexec/rc/rc.d/ugidfw @@ -0,0 +1,55 @@ +#!/bin/sh +# + +# PROVIDE: ugidfw +# REQUIRE: FILESYSTEMS +# BEFORE: LOGIN +# KEYWORD: nojail shutdown + +. /etc/rc.subr + +name="ugidfw" +desc="Firewall-like access controls for file system objects" +rcvar="ugidfw_enable" +start_cmd="ugidfw_start" +stop_cmd="ugidfw_stop" +required_modules="mac_bsdextended" + +ugidfw_load() +{ + if [ -r "${bsdextended_script}" ]; then + . "${bsdextended_script}" + fi +} + +ugidfw_start() +{ + [ -z "${bsdextended_script}" ] && bsdextended_script=/etc/rc.bsdextended + + if [ -r "${bsdextended_script}" ]; then + ugidfw_load + echo "MAC bsdextended rules loaded." + fi +} + +ugidfw_stop() +{ + local rulecount + + # Disable the policy + # + # Check for the existence of rules and flush them if needed. + rulecount=$(sysctl -in security.mac.bsdextended.rule_count) + if [ ${rulecount:-0} -gt 0 ]; then + ugidfw list | sed -n '2,$p' | cut -d ' ' -f 1 | sort -r -n | + xargs -n 1 ugidfw remove + echo "MAC bsdextended rules flushed." + fi +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: nojail keyword +ugidfw_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/utx b/libexec/rc/rc.d/utx new file mode 100755 index 000000000000..d7149f66e68b --- /dev/null +++ b/libexec/rc/rc.d/utx @@ -0,0 +1,23 @@ +#!/bin/sh +# +# + +# PROVIDE: utx +# REQUIRE: DAEMON FILESYSTEMS +# BEFORE: LOGIN +# KEYWORD: shutdown + +. /etc/rc.subr + +name="utx" +desc="Manage the user accounting database" +rcvar="utx_enable" +start_cmd="utx boot" +stop_cmd="utx shutdown" + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +utx_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/var b/libexec/rc/rc.d/var new file mode 100755 index 000000000000..b4939e2bc4a0 --- /dev/null +++ b/libexec/rc/rc.d/var @@ -0,0 +1,114 @@ +#!/bin/sh +# +# Copyright (c) 1999 Matt Dillon +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# + +# PROVIDE: var +# REQUIRE: mountcritlocal + +# NFS /var is not supported, unless NFS /var is part of diskless NFS / + +. /etc/rc.subr + +name="var" +desc="Populate /var directory" +stop_cmd=':' + +load_rc_config $name + +# doesn't make sense to run in a svcj: mounting +var_svcj="NO" + +populate_var() +{ + /usr/sbin/mtree -deiU -f /etc/mtree/BSD.var.dist -p /var > /dev/null + case ${sendmail_enable} in + [Nn][Oo][Nn][Ee]) + ;; + *) + /usr/sbin/mtree -deiU -f /etc/mtree/BSD.sendmail.dist -p / > /dev/null + ;; + esac +} + +# If we do not have a writable /var, create a memory filesystem for /var +# unless told otherwise by rc.conf. We don't have /usr yet so use mkdir +# instead of touch to test. We want mount to record its mounts so we +# have to make sure /var/db exists before doing the mount -a. +# +case "${varmfs}" in +[Yy][Ee][Ss]) + mount_md ${varsize} /var "${varmfs_flags}" + ;; +[Nn][Oo]) + ;; +*) + if /bin/mkdir -p /var/.diskless 2> /dev/null; then + rmdir /var/.diskless + else + mount_md ${varsize} /var "${varmfs_flags}" + fi +esac + + +# If we have an empty looking /var, populate it, but only if we have +# /usr available. Hopefully, we'll eventually find a workaround, but +# in realistic diskless setups, we're probably ok. +case "${populate_var}" in +[Yy][Ee][Ss]) + populate_var + ;; +[Nn][Oo]) + exit 0 + ;; +*) + if [ -d /var/run -a -d /var/db -a -d /var/empty ] ; then + true + elif [ -x /usr/sbin/mtree ] ; then + populate_var + else + # We need mtree to populate /var so try mounting /usr. + # If this does not work, we can not boot so it is OK to + # try to mount out of order. + mount /usr + if [ ! -x /usr/sbin/mtree ] ; then + exit 1 + else + populate_var + fi + fi + ;; +esac + +# Make sure we have /var/log/utx.lastlogin and /var/log/utx.log files +if [ ! -f /var/log/utx.lastlogin ]; then + cp /dev/null /var/log/utx.lastlogin + chmod 644 /var/log/utx.lastlogin +fi +if [ ! -f /var/log/utx.log ]; then + cp /dev/null /var/log/utx.log + chmod 644 /var/log/utx.log +fi diff --git a/libexec/rc/rc.d/var_run b/libexec/rc/rc.d/var_run new file mode 100755 index 000000000000..9a3732f593b6 --- /dev/null +++ b/libexec/rc/rc.d/var_run @@ -0,0 +1,50 @@ +#!/bin/sh + +# PROVIDE: var_run +# REQUIRE: mountcritlocal +# BEFORE: cleanvar +# KEYWORD: shutdown + +. /etc/rc.subr + +name=var_run +rcvar=var_run_enable +extra_commands="load save" +start_cmd="_var_run_start" +load_cmd="_var_run_load" +save_cmd="_var_run_save" +stop_cmd="_var_run_stop" + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +var_run_svcj="NO" + +_var_run_load() { + if [ -f "${var_run_mtree}" ] ; then + mtree -U -i -q -f "${var_run_mtree}" -p /var/run > /dev/null + fi +} + +_var_run_save() { + if ! [ -d "${var_run_mtree%/*}" ]; then + mkdir -p "${var_run_mtree%/*}" + fi + mtree -dcbj -p /var/run > "${var_run_mtree}" +} + +_var_run_start() { + if df -ttmpfs /var/run > /dev/null 2>&1; then + _var_run_load + fi +} + +_var_run_stop() { + if checkyesno var_run_autosave; then + if df -ttmpfs /var/run > /dev/null 2>&1; then + _var_run_save + fi + fi +} + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/virecover b/libexec/rc/rc.d/virecover new file mode 100755 index 000000000000..d6f9f8bdef9a --- /dev/null +++ b/libexec/rc/rc.d/virecover @@ -0,0 +1,69 @@ +#!/bin/sh +# +# + +# PROVIDE: virecover +# REQUIRE: mountcritremote ldconfig +# BEFORE: DAEMON +# +# XXX: should require `mail'! + +. /etc/rc.subr + +name="virecover" +desc="Recover crashed vi sessions" +rcvar="virecover_enable" +stop_cmd=":" +start_cmd="virecover_start" + +virecover_start() +{ + [ -d /var/tmp/vi.recover ] || return + find /var/tmp/vi.recover ! -type f -a ! -type d -delete + vibackup=`echo /var/tmp/vi.recover/vi.*` + if [ "${vibackup}" != '/var/tmp/vi.recover/vi.*' ]; then + echo -n 'Recovering vi editor sessions:' + for i in /var/tmp/vi.recover/vi.*; do + # Only test files that are readable. + if [ ! -r "${i}" ]; then + continue + fi + + # Unmodified nvi editor backup files either have the + # execute bit set or are zero length. Delete them. + if [ -x "${i}" -o ! -s "${i}" ]; then + rm -f "${i}" + fi + done + + # It is possible to get incomplete recovery files, if the editor + # crashes at the right time. + virecovery=`echo /var/tmp/vi.recover/recover.*` + if [ "${virecovery}" != "/var/tmp/vi.recover/recover.*" ]; then + for i in /var/tmp/vi.recover/recover.*; do + # Only test files that are readable. + if [ ! -r "${i}" ]; then + continue + fi + + # Delete any recovery files that are zero length, + # corrupted, or that have no corresponding backup file. + # Else send mail to the user. + recfile=`awk '/^X-vi-recover-path:/{print $2}' < "${i}"` + if [ -n "${recfile}" -a -s "${recfile}" ]; then + sendmail -t < "${i}" + else + rm -f "${i}" + fi + done + fi + echo '.' + fi +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +virecover_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/virtual_oss b/libexec/rc/rc.d/virtual_oss new file mode 100644 index 000000000000..b9c830617385 --- /dev/null +++ b/libexec/rc/rc.d/virtual_oss @@ -0,0 +1,119 @@ +#!/bin/sh + +# PROVIDE: virtual_oss +# REQUIRE: NETWORKING kld ldconfig +# BEFORE: LOGIN +# KEYWORD: shutdown + +. /etc/rc.subr + +name="virtual_oss" +desc="virtual_oss device manager" +rcvar="${name}_enable" + +command="/usr/sbin/${name}" +command_args="-B" + +load_rc_config "$name" +start_precmd="${name}_precmd" +start_cmd="${name}_start" +stop_cmd="${name}_stop" +status_cmd="${name}_status" + +configs= +pidpath="/var/run/${name}" +virtual_oss_default_args="\ + -S \ + -C 2 \ + -c 2 \ + -r 48000 \ + -b 24 \ + -s 8ms \ + -i 8 \ + -f /dev/dsp \ + -d dsp \ + -t vdsp.ctl" + +# Set to NO by default. Set it to "YES" to enable virtual_oss. +: "${virtual_oss_enable:="NO"}" + +# List of configurations to use. Default is "dsp". +: "${virtual_oss_configs:="dsp"}" + +# Default (dsp) virtual_oss config. +: "${virtual_oss_dsp:="${virtual_oss_default_args}"}" + +virtual_oss_pids() +{ + pids=$(pgrep -d ' ' ${name}) + pids=${pids% } + printf '%s\n' "${pids}" +} + +virtual_oss_precmd() +{ + /usr/bin/install -d -m 0755 -o root "${pidpath}" + load_kld cuse +} + +start_instance() +{ + config="$1" + instance_args=$(eval "echo \$virtual_oss_${config}") + if [ -z "${instance_args}" ]; then + warn "no such config: ${config}" + else + startmsg -n "Starting virtual_oss config: ${config}: " + ${command} \ + ${command_args} \ + -D "${pidpath}/${config}.pid" \ + ${instance_args} + startmsg "done" + fi +} + +stop_instance() +{ + config="$1" + instance_args=$(eval "echo \$virtual_oss_${config}") + if [ -z "${instance_args}" ]; then + warn "no such config: ${config}" + else + startmsg -n "Stopping virtual_oss config: ${config}: " + kill "$(cat "${pidpath}/${config}.pid")" + rm -f "${pidpath}/${config}.pid" + startmsg "done" + fi +} + +virtual_oss_start() +{ + configs="$1" + [ -z "${configs}" ] && configs="${virtual_oss_configs}" + for config in ${configs}; do + start_instance "${config}" + done +} + +virtual_oss_stop() +{ + configs="$1" + [ -z "${configs}" ] && configs="${virtual_oss_configs}" + for config in ${configs}; do + stop_instance "${config}" + done +} + +virtual_oss_status() +{ + pids=$(virtual_oss_pids) + + if [ "${pids}" ]; then + echo "${name} is running as pid ${pids}." + else + echo "${name} is not running." + return 1 + fi +} + +run_rc_command "$@" diff --git a/libexec/rc/rc.d/watchdogd b/libexec/rc/rc.d/watchdogd new file mode 100755 index 000000000000..6cd37b8c5ceb --- /dev/null +++ b/libexec/rc/rc.d/watchdogd @@ -0,0 +1,95 @@ +#!/bin/sh + +# Copyright (c) 2003 Sean M. Kelly <smkelly@FreeBSD.org> +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# + +# PROVIDE: watchdogd +# REQUIRE: FILESYSTEMS syslogd +# KEYWORD: nojail shutdown + +. /etc/rc.subr + +name="watchdogd" +desc="Watchdog daemon" +rcvar="watchdogd_enable" +command="/usr/sbin/${name}" +pidfile="/var/run/${name}.pid" +start_precmd="watchdogd_prestart" +stop_precmd="watchdogd_prestop" +stop_postcmd="watchdogd_poststop" +watchdog_command="/usr/sbin/watchdog" + +watchdogd_prestart() +{ + if [ -n "${watchdogd_timeout}" ] ; then + rc_flags="${rc_flags} -t ${watchdogd_timeout}" + fi + if [ -n "$watchdogd_shutdown_timeout" ] ; then + rc_flags="${rc_flags} -x ${watchdogd_shutdown_timeout}" + fi + return 0 +} + +watchdogd_prestop() +{ + sig_stop="${watchdogd_sig_stop:-TERM}" +} + +watchdogd_poststop() +{ + if [ ${watchdogd_shutdown_timeout:-0} -gt 0 ] ; then + case "${rc_shutdown}" in + "reboot") + info "watchdog timer is set to" \ + ${watchdogd_shutdown_timeout} "before shutdown" + return 0 + ;; + "single") + info "watchdog timer is disabled before going to" \ + "single user mode" + ${watchdog_command} -t 0 + ;; + "") + info "watchdog timer is disabled after administrative" \ + "${name} stop" + ${watchdog_command} -t 0 + ;; + *) + warn "unknown shutdown mode '${rc_shutdown}'" + warn "watchdog timer is set to ${watchdogd_shutdown_timeout}" + return 0 + ;; + esac + fi + return 0 +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: privileged operations +watchdogd_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/wpa_supplicant b/libexec/rc/rc.d/wpa_supplicant new file mode 100755 index 000000000000..e11dddfb5fd3 --- /dev/null +++ b/libexec/rc/rc.d/wpa_supplicant @@ -0,0 +1,39 @@ +#!/bin/sh +# +# + +# PROVIDE: wpa_supplicant +# REQUIRE: mountcritremote +# KEYWORD: nojail nostart + +. /etc/rc.subr +. /etc/network.subr + +name="wpa_supplicant" +desc="WPA/802.11i Supplicant for wireless network devices" +rcvar= + +ifn="$2" +if [ -z "$ifn" ]; then + return 1 +fi + +if is_wired_interface ${ifn} ; then + driver="wired" +else + driver="bsd" +fi + +load_rc_config $name + +command=${wpa_supplicant_program} +conf_file=${wpa_supplicant_conf_file} +pidfile="/var/run/${name}/${ifn}.pid" +command_args="-B -i $ifn -c $conf_file -D $driver -P $pidfile" +required_files=$conf_file +required_modules="wlan_wep wlan_tkip wlan_ccmp wlan_gcmp" + +# doesn't make sense to run in a svcj: nojail keyword +wpa_supplicant_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/ypbind b/libexec/rc/rc.d/ypbind new file mode 100755 index 000000000000..a6bf00f1ed9d --- /dev/null +++ b/libexec/rc/rc.d/ypbind @@ -0,0 +1,38 @@ +#!/bin/sh +# +# + +# PROVIDE: ypbind +# REQUIRE: ypserv +# BEFORE: DAEMON +# KEYWORD: shutdown + +. /etc/rc.subr + +name="ypbind" +desc="NIS domain binding daemon" +rcvar="nis_client_enable" + +: ${ypbind_svcj_options:="net_basic"} + +load_rc_config $name + +command="/usr/sbin/${name}" +command_args="${nis_client_flags}" + +start_precmd="ypbind_precmd" + +ypbind_precmd() +{ + local _domain + + force_depend rpcbind || return 1 + + _domain=`domainname` + if [ -z "$_domain" ]; then + warn "NIS domainname(1) is not set." + return 1 + fi +} + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/ypldap b/libexec/rc/rc.d/ypldap new file mode 100755 index 000000000000..579b004a07c0 --- /dev/null +++ b/libexec/rc/rc.d/ypldap @@ -0,0 +1,28 @@ +#!/bin/sh +# +# + +# PROVIDE: ypldap +# REQUIRE: ypserv +# BEFORE: DAEMON +# KEYWORD: shutdown + +. /etc/rc.subr + +name="ypldap" +rcvar="nis_ypldap_enable" + +: ${ypldap_svcj_options:="net_basic"} + +load_rc_config $name + +command="/usr/sbin/${name}" +command_args="${nis_ypldap_flags}" + +start_precmd="ypldap_precmd" + +ypldap_precmd() +{ + force_depend ypserv nis_server || return 1 +} +run_rc_command "$1" diff --git a/libexec/rc/rc.d/yppasswdd b/libexec/rc/rc.d/yppasswdd new file mode 100755 index 000000000000..81a04d753305 --- /dev/null +++ b/libexec/rc/rc.d/yppasswdd @@ -0,0 +1,39 @@ +#!/bin/sh +# +# + +# PROVIDE: yppasswdd +# REQUIRE: ypserv ypset +# BEFORE: LOGIN +# KEYWORD: shutdown + +. /etc/rc.subr + +name="yppasswdd" +desc="Server for updating NIS passwords" +rcvar="nis_yppasswdd_enable" + +: ${yppasswdd_svcj_options:="net_basic"} + +load_rc_config $name + +command="/usr/sbin/rpc.${name}" +command_args="${nis_yppasswdd_flags}" + +start_precmd="yppasswdd_precmd" + +yppasswdd_precmd() +{ + local _domain + + force_depend rpcbind || return 1 + force_depend ypserv nis_server || return 1 + + _domain=`domainname` + if [ -z "$_domain" ]; then + warn "NIS domainname(1) is not set." + return 1 + fi +} + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/ypserv b/libexec/rc/rc.d/ypserv new file mode 100755 index 000000000000..8cae179fdd11 --- /dev/null +++ b/libexec/rc/rc.d/ypserv @@ -0,0 +1,41 @@ +#!/bin/sh +# +# + +# PROVIDE: ypserv +# REQUIRE: rpcbind +# KEYWORD: shutdown + +. /etc/rc.subr + +name="ypserv" +desc="NIS database server" +rcvar="nis_server_enable" + +: ${ypserv_svcj_options:="net_basic"} + +load_rc_config $name + +command="/usr/sbin/${name}" +command_args="${nis_server_flags}" + +start_precmd="ypserv_prestart" + +ypserv_prestart() +{ + local _domain + + force_depend rpcbind || return 1 + + _domain=`domainname` + if [ -z "$_domain" ]; then + warn "NIS domainname(1) is not set." + return 1 + fi + if [ ! -d /var/yp/$_domain/. ]; then + warn "/var/yp/$_domain is not a directory." + return 1 + fi +} + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/ypset b/libexec/rc/rc.d/ypset new file mode 100755 index 000000000000..123a94ea44e8 --- /dev/null +++ b/libexec/rc/rc.d/ypset @@ -0,0 +1,39 @@ +#!/bin/sh +# +# + +# PROVIDE: ypset +# REQUIRE: ypbind +# KEYWORD: shutdown + +. /etc/rc.subr + +name="ypset" +desc="tell ypbind(8) which YP server process to use" +rcvar="nis_ypset_enable" + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +ypset_svcj="NO" + +command="/usr/sbin/${name}" +command_args="${nis_ypset_flags}" + +start_precmd="ypset_precmd" + +ypset_precmd() +{ + local _domain + + force_depend rpcbind || return 1 + force_depend ypbind nis_client || return 1 + + _domain=`domainname` + if [ -z "$_domain" ]; then + warn "NIS domainname(1) is not set." + return 1 + fi +} + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/ypupdated b/libexec/rc/rc.d/ypupdated new file mode 100755 index 000000000000..1a4c595c745a --- /dev/null +++ b/libexec/rc/rc.d/ypupdated @@ -0,0 +1,35 @@ +#!/bin/sh +# +# + +# PROVIDE: ypupdated +# REQUIRE: rpcbind ypserv +# KEYWORD: shutdown + +. /etc/rc.subr + +name="ypupdated" +rcvar="rpc_ypupdated_enable" + +: ${ypupdated_svcj_options:="net_basic"} + +load_rc_config $name + +command="/usr/sbin/rpc.${name}" +start_precmd="rpc_ypupdated_precmd" + +rpc_ypupdated_precmd() +{ + local _domain + + force_depend rpcbind || return 1 + force_depend ypserv nis_server || return 1 + + _domain=`domainname` + if [ -z "$_domain" ]; then + warn "NIS domainname(1) is not set." + return 1 + fi +} + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/ypxfrd b/libexec/rc/rc.d/ypxfrd new file mode 100755 index 000000000000..ea929b0d25ce --- /dev/null +++ b/libexec/rc/rc.d/ypxfrd @@ -0,0 +1,38 @@ +#!/bin/sh +# +# + +# PROVIDE: ypxfrd +# REQUIRE: rpcbind ypserv +# KEYWORD: shutdown + +. /etc/rc.subr + +name="ypxfrd" +desc="NIS map transfer server" +rcvar="nis_ypxfrd_enable" + +: ${ypxfrd_svcj_options:="net_basic"} + +load_rc_config $name + +command="/usr/sbin/rpc.${name}" +command_args="${nis_ypxfrd_flags}" + +start_precmd="ypxfrd_precmd" + +ypxfrd_precmd() +{ + local _domain + + force_depend rpcbind || return 1 + force_depend ypserv nis_server || return 1 + + _domain=`domainname` + if [ -z "$_domain" ]; then + warn "NIS domainname(1) is not set." + return 1 + fi +} + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/zfs b/libexec/rc/rc.d/zfs new file mode 100755 index 000000000000..f88f65c2ec18 --- /dev/null +++ b/libexec/rc/rc.d/zfs @@ -0,0 +1,82 @@ +#!/bin/sh +# +# + +# PROVIDE: zfs +# REQUIRE: zfsbe +# BEFORE: FILESYSTEMS var + +. /etc/rc.subr + +name="zfs" +desc="Mount and share ZFS datasets" +rcvar="zfs_enable" +start_cmd="zfs_start" +start_postcmd="zfs_poststart" +stop_cmd="zfs_stop" +required_modules="zfs" + +zfs_start_jail() +{ + if check_jail mount_allowed; then + zfs mount -a + fi +} + +zfs_start_main() +{ + zfs mount -va + zfs share -a + if [ ! -r /etc/zfs/exports ]; then + touch /etc/zfs/exports + fi +} + +zfs_start() +{ + if check_jail jailed; then + zfs_start_jail + else + zfs_start_main + fi +} + +zfs_poststart() +{ + # Some of the keys to decrypt datasets are potentially stored on ZFS + # datasets that just got mounted. Let's try to load those keys and + # mount the datasets. + if checkyesno zfskeys_enable; then + /etc/rc.d/zfskeys start + zfs_start + fi +} + +zfs_stop_jail() +{ + if check_jail mount_allowed; then + zfs unmount -a + fi +} + +zfs_stop_main() +{ + zfs unshare -a + zfs unmount -a +} + +zfs_stop() +{ + if check_jail jailed; then + zfs_stop_jail + else + zfs_stop_main + fi +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: mounting / config setting +zfs_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/zfsbe b/libexec/rc/rc.d/zfsbe new file mode 100755 index 000000000000..22d53f219679 --- /dev/null +++ b/libexec/rc/rc.d/zfsbe @@ -0,0 +1,92 @@ +#!/bin/sh +# +# + +# PROVIDE: zfsbe +# REQUIRE: mountcritlocal + +# Handle boot environment subordinate filesystems +# that may have canmount property set to noauto. +# For these filesystems mountpoint relative to / +# must be the same as their dataset name relative +# to BE root dataset. + +. /etc/rc.subr + +name="zfsbe" +rcvar="zfs_enable" +start_cmd="be_start" +stop_cmd="be_stop" +required_modules="zfs" + +mount_subordinate() +{ + local _be + + _be=$1 + zfs list -rH -o mountpoint,name,canmount,mounted -s mountpoint -t filesystem $_be | \ + while read _mp _name _canmount _mounted ; do + # skip filesystems that must not be mounted + [ "$_canmount" = "off" ] && continue + # skip filesystems that are already mounted + [ "$_mounted" = "yes" ] && continue + case "$_mp" in + "none" | "legacy" | "/" | "/$_be") + # do nothing for filesystems with unset or legacy mountpoint + # or those that would be mounted over / + ;; + "/$_be/"*) + # filesystems with mountpoint relative to BE + mount -t zfs $_name ${_mp#/$_be} + ;; + *) + # filesystems with mountpoint elsewhere + zfs mount $_name + ;; + esac + done +} + +activate_bootonce() +{ + local _dev + local _bootonce + local _be + + _dev=$1 + _be=${_dev##*/} + + _bootonce=$(kenv -q zfs-bootonce) + if [ "$_bootonce" = "zfs:${_dev}:" ] ; then + bectl activate $_be + fi +} + +be_start() +{ + if check_jail jailed; then + : + else + mount -p | while read _dev _mp _type _rest; do + [ $_mp = "/" ] || continue + if [ $_type = "zfs" ] ; then + mount_subordinate $_dev + if checkyesno zfs_bootonce_activate; then + activate_bootonce $_dev + fi + fi + break + done + fi +} + +be_stop() +{ +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: mounting / config setting +zfsbe_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/zfsd b/libexec/rc/rc.d/zfsd new file mode 100755 index 000000000000..f0abeeeb446b --- /dev/null +++ b/libexec/rc/rc.d/zfsd @@ -0,0 +1,20 @@ +#!/bin/sh +# +# + +# PROVIDE: zfsd +# REQUIRE: devd zfs +# KEYWORD: nojail shutdown + +. /etc/rc.subr + +name="zfsd" +rcvar="zfsd_enable" +command="/usr/sbin/${name}" + +load_rc_config $name + +# doesn't make sense to run in a svcj +zfsd_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/zfskeys b/libexec/rc/rc.d/zfskeys new file mode 100755 index 000000000000..aff0224d5c9d --- /dev/null +++ b/libexec/rc/rc.d/zfskeys @@ -0,0 +1,131 @@ +#!/bin/sh + +# PROVIDE: zfskeys +# REQUIRE: zpool +# BEFORE: zfs zvol + +. /etc/rc.subr + +name="zfskeys" +desc="Load dataset keys" +rcvar="zfskeys_enable" +extra_commands="status" +start_cmd="load_zfs_keys" +stop_cmd="unload_zfs_keys" +status_cmd="status_zfs_keys" +required_modules="zfs" + +# Note that zfskeys_datasets must have any character found in IFS escaped. +# Forcibly unmounting/unloading only applies to filesystems; ignored for zvols. +: ${zfskeys_datasets:=''} +: ${zfskeys_timeout:=10} +: ${zfskeys_unload_force:='NO'} + +encode_args() +{ + shift && [ $# -gt 0 ] && printf "%s\0" "$@" | b64encode -r - +} + +list_datasets() +{ + if [ "$zfskeys_args" ]; then + echo "$zfskeys_args" | b64decode -r | + xargs -0 zfs get -H -s local -o value,name keylocation + elif [ ! "$zfskeys_datasets" ]; then + zfs get -H -t filesystem,volume -s local -o value,name keylocation + else + echo "$zfskeys_datasets" | xargs -n 1 zfs get -H -s local \ + -o value,name keylocation + fi +} + +unlock_fs() +{ + local fs="$1" + local kl="$2" + local k="${kl##file://}" + + if [ "$kl" == "prompt" ] + then + echo "Key prompt for $fs." + if zfs load-key -L "$kl" "$fs" < /dev/tty > /dev/tty 2>/dev/tty ; then + echo "Key loaded for $fs." + else + echo "Key failed to load for $fs." + fi + elif [ "$k" ] && [ -f "$k" ] && [ -s "$k" ] && [ -r "$k" ]; then + if [ "$(zfs get -Ho value keystatus "$fs")" = 'available' ]; then + echo "Key already loaded for $fs." + elif keytest=$(zfs load-key -n -L "$kl" "$fs" 2>&1); then + echo "Loading key for $fs from $kl.." + if ! keyload=$(timeout $zfskeys_timeout zfs load-key -L "$kl" "$fs" 2>&1) ; then + if [ $? -eq 124 ]; then + echo "Timed out loading key from $kl for $fs" + else + echo "Failed to load key from $kl for $fs:" + echo "$keyload" + fi + fi + else + echo "Could not verify key from $kl for $fs:" + echo "$keytest" + fi + else + echo "Key file $k not found, empty or unreadable. Skipping $fs.." + fi +} + +lock_fs() +{ + local fs=$1 + + if [ "$(zfs get -Ho value mounted "$fs")" = 'yes' ]; then + if checkyesno zfskeys_unload_force ; then + zfs unmount -f "$fs" && echo "Forcibly unmounted $fs." + else + zfs unmount "$fs" && echo "Unmounted $fs." + fi + fi + if [ "$?" -ne 0 ]; then + echo "Unmount failed for $fs" + elif [ "$(zfs get -Ho value keystatus "$fs")" = 'available' ]; then + zfs unload-key "$fs" && echo "Unloaded key for $fs." + else + echo "No key loaded for $fs." + fi +} + +status_zfs_keys() +{ + local IFS=$(printf "\t") + + list_datasets | while read kl fs ; do + echo "$fs: $(zfs get -Ho value keystatus "$fs")" + done +} + +load_zfs_keys() +{ + local IFS=$(printf "\t") + + list_datasets | while read kl fs ; do + unlock_fs "$fs" "$kl" + done +} + +unload_zfs_keys() +{ + local IFS=$(printf "\t") + + list_datasets | while read kl fs ; do + lock_fs "$fs" + done +} + +zfskeys_args=$(encode_args "$@") +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +zfskeys_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/zpool b/libexec/rc/rc.d/zpool new file mode 100755 index 000000000000..63f040ad122b --- /dev/null +++ b/libexec/rc/rc.d/zpool @@ -0,0 +1,40 @@ +#!/bin/sh +# +# + +# PROVIDE: zpool +# REQUIRE: hostid disks mountcritlocal +# KEYWORD: nojail + +. /etc/rc.subr + +name="zpool" +desc="Import ZPOOLs" +rcvar="zfs_enable" +start_cmd="zpool_start" +required_modules="zfs" + +zpool_start() +{ + local cachefile + + for cachefile in /etc/zfs/zpool.cache /boot/zfs/zpool.cache; do + if [ -r $cachefile ]; then + zpool import -c $cachefile -a -N + if [ $? -ne 0 ]; then + echo "Import of zpool cache ${cachefile} failed," \ + "will retry after root mount hold release" + root_hold_wait + zpool import -c $cachefile -a -N + fi + break + fi + done +} + +load_rc_config $name + +# doesn't make sense to run in a svcj +zpool_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/zpoolreguid b/libexec/rc/rc.d/zpoolreguid new file mode 100755 index 000000000000..c19f52d3d702 --- /dev/null +++ b/libexec/rc/rc.d/zpoolreguid @@ -0,0 +1,29 @@ +#!/bin/sh + +# PROVIDE: zpoolreguid +# REQUIRE: zpool +# BEFORE: FILESYSTEMS +# KEYWORD: firstboot nojail + +. /etc/rc.subr + +name="zpoolreguid" +desc="Generate a new zpool GUID" +rcvar="zfs_enable" +start_cmd="zpoolreguid_start" + +zpoolreguid_start() +{ + local pool + + for pool in ${zpool_reguid}; do + zpool reguid $pool + done +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +zpoolreguid_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/zpoolupgrade b/libexec/rc/rc.d/zpoolupgrade new file mode 100755 index 000000000000..5e623a9c2bf0 --- /dev/null +++ b/libexec/rc/rc.d/zpoolupgrade @@ -0,0 +1,29 @@ +#!/bin/sh + +# PROVIDE: zpoolupgrade +# REQUIRE: zpool +# BEFORE: FILESYSTEMS +# KEYWORD: firstboot nojail + +. /etc/rc.subr + +name="zpoolupgrade" +desc="Upgrade zpool version" +rcvar="zfs_enable" +start_cmd="zpoolupgrade_start" + +zpoolupgrade_start() +{ + local pool + + for pool in ${zpool_upgrade}; do + zpool upgrade $pool + done +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +zpoolupgrade_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/zvol b/libexec/rc/rc.d/zvol new file mode 100755 index 000000000000..b9f17fad5bfd --- /dev/null +++ b/libexec/rc/rc.d/zvol @@ -0,0 +1,49 @@ +#!/bin/sh +# +# + +# PROVIDE: zvol +# REQUIRE: zpool +# KEYWORD: nojail + +. /etc/rc.subr + +name="zvol" +desc="Activate swap on ZVOLs" +rcvar="zfs_enable" +start_cmd="zvol_start" +stop_cmd="zvol_stop" +required_modules="zfs" + +zvol_start() +{ + # Enable swap on ZVOLs with property org.freebsd:swap=on. + zfs list -H -o org.freebsd:swap,name -t volume | + while read state name; do + case "${state}" in + ([oO][nN]) + swapon /dev/zvol/${name} + ;; + esac + done +} + +zvol_stop() +{ + # Disable swap on ZVOLs with property org.freebsd:swap=on. + zfs list -H -o org.freebsd:swap,name -t volume | + while read state name; do + case "${state}" in + ([oO][nN]) + swapoff /dev/zvol/${name} + ;; + esac + done +} + +load_rc_config $name + +# doesn't make sense to run in a svcj: config setting +zvol_svcj="NO" + +run_rc_command "$1" diff --git a/libexec/rc/rc.firewall b/libexec/rc/rc.firewall new file mode 100644 index 000000000000..e4fc8cc3db78 --- /dev/null +++ b/libexec/rc/rc.firewall @@ -0,0 +1,553 @@ +#!/bin/sh - +# Copyright (c) 1996 Poul-Henning Kamp +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# + +# +# Setup system for ipfw(4) firewall service. +# + +# Suck in the configuration variables. +if [ -z "${source_rc_confs_defined}" ]; then + if [ -r /etc/defaults/rc.conf ]; then + . /etc/defaults/rc.conf + source_rc_confs + elif [ -r /etc/rc.conf ]; then + . /etc/rc.conf + fi +fi + +############ +# Define the firewall type in /etc/rc.conf. Valid values are: +# open - will allow anyone in +# client - will try to protect just this machine +# simple - will try to protect a whole network +# closed - totally disables IP services except via lo0 interface +# workstation - will try to protect just this machine using stateful +# firewalling. See below for rc.conf variables used +# UNKNOWN - disables the loading of firewall rules. +# filename - will load the rules in the given filename (full path required) +# +# For ``client'' and ``simple'' the entries below should be customized +# appropriately. + +############ +# +# If you don't know enough about packet filtering, we suggest that you +# take time to read this book: +# +# Building Internet Firewalls, 2nd Edition +# Brent Chapman and Elizabeth Zwicky +# +# O'Reilly & Associates, Inc +# ISBN 1-56592-871-7 +# http://www.ora.com/ +# http://www.oreilly.com/catalog/fire2/ +# +# For a more advanced treatment of Internet Security read: +# +# Firewalls and Internet Security: Repelling the Wily Hacker, 2nd Edition +# William R. Cheswick, Steven M. Bellowin, Aviel D. Rubin +# +# Addison-Wesley / Prentice Hall +# ISBN 0-201-63466-X +# http://www.pearsonhighered.com/ +# http://www.pearsonhighered.com/educator/academic/product/0,3110,020163466X,00.html +# + +setup_loopback() { + ############ + # Only in rare cases do you want to change these rules + # + ${fwcmd} add 100 pass all from any to any via lo0 + ${fwcmd} add 200 deny all from any to 127.0.0.0/8 + ${fwcmd} add 300 deny ip from 127.0.0.0/8 to any + if [ $ipv6_available -eq 0 ]; then + ${fwcmd} add 400 deny all from any to ::1 + ${fwcmd} add 500 deny all from ::1 to any + fi +} + +setup_ipv6_mandatory() { + [ $ipv6_available -eq 0 ] || return 0 + + ############ + # Only in rare cases do you want to change these rules + # + # ND + # + # DAD + ${fwcmd} add pass ipv6-icmp from :: to ff02::/16 + # RS, RA, NS, NA, redirect... + ${fwcmd} add pass ipv6-icmp from fe80::/10 to fe80::/10 + ${fwcmd} add pass ipv6-icmp from fe80::/10 to ff02::/16 + + # Allow ICMPv6 destination unreachable + ${fwcmd} add pass ipv6-icmp from any to any icmp6types 1 + + # Allow NS/NA/toobig (don't filter it out) + ${fwcmd} add pass ipv6-icmp from any to any icmp6types 2,135,136 +} + +. /etc/rc.subr +. /etc/network.subr + +if [ -n "${1}" ]; then + firewall_type="${1}" +fi +if [ -z "${firewall_rc_config_load}" ]; then + load_rc_config ipfw +else + for i in ${firewall_rc_config_load}; do + load_rc_config $i + done +fi + +afexists inet6 +ipv6_available=$? + +############ +# Set quiet mode if requested +# +case ${firewall_quiet} in +[Yy][Ee][Ss]) + fwcmd="/sbin/ipfw -q" + ;; +*) + fwcmd="/sbin/ipfw" + ;; +esac + +############ +# Flush out the list before we begin. +# +${fwcmd} -f flush + +setup_loopback +setup_ipv6_mandatory + +############ +# Network Address Translation. All packets are passed to natd(8) +# before they encounter your remaining rules. The firewall rules +# will then be run again on each packet after translation by natd +# starting at the rule number following the divert rule. +# +# For ``simple'' firewall type the divert rule should be put to a +# different place to not interfere with address-checking rules. +# +case ${firewall_type} in +[Oo][Pp][Ee][Nn]|[Cc][Ll][Ii][Ee][Nn][Tt]) + case ${natd_enable} in + [Yy][Ee][Ss]) + if [ -n "${natd_interface}" ]; then + ${fwcmd} add 50 divert natd ip4 from any to any via ${natd_interface} + fi + ;; + esac + case ${firewall_nat_enable} in + [Yy][Ee][Ss]) + if [ -n "${firewall_nat_interface}" ]; then + if echo "${firewall_nat_interface}" | \ + grep -q -E '^[0-9]+(\.[0-9]+){0,3}$'; then + firewall_nat_flags="ip ${firewall_nat_interface} ${firewall_nat_flags}" + else + firewall_nat_flags="if ${firewall_nat_interface} ${firewall_nat_flags}" + fi + ${fwcmd} nat 123 config log ${firewall_nat_flags} + ${fwcmd} add 50 nat 123 ip4 from any to any via ${firewall_nat_interface} + fi + ;; + esac +esac + +############ +# If you just configured ipfw in the kernel as a tool to solve network +# problems or you just want to disallow some particular kinds of traffic +# then you will want to change the default policy to open. You can also +# do this as your only action by setting the firewall_type to ``open''. +# +# ${fwcmd} add 65000 pass all from any to any + + +# Prototype setups. +# +case ${firewall_type} in +[Oo][Pp][Ee][Nn]) + ${fwcmd} add 65000 pass all from any to any + ;; + +[Cc][Ll][Ii][Ee][Nn][Tt]) + ############ + # This is a prototype setup that will protect your system somewhat + # against people from outside your own network. + # + # Configuration: + # firewall_client_net: Network address of local IPv4 network. + # firewall_client_net_ipv6: Network address of local IPv6 network. + ############ + + # set this to your local network + net="$firewall_client_net" + net6="$firewall_client_net_ipv6" + + # Allow limited broadcast traffic from my own net. + ${fwcmd} add pass all from ${net} to 255.255.255.255 + + # Allow any traffic to or from my own net. + ${fwcmd} add pass all from me to ${net} + ${fwcmd} add pass all from ${net} to me + if [ -n "$net6" ]; then + ${fwcmd} add pass all from me to ${net6} + ${fwcmd} add pass all from ${net6} to me + # Allow any link-local multicast traffic + ${fwcmd} add pass all from fe80::/10 to ff02::/16 + ${fwcmd} add pass all from ${net6} to ff02::/16 + # Allow DHCPv6 + ${fwcmd} add pass udp from fe80::/10 to me 546 + fi + + # Allow TCP through if setup succeeded + ${fwcmd} add pass tcp from any to any established + + # Allow IP fragments to pass through + ${fwcmd} add pass all from any to any frag + + # Allow setup of incoming email + ${fwcmd} add pass tcp from any to me 25 setup + + # Allow setup of outgoing TCP connections only + ${fwcmd} add pass tcp from me to any setup + + # Disallow setup of all other TCP connections + ${fwcmd} add deny tcp from any to any setup + + # Allow DNS queries out in the world + ${fwcmd} add pass udp from me to any 53 keep-state + + # Allow NTP queries out in the world + ${fwcmd} add pass udp from me to any 123 keep-state + + # Everything else is denied by default, unless the + # IPFIREWALL_DEFAULT_TO_ACCEPT option is set in your kernel + # config file. + ;; + +[Ss][Ii][Mm][Pp][Ll][Ee]) + ############ + # This is a prototype setup for a simple firewall. Configure this + # machine as a DNS and NTP server, and point all the machines + # on the inside at this machine for those services. + # + # Configuration: + # firewall_simple_iif: Inside IPv4 network interface. + # firewall_simple_inet: Inside IPv4 network address. + # firewall_simple_oif: Outside IPv4 network interface. + # firewall_simple_onet: Outside IPv4 network address. + # firewall_simple_iif_ipv6: Inside IPv6 network interface. + # firewall_simple_inet_ipv6: Inside IPv6 network prefix. + # firewall_simple_oif_ipv6: Outside IPv6 network interface. + # firewall_simple_onet_ipv6: Outside IPv6 network prefix. + ############ + BAD_ADDR_TBL=13 + + # set these to your outside interface network + oif="$firewall_simple_oif" + onet="$firewall_simple_onet" + oif6="${firewall_simple_oif_ipv6:-$firewall_simple_oif}" + onet6="$firewall_simple_onet_ipv6" + + # set these to your inside interface network + iif="$firewall_simple_iif" + inet="$firewall_simple_inet" + iif6="${firewall_simple_iif_ipv6:-$firewall_simple_iif}" + inet6="$firewall_simple_inet_ipv6" + + # Stop spoofing + ${fwcmd} add deny all from ${inet} to any in via ${oif} + ${fwcmd} add deny all from ${onet} to any in via ${iif} + if [ -n "$inet6" ]; then + ${fwcmd} add deny all from ${inet6} to any in via ${oif6} + if [ -n "$onet6" ]; then + ${fwcmd} add deny all from ${onet6} to any in \ + via ${iif6} + fi + fi + + # Define stuff we should never send out or receive in. + # Stop RFC1918 nets on the outside interface + ${fwcmd} table ${BAD_ADDR_TBL} flush + ${fwcmd} table ${BAD_ADDR_TBL} add 10.0.0.0/8 + ${fwcmd} table ${BAD_ADDR_TBL} add 172.16.0.0/12 + ${fwcmd} table ${BAD_ADDR_TBL} add 192.168.0.0/16 + + # And stop draft-manning-dsua-03.txt (1 May 2000) nets (includes RESERVED-1, + # DHCP auto-configuration, NET-TEST, MULTICAST (class D), and class E) + # on the outside interface + ${fwcmd} table ${BAD_ADDR_TBL} add 0.0.0.0/8 + ${fwcmd} table ${BAD_ADDR_TBL} add 169.254.0.0/16 + ${fwcmd} table ${BAD_ADDR_TBL} add 192.0.2.0/24 + ${fwcmd} table ${BAD_ADDR_TBL} add 224.0.0.0/4 + ${fwcmd} table ${BAD_ADDR_TBL} add 240.0.0.0/4 + + ${fwcmd} add deny all from any to "table($BAD_ADDR_TBL)" via ${oif} + + # Network Address Translation. This rule is placed here deliberately + # so that it does not interfere with the surrounding address-checking + # rules. If for example one of your internal LAN machines had its IP + # address set to 192.0.2.1 then an incoming packet for it after being + # translated by natd(8) would match the `deny' rule above. Similarly + # an outgoing packet originated from it before being translated would + # match the `deny' rule below. + case ${natd_enable} in + [Yy][Ee][Ss]) + if [ -n "${natd_interface}" ]; then + ${fwcmd} add divert natd ip4 from any to any via ${natd_interface} + fi + ;; + esac + + ${fwcmd} add deny all from "table($BAD_ADDR_TBL)" to any via ${oif} + if [ -n "$inet6" ]; then + # Stop unique local unicast address on the outside interface + ${fwcmd} add deny all from fc00::/7 to any via ${oif6} + ${fwcmd} add deny all from any to fc00::/7 via ${oif6} + + # Stop site-local on the outside interface + ${fwcmd} add deny all from fec0::/10 to any via ${oif6} + ${fwcmd} add deny all from any to fec0::/10 via ${oif6} + + # Disallow "internal" addresses to appear on the wire. + ${fwcmd} add deny all from ::ffff:0.0.0.0/96 to any \ + via ${oif6} + ${fwcmd} add deny all from any to ::ffff:0.0.0.0/96 \ + via ${oif6} + + # Disallow packets to malicious IPv4 compatible prefix. + ${fwcmd} add deny all from ::224.0.0.0/100 to any via ${oif6} + ${fwcmd} add deny all from any to ::224.0.0.0/100 via ${oif6} + ${fwcmd} add deny all from ::127.0.0.0/104 to any via ${oif6} + ${fwcmd} add deny all from any to ::127.0.0.0/104 via ${oif6} + ${fwcmd} add deny all from ::0.0.0.0/104 to any via ${oif6} + ${fwcmd} add deny all from any to ::0.0.0.0/104 via ${oif6} + ${fwcmd} add deny all from ::255.0.0.0/104 to any via ${oif6} + ${fwcmd} add deny all from any to ::255.0.0.0/104 via ${oif6} + + ${fwcmd} add deny all from ::0.0.0.0/96 to any via ${oif6} + ${fwcmd} add deny all from any to ::0.0.0.0/96 via ${oif6} + + # Disallow packets to malicious 6to4 prefix. + ${fwcmd} add deny all from 2002:e000::/20 to any via ${oif6} + ${fwcmd} add deny all from any to 2002:e000::/20 via ${oif6} + ${fwcmd} add deny all from 2002:7f00::/24 to any via ${oif6} + ${fwcmd} add deny all from any to 2002:7f00::/24 via ${oif6} + ${fwcmd} add deny all from 2002:0000::/24 to any via ${oif6} + ${fwcmd} add deny all from any to 2002:0000::/24 via ${oif6} + ${fwcmd} add deny all from 2002:ff00::/24 to any via ${oif6} + ${fwcmd} add deny all from any to 2002:ff00::/24 via ${oif6} + + ${fwcmd} add deny all from 2002:0a00::/24 to any via ${oif6} + ${fwcmd} add deny all from any to 2002:0a00::/24 via ${oif6} + ${fwcmd} add deny all from 2002:ac10::/28 to any via ${oif6} + ${fwcmd} add deny all from any to 2002:ac10::/28 via ${oif6} + ${fwcmd} add deny all from 2002:c0a8::/32 to any via ${oif6} + ${fwcmd} add deny all from any to 2002:c0a8::/32 via ${oif6} + + ${fwcmd} add deny all from ff05::/16 to any via ${oif6} + ${fwcmd} add deny all from any to ff05::/16 via ${oif6} + fi + + # Allow TCP through if setup succeeded + ${fwcmd} add pass tcp from any to any established + + # Allow IP fragments to pass through + ${fwcmd} add pass all from any to any frag + + # Allow setup of incoming email + ${fwcmd} add pass tcp from any to me 25 setup + + # Allow access to our DNS + ${fwcmd} add pass tcp from any to me 53 setup + ${fwcmd} add pass udp from any to me 53 + ${fwcmd} add pass udp from me 53 to any + + # Allow access to our WWW + ${fwcmd} add pass tcp from any to me 80 setup + + # Reject&Log all setup of incoming connections from the outside + ${fwcmd} add deny log ip4 from any to any in via ${oif} setup proto tcp + if [ -n "$inet6" ]; then + ${fwcmd} add deny log ip6 from any to any in via ${oif6} \ + setup proto tcp + fi + + # Allow setup of any other TCP connection + ${fwcmd} add pass tcp from any to any setup + + # Allow DNS queries out in the world + ${fwcmd} add pass udp from me to any 53 keep-state + + # Allow NTP queries out in the world + ${fwcmd} add pass udp from me to any 123 keep-state + + # Everything else is denied by default, unless the + # IPFIREWALL_DEFAULT_TO_ACCEPT option is set in your kernel + # config file. + ;; + +[Ww][Oo][Rr][Kk][Ss][Tt][Aa][Tt][Ii][Oo][Nn]) + # Configuration: + # firewall_myservices: List of ports/protocols on which this + # host offers services. + # firewall_allowservices: List of IPv4 and/or IPv6 addresses + # that have access to + # $firewall_myservices. + # firewall_trusted: List of IPv4 and/or IPv6 addresses + # that have full access to this host. + # Be very careful when setting this. + # This option can seriously degrade + # the level of protection provided by + # the firewall. + # firewall_logdeny: Boolean (YES/NO) specifying if the + # default denied packets should be + # logged (in /var/log/security). + # firewall_nologports: List of TCP/UDP ports for which + # denied incoming packets are not + # logged. + + # Allow packets for which a state has been built. + ${fwcmd} add check-state + + # For services permitted below. + ${fwcmd} add pass tcp from me to any established + + # Allow any connection out, adding state for each. + ${fwcmd} add pass tcp from me to any setup keep-state + ${fwcmd} add pass udp from me to any keep-state + ${fwcmd} add pass icmp from me to any keep-state + if [ $ipv6_available -eq 0 ]; then + ${fwcmd} add pass ipv6-icmp from me to any keep-state + fi + + # Allow DHCP. + ${fwcmd} add pass udp from 0.0.0.0 68 to 255.255.255.255 67 out + ${fwcmd} add pass udp from any 67 to me 68 in + ${fwcmd} add pass udp from any 67 to 255.255.255.255 68 in + if [ $ipv6_available -eq 0 ]; then + ${fwcmd} add pass udp from fe80::/10 to me 546 in + fi + # Some servers will ping the IP while trying to decide if it's + # still in use. + ${fwcmd} add pass icmp from any to any icmptype 8 + if [ $ipv6_available -eq 0 ]; then + ${fwcmd} add pass ipv6-icmp from any to any icmp6type 128,129 + fi + + # Allow "mandatory" ICMP in. + ${fwcmd} add pass icmp from any to any icmptype 3,4,11 + if [ $ipv6_available -eq 0 ]; then + ${fwcmd} add pass ipv6-icmp from any to any icmp6type 3 + fi + + # Add permits for this workstations published services below + # Only IPs and nets in firewall_allowservices is allowed in. + # If you really wish to let anyone use services on your + # workstation, then set "firewall_allowservices='any'" in /etc/rc.conf + # + # Note: We don't use keep-state as that would allow DoS of + # our statetable. + # You can add 'keep-state' to the lines for slightly + # better performance if you fell that DoS of your + # workstation won't be a problem. + # + for i in ${firewall_allowservices} ; do + for j in ${firewall_myservices} ; do + case $j in + [0-9A-Za-z]*/[Pp][Rr][Oo][Tt][Oo]) + ${fwcmd} add pass ${j%/[Pp][Rr][Oo][Tt][Oo]} from $i to me + ;; + [0-9A-Za-z]*/[Tt][Cc][Pp]) + ${fwcmd} add pass tcp from $i to me ${j%/[Tt][Cc][Pp]} + ;; + [0-9A-Za-z]*/[Uu][Dd][Pp]) + ${fwcmd} add pass udp from $i to me ${j%/[Uu][Dd][Pp]} + ;; + *[0-9A-Za-z]) + echo "Consider using ${j}/tcp in firewall_myservices." \ + > /dev/stderr + ${fwcmd} add pass tcp from $i to me $j + ;; + *) + echo "Invalid port in firewall_myservices: $j" > /dev/stderr + ;; + esac + done + done + + # Allow all connections from trusted IPs. + # Playing with the content of firewall_trusted could seriously + # degrade the level of protection provided by the firewall. + for i in ${firewall_trusted} ; do + ${fwcmd} add pass ip from $i to me + done + + ${fwcmd} add 65000 count ip from any to any + + # Drop packets to ports where we don't want logging + for i in ${firewall_nologports} ; do + ${fwcmd} add deny { tcp or udp } from any to any $i in + done + + # Broadcasts and multicasts + ${fwcmd} add deny ip from any to 255.255.255.255 + ${fwcmd} add deny ip from any to 224.0.0.0/24 in # XXX + + # Noise from routers + ${fwcmd} add deny udp from any to any 520 in + + # Noise from webbrowsing. + # The stateful filter is a bit aggressive, and will cause some + # connection teardowns to be logged. + ${fwcmd} add deny tcp from any 80,443 to any 1024-65535 in + + # Deny and (if wanted) log the rest unconditionally. + log="" + if [ ${firewall_logdeny:-x} = "YES" -o ${firewall_logdeny:-x} = "yes" ] ; then + log="log logamount 500" # The default of 100 is too low. + sysctl net.inet.ip.fw.verbose=1 >/dev/null + fi + ${fwcmd} add deny $log ip from any to any + ;; + +[Cc][Ll][Oo][Ss][Ee][Dd]) + ${fwcmd} add 65000 deny ip from any to any + ;; +[Uu][Nn][Kk][Nn][Oo][Ww][Nn]) + ;; +*) + if [ -r "${firewall_type}" ]; then + ${fwcmd} ${firewall_flags} ${firewall_type} + fi + ;; +esac diff --git a/libexec/rc/rc.initdiskless b/libexec/rc/rc.initdiskless new file mode 100644 index 000000000000..3b66a3c4928a --- /dev/null +++ b/libexec/rc/rc.initdiskless @@ -0,0 +1,408 @@ +#!/bin/sh +# +# Copyright (c) 1999 Matt Dillon +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +# On entry to this script the entire system consists of a read-only root +# mounted via NFS. The kernel has run BOOTP and configured an interface +# (otherwise it would not have been able to mount the NFS root!) +# +# We use the contents of /conf to create and populate memory filesystems +# that are mounted on top of this root to implement the writable +# (and host-specific) parts of the root filesystem, and other volatile +# filesystems. +# +# The hierarchy in /conf has the form /conf/T/M/ where M are directories +# for which memory filesystems will be created and filled, +# and T is one of the "template" directories below: +# +# base universal base, typically a replica of the original root; +# default secondary universal base, typically overriding some +# of the files in the original root; +# ${ipba} where ${ipba} is the assigned broadcast IP address +# bcast/${ipba} same as above +# ${class} where ${class} is a list of directories supplied by +# bootp/dhcp through the T134 option. +# ${ipba} and ${class} are typically used to configure features +# for group of diskless clients, or even individual features; +# ${ip} where ${ip} is the machine's assigned IP address, typically +# used to set host-specific features; +# ip/${ip} same as above +# +# Template directories are scanned in the order they are listed above, +# with each successive directory overriding (merged into) the previous one; +# non-existing directories are ignored. The subdirectory forms exist to +# help keep the top level /conf manageable in large installations. +# +# The existence of a directory /conf/T/M causes this script to create a +# memory filesystem mounted as /M on the client. +# +# Some files in /conf have special meaning, namely: +# +# Filename Action +# ---------------------------------------------------------------- +# /conf/T/M/remount +# The contents of the file is a mount command. E.g. if +# /conf/1.2.3.4/foo/remount contains "mount -o ro /dev/ad0s3", +# then /dev/ad0s3 will be mounted on /conf/1.2.3.4/foo/ +# +# /conf/T/M/remount_optional +# If this file exists, then failure to execute the mount +# command contained in /conf/T/M/remount is non-fatal. +# +# /conf/T/M/remount_subdir +# If this file exists, then the behaviour of /conf/T/M/remount +# changes as follows: +# 1. /conf/T/M/remount is invoked to mount the root of the +# filesystem where the configuration data exists on a +# temporary mountpoint. +# 2. /conf/T/M/remount_subdir is then invoked to mount a +# *subdirectory* of the filesystem mounted by +# /conf/T/M/remount on /conf/T/M/. +# +# /conf/T/M/diskless_remount +# The contents of the file points to an NFS filesystem, +# possibly followed by mount_nfs options. If the server name +# is omitted, the script will prepend the root path used when +# booting. E.g. if you booted from foo.com:/path/to/root, +# an entry for /conf/base/etc/diskless_remount could be any of +# foo.com:/path/to/root/etc +# /etc -o ro +# Because mount_nfs understands ".." in paths, it is +# possible to mount from locations above the NFS root with +# paths such as "/../../etc". +# +# /conf/T/M/md_size +# The contents of the file specifies the size of the memory +# filesystem to be created, in 512 byte blocks. +# The default size is 10240 blocks (5MB). E.g. if +# /conf/base/etc/md_size contains "30000" then a 15MB MFS +# will be created. In case of multiple entries for the same +# directory M, the last one in the scanning order is used. +# NOTE: If you only need to create a memory filesystem but not +# initialize it from a template, it is preferable to specify +# it in fstab e.g. as "md /tmp mfs -s=30m,rw 0 0" +# +# /conf/T/SUBDIR.cpio.gz +# The file is cpio'd into /SUBDIR (and a memory filesystem is +# created for /SUBDIR if necessary). The presence of this file +# prevents the copy from /conf/T/SUBDIR/ +# +# /conf/T/M/extract +# This is alternative to SUBDIR.cpio.gz and remount. +# Similar to remount case, a memory filesystem is created +# for /M and initialized from a template but no mounting +# performed. Instead, this file is run passing /M as single +# argument. It is expected to extract template override to /M +# using auxiliary storage found in some embedded systems +# having NVRAM too small to hold mountable file system. +# +# /conf/T/SUBDIR.remove +# The list of paths contained in the file are rm -rf'd +# relative to /SUBDIR. +# +# /conf/diskless_remount +# Similar to /conf/T/M/diskless_remount above, but allows +# all of /conf to be remounted. This can be used to allow +# multiple roots to share the same /conf. +# +# +# You will almost universally want to create the following files under /conf +# +# File Content +# ---------------------------- ---------------------------------- +# /conf/base/etc/md_size size of /etc filesystem +# /conf/base/etc/diskless_remount "/etc" +# /conf/default/etc/rc.conf generic diskless config parameters +# /conf/default/etc/fstab generic diskless fstab e.g. like this +# +# foo:/root_part / nfs ro 0 0 +# foo:/usr_part /usr nfs ro 0 0 +# foo:/home_part /home nfs rw 0 0 +# md /tmp mfs -s=30m,rw 0 0 +# md /var mfs -s=30m,rw 0 0 +# proc /proc procfs rw 0 0 +# +# plus, possibly, overrides for password files etc. +# +# NOTE! /var, /tmp, and /dev will be typically created elsewhere, e.g. +# as entries in the fstab as above. +# Those filesystems should not be specified in /conf. +# +# (end of documentation, now get to the real code) + +dlv=`/sbin/sysctl -n vfs.nfs.diskless_valid 2> /dev/null` + +# DEBUGGING +# log something on stdout if verbose. +o_verbose=0 # set to 1 or 2 if you want more debugging +log() { + [ ${o_verbose} -gt 0 ] && echo "*** $* ***" + [ ${o_verbose} -gt 1 ] && read -p "=== Press enter to continue" foo +} + +# chkerr: +# +# Routine to check for error +# +# checks error code and drops into shell on failure. +# if shell exits, terminates script as well as /etc/rc. +# if remount_optional exists under the mountpoint, skip this check. +# +chkerr() { + lastitem () ( n=$(($# - 1)) ; shift $n ; echo $1 ) + mountpoint="$(lastitem $2)" + if [ -r $mountpoint/remount_optional ]; then + echo "$2 failed: ignoring due to remount_optional" + return + fi + case $1 in + 0) + ;; + *) + echo "$2 failed: dropping into /bin/sh" + /bin/sh + # RESUME + ;; + esac +} + +# The list of filesystems to umount after the copy +to_umount="" + +handle_remount() { # $1 = mount point + local nfspt mountopts b + b=$1 + log handle_remount $1 + [ -d $b -a -f $b/diskless_remount ] || return + read nfspt mountopts < $b/diskless_remount + log "nfspt ${nfspt} mountopts ${mountopts}" + # prepend the nfs root if not present + [ `expr "$nfspt" : '\(.\)'` = "/" ] && nfspt="${nfsroot}${nfspt}" + mount_nfs $mountopts $nfspt $b + chkerr $? "mount_nfs $nfspt $b" + to_umount="$b ${to_umount}" +} + +# Create a generic memory disk. +# The 'auto' parameter will attempt to use tmpfs(4), falls back to md(4). +# $1 is size in 512-byte sectors, $2 is the mount point. +mount_md() { + if [ ${o_verbose} -gt 0 ] ; then + /sbin/mdmfs -XL -S -s $1 auto $2 + else + /sbin/mdmfs -S -s $1 auto $2 + fi +} + +# Create the memory filesystem if it has not already been created +# +create_md() { + [ "x`eval echo \\$md_created_$1`" = "x" ] || return # only once + if [ "x`eval echo \\$md_size_$1`" = "x" ]; then + md_size=10240 + else + md_size=`eval echo \\$md_size_$1` + fi + log create_md $1 with size $md_size + mount_md $md_size /$1 + /bin/chmod 755 /$1 + eval md_created_$1=created +} + +# DEBUGGING +# +# set -v + +# Figure out our interface and IP. +# +bootp_ifc="" +bootp_ipa="" +bootp_ipbca="" +class="" +if [ ${dlv:=0} -ne 0 ] ; then + iflist=`ifconfig -l` + for i in ${iflist} ; do + set -- `ifconfig ${i}` + while [ $# -ge 1 ] ; do + if [ "${bootp_ifc}" = "" -a "$1" = "inet" ] ; then + bootp_ifc=${i} ; bootp_ipa=${2} ; shift + fi + if [ "${bootp_ipbca}" = "" -a "$1" = "broadcast" ] ; then + bootp_ipbca=$2; shift + fi + shift + done + if [ "${bootp_ifc}" != "" ] ; then + break + fi + done + # Get the values passed with the T134 bootp cookie. + class="`/sbin/sysctl -qn kern.bootp_cookie`" + + echo "Interface ${bootp_ifc} IP-Address ${bootp_ipa} Broadcast ${bootp_ipbca} ${class}" +fi + +log Figure out our NFS root path +# +set -- `mount -t nfs` +while [ $# -ge 1 ] ; do + if [ "$2" = "on" -a "$3" = "/" ]; then + nfsroot="$1" + break + fi + shift +done + +# The list of directories with template files +templates="base default" +if [ -n "${bootp_ipbca}" ]; then + templates="${templates} ${bootp_ipbca} bcast/${bootp_ipbca}" +fi +if [ -n "${class}" ]; then + templates="${templates} ${class}" +fi +if [ -n "${bootp_ipa}" ]; then + templates="${templates} ${bootp_ipa} ip/${bootp_ipa}" +fi + +# If /conf/diskless_remount exists, remount all of /conf. +handle_remount /conf + +# Resolve templates in /conf/base, /conf/default, /conf/${bootp_ipbca}, +# and /conf/${bootp_ipa}. For each subdirectory found within these +# directories: +# +# - calculate memory filesystem sizes. If the subdirectory (prior to +# NFS remounting) contains the file 'md_size', the contents specified +# in 512 byte sectors will be used to size the memory filesystem. Otherwise +# 8192 sectors (4MB) is used. +# +# - handle NFS remounts. If the subdirectory contains the file +# diskless_remount, the contents of the file is NFS mounted over +# the directory. For example /conf/base/etc/diskless_remount +# might contain 'myserver:/etc'. NFS remounts allow you to avoid +# having to dup your system directories in /conf. Your server must +# be sure to export those filesystems -alldirs, however. +# If the diskless_remount file contains a string beginning with a +# '/' it is assumed that the local nfsroot should be prepended to +# it before attempting to the remount. This allows the root to be +# relocated without needing to change the remount files. +# +log "templates are ${templates}" +for i in ${templates} ; do + for j in /conf/$i/* ; do + [ -d $j ] || continue + + # memory filesystem size specification + subdir=${j##*/} + [ -f $j/md_size ] && eval md_size_$subdir=`cat $j/md_size` + + # remount. Beware, the command is in the file itself! + if [ -f $j/remount ]; then + if [ -f $j/remount_subdir ]; then + k="/conf.tmp/$i/$subdir" + [ -d $k ] || continue + + # Mount the filesystem root where the config data is + # on the temporary mount point. + nfspt=`/bin/cat $j/remount` + $nfspt $k + chkerr $? "$nfspt $k" + + # Now use a nullfs mount to get the data where we + # really want to see it. + remount_subdir=`/bin/cat $j/remount_subdir` + remount_subdir_cmd="mount -t nullfs $k/$remount_subdir" + + $remount_subdir_cmd $j + chkerr $? "$remount_subdir_cmd $j" + + # XXX check order -- we must force $k to be unmounted + # after j, as j depends on k. + to_umount="$j $k ${to_umount}" + else + nfspt=`/bin/cat $j/remount` + $nfspt $j + chkerr $? "$nfspt $j" + to_umount="$j ${to_umount}" # XXX hope it is really a mount! + fi + fi + + # NFS remount + handle_remount $j + done +done + +# - Create all required MFS filesystems and populate them from +# our templates. Support both a direct template and a dir.cpio.gz +# archive. Support for auxiliary NVRAM. Support dir.remove files containing +# a list of relative paths to remove. +# +# The dir.cpio.gz form is there to make the copy process more efficient, +# so if the cpio archive is present, it prevents the files from dir/ +# from being copied. + +PATH=${PATH}:/rescue + +for i in ${templates} ; do + for j in /conf/$i/* ; do + subdir=${j##*/} + if [ -d $j -a ! -f $j.cpio.gz ]; then + create_md $subdir + cp -Rp $j/ /$subdir + fi + done + for j in /conf/$i/*.cpio.gz ; do + subdir=${j%*.cpio.gz} + subdir=${subdir##*/} + if [ -f $j ]; then + create_md $subdir + echo "Loading /$subdir from cpio archive $j" + (cd / ; tar -xpf $j) + fi + done + for j in /conf/$i/*/extract ; do + if [ -x $j ]; then + subdir=${j%*/extract} + subdir=${subdir##*/} + create_md $subdir + echo "Loading /$subdir using auxiliary command $j" + $j /$subdir + fi + done + for j in /conf/$i/*.remove ; do + subdir=${j%*.remove} + subdir=${subdir##*/} + if [ -f $j ]; then + # doubly sure it is a memory disk before rm -rf'ing + create_md $subdir + (cd /$subdir; rm -rf `/bin/cat $j`) + fi + done +done + +# umount partitions used to fill the memory filesystems +[ -n "${to_umount}" ] && umount $to_umount diff --git a/libexec/rc/rc.resume b/libexec/rc/rc.resume new file mode 100755 index 000000000000..147bc2ba4f8d --- /dev/null +++ b/libexec/rc/rc.resume @@ -0,0 +1,70 @@ +#!/bin/sh +# +# Copyright (c) 1999 Mitsuru IWASAKI +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# + +# sample run command file for APM Resume Event + +if [ $# -ne 2 ]; then + echo "Usage: $0 [apm|acpi] [standby,suspend|1-4]" + exit 1 +fi + +subsystem=$1 +state=$2 + +if [ -r /var/run/rc.suspend.pid ]; then + kill -9 `cat /var/run/rc.suspend.pid` + /bin/rm -f /var/run/rc.suspend.pid + echo 'rc.resume: killed rc.suspend that was still around' +fi + +# If a device driver has problems resuming, try unloading it before +# suspend and reloading it on resume. Example: +# kldload usb + +/usr/bin/logger -t $subsystem resumed at `/bin/date +'%Y%m%d %H:%M:%S'` +/bin/sync && /bin/sync && /bin/sync + +. /etc/rc.subr + +load_rc_config + +rcorder_opts="-k resume" + +case ${local_startup} in +[Nn][Oo] | '') ;; +*) find_local_scripts_new ;; +esac + +files=`rcorder ${rcorder_opts} /etc/rc.d/* ${local_rc} 2>/dev/null` + +for _rc_elem in $files; do + debug "run_rc_script $_rc_elem resume" + run_rc_script $_rc_elem resume +done + +exit 0 diff --git a/libexec/rc/rc.shutdown b/libexec/rc/rc.shutdown new file mode 100644 index 000000000000..3dfd7a7e0936 --- /dev/null +++ b/libexec/rc/rc.shutdown @@ -0,0 +1,115 @@ +#!/bin/sh +# +# Copyright (c) 1997 Ollivier Robert +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# + +# Site-specific closing actions for daemons run by init on shutdown, +# or before going single-user from multi-user. +# Output and errors are directed to console by init, and the +# console is the controlling terminal. + +stty status '^T' 2> /dev/null + +# Set shell to ignore SIGINT (2), but not children; +# shell catches SIGQUIT (3) and returns to single user after fsck. +trap : 2 +trap : 3 # shouldn't be needed + +HOME=/ +PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin +export HOME PATH + +rc_shutdown=${1:-"unspecified"} + +. /etc/rc.subr + +load_rc_config + +# reverse_list list +# print the list in reverse order +# +reverse_list() +{ + _revlist= + for _revfile in $*; do + _revlist="$_revfile${script_name_sep}$_revlist" + done + echo $_revlist +} + +# If requested, start a watchdog timer in the background which +# will terminate rc.shutdown if rc.shutdown doesn't complete +# within the specified time. +# +_rcshutdown_watchdog= +if [ -n "$rcshutdown_timeout" ]; then + debug "Initiating watchdog timer." + sleep $rcshutdown_timeout && ( + _msg="$rcshutdown_timeout second watchdog" + _msg="$_msg timeout expired. Shutdown terminated." + logger -t rc.shutdown "$_msg" + echo + echo "$_msg" + date + kill -KILL $$ >/dev/null 2>&1 + ) & + _rcshutdown_watchdog=$! +fi + +# Determine the shutdown order of the /etc/rc.d scripts, +# and perform the operation +# +rcorder_opts="-k shutdown" +if check_jail jailed; then + rcorder_opts="$rcorder_opts -s nojail" + if ! check_jail vnet; then + rcorder_opts="$rcorder_opts -s nojailvnet" + fi +fi + +case ${local_startup} in +[Nn][Oo] | '') ;; +*) find_local_scripts_new ;; +esac + +files=`rcorder ${rcorder_opts} /etc/rc.d/* ${local_rc} 2>/dev/null` + +for _rc_elem in `reverse_list $files`; do + debug "run_rc_script $_rc_elem faststop" + run_rc_script $_rc_elem faststop +done + +# Terminate the background watchdog timer (if it is running) +# +if [ -n "$_rcshutdown_watchdog" ]; then + pkill -TERM -P $_rcshutdown_watchdog >/dev/null 2>&1 +fi + +# Insert other shutdown procedures here + + +echo '.' +exit 0 diff --git a/libexec/rc/rc.subr b/libexec/rc/rc.subr new file mode 100644 index 000000000000..6be226021949 --- /dev/null +++ b/libexec/rc/rc.subr @@ -0,0 +1,2883 @@ +# $NetBSD: rc.subr,v 1.67 2006/10/07 11:25:15 elad Exp $ +# +# Copyright (c) 1997-2004 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Luke Mewburn. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# rc.subr +# functions used by various rc scripts +# + +: ${RC_PID:=$$}; export RC_PID + +# +# Operating System dependent/independent variables +# + +if [ -n "${_rc_subr_loaded}" ]; then + return +fi + +_rc_subr_loaded="YES" + +SYSCTL="/sbin/sysctl" +SYSCTL_N="${SYSCTL} -n" +SYSCTL_W="${SYSCTL}" +PROTECT="/usr/bin/protect" +ID="/usr/bin/id" +IDCMD="if [ -x $ID ]; then $ID -un; fi" +PS="/bin/ps -ww" +SERVICE=/usr/sbin/service +JAIL_CMD=/usr/sbin/jail +_svcj_generic_params="path=/ mount.nodevfs host=inherit" +JID=0 +CPUSET="/bin/cpuset" + +# Cache the services that we loaded with load_rc_config. +_loaded_services="" + +# rc_service provides the path to the service script that we are executing. +# This is not being set here in an execution context, necessarily, so it's +# really just a reasonable guess, and it will get overwritten later if +# we are executing from some other means than direct execution by service(8) +# or manual invocation of the service script. The prime example of this is +# during system startup, all rc scripts will be invoked via /etc/rc, so +# run_rc_script will overwrite rc_service with the file being sourced. +rc_service="$0" + +# +# functions +# --------- + +# is_verified file +# if VERIEXEC is active check that $file is verified +# +VERIEXEC="/sbin/veriexec" +if test -x $VERIEXEC && $VERIEXEC -i active > /dev/null 2>&1; then + is_verified() { $VERIEXEC -x $1; } +else + is_verified() { return 0; } +fi + +# indicate that we have vdot +_VDOT_SH=: + +# current state of O_VERIFY +o_verify() +{ + case $(echo $(set -o)) in + *verify" "off*) echo off;; + *verify" "on*) echo on;; + esac +} + +## +# o_verify_set want [save] +# +# record current state of verify in $save +# and set it to $want if different +# +o_verify_set() { + local x=$(o_verify) + + [ -z "$x" ] && return 0 + [ -z "$2" ] || eval $2=$x + [ "$x" = "$1" ] && return 0 + case "$1" in + on) + set -o verify + ;; + off) + set +o verify + ;; + esac +} + +# for unverified files +dotted= +dot() +{ + local f verify + + o_verify_set off verify + for f in "$@"; do + if [ -f $f -a -s $f ]; then + dotted="$dotted $f" + . $f + fi + done + o_verify_set $verify +} + +# try for verified, fallback to safe +sdot() +{ + local f + + for f in "$@"; do + [ -f $f -a -s $f ] || continue + vdot $f || safe_dot $f + done +} + +# convenience function - skip if not verified +vdot() +{ + local f rc=0 verify + + o_verify_set on verify + for f in "$@"; do + [ -f $f -a -s $f ] || continue + if is_verified $f 2> /dev/null; then + dotted="$dotted $f" + . $f + else + rc=80 # EAUTH + fi + done + o_verify_set $verify + return $rc +} + +# Exists [test] file ... +# report the first "file" that passes "test" (default -s). +Exists() +{ + local f _t=-s + + while :; do + : 1=$1 + case "$1" in + -?) + _t=$1 + shift + ;; + *) + break + ;; + esac + done + + for f in "$@"; do + [ $_t $f ] || continue + echo $f + return 0 + done + return 1 +} + +# do we have $1 (could be a function) +have() +{ + type "$1" > /dev/null 2>&1 +} + +# provide consistent means of logging progress +rc_log() +{ + date "+@ %s [%Y-%m-%d %H:%M:%S %Z] $*" +} + +# only rc_log if tracing enabled +# and $level >= $RC_LEVEL +rc_trace() +{ + local level=$1; shift + local cf=/etc/rc.conf.d/rc_trace + + if [ -z "$RC_LEVEL" ]; then + [ -f $cf ] || return + RC_LEVEL=0 # existence is 0 at least + sdot $cf # allow override + fi + [ ${RC_LEVEL:-0} -ge ${level:-0} ] || return + rc_log "$@" +} + +# list_vars pattern +# List variables matching glob pattern. +# +list_vars() +{ + # Localize 'set' option below. + local - + local IFS=$'\n' line varname + + # Disable path expansion in unquoted 'for' parameters below. + set -o noglob + + for line in $(set); do + varname="${line%%=*}" + + case "$varname" in + "$line"|*[!a-zA-Z0-9_]*) + continue + ;; + $1) + echo $varname + ;; + esac + done +} + +# set_rcvar [var] [defval] [desc] +# +# Echo or define a rc.conf(5) variable name. Global variable +# $rcvars is used. +# +# If no argument is specified, echo "${name}_enable". +# +# If only a var is specified, echo "${var}_enable". +# +# If var and defval are specified, the ${var} is defined as +# rc.conf(5) variable and the default value is ${defvar}. An +# optional argument $desc can also be specified to add a +# description for that. +# +set_rcvar() +{ + local _var + + case $# in + 0) echo ${name}_enable ;; + 1) echo ${1}_enable ;; + *) + debug "set_rcvar: \$$1=$2 is added" \ + " as a rc.conf(5) variable." + _var=$1 + rcvars="${rcvars# } $_var" + eval ${_var}_defval=\"$2\" + shift 2 + eval ${_var}_desc=\"$*\" + ;; + esac +} + +# set_rcvar_obsolete oldvar [newvar] [msg] +# Define obsolete variable. +# Global variable $rcvars_obsolete is used. +# +set_rcvar_obsolete() +{ + local _var + _var=$1 + debug "set_rcvar_obsolete: \$$1(old) -> \$$2(new) is defined" + + rcvars_obsolete="${rcvars_obsolete# } $1" + eval ${1}_newvar=\"$2\" + shift 2 + eval ${_var}_obsolete_msg=\"$*\" +} + +# +# force_depend script [rcvar] +# Force a service to start. Intended for use by services +# to resolve dependency issues. +# $1 - filename of script, in /etc/rc.d, to run +# $2 - name of the script's rcvar (minus the _enable) +# +force_depend() +{ + local _depend _dep_rcvar + + _depend="$1" + _dep_rcvar="${2:-$1}_enable" + + [ -n "$rc_fast" ] && ! checkyesno always_force_depends && + checkyesno $_dep_rcvar && return 0 + + /etc/rc.d/${_depend} forcestatus >/dev/null 2>&1 && return 0 + + info "${name} depends on ${_depend}, which will be forced to start." + if ! /etc/rc.d/${_depend} forcestart; then + warn "Unable to force ${_depend}. It may already be running." + return 1 + fi +} + +# +# checkyesno var +# Test $1 variable, and warn if not set to YES or NO. +# Return 0 if it's "yes" (et al), nonzero otherwise. +# +checkyesno() +{ + eval _value=\$${1} + debug "checkyesno: $1 is set to $_value." + case $_value in + + # "yes", "true", "on", or "1" + [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) + return 0 + ;; + + # "no", "false", "off", or "0" + [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0) + return 1 + ;; + *) + warn "\$${1} is not set properly - see rc.conf(5)." + return 1 + ;; + esac +} + +# +# reverse_list list +# print the list in reverse order +# +reverse_list() +{ + _revlist= + for _revfile; do + _revlist="$_revfile $_revlist" + done + echo $_revlist +} + +# stop_boot always +# If booting directly to multiuser or $always is enabled, +# send SIGTERM to the parent (/etc/rc) to abort the boot. +# Otherwise just exit. +# +stop_boot() +{ + local always + + case $1 in + # "yes", "true", "on", or "1" + [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) + always=true + ;; + *) + always=false + ;; + esac + if [ "$autoboot" = yes -o "$always" = true ]; then + echo "ERROR: ABORTING BOOT (sending SIGTERM to parent)!" + kill -TERM ${RC_PID} + fi + exit 1 +} + +# +# mount_critical_filesystems type +# Go through the list of critical filesystems as provided in +# the rc.conf(5) variable $critical_filesystems_${type}, checking +# each one to see if it is mounted, and if it is not, mounting it. +# +mount_critical_filesystems() +{ + eval _fslist=\$critical_filesystems_${1} + for _fs in $_fslist; do + mount | ( + _ismounted=false + while read what _on on _type type; do + if [ $on = $_fs ]; then + _ismounted=true + fi + done + if $_ismounted; then + : + else + mount $_fs >/dev/null 2>&1 + fi + ) + done +} + +# +# check_pidfile pidfile procname [interpreter] +# Parses the first line of pidfile for a PID, and ensures +# that the process is running and matches procname. +# Prints the matching PID upon success, nothing otherwise. +# interpreter is optional; see _find_processes() for details. +# +check_pidfile() +{ + _pidfile=$1 + _procname=$2 + _interpreter=$3 + if [ -z "$_pidfile" -o -z "$_procname" ]; then + err 3 'USAGE: check_pidfile pidfile procname [interpreter]' + fi + if [ ! -f $_pidfile ]; then + debug "pid file ($_pidfile): not readable." + return + fi + read _pid _junk < $_pidfile + if [ -z "$_pid" ]; then + debug "pid file ($_pidfile): no pid in file." + return + fi + _find_processes $_procname ${_interpreter:-.} '-p '"$_pid" +} + +# +# check_process procname [interpreter] +# Ensures that a process (or processes) named procname is running. +# Prints a list of matching PIDs. +# interpreter is optional; see _find_processes() for details. +# +check_process() +{ + _procname=$1 + _interpreter=$2 + if [ -z "$_procname" ]; then + err 3 'USAGE: check_process procname [interpreter]' + fi + _find_processes $_procname ${_interpreter:-.} '-ax' +} + +# +# _find_processes procname interpreter psargs +# Search for procname in the output of ps generated by psargs. +# Prints the PIDs of any matching processes, space separated. +# +# If interpreter == ".", check the following variations of procname +# against the first word of each command: +# procname +# `basename procname` +# `basename procname` + ":" +# "(" + `basename procname` + ")" +# "[" + `basename procname` + "]" +# +# If interpreter != ".", read the first line of procname, remove the +# leading #!, normalise whitespace, append procname, and attempt to +# match that against each command, either as is, or with extra words +# at the end. As an alternative, to deal with interpreted daemons +# using perl, the basename of the interpreter plus a colon is also +# tried as the prefix to procname. +# +_find_processes() +{ + if [ $# -ne 3 ]; then + err 3 'USAGE: _find_processes procname interpreter psargs' + fi + _procname=$1 + _interpreter=$2 + _psargs=$3 + + _pref= + if [ $_interpreter != "." ]; then # an interpreted script + _script="${_chroot}${_chroot:+/}$_procname" + if [ -r "$_script" ]; then + read _interp < $_script # read interpreter name + case "$_interp" in + \#!*) + _interp=${_interp#\#!} # strip #! + set -- $_interp + case $1 in + */bin/env) + shift # drop env to get real name + ;; + esac + if [ $_interpreter != $1 ]; then + warn "\$command_interpreter $_interpreter != $1" + fi + ;; + *) + warn "no shebang line in $_script" + set -- $_interpreter + ;; + esac + else + warn "cannot read shebang line from $_script" + set -- $_interpreter + fi + _interp="$* $_procname" # cleanup spaces, add _procname + _interpbn=${1##*/} + _fp_args='_argv' + _fp_match='case "$_argv" in + ${_interp}|"${_interp} "*|"[${_interpbn}]"|"${_interpbn}: ${_procname}"*)' + else # a normal daemon + _procnamebn=${_procname##*/} + _fp_args='_arg0 _argv' + _fp_match='case "$_arg0" in + $_procname|$_procnamebn|${_procnamebn}:|"(${_procnamebn})"|"[${_procnamebn}]")' + fi + + if checkyesno ${name}_svcj && [ "${_rc_svcj}" != jailing ]; then + JID=$(/usr/sbin/jls -j svcj-${name} jid 2>/dev/null) + + case ${JID} in + ''|*[!0-9]*) + # svcj-jail doesn't exist, fallback to host-check + JID=0 + ;; + esac + fi + _proccheck="\ + $PS 2>/dev/null -o pid= -o jid= -o command= $_psargs"' | + while read _npid _jid '"$_fp_args"'; do + '"$_fp_match"' + if [ "$JID" -eq "$_jid" ]; + then echo -n "$_pref$_npid"; + _pref=" "; + fi + ;; + esac + done' + +# debug "in _find_processes: proccheck is ($_proccheck)." + eval $_proccheck +} + +# sort_lite [-b] [-n] [-k POS] [-t SEP] +# A lite version of sort(1) (supporting a few options) that can be used +# before the real sort(1) is available (e.g., in scripts that run prior +# to mountcritremote). Requires only shell built-in functionality. +# +sort_lite() +{ + local funcname=sort_lite + local sort_sep="$IFS" sort_ignore_leading_space= + local sort_field=0 sort_strict_fields= sort_numeric= + local nitems=0 skip_leading=0 trim= + + local OPTIND flag + while getopts bnk:t: flag; do + case "$flag" in + b) sort_ignore_leading_space=1 ;; + n) sort_numeric=1 sort_ignore_leading_space=1 ;; + k) sort_field="${OPTARG%%,*}" ;; # only up to first comma + # NB: Unlike sort(1) only one POS allowed + t) sort_sep="$OPTARG" + if [ ${#sort_sep} -gt 1 ]; then + echo "$funcname: multi-character tab \`$sort_sep'" >&2 + return 1 + fi + sort_strict_fields=1 + ;; + \?) return 1 ;; + esac + done + shift $(( $OPTIND - 1 )) + + # Create transformation pattern to trim leading text if desired + case "$sort_field" in + ""|[!0-9]*|*[!0-9.]*) + echo "$funcname: invalid sort field \`$sort_field'" >&2 + return 1 + ;; + *.*) + skip_leading=${sort_field#*.} sort_field=${sort_field%%.*} + while [ ${skip_leading:-0} -gt 1 ] 2> /dev/null; do + trim="$trim?" skip_leading=$(( $skip_leading - 1 )) + done + esac + + # Copy input to series of local numbered variables + # NB: IFS of NULL preserves leading whitespace + local LINE + while IFS= read -r LINE || [ "$LINE" ]; do + nitems=$(( $nitems + 1 )) + local src_$nitems="$LINE" + done + + # + # Sort numbered locals using insertion sort + # + local curitem curitem_orig curitem_mod curitem_haskey + local dest dest_orig dest_mod dest_haskey + local d gt n + local i=1 + while [ $i -le $nitems ]; do + curitem_haskey=1 # Assume sort field (-k POS) exists + eval curitem=\"\$src_$i\" + curitem_mod="$curitem" # for modified comparison + curitem_orig="$curitem" # for original comparison + + # Trim leading whitespace if desired + if [ "$sort_ignore_leading_space" ]; then + while case "$curitem_orig" in + [$IFS]*) : ;; *) false; esac + do + curitem_orig="${curitem_orig#?}" + done + curitem_mod="$curitem_orig" + fi + + # Shift modified comparison value if sort field (-k POS) is > 1 + n=$sort_field + while [ $n -gt 1 ]; do + case "$curitem_mod" in + *[$sort_sep]*) + # Cut text up-to (and incl.) first separator + curitem_mod="${curitem_mod#*[$sort_sep]}" + + # Skip NULLs unless strict field splitting + [ "$sort_strict_fields" ] || + [ "${curitem_mod%%[$sort_sep]*}" ] || + [ $n -eq 2 ] || + continue + ;; + *) + # Asked for a field that doesn't exist + curitem_haskey= break + esac + n=$(( $n - 1 )) + done + + # Trim trailing words if sort field >= 1 + [ $sort_field -ge 1 -a "$sort_numeric" ] && + curitem_mod="${curitem_mod%%[$sort_sep]*}" + + # Apply optional trim (-k POS.TRIM) to cut leading characters + curitem_mod="${curitem_mod#$trim}" + + # Determine the type of modified comparison to use initially + # NB: Prefer numerical if requested but fallback to standard + case "$curitem_mod" in + ""|[!0-9]*) # NULL or begins with non-number + gt=">" + [ "$sort_numeric" ] && curitem_mod=0 + ;; + *) + if [ "$sort_numeric" ]; then + gt="-gt" + curitem_mod="${curitem_mod%%[!0-9]*}" + # NB: trailing non-digits removed + # otherwise numeric comparison fails + else + gt=">" + fi + esac + + # If first time through, short-circuit below position-search + if [ $i -le 1 ]; then + d=0 + else + d=1 + fi + + # + # Find appropriate element position + # + while [ $d -gt 0 ] + do + dest_haskey=$curitem_haskey + eval dest=\"\$dest_$d\" + dest_mod="$dest" # for modified comparison + dest_orig="$dest" # for original comparison + + # Trim leading whitespace if desired + if [ "$sort_ignore_leading_space" ]; then + while case "$dest_orig" in + [$IFS]*) : ;; *) false; esac + do + dest_orig="${dest_orig#?}" + done + dest_mod="$dest_orig" + fi + + # Shift modified value if sort field (-k POS) is > 1 + n=$sort_field + while [ $n -gt 1 ]; do + case "$dest_mod" in + *[$sort_sep]*) + # Cut text up-to (and incl.) 1st sep + dest_mod="${dest_mod#*[$sort_sep]}" + + # Skip NULLs unless strict fields + [ "$sort_strict_fields" ] || + [ "${dest_mod%%[$sort_sep]*}" ] || + [ $n -eq 2 ] || + continue + ;; + *) + # Asked for a field that doesn't exist + dest_haskey= break + esac + n=$(( $n - 1 )) + done + + # Trim trailing words if sort field >= 1 + [ $sort_field -ge 1 -a "$sort_numeric" ] && + dest_mod="${dest_mod%%[$sort_sep]*}" + + # Apply optional trim (-k POS.TRIM), cut leading chars + dest_mod="${dest_mod#$trim}" + + # Determine type of modified comparison to use + # NB: Prefer numerical if requested, fallback to std + case "$dest_mod" in + ""|[!0-9]*) # NULL or begins with non-number + gt=">" + [ "$sort_numeric" ] && dest_mod=0 + ;; + *) + if [ "$sort_numeric" ]; then + gt="-gt" + dest_mod="${dest_mod%%[!0-9]*}" + # NB: kill trailing non-digits + # for numeric comparison safety + else + gt=">" + fi + esac + + # Break if we've found the proper element position + if [ "$curitem_haskey" -a "$dest_haskey" ]; then + if [ "$dest_mod" = "$curitem_mod" ]; then + [ "$dest_orig" ">" "$curitem_orig" ] && + break + elif [ "$dest_mod" $gt "$curitem_mod" ] \ + 2> /dev/null + then + break + fi + else + [ "$dest_orig" ">" "$curitem_orig" ] && break + fi + + # Break if we've hit the end + [ $d -ge $i ] && break + + d=$(( $d + 1 )) + done + + # Shift remaining positions forward, making room for new item + n=$i + while [ $n -ge $d ]; do + # Shift destination item forward one placement + eval dest_$(( $n + 1 ))=\"\$dest_$n\" + n=$(( $n - 1 )) + done + + # Place the element + if [ $i -eq 1 ]; then + local dest_1="$curitem" + else + local dest_$d="$curitem" + fi + + i=$(( $i + 1 )) + done + + # Print sorted results + d=1 + while [ $d -le $nitems ]; do + eval echo \"\$dest_$d\" + d=$(( $d + 1 )) + done +} + +# +# wait_for_pids pid [pid ...] +# spins until none of the pids exist +# +wait_for_pids() +{ + local _list _prefix _nlist _j + + _list="$@" + if [ -z "$_list" ]; then + return + fi + _prefix= + while true; do + _nlist="" + for _j in $_list; do + if kill -0 $_j 2>/dev/null; then + _nlist="${_nlist}${_nlist:+ }$_j" + fi + done + if [ -z "$_nlist" ]; then + break + fi + _list=$_nlist + echo -n ${_prefix:-"Waiting for PIDS: "}$_list + _prefix=", " + pwait -o $_list 2>/dev/null + # At least one of the processes we were waiting for + # has terminated. Give init a chance to collect it + # before looping around and checking again. + sleep 1 + done + if [ -n "$_prefix" ]; then + echo "." + fi +} + +# +# get_pidfile_from_conf string file +# +# Takes a string to search for in the specified file. +# Ignores lines with traditional comment characters. +# +# Example: +# +# if get_pidfile_from_conf string file; then +# pidfile="$_pidfile_from_conf" +# else +# pidfile='appropriate default' +# fi +# +get_pidfile_from_conf() +{ + if [ -z "$1" -o -z "$2" ]; then + err 3 "USAGE: get_pidfile_from_conf string file ($name)" + fi + + local string file line + + string="$1" ; file="$2" + + if [ ! -s "$file" ]; then + err 3 "get_pidfile_from_conf: $file does not exist ($name)" + fi + + while read line; do + case "$line" in + *[#\;]*${string}*) continue ;; + *${string}*) break ;; + esac + done < $file + + if [ -n "$line" ]; then + line=${line#*/} + _pidfile_from_conf="/${line%%[\"\;]*}" + else + return 1 + fi +} + +# +# check_startmsgs +# If rc_quiet is set (usually as a result of using faststart at +# boot time) check if rc_startmsgs is enabled. +# +check_startmsgs() +{ + if [ -n "$rc_quiet" ]; then + checkyesno rc_startmsgs + else + return 0 + fi +} + +# +# startmsg +# Preferred method to use when displaying start messages in lieu of echo. +# +startmsg() +{ + check_startmsgs && echo "$@" +} + +# +# run_rc_command argument +# Search for argument in the list of supported commands, which is: +# "start stop restart rcvar status poll ${extra_commands}" +# If there's a match, run ${argument}_cmd or the default method +# (see below). +# +# If argument has a given prefix, then change the operation as follows: +# Prefix Operation +# ------ --------- +# fast Skip the pid check, and set rc_fast=yes, rc_quiet=yes +# force Set ${rcvar} to YES, and set rc_force=yes +# one Set ${rcvar} to YES +# quiet Don't output some diagnostics, and set rc_quiet=yes +# +# The following globals are used: +# +# Name Needed Purpose +# ---- ------ ------- +# name y Name of script. +# +# command n Full path to command. +# Not needed if ${rc_arg}_cmd is set for +# each keyword. +# +# command_args n Optional args/shell directives for command. +# +# command_interpreter n If not empty, command is interpreted, so +# call check_{pidfile,process}() appropriately. +# +# desc n Description of script. +# +# extra_commands n List of extra commands supported. +# +# pidfile n If set, use check_pidfile $pidfile $command, +# otherwise use check_process $command. +# In either case, only check if $command is set. +# +# procname n Process name to check for instead of $command. +# +# rcvar n This is checked with checkyesno to determine +# if the action should be run. +# +# ${name}_program n Full path to command. +# Meant to be used in /etc/rc.conf to override +# ${command}. +# +# ${name}_chroot n Directory to chroot to before running ${command} +# Requires /usr to be mounted. +# +# ${name}_chdir n Directory to cd to before running ${command} +# (if not using ${name}_chroot). +# +# ${name}_cpuset n A list of CPUs to run ${command} on. +# Requires /usr to be mounted. +# +# ${name}_flags n Arguments to call ${command} with. +# NOTE: $flags from the parent environment +# can be used to override this. +# +# ${name}_env n Environment variables to run ${command} with. +# +# ${name}_env_file n File to source variables to run ${command} with. +# +# ${name}_fib n Routing table number to run ${command} with. +# +# ${name}_nice n Nice level to run ${command} at. +# +# ${name}_oomprotect n Don't kill ${command} when swap space is exhausted. +# +# ${name}_umask n The file creation mask to run ${command} with. +# +# ${name}_user n User to run ${command} as, using su(1) if not +# using ${name}_chroot. +# Requires /usr to be mounted. +# +# ${name}_group n Group to run chrooted ${command} as. +# Requires /usr to be mounted. +# +# ${name}_groups n Comma separated list of supplementary groups +# to run the chrooted ${command} with. +# Requires /usr to be mounted. +# +# ${name}_prepend n Command added before ${command}. +# +# ${name}_setup n Command executed during start, restart and +# reload before ${rc_arg}_precmd is run. +# +# ${name}_login_class n Login class to use, else "daemon". +# +# ${name}_limits n limits(1) to apply to ${command}. +# +# ${name}_offcmd n If set, run during start +# if a service is not enabled. +# +# ${rc_arg}_cmd n If set, use this as the method when invoked; +# Otherwise, use default command (see below) +# +# ${rc_arg}_precmd n If set, run just before performing the +# ${rc_arg}_cmd method in the default +# operation (i.e, after checking for required +# bits and process (non)existence). +# If this completes with a non-zero exit code, +# don't run ${rc_arg}_cmd. +# +# ${rc_arg}_postcmd n If set, run just after performing the +# ${rc_arg}_cmd method, if that method +# returned a zero exit code. +# +# required_dirs n If set, check for the existence of the given +# directories before running a (re)start command. +# +# required_files n If set, check for the readability of the given +# files before running a (re)start command. +# +# required_modules n If set, ensure the given kernel modules are +# loaded before running a (re)start command. +# The check and possible loads are actually +# done after start_precmd so that the modules +# aren't loaded in vain, should the precmd +# return a non-zero status to indicate a error. +# If a word in the list looks like "foo:bar", +# "foo" is the KLD file name and "bar" is the +# module name. If a word looks like "foo~bar", +# "foo" is the KLD file name and "bar" is a +# egrep(1) pattern matching the module name. +# Otherwise the module name is assumed to be +# the same as the KLD file name, which is most +# common. See load_kld(). +# +# required_vars n If set, perform checkyesno on each of the +# listed variables before running the default +# (re)start command. +# +# Default behaviour for a given argument, if no override method is +# provided: +# +# Argument Default behaviour +# -------- ----------------- +# start if !running && checkyesno ${rcvar} +# ${command} +# +# stop if ${pidfile} +# rc_pid=$(check_pidfile $pidfile $command) +# else +# rc_pid=$(check_process $command) +# kill $sig_stop $rc_pid +# wait_for_pids $rc_pid +# ($sig_stop defaults to TERM.) +# +# reload Similar to stop, except use $sig_reload instead, +# and don't wait_for_pids. +# $sig_reload defaults to HUP. +# Note that `reload' isn't provided by default, +# it should be enabled via $extra_commands. +# +# restart Run `stop' then `start'. +# +# status Show if ${command} is running, etc. +# +# poll Wait for ${command} to exit. +# +# rcvar Display what rc.conf variable is used (if any). +# +# enabled Return true if the service is enabled. +# +# describe Show the service's description +# +# extracommands Show the service's extra commands +# +# Variables available to methods, and after run_rc_command() has +# completed: +# +# Variable Purpose +# -------- ------- +# rc_arg Argument to command, after fast/force/one processing +# performed +# +# rc_flags Flags to start the default command with. +# Defaults to ${name}_flags, unless overridden +# by $flags from the environment. +# This variable may be changed by the precmd method. +# +# rc_service Path to the service being executed, in case the service +# needs to re-invoke itself. +# +# rc_pid PID of command (if appropriate) +# +# rc_fast Not empty if "fast" was provided (q.v.) +# +# rc_force Not empty if "force" was provided (q.v.) +# +# rc_quiet Not empty if "quiet" was provided +# +# +run_rc_command() +{ + _return=0 + rc_arg=$1 + if [ -z "$name" ]; then + err 3 'run_rc_command: $name is not set.' + fi + + DebugOn rc:all rc:all:$rc_arg rc:$name rc:$name:$rc_arg $name:$rc_arg + + # Don't repeat the first argument when passing additional command- + # line arguments to the command subroutines. + # + shift 1 + rc_extra_args="$*" + + _rc_prefix= + case "$rc_arg" in + fast*) # "fast" prefix; don't check pid + rc_arg=${rc_arg#fast} + rc_fast=yes + rc_quiet=yes + ;; + force*) # "force" prefix; always run + rc_force=yes + _rc_prefix=force + rc_arg=${rc_arg#${_rc_prefix}} + if [ -n "${rcvar}" ]; then + eval ${rcvar}=YES + fi + ;; + one*) # "one" prefix; set ${rcvar}=yes + _rc_prefix=one + rc_arg=${rc_arg#${_rc_prefix}} + if [ -n "${rcvar}" ]; then + eval ${rcvar}=YES + fi + ;; + quiet*) # "quiet" prefix; omit some messages + _rc_prefix=quiet + rc_arg=${rc_arg#${_rc_prefix}} + rc_quiet=yes + ;; + esac + + eval _override_command=\$${name}_program + command=${_override_command:-$command} + + _keywords="start stop restart rcvar enable disable delete enabled describe extracommands $extra_commands" + rc_pid= + _pidcmd= + _procname=${procname:-${command}} + + eval _cpuset=\$${name}_cpuset + + # Loose validation of the configured cpuset; just make sure it starts + # with a number. There have also been cases in the past where a hyphen + # in a service name has caused eval errors, which trickle down into + # various variables; don't let a situation like that break a bunch of + # services just because of cpuset(1). + case "$_cpuset" in + [0-9]*) ;; + *) _cpuset="" ;; + esac + + _cpusetcmd= + if [ -n "$_cpuset" ]; then + _cpusetcmd="$CPUSET -l $_cpuset" + fi + + # If a specific jail has a specific svcj request, honor it (YES/NO). + # If not (variable empty), evaluate the global svcj catch-all. + # A global YES can be overriden by a specific NO, and a global NO is overriden + # by a specific YES. + eval _svcj=\$${name}_svcj + if [ -z "$_svcj" ]; then + _svcj=${svcj_all_enable} + if [ -z "$_svcj" ]; then + eval ${name}_svcj=NO + fi + fi + + # setup pid check command + if [ -n "$_procname" ]; then + if [ -n "$pidfile" ]; then + _pidcmd='rc_pid=$(check_pidfile '"$pidfile $_procname $command_interpreter"')' + else + _pidcmd='rc_pid=$(check_process '"$_procname $command_interpreter"')' + fi + _keywords="${_keywords} status poll" + else + if [ ! -z "${status_cmd}" ] + then + _keywords="${_keywords} status" + fi + fi + + if [ -z "$rc_arg" ]; then + rc_usage $_keywords + fi + + if [ "$rc_arg" = "enabled" ] ; then + checkyesno ${rcvar} + return $? + fi + + if [ -n "$flags" ]; then # allow override from environment + rc_flags=$flags + else + eval rc_flags=\$${name}_flags + fi + eval _chdir=\$${name}_chdir _chroot=\$${name}_chroot \ + _nice=\$${name}_nice _user=\$${name}_user \ + _group=\$${name}_group _groups=\$${name}_groups \ + _fib=\$${name}_fib _env=\$${name}_env \ + _prepend=\$${name}_prepend _login_class=\${${name}_login_class:-daemon} \ + _limits=\$${name}_limits _oomprotect=\$${name}_oomprotect \ + _setup=\$${name}_setup _env_file=\$${name}_env_file \ + _umask=\$${name}_umask _svcj_options=\$${name}_svcj_options \ + _svcj_ipaddrs=\$${name}_svcj_ipaddrs + + if [ -n "$_env_file" ] && [ -r "${_env_file}" ]; then # load env from file + set -a + . $_env_file + set +a + fi + + if [ -n "$_user" ]; then # unset $_user if running as that user + if [ "$_user" = "$(eval $IDCMD)" ]; then + unset _user + fi + fi + + _svcj_ip4_addrs="" + _svcj_ip6_addrs="" + _svcj_cmd_options="" + + if [ -n "$_svcj_ipaddrs" ]; then + _svcj_ip="new" + + for addr in $_svcj_ipaddrs; do + case $addr in + *:*) _svcj_ip6_addrs="$addr,${_svcj_ip6_addrs}" ;; + *) _svcj_ip4_addrs="$addr,${_svcj_ip4_addrs}" ;; + esac + done + else + _svcj_ip="inherit" + fi + + if check_kern_features inet; then + _svcj_ip4="ip4=${_svcj_ip}" + if [ -n "$_svcj_ip4_addrs" ]; then + _svcj_cmd_options="ip4.addr=${_svcj_ip4_addrs%*,} ${_svcj_cmd_options}" + fi + else + if [ -n "$_svcj_ip4_addrs" ]; then + warn "$rc_service: ${name}_svcj_ipaddrs contains at least one IPv4 address, but IPv4 is not enabled in the kernel; IPv4 addresses will be ignored." + fi + fi + + if check_kern_features inet6; then + _svcj_ip6="ip6=${_svcj_ip}" + if [ -n "$_svcj_ip6_addrs" ]; then + _svcj_cmd_options="ip6.addr=${_svcj_ip6_addrs%*,} ${_svcj_cmd_options}" + fi + else + if [ -n "$_svcj_ip6_addrs" ]; then + warn "$rc_service: ${name}_svcj_ipaddrs contains at least one IPv6 address, but IPv6 is not enabled in the kernel; IPv6 addresses will be ignored." + fi + fi + + if [ -n "$_svcj_options" ]; then # translate service jail options + _svcj_sysvipc_x=0 + for _svcj_option in $_svcj_options; do + case "$_svcj_option" in + mlock) + _svcj_cmd_options="allow.mlock ${_svcj_cmd_options}" + ;; + netv4) + _svcj_cmd_options="${_svcj_ip4} allow.reserved_ports ${_svcj_cmd_options}" + ;; + netv6) + _svcj_cmd_options="${_svcj_ip6} allow.reserved_ports ${_svcj_cmd_options}" + ;; + net_basic) + _svcj_cmd_options="${_svcj_ip4} ${_svcj_ip6} allow.reserved_ports ${_svcj_cmd_options}" + ;; + net_raw) + _svcj_cmd_options="allow.raw_sockets ${_svcj_cmd_options}" + ;; + net_all) + _svcj_cmd_options="allow.socket_af allow.raw_sockets allow.reserved_ports ${_svcj_ip4} ${_svcj_ip6} ${_svcj_cmd_options}" + ;; + nfsd) + _svcj_cmd_options="allow.nfsd enforce_statfs=1 ${_svcj_cmd_options}" + ;; + routing) + _svcj_cmd_options="allow.routing ${_svcj_cmd_options}" + ;; + settime) + _svcj_cmd_options="allow.settime ${_svcj_cmd_options}" + ;; + sysvipc) + _svcj_sysvipc_x=$((${_svcj_sysvipc_x} + 1)) + _svcj_cmd_options="sysvmsg=inherit sysvsem=inherit sysvshm=inherit ${_svcj_cmd_options}" + ;; + sysvipcnew) + _svcj_sysvipc_x=$((${_svcj_sysvipc_x} + 1)) + _svcj_cmd_options="sysvmsg=new sysvsem=new sysvshm=new ${_svcj_cmd_options}" + ;; + vmm) + _svcj_cmd_options="allow.vmm ${_svcj_cmd_options}" + ;; + *) + echo ${name}: unknown service jail option: $_svcj_option + ;; + esac + done + if [ ${_svcj_sysvipc_x} -gt 1 ]; then + echo -n "ERROR: more than one sysvipc option is " + echo "specified in ${name}_svcj_options: $_svcj_options" + return 1 + fi + fi + + [ -z "$autoboot" ] && eval $_pidcmd # determine the pid if necessary + + for _elem in $_keywords; do + if [ "$_elem" != "$rc_arg" ]; then + continue + fi + # if ${rcvar} is set, $1 is not "rcvar", "describe", + # "enable", "delete" or "status", and ${rc_pid} is + # not set, run: + # checkyesno ${rcvar} + # and return if that failed + # + if [ -n "${rcvar}" -a "$rc_arg" != "rcvar" -a "$rc_arg" != "stop" \ + -a "$rc_arg" != "delete" -a "$rc_arg" != "enable" \ + -a "$rc_arg" != "describe" -a "$rc_arg" != "status" ] || + [ -n "${rcvar}" -a "$rc_arg" = "stop" -a -z "${rc_pid}" ]; then + if ! checkyesno ${rcvar}; then + [ "$rc_arg" = "start" ] && _run_rc_offcmd + if [ -z "${rc_quiet}" ]; then + echo -n "Cannot '${rc_arg}' $name. Set ${rcvar} to " + echo -n "YES in /etc/rc.conf or use 'one${rc_arg}' " + echo "instead of '${rc_arg}'." + fi + return 0 + fi + fi + + if [ $rc_arg = "start" -a -z "$rc_fast" -a -n "$rc_pid" ]; then + if [ -z "$rc_quiet" ]; then + echo 1>&2 "${name} already running? " \ + "(pid=$rc_pid)." + fi + return 1 + fi + + # if there's a custom ${XXX_cmd}, + # run that instead of the default + # + eval _cmd=\$${rc_arg}_cmd \ + _precmd=\$${rc_arg}_precmd \ + _postcmd=\$${rc_arg}_postcmd + + if [ -n "$_cmd" ]; then + if [ "$_cmd" != : ]; then + rc_trace 1 "$_cmd" + fi + if [ -n "$_env" ]; then + eval "export -- $_env" + fi + + if [ "${_rc_svcj}" != jailing ]; then + # service can redefine all so + # check for valid setup target + if [ "$rc_arg" = 'start' -o \ + "$rc_arg" = 'restart' -o \ + "$rc_arg" = 'reload' ]; then + _run_rc_setup || \ + warn "failed to setup ${name}" + fi + _run_rc_precmd || return 1 + fi + if ! checkyesno ${name}_svcj; then + _run_rc_doit "$_cpusetcmd $_cmd $rc_extra_args" || return 1 + else + case "$rc_arg" in + start) + if [ "${_rc_svcj}" != jailing ]; then + _return=1 + _do_jailing=1 + + if check_jail jailed; then + if [ $(${SYSCTL_N} security.jail.children.max) -eq 0 ]; then + echo ERROR: jail parameter children.max is set to 0, can not create a new service jail. + _do_jailing=0 + else + _free_jails=$(($(${SYSCTL_N} security.jail.children.max) - $(${SYSCTL_N} security.jail.children.cur))) + if [ ${_free_jails} -eq 0 ]; then + echo ERROR: max number of jail children reached, can not create a new service jail. + _do_jailing=0 + + fi + fi + fi + if [ ${_do_jailing} -eq 1 ]; then + $JAIL_CMD -c $_svcj_generic_params $_svcj_cmd_options \ + exec.start="${SERVICE} -E _rc_svcj=jailing ${name} ${_rc_prefix}start $rc_extra_args" \ + exec.stop="${SERVICE} -E _rc_svcj=jailing ${name} ${_rc_prefix}stop $rc_extra_args" \ + exec.consolelog="/var/log/svcj_${name}_console.log" \ + name=svcj-${name} && _return=0 + fi + else + _run_rc_doit "$_cpusetcmd $_cmd $rc_extra_args" || _return=1 + fi + ;; + stop) + if [ "${_rc_svcj}" != jailing ]; then + $SERVICE -E _rc_svcj=jailing -j svcj-${name} ${name} ${_rc_prefix}stop $rc_extra_args || _return=1 + $JAIL_CMD -r svcj-${name} 2>/dev/null + else + _run_rc_doit "$_cpusetcmd $_cmd $rc_extra_args" || _return=1 + fi + ;; + restart|status) ;; # no special case needed for svcj or handled somewhere else + *) + eval _rc_svcj_extra_cmd=\$${name}_${rc_arg}_svcj_enable + : ${_rc_svcj_extra_cmd:=NO} + if checkyesno _rc_svcj_extra_cmd && [ "${_rc_svcj}" != jailing ]; then + $SERVICE -v -E _rc_svcj=jailing -j svcj-${name} ${name} ${_rc_prefix}${rc_arg} $rc_extra_args || _return=1 + else + _run_rc_doit "$_cpusetcmd $_cmd $rc_extra_args" || _return=1 + fi + ;; + esac + fi + if [ "${_rc_svcj}" != jailing ]; then + _run_rc_postcmd + fi + return $_return + fi + + case "$rc_arg" in # default operations... + + describe) + if [ -n "$desc" ]; then + echo "$desc" + fi + ;; + + extracommands) + echo "$extra_commands" + ;; + + enable) + _out=$(write_rcvar "$rcvar" "YES") && + echo "$name enabled in $_out" + ;; + + disable) + _out=$(write_rcvar "$rcvar" "NO") && + echo "$name disabled in $_out" + ;; + + delete) + delete_rcvar "$rcvar" + ;; + + status) + _run_rc_precmd || return 1 + if [ -n "$rc_pid" ]; then + echo "${name} is running as pid $rc_pid." + else + echo "${name} is not running." + return 1 + fi + _run_rc_postcmd + ;; + + start) + if [ ! -x "${_chroot}${_chroot:+/}${command}" ]; then + warn "run_rc_command: cannot run $command" + return 1 + fi + + if [ "${_rc_svcj}" != jailing ]; then + _run_rc_setup || warn "failed to setup ${name}" + + if ! _run_rc_precmd; then + warn "failed precmd routine for ${name}" + return 1 + fi + fi + + if checkyesno ${name}_svcj; then + if [ "${_rc_svcj}" != jailing ]; then + if check_jail jailed; then + if [ $(${SYSCTL_N} security.jail.children.max) -eq 0 ]; then + echo ERROR: jail parameter children.max is set to 0, can not create a new service jail. + return 1 + else + _free_jails=$(($(${SYSCTL_N} security.jail.children.max) - $(${SYSCTL_N} security.jail.children.cur))) + if [ ${_free_jails} -eq 0 ]; then + echo ERROR: max number of jail children reached, can not create a new service jail. + return 1 + fi + fi + fi + $JAIL_CMD -c $_svcj_generic_params $_svcj_cmd_options\ + exec.start="${SERVICE} -E _rc_svcj=jailing ${name} ${_rc_prefix}start $rc_extra_args" \ + exec.stop="${SERVICE} -E _rc_svcj=jailing ${name} ${_rc_prefix}stop $rc_extra_args" \ + exec.consolelog="/var/log/svcj_${name}_console.log" \ + name=svcj-${name} || return 1 + fi + fi + + # setup the full command to run + # + startmsg "Starting ${name}." + if [ -n "$_chroot" ]; then + _cd= + _doit="\ +${_nice:+nice -n $_nice }\ +$_cpusetcmd \ +${_fib:+setfib -F $_fib }\ +${_env:+env $_env }\ +chroot ${_user:+-u $_user }${_group:+-g $_group }${_groups:+-G $_groups }\ +$_chroot $command $rc_flags $command_args" + else + _cd="${_chdir:+cd $_chdir && }" + _doit="\ +${_fib:+setfib -F $_fib }\ +${_env:+env $_env }\ +$_cpusetcmd $command $rc_flags $command_args" + if [ -n "$_user" ]; then + _doit="su -m $_user -c 'sh -c \"$_doit\"'" + fi + if [ -n "$_nice" ]; then + if [ -z "$_user" ]; then + _doit="sh -c \"$_doit\"" + fi + _doit="nice -n $_nice $_doit" + fi + if [ -n "$_prepend" ]; then + _doit="$_prepend $_doit" + fi + fi + + # Prepend default limits + _doit="$_cd limits -C $_login_class $_limits $_doit" + + local _really_run_it=true + if checkyesno ${name}_svcj; then + if [ "${_rc_svcj}" != jailing ]; then + _really_run_it=false + fi + fi + + if [ "$_really_run_it" = true ]; then + # run the full command + # + if ! _run_rc_doit "$_doit"; then + warn "failed to start ${name}" + return 1 + fi + fi + + if [ "${_rc_svcj}" != jailing ]; then + # finally, run postcmd + # + _run_rc_postcmd + fi + ;; + + stop) + if [ -z "$rc_pid" ]; then + [ -n "$rc_fast" ] && return 0 + _run_rc_notrunning + return 1 + fi + + _run_rc_precmd || return 1 + + # send the signal to stop + # + echo "Stopping ${name}." + _doit=$(_run_rc_killcmd "${sig_stop:-TERM}") + _run_rc_doit "$_doit" || return 1 + + # wait for the command to exit, + # and run postcmd. + wait_for_pids $rc_pid + + if checkyesno ${name}_svcj; then + # remove service jail + $JAIL_CMD -r svcj-${name} 2>/dev/null + fi + + _run_rc_postcmd + ;; + + reload) + if [ -z "$rc_pid" ]; then + _run_rc_notrunning + return 1 + fi + + _run_rc_setup || warn "failed to setup ${name}" + + _run_rc_precmd || return 1 + + _doit=$(_run_rc_killcmd "${sig_reload:-HUP}") + _run_rc_doit "$_doit" || return 1 + + _run_rc_postcmd + ;; + + restart) + _run_rc_setup || warn "failed to setup ${name}" + + # prevent restart being called more + # than once by any given script + # + if ${_rc_restart_done:-false}; then + return 0 + fi + _rc_restart_done=true + + _run_rc_precmd || return 1 + + # run those in a subshell to keep global variables + ( run_rc_command ${_rc_prefix}stop $rc_extra_args ) + ( run_rc_command ${_rc_prefix}start $rc_extra_args ) + _return=$? + [ $_return -ne 0 ] && [ -z "$rc_force" ] && return 1 + + _run_rc_postcmd + ;; + + poll) + _run_rc_precmd || return 1 + if [ -n "$rc_pid" ]; then + wait_for_pids $rc_pid + fi + _run_rc_postcmd + ;; + + rcvar) + echo -n "# $name" + if [ -n "$desc" ]; then + echo " : $desc" + else + echo "" + fi + echo "#" + # Get unique vars in $rcvar $rcvars + for _v in $rcvar $rcvars; do + case $v in + $_v\ *|\ *$_v|*\ $_v\ *) ;; + *) v="${v# } $_v" ;; + esac + done + + # Display variables. + for _v in $v; do + if [ -z "$_v" ]; then + continue + fi + + eval _desc=\$${_v}_desc + eval _defval=\$${_v}_defval + _h="-" + + eval echo \"$_v=\\\"\$$_v\\\"\" + # decode multiple lines of _desc + while [ -n "$_desc" ]; do + case $_desc in + *^^*) + echo "# $_h ${_desc%%^^*}" + _desc=${_desc#*^^} + _h=" " + ;; + *) + echo "# $_h ${_desc}" + break + ;; + esac + done + echo "# (default: \"$_defval\")" + done + echo "" + ;; + + *) + rc_usage $_keywords + ;; + + esac + + # Apply protect(1) to the PID if ${name}_oomprotect is set. + case "$rc_arg" in + start) + # We cannot use protect(1) inside jails. + if [ -n "$_oomprotect" ] && [ -f "${PROTECT}" ] && + ! check_jail jailed; then + [ -z "${rc_pid}" ] && eval $_pidcmd + case $_oomprotect in + [Aa][Ll][Ll]) + ${PROTECT} -d -i -p ${rc_pid} + ;; + [Yy][Ee][Ss]) + ${PROTECT} -p ${rc_pid} + ;; + esac + fi + ;; + esac + + return $_return + done + + echo 1>&2 "$0: unknown directive '$rc_arg'." + rc_usage $_keywords + # not reached +} + +# +# Helper functions for run_rc_command: common code. +# They use such global variables besides the exported rc_* ones: +# +# name R/W +# ------------------ +# _offcmd R +# _precmd R +# _postcmd R +# _return W +# _setup R +# +_run_rc_offcmd() +{ + eval _offcmd=\$${name}_offcmd + if [ -n "$_offcmd" ]; then + if [ -n "$_env" ]; then + eval "export -- $_env" + fi + debug "run_rc_command: ${name}_offcmd: $_offcmd $rc_extra_args" + eval "$_offcmd $rc_extra_args" + _return=$? + fi + return 0 +} + +_run_rc_precmd() +{ + check_required_before "$rc_arg" || return 1 + + if [ -n "$_precmd" ]; then + debug "run_rc_command: ${rc_arg}_precmd: $_precmd $rc_extra_args" + eval "$_precmd $rc_extra_args" + _return=$? + + # If precmd failed and force isn't set, request exit. + if [ $_return -ne 0 ] && [ -z "$rc_force" ]; then + return 1 + fi + fi + + check_required_after "$rc_arg" || return 1 + + return 0 +} + +_run_rc_postcmd() +{ + if [ -n "$_postcmd" ]; then + debug "run_rc_command: ${rc_arg}_postcmd: $_postcmd $rc_extra_args" + eval "$_postcmd $rc_extra_args" + _return=$? + fi + return 0 +} + +_run_rc_setup() +{ + # prevent multiple execution on restart => stop/start split + if ! ${_rc_restart_done:-false} && [ -n "$_setup" ]; then + debug "run_rc_command: ${rc_arg}_setup: $_setup" + eval "$_setup" + _return=$? + if [ $_return -ne 0 ]; then + return 1 + fi + fi + return 0 +} + +_run_rc_doit() +{ + local _m + + debug "run_rc_command: doit: $*" + _m=$(umask) + ${_umask:+umask ${_umask}} + eval "$@" + _return=$? + umask ${_m} + + # If command failed and force isn't set, request exit. + if [ $_return -ne 0 ] && [ -z "$rc_force" ]; then + return 1 + fi + + return 0 +} + +_run_rc_notrunning() +{ + local _pidmsg + + if [ -n "$pidfile" ]; then + _pidmsg=" (check $pidfile)." + else + _pidmsg= + fi + echo 1>&2 "${name} not running?${_pidmsg}" +} + +_run_rc_killcmd() +{ + local _cmd + + _cmd="kill -$1 $rc_pid" + if [ -n "$_user" ]; then + _cmd="su -m ${_user} -c 'sh -c \"${_cmd}\"'" + fi + echo "$_cmd" +} + +# +# run_rc_script file arg +# Start the script `file' with `arg', and correctly handle the +# return value from the script. +# If `file' ends with `.sh' and lives in /etc/rc.d, ignore it as it's +# an old-style startup file. +# If `file' appears to be a backup or scratch file, ignore it. +# Otherwise if it is executable run as a child process. +# +run_rc_script() +{ + _file=$1 + _arg=$2 + if [ -z "$_file" -o -z "$_arg" ]; then + err 3 'USAGE: run_rc_script file arg' + fi + + unset name command command_args command_interpreter \ + extra_commands pidfile procname \ + rcvar rcvars rcvars_obsolete required_dirs required_files \ + required_vars + eval unset ${_arg}_cmd ${_arg}_precmd ${_arg}_postcmd + + rc_trace 0 "$_file $_arg" + # don't use it if we don't trust it + is_verified $_file || return + + rc_service="$_file" + case "$_file" in + /etc/rc.d/*.sh) # no longer allowed in the base + warn "Ignoring old-style startup script $_file" + ;; + *[~#]|*.OLD|*.bak|*.orig|*,v) # scratch file; skip + warn "Ignoring scratch file $_file" + ;; + *) # run in subshell + if [ -x $_file ]; then + DebugOn $_file $_file:$_arg rc:${_file##*/} rc:${_file##*/}:$_arg ${_file##*/} ${_file##*/}:$_arg + + if [ -n "$rc_boottrace" ]; then + boottrace_fn "$_file" "$_arg" + else + ( trap "echo Script $_file interrupted >&2 ; kill -QUIT $$" 3 + trap "echo Script $_file interrupted >&2 ; exit 1" 2 + trap "echo Script $_file running >&2" 29 + set $_arg; . $_file ) + fi + DebugOff rc=$? $_file $_file:$_arg rc:${_file##*/} rc:${_file##*/}:$_arg ${_file##*/} ${_file##*/}:$_arg + fi + ;; + esac +} + +# +# run_rc_scripts [options] file [...] +# +# Call `run_rc_script' for each "file" unless already listed in +# $_rc_elem_done. +# +# Options: +# +# --arg "arg" +# Pass "arg" to `run_rc_script' default is $_boot. +# +# --break "marker" +# If any "file" matches "marker" stop processing. +# +_rc_elem_done= +run_rc_scripts() +{ + local _arg=${_boot} + local _rc_elem + local _rc_breaks= + + while :; do + case "$1" in + --arg) + _arg="$2" + shift 2 + ;; + --break) + _rc_breaks="$_rc_breaks $2" + shift 2 + ;; + *) + break + ;; + esac + done + for _rc_elem in "$@"; do + : _rc_elem=$_rc_elem + case " $_rc_elem_done " in + *" $_rc_elem "*) + continue + ;; + esac + run_rc_script ${_rc_elem} ${_arg} + _rc_elem_done="$_rc_elem_done $_rc_elem" + case " $_rc_breaks " in + *" ${_rc_elem##*/} "*) + break + ;; + esac + done +} + +boottrace_fn() +{ + local _file _arg + _file=$1 + _arg=$2 + + _boot="${_boot}" rc_fast="${rc_fast}" autoboot="${autoboot}" \ + $boottrace_cmd "$_file" "$_arg" +} + +# +# load_rc_config [service] +# Source in the configuration file(s) for a given service. +# If no service is specified, only the global configuration +# file(s) will be loaded. +# +load_rc_config() +{ + local _name _rcvar_val _var _defval _v _msg _new _d _dot + _name=$1 + _dot=${load_rc_config_reader:-dot} + + case "$_dot" in + dot|[sv]dot) + ;; + *) warn "Ignoring invalid load_rc_config_reader" + _dot=dot + ;; + esac + case "$1" in + -s|--safe) + _dot=sdot + _name=$2 + shift + ;; + -v|--verify) + _dot=vdot + _name=$2 + shift + ;; + esac + + DebugOn rc:$_name $_name + + if ${_rc_conf_loaded:-false}; then + : + else + if [ -r /etc/defaults/rc.conf ]; then + debug "Sourcing /etc/defaults/rc.conf" + $_dot /etc/defaults/rc.conf + source_rc_confs + elif [ -r /etc/rc.conf ]; then + debug "Sourcing /etc/rc.conf (/etc/defaults/rc.conf doesn't exist)." + $_dot /etc/rc.conf + fi + _rc_conf_loaded=true + fi + + # If a service name was specified, attempt to load + # service-specific configuration + if [ -n "$_name" ] ; then + _loaded_services="${_loaded_services} ${_name}" + for _d in /etc ${local_startup}; do + _d=${_d%/rc.d} + if [ -f ${_d}/rc.conf.d/"$_name" ]; then + debug "Sourcing ${_d}/rc.conf.d/$_name" + $_dot ${_d}/rc.conf.d/"$_name" + elif [ -d ${_d}/rc.conf.d/"$_name" ] ; then + local _rc + for _rc in ${_d}/rc.conf.d/"$_name"/* ; do + if [ -f "$_rc" ] ; then + debug "Sourcing $_rc" + $_dot "$_rc" + fi + done + fi + done + fi + + # Set defaults if defined. + for _var in $rcvar $rcvars; do + eval _defval=\$${_var}_defval + if [ -n "$_defval" ]; then + eval : \${$_var:=\$${_var}_defval} + fi + done + + # check obsolete rc.conf variables + for _var in $rcvars_obsolete; do + eval _v=\$$_var + eval _msg=\$${_var}_obsolete_msg + eval _new=\$${_var}_newvar + case $_v in + "") + ;; + *) + if [ -z "$_new" ]; then + _msg="Ignored." + else + eval $_new=\"\$$_var\" + if [ -z "$_msg" ]; then + _msg="Use \$$_new instead." + fi + fi + warn "\$$_var is obsolete. $_msg" + ;; + esac + done +} + +# +# load_rc_config_var name var +# Read the rc.conf(5) var for name and set in the +# current shell, using load_rc_config in a subshell to prevent +# unwanted side effects from other variable assignments. +# +load_rc_config_var() +{ + if [ $# -ne 2 ]; then + err 3 'USAGE: load_rc_config_var name var' + fi + eval $(eval '( + load_rc_config '$1' >/dev/null; + if [ -n "${'$2'}" -o "${'$2'-UNSET}" != "UNSET" ]; then + echo '$2'=\'\''${'$2'}\'\''; + fi + )' ) +} + +# +# rc_usage commands +# Print a usage string for $0, with `commands' being a list of +# valid commands. +# +rc_usage() +{ + echo -n 1>&2 "Usage: $0 [fast|force|one|quiet](" + + _sep= + for _elem; do + echo -n 1>&2 "$_sep$_elem" + _sep="|" + done + echo 1>&2 ")" + exit 1 +} + +# +# err exitval message +# Display message to stderr and log to the syslog, and exit with exitval. +# +err() +{ + exitval=$1 + shift + + if [ -x /usr/bin/logger ]; then + logger "$0: ERROR: $*" + fi + echo 1>&2 "$0: ERROR: $*" + exit $exitval +} + +# +# warn message +# Display message to stderr and log to the syslog. +# +warn() +{ + if [ -x /usr/bin/logger ]; then + logger "$0: WARNING: $*" + fi + echo 1>&2 "$0: WARNING: $*" +} + +# +# info message +# Display informational message to stdout and log to syslog. +# +info() +{ + case ${rc_info} in + [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) + if [ -x /usr/bin/logger ]; then + logger "$0: INFO: $*" + fi + echo "$0: INFO: $*" + ;; + esac +} + +# +# debug message +# If debugging is enabled in rc.conf output message to stderr. +# BEWARE that you don't call any subroutine that itself calls this +# function. +# +debug() +{ + case ${rc_debug} in + [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) + if [ -x /usr/bin/logger ]; then + logger "$0: DEBUG: $*" + fi + echo 1>&2 "$0: DEBUG: $*" + ;; + esac +} + +# +# backup_file action file cur backup +# Make a backup copy of `file' into `cur', and save the previous +# version of `cur' as `backup'. +# +# The `action' keyword can be one of the following: +# +# add `file' is now being backed up (and is possibly +# being reentered into the backups system). `cur' +# is created. +# +# update `file' has changed and needs to be backed up. +# If `cur' exists, it is copied to `back' +# and then `file' is copied to `cur'. +# +# remove `file' is no longer being tracked by the backups +# system. `cur' is moved `back'. +# +# +backup_file() +{ + _action=$1 + _file=$2 + _cur=$3 + _back=$4 + + case $_action in + add|update) + if [ -f $_cur ]; then + cp -p $_cur $_back + fi + cp -p $_file $_cur + chown root:wheel $_cur + ;; + remove) + mv -f $_cur $_back + ;; + esac +} + +# make_symlink src link +# Make a symbolic link 'link' to src from basedir. If the +# directory in which link is to be created does not exist +# a warning will be displayed and an error will be returned. +# Returns 0 on success, 1 otherwise. +# +make_symlink() +{ + local src link linkdir _me + src="$1" + link="$2" + linkdir="`dirname $link`" + _me="make_symlink()" + + if [ -z "$src" -o -z "$link" ]; then + warn "$_me: requires two arguments." + return 1 + fi + if [ ! -d "$linkdir" ]; then + warn "$_me: the directory $linkdir does not exist." + return 1 + fi + if ! ln -sf $src $link; then + warn "$_me: unable to make a symbolic link from $link to $src" + return 1 + fi + return 0 +} + +# devfs_rulesets_from_file file +# Reads a set of devfs commands from file, and creates +# the specified rulesets with their rules. Returns non-zero +# if there was an error. +# +devfs_rulesets_from_file() +{ + local file _err _me _opts + file="$1" + _me="devfs_rulesets_from_file" + _err=0 + + if [ -z "$file" ]; then + warn "$_me: you must specify a file" + return 1 + fi + if [ ! -e "$file" ]; then + debug "$_me: no such file ($file)" + return 0 + fi + + # Disable globbing so that the rule patterns are not expanded + # by accident with matching filesystem entries. + _opts=$-; set -f + + debug "reading rulesets from file ($file)" + { while read line + do + case $line in + \#*) + continue + ;; + \[*\]*) + rulenum=`expr "$line" : "\[.*=\([0-9]*\)\]"` + if [ -z "$rulenum" ]; then + warn "$_me: cannot extract rule number ($line)" + _err=1 + break + fi + rulename=`expr "$line" : "\[\(.*\)=[0-9]*\]"` + if [ -z "$rulename" ]; then + warn "$_me: cannot extract rule name ($line)" + _err=1 + break; + fi + eval $rulename=\$rulenum + debug "found ruleset: $rulename=$rulenum" + if ! /sbin/devfs rule -s $rulenum delset; then + _err=1 + break + fi + ;; + *) + rulecmd="${line%%"\#*"}" + # evaluate the command incase it includes + # other rules + if [ -n "$rulecmd" ]; then + debug "adding rule ($rulecmd)" + if ! eval /sbin/devfs rule -s $rulenum $rulecmd + then + _err=1 + break + fi + fi + ;; + esac + if [ $_err -ne 0 ]; then + debug "error in $_me" + break + fi + done } < $file + case $_opts in *f*) ;; *) set +f ;; esac + return $_err +} + +# devfs_init_rulesets +# Initializes rulesets from configuration files. Returns +# non-zero if there was an error. +# +devfs_init_rulesets() +{ + local file _me + _me="devfs_init_rulesets" + + # Go through this only once + if [ -n "$devfs_rulesets_init" ]; then + debug "$_me: devfs rulesets already initialized" + return + fi + for file in $devfs_rulesets; do + if ! devfs_rulesets_from_file $file; then + warn "$_me: could not read rules from $file" + return 1 + fi + done + devfs_rulesets_init=1 + debug "$_me: devfs rulesets initialized" + return 0 +} + +# devfs_set_ruleset ruleset [dir] +# Sets the default ruleset of dir to ruleset. The ruleset argument +# must be a ruleset name as specified in devfs.rules(5) file. +# Returns non-zero if it could not set it successfully. +# +devfs_set_ruleset() +{ + local devdir rs _me + [ -n "$1" ] && eval rs=\$$1 || rs= + [ -n "$2" ] && devdir="-m "$2"" || devdir= + _me="devfs_set_ruleset" + + if [ -z "$rs" ]; then + warn "$_me: you must specify a ruleset number" + return 1 + fi + debug "$_me: setting ruleset ($rs) on mount-point (${devdir#-m })" + if ! /sbin/devfs $devdir ruleset $rs; then + warn "$_me: unable to set ruleset $rs to ${devdir#-m }" + return 1 + fi + return 0 +} + +# devfs_apply_ruleset ruleset [dir] +# Apply ruleset number $ruleset to the devfs mountpoint $dir. +# The ruleset argument must be a ruleset name as specified +# in a devfs.rules(5) file. Returns 0 on success or non-zero +# if it could not apply the ruleset. +# +devfs_apply_ruleset() +{ + local devdir rs _me + [ -n "$1" ] && eval rs=\$$1 || rs= + [ -n "$2" ] && devdir="-m "$2"" || devdir= + _me="devfs_apply_ruleset" + + if [ -z "$rs" ]; then + warn "$_me: you must specify a ruleset" + return 1 + fi + debug "$_me: applying ruleset ($rs) to mount-point (${devdir#-m })" + if ! /sbin/devfs $devdir rule -s $rs applyset; then + warn "$_me: unable to apply ruleset $rs to ${devdir#-m }" + return 1 + fi + return 0 +} + +# devfs_domount dir [ruleset] +# Mount devfs on dir. If ruleset is specified it is set +# on the mount-point. It must also be a ruleset name as specified +# in a devfs.rules(5) file. Returns 0 on success. +# +devfs_domount() +{ + local devdir rs _me + devdir="$1" + [ -n "$2" ] && rs=$2 || rs= + _me="devfs_domount()" + + if [ -z "$devdir" ]; then + warn "$_me: you must specify a mount-point" + return 1 + fi + debug "$_me: mount-point is ($devdir), ruleset is ($rs)" + if ! mount -t devfs dev "$devdir"; then + warn "$_me: Unable to mount devfs on $devdir" + return 1 + fi + if [ -n "$rs" ]; then + devfs_init_rulesets + devfs_set_ruleset $rs $devdir + devfs -m $devdir rule applyset + fi + return 0 +} + +# Provide a function for normalizing the mounting of memory +# filesystems. This should allow the rest of the code here to remain +# as close as possible between 5-current and 4-stable. +# $1 = size +# $2 = mount point +# $3 = (optional) extra mdmfs flags +mount_md() +{ + if [ -n "$3" ]; then + flags="$3" + fi + /sbin/mdmfs $flags -s $1 ${mfs_type} $2 +} + +# Code common to scripts that need to load a kernel module +# if it isn't in the kernel yet. Syntax: +# load_kld [-e regex] [-m module] file +# where -e or -m chooses the way to check if the module +# is already loaded: +# regex is egrep'd in the output from `kldstat -v', +# module is passed to `kldstat -m'. +# The default way is as though `-m file' were specified. +load_kld() +{ + local _loaded _mod _opt _re + + while getopts "e:m:" _opt; do + case "$_opt" in + e) _re="$OPTARG" ;; + m) _mod="$OPTARG" ;; + *) err 3 'USAGE: load_kld [-e regex] [-m module] file' ;; + esac + done + shift $(($OPTIND - 1)) + if [ $# -ne 1 ]; then + err 3 'USAGE: load_kld [-e regex] [-m module] file' + fi + _mod=${_mod:-$1} + _loaded=false + if [ -n "$_re" ]; then + if kldstat -v | egrep -q -e "$_re"; then + _loaded=true + fi + else + if kldstat -q -m "$_mod"; then + _loaded=true + fi + fi + if ! $_loaded; then + if ! kldload "$1"; then + warn "Unable to load kernel module $1" + return 1 + else + info "$1 kernel module loaded." + if [ -f "/etc/sysctl.kld.d/$1.conf" ]; then + sysctl -f "/etc/sysctl.kld.d/$1.conf" + fi + fi + else + debug "load_kld: $1 kernel module already loaded." + fi + return 0 +} + +# ltr str src dst [var] +# Change every $src in $str to $dst. +# Useful when /usr is not yet mounted and we cannot use tr(1), sed(1) nor +# awk(1). If var is non-NULL, set it to the result. +ltr() +{ + local _str _src _dst _out _com _var + _str="$1" + _src="$2" + _dst="$3" + _var="$4" + _out="" + + local IFS="${_src}" + for _com in ${_str}; do + if [ -z "${_out}" ]; then + _out="${_com}" + else + _out="${_out}${_dst}${_com}" + fi + done + if [ -n "${_var}" ]; then + setvar "${_var}" "${_out}" + else + echo "${_out}" + fi +} + +# Creates a list of providers for GELI encryption. +geli_make_list() +{ + local devices devices2 + local provider mountpoint type options rest + + # Create list of GELI providers from fstab. + while read provider mountpoint type options rest ; do + case ":${options}" in + :*noauto*) + noauto=yes + ;; + *) + noauto=no + ;; + esac + + case ":${provider}" in + :#*) + continue + ;; + *.eli) + # Skip swap devices. + if [ "${type}" = "swap" -o "${options}" = "sw" -o "${noauto}" = "yes" ]; then + continue + fi + devices="${devices} ${provider}" + ;; + esac + done < /etc/fstab + + # Append providers from geli_devices. + devices="${devices} ${geli_devices}" + + for provider in ${devices}; do + provider=${provider%.eli} + provider=${provider#/dev/} + devices2="${devices2} ${provider}" + done + + echo ${devices2} +} + +# Originally, root mount hold had to be released before mounting +# the root filesystem. This delayed the boot, so it was changed +# to only wait if the root device isn't readily available. This +# can result in rc scripts executing before all the devices - such +# as graid(8), or USB disks - can be accessed. This function can +# be used to explicitly wait for root mount holds to be released. +root_hold_wait() +{ + local wait waited holders + + waited=0 + while true; do + holders="$(sysctl -n vfs.root_mount_hold)" + if [ -z "${holders}" ]; then + break; + fi + if [ ${waited} -eq 0 ]; then + echo -n "Waiting ${root_hold_delay}s" \ + "for the root mount holders: ${holders}" + else + echo -n . + fi + if [ ${waited} -ge ${root_hold_delay} ]; then + echo + break + fi + sleep 1 + waited=$(($waited + 1)) + done +} + +# Find scripts in local_startup directories that use the old syntax +# +find_local_scripts_old() { + zlist='' + slist='' + for dir in ${local_startup}; do + if [ -d "${dir}" ]; then + for file in ${dir}/[0-9]*.sh; do + grep '^# PROVIDE:' $file >/dev/null 2>&1 && + continue + zlist="$zlist $file" + done + for file in ${dir}/[!0-9]*.sh; do + grep '^# PROVIDE:' $file >/dev/null 2>&1 && + continue + slist="$slist $file" + done + fi + done +} + +find_local_scripts_new() { + local_rc='' + for dir in ${local_startup}; do + if [ -d "${dir}" ]; then + for file in `grep -l '^# PROVIDE:' ${dir}/* 2>/dev/null`; do + case "$file" in + *.sample|*.pkgsave) ;; + *) if [ -x "$file" ]; then + local_rc="${local_rc} ${file}" + fi + ;; + esac + done + fi + done +} + +find_system_scripts() { + system_rc='' + for file in /etc/rc.d/*; do + case "${file##*/}" in + *.pkgsave) ;; + *) if [ -x "$file" ]; then + system_rc="${system_rc} ${file}" + fi + ;; + esac + done +} + +# check_required_{before|after} command +# Check for things required by the command before and after its precmd, +# respectively. The two separate functions are needed because some +# conditions should prevent precmd from being run while other things +# depend on precmd having already been run. +# +check_required_before() +{ + local _f + + case "$1" in + start) + for _f in $required_vars; do + if ! checkyesno $_f; then + warn "\$${_f} is not enabled." + if [ -z "$rc_force" ]; then + return 1 + fi + fi + done + + for _f in $required_dirs; do + if [ ! -d "${_f}/." ]; then + warn "${_f} is not a directory." + if [ -z "$rc_force" ]; then + return 1 + fi + fi + done + + for _f in $required_files; do + if [ ! -r "${_f}" ]; then + warn "${_f} is not readable." + if [ -z "$rc_force" ]; then + return 1 + fi + fi + done + ;; + esac + + return 0 +} + +check_required_after() +{ + local _f _args + + case "$1" in + start) + for _f in $required_modules; do + case "${_f}" in + *~*) _args="-e ${_f#*~} ${_f%%~*}" ;; + *:*) _args="-m ${_f#*:} ${_f%%:*}" ;; + *) _args="${_f}" ;; + esac + if ! load_kld ${_args}; then + if [ -z "$rc_force" ]; then + return 1 + fi + fi + done + ;; + esac + + return 0 +} + +# check_jail mib +# Return true if security.jail.$mib exists and is set to 1. + +check_jail() +{ + local _mib _v + + _mib=$1 + if _v=$(${SYSCTL_N} "security.jail.$_mib" 2> /dev/null); then + case $_v in + 1) return 0;; + esac + fi + return 1 +} + +# check_kern_features mib +# Return existence of kern.features.* sysctl MIB as true or +# false. The result will be cached in $_rc_cache_kern_features_ +# namespace. "0" means the kern.features.X exists. + +check_kern_features() +{ + local _v + + [ -n "$1" ] || return 1; + eval _v=\$_rc_cache_kern_features_$1 + [ -n "$_v" ] && return "$_v"; + + if ${SYSCTL_N} kern.features.$1 > /dev/null 2>&1; then + eval _rc_cache_kern_features_$1=0 + return 0 + else + eval _rc_cache_kern_features_$1=1 + return 1 + fi +} + +# check_namevarlist var +# Return "0" if ${name}_var is reserved in rc.subr. + +_rc_namevarlist="program chroot chdir env flags fib nice user group groups prepend setup" +check_namevarlist() +{ + local _v + + for _v in $_rc_namevarlist; do + case $1 in + $_v) return 0 ;; + esac + done + + return 1 +} + +# _echoonce var msg mode +# mode=0: Echo $msg if ${$var} is empty. +# After doing echo, a string is set to ${$var}. +# +# mode=1: Echo $msg if ${$var} is a string with non-zero length. +# +_echoonce() +{ + local _var _msg _mode + eval _var=\$$1 + _msg=$2 + _mode=$3 + + case $_mode in + 1) [ -n "$_var" ] && echo "$_msg" ;; + *) [ -z "$_var" ] && echo -n "$_msg" && eval "$1=finished" ;; + esac +} + +# _find_rcvar var +# Find the rc.conf file (other than /etc/defaults/rc.conf) that sets $var. +_find_rcvar() +{ + local _var _dir _files + + [ -n "$1" ] || return 1 + _var="$1"; shift + + _files="/etc/rc.conf" + for _dir in /etc ${local_startup}; do + for _name in $_loaded_services; do + _files="${_dir%/rc.d}/rc.conf.d/${_name} ${_files}" + done + done + + /usr/bin/grep 2>/dev/null -rl "^${_var}=" $_files | /usr/bin/head -1 +} + +# write_rcvar var value +# Add or replace the rc var $var with the value $value. +# Look for a current setting of $var in /etc/rc.conf or /etc/rc.conf.d/$name, +# and if found, modify it there; otherwise, append to /etc/rc.conf. +write_rcvar() +{ + local _var _value _file _dir + + [ -n "$1" ] || return 1 + _var="$1"; shift + [ -n "$1" ] || return 1 + _value="$1"; shift + + _file="$(_find_rcvar "$_var")" + if [ -n "$_file" ]; then + local _=$'\01' + /usr/bin/sed -i '' "s${_}^${_var}=.*${_}${_var}=\"$_value\"${_}" "$_file" + echo $_file + return + fi + + for _dir in /etc ${local_startup}; do + _file="${_dir%/rc.d}/rc.conf.d/${name}" + if [ -f "$_file" ]; then + echo "${_var}=\"${_value}\"" >>"$_file" + echo "$_file" + return + fi + done + + echo "${_var}=\"${_value}\"" >>/etc/rc.conf + echo "/etc/rc.conf" +} + +# delete_rcvar var +# Remove the rc var $var. +# Look for a current setting of $var in /etc/rc.conf or /etc/rc.conf.d/$name, +# and if found, remove it. If service_delete_empty is enabled, and the +# resulting file is empty, also delete the file. +delete_rcvar() +{ + local _var _files + + [ -n "$1" ] || return 1 + _var="$1"; shift + + _file="$(_find_rcvar "$_var")" + if [ -n "$_file" ]; then + /usr/bin/sed -i '' "/^${_var}=/d" "$_file" + echo "$_var deleted in $_file" + + if checkyesno service_delete_empty && [ ! -s "$_file" ]; then + /bin/rm -f "$_file" + echo "Empty file $_file removed" + fi + fi +} + +# If the loader env variable rc.debug is set, turn on debugging. rc.conf will +# still override this, but /etc/defaults/rc.conf can't unconditionally set this +# since it would undo what we've done here. +if kenv -q rc.debug > /dev/null ; then + rc_debug=YES +fi + +boottrace_cmd=`command -v boottrace` +if [ -n "$boottrace_cmd" ] && [ "`${SYSCTL_N} -q kern.boottrace.enabled`" = "1" ]; then + rc_boottrace=YES +fi + +SED=${SED:-$(Exists -x /usr/bin/sed /rescue/sed)} + +# Allow for local additions and overrides. +# Use vdot to ensure the file has not been tampered with. +vdot /etc/local.rc.subr + +# Avoid noise - when we do not have /usr mounted, +# and we cannot use safe_dot without sed. +if ! have basename; then + basename() + { + local b=${1%$2} + echo ${b##*/} + } + tty() + { + return 0 + } + # we cannot use safe_dot without sed + [ -z "$SED" ] && _SAFE_EVAL_SH=: +fi +# safe_eval.sh provides safe_dot - for untrusted files +$_SAFE_EVAL_SH vdot /libexec/safe_eval.sh +$_DEBUG_SH vdot /libexec/debug.sh + +# Ensure we can still operate if debug.sh and +# safe_eval.sh are not found. +if ! have DebugOn; then + DebugOn() { return 0; } + DebugOff() { + local _rc=0 + while : + do + case "$1" in + -[eo]) shift;; # ignore it + rc=*) eval "_$1"; shift;; + *) break;; + esac + done + return $_rc + } +fi +if ! have safe_dot; then + safe_dot() { dot "$@"; } +fi diff --git a/libexec/rc/rc.suspend b/libexec/rc/rc.suspend new file mode 100755 index 000000000000..8990be81466c --- /dev/null +++ b/libexec/rc/rc.suspend @@ -0,0 +1,79 @@ +#!/bin/sh +# +# Copyright (c) 1999 Mitsuru IWASAKI +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# + +# sample run command file for APM Suspend Event + +if [ $# -ne 2 ]; then + echo "Usage: $0 [apm|acpi] [standby,suspend|1-4]" + exit 1 +fi + +subsystem=$1 +state=$2 + +if [ -r /var/run/rc.suspend.pid ]; then + exit 1 +fi + +echo $$ 2> /dev/null > /var/run/rc.suspend.pid + +# If a device driver has problems suspending, try unloading it before +# suspend and reloading it on resume. Example: +# kldunload usb + +. /etc/rc.subr + +load_rc_config + +rcorder_opts="-k suspend" + +case ${local_startup} in +[Nn][Oo] | '') ;; +*) find_local_scripts_new ;; +esac + +files=`rcorder ${rcorder_opts} /etc/rc.d/* ${local_rc} 2>/dev/null` + +for _rc_elem in $files; do + debug "run_rc_script $_rc_elem suspend" + run_rc_script $_rc_elem suspend +done + +/usr/bin/logger -t $subsystem suspend at `/bin/date +'%Y%m%d %H:%M:%S'` +/bin/sync && /bin/sync && /bin/sync +/bin/sleep 3 + +/bin/rm -f /var/run/rc.suspend.pid +if [ $subsystem = "apm" ]; then + /usr/sbin/zzz +else + # Notify the kernel to continue the suspend process + /usr/sbin/acpiconf -k 0 +fi + +exit 0 diff --git a/libexec/rc/safe_eval.sh b/libexec/rc/safe_eval.sh new file mode 100644 index 000000000000..6c23b4c98218 --- /dev/null +++ b/libexec/rc/safe_eval.sh @@ -0,0 +1,100 @@ +: +# RCSid: +# $Id: safe_eval.sh,v 1.25 2025/08/07 22:13:03 sjg Exp $ +# +# @(#) Copyright (c) 2023-2024 Simon J. Gerraty +# +# SPDX-License-Identifier: BSD-2-Clause +# +# Please send copies of changes and bug-fixes to: +# sjg@crufty.net + +_SAFE_EVAL_SH=: + +# does local *actually* work? +local_works() { + local _fu +} + +if local_works > /dev/null 2>&1; then + _local=local +else + _local=: +fi + +## +# safe_set +# +# return a safe variable setting +# any non-alphanumeric chars are replaced with '_' +# +safe_set() { + ${SED:-sed} 's/[ ]*#.*//;/^[A-Za-z_][A-Za-z0-9_]*=/!d;s;[^A-Za-z0-9_. "$,/=:+-];_;g' +} + +## +# safe_eval [file] +# +# eval variable assignments only from file +# taking care to eliminate any shell meta chars +# +safe_eval() { + eval `cat "$@" | safe_set` +} + +## +# safe_eval_export [file] +# +# eval variable assignments only from file +# taking care to eliminate any shell meta chars +# export any variables thus set +# +safe_eval_export() { + eval `cat "$@" | safe_set | ${SED:-sed} 's/^\([^=]*\)=.*/&; export \1/'` +} + +## +# safe_dot file [...] +# +# feed all "file" that exist to safe_eval +# +safe_dot() { + eval $_local ef ex f rc + ef= + ex= + rc=1 + while : + do + case "$1" in + --export) ex=_export; shift;; + *) break;; + esac + done + for f in "$@" + do + test -s "$f" -a -f "$f" || continue + : check for space or tab in "$f" + case "$f" in + *[[:space:]]*|*" "*|*" "*) # we cannot do this efficiently + dotted="$dotted $f" + safe_eval$ex "$f" + rc=$? + continue + ;; + esac + ef="${ef:+$ef }$f" + dotted="$dotted $f" + done + test -z "$ef" && return $rc + safe_eval$ex $ef + return 0 +} + +case /$0 in +*/safe_eval*) + case "$1" in + dot|eval|set) op=safe_$1; shift; $op "$@";; + *) safe_dot "$@";; + esac + ;; +esac diff --git a/libexec/rc/tests/Makefile b/libexec/rc/tests/Makefile new file mode 100644 index 000000000000..c44c6db90b77 --- /dev/null +++ b/libexec/rc/tests/Makefile @@ -0,0 +1,3 @@ +ATF_TESTS_SH+= rc_subr_test + +.include <bsd.test.mk> diff --git a/libexec/rc/tests/rc_subr_test.sh b/libexec/rc/tests/rc_subr_test.sh new file mode 100644 index 000000000000..9ddd13b61a7c --- /dev/null +++ b/libexec/rc/tests/rc_subr_test.sh @@ -0,0 +1,148 @@ +#- +# SPDX-License-Identifier: BSD-2-Clause +# +# Copyright 2022 Mateusz Piotrowski <0mp@FreeBSD.org> +# Copyright (c) 2025 Klara, Inc. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +atf_test_case no_cycles +no_cycles_head() +{ + atf_set "descr" "Verify that /etc/rc.d/* contains no cycles" +} + +no_cycles_body() +{ + atf_check -e empty -o ignore rcorder /etc/rc.d/* +} + +atf_test_case oomprotect_all +oomprotect_all_head() +{ + atf_set "descr" "Verify that \${name}_oomprotect=all protects " \ + "the command and all its current and future children" + atf_set "require.user" "root" # For protect(1). +} + +oomprotect_all_body() +{ + if [ "$(sysctl -n security.jail.jailed)" != 0 ]; then + atf_skip "protect(1) cannot be used in a jail" + fi + + __name="$(atf_get ident)" + __pidfile="$(mktemp -t "${__name}.pid")" + __childpidfile="$(mktemp -t "${__name}.childpid")" + __script=$(mktemp -t "${__name}.script") + + cat >> "$__script" <<-'LITERAL' + . /etc/rc.subr + name="$1" + pidfile="$2" + _childpidfile="$3" + _rc_arg="$4" + setvar "${name}_oomprotect" all + command="/usr/sbin/daemon" + command_args="-P $pidfile -p $_childpidfile -- /bin/sleep 60" + run_rc_command "$_rc_arg" + LITERAL + + atf_check -s exit:0 -o inline:"Starting ${__name}.\n" -e empty \ + /bin/sh "$__script" "$__name" "$__pidfile" "$__childpidfile" onestart + atf_check -s exit:0 -o match:'^..1..... .......1$' -e empty \ + ps -p "$(cat "$__pidfile")" -o flags,flags2 + atf_check -s exit:0 -o match:'^..1..... .......1$' -e empty \ + ps -p "$(cat "$__childpidfile")" -o flags,flags2 + atf_check -s exit:0 -o ignore -e empty \ + /bin/sh "$__script" "$__name" "$__pidfile" "$__childpidfile" onestop +} + +atf_test_case oomprotect_yes +oomprotect_yes_head() +{ + atf_set "descr" "Verify that \${name}_oomprotect=yes protects " \ + "the command but not its children" + atf_set "require.user" "root" # For protect(1). +} + +oomprotect_yes_body() +{ + if [ "$(sysctl -n security.jail.jailed)" != 0 ]; then + atf_skip "protect(1) cannot be used in a jail" + fi + + __name="$(atf_get ident)" + __pidfile="$(mktemp -t "${__name}.pid")" + __script=$(mktemp -t "${__name}.script") + + cat >> "$__script" <<-'LITERAL' + . /etc/rc.subr + name="$1" + pidfile="$2" + _rc_arg="$3" + setvar "${name}_oomprotect" yes + procname="/bin/sleep" + command="/usr/sbin/daemon" + command_args="-p $pidfile -- $procname 60" + run_rc_command "$_rc_arg" + LITERAL + + atf_check -s exit:0 -o inline:"Starting ${__name}.\n" -e empty \ + /bin/sh "$__script" "$__name" "$__pidfile" onestart + atf_check -s exit:0 -o match:'^..1..... .......0$' -e empty \ + ps -p "$(cat "$__pidfile")" -ax -o flags,flags2 + atf_check -s exit:0 -o ignore -e empty \ + /bin/sh "$__script" "$__name" "$__pidfile" onestop +} + +atf_test_case wait_for_pids_progress +wait_for_pids_progress_head() +{ + atf_set "descr" "Verify that wait_for_pids prints progress updates" +} +wait_for_pids_progress_body() +{ + cat >>script <<'EOF' +. /etc/rc.subr +sleep 15 & +a=$! +sleep 10 & +b=$! +sleep 5 & +c=$! +wait_for_pids $a $b $c +EOF + re="^Waiting for PIDS: [0-9]+ [0-9]+ [0-9]+" + re="${re}, [0-9]+ [0-9]+" + re="${re}, [0-9]+\.$" + atf_check -s exit:0 -o match:"${re}" /bin/sh script +} + +atf_init_test_cases() +{ + atf_add_test_case no_cycles + atf_add_test_case oomprotect_all + atf_add_test_case oomprotect_yes + atf_add_test_case wait_for_pids_progress +} |