svn commit: r256256 - in head: . etc etc/defaults etc/rc.d share/man/man5 usr.sbin/jail

Remko Lodder remko at FreeBSD.org
Fri Oct 11 13:04:17 UTC 2013


Hi Hiroki,

On Oct 10, 2013, at 11:32 AM, Hiroki Sato <hrs at FreeBSD.org> wrote:

> Author: hrs
> Date: Thu Oct 10 09:32:27 2013
> New Revision: 256256
> URL: http://svnweb.freebsd.org/changeset/base/256256
> 
> Log:
>  - Update rc.d/jail to use a jail(8) configuration file instead of
>    command line options.  The "jail_<jname>_*" rc.conf(5) variables for
>    per-jail configuration are automatically converted to
>    /var/run/jail.<jname>.conf before the jail(8) utility is invoked.
>    This is transparently backward compatible.
> 
>  - Fix a minor bug in jail(8) which prevented it from returning false
>    when jail -r failed.
> 

Thanks for doing such a massive update. However it seems to break the ezjail utility.
My jails didn't restart after I upgraded to the most recent -head version 

FreeBSD nakur.elvandar.org 10.0-ALPHA6 FreeBSD 10.0-ALPHA6 #7 r256311: Fri Oct 11 13:27:54 CEST 2013     root at nakur.elvandar.org:/usr/obj/usr/src/sys/NAKUR  amd64

If I replace this with an older version, the utility starts and complains about certain things not being done properly. The
system does not mount devfs nodes anylonger and thus is basically out of function.

I was not expecting this much fallout from this change, others that will be upgrading will loose the ability to start their jails until they can
resolve this by hand.

Thanks
Remko

