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 <cbodley@citi.umich.edu>
This commit is contained in:
Olga Kornievskaia 2011-04-12 14:07:24 -04:00
parent b9e369fac6
commit b6d81b3419
3 changed files with 73 additions and 22 deletions

View file

@ -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 */

View file

@ -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;

View file

@ -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__ */