Last active
November 28, 2016 20:30
-
-
Save jessepeterson/50d58d0de0e12345c42f8d34c1ce52dc to your computer and use it in GitHub Desktop.
Finds bad ACE qualifiers (user/group UUIDs) in ACLs on files on macOS. Takes a list of file/directory names on stdin.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
''' | |
Takes a list of file names/paths on stdin and checks to see if they have | |
unresolvable ACE entries in their ACLs. E.g. ACEs which have a non-resolvable | |
UUID on the system. | |
Usage: | |
find /some/file/path | /path/to/findbadacls.py | |
''' | |
import sys | |
import os | |
from ctypes import * | |
from ctypes.util import find_library | |
import uuid | |
from pipes import quote | |
libc = cdll.LoadLibrary(find_library('c')) | |
# from <sys/acl.h> | |
ACL_TYPE_EXTENDED = 0x00000100 | |
ACL_FIRST_ENTRY = 0 | |
ACL_NEXT_ENTRY = -1 | |
ACL_LAST_ENTRY = -2 | |
acl_get_file = libc.acl_get_file | |
acl_get_file.argtypes = [c_char_p, c_int] | |
acl_get_file.restype = c_void_p | |
acl_free = libc.acl_free | |
acl_free.argtypes = [c_void_p] | |
acl_free.restype = c_int | |
class ACLEntry(Structure): | |
pass | |
acl_get_entry = libc.acl_get_entry | |
acl_get_entry.argtypes = [c_void_p, c_int, POINTER(POINTER(ACLEntry))] | |
acl_get_entry.restype = c_int | |
acl_get_qualifier = libc.acl_get_qualifier | |
acl_get_qualifier.argtypes = [POINTER(ACLEntry)] | |
acl_get_qualifier.restype = POINTER(c_ubyte * 16) | |
mbr_uuid_to_id = libc.mbr_uuid_to_id | |
mbr_uuid_to_id.argtypes = [(c_ubyte * 16), POINTER(c_uint), POINTER(c_int)] | |
mbr_uuid_to_id.restype = c_int | |
for stdinline in sys.stdin: | |
if stdinline[-1] == '\n': | |
filename = stdinline[:-1] | |
if os.path.exists(filename): | |
acl = acl_get_file(filename, ACL_TYPE_EXTENDED) | |
entry = POINTER(ACLEntry)() | |
uid = c_uint() | |
idtype = c_int() | |
if acl: | |
bad_acls = [] | |
ace_i = 0 | |
while True: | |
if acl_get_entry(acl, ACL_FIRST_ENTRY if not entry else ACL_NEXT_ENTRY, byref(entry)) != 0: | |
break | |
q_uuid = acl_get_qualifier(entry) | |
p_uuid = uuid.UUID(bytes=''.join([chr(x) for x in q_uuid.contents[0:16]])) | |
if mbr_uuid_to_id(q_uuid.contents, byref(uid), byref(idtype)) != 0: | |
bad_acls.append(ace_i) | |
acl_free(q_uuid) | |
ace_i += 1 | |
if bad_acls: | |
print '#', filename | |
bad_acls.reverse() | |
for ace_i in bad_acls: | |
print "/bin/chmod -a# %d %s" % (ace_i, quote(filename)) | |
acl_free(acl) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment