diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index b4eba19fafde..e7ac249df1ad 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -71,13 +71,6 @@ #include "nfs4trace.h" -#if CONFIG_TRUENAS -#include "../nfs_common/nfs41acl_xdr.h" - -/* 0xFFFFFFFFFFFFFFFF == 18446744073709551615, len('18446744073709551615') == 20 */ -#define U64_STRBUF_SIZE 21 -#endif /* CONFIG_TRUENAS */ - #define NFSDBG_FACILITY NFSDBG_PROC #define NFS4_BITMASK_SZ 3 @@ -7803,508 +7796,6 @@ static bool nfs4_xattr_list_nfs4_sacl(struct dentry *dentry) return nfs4_server_supports_acls(NFS_SB(dentry->d_sb), NFS4ACL_SACL); } -#if CONFIG_TRUENAS -/* - * We will publish the DACL thru NA41_NAME ("system.nfs4_acl_xdr") - * - * First some support functions. These may be similar to upstream - * functions in nfsd. - */ - -/* - * return the size of the struct nfs4_acl required to represent an acl - * with @entries entries. - */ -static int nfs4_acl_bytes(int entries) -{ - return sizeof(struct nfs4_acl) + entries * sizeof(struct nfs4_ace); -} - -static struct { - char *string; - int stringlen; - int type; -} s2t_map[] = { - { - .string = "OWNER@", - .stringlen = sizeof("OWNER@") - 1, - .type = NFS4_ACL_WHO_OWNER, - }, - { - .string = "GROUP@", - .stringlen = sizeof("GROUP@") - 1, - .type = NFS4_ACL_WHO_GROUP, - }, - { - .string = "EVERYONE@", - .stringlen = sizeof("EVERYONE@") - 1, - .type = NFS4_ACL_WHO_EVERYONE, - }, -}; - -static int nfs4_acl_get_whotype(char *p, u32 len) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(s2t_map); i++) { - if (s2t_map[i].stringlen == len && - (memcmp(s2t_map[i].string, p, len) == 0)) - return s2t_map[i].type; - } - return NFS4_ACL_WHO_NAMED; -} - -/* - * XDR encode the ace who into the supplied buffer. - * - * Return the number of bytes (including the leading nbytes and - * any padding necessary) - */ -static int nfs4_ace_encode_who(struct nfs4_ace *ace, char *buf) -{ - u32 *p = (u32 *)buf; - int count = -EINVAL; - const char *pstr = NULL; - char idbuf[U64_STRBUF_SIZE]; /* Future-proof in case uid_t / gid_t change size */ - int total_bytes, pad_count; - - /* - * First find the size of the string (into count) - * - * Will also have some side-effects which will be used below: - * either idbuf will be populated (for NFS4_ACL_WHO_NAMED) or - * pstr will point into s2t_map. - */ - if (ace->whotype == NFS4_ACL_WHO_NAMED) { - if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP) { - gid_t gid = from_kgid_munged(&init_user_ns, ace->who_gid); - - snprintf(idbuf, sizeof(idbuf), "%llu", (unsigned long long)gid); - } else { - uid_t uid = from_kuid_munged(&init_user_ns, ace->who_uid); - - snprintf(idbuf, sizeof(idbuf), "%llu", (unsigned long long)uid); - } - count = strlen(idbuf); - } else { - int i; - - for (i = 0; i < ARRAY_SIZE(s2t_map); i++) { - if (ace->whotype == s2t_map[i].type) { - count = s2t_map[i].stringlen; - pstr = s2t_map[i].string; - break; - } - } - } - if (count < 0) - return count; /* error */ - - /* - * who is a utf8str_mixed, i.e. a utf8string. Per RFC 1832 - * this is encoded as a uint32_t length followed by - * string bytes, and then padded by null up to a 4 byte - * boundary. - */ - total_bytes = 4 + (XDR_QUADLEN(count) << 2); - if (!buf) - return total_bytes; - pad_count = total_bytes - (4 + count); - - /* - * A buffer was supplied. Write the string length, followed by the - * string bytes and then null padding, if necessary. - */ - *p++ = htonl(count); - if (ace->whotype == NFS4_ACL_WHO_NAMED) - memcpy(p, idbuf, count); - else - memcpy(p, pstr, count); - if (pad_count) { - char *pad = buf + (4 + count); - - memset(pad, 0, pad_count); - } - return total_bytes; -} - -/* - * Convert the specified (numeric) name into a unsigned long long ID. - * - * Do this rather than u32 in an effort to future-proof. - * - * Returns true on success. - */ -static bool numeric_name_to_id(const char *name, u32 namelen, unsigned long long *id) -{ - int ret; - char buf[U64_STRBUF_SIZE]; - - if (id && (namelen + 1 > sizeof(buf))) - /* no id buffer or too long to represent a 64-bit id: */ - return false; - /* Just to make sure it's null-terminated: */ - memcpy(buf, name, namelen); - buf[namelen] = '\0'; - ret = kstrtoull(buf, 10, id); - return ret == 0; -} - -/* - * Decode the XDR data supplied in data parameter into an ACE. - * - * Upon success 0 is returned, and the data parameter is advanced. - */ -static int nfs4_decode_nfsace4(void **data, size_t *remaining, struct nfs4_ace *ace) -{ - u32 *p = *data; - u32 length, length_incl_padding; - int error = 0; - - /* - * Per RFC8881 6.2.1 acl the format of nfsace4 is: - * uint32_t type - * uint32_t flag - * uint32_t access_mask - * utf8str_mixed who - * - * where utf8str_mixed is a utf8string. Per RFC 1832 - * this is encoded as a uint32_t length followed by - * string bytes, and then padded by null up to a 4 byte - * boundary. - * - * When it comes to checking remaining, first we will check - * the first four uint32_t (4*4 -> 16 bytes), so that we can - * read the length of the who string. We do not modify remaining - * unless we are successful in decoding the ACE & advancing thru - * the data buffer. - */ - #define NFSACE4_HEADER_BYTES (4 * sizeof(u32)) - if (*remaining < NFSACE4_HEADER_BYTES) { - pr_err("NFS: %s buffer not large enough to contain ACE head", __func__); - return -EOVERFLOW; - } - ace->type = ntohl(*(p++)); - ace->flag = ntohl(*(p++)); - ace->access_mask = ntohl(*(p++)); - length = ntohl(*(p++)); - length_incl_padding = XDR_QUADLEN(length) << 2; - - /* - * Now that we have the length, check remaining again. - * - * The input buffer includes both the string and null - * padding (if necessary to align things). - */ - if (*remaining < (NFSACE4_HEADER_BYTES + length_incl_padding)) { - pr_err("NFS: %s buffer not large enough to contain ACE who", __func__); - return -EOVERFLOW; - } - - ace->whotype = nfs4_acl_get_whotype((char *)p, length); - - if (ace->whotype == NFS4_ACL_WHO_NAMED) { - /* - * We're just going to support numeric IDs here. - * (it's very expensive to do otherwise) - */ - unsigned long long id = -1; - - if (numeric_name_to_id((const char *)p, length, &id)) { - if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP) { - ace->who_gid = make_kgid(&init_user_ns, id); - if (!gid_valid(ace->who_gid)) { - pr_err("NFS: %s Invalid who_gid: %.*s", __func__, - length, (char *)p); - error = -EINVAL; - } - } else { - ace->who_uid = make_kuid(&init_user_ns, id); - if (!uid_valid(ace->who_uid)) { - pr_err("NFS: %s Invalid who_uid: %.*s", __func__, - length, (char *)p); - error = -EINVAL; - } - } - } else { - pr_err("NFS: %s Non-numeric who: %.*s", __func__, length, (char *)p); - error = -EINVAL; - } - } - /* - * If the whotype was a value other than NFS4_ACL_WHO_NAMED - * (e.g. NFS4_ACL_WHO_OWNER), then no further decoding is - * required (so, no else statement). - */ - - if (error >= 0) { - /* - * Advance by a multiple of 4 bytes (string + padding). - * Since p is a pointer to u32 we don't need to << 2 the - * output from XDR_QUADLEN. - */ - p += XDR_QUADLEN(length); - *data = p; - /* Reduce remaining by initial 4 uint32_t + the string (incl padding) */ - *remaining -= (NFSACE4_HEADER_BYTES + length_incl_padding); - } - return error; -} - -/* - * Decode the buffer containing the raw XDR data into struct nfs4_acl. - * - * This is similar to nfsd4_decode_acl - */ -static int nfs4_aclbuf_decode(void *buf, size_t buflen, enum nfs4_acl_type type, - struct nfs4_acl **pacl) -{ - u32 acl_flag, count; - u32 *p = buf; - struct nfs4_acl *acl; - int acl_bytes; - struct nfs4_ace *ace; - int status; - size_t remaining; - - if (buflen < 8) { - pr_err("NFS: %s ACL buffer too small: %zd", __func__, buflen); - return -EINVAL; - } - - acl_flag = ntohl(*(p++)); - count = ntohl(*(p++)); - remaining = buflen - 8; - acl_bytes = nfs4_acl_bytes(count); - acl = kmalloc(acl_bytes, GFP_KERNEL); - if (acl == NULL) - return -ENOMEM; - - acl->flag = acl_flag; - acl->naces = count; - for (ace = acl->aces; ace < acl->aces + count; ace++) { - status = nfs4_decode_nfsace4((void **)&p, &remaining, ace); - if (status) { - kfree(acl); - return status; - } - } - - *pacl = acl; - return acl_bytes; -} - -/* - * XDR encode the specified ACL. - * - * Returns 0 on success, and populates the buf and buflen parameters. The - * buf must be freed by the caller. - */ -static int nfs4_encode_acl_to_buf(struct nfs4_acl *acl, void **buf, size_t *buflen) -{ - int byte_count = 0; - struct nfs4_ace *ace; - void *xdrbuf; - u32 *p; - - /* - * First count how many bytes we will need. - */ - byte_count += 8; /* acl_type and naces */ - for (ace = acl->aces; ace < acl->aces + acl->naces; ace++) { - int who_bytes; - - byte_count += 12; /* ace type, flag, access_mask */ - who_bytes = nfs4_ace_encode_who(ace, NULL); - if (who_bytes < 0) { - pr_err("NFS: %s Failed to determine bytes for ACE (%d)", __func__, - who_bytes); - return who_bytes; - } - byte_count += who_bytes; - } - - xdrbuf = kmalloc(byte_count, GFP_KERNEL); - if (xdrbuf == NULL) - return -ENOMEM; - - /* - * Next encode the acl to the buffer - */ - p = xdrbuf; - *p++ = htonl(acl->flag); - *p++ = htonl(acl->naces); - for (ace = acl->aces; ace < acl->aces + acl->naces; ace++) { - int bytes; - *p++ = htonl(ace->type); - *p++ = htonl(ace->flag); - *p++ = htonl(ace->access_mask); - bytes = nfs4_ace_encode_who(ace, (char *)p); - p += (bytes >> 2); /* >> 2 because pointer to u32 */ - } - - /* Return the allocated buffer */ - *buf = xdrbuf; - *buflen = byte_count; - return 0; -} - -/* - * Allow the client to WRITE the NA41_NAME ("system.nfs4_acl_xdr") - */ -static int nfs4_xattr_set_nfs4_acl_xdr(const struct xattr_handler *handler, - struct mnt_idmap *idmap, - struct dentry *unused, struct inode *inode, - const char *key, const void *buf, - size_t buflen, int flags) -{ - u32 *p = (u32 *)buf; - u32 acl_flag, ace_cnt; - struct nfs4_acl *acl = NULL; - int error; - void *xdrbuf = NULL; - size_t xdrbuflen; - - /* Ensure data was provided */ - if (!buf || !buflen || buflen < 8) - return -EINVAL; - - /* - * In order to write this view (system.nfs4_acl_xdr) of our ZFS ACL - * we will need to: - * - Decode supplied data (system.nfs4_acl_xdr) to struct nfs4_acl - * - Encode struct nfs4_acl to DACL XDR - * - Write the DACL XDR. The nfsd will store it as the NA41_NAME. - * - * To perform the first step we will also need to decode the number - * of ACEs to calculate the size of the buffer required. - */ - - /* Mask out bits from the DACL flag that are not supported by the protocol */ - acl_flag = ntohl(*(p++)) & (ACL4_AUTO_INHERIT | ACL4_PROTECTED | ACL4_DEFAULTED); - ace_cnt = ntohl(*(p++)); - if (ace_cnt > NFS41ACL_MAX_ENTRIES) - return -ERANGE; - - /* Allocate a buffer for the struct nfs4_acl */ - acl = kzalloc(nfs4_acl_bytes(ace_cnt), GFP_KERNEL); - if (!acl) - return -ENOMEM; - - /* Decode supplied data (system.nfs4_acl_xdr) to struct nfs4_acl */ - acl->flag = acl_flag; - acl->naces = ace_cnt; - error = convert_nfs41xdr_to_nfs40_acl(p++, buflen - (2 * sizeof(u32)), acl); - if (error) - goto acl_out; - - /* Encode struct nfs4_acl to DACL XDR */ - error = nfs4_encode_acl_to_buf(acl, &xdrbuf, &xdrbuflen); - if (error) - goto acl_out; - - /* Write the DACL XDR. */ - error = nfs4_proc_set_acl(inode, xdrbuf, xdrbuflen, NFS4ACL_DACL); - kfree(xdrbuf); - -acl_out: - kfree(acl); - return error; -} - -/* - * Allow the client to READ the NA41_NAME ("system.nfs4_acl_xdr") - */ -static int nfs4_xattr_get_nfs4_acl_xdr(const struct xattr_handler *handler, - struct dentry *unused, struct inode *inode, - const char *key, void *buf, size_t buflen) -{ - int ret = 0; - ssize_t dacl_size, acl_size; - void *dacl_buf = NULL; - - /* - * In order to present this view (system.nfs4_acl_xdr) of our ZFS ACL - * we will need to: - * - Read the DACL - * - Decode DACL to struct nfs4_acl - * - Encode nfs4_acl to system.nfs4_acl_xdr (to be returned) - * - * Even if the caller just requested the size we will have to fetch - * the DACL in order to calculate the size required. - */ - - /* Fetch the DACL size first */ - dacl_size = nfs4_proc_get_acl(inode, NULL, 0, NFS4ACL_DACL); - if (dacl_size <= 0) - return dacl_size; - dacl_buf = kmalloc(dacl_size, GFP_KERNEL); - if (dacl_buf == NULL) - return -ENOMEM; - - /* Read the DACL */ - ret = nfs4_proc_get_acl(inode, dacl_buf, dacl_size, NFS4ACL_DACL); - if (ret < 0) { - pr_err("NFS: %s Failed to read DACL: %d", __func__, ret); - goto dacl_out; - } - - if (!buf || buflen == 0) { - /* - * We just want the size, so decode the number of ACEs - * in the DACL and perform a calculation. - */ - u32 count; - u32 *p = dacl_buf; - - p++; /* Skip the acl_flag */ - count = ntohl(*(p++)); - ret = ACES_TO_XDRSIZE(count); - } else { - /* - * Decode DACL to struct nfs4_acl - */ - struct nfs4_acl *acl = NULL; - - acl_size = nfs4_aclbuf_decode(dacl_buf, dacl_size, NFS4ACL_DACL, &acl); - if (acl_size < 0) { - pr_err("NFS: %s Failed to decode DACL: %zu", __func__, acl_size); - ret = -EINVAL; - goto dacl_out; - } - /* This should be the same as acl_size */ - ret = ACES_TO_XDRSIZE(acl->naces); - if (buflen >= ret) { - int error; - - /* Encode nfs4_acl to system.nfs4_acl_xdr (to be returned) */ - error = generate_nfs41acl_buf(buf, acl, S_ISDIR(inode->i_mode)); - if (error) { - pr_err("NFS: %s generate_nfs41acl_buf returned: %d", __func__, - error); - ret = error; - } - } else { - pr_err("NFS: %s Supplied buffer too small: %zu vs %d", __func__, - buflen, ret); - ret = -EINVAL; - } - - kfree(acl); - } - - -dacl_out: - kfree(dacl_buf); - return ret; -} - -static bool nfs4_xattr_list_nfs4_acl_xdr(struct dentry *dentry) -{ - return nfs4_server_supports_acls(NFS_SB(dentry->d_sb), NFS4ACL_DACL); -} -#endif /* CONFIG_TRUENAS */ - #endif #ifdef CONFIG_NFS_V4_SECURITY_LABEL @@ -11271,15 +10762,6 @@ static const struct xattr_handler nfs4_xattr_nfs4_sacl_handler = { .get = nfs4_xattr_get_nfs4_sacl, .set = nfs4_xattr_set_nfs4_sacl, }; - -#if CONFIG_TRUENAS -static const struct xattr_handler nfs4_xattr_nfs4_acl_xdr_handler = { - .name = NA41_NAME, - .list = nfs4_xattr_list_nfs4_acl_xdr, - .get = nfs4_xattr_get_nfs4_acl_xdr, - .set = nfs4_xattr_set_nfs4_acl_xdr, -}; -#endif /* CONFIG_TRUENAS */ #endif #ifdef CONFIG_NFS_V4_2 @@ -11295,9 +10777,6 @@ const struct xattr_handler *nfs4_xattr_handlers[] = { #if defined(CONFIG_NFS_V4_1) &nfs4_xattr_nfs4_dacl_handler, &nfs4_xattr_nfs4_sacl_handler, -#if CONFIG_TRUENAS - &nfs4_xattr_nfs4_acl_xdr_handler, -#endif /* CONFIG_TRUENAS */ #endif #ifdef CONFIG_NFS_V4_SECURITY_LABEL &nfs4_xattr_nfs4_label_handler, diff --git a/fs/nfs_common/nfs41acl_xdr.h b/fs/nfs_common/nfs41acl_xdr.h deleted file mode 100644 index 31d2f5456a07..000000000000 --- a/fs/nfs_common/nfs41acl_xdr.h +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef _NFS41ACL_H_RPCGEN -#define _NFS41ACL_H_RPCGEN - -/* - * Native ZFS NFSv41-style ACL is packed in xattr as - * follows: - * - * struct nfsace4i { - * uint32_t type; RFC 5661 Section 6.2.1.1 - * uint32_t flag; RFC 5661 Section 6.2.1.4 - * uint32_t iflag; - * uint32_t access_mask; RFC 5661 Section 6.2.1.3 - * uint32_t who_id; - * }; - * - * struct nfsacl4 { - * uint32_t acl_flags; RFC 5661 Section 6.4.3.2 - * uint32_t ace_count; - * struct nfsace4i aces<>; - * }; - * - * iflag and who_id combined are sufficent for NFS server to convert into ACE - * who (RFC 5661 Section 6.2.1.5). - */ - -#define NA41_NAME "system.nfs4_acl_xdr" - -#define ACE4_FILE_INHERIT_ACE 0x00000001 -#define ACE4_DIRECTORY_INHERIT_ACE 0x00000002 -#define ACE4_NO_PROPAGATE_INHERIT_ACE 0x00000004 -#define ACE4_INHERIT_ONLY_ACE 0x00000008 -#define ACE4_SUCCESSFUL_ACCESS_ACE_FLAG 0x00000010 -#define ACE4_FAILED_ACCESS_ACE_FLAG 0x00000020 -#define ACE4_IDENTIFIER_GROUP 0x00000040 -#define ACE4_INHERITED_ACE 0x00000080 -#define NFS41_FLAGS (ACE4_DIRECTORY_INHERIT_ACE| \ - ACE4_FILE_INHERIT_ACE| \ - ACE4_NO_PROPAGATE_INHERIT_ACE| \ - ACE4_INHERIT_ONLY_ACE| \ - ACE4_INHERITED_ACE| \ - ACE4_IDENTIFIER_GROUP) - -#define ACEI4_SPECIAL_WHO 0x00000001 -#define ACE4_SPECIAL_OWNER 1 -#define ACE4_SPECIAL_GROUP 2 -#define ACE4_SPECIAL_EVERYONE 3 -#define NACE41_LEN 5 - -#define ACL4_AUTO_INHERIT 0x00000001 -#define ACL4_PROTECTED 0x00000002 -#define ACL4_DEFAULTED 0x00000004 - -/* - * Macros for sanity checks related to XDR and ACL buffer sizes - */ -#define NFS41ACL_MAX_ENTRIES 1024 -#define ACE4SIZE (NACE41_LEN * sizeof(u32)) -#define XDRBASE (2 * sizeof (u32)) - -#define ACES_TO_SIZE(x, y) (x + (y * ACE4SIZE)) -#define SIZE_IS_VALID(x, y) ((x >= ACES_TO_SIZE(y, 0)) && \ - (((x - y) % ACE4SIZE) == 0)) - -#define ACES_TO_XDRSIZE(x) (ACES_TO_SIZE(XDRBASE, x)) -#define XDRSIZE_IS_VALID(x) (SIZE_IS_VALID(x, XDRBASE)) - -#endif /* !_NFS41ACL_H_RPCGEN */ diff --git a/fs/nfs_common/nfsacl.c b/fs/nfs_common/nfsacl.c index 0954b0c9dd2d..5a5bd85d08f8 100644 --- a/fs/nfs_common/nfsacl.c +++ b/fs/nfs_common/nfsacl.c @@ -28,13 +28,6 @@ #include #include #include -#if CONFIG_TRUENAS -#include "nfs41acl_xdr.h" - -/* Value from zfs/include/os/linux/spl/sys/acl.h */ -#define ACL_IS_DIR 0x20000 -#endif /* CONFIG_TRUENAS */ - MODULE_LICENSE("GPL"); @@ -425,136 +418,3 @@ bool nfs_stream_decode_acl(struct xdr_stream *xdr, unsigned int *aclcnt, return true; } EXPORT_SYMBOL_GPL(nfs_stream_decode_acl); - -#if CONFIG_TRUENAS -static int -convert_to_nfs40_ace(u32 *xdrbuf, size_t *remaining, struct nfs4_ace *ace) -{ - int error = 0; - u32 iflag, id; - - if (*remaining < ACE4SIZE) - return -EOVERFLOW; - - ace->type = ntohl(*(xdrbuf++)); - if (ace->type > NFS4_ACE_ACCESS_DENIED_ACE_TYPE) - return -EINVAL; - - ace->flag = ntohl(*(xdrbuf++)); - iflag = ntohl(*(xdrbuf++)); - ace->access_mask = ntohl(*(xdrbuf++)) & NFS4_ACE_MASK_ALL; - id = ntohl(*(xdrbuf++)); - - *remaining -= ACE4SIZE; - - if (iflag & ACEI4_SPECIAL_WHO) { - switch (id) { - case ACE4_SPECIAL_OWNER: - ace->whotype = NFS4_ACL_WHO_OWNER; - break; - case ACE4_SPECIAL_GROUP: - ace->whotype = NFS4_ACL_WHO_GROUP; - break; - case ACE4_SPECIAL_EVERYONE: - ace->whotype = NFS4_ACL_WHO_EVERYONE; - break; - } - } else { - ace->whotype = NFS4_ACL_WHO_NAMED; - if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP) { - ace->who_gid = make_kgid(&init_user_ns, id); - if (!gid_valid(ace->who_gid)) { - error = -EINVAL; - } - } else { - ace->who_uid = make_kuid(&init_user_ns, id); - if (!uid_valid(ace->who_uid)) { - error = -EINVAL; - } - } - } - - return error; -} - -int -convert_nfs41xdr_to_nfs40_acl(u32 *xdrbuf, size_t remaining, struct nfs4_acl *acl) -{ - int error = 0; - int i; - - for (i = 0; i < acl->naces; i++, xdrbuf += NACE41_LEN) { - error = convert_to_nfs40_ace(xdrbuf, &remaining, &acl->aces[i]); - if (error) - break; - } - - return error; -} -EXPORT_SYMBOL_GPL(convert_nfs41xdr_to_nfs40_acl); - -static int -convert_ace_to_nfs41(u32 *p, const struct nfs4_ace *ace) -{ - int error = 0; - u32 iflag = 0, who = -1; - - /* Audit and Alarm are not currently supported */ - if (ace->type > NFS4_ACE_ACCESS_DENIED_ACE_TYPE) - return -EINVAL; - - switch (ace->whotype) { - case NFS4_ACL_WHO_OWNER: - iflag = ACEI4_SPECIAL_WHO; - who = ACE4_SPECIAL_OWNER; - break; - case NFS4_ACL_WHO_GROUP: - iflag = ACEI4_SPECIAL_WHO; - who = ACE4_SPECIAL_GROUP; - break; - case NFS4_ACL_WHO_EVERYONE: - iflag = ACEI4_SPECIAL_WHO; - who = ACE4_SPECIAL_EVERYONE; - break; - case NFS4_ACL_WHO_NAMED: - if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP) - who = (u32)__kgid_val(ace->who_gid); - else - who = (u32)__kuid_val(ace->who_uid); - break; - default: - error = -EINVAL; - } - - *p++ = htonl(ace->type); - *p++ = htonl(ace->flag & NFS41_FLAGS); - *p++ = htonl(iflag); - *p++ = htonl(ace->access_mask & NFS4_ACE_MASK_ALL); - *p++ = htonl(who); - - return error; -} - -int -generate_nfs41acl_buf(u32 *xdrbuf, const struct nfs4_acl *acl, bool isdir) -{ - int error = 0; - int i; - - /* - * first byte is NFS41 Flags. Maybe be zero if these are RFC3530 acls - */ - *xdrbuf++ = htonl(acl->flag | (isdir ? ACL_IS_DIR : 0)); - *xdrbuf++ = htonl(acl->naces); - - for (i = 0; i < acl->naces; i++, xdrbuf += NACE41_LEN) { - error = convert_ace_to_nfs41(xdrbuf, &acl->aces[i]); - if (error) - break; - } - - return error; -} -EXPORT_SYMBOL_GPL(generate_nfs41acl_buf); -#endif /* CONFIG_TRUENAS */ - diff --git a/fs/nfsd/acl.h b/fs/nfsd/acl.h index 4d2e2c168c10..4b7324458a94 100644 --- a/fs/nfsd/acl.h +++ b/fs/nfsd/acl.h @@ -40,22 +40,14 @@ struct svc_fh; struct svc_rqst; struct nfsd_attrs; enum nfs_ftype4; -#if CONFIG_TRUENAS -enum nfs4_acl_type; -#endif /* CONFIG_TRUENAS */ int nfs4_acl_bytes(int entries); int nfs4_acl_get_whotype(char *, u32); __be32 nfs4_acl_write_who(struct xdr_stream *xdr, int who); -void nfsd4_setup_attr(struct dentry *dentry, struct nfsd_attrs *attr); int nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, -#if CONFIG_TRUENAS - struct nfs4_acl **acl, enum nfs4_acl_type acl_type); -#else struct nfs4_acl **acl); -#endif /* CONFIG_TRUENAS */ -int nfsv4_set_zfacl_from_attr(struct dentry *dentry, - struct nfsd_attrs *attr); +__be32 nfsd4_acl_to_attr(enum nfs_ftype4 type, struct nfs4_acl *acl, + struct nfsd_attrs *attr); #endif /* LINUX_NFS4_ACL_H */ diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c index 5e48998c8f9a..268ef57751c4 100644 --- a/fs/nfsd/nfs3proc.c +++ b/fs/nfsd/nfs3proc.c @@ -304,7 +304,7 @@ nfsd3_create_file(struct svc_rqst *rqstp, struct svc_fh *fhp, goto out; } - if (!IS_POSIXACL(inode) && !IS_NFSV4ACL(inode)) + if (!IS_POSIXACL(inode)) iap->ia_mode &= ~current_umask(); status = fh_fill_pre_attrs(fhp); diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c index 37399b4557a4..96e786b5e544 100644 --- a/fs/nfsd/nfs4acl.c +++ b/fs/nfsd/nfs4acl.c @@ -37,14 +37,11 @@ #include #include #include -#include #include "nfsfh.h" #include "nfsd.h" #include "acl.h" #include "vfs.h" -#include "../nfs_common/nfs41acl_xdr.h" -#include /* For convert_nfs41xdr_to_nfs40_acl and generate_nfs41acl_buf */ #define NFS4_ACL_TYPE_DEFAULT 0x01 #define NFS4_ACL_DIR 0x02 @@ -128,8 +125,8 @@ static short ace2type(struct nfs4_ace *); static void _posix_to_nfsv4_one(struct posix_acl *, struct nfs4_acl *, unsigned int); -static int -get_nfs4_posix_acl(struct svc_rqst *rqstp, struct dentry *dentry, +int +nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, struct nfs4_acl **acl) { struct inode *inode = d_inode(dentry); @@ -179,121 +176,6 @@ get_nfs4_posix_acl(struct svc_rqst *rqstp, struct dentry *dentry, return error; } -static int -get_nfs4_nfsv41xdr_acl(struct svc_rqst *rqstp, struct dentry *dentry, - struct nfs4_acl **pacl, enum nfs4_acl_type acl_type) -{ - int error = 0; - u32 ace_cnt, acl_flag = 0; - u32 *xdr_buf = NULL, *p; - struct nfs4_acl *acl = NULL; - ssize_t len; - size_t xdr_buf_sz = ACES_TO_XDRSIZE(NFS41ACL_MAX_ENTRIES); - - xdr_buf = kzalloc(xdr_buf_sz, GFP_KERNEL); - if (!xdr_buf) - return -ENOMEM; - - len = vfs_getxattr(&nop_mnt_idmap, dentry, NA41_NAME, xdr_buf, xdr_buf_sz); - if (len == 0) { - error = -EOPNOTSUPP; - goto out; - } - - if (len < 0) { - switch (len) { - case -EOPNOTSUPP: - /* ZFS says NFSv4 ACLs not supported */ - error = -EOPNOTSUPP; - goto out; - case -EINVAL: - /* ZFS unhappy with buffer size */ - error = -EINVAL; - goto out; - case -ERANGE: - /* our buffer is too small. This is _very_ unexpected */ - error = -EINVAL; - goto out; - case -EPERM: - case -EACCES: - error = -EPERM; - goto out; - default: - error = -ENOMEM; - goto out; - } - } - - BUG_ON(!(XDRSIZE_IS_VALID(len))); - - switch (acl_type) { - case NFS4ACL_ACL: - /* - * Only NFS 4.0 (RFC 3530) ACLs are to be exported here by the NFS - * server, and so the ACL-wide flags are ignored when generating the - * internal NFS server ACL. - */ - p = xdr_buf + 1; - break; - - case NFS4ACL_DACL: - case NFS4ACL_SACL: - /* - * When we read the vsa_aclflags from the xattr there are some - * values that are not supported by NFS (e.g. ACL_IS_DIR).Mask - * them out. - * - * Fortunately, ACL4_AUTO_INHERIT, ACL4_PROTECTED and - * ACL4_DEFAULTED have the same values as the ZFS equivalents - * (ACL_AUTO_INHERIT, ACL_PROTECTED, ACL_DEFAULTED) so no - * value mapping is required. - */ - p = xdr_buf; - acl_flag = ntohl(*(p++)) & (ACL4_AUTO_INHERIT | ACL4_PROTECTED | ACL4_DEFAULTED); - break; - - default: - /* Should never happen */ - error = -EINVAL; - goto out; - } - - ace_cnt = ntohl(*(p++)); - if (ace_cnt > NFS41ACL_MAX_ENTRIES) { - error = -ERANGE; - goto out; - } - - acl = kzalloc(nfs4_acl_bytes(ace_cnt), GFP_KERNEL); - if (!acl) { - error = -ENOMEM; - goto out; - } - acl->naces = ace_cnt; - acl->flag = acl_flag; - - error = convert_nfs41xdr_to_nfs40_acl(p++, len - (2 * sizeof(u32)), acl); - if (error) - kfree(acl); - else - *pacl = acl; -out: - kfree(xdr_buf); - return (error); -} - -int -nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, - struct nfs4_acl **acl, enum nfs4_acl_type acl_type) -{ - struct inode *inode = d_inode(dentry); - - if (IS_NFSV4ACL(inode)) - return get_nfs4_nfsv41xdr_acl(rqstp, dentry, acl, acl_type); - else - return get_nfs4_posix_acl(rqstp, dentry, acl); -} - struct posix_acl_summary { unsigned short owner; unsigned short users; @@ -893,89 +775,26 @@ static int nfs4_acl_nfsv4_to_posix(struct nfs4_acl *acl, return ret; } -static __be32 -nfsd4_acl_to_attr_posix(enum nfs_ftype4 type, struct nfs4_acl *acl, - fsacl_t *fsaclp) +__be32 nfsd4_acl_to_attr(enum nfs_ftype4 type, struct nfs4_acl *acl, + struct nfsd_attrs *attr) { int host_error; unsigned int flags = 0; if (!acl) return nfs_ok; + if (type == NF4DIR) flags = NFS4_ACL_DIR; - host_error = nfs4_acl_nfsv4_to_posix(acl, &fsaclp->posixacl.na_pacl, - &fsaclp->posixacl.na_dpacl, flags); + host_error = nfs4_acl_nfsv4_to_posix(acl, &attr->na_pacl, + &attr->na_dpacl, flags); if (host_error == -EINVAL) return nfserr_attrnotsupp; else return nfserrno(host_error); } -static __be32 -nfsd4_acl_to_attr_zfsacl(enum nfs_ftype4 type, struct nfs4_acl *acl, - fsacl_t *fsaclp) -{ - int error; - u32 *xdr_buf = NULL; - size_t len; - - if (!acl) - return nfs_ok; - - if (acl->naces > NFS41ACL_MAX_ENTRIES) - return nfserrno(-ERANGE); - - else if (acl->naces == 0) - return nfserrno(-EINVAL); - - len = ACES_TO_XDRSIZE(acl->naces); - - xdr_buf = kzalloc(len, GFP_KERNEL); - if (!xdr_buf) - return nfserrno(-ENOMEM); - - error = generate_nfs41acl_buf(xdr_buf, acl, type == NF4DIR); - if (error) { - kfree(xdr_buf); - return nfserrno(error); - } - - fsaclp->zfsacl.aclbuf = xdr_buf; - fsaclp->zfsacl.sz = len; - - return nfs_ok; -} - -static __be32 -nfsd4_acl_to_attr_fail(enum nfs_ftype4 type, struct nfs4_acl *acl, - fsacl_t *fsaclp) -{ - if (!acl) - return nfs_ok; - - return nfserr_attrnotsupp; -} - -int -nfsv4_set_zfacl_from_attr(struct dentry *dentry, struct nfsd_attrs *attr) -{ - struct inode *delegated_inode = NULL; - int error; - -retry: - error = __vfs_setxattr_locked(&nop_mnt_idmap, dentry, NA41_NAME, - attr->na_fsacl.zfsacl.aclbuf, - attr->na_fsacl.zfsacl.sz, - XATTR_REPLACE, &delegated_inode); - - if (delegated_inode) - goto retry; - - return error; -} - static short ace2type(struct nfs4_ace *ace) { @@ -1056,20 +875,3 @@ __be32 nfs4_acl_write_who(struct xdr_stream *xdr, int who) WARN_ON_ONCE(1); return nfserr_serverfault; } - -void -nfsd4_setup_attr(struct dentry *dentry, struct nfsd_attrs *attr) -{ - struct inode *inode = d_inode(dentry); - - if (IS_NFSV4ACL(inode)) { - attr->na_acltype = ACL_TYPE_ZFS; - attr->na_conv_fn = nfsd4_acl_to_attr_zfsacl; - } else if (IS_POSIXACL(inode)) { - attr->na_acltype = ACL_TYPE_POSIX; - attr->na_conv_fn = nfsd4_acl_to_attr_posix; - } else { - attr->na_acltype = ACL_TYPE_NONE; - attr->na_conv_fn = nfsd4_acl_to_attr_fail; - } -} diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 199dca85a75d..451026f9986b 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -87,13 +87,8 @@ check_attr_support(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, if (!nfsd_attrs_supported(cstate->minorversion, bmval)) return nfserr_attrnotsupp; - if ((bmval[0] & FATTR4_WORD0_ACL) && !IS_POSIXACL(d_inode(dentry)) && - !IS_NFSV4ACL(d_inode(dentry))) + if ((bmval[0] & FATTR4_WORD0_ACL) && !IS_POSIXACL(d_inode(dentry))) return nfserr_attrnotsupp; -#if CONFIG_TRUENAS - if ((bmval[1] & FATTR4_WORD1_DACL) && !IS_NFSV4ACL(d_inode(dentry))) - return nfserr_attrnotsupp; -#endif /* CONFIG_TRUENAS */ if ((bmval[2] & FATTR4_WORD2_SECURITY_LABEL) && !(exp->ex_flags & NFSEXP_SECURITY_LABEL)) return nfserr_attrnotsupp; @@ -241,7 +236,6 @@ nfsd4_create_file(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_attrs attrs = { .na_iattr = iap, .na_seclabel = &open->op_label, - .na_acltype = ACL_TYPE_NONE }; struct dentry *parent, *child; __u32 v_mtime, v_atime; @@ -264,10 +258,8 @@ nfsd4_create_file(struct svc_rqst *rqstp, struct svc_fh *fhp, if (host_err) return nfserrno(host_err); - if (is_create_with_attrs(open)) { - nfsd4_setup_attr(parent, &attrs); - attrs.na_conv_fn(NF4REG, open->op_acl, &attrs.na_fsacl); - } + if (is_create_with_attrs(open)) + nfsd4_acl_to_attr(NF4REG, open->op_acl, &attrs); inode_lock_nested(inode, I_MUTEX_PARENT); @@ -350,7 +342,7 @@ nfsd4_create_file(struct svc_rqst *rqstp, struct svc_fh *fhp, goto out; } - if (!IS_POSIXACL(inode) && !IS_NFSV4ACL(inode)) + if (!IS_POSIXACL(inode)) iap->ia_mode &= ~current_umask(); status = fh_fill_pre_attrs(fhp); @@ -379,15 +371,8 @@ nfsd4_create_file(struct svc_rqst *rqstp, struct svc_fh *fhp, if (attrs.na_labelerr) open->op_bmval[2] &= ~FATTR4_WORD2_SECURITY_LABEL; -#if CONFIG_TRUENAS - if (attrs.na_aclerr) { - open->op_bmval[0] &= ~FATTR4_WORD0_ACL; - open->op_bmval[1] &= ~FATTR4_WORD1_DACL; - } -#else if (attrs.na_aclerr) open->op_bmval[0] &= ~FATTR4_WORD0_ACL; -#endif /* CONFIG_TRUENAS */ out: inode_unlock(inode); nfsd_attrs_free(&attrs); @@ -803,7 +788,6 @@ nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd_attrs attrs = { .na_iattr = &create->cr_iattr, .na_seclabel = &create->cr_label, - .na_acltype = ACL_TYPE_NONE }; struct svc_fh resfh; __be32 status; @@ -820,9 +804,7 @@ nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, if (status) return status; - nfsd4_setup_attr(cstate->current_fh.fh_dentry, &attrs); - status = attrs.na_conv_fn(create->cr_type, create->cr_acl, - &attrs.na_fsacl); + status = nfsd4_acl_to_attr(create->cr_type, create->cr_acl, &attrs); current->fs->umask = create->cr_umask; switch (create->cr_type) { case NF4LNK: @@ -881,15 +863,8 @@ nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, if (attrs.na_labelerr) create->cr_bmval[2] &= ~FATTR4_WORD2_SECURITY_LABEL; -#if CONFIG_TRUENAS - if (attrs.na_aclerr) { - create->cr_bmval[0] &= ~FATTR4_WORD0_ACL; - create->cr_bmval[1] &= ~FATTR4_WORD1_DACL; - } -#else if (attrs.na_aclerr) create->cr_bmval[0] &= ~FATTR4_WORD0_ACL; -#endif /* CONFIG_TRUENAS */ set_change_info(&create->cr_cinfo, &cstate->current_fh); fh_dup2(&cstate->current_fh, &resfh); out: @@ -1162,7 +1137,6 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd_attrs attrs = { .na_iattr = &setattr->sa_iattr, .na_seclabel = &setattr->sa_label, - .na_acltype = ACL_TYPE_NONE }; struct inode *inode; __be32 status = nfs_ok; @@ -1186,9 +1160,8 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, goto out; inode = cstate->current_fh.fh_dentry->d_inode; - nfsd4_setup_attr(cstate->current_fh.fh_dentry, &attrs); - status = attrs.na_conv_fn(S_ISDIR(inode->i_mode) ? NF4DIR : NF4REG, - setattr->sa_acl, &attrs.na_fsacl); + status = nfsd4_acl_to_attr(S_ISDIR(inode->i_mode) ? NF4DIR : NF4REG, + setattr->sa_acl, &attrs); if (status) goto out; @@ -2878,10 +2851,6 @@ static u32 nfsd4_getattr_rsize(const struct svc_rqst *rqstp, return nfsd4_max_payload(rqstp); if (bmap0 & FATTR4_WORD0_FS_LOCATIONS) return nfsd4_max_payload(rqstp); -#if CONFIG_TRUENAS - if (bmap1 & FATTR4_WORD1_DACL) - return nfsd4_max_payload(rqstp); -#endif /* CONFIG_TRUENAS */ if (bmap1 & FATTR4_WORD1_OWNER) { ret += IDMAP_NAMESZ + 4; diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 1136d3d9f538..c7e52d980cd7 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -2541,7 +2541,7 @@ static int client_info_show(struct seq_file *m, void *v) clp->cl_nii_time.tv_sec, clp->cl_nii_time.tv_nsec); } seq_printf(m, "callback state: %s\n", cb_state2str(clp->cl_cb_state)); - seq_printf(m, "callback address: \"%pISpc\"\n", &clp->cl_cb_conn.cb_addr); + seq_printf(m, "callback address: %pISpc\n", &clp->cl_cb_conn.cb_addr); drop_client(clp); return 0; diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 434860cd93ae..92c7dde148a4 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -318,36 +318,11 @@ nfsd4_decode_nfsace4(struct nfsd4_compoundargs *argp, struct nfs4_ace *ace) /* A counted array of nfsace4's */ static noinline __be32 -#if CONFIG_TRUENAS -nfsd4_decode_acl(struct nfsd4_compoundargs *argp, struct nfs4_acl **acl, - enum nfs4_acl_type acl_type) -{ - struct nfs4_ace *ace; - __be32 status; - u32 count; - u32 acl_flag = 0; - - switch (acl_type) { - case NFS4ACL_NONE: - case NFS4ACL_ACL: - break; - - case NFS4ACL_DACL: - case NFS4ACL_SACL: - /* - * Per RFC-8881 Section 6.4.3.2 nfsacl41 has a leading aclflag4 - */ - if (xdr_stream_decode_u32(argp->xdr, &acl_flag) < 0) - return nfserr_bad_xdr; - break; - } -#else nfsd4_decode_acl(struct nfsd4_compoundargs *argp, struct nfs4_acl **acl) { struct nfs4_ace *ace; __be32 status; u32 count; -#endif /* CONFIG_TRUENAS */ if (xdr_stream_decode_u32(argp->xdr, &count) < 0) return nfserr_bad_xdr; @@ -364,9 +339,6 @@ nfsd4_decode_acl(struct nfsd4_compoundargs *argp, struct nfs4_acl **acl) if (*acl == NULL) return nfserr_jukebox; -#if CONFIG_TRUENAS - (*acl)->flag = acl_flag; -#endif /* CONFIG_TRUENAS */ (*acl)->naces = count; for (ace = (*acl)->aces; ace < (*acl)->aces + count; ace++) { status = nfsd4_decode_nfsace4(argp, ace); @@ -439,11 +411,7 @@ nfsd4_decode_fattr4(struct nfsd4_compoundargs *argp, u32 *bmval, u32 bmlen, iattr->ia_valid |= ATTR_SIZE; } if (bmval[0] & FATTR4_WORD0_ACL) { -#if CONFIG_TRUENAS - status = nfsd4_decode_acl(argp, acl, NFS4ACL_ACL); -#else status = nfsd4_decode_acl(argp, acl); -#endif /* CONFIG_TRUENAS */ if (status) return status; } else @@ -532,16 +500,6 @@ nfsd4_decode_fattr4(struct nfsd4_compoundargs *argp, u32 *bmval, u32 bmlen, return nfserr_bad_xdr; } } -#if CONFIG_TRUENAS - /* - * This is based on the FATTR4_WORD0_ACL handling above. - */ - if (bmval[1] & FATTR4_WORD1_DACL) { - status = nfsd4_decode_acl(argp, acl, NFS4ACL_DACL); - if (status) - return status; - } -#endif /* CONFIG_TRUENAS */ label->len = 0; if (IS_ENABLED(CONFIG_NFSD_V4_SECURITY_LABEL) && bmval[2] & FATTR4_WORD2_SECURITY_LABEL) { @@ -3005,13 +2963,6 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, __be32 status; int err; struct nfs4_acl *acl = NULL; -#if CONFIG_TRUENAS - /* - * Even though we expect *either* ACL or DACL to be fetched, - * lets be cautious and use separate variables. - */ - struct nfs4_acl *dacl = NULL; -#endif /* CONFIG_TRUENAS */ #ifdef CONFIG_NFSD_V4_SECURITY_LABEL void *context = NULL; int contextlen; @@ -3067,19 +3018,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, fhp = tempfh; } if (bmval0 & FATTR4_WORD0_ACL) { -#if CONFIG_TRUENAS - /* - * In TrueNAS we have renamed the existing nfsd4_get_nfs4_acl - * to get_nfs4_posix_acl, so that we can implement a nfsd4_get_nfs4_acl - * that can be based either on POSIX ACL or ZFS ACL. - * - * Add a acl_type parameter so that the same underlying function - * can be adapted to get either ACL or DACL. - */ - err = nfsd4_get_nfs4_acl(rqstp, dentry, &acl, NFS4ACL_ACL); -#else err = nfsd4_get_nfs4_acl(rqstp, dentry, &acl); -#endif /* CONFIG_TRUENAS */ if (err == -EOPNOTSUPP) bmval0 &= ~FATTR4_WORD0_ACL; else if (err == -EINVAL) { @@ -3089,19 +3028,6 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, goto out_nfserr; } -#if CONFIG_TRUENAS - if (bmval1 & FATTR4_WORD1_DACL) { - err = nfsd4_get_nfs4_acl(rqstp, dentry, &dacl, NFS4ACL_DACL); - if (err == -EOPNOTSUPP) - bmval1 &= ~FATTR4_WORD1_DACL; - else if (err == -EINVAL) { - status = nfserr_attrnotsupp; - goto out; - } else if (err != 0) - goto out_nfserr; - } -#endif /* CONFIG_TRUENAS */ - #ifdef CONFIG_NFSD_V4_SECURITY_LABEL if ((bmval2 & FATTR4_WORD2_SECURITY_LABEL) || bmval0 & FATTR4_WORD0_SUPPORTED_ATTRS) { @@ -3134,13 +3060,8 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, memcpy(supp, nfsd_suppattrs[minorversion], sizeof(supp)); - if (!IS_POSIXACL(dentry->d_inode) && - !IS_NFSV4ACL(dentry->d_inode)) + if (!IS_POSIXACL(dentry->d_inode)) supp[0] &= ~FATTR4_WORD0_ACL; -#if CONFIG_TRUENAS - if (!IS_NFSV4ACL(dentry->d_inode)) - supp[1] &= ~FATTR4_WORD1_DACL; -#endif /* CONFIG_TRUENAS */ if (!contextsupport) supp[2] &= ~FATTR4_WORD2_SECURITY_LABEL; if (!supp[2]) { @@ -3287,7 +3208,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, p = xdr_reserve_space(xdr, 4); if (!p) goto out_resource; - *p++ = cpu_to_be32(IS_POSIXACL(dentry->d_inode) || IS_NFSV4ACL(dentry->d_inode) ? + *p++ = cpu_to_be32(IS_POSIXACL(dentry->d_inode) ? ACL4_SUPPORT_ALLOW_ACL|ACL4_SUPPORT_DENY_ACL : 0); } if (bmval0 & FATTR4_WORD0_CANSETTIME) { @@ -3494,44 +3415,6 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, } p = xdr_encode_hyper(p, ino); } -#if CONFIG_TRUENAS - /* See FATTR4_WORD0_ACL above */ - if (bmval1 & FATTR4_WORD1_DACL) { - struct nfs4_ace *ace; - - if (dacl == NULL) { - p = xdr_reserve_space(xdr, 4); - if (!p) - goto out_resource; - - *p++ = cpu_to_be32(0); - goto out_dacl; - } - p = xdr_reserve_space(xdr, 4); - if (!p) - goto out_resource; - *p++ = cpu_to_be32(dacl->flag); - - p = xdr_reserve_space(xdr, 4); - if (!p) - goto out_resource; - *p++ = cpu_to_be32(dacl->naces); - - for (ace = dacl->aces; ace < dacl->aces + dacl->naces; ace++) { - p = xdr_reserve_space(xdr, 4*3); - if (!p) - goto out_resource; - *p++ = cpu_to_be32(ace->type); - *p++ = cpu_to_be32(ace->flag); - *p++ = cpu_to_be32(ace->access_mask & - NFS4_ACE_MASK_ALL); - status = nfsd4_encode_aclname(xdr, rqstp, ace); - if (status) - goto out; - } - } -out_dacl: -#endif /* CONFIG_TRUENAS */ #ifdef CONFIG_NFSD_PNFS if (bmval1 & FATTR4_WORD1_FS_LAYOUT_TYPES) { status = nfsd4_encode_layout_types(xdr, exp->ex_layout_types); @@ -3591,9 +3474,6 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, security_release_secctx(context, contextlen); #endif /* CONFIG_NFSD_V4_SECURITY_LABEL */ kfree(acl); -#if CONFIG_TRUENAS - kfree(dacl); -#endif /* CONFIG_TRUENAS */ if (tempfh) { fh_put(tempfh); kfree(tempfh); diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h index 257bf59e55bf..fe846a360ae1 100644 --- a/fs/nfsd/nfsd.h +++ b/fs/nfsd/nfsd.h @@ -394,13 +394,8 @@ void nfsd_lockd_shutdown(void); #define NFSD4_1_SUPPORTED_ATTRS_WORD0 \ NFSD4_SUPPORTED_ATTRS_WORD0 -#if CONFIG_TRUENAS -#define NFSD4_1_SUPPORTED_ATTRS_WORD1 \ - (NFSD4_SUPPORTED_ATTRS_WORD1 | PNFSD_SUPPORTED_ATTRS_WORD1 | FATTR4_WORD1_DACL) -#else #define NFSD4_1_SUPPORTED_ATTRS_WORD1 \ (NFSD4_SUPPORTED_ATTRS_WORD1 | PNFSD_SUPPORTED_ATTRS_WORD1) -#endif /* CONFIG_TRUENAS */ #define NFSD4_1_SUPPORTED_ATTRS_WORD2 \ (NFSD4_SUPPORTED_ATTRS_WORD2 | PNFSD_SUPPORTED_ATTRS_WORD2 | \ @@ -475,17 +470,10 @@ static inline bool nfsd_attrs_supported(u32 minorversion, const u32 *bmval) */ #define NFSD_WRITEABLE_ATTRS_WORD0 \ (FATTR4_WORD0_SIZE | FATTR4_WORD0_ACL) -#if CONFIG_TRUENAS -#define NFSD_WRITEABLE_ATTRS_WORD1 \ - (FATTR4_WORD1_MODE | FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP \ - | FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_CREATE \ - | FATTR4_WORD1_TIME_MODIFY_SET | FATTR4_WORD1_DACL) -#else #define NFSD_WRITEABLE_ATTRS_WORD1 \ (FATTR4_WORD1_MODE | FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP \ | FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_CREATE \ | FATTR4_WORD1_TIME_MODIFY_SET) -#endif /* CONFIG_TRUENAS */ #ifdef CONFIG_NFSD_V4_SECURITY_LABEL #define MAYBE_FATTR4_WORD2_SECURITY_LABEL \ FATTR4_WORD2_SECURITY_LABEL diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 8f4a9051d713..d0fdf70ab20d 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -555,29 +555,15 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, if (attr->na_seclabel && attr->na_seclabel->len) attr->na_labelerr = security_inode_setsecctx(dentry, attr->na_seclabel->data, attr->na_seclabel->len); - - switch(attr->na_acltype) { - case ACL_TYPE_POSIX: - if (IS_ENABLED(CONFIG_FS_POSIX_ACL) && attr->na_fsacl.posixacl.na_pacl) - attr->na_aclerr = set_posix_acl(&nop_mnt_idmap, - dentry, ACL_TYPE_ACCESS, - attr->na_fsacl.posixacl.na_pacl); - if (IS_ENABLED(CONFIG_FS_POSIX_ACL) && - !attr->na_aclerr && attr->na_fsacl.posixacl.na_dpacl && - S_ISDIR(inode->i_mode)) - attr->na_aclerr = set_posix_acl(&nop_mnt_idmap, - dentry, ACL_TYPE_DEFAULT, - attr->na_fsacl.posixacl.na_dpacl); - break; - case ACL_TYPE_ZFS: - if (attr->na_fsacl.zfsacl.aclbuf) - attr->na_aclerr = nfsv4_set_zfacl_from_attr(dentry, attr); - break; - case ACL_TYPE_NONE: - break; - default: - BUG(); - }; + if (IS_ENABLED(CONFIG_FS_POSIX_ACL) && attr->na_pacl) + attr->na_aclerr = set_posix_acl(&nop_mnt_idmap, + dentry, ACL_TYPE_ACCESS, + attr->na_pacl); + if (IS_ENABLED(CONFIG_FS_POSIX_ACL) && + !attr->na_aclerr && attr->na_dpacl && S_ISDIR(inode->i_mode)) + attr->na_aclerr = set_posix_acl(&nop_mnt_idmap, + dentry, ACL_TYPE_DEFAULT, + attr->na_dpacl); inode_unlock(inode); if (size_change) put_write_access(inode); @@ -1440,7 +1426,7 @@ nfsd_create_locked(struct svc_rqst *rqstp, struct svc_fh *fhp, iap->ia_mode = 0; iap->ia_mode = (iap->ia_mode & S_IALLUGO) | type; - if (!IS_POSIXACL(dirp) && !IS_NFSV4ACL(dirp)) + if (!IS_POSIXACL(dirp)) iap->ia_mode &= ~current_umask(); err = 0; @@ -2480,20 +2466,6 @@ nfsd_permission(struct svc_rqst *rqstp, struct svc_export *exp, err = inode_permission(&nop_mnt_idmap, inode, acc & (MAY_READ | MAY_WRITE | MAY_EXEC)); - /* - * See RFC 5661 Section 6.2.1.3.2 - * Allow NFSv4 ACL to override normal delete permission - * In this case REMOVE is granted if DELETE is granted on file - * or DELETE_CHILD is granted on parent. - */ - if ((err == -EACCES) && IS_NFSV4ACL(inode) && - (acc == NFSD_MAY_REMOVE)) { - err = inode_permission(&nop_mnt_idmap, inode, MAY_DELETE); - if (err == -EACCES) - err = inode_permission(&nop_mnt_idmap, d_inode(dentry->d_parent), - MAY_DELETE_CHILD); - } - /* Allow read access to binaries even when mode 111 */ if (err == -EACCES && S_ISREG(inode->i_mode) && (acc == (NFSD_MAY_READ | NFSD_MAY_OWNER_OVERRIDE) || diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h index 3b36390b4146..e3c29596f4df 100644 --- a/fs/nfsd/vfs.h +++ b/fs/nfsd/vfs.h @@ -43,43 +43,21 @@ struct nfsd_file; */ typedef int (*nfsd_filldir_t)(void *, const char *, int, loff_t, u64, unsigned); -enum acltype { ACL_TYPE_NONE, ACL_TYPE_POSIX, ACL_TYPE_ZFS }; -typedef struct zacl { u32 *aclbuf; size_t sz; } zacl_t; -typedef struct pacl { struct posix_acl *na_pacl; struct posix_acl *na_dpacl;} pacl_t; -typedef union fsacl { zacl_t zfsacl; pacl_t posixacl; } fsacl_t; -typedef __be32(*aclconv_t)(enum nfs_ftype4, struct nfs4_acl *, fsacl_t *); - /* nfsd/vfs.c */ struct nfsd_attrs { struct iattr *na_iattr; /* input */ struct xdr_netobj *na_seclabel; /* input */ - fsacl_t na_fsacl; - enum acltype na_acltype; + struct posix_acl *na_pacl; /* input */ + struct posix_acl *na_dpacl; /* input */ int na_labelerr; /* output */ int na_aclerr; /* output */ - aclconv_t na_conv_fn; }; static inline void nfsd_attrs_free(struct nfsd_attrs *attrs) { - switch(attrs->na_acltype) { - case ACL_TYPE_POSIX: - posix_acl_release(attrs->na_fsacl.posixacl.na_pacl); - posix_acl_release(attrs->na_fsacl.posixacl.na_dpacl); - break; - case ACL_TYPE_ZFS: - kfree(attrs->na_fsacl.zfsacl.aclbuf); - attrs->na_fsacl.zfsacl.aclbuf = NULL; - attrs->na_fsacl.zfsacl.sz = 0; - break; - case ACL_TYPE_NONE: - break; - default: - BUG(); - }; - - attrs->na_acltype = ACL_TYPE_NONE; + posix_acl_release(attrs->na_pacl); + posix_acl_release(attrs->na_dpacl); } __be32 nfserrno (int errno);