Created
June 11, 2020 13:24
-
-
Save stbuehler/412b04948953a11527a4c99c450fd76a to your computer and use it in GitHub Desktop.
run a given command (or the login shell) with additional capabilities as a normal user.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Start as root; run a given command (or the login shell) with additional capabilities as a normal user. | |
# Eg: with-cap-as-user.sh +net_bind_service -u myhttpuser -- nc -l -p 80 | |
caps= | |
user= | |
keepenv=0 | |
syntax() { | |
echo >&2 "Usage: $0 [-k] -u username (+capability)* [-- command]" | |
echo >&2 | |
echo >&2 "Options:" | |
echo >&2 " -k Keep environment" | |
echo >&2 " -u username Run command (or login shell) as user" | |
echo >&2 " +capability Capability name to run command with (see setpriv --list-caps)" | |
exit 1 | |
} | |
while [ $# -gt 0 ]; do | |
case "$1" in | |
+*) | |
caps=${caps},$1 | |
shift | |
;; | |
-k) | |
keepenv=1 | |
shift | |
;; | |
-u) | |
if [ -n "${user}" ]; then | |
echo >&2 "Already have user" | |
exit 1 | |
fi | |
if [ -z "$2" ]; then | |
echo >&2 "Missing/empty username" | |
exit 1 | |
fi | |
user=$2 | |
shift 2 | |
;; | |
-h|--help) | |
syntax | |
;; | |
--) | |
shift | |
break | |
;; | |
-*) | |
echo >&2 "Unknown option: $1" | |
syntax | |
;; | |
*) | |
break | |
;; | |
esac | |
done | |
if [ -z "${user}" ]; then | |
echo >&2 "Missing username" | |
syntax | |
fi | |
passwd=$(getent passwd -- "${user}") | |
if [ -z "${passwd}" ]; then | |
echo >&2 "User ${user} not found" | |
exit 2 | |
fi | |
IFS=: read name pass uid gid comment home shell <<< "${passwd}" | |
if [ -z "${uid}" -o -z "${gid}" -o "${uid}" = 0 -o "${gid}" = 0 ]; then | |
echo >&2 "Invalid user ${user}" | |
exit 1 | |
fi | |
if [ $# -gt 0 ]; then | |
prog=$1 | |
shift | |
if [ "${prog:0:1}" != '/' ]; then | |
absprog=$(which "${prog}") | |
if [ ! -x "${absprog}" ]; then | |
echo >&2 "Couldn't find ${prog} in PATH" | |
exit 1 | |
fi | |
prog=${absprog} | |
fi | |
command=("${prog}" "$@") | |
else | |
if [ -z "${shell}" -o ! -x "${shell}" ]; then | |
echo >&2 "User ${user} has no executable shell" | |
exit 1 | |
fi | |
command=("${shell}" -) | |
fi | |
args=( | |
--reuid "${uid}" | |
--regid "${gid}" | |
--init-groups | |
) | |
if [ "${keepenv}" = 0 ]; then | |
args+=( | |
--reset-env | |
) | |
fi | |
if [ -n "${caps}" ]; then | |
caps=${caps:1} # remove leading comma | |
args+=( | |
--inh-caps "${caps}" | |
--ambient-caps "${caps}" | |
--securebits +no_setuid_fixup | |
) | |
fi | |
if [ -d "${home}" ]; then | |
cd "${home}" | |
else | |
cd "/" | |
fi | |
exec setpriv "${args[@]}" -- "${command[@]}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment