acl: make darwin acl code numeric_owner aware

This commit is contained in:
Jonas Borgström 2014-05-03 23:22:55 +02:00
parent 47c6141aab
commit dd5c0aa0e3
2 changed files with 47 additions and 3 deletions

View File

@ -1,4 +1,6 @@
import os import os
from attic.helpers import user2uid, group2gid
API_VERSION = 1 API_VERSION = 1
cdef extern from "sys/acl.h": cdef extern from "sys/acl.h":
@ -14,6 +16,38 @@ cdef extern from "sys/acl.h":
int ACL_TYPE_EXTENDED int ACL_TYPE_EXTENDED
def _remove_numeric_id_if_possible(acl):
"""Replace the user/group field with the local uid/gid if possible
"""
entries = []
for entry in acl.decode('ascii').split('\n'):
if entry:
fields = entry.split(':')
if fields[0] == 'user':
if user2uid(fields[2]) is not None:
fields[1] = fields[3] = ''
elif fields[0] == 'group':
if group2gid(fields[2]) is not None:
fields[1] = fields[3] = ''
entries.append(':'.join(fields))
return ('\n'.join(entries)).encode('ascii')
def _remove_non_numeric_identifier(acl):
"""Remove user and group names from the acl
"""
entries = []
for entry in acl.split(b'\n'):
if entry:
fields = entry.split(b':')
if fields[0] in (b'user', b'group'):
fields[2] = b''
entries.append(b':'.join(fields))
else:
entries.append(entry)
return b'\n'.join(entries)
def acl_get(path, item, numeric_owner=False): def acl_get(path, item, numeric_owner=False):
cdef acl_t acl = NULL cdef acl_t acl = NULL
cdef char *text = NULL cdef char *text = NULL
@ -24,7 +58,10 @@ def acl_get(path, item, numeric_owner=False):
text = acl_to_text(acl, NULL) text = acl_to_text(acl, NULL)
if text == NULL: if text == NULL:
return return
item[b'acl_extended'] = text if numeric_owner:
item[b'acl_extended'] = _remove_non_numeric_identifier(text)
else:
item[b'acl_extended'] = text
finally: finally:
acl_free(text) acl_free(text)
acl_free(acl) acl_free(acl)
@ -34,7 +71,10 @@ def acl_set(path, item, numeric_owner=False):
cdef acl_t acl = NULL cdef acl_t acl = NULL
try: try:
try: try:
acl = acl_from_text(item[b'acl_extended']) if numeric_owner:
acl = acl_from_text(item[b'acl_extended'])
else:
acl = acl_from_text(<bytes>_remove_numeric_id_if_possible(item[b'acl_extended']))
except KeyError: except KeyError:
return return
if acl == NULL: if acl == NULL:

View File

@ -93,8 +93,12 @@ class PlatformDarwinTestCase(AtticTestCase):
def test_access_acl(self): def test_access_acl(self):
file = tempfile.NamedTemporaryFile() file = tempfile.NamedTemporaryFile()
file2 = tempfile.NamedTemporaryFile()
self.assert_equal(self.get_acl(file.name), {}) self.assert_equal(self.get_acl(file.name), {})
self.set_acl(file.name, b'!#acl 1\ngroup:ABCDEFAB-CDEF-ABCD-EFAB-CDEF00000014:staff:9999:allow:read\nuser:FFFFEEEE-DDDD-CCCC-BBBB-AAAA00000000:root:0:allow:read\n', numeric_owner=False) self.set_acl(file.name, b'!#acl 1\ngroup:ABCDEFAB-CDEF-ABCD-EFAB-CDEF00000000:staff:0:allow:read\nuser:FFFFEEEE-DDDD-CCCC-BBBB-AAAA00000000:root:0:allow:read\n', numeric_owner=False)
self.assert_in(b'group:ABCDEFAB-CDEF-ABCD-EFAB-CDEF00000014:staff:20:allow:read', self.get_acl(file.name)[b'acl_extended']) self.assert_in(b'group:ABCDEFAB-CDEF-ABCD-EFAB-CDEF00000014:staff:20:allow:read', self.get_acl(file.name)[b'acl_extended'])
self.assert_in(b'user:FFFFEEEE-DDDD-CCCC-BBBB-AAAA00000000:root:0:allow:read', self.get_acl(file.name)[b'acl_extended']) self.assert_in(b'user:FFFFEEEE-DDDD-CCCC-BBBB-AAAA00000000:root:0:allow:read', self.get_acl(file.name)[b'acl_extended'])
self.set_acl(file2.name, b'!#acl 1\ngroup:ABCDEFAB-CDEF-ABCD-EFAB-CDEF00000000:staff:0:allow:read\nuser:FFFFEEEE-DDDD-CCCC-BBBB-AAAA00000000:root:0:allow:read\n', numeric_owner=True)
self.assert_in(b'group:ABCDEFAB-CDEF-ABCD-EFAB-CDEF00000000:wheel:0:allow:read', self.get_acl(file2.name)[b'acl_extended'])
self.assert_in(b'group:ABCDEFAB-CDEF-ABCD-EFAB-CDEF00000000::0:allow:read', self.get_acl(file2.name, numeric_owner=True)[b'acl_extended'])