From: Kamil Dudka Date: Mon, 3 Oct 2011 10:17:22 +0000 (+0200) Subject: file-has-acl: revert unintended change in behavior of ls -L X-Git-Tag: v0.1~1701 X-Git-Url: http://erislabs.org.uk/gitweb/?a=commitdiff_plain;h=80af92af;p=gnulib.git 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 --- diff --git a/ChangeLog b/ChangeLog index 7906531a1..6715d96dd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2011-10-03 Kamil Dudka + + 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 poll: Avoid link errors on MSVC. diff --git a/lib/file-has-acl.c b/lib/file-has-acl.c index 9a5e249c2..532cafca7 100644 --- a/lib/file-has-acl.c +++ b/lib/file-has-acl.c @@ -437,6 +437,34 @@ acl_nontrivial (int count, struct acl *entries) #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 @@ file_has_acl (char const *name, struct stat const *sb) /* 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 */ {