#!/usr/bin/python import errno import fuse import grp import re import stat fuse.fuse_python_api = (0, 2) def protected_users(): try: nonlocal = set(grp.getgrnam('nss-nonlocal-users').gr_mem) except KeyError: nonlocal = set() with open('/etc/passwd') as pw: for line in pw: user = line.split(':', 1)[0] if user not in nonlocal: yield user def realms_conf(): with open('/etc/krb5.conf') as f: in_realms = False for line in f: sline = line.lstrip() if sline.startswith('['): in_realms = sline.startswith('[realms]') elif (sline.startswith(';') or sline.startswith('#') or sline.startswith('{') or sline.startswith('}')): pass elif '=' in sline: key, val = sline.split('=', 1) if in_realms and key.rstrip() == 'ATHENA.MIT.EDU': s = '[realms]\n' s += line if val.strip() == '': line = next(f, '') if line.strip() != '{': return '' s += line elif val.strip() != '{': continue level = 1 for line in f: sline = line.lstrip() if sline.startswith('['): return '' elif sline.startswith(';') or sline.startswith('#'): pass elif sline.startswith('}'): level -= 1 if level == 0: s += '\t\tauth_to_local = RULE:[1:$1@$0](' + \ '|'.join(re.escape(user + '@ATHENA.MIT.EDU') for user in protected_users()) + \ ')s/^.*/nobody/\n' s += '\t\tauth_to_local = DEFAULT\n' s += line return s elif (sline.startswith('{') or ('=' in sline and sline.split('=', 1)[1].strip() == '{')): level += 1 s += line return '' realms_conf_path = '/realms.conf' class Krb5FS(fuse.Fuse): def getattr(self, path): if path == '/': return fuse.Stat(st_mode = stat.S_IFDIR | 0555, st_nlink = 2) elif path == realms_conf_path: return fuse.Stat(st_mode = stat.S_IFREG | 0444, st_nlink = 1, st_size = len(realms_conf())) else: return -errno.ENOENT def readdir(self, path, offset): if path == '/': return (fuse.Direntry(p) for p in ['.', '..', realms_conf_path[1:]]) else: return -errno.ENOENT def read(self, path, size, offset): if path == realms_conf_path: return realms_conf()[offset:offset + size] else: return -errno.ENOENT def main(): fs = Krb5FS() fs.parse(errex=1) fs.fuse_args.add('allow_other') fs.fuse_args.add('nonempty') fs.main() if __name__ == '__main__': main()