Author: trasz
Date: Mon Nov  1 15:36:47 2010
New Revision: 214626
URL: http://svn.freebsd.org/changeset/base/214626

Log:
  MFC r212906:
  
  First step at adopting FreeBSD to support PSARC/2010/029.  This makes
  acl_is_trivial_np(3) properly recognize the new trivial ACLs.  From
  the user point of view, that means "ls -l" no longer shows plus signs
  for all the files when running ZFS v28.

Modified:
  stable/8/lib/libc/posix1e/acl_strip.c
  stable/8/sys/kern/subr_acl_nfs4.c
  stable/8/sys/sys/acl.h
Directory Properties:
  stable/8/lib/libc/   (props changed)
  stable/8/lib/libc/locale/   (props changed)
  stable/8/lib/libc/stdtime/   (props changed)
  stable/8/lib/libc/sys/   (props changed)
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)

Modified: stable/8/lib/libc/posix1e/acl_strip.c
==============================================================================
--- stable/8/lib/libc/posix1e/acl_strip.c       Mon Nov  1 15:18:57 2010        
(r214625)
+++ stable/8/lib/libc/posix1e/acl_strip.c       Mon Nov  1 15:36:47 2010        
(r214626)
@@ -31,19 +31,21 @@ __FBSDID("$FreeBSD$");
 #include <stdio.h>
 #include <assert.h>
 #include <sys/acl.h>
+#include <sys/stat.h>
 
 #include "acl_support.h"
 
 /*
- * These two routines from sys/kern/subr_acl_nfs4.c are used by both kernel
+ * These three routines from sys/kern/subr_acl_nfs4.c are used by both kernel
  * and libc.
  */
+void   acl_nfs4_trivial_from_mode(struct acl *aclp, mode_t mode);
 void   acl_nfs4_sync_acl_from_mode(struct acl *aclp, mode_t mode,
            int file_owner_id);
 void   acl_nfs4_sync_mode_from_acl(mode_t *_mode, const struct acl *aclp);
 
 static acl_t