>  Approved by:	re (glebius)
> 
> Modified:
>  head/UPDATING
>  head/etc/defaults/rc.conf
>  head/etc/rc.d/jail
>  head/etc/rc.subr
>  head/share/man/man5/rc.conf.5
>  head/usr.sbin/jail/jail.c
> 
> Modified: head/UPDATING
> ==============================================================================
> --- head/UPDATING	Thu Oct 10 07:41:11 2013	(r256255)
> +++ head/UPDATING	Thu Oct 10 09:32:27 2013	(r256256)
> @@ -31,6 +31,25 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 10
> 	disable the most expensive debugging functionality run
> 	"ln -s 'abort:false,junk:false' /etc/malloc.conf".)
> 
> +20131010:
> +	The rc.d/jail script has been updated to support jail(8)
> +	configuration file.  The "jail_<jname>_*" rc.conf(5) variables
> +	for per-jail configuration are automatically converted to
> +	/var/run/jail.<jname>.conf before the jail(8) utility is invoked.
> +	This is transparently backward compatible.  See below about some
> +	incompatibilities and rc.conf(5) manual page for more details.
> +
> +	These variables are now deprecated in favor of jail(8) configuration
> +	file.  One can use "rc.d/jail config <jname>" command to generate
> +	a jail(8) configuration file in /var/run/jail.<jname>.conf without
> +	running the jail(8) utility.   The default pathname of the
> +	configuration file is /etc/jail.conf and can be specified by
> +	using $jail_conf or $jail_<jname>_conf variables.
> +
> +	Please note that jail_devfs_ruleset accepts an integer at
> +	this moment.  Please consider to rewrite the ruleset name
> +	with an integer.
> +
> 20130930:
> 	BIND has been removed from the base system.  If all you need
> 	is a local resolver, simply enable and start the local_unbound
> 
> Modified: head/etc/defaults/rc.conf
> ==============================================================================
> --- head/etc/defaults/rc.conf	Thu Oct 10 07:41:11 2013	(r256255)
> +++ head/etc/defaults/rc.conf	Thu Oct 10 09:32:27 2013	(r256256)
> @@ -674,44 +674,11 @@ mixer_enable="YES"	# Run the sound mixer
> opensm_enable="NO"	# Opensm(8) for infiniband devices defaults to off
> 
> ##############################################################
> -### Jail Configuration #######################################
> +### Jail Configuration (see rc.conf(5) manual page) ##########
> ##############################################################
> jail_enable="NO"	# Set to NO to disable starting of any jails
> jail_parallel_start="NO"	# Start jails in the background
> jail_list=""		# Space separated list of names of jails
> -jail_set_hostname_allow="YES" # Allow root user in a jail to change its hostname
> -jail_socket_unixiproute_only="YES" # Route only TCP/IP within a jail
> -jail_sysvipc_allow="NO"	# Allow SystemV IPC use from within a jail
> -
> -#
> -# To use rc's built-in jail infrastructure create entries for
> -# each jail, specified in jail_list, with the following variables.
> -# NOTES:
> -# - replace 'example' with the jail's name.
> -# - except rootdir, hostname, ip and the _multi<n> addresses,
> -#   all of the following variables may be made global jail variables
> -#   if you don't specify a jail name (ie. jail_interface, jail_devfs_ruleset).
> -#
> -#jail_example_rootdir="/usr/jail/default"	# Jail's root directory
> -#jail_example_hostname="default.domain.com"	# Jail's hostname
> -#jail_example_interface=""			# Jail's interface variable to create IP aliases on
> -#jail_example_fib="0"				# Routing table for setfib(1)
> -#jail_example_ip="192.0.2.10,2001:db8::17"	# Jail's primary IPv4 and IPv6 address
> -#jail_example_ip_multi0="2001:db8::10"		#  and another IPv6 address
> -#jail_example_exec_start="/bin/sh /etc/rc"		# command to execute in jail for starting
> -#jail_example_exec_afterstart0="/bin/sh command"	# command to execute after the one for
> -							# starting the jail. More than one can be
> -							# specified using a trailing number
> -#jail_example_exec_stop="/bin/sh /etc/rc.shutdown"	# command to execute in jail for stopping
> -#jail_example_devfs_enable="NO"			# mount devfs in the jail
> -#jail_example_devfs_ruleset="ruleset_name"	# devfs ruleset to apply to jail -
> -						# usually you want "devfsrules_jail".
> -#jail_example_fdescfs_enable="NO"		# mount fdescfs in the jail
> -#jail_example_procfs_enable="NO"		# mount procfs in jail
> -#jail_example_mount_enable="NO"			# mount/umount jail's fs
> -#jail_example_fstab=""				# fstab(5) for mount/umount
> -#jail_example_flags="-l -U root"		# flags for jail(8)
> -#jail_example_parameters="allow.raw_sockets=1"	# extra parameters for this jail
> 
> ##############################################################
> ### Define source_rc_confs, the mechanism used by /etc/rc.* ##
> 
> Modified: head/etc/rc.d/jail
> ==============================================================================
> --- head/etc/rc.d/jail	Thu Oct 10 07:41:11 2013	(r256255)
> +++ head/etc/rc.d/jail	Thu Oct 10 09:32:27 2013	(r256256)
> @@ -8,81 +8,138 @@
> # BEFORE: securelevel
> # KEYWORD: nojail shutdown
> 
> -# WARNING: This script deals with untrusted data (the data and
> -# processes inside the jails) and care must be taken when changing the
> -# code related to this!  If you have any doubt whether a change is
> -# correct and have security impact, please get the patch reviewed by
> -# the FreeBSD Security Team prior to commit.
> -
> . /etc/rc.subr
> 
> name="jail"
> rcvar="jail_enable"
> 
> -start_precmd="jail_prestart"
> 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_conf:=/etc/jail.conf}
> +: ${jail_program:=/usr/sbin/jail}
> +: ${jail_consolecmd:=/bin/sh}
> +: ${jail_jexec:=/usr/sbin/jexec}
> +: ${jail_jls:=/usr/sbin/jls}
> +
> +need_dad_wait=
> +
> +# extact_var jail name param num defval
> +#	Extract value from ${jail_$jail_$name} or ${jail_$name} and
> +#	set it to $param.  If not defined, $defval is used.
> +#	When $num is [0-9]*, ${jail_$jail_$name$num} are looked up and
> +#	$param is set by using +=.
> +#	When $num is YN or NY, the value is interpret as boolean.
> +extract_var()
> +{
> +	local i _j _name _param _num _def _name1 _name2
> +	_j=$1
> +	_name=$2
> +	_param=$3
> +	_num=$4
> +	_def=$5
> +
> +	case $_num in
> +	YN)
> +		_name1=jail_${_j}_${_name}
> +		_name2=jail_${_name}
> +		eval $_name1=\"\${$_name1:-\${$_name2:-$_def}}\"
> +		if checkyesno $_name1; then
> +			echo "	$_param = 1;"
> +		else
> +			echo "	$_param = 0;"
> +		fi
> +	;;
> +	NY)
> +		_name1=jail_${_j}_${_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_${_j}_${_name}${i}
> +			_name2=jail_${_name}${i}
> +			eval _tmpargs=\"\${$_name1:-\${$_name2:-$_def}}\"
> +			if [ -n "$_tmpargs" ]; then 
> +				echo "	$_param += \"$_tmpargs\";"
> +			else
> +				break;
> +			fi
> +			i=$(($i + 1))
> +		done
> +	;;
> +	*)
> +		_name1=jail_${_j}_${_name}
> +		_name2=jail_${_name}
> +		eval _tmpargs=\"\${$_name1:-\${$_name2:-$_def}}\"
> +		if [ -n "$_tmpargs" ]; then
> +			echo "	$_param = \"$_tmpargs\";"
> +		fi
> +	;;
> +	esac
> +}
> 
> -# init_variables _j
> -#	Initialize the various jail variables for jail _j.
> +# parse_options _j
> +#	Parse options and create a temporary configuration file if necessary.
> #
> -init_variables()
> +parse_options()
> {
> -	_j="$1"
> +	local _j
> +	_j=$1
> 
> +	_confwarn=0
> 	if [ -z "$_j" ]; then
> -		warn "init_variables: you must specify a jail"
> +		warn "parse_options: you must specify a jail"
> 		return
> 	fi
> -
> +	eval _jconf=\"\${jail_${_j}_conf:-/etc/jail.${_j}.conf}\"
> 	eval _rootdir=\"\$jail_${_j}_rootdir\"
> -	_devdir="${_rootdir}/dev"
> -	_fdescdir="${_devdir}/fd"
> -	_procdir="${_rootdir}/proc"
> 	eval _hostname=\"\$jail_${_j}_hostname\"
> +	if [ -z "$_rootdir" -o \
> +	     -z "$_hostname" ]; then
> +		if [ -r "$_jconf" ]; then
> +			_conf="$_jconf"
> +			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_${_j}_ip\"
> -	eval _interface=\"\${jail_${_j}_interface:-${jail_interface}}\"
> -	eval _exec=\"\$jail_${_j}_exec\"
> -
> -	i=0
> -	while : ; do
> -		eval _exec_prestart${i}=\"\${jail_${_j}_exec_prestart${i}:-\${jail_exec_prestart${i}}}\"
> -		[ -z "$(eval echo \"\$_exec_prestart${i}\")" ] && break
> -		i=$((i + 1))
> -	done
> -
> -	eval _exec_start=\"\${jail_${_j}_exec_start:-${jail_exec_start}}\"
> -
> -	i=1
> -	while : ; do
> -		eval _exec_afterstart${i}=\"\${jail_${_j}_exec_afterstart${i}:-\${jail_exec_afterstart${i}}}\"
> -		[ -z "$(eval echo \"\$_exec_afterstart${i}\")" ] &&  break
> -		i=$((i + 1))
> -	done
> -
> -	i=0
> -	while : ; do
> -		eval _exec_poststart${i}=\"\${jail_${_j}_exec_poststart${i}:-\${jail_exec_poststart${i}}}\"
> -		[ -z "$(eval echo \"\$_exec_poststart${i}\")" ] && break
> -		i=$((i + 1))
> -	done
> -
> -	i=0
> -	while : ; do
> -		eval _exec_prestop${i}=\"\${jail_${_j}_exec_prestop${i}:-\${jail_exec_prestop${i}}}\"
> -		[ -z "$(eval echo \"\$_exec_prestop${i}\")" ] && break
> -		i=$((i + 1))
> -	done
> -
> -	eval _exec_stop=\"\${jail_${_j}_exec_stop:-${jail_exec_stop}}\"
> -
> -	i=0
> -	while : ; do
> -		eval _exec_poststop${i}=\"\${jail_${_j}_exec_poststop${i}:-\${jail_exec_poststop${i}}}\"
> -		[ -z "$(eval echo \"\$_exec_poststop${i}\")" ] && break
> -		i=$((i + 1))
> -	done
> +	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.
> +	#
> +	_confwarn=1
> +	if [ -r "$jail_conf" -o -r "$_jconf" ]; then
> +		warn "$_conf is created and used for jail $_j."
> +	fi
> +	/usr/bin/install -m 0644 -o root -g wheel /dev/null $_conf || return 1
> 
> +	eval : \${jail_${_j}_flags:=${jail_flags}}
> +	eval _exec=\"\$jail_${_j}_exec\"
> +	eval _exec_start=\"\$jail_${_j}_exec_start\"
> +	eval _exec_stop=\"\$jail_${_j}_exec_stop\"
> 	if [ -n "${_exec}" ]; then
> 		#   simple/backward-compatible execution
> 		_exec_start="${_exec}"
> @@ -96,285 +153,104 @@ init_variables()
> 			fi
> 		fi
> 	fi
> -
> -	# The default jail ruleset will be used by rc.subr if none is specified.
> -	eval _ruleset=\"\${jail_${_j}_devfs_ruleset:-${jail_devfs_ruleset}}\"
> -	eval _devfs=\"\${jail_${_j}_devfs_enable:-${jail_devfs_enable}}\"
> -	[ -z "${_devfs}" ] && _devfs="NO"
> -	eval _fdescfs=\"\${jail_${_j}_fdescfs_enable:-${jail_fdescfs_enable}}\"
> -	[ -z "${_fdescfs}" ] && _fdescfs="NO"
> -	eval _procfs=\"\${jail_${_j}_procfs_enable:-${jail_procfs_enable}}\"
> -	[ -z "${_procfs}" ] && _procfs="NO"
> -
> -	eval _mount=\"\${jail_${_j}_mount_enable:-${jail_mount_enable}}\"
> -	[ -z "${_mount}" ] && _mount="NO"
> -	# "/etc/fstab.${_j}" will be used for {,u}mount(8) if none is specified.
> -	eval _fstab=\"\${jail_${_j}_fstab:-${jail_fstab}}\"
> -	[ -z "${_fstab}" ] && _fstab="/etc/fstab.${_j}"
> -	eval _flags=\"\${jail_${_j}_flags:-${jail_flags}}\"
> -	[ -z "${_flags}" ] && _flags="-l -U root"
> -	eval _consolelog=\"\${jail_${_j}_consolelog:-${jail_consolelog}}\"
> -	[ -z "${_consolelog}" ] && _consolelog="/var/log/jail_${_j}_console.log"
> +	eval _interface=\"\${jail_${_j}_interface:-${jail_interface}}\"
> 	eval _parameters=\"\${jail_${_j}_parameters:-${jail_parameters}}\"
> -	[ -z "${_parameters}" ] && _parameters=""
> -	eval _fib=\"\${jail_${_j}_fib:-${jail_fib}}\"
> -
> -	# Debugging aid
> -	#
> -	debug "$_j devfs enable: $_devfs"
> -	debug "$_j fdescfs enable: $_fdescfs"
> -	debug "$_j procfs enable: $_procfs"
> -	debug "$_j mount enable: $_mount"
> -	debug "$_j hostname: $_hostname"
> -	debug "$_j ip: $_ip"
> -	jail_show_addresses ${_j}
> -	debug "$_j interface: $_interface"
> -	debug "$_j fib: $_fib"
> -	debug "$_j root: $_rootdir"
> -	debug "$_j devdir: $_devdir"
> -	debug "$_j fdescdir: $_fdescdir"
> -	debug "$_j procdir: $_procdir"
> -	debug "$_j ruleset: $_ruleset"
> -	debug "$_j fstab: $_fstab"
> -
> -	i=0
> -	while : ; do
> -		eval out=\"\${_exec_prestart${i}:-''}\"
> -		if [ -z "$out" ]; then
> -			break
> -		fi
> -		debug "$_j exec pre-start #${i}: ${out}"
> -		i=$((i + 1))
> -	done
> -
> -	debug "$_j exec start: $_exec_start"
> -
> -	i=1
> -	while : ; do
> -		eval out=\"\${_exec_afterstart${i}:-''}\"
> -
> -		if [ -z "$out" ]; then
> -			break;
> -		fi
> -
> -		debug "$_j exec after start #${i}: ${out}"
> -		i=$((i + 1))
> -	done
> -
> -	i=0
> -	while : ; do
> -		eval out=\"\${_exec_poststart${i}:-''}\"
> -		if [ -z "$out" ]; then
> -			break
> -		fi
> -		debug "$_j exec post-start #${i}: ${out}"
> -		i=$((i + 1))
> -	done
> -
> -	i=0
> -	while : ; do
> -		eval out=\"\${_exec_prestop${i}:-''}\"
> -		if [ -z "$out" ]; then
> -			break
> -		fi
> -		debug "$_j exec pre-stop #${i}: ${out}"
> -		i=$((i + 1))
> -	done
> -
> -	debug "$_j exec stop: $_exec_stop"
> +	eval _fstab=\"\${jail_${_j}_fstab:-${jail_fstab:-/etc/fstab.$_j}}\"
> +	(
> +		date +"# Generated by rc.d/jail at %Y-%m-%d %H:%M:%S"
> +		echo "$_j {"
> +		extract_var $_j hostname host.hostname - ""
> +		extract_var $_j rootdir path - ""
> +		if [ -n "$_ip" ]; then
> +			extract_var $_j interface interface - ""
> +			jail_handle_ips_option $_ip $_interface
> +			alias=0
> +			while : ; do
> +				eval _x=\"\$jail_${_jail}_ip_multi${alias}\"
> +				[ -z "$_x" ] && break
> 
> -	i=0
> -	while : ; do
> -		eval out=\"\${_exec_poststop${i}:-''}\"
> -		if [ -z "$out" ]; then
> -			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 $_j fib exec.fib - ""
> +			extract_var $_j socket_unixiproute_only \
> +			    allow.raw_sockets NY YES
> +		else
> +			echo "	vnet;"
> +			extract_var $_j vnet_interface vnet.interface - ""
> 		fi
> -		debug "$_j exec post-stop #${i}: ${out}"
> -		i=$((i + 1))
> -	done
> -
> -	debug "$_j flags: $_flags"
> -	debug "$_j consolelog: $_consolelog"
> -	debug "$_j parameters: $_parameters"
> 
> -	if [ -z "${_hostname}" ]; then
> -		err 3 "$name: No hostname has been defined for ${_j}"
> -	fi
> -	if [ -z "${_rootdir}" ]; then
> -		err 3 "$name: No root directory has been defined for ${_j}"
> -	fi
> -}
> -
> -# set_sysctl rc_knob mib msg
> -#	If the mib sysctl is set according to what rc_knob
> -#	specifies, this function does nothing. However if
> -#	rc_knob is set differently than mib, then the mib
> -#	is set accordingly and msg is displayed followed by
> -#	an '=" sign and the word 'YES' or 'NO'.
> -#
> -set_sysctl()
> -{
> -	_knob="$1"
> -	_mib="$2"
> -	_msg="$3"
> -
> -	_current=`${SYSCTL} -n $_mib 2>/dev/null`
> -	if checkyesno $_knob ; then
> -		if [ "$_current" -ne 1 ]; then
> -			echo -n " ${_msg}=YES"
> -			${SYSCTL} 1>/dev/null ${_mib}=1
> -		fi
> -	else
> -		if [ "$_current" -ne 0 ]; then
> -			echo -n " ${_msg}=NO"
> -			${SYSCTL} 1>/dev/null ${_mib}=0
> +		echo "	exec.clean;"
> +		echo "	exec.system_user = \"root\";"
> +		echo "	exec.jail_user = \"root\";"
> +		extract_var $_j exec_prestart exec.prestart 0 ""
> +		extract_var $_j exec_poststart exec.poststart 0 ""
> +		extract_var $_j exec_prestop exec.prestop 0 ""
> +		extract_var $_j exec_poststop exec.poststop 0 ""
> +
> +		echo "	exec.start += \"$_exec_start\";"
> +		extract_var $_j exec_afterstart exec.start 1 ""
> +		echo "	exec.stop = \"$_exec_stop\";"
> +
> +		extract_var $_j consolelog exec.consolelog - \
> +		    /var/log/jail_${_j}_console.log
> +
> +		eval : \${jail_${_j}_devfs_enable:=${jail_devfs_enable:-NO}}
> +		if checkyesno jail_${_j}_devfs_enable; then
> +			echo "	mount.devfs;"
> +			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 integer." ;;
> +			esac
> +			if [ -r $_fstab ]; then
> +				echo "	mount.fstab = \"$_fstab\";"
> +			fi
> 		fi
> -	fi
> -}
> -
> -# is_current_mountpoint()
> -#	Is the directory mount point for a currently mounted file
> -#	system?
> -#
> -is_current_mountpoint()
> -{
> -	local _dir _dir2
> -
> -	_dir=$1
> -
> -	_dir=`echo $_dir | sed -Ee 's#//+#/#g' -e 's#/$##'`
> -	[ ! -d "${_dir}" ] && return 1
> -	_dir2=`df ${_dir} | tail +2 | awk '{ print $6 }'`
> -	[ "${_dir}" = "${_dir2}" ]
> -	return $?
> -}
> -
> -# is_symlinked_mountpoint()
> -#	Is a mount point, or any of its parent directories, a symlink?
> -#
> -is_symlinked_mountpoint()
> -{
> -	local _dir
> -
> -	_dir=$1
> -
> -	[ -L "$_dir" ] && return 0
> -	[ "$_dir" = "/" ] && return 1
> -	is_symlinked_mountpoint `dirname $_dir`
> -	return $?
> -}
> -
> -# secure_umount
> -#	Try to unmount a mount point without being vulnerable to
> -#	symlink attacks.
> -#
> -secure_umount()
> -{
> -	local _dir
> -
> -	_dir=$1
> -
> -	if is_current_mountpoint ${_dir}; then
> -		umount -f ${_dir} >/dev/null 2>&1
> -	else
> -		debug "Nothing mounted on ${_dir} - not unmounting"
> -	fi
> -}
> -
> -
> -# jail_umount_fs
> -#	This function unmounts certain special filesystems in the
> -#	currently selected jail. The caller must call the init_variables()
> -#	routine before calling this one.
> -#
> -jail_umount_fs()
> -{
> -	local _device _mountpt _rest
> 
> -	if checkyesno _fdescfs; then
> -		if [ -d "${_fdescdir}" ] ; then
> -			secure_umount ${_fdescdir}
> -		fi
> -	fi
> -	if checkyesno _devfs; then
> -		if [ -d "${_devdir}" ] ; then
> -			secure_umount ${_devdir}
> +		eval : \${jail_${_j}_fdescfs_enable:=${jail_fdescfs_enable:-NO}}
> +		if checkyesno jail_${_j}_fdescfs_enable; then
> +			echo "	mount += " \
> +			    "\"fdescfs ${_rootdir%/}/dev/fd fdescfs rw 0 0\";"
> 		fi
> -	fi
> -	if checkyesno _procfs; then
> -		if [ -d "${_procdir}" ] ; then
> -			secure_umount ${_procdir}
> +		eval : \${jail_${_j}_procfs_enable:=${jail_procfs_enable:-NO}}
> +		if checkyesno jail_${_j}_procfs_enable; then
> +			echo "	mount += " \
> +			    "\"procfs ${_rootdir%/}/proc procfs rw 0 0\";"
> 		fi
> -	fi
> -	if checkyesno _mount; then
> -		[ -f "${_fstab}" ] || warn "${_fstab} does not exist"
> -		tail -r ${_fstab} | while read _device _mountpt _rest; do
> -			case ":${_device}" in
> -			:#* | :)
> -				continue
> -				;;
> -			esac
> -			secure_umount ${_mountpt}
> -		done
> -	fi
> -}
> 
> -# jail_mount_fstab()
> -#	Mount file systems from a per jail fstab while trying to
> -#	secure against symlink attacks at the mount points.
> -#
> -#	If we are certain we cannot secure against symlink attacks we
> -#	do not mount all of the file systems (since we cannot just not
> -#	mount the file system with the problematic mount point).
> -#
> -#	The caller must call the init_variables() routine before
> -#	calling this one.
> -#
> -jail_mount_fstab()
> -{
> -	local _device _mountpt _rest
> +		echo "	${_parameters};"
> 
> -	while read _device _mountpt _rest; do
> -		case ":${_device}" in
> -		:#* | :)
> -			continue
> -			;;
> -		esac
> -		if is_symlinked_mountpoint ${_mountpt}; then
> -			warn "${_mountpt} has symlink as parent - not mounting from ${_fstab}"
> -			return
> +		eval : \${jail_${_j}_mount_enable:=${jail_mount_enable:-NO}}
> +		if checkyesno jail_${_j}_mount_enable; then
> +			echo "	allow.mount;" >> $_conf
> 		fi
> -	done <${_fstab}
> -	mount -a -F "${_fstab}"
> -}
> -
> -# jail_show_addresses jail
> -#	Debug print the input for the given _multi aliases
> -#	for a jail for init_variables().
> -#
> -jail_show_addresses()
> -{
> -	local _j _type alias
> -	_j="$1"
> -	alias=0
> 
> -	if [ -z "${_j}" ]; then
> -		warn "jail_show_addresses: you must specify a jail"
> -		return
> -	fi
> +		extract_var $_j set_hostname_allow allow.set_hostname YN NO
> +		extract_var $_j sysvipc_allow allow.sysvipc YN NO
> +		echo "}"
> +	) >> $_conf
> 
> -	while : ; do
> -		eval _addr=\"\$jail_${_j}_ip_multi${alias}\"
> -		if [ -n "${_addr}" ]; then
> -			debug "${_j} ip_multi${alias}: $_addr"
> -			alias=$((${alias} + 1))
> -		else
> -			break
> -		fi
> -	done
> +	return 0
> }
> 
> -# jail_extract_address argument
> +# 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.
> @@ -382,8 +258,9 @@ jail_show_addresses()
> #
> jail_extract_address()
> {
> -	local _i
> +	local _i _interface
> 	_i=$1
> +	_interface=$2
> 
> 	if [ -z "${_i}" ]; then
> 		warn "jail_extract_address: called without input"
> @@ -439,21 +316,21 @@ jail_extract_address()
> 		_mask=${_mask:-/32}
> 
> 	elif [ "${_type}" = "inet6" ]; then
> -		# In case _maske is not set for IPv6, use /128.
> -		_mask=${_mask:-/128}
> +		# In case _maske is not set for IPv6, use /64.
> +		_mask=${_mask:-/64}
> 	fi
> }
> 
> -# jail_handle_ips_option {add,del} input
> +# 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 _action _type _i
> -	_action=$1
> -	_x=$2
> +	local _x _type _i _iface
> +	_x=$1
> +	_iface=$2
> 
> 	if [ -z "${_x}" ]; then
> 		# No IP given. This can happen for the primary address
> @@ -468,294 +345,146 @@ jail_handle_ips_option()
> 		*,*)	# Extract the first argument and strip it off the list.
> 			_i=`expr "${_x}" : '^\([^,]*\)'`
> 			_x=`expr "${_x}" : "^[^,]*,\(.*\)"`
> -			;;
> +		;;
> 		*)	_i=${_x}
> 			_x=""
> -			;;
> +		;;
> 		esac
> 
> 		_type=""
> -		_iface=""
> 		_addr=""
> 		_mask=""
> -		jail_extract_address "${_i}"
> +		jail_extract_address $_i $_iface
> 
> 		# make sure we got an address.
> -		case "${_addr}" in
> +		case $_addr in
> 		"")	continue ;;
> 		*)	;;
> 		esac
> 
> 		# Append address to list of addresses for the jail command.
> -		case "${_type}" in
> +		case $_type in
> 		inet)
> -			case "${_addrl}" in
> -			"")	_addrl="${_addr}" ;;
> -			*)	_addrl="${_addrl},${_addr}" ;;
> -			esac
> -			;;
> +			echo "	ip4.addr += \"${_addr}${_mask}\";"
> +		;;
> 		inet6)
> -			case "${_addr6l}" in
> -			"")	_addr6l="${_addr}" ;;
> -			*)	_addr6l="${_addr6l},${_addr}" ;;
> -			esac
> -			;;
> -		esac
> -
> -		# Configure interface alias if requested by a given interface
> -		# and if we could correctly parse everything.
> -		case "${_iface}" in
> -		"")	continue ;;
> -		esac
> -		case "${_type}" in
> -		inet)	;;
> -		inet6)	ipv6_address_count=$((ipv6_address_count + 1)) ;;
> -		*)	warn "Could not determine address family.  Not going" \
> -			    "to ${_action} address '${_addr}' for ${_jail}."
> -			continue
> -			;;
> -		esac
> -		case "${_action}" in
> -		add)	ifconfig ${_iface} ${_type} ${_addr}${_mask} alias
> -			;;
> -		del)	# When removing the IP, ignore the _mask.
> -			ifconfig ${_iface} ${_type} ${_addr} -alias
> -			;;
> +			echo "	ip6.addr += \"${_addr}${_mask}\";"
> +			need_dad_wait=1
> +		;;
> 		esac
> 	done
> }
> 
> -# jail_ips {add,del}
> -#	Extract the comma separated list of addresses and return them
> -#	for the jail command.
> -#	Handle more than one address via the _multi option as well.
> -#	If an interface is given also add/remove an alias for the
> -#	address with an optional netmask.
> -#
> -jail_ips()
> +jail_config()
> {
> -	local _action
> -	_action=$1
> -
> -	case "${_action}" in
> -	add)	;;
> -	del)	;;
> -	*)	warn "jail_ips: invalid action '${_action}'"
> -		return
> -		;;
> +	case $1 in
> +	_ALL)	return ;;
> 	esac
> -
> -	# Handle addresses.
> -	ipv6_address_count=0
> -	jail_handle_ips_option ${_action} "${_ip}"
> -	# Handle jail_xxx_ip_multi<N>
> -	alias=0
> -	while : ; do
> -		eval _x=\"\$jail_${_jail}_ip_multi${alias}\"
> -		case "${_x}" in
> -		"")	break ;;
> -		*)	jail_handle_ips_option ${_action} "${_x}"
> -			alias=$((${alias} + 1))
> -			;;
> -		esac
> +	for _jail in $@; do
> +		if parse_options $_jail; then 
> +			echo "$_jail: parameters are in $_conf."
> +		fi
> 	done
> -	case ${ipv6_address_count} in
> -	0)	;;
> -	*)	# Sleep 1 second to let DAD complete before starting services.
> -		sleep 1
> -		;;
> +}
> +
> +jail_console()
> +{
> +	# One argument that is not _ALL.
> +	case $#:$1 in
> +	1:_ALL)	err 3 "Specify a jail name." ;;
> +	1:*)	;;
> +	*)	err 3 "Specify a jail name." ;;
> 	esac
> +	eval _cmd=\${jail_$1_consolecmd:-$jail_consolecmd}
> +	$jail_jexec $1 $_cmd
> }
> 
> -jail_prestart()
> +jail_status()
> {
> -	if checkyesno jail_parallel_start; then
> -		command_args='&'
> -	fi
> +
> +	$jail_jls -N
> }
> 
> jail_start()
> {
> -	echo -n 'Configuring jails:'
> -	set_sysctl jail_set_hostname_allow security.jail.set_hostname_allowed \
> -	    set_hostname_allow
> -	set_sysctl jail_socket_unixiproute_only \
> -	    security.jail.socket_unixiproute_only unixiproute_only
> -	set_sysctl jail_sysvipc_allow security.jail.sysvipc_allowed \
> -	    sysvipc_allow
> -	echo '.'
> -
> +	if [ $# = 0 ]; then
> +		return
> +	fi
> 	echo -n 'Starting jails:'
> -	_tmp_dir=`mktemp -d /tmp/jail.XXXXXXXX` || \
> -	    err 3 "$name: Can't create temp dir, exiting..."
> -	for _jail in ${jail_list}
> -	do
> -		init_variables $_jail
> -		if [ -f /var/run/jail_${_jail}.id ]; then
> -			echo -n " [${_hostname} already running (/var/run/jail_${_jail}.id exists)]"
> -			continue;
> -		fi
> -		_addrl=""
> -		_addr6l=""
> -		jail_ips "add"
> -		if [ -n "${_fib}" ]; then
> -			_setfib="setfib -F '${_fib}'"
> +	case $1 in
> +	_ALL)
> +		echo -n ' '
> +		command=$jail_program
> +		rc_flags=$jail_flags
> +		command_args="-f $jail_conf -c"
> +		$command $rc_flags $command_args "*"
> +		echo '.'
> +		return
> +	;;
> +	esac
> +	_tmp=`mktemp -t jail` || exit 3
> +	for _jail in $@; do
> +		parse_options $_jail || continue
> +
> +		eval rc_flags=\${jail_${_j}_flags:-$jail_flags}
> +		eval command=\${jail_${_j}_program:-$jail_program}
> +		if checkyesno jail_parallel_start; then
> +			command_args="-i -f $_conf -c $_jail &"
> 		else
> -			_setfib=""
> -		fi
> -		if checkyesno _mount; then
> -			info "Mounting fstab for jail ${_jail} (${_fstab})"
> -			if [ ! -f "${_fstab}" ]; then
> -				err 3 "$name: ${_fstab} does not exist"
> -			fi
> -			jail_mount_fstab
> -		fi
> -		if checkyesno _devfs; then
> -			# If devfs is already mounted here, skip it.
> -			df -t devfs "${_devdir}" >/dev/null
> -			if [ $? -ne 0 ]; then
> -				if is_symlinked_mountpoint ${_devdir}; then
> -					warn "${_devdir} has symlink as parent - not starting jail ${_jail}"
> -					continue
> -				fi
> -				info "Mounting devfs on ${_devdir}"
> -				devfs_mount_jail "${_devdir}" ${_ruleset}
> -				# Transitional symlink for old binaries
> -				if [ ! -L "${_devdir}/log" ]; then
> -					ln -sf ../var/run/log "${_devdir}/log"
> -				fi
> -			fi
> -
> -			# XXX - It seems symlinks don't work when there
> -			#	is a devfs(5) device of the same name.
> -			# Jail console output
> -			#	__pwd="`pwd`"
> -			#	cd "${_devdir}"
> -			#	ln -sf ../var/log/console console
> -			#	cd "$__pwd"
> -		fi
> -		if checkyesno _fdescfs; then
> -			if is_symlinked_mountpoint ${_fdescdir}; then
> -				warn "${_fdescdir} has symlink as parent, not mounting"
> -			else
> -				info "Mounting fdescfs on ${_fdescdir}"
> -				mount -t fdescfs fdesc "${_fdescdir}"
> -			fi
> -		fi
> -		if checkyesno _procfs; then
> -			if is_symlinked_mountpoint ${_procdir}; then
> -				warn "${_procdir} has symlink as parent, not mounting"
> -			else
> -				info "Mounting procfs onto ${_procdir}"
> -				if [ -d "${_procdir}" ] ; then
> -					mount -t procfs proc "${_procdir}"
> -				fi
> -			fi
> +			command_args="-i -f $_conf -c $_jail"
> 		fi
> -		_tmp_jail=${_tmp_dir}/jail.$$
> -
> -		i=0
> -		while : ; do
> -			eval out=\"\${_exec_prestart${i}:-''}\"
> -			[ -z "$out" ] && break
> -			${out}
> -			i=$((i + 1))
> -		done
> -
> -		eval ${_setfib} jail -n ${_jail} ${_flags} -i -c path=${_rootdir} host.hostname=${_hostname} \
> -			${_addrl:+ip4.addr=\"${_addrl}\"} ${_addr6l:+ip6.addr=\"${_addr6l}\"} \
> -			${_parameters} command=${_exec_start} > ${_tmp_jail} 2>&1 \
> -			</dev/null
> -
> -		if [ "$?" -eq 0 ] ; then
> -			_jail_id=$(head -1 ${_tmp_jail})
> -			i=1
> -			while : ; do
> -				eval out=\"\${_exec_afterstart${i}:-''}\"
> -
> -				if [ -z "$out" ]; then
> -					break;
> -				fi
> -
> -				jexec "${_jail_id}" ${out}
> -				i=$((i + 1))
> -			done
> -
> -			echo -n " $_hostname"
> -			tail +2 ${_tmp_jail} >${_consolelog}
> -			echo ${_jail_id} > /var/run/jail_${_jail}.id
> -
> -			i=0
> -			while : ; do
> -				eval out=\"\${_exec_poststart${i}:-''}\"
> -				[ -z "$out" ] && break
> -				${out}
> -				i=$((i + 1))
> -			done
> +		if $command $rc_flags $command_args \
> +		    >> $_tmp 2>&1 </dev/null; then
> +			echo -n " ${_hostname:-${_jail}}"
> 		else
> -			jail_umount_fs
> -			jail_ips "del"
> -			echo " cannot start jail \"${_jail}\": "
> -			tail +2 ${_tmp_jail}
> +			echo " cannot start jail \"${_hostname:-${jail}}\": "
> +			tail +2 $_tmp
> 		fi
> -		rm -f ${_tmp_jail}
> +		rm -f $_tmp
> 	done
> -	rmdir ${_tmp_dir}
> 	echo '.'
> }
> 
> jail_stop()
> {
> +	if [ $# = 0 ]; then
> +		return
> +	fi
> 	echo -n 'Stopping jails:'
> -	for _jail in ${jail_list}
> -	do
> -		if [ -f "/var/run/jail_${_jail}.id" ]; then
> -			_jail_id=$(cat /var/run/jail_${_jail}.id)
> -			if [ ! -z "${_jail_id}" ]; then
> -				init_variables $_jail
> -
> -				i=0
> -				while : ; do
> -					eval out=\"\${_exec_prestop${i}:-''}\"
> -					[ -z "$out" ] && break
> -					${out}
> 
> *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***

-- 
/"\   With kind regards,			| remko at elvandar.org
\ /   Remko Lodder			| remko at FreeBSD.org
X    FreeBSD					| http://www.evilcoder.org
/ \   The Power to Serve		| Quis custodiet ipsos custodes

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 841 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <http://lists.freebsd.org/pipermail/svn-src-head/attachments/20131011/b167e338/attachment.sig>


More information about the svn-src-head mailing list