Index: usr.sbin/service/service.sh =================================================================== --- usr.sbin/service/service.sh +++ usr.sbin/service/service.sh @@ -49,39 +49,50 @@ echo '' } -accepted_argstr='jehlrRv' +accepted_argstr='j:ehlrRv' + +# If running outside of a jail, check if -j was used. +if [ `/sbin/sysctl -n security.jail.jailed` -eq 0 ]; then + # Only deal with the -j option here. If found, JAIL is set to OPTARG + # and OPTIND is left untouched. This is fine as we only parse getopts + # once in this scenario. + # The whole $* will be passed along to jexec(8) unmodified. + while getopts ${accepted_argstr} COMMAND_LINE_ARGUMENT ; do + case "${COMMAND_LINE_ARGUMENT}" in + j) JAIL="${OPTARG}" ;; + esac + done -# Only deal with the -j option here. If found, JAIL is set and the opt and -# arg are shifted out. OPTIND is left untouched. We strip the -j option out -# here because we'll be proxying this invocation through to the jail via -# jls(8) instead of handling it ourselves. -while getopts ${accepted_argstr} COMMAND_LINE_ARGUMENT ; do - case "${COMMAND_LINE_ARGUMENT}" in - j) JAIL="$2" ; shift ; shift ;; - esac -done + # If -j was provided, then we pass everthing along to jexec(8) and + # execute service(8) within the named JAIL. Provided that the jail + # actually exists, as checked by jls(8). + # We do this so that if the jail does exist, we can then return the + # exit code of jexec(8) and it should be the exit code of whatever ran + # inside the jail. + # There is a race condition here in that the jail might exist at + # jls(8) time and be gone by jexec(8) time, but it shouldn't be a big + # deal. + if [ -n "$JAIL" ]; then + /usr/sbin/jls -j "$JAIL" 2>/dev/null >/dev/null + if [ $? -ne 0 ]; then + echo "Jail '$JAIL' does not exist." + exit 1 + fi -# If -j was provided, then we pass everthing along to the jexec command -# and execute `service` within the named JAIL. Provided that the jail -# actually exists, as checked by `jls`. -# We do this so that if the jail does exist, we can then return the exit -# code of `jexec` and it should be the exit code of whatever ran in the jail. -# There is a race condition here in that the jail might exist at `jls` time -# and be gone by `jexec` time, but it shouldn't be a big deal. -if [ -n "$JAIL" ]; then - /usr/sbin/jls -j "$JAIL" 2>/dev/null >/dev/null - if [ $? -ne 0 ]; then - echo "Jail '$JAIL' does not exist." - exit 1 + /usr/sbin/jexec -l "$JAIL" /usr/sbin/service $* + exit $? fi - /usr/sbin/jexec -l "$JAIL" /usr/sbin/service $* - exit $? + # Reset OPTIND if we are not executing inside a jail as we're about to + # parse getopts for a second time. + OPTIND=1 fi -OPTIND=1 +# If we get to this point with a -j argument, execution is happening inside a +# jail. The -j argument is not used beyond this point. while getopts ${accepted_argstr} COMMAND_LINE_ARGUMENT ; do case "${COMMAND_LINE_ARGUMENT}" in + j) JAIL=jopt ;; e) ENABLED=eopt ;; h) usage ; exit 0 ;; l) LIST=lopt ;;