Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 420165 | Differences between
and this patch

Collapse All | Expand All

(-)a/conf.d/Makefile (-1 / +1 lines)
Lines 13-19 endif Link Here
13
MK=	../mk
13
MK=	../mk
14
include ${MK}/os.mk
14
include ${MK}/os.mk
15
15
16
CONF-FreeBSD=	ipfw moused powerd rarpd savecore syscons
16
CONF-FreeBSD=	ipfw jail moused powerd rarpd savecore syscons
17
17
18
CONF-Linux=	consolefont dmesg hwclock keymaps killprocs modules
18
CONF-Linux=	consolefont dmesg hwclock keymaps killprocs modules
19
19
(-)a/conf.d/jail (+62 lines)
Line 0 Link Here
1
# Example jail config file.
2
# This is the place to define settings for jails you wish to control
3
# with the jail init script.
4
5
# Global Settings:
6
# This group of settings affects all jails.
7
8
# List the jails you wish to control separated by spaces.
9
#jail_list="jail1 jail2"
10
11
# Document this variable.
12
# What does it do? Show a commented default setting.
13
#jail_set_hostname_allow="YES"
14
15
# Document this variable.
16
# What does it do? Show a commented default setting.
17
#jail_socket_unixiproute_only
18
19
# Document this variable.
20
# What does it do? Show a commented default setting.
21
#jail_sysvipc_allow
22
23
# jail-specific settings:
24
# These variables must be set for each jail.
25
# The example is for jail1 listed above, but you must repeat these
26
# settings for each jail unless you want to use the defaults.
27
28
# Document this variable.
29
# What does it do? Show a commented default setting below.
30
#jail_jail1_devfs_enable="YES"
31
32
# Document this variable.
33
# What does it do? Show a commented default setting below.
34
#jail_jail1_fdescfs_enable="YES"
35
36
# Document this variable.
37
# What does it do? Show a commented default setting below.
38
#jail_jail1_exec_start="/sbin/rc default"
39
40
# Document this variable.
41
# What does it do? Show a commented default setting below.
42
#jail_jail1_exec_stop="/sbin/rc shutdown"
43
44
# Document this variable.
45
# What does it do? Show a commented default setting below.
46
#jail_jail1_rootdir="/mnt/linux"
47
48
# Document this variable.
49
# What does it do? Show a commented default setting below.
50
#jail_jail1_hostname="linux"
51
52
# Document this variable.
53
# What does it do? Show a commented default setting below.
54
#jail_jail1_ip="192.168.1.252"
55
56
# Document this variable.
57
# What does it do? Show a commented default setting below.
58
#jail_jail1_fstab="/etc/jail/fstab.linux" # for linprocfs
59
60
# Document this variable.
61
# What does it do? Show a commented default setting below.
62
#jail_jail1_flags="-l -u root"
(-)a/init.d/Makefile (-1 / +1 lines)
Lines 18-24 include ${MK}/os.mk Link Here
18
SRCS-FreeBSD=	hostid.in moused.in newsyslog.in pf.in rarpd.in rc-enabled.in \
18
SRCS-FreeBSD=	hostid.in moused.in newsyslog.in pf.in rarpd.in rc-enabled.in \
19
		rpcbind.in savecore.in syslogd.in
19
		rpcbind.in savecore.in syslogd.in
20
# These are FreeBSD specific
20
# These are FreeBSD specific
21
SRCS-FreeBSD+=	adjkerntz.in devd.in dumpon.in encswap.in ipfw.in \
21
SRCS-FreeBSD+=	adjkerntz.in devd.in dumpon.in encswap.in ipfw.in jail.in \
22
		mixer.in nscd.in powerd.in syscons.in
22
		mixer.in nscd.in powerd.in syscons.in
