D7net
Home
Console
Upload
information
Create File
Create Folder
About
Tools
:
/
opt
/
alt
/
python37
/
lib
/
python3.7
/
site-packages
/
orphanedaccountscanner
/
Filename :
main.py
back
Copy
#! /opt/alt/python37/bin/python3 import os import re import json import typing import socket import datetime import requests from typing import Dict from config import oas_url from utils.ranking import rank dirs = { '/home': { 'type': 'account' }, } ignore = [ 'gdlinuxm', 'cpsupport', 'gdresell', 'gdmigrate', 'vpsmigrate', 'cpanelsolr', 'diablo', 'gdlegal', 'binlogs', 'cphulkd', 'gdlinuxm_wp2', 'horde', 'modsec', 'mysql', 'performance_schema', 'roundcube', 'ikvminit', 'srebackup', 'svc4xdmzoss1h9vet' ] SSOT = { 'accounts': [], 'databases': [] } LOCAL = { 'accounts': {}, 'databases': {} } localSOT = '/home/diablo/non_orphan_accounts' #'accounts' [{ # 'db_after_asr': { # 'uid': 1, # 'gid': 1, # 'last_accessed': 1 # } #}, # #] def system_health() -> bool: for _ in dirs: if not os.path.exists(_): 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 = '^(p3|sg2|sxb1|bom1)(p|t)l(m|z)cpnl\d{2,}$' if re.search(hostname_regex, short_name): return True # Local account scanning 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 return if os.path.islink(dir): # Skip symlinks return if dir.name in ignore: # Skip all things that we are explicitly ignoring return # 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] size_in_kb = 0 return [ dir.name, stat.st_uid, stat.st_gid, stat.st_atime , size_in_kb ] relevance_queries = { 'cpanel_migrations': { 'description': 'cpmove_ accounts' } } removal_command = [''] def process(accounts: Dict[str, Dict[str, str]], ssot): real = [] rank_2 = [] rank_3 = [] rank_4 = [] for account in accounts: rank = 0 for query in relevance_queries: account_details = accounts[account] if account_details['gid'] <= 9999: rank = -1 if 'cpmove_' in account: # query and rank significance rank += 3 if account in ssot: rank = -1 if account not in ssot: rank += 3 if account in ignore: rank = -1 rank = 4 if rank >= 4 else rank if rank == 0 or rank == -1: real.append((account, rank)) if rank == 1 or rank == 2: rank_2.append((account, rank)) if rank == 3: rank_3.append((account, rank)) if rank == 4: rank_4.append((account, rank)) return real, rank_2, rank_3, rank_4 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('unable to verify server') # Get data from source of truth f = open(f'/home/diablo/non_orphan_accounts') ssot = { 'users': [] } for line in f: ssot['users'].append(line.rstrip()) ACCOUNTS = ssot['users'] # Get data from local_ l_ l_accounts = directory_scan('/home') for entry in l_accounts: try: name, uid, gid, st_atime, size = get_directory_info(entry, '/home/') LOCAL['accounts'][name] = { 'uid': uid, 'gid': gid, 'st_atime': datetime.datetime.fromtimestamp(st_atime).strftime("%Y-%m-%d %I:%M:%S"), 'size': size } except Exception as e: pass real, rank_2, rank_3, rank_4= process(LOCAL['accounts'], ACCOUNTS) print(len(rank_3), rank_3)