Example #1
0
/**
 * 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)
{
    int entries = (acl && acl->a_count) ? max_t(int, acl->a_count, 4) : 0;
    struct nfsacl_encode_desc nfsacl_desc = {
        .desc = {
            .elem_size = 12,
            .array_len = encode_entries ? entries : 0,
            .xcode = xdr_nfsace_encode,
        },
        .acl = acl,
        .typeflag = typeflag,
        .uid = inode->i_uid,
        .gid = inode->i_gid,
    };
    struct nfsacl_simple_acl aclbuf;
    int err;

    if (entries > NFS_ACL_MAX_ENTRIES ||
            xdr_encode_word(buf, base, entries))
        return -EINVAL;
    if (encode_entries && acl && acl->a_count == 3) {
        struct posix_acl *acl2 = &aclbuf.acl;

        /* Avoid the use of posix_acl_alloc().  nfsacl_encode() is
         * invoked in contexts where a memory allocation failure is
         * fatal.  Fortunately this fake ACL is small enough to
         * construct on the stack. */
        posix_acl_init(acl2, 4);

        /* Insert entries in canonical order: other orders seem
         to confuse Solaris VxFS. */
        acl2->a_entries[0] = acl->a_entries[0];  /* ACL_USER_OBJ */
        acl2->a_entries[1] = acl->a_entries[1];  /* ACL_GROUP_OBJ */
        acl2->a_entries[2] = acl->a_entries[1];  /* ACL_MASK */
        acl2->a_entries[2].e_tag = ACL_MASK;
        acl2->a_entries[3] = acl->a_entries[2];  /* ACL_OTHER */
        nfsacl_desc.acl = acl2;
    }
    err = xdr_encode_array2(buf, base + 4, &nfsacl_desc.desc);
    if (!err)
        err = 8 + nfsacl_desc.desc.elem_size *
              nfsacl_desc.desc.array_len;
    return err;
}
Example #2
0
File: nfsacl.c Project: 274914765/C
unsigned int
nfsacl_encode(struct xdr_buf *buf, unsigned int base, struct inode *inode,
          struct posix_acl *acl, int encode_entries, int typeflag)
{
    int entries = (acl && acl->a_count) ? max_t(int, acl->a_count, 4) : 0;
    struct nfsacl_encode_desc nfsacl_desc = {
        .desc = {
            .elem_size = 12,
            .array_len = encode_entries ? entries : 0,
            .xcode = xdr_nfsace_encode,
        },
        .acl = acl,
        .typeflag = typeflag,
        .uid = inode->i_uid,
        .gid = inode->i_gid,
    };
    int err;
    struct posix_acl *acl2 = NULL;

    if (entries > NFS_ACL_MAX_ENTRIES ||
        xdr_encode_word(buf, base, entries))
        return -EINVAL;
    if (encode_entries && acl && acl->a_count == 3) {
        /* Fake up an ACL_MASK entry. */
        acl2 = posix_acl_alloc(4, GFP_KERNEL);
        if (!acl2)
            return -ENOMEM;
        /* Insert entries in canonical order: other orders seem
         to confuse Solaris VxFS. */
        acl2->a_entries[0] = acl->a_entries[0];  /* ACL_USER_OBJ */
        acl2->a_entries[1] = acl->a_entries[1];  /* ACL_GROUP_OBJ */
        acl2->a_entries[2] = acl->a_entries[1];  /* ACL_MASK */
        acl2->a_entries[2].e_tag = ACL_MASK;
        acl2->a_entries[3] = acl->a_entries[2];  /* ACL_OTHER */
        nfsacl_desc.acl = acl2;
    }
    err = xdr_encode_array2(buf, base + 4, &nfsacl_desc.desc);
    if (acl2)
        posix_acl_release(acl2);
    if (!err)
        err = 8 + nfsacl_desc.desc.elem_size *
              nfsacl_desc.desc.array_len;
    return err;
}
Example #3
0
int nfsacl_encode(struct xdr_buf *buf, unsigned int base, struct inode *inode,
		  struct posix_acl *acl, int encode_entries, int typeflag)
{
	int entries = (acl && acl->a_count) ? max_t(int, acl->a_count, 4) : 0;
	struct nfsacl_encode_desc nfsacl_desc = {
		.desc = {
			.elem_size = 12,
			.array_len = encode_entries ? entries : 0,
			.xcode = xdr_nfsace_encode,
		},
		.acl = acl,
		.typeflag = typeflag,
		.uid = inode->i_uid,
		.gid = inode->i_gid,
	};
	struct nfsacl_simple_acl aclbuf;
	int err;

	if (entries > NFS_ACL_MAX_ENTRIES ||
	    xdr_encode_word(buf, base, entries))
		return -EINVAL;
	if (encode_entries && acl && acl->a_count == 3) {
		struct posix_acl *acl2 = &aclbuf.acl;

		posix_acl_init(acl2, 4);

		acl2->a_entries[0] = acl->a_entries[0];  
		acl2->a_entries[1] = acl->a_entries[1];  
		acl2->a_entries[2] = acl->a_entries[1];  
		acl2->a_entries[2].e_tag = ACL_MASK;
		acl2->a_entries[3] = acl->a_entries[2];  
		nfsacl_desc.acl = acl2;
	}
	err = xdr_encode_array2(buf, base + 4, &nfsacl_desc.desc);
	if (!err)
		err = 8 + nfsacl_desc.desc.elem_size *
			  nfsacl_desc.desc.array_len;
	return err;
}