Suppose I have a script commands.sh
that looks something like the following:
command1 # Must be run as root
command2 # Absolutely cannot be run as root
command3 # Should be run as unprivileged user, but can be run as root
...
...
If we run commands.sh
, then command1
will complain. If we run sudo commands.sh
, then command2
will complain. We could edit commands.sh
to look like the following,
sudo command1
command2
command3
...
...
That is, inserting sudo
s in the appropriate places. With the default sudo
config (15 minute authentication persistence), this works great (assuming the script takes less than 15 minutes to run). However, if the script is longer, or we have authentication persistence disabled, then I feel there's not an obvious way forward. Additionally, some systems might not even use sudo
to authenticate - they may use doas
or something else instead.
Is there any (POSIX-y?) way of creating a script, authenticating once at the start, and then persisting that authentication through the script when necessary, without the use of sudo
's persistence?
CodePudding user response:
One possibility is to require the script to be run via sudo
, but then use sudo -u
within the script to revert (/demote) to the original user for commands that shouldn't be run as root. It'd probably be a good idea to include some sanity-checking at the beginning of the script to make sure it's being run from the right environment:
#!/bin/bash
if [[ "$EUID" != 0 ]]; then
# The script is not running as root
echo "This script must be run via sudo (as root)" >&2
exit 1
# Optional: replace exit 1 with:
# exec sudo "$0" "$@" # Re-run this script via sudo
# exit $? # In case the exec fails
elif [[ -z "$SUDO_USER" ]]; then
# The script is running as root, but doesn't have $SUDO_USER
# (the original user who ran sudo) to revert back to for
# unprivileged operations
echo "This script must be run via sudo, not directly as root" >&2
exit 1
elif [[ "$SUDO_USER" = root || "$SUDO_UID" = 0 ]]; then
# The script is running as root via sudo, but $SUDO_USER is
# *also* root, so is not suitable to revert back to for
# unprivileged operations
echo "This script must be run via sudo, from a regular (non-root) account" >&2
exit 1
fi
command1 # Must be run as root
sudo -u "$SUDO_USER" command2 # Absolutely cannot be run as root
sudo -u "$SUDO_USER" command3 # Should be run as unprivileged user, but can be run as root