[prev in list] [next in list] [prev in thread] [next in thread] 

List:       freebsd-jail
Subject:    Re: Auto-jailing of services - 2nd implementation
From:       Alexander Leidinger <Alexander () leidinger ! net>
Date:       2022-05-16 8:25:00
Message-ID: 20220516102500.Horde.Jmefw9B2HNSietK_UGUuNbn () webmail ! leidinger ! net
[Download RAW message or body]

This message is in MIME format and has been PGP signed.

[Attachment #2 (multipart/mixed)]
This message is in MIME format.


Quoting FreeBSD User <freebsd@walstatt-de.de> (from Sun, 15 May 2022  
12:49:06 +0200):

> On Sun, 03 Apr 2022 21:48:42 +0200
> Alexander Leidinger <Alexander@leidinger.net> wrote:
>
>> Hi,
>>
>> attached is a new implementation of service jails (auto-jailing of
>> services). This one now supports rc command prefixes (e.g. onestart)
>> and I tested it in nested jails. The benefit of auto-jailing services
>> is, that you can apply some restrictions to services (and what other
>> processes it may see). If your service requires access to network but
>> not sysvipc, and it doesn't run as root, it can be limited to network
>> access with or without raw sockets, filesystem-permitted files, and
>> doesn't see other processes on the system.
>>
>> For a few services I have added the required "svcj-config" in the
>> start scripts (e.g. network access for syslog by setting
>> syslogd_svj_options=net_basic).
>>
>> Possible svcj config options for service jails:
>> +				netv4)
>> +					_svcj_cmd_options="ip4=inherit
>> allow.reserved_ports ${_svcj_cmd_options}"
>> +					;;
>> +				netv6)
>> +					_svcj_cmd_options="ip6=inherit
>> allow.reserved_ports ${_svcj_cmd_options}"
>> +					;;
>> +				net_basic)
>> +					_svcj_cmd_options="ip4=inherit ip6=inherit
>> allow.reserved_ports ${_svcj_cmd_options}"
>> +					;;
>> +				net_raw)
>> +					_svcj_cmd_options="allow.raw_sockets
>> ${_svcj_cmd_options}"
>> +					;;
>> +				net_all)
>> +					_svcj_cmd_options="allow.socket_af
>> allow.raw_sockets allow.reserved_ports ip4=inherit ip6=inherit  
>> ${_svcj_cmd_options}"
>> +					;;
>> +				sysvipc)
>> +					_svcj_cmd_options="sysvmsg=inherit
>> sysvsem=inherit sysvshm=inherit  ${_svcj_cmd_options}"
>> +					;;
>> +				mlock)
>> +					_svcj_cmd_options="allow.mlock
>> ${_svcj_cmd_options}"
>> +					;;
>> +				vmm)
>> +					_svcj_cmd_options="allow.vmm
>> ${_svcj_cmd_options}"
>>
>> By setting syslogd_svcj="YES" in rc.conf your syslogd will be started
>> in a jail which inherits the full filesystem and the ipv4 and ipv6
>> addresses of the parent.
>>
>> It would be nice if interested people could experiment a little bit
>> with this, e.g. adding name_svcj_options="X Y" from above and
>> name_svcj="YES" into rc.conf and see if it works. Note, doing that for
>> sshd doesn't make sense in the generic case, it wouldn't see your
>> jails. It may make sense for services.
>>
>> Any kind of feedback and tested name_svcj_options submissions welcome...
>>
>> Bye,
>> Alexander.
>>
>
> Hello Alexander Leidinger,
>
> is this really interesting feature already part of recent CURRENT rc  
> subsystem or do I

No.

> have to "patch" CURRENT with the rc script provided by some place  
> first to obtain the
> functionality you are talking here about?

The patch was supposed to be attached to the mail you quoted. A more  
recent patch (now with docu in the rc.conf man page) is attached to  
this email (rc.subr + service command + man pages + a few services ->  
"grep diff svcjails.diff" for the list of OS services which can enable  
without research about the svcj_options). At least /etc/rc.subr and  
/usr/sbin/service need to be patched (respectively a  
buildworld+installworld).

