summaryrefslogtreecommitdiffstats
path: root/sys/kern/subr_acl_nfs4.c
diff options
context:
space:
mode:
authortrasz <trasz@FreeBSD.org>2010-09-20 17:10:06 +0000
committertrasz <trasz@FreeBSD.org>2010-09-20 17:10:06 +0000
commit3e2d23f909272476403e9cfd83e4f5c8c0110d07 (patch)
treef8114c58aa3c9da5fbe374cab1b67f84701f28fa /sys/kern/subr_acl_nfs4.c
parent154966ba66b85cf61d19a97a29e55b603e63a9ec (diff)
downloadFreeBSD-src-3e2d23f909272476403e9cfd83e4f5c8c0110d07.zip
FreeBSD-src-3e2d23f909272476403e9cfd83e4f5c8c0110d07.tar.gz
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.
Diffstat (limited to 'sys/kern/subr_acl_nfs4.c')
-rw-r--r--sys/kern/subr_acl_nfs4.c77
1 files changed, 77 insertions, 0 deletions
diff --git a/sys/kern/subr_acl_nfs4.c b/sys/kern/subr_acl_nfs4.c
index 5b2b086..3498ddf 100644
--- a/sys/kern/subr_acl_nfs4.c
+++ b/sys/kern/subr_acl_nfs4.c
@@ -349,6 +349,83 @@ _acl_duplicate_entry(struct acl *aclp, int entry_index)
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)
{
OpenPOWER on IntegriCloud