From owner-svn-src-stable@FreeBSD.ORG Mon Nov 1 15:36:48 2010 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 50718106566C; Mon, 1 Nov 2010 15:36:48 +0000 (UTC) (envelope-from trasz@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 3C8468FC14; Mon, 1 Nov 2010 15:36:48 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id oA1Famwk069805; Mon, 1 Nov 2010 15:36:48 GMT (envelope-from trasz@svn.freebsd.org) Received: (from trasz@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id oA1FamsX069801; Mon, 1 Nov 2010 15:36:48 GMT (envelope-from trasz@svn.freebsd.org) Message-Id: <201011011536.oA1FamsX069801@svn.freebsd.org> From: Edward Tomasz Napierala Date: Mon, 1 Nov 2010 15:36:48 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r214626 - in stable/8: lib/libc/posix1e sys/kern sys/sys X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 01 Nov 2010 15:36:48 -0000 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 #include #include +#include #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,