-_nfs4_acl_strip_np(const acl_t aclp, int recalculate_mask)
+_nfs4_acl_strip_np(const acl_t aclp, int canonical_six)
 {
        acl_t newacl;
        mode_t mode = 0;
@@ -57,7 +59,10 @@ _nfs4_acl_strip_np(const acl_t aclp, int
        _acl_brand_as(newacl, ACL_BRAND_NFS4);
 
        acl_nfs4_sync_mode_from_acl(&mode, &(aclp->ats_acl));
-       acl_nfs4_sync_acl_from_mode(&(newacl->ats_acl), mode, -1);
+       if (canonical_six)
+               acl_nfs4_sync_acl_from_mode(&(newacl->ats_acl), mode, -1);
+       else
+               acl_nfs4_trivial_from_mode(&(newacl->ats_acl), mode);
 
        return (newacl);
 }
@@ -136,7 +141,7 @@ acl_strip_np(const acl_t aclp, int recal
 {
        switch (_acl_brand(aclp)) {
        case ACL_BRAND_NFS4:
-               return (_nfs4_acl_strip_np(aclp, recalculate_mask));
+               return (_nfs4_acl_strip_np(aclp, 1));
 
        case ACL_BRAND_POSIX:
                return (_posix1e_acl_strip_np(aclp, recalculate_mask));
@@ -185,10 +190,25 @@ acl_is_trivial_np(const acl_t aclp, int 
                }
                        
                /*
-                * Calculate trivial ACL - using acl_strip_np - and compare
+                * Calculate trivial ACL - using acl_strip_np(3) - and compare
                 * with the original.
                 */
-               tmpacl = acl_strip_np(aclp, 0);
+               tmpacl = _nfs4_acl_strip_np(aclp, 0);
+               if (tmpacl == NULL)
+                       return (-1);
+
+               differs = _acl_differs(aclp, tmpacl);
+               acl_free(tmpacl);
+
+               if (differs == 0) {
+                       *trivialp = 1;
+                       return (0);
+               }
+
+               /*
+                * Try again with an old-style, "canonical six" trivial ACL.
+                */
+               tmpacl = _nfs4_acl_strip_np(aclp, 1);
                if (tmpacl == NULL)
                        return (-1);
 

Modified: stable/8/sys/kern/subr_acl_nfs4.c
==============================================================================
--- stable/8/sys/kern/subr_acl_nfs4.c   Mon Nov  1 15:18:57 2010        
(r214625)
+++ stable/8/sys/kern/subr_acl_nfs4.c   Mon Nov  1 15:36:47 2010        
(r214626)
@@ -323,6 +323,83 @@ _acl_duplicate_entry(struct acl *aclp, i
        return (&(aclp->acl_entry[entry_index + 1]));
 }
 
+/*
+ * Calculate trivial ACL in a manner compatible with PSARC/2010/029.
+ * Note that this results in an ACL different from (but semantically
+ * equal to) the "canonical six" trivial ACL computed using algorithm
+ * described in draft-ietf-nfsv4-minorversion1-03.txt, 3.16.6.2.
+ */
+void
+acl_nfs4_trivial_from_mode(struct acl *aclp, mode_t mode)
+{
+       acl_perm_t user_allow_first = 0, user_deny = 0, group_deny = 0;
+       acl_perm_t user_allow, group_allow, everyone_allow;
+
+       KASSERT(aclp->acl_cnt == 0, ("aclp->acl_cnt == 0"));
+
+       user_allow = group_allow = everyone_allow = ACL_READ_ACL |
+           ACL_READ_ATTRIBUTES | ACL_READ_NAMED_ATTRS | ACL_SYNCHRONIZE;
+       user_allow |= ACL_WRITE_ACL | ACL_WRITE_OWNER | ACL_WRITE_ATTRIBUTES |
+           ACL_WRITE_NAMED_ATTRS;
+
+       if (mode & S_IRUSR)
+               user_allow |= ACL_READ_DATA;
+       if (mode & S_IWUSR)
+               user_allow |= (ACL_WRITE_DATA | ACL_APPEND_DATA);
+       if (mode & S_IXUSR)
+               user_allow |= ACL_EXECUTE;
+
+       if (mode & S_IRGRP)
+               group_allow |= ACL_READ_DATA;
+       if (mode & S_IWGRP)
+               group_allow |= (ACL_WRITE_DATA | ACL_APPEND_DATA);
+       if (mode & S_IXGRP)
+               group_allow |= ACL_EXECUTE;
+
+       if (mode & S_IROTH)
+               everyone_allow |= ACL_READ_DATA;
+       if (mode & S_IWOTH)
+               everyone_allow |= (ACL_WRITE_DATA | ACL_APPEND_DATA);
+       if (mode & S_IXOTH)
+               everyone_allow |= ACL_EXECUTE;
+
+       user_deny = ((group_allow | everyone_allow) & ~user_allow);
+       group_deny = everyone_allow & ~group_allow;
+       user_allow_first = group_deny & ~user_deny;
+
+#if 1
+       /*
+        * This is a workaround for what looks like a bug in ZFS - trivial
+        * ACL for mode 0077 should look like this:
+        *
+        *    owner@:rwxp----------:------:deny
+        *    owner@:------aARWcCos:------:allow
+        *    group@:rwxp--a-R-c--s:------:allow
+        * everyone@:rwxp--a-R-c--s:------:allow
+        *
+        * Instead, ZFS makes it like this:
+        *
+        *    owner@:rwx-----------:------:deny
+        *    owner@:------aARWcCos:------:allow
+        *    group@:rwxp--a-R-c--s:------:allow
+        * everyone@:rwxp--a-R-c--s:------:allow
+        */
+       user_allow_first &= ~ACL_APPEND_DATA;
+       user_deny &= ~ACL_APPEND_DATA;
+       group_deny &= ~ACL_APPEND_DATA;
+#endif
+
+       if (user_allow_first != 0)
+               _acl_append(aclp, ACL_USER_OBJ, user_allow_first, 
ACL_ENTRY_TYPE_ALLOW);
+       if (user_deny != 0)
+               _acl_append(aclp, ACL_USER_OBJ, user_deny, ACL_ENTRY_TYPE_DENY);
+       if (group_deny != 0)
+               _acl_append(aclp, ACL_GROUP_OBJ, group_deny, 
ACL_ENTRY_TYPE_DENY);
+       _acl_append(aclp, ACL_USER_OBJ, user_allow, ACL_ENTRY_TYPE_ALLOW);
+       _acl_append(aclp, ACL_GROUP_OBJ, group_allow, ACL_ENTRY_TYPE_ALLOW);
+       _acl_append(aclp, ACL_EVERYONE, everyone_allow, ACL_ENTRY_TYPE_ALLOW);
+}
+
 void
 acl_nfs4_sync_acl_from_mode(struct acl *aclp, mode_t mode, int file_owner_id)
 {

Modified: stable/8/sys/sys/acl.h
==============================================================================
--- stable/8/sys/sys/acl.h      Mon Nov  1 15:18:57 2010        (r214625)
+++ stable/8/sys/sys/acl.h      Mon Nov  1 15:36:47 2010        (r214626)
@@ -285,6 +285,8 @@ mode_t                      acl_posix1e_newfilemode(mode_t 
 struct acl             *acl_alloc(int flags);
 void                   acl_free(struct acl *aclp);
 
+void                   acl_nfs4_trivial_from_mode(struct acl *aclp,
+                           mode_t mode);
 void                   acl_nfs4_sync_acl_from_mode(struct acl *aclp,
                            mode_t mode, int file_owner_id);
 void                   acl_nfs4_sync_mode_from_acl(mode_t *mode,
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to