> Thanks in advance and kind regards
>
> O. Hartmann
>
> p.s. would it be possible toput as service with a dedicated network  
> interfacing (say,
> jailed vnet/vlan, forinstance an asterisk service running on a small  
> router appliance, as
> we do in our projects?).

This will use the networking of the host. This is really automatic  
stuff, no additional network interface (all what the hosts sees is  
also available in the service-jail), no dedicated directory/filesystem  
area (as if it runs unjailed). All is used from the host. The  
additional security this provides is the limit of what the process is  
allowed to do in the kernel and the namespace isolation. So you could  
prevent sysvipc access. You could restrict it to ipv6 even if ipv4 is  
configured. You wouldn't see processes outside of the service jail  
even if running as root. If you want more advanced things, you need to  
create a jail on your own. Parts of what service jails do, could be  
done with capabilities (sometimes even with more restrictions), but  
this needs support inside the application for capabilities, whereas  
service jails do not need changes to the application itself.

If you want to put asterisk into one of my service jails, you would  
have to set the following in rc.conf:
   asterisk_enable="YES"
   asterisk_svcj_options="<see the rc.conf man page for the options in  
the SERVICE JAILS part>"
   asterisk_svcj="YES"
The asterisk_svcj_options part is supposed to be included in the rc  
script of asterisk (if/once this is committed to FreeBSD), but can be  
specified in rc.conf to override it if needed (or to test things). For  
asterisk I would assume at least asterisk_svcj_options="net_basic".

There's also a svcj_all_enable variable, but as long as not all  
services have a correct setting of their svcj_options, this will not  
do what you mean.

Bye,
Alexander.

-- 
http://www.Leidinger.net Alexander@Leidinger.net: PGP 0x8F31830F9F2772BF
http://www.FreeBSD.org    netchild@FreeBSD.org  : PGP 0x8F31830F9F2772BF

["svcjails.diff" (text/diff)]

diff --git a/libexec/rc/rc.d/auditdistd b/libexec/rc/rc.d/auditdistd
index 13cb5d5b69d..3218bd35755 100755
--- a/libexec/rc/rc.d/auditdistd
+++ b/libexec/rc/rc.d/auditdistd
@@ -19,4 +19,7 @@ required_files="/etc/security/${name}.conf"
 extra_commands="reload"
 
 load_rc_config $name
+
+: ${auditdistd_svcj_options:="net_basic"}
+
 run_rc_command "$1"
diff --git a/libexec/rc/rc.d/ftpd b/libexec/rc/rc.d/ftpd
index dc623ea5943..a04c7ce5ee2 100755
--- a/libexec/rc/rc.d/ftpd
+++ b/libexec/rc/rc.d/ftpd
@@ -23,4 +23,7 @@ ftpd_prestart()
 }
 
 load_rc_config $name
+
+: ${ftpd_svcj_options:="net_all"}
+
 run_rc_command "$1"
diff --git a/libexec/rc/rc.d/inetd b/libexec/rc/rc.d/inetd
index aa8ac20aeae..8cf7be5d91e 100755
--- a/libexec/rc/rc.d/inetd
+++ b/libexec/rc/rc.d/inetd
@@ -18,4 +18,7 @@ required_files="/etc/${name}.conf"
 extra_commands="reload"
 
 load_rc_config $name
+
+: ${inetd_svcj_options:="net_basic"}
+
 run_rc_command "$1"
diff --git a/libexec/rc/rc.d/kadmind b/libexec/rc/rc.d/kadmind
index 773b2d0e499..1bdd420e415 100755
--- a/libexec/rc/rc.d/kadmind
+++ b/libexec/rc/rc.d/kadmind
@@ -26,4 +26,7 @@ kadmind_start_precmd()
 }
 
 load_rc_config $name
+
+: ${kadmind_svcj_options:="net_basic"}
+
 run_rc_command "$1"
diff --git a/libexec/rc/rc.d/kdc b/libexec/rc/rc.d/kdc
index c2747ae08ca..11205d6e092 100755
--- a/libexec/rc/rc.d/kdc
+++ b/libexec/rc/rc.d/kdc
@@ -26,4 +26,7 @@ kdc_start_precmd()
 }
 
 load_rc_config $name
