From fa3c25beeeb4c533089a2af8454ef50e21e7b8f5 Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Thu, 8 Mar 2012 21:25:21 +1100 Subject: [PATCH] NFSACL: Add support for SETACL3 --- include/libnfs-private.h | 1 - include/libnfs-raw.h | 33 +++++++++++++++++++++++++++++++-- lib/libnfs.c | 4 ++++ nfs/nfs.x | 23 +++++++++++++++++++++++ nfs/nfsacl.c | 25 +++++++++++++++++++++++++ 5 files changed, 83 insertions(+), 3 deletions(-) diff --git a/include/libnfs-private.h b/include/libnfs-private.h index 29f0406..a083b37 100644 --- a/include/libnfs-private.h +++ b/include/libnfs-private.h @@ -88,7 +88,6 @@ void rpc_error_all_pdus(struct rpc_context *rpc, char *error); void rpc_set_error(struct rpc_context *rpc, char *error_string, ...); void nfs_set_error(struct nfs_context *nfs, char *error_string, ...); -struct rpc_context *nfs_get_rpc_context(struct nfs_context *nfs); const char *nfs_get_server(struct nfs_context *nfs); const char *nfs_get_export(struct nfs_context *nfs); diff --git a/include/libnfs-raw.h b/include/libnfs-raw.h index 060b08c..c577aa5 100644 --- a/include/libnfs-raw.h +++ b/include/libnfs-raw.h @@ -40,6 +40,16 @@ int rpc_service(struct rpc_context *rpc, int revents); char *rpc_get_error(struct rpc_context *rpc); int rpc_queue_length(struct rpc_context *rpc); +/* Utility function to get an RPC context from a NFS context. Useful for doing low level NFSACL + * calls on a NFS context. + */ +struct rpc_context *nfs_get_rpc_context(struct nfs_context *nfs); + +/* This function returns the nfs_fh3 structure from a nfsfh structure. + This allows to use a file onened with nfs_open() together with low-level + rpc functions that thake a nfs filehandle +*/ +struct nfs_fh3 *nfs_get_fh(struct nfsfh *nfsfh); #define RPC_STATUS_SUCCESS 0 #define RPC_STATUS_ERROR 1 @@ -768,12 +778,31 @@ int rpc_nfsacl_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: - * RPC_STATUS_SUCCESS : We got a successful response from the rquota daemon. + * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon. * data is a GETACL3res pointer - * RPC_STATUS_ERROR : An error occured when trying to contact the rquota daemon. + * RPC_STATUS_ERROR : An error occured when trying to contact the nfs daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ int rpc_nfsacl_getacl_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, uint32_t mask, void *private_data); + + +/* + * Call NFSACL/SETACL + * + * Function returns + * 0 : The call was initiated. The callback will be invoked when the call completes. + * <0 : An error occured when trying to set up the call. The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon. + * data is a SETACL3res pointer + * RPC_STATUS_ERROR : An error occured when trying to contact the nfs daemon. + * data is the error string. + * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. + * data is NULL. + */ +struct SETACL3args; +int rpc_nfsacl_setacl_async(struct rpc_context *rpc, rpc_cb cb, struct SETACL3args *args, void *private_data); diff --git a/lib/libnfs.c b/lib/libnfs.c index e2f9672..86ff7c2 100644 --- a/lib/libnfs.c +++ b/lib/libnfs.c @@ -3547,3 +3547,7 @@ const char *nfs_get_export(struct nfs_context *nfs) { const struct nfs_fh3 *nfs_get_rootfh(struct nfs_context *nfs) { return &nfs->rootfh; } + +struct nfs_fh3 *nfs_get_fh(struct nfsfh *nfsfh) { + return &nfsfh->fh; +} diff --git a/nfs/nfs.x b/nfs/nfs.x index 76b6d7e..31f378b 100644 --- a/nfs/nfs.x +++ b/nfs/nfs.x @@ -908,6 +908,26 @@ default: void; }; +struct SETACL3args { + nfs_fh3 dir; + uint32_t mask; + uint32_t ace_count; + struct nfsacl_ace ace<>; + uint32_t default_ace_count; + struct nfsacl_ace default_ace<>; +}; + +struct SETACL3resok { + post_op_attr attr; +}; + +union SETACL3res switch (nfsstat3 status) { +case NFS3_OK: + SETACL3resok resok; +default: + void; +}; + program NFSACL_PROGRAM { version NFSACL_V3 { void @@ -915,5 +935,8 @@ program NFSACL_PROGRAM { GETACL3res NFSACL3_GETACL(GETACL3args) = 1; + + SETACL3res + NFSACL3_SETACL(SETACL3args) = 2; } = 3; } = 100227; diff --git a/nfs/nfsacl.c b/nfs/nfsacl.c index e48db02..4561589 100644 --- a/nfs/nfsacl.c +++ b/nfs/nfsacl.c @@ -80,3 +80,28 @@ int rpc_nfsacl_getacl_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 * return 0; } + +int rpc_nfsacl_setacl_async(struct rpc_context *rpc, rpc_cb cb, struct SETACL3args *args, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NFSACL_PROGRAM, NFSACL_V3, NFSACL3_SETACL, cb, private_data, (xdrproc_t)xdr_SETACL3res, sizeof(SETACL3res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nfsacl/setacl call"); + return -1; + } + + if (xdr_SETACL3args(&pdu->xdr, args) == 0) { + rpc_set_error(rpc, "XDR error: Failed to encode SETACL3args"); + rpc_free_pdu(rpc, pdu); + return -2; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nfsacl/setacl call"); + rpc_free_pdu(rpc, pdu); + return -2; + } + + return 0; +} -- 2.34.1