diff --git a/bin/check-home-permissions.py b/bin/check-home-permissions.py deleted file mode 100755 index 5a747c878957eface1f48c6da692ea2953cd53a5..0000000000000000000000000000000000000000 --- a/bin/check-home-permissions.py +++ /dev/null @@ -1,301 +0,0 @@ -#!/usr/bin/env python3 - -import os -import sys -import pwd -import grp -import stat -import posix1e -import lib_path -import lib -import dphysldap - - -home_dirs = 0 -users = {} -nis_homes = {} -nis_shares = {} -owner = [] -permission = [] -acl = [] -bad_home_directory = [] -no_ldap_user = [] -bad_nis_map = [] -no_nis_map = [] -no_blocked = [] -not_closed = [] -not_open = [] - - -class Home(object): - """ - Holds info about a home directory - """ - def __init__(self, name, path, st): - self.name = name - self.path = path - self.st = st - - @property - def uid(self): - return self.st.st_uid - - @property - def gid(self): - return self.st.st_gid - - @property - def uname(self): - return pwd.getpwuid(self.uid).pw_name - - @property - def gname(self): - return grp.getgrgid(self.gid).gr_name - - @property - def filemode(self): - return stat.filemode(self.st.st_mode) - - @property - def permission(self): - return ' '.join([self.filemode, self.path]) - - def __str__(self): - return ' '.join([self.filemode, self.uname, self.gname, self.path]) - - -def search_ldap(): - ldap = dphysldap.Ldap() - people = 'ou=people,dc=phys,dc=ethz,dc=ch' - auto_home = 'nisMapName=auto.home,ou=automount,dc=phys,dc=ethz,dc=ch' - - ldap.search('(objectClass=posixAccount)', search_base=people, attributes=['uid', 'blocked', 'homeDirectory']) - ldap_users = ldap.response - for user in ldap_users: - uid = user['attributes']['uid'][0] - blocked = user['attributes']['blocked'] - home_dir = user['attributes']['homeDirectory'] - user_attrs = {} - user_attrs['homeDirectory'] = home_dir - if blocked: - user_attrs['blocked'] = blocked - else: - no_blocked.append(uid) - user_attrs['blocked'] = 'no' - users[uid] = user_attrs - - ldap.search('(&(objectClass=nisObject)(cn=*)(nisMapEntry=phd-home*))', - search_base=auto_home, attributes=['cn', 'nisMapEntry']) - entries = ldap.response - for entry in entries: - cn = entry['attributes']['cn'][0] - nis_map = entry['attributes']['nisMapEntry'] - nis_homes[cn] = nis_map - - ldap.search('(&(objectClass=nisObject)(cn=*)(!(nisMapEntry=phd-home*)))', - search_base=auto_home, attributes=['cn', 'nisMapEntry']) - entries = ldap.response - for entry in entries: - cn = entry['attributes']['cn'][0] - nis_map = entry['attributes']['nisMapEntry'] - nis_shares[cn] = nis_map - - -def check_homes(top): - global home_dirs - - if not os.path.isdir(top): - return - - for f in os.listdir(top): - pathname = os.path.join(top, f) - if not os.path.isdir(pathname): - continue - st = os.stat(pathname) - home = Home(f, pathname, st) - home_dirs += 1 - - if bad_owner(home): - owner.append(home) - - if bad_permission(home): - permission.append(home) - - if posix1e.has_extended(home.path): - acl.append(home) - - if home.name in users: - if users[home.name]['homeDirectory'][6:] != home.name: - bad_home_directory.append(': '.join([home.name, users[home.name]['homeDirectory']])) - if users[home.name]['blocked'] == 'yes': - if home.st.st_mode & stat.S_IRWXU: - not_closed.append(home) - else: - if home.st.st_mode & stat.S_IRWXU != stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR: - not_open.append(home) - del users[home.name] - else: - no_ldap_user.append(home) - - if home.name in nis_homes: - if nis_homes[home.name].split(':', maxsplit=1)[1] != home.path: - bad_nis_map.append(': '.join([home.name, nis_homes[home.name]])) - del nis_homes[home.name] - else: - no_nis_map.append(home) - - -def check_shares(): - for user in list(users.keys()): - if user in nis_shares: - del nis_shares[user] - del users[user] - - -def bad_owner(home): - if home.name == home.uname and home.name == home.gname: - return False - return True - - -def bad_permission(home): - # d--------- - if home.st.st_mode == stat.S_IFDIR: - return False - # drwx------ - elif home.st.st_mode == stat.S_IFDIR | stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR: - return False - return True - - -def list_homes(homes): - for home in homes: - print(home) - - -if __name__ == '__main__': - arg_count = len(sys.argv) - 1 - - search_ldap() - - print('statistics') - print('----------') - print('ldap users: ' + str(len(users))) - print('ldap nismaps (home): ' + str(len(nis_homes))) - print('ldap nismaps (share): ' + str(len(nis_shares))) - - for i, arg in enumerate(sys.argv): - if i == 0: - continue - check_homes(arg) - - check_shares() - - print('home dirs: ' + str(home_dirs)) - print('bad owner: ' + str(len(owner))) - print('bad permission: ' + str(len(permission))) - print('strange ldap users: ' + str(len(users))) - print('no blocked attr: ' + str(len(no_blocked))) - print('home not closed: ' + str(len(not_closed))) - print('home not open: ' + str(len(not_open))) - print('orphaned nis homes: ' + str(len(nis_homes))) - print('orphaned nis shares: ' + str(len(nis_shares))) - print('bad homeDirectory: ' + str(len(bad_home_directory))) - print('no user for home: ' + str(len(no_ldap_user))) - print('bad nismaps (home): ' + str(len(bad_nis_map))) - print('no nismap for home: ' + str(len(no_nis_map))) - print() - - if no_blocked: - print('no blocked attr:') - print('----------------') - for home in no_blocked: - print(home) - print() - - if owner: - print('bad owner or group:') - print('-------------------') - for home in owner: - print(home) - print() - - if permission: - print('bad permission:') - print('---------------') - for home in permission: - print(home.permission) - print() - - if acl: - print('bad acl:') - print('--------') - for home in acl: - extacl = posix1e.ACL(file=home.path) - print(home.path) - print(extacl) - print() - - if users: - print('strange ldap users:') - print('-------------------') - for k, v in users.items(): - print(''.join([k, ': ', 'blocked=', v['blocked'], ' ', 'homeDirectory=', v['homeDirectory']])) - print() - - if not_closed: - print('home not closed:') - print('----------------') - for home in not_closed: - print(home) - print() - - if not_open: - print('home not open:') - print('-------------') - for home in not_open: - print(home) - print() - - if nis_homes: - print('orphaned nis homes:') - print('-------------------') - for k, v in nis_homes.items(): - print(': '.join([k, v])) - print() - - if nis_shares: - print('orphaned nis shares:') - print('--------------------') - for k, v in nis_shares.items(): - print(': '.join([k, v])) - print() - - if bad_home_directory: - print('bad homeDirectory:') - print('------------------') - for home in bad_home_directory: - print(home) - print() - - if no_ldap_user: - print('no user for home:') - print('-----------------') - for home in no_ldap_user: - print(home) - print() - - if bad_nis_map: - print('bad nismaps (home):') - print('-------------------') - for home in bad_nis_map: - print(home) - print() - - if no_nis_map: - print('no nismap for home:') - print('-------------------') - for home in no_nis_map: - print(home) - print() - diff --git a/bin/xymon-permissions.py b/bin/xymon-permissions.py deleted file mode 100755 index 1f3f9c33a5b9fe783a273a2c68e65dd5dee0d0a0..0000000000000000000000000000000000000000 --- a/bin/xymon-permissions.py +++ /dev/null @@ -1,150 +0,0 @@ -#!/usr/bin/env python3 - -import os -import sys -import pwd -import grp -import stat -import glob -import posix1e -import pyxymon as pymon - -CHECK_NAME = 'permissions' -CHECK_VERSION = 2 -LIFETIME = 30 - -home_dir = '/export/home1/*' -owner = [] -permission = [] -acl = [] - - -class Home(object): - """ - Holds info about a home directory - """ - def __init__(self, name, path, st): - self.name = name - self.path = path - self.st = st - - @property - def uid(self): - return self.st.st_uid - - @property - def gid(self): - return self.st.st_gid - - @property - def uname(self): - return pwd.getpwuid(self.uid).pw_name - - @property - def gname(self): - return grp.getgrgid(self.gid).gr_name - - @property - def filemode(self): - return stat.filemode(self.st.st_mode) - - @property - def permission(self): - return ' '.join([self.filemode, self.path]) - - def __str__(self): - return ' '.join([self.filemode, self.uname, self.gname, self.path]) - - -def check_homes(top): - if not os.path.isdir(top): - return - for f in os.listdir(top): - pathname = os.path.join(top, f) - if not os.path.isdir(pathname): - continue - st = os.stat(pathname) - home = Home(f, pathname, st) - - if bad_owner(home): - owner.append(home) - - if bad_permission(home): - permission.append(home) - - if posix1e.has_extended(home.path): - acl.append(home) - - -def bad_owner(home): - if home.name == home.uname and home.name == home.gname: - return False - return True - - -def bad_permission(home): - # d--------- - if home.st.st_mode == stat.S_IFDIR: - return False - # drwx------ - elif home.st.st_mode == stat.S_IFDIR | stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR: - return False - return True - - -def list_homes(homes): - for home in homes: - print(home) - - -def run_check(xymon): - for path in glob.glob(home_dir): - check_homes(path) - - if owner: - title = 'bad owner or group' - content = 'home must be owned by the respective user and the group his user-private-group<br/><br/>' - for home in owner: - content += ''.join([str(home), '<br/>']) - xymon.section(title, content) - xymon.color = pymon.STATUS_CRITICAL - - if permission: - title = 'bad permissions' - content = 'home permission not <code>drwx------</code> (active user) or <code>d---------</code> (blocked user)<br/><br/>' - for home in permission: - content += ''.join([str(home.permission), '<br/>']) - xymon.section(title, content) - xymon.color = pymon.STATUS_CRITICAL - - if acl: - title = 'bad acls' - content = 'home has posix.1e extended ACLs<br/>check acls using `getfacl`, which stands for `get fucking ACL`<br/><br/>' - for home in acl: - extacl = posix1e.ACL(file=home.path) - content += ''.join([home.path, '<br/>']) - content += ''.join([str(extacl), '<br/>']) - xymon.section(title, content) - xymon.color = pymon.STATUS_CRITICAL - -def main(): - """Run xymon check""" - xymon = pymon.XymonClient(CHECK_NAME) - check_script = os.path.basename(__file__) - # The default criticity is set to 'pymon.STATUS_OK' - xymon.lifetime = LIFETIME - xymon.title('home ownership and permissions') - - try: - run_check(xymon) - except Exception as e: - xymon.color = pymon.STATUS_WARNING - xymon.section('Exception', e) - - xymon.footer(check_script, CHECK_VERSION) - xymon.send() - - -if __name__ == '__main__': - main() - sys.exit(0)