+
+: ${kdc_svcj_options:="net_basic"}
+
 run_rc_command "$1"
diff --git a/libexec/rc/rc.d/kpasswdd b/libexec/rc/rc.d/kpasswdd
index a2875bf1515..af7b7a6b9aa 100755
--- a/libexec/rc/rc.d/kpasswdd
+++ b/libexec/rc/rc.d/kpasswdd
@@ -26,4 +26,7 @@ kpasswdd_start_precmd()
 }
 
 load_rc_config $name
+
+: ${kapsswd_svcj_options:="net_basic"}
+
 run_rc_command "$1"
diff --git a/libexec/rc/rc.d/local_unbound b/libexec/rc/rc.d/local_unbound
index 19cb9a6c5c0..7436034495f 100755
--- a/libexec/rc/rc.d/local_unbound
+++ b/libexec/rc/rc.d/local_unbound
@@ -34,6 +34,7 @@ load_rc_config $name
 : ${local_unbound_anchor:=${local_unbound_workdir}/root.key}
 : ${local_unbound_forwarders:=}
 : ${local_unbound_tls:=}
+: ${local_unbound_svcj_options:="net_basic"}
 
 do_as_unbound()
 {
diff --git a/libexec/rc/rc.d/lpd b/libexec/rc/rc.d/lpd
index fc8180cb221..725adda9072 100755
--- a/libexec/rc/rc.d/lpd
+++ b/libexec/rc/rc.d/lpd
@@ -25,4 +25,7 @@ chkprintcap()
 }
 
 load_rc_config $name
+
+: ${lpd_svcj_options:="net_basic"}
+
 run_rc_command "$1"
diff --git a/libexec/rc/rc.d/sshd b/libexec/rc/rc.d/sshd
index 282f69f8e4c..9c3b5762579 100755
--- a/libexec/rc/rc.d/sshd
+++ b/libexec/rc/rc.d/sshd
@@ -81,4 +81,11 @@ sshd_precmd()
 }
 
 load_rc_config $name
+
+# sshd in a jail would not see other jails. As such exclude it from
+# svcj_all_enable="YES" by setting sshd_svcj to NO. This allows to
+# enable it in rc.conf.
+: ${sshd_svcj:="NO"}
+: ${sshd_svcj_options:="net_basic"}
+
 run_rc_command "$1"
diff --git a/libexec/rc/rc.d/syslogd b/libexec/rc/rc.d/syslogd
index 2351c086212..95d2b156b88 100755
--- a/libexec/rc/rc.d/syslogd
+++ b/libexec/rc/rc.d/syslogd
@@ -71,4 +71,7 @@ set_socketlist()
 	echo $_socketargs
 }
 load_rc_config $name
+
+: ${syslogd_svcj_options:="net_basic"}
+
 run_rc_command "$1"
diff --git a/libexec/rc/rc.subr b/libexec/rc/rc.subr
index dc4f49612c2..356fb0fea61 100644
--- a/libexec/rc/rc.subr
+++ b/libexec/rc/rc.subr
@@ -51,6 +51,9 @@ PROTECT="/usr/bin/protect"
 ID="/usr/bin/id"
 IDCMD="if [ -x $ID ]; then $ID -un; fi"
 PS="/bin/ps -ww"
+SERVICE=/usr/sbin/service
+JAIL_CMD=/usr/sbin/jail
+_svcj_generic_params="path=/ mount.nodevfs host=inherit"
 JID=0
 # rc_service provides the path to the service script that we are executing.
 # This is not being set here in an execution context, necessarily, so it's
@@ -368,6 +371,16 @@ _find_processes()
 		    $_procname|$_procnamebn|${_procnamebn}:|"(${_procnamebn})"|"[${_procnamebn}]")'
  fi
 
+	if checkyesno ${name}_svcj; then
+		JID=$(/usr/sbin/jls -j svcj-${name} jid)
+
+		case ${JID} in
+		''|*[!0-9]*)
+			# svj-jail doesn't exist, fallback to host-check
+			JID=0
+			;;
+		esac
+	fi
 	_proccheck="\
 		$PS 2>/dev/null -o pid= -o jid= -o command= $_psargs"' |
 		while read _npid _jid '"$_fp_args"'; do
