Deleted Added
full compact
jail (256281) jail (256387)
1#!/bin/sh
2#
1#!/bin/sh
2#
3# $FreeBSD: stable/10/etc/rc.d/jail 256256 2013-10-10 09:32:27Z hrs $
3# $FreeBSD: stable/10/etc/rc.d/jail 256387 2013-10-12 17:46:13Z hrs $
4#
5
6# PROVIDE: jail
7# REQUIRE: LOGIN FILESYSTEMS
8# BEFORE: securelevel
9# KEYWORD: nojail shutdown
10
11. /etc/rc.subr
12
13name="jail"
14rcvar="jail_enable"
15
16start_cmd="jail_start"
17start_postcmd="jail_warn"
18stop_cmd="jail_stop"
19config_cmd="jail_config"
20console_cmd="jail_console"
21status_cmd="jail_status"
22extra_commands="config console status"
23: ${jail_conf:=/etc/jail.conf}
24: ${jail_program:=/usr/sbin/jail}
25: ${jail_consolecmd:=/bin/sh}
26: ${jail_jexec:=/usr/sbin/jexec}
27: ${jail_jls:=/usr/sbin/jls}
28
29need_dad_wait=
30
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.
37extract_var()
38{
39 local i _j _name _param _num _def _name1 _name2
40 _j=$1
41 _name=$2
42 _param=$3
43 _num=$4
44 _def=$5
45
46 case $_num in
47 YN)
48 _name1=jail_${_j}_${_name}
49 _name2=jail_${_name}
50 eval $_name1=\"\${$_name1:-\${$_name2:-$_def}}\"
51 if checkyesno $_name1; then
52 echo " $_param = 1;"
53 else
54 echo " $_param = 0;"
55 fi
56 ;;
57 NY)
58 _name1=jail_${_j}_${_name}
59 _name2=jail_${_name}
60 eval $_name1=\"\${$_name1:-\${$_name2:-$_def}}\"
61 if checkyesno $_name1; then
62 echo " $_param = 0;"
63 else
64 echo " $_param = 1;"
65 fi
66 ;;
67 [0-9]*)
68 i=$_num
69 while : ; do
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\";"
75 else
76 break;
77 fi
78 i=$(($i + 1))
79 done
80 ;;
81 *)
82 _name1=jail_${_j}_${_name}
83 _name2=jail_${_name}
84 eval _tmpargs=\"\${$_name1:-\${$_name2:-$_def}}\"
85 if [ -n "$_tmpargs" ]; then
86 echo " $_param = \"$_tmpargs\";"
87 fi
88 ;;
89 esac
90}
91
92# parse_options _j
93# Parse options and create a temporary configuration file if necessary.
94#
95parse_options()
96{
97 local _j
98 _j=$1
99
100 _confwarn=0
101 if [ -z "$_j" ]; then
102 warn "parse_options: you must specify a jail"
103 return
104 fi
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
111 _conf="$_jconf"
112 return 0
113 elif [ -r "$jail_conf" ]; then
114 _conf="$jail_conf"
115 return 0
116 else
117 warn "Invalid configuration for $_j " \
118 "(no jail.conf, no hostname, or no path). " \
119 "Jail $_j was ignored."
120 fi
121 return 1
122 fi
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."
127 return 1
128 fi
129 _conf=/var/run/jail.${_j}.conf
130 #
131 # To relieve confusion, show a warning message.
132 #
133 _confwarn=1
134 if [ -r "$jail_conf" -o -r "$_jconf" ]; then
135 warn "$_conf is created and used for jail $_j."
136 fi
137 /usr/bin/install -m 0644 -o root -g wheel /dev/null $_conf || return 1
138
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}"
146 _exec_stop=""
147 else
148 # flexible execution
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"
153 fi
154 fi
155 fi
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}}\"
159 (
160 date +"# Generated by rc.d/jail at %Y-%m-%d %H:%M:%S"
161 echo "$_j {"
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
167 alias=0
168 while : ; do
169 eval _x=\"\$jail_${_jail}_ip_multi${alias}\"
170 [ -z "$_x" ] && break
171
172 jail_handle_ips_option $_x $_interface
173 alias=$(($alias + 1))
174 done
175 case $need_dad_wait in
176 1)
177 # Sleep to let DAD complete before
178 # starting services.
179 echo " exec.start += \"sleep " \
180 $(($(${SYSCTL_N} net.inet6.ip6.dad_count) + 1)) \
181 "\";"
182 ;;
183 esac
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
188 else
189 echo " vnet;"
190 extract_var $_j vnet_interface vnet.interface - ""
191 fi
192
193 echo " exec.clean;"
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 ""
200
201 echo " exec.start += \"$_exec_start\";"
202 extract_var $_j exec_afterstart exec.start 1 ""
203 echo " exec.stop = \"$_exec_stop\";"
204
205 extract_var $_j consolelog exec.consolelog - \
206 /var/log/jail_${_j}_console.log
207
208 eval : \${jail_${_j}_devfs_enable:=${jail_devfs_enable:-NO}}
209 if checkyesno jail_${_j}_devfs_enable; then
210 echo " mount.devfs;"
211 case $_ruleset in
212 "") ;;
213 [0-9]*) echo " devfs_ruleset = \"$_ruleset\";" ;;
214 devfsrules_jail)
215 # XXX: This is the default value,
216 # Let jail(8) to use the default because
217 # mount(8) only accepts an integer.
218 # This should accept a ruleset name.
219 ;;
220 *) warn "devfs_ruleset must be integer." ;;
221 esac
222 if [ -r $_fstab ]; then
223 echo " mount.fstab = \"$_fstab\";"
224 fi
225 fi
226
227 eval : \${jail_${_j}_fdescfs_enable:=${jail_fdescfs_enable:-NO}}
228 if checkyesno jail_${_j}_fdescfs_enable; then
4#
5
6# PROVIDE: jail
7# REQUIRE: LOGIN FILESYSTEMS
8# BEFORE: securelevel
9# KEYWORD: nojail shutdown
10
11. /etc/rc.subr
12
13name="jail"
14rcvar="jail_enable"
15
16start_cmd="jail_start"
17start_postcmd="jail_warn"
18stop_cmd="jail_stop"
19config_cmd="jail_config"
20console_cmd="jail_console"
21status_cmd="jail_status"
22extra_commands="config console status"
23: ${jail_conf:=/etc/jail.conf}
24: ${jail_program:=/usr/sbin/jail}
25: ${jail_consolecmd:=/bin/sh}
26: ${jail_jexec:=/usr/sbin/jexec}
27: ${jail_jls:=/usr/sbin/jls}
28
29need_dad_wait=
30
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.
37extract_var()
38{
39 local i _j _name _param _num _def _name1 _name2
40 _j=$1
41 _name=$2
42 _param=$3
43 _num=$4
44 _def=$5
45
46 case $_num in
47 YN)
48 _name1=jail_${_j}_${_name}
49 _name2=jail_${_name}
50 eval $_name1=\"\${$_name1:-\${$_name2:-$_def}}\"
51 if checkyesno $_name1; then
52 echo " $_param = 1;"
53 else
54 echo " $_param = 0;"
55 fi
56 ;;
57 NY)
58 _name1=jail_${_j}_${_name}
59 _name2=jail_${_name}
60 eval $_name1=\"\${$_name1:-\${$_name2:-$_def}}\"
61 if checkyesno $_name1; then
62 echo " $_param = 0;"
63 else
64 echo " $_param = 1;"
65 fi
66 ;;
67 [0-9]*)
68 i=$_num
69 while : ; do
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\";"
75 else
76 break;
77 fi
78 i=$(($i + 1))
79 done
80 ;;
81 *)
82 _name1=jail_${_j}_${_name}
83 _name2=jail_${_name}
84 eval _tmpargs=\"\${$_name1:-\${$_name2:-$_def}}\"
85 if [ -n "$_tmpargs" ]; then
86 echo " $_param = \"$_tmpargs\";"
87 fi
88 ;;
89 esac
90}
91
92# parse_options _j
93# Parse options and create a temporary configuration file if necessary.
94#
95parse_options()
96{
97 local _j
98 _j=$1
99
100 _confwarn=0
101 if [ -z "$_j" ]; then
102 warn "parse_options: you must specify a jail"
103 return
104 fi
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
111 _conf="$_jconf"
112 return 0
113 elif [ -r "$jail_conf" ]; then
114 _conf="$jail_conf"
115 return 0
116 else
117 warn "Invalid configuration for $_j " \
118 "(no jail.conf, no hostname, or no path). " \
119 "Jail $_j was ignored."
120 fi
121 return 1
122 fi
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."
127 return 1
128 fi
129 _conf=/var/run/jail.${_j}.conf
130 #
131 # To relieve confusion, show a warning message.
132 #
133 _confwarn=1
134 if [ -r "$jail_conf" -o -r "$_jconf" ]; then
135 warn "$_conf is created and used for jail $_j."
136 fi
137 /usr/bin/install -m 0644 -o root -g wheel /dev/null $_conf || return 1
138
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}"
146 _exec_stop=""
147 else
148 # flexible execution
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"
153 fi
154 fi
155 fi
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}}\"
159 (
160 date +"# Generated by rc.d/jail at %Y-%m-%d %H:%M:%S"
161 echo "$_j {"
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
167 alias=0
168 while : ; do
169 eval _x=\"\$jail_${_jail}_ip_multi${alias}\"
170 [ -z "$_x" ] && break
171
172 jail_handle_ips_option $_x $_interface
173 alias=$(($alias + 1))
174 done
175 case $need_dad_wait in
176 1)
177 # Sleep to let DAD complete before
178 # starting services.
179 echo " exec.start += \"sleep " \
180 $(($(${SYSCTL_N} net.inet6.ip6.dad_count) + 1)) \
181 "\";"
182 ;;
183 esac
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
188 else
189 echo " vnet;"
190 extract_var $_j vnet_interface vnet.interface - ""
191 fi
192
193 echo " exec.clean;"
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 ""
200
201 echo " exec.start += \"$_exec_start\";"
202 extract_var $_j exec_afterstart exec.start 1 ""
203 echo " exec.stop = \"$_exec_stop\";"
204
205 extract_var $_j consolelog exec.consolelog - \
206 /var/log/jail_${_j}_console.log
207
208 eval : \${jail_${_j}_devfs_enable:=${jail_devfs_enable:-NO}}
209 if checkyesno jail_${_j}_devfs_enable; then
210 echo " mount.devfs;"
211 case $_ruleset in
212 "") ;;
213 [0-9]*) echo " devfs_ruleset = \"$_ruleset\";" ;;
214 devfsrules_jail)
215 # XXX: This is the default value,
216 # Let jail(8) to use the default because
217 # mount(8) only accepts an integer.
218 # This should accept a ruleset name.
219 ;;
220 *) warn "devfs_ruleset must be integer." ;;
221 esac
222 if [ -r $_fstab ]; then
223 echo " mount.fstab = \"$_fstab\";"
224 fi
225 fi
226
227 eval : \${jail_${_j}_fdescfs_enable:=${jail_fdescfs_enable:-NO}}
228 if checkyesno jail_${_j}_fdescfs_enable; then
229 echo " mount += " \
230 "\"fdescfs ${_rootdir%/}/dev/fd fdescfs rw 0 0\";"
229 echo " mount.fdescfs;"
231 fi
232 eval : \${jail_${_j}_procfs_enable:=${jail_procfs_enable:-NO}}
233 if checkyesno jail_${_j}_procfs_enable; then
234 echo " mount += " \
235 "\"procfs ${_rootdir%/}/proc procfs rw 0 0\";"
236 fi
237
238 echo " ${_parameters};"
239
240 eval : \${jail_${_j}_mount_enable:=${jail_mount_enable:-NO}}
241 if checkyesno jail_${_j}_mount_enable; then
242 echo " allow.mount;" >> $_conf
243 fi
244
245 extract_var $_j set_hostname_allow allow.set_hostname YN NO
246 extract_var $_j sysvipc_allow allow.sysvipc YN NO
247 echo "}"
248 ) >> $_conf
249
250 return 0
251}
252
253# jail_extract_address argument iface
254# The second argument is the string from one of the _ip
255# or the _multi variables. In case of a comma separated list
256# only one argument must be passed in at a time.
257# The function alters the _type, _iface, _addr and _mask variables.
258#
259jail_extract_address()
260{
261 local _i _interface
262 _i=$1
263 _interface=$2
264
265 if [ -z "${_i}" ]; then
266 warn "jail_extract_address: called without input"
267 return
268 fi
269
270 # Check if we have an interface prefix given and split into
271 # iFace and rest.
272 case "${_i}" in
273 *\|*) # ifN|.. prefix there
274 _iface=${_i%%|*}
275 _r=${_i##*|}
276 ;;
277 *) _iface=""
278 _r=${_i}
279 ;;
280 esac
281
282 # In case the IP has no interface given, check if we have a global one.
283 _iface=${_iface:-${_interface}}
284
285 # Set address, cut off any prefix/netmask/prefixlen.
286 _addr=${_r}
287 _addr=${_addr%%[/ ]*}
288
289 # Theoretically we can return here if interface is not set,
290 # as we only care about the _mask if we call ifconfig.
291 # This is not done because we may want to santize IP addresses
292 # based on _type later, and optionally change the type as well.
293
294 # Extract the prefix/netmask/prefixlen part by cutting off the address.
295 _mask=${_r}
296 _mask=`expr "${_mask}" : "${_addr}\(.*\)"`
297
298 # Identify type {inet,inet6}.
299 case "${_addr}" in
300 *\.*\.*\.*) _type="inet" ;;
301 *:*) _type="inet6" ;;
302 *) warn "jail_extract_address: type not identified"
303 ;;
304 esac
305
306 # Handle the special /netmask instead of /prefix or
307 # "netmask xxx" case for legacy IP.
308 # We do NOT support shortend class-full netmasks.
309 if [ "${_type}" = "inet" ]; then
310 case "${_mask}" in
311 /*\.*\.*\.*) _mask=" netmask ${_mask#/}" ;;
312 *) ;;
313 esac
314
315 # In case _mask is still not set use /32.
316 _mask=${_mask:-/32}
317
318 elif [ "${_type}" = "inet6" ]; then
319 # In case _maske is not set for IPv6, use /64.
320 _mask=${_mask:-/64}
321 fi
322}
323
324# jail_handle_ips_option input iface
325# Handle a single argument imput which can be a comma separated
326# list of addresses (theoretically with an option interface and
327# prefix/netmask/prefixlen).
328#
329jail_handle_ips_option()
330{
331 local _x _type _i _iface
332 _x=$1
333 _iface=$2
334
335 if [ -z "${_x}" ]; then
336 # No IP given. This can happen for the primary address
337 # of each address family.
338 return
339 fi
340
341 # Loop, in case we find a comma separated list, we need to handle
342 # each argument on its own.
343 while [ ${#_x} -gt 0 ]; do
344 case "${_x}" in
345 *,*) # Extract the first argument and strip it off the list.
346 _i=`expr "${_x}" : '^\([^,]*\)'`
347 _x=`expr "${_x}" : "^[^,]*,\(.*\)"`
348 ;;
349 *) _i=${_x}
350 _x=""
351 ;;
352 esac
353
354 _type=""
355 _addr=""
356 _mask=""
357 jail_extract_address $_i $_iface
358
359 # make sure we got an address.
360 case $_addr in
361 "") continue ;;
362 *) ;;
363 esac
364
365 # Append address to list of addresses for the jail command.
366 case $_type in
367 inet)
368 echo " ip4.addr += \"${_addr}${_mask}\";"
369 ;;
370 inet6)
371 echo " ip6.addr += \"${_addr}${_mask}\";"
372 need_dad_wait=1
373 ;;
374 esac
375 done
376}
377
378jail_config()
379{
380 case $1 in
381 _ALL) return ;;
382 esac
383 for _jail in $@; do
384 if parse_options $_jail; then
385 echo "$_jail: parameters are in $_conf."
386 fi
387 done
388}
389
390jail_console()
391{
392 # One argument that is not _ALL.
393 case $#:$1 in
394 1:_ALL) err 3 "Specify a jail name." ;;
395 1:*) ;;
396 *) err 3 "Specify a jail name." ;;
397 esac
398 eval _cmd=\${jail_$1_consolecmd:-$jail_consolecmd}
399 $jail_jexec $1 $_cmd
400}
401
402jail_status()
403{
404
405 $jail_jls -N
406}
407
408jail_start()
409{
410 if [ $# = 0 ]; then
411 return
412 fi
413 echo -n 'Starting jails:'
414 case $1 in
415 _ALL)
416 echo -n ' '
417 command=$jail_program
418 rc_flags=$jail_flags
419 command_args="-f $jail_conf -c"
420 $command $rc_flags $command_args "*"
421 echo '.'
422 return
423 ;;
424 esac
425 _tmp=`mktemp -t jail` || exit 3
426 for _jail in $@; do
427 parse_options $_jail || continue
428
429 eval rc_flags=\${jail_${_j}_flags:-$jail_flags}
430 eval command=\${jail_${_j}_program:-$jail_program}
431 if checkyesno jail_parallel_start; then
432 command_args="-i -f $_conf -c $_jail &"
433 else
434 command_args="-i -f $_conf -c $_jail"
435 fi
436 if $command $rc_flags $command_args \
437 >> $_tmp 2>&1 </dev/null; then
438 echo -n " ${_hostname:-${_jail}}"
439 else
440 echo " cannot start jail \"${_hostname:-${jail}}\": "
230 fi
231 eval : \${jail_${_j}_procfs_enable:=${jail_procfs_enable:-NO}}
232 if checkyesno jail_${_j}_procfs_enable; then
233 echo " mount += " \
234 "\"procfs ${_rootdir%/}/proc procfs rw 0 0\";"
235 fi
236
237 echo " ${_parameters};"
238
239 eval : \${jail_${_j}_mount_enable:=${jail_mount_enable:-NO}}
240 if checkyesno jail_${_j}_mount_enable; then
241 echo " allow.mount;" >> $_conf
242 fi
243
244 extract_var $_j set_hostname_allow allow.set_hostname YN NO
245 extract_var $_j sysvipc_allow allow.sysvipc YN NO
246 echo "}"
247 ) >> $_conf
248
249 return 0
250}
251
252# jail_extract_address argument iface
253# The second argument is the string from one of the _ip
254# or the _multi variables. In case of a comma separated list
255# only one argument must be passed in at a time.
256# The function alters the _type, _iface, _addr and _mask variables.
257#
258jail_extract_address()
259{
260 local _i _interface
261 _i=$1
262 _interface=$2
263
264 if [ -z "${_i}" ]; then
265 warn "jail_extract_address: called without input"
266 return
267 fi
268
269 # Check if we have an interface prefix given and split into
270 # iFace and rest.
271 case "${_i}" in
272 *\|*) # ifN|.. prefix there
273 _iface=${_i%%|*}
274 _r=${_i##*|}
275 ;;
276 *) _iface=""
277 _r=${_i}
278 ;;
279 esac
280
281 # In case the IP has no interface given, check if we have a global one.
282 _iface=${_iface:-${_interface}}
283
284 # Set address, cut off any prefix/netmask/prefixlen.
285 _addr=${_r}
286 _addr=${_addr%%[/ ]*}
287
288 # Theoretically we can return here if interface is not set,
289 # as we only care about the _mask if we call ifconfig.
290 # This is not done because we may want to santize IP addresses
291 # based on _type later, and optionally change the type as well.
292
293 # Extract the prefix/netmask/prefixlen part by cutting off the address.
294 _mask=${_r}
295 _mask=`expr "${_mask}" : "${_addr}\(.*\)"`
296
297 # Identify type {inet,inet6}.
298 case "${_addr}" in
299 *\.*\.*\.*) _type="inet" ;;
300 *:*) _type="inet6" ;;
301 *) warn "jail_extract_address: type not identified"
302 ;;
303 esac
304
305 # Handle the special /netmask instead of /prefix or
306 # "netmask xxx" case for legacy IP.
307 # We do NOT support shortend class-full netmasks.
308 if [ "${_type}" = "inet" ]; then
309 case "${_mask}" in
310 /*\.*\.*\.*) _mask=" netmask ${_mask#/}" ;;
311 *) ;;
312 esac
313
314 # In case _mask is still not set use /32.
315 _mask=${_mask:-/32}
316
317 elif [ "${_type}" = "inet6" ]; then
318 # In case _maske is not set for IPv6, use /64.
319 _mask=${_mask:-/64}
320 fi
321}
322
323# jail_handle_ips_option input iface
324# Handle a single argument imput which can be a comma separated
325# list of addresses (theoretically with an option interface and
326# prefix/netmask/prefixlen).
327#
328jail_handle_ips_option()
329{
330 local _x _type _i _iface
331 _x=$1
332 _iface=$2
333
334 if [ -z "${_x}" ]; then
335 # No IP given. This can happen for the primary address
336 # of each address family.
337 return
338 fi
339
340 # Loop, in case we find a comma separated list, we need to handle
341 # each argument on its own.
342 while [ ${#_x} -gt 0 ]; do
343 case "${_x}" in
344 *,*) # Extract the first argument and strip it off the list.
345 _i=`expr "${_x}" : '^\([^,]*\)'`
346 _x=`expr "${_x}" : "^[^,]*,\(.*\)"`
347 ;;
348 *) _i=${_x}
349 _x=""
350 ;;
351 esac
352
353 _type=""
354 _addr=""
355 _mask=""
356 jail_extract_address $_i $_iface
357
358 # make sure we got an address.
359 case $_addr in
360 "") continue ;;
361 *) ;;
362 esac
363
364 # Append address to list of addresses for the jail command.
365 case $_type in
366 inet)
367 echo " ip4.addr += \"${_addr}${_mask}\";"
368 ;;
369 inet6)
370 echo " ip6.addr += \"${_addr}${_mask}\";"
371 need_dad_wait=1
372 ;;
373 esac
374 done
375}
376
377jail_config()
378{
379 case $1 in
380 _ALL) return ;;
381 esac
382 for _jail in $@; do
383 if parse_options $_jail; then
384 echo "$_jail: parameters are in $_conf."
385 fi
386 done
387}
388
389jail_console()
390{
391 # One argument that is not _ALL.
392 case $#:$1 in
393 1:_ALL) err 3 "Specify a jail name." ;;
394 1:*) ;;
395 *) err 3 "Specify a jail name." ;;
396 esac
397 eval _cmd=\${jail_$1_consolecmd:-$jail_consolecmd}
398 $jail_jexec $1 $_cmd
399}
400
401jail_status()
402{
403
404 $jail_jls -N
405}
406
407jail_start()
408{
409 if [ $# = 0 ]; then
410 return
411 fi
412 echo -n 'Starting jails:'
413 case $1 in
414 _ALL)
415 echo -n ' '
416 command=$jail_program
417 rc_flags=$jail_flags
418 command_args="-f $jail_conf -c"
419 $command $rc_flags $command_args "*"
420 echo '.'
421 return
422 ;;
423 esac
424 _tmp=`mktemp -t jail` || exit 3
425 for _jail in $@; do
426 parse_options $_jail || continue
427
428 eval rc_flags=\${jail_${_j}_flags:-$jail_flags}
429 eval command=\${jail_${_j}_program:-$jail_program}
430 if checkyesno jail_parallel_start; then
431 command_args="-i -f $_conf -c $_jail &"
432 else
433 command_args="-i -f $_conf -c $_jail"
434 fi
435 if $command $rc_flags $command_args \
436 >> $_tmp 2>&1 </dev/null; then
437 echo -n " ${_hostname:-${_jail}}"
438 else
439 echo " cannot start jail \"${_hostname:-${jail}}\": "
441 tail +2 $_tmp
440 cat $_tmp
442 fi
443 rm -f $_tmp
444 done
445 echo '.'
446}
447
448jail_stop()
449{
450 if [ $# = 0 ]; then
451 return
452 fi
453 echo -n 'Stopping jails:'
454 case $1 in
455 _ALL)
456 echo -n ' '
457 command=$jail_program
458 rc_flags=$jail_flags
459 command_args="-f $jail_conf -r"
460 $command $rc_flags $command_args "*"
461 echo '.'
462 return
463 ;;
464 esac
465 for _jail in $@; do
466 parse_options $_jail || continue
467 eval command=\${jail_${_j}_program:-$jail_program}
468 if $command -q -f $_conf -r $_jail; then
469 echo -n " ${_hostname:-${_jail}}"
470 fi
471 done
472 echo '.'
473}
474
475jail_warn()
476{
477
478 # To relieve confusion, show a warning message.
479 case $_confwarn in
480 1) warn "Per-jail configuration via jail_* variables " \
481 "is obsolete. Please consider to migrate to $jail_conf."
482 ;;
483 esac
484}
485
486load_rc_config $name
487case $# in
4881) run_rc_command $@ ${jail_list:-_ALL} ;;
489*) run_rc_command $@ ;;
490esac
441 fi
442 rm -f $_tmp
443 done
444 echo '.'
445}
446
447jail_stop()
448{
449 if [ $# = 0 ]; then
450 return
451 fi
452 echo -n 'Stopping jails:'
453 case $1 in
454 _ALL)
455 echo -n ' '
456 command=$jail_program
457 rc_flags=$jail_flags
458 command_args="-f $jail_conf -r"
459 $command $rc_flags $command_args "*"
460 echo '.'
461 return
462 ;;
463 esac
464 for _jail in $@; do
465 parse_options $_jail || continue
466 eval command=\${jail_${_j}_program:-$jail_program}
467 if $command -q -f $_conf -r $_jail; then
468 echo -n " ${_hostname:-${_jail}}"
469 fi
470 done
471 echo '.'
472}
473
474jail_warn()
475{
476
477 # To relieve confusion, show a warning message.
478 case $_confwarn in
479 1) warn "Per-jail configuration via jail_* variables " \
480 "is obsolete. Please consider to migrate to $jail_conf."
481 ;;
482 esac
483}
484
485load_rc_config $name
486case $# in
4871) run_rc_command $@ ${jail_list:-_ALL} ;;
488*) run_rc_command $@ ;;
489esac