diff --git a/experimental/uidgid-analysis b/experimental/uidgid-analysis new file mode 100755 index 0000000..eb17fb4 --- /dev/null +++ b/experimental/uidgid-analysis @@ -0,0 +1,86 @@ +#!/usr/bin/env python3 +# +# Print statistics on the objects for a given ref/commit in an OSTree repo +# +# Copyright 2015 Colin Walters +# Licensed under the new-BSD license (http://www.opensource.org/licenses/bsd-license.php) + +import gi +gi.require_version('OSTree', '1.0') +import sys,os,argparse +from gi.repository import GLib, Gio, OSTree + +parser = argparse.ArgumentParser(prog=sys.argv[0]) +parser.add_argument("path", help="filesystem tree path", + action='store') +args = parser.parse_args() + +passwd_db = {} +group_db = {} +if os.path.isfile(args.path + '/usr/lib/passwd'): + with open(args.path + '/usr/lib/passwd') as f: + for line in f: + if line == '': continue + (name, _, uid, gid, _) = line.split(':', 4) + passwd_db[int(uid)] = (True, name, int(gid)) +with open(args.path + '/usr/etc/passwd') as f: + for line in f: + if line == '': continue + (name, _, uid, gid, _) = line.split(':', 4) + passwd_db[int(uid)] = (False, name, int(gid)) + +if os.path.isfile(args.path + '/usr/lib/group'): + with open(args.path + '/usr/lib/group') as f: + for line in f: + if line == '': continue + (name, _, gid, _) = line.split(':', 3) + group_db[int(gid)] = (True, name) +with open(args.path + '/usr/etc/group') as f: + for line in f: + if line == '': continue + (name, _, gid, _) = line.split(':', 3) + group_db[int(gid)] = (False, name) + +usr_nonroot = set() +usretc_nonroot = set() +other_nonroot = set() + +def analyze_path(dfd, name, fpath): + stbuf = os.lstat(name, dir_fd=dfd) + uid_or_gid_nonzero = False + if stbuf.st_uid != 0: + entry = passwd_db.get(stbuf.st_uid) + if entry is None: + print("Unknown uid {} for {}".format(stbuf.st_uid, fpath)) + uid_or_gid_nonzero = True + if stbuf.st_gid != 0: + entry = group_db.get(stbuf.st_gid) + if entry is None: + print("Unknown gid {} for {}".format(stbuf.st_gid, fpath)) + uid_or_gid_nonzero = True + if not uid_or_gid_nonzero: + return + if fpath.startswith('./usr/etc/'): + usretc_nonroot.add((fpath, stbuf.st_uid, stbuf.st_gid)) + elif fpath.startswith('./usr/'): + usr_nonroot.add((fpath, stbuf.st_uid, stbuf.st_gid)) + else: + other_nonroot.add((fpath, stbuf.st_uid, stbuf.st_gid)) + +rootfd = os.open(args.path, os.O_DIRECTORY) +for (dpath, dirnames, fnames, rootfd) in os.fwalk(dir_fd=rootfd): + for fname in fnames: + analyze_path(rootfd, fname, dpath + '/' + fname) + for dname in dirnames: + analyze_path(rootfd, dname, dpath + '/' + dname) + +def dumpset(title, s): + print("{}: {}".format(title, len(s))) + + for (path, uid, gid) in sorted(s): + print(" {}:{}: {}".format(passwd_db[uid][1], group_db[gid][1], path)) + print("") + +dumpset("Other nonroot", other_nonroot) +dumpset("/usr/etc nonroot", usretc_nonroot) +dumpset("/usr nonroot", usr_nonroot)