// SPDX-License-Identifier: GPL-2.0-only /* * fs/nfs_common/nfsacl.c * * Copyright (C) 2002-2003 Andreas Gruenbacher <[email protected]> */ /* * The Solaris nfsacl protocol represents some ACLs slightly differently * than POSIX 1003.1e draft 17 does (and we do): * * - Minimal ACLs always have an ACL_MASK entry, so they have * four instead of three entries. * - The ACL_MASK entry in such minimal ACLs always has the same * permissions as the ACL_GROUP_OBJ entry. (In extended ACLs * the ACL_MASK and ACL_GROUP_OBJ entries may differ.) * - The identifier fields of the ACL_USER_OBJ and ACL_GROUP_OBJ * entries contain the identifiers of the owner and owning group. * (In POSIX ACLs we always set them to ACL_UNDEFINED_ID). * - ACL entries in the kernel are kept sorted in ascending order * of (e_tag, e_id). Solaris ACLs are unsorted. */ #include <linux/module.h> #include <linux/fs.h> #include <linux/gfp.h> #include <linux/sunrpc/xdr.h> #include <linux/nfsacl.h> #include <linux/nfs3.h> #include <linux/sort.h> MODULE_DESCRIPTION(…) …; MODULE_LICENSE(…) …; struct nfsacl_encode_desc { … }; struct nfsacl_simple_acl { … }; static int xdr_nfsace_encode(struct xdr_array2_desc *desc, void *elem) { … } /** * nfsacl_encode - Encode an NFSv3 ACL * * @buf: destination xdr_buf to contain XDR encoded ACL * @base: byte offset in xdr_buf where XDR'd ACL begins * @inode: inode of file whose ACL this is * @acl: posix_acl to encode * @encode_entries: whether to encode ACEs as well * @typeflag: ACL type: NFS_ACL_DEFAULT or zero * * Returns size of encoded ACL in bytes or a negative errno value. */ int nfsacl_encode(struct xdr_buf *buf, unsigned int base, struct inode *inode, struct posix_acl *acl, int encode_entries, int typeflag) { … } EXPORT_SYMBOL_GPL(…); /** * nfs_stream_encode_acl - Encode an NFSv3 ACL * * @xdr: an xdr_stream positioned to receive an encoded ACL * @inode: inode of file whose ACL this is * @acl: posix_acl to encode * @encode_entries: whether to encode ACEs as well * @typeflag: ACL type: NFS_ACL_DEFAULT or zero * * Return values: * %false: The ACL could not be encoded * %true: @xdr is advanced to the next available position */ bool nfs_stream_encode_acl(struct xdr_stream *xdr, struct inode *inode, struct posix_acl *acl, int encode_entries, int typeflag) { … } EXPORT_SYMBOL_GPL(…); struct nfsacl_decode_desc { … }; static int xdr_nfsace_decode(struct xdr_array2_desc *desc, void *elem) { … } static int cmp_acl_entry(const void *x, const void *y) { … } /* * Convert from a Solaris ACL to a POSIX 1003.1e draft 17 ACL. */ static int posix_acl_from_nfsacl(struct posix_acl *acl) { … } /** * nfsacl_decode - Decode an NFSv3 ACL * * @buf: xdr_buf containing XDR'd ACL data to decode * @base: byte offset in xdr_buf where XDR'd ACL begins * @aclcnt: count of ACEs in decoded posix_acl * @pacl: buffer in which to place decoded posix_acl * * Returns the length of the decoded ACL in bytes, or a negative errno value. */ int nfsacl_decode(struct xdr_buf *buf, unsigned int base, unsigned int *aclcnt, struct posix_acl **pacl) { … } EXPORT_SYMBOL_GPL(…); /** * 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) { … } EXPORT_SYMBOL_GPL(…);