#!/usr/bin/env bash # switch: "Switch" into a user on a CWP server to perform local actions # Nathan P. # 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}"