Forráskód Böngészése

acl: make darwin acl code numeric_owner aware

Jonas Borgström 11 éve
szülő
commit
dd5c0aa0e3
2 módosított fájl, 47 hozzáadás és 3 törlés
  1. 42 2
      attic/platform_darwin.pyx
  2. 5 1
      attic/testsuite/platform.py

+ 42 - 2
attic/platform_darwin.pyx

@@ -1,4 +1,6 @@
 import os
+from attic.helpers import user2uid, group2gid
+
 API_VERSION = 1
 
 cdef extern from "sys/acl.h":
@@ -14,6 +16,38 @@ cdef extern from "sys/acl.h":
     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):
     cdef acl_t acl = NULL
     cdef char *text = NULL
@@ -24,7 +58,10 @@ def acl_get(path, item, numeric_owner=False):
         text = acl_to_text(acl, NULL)
         if text == NULL:
             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:
         acl_free(text)
         acl_free(acl)
@@ -34,7 +71,10 @@ def acl_set(path, item, numeric_owner=False):
     cdef acl_t acl = NULL
     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:
             return
         if acl == NULL:

+ 5 - 1
attic/testsuite/platform.py

@@ -93,8 +93,12 @@ class PlatformDarwinTestCase(AtticTestCase):
 
     def test_access_acl(self):
         file = tempfile.NamedTemporaryFile()
+        file2 = tempfile.NamedTemporaryFile()
         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'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'])