diff --git a/CHANGES b/CHANGES index 47398a227..6fce89758 100644 --- a/CHANGES +++ b/CHANGES @@ -7,7 +7,7 @@ Version 0.14 ------------ (feature release, released on X) - +- Add workaround for old Linux systems without acl_extended_file_no_follow (#96) - Add MacPorts' path to the default openssl search path (#101) - HashIndex improvements, eliminates unnecessary IO on low memory systems. diff --git a/attic/archive.py b/attic/archive.py index c93c1886a..a49d39510 100644 --- a/attic/archive.py +++ b/attic/archive.py @@ -354,7 +354,7 @@ class Archive: item[b'xattrs'] = StableDict(xattrs) if has_lchflags and st.st_flags: item[b'bsdflags'] = st.st_flags - item[b'acl'] = acl_get(path, item, self.numeric_owner) + acl_get(path, item, st, self.numeric_owner) return item def process_item(self, path, st): diff --git a/attic/helpers.py b/attic/helpers.py index 5e9be6ab2..56ce4263c 100644 --- a/attic/helpers.py +++ b/attic/helpers.py @@ -76,7 +76,7 @@ def check_extension_modules(): if (attic.hashindex.API_VERSION != 2 or attic.chunker.API_VERSION != 1 or attic.crypto.API_VERSION != 2 or - attic.platform.API_VERSION != 1): + attic.platform.API_VERSION != 2): raise ExtensionModuleError diff --git a/attic/platform_darwin.pyx b/attic/platform_darwin.pyx index a0ea7b929..37ed2d461 100644 --- a/attic/platform_darwin.pyx +++ b/attic/platform_darwin.pyx @@ -1,7 +1,7 @@ import os from attic.helpers import user2uid, group2gid -API_VERSION = 1 +API_VERSION = 2 cdef extern from "sys/acl.h": ctypedef struct _acl_t: @@ -48,7 +48,7 @@ def _remove_non_numeric_identifier(acl): return b'\n'.join(entries) -def acl_get(path, item, numeric_owner=False): +def acl_get(path, item, st, numeric_owner=False): cdef acl_t acl = NULL cdef char *text = NULL try: diff --git a/attic/platform_freebsd.pyx b/attic/platform_freebsd.pyx index c3a9a0662..074eebca1 100644 --- a/attic/platform_freebsd.pyx +++ b/attic/platform_freebsd.pyx @@ -1,7 +1,7 @@ import os from attic.helpers import posix_acl_use_stored_uid_gid -API_VERSION = 1 +API_VERSION = 2 cdef extern from "errno.h": int errno @@ -42,7 +42,7 @@ cdef _get_acl(p, type, item, attribute, int flags): acl_free(acl) -def acl_get(path, item, numeric_owner=False): +def acl_get(path, item, st, numeric_owner=False): """Saves ACL Entries If `numeric_owner` is True the user/group field is not preserved only uid/gid diff --git a/attic/platform_linux.pyx b/attic/platform_linux.pyx index ee0f0bd59..1a6dd73be 100644 --- a/attic/platform_linux.pyx +++ b/attic/platform_linux.pyx @@ -1,8 +1,9 @@ import os import re +from stat import S_ISLNK from attic.helpers import posix_acl_use_stored_uid_gid, user2uid, group2gid -API_VERSION = 1 +API_VERSION = 2 cdef extern from "sys/types.h": int ACL_TYPE_ACCESS @@ -20,7 +21,7 @@ cdef extern from "sys/acl.h": char *acl_to_text(acl_t acl, ssize_t *len) cdef extern from "acl/libacl.h": - int acl_extended_file_nofollow(const char *path) + int acl_extended_file(const char *path) _comment_re = re.compile(' *#.*', re.M) @@ -75,7 +76,7 @@ cdef acl_numeric_ids(acl): return ('\n'.join(entries)).encode('ascii') -def acl_get(path, item, numeric_owner=False): +def acl_get(path, item, st, numeric_owner=False): """Saves ACL Entries If `numeric_owner` is True the user/group field is not preserved only uid/gid @@ -85,7 +86,7 @@ def acl_get(path, item, numeric_owner=False): cdef char *default_text = NULL cdef char *access_text = NULL - if acl_extended_file_nofollow(os.fsencode(path)) <= 0: + if S_ISLNK(st.st_mode) or acl_extended_file(os.fsencode(path)) <= 0: return if numeric_owner: converter = acl_numeric_ids diff --git a/attic/testsuite/platform.py b/attic/testsuite/platform.py index f7bf2afd6..90abfd85e 100644 --- a/attic/testsuite/platform.py +++ b/attic/testsuite/platform.py @@ -46,7 +46,7 @@ class PlatformLinuxTestCase(AtticTestCase): def get_acl(self, path, numeric_owner=False): item = {} - acl_get(path, item, numeric_owner=numeric_owner) + acl_get(path, item, os.stat(path), numeric_owner=numeric_owner) return item def set_acl(self, path, access=None, default=None, numeric_owner=False): @@ -84,7 +84,7 @@ class PlatformDarwinTestCase(AtticTestCase): def get_acl(self, path, numeric_owner=False): item = {} - acl_get(path, item, numeric_owner=numeric_owner) + acl_get(path, item, os.stat(path), numeric_owner=numeric_owner) return item def set_acl(self, path, acl, numeric_owner=False):