7 # REQUIRE: LOGIN FILESYSTEMS
9 # KEYWORD: nojail shutdown
16 start_cmd="jail_start"
17 start_postcmd="jail_warn"
19 config_cmd="jail_config"
20 console_cmd="jail_console"
21 status_cmd="jail_status"
22 extra_commands="config console status"
23 : ${jail_conf:=/etc/jail.conf}
24 : ${jail_program:=/usr/sbin/jail}
25 : ${jail_consolecmd:=/usr/bin/login -f root}
26 : ${jail_jexec:=/usr/sbin/jexec}
27 : ${jail_jls:=/usr/sbin/jls}
31 # extact_var jail name param num defval
32 # Extract value from ${jail_$jail_$name} or ${jail_$name} and
33 # set it to $param. If not defined, $defval is used.
34 # When $num is [0-9]*, ${jail_$jail_$name$num} are looked up and
35 # $param is set by using +=.
36 # When $num is YN or NY, the value is interpret as boolean.
39 local i _j _name _param _num _def _name1 _name2
48 _name1=jail_${_j}_${_name}
50 eval $_name1=\"\${$_name1:-\${$_name2:-$_def}}\"
51 if checkyesno $_name1; then
58 _name1=jail_${_j}_${_name}
60 eval $_name1=\"\${$_name1:-\${$_name2:-$_def}}\"
61 if checkyesno $_name1; then
70 _name1=jail_${_j}_${_name}${i}
71 _name2=jail_${_name}${i}
72 eval _tmpargs=\"\${$_name1:-\${$_name2:-$_def}}\"
73 if [ -n "$_tmpargs" ]; then
74 echo " $_param += \"$_tmpargs\";"
82 _name1=jail_${_j}_${_name}
84 eval _tmpargs=\"\${$_name1:-\${$_name2:-$_def}}\"
85 if [ -n "$_tmpargs" ]; then
86 echo " $_param = \"$_tmpargs\";"
93 # Parse options and create a temporary configuration file if necessary.
101 if [ -z "$_j" ]; then
102 warn "parse_options: you must specify a jail"
105 eval _jconf=\"\${jail_${_j}_conf:-/etc/jail.${_j}.conf}\"
106 eval _rootdir=\"\$jail_${_j}_rootdir\"
107 eval _hostname=\"\$jail_${_j}_hostname\"
108 if [ -z "$_rootdir" -o \
109 -z "$_hostname" ]; then
110 if [ -r "$_jconf" ]; then
113 elif [ -r "$jail_conf" ]; then
117 warn "Invalid configuration for $_j " \
118 "(no jail.conf, no hostname, or no path). " \
119 "Jail $_j was ignored."
123 eval _ip=\"\$jail_${_j}_ip\"
124 if [ -z "$_ip" ] && ! check_kern_features vimage; then
125 warn "no ipaddress specified and no vimage support. " \
126 "Jail $_j was ignored."
129 _conf=/var/run/jail.${_j}.conf
131 # To relieve confusion, show a warning message.
134 if [ -r "$jail_conf" -o -r "$_jconf" ]; then
135 warn "$_conf is created and used for jail $_j."
137 /usr/bin/install -m 0644 -o root -g wheel /dev/null $_conf || return 1
139 eval : \${jail_${_j}_flags:=${jail_flags}}
140 eval _exec=\"\$jail_${_j}_exec\"
141 eval _exec_start=\"\$jail_${_j}_exec_start\"
142 eval _exec_stop=\"\$jail_${_j}_exec_stop\"
143 if [ -n "${_exec}" ]; then
144 # simple/backward-compatible execution
145 _exec_start="${_exec}"
149 if [ -z "${_exec_start}" ]; then
150 _exec_start="/bin/sh /etc/rc"
151 if [ -z "${_exec_stop}" ]; then
152 _exec_stop="/bin/sh /etc/rc.shutdown"
156 eval _interface=\"\${jail_${_j}_interface:-${jail_interface}}\"
157 eval _parameters=\"\${jail_${_j}_parameters:-${jail_parameters}}\"
158 eval _fstab=\"\${jail_${_j}_fstab:-${jail_fstab:-/etc/fstab.$_j}}\"
160 date +"# Generated by rc.d/jail at %Y-%m-%d %H:%M:%S"
162 extract_var $_j hostname host.hostname - ""
163 extract_var $_j rootdir path - ""
164 if [ -n "$_ip" ]; then
165 extract_var $_j interface interface - ""
166 jail_handle_ips_option $_ip $_interface
169 eval _x=\"\$jail_${_j}_ip_multi${alias}\"
170 [ -z "$_x" ] && break
172 jail_handle_ips_option $_x $_interface
173 alias=$(($alias + 1))
175 case $need_dad_wait in
177 # Sleep to let DAD complete before
179 echo " exec.start += \"sleep " \
180 $(($(${SYSCTL_N} net.inet6.ip6.dad_count) + 1)) \
184 # These are applicable only to non-vimage jails.
185 extract_var $_j fib exec.fib - ""
186 extract_var $_j socket_unixiproute_only \
187 allow.raw_sockets NY YES
190 extract_var $_j vnet_interface vnet.interface - ""
194 echo " exec.system_user = \"root\";"
195 echo " exec.jail_user = \"root\";"
196 extract_var $_j exec_prestart exec.prestart 0 ""
197 extract_var $_j exec_poststart exec.poststart 0 ""
198 extract_var $_j exec_prestop exec.prestop 0 ""
199 extract_var $_j exec_poststop exec.poststop 0 ""
201 echo " exec.start += \"$_exec_start\";"
202 extract_var $_j exec_afterstart exec.start 1 ""
203 echo " exec.stop = \"$_exec_stop\";"
205 extract_var $_j consolelog exec.consolelog - \
206 /var/log/jail_${_j}_console.log
208 eval : \${jail_${_j}_devfs_enable:=${jail_devfs_enable:-NO}}
209 if checkyesno jail_${_j}_devfs_enable; then
211 eval _ruleset=\${jail_${_j}_devfs_ruleset:-${jail_devfs_ruleset}}
214 [0-9]*) echo " devfs_ruleset = \"$_ruleset\";" ;;
216 # XXX: This is the default value,
217 # Let jail(8) to use the default because
218 # mount(8) only accepts an integer.
219 # This should accept a ruleset name.
221 *) warn "devfs_ruleset must be an integer." ;;
223 if [ -r $_fstab ]; then
224 echo " mount.fstab = \"$_fstab\";"
228 eval : \${jail_${_j}_fdescfs_enable:=${jail_fdescfs_enable:-NO}}
229 if checkyesno jail_${_j}_fdescfs_enable; then
230 echo " mount.fdescfs;"
232 eval : \${jail_${_j}_procfs_enable:=${jail_procfs_enable:-NO}}
233 if checkyesno jail_${_j}_procfs_enable; then
235 "\"procfs ${_rootdir%/}/proc procfs rw 0 0\";"
238 eval : \${jail_${_j}_mount_enable:=${jail_mount_enable:-NO}}
239 if checkyesno jail_${_j}_mount_enable; then
240 echo " allow.mount;" >> $_conf
243 extract_var $_j set_hostname_allow allow.set_hostname YN NO
244 extract_var $_j sysvipc_allow allow.sysvipc YN NO
245 for _p in $_parameters; do
254 # jail_extract_address argument iface
255 # The second argument is the string from one of the _ip
256 # or the _multi variables. In case of a comma separated list
257 # only one argument must be passed in at a time.
258 # The function alters the _type, _iface, _addr and _mask variables.
260 jail_extract_address()
266 if [ -z "${_i}" ]; then
267 warn "jail_extract_address: called without input"
271 # Check if we have an interface prefix given and split into
274 *\|*) # ifN|.. prefix there
283 # In case the IP has no interface given, check if we have a global one.
284 _iface=${_iface:-${_interface}}
286 # Set address, cut off any prefix/netmask/prefixlen.
288 _addr=${_addr%%[/ ]*}
290 # Theoretically we can return here if interface is not set,
291 # as we only care about the _mask if we call ifconfig.
292 # This is not done because we may want to santize IP addresses
293 # based on _type later, and optionally change the type as well.
295 # Extract the prefix/netmask/prefixlen part by cutting off the address.
297 _mask=`expr "${_mask}" : "${_addr}\(.*\)"`
299 # Identify type {inet,inet6}.
301 *\.*\.*\.*) _type="inet" ;;
302 *:*) _type="inet6" ;;
303 *) warn "jail_extract_address: type not identified"
307 # Handle the special /netmask instead of /prefix or
308 # "netmask xxx" case for legacy IP.
309 # We do NOT support shortend class-full netmasks.
310 if [ "${_type}" = "inet" ]; then
312 /*\.*\.*\.*) _mask=" netmask ${_mask#/}" ;;
316 # In case _mask is still not set use /32.
319 elif [ "${_type}" = "inet6" ]; then
320 # In case _maske is not set for IPv6, use /64.
325 # jail_handle_ips_option input iface
326 # Handle a single argument imput which can be a comma separated
327 # list of addresses (theoretically with an option interface and
328 # prefix/netmask/prefixlen).
330 jail_handle_ips_option()
332 local _x _type _i _defif
336 if [ -z "${_x}" ]; then
337 # No IP given. This can happen for the primary address
338 # of each address family.
342 # Loop, in case we find a comma separated list, we need to handle
343 # each argument on its own.
344 while [ ${#_x} -gt 0 ]; do
346 *,*) # Extract the first argument and strip it off the list.
347 _i=`expr "${_x}" : '^\([^,]*\)'`
348 _x=`expr "${_x}" : "^[^,]*,\(.*\)"`
359 jail_extract_address $_i $_defif
361 # make sure we got an address.
367 # Append address to list of addresses for the jail command.
370 echo " ip4.addr += \"${_iface}|${_addr}${_mask}\";"
373 echo " ip6.addr += \"${_iface}|${_addr}${_mask}\";"
388 _j=$(echo $_j | tr /. _)
389 if parse_options $_j; then
390 echo "$_j: parameters are in $_conf."
399 # One argument that is not _ALL.
401 0:*|1:_ALL) err 3 "Specify a jail name." ;;
404 _j=$(echo $1 | tr /. _)
407 0) eval _cmd=\${jail_${_j}_consolecmd:-$jail_consolecmd} ;;
410 $jail_jexec $_j $_cmd
426 echo -n 'Starting jails:'
430 command=$jail_program
432 command_args="-f $jail_conf -c"
433 $jail_jls -nq | while read IN; do
434 _jn=$(echo $IN | tr " " "\n" | grep name=)
435 _jid=$(echo $IN | tr " " "\n" | grep jid=)
436 if $command $rc_flags $command_args ${_jn#name=}; then
437 echo -n " ${_jn#name=}"
438 echo "${_jid#jid=}" \
439 > /var/run/jail_${_jn#name=}.id
446 _tmp=`mktemp -t jail` || exit 3
448 _j=$(echo $_j | tr /. _)
449 parse_options $_j || continue
451 eval rc_flags=\${jail_${_j}_flags:-$jail_flags}
452 eval command=\${jail_${_j}_program:-$jail_program}
453 if checkyesno jail_parallel_start; then
454 command_args="-i -f $_conf -c $_j &"
456 command_args="-i -f $_conf -c $_j"
458 if $command $rc_flags $command_args \
459 >> $_tmp 2>&1 </dev/null; then
460 echo -n " ${_hostname:-${_j}}"
461 _jid=$($jail_jls -n -j $_j | tr " " "\n" | grep jid=)
462 echo "${_jid#jid=}" > /var/run/jail_${_j}.id
464 rm -f /var/run/jail_${_j}.id
465 echo " cannot start jail \"${_hostname:-${_j}}\": "
480 echo -n 'Stopping jails:'
484 command=$jail_program
486 command_args="-f $jail_conf -r"
487 $jail_jls -nq | while read IN; do
488 _jn=$(echo $IN | tr " " "\n" | grep name=)
489 echo -n " ${_jn#name=}"
490 $command $rc_flags $command_args ${_jn#name=}
491 if ! $jail_jls -j ${_jn#name=} > /dev/null 2>&1; then
492 rm -f /var/run/jail_${_jn#name=}.id
500 _j=$(echo $_j | tr /. _)
501 parse_options $_j || continue
502 if ! $jail_jls -j $_j > /dev/null 2>&1; then
505 eval command=\${jail_${_j}_program:-$jail_program}
506 echo -n " ${_hostname:-${_j}}"
507 $command -q -f $_conf -r $_j
508 if ! $jail_jls -j $_j > /dev/null 2>&1; then
509 rm -f /var/run/jail_${_j}.id
518 # To relieve confusion, show a warning message.
520 1) warn "Per-jail configuration via jail_* variables " \
521 "is obsolete. Please consider to migrate to $jail_conf."
528 1) run_rc_command $@ ${jail_list:-_ALL} ;;
529 *) run_rc_command $@ ;;