jail revision 133869
1#!/bin/sh
2#
3# $FreeBSD: head/etc/rc.d/jail 133869 2004-08-16 16:37:06Z nectar $
4#
5
6# PROVIDE: jail
7# REQUIRE: LOGIN
8# BEFORE: securelevel
9# KEYWORD: FreeBSD nojail shutdown
10
11. /etc/rc.subr
12
13name="jail"
14rcvar=`set_rcvar`
15start_cmd="jail_start"
16stop_cmd="jail_stop"
17
18# init_variables _j
19#	Initialize the various jail variables for jail _j.
20#
21init_variables()
22{
23	_j="$1"
24
25	if [ -z "$_j" ]; then
26		warn "init_variables: you must specify a jail"
27		return
28	fi
29
30	eval jail_rootdir=\"\$jail_${_j}_rootdir\"
31	jail_devdir="${jail_rootdir}/dev"
32	jail_fdescdir="${jail_devdir}/fd"
33	jail_procdir="${jail_rootdir}/proc"
34	eval jail_hostname=\"\$jail_${_j}_hostname\"
35	eval jail_ip=\"\$jail_${_j}_ip\"
36	eval jail_exec=\"\$jail_${_j}_exec\"
37	[ -z "${jail_exec}" ] && jail_exec="/bin/sh /etc/rc"
38
39	# The default jail ruleset will be used by rc.subr if none is specified.
40	eval jail_ruleset=\"\$jail_${_j}_devfs_ruleset\"
41	eval jail_devfs=\"\$jail_${_j}_devfs_enable\"
42	[ -z "${jail_devfs}" ] && jail_devfs="NO"
43	eval jail_fdescfs=\"\$jail_${_j}_fdescfs_enable\"
44	[ -z "${jail_fdescfs}" ] && jail_fdescfs="NO"
45	eval jail_procfs=\"\$jail_${_j}_procfs_enable\"
46	[ -z "${jail_procfs}" ] && jail_procfs="NO"
47
48	# Debugging aid
49	#
50	debug "$_j devfs enable: $jail_devfs"
51	debug "$_j fdescfs enable: $jail_fdescfs"
52	debug "$_j procfs enable: $jail_procfs"
53	debug "$_j hostname: $jail_hostname"
54	debug "$_j ip: $jail_ip"
55	debug "$_j root: $jail_rootdir"
56	debug "$_j devdir: $jail_devdir"
57	debug "$_j fdescdir: $jail_fdescdir"
58	debug "$_j procdir: $jail_procdir"
59	debug "$_j ruleset: $jail_ruleset"
60}
61
62# set_sysctl rc_knob mib msg
63#	If the mib sysctl is set according to what rc_knob
64#	specifies, this function does nothing. However if
65#	rc_knob is set differently than mib, then the mib
66#	is set accordingly and msg is displayed followed by
67#	an '=" sign and the word 'YES' or 'NO'.
68#
69set_sysctl()
70{
71	_knob="$1"
72	_mib="$2"
73	_msg="$3"
74
75	_current=`${SYSCTL} -n $_mib 2>/dev/null`
76	if checkyesno $_knob ; then
77		if [ "$_current" -ne 1 ]; then
78			echo -n " ${_msg}=YES"
79			${SYSCTL_W} 1>/dev/null ${_mib}=1
80		fi
81	else
82		if [ "$_current" -ne 0 ]; then
83			echo -n " ${_msg}=NO"
84			${SYSCTL_W} 1>/dev/null ${_mib}=0
85		fi
86	fi
87}
88
89# jail_umount_fs
90#	This function unmounts certain special filesystems in the
91#	currently selected jail. The caller must call the init_variables()
92#	routine before calling this one.
93#
94jail_umount_fs()
95{
96	if checkyesno jail_fdescfs; then
97		if [ -d ${jail_fdescdir} ] ; then
98			umount -f ${jail_fdescdir} >/dev/null 2>&1
99		fi
100	fi
101	if checkyesno jail_devfs; then
102		if [ -d ${jail_devdir} ] ; then
103			umount -f ${jail_devdir} >/dev/null 2>&1
104		fi
105	fi
106	if checkyesno jail_procfs; then
107		if [ -d ${jail_procdir} ] ; then
108			umount -f ${jail_procdir} >/dev/null 2>&1
109		fi
110	fi
111}
112
113jail_start()
114{
115	echo -n 'Configuring jails:'
116	set_sysctl jail_set_hostname_allow security.jail.set_hostname_allowed \
117	    set_hostname_allow
118	set_sysctl jail_socket_unixiproute_only \
119	    security.jail.socket_unixiproute_only unixiproute_only
120	set_sysctl jail_sysvipc_allow security.jail.sysvipc_allowed \
121	    sysvipc_allow
122	echo '.'
123
124	echo -n 'Starting jails:'
125	_tmp_dir=`mktemp -d /tmp/jail.XXXXXXXX` || \
126	    err 3 "$name: Can't create temp dir, exiting..."
127	for _jail in ${jail_list}
128	do
129		init_variables $_jail
130		if checkyesno jail_devfs; then
131			info "Mounting devfs on ${jail_devdir}"
132			devfs_mount_jail "${jail_devdir}" ${jail_ruleset}
133
134			# Transitional symlink for old binaries
135			if [ ! -L ${jail_devdir}/log ]; then
136				__pwd="`pwd`"
137				cd "${jail_devdir}"
138				ln -sf ../var/run/log log
139				cd "$__pwd"
140			fi
141
142			# XXX - It seems symlinks don't work when there
143			#	is a devfs(5) device of the same name.
144			# Jail console output
145			#	__pwd="`pwd`"
146			#	cd "${jail_devdir}"
147			#	ln -sf ../var/log/console console
148			#	cd "$__pwd"
149		fi
150		if checkyesno jail_fdescfs; then
151			info "Mounting fdescfs on ${jail_fdescdir}"
152			mount -t fdescfs fdesc "${jail_fdescdir}"
153		fi
154		if checkyesno jail_procfs; then
155			info "Mounting procfs onto ${jail_procdir}"
156			if [ -d ${jail_procdir} ] ; then
157				mount -t procfs proc "${jail_procdir}"
158			fi
159		fi
160		_tmp_jail=${_tmp_dir}/jail.$$
161		jail -i ${jail_rootdir} ${jail_hostname} \
162			${jail_ip} ${jail_exec} > ${_tmp_jail} 2>&1
163		[ "$?" -eq 0 ] && echo -n " $jail_hostname"
164		_jail_id=$(head -1 ${_tmp_jail})
165		tail +2 ${_tmp_jail} >${jail_rootdir}/var/log/console.log
166		rm -f ${_tmp_jail}
167		echo ${_jail_id} > /var/run/jail_${_jail}.id
168	done
169	rmdir ${_tmp_dir}
170	echo '.'
171}
172
173jail_stop()
174{
175	echo -n 'Stopping jails:'
176	for _jail in ${jail_list}
177	do
178		if [ -f /var/run/jail_${_jail}.id ]; then
179			_jail_id=$(cat /var/run/jail_${_jail}.id)
180			if [ ! -z ${_jail_id} ]; then
181				init_variables $_jail
182				killall -j ${_jail_id} -TERM > /dev/null 2>&1
183				jail_umount_fs
184				echo -n " $jail_hostname"
185			fi
186			rm /var/run/jail_${_jail}.id
187		else
188			echo "cannot stop jail ${_jail}. No jail id in /var/run"
189		fi
190	done
191	echo '.'
192}
193
194load_rc_config $name
195[ -n "$2" ] && jail_list="$2"
196run_rc_command "$1"
197