changeset 15825:ab0a4f49f2e8

file-has-acl: revert unintended change in behavior of ls -L * lib/file-has-acl.c (acl_extended_file_wrap): New function, derived from... (file_has_acl): ...code here. Call it. This problem was introduced with 2011-07-22 commit 95f7c57f, "file-has-acl: use acl_extended_file_nofollow if available". See http://thread.gmane.org/gmane.comp.lib.gnulib.bugs/28538
author Kamil Dudka <kdudka@redhat.com>
date Mon, 03 Oct 2011 12:17:22 +0200
parents 3a4d1597833c
children 23243d868d35
files ChangeLog lib/file-has-acl.c
diffstat 2 files changed, 40 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2011-10-03  Kamil Dudka  <kdudka@redhat.com>
+
+	file-has-acl: revert unintended change in behavior of ls -L
+	* lib/file-has-acl.c (acl_extended_file_wrap): New function,
+	derived from...
+	(file_has_acl): ...code here.  Call it.
+	This problem was introduced with 2011-07-22 commit 95f7c57f,
+	"file-has-acl: use acl_extended_file_nofollow if available".
+	See http://thread.gmane.org/gmane.comp.lib.gnulib.bugs/28538
+
 2011-10-03  Bruno Haible  <bruno@clisp.org>
 
 	poll: Avoid link errors on MSVC.
--- a/lib/file-has-acl.c
+++ b/lib/file-has-acl.c
@@ -437,6 +437,34 @@
 #endif
 
 
+/* acl_extended_file() tests whether a file has an ACL.  But it can trigger
+   unnecessary autofs mounts.  In newer versions of libacl, a function
+   acl_extended_file_nofollow() is available that uses lgetxattr() and
+   therefore does not have this problem.  It is equivalent to
+   acl_extended_file(), except on symbolic links.  */
+
+static int
+acl_extended_file_wrap (char const *name)
+{
+  if ( ! HAVE_ACL_EXTENDED_FILE)
+    return -1;
+
+  if (HAVE_ACL_EXTENDED_FILE_NOFOLLOW)
+    {
+      struct stat sb;
+      if (! lstat (name, &sb) && ! S_ISLNK (sb.st_mode))
+        /* acl_extended_file_nofollow() uses lgetxattr() in order to
+           prevent unnecessary mounts.  It returns the same result as
+           acl_extended_file() since we already know that NAME is not a
+           symbolic link at this point (modulo the TOCTTOU race condition).  */
+        return acl_extended_file_nofollow (name);
+    }
+
+  /* fallback for symlinks and old versions of libacl */
+  return acl_extended_file (name);
+}
+
+
 /* Return 1 if NAME has a nontrivial access control list, 0 if NAME
    only has no or a base access control list, and -1 (setting errno)
    on error.  SB must be set to the stat buffer of NAME, obtained
@@ -454,20 +482,12 @@
       /* Linux, FreeBSD, MacOS X, IRIX, Tru64 */
       int ret;
 
-      if (HAVE_ACL_EXTENDED_FILE || HAVE_ACL_EXTENDED_FILE_NOFOLLOW) /* Linux */
+      if (HAVE_ACL_EXTENDED_FILE) /* Linux */
         {
-#  if HAVE_ACL_EXTENDED_FILE_NOFOLLOW
-          /* acl_extended_file_nofollow() uses lgetxattr() in order to prevent
-             unnecessary mounts, but it returns the same result as we already
-             know that NAME is not a symbolic link at this point (modulo the
-             TOCTTOU race condition).  */
-          ret = acl_extended_file_nofollow (name);
-#  else
           /* On Linux, acl_extended_file is an optimized function: It only
              makes two calls to getxattr(), one for ACL_TYPE_ACCESS, one for
              ACL_TYPE_DEFAULT.  */
-          ret = acl_extended_file (name);
-#  endif
+          ret = acl_extended_file_wrap (name);
         }
       else /* FreeBSD, MacOS X, IRIX, Tru64 */
         {