@@ -959,6 +972,18 @@ run_rc_command()
 	_pidcmd=
 	_procname=${procname:-${command}}
 
+	# If a specifc jail has a specific svcj request, honor it (YES/NO).
+	# If not (variable empty), evaluate the global svcj catch-call.
+	# A global YES can be overriden by a specific NO, and a global NO is overriden
+	# by a specific YES.
+	eval _svcj=\$${name}_svcj
+	if [ -z "$_svcj" ]; then
+		_svcj=${svcj_all_enable}
+		if [ -z "$_svcj" ]; then
+			eval ${name}_svcj=NO
+		fi
+	fi
+
 					# setup pid check command
 	if [ -n "$_procname" ]; then
 		if [ -n "$pidfile" ]; then
@@ -994,7 +1019,7 @@ run_rc_command()
 	    _fib=\$${name}_fib		_env=\$${name}_env \
 	    _prepend=\$${name}_prepend	_login_class=\${${name}_login_class:-daemon} \
 	    _limits=\$${name}_limits    _oomprotect=\$${name}_oomprotect \
-	    _env_file=\$${name}_env_file
+	    _env_file=\$${name}_env_file _svcj_options=\$${name}_svcj_options
 
 	if [ -n "$_env_file" ] && [ -r "${_env_file}" ]; then	# load env from file
 		set -a
@@ -1008,6 +1033,42 @@ run_rc_command()
 		fi
 	fi
 
+	if [ -n "$_svcj_options" ]; then	# translate service jail options
+		_svcj_cmd_options=""
+
+		for _svcj_option in $_svcj_options; do
+			case "$_svcj_option" in
+				netv4)
+					_svcj_cmd_options="ip4=inherit allow.reserved_ports ${_svcj_cmd_options}"
+					;;
+				netv6)
+					_svcj_cmd_options="ip6=inherit allow.reserved_ports ${_svcj_cmd_options}"
+					;;
+				net_basic)
+					_svcj_cmd_options="ip4=inherit ip6=inherit allow.reserved_ports \
${_svcj_cmd_options}" +					;;
+				net_raw)
+					_svcj_cmd_options="allow.raw_sockets ${_svcj_cmd_options}"
+					;;
+				net_all)
+					_svcj_cmd_options="allow.socket_af allow.raw_sockets allow.reserved_ports \
ip4=inherit ip6=inherit ${_svcj_cmd_options}" +					;;
+				sysvipc)
+					_svcj_cmd_options="sysvmsg=inherit sysvsem=inherit sysvshm=inherit  \
${_svcj_cmd_options}" +					;;
+				mlock)
+					_svcj_cmd_options="allow.mlock ${_svcj_cmd_options}"
+					;;
+				vmm)
+					_svcj_cmd_options="allow.vmm ${_svcj_cmd_options}"
+					;;
+				*)
+					echo ${name}: unknown service jail option: $_svcj_option
+					;;
+			esac
+		done
+	fi
+
 	[ -z "$autoboot" ] && eval $_pidcmd	# determine the pid if necessary
 
 	for _elem in $_keywords; do
@@ -1053,9 +1114,50 @@ run_rc_command()
 			if [ -n "$_env" ]; then
 				eval "export -- $_env"
 			fi
