add support for nfsv3 getacl
Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>master
parent
c851f458a0
commit
efa9085cfa
|
@ -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;
|
||||
|
|
|
@ -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()
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
|
|
92
lib/nfs_v3.c
92
lib/nfs_v3.c
|
@ -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)
|
||||
|
|
|
@ -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
|
@ -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
|
||||
|
|
|
@ -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 */
|
|
@ -96,3 +96,4 @@ int rpc_nfsacl_setacl_async(struct rpc_context *rpc, rpc_cb cb, struct SETACL3ar
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue