forked from Minki/linux
NFSD: Add an xdr_stream-based decoder for NFSv2/3 ACLs
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
This commit is contained in:
parent
635a45d347
commit
6bb844b4eb
@ -295,3 +295,55 @@ int nfsacl_decode(struct xdr_buf *buf, unsigned int base, unsigned int *aclcnt,
|
||||
nfsacl_desc.desc.array_len;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfsacl_decode);
|
||||
|
||||
/**
|
||||
* nfs_stream_decode_acl - Decode an NFSv3 ACL
|
||||
*
|
||||
* @xdr: an xdr_stream positioned at an encoded ACL
|
||||
* @aclcnt: OUT: count of ACEs in decoded posix_acl
|
||||
* @pacl: OUT: a dynamically-allocated buffer containing the decoded posix_acl
|
||||
*
|
||||
* Return values:
|
||||
* %false: The encoded ACL is not valid
|
||||
* %true: @pacl contains a decoded ACL, and @xdr is advanced
|
||||
*
|
||||
* On a successful return, caller must release *pacl using posix_acl_release().
|
||||
*/
|
||||
bool nfs_stream_decode_acl(struct xdr_stream *xdr, unsigned int *aclcnt,
|
||||
struct posix_acl **pacl)
|
||||
{
|
||||
const size_t elem_size = XDR_UNIT * 3;
|
||||
struct nfsacl_decode_desc nfsacl_desc = {
|
||||
.desc = {
|
||||
.elem_size = elem_size,
|
||||
.xcode = pacl ? xdr_nfsace_decode : NULL,
|
||||
},
|
||||
};
|
||||
unsigned int base;
|
||||
u32 entries;
|
||||
|
||||
if (xdr_stream_decode_u32(xdr, &entries) < 0)
|
||||
return false;
|
||||
if (entries > NFS_ACL_MAX_ENTRIES)
|
||||
return false;
|
||||
|
||||
base = xdr_stream_pos(xdr);
|
||||
if (!xdr_inline_decode(xdr, XDR_UNIT + elem_size * entries))
|
||||
return false;
|
||||
nfsacl_desc.desc.array_maxlen = entries;
|
||||
if (xdr_decode_array2(xdr->buf, base, &nfsacl_desc.desc))
|
||||
return false;
|
||||
|
||||
if (pacl) {
|
||||
if (entries != nfsacl_desc.desc.array_len ||
|
||||
posix_acl_from_nfsacl(nfsacl_desc.acl) != 0) {
|
||||
posix_acl_release(nfsacl_desc.acl);
|
||||
return false;
|
||||
}
|
||||
*pacl = nfsacl_desc.acl;
|
||||
}
|
||||
if (aclcnt)
|
||||
*aclcnt = entries;
|
||||
return true;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_stream_decode_acl);
|
||||
|
@ -38,5 +38,8 @@ nfsacl_encode(struct xdr_buf *buf, unsigned int base, struct inode *inode,
|
||||
extern int
|
||||
nfsacl_decode(struct xdr_buf *buf, unsigned int base, unsigned int *aclcnt,
|
||||
struct posix_acl **pacl);
|
||||
extern bool
|
||||
nfs_stream_decode_acl(struct xdr_stream *xdr, unsigned int *aclcnt,
|
||||
struct posix_acl **pacl);
|
||||
|
||||
#endif /* __LINUX_NFSACL_H */
|
||||
|
Loading…
Reference in New Issue
Block a user