mirror of
https://github.com/Pardus-LiderAhenk/ahenk
synced 2024-11-29 21:22:22 +03:00
75 lines
2.2 KiB
Python
75 lines
2.2 KiB
Python
|
#!/usr/bin/env python3
|
||
|
# -*- coding: utf-8 -*-
|
||
|
|
||
|
import os, signal
|
||
|
|
||
|
class ProcEntry(object):
|
||
|
|
||
|
def __init__(self, name, pid, cmdline, euid, egid):
|
||
|
super(ProcEntry, self).__init__()
|
||
|
self.name = name
|
||
|
self.pid = pid
|
||
|
self.cmdline = cmdline
|
||
|
self.euid = euid
|
||
|
self.egid = egid
|
||
|
|
||
|
def __str__(self):
|
||
|
return 'name: {0}, pid: {1}, uid: {2}, gid: {3}, cmd: {4}' \
|
||
|
.format(self.name, self.pid, self.euid, self.egid, self.cmdline)
|
||
|
|
||
|
|
||
|
class ProcParseError(Exception):
|
||
|
|
||
|
def __init__(self, msg):
|
||
|
super(Exception, self).__init__(msg)
|
||
|
|
||
|
|
||
|
def proclist():
|
||
|
def raise_if_less(l, n):
|
||
|
if len(l) < n:
|
||
|
raise ProcParseError('too few fields, expected at least ' + str(n))
|
||
|
|
||
|
for pid in [pid for pid in os.listdir('/proc') if pid.isdigit()]:
|
||
|
p = os.path.join('/proc', pid, 'cmdline')
|
||
|
cmdline = open(p).read()
|
||
|
p = os.path.join('/proc', pid, 'status')
|
||
|
euid = None
|
||
|
egid = None
|
||
|
name = None
|
||
|
for lin in open(p):
|
||
|
if lin.startswith('Name:'):
|
||
|
s = lin.split()
|
||
|
raise_if_less(s, 2)
|
||
|
name = s[1]
|
||
|
elif lin.startswith('Uid:'):
|
||
|
uid_line = lin.split()
|
||
|
raise_if_less(uid_line, 3)
|
||
|
euid = int(uid_line[2])
|
||
|
elif lin.startswith('Gid:'):
|
||
|
gid_line = lin.split()
|
||
|
raise_if_less(gid_line, 3)
|
||
|
egid = int(gid_line[2])
|
||
|
|
||
|
yield ProcEntry(name, int(pid), cmdline, euid, egid)
|
||
|
|
||
|
PATH_SHELLS='/etc/shells'
|
||
|
|
||
|
def login_shells():
|
||
|
valid = lambda s: s.rstrip(' \n') and not s.lstrip(' \t').startswith('#')
|
||
|
return [lin.rstrip('\n') for lin in open(PATH_SHELLS).readlines()
|
||
|
if valid(lin)]
|
||
|
|
||
|
def shell_is_interactive(sh):
|
||
|
shells = ['sh', 'bash', 'dash', 'zsh', 'fish', 'ksh', 'csh', 'tcsh']
|
||
|
return any(s == os.path.basename(sh) for s in shells)
|
||
|
|
||
|
def killuserprocs(uid):
|
||
|
for p in proclist():
|
||
|
if p.euid == uid:
|
||
|
try:
|
||
|
os.kill(p.pid, signal.SIGTERM)
|
||
|
except ProcessLookupError as e:
|
||
|
# The process might have died immediately, up till now, even
|
||
|
# before we had a chance to send a signal to it.
|
||
|
pass
|