diff options
author | Andreas Gruenbacher <andreas.gruenbacher@gmail.com> | 2015-04-11 14:44:30 +0200 |
---|---|---|
committer | Andreas Gruenbacher <andreas.gruenbacher@gmail.com> | 2015-05-27 23:37:53 +0200 |
commit | 2d5ce445d63109b3999402effbc6f8c1db4e8920 (patch) | |
tree | 3307f3e46478ede63f2fe05fff4a3270ca8fd5f2 /lib/acl-internal.h | |
parent | f1b37e3afb1ba17be1c11012f86ff14e5cc357af (diff) | |
download | gnulib-2d5ce445d63109b3999402effbc6f8c1db4e8920.tar.gz |
qacl: Reimplement qset_acl and qcopy_acl (Bug#20666)
Implement get_permissions and set_permissions primitives for getting all
the permissions of a file, storing them, and later setting them. (In the
minimal case, the permissions consist only of a file mode.) Reimplement
qset_acl and qcopy_acl based on these new primitives: this avoids code
duplication and makes error handling more consistent.
The Solaris and Cygwin code still uses duplicate code paths for setting
a file mode while making sure that no acls exist and setting an explicit
acl; this is no worse than before, but could be cleaned up. The AIX
code still doesn't read ACLs, it only makes sure that acls don't get in
the way when setting a file mode.
* lib/acl-internal.h (struct permission_context): New data structure.
(get_permissions, set_permissions, free_permission_context): Declare.
* lib/acl-internal.c (free_permission_context): New helper function.
* lib/get-permissions.c (get_permissions): New helper function split off
from qcopy_acl.
* lib/set-permissions.c: (set_acls_from_mode): On Solaris, Cygwin, and
AIX, set a file's permissions based only on a file mode.
(acl_from_mode, context_acl_from_mode, context_aclv_from_mode): All
other platforms construct a temporary acl from the file mode and set
that acl in the same way as setting an acl read from the source file.
This should help avoid code duplication and inconsistent / buggy
behavior.
(set_acls): New helper function Split off from qcopy_acl.
(chmod_or_fchmod): Moved here from qset-acl.c.
(set_permissions): New helper function.
* lib/qcopy-acl.c (qcopy_acl): Rewrite using get_permissions and
set_permissions.
* lib/qset-acl.c (qset_acl): Rewrite using set_permissions.
* modules/qacl: Add get-permissions.c and set-permissions.c.
Diffstat (limited to 'lib/acl-internal.h')
-rw-r--r-- | lib/acl-internal.h | 57 |
1 files changed, 49 insertions, 8 deletions
diff --git a/lib/acl-internal.h b/lib/acl-internal.h index 9b9fae2e9e..11fdea1404 100644 --- a/lib/acl-internal.h +++ b/lib/acl-internal.h @@ -133,12 +133,9 @@ rpl_acl_set_fd (int fd, acl_t acl) # define acl_from_mode(mode) (NULL) # endif -/* Set to 1 if a file's mode is implicit by the ACL. - Set to 0 if a file's mode is stored independently from the ACL. */ +/* Set to 0 if a file's mode is stored independently from the ACL. */ # if (HAVE_ACL_COPY_EXT_NATIVE && HAVE_ACL_CREATE_ENTRY_NP) || defined __sgi /* Mac OS X, IRIX */ # define MODE_INSIDE_ACL 0 -# else -# define MODE_INSIDE_ACL 1 # endif /* Return the number of entries in ACL. @@ -164,12 +161,9 @@ extern int acl_access_nontrivial (acl_t); # elif HAVE_FACL && defined GETACL /* Solaris, Cygwin, not HP-UX */ -/* Set to 1 if a file's mode is implicit by the ACL. - Set to 0 if a file's mode is stored independently from the ACL. */ +/* Set to 0 if a file's mode is stored independently from the ACL. */ # if defined __CYGWIN__ /* Cygwin */ # define MODE_INSIDE_ACL 0 -# else /* Solaris */ -# define MODE_INSIDE_ACL 1 # endif /* Return 1 if the given ACL is non-trivial. @@ -248,6 +242,53 @@ extern int acl_nontrivial (int count, struct acl *entries); # endif +/* Set to 1 if a file's mode is implicit by the ACL. */ +# ifndef MODE_INSIDE_ACL +# define MODE_INSIDE_ACL 1 +# endif + #endif +struct permission_context { + mode_t mode; +#ifdef USE_ACL +# if HAVE_ACL_GET_FILE /* Linux, FreeBSD, Mac OS X, IRIX, Tru64 */ + acl_t acl; +# if !HAVE_ACL_TYPE_EXTENDED + acl_t default_acl; +# endif + bool acls_not_supported; + +# elif defined GETACL /* Solaris, Cygwin */ + int count; + aclent_t *entries; +# ifdef ACE_GETACL + int ace_count; + ace_t *ace_entries; +# endif + +# elif HAVE_GETACL /* HP-UX */ + struct acl_entry entries[NACLENTRIES]; + int count; +# if HAVE_ACLV_H + struct acl aclv_entries[NACLVENTRIES]; + int aclv_count; +# endif + +# elif HAVE_STATACL /* older AIX */ + union { struct acl a; char room[4096]; } u; + bool have_u; + +# elif HAVE_ACLSORT /* NonStop Kernel */ + struct acl entries[NACLENTRIES]; + int count; + +# endif +#endif +}; + +int get_permissions (const char *, int, mode_t, struct permission_context *); +int set_permissions (struct permission_context *, const char *, int); +void free_permission_context (struct permission_context *); + _GL_INLINE_HEADER_END |