-			_run_rc_precmd || return 1
-			_run_rc_doit "$_cmd $rc_extra_args" || return 1
-			_run_rc_postcmd
+
+			if [ "${_rc_svcj}" != jailing ]; then
+				_run_rc_precmd || return 1
+			fi
+			if ! checkyesno ${name}_svcj; then
+				_run_rc_doit "$_cmd $rc_extra_args" || return 1
+			else
+				case "$rc_arg" in
+				start)
+					if [ "${_rc_svcj}" != jailing ]; then
+						_return=1
+						$JAIL_CMD -c $_svcj_generic_params $_svcj_cmd_options \
+						    exec.start="${SERVICE} -E _rc_svcj=jailing ${name} ${_rc_prefix}start \
$rc_extra_args" \ +						    exec.stop="${SERVICE} -E _rc_svcj=jailing ${name} \
${_rc_prefix}stop $rc_extra_args" \ +						    \
exec.consolelog="/var/log/svcj_${name}_console.log" \ +						    name=svcj-${name} && \
_return=0 +					else
+						_run_rc_doit "$_cmd $rc_extra_args" || _return=1
+					fi
+					;;
+				stop)
+					if [ "${_rc_svcj}" != jailing ]; then
+						$SERVICE -E _rc_svcj=jailing -j svcj-${name} ${name} ${_rc_prefix}stop \
$rc_extra_args || _return=1 +						$JAIL_CMD -r svcj-${name} 2>/dev/null
+					else
+						_run_rc_doit "$_cmd $rc_extra_args" || _return=1
+					fi
+					;;
+				restart|status) ;; # no special case needed for svcj or handled somewhere else
+				*)
+if checkyesno ${name}_svcj; then
+echo XXX: check if \"$rc_arg\" needs to be executed in the jail or outside
+fi
+#					if [ "${_rc_svcj}" != jailing ]; then
+#						$SERVICE -j svcj-${name} ${name} ${_rc_prefix}${rc_arg} $rc_extra_args || \
_return=1 +#					else
+						_run_rc_doit "$_cmd $rc_extra_args" || _return=1
+#					fi
+					;;
+				esac
+			fi
+			if [ "${_rc_svcj}" != jailing ]; then
+				_run_rc_postcmd
+			fi
 			return $_return
 		fi
 
@@ -1113,9 +1215,21 @@ run_rc_command()
 				return 1
 			fi
 
-			if ! _run_rc_precmd; then
-				warn "failed precmd routine for ${name}"
-				return 1
+			if [ "${_rc_svcj}" != jailing ]; then
+				if ! _run_rc_precmd; then
+					warn "failed precmd routine for ${name}"
+					return 1
+				fi
+			fi
+
+			if checkyesno ${name}_svcj; then
+				if [ "${_rc_svcj}" != jailing ]; then
+					$JAIL_CMD -c $_svcj_generic_params $_svcj_cmd_options\
+					    exec.start="${SERVICE} -E _rc_svcj=jailing ${name} ${_rc_prefix}start \
$rc_extra_args" \ +					    exec.stop="${SERVICE} -E _rc_svcj=jailing ${name} \
${_rc_prefix}stop $rc_extra_args" \ +					    \
exec.consolelog="/var/log/svcj_${name}_console.log" \ +					    name=svcj-${name} || \
return 1 +				fi
 			fi
 
 					# setup the full command to run
@@ -1152,16 +1266,28 @@ $command $rc_flags $command_args"
 					# Prepend default limits
 			_doit="$_cd limits -C $_login_class $_limits $_doit"
 
+
+			local _really_run_it=true
+			if checkyesno ${name}_svcj; then
+				if [ "${_rc_svcj}" != jailing ]; then
+					_really_run_it=false
+				fi
+			fi
+
+			if [ "$_really_run_it" = true ]; then
 					# run the full command
 					#
-			if ! _run_rc_doit "$_doit"; then
-				warn "failed to start ${name}"
-				return 1
+				if ! _run_rc_doit "$_doit"; then
+					warn "failed to start ${name}"
+					return 1
+				fi
 			fi
 
+			if [ "${_rc_svcj}" != jailing ]; then
 					# finally, run postcmd
 					#
-			_run_rc_postcmd
+				_run_rc_postcmd
+			fi
 			;;
 
 		stop)
@@ -1183,6 +1309,11 @@ $command $rc_flags $command_args"
 					# and run postcmd.
 			wait_for_pids $rc_pid
 
+			if checkyesno ${name}_svcj; then
+				# remove service jail
+				$JAIL_CMD -r svcj-${name} 2>/dev/null
+			fi
+
 			_run_rc_postcmd
 			;;
 
@@ -1211,6 +1342,7 @@ $command $rc_flags $command_args"
 
 			_run_rc_precmd || return 1
 
+
 			# run those in a subshell to keep global variables
 			( run_rc_command ${_rc_prefix}stop $rc_extra_args )
 			( run_rc_command ${_rc_prefix}start $rc_extra_args )
diff --git a/share/man/man5/rc.conf.5 b/share/man/man5/rc.conf.5
index 01b09b1a59b..320e0c40765 100644
--- a/share/man/man5/rc.conf.5
+++ b/share/man/man5/rc.conf.5
@@ -239,6 +239,19 @@ such as PostgreSQL will not inherit the OOM killer protection.
 .It Ao Ar name Ac Ns Va _user
 .Pq Vt str
 Run the service under this user account.
+.It Ao Ar name Ac Ns Va _svcj
+.Pq Vt bool
+If set to
+.Dq Li YES ,
+auto-jail the service with inherited filesystem and other
+jail properties depending on
+.Ao Ar name Ac Ns Va _svcj_options .
+.It Ao Ar name Ac Ns Va _svcj_options
+.Pq Vt str
+A list of jail properties for the service.
+See
+.Sx SERVICE JAILS
+for a list of valid properties.
 .It Va apm_enable
 .Pq Vt bool
 If set to
@@ -372,6 +385,12 @@ is set to
 these are the flags to pass to the
 .Xr powerd 8
 daemon.
+.It Va svcj_all_enable
+Enable auto-jailing of all services which are not explicitely
+excluded.
+See
+.Sx SERVICE JAILS
+for more info.
 .It Va tmpmfs
 Controls the creation of a
 .Pa /tmp
@@ -4666,6 +4685,94 @@ Define the total number of seconds to wait for the zfskeys \
script  to unlock an encrypted dataset.
 The default is 10.
 .El
+.Sh SERVICE JAILS
+The service jails part of the rc system automatically puts a service
+into a jail.
+This jail inherits the filesystem and various other parts of the
+parent (if you allow child-jails in your jails, service jails
+can be used in jails) depending on the content of the
+.Ao Ar name Ac Ns Va _svcj_options
+variable.
+Typically this variable is set inside rc scripts, but it can be
+overriden in the rc config.
+Valid options for
+.Ao Ar name Ac Ns Va _svcj_options
+are:
+.Bl -tag -width indent-two
+.It netv4
+Inherit the IPv4 address and allows to open reserved ports.
+This can not be combined with
+.Pa netv6 .
+.It netv6
+Inherit the IPv6 address and allows to open reserved ports.
+This can not be combined with
+.Pa netv4 .
+.It net_basic
+Inherits the IPv4 and IPv6 addresses and allows to open
+reserved ports.
+.It net_raw
+Allow to open raw sockets. This option can be combined with
+.Pa netv4 ,
+.Pa netv6 ,
+.Pa net_basic .
+.It net_all
+Inherits the IPv4 and IPv6 addresses, allows to open reserved
+ports, allows to open raw sockets, and allows to open sockets
+of protocol stacks that have not had jail functionality added
+to them.
+.It sysvipc
+Allows access to SysV semaphores, SysV shared memory and
+SysV messages.
+.It mlock
+Allows to lock memory pages into the physical memory.
+.It vmm
+Allows access to
+.Xr vmm 4 .
+This option is only available when
+.Xr vmm 4
+is enabled in the kernel.
+.El
+
+All non-network options can be combined with all other options.
+
+If the
+.Ao Ar name Ac Ns Va _svcj
+variable is set to
+.Dq Li YES ,
+this particular service is started in a
+service jail named
+.Va svcj- Ns Ar name Ac .
+
+The
+.Va svcj_all_enable
+variable allows to enable service jails for all services of the
+system at once.
+Services which have
+.Ao Ar name Ac Ns Va _svcj
+set to
+.Dq Li NO
+are excluded.
+Some services may set
+.Ao Ar name Ac Ns Va _svcj
+to
+.Dq Li NO
+in the script to either prevent service jails for this
+service at all, or may set it to
+.Dq Li NO
+if it is not set in the
+rc config, to exclude it from
+.Va svcj_all_enable
+but allow to explicitely enable it.
+The sshd service for example would not see other jails, if
+it would run as a service jail.
+This may or may not be what is needed, and as such it is
+excluded from
+.Va svcj_all_enable
+but can be enabled via setting
+.Va sshd_svcj
+to
+.Dq Li YES .
+.El
 .Sh FILES
 .Bl -tag -width ".Pa /etc/defaults/rc.conf" -compact
 .It Pa /etc/defaults/rc.conf
