#!/bin/bash set -euo pipefail MYNAME=$(basename "${0}") opts=$(getopt --name "$MYNAME" --options 'hVsEnu:g:D:' \ --longoptions 'help,version,shell,preserve-env,non-interactive,user:,group:,chdir:' -- "${@}") eval set -- "${opts}" U=0 G=0 SHELLARGS=() NOINTERACTIVEARGS=() ENVARGS=() WDIR="$PWD" while true; do case "$1" in -h|--help) echo "$MYNAME - execute a command as another user through systemd-run (no SUID binary involved except /usr/lib/polkit-1/polkit-agent-helper-1), recognizes set PATH in contrast to sudo" echo "usage: $MYNAME -h" echo "usage: $MYNAME [-En] [-D directory] [-g group] [-u user] [-s] [<command>]" echo echo "Options:" echo "-D, --chdir=directory change the working directory before running command" echo "-E, --preserve-env preserve user environment when running command (includes PATH in constrast to sudo)" echo "-g, --group=group run command as the specified group name or ID" echo "-h, --help display help message and exit" echo "-n, --non-interactive non-interactive mode, no prompts are used" echo "-s, --shell run shell as the target user; a command may also be specified" echo "-u, --user=user run command (or edit file) as specified user name or ID" echo "-V, --version display version information and exit" echo "-- stop processing command line arguments" echo "The following sudo options will not be supported: -A -B -C -e -h -i -K -k -l -p -r -S -t -U -v" echo "TODO: implement setting env vars by specifying VAR=VALUE" echo "TODO: implement --preserve-env=list" echo "TODO: implement -P -S -b -H -R -T" exit 1 ;; -V|--version) echo "systemd-sudo version 0.1" exit 0 ;; -s|--shell) # runs "$SHELL" SHELLARGS=("-S" "--pty") ;; -E|--preserve-env) ENVARGS=() # Extra "sh -c" is needed to only export the exported variables for VARNAME in $(sh -c 'compgen -v'); do set +u VAL="${!VARNAME}" set -u ENVARGS+=("--setenv" "${VARNAME}=${VAL}") done ;; -n|--non-interactive) NOINTERACTIVEARGS=("--no-ask-password") ;; -D|--chdir) WDIR="$1" shift ;; -u|--user) UNAME="$1" shift U=$(id -u "$UNAME") ;; -g|--group) GNAME="$1" G=$(id -g "$GNAME") shift ;; --) shift break;; esac shift done exec systemd-run --system --quiet --wait --collect --pipe --working-directory "$WDIR" --uid "$U" --gid "$G" "${SHELLARGS[@]}" "${NOINTERACTIVEARGS[@]}" "${ENVARGS[@]}" -- "$@"