File: //opt/alt/python37/lib/python3.7/site-packages/orphanedaccountscanner/cpanel_databases.py
#! /opt/alt/python37/bin/python3
import os
import re
import socket
import datetime
ignore = [
'gdlinuxm',
'gdresell',
'gdmigrate',
'vpsmigrate',
'cpanelsolr',
'diablo',
'gdlegal',
'binlogs',
'cphulkd',
'gdlinuxm_wp2',
'horde',
'modsec',
'mysql',
'performance_schema',
'roundcube',
]
def system_health() -> bool:
if not os.path.exists('/var/lib/mysql'):
raise SystemError('Directory not found')
return True
def get_hostname() -> str:
if socket.gethostname() == str():
raise TypeError("Hostname audit event failed!")
return socket.gethostname().split('.')[0]
def check_hostname() -> bool:
"""
Grabs a servers unix hostname and checks if it's a cPanel server
Returns: bool
"""
short_name = get_hostname()
hostname_regex = '^(a2|p3|sg2|sg3|sxb1|n1|n3)pl(v|vw|m|z|)cpnl\d{2,}$'
if re.search(hostname_regex, short_name):
return True
def directory_scan(dir) -> list:
"""
Parses a given directory and returns a list of sub directories ignoring
files and hidden dirs/files
Returns: list of dirs
"""
if dir not in ['/home', '/var/lib/mysql']:
raise TypeError('We have no idea how to scan that, sorry')
try:
entries = []
with os.scandir(dir) as scan_path:
for entry in scan_path:
if not entry.name.startswith('.') and entry.is_file():
# both parsers need dirs and not hidden
continue
else:
entries.append(entry)
except OSError as error_message:
raise SystemError(error_message)
return entries
def get_directory_info(dir: os.DirEntry, base_dir: str,) -> list:
stat = dir.stat()
if stat.st_gid == 199 or stat.st_gid == 0:
# Skip GDSTAFF and ROOT owned things
pass
if dir.name in ignore:
# Skip all things that we are explicitly ignoring
pass
# If there's not a trailing / the name conc. doesn't work
if base_dir[-1] is not '/':
base_dir += '/'
from subprocess import run
process = run(['du', '-s', base_dir + dir.name], capture_output=True, text=True)
size_in_kb = process.stdout.split('\t')[0]
return [ dir.name, stat.st_uid, stat.st_gid, stat.st_atime, size_in_kb ]
def build_databases_sot():
'''We found that the best SOT for databases is on-box with
`whmapi1 list_databases'''
from subprocess import Popen, PIPE
whmapi = Popen("whmapi1 list_databases".split(), stdout=PIPE)
grep = Popen("grep name".split(), stdin=whmapi.stdout, stdout=PIPE)
cut = Popen(['cut', '-d', ':', '-f2'], stdin=grep.stdout, stdout=PIPE)
process = Popen("sort -n".split(), stdin=cut.stdout, stdout=PIPE)
out, err = process.communicate()
dbs = []
for db in out:
dbs.append(db)
return dbs
if __name__ == '__main__':
# Build a list of commands to ensure the host is operational to scan
verification_commands = [
check_hostname(),
system_health()
]
for _ in verification_commands:
if not _ == True:
raise SystemError(message)
DATABASES = build_databases_sot()
ldatabases = directory_scan('/var/lib/mysql')
for entry in ldatabases:
name, uid, gid, st_atime, size = get_directory_info(entry, '/var/lib/mysql')
LOCAL['databases'][name] = {
'uid': uid,
'gid': gid,
'st_atime': datetime.datetime.fromtimestamp(st_atime).strftime("%Y-%m-%d %I:%M:%S"),
'size': size
}
print(LOCAL['databases'], DATABASES)