23
23
24
SRCS-Linux=	devfs.in dmesg.in hwclock.in consolefont.in keymaps.in \
24
SRCS-Linux=	devfs.in dmesg.in hwclock.in consolefont.in keymaps.in \
(-)a/init.d/jail.in (-1 / +885 lines)
Line 0 Link Here
0
- 
1
#!@PREFIX@/sbin/runscript
2
# Copyright 1992-2012 FreeBSD Project
3
# Released under the 2-clause BSD license
4
5
depend()
6
{
7
	after net
8
}
9
10
# devfs_rulesets_from_file file
11
#	Reads a set of devfs commands from file, and creates
12
#	the specified rulesets with their rules. Returns non-zero
13
#	if there was an eerroror.
14
#
15
devfs_rulesets_from_file()
16
{
17
	local file _eerror _me
18
	file="$1"
19
	_me="devfs_rulesets_from_file"
20
	_eerror=0
21
22
	if [ -z "$file" ]; then
23
		ewarn "$_me: you must specify a file"
24
		return 1
25
	fi
26
	if [ ! -e "$file" ]; then
27
		veinfo "$_me: no such file ($file)"
28
		return 0
29
	fi
30
	veinfo "reading rulesets from file ($file)"
31
	{ while read line
32
	do
33
		case $line in
34
		\#*)
35
			continue
36
			;;
37
		\[*\]*)
38
			rulenum=`expr "$line" : "\[.*=\([0-9]*\)\]"`
39
			if [ -z "$rulenum" ]; then
40
				ewarn "$_me: cannot extract rule number ($line)"
41
				_eerror=1
42
				break
43
			fi
44
			rulename=`expr "$line" : "\[\(.*\)=[0-9]*\]"`
45
			if [ -z "$rulename" ]; then
46
				ewarn "$_me: cannot extract rule name ($line)"
47
				_eerror=1
48
				break;
49
			fi
50
			eval $rulename=\$rulenum
51
			veinfo "found ruleset: $rulename=$rulenum"
52
			if ! /sbin/devfs rule -s $rulenum delset; then
53
				_eerror=1
54
				break
55
			fi
56
			;;
57
		*)
58
			rulecmd="${line%%"\#*"}"
59
			# evaluate the command incase it includes
60
			# other rules
61
			if [ -n "$rulecmd" ]; then
62
				veinfo "adding rule ($rulecmd)"
63
				if ! eval /sbin/devfs rule -s $rulenum $rulecmd
64
				then
65
					_eerror=1
66
					break
67
				fi
68
			fi
69
			;;
70
		esac
71
		if [ $_eerror -ne 0 ]; then
72
			veinfo "eerroror in $_me"
73
			break
74
		fi
75
	done } < $file
76
	return $_eerror
