HEX
Server: Apache/2.4.65 (Unix) OpenSSL/1.1.1k
System: Linux vps109042.inmotionhosting.com 4.18.0 #1 SMP Mon Sep 30 15:36:27 MSK 2024 x86_64
User: cisa (1010)
PHP: 8.2.30
Disabled: NONE
Upload Files
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}"