add support for nfsv3 getacl

Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
master
Ronnie Sahlberg 2021-12-31 11:42:48 +10:00
parent c851f458a0
commit efa9085cfa
9 changed files with 855 additions and 9 deletions

View File

@ -55,6 +55,7 @@ WSADATA wsaData;
#include "../include/nfsc/libnfs.h"
#include "../include/nfsc/libnfs-raw.h"
#include "../mount/libnfs-raw-mount.h"
#include "../nfs/libnfs-raw-nfs.h"
#include "../nfs4/libnfs-raw-nfs4.h"
void print_usage(void)
@ -62,6 +63,27 @@ void print_usage(void)
fprintf(stderr, "Usage: nfs-io [-?|--help|--usage] [stat|creat|trunc|unlink|mkdir|rmdir|touch|chmod] <url>\n");
}
static char *acl3_type(int type)
{
switch(type) {
case NFSACL_TYPE_USER_OBJ: return "USER_OBJ";
case NFSACL_TYPE_USER: return "USER";
case NFSACL_TYPE_GROUP_OBJ: return "GROUP_OBJ";
case NFSACL_TYPE_GROUP: return "GROUP";
case NFSACL_TYPE_CLASS_OBJ: return "CLASS_OBJ";
case NFSACL_TYPE_CLASS: return "CLASS";
case NFSACL_TYPE_DEFAULT: return "DEFAULT";
case NFSACL_TYPE_DEFAULT_USER_OBJ: return "DEFAULT_USER_OBJ";
case NFSACL_TYPE_DEFAULT_USER: return "DEFAULT_USER";
case NFSACL_TYPE_DEFAULT_GROUP_OBJ: return "DEFAULT_GROUP_OBJ";
case NFSACL_TYPE_DEFAULT_GROUP: return "DEFAULT_GROUP";
case NFSACL_TYPE_DEFAULT_CLASS_OBJ: return "DEFAULT_CLASS_OBJ";
case NFSACL_TYPE_DEFAULT_OTHER_OBJ: return "DEFAULT_OTHER_OBJ";
}
return "Unknown ACE type";
}
int main(int argc, char *argv[])
{
int ret = 1;
@ -69,6 +91,7 @@ int main(int argc, char *argv[])
struct nfsfh *nfsfh = NULL;
struct nfs_url *url = NULL;
fattr4_acl acl4;
fattr3_acl acl3;
int i;
#ifdef WIN32
@ -183,18 +206,34 @@ int main(int argc, char *argv[])
printf("\n");
}
} else if (!strncmp(argv[1], "acl", 3)) {
printf("ACL version:%d\n", nfs_get_version(nfs));
if (nfs_get_version(nfs) != NFS_V4) {
printf("acl support only for nfsv4 for now\n");
goto finished;
}
/* NFS_V4 */
ret = nfs_open(nfs, url->file, 0600, &nfsfh);
if (ret != 0) {
printf("failed to open %s\n", url->file);
goto finished;
}
printf("ACL version:%d\n", nfs_get_version(nfs));
if (nfs_get_version(nfs) == NFS_V3) {
printf("Get v3 ACL\n");
memset(&acl3, 0, sizeof(fattr3_acl));
if (nfs3_getacl(nfs, nfsfh, &acl3) != 0) {
printf("nfs3_getacl_async failed\n");
}
printf("Number of ACEs: %d\n", acl3.ace_count);
for (i = 0; i < acl3.ace_count; i++) {
printf("%s(%d) ", acl3_type(acl3.ace[i].type), acl3.ace[i].type);
printf("Id: %d ", acl3.ace[i].id);
printf("Perm: 0x%x: %s%s%s\n", acl3.ace[i].perm,
acl3.ace[i].perm & NFSACL_PERM_READ ? "READ ":"",
acl3.ace[i].perm & NFSACL_PERM_WRITE ? "WRITE ":"",
acl3.ace[i].perm & NFSACL_PERM_EXEC ? "EXEC ":"");
}
nfs3_acl_free(&acl3);
goto finished;
}
/* NFS_V4 */
if (nfs4_getacl(nfs, nfsfh, &acl4)) {
printf("Failed to read ACLs %s\n", nfs_get_error(nfs));
goto finished;

View File

@ -2103,6 +2103,67 @@ nfs_link(struct nfs_context *nfs, const char *oldpath, const char *newpath)
}
/*
* nfs3_getacl()
*/
void nfs3_acl_free(fattr3_acl *nfs3acl)
{
if (nfs3acl == NULL) {
return;
}
if (nfs3acl->ace) {
free(nfs3acl->ace);
}
if (nfs3acl->default_ace) {
free(nfs3acl->default_ace);
}
}
static void
nfs3_getacl_cb(int status, struct nfs_context *nfs, void *data, void *private_data)
{
struct sync_cb_data *cb_data = private_data;
fattr3_acl *src = data;
fattr3_acl *dst = cb_data->return_data;
if (status < 0) {
nfs_set_error(nfs, "getacl call failed with \"%s\"",
(char *)data);
goto finished;
}
memcpy(dst, src, sizeof(fattr3_acl));
src->ace = NULL; /* steal the pointer to ACEs */
src->default_ace = NULL; /* steal the pointer to Default ACEs */
finished:
cb_data_is_finished(cb_data, status);
}
int
nfs3_getacl(struct nfs_context *nfs, struct nfsfh *nfsfh,
fattr3_acl *acl)
{
struct sync_cb_data cb_data;
cb_data.return_data = acl;
if (nfs_init_cb_data(nfs, &cb_data)) {
return -1;
}
if (nfs3_getacl_async(nfs, nfsfh, nfs3_getacl_cb, &cb_data) != 0) {
nfs_set_error(nfs, "nfs_getacl_async failed. %s",
nfs_get_error(nfs));
nfs_destroy_cb_sem(&cb_data);
return -1;
}
wait_for_nfs_reply(nfs, &cb_data);
nfs_destroy_cb_sem(&cb_data);
return cb_data.status;
}
/*
* nfs4_getacl()
*/

View File

@ -121,6 +121,8 @@ nfsstat3_to_errno
nfsstat3_to_str
nfsstat4_to_errno
nfsstat4_to_str
nfs3_getacl
nfs3_getacl_async
nfs4_set_client_name
nfs4_set_verifier
nfs4_acl_free

View File

@ -3994,6 +3994,98 @@ nfs3_fsync_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb,
return 0;
}
static void
nfs3_getacl_cb(struct rpc_context *rpc, int status, void *command_data,
void *private_data)
{
GETACL3res *res;
GETACL3resok *resok;
struct nfs_cb_data *data = private_data;
struct nfs_context *nfs = data->nfs;
fattr3_acl acl;
int i;
assert(rpc->magic == RPC_CONTEXT_MAGIC);
if (check_nfs3_error(nfs, status, data, command_data)) {
free_nfs_cb_data(data);
return;
}
res = command_data;
if (res->status != NFS3_OK) {
nfs_set_error(nfs, "NFS: GETACL of %s failed with "
"%s(%d)", data->saved_path,
nfsstat3_to_str(res->status),
nfsstat3_to_errno(res->status));
data->cb(nfsstat3_to_errno(res->status), nfs,
nfs_get_error(nfs), data->private_data);
free_nfs_cb_data(data);
return;
}
memset(&acl, 0, sizeof(acl));
resok = &res->GETACL3res_u.resok;
acl.ace_count = resok->ace_count;
if (acl.ace_count) {
acl.ace = calloc(acl.ace_count, sizeof(struct nfsacl_ace));
if (acl.ace == NULL) {
data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data);
free_nfs_cb_data(data);
return;
}
for (i = 0; i < acl.ace_count; i++) {
acl.ace[i] = resok->ace.ace_val[i];
}
}
acl.default_ace_count = resok->default_ace_count;
if (acl.default_ace_count) {
acl.default_ace = calloc(acl.default_ace_count, sizeof(struct nfsacl_ace));
if (acl.default_ace == NULL) {
data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data);
free_nfs_cb_data(data);
return;
}
for (i = 0; i < acl.default_ace_count; i++) {
acl.default_ace[i] = resok->default_ace.default_ace_val[i];
}
}
data->cb(0, nfs, &acl, data->private_data);
free_nfs_cb_data(data);
}
int
nfs3_getacl_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb,
void *private_data)
{
struct nfs_cb_data *data;
GETACL3args args;
printf("getacl async\n");
data = malloc(sizeof(struct nfs_cb_data));
if (data == NULL) {
nfs_set_error(nfs, "out of memory: failed to allocate "
"nfs_cb_data structure");
return -1;
}
memset(data, 0, sizeof(struct nfs_cb_data));
data->nfs = nfs;
data->cb = cb;
data->private_data = private_data;
memset(&args, 0, sizeof(GETACL3args));
args.dir.data.data_len = nfsfh->fh.len;
args.dir.data.data_val = nfsfh->fh.val;
args.mask = NFSACL_MASK_ACL_ENTRY|NFSACL_MASK_ACL_COUNT|NFSACL_MASK_ACL_DEFAULT_ENTRY|NFSACL_MASK_ACL_DEFAULT_COUNT;
if (rpc_nfsacl_getacl_async(nfs->rpc, nfs3_getacl_cb, &args, data) != 0) {
data->cb(-ENOMEM, nfs, nfs_get_error(nfs),
data->private_data);
free_nfs_cb_data(data);
return -1;
}
return 0;
}
static void
nfs3_stat_1_cb(struct rpc_context *rpc, int status, void *command_data,
void *private_data)

