Mini Shell
#!/opt/imh-python/bin/python3
"""Switch to another user's shell"""
import argparse
import subprocess
import sys
import select
import os
import pymysql
from argparse import ArgumentTypeError as BadArg
sys.path.insert(0, '/opt/support/lib')
from arg_types import cpuser_safe_arg
def is_cwp():
"""Returns true the server is CWP"""
return os.path.exists("/usr/local/cwp")
def cwp_user_safe(user: str) -> str:
"""Returns the username if the CWP user is safe by verifying it exists in CWP, raises an exception otherwise"""
try:
mysql_conn = pymysql.connect(read_default_file="~/.my.cnf",db="root_cwp")
cursor = mysql_conn.cursor()
result = cursor.execute(f"SELECT * FROM `user` WHERE `username` = '{user}'") # result is number of lines found
cursor.close()
mysql_conn.close()
except Exception as e:
print(e)
raise BadArg('Failed to query MySQL')
if result == 0:
raise BadArg('user does not exist or is restricted')
return user
def switch(username: str):
"""Switches to ``username``"""
# We use subprocess because we actually want to pass our raw file
# descriptors to the child in this instance.
with subprocess.Popen(
['/bin/su', '-s', '/bin/bash', '-', username]
) as shell:
shell.communicate()
def parse_args() -> str:
"""Parses command line arguments and returns a username"""
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('user', type=valid_user, help="user to switch to")
return parser.parse_args().user
def valid_user(user: str) -> str:
if user == 'wordpress':
return user
if is_cwp():
return cwp_user_safe(user)
return cpuser_safe_arg(user)
def main():
"""Handle command line access"""
if select.select([sys.stdin], [], [], 0.0)[0]:
sys.exit("Cannot have stdin")
user = parse_args()
switch(user)
if __name__ == "__main__":
main()
Zerion Mini Shell 1.0