changeset 18050:5721cf9a74dd

acl-permissions: Fix on FreeBSD When a directory doesn't have an ACL_TYPE_DEFAULT acl, acl_get_file will return an empty acl, but when trying to set that acl, FreeBSD's acl_set_file will fail with errno == EINVAL. Instead, FreeBSD expects acl_delete_def_file to be used. * lib/acl-internal.c (acl_default_nontrivial): Recognize empty default acls. * lib/set-permissions.c (set_acls): Avoid calling acl_set_file for empty ACL_TYPE_DEFAULT acls.
author Andreas Gruenbacher <andreas.gruenbacher@gmail.com>
date Tue, 30 Jun 2015 21:09:28 +0200
parents c0df04e73c91
children 07dbc84077fc
files lib/acl-internal.c lib/acl-internal.h lib/set-permissions.c
diffstat 3 files changed, 15 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/lib/acl-internal.c
+++ b/lib/acl-internal.c
@@ -115,6 +115,13 @@
 #  endif
 }
 
+int
+acl_default_nontrivial (acl_t acl)
+{
+  /* acl is non-trivial if it is non-empty.  */
+  return (acl_entries (acl) > 0);
+}
+
 # endif
 
 #elif USE_ACL && HAVE_FACL && defined GETACL /* Solaris, Cygwin, not HP-UX */
--- a/lib/acl-internal.h
+++ b/lib/acl-internal.h
@@ -155,6 +155,12 @@
    Return 0 if it is trivial, i.e. equivalent to a simple stat() mode.
    Return -1 and set errno upon failure to determine it.  */
 extern int acl_access_nontrivial (acl_t);
+
+/* ACL is an ACL, from a file, stored as type ACL_TYPE_DEFAULT.
+   Return 1 if the given ACL is non-trivial.
+   Return 0 if it is trivial, i.e. equivalent to a simple stat() mode.
+   Return -1 and set errno upon failure to determine it.  */
+extern int acl_default_nontrivial (acl_t);
 #  endif
 
 # elif HAVE_FACL && defined GETACL /* Solaris, Cygwin, not HP-UX */
--- a/lib/set-permissions.c
+++ b/lib/set-permissions.c
@@ -530,7 +530,8 @@
 	      *acls_set = true;
 	      if (S_ISDIR(ctx->mode))
 		{
-		  if (! from_mode && ctx->default_acl)
+		  if (! from_mode && ctx->default_acl &&
+		      acl_default_nontrivial (ctx->default_acl))
 		    ret = acl_set_file (name, ACL_TYPE_DEFAULT,
 					ctx->default_acl);
 		  else