View File

@ -21,5 +21,6 @@ nfs-stamp : nfs.x
compile_rpc:
cat nfs.x | head -29 >libnfs-raw-nfs.h
rpcgen -h nfs.x | sed -e "s/#include <rpc\/rpc.h>/#include <nfsc\/libnfs-zdr.h>/" -e "s/xdr/zdr/g" -e "s/XDR/ZDR/g" -e "s/#define _NFS_H_RPCGEN/#define _NFS_H_RPCGEN\n#include <nfsc\/libnfs-zdr.h>/g" -e "s/#define NFS3_COOKIEVERFSIZE 8/#define NFS3_COOKIEVERFSIZE 8\n\n/g" -e "s/ CLIENT / void /g" -e "s/SVCXPRT /void /g" -e "s/bool_t/uint32_t/g" >> libnfs-raw-nfs.h
cat libnfs-raw-nfs.h.extra >>libnfs-raw-nfs.h
cat nfs.x | head -29 >libnfs-raw-nfs.c
rpcgen -c nfs.x | sed -e "s/#include \".*nfs.h\"/#include \"libnfs-xdr.h\"\n#include \"libnfs-raw-nfs.h\"/" -e "s/xdr/zdr/g" -e "s/XDR/ZDR/g" -e "s/register int32_t \*buf;/register int32_t *buf;\n buf = NULL;/" -e "s/bool_t/uint32_t/g" >> libnfs-raw-nfs.c

File diff suppressed because it is too large Load Diff

View File

@ -2005,6 +2005,57 @@ extern uint32_t zdr_SETACL3res ();
#endif /* K&R C */
#include <nfsc/libnfs.h>
#if defined(WIN32) && defined(libnfs_EXPORTS)
#define EXTERN __declspec( dllexport )
#else
#ifndef EXTERN
#define EXTERN
#endif
#endif
typedef struct {
u_int ace_count;
struct nfsacl_ace *ace;
u_int default_ace_count;
struct nfsacl_ace *default_ace;
} fattr3_acl;
/*
* NFSv3 ACL
*/
/*
* Async nfs3 get acl
* Function returns
* 0 : The command was queued successfully. The callback will be invoked once
* the command completes.
* <0 : An error occured when trying to queue the command.
* The callback will not be invoked.
*
* When the callback is invoked, status indicates the result:
* 0 : Success.
* data is fattr3_acl *
* -errno : An error occured.
* data is the error string.
*/
EXTERN int nfs3_getacl_async(struct nfs_context *nfs, struct nfsfh *nfsfh,
nfs_cb cb, void *private_data);
/*
* Sync nfs3 get acl
* Function returns
* 0 : The operation was successful.
* -errno : The command failed.
*
* If the command was successful, the returned data in nfs3acl must be freed
* by calling nfs3_acl_free()
*/
EXTERN int nfs3_getacl(struct nfs_context *nfs, struct nfsfh *nfsfh,
fattr3_acl *nfs3acl);
EXTERN void nfs3_acl_free(fattr3_acl *nfs3acl);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,56 @@
#include <nfsc/libnfs.h>
#if defined(WIN32) && defined(libnfs_EXPORTS)
#define EXTERN __declspec( dllexport )
#else
#ifndef EXTERN
#define EXTERN
#endif
#endif
typedef struct {
u_int ace_count;
struct nfsacl_ace *ace;
u_int default_ace_count;
struct nfsacl_ace *default_ace;
} fattr3_acl;
/*
* NFSv3 ACL
*/
/*
* Async nfs3 get acl
* Function returns
* 0 : The command was queued successfully. The callback will be invoked once
* the command completes.
* <0 : An error occured when trying to queue the command.
* The callback will not be invoked.
*
* When the callback is invoked, status indicates the result:
* 0 : Success.
* data is fattr3_acl *
* -errno : An error occured.
* data is the error string.
*/
EXTERN int nfs3_getacl_async(struct nfs_context *nfs, struct nfsfh *nfsfh,
nfs_cb cb, void *private_data);
/*
* Sync nfs3 get acl
* Function returns
* 0 : The operation was successful.
* -errno : The command failed.
*
* If the command was successful, the returned data in nfs3acl must be freed
* by calling nfs3_acl_free()
*/
EXTERN int nfs3_getacl(struct nfs_context *nfs, struct nfsfh *nfsfh,
fattr3_acl *nfs3acl);
EXTERN void nfs3_acl_free(fattr3_acl *nfs3acl);
#ifdef __cplusplus
}
#endif
#endif /* !_NFS_H_RPCGEN */

View File

@ -96,3 +96,4 @@ int rpc_nfsacl_setacl_async(struct rpc_context *rpc, rpc_cb cb, struct SETACL3ar
return 0;
}