Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  *  Common NFSv4 ACL handling code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *  Copyright (c) 2002, 2003 The Regents of the University of Michigan.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *  All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *  Marius Aamodt Eriksen <marius@umich.edu>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *  Jeff Sedlak <jsedlak@umich.edu>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  *  J. Bruce Fields <bfields@umich.edu>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  *  Redistribution and use in source and binary forms, with or without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  *  modification, are permitted provided that the following conditions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  *  are met:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  *  1. Redistributions of source code must retain the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  *     notice, this list of conditions and the following disclaimer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  *  2. Redistributions in binary form must reproduce the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  *     notice, this list of conditions and the following disclaimer in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  *     documentation and/or other materials provided with the distribution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  *  3. Neither the name of the University nor the names of its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  *     contributors may be used to endorse or promote products derived
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  *     from this software without specific prior written permission.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  *  DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  *  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #include <linux/posix_acl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #include "nfsfh.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) #include "nfsd.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #include "acl.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #include "vfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #define NFS4_ACL_TYPE_DEFAULT	0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) #define NFS4_ACL_DIR		0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) #define NFS4_ACL_OWNER		0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) /* mode bit translations: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) #define NFS4_READ_MODE (NFS4_ACE_READ_DATA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) #define NFS4_WRITE_MODE (NFS4_ACE_WRITE_DATA | NFS4_ACE_APPEND_DATA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) #define NFS4_EXECUTE_MODE NFS4_ACE_EXECUTE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) #define NFS4_ANYONE_MODE (NFS4_ACE_READ_ATTRIBUTES | NFS4_ACE_READ_ACL | NFS4_ACE_SYNCHRONIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) #define NFS4_OWNER_MODE (NFS4_ACE_WRITE_ATTRIBUTES | NFS4_ACE_WRITE_ACL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) /* flags used to simulate posix default ACLs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) #define NFS4_INHERITANCE_FLAGS (NFS4_ACE_FILE_INHERIT_ACE \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 		| NFS4_ACE_DIRECTORY_INHERIT_ACE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) #define NFS4_SUPPORTED_FLAGS (NFS4_INHERITANCE_FLAGS \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 		| NFS4_ACE_INHERIT_ONLY_ACE \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 		| NFS4_ACE_IDENTIFIER_GROUP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) static u32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) mask_from_posix(unsigned short perm, unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	int mask = NFS4_ANYONE_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	if (flags & NFS4_ACL_OWNER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 		mask |= NFS4_OWNER_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	if (perm & ACL_READ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 		mask |= NFS4_READ_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	if (perm & ACL_WRITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 		mask |= NFS4_WRITE_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	if ((perm & ACL_WRITE) && (flags & NFS4_ACL_DIR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 		mask |= NFS4_ACE_DELETE_CHILD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	if (perm & ACL_EXECUTE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 		mask |= NFS4_EXECUTE_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	return mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) static u32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) deny_mask_from_posix(unsigned short perm, u32 flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	u32 mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	if (perm & ACL_READ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		mask |= NFS4_READ_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	if (perm & ACL_WRITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 		mask |= NFS4_WRITE_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	if ((perm & ACL_WRITE) && (flags & NFS4_ACL_DIR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 		mask |= NFS4_ACE_DELETE_CHILD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	if (perm & ACL_EXECUTE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		mask |= NFS4_EXECUTE_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	return mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) /* XXX: modify functions to return NFS errors; they're only ever
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)  * used by nfs code, after all.... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) /* We only map from NFSv4 to POSIX ACLs when setting ACLs, when we err on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)  * side of being more restrictive, so the mode bit mapping below is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)  * pessimistic.  An optimistic version would be needed to handle DENY's,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)  * but we expect to coalesce all ALLOWs and DENYs before mapping to mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)  * bits. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) low_mode_from_nfs4(u32 perm, unsigned short *mode, unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	u32 write_mode = NFS4_WRITE_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	if (flags & NFS4_ACL_DIR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 		write_mode |= NFS4_ACE_DELETE_CHILD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	*mode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	if ((perm & NFS4_READ_MODE) == NFS4_READ_MODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		*mode |= ACL_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	if ((perm & write_mode) == write_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		*mode |= ACL_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	if ((perm & NFS4_EXECUTE_MODE) == NFS4_EXECUTE_MODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		*mode |= ACL_EXECUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) static short ace2type(struct nfs4_ace *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static void _posix_to_nfsv4_one(struct posix_acl *, struct nfs4_acl *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 				unsigned int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 		struct nfs4_acl **acl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	struct inode *inode = d_inode(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	int error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	struct posix_acl *pacl = NULL, *dpacl = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	unsigned int flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	int size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	pacl = get_acl(inode, ACL_TYPE_ACCESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	if (!pacl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 		pacl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	if (IS_ERR(pacl))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 		return PTR_ERR(pacl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	/* allocate for worst case: one (deny, allow) pair each: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	size += 2 * pacl->a_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	if (S_ISDIR(inode->i_mode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		flags = NFS4_ACL_DIR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 		dpacl = get_acl(inode, ACL_TYPE_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 		if (IS_ERR(dpacl)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 			error = PTR_ERR(dpacl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 			goto rel_pacl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		if (dpacl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 			size += 2 * dpacl->a_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	*acl = kmalloc(nfs4_acl_bytes(size), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	if (*acl == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 		error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	(*acl)->naces = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	_posix_to_nfsv4_one(pacl, *acl, flags & ~NFS4_ACL_TYPE_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	if (dpacl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 		_posix_to_nfsv4_one(dpacl, *acl, flags | NFS4_ACL_TYPE_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	posix_acl_release(dpacl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) rel_pacl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	posix_acl_release(pacl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) struct posix_acl_summary {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	unsigned short owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	unsigned short users;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	unsigned short group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	unsigned short groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	unsigned short other;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	unsigned short mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) summarize_posix_acl(struct posix_acl *acl, struct posix_acl_summary *pas)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	struct posix_acl_entry *pa, *pe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	 * Only pas.users and pas.groups need initialization; previous
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	 * posix_acl_valid() calls ensure that the other fields will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	 * initialized in the following loop.  But, just to placate gcc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	memset(pas, 0, sizeof(*pas));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	pas->mask = 07;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	pe = acl->a_entries + acl->a_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	FOREACH_ACL_ENTRY(pa, acl, pe) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 		switch (pa->e_tag) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 			case ACL_USER_OBJ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 				pas->owner = pa->e_perm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 			case ACL_GROUP_OBJ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 				pas->group = pa->e_perm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 			case ACL_USER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 				pas->users |= pa->e_perm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 			case ACL_GROUP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 				pas->groups |= pa->e_perm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 			case ACL_OTHER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 				pas->other = pa->e_perm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 			case ACL_MASK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 				pas->mask = pa->e_perm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	/* We'll only care about effective permissions: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	pas->users &= pas->mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	pas->group &= pas->mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	pas->groups &= pas->mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) /* We assume the acl has been verified with posix_acl_valid. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 						unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	struct posix_acl_entry *pa, *group_owner_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	struct nfs4_ace *ace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	struct posix_acl_summary pas;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	unsigned short deny;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	int eflag = ((flags & NFS4_ACL_TYPE_DEFAULT) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 		NFS4_INHERITANCE_FLAGS | NFS4_ACE_INHERIT_ONLY_ACE : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	BUG_ON(pacl->a_count < 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	summarize_posix_acl(pacl, &pas);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	pa = pacl->a_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	ace = acl->aces + acl->naces;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	/* We could deny everything not granted by the owner: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	deny = ~pas.owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	 * but it is equivalent (and simpler) to deny only what is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	 * granted by later entries:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	deny &= pas.users | pas.group | pas.groups | pas.other;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	if (deny) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 		ace->type = NFS4_ACE_ACCESS_DENIED_ACE_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		ace->flag = eflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 		ace->access_mask = deny_mask_from_posix(deny, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 		ace->whotype = NFS4_ACL_WHO_OWNER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 		ace++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 		acl->naces++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	ace->type = NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	ace->flag = eflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	ace->access_mask = mask_from_posix(pa->e_perm, flags | NFS4_ACL_OWNER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	ace->whotype = NFS4_ACL_WHO_OWNER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	ace++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	acl->naces++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	pa++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	while (pa->e_tag == ACL_USER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 		deny = ~(pa->e_perm & pas.mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 		deny &= pas.groups | pas.group | pas.other;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 		if (deny) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 			ace->type = NFS4_ACE_ACCESS_DENIED_ACE_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 			ace->flag = eflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 			ace->access_mask = deny_mask_from_posix(deny, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 			ace->whotype = NFS4_ACL_WHO_NAMED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 			ace->who_uid = pa->e_uid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 			ace++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 			acl->naces++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 		ace->type = NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 		ace->flag = eflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		ace->access_mask = mask_from_posix(pa->e_perm & pas.mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 						   flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 		ace->whotype = NFS4_ACL_WHO_NAMED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 		ace->who_uid = pa->e_uid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 		ace++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 		acl->naces++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 		pa++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	/* In the case of groups, we apply allow ACEs first, then deny ACEs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	 * since a user can be in more than one group.  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	/* allow ACEs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	group_owner_entry = pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	ace->type = NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	ace->flag = eflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	ace->access_mask = mask_from_posix(pas.group, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	ace->whotype = NFS4_ACL_WHO_GROUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	ace++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	acl->naces++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	pa++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	while (pa->e_tag == ACL_GROUP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 		ace->type = NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 		ace->flag = eflag | NFS4_ACE_IDENTIFIER_GROUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 		ace->access_mask = mask_from_posix(pa->e_perm & pas.mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 						   flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 		ace->whotype = NFS4_ACL_WHO_NAMED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 		ace->who_gid = pa->e_gid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 		ace++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 		acl->naces++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 		pa++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	/* deny ACEs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	pa = group_owner_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	deny = ~pas.group & pas.other;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	if (deny) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 		ace->type = NFS4_ACE_ACCESS_DENIED_ACE_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 		ace->flag = eflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 		ace->access_mask = deny_mask_from_posix(deny, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 		ace->whotype = NFS4_ACL_WHO_GROUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 		ace++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 		acl->naces++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	pa++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	while (pa->e_tag == ACL_GROUP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 		deny = ~(pa->e_perm & pas.mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 		deny &= pas.other;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 		if (deny) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 			ace->type = NFS4_ACE_ACCESS_DENIED_ACE_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 			ace->flag = eflag | NFS4_ACE_IDENTIFIER_GROUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 			ace->access_mask = deny_mask_from_posix(deny, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 			ace->whotype = NFS4_ACL_WHO_NAMED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 			ace->who_gid = pa->e_gid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 			ace++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 			acl->naces++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 		pa++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	if (pa->e_tag == ACL_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 		pa++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	ace->type = NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	ace->flag = eflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	ace->access_mask = mask_from_posix(pa->e_perm, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	ace->whotype = NFS4_ACL_WHO_EVERYONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	acl->naces++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) pace_gt(struct posix_acl_entry *pace1, struct posix_acl_entry *pace2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	if (pace1->e_tag != pace2->e_tag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 		return pace1->e_tag > pace2->e_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	if (pace1->e_tag == ACL_USER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 		return uid_gt(pace1->e_uid, pace2->e_uid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	if (pace1->e_tag == ACL_GROUP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 		return gid_gt(pace1->e_gid, pace2->e_gid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) sort_pacl_range(struct posix_acl *pacl, int start, int end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	int sorted = 0, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	/* We just do a bubble sort; easy to do in place, and we're not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	 * expecting acl's to be long enough to justify anything more. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	while (!sorted) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 		sorted = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 		for (i = start; i < end; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 			if (pace_gt(&pacl->a_entries[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 				    &pacl->a_entries[i+1])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 				sorted = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 				swap(pacl->a_entries[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 				     pacl->a_entries[i + 1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) sort_pacl(struct posix_acl *pacl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 	/* posix_acl_valid requires that users and groups be in order
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	 * by uid/gid. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	/* no users or groups */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	if (!pacl || pacl->a_count <= 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 	i = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	while (pacl->a_entries[i].e_tag == ACL_USER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 		i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	sort_pacl_range(pacl, 1, i-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	BUG_ON(pacl->a_entries[i].e_tag != ACL_GROUP_OBJ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	j = ++i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	while (pacl->a_entries[j].e_tag == ACL_GROUP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 		j++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	sort_pacl_range(pacl, i, j-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)  * While processing the NFSv4 ACE, this maintains bitmasks representing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)  * which permission bits have been allowed and which denied to a given
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)  * entity: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) struct posix_ace_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	u32 allow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 	u32 deny;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) struct posix_user_ace_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 		kuid_t uid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 		kgid_t gid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 	struct posix_ace_state perms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) struct posix_ace_state_array {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	int n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 	struct posix_user_ace_state aces[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)  * While processing the NFSv4 ACE, this maintains the partial permissions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)  * calculated so far: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) struct posix_acl_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	int empty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	struct posix_ace_state owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	struct posix_ace_state group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	struct posix_ace_state other;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	struct posix_ace_state everyone;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	struct posix_ace_state mask; /* Deny unused in this case */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	struct posix_ace_state_array *users;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	struct posix_ace_state_array *groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) init_state(struct posix_acl_state *state, int cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	int alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	memset(state, 0, sizeof(struct posix_acl_state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	state->empty = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	 * In the worst case, each individual acl could be for a distinct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 	 * named user or group, but we don't know which, so we allocate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	 * enough space for either:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	alloc = sizeof(struct posix_ace_state_array)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 		+ cnt*sizeof(struct posix_user_ace_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 	state->users = kzalloc(alloc, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	if (!state->users)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 	state->groups = kzalloc(alloc, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	if (!state->groups) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 		kfree(state->users);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) free_state(struct posix_acl_state *state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 	kfree(state->users);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	kfree(state->groups);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) static inline void add_to_mask(struct posix_acl_state *state, struct posix_ace_state *astate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 	state->mask.allow |= astate->allow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) static struct posix_acl *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) posix_state_to_acl(struct posix_acl_state *state, unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	struct posix_acl_entry *pace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 	struct posix_acl *pacl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 	int nace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	 * ACLs with no ACEs are treated differently in the inheritable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 	 * and effective cases: when there are no inheritable ACEs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 	 * calls ->set_acl with a NULL ACL structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 	if (state->empty && (flags & NFS4_ACL_TYPE_DEFAULT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 	 * When there are no effective ACEs, the following will end
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 	 * up setting a 3-element effective posix ACL with all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	 * permissions zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 	if (!state->users->n && !state->groups->n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 		nace = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	else /* Note we also include a MASK ACE in this case: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 		nace = 4 + state->users->n + state->groups->n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 	pacl = posix_acl_alloc(nace, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 	if (!pacl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 		return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 	pace = pacl->a_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 	pace->e_tag = ACL_USER_OBJ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 	low_mode_from_nfs4(state->owner.allow, &pace->e_perm, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 	for (i=0; i < state->users->n; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 		pace++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 		pace->e_tag = ACL_USER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 		low_mode_from_nfs4(state->users->aces[i].perms.allow,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 					&pace->e_perm, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 		pace->e_uid = state->users->aces[i].uid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 		add_to_mask(state, &state->users->aces[i].perms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 	pace++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 	pace->e_tag = ACL_GROUP_OBJ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 	low_mode_from_nfs4(state->group.allow, &pace->e_perm, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 	add_to_mask(state, &state->group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 	for (i=0; i < state->groups->n; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 		pace++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 		pace->e_tag = ACL_GROUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 		low_mode_from_nfs4(state->groups->aces[i].perms.allow,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 					&pace->e_perm, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 		pace->e_gid = state->groups->aces[i].gid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 		add_to_mask(state, &state->groups->aces[i].perms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 	if (state->users->n || state->groups->n) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 		pace++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 		pace->e_tag = ACL_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 		low_mode_from_nfs4(state->mask.allow, &pace->e_perm, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 	pace++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 	pace->e_tag = ACL_OTHER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 	low_mode_from_nfs4(state->other.allow, &pace->e_perm, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 	return pacl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) static inline void allow_bits(struct posix_ace_state *astate, u32 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 	/* Allow all bits in the mask not already denied: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 	astate->allow |= mask & ~astate->deny;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) static inline void deny_bits(struct posix_ace_state *astate, u32 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 	/* Deny all bits in the mask not already allowed: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	astate->deny |= mask & ~astate->allow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) static int find_uid(struct posix_acl_state *state, kuid_t uid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 	struct posix_ace_state_array *a = state->users;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 	for (i = 0; i < a->n; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 		if (uid_eq(a->aces[i].uid, uid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 			return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 	/* Not found: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 	a->n++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 	a->aces[i].uid = uid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 	a->aces[i].perms.allow = state->everyone.allow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 	a->aces[i].perms.deny  = state->everyone.deny;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 	return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) static int find_gid(struct posix_acl_state *state, kgid_t gid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	struct posix_ace_state_array *a = state->groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 	for (i = 0; i < a->n; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 		if (gid_eq(a->aces[i].gid, gid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 			return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 	/* Not found: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 	a->n++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 	a->aces[i].gid = gid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 	a->aces[i].perms.allow = state->everyone.allow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 	a->aces[i].perms.deny  = state->everyone.deny;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 	return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) static void deny_bits_array(struct posix_ace_state_array *a, u32 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 	for (i=0; i < a->n; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 		deny_bits(&a->aces[i].perms, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) static void allow_bits_array(struct posix_ace_state_array *a, u32 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 	for (i=0; i < a->n; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 		allow_bits(&a->aces[i].perms, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) static void process_one_v4_ace(struct posix_acl_state *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 				struct nfs4_ace *ace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 	u32 mask = ace->access_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 	state->empty = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 	switch (ace2type(ace)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 	case ACL_USER_OBJ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 		if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 			allow_bits(&state->owner, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 			deny_bits(&state->owner, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 	case ACL_USER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 		i = find_uid(state, ace->who_uid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 		if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 			allow_bits(&state->users->aces[i].perms, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 			deny_bits(&state->users->aces[i].perms, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 			mask = state->users->aces[i].perms.deny;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 			deny_bits(&state->owner, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 	case ACL_GROUP_OBJ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 		if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 			allow_bits(&state->group, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 			deny_bits(&state->group, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 			mask = state->group.deny;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 			deny_bits(&state->owner, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 			deny_bits(&state->everyone, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 			deny_bits_array(state->users, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 			deny_bits_array(state->groups, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 	case ACL_GROUP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 		i = find_gid(state, ace->who_gid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 		if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 			allow_bits(&state->groups->aces[i].perms, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 			deny_bits(&state->groups->aces[i].perms, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 			mask = state->groups->aces[i].perms.deny;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 			deny_bits(&state->owner, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 			deny_bits(&state->group, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 			deny_bits(&state->everyone, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 			deny_bits_array(state->users, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 			deny_bits_array(state->groups, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 	case ACL_OTHER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 		if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 			allow_bits(&state->owner, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 			allow_bits(&state->group, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 			allow_bits(&state->other, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 			allow_bits(&state->everyone, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 			allow_bits_array(state->users, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 			allow_bits_array(state->groups, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 			deny_bits(&state->owner, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 			deny_bits(&state->group, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 			deny_bits(&state->other, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 			deny_bits(&state->everyone, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 			deny_bits_array(state->users, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 			deny_bits_array(state->groups, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) static int nfs4_acl_nfsv4_to_posix(struct nfs4_acl *acl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 		struct posix_acl **pacl, struct posix_acl **dpacl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 		unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 	struct posix_acl_state effective_acl_state, default_acl_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 	struct nfs4_ace *ace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 	ret = init_state(&effective_acl_state, acl->naces);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 	ret = init_state(&default_acl_state, acl->naces);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 		goto out_estate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 	ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 	for (ace = acl->aces; ace < acl->aces + acl->naces; ace++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 		if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 		    ace->type != NFS4_ACE_ACCESS_DENIED_ACE_TYPE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 			goto out_dstate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 		if (ace->flag & ~NFS4_SUPPORTED_FLAGS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 			goto out_dstate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 		if ((ace->flag & NFS4_INHERITANCE_FLAGS) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 			process_one_v4_ace(&effective_acl_state, ace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 		if (!(flags & NFS4_ACL_DIR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 			goto out_dstate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 		 * Note that when only one of FILE_INHERIT or DIRECTORY_INHERIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 		 * is set, we're effectively turning on the other.  That's OK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 		 * according to rfc 3530.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 		process_one_v4_ace(&default_acl_state, ace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 		if (!(ace->flag & NFS4_ACE_INHERIT_ONLY_ACE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 			process_one_v4_ace(&effective_acl_state, ace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 	*pacl = posix_state_to_acl(&effective_acl_state, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 	if (IS_ERR(*pacl)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 		ret = PTR_ERR(*pacl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 		*pacl = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 		goto out_dstate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 	*dpacl = posix_state_to_acl(&default_acl_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 						flags | NFS4_ACL_TYPE_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 	if (IS_ERR(*dpacl)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 		ret = PTR_ERR(*dpacl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 		*dpacl = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 		posix_acl_release(*pacl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 		*pacl = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 		goto out_dstate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 	sort_pacl(*pacl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 	sort_pacl(*dpacl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 	ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) out_dstate:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 	free_state(&default_acl_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) out_estate:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 	free_state(&effective_acl_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 		struct nfs4_acl *acl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 	__be32 error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 	int host_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) 	struct dentry *dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) 	struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 	struct posix_acl *pacl = NULL, *dpacl = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 	unsigned int flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) 	/* Get inode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 	error = fh_verify(rqstp, fhp, 0, NFSD_MAY_SATTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) 	dentry = fhp->fh_dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) 	inode = d_inode(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 	if (S_ISDIR(inode->i_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 		flags = NFS4_ACL_DIR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 	host_error = nfs4_acl_nfsv4_to_posix(acl, &pacl, &dpacl, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) 	if (host_error == -EINVAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) 		return nfserr_attrnotsupp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) 	if (host_error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) 		goto out_nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) 	fh_lock(fhp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) 	host_error = set_posix_acl(inode, ACL_TYPE_ACCESS, pacl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) 	if (host_error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) 		goto out_drop_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) 	if (S_ISDIR(inode->i_mode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) 		host_error = set_posix_acl(inode, ACL_TYPE_DEFAULT, dpacl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) out_drop_lock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) 	fh_unlock(fhp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) 	posix_acl_release(pacl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) 	posix_acl_release(dpacl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) out_nfserr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) 	if (host_error == -EOPNOTSUPP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) 		return nfserr_attrnotsupp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) 		return nfserrno(host_error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) static short
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) ace2type(struct nfs4_ace *ace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) 	switch (ace->whotype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) 		case NFS4_ACL_WHO_NAMED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) 			return (ace->flag & NFS4_ACE_IDENTIFIER_GROUP ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) 					ACL_GROUP : ACL_USER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) 		case NFS4_ACL_WHO_OWNER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) 			return ACL_USER_OBJ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) 		case NFS4_ACL_WHO_GROUP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) 			return ACL_GROUP_OBJ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) 		case NFS4_ACL_WHO_EVERYONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) 			return ACL_OTHER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) 	BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)  * return the size of the struct nfs4_acl required to represent an acl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)  * with @entries entries.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) int nfs4_acl_bytes(int entries)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) 	return sizeof(struct nfs4_acl) + entries * sizeof(struct nfs4_ace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) static struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) 	char *string;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) 	int   stringlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) 	int type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) } s2t_map[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) 		.string    = "OWNER@",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) 		.stringlen = sizeof("OWNER@") - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) 		.type      = NFS4_ACL_WHO_OWNER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) 		.string    = "GROUP@",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) 		.stringlen = sizeof("GROUP@") - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) 		.type      = NFS4_ACL_WHO_GROUP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) 		.string    = "EVERYONE@",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) 		.stringlen = sizeof("EVERYONE@") - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) 		.type      = NFS4_ACL_WHO_EVERYONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) nfs4_acl_get_whotype(char *p, u32 len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) 	for (i = 0; i < ARRAY_SIZE(s2t_map); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) 		if (s2t_map[i].stringlen == len &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) 				0 == memcmp(s2t_map[i].string, p, len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) 			return s2t_map[i].type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) 	return NFS4_ACL_WHO_NAMED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) __be32 nfs4_acl_write_who(struct xdr_stream *xdr, int who)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) 	__be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) 	for (i = 0; i < ARRAY_SIZE(s2t_map); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) 		if (s2t_map[i].type != who)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) 		p = xdr_reserve_space(xdr, s2t_map[i].stringlen + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) 		if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) 			return nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) 		p = xdr_encode_opaque(p, s2t_map[i].string,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) 					s2t_map[i].stringlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) 	WARN_ON_ONCE(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) 	return nfserr_serverfault;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) }