77
}
78
79
# devfs_init_rulesets
80
#	Initializes rulesets from configuration files. Returns
81
#	non-zero if there was an eerroror.
82
#
83
devfs_init_rulesets()
84
{
85
	local file _me
86
	_me="devfs_init_rulesets"
87
88
	# Go through this only once
89
	if [ -n "$devfs_rulesets_init" ]; then
90
		veinfo "$_me: devfs rulesets already initialized"
91
		return
92
	fi
93
	for file in $devfs_rulesets; do
94
		if ! devfs_rulesets_from_file $file; then
95
			ewarn "$_me: could not read rules from $file"
96
			return 1
97
		fi
98
	done
99
	devfs_rulesets_init=1
100
	veinfo "$_me: devfs rulesets initialized"
101
	return 0
102
}
103
104
# devfs_set_ruleset ruleset [dir]
105
#	Sets the default ruleset of dir to ruleset. The ruleset argument
106
#	must be a ruleset name as specified in devfs.rules(5) file.
107
#	Returns non-zero if it could not set it successfully.
108
#
109
devfs_set_ruleset()
110
{
111
	local devdir rs _me
112
	[ -n "$1" ] && eval rs=\$$1 || rs=
113
	[ -n "$2" ] && devdir="-m "$2"" || devdir=
114
	_me="devfs_set_ruleset"
115
116
	if [ -z "$rs" ]; then
117
		ewarn "$_me: you must specify a ruleset number"
118
		return 1
119
	fi
120
	veinfo "$_me: setting ruleset ($rs) on mount-point (${devdir#-m })"
121
	if ! /sbin/devfs $devdir ruleset $rs; then
122
		ewarn "$_me: unable to set ruleset $rs to ${devdir#-m }"
123
		return 1
124
	fi
125
	return 0
126
}
127
128
# devfs_domount dir [ruleset]
129
#	Mount devfs on dir. If ruleset is specified it is set
130
#	on the mount-point. It must also be a ruleset name as specified
131
#	in a devfs.rules(5) file. Returns 0 on success.
132
#
133
devfs_domount()
134
{
135
	local devdir rs _me
136
	devdir="$1"
137
	[ -n "$2" ] && rs=$2 || rs=
138
	_me="devfs_domount()"
139
140
	if [ -z "$devdir" ]; then
141
		ewarn "$_me: you must specify a mount-point"
142
		return 1
143
	fi
144
	veinfo "$_me: mount-point is ($devdir), ruleset is ($rs)"
145
	if ! mount -t devfs dev "$devdir"; then
146
		ewarn "$_me: Unable to mount devfs on $devdir"
147
		return 1
148
	fi
149
	if [ -n "$rs" ]; then
150
		devfs_init_rulesets
151
		devfs_set_ruleset $rs $devdir
152
		devfs -m $devdir rule applyset
153
	fi
154
	return 0
155
}
156
157
# devfs_mount_jail dir [ruleset]
158
#	Mounts a devfs file system appropriate for jails
159
#	on the directory dir. If ruleset is specified, the ruleset
160
#	it names will be used instead.  If present, ruleset must
161
#	be the name of a ruleset as defined in a devfs.rules(5) file.
162
#	This function returns non-zero if an eerroror occurs.
163
#
164
devfs_mount_jail()
165
{
166
	local jdev rs _me
167
	jdev="$1"
168
	[ -n "$2" ] && rs=$2 || rs="devfsrules_jail"
169
	_me="devfs_mount_jail"
170
171
	devfs_init_rulesets
172
	if ! devfs_domount "$jdev" $rs; then
173
		ewarn "$_me: devfs was not mounted on $jdev"
174
		return 1
175
	fi
176
	return 0
177
}
178
179
# init_variables _j
180
#	Initialize the various jail variables for jail _j.
181
#
182
init_variables()
183
{
184
	_j="$1"
185
186
	if [ -z "$_j" ]; then
187
		ewarn "init_variables: you must specify a jail"
188
		return
189
	fi
190
191
	eval _rootdir=\"\$jail_${_j}_rootdir\"
192
	_devdir="${_rootdir}/dev"
193
	_fdescdir="${_devdir}/fd"
194
	_procdir="${_rootdir}/proc"
195
	eval _hostname=\"\$jail_${_j}_hostname\"
196
	eval _ip=\"\$jail_${_j}_ip\"
197
	eval _interface=\"\${jail_${_j}_interface:-${jail_interface}}\"
198
	eval _exec=\"\$jail_${_j}_exec\"
199
200
	i=0
201
	while : ; do
202
		eval _exec_prestart${i}=\"\${jail_${_j}_exec_prestart${i}:-\${jail_exec_prestart${i}}}\"
203
		[ -z "$(eval echo \"\$_exec_prestart${i}\")" ] && break
204
		i=$((i + 1))
205
	done
206
207
	eval _exec_start=\"\${jail_${_j}_exec_start:-${jail_exec_start}}\"
208
209
	i=1
210
	while : ; do
211
		eval _exec_afterstart${i}=\"\${jail_${_j}_exec_afterstart${i}:-\${jail_exec_afterstart${i}}}\"
212
		[ -z "$(eval echo \"\$_exec_afterstart${i}\")" ] &&  break
213
		i=$((i + 1))
214
	done
215
216
	i=0
217
	while : ; do
218
		eval _exec_poststart${i}=\"\${jail_${_j}_exec_poststart${i}:-\${jail_exec_poststart${i}}}\"
219
		[ -z "$(eval echo \"\$_exec_poststart${i}\")" ] && break
220
		i=$((i + 1))
221
	done
222
223
	i=0
224
	while : ; do
225
		eval _exec_prestop${i}=\"\${jail_${_j}_exec_prestop${i}:-\${jail_exec_prestop${i}}}\"
226
		[ -z "$(eval echo \"\$_exec_prestop${i}\")" ] && break
227
		i=$((i + 1))
228
	done
229
230
	eval _exec_stop=\"\${jail_${_j}_exec_stop:-${jail_exec_stop}}\"
231
232
	i=0
233
	while : ; do
234
		eval _exec_poststop${i}=\"\${jail_${_j}_exec_poststop${i}:-\${jail_exec_poststop${i}}}\"
235
		[ -z "$(eval echo \"\$_exec_poststop${i}\")" ] && break
236
		i=$((i + 1))
237
	done
238
239
	if [ -n "${_exec}" ]; then
240
		#   simple/backward-compatible execution
241
		_exec_start="${_exec}"
242
		_exec_stop=""
243
	else
244
		#   flexible execution
245
		if [ -z "${_exec_start}" ]; then
246
			_exec_start="/bin/sh /etc/rc"
247
			if [ -z "${_exec_stop}" ]; then
248
				_exec_stop="/bin/sh /etc/rc.shutdown"
249
			fi
250
		fi
251
	fi
252
253
	# The default jail ruleset will be used by rc.subr if none is specified.
254
	eval _ruleset=\"\${jail_${_j}_devfs_ruleset:-${jail_devfs_ruleset}}\"
255
	eval _devfs=\"\${jail_${_j}_devfs_enable:-${jail_devfs_enable}}\"
256
	[ -z "${_devfs}" ] && _devfs="NO"
257
	eval _fdescfs=\"\${jail_${_j}_fdescfs_enable:-${jail_fdescfs_enable}}\"
258
	[ -z "${_fdescfs}" ] && _fdescfs="NO"
259
	eval _procfs=\"\${jail_${_j}_procfs_enable:-${jail_procfs_enable}}\"
260
	[ -z "${_procfs}" ] && _procfs="NO"
261
262
	eval _mount=\"\${jail_${_j}_mount_enable:-${jail_mount_enable}}\"
263
	[ -z "${_mount}" ] && _mount="NO"
264
	# "/etc/fstab.${_j}" will be used for {,u}mount(8) if none is specified.
265
	eval _fstab=\"\${jail_${_j}_fstab:-${jail_fstab}}\"
266
	[ -z "${_fstab}" ] && _fstab="/etc/fstab.${_j}"
267
	eval _flags=\"\${jail_${_j}_flags:-${jail_flags}}\"
268
	[ -z "${_flags}" ] && _flags="-l -U root"
269
	eval _consolelog=\"\${jail_${_j}_consolelog:-${jail_consolelog}}\"
270
	[ -z "${_consolelog}" ] && _consolelog="/var/log/jail_${_j}_console.log"
271
	eval _fib=\"\${jail_${_j}_fib:-${jail_fib}}\"
272
273
	# Debugging aid
274
	#
275
	veinfo "$_j devfs enable: $_devfs"
276
	veinfo "$_j fdescfs enable: $_fdescfs"
277
	veinfo "$_j procfs enable: $_procfs"
278
	veinfo "$_j mount enable: $_mount"
279
	veinfo "$_j hostname: $_hostname"
280
	veinfo "$_j ip: $_ip"
281
	jail_show_addresses ${_j}
282
	veinfo "$_j interface: $_interface"
283
	veinfo "$_j fib: $_fib"
284
	veinfo "$_j root: $_rootdir"
285
	veinfo "$_j devdir: $_devdir"
286
	veinfo "$_j fdescdir: $_fdescdir"
287
	veinfo "$_j procdir: $_procdir"
288
	veinfo "$_j ruleset: $_ruleset"
289
	veinfo "$_j fstab: $_fstab"
290
291
	i=0
292
	while : ; do
293
		eval out=\"\${_exec_prestart${i}:-''}\"
294
		if [ -z "$out" ]; then
295
			break
296
		fi
297
		veinfo "$_j exec pre-start #${i}: ${out}"
298
		i=$((i + 1))
299
	done
300
301
	veinfo "$_j exec start: $_exec_start"
302
303
	i=1
304
	while : ; do
305
		eval out=\"\${_exec_afterstart${i}:-''}\"
306
307
		if [ -z "$out" ]; then
308
			break;
309
		fi
310
311
		veinfo "$_j exec after start #${i}: ${out}"
312
		i=$((i + 1))
313
	done
314
315
	i=0
316
	while : ; do
317
		eval out=\"\${_exec_poststart${i}:-''}\"
318
		if [ -z "$out" ]; then
319
			break
320
		fi
321
		veinfo "$_j exec post-start #${i}: ${out}"
322
		i=$((i + 1))
323
	done
324
325
	i=0
326
	while : ; do
327
		eval out=\"\${_exec_prestop${i}:-''}\"
328
		if [ -z "$out" ]; then
329
			break
330
		fi
331
		veinfo "$_j exec pre-stop #${i}: ${out}"
332
		i=$((i + 1))
333
	done
334
335
	veinfo "$_j exec stop: $_exec_stop"
336
337
	i=0
338
	while : ; do
339
		eval out=\"\${_exec_poststop${i}:-''}\"
340
		if [ -z "$out" ]; then
341
			break
342
		fi
343
		veinfo "$_j exec post-stop #${i}: ${out}"
344
		i=$((i + 1))
345
	done
346
347
	veinfo "$_j flags: $_flags"
348
	veinfo "$_j consolelog: $_consolelog"
349
350
	if [ -z "${_hostname}" ]; then
351
		eerror 3 "$name: No hostname has been defined for ${_j}"
352
	fi
353
	if [ -z "${_rootdir}" ]; then
354
		eerror 3 "$name: No root directory has been defined for ${_j}"
355
	fi
356
}
357
358
# set_sysctl rc_knob mib msg
359
#	If the mib sysctl is set according to what rc_knob
360
#	specifies, this function does nothing. However if
361
#	rc_knob is set differently than mib, then the mib
362
#	is set accordingly and msg is displayed followed by
363
#	an '=" sign and the word 'YES' or 'NO'.
364
#
365
set_sysctl()
366
{
367
	_knob="$1"
368
	_mib="$2"
369
	_msg="$3"
370
371
	SYSCTL="@PREFIX@/sbin/sysctl"
372
	_current=`${SYSCTL} -n $_mib 2>/dev/null`
373
	if yesno $_knob ; then
374
		if [ "$_current" -ne 1 ]; then
375
			einfo "${_msg}=YES"
376
			${SYSCTL} 1>/dev/null ${_mib}=1
377
		fi
378
	else
379
		if [ "$_current" -ne 0 ]; then
380
			einfo "${_msg}=NO"
381
			${SYSCTL} 1>/dev/null ${_mib}=0
382
		fi
383
	fi
384
}
385
386
# is_current_mountpoint()
387
#	Is the directory mount point for a currently mounted file
388
#	system?
389
#
390
is_current_mountpoint()
391
{
392
	local _dir _dir2
393
394
	_dir=$1
395
396
	_dir=`echo $_dir | sed -Ee 's#//+#/#g' -e 's#/$##'`
397
	[ ! -d "${_dir}" ] && return 1
398
	_dir2=`df ${_dir} | tail +2 | awk '{ print $6 }'`
399
	[ "${_dir}" = "${_dir2}" ]
400
	return $?
401
}
402
403
# is_symlinked_mountpoint()
404
#	Is a mount point, or any of its parent directories, a symlink?
405
#
406
is_symlinked_mountpoint()
407
{
408
	local _dir
409
410
	_dir=$1
411
412
	[ -L "$_dir" ] && return 0
413
	[ "$_dir" = "/" ] && return 1
414
	is_symlinked_mountpoint `dirname $_dir`
415
	return $?
416
}
417
418
# secure_umount
419
#	Try to unmount a mount point without being vulnerable to
420
#	symlink attacks.
421
#
422
secure_umount()
423
{
424
	local _dir
425
426
	_dir=$1
427
428
	if is_current_mountpoint ${_dir}; then
429
		umount -f ${_dir} >/dev/null 2>&1
430
	else
431
		ewarn "Nothing mounted on ${_dir} - not unmounting"
432
	fi
433
}
434
435
436
# jail_umount_fs
437
#	This function unmounts certain special filesystems in the
438
#	currently selected jail. The caller must call the init_variables()
439
#	routine before calling this one.
440
#
441
jail_umount_fs()
442
{
443
	local _device _mountpt _rest
444
445
	if yesno _fdescfs; then
446
		if [ -d "${_fdescdir}" ] ; then
447
			secure_umount ${_fdescdir}
448
		fi
449
	fi
450
	if yesno _devfs; then
451
		if [ -d "${_devdir}" ] ; then
452
			secure_umount ${_devdir}
453
		fi
454
	fi
455
	if yesno _procfs; then
456
		if [ -d "${_procdir}" ] ; then
457
			secure_umount ${_procdir}
458
		fi
459
	fi
460
	if yesno _mount; then
461
		[ -f "${_fstab}" ] || ewarn "${_fstab} does not exist"
462
		tail -r ${_fstab} | while read _device _mountpt _rest; do
463
			case ":${_device}" in
464
			:#* | :)
465
				continue
466
				;;
467
			esac
468
			secure_umount ${_mountpt}
469
		done
470
	fi
471
}
472
473
# jail_mount_fstab()
474
#	Mount file systems from a per jail fstab while trying to
475
#	secure against symlink attacks at the mount points.
476
#
477
#	If we are certain we cannot secure against symlink attacks we
478
#	do not mount all of the file systems (since we cannot just not
479
#	mount the file system with the problematic mount point).
480
#
481
#	The caller must call the init_variables() routine before
482
#	calling this one.
483
#
484
jail_mount_fstab()
485
{
486
	local _device _mountpt _rest
487
488
	while read _device _mountpt _rest; do
489
		case ":${_device}" in
490
		:#* | :)
491
			continue
492
			;;
493
		esac
494
		if is_symlinked_mountpoint ${_mountpt}; then
495
			ewarn "${_mountpt} has symlink as parent - not mounting from ${_fstab}"
496
			return
497
		fi
498
	done <${_fstab}
499
	mount -a -F "${_fstab}"
500
}
501
502
# jail_show_addresses jail
503
#	Debug print the input for the given _multi aliases
504
#	for a jail for init_variables().
505
#
506
jail_show_addresses()
507
{
508
	local _j _type alias
509
	_j="$1"
510
	alias=0
511
512
	if [ -z "${_j}" ]; then
513
		ewarn "jail_show_addresses: you must specify a jail"
514
		return
515
	fi
516
517
	while : ; do
518
		eval _addr=\"\$jail_${_j}_ip_multi${alias}\"
519
		if [ -n "${_addr}" ]; then
520
			veinfo "${_j} ip_multi${alias}: $_addr"
521
			alias=$((${alias} + 1))
522
		else
523
			break
524
		fi
525
	done
526
}
527
528
# jail_extract_address argument
529
#	The second argument is the string from one of the _ip
530
#	or the _multi variables. In case of a comma separated list
531
#	only one argument must be passed in at a time.
532
#	The function alters the _type, _iface, _addr and _mask variables.
533
#
534
jail_extract_address()
535
{
536
	local _i
537
	_i=$1
538
539
	if [ -z ${_i}" ]; then
540
		ewarn "jail_extract_address: called without input"
541
		return
542
	fi
543
544
	# Check if we have an interface prefix given and split into
545
	# iFace and rest.
546
	case "${_i}" in
547
	*\|*)	# ifN|.. prefix there
548
		_iface=${_i%%|*}
549
		_r=${_i##*|}
550
		;;
551
	*)	_iface=""
552
		_r=${_i}
553
		;;
554
	esac
555
556
	# In case the IP has no interface given, check if we have a global one.
557
	_iface=${_iface:-${_interface}}
558
559
	# Set address, cut off any prefix/netmask/prefixlen.
560
	_addr=${_r}
561
	_addr=${_addr%%[/ ]*}
562
563
	# Theoretically we can return here if interface is not set,
564
	# as we only care about the _mask if we call ifconfig.
565
	# This is not done because we may want to santize IP addresses
566
	# based on _type later, and optionally change the type as well.
567
568
	# Extract the prefix/netmask/prefixlen part by cutting off the address.
569
	_mask=${_r}
570
	_mask=`expr "${_mask}" : "${_addr}\(.*\)"`
571
572
	# Identify type {inet,inet6}.
573
	case "${_addr}" in
574
	*\.*\.*\.*)	_type="inet" ;;
