Mercurial > hg > octave-kai > gnulib-hg
changeset 15570:cd0bdf15a524
acl: Improve support of NFSv4 ACLs on Solaris 10 (newer version).
* lib/acl-internal.h (acl_nontrivial): Declare also on newer Solaris
10.
* lib/file-has-acl.c (acl_nontrivial): Define also on newer Solaris 10.
(acl_ace_nontrivial): Likewise. Recognize the trivial ACLs with 6 ACEs.
* lib/copy-acl.c (qcopy_acl): On newer Solaris 10, use acl or facl
instead of acl_get, facl_get, acl_set, facl_set.
author | Bruno Haible <bruno@clisp.org> |
---|---|
date | Mon, 05 Sep 2011 23:45:11 +0200 |
parents | bc7d656f8f54 |
children | 5d1d1c0b8204 |
files | ChangeLog lib/acl-internal.h lib/copy-acl.c lib/file-has-acl.c |
diffstat | 4 files changed, 123 insertions(+), 22 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2011-09-05 Bruno Haible <bruno@clisp.org> + + acl: Improve support of NFSv4 ACLs on Solaris 10 (newer version). + * lib/acl-internal.h (acl_nontrivial): Declare also on newer Solaris + 10. + * lib/file-has-acl.c (acl_nontrivial): Define also on newer Solaris 10. + (acl_ace_nontrivial): Likewise. Recognize the trivial ACLs with 6 ACEs. + * lib/copy-acl.c (qcopy_acl): On newer Solaris 10, use acl or facl + instead of acl_get, facl_get, acl_set, facl_set. + 2011-09-05 Bruno Haible <bruno@clisp.org> copy-file: Try unit tests on more file systems.
--- a/lib/acl-internal.h +++ b/lib/acl-internal.h @@ -183,7 +183,7 @@ # define MODE_INSIDE_ACL 1 # endif -# if !defined ACL_NO_TRIVIAL /* Solaris <= 10, Cygwin */ +# if !(defined ACL_NO_TRIVIAL && 0) /* Solaris <= 10, Cygwin */ /* Return 1 if the given ACL is non-trivial. Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */
--- a/lib/copy-acl.c +++ b/lib/copy-acl.c @@ -181,7 +181,7 @@ #elif USE_ACL && defined GETACL /* Solaris, Cygwin, not HP-UX */ -# if defined ACL_NO_TRIVIAL +# if defined ACL_NO_TRIVIAL && 0 /* Solaris 10 (newer version), which has additional API declared in <sys/acl.h> (acl_t) and implemented in libsec (acl_set, acl_trivial, acl_fromtext, ...). */
--- a/lib/file-has-acl.c +++ b/lib/file-has-acl.c @@ -120,7 +120,7 @@ #elif USE_ACL && HAVE_FACL && defined GETACL /* Solaris, Cygwin, not HP-UX */ -# if !defined ACL_NO_TRIVIAL /* Solaris <= 10, Cygwin */ +# if !(defined ACL_NO_TRIVIAL && 0) /* Solaris <= 10, Cygwin */ /* Test an ACL retrieved with GETACL. Return 1 if the given ACL, consisting of COUNT entries, is non-trivial. @@ -167,7 +167,7 @@ int old_convention = 0; for (i = 0; i < count; i++) - if (entries[i].a_flags & (ACE_OWNER | ACE_GROUP | ACE_OTHER)) + if (entries[i].a_flags & (OLD_ACE_OWNER | OLD_ACE_GROUP | OLD_ACE_OTHER)) { old_convention = 1; break; @@ -183,28 +183,119 @@ If ace->a_flags = ACE_OWNER, ace->a_who is the st_uid from stat(). If ace->a_flags = ACE_GROUP, ace->a_who is the st_gid from stat(). We don't need to check ace->a_who in these cases. */ - if (!(ace->a_type == ALLOW - && (ace->a_flags == ACE_OWNER - || ace->a_flags == ACE_GROUP - || ace->a_flags == ACE_OTHER))) + if (!(ace->a_type == OLD_ALLOW + && (ace->a_flags == OLD_ACE_OWNER + || ace->a_flags == OLD_ACE_GROUP + || ace->a_flags == OLD_ACE_OTHER))) return 1; } else - /* Running on Solaris 10 (newer version) or Solaris 11. */ - for (i = 0; i < count; i++) - { - ace_t *ace = &entries[i]; + { + /* Running on Solaris 10 (newer version) or Solaris 11. */ + unsigned int access_masks[6] = + { + 0, /* owner@ deny */ + 0, /* owner@ allow */ + 0, /* group@ deny */ + 0, /* group@ allow */ + 0, /* everyone@ deny */ + 0 /* everyone@ allow */ + }; + + for (i = 0; i < count; i++) + { + ace_t *ace = &entries[i]; + unsigned int index1; + unsigned int index2; + + if (ace->a_type == NEW_ACE_ACCESS_ALLOWED_ACE_TYPE) + index1 = 1; + else if (ace->a_type == NEW_ACE_ACCESS_DENIED_ACE_TYPE) + index1 = 0; + else + return 1; + + if (ace->a_flags == NEW_ACE_OWNER) + index2 = 0; + else if (ace->a_flags == (NEW_ACE_GROUP | NEW_ACE_IDENTIFIER_GROUP)) + index2 = 2; + else if (ace->a_flags == ACE_EVERYONE) + index2 = 4; + else + return 1; + + access_masks[index1 + index2] |= ace->a_access_mask; + } + + /* The same bit shouldn't be both allowed and denied. */ + if (access_masks[0] & access_masks[1]) + return 1; + if (access_masks[2] & access_masks[3]) + return 1; + if (access_masks[4] & access_masks[5]) + return 1; - if (!(ace->a_type == ACE_ACCESS_ALLOWED_ACE_TYPE - && (ace->a_flags == NEW_ACE_OWNER - || ace->a_flags - == (NEW_ACE_GROUP | NEW_ACE_IDENTIFIER_GROUP) - || ace->a_flags == ACE_EVERYONE) - && (ace->a_access_mask - & ~(NEW_ACE_READ_DATA | NEW_ACE_WRITE_DATA | NEW_ACE_EXECUTE)) - == 0)) - return 1; - } + /* Check minimum masks. */ + if ((NEW_ACE_WRITE_NAMED_ATTRS + | NEW_ACE_WRITE_ATTRIBUTES + | NEW_ACE_WRITE_ACL + | NEW_ACE_WRITE_OWNER) + & ~ access_masks[1]) + return 1; + access_masks[1] &= ~(NEW_ACE_WRITE_NAMED_ATTRS + | NEW_ACE_WRITE_ATTRIBUTES + | NEW_ACE_WRITE_ACL + | NEW_ACE_WRITE_OWNER); + if ((NEW_ACE_WRITE_NAMED_ATTRS + | NEW_ACE_WRITE_ATTRIBUTES + | NEW_ACE_WRITE_ACL + | NEW_ACE_WRITE_OWNER) + & ~ access_masks[4]) + return 1; + access_masks[4] &= ~(NEW_ACE_WRITE_NAMED_ATTRS + | NEW_ACE_WRITE_ATTRIBUTES + | NEW_ACE_WRITE_ACL + | NEW_ACE_WRITE_OWNER); + if ((NEW_ACE_READ_NAMED_ATTRS + | NEW_ACE_READ_ATTRIBUTES + | NEW_ACE_READ_ACL + | NEW_ACE_SYNCHRONIZE) + & ~ access_masks[5]) + return 1; + access_masks[5] &= ~(NEW_ACE_READ_NAMED_ATTRS + | NEW_ACE_READ_ATTRIBUTES + | NEW_ACE_READ_ACL + | NEW_ACE_SYNCHRONIZE); + + /* Check the allowed or denied bits. */ + if ((access_masks[0] | access_masks[1]) + != (NEW_ACE_READ_DATA + | NEW_ACE_WRITE_DATA | NEW_ACE_APPEND_DATA + | NEW_ACE_EXECUTE)) + return 1; + if ((access_masks[2] | access_masks[3]) + != (NEW_ACE_READ_DATA + | NEW_ACE_WRITE_DATA | NEW_ACE_APPEND_DATA + | NEW_ACE_EXECUTE)) + return 1; + if ((access_masks[4] | access_masks[5]) + != (NEW_ACE_READ_DATA + | NEW_ACE_WRITE_DATA | NEW_ACE_APPEND_DATA + | NEW_ACE_EXECUTE)) + return 1; + + /* Check that the NEW_ACE_WRITE_DATA and NEW_ACE_APPEND_DATA bits are + either both allowed or both denied. */ + if (((access_masks[0] & NEW_ACE_WRITE_DATA) != 0) + != ((access_masks[0] & NEW_ACE_APPEND_DATA) != 0)) + return 1; + if (((access_masks[2] & NEW_ACE_WRITE_DATA) != 0) + != ((access_masks[2] & NEW_ACE_APPEND_DATA) != 0)) + return 1; + if (((access_masks[4] & NEW_ACE_WRITE_DATA) != 0) + != ((access_masks[4] & NEW_ACE_APPEND_DATA) != 0)) + return 1; + } return 0; }