X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Ffile-has-acl.c;h=c3b77c395f85debf29442189cacd2c7d47121655;hb=567f85cfcdb0a63cf96730d0858581b013765d59;hp=9589db9656dec234413ae4b5193950de6688d03f;hpb=45b218a2676681aa16f4bc92578abae99cad4921;p=gnulib.git diff --git a/lib/file-has-acl.c b/lib/file-has-acl.c index 9589db965..c3b77c395 100644 --- a/lib/file-has-acl.c +++ b/lib/file-has-acl.c @@ -1,6 +1,6 @@ /* Test whether a file has a nontrivial access control list. - Copyright (C) 2002-2003, 2005-2008 Free Software Foundation, Inc. + Copyright (C) 2002-2003, 2005-2009 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -55,11 +55,11 @@ acl_access_nontrivial (acl_t acl) # if HAVE_ACL_FIRST_ENTRY /* Linux, FreeBSD */ acl_entry_t ace; - int at_end; + int got_one; - for (at_end = acl_get_entry (acl, ACL_FIRST_ENTRY, &ace); - !at_end; - at_end = acl_get_entry (acl, ACL_NEXT_ENTRY, &ace)) + for (got_one = acl_get_entry (acl, ACL_FIRST_ENTRY, &ace); + got_one > 0; + got_one = acl_get_entry (acl, ACL_NEXT_ENTRY, &ace)) { acl_tag_t tag; if (acl_get_tag_type (ace, &tag) < 0) @@ -67,7 +67,7 @@ acl_access_nontrivial (acl_t acl) if (!(tag == ACL_USER_OBJ || tag == ACL_GROUP_OBJ || tag == ACL_OTHER)) return 1; } - return 0; + return got_one; # else /* IRIX, Tru64 */ # if HAVE_ACL_TO_SHORT_TEXT /* IRIX */ @@ -120,6 +120,8 @@ acl_access_nontrivial (acl_t acl) #elif USE_ACL && HAVE_ACL && defined GETACL /* Solaris, Cygwin, not HP-UX */ +# if !defined ACL_NO_TRIVIAL /* Solaris <= 10, Cygwin */ + /* Test an ACL retrieved with GETACL. Return 1 if the given ACL, consisting of COUNT entries, is non-trivial. Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */ @@ -146,7 +148,7 @@ acl_nontrivial (int count, aclent_t *entries) return 0; } -# ifdef ACE_GETACL +# ifdef ACE_GETACL /* Test an ACL retrieved with ACE_GETACL. Return 1 if the given ACL, consisting of COUNT entries, is non-trivial. @@ -156,22 +158,59 @@ acl_ace_nontrivial (int count, ace_t *entries) { int i; + /* The flags in the ace_t structure changed in a binary incompatible way + when ACL_NO_TRIVIAL etc. were introduced in version 1.15. + How to distinguish the two conventions at runtime? + In the old convention, usually three ACEs have a_flags = ACE_OWNER / + ACE_GROUP / ACE_OTHER, in the range 0x0100..0x0400. In the new + convention, these values are not used. */ + int old_convention = 0; + for (i = 0; i < count; i++) - { - ace_t *ace = &entries[i]; - - /* Note: 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))) - return 1; - } + if (entries[i].a_flags & (ACE_OWNER | ACE_GROUP | ACE_OTHER)) + { + old_convention = 1; + break; + } + + if (old_convention) + /* Running on Solaris 10. */ + for (i = 0; i < count; i++) + { + ace_t *ace = &entries[i]; + + /* Note: + 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))) + return 1; + } + else + /* Running on Solaris 10 (newer version) or Solaris 11. */ + for (i = 0; i < count; i++) + { + ace_t *ace = &entries[i]; + + 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; + } + return 0; } +# endif + # endif #elif USE_ACL && HAVE_GETACL /* HP-UX */ @@ -310,7 +349,7 @@ file_has_acl (char const *name, struct stat const *sb) # elif HAVE_ACL && defined GETACLCNT /* Solaris, Cygwin, not HP-UX */ -# if HAVE_ACL_TRIVIAL +# if defined ACL_NO_TRIVIAL /* Solaris 10 (newer version), which has additional API declared in (acl_t) and implemented in libsec (acl_set, acl_trivial,