575
	*:*)		_type="inet6" ;;
576
	*)		ewarn "jail_extract_address: type not identified"
577
			;;
578
	esac
579
580
	# Handle the special /netmask instead of /prefix or
581
	# "netmask xxx" case for legacy IP.
582
	# We do NOT support shortend class-full netmasks.
583
	if [ "${_type}" = "inet" ]; then
584
		case "${_mask}" in
585
		/*\.*\.*\.*)	_mask=" netmask ${_mask#/}" ;;
586
		*)		;;
587
		esac
588
589
		# In case _mask is still not set use /32.
590
		_mask=${_mask:-/32}
591
592
	elif [ "${_type}" = "inet6" ]; then
593
		# In case _maske is not set for IPv6, use /128.
594
		_mask=${_mask:-/128}
595
	fi
596
}
597
598
# jail_handle_ips_option {add,del} input
599
#	Handle a single argument imput which can be a comma separated
600
#	list of addresses (theoretically with an option interface and
601
#	prefix/netmask/prefixlen).
602
#
603
jail_handle_ips_option()
604
{
605
	local _x _action _type _i
606
	_action=$1
607
	_x=$2
608
609
	if [ -z "${_x}" ]; then
610
		# No IP given. This can happen for the primary address
611
		# of each address family.
612
		return
613
	fi
614
615
	# Loop, in case we find a comma separated list, we need to handle
616
	# each argument on its own.
617
	while [ ${#_x} -gt 0 ]; do
618
		case "${_x}" in
619
		*,*)	# Extract the first argument and strip it off the list.
620
			_i=`expr "${_x}" : '^\([^,]*\)'`
621
			_x=`expr "${_x}" : "^[^,]*,\(.*\)"`
622
			;;
623
		*)	_i=${_x}
624
			_x=""
625
			;;
626
		esac
627
628
		_type=""
629
		_iface=""
630
		_addr=""
631
		_mask=""
632
		jail_extract_address "${_i}"
633
634
		# make sure we got an address.
635
		case "${_addr}" in
636
		"")	continue ;;
637
		*)	;;
638
		esac
639
640
		# Append address to list of addresses for the jail command.
641
		case "${_addrl}" in
642
		"")	_addrl="${_addr}" ;;
643
		*)	_addrl="${_addrl},${_addr}" ;;
644
		esac
645
646
		# Configure interface alias if requested by a given interface
647
		# and if we could correctly parse everything.
648
		case "${_iface}" in
649
		"")	continue ;;
650
		esac
651
		case "${_type}" in
652
		inet)	;;
653
		inet6)	;;
654
		*)	ewarn "Could not determine address family.  Not going" \
655
			    "to ${_action} address '${_addr}' for ${_jail}."
656
			continue
657
			;;
658
		esac
659
		case "${_action}" in
660
		add)	ifconfig ${_iface} ${_type} ${_addr}${_mask} alias
661
			;;
662
		del)	# When removing the IP, ignore the _mask.
663
			ifconfig ${_iface} ${_type} ${_addr} -alias
664
			;;
665
		esac
666
	done
667
}
668
669
# jail_ips {add,del}
670
#	Extract the comma separated list of addresses and return them
671
#	for the jail command.
672
#	Handle more than one address via the _multi option as well.
673
#	If an interface is given also add/remove an alias for the
674
#	address with an optional netmask.
675
#
676
jail_ips()
677
{
678
	local _action
679
	_action=$1
680
681
	case "${_action}" in
682
	add)	;;
683
	del)	;;
684
	*)	ewarn "jail_ips: invalid action '${_action}'"
685
		return
686
		;;
687
	esac
688
689
	# Handle addresses.
690
	jail_handle_ips_option ${_action} "${_ip}"
691
	# Handle jail_xxx_ip_multi<N>
692
	alias=0
693
	while : ; do
694
		eval _x=\"\$jail_${_jail}_ip_multi${alias}\"
695
		case "${_x}" in
696
		"")	break ;;
697
		*)	jail_handle_ips_option ${_action} "${_x}"
698
			alias=$((${alias} + 1))
699
			;;
700
		esac
701
	done
702
}
703
704
start_pre()
705
{
706
	if yesno jail_parallel_start; then
707
		command_args='&'
708
	fi
709
}
710
711
start()
712
{
713
	ebegin 'Configuring jails:'
714
	set_sysctl jail_set_hostname_allow security.jail.set_hostname_allowed \
715
	    set_hostname_allow
716
	set_sysctl jail_socket_unixiproute_only \
717
	    security.jail.socket_unixiproute_only unixiproute_only
718
	set_sysctl jail_sysvipc_allow security.jail.sysvipc_allowed \
719
	    sysvipc_allow
720
	eend
721
722
	ebegin 'Starting jails:'
723
	_tmp_dir=`mktemp -d /tmp/jail.XXXXXXXX` || \
724
	    eerror 3 "$name: Can't create temp dir, exiting..."
725
	for _jail in ${jail_list}
726
	do
727
		init_variables $_jail
728
		if [ -f /var/run/jail_${_jail}.id ]; then
729
			ewarn " [${_hostname} already running (/var/run/jail_${_jail}.id exists)]"
730
			continue;
731
		fi
732
		_addrl=""
733
		jail_ips "add"
734
		if [ -n "${_fib}" ]; then
735
			_setfib="setfib -F '${_fib}'"
736
		else
737
			_setfib=""
738
		fi
739
		if yesno _mount; then
740
			einfo "Mounting fstab for jail ${_jail} (${_fstab})"
741
			if [ ! -f "${_fstab}" ]; then
742
				eerror 3 "$name: ${_fstab} does not exist"
743
			fi
744
			jail_mount_fstab
745
		fi
746
		if yesno _devfs; then
747
			# If devfs is already mounted here, skip it.
748
			df -t devfs "${_devdir}" >/dev/null
749
			if [ $? -ne 0 ]; then
750
				if is_symlinked_mountpoint ${_devdir}; then
751
					ewarn "${_devdir} has symlink as parent - not starting jail ${_jail}"
752
					continue
753
				fi
754
				einfo "Mounting devfs on ${_devdir}"
755
				devfs_mount_jail "${_devdir}" ${_ruleset}
756
				# Transitional symlink for old binaries
757
				if [ ! -L "${_devdir}/log" ]; then
758
					__pwd="`pwd`"
759
					cd "${_devdir}"
760
					ln -sf ../var/run/log log
761
					cd "$__pwd"
762
				fi
763
			fi
764
765
			# XXX - It seems symlinks don't work when there
766
			#	is a devfs(5) device of the same name.
767
			# Jail console output
768
			#	__pwd="`pwd`"
769
			#	cd "${_devdir}"
770
			#	ln -sf ../var/log/console console
771
			#	cd "$__pwd"
772
		fi
773
		if yesno _fdescfs; then
774
			if is_symlinked_mountpoint ${_fdescdir}; then
775
				ewarn "${_fdescdir} has symlink as parent, not mounting"
776
			else
777
				einfo "Mounting fdescfs on ${_fdescdir}"
778
				mount -t fdescfs fdesc "${_fdescdir}"
779
			fi
780
		fi
781
		if yesno _procfs; then
782
			if is_symlinked_mountpoint ${_procdir}; then
783
				ewarn "${_procdir} has symlink as parent, not mounting"
784
			else
785
				einfo "Mounting procfs onto ${_procdir}"
786
				if [ -d "${_procdir}" ] ; then
787
					mount -t procfs proc "${_procdir}"
788
				fi
789
			fi
790
		fi
791
		_tmp_jail=${_tmp_dir}/jail.$$
792
793
		i=0
794
		while : ; do
795
			eval out=\"\${_exec_prestart${i}:-''}\"
796
			[ -z "$out" ] && break
797
			${out}
798
			i=$((i + 1))
799
		done
800
801
		eval ${_setfib} jail ${_flags} -i ${_rootdir} ${_hostname} \
802
			\"${_addrl}\" ${_exec_start} > ${_tmp_jail} 2>&1 \
803
			</dev/null
804
805
		if [ "$?" -eq 0 ] ; then
806
			_jail_id=$(head -1 ${_tmp_jail})
807
			i=1
808
			while : ; do
809
				eval out=\"\${_exec_afterstart${i}:-''}\"
810
811
				if [ -z "$out" ]; then
812
					break;
813
				fi
814
815
				jexec "${_jail_id}" ${out}
816
				i=$((i + 1))
817
			done
818
819
			einfo "Started $_hostname"
820
			tail +2 ${_tmp_jail} >${_consolelog}
821
			echo ${_jail_id} > /var/run/jail_${_jail}.id
822
823
			i=0
824
			while : ; do
825
				eval out=\"\${_exec_poststart${i}:-''}\"
826
				[ -z "$out" ] && break
827
				${out}
828
				i=$((i + 1))
829
			done
830
		else
831
			jail_umount_fs
832
			jail_ips "del"
833
			eerror " cannot start jail \"${_jail}\": "
834
			tail +2 ${_tmp_jail}
835
		fi
836
		rm -f ${_tmp_jail}
837
	done
838
	rmdir ${_tmp_dir}
839
	eend
840
}
841
842
stop()
843
{
844
	ebegin 'Stopping jails:'
845
	for _jail in ${jail_list}
846
	do
847
		if [ -f "/var/run/jail_${_jail}.id" ]; then
848
			_jail_id=$(cat /var/run/jail_${_jail}.id)
849
			if [ ! -z "${_jail_id}" ]; then
850
				init_variables $_jail
851
852
				i=0
853
				while : ; do
854
					eval out=\"\${_exec_prestop${i}:-''}\"
855
					[ -z "$out" ] && break
856
					${out}
857
					i=$((i + 1))
858
				done
859
860
				if [ -n "${_exec_stop}" ]; then
861
					eval env -i /usr/sbin/jexec ${_jail_id} ${_exec_stop} \
862
						>> ${_consolelog} 2>&1
863
				fi
864
				killall -j ${_jail_id} -TERM > /dev/null 2>&1
865
				sleep 1
866
				killall -j ${_jail_id} -KILL > /dev/null 2>&1
867
				jail_umount_fs
868
				einfo "Stopped $_hostname"
869
870
				i=0
871
				while : ; do
872
					eval out=\"\${_exec_poststop${i}:-''}\"
873
					[ -z "$out" ] && break
874
					${out}
875
					i=$((i + 1))
876
				done
877
			fi
878
			jail_ips "del"
879
			rm /var/run/jail_${_jail}.id
880
		else
881
			ewarn " cannot stop jail ${_jail}. No jail id in /var/run"
882
		fi
883
	done
884
	eend
885
}

Return to bug 420165