1113568Smtm#!/bin/sh
2113568Smtm#
3113568Smtm# $FreeBSD$
4113568Smtm#
5113568Smtm
6113568Smtm# PROVIDE: jail
7240336Sobrien# REQUIRE: LOGIN FILESYSTEMS
8114735Smtm# BEFORE: securelevel
9136224Smtm# KEYWORD: nojail shutdown
10113568Smtm
11113568Smtm. /etc/rc.subr
12113568Smtm
13113568Smtmname="jail"
14230099Sdougbrcvar="jail_enable"
15204818Sdougb
16113568Smtmstart_cmd="jail_start"
17256256Shrsstart_postcmd="jail_warn"
18113568Smtmstop_cmd="jail_stop"
19256256Shrsconfig_cmd="jail_config"
20256256Shrsconsole_cmd="jail_console"
21256256Shrsstatus_cmd="jail_status"
22256256Shrsextra_commands="config console status"
23256256Shrs: ${jail_conf:=/etc/jail.conf}
24256256Shrs: ${jail_program:=/usr/sbin/jail}
25256668Shrs: ${jail_consolecmd:=/usr/bin/login -f root}
26256256Shrs: ${jail_jexec:=/usr/sbin/jexec}
27256256Shrs: ${jail_jls:=/usr/sbin/jls}
28113568Smtm
29256256Shrsneed_dad_wait=
30256256Shrs
31256256Shrs# extact_var jail name param num defval
32256256Shrs#	Extract value from ${jail_$jail_$name} or ${jail_$name} and
33256256Shrs#	set it to $param.  If not defined, $defval is used.
34256256Shrs#	When $num is [0-9]*, ${jail_$jail_$name$num} are looked up and
35256256Shrs#	$param is set by using +=.
36256256Shrs#	When $num is YN or NY, the value is interpret as boolean.
37256256Shrsextract_var()
38256256Shrs{
39256256Shrs	local i _j _name _param _num _def _name1 _name2
40256256Shrs	_j=$1
41256256Shrs	_name=$2
42256256Shrs	_param=$3
43256256Shrs	_num=$4
44256256Shrs	_def=$5
45256256Shrs
46256256Shrs	case $_num in
47256256Shrs	YN)
48256256Shrs		_name1=jail_${_j}_${_name}
49256256Shrs		_name2=jail_${_name}
50256256Shrs		eval $_name1=\"\${$_name1:-\${$_name2:-$_def}}\"
51256256Shrs		if checkyesno $_name1; then
52256256Shrs			echo "	$_param = 1;"
53256256Shrs		else
54256256Shrs			echo "	$_param = 0;"
55256256Shrs		fi
56256256Shrs	;;
57256256Shrs	NY)
58256256Shrs		_name1=jail_${_j}_${_name}
59256256Shrs		_name2=jail_${_name}
60256256Shrs		eval $_name1=\"\${$_name1:-\${$_name2:-$_def}}\"
61256256Shrs		if checkyesno $_name1; then
62256256Shrs			echo "	$_param = 0;"
63256256Shrs		else
64256256Shrs			echo "	$_param = 1;"
65256256Shrs		fi
66256256Shrs	;;
67256256Shrs	[0-9]*)
68256256Shrs		i=$_num
69256256Shrs		while : ; do
70256256Shrs			_name1=jail_${_j}_${_name}${i}
71256256Shrs			_name2=jail_${_name}${i}
72256256Shrs			eval _tmpargs=\"\${$_name1:-\${$_name2:-$_def}}\"
73256256Shrs			if [ -n "$_tmpargs" ]; then 
74256256Shrs				echo "	$_param += \"$_tmpargs\";"
75256256Shrs			else
76256256Shrs				break;
77256256Shrs			fi
78256256Shrs			i=$(($i + 1))
79256256Shrs		done
80256256Shrs	;;
81256256Shrs	*)
82256256Shrs		_name1=jail_${_j}_${_name}
83256256Shrs		_name2=jail_${_name}
84256256Shrs		eval _tmpargs=\"\${$_name1:-\${$_name2:-$_def}}\"
85256256Shrs		if [ -n "$_tmpargs" ]; then
86256256Shrs			echo "	$_param = \"$_tmpargs\";"
87256256Shrs		fi
88256256Shrs	;;
89256256Shrs	esac
90256256Shrs}
91256256Shrs
92256256Shrs# parse_options _j
93256256Shrs#	Parse options and create a temporary configuration file if necessary.
94119397Smtm#
95256256Shrsparse_options()
96119397Smtm{
97256668Shrs	local _j _p
98256256Shrs	_j=$1
99119397Smtm
100256256Shrs	_confwarn=0
101119397Smtm	if [ -z "$_j" ]; then
102256256Shrs		warn "parse_options: you must specify a jail"
103119397Smtm		return
104119397Smtm	fi
105256256Shrs	eval _jconf=\"\${jail_${_j}_conf:-/etc/jail.${_j}.conf}\"
106158431Sflz	eval _rootdir=\"\$jail_${_j}_rootdir\"
107158431Sflz	eval _hostname=\"\$jail_${_j}_hostname\"
108256256Shrs	if [ -z "$_rootdir" -o \
109256256Shrs	     -z "$_hostname" ]; then
110256256Shrs		if [ -r "$_jconf" ]; then
111256256Shrs			_conf="$_jconf"
112256256Shrs			return 0
113256256Shrs		elif [ -r "$jail_conf" ]; then
114256256Shrs			_conf="$jail_conf"
115256256Shrs			return 0
116256256Shrs		else
117256256Shrs			warn "Invalid configuration for $_j " \
118256256Shrs			    "(no jail.conf, no hostname, or no path).  " \
119256256Shrs			    "Jail $_j was ignored."
120256256Shrs		fi
121256256Shrs		return 1
122256256Shrs	fi
123158431Sflz	eval _ip=\"\$jail_${_j}_ip\"
124256256Shrs	if [ -z "$_ip" ] && ! check_kern_features vimage; then
125256256Shrs		warn "no ipaddress specified and no vimage support.  " \
126256256Shrs		    "Jail $_j was ignored."
127256256Shrs		return 1
128256256Shrs	fi
129256256Shrs	_conf=/var/run/jail.${_j}.conf
130256256Shrs	#
131256256Shrs	# To relieve confusion, show a warning message.
132256256Shrs	#
133256256Shrs	_confwarn=1
134256256Shrs	if [ -r "$jail_conf" -o -r "$_jconf" ]; then
135256874Shrs		if ! checkyesno jail_parallel_start; then
136256874Shrs			warn "$_conf is created and used for jail $_j."
137256874Shrs		fi
138256256Shrs	fi
139256256Shrs	/usr/bin/install -m 0644 -o root -g wheel /dev/null $_conf || return 1
140256256Shrs
141256256Shrs	eval : \${jail_${_j}_flags:=${jail_flags}}
142158431Sflz	eval _exec=\"\$jail_${_j}_exec\"
143256256Shrs	eval _exec_start=\"\$jail_${_j}_exec_start\"
144256256Shrs	eval _exec_stop=\"\$jail_${_j}_exec_stop\"
145158431Sflz	if [ -n "${_exec}" ]; then
146138847Srse		#   simple/backward-compatible execution
147158431Sflz		_exec_start="${_exec}"
148158431Sflz		_exec_stop=""
149138847Srse	else
150138847Srse		#   flexible execution
151158431Sflz		if [ -z "${_exec_start}" ]; then
152158431Sflz			_exec_start="/bin/sh /etc/rc"
153158431Sflz			if [ -z "${_exec_stop}" ]; then
154158431Sflz				_exec_stop="/bin/sh /etc/rc.shutdown"
155138847Srse			fi
156138847Srse		fi
157138847Srse	fi
158256256Shrs	eval _interface=\"\${jail_${_j}_interface:-${jail_interface}}\"
159239382Skuriyama	eval _parameters=\"\${jail_${_j}_parameters:-${jail_parameters}}\"
160256256Shrs	eval _fstab=\"\${jail_${_j}_fstab:-${jail_fstab:-/etc/fstab.$_j}}\"
161256256Shrs	(
162256256Shrs		date +"# Generated by rc.d/jail at %Y-%m-%d %H:%M:%S"
163256256Shrs		echo "$_j {"
164256256Shrs		extract_var $_j hostname host.hostname - ""
165256256Shrs		extract_var $_j rootdir path - ""
166256256Shrs		if [ -n "$_ip" ]; then
167256256Shrs			extract_var $_j interface interface - ""
168256256Shrs			jail_handle_ips_option $_ip $_interface
169256256Shrs			alias=0
170256256Shrs			while : ; do
171256668Shrs				eval _x=\"\$jail_${_j}_ip_multi${alias}\"
172256256Shrs				[ -z "$_x" ] && break
173138027Smux
174256256Shrs				jail_handle_ips_option $_x $_interface
175256256Shrs				alias=$(($alias + 1))
176256256Shrs			done
177256256Shrs			case $need_dad_wait in
178256256Shrs			1)
179256256Shrs				# Sleep to let DAD complete before
180256256Shrs				# starting services.
181256256Shrs				echo "	exec.start += \"sleep " \
182256256Shrs				$(($(${SYSCTL_N} net.inet6.ip6.dad_count) + 1)) \
183256256Shrs				"\";"
184256256Shrs			;;
185256256Shrs			esac
186256256Shrs			# These are applicable only to non-vimage jails. 
187256256Shrs			extract_var $_j fib exec.fib - ""
188256256Shrs			extract_var $_j socket_unixiproute_only \
189256256Shrs			    allow.raw_sockets NY YES
190256256Shrs		else
191256256Shrs			echo "	vnet;"
192256256Shrs			extract_var $_j vnet_interface vnet.interface - ""
193191620Sru		fi
194191620Sru
195256256Shrs		echo "	exec.clean;"
196256256Shrs		echo "	exec.system_user = \"root\";"
197256256Shrs		echo "	exec.jail_user = \"root\";"
198256256Shrs		extract_var $_j exec_prestart exec.prestart 0 ""
199256256Shrs		extract_var $_j exec_poststart exec.poststart 0 ""
200256256Shrs		extract_var $_j exec_prestop exec.prestop 0 ""
201256256Shrs		extract_var $_j exec_poststop exec.poststop 0 ""
202191620Sru
203256256Shrs		echo "	exec.start += \"$_exec_start\";"
204256256Shrs		extract_var $_j exec_afterstart exec.start 1 ""
205256256Shrs		echo "	exec.stop = \"$_exec_stop\";"
206159072Smatteo
207256256Shrs		extract_var $_j consolelog exec.consolelog - \
208256256Shrs		    /var/log/jail_${_j}_console.log
209159072Smatteo
210256256Shrs		eval : \${jail_${_j}_devfs_enable:=${jail_devfs_enable:-NO}}
211256256Shrs		if checkyesno jail_${_j}_devfs_enable; then
212256256Shrs			echo "	mount.devfs;"
213256668Shrs			eval _ruleset=\${jail_${_j}_devfs_ruleset:-${jail_devfs_ruleset}}
214256256Shrs			case $_ruleset in
215256256Shrs			"")	;;
216256256Shrs			[0-9]*) echo "	devfs_ruleset = \"$_ruleset\";" ;;
217256256Shrs			devfsrules_jail)
218256256Shrs				# XXX: This is the default value,
219256256Shrs				# Let jail(8) to use the default because
220256256Shrs				# mount(8) only accepts an integer. 
221256256Shrs				# This should accept a ruleset name.
222256256Shrs			;;
223256668Shrs			*)	warn "devfs_ruleset must be an integer." ;;
224256256Shrs			esac
225256256Shrs			if [ -r $_fstab ]; then
226256256Shrs				echo "	mount.fstab = \"$_fstab\";"
227256256Shrs			fi
228191620Sru		fi
229191620Sru
230256256Shrs		eval : \${jail_${_j}_fdescfs_enable:=${jail_fdescfs_enable:-NO}}
231256256Shrs		if checkyesno jail_${_j}_fdescfs_enable; then
232256387Shrs			echo "	mount.fdescfs;"
233191620Sru		fi
234256256Shrs		eval : \${jail_${_j}_procfs_enable:=${jail_procfs_enable:-NO}}
235256256Shrs		if checkyesno jail_${_j}_procfs_enable; then
236256256Shrs			echo "	mount += " \
237256256Shrs			    "\"procfs ${_rootdir%/}/proc procfs rw 0 0\";"
238191620Sru		fi
239191620Sru
240256256Shrs		eval : \${jail_${_j}_mount_enable:=${jail_mount_enable:-NO}}
241256256Shrs		if checkyesno jail_${_j}_mount_enable; then
242256256Shrs			echo "	allow.mount;" >> $_conf
243125376Smtm		fi
244113568Smtm
245256256Shrs		extract_var $_j set_hostname_allow allow.set_hostname YN NO
246256256Shrs		extract_var $_j sysvipc_allow allow.sysvipc YN NO
247256668Shrs		for _p in $_parameters; do
248256668Shrs			echo "	${_p%\;};"
249256668Shrs		done
250256256Shrs		echo "}"
251256256Shrs	) >> $_conf
252165942Ssimon
253256256Shrs	return 0
254165942Ssimon}
255165942Ssimon
256256256Shrs# jail_extract_address argument iface
257187708Sbz#	The second argument is the string from one of the _ip
258187708Sbz#	or the _multi variables. In case of a comma separated list
259187708Sbz#	only one argument must be passed in at a time.
260187708Sbz#	The function alters the _type, _iface, _addr and _mask variables.
261187708Sbz#
262187708Sbzjail_extract_address()
263187708Sbz{
264256256Shrs	local _i _interface
265187708Sbz	_i=$1
266256256Shrs	_interface=$2
267187708Sbz
268187708Sbz	if [ -z "${_i}" ]; then
269187708Sbz		warn "jail_extract_address: called without input"
270187708Sbz		return
271187708Sbz	fi
272187708Sbz
273187708Sbz	# Check if we have an interface prefix given and split into
274187708Sbz	# iFace and rest.
275187708Sbz	case "${_i}" in
276187708Sbz	*\|*)	# ifN|.. prefix there
277187708Sbz		_iface=${_i%%|*}
278187708Sbz		_r=${_i##*|}
279187708Sbz		;;
280187708Sbz	*)	_iface=""
281187708Sbz		_r=${_i}
282187708Sbz		;;
283187708Sbz	esac
284187708Sbz
285187708Sbz	# In case the IP has no interface given, check if we have a global one.
286187708Sbz	_iface=${_iface:-${_interface}}
287187708Sbz
288187708Sbz	# Set address, cut off any prefix/netmask/prefixlen.
289187708Sbz	_addr=${_r}
290187708Sbz	_addr=${_addr%%[/ ]*}
291187708Sbz
292187708Sbz	# Theoretically we can return here if interface is not set,
293187708Sbz	# as we only care about the _mask if we call ifconfig.
294187708Sbz	# This is not done because we may want to santize IP addresses
295187708Sbz	# based on _type later, and optionally change the type as well.
296187708Sbz
297187708Sbz	# Extract the prefix/netmask/prefixlen part by cutting off the address.
298187708Sbz	_mask=${_r}
299187708Sbz	_mask=`expr "${_mask}" : "${_addr}\(.*\)"`
300187708Sbz
301187708Sbz	# Identify type {inet,inet6}.
302187708Sbz	case "${_addr}" in
303187708Sbz	*\.*\.*\.*)	_type="inet" ;;
304187708Sbz	*:*)		_type="inet6" ;;
305187708Sbz	*)		warn "jail_extract_address: type not identified"
306187708Sbz			;;
307187708Sbz	esac
308187708Sbz
309187708Sbz	# Handle the special /netmask instead of /prefix or
310187708Sbz	# "netmask xxx" case for legacy IP.
311187708Sbz	# We do NOT support shortend class-full netmasks.
312187708Sbz	if [ "${_type}" = "inet" ]; then
313187708Sbz		case "${_mask}" in
314187708Sbz		/*\.*\.*\.*)	_mask=" netmask ${_mask#/}" ;;
315187708Sbz		*)		;;
316187708Sbz		esac
317187708Sbz
318187708Sbz		# In case _mask is still not set use /32.
319187708Sbz		_mask=${_mask:-/32}
320187708Sbz
321187708Sbz	elif [ "${_type}" = "inet6" ]; then
322256256Shrs		# In case _maske is not set for IPv6, use /64.
323256256Shrs		_mask=${_mask:-/64}
324187708Sbz	fi
325187708Sbz}
326187708Sbz
327256256Shrs# jail_handle_ips_option input iface
328187708Sbz#	Handle a single argument imput which can be a comma separated
329187708Sbz#	list of addresses (theoretically with an option interface and
330187708Sbz#	prefix/netmask/prefixlen).
331187708Sbz#
332187708Sbzjail_handle_ips_option()
333187708Sbz{
334256668Shrs	local _x _type _i _defif
335256256Shrs	_x=$1
336256668Shrs	_defif=$2
337187708Sbz
338187708Sbz	if [ -z "${_x}" ]; then
339187708Sbz		# No IP given. This can happen for the primary address
340187708Sbz		# of each address family.
341187708Sbz		return
342187708Sbz	fi
343187708Sbz
344187708Sbz	# Loop, in case we find a comma separated list, we need to handle
345187708Sbz	# each argument on its own.
346187708Sbz	while [ ${#_x} -gt 0 ]; do
347187708Sbz		case "${_x}" in
348187708Sbz		*,*)	# Extract the first argument and strip it off the list.
349187708Sbz			_i=`expr "${_x}" : '^\([^,]*\)'`
350187708Sbz			_x=`expr "${_x}" : "^[^,]*,\(.*\)"`
351256256Shrs		;;
352187708Sbz		*)	_i=${_x}
353187708Sbz			_x=""
354256256Shrs		;;
355187708Sbz		esac
356187708Sbz
357187708Sbz		_type=""
358187708Sbz		_addr=""
359187708Sbz		_mask=""
360256668Shrs		_iface=""
361256668Shrs		jail_extract_address $_i $_defif
362187708Sbz
363187708Sbz		# make sure we got an address.
364256256Shrs		case $_addr in
365187708Sbz		"")	continue ;;
366187708Sbz		*)	;;
367187708Sbz		esac
368187708Sbz
369187708Sbz		# Append address to list of addresses for the jail command.
370256256Shrs		case $_type in
371239382Skuriyama		inet)
372256874Shrs			echo "	ip4.addr += \"${_iface:+${_iface}|}${_addr}${_mask}\";"
373256256Shrs		;;
374239382Skuriyama		inet6)
375256874Shrs			echo "	ip6.addr += \"${_iface:+${_iface}|}${_addr}${_mask}\";"
376256256Shrs			need_dad_wait=1
377256256Shrs		;;
378187708Sbz		esac
379187708Sbz	done
380187708Sbz}
381187708Sbz
382256256Shrsjail_config()
383187708Sbz{
384256668Shrs	local _j
385256668Shrs
386256256Shrs	case $1 in
387256256Shrs	_ALL)	return ;;
388187708Sbz	esac
389256668Shrs	for _j in $@; do
390256668Shrs		_j=$(echo $_j | tr /. _)
391256668Shrs		if parse_options $_j; then 
392256668Shrs			echo "$_j: parameters are in $_conf."
393256256Shrs		fi
394256256Shrs	done
395256256Shrs}
396187708Sbz
397256256Shrsjail_console()
398256256Shrs{
399256668Shrs	local _j _cmd
400256668Shrs
401256256Shrs	# One argument that is not _ALL.
402256256Shrs	case $#:$1 in
403256668Shrs	0:*|1:_ALL)	err 3 "Specify a jail name." ;;
404256668Shrs	1:*)		;;
405245525Sbz	esac
406256668Shrs	_j=$(echo $1 | tr /. _)
407256668Shrs	shift
408256668Shrs	case $# in
409256668Shrs	0)	eval _cmd=\${jail_${_j}_consolecmd:-$jail_consolecmd} ;;
410256668Shrs	*)	_cmd=$@ ;;
411256668Shrs	esac
412256668Shrs	$jail_jexec $_j $_cmd
413187708Sbz}
414187708Sbz
415256256Shrsjail_status()
416204818Sdougb{
417256256Shrs
418256256Shrs	$jail_jls -N
419204818Sdougb}
420204818Sdougb
421125376Smtmjail_start()
422125376Smtm{
423256874Shrs	local _j _jid _jn _jl
424256668Shrs
425256256Shrs	if [ $# = 0 ]; then
426256256Shrs		return
427256256Shrs	fi
428256256Shrs	echo -n 'Starting jails:'
429256256Shrs	case $1 in
430256256Shrs	_ALL)
431256256Shrs		command=$jail_program
432256256Shrs		rc_flags=$jail_flags
433256256Shrs		command_args="-f $jail_conf -c"
434256874Shrs		_tmp=`mktemp -t jail` || exit 3
435256874Shrs		if $command $rc_flags $command_args >> $_tmp 2>&1; then
436256874Shrs			$jail_jls -nq | while read IN; do
437256874Shrs				_jn=$(echo $IN | tr " " "\n" | grep ^name=)
438256874Shrs				_jid=$(echo $IN | tr " " "\n" | grep ^jid=)
439256668Shrs				echo -n " ${_jn#name=}"
440256668Shrs				echo "${_jid#jid=}" \
441256668Shrs				    > /var/run/jail_${_jn#name=}.id
442256874Shrs			done
443256874Shrs		else
444256874Shrs			tail -1 $_tmp
445256874Shrs		fi
446256874Shrs		rm -f $_tmp
447256256Shrs		echo '.'
448256256Shrs		return
449256256Shrs	;;
450256256Shrs	esac
451256874Shrs	if checkyesno jail_parallel_start; then
452256874Shrs		#
453256874Shrs		# Start jails in parallel and then check jail id when
454256874Shrs		# jail_parallel_start is YES.
455256874Shrs		#
456256874Shrs		_jl=
457256874Shrs		for _j in $@; do
458256874Shrs			_j=$(echo $_j | tr /. _)
459256874Shrs			parse_options $_j || continue
460113568Smtm
461256874Shrs			_jl="$_jl $_j"
462256874Shrs			eval rc_flags=\${jail_${_j}_flags:-$jail_flags}
463256874Shrs			eval command=\${jail_${_j}_program:-$jail_program}
464256668Shrs			command_args="-i -f $_conf -c $_j"
465256874Shrs			$command $rc_flags $command_args \
466256874Shrs			    >/dev/null 2>&1 </dev/null &
467256874Shrs		done
468256874Shrs		sleep 1
469256874Shrs		for _j in $_jl; do
470256668Shrs			echo -n " ${_hostname:-${_j}}"
471256874Shrs			if _jid=$($jail_jls -n -j $_j | tr " " "\n" | \
472256874Shrs			    grep ^jid=); then
473256874Shrs				echo "${_jid#jid=}" > /var/run/jail_${_j}.id
474256874Shrs			else
475256874Shrs				rm -f /var/run/jail_${_j}.id
476256874Shrs				echo " cannot start jail " \
477256874Shrs				    "\"${_hostname:-${_j}}\": "
478256874Shrs			fi
479256874Shrs		done
480256874Shrs	else
481256874Shrs		#
482256874Shrs		# Start jails one-by-one when jail_parallel_start is NO.
483256874Shrs		#
484256874Shrs		for _j in $@; do
485256874Shrs			_j=$(echo $_j | tr /. _)
486256874Shrs			parse_options $_j || continue
487256874Shrs
488256874Shrs			eval rc_flags=\${jail_${_j}_flags:-$jail_flags}
489256874Shrs			eval command=\${jail_${_j}_program:-$jail_program}
490256874Shrs			command_args="-i -f $_conf -c $_j"
491256874Shrs			_tmp=`mktemp -t jail` || exit 3
492256874Shrs			if $command $rc_flags $command_args \
493256874Shrs			    >> $_tmp 2>&1 </dev/null; then
494256874Shrs				echo -n " ${_hostname:-${_j}}"
495256874Shrs				_jid=$($jail_jls -n -j $_j | \
496256874Shrs				    tr " " "\n" | grep ^jid=)
497256874Shrs				echo "${_jid#jid=}" > /var/run/jail_${_j}.id
498256874Shrs			else
499256874Shrs				rm -f /var/run/jail_${_j}.id
500256874Shrs				echo " cannot start jail " \
501256874Shrs				    "\"${_hostname:-${_j}}\": "
502256874Shrs				cat $_tmp
503256874Shrs			fi
504256874Shrs			rm -f $_tmp
505256874Shrs		done
506256874Shrs	fi
507119397Smtm	echo '.'
508113568Smtm}
509113568Smtm
510113568Smtmjail_stop()
511113568Smtm{
512256668Shrs	local _j _jn
513256668Shrs
514256256Shrs	if [ $# = 0 ]; then
515256256Shrs		return
516256256Shrs	fi
517125391Smtm	echo -n 'Stopping jails:'
518256256Shrs	case $1 in
519256256Shrs	_ALL)
520256256Shrs		command=$jail_program
521256256Shrs		rc_flags=$jail_flags
522256256Shrs		command_args="-f $jail_conf -r"
523256668Shrs		$jail_jls -nq | while read IN; do
524256874Shrs			_jn=$(echo $IN | tr " " "\n" | grep ^name=)
525256668Shrs			echo -n " ${_jn#name=}"
526256874Shrs			_tmp=`mktemp -t jail` || exit 3
527256874Shrs			$command $rc_flags $command_args ${_jn#name=} \
528256874Shrs			    >> $_tmp 2>&1
529256874Shrs			if $jail_jls -j ${_jn#name=} > /dev/null 2>&1; then
530256874Shrs				tail -1 $_tmp
531256874Shrs			else
532256668Shrs				rm -f /var/run/jail_${_jn#name=}.id
533256668Shrs			fi
534256874Shrs			rm -f $_tmp
535256668Shrs		done
536256256Shrs		echo '.'
537256256Shrs		return
538256256Shrs	;;
539256256Shrs	esac
540256668Shrs	for _j in $@; do
541256668Shrs		_j=$(echo $_j | tr /. _)
542256668Shrs		parse_options $_j || continue
543256668Shrs		if ! $jail_jls -j $_j > /dev/null 2>&1; then
544256668Shrs			continue
545256668Shrs		fi
546256256Shrs		eval command=\${jail_${_j}_program:-$jail_program}
547256668Shrs		echo -n " ${_hostname:-${_j}}"
548256874Shrs		_tmp=`mktemp -t jail` || exit 3
549256874Shrs		$command -q -f $_conf -r $_j >> $_tmp 2>&1
550256874Shrs		if $jail_jls -j $_j > /dev/null 2>&1; then
551256874Shrs			tail -1 $_tmp
552256874Shrs		else
553256668Shrs			rm -f /var/run/jail_${_j}.id
554125323Smtm		fi
555256874Shrs		rm -f $_tmp
556125323Smtm	done
557125391Smtm	echo '.'
558113568Smtm}
559113568Smtm
560256256Shrsjail_warn()
561256256Shrs{
562256256Shrs
563256256Shrs	# To relieve confusion, show a warning message.
564256256Shrs	case $_confwarn in
565256256Shrs	1)	warn "Per-jail configuration via jail_* variables " \
566256256Shrs		    "is obsolete.  Please consider to migrate to $jail_conf."
567256256Shrs	;;
568256256Shrs	esac
569256256Shrs}
570256256Shrs
571125391Smtmload_rc_config $name
572256256Shrscase $# in
573256256Shrs1)	run_rc_command $@ ${jail_list:-_ALL} ;;
574256256Shrs*)	run_rc_command $@ ;;
575256256Shrsesac
576