From b6d81b341944679b82dbafb5f7b7c1d3d6499434 Mon Sep 17 00:00:00 2001 From: Olga Kornievskaia Date: Tue, 12 Apr 2011 14:07:24 -0400 Subject: [PATCH] xdr encode decode acl and dacl attributes acls are lists of arbitrary length, so xdr_array() is used to allocate the array during decode. because this memory is allocated by the tirpc library, it needs to be freed there as well; added function nfsacl41_free() to do this with XDR_F REE Signed-off-by: Casey Bodley --- daemon/nfs41_types.h | 9 ++++- daemon/nfs41_xdr.c | 85 +++++++++++++++++++++++++++++++++----------- daemon/nfs41_xdr.h | 1 + 3 files changed, 73 insertions(+), 22 deletions(-) diff --git a/daemon/nfs41_types.h b/daemon/nfs41_types.h index 5b181d0..6fa8d4d 100644 --- a/daemon/nfs41_types.h +++ b/daemon/nfs41_types.h @@ -123,9 +123,15 @@ typedef struct __nfsace4 { uint32_t acetype; uint32_t aceflag; uint32_t acemask; - unsigned char who[NFS4_OPAQUE_LIMIT]; + char who[NFS4_OPAQUE_LIMIT]; } nfsace4; +typedef struct __nfsacl41 { + uint32_t flag; + nfsace4 *aces; + uint32_t count; +} nfsacl41; + typedef struct __stateid4 { uint32_t seqid; unsigned char other[NFS4_STATEID_OTHER]; @@ -186,6 +192,7 @@ typedef struct __nfs41_file_info { nfstime4 time_access; nfstime4 time_create; nfstime4 time_modify; + nfsacl41 *acl; nfstime4 *time_delta; /* XXX: per-fs */ bitmap4 attrmask; bitmap4 *supported_attrs; /* XXX: per-fs */ diff --git a/daemon/nfs41_xdr.c b/daemon/nfs41_xdr.c index 38e1e82..f7e2ebb 100644 --- a/daemon/nfs41_xdr.c +++ b/daemon/nfs41_xdr.c @@ -293,6 +293,53 @@ static bool_t xdr_mdsthreshold( return TRUE; } +static bool_t xdr_nfsace4( + XDR *xdr, + nfsace4 *ace) +{ + char *who = ace->who; + + if (!xdr_u_int32_t(xdr, &ace->acetype)) + return FALSE; + + if (!xdr_u_int32_t(xdr, &ace->aceflag)) + return FALSE; + + if (!xdr_u_int32_t(xdr, &ace->acemask)) + return FALSE; + + /* 'who' is a static array, so don't try to free it */ + if (xdr->x_op == XDR_FREE) + return TRUE; + + return xdr_string(xdr, &who, NFS4_OPAQUE_LIMIT); +} + +static bool_t xdr_nfsdacl41( + XDR *xdr, + nfsacl41 *acl) +{ + if (!xdr_u_int32_t(xdr, &acl->flag)) + return FALSE; + + return xdr_array(xdr, (char**)&acl->aces, &acl->count, + 32, sizeof(nfsace4), (xdrproc_t)xdr_nfsace4); +} + +static bool_t xdr_nfsacl41( + XDR *xdr, + nfsacl41 *acl) +{ + return xdr_array(xdr, (char**)&acl->aces, &acl->count, + 32, sizeof(nfsace4), (xdrproc_t)xdr_nfsace4); +} + +void nfsacl41_free(nfsacl41 *acl) +{ + XDR xdr = { XDR_FREE }; + xdr_nfsacl41(&xdr, acl); +} + /* pathname4 * decode a variable array of components into a nfs41_abs_path */ static bool_t decode_pathname4( @@ -1654,6 +1701,12 @@ static bool_t decode_file_attrs( if (!xdr_u_int32_t(xdr, &info->rdattr_error)) return FALSE; } + if (attrs->attrmask.arr[0] & FATTR4_WORD0_ACL) { + nfsacl41 *acl = info->acl; + if (!xdr_array(xdr, (char**)&acl->aces, &acl->count, + 32, sizeof(nfsace4), (xdrproc_t)xdr_nfsace4)) + return FALSE; + } if (attrs->attrmask.arr[0] & FATTR4_WORD0_ACLSUPPORT) { if (!xdr_u_int32_t(xdr, &info->aclsupport)) return FALSE; @@ -1736,6 +1789,10 @@ static bool_t decode_file_attrs( if (!xdr_nfstime4(xdr, &info->time_modify)) return FALSE; } + if (attrs->attrmask.arr[1] & FATTR4_WORD1_DACL) { + if (!xdr_nfsdacl41(xdr, info->acl)) + return FALSE; + } if (attrs->attrmask.arr[1] & FATTR4_WORD1_FS_LAYOUT_TYPE) { if (!xdr_layout_types(xdr, &info->fs_layout_types)) return FALSE; @@ -1909,25 +1966,6 @@ static bool_t decode_open_none_delegation4( return result; } -static bool_t xdr_decode_nfsace4( - XDR *xdr, - nfsace4 *res) -{ - char *who = (char*)res->who; - uint32_t tmp; - - if (!xdr_u_int32_t(xdr, &tmp)) - return FALSE; - - if (!xdr_u_int32_t(xdr, &tmp)) - return FALSE; - - if (!xdr_u_int32_t(xdr, &tmp)) - return FALSE; - - return xdr_bytes(xdr, &who, &tmp, NFS4_OPAQUE_LIMIT); -} - static bool_t decode_open_read_delegation4( XDR *xdr, nfs41_op_open_res_ok *res) @@ -1941,7 +1979,7 @@ static bool_t decode_open_read_delegation4( if (!xdr_bool(xdr, &tmp_bool)) return FALSE; - return xdr_decode_nfsace4(xdr, &tmp_nfsace); + return xdr_nfsace4(xdr, &tmp_nfsace); } static bool_t decode_modified_limit4( @@ -2001,7 +2039,7 @@ static bool_t decode_open_write_delegation4( if (!decode_space_limit4(xdr)) return FALSE; - return xdr_decode_nfsace4(xdr, &tmp_nfsace); + return xdr_nfsace4(xdr, &tmp_nfsace); } static bool_t decode_open_res_ok( @@ -2454,6 +2492,11 @@ static bool_t encode_file_attrs( return FALSE; attrs->attrmask.arr[0] |= FATTR4_WORD0_SIZE; } + if (info->attrmask.arr[0] & FATTR4_WORD0_ACL) { + if (!xdr_nfsacl41(&localxdr, info->acl)) + return FALSE; + attrs->attrmask.arr[0] |= FATTR4_WORD0_ACL; + } if (info->attrmask.arr[0] & FATTR4_WORD0_HIDDEN) { if (!xdr_bool(&localxdr, &info->hidden)) return FALSE; diff --git a/daemon/nfs41_xdr.h b/daemon/nfs41_xdr.h index be53dab..19c150c 100644 --- a/daemon/nfs41_xdr.h +++ b/daemon/nfs41_xdr.h @@ -29,5 +29,6 @@ bool_t nfs_encode_compound(XDR *xdr, caddr_t *args); bool_t nfs_decode_compound(XDR *xdr, caddr_t *res); +void nfsacl41_free(nfsacl41 *acl); #endif /* !__NFS41_NFS_XDR_H__ */