File: //opt/cwprads/switch
#!/usr/bin/env bash
# switch: "Switch" into a user on a CWP server to perform local actions
# Nathan P. <code@tchbnl.net>
# 0.1d
set -euo pipefail
# This script is meant to be used by root or a user with sudo access to it
# The silent exit is intentional
current_user="$(whoami)"
if [[ "${current_user}" != 'root' ]]; then
exit 1
fi
# Version information
VERSION='0.1d'
# Nice text formatting options
TEXT_BOLD='\e[1m'
TEXT_UNSET='\e[0m'
# Help message
show_help() {
cat << END_OF_HELP
$(echo -e "${TEXT_BOLD}")switch:$(echo -e "${TEXT_UNSET}") "Switch" into a local CWP user's shell account
USAGE: switch USER
--help -h Show this message
--version -v Show version information
END_OF_HELP
}
# Newer versions of MariaDB complain about using 'mysql'
if command -v mariadb >/dev/null 2>&1; then
MYSQL_COMMAND='mariadb'
else
MYSQL_COMMAND='mysql'
fi
# We do an initial check if the user was found in the CWP database. If it
# was, we continue on.
switch_into() {
result="$(${MYSQL_COMMAND} -u root root_cwp -Nse "SELECT username FROM user WHERE username = '${user}';")"
if [[ -z "${result}" ]]; then
echo "${user} wasn't found in the CWP database." >&2
return 1
fi
# CWP has a low nproc limit of 40 set for users by default, which tends to
# be too low to run their shell. We need to work around this. su and sudo
# won't work because the original user's nproc limit is replaced. So we
# have to resort to setpriv and some voodo.
user_uid="$(id -u "${user}")"
user_gid="$(id -g "${user}")"
user_home="$(getent passwd "${user}" | awk -F ':' '{print $6}')"
HOME="${user_home}" setpriv --clear-groups --regid="${user_gid}" --reuid="${user_uid}" bash -c 'cd && bash'
}
# Command options
while [[ "${#}" -gt 0 ]]; do
case "${1}" in
--help | -h)
show_help
exit 0
;;
--version | -v)
echo -e "${TEXT_BOLD}switch${TEXT_UNSET} ${VERSION}"
exit 0
;;
-*)
echo -e "Not sure what ${1} is supposed to mean..." >&2
echo
show_help
exit 1
;;
*)
break
;;
esac
done
# Show help message and exit if no arguments (like a domain) were passed
if [[ "${#}" -eq 0 ]]; then
show_help
exit 0
fi
# First convert the user's input into lowercase (usernames are always
# lowercase) and capture it
user="$(echo "${1}" | tr '[:upper:]' '[:lower:]')"
# And then check if it's valid for a Linux username
if [[ ! "${user}" =~ ^[a-z_][a-z0-9_-]*$ ]]; then
echo "That doesn't look like a valid username." >&2
exit 1
fi
# And then pass the valid input to switch_into if it's valid. Valid.
switch_into "${user}"