From ae8581a2c565708fd6d33baac6af19f45abdff9c Mon Sep 17 00:00:00 2001 From: ajacoutot Date: Thu, 26 May 2022 11:27:03 +0000 Subject: [PATCH] Introduce a new daemon_execdir variable for changing to a specified directory before running rc_rcexec. Based on an proposal from openbsd.tech at aisha.cc ok robert@ abieber@ --- etc/rc.d/amd | 7 ++----- etc/rc.d/rc.subr | 20 ++++++++++++++------ share/man/man8/rc.d.8 | 6 ++++-- share/man/man8/rc.subr.8 | 14 ++++++++++---- usr.sbin/rcctl/rcctl.8 | 8 +++++--- usr.sbin/rcctl/rcctl.sh | 32 ++++++++++++++++++++++---------- 6 files changed, 57 insertions(+), 30 deletions(-) diff --git a/etc/rc.d/amd b/etc/rc.d/amd index dbfb3d92503..39df91c26dd 100644 --- a/etc/rc.d/amd +++ b/etc/rc.d/amd @@ -1,8 +1,9 @@ #!/bin/ksh # -# $OpenBSD: amd,v 1.10 2022/05/21 12:42:21 ajacoutot Exp $ +# $OpenBSD: amd,v 1.11 2022/05/26 11:27:03 ajacoutot Exp $ daemon="/usr/sbin/amd" +daemon_execdir="/etc/amd" . /etc/rc.d/rc.subr @@ -15,8 +16,4 @@ rc_pre() { daemon_flags="${daemon_flags} $(print -rn -- $(< ${amd_master}))" } -rc_start() { - rc_exec "cd /etc/amd; ${daemon} ${daemon_flags}" -} - rc_cmd $1 diff --git a/etc/rc.d/rc.subr b/etc/rc.d/rc.subr index 3ad058c56cd..ef2b6d6f49b 100644 --- a/etc/rc.d/rc.subr +++ b/etc/rc.d/rc.subr @@ -1,6 +1,6 @@ -# $OpenBSD: rc.subr,v 1.153 2022/05/21 10:50:09 ajacoutot Exp $ +# $OpenBSD: rc.subr,v 1.154 2022/05/26 11:27:03 ajacoutot Exp $ # -# Copyright (c) 2010, 2011, 2014-2021 Antoine Jacoutot +# Copyright (c) 2010, 2011, 2014-2022 Antoine Jacoutot # Copyright (c) 2010, 2011 Ingo Schwarze # Copyright (c) 2010, 2011, 2014 Robert Nagy # @@ -49,7 +49,7 @@ _rc_parse_conf() { while IFS=' ' read -r _l; do [[ $_l == [!#=]*=* ]] || continue _key=${_l%%*([[:blank:]])=*} - [[ $_key == *_@(flags|logger|rtable|timeout|user) ]] || + [[ $_key == *_@(execdir|flags|logger|rtable|timeout|user) ]] || [[ " ${_allowed_keys[*]} " == *" $_key "* ]] || continue [[ $_key == "" ]] && continue @@ -114,14 +114,17 @@ _rc_write_runfile() { [ -d ${_RC_RUNDIR} ] || mkdir -p ${_RC_RUNDIR} && cat >${_RC_RUNFILE} <&1 | - logger -ip ${daemon_logger} -t ${_name}}" + ${_rcexec} "${daemon_logger:+set -o pipefail; } \ + ${daemon_execdir:+cd ${daemon_execdir} && } \ + $@ \ + ${daemon_logger:+ 2>&1 | + logger -ip ${daemon_logger} -t ${_name}}" } rc_start() { @@ -317,6 +323,7 @@ _rc_do _rc_parse_conf rc_reload_signal=${rc_reload_signal:=HUP} rc_stop_signal=${rc_stop_signal:=TERM} +eval _rcexecdir=\${${_name}_execdir} eval _rcflags=\${${_name}_flags} eval _rclogger=\${${_name}_logger} eval _rcrtable=\${${_name}_rtable} @@ -334,6 +341,7 @@ getcap -f /etc/login.conf.d/${_name}:/etc/login.conf ${_name} 1>/dev/null 2>&1 & [ -n "${_RC_FORCE}" -o "$1" != "start" ] && [ X"${_rcflags}" = X"NO" ] && unset _rcflags +[ -n "${_rcexecdir}" ] && daemon_execdir=${_rcexecdir} [ -n "${_rcflags}" ] && daemon_flags=${_rcflags} [ -n "${_rclogger}" ] && daemon_logger=${_rclogger} [ -n "${_rcrtable}" ] && daemon_rtable=${_rcrtable} @@ -347,7 +355,7 @@ if [ -n "${_RC_DEBUG}" ]; then fi readonly daemon_class -unset _rcflags _rclogger _rcrtable _rctimeout _rcuser +unset _rcexecdir _rcflags _rclogger _rcrtable _rctimeout _rcuser # the shell will strip the quotes from daemon_flags when starting a daemon; # make sure pexp matches the process (i.e. doesn't include the quotes) pexp="$(eval echo ${daemon}${daemon_flags:+ ${daemon_flags}})" diff --git a/share/man/man8/rc.d.8 b/share/man/man8/rc.d.8 index cc1574f35ad..581743629b7 100644 --- a/share/man/man8/rc.d.8 +++ b/share/man/man8/rc.d.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: rc.d.8,v 1.37 2021/11/09 11:43:47 kn Exp $ +.\" $OpenBSD: rc.d.8,v 1.38 2022/05/26 11:27:03 ajacoutot Exp $ .\" .\" Copyright (c) 2021 Antoine Jacoutot .\" Copyright (c) 2011 Robert Nagy, Antoine Jacoutot, Ingo Schwarze @@ -25,7 +25,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: November 9 2021 $ +.Dd $Mdocdate: May 26 2022 $ .Dt RC.D 8 .Os .Sh NAME @@ -102,6 +102,8 @@ variables when starting a daemon. The following can be overridden by site-specific values provided in .Xr rc.conf.local 8 : .Bl -tag -width daemon_timeout -offset indent +.It Ar daemon Ns _execdir +Run daemon from the specified directory. .It Ar daemon Ns _flags Additional arguments to call the daemon with. These will be appended to any mandatory arguments already contained in the diff --git a/share/man/man8/rc.subr.8 b/share/man/man8/rc.subr.8 index 51fe5de956d..42295e62dd3 100644 --- a/share/man/man8/rc.subr.8 +++ b/share/man/man8/rc.subr.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: rc.subr.8,v 1.43 2022/05/21 14:11:39 ajacoutot Exp $ +.\" $OpenBSD: rc.subr.8,v 1.44 2022/05/26 11:27:03 ajacoutot Exp $ .\" .\" Copyright (c) 2021 Antoine Jacoutot .\" Copyright (c) 2011 Robert Nagy, Antoine Jacoutot, Ingo Schwarze @@ -25,7 +25,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: May 21 2022 $ +.Dd $Mdocdate: May 26 2022 $ .Dt RC.SUBR 8 .Os .Sh NAME @@ -189,10 +189,11 @@ call .Ic rc_reload . .El .It Ic rc_exec -Execute process using +Execute argument using .Xr su 1 according to .Va daemon_class , +.Va daemon_execdir , .Va daemon_user , .Va daemon_rtable and @@ -256,6 +257,9 @@ script itself and uses that. If no such login class exists then .Dq daemon will be used. +.It Va daemon_execdir +Change to this directory before running +.Ic rc_exec . .It Va daemon_flags Arguments to call the daemon with. .It Ar daemon Ns _logger @@ -337,6 +341,7 @@ in an script, if the .Cm check action needs root privileges. +.El .Pp All .Va daemon_* @@ -347,6 +352,7 @@ Global defaults are provided by .Nm : .Bd -literal -offset indent daemon_class=daemon +daemon_execdir= daemon_flags= daemon_logger= daemon_rtable=0 @@ -367,6 +373,7 @@ As noted in site-specific values provided in .Xr rc.conf.local 8 for +.Va daemon_execdir , .Va daemon_flags , .Va daemon_logger , .Va daemon_rtable , @@ -375,7 +382,6 @@ and .Va daemon_user will override those defaults. .El -.El .Sh FILES .Bl -tag -width Ds .It Pa /etc/rc.d/ diff --git a/usr.sbin/rcctl/rcctl.8 b/usr.sbin/rcctl/rcctl.8 index ba8e7994572..31c5ec19005 100644 --- a/usr.sbin/rcctl/rcctl.8 +++ b/usr.sbin/rcctl/rcctl.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: rcctl.8,v 1.39 2022/04/01 10:13:35 ajacoutot Exp $ +.\" $OpenBSD: rcctl.8,v 1.40 2022/05/26 11:27:03 ajacoutot Exp $ .\" .\" Copyright (c) 2014 Antoine Jacoutot .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: April 1 2022 $ +.Dd $Mdocdate: May 26 2022 $ .Dt RCCTL 8 .Os .Sh NAME @@ -62,6 +62,7 @@ The following commands are available .Ar variable can be one of .Cm class , +.Cm execdir , .Cm flags , .Cm logger , .Cm rtable , @@ -206,7 +207,8 @@ flags: # rcctl set apmd flags -A # rcctl get apmd apmd_class=daemon -apmd_flags=-A +apmd_execdir= +apmd_flags=NO apmd_logger= apmd_rtable=0 apmd_timeout=30 diff --git a/usr.sbin/rcctl/rcctl.sh b/usr.sbin/rcctl/rcctl.sh index e36248a89a6..9d72fa6944f 100644 --- a/usr.sbin/rcctl/rcctl.sh +++ b/usr.sbin/rcctl/rcctl.sh @@ -1,8 +1,8 @@ #!/bin/ksh # -# $OpenBSD: rcctl.sh,v 1.112 2022/02/10 16:57:33 robert Exp $ +# $OpenBSD: rcctl.sh,v 1.113 2022/05/26 11:27:03 ajacoutot Exp $ # -# Copyright (c) 2014, 2015-2021 Antoine Jacoutot +# Copyright (c) 2014, 2015-2022 Antoine Jacoutot # Copyright (c) 2014 Ingo Schwarze # # Permission to use, copy, modify, and distribute this software for any @@ -258,8 +258,8 @@ svc_get() [ -n "${_svc}" ] || return local _status=0 _val _var=$2 - local daemon_class daemon_flags daemon_logger daemon_rtable - local daemon_timeout daemon_user + local daemon_class daemon_execdir daemon_flags daemon_logger + local daemon_rtable daemon_timeout daemon_user if svc_is_special ${_svc}; then daemon_flags="$(eval echo \${${_svc}})" @@ -279,6 +279,12 @@ svc_get() [ -z "${daemon_class}" ] && \ daemon_class="$(svc_getdef ${_svc} class)" fi + if [ -z "${_var}" -o "${_var}" = "execdir" ]; then + [ -z "${daemon_execdir}" ] && \ + daemon_execdir="$(eval echo \"\${${_svc}_execdir}\")" + [ -z "${daemon_execdir}" ] && \ + daemon_execdir="$(svc_getdef ${_svc} execdir)" + fi if [[ -z ${_var} || ${_var} == @(flags|status) ]]; then [ -z "${daemon_flags}" ] && \ daemon_flags="$(eval echo \"\${${_svc}_flags}\")" @@ -324,6 +330,7 @@ svc_get() echo "${_svc}=${daemon_flags}" else echo "${_svc}_class=${daemon_class}" + echo "${_svc}_execdir=${daemon_execdir}" echo "${_svc}_flags=${daemon_flags}" echo "${_svc}_logger=${daemon_logger}" echo "${_svc}_rtable=${daemon_rtable}" @@ -341,8 +348,8 @@ svc_getdef() [ -n "${_svc}" ] || return local _status=0 _val _var=$2 - local daemon_class daemon_flags daemon_logger daemon_rtable - local daemon_timeout daemon_user + local daemon_class daemon_execdir daemon_flags daemon_logger + local daemon_rtable daemon_timeout daemon_user if svc_is_special ${_svc}; then # unconditionally parse: we always output flags and/or status @@ -382,6 +389,7 @@ svc_getdef() echo "${_svc}=${daemon_flags}" else echo "${_svc}_class=${daemon_class}" + echo "${_svc}_execdir=${daemon_execdir}" echo "${_svc}_flags=${daemon_flags}" echo "${_svc}_logger=${daemon_logger}" echo "${_svc}_rtable=${daemon_rtable}" @@ -403,7 +411,7 @@ svc_rm() ( svc_getdef ${_svc} status ) && \ echo "${_svc}=NO" >>${_TMP_RCCONF} else - grep -Ev "^${_svc}_(flags|logger|rtable|timeout|user).*=" \ + grep -Ev "^${_svc}_(execdir|flags|logger|rtable|timeout|user).*=" \ /etc/rc.conf.local >${_TMP_RCCONF} ( svc_getdef ${_svc} status ) && \ echo "${_svc}_flags=NO" >>${_TMP_RCCONF} @@ -456,6 +464,10 @@ svc_set() fi if [ -n "${_args}" ]; then + if [ "${_var}" = "execdir" ]; then + [[ ${_args%${_args#?}} == / ]] || + rcctl_err "\"${_args}\" must be an absolute path" + fi if [ "${_var}" = "logger" ]; then logger -p "${_args}" /dev/null 2>&1 || rcctl_err "unknown priority name: \"${_args}\"" @@ -539,13 +551,13 @@ case ${action} in rcctl_err "service ${svc} does not exist" 2 if [ -n "${var}" ]; then [ "${svc}" = "all" ] && usage - [[ ${var} != @(class|flags|logger|rtable|status|timeout|user) ]] && usage + [[ ${var} != @(class|execdir|flags|logger|rtable|status|timeout|user) ]] && usage if svc_is_meta ${svc}; then [ "${var}" != "status" ] && \ rcctl_err "/etc/rc.d/${svc} is a meta script, cannot \"${action} ${var}\"" fi if svc_is_special ${svc}; then - [[ ${var} == @(class|logger|rtable|timeout|user) ]] && \ + [[ ${var} == @(class|execdir|logger|rtable|timeout|user) ]] && \ rcctl_err "\"${svc}\" is a special variable, cannot \"${action} ${var}\"" fi fi @@ -561,7 +573,7 @@ case ${action} in svc_is_avail ${svc} || \ rcctl_err "service ${svc} does not exist" 2 fi - [[ ${var} != @(class|flags|logger|rtable|status|timeout|user) ]] && usage + [[ ${var} != @(class|execdir|flags|logger|rtable|status|timeout|user) ]] && usage svc_is_meta ${svc} && [ "${var}" != "status" ] && \ rcctl_err "/etc/rc.d/${svc} is a meta script, cannot \"${action} ${var}\"" [[ ${var} = flags && ${args} = NO ]] && \ -- 2.20.1