diff --git a/usr.sbin/service/service.8 b/usr.sbin/service/service.8
index 9902ae3c857..c2be0e0af03 100644
--- a/usr.sbin/service/service.8
+++ b/usr.sbin/service/service.8
@@ -48,6 +48,7 @@
 .Nm
 .Op Fl j Ar jail
 .Op Fl v
+.Op Fl E Ar var=value
 .Ar script
 .Ar command
 .Sh DESCRIPTION
@@ -67,6 +68,13 @@ the scripts using various criteria.
 .Pp
 The options are as follows:
 .Bl -tag -width F1
+.It Fl E Ar var=value
+Set the environment variable
+.Ar var
+to the specified
+.Ar value
+before starting the script.
+This option can be used multiple times.
 .It Fl e
 List services that are enabled.
 The list of scripts to check is compiled using
@@ -117,6 +125,9 @@ to
 which is how they are set in
 .Pa /etc/rc
 at boot time.
+If the
+.Fl E
+option is used, the corresponding variable is set accordingly.
 .Sh EXIT STATUS
 .Ex -std
 .Sh EXAMPLES
@@ -126,6 +137,7 @@ command:
 .Bd -literal -offset -ident
 service named status
 service -j dns named status
+service -E LC_ALL=C.UTF-8 named start
 service -rv
 .Ed
 .Pp
diff --git a/usr.sbin/service/service.sh b/usr.sbin/service/service.sh
index 76cce580c5b..2f86d117fd1 100755
--- a/usr.sbin/service/service.sh
+++ b/usr.sbin/service/service.sh
@@ -37,10 +37,11 @@ usage () {
 	echo "${0##*/} [-j <jail name or id>] -e"
 	echo "${0##*/} [-j <jail name or id>] -R"
 	echo "${0##*/} [-j <jail name or id>] [-v] -l | -r"
-	echo "${0##*/} [-j <jail name or id>] [-v] <rc.d script> start|stop|etc."
+	echo "${0##*/} [-j <jail name or id>] [-v] [-E var=value] <rc.d script> \
start|stop|etc."  echo "${0##*/} -h"
 	echo ''
 	echo "-j	Perform actions within the named jail"
+	echo "-E n=val	Set variable n to val before executing the rc.d script"
 	echo '-e	Show services that are enabled'
 	echo "-R	Stop and start enabled $local_startup services"
 	echo "-l	List all scripts in /etc/rc.d and $local_startup"
@@ -49,9 +50,10 @@ usage () {
 	echo ''
 }
 
-while getopts 'j:ehlrRv' COMMAND_LINE_ARGUMENT ; do
+while getopts 'j:E:ehlrRv' COMMAND_LINE_ARGUMENT ; do
 	case "${COMMAND_LINE_ARGUMENT}" in
 	j)	JAIL="${OPTARG}" ;;
+	E)	VARS="${VARS} ${OPTARG}" ;;
 	e)	ENABLED=eopt ;;
 	h)	usage ; exit 0 ;;
 	l)	LIST=lopt ;;
@@ -72,6 +74,9 @@ if [ -n "${JAIL}" ]; then
 	[ -n "${RCORDER}" ] && args="${args} -r"
 	[ -n "${RESTART}" ] && args="${args} -R"
 	[ -n "${VERBOSE}" ] && args="${args} -v"
+	for var in ${VARS}; do
+		args="${args} -E ${var}"
+	done
 
 	# Call jexec(8) with the rebuild args and any positional args that
 	# were left in $@
@@ -171,7 +176,7 @@ cd /
 for dir in /etc/rc.d $local_startup; do
 	if [ -x "$dir/$script" ]; then
 		[ -n "$VERBOSE" ] && echo "$script is located in $dir"
-		exec env -i -L -/daemon HOME=/ PATH=/sbin:/bin:/usr/sbin:/usr/bin "$dir/$script" \
"$@" +		exec env -i -L -/daemon HOME=/ PATH=/sbin:/bin:/usr/sbin:/usr/bin ${VARS} \
"$dir/$script" "$@"  fi
 done
 


[Attachment #6 (application/pgp-signature)]

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic