acl: add support and helpers to read nfsv4 acls
Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>master
parent
1cdc8657de
commit
cdb377532a
|
@ -55,6 +55,7 @@ WSADATA wsaData;
|
|||
#include "../include/nfsc/libnfs.h"
|
||||
#include "../include/nfsc/libnfs-raw.h"
|
||||
#include "../mount/libnfs-raw-mount.h"
|
||||
#include "../nfs4/libnfs-raw-nfs4.h"
|
||||
|
||||
void print_usage(void)
|
||||
{
|
||||
|
@ -67,6 +68,8 @@ int main(int argc, char *argv[])
|
|||
struct nfs_context *nfs = NULL;
|
||||
struct nfsfh *nfsfh = NULL;
|
||||
struct nfs_url *url = NULL;
|
||||
fattr4_acl acl4;
|
||||
int i;
|
||||
|
||||
#ifdef WIN32
|
||||
if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) {
|
||||
|
@ -179,6 +182,32 @@ int main(int argc, char *argv[])
|
|||
printf(" mtime: %lu %lu", st.nfs_mtime, st.nfs_mtime_nsec);
|
||||
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;
|
||||
}
|
||||
if (nfs4_getacl(nfs, nfsfh, &acl4)) {
|
||||
printf("Failed to read ACLs %s\n", nfs_get_error(nfs));
|
||||
goto finished;
|
||||
}
|
||||
for (i = 0; i < acl4.fattr4_acl_len; i++) {
|
||||
printf("Type:%d Flag:%d Mask:0x%08x Who:%s\n",
|
||||
acl4.fattr4_acl_val[i].type,
|
||||
acl4.fattr4_acl_val[i].flag,
|
||||
acl4.fattr4_acl_val[i].access_mask,
|
||||
acl4.fattr4_acl_val[i].who.utf8string_val);
|
||||
}
|
||||
nfs4_acl_free(&acl4);
|
||||
ret = 0;
|
||||
} else {
|
||||
goto finished;
|
||||
}
|
||||
|
|
|
@ -275,6 +275,12 @@ EXTERN void nfs_set_autoreconnect(struct nfs_context *nfs, int num_retries);
|
|||
* NFS_V4
|
||||
*/
|
||||
EXTERN int nfs_set_version(struct nfs_context *nfs, int version);
|
||||
/*
|
||||
* Get NFS version of a connected share. Supported versions are
|
||||
* NFS_V3
|
||||
* NFS_V4
|
||||
*/
|
||||
EXTERN int nfs_get_version(struct nfs_context *nfs);
|
||||
|
||||
/*
|
||||
* Invalidate the pagecache
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
#include "libnfs-raw.h"
|
||||
#include "libnfs-raw-mount.h"
|
||||
#include "libnfs-raw-nfs.h"
|
||||
#include "libnfs-raw-nfs4.h"
|
||||
#include "libnfs-private.h"
|
||||
|
||||
struct sync_cb_data {
|
||||
|
@ -1850,6 +1851,81 @@ nfs_link(struct nfs_context *nfs, const char *oldpath, const char *newpath)
|
|||
return cb_data.status;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nfs4_getacl()
|
||||
*/
|
||||
void nfs4_acl_free(fattr4_acl *acl)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < acl->fattr4_acl_len; i++) {
|
||||
free(acl->fattr4_acl_val[i].who.utf8string_val);
|
||||
}
|
||||
free(acl->fattr4_acl_val);
|
||||
}
|
||||
|
||||
static void
|
||||
nfs4_getacl_cb(int status, struct nfs_context *nfs, void *data, void *private_data)
|
||||
{
|
||||
struct sync_cb_data *cb_data = private_data;
|
||||
fattr4_acl *src = data;
|
||||
fattr4_acl *dst = cb_data->return_data;
|
||||
int i;
|
||||
|
||||
cb_data->is_finished = 1;
|
||||
cb_data->status = status;
|
||||
|
||||
if (status < 0) {
|
||||
nfs_set_error(nfs, "getacl call failed with \"%s\"",
|
||||
(char *)data);
|
||||
return;
|
||||
}
|
||||
dst->fattr4_acl_len = src->fattr4_acl_len;
|
||||
dst->fattr4_acl_val = calloc(dst->fattr4_acl_len, sizeof(nfsace4));
|
||||
if (dst->fattr4_acl_val == NULL) {
|
||||
cb_data->status = -ENOMEM;
|
||||
nfs_set_error(nfs, "Failed to allocate fattr4_acl_val");
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < dst->fattr4_acl_len; i++) {
|
||||
dst->fattr4_acl_val[i].type = src->fattr4_acl_val[i].type;
|
||||
dst->fattr4_acl_val[i].flag = src->fattr4_acl_val[i].flag;
|
||||
dst->fattr4_acl_val[i].access_mask = src->fattr4_acl_val[i].access_mask;
|
||||
dst->fattr4_acl_val[i].who.utf8string_len = src->fattr4_acl_val[i].who.utf8string_len;
|
||||
dst->fattr4_acl_val[i].who.utf8string_val = calloc(dst->fattr4_acl_val[i].who.utf8string_len + 1, 1);
|
||||
if (dst->fattr4_acl_val[i].who.utf8string_val == NULL) {
|
||||
cb_data->status = -ENOMEM;
|
||||
nfs4_acl_free(dst);
|
||||
nfs_set_error(nfs, "Failed to allocate acl name");
|
||||
return;
|
||||
}
|
||||
memcpy(dst->fattr4_acl_val[i].who.utf8string_val,
|
||||
src->fattr4_acl_val[i].who.utf8string_val,
|
||||
dst->fattr4_acl_val[i].who.utf8string_len);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
nfs4_getacl(struct nfs_context *nfs, struct nfsfh *nfsfh,
|
||||
fattr4_acl *acl)
|
||||
{
|
||||
struct sync_cb_data cb_data;
|
||||
|
||||
cb_data.is_finished = 0;
|
||||
cb_data.return_data = acl;
|
||||
|
||||
if (nfs4_getacl_async(nfs, nfsfh, nfs4_getacl_cb, &cb_data) != 0) {
|
||||
nfs_set_error(nfs, "nfs_getacl_async failed. %s",
|
||||
nfs_get_error(nfs));
|
||||
return -1;
|
||||
}
|
||||
|
||||
wait_for_nfs_reply(nfs, &cb_data);
|
||||
|
||||
return cb_data.status;
|
||||
}
|
||||
|
||||
void
|
||||
mount_getexports_cb(struct rpc_context *mount_context, int status, void *data,
|
||||
void *private_data)
|
||||
|
|
|
@ -35,6 +35,7 @@ nfs_get_fd
|
|||
nfs_get_readmax
|
||||
nfs_get_writemax
|
||||
nfs_getcwd
|
||||
nfs_get_version
|
||||
nfs_get_timeout
|
||||
nfs_init_context
|
||||
nfs_link
|
||||
|
@ -118,6 +119,9 @@ nfsstat4_to_errno
|
|||
nfsstat4_to_str
|
||||
nfs4_set_client_name
|
||||
nfs4_set_verifier
|
||||
nfs4_acl_free
|
||||
nfs4_getacl
|
||||
nfs4_getacl_async
|
||||
win32_poll
|
||||
rpc_connect_async
|
||||
rpc_connect_port_async
|
||||
|
|
|
@ -1848,6 +1848,11 @@ nfs_set_version(struct nfs_context *nfs, int version) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
nfs_get_version(struct nfs_context *nfs) {
|
||||
return nfs->version;
|
||||
}
|
||||
|
||||
void
|
||||
nfs_set_error(struct nfs_context *nfs, char *error_string, ...)
|
||||
{
|
||||
|
|
85
lib/nfs_v4.c
85
lib/nfs_v4.c
|
@ -99,6 +99,7 @@
|
|||
#include "slist.h"
|
||||
#include "libnfs.h"
|
||||
#include "libnfs-raw.h"
|
||||
#include "libnfs-raw-nfs4.h"
|
||||
#include "libnfs-private.h"
|
||||
|
||||
#ifndef discard_const
|
||||
|
@ -193,6 +194,10 @@ static uint32_t statvfs_attributes[2] = {
|
|||
1 << (FATTR4_SPACE_TOTAL - 32))
|
||||
};
|
||||
|
||||
static uint32_t getacl_attributes[1] = {
|
||||
(1 << FATTR4_ACL )
|
||||
};
|
||||
|
||||
static int
|
||||
nfs4_open_async_internal(struct nfs_context *nfs, struct nfs4_cb_data *data,
|
||||
int flags, int mode);
|
||||
|
@ -2530,6 +2535,86 @@ nfs4_fstat64_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
nfs4_getacl_cb(struct rpc_context *rpc, int status, void *command_data,
|
||||
void *private_data)
|
||||
{
|
||||
struct nfs4_cb_data *data = private_data;
|
||||
struct nfs_context *nfs = data->nfs;
|
||||
COMPOUND4res *res = command_data;
|
||||
GETATTR4resok *garesok;
|
||||
fattr4_acl acl;
|
||||
ZDR zdr;
|
||||
int i;
|
||||
|
||||
assert(rpc->magic == RPC_CONTEXT_MAGIC);
|
||||
|
||||
if (check_nfs4_error(nfs, status, data, res, "GETACL")) {
|
||||
data->cb(-EIO, nfs, "GETACL failed", data->private_data);
|
||||
free_nfs4_cb_data(data);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((i = nfs4_find_op(nfs, data, res, OP_GETATTR, "GETATTR")) < 0) {
|
||||
data->cb(-EIO, nfs, "GETACL failed", data->private_data);
|
||||
free_nfs4_cb_data(data);
|
||||
return;
|
||||
}
|
||||
garesok = &res->resarray.resarray_val[i].nfs_resop4_u.opgetattr.GETATTR4res_u.resok4;
|
||||
|
||||
memset(&acl, 0, sizeof(acl));
|
||||
zdrmem_create(&zdr,
|
||||
garesok->obj_attributes.attr_vals.attrlist4_val,
|
||||
garesok->obj_attributes.attr_vals.attrlist4_len,
|
||||
ZDR_DECODE);
|
||||
if (zdr_fattr4_acl(&zdr, &acl)) {
|
||||
data->cb(0, nfs, &acl, data->private_data);
|
||||
} else {
|
||||
data->cb(-EIO, nfs, "Failed to unmarshall fattr4_acl", data->private_data);
|
||||
}
|
||||
|
||||
zdr_destroy(&zdr);
|
||||
free_nfs4_cb_data(data);
|
||||
}
|
||||
|
||||
int
|
||||
nfs4_getacl_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb,
|
||||
void *private_data)
|
||||
{
|
||||
COMPOUND4args args;
|
||||
nfs_argop4 op[2];
|
||||
struct nfs4_cb_data *data;
|
||||
int i;
|
||||
|
||||
data = malloc(sizeof(*data));
|
||||
if (data == NULL) {
|
||||
nfs_set_error(nfs, "Out of memory. Failed to allocate "
|
||||
"cb data");
|
||||
return -1;
|
||||
}
|
||||
memset(data, 0, sizeof(*data));
|
||||
|
||||
data->nfs = nfs;
|
||||
data->cb = cb;
|
||||
data->private_data = private_data;
|
||||
|
||||
i = nfs4_op_putfh(nfs, &op[0], nfsfh);
|
||||
i += nfs4_op_getattr(nfs, &op[i], getacl_attributes, 1);
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
args.argarray.argarray_len = i;
|
||||
args.argarray.argarray_val = op;
|
||||
|
||||
if (rpc_nfs4_compound_async(nfs->rpc, nfs4_getacl_cb, &args,
|
||||
data) != 0) {
|
||||
free_nfs4_cb_data(data);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
nfs4_close_cb(struct rpc_context *rpc, int status, void *command_data,
|
||||
void *private_data)
|
||||
|
|
|
@ -2754,3 +2754,46 @@ extern uint32_t zdr_CB_COMPOUND4res ();
|
|||
#endif
|
||||
|
||||
#endif /* !_NFS4_H_RPCGEN */
|
||||
#include <nfsc/libnfs.h>
|
||||
|
||||
#if defined(WIN32) && defined(libnfs_EXPORTS)
|
||||
#define EXTERN __declspec( dllexport )
|
||||
#else
|
||||
#ifndef EXTERN
|
||||
#define EXTERN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* NFSv4 ACL
|
||||
*/
|
||||
/*
|
||||
* Async nfs4 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 fattr4_acl *
|
||||
* -errno : An error occured.
|
||||
* data is the error string.
|
||||
*/
|
||||
EXTERN int nfs4_getacl_async(struct nfs_context *nfs, struct nfsfh *nfsfh,
|
||||
nfs_cb cb, void *private_data);
|
||||
|
||||
/*
|
||||
* Sync nfs4 get acl
|
||||
* Function returns
|
||||
* 0 : The operation was successful.
|
||||
* -errno : The command failed.
|
||||
*
|
||||
* If the command was successful, the returned data in nfs4acl must be freed
|
||||
* by calling nfs4_acl_free()
|
||||
*/
|
||||
EXTERN int nfs4_getacl(struct nfs_context *nfs, struct nfsfh *nfsfh,
|
||||
fattr4_acl *nfs4acl);
|
||||
|
||||
EXTERN void nfs4_acl_free(fattr4_acl *nfs4acl);
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
#include <nfsc/libnfs.h>
|
||||
|
||||
#if defined(WIN32) && defined(libnfs_EXPORTS)
|
||||
#define EXTERN __declspec( dllexport )
|
||||
#else
|
||||
#ifndef EXTERN
|
||||
#define EXTERN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* NFSv4 ACL
|
||||
*/
|
||||
/*
|
||||
* Async nfs4 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 fattr4_acl *
|
||||
* -errno : An error occured.
|
||||
* data is the error string.
|
||||
*/
|
||||
EXTERN int nfs4_getacl_async(struct nfs_context *nfs, struct nfsfh *nfsfh,
|
||||
nfs_cb cb, void *private_data);
|
||||
|
||||
/*
|
||||
* Sync nfs4 get acl
|
||||
* Function returns
|
||||
* 0 : The operation was successful.
|
||||
* -errno : The command failed.
|
||||
*
|
||||
* If the command was successful, the returned data in nfs4acl must be freed
|
||||
* by calling nfs4_acl_free()
|
||||
*/
|
||||
EXTERN int nfs4_getacl(struct nfs_context *nfs, struct nfsfh *nfsfh,
|
||||
fattr4_acl *nfs4acl);
|
||||
|
||||
EXTERN void nfs4_acl_free(fattr4_acl *nfs4acl);
|
|
@ -1,7 +1,7 @@
|
|||
set(UTILITIES nfs-cat nfs-ls nfs-stat)
|
||||
set(UTILITIES nfs-cat nfs-ls)
|
||||
|
||||
if(NOT CMAKE_SYSTEM_NAME STREQUAL Windows)
|
||||
list(APPEND UTILITIES nfs-cp)
|
||||
list(APPEND UTILITIES nfs-cp nfs-stat)
|
||||
endif()
|
||||
|
||||
foreach(TARGET ${UTILITIES})
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
bin_PROGRAMS = nfs-cat nfs-ls nfs-stat
|
||||
bin_PROGRAMS = nfs-cat nfs-ls
|
||||
|
||||
if !HAVE_WIN32
|
||||
bin_PROGRAMS += nfs-cp
|
||||
bin_PROGRAMS += nfs-cp nfs-stat
|
||||
endif
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
|
|
Loading…
Reference in New Issue