ACLv3 - Access Control Lists V3
Change-Id: I43e544d6cdeac5e3880141477461e7c22cbf6e91 BUG: 847622 Signed-off-by: Krishna Srinivas <ksriniva@redhat.com> Reviewed-on: http://review.gluster.org/4045 Reviewed-by: Kaleb KEITHLEY <kkeithle@redhat.com> Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Anand Avati <avati@redhat.com>
This commit is contained in:
parent
ca666417f3
commit
1c4cb52377
@ -14,7 +14,7 @@ libgfxdr_la_SOURCES = xdr-generic.c rpc-common-xdr.c \
|
||||
glusterd1-xdr.c \
|
||||
portmap-xdr.c \
|
||||
nlm4-xdr.c xdr-nfs3.c msg-nfs3.c nsm-xdr.c \
|
||||
nlmcbk-xdr.c
|
||||
nlmcbk-xdr.c acl3-xdr.c
|
||||
|
||||
noinst_HEADERS = xdr-generic.h rpc-common-xdr.h \
|
||||
glusterfs3-xdr.h glusterfs3.h \
|
||||
@ -22,4 +22,4 @@ noinst_HEADERS = xdr-generic.h rpc-common-xdr.h \
|
||||
glusterd1-xdr.h \
|
||||
portmap-xdr.h \
|
||||
nlm4-xdr.h xdr-nfs3.h msg-nfs3.h nsm-xdr.h \
|
||||
nlmcbk-xdr.h
|
||||
nlmcbk-xdr.h acl3-xdr.h
|
||||
|
48
rpc/xdr/src/acl.x
Normal file
48
rpc/xdr/src/acl.x
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Red Hat, Inc. <http://www.redhat.com>
|
||||
* This file is part of GlusterFS.
|
||||
*
|
||||
* This file is licensed to you under your choice of the GNU Lesser
|
||||
* General Public License, version 3 or any later version (LGPLv3 or
|
||||
* later), or the GNU General Public License, version 2 (GPLv2), in all
|
||||
* cases as published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
|
||||
struct aclentry {
|
||||
int type;
|
||||
int uid;
|
||||
int perm;
|
||||
};
|
||||
|
||||
struct getaclargs {
|
||||
netobj fh;
|
||||
int mask;
|
||||
};
|
||||
|
||||
struct getaclreply {
|
||||
int status;
|
||||
int attr_follows;
|
||||
struct fattr3 attr;
|
||||
int mask;
|
||||
int aclcount;
|
||||
struct aclentry aclentry<>;
|
||||
int daclcount;
|
||||
struct aclentry daclentry<>;
|
||||
};
|
||||
|
||||
struct setaclargs {
|
||||
netobj fh;
|
||||
int mask;
|
||||
int aclcount;
|
||||
struct aclentry aclentry<>;
|
||||
int daclcount;
|
||||
struct aclentry daclentry<>;
|
||||
};
|
||||
|
||||
struct setaclreply {
|
||||
int status;
|
||||
int attr_follows;
|
||||
struct fattr3 attr;
|
||||
};
|
||||
|
94
rpc/xdr/src/acl3-xdr.c
Normal file
94
rpc/xdr/src/acl3-xdr.c
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Red Hat, Inc. <http://www.redhat.com>
|
||||
* This file is part of GlusterFS.
|
||||
*
|
||||
* This file is licensed to you under your choice of the GNU Lesser
|
||||
* General Public License, version 3 or any later version (LGPLv3 or
|
||||
* later), or the GNU General Public License, version 2 (GPLv2), in all
|
||||
* cases as published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Please do not edit this file.
|
||||
* It was generated using rpcgen.
|
||||
*/
|
||||
|
||||
#include "acl3-xdr.h"
|
||||
|
||||
bool_t
|
||||
xdr_aclentry (XDR *xdrs, aclentry *objp)
|
||||
{
|
||||
if (!xdr_int (xdrs, &objp->type))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->uid))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->perm))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_getaclargs (XDR *xdrs, getaclargs *objp)
|
||||
{
|
||||
if (!xdr_netobj (xdrs, &objp->fh))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->mask))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_getaclreply (XDR *xdrs, getaclreply *objp)
|
||||
{
|
||||
if (!xdr_int (xdrs, &objp->status))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->attr_follows))
|
||||
return FALSE;
|
||||
if (!xdr_fattr3 (xdrs, &objp->attr))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->mask))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->aclcount))
|
||||
return FALSE;
|
||||
if (!xdr_array (xdrs, (char **)&objp->aclentry.aclentry_val, (u_int *) &objp->aclentry.aclentry_len, ~0,
|
||||
sizeof (aclentry), (xdrproc_t) xdr_aclentry))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->daclcount))
|
||||
return FALSE;
|
||||
if (!xdr_array (xdrs, (char **)&objp->daclentry.daclentry_val, (u_int *) &objp->daclentry.daclentry_len, ~0,
|
||||
sizeof (aclentry), (xdrproc_t) xdr_aclentry))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_setaclargs (XDR *xdrs, setaclargs *objp)
|
||||
{
|
||||
if (!xdr_netobj (xdrs, &objp->fh))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->mask))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->aclcount))
|
||||
return FALSE;
|
||||
if (!xdr_array (xdrs, (char **)&objp->aclentry.aclentry_val, (u_int *) &objp->aclentry.aclentry_len, ~0,
|
||||
sizeof (aclentry), (xdrproc_t) xdr_aclentry))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->daclcount))
|
||||
return FALSE;
|
||||
if (!xdr_array (xdrs, (char **)&objp->daclentry.daclentry_val, (u_int *) &objp->daclentry.daclentry_len, ~0,
|
||||
sizeof (aclentry), (xdrproc_t) xdr_aclentry))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_setaclreply (XDR *xdrs, setaclreply *objp)
|
||||
{
|
||||
if (!xdr_int (xdrs, &objp->status))
|
||||
return FALSE;
|
||||
if (!xdr_int (xdrs, &objp->attr_follows))
|
||||
return FALSE;
|
||||
if (!xdr_fattr3 (xdrs, &objp->attr))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
107
rpc/xdr/src/acl3-xdr.h
Normal file
107
rpc/xdr/src/acl3-xdr.h
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Red Hat, Inc. <http://www.redhat.com>
|
||||
* This file is part of GlusterFS.
|
||||
*
|
||||
* This file is licensed to you under your choice of the GNU Lesser
|
||||
* General Public License, version 3 or any later version (LGPLv3 or
|
||||
* later), or the GNU General Public License, version 2 (GPLv2), in all
|
||||
* cases as published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Please do not edit this file.
|
||||
* It was generated using rpcgen.
|
||||
*/
|
||||
|
||||
#ifndef _ACL_H_RPCGEN
|
||||
#define _ACL_H_RPCGEN
|
||||
|
||||
#include <rpc/rpc.h>
|
||||
#include "xdr-nfs3.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
struct aclentry {
|
||||
int type;
|
||||
int uid;
|
||||
int perm;
|
||||
};
|
||||
typedef struct aclentry aclentry;
|
||||
|
||||
struct getaclargs {
|
||||
netobj fh;
|
||||
int mask;
|
||||
};
|
||||
typedef struct getaclargs getaclargs;
|
||||
|
||||
struct getaclreply {
|
||||
int status;
|
||||
int attr_follows;
|
||||
struct fattr3 attr;
|
||||
int mask;
|
||||
int aclcount;
|
||||
struct {
|
||||
u_int aclentry_len;
|
||||
struct aclentry *aclentry_val;
|
||||
} aclentry;
|
||||
int daclcount;
|
||||
struct {
|
||||
u_int daclentry_len;
|
||||
struct aclentry *daclentry_val;
|
||||
} daclentry;
|
||||
};
|
||||
typedef struct getaclreply getaclreply;
|
||||
|
||||
struct setaclargs {
|
||||
netobj fh;
|
||||
int mask;
|
||||
int aclcount;
|
||||
struct {
|
||||
u_int aclentry_len;
|
||||
struct aclentry *aclentry_val;
|
||||
} aclentry;
|
||||
int daclcount;
|
||||
struct {
|
||||
u_int daclentry_len;
|
||||
struct aclentry *daclentry_val;
|
||||
} daclentry;
|
||||
};
|
||||
typedef struct setaclargs setaclargs;
|
||||
|
||||
struct setaclreply {
|
||||
int status;
|
||||
int attr_follows;
|
||||
struct fattr3 attr;
|
||||
};
|
||||
typedef struct setaclreply setaclreply;
|
||||
|
||||
#define ACL3_NULL 0
|
||||
#define ACL3_GETACL 1
|
||||
#define ACL3_SETACL 2
|
||||
#define ACL3_PROC_COUNT 3
|
||||
/* the xdr functions */
|
||||
|
||||
#if defined(__STDC__) || defined(__cplusplus)
|
||||
extern bool_t xdr_aclentry (XDR *, aclentry*);
|
||||
extern bool_t xdr_getaclargs (XDR *, getaclargs*);
|
||||
extern bool_t xdr_getaclreply (XDR *, getaclreply*);
|
||||
extern bool_t xdr_setaclargs (XDR *, setaclargs*);
|
||||
extern bool_t xdr_setaclreply (XDR *, setaclreply*);
|
||||
|
||||
#else /* K&R C */
|
||||
extern bool_t xdr_aclentry ();
|
||||
extern bool_t xdr_getaclargs ();
|
||||
extern bool_t xdr_getaclreply ();
|
||||
extern bool_t xdr_setaclargs ();
|
||||
extern bool_t xdr_setaclreply ();
|
||||
|
||||
#endif /* K&R C */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !_ACL_H_RPCGEN */
|
@ -541,3 +541,32 @@ xdr_to_nlm4_freeallargs (struct iovec inmsg, nlm4_freeallargs *args)
|
||||
return xdr_to_generic (inmsg, (void*)args,
|
||||
(xdrproc_t)xdr_nlm4_freeallargs);
|
||||
}
|
||||
|
||||
ssize_t
|
||||
xdr_to_getaclargs (struct iovec inmsg, getaclargs *args)
|
||||
{
|
||||
return xdr_to_generic (inmsg, (void *) args,
|
||||
(xdrproc_t)xdr_getaclargs);
|
||||
}
|
||||
|
||||
ssize_t
|
||||
xdr_to_setaclargs (struct iovec inmsg, setaclargs *args)
|
||||
{
|
||||
return xdr_to_generic (inmsg, (void *) args,
|
||||
(xdrproc_t)xdr_setaclargs);
|
||||
}
|
||||
|
||||
ssize_t
|
||||
xdr_serialize_getaclreply (struct iovec inmsg, getaclreply *res)
|
||||
{
|
||||
return xdr_serialize_generic (inmsg, (void *) res,
|
||||
(xdrproc_t)xdr_getaclreply);
|
||||
}
|
||||
|
||||
ssize_t
|
||||
xdr_serialize_setaclreply (struct iovec inmsg, setaclreply *res)
|
||||
{
|
||||
return xdr_serialize_generic (inmsg, (void *) res,
|
||||
(xdrproc_t)xdr_setaclreply);
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include "xdr-nfs3.h"
|
||||
#include "nlm4-xdr.h"
|
||||
#include "acl3-xdr.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
@ -208,4 +209,16 @@ xdr_to_nlm4_res (struct iovec inmsg, nlm4_res *args);
|
||||
extern ssize_t
|
||||
xdr_to_nlm4_freeallargs (struct iovec inmsg, nlm4_freeallargs *args);
|
||||
|
||||
extern ssize_t
|
||||
xdr_to_getaclargs (struct iovec inmsg, getaclargs *args);
|
||||
|
||||
extern ssize_t
|
||||
xdr_to_setaclargs (struct iovec inmsg, setaclargs *args);
|
||||
|
||||
extern ssize_t
|
||||
xdr_serialize_getaclreply (struct iovec inmsg, getaclreply *res);
|
||||
|
||||
extern ssize_t
|
||||
xdr_serialize_setaclreply (struct iovec inmsg, setaclreply *res);
|
||||
|
||||
#endif
|
||||
|
25
tests/bugs/bug-847622.t
Executable file
25
tests/bugs/bug-847622.t
Executable file
@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
|
||||
. $(dirname $0)/../include.rc
|
||||
|
||||
cleanup;
|
||||
|
||||
TEST glusterd
|
||||
TEST pidof glusterd
|
||||
TEST $CLI volume create $V0 $H0:$B0/brick0
|
||||
TEST $CLI volume start $V0
|
||||
|
||||
sleep 5
|
||||
|
||||
TEST mount -t nfs -o vers=3,nolock $H0:/$V0 $N0
|
||||
cd $N0
|
||||
|
||||
# simple getfacl setfacl commands
|
||||
TEST touch testfile
|
||||
TEST setfacl -m u:14:r testfile
|
||||
TEST getfacl testfile
|
||||
|
||||
cd
|
||||
TEST umount $N0
|
||||
cleanup
|
||||
|
@ -4,11 +4,12 @@ nfsrpclibdir = $(top_srcdir)/rpc/rpc-lib/src
|
||||
server_la_LDFLAGS = -module -avoidversion
|
||||
server_la_SOURCES = nfs.c nfs-common.c nfs-fops.c nfs-inodes.c \
|
||||
nfs-generics.c mount3.c nfs3-fh.c nfs3.c nfs3-helpers.c nlm4.c \
|
||||
nlmcbk_svc.c mount3udp_svc.c
|
||||
nlmcbk_svc.c mount3udp_svc.c acl3.c
|
||||
server_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
|
||||
|
||||
noinst_HEADERS = nfs.h nfs-common.h nfs-fops.h nfs-inodes.h nfs-generics.h \
|
||||
mount3.h nfs3-fh.h nfs3.h nfs3-helpers.h nfs-mem-types.h nlm4.h
|
||||
acl3.h
|
||||
|
||||
AM_CPPFLAGS = $(GF_CPPFLAGS) \
|
||||
-DLIBDIR=\"$(libdir)/glusterfs/$(PACKAGE_VERSION)/auth\" \
|
||||
|
621
xlators/nfs/server/src/acl3.c
Normal file
621
xlators/nfs/server/src/acl3.c
Normal file
@ -0,0 +1,621 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Red Hat, Inc. <http://www.redhat.com>
|
||||
* This file is part of GlusterFS.
|
||||
*
|
||||
* This file is licensed to you under your choice of the GNU Lesser
|
||||
* General Public License, version 3 or any later version (LGPLv3 or
|
||||
* later), or the GNU General Public License, version 2 (GPLv2), in all
|
||||
* cases as published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef _CONFIG_H
|
||||
#define _CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "defaults.h"
|
||||
#include "rpcsvc.h"
|
||||
#include "dict.h"
|
||||
#include "xlator.h"
|
||||
#include "nfs.h"
|
||||
#include "mem-pool.h"
|
||||
#include "logging.h"
|
||||
#include "nfs-fops.h"
|
||||
#include "inode.h"
|
||||
#include "nfs3.h"
|
||||
#include "nfs-mem-types.h"
|
||||
#include "nfs3-helpers.h"
|
||||
#include "nfs3-fh.h"
|
||||
#include "nfs-generics.h"
|
||||
#include "acl3.h"
|
||||
|
||||
|
||||
typedef ssize_t (*acl3_serializer) (struct iovec outmsg, void *args);
|
||||
|
||||
extern void nfs3_call_state_wipe (nfs3_call_state_t *cs);
|
||||
|
||||
extern nfs3_call_state_t *
|
||||
nfs3_call_state_init (struct nfs3_state *s, rpcsvc_request_t *req, xlator_t *v);
|
||||
|
||||
extern int
|
||||
nfs3_fh_validate (struct nfs3_fh *fh);
|
||||
|
||||
extern fattr3
|
||||
nfs3_stat_to_fattr3 (struct iatt *buf);
|
||||
|
||||
#define acl3_validate_nfs3_state(request, state, status, label, retval) \
|
||||
do { \
|
||||
state = rpcsvc_request_program_private (request); \
|
||||
if (!state) { \
|
||||
gf_log (GF_ACL, GF_LOG_ERROR, "NFSv3 state " \
|
||||
"missing from RPC request"); \
|
||||
rpcsvc_request_seterr (req, SYSTEM_ERR); \
|
||||
status = NFS3ERR_SERVERFAULT; \
|
||||
goto label; \
|
||||
} \
|
||||
} while (0); \
|
||||
|
||||
#define acl3_validate_gluster_fh(handle, status, errlabel) \
|
||||
do { \
|
||||
if (!nfs3_fh_validate (handle)) { \
|
||||
status = NFS3ERR_SERVERFAULT; \
|
||||
goto errlabel; \
|
||||
} \
|
||||
} while (0) \
|
||||
|
||||
|
||||
extern xlator_t *
|
||||
nfs3_fh_to_xlator (struct nfs3_state *nfs3, struct nfs3_fh *fh);
|
||||
|
||||
#define acl3_map_fh_to_volume(nfs3state, handle, req, volume, status, label) \
|
||||
do { \
|
||||
char exportid[256], gfid[256]; \
|
||||
rpc_transport_t *trans = NULL; \
|
||||
volume = nfs3_fh_to_xlator ((nfs3state), handle); \
|
||||
if (!volume) { \
|
||||
uuid_unparse (handle->exportid, exportid); \
|
||||
uuid_unparse (handle->gfid, gfid); \
|
||||
trans = rpcsvc_request_transport (req); \
|
||||
gf_log (GF_ACL, GF_LOG_ERROR, "Failed to map " \
|
||||
"FH to vol: client=%s, exportid=%s, gfid=%s",\
|
||||
trans->peerinfo.identifier, exportid, \
|
||||
gfid); \
|
||||
gf_log (GF_ACL, GF_LOG_ERROR, \
|
||||
"Stale nfs client %s must be trying to "\
|
||||
"connect to a deleted volume, please " \
|
||||
"unmount it.", trans->peerinfo.identifier);\
|
||||
status = NFS3ERR_STALE; \
|
||||
goto label; \
|
||||
} else { \
|
||||
gf_log (GF_ACL, GF_LOG_TRACE, "FH to Volume: %s"\
|
||||
,volume->name); \
|
||||
rpcsvc_request_set_private (req, volume); \
|
||||
} \
|
||||
} while (0); \
|
||||
|
||||
#define acl3_volume_started_check(nfs3state, vlm, rtval, erlbl) \
|
||||
do { \
|
||||
if ((!nfs_subvolume_started (nfs_state (nfs3state->nfsx), vlm))){\
|
||||
gf_log (GF_ACL, GF_LOG_ERROR, "Volume is disabled: %s",\
|
||||
vlm->name); \
|
||||
rtval = RPCSVC_ACTOR_IGNORE; \
|
||||
goto erlbl; \
|
||||
} \
|
||||
} while (0) \
|
||||
|
||||
#define acl3_check_fh_resolve_status(cst, nfstat, erlabl) \
|
||||
do { \
|
||||
xlator_t *xlatorp = NULL; \
|
||||
char buf[256], gfid[256]; \
|
||||
rpc_transport_t *trans = NULL; \
|
||||
if ((cst)->resolve_ret < 0) { \
|
||||
trans = rpcsvc_request_transport (cst->req); \
|
||||
xlatorp = nfs3_fh_to_xlator (cst->nfs3state, \
|
||||
&cst->resolvefh); \
|
||||
uuid_unparse (cst->resolvefh.gfid, gfid); \
|
||||
sprintf (buf, "(%s) %s : %s", trans->peerinfo.identifier,\
|
||||
xlatorp ? xlatorp->name : "ERR", gfid); \
|
||||
gf_log (GF_ACL, GF_LOG_ERROR, "Unable to resolve FH"\
|
||||
": %s", buf); \
|
||||
nfstat = nfs3_errno_to_nfsstat3 (cst->resolve_errno);\
|
||||
goto erlabl; \
|
||||
} \
|
||||
} while (0) \
|
||||
|
||||
#define acl3_handle_call_state_init(nfs3state, calls, rq, v, opstat, errlabel)\
|
||||
do { \
|
||||
calls = nfs3_call_state_init ((nfs3state), (rq), v); \
|
||||
if (!calls) { \
|
||||
gf_log (GF_NLM, GF_LOG_ERROR, "Failed to " \
|
||||
"init call state"); \
|
||||
opstat = nlm4_failed; \
|
||||
rpcsvc_request_seterr (req, SYSTEM_ERR); \
|
||||
goto errlabel; \
|
||||
} \
|
||||
} while (0) \
|
||||
|
||||
|
||||
int
|
||||
acl3svc_submit_reply (rpcsvc_request_t *req, void *arg, acl3_serializer sfunc)
|
||||
{
|
||||
struct iovec outmsg = {0, };
|
||||
struct iobuf *iob = NULL;
|
||||
struct nfs3_state *nfs3 = NULL;
|
||||
int ret = -1;
|
||||
struct iobref *iobref = NULL;
|
||||
|
||||
if (!req)
|
||||
return -1;
|
||||
|
||||
nfs3 = (struct nfs3_state *)rpcsvc_request_program_private (req);
|
||||
if (!nfs3) {
|
||||
gf_log (GF_ACL, GF_LOG_ERROR, "mount state not found");
|
||||
goto ret;
|
||||
}
|
||||
|
||||
/* First, get the io buffer into which the reply in arg will
|
||||
* be serialized.
|
||||
*/
|
||||
iob = iobuf_get (nfs3->iobpool);
|
||||
if (!iob) {
|
||||
gf_log (GF_ACL, GF_LOG_ERROR, "Failed to get iobuf");
|
||||
goto ret;
|
||||
}
|
||||
|
||||
iobuf_to_iovec (iob, &outmsg);
|
||||
/* Use the given serializer to translate the give C structure in arg
|
||||
* to XDR format which will be written into the buffer in outmsg.
|
||||
*/
|
||||
outmsg.iov_len = sfunc (outmsg, arg);
|
||||
|
||||
iobref = iobref_new ();
|
||||
if (iobref == NULL) {
|
||||
gf_log (GF_ACL, GF_LOG_ERROR, "Failed to get iobref");
|
||||
goto ret;
|
||||
}
|
||||
|
||||
iobref_add (iobref, iob);
|
||||
|
||||
/* Then, submit the message for transmission. */
|
||||
ret = rpcsvc_submit_message (req, &outmsg, 1, NULL, 0, iobref);
|
||||
if (ret == -1) {
|
||||
gf_log (GF_ACL, GF_LOG_ERROR, "Reply submission failed");
|
||||
goto ret;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
ret:
|
||||
if (iob)
|
||||
iobuf_unref (iob);
|
||||
if (iobref)
|
||||
iobref_unref (iobref);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
acl3svc_null (rpcsvc_request_t *req)
|
||||
{
|
||||
struct iovec dummyvec = {0, };
|
||||
|
||||
if (!req) {
|
||||
gf_log (GF_ACL, GF_LOG_ERROR, "Got NULL request!");
|
||||
return 0;
|
||||
}
|
||||
rpcsvc_submit_generic (req, &dummyvec, 1, NULL, 0, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
acl3_getacl_reply (nfs3_call_state_t *cs, getaclreply *reply)
|
||||
{
|
||||
acl3svc_submit_reply (cs->req, (void *)reply,
|
||||
(acl3_serializer)xdr_serialize_getaclreply);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
acl3_getacl_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
||||
int32_t op_ret, int32_t op_errno, dict_t *dict,
|
||||
dict_t *xdata)
|
||||
{
|
||||
nfsstat3 stat = NFS3ERR_SERVERFAULT;
|
||||
nfs3_call_state_t *cs = NULL;
|
||||
data_t *data = NULL;
|
||||
int *p = NULL;
|
||||
int i = 0;
|
||||
getaclreply *getaclreply = NULL;
|
||||
|
||||
cs = frame->local;
|
||||
if (op_ret == -1) {
|
||||
stat = nfs3_errno_to_nfsstat3 (op_errno);
|
||||
goto err;
|
||||
}
|
||||
|
||||
getaclreply = &cs->args.getaclreply;
|
||||
getaclreply->aclentry.aclentry_val = cs->aclentry;
|
||||
getaclreply->daclentry.daclentry_val = cs->daclentry;
|
||||
|
||||
/* FIXME: use posix_acl_from_xattr() */
|
||||
data = dict_get (dict, "system.posix_acl_access");
|
||||
if (data && (p = data_to_bin (data))) {
|
||||
/* POSIX_ACL_XATTR_VERSION */
|
||||
p++;
|
||||
while ((char *)p < (data->data + data->len)) {
|
||||
getaclreply->aclentry.aclentry_val[i].type = *(*(short **)&p)++;
|
||||
getaclreply->aclentry.aclentry_val[i].perm = *(*(short **)&p)++;
|
||||
getaclreply->aclentry.aclentry_val[i].uid = *(*(int **)&p)++;
|
||||
i++;
|
||||
}
|
||||
getaclreply->aclcount = getaclreply->aclentry.aclentry_len = i;
|
||||
}
|
||||
i = 0;
|
||||
|
||||
data = dict_get (dict, "system.posix_acl_default");
|
||||
if (data && (p = data_to_bin (data))) {
|
||||
/* POSIX_ACL_XATTR_VERSION */
|
||||
p++;
|
||||
while ((char *)p < (data->data + data->len)) {
|
||||
getaclreply->daclentry.daclentry_val[i].type = *(*(short **)&p)++;
|
||||
getaclreply->daclentry.daclentry_val[i].perm = *(*(short **)&p)++;
|
||||
getaclreply->daclentry.daclentry_val[i].uid = *(*(int **)&p)++;
|
||||
i++;
|
||||
}
|
||||
getaclreply->daclcount = getaclreply->daclentry.daclentry_len = i;
|
||||
}
|
||||
|
||||
acl3_getacl_reply (cs, getaclreply);
|
||||
nfs3_call_state_wipe (cs);
|
||||
return 0;
|
||||
|
||||
err:
|
||||
getaclreply->status = stat;
|
||||
acl3_getacl_reply (cs, getaclreply);
|
||||
nfs3_call_state_wipe (cs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
acl3_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
||||
int32_t op_ret, int32_t op_errno, struct iatt *buf,
|
||||
dict_t *xdata)
|
||||
{
|
||||
nfsstat3 stat = NFS3ERR_SERVERFAULT;
|
||||
nfs3_call_state_t *cs = NULL;
|
||||
getaclreply *getaclreply = NULL;
|
||||
int ret = -1;
|
||||
nfs_user_t nfu = {0, };
|
||||
|
||||
cs = frame->local;
|
||||
if (op_ret == -1) {
|
||||
stat = nfs3_errno_to_nfsstat3 (op_errno);
|
||||
goto err;
|
||||
}
|
||||
|
||||
getaclreply = &cs->args.getaclreply;
|
||||
|
||||
getaclreply->attr_follows = 1;
|
||||
getaclreply->attr = nfs3_stat_to_fattr3 (buf);
|
||||
getaclreply->mask = 0xf;
|
||||
nfs_request_user_init (&nfu, cs->req);
|
||||
ret = nfs_getxattr (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc, NULL, NULL,
|
||||
acl3_getacl_cbk, cs);
|
||||
if (ret == -1) {
|
||||
stat = nfs3_errno_to_nfsstat3 (op_errno);
|
||||
goto err;
|
||||
}
|
||||
return 0;
|
||||
err:
|
||||
getaclreply->status = stat;
|
||||
acl3_getacl_reply (cs, getaclreply);
|
||||
nfs3_call_state_wipe (cs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
acl3_getacl_resume (void *carg)
|
||||
{
|
||||
int ret = -1;
|
||||
nfs3_call_state_t *cs = NULL;
|
||||
nfsstat3 stat = NFS3ERR_SERVERFAULT;
|
||||
nfs_user_t nfu = {0, };
|
||||
|
||||
if (!carg)
|
||||
return ret;
|
||||
|
||||
cs = (nfs3_call_state_t *)carg;
|
||||
acl3_check_fh_resolve_status (cs, stat, acl3err);
|
||||
nfs_request_user_init (&nfu, cs->req);
|
||||
|
||||
ret = nfs_stat (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
|
||||
acl3_stat_cbk, cs);
|
||||
stat = -ret;
|
||||
acl3err:
|
||||
if (ret < 0) {
|
||||
gf_log (GF_ACL, GF_LOG_ERROR, "unable to open_and_resume");
|
||||
cs->args.getaclreply.status = nfs3_errno_to_nfsstat3 (stat);
|
||||
acl3_getacl_reply (cs, &cs->args.getaclreply);
|
||||
nfs3_call_state_wipe (cs);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
acl3svc_getacl (rpcsvc_request_t *req)
|
||||
{
|
||||
xlator_t *vol = NULL;
|
||||
struct nfs_state *nfs = NULL;
|
||||
nfs3_state_t *nfs3 = NULL;
|
||||
nfs3_call_state_t *cs = NULL;
|
||||
int ret = RPCSVC_ACTOR_ERROR;
|
||||
nfsstat3 stat = NFS3ERR_SERVERFAULT;
|
||||
struct nfs3_fh fh, *fhp = NULL;
|
||||
getaclargs getaclargs;
|
||||
|
||||
if (!req)
|
||||
return ret;
|
||||
|
||||
acl3_validate_nfs3_state (req, nfs3, stat, rpcerr, ret);
|
||||
nfs = nfs_state (nfs3->nfsx);
|
||||
memset (&getaclargs, 0, sizeof (getaclargs));
|
||||
getaclargs.fh.n_bytes = (char *)&fh;
|
||||
if (xdr_to_getaclargs(req->msg[0], &getaclargs) <= 0) {
|
||||
gf_log (GF_ACL, GF_LOG_ERROR, "Error decoding args");
|
||||
rpcsvc_request_seterr (req, GARBAGE_ARGS);
|
||||
goto rpcerr;
|
||||
}
|
||||
fhp = &fh;
|
||||
acl3_validate_gluster_fh (&fh, stat, acl3err);
|
||||
acl3_map_fh_to_volume (nfs->nfs3state, fhp, req,
|
||||
vol, stat, acl3err);
|
||||
acl3_handle_call_state_init (nfs->nfs3state, cs, req,
|
||||
vol, stat, rpcerr);
|
||||
|
||||
cs->vol = vol;
|
||||
acl3_volume_started_check (nfs3, vol, ret, rpcerr);
|
||||
|
||||
ret = nfs3_fh_resolve_and_resume (cs, fhp,
|
||||
NULL, acl3_getacl_resume);
|
||||
|
||||
acl3err:
|
||||
if (ret < 0) {
|
||||
gf_log (GF_ACL, GF_LOG_ERROR, "unable to resolve and resume");
|
||||
cs->args.getaclreply.status = stat;
|
||||
acl3_getacl_reply (cs, &cs->args.getaclreply);
|
||||
nfs3_call_state_wipe (cs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
rpcerr:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
acl3_setacl_cbk (call_frame_t *frame, void *cookie,
|
||||
xlator_t *this, int32_t op_ret, int32_t op_errno,
|
||||
dict_t *xdata)
|
||||
{
|
||||
nfs3_call_state_t *cs = NULL;
|
||||
cs = frame->local;
|
||||
if (op_ret < 0) {
|
||||
cs->args.setaclreply.status = nfs3_errno_to_nfsstat3 (op_errno);
|
||||
}
|
||||
|
||||
acl3svc_submit_reply (cs->req, (void *)&cs->args.setaclreply,
|
||||
(acl3_serializer)xdr_serialize_setaclreply);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
acl3_setacl_resume (void *carg)
|
||||
{
|
||||
int ret = -1;
|
||||
nfs3_call_state_t *cs = NULL;
|
||||
nfsstat3 stat = NFS3ERR_SERVERFAULT;
|
||||
nfs_user_t nfu = {0, };
|
||||
dict_t *xattr = NULL;
|
||||
|
||||
if (!carg)
|
||||
return ret;
|
||||
|
||||
cs = (nfs3_call_state_t *)carg;
|
||||
acl3_check_fh_resolve_status (cs, stat, acl3err);
|
||||
nfs_request_user_init (&nfu, cs->req);
|
||||
xattr = dict_new();
|
||||
if (cs->aclcount)
|
||||
ret = dict_set_static_bin (xattr, "system.posix_acl_access", cs->aclxattr,
|
||||
cs->aclcount * 8 + 4);
|
||||
if (cs->daclcount)
|
||||
ret = dict_set_static_bin (xattr, "system.posix_acl_default", cs->daclxattr,
|
||||
cs->daclcount * 8 + 4);
|
||||
|
||||
ret = nfs_setxattr (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc, xattr,
|
||||
0, NULL, acl3_setacl_cbk, cs);
|
||||
dict_unref (xattr);
|
||||
|
||||
acl3err:
|
||||
if (ret < 0) {
|
||||
stat = -ret;
|
||||
gf_log (GF_ACL, GF_LOG_ERROR, "unable to open_and_resume");
|
||||
cs->args.setaclreply.status = nfs3_errno_to_nfsstat3 (stat);
|
||||
acl3svc_submit_reply (cs->req, (void *)&cs->args.setaclreply,
|
||||
(acl3_serializer)xdr_serialize_setaclreply);
|
||||
nfs3_call_state_wipe (cs);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
acl3svc_setacl (rpcsvc_request_t *req)
|
||||
{
|
||||
xlator_t *vol = NULL;
|
||||
struct nfs_state *nfs = NULL;
|
||||
nfs3_state_t *nfs3 = NULL;
|
||||
nfs3_call_state_t *cs = NULL;
|
||||
int ret = RPCSVC_ACTOR_ERROR;
|
||||
nfsstat3 stat = NFS3ERR_SERVERFAULT;
|
||||
struct nfs3_fh fh;
|
||||
struct nfs3_fh *fhp = NULL;
|
||||
setaclargs setaclargs;
|
||||
aclentry aclentry[NFS_ACL_MAX_ENTRIES];
|
||||
struct aclentry daclentry[NFS_ACL_MAX_ENTRIES];
|
||||
int *p = NULL, i = 0;
|
||||
|
||||
if (!req)
|
||||
return ret;
|
||||
|
||||
acl3_validate_nfs3_state (req, nfs3, stat, rpcerr, ret);
|
||||
nfs = nfs_state (nfs3->nfsx);
|
||||
memset (&setaclargs, 0, sizeof (setaclargs));
|
||||
memset (&fh, 0, sizeof (fh));
|
||||
setaclargs.fh.n_bytes = (char *)&fh;
|
||||
setaclargs.aclentry.aclentry_val = aclentry;
|
||||
setaclargs.daclentry.daclentry_val = daclentry;
|
||||
if (xdr_to_setaclargs(req->msg[0], &setaclargs) <= 0) {
|
||||
gf_log (GF_ACL, GF_LOG_ERROR, "Error decoding args");
|
||||
rpcsvc_request_seterr (req, GARBAGE_ARGS);
|
||||
goto rpcerr;
|
||||
}
|
||||
fhp = &fh;
|
||||
acl3_validate_gluster_fh (fhp, stat, acl3err);
|
||||
acl3_map_fh_to_volume (nfs->nfs3state, fhp, req,
|
||||
vol, stat, acl3err);
|
||||
acl3_handle_call_state_init (nfs->nfs3state, cs, req,
|
||||
vol, stat, rpcerr);
|
||||
|
||||
cs->vol = vol;
|
||||
acl3_volume_started_check (nfs3, vol, ret, rpcerr);
|
||||
|
||||
cs->aclcount = setaclargs.aclcount;
|
||||
cs->daclcount = setaclargs.daclcount;
|
||||
|
||||
if ((cs->aclcount > NFS_ACL_MAX_ENTRIES) ||
|
||||
(cs->daclcount > NFS_ACL_MAX_ENTRIES))
|
||||
goto acl3err;
|
||||
/* FIXME: use posix_acl_to_xattr() */
|
||||
p = (int *)cs->aclxattr;
|
||||
*(*(int **)&p)++ = POSIX_ACL_XATTR_VERSION;
|
||||
for (i = 0; i < cs->aclcount; i++) {
|
||||
*(*(short **)&p)++ = aclentry[i].type;
|
||||
*(*(short **)&p)++ = aclentry[i].perm;
|
||||
*(*(int **)&p)++ = aclentry[i].uid;
|
||||
}
|
||||
p = (int *)cs->daclxattr;
|
||||
*(*(int **)&p)++ = POSIX_ACL_XATTR_VERSION;
|
||||
for (i = 0; i < cs->daclcount; i++) {
|
||||
*(*(short **)&p)++ = daclentry[i].type;
|
||||
*(*(short **)&p)++ = daclentry[i].perm;
|
||||
*(*(int **)&p)++ = daclentry[i].uid;
|
||||
}
|
||||
|
||||
|
||||
ret = nfs3_fh_resolve_and_resume (cs, fhp,
|
||||
NULL, acl3_setacl_resume);
|
||||
|
||||
acl3err:
|
||||
if (ret < 0) {
|
||||
gf_log (GF_ACL, GF_LOG_ERROR, "unable to resolve and resume");
|
||||
cs->args.setaclreply.status = stat;
|
||||
acl3svc_submit_reply (cs->req, (void *)&cs->args.setaclreply,
|
||||
(acl3_serializer)xdr_serialize_setaclreply);
|
||||
nfs3_call_state_wipe (cs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
rpcerr:
|
||||
if (ret < 0)
|
||||
nfs3_call_state_wipe (cs);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
rpcsvc_actor_t acl3svc_actors[ACL3_PROC_COUNT] = {
|
||||
{"NULL", ACL3_NULL, acl3svc_null, NULL, 0},
|
||||
{"GETACL", ACL3_GETACL, acl3svc_getacl, NULL, 0},
|
||||
{"SETACL", ACL3_SETACL, acl3svc_setacl, NULL, 0},
|
||||
};
|
||||
|
||||
rpcsvc_program_t acl3prog = {
|
||||
.progname = "ACL3",
|
||||
.prognum = ACL_PROGRAM,
|
||||
.progver = ACL_V3,
|
||||
.progport = GF_NFS3_PORT,
|
||||
.actors = acl3svc_actors,
|
||||
.numactors = ACL3_PROC_COUNT,
|
||||
.min_auth = AUTH_NULL,
|
||||
};
|
||||
|
||||
rpcsvc_program_t *
|
||||
acl3svc_init(xlator_t *nfsx)
|
||||
{
|
||||
struct nfs3_state *ns = NULL;
|
||||
struct nfs_state *nfs = NULL;
|
||||
dict_t *options = NULL;
|
||||
int ret = -1;
|
||||
char *portstr = NULL;
|
||||
|
||||
nfs = (struct nfs_state*)nfsx->private;
|
||||
|
||||
ns = nfs->nfs3state;
|
||||
if (!ns) {
|
||||
gf_log (GF_ACL, GF_LOG_ERROR, "ACL3 init failed");
|
||||
goto err;
|
||||
}
|
||||
acl3prog.private = ns;
|
||||
|
||||
options = dict_new ();
|
||||
|
||||
ret = gf_asprintf (&portstr, "%d", GF_ACL3_PORT);
|
||||
if (ret == -1)
|
||||
goto err;
|
||||
|
||||
ret = dict_set_dynstr (options, "transport.socket.listen-port",
|
||||
portstr);
|
||||
if (ret == -1)
|
||||
goto err;
|
||||
ret = dict_set_str (options, "transport-type", "socket");
|
||||
if (ret == -1) {
|
||||
gf_log (GF_ACL, GF_LOG_ERROR, "dict_set_str error");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (nfs->allow_insecure) {
|
||||
ret = dict_set_str (options, "rpc-auth-allow-insecure", "on");
|
||||
if (ret == -1) {
|
||||
gf_log (GF_ACL, GF_LOG_ERROR, "dict_set_str error");
|
||||
goto err;
|
||||
}
|
||||
ret = dict_set_str (options, "rpc-auth.ports.insecure", "on");
|
||||
if (ret == -1) {
|
||||
gf_log (GF_ACL, GF_LOG_ERROR, "dict_set_str error");
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
ret = dict_set_str (options, "transport.address-family", "inet");
|
||||
if (ret == -1) {
|
||||
gf_log (GF_ACL, GF_LOG_ERROR, "dict_set_str error");
|
||||
goto err;
|
||||
}
|
||||
|
||||
rpcsvc_create_listeners (nfs->rpcsvc, options, "ACL");
|
||||
if (ret == -1) {
|
||||
gf_log (GF_ACL, GF_LOG_ERROR, "Unable to create listeners");
|
||||
dict_unref (options);
|
||||
goto err;
|
||||
}
|
||||
|
||||
return &acl3prog;
|
||||
err:
|
||||
return NULL;
|
||||
}
|
30
xlators/nfs/server/src/acl3.h
Normal file
30
xlators/nfs/server/src/acl3.h
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Red Hat, Inc. <http://www.redhat.com>
|
||||
* This file is part of GlusterFS.
|
||||
*
|
||||
* This file is licensed to you under your choice of the GNU Lesser
|
||||
* General Public License, version 3 or any later version (LGPLv3 or
|
||||
* later), or the GNU General Public License, version 2 (GPLv2), in all
|
||||
* cases as published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef _ACL3_H
|
||||
#define _ACL3_H
|
||||
|
||||
#define GF_ACL3_PORT 38469
|
||||
#define GF_ACL GF_NFS"-ACL"
|
||||
|
||||
#define ACL_PROGRAM 100227
|
||||
#define ACL_V3 3
|
||||
|
||||
#define ACL_USER_OBJ 0x1
|
||||
#define ACL_GROUP_OBJ 0x4
|
||||
#define ACL_OTHER_OBJ 0x20
|
||||
|
||||
#define POSIX_ACL_XATTR_VERSION 0x0002
|
||||
#define NFS_ACL_MAX_ENTRIES 1024
|
||||
|
||||
rpcsvc_program_t *
|
||||
acl3svc_init(xlator_t *nfsx);
|
||||
|
||||
#endif
|
@ -1539,6 +1539,95 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t
|
||||
nfs_fop_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
||||
int32_t op_ret, int32_t op_errno, dict_t *dict,
|
||||
dict_t *xdata)
|
||||
{
|
||||
struct nfs_fop_local *nfl = NULL;
|
||||
fop_getxattr_cbk_t progcbk = NULL;
|
||||
|
||||
nfl_to_prog_data (nfl, progcbk, frame);
|
||||
|
||||
if (progcbk)
|
||||
progcbk (frame, cookie, this, op_ret, op_errno, dict, xdata);
|
||||
|
||||
nfs_stack_destroy (nfl, frame);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
nfs_fop_getxattr (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *loc,
|
||||
char *name, dict_t *xdata, fop_getxattr_cbk_t cbk, void *local)
|
||||
{
|
||||
call_frame_t *frame = NULL;
|
||||
int ret = -EFAULT;
|
||||
struct nfs_fop_local *nfl = NULL;
|
||||
|
||||
if ((!xl) || (!loc) || (!nfu))
|
||||
return ret;
|
||||
|
||||
nfs_fop_handle_frame_create (frame, nfsx, nfu, ret, err);
|
||||
nfs_fop_handle_local_init (frame, nfsx, nfl, cbk, local, ret, err);
|
||||
|
||||
STACK_WIND_COOKIE (frame, nfs_fop_getxattr_cbk, xl, xl, xl->fops->getxattr,
|
||||
loc, name, NULL);
|
||||
ret = 0;
|
||||
err:
|
||||
if (ret < 0) {
|
||||
if (frame)
|
||||
nfs_stack_destroy (nfl, frame);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int32_t
|
||||
nfs_fop_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
||||
int32_t op_ret, int32_t op_errno, dict_t *xdata)
|
||||
{
|
||||
struct nfs_fop_local *nfl = NULL;
|
||||
fop_setxattr_cbk_t progcbk = NULL;
|
||||
|
||||
nfl_to_prog_data (nfl, progcbk, frame);
|
||||
|
||||
if (progcbk)
|
||||
progcbk (frame, cookie, this, op_ret, op_errno, xdata);
|
||||
|
||||
nfs_stack_destroy (nfl, frame);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
nfs_fop_setxattr (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu,
|
||||
loc_t *loc, dict_t *dict, int32_t flags, dict_t *xdata,
|
||||
fop_setxattr_cbk_t cbk, void *local)
|
||||
{
|
||||
call_frame_t *frame = NULL;
|
||||
int ret = -EFAULT;
|
||||
struct nfs_fop_local *nfl = NULL;
|
||||
|
||||
if ((!xl) || (!loc) || (!nfu))
|
||||
return ret;
|
||||
|
||||
nfs_fop_handle_frame_create (frame, nfsx, nfu, ret, err);
|
||||
nfs_fop_handle_local_init (frame, nfsx, nfl, cbk, local, ret, err);
|
||||
|
||||
STACK_WIND_COOKIE (frame, nfs_fop_setxattr_cbk, xl, xl, xl->fops->setxattr,
|
||||
loc, dict, flags, xdata);
|
||||
ret = 0;
|
||||
err:
|
||||
if (ret < 0) {
|
||||
if (frame)
|
||||
nfs_stack_destroy (nfl, frame);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int32_t
|
||||
nfs_fop_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
||||
|
@ -245,4 +245,13 @@ extern int
|
||||
nfs_fop_lk (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd,
|
||||
int cmd, struct gf_flock *flock, fop_lk_cbk_t cbk, void *local);
|
||||
|
||||
extern int
|
||||
nfs_fop_getxattr (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *loc,
|
||||
char *name, dict_t *xdata, fop_getxattr_cbk_t cbk, void *local);
|
||||
|
||||
extern int
|
||||
nfs_fop_setxattr (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu,
|
||||
loc_t *loc, dict_t *dict, int32_t flags, dict_t *xdata,
|
||||
fop_setxattr_cbk_t cbk, void *local);
|
||||
|
||||
#endif
|
||||
|
@ -165,6 +165,22 @@ nfs_lk (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd,
|
||||
return nfs_fop_lk ( nfsx, xl, nfu, fd, cmd, flock, cbk, local);
|
||||
}
|
||||
|
||||
int
|
||||
nfs_getxattr (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *loc,
|
||||
char *name, dict_t *xdata, fop_getxattr_cbk_t cbk, void *local)
|
||||
{
|
||||
return nfs_fop_getxattr (nfsx, xl, nfu, loc, name, xdata, cbk, local);
|
||||
}
|
||||
|
||||
int
|
||||
nfs_setxattr (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu,
|
||||
loc_t *loc, dict_t *dict, int32_t flags, dict_t *xdata,
|
||||
fop_setxattr_cbk_t cbk, void *local)
|
||||
{
|
||||
return nfs_fop_setxattr (nfsx, xl, nfu, loc, dict, flags, xdata, cbk,
|
||||
local);
|
||||
}
|
||||
|
||||
int
|
||||
nfs_fsync (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd,
|
||||
int32_t datasync, fop_fsync_cbk_t cbk, void *local)
|
||||
|
@ -164,4 +164,14 @@ nfs_access (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
|
||||
extern int
|
||||
nfs_lk (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd,
|
||||
int cmd, struct gf_flock *flock, fop_lk_cbk_t cbk, void *local);
|
||||
|
||||
extern int
|
||||
nfs_getxattr (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *loc,
|
||||
char *name, dict_t *xdata, fop_getxattr_cbk_t cbk, void *local);
|
||||
|
||||
extern int
|
||||
nfs_setxattr (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu,
|
||||
loc_t *loc, dict_t *dict, int32_t flags, dict_t *xdata,
|
||||
fop_setxattr_cbk_t cbk, void *local);
|
||||
|
||||
#endif
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include "nfs3-helpers.h"
|
||||
#include "nlm4.h"
|
||||
#include "options.h"
|
||||
#include "acl3.h"
|
||||
|
||||
#define OPT_SERVER_AUX_GIDS "nfs.server-aux-gids"
|
||||
#define OPT_SERVER_GID_CACHE_TIMEOUT "nfs.server.aux-gid-timeout"
|
||||
@ -186,6 +187,13 @@ nfs_add_all_initiators (struct nfs_state *nfs)
|
||||
}
|
||||
}
|
||||
|
||||
ret = nfs_add_initer (&nfs->versions, acl3svc_init);
|
||||
if (ret == -1) {
|
||||
gf_log (GF_NFS, GF_LOG_ERROR, "Failed to add protocol"
|
||||
" initializer");
|
||||
goto ret;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
ret:
|
||||
return ret;
|
||||
|
@ -35,7 +35,8 @@
|
||||
#include "xdr-nfs3.h"
|
||||
#include "mem-pool.h"
|
||||
#include "nlm4.h"
|
||||
|
||||
#include "acl3-xdr.h"
|
||||
#include "acl3.h"
|
||||
#include <sys/statvfs.h>
|
||||
|
||||
#define GF_NFS3 GF_NFS"-nfsv3"
|
||||
@ -155,6 +156,10 @@ typedef union args_ {
|
||||
nlm4_shareargs nlm4_shareargs;
|
||||
nlm4_shareres nlm4_shareres;
|
||||
nlm4_freeallargs nlm4_freeallargs;
|
||||
getaclargs getaclargs;
|
||||
setaclargs setaclargs;
|
||||
getaclreply getaclreply;
|
||||
setaclreply setaclreply;
|
||||
} args;
|
||||
|
||||
|
||||
@ -234,6 +239,14 @@ struct nfs3_local {
|
||||
int monitor;
|
||||
rpc_transport_t *trans;
|
||||
call_frame_t *frame;
|
||||
|
||||
/* ACL */
|
||||
aclentry aclentry[NFS_ACL_MAX_ENTRIES];
|
||||
aclentry daclentry[NFS_ACL_MAX_ENTRIES];
|
||||
int aclcount;
|
||||
char aclxattr[NFS_ACL_MAX_ENTRIES*8 + 4];
|
||||
int daclcount;
|
||||
char daclxattr[NFS_ACL_MAX_ENTRIES*8 + 4];
|
||||
};
|
||||
|
||||
#define nfs3_is_revalidate_lookup(cst) ((cst)->lookuptype == GF_NFS3_REVALIDATE)
|
||||
|
Loading…
x
Reference in New Issue
Block a user