mirror of https://github.com/borgbackup/borg.git
acl: make darwin acl code numeric_owner aware
This commit is contained in:
parent
47c6141aab
commit
dd5c0aa0e3
|
@ -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:
|
||||||
|
|
|
@ -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'])
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue