From f9e0638b7597f4b1a4245f63c94d3d6bd3158136 Mon Sep 17 00:00:00 2001 From: Shehjar Tikoo Date: Mon, 4 Jul 2011 06:32:32 +0000 Subject: nfs: Change NFS3 access op to use access fop This change is needed so that we have a uniform dependence on posix-acl for permission checks as well as ACL checks. Signed-off-by: Shehjar Tikoo Signed-off-by: Anand Avati BUG: 3057 (acl permissions don't work on nfs mount) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=3057 --- xlators/nfs/server/src/nfs-fops.c | 42 +++++++++ xlators/nfs/server/src/nfs-fops.h | 3 + xlators/nfs/server/src/nfs-generics.c | 13 +++ xlators/nfs/server/src/nfs-generics.h | 4 + xlators/nfs/server/src/nfs3-helpers.c | 169 +++------------------------------- xlators/nfs/server/src/nfs3-helpers.h | 4 +- xlators/nfs/server/src/nfs3.c | 23 ++--- 7 files changed, 84 insertions(+), 174 deletions(-) (limited to 'xlators') diff --git a/xlators/nfs/server/src/nfs-fops.c b/xlators/nfs/server/src/nfs-fops.c index ff055aa51..0a0e01fc9 100644 --- a/xlators/nfs/server/src/nfs-fops.c +++ b/xlators/nfs/server/src/nfs-fops.c @@ -353,6 +353,48 @@ err: return ret; } +int32_t +nfs_fop_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno) +{ + struct nfs_fop_local *nfl = NULL; + fop_access_cbk_t progcbk = NULL; + + nfl_to_prog_data (nfl, progcbk, frame); + if (progcbk) + progcbk (frame, cookie, this, op_ret, op_errno); + + nfs_stack_destroy (nfl, frame); + return 0; +} + +int +nfs_fop_access (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *loc, + int32_t accesstest, fop_access_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; + + gf_log (GF_NFS, GF_LOG_TRACE, "Access: %s", loc->path); + nfs_fop_handle_frame_create (frame, nfsx, nfu, ret, err); + nfs_fop_handle_local_init (frame, nfsx, nfl, cbk, local, ret, err); + nfs_fop_save_root_ino (nfl, loc); + + STACK_WIND_COOKIE (frame, nfs_fop_access_cbk, xl, xl, xl->fops->access, + loc, accesstest); + ret = 0; +err: + if (ret < 0) { + if (frame) + nfs_stack_destroy (nfl, frame); + } + + return ret; +} int32_t nfs_fop_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, diff --git a/xlators/nfs/server/src/nfs-fops.h b/xlators/nfs/server/src/nfs-fops.h index d010db282..4d09e3e24 100644 --- a/xlators/nfs/server/src/nfs-fops.h +++ b/xlators/nfs/server/src/nfs-fops.h @@ -233,4 +233,7 @@ extern int nfs_fop_stat (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *loc, fop_stat_cbk_t cbk, void *local); +extern int +nfs_fop_access (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *loc, + int32_t accesstest, fop_access_cbk_t cbk, void *local); #endif diff --git a/xlators/nfs/server/src/nfs-generics.c b/xlators/nfs/server/src/nfs-generics.c index 0ebba689a..010fb1756 100644 --- a/xlators/nfs/server/src/nfs-generics.c +++ b/xlators/nfs/server/src/nfs-generics.c @@ -46,6 +46,19 @@ nfs_fstat (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd, return ret; } +int +nfs_access (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc, + int32_t accesstest, fop_access_cbk_t cbk, void *local) +{ + int ret = -EFAULT; + + if ((!nfsx) || (!xl) || (!pathloc) || (!nfu)) + return ret; + + ret = nfs_fop_access (nfsx, xl, nfu, pathloc, accesstest, cbk, local); + + return ret; +} int nfs_stat (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc, diff --git a/xlators/nfs/server/src/nfs-generics.h b/xlators/nfs/server/src/nfs-generics.h index 91915f120..fa907b7c5 100644 --- a/xlators/nfs/server/src/nfs-generics.h +++ b/xlators/nfs/server/src/nfs-generics.h @@ -157,4 +157,8 @@ nfs_read_sync (xlator_t *xl, nfs_user_t *nfu, fd_t *fd, size_t size, extern int nfs_opendir (xlator_t *nfsx, xlator_t *fopxl, nfs_user_t *nfu, loc_t *pathloc, fop_opendir_cbk_t cbk, void *local); + +extern int +nfs_access (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc, + int32_t accesstest, fop_access_cbk_t cbk, void *local); #endif diff --git a/xlators/nfs/server/src/nfs3-helpers.c b/xlators/nfs/server/src/nfs3-helpers.c index 468f8f7af..caeff9261 100644 --- a/xlators/nfs/server/src/nfs3-helpers.c +++ b/xlators/nfs/server/src/nfs3-helpers.c @@ -565,171 +565,31 @@ nfs3_prep_access3args (access3args *args, struct nfs3_fh *fh) args->object.data.data_val = (void *)fh; } +#define POSIX_READ 4 +#define POSIX_WRITE 2 +#define POSIX_EXEC 1 uint32_t -nfs3_owner_accessbits (ia_prot_t prot, ia_type_t type, uint32_t request) +nfs3_accessbits (int32_t accbits) { - uint32_t accresult = 0; - - if (IA_PROT_RUSR (prot) && (request & ACCESS3_READ)) - accresult |= ACCESS3_READ; - - if (request & ACCESS3_LOOKUP) - if ((IA_ISDIR (type)) && (IA_PROT_XUSR (prot))) - accresult |= ACCESS3_LOOKUP; - - if ((IA_PROT_WUSR (prot) && (request & ACCESS3_MODIFY))) - accresult |= ACCESS3_MODIFY; - - if ((IA_PROT_WUSR (prot) && (request & ACCESS3_EXTEND))) - accresult |= ACCESS3_EXTEND; - - /* ACCESS3_DELETE is ignored for now since that requires - * knowing the permissions on the parent directory. - */ - - if (request & ACCESS3_EXECUTE) - if (IA_PROT_XUSR (prot) && (!IA_ISDIR (type))) - accresult |= ACCESS3_EXECUTE; - - return accresult; -} - - -uint32_t -nfs3_group_accessbits (ia_prot_t prot, ia_type_t type, uint32_t request) -{ - uint32_t accresult = 0; - - if (IA_PROT_RGRP (prot) && (request & ACCESS3_READ)) - accresult |= ACCESS3_READ; - - if (request & ACCESS3_LOOKUP) - if ((IA_ISDIR (type)) && IA_PROT_RGRP (prot)) - accresult |= ACCESS3_LOOKUP; - - if (IA_PROT_WGRP (prot) && (request & ACCESS3_MODIFY)) - accresult |= ACCESS3_MODIFY; - - if (IA_PROT_WGRP (prot) && (request & ACCESS3_EXTEND)) - accresult |= ACCESS3_EXTEND; - - /* ACCESS3_DELETE is ignored for now since that requires - * knowing the permissions on the parent directory. - */ - - if (request & ACCESS3_EXECUTE) - if (IA_PROT_XGRP (prot) && (!IA_ISDIR (type))) - accresult |= ACCESS3_EXECUTE; - - return accresult; -} - - -uint32_t -nfs3_other_accessbits (ia_prot_t prot, ia_type_t type, uint32_t request) -{ - uint32_t accresult = 0; - - if (IA_PROT_ROTH (prot) && (request & ACCESS3_READ)) - accresult |= ACCESS3_READ; - - if (request & ACCESS3_LOOKUP) - if (IA_ISDIR (type) && IA_PROT_ROTH (prot)) - accresult |= ACCESS3_LOOKUP; - - if (IA_PROT_WOTH (prot) && (request & ACCESS3_MODIFY)) - accresult |= ACCESS3_MODIFY; - - if (IA_PROT_WOTH (prot) && (request & ACCESS3_EXTEND)) - accresult |= ACCESS3_EXTEND; - - /* ACCESS3_DELETE is ignored for now since that requires - * knowing the permissions on the parent directory. - */ - - if (request & ACCESS3_EXECUTE) - if (IA_PROT_XOTH (prot) && (!IA_ISDIR (type))) - accresult |= ACCESS3_EXECUTE; - - return accresult; -} - - -uint32_t -nfs3_superuser_accessbits (ia_prot_t prot, ia_type_t type, uint32_t request) -{ - uint32_t accresult = 0; - - if (request & ACCESS3_READ) - accresult |= ACCESS3_READ; - - if (request & ACCESS3_LOOKUP) - if (IA_ISDIR (type)) - accresult |= ACCESS3_LOOKUP; - - if (request & ACCESS3_MODIFY) - accresult |= ACCESS3_MODIFY; - - if (request & ACCESS3_EXTEND) - accresult |= ACCESS3_EXTEND; - - /* ACCESS3_DELETE is ignored for now since that requires - * knowing the permissions on the parent directory. - */ + uint32_t accresult = 0; - if (request & ACCESS3_EXECUTE) - if ((IA_PROT_XOTH (prot) || IA_PROT_XUSR (prot) || - IA_PROT_XGRP (prot)) && (!IA_ISDIR (type))) - accresult |= ACCESS3_EXECUTE; + if (accbits & POSIX_READ) + accresult |= (ACCESS3_READ | ACCESS3_LOOKUP); - return accresult; -} + if (accbits & POSIX_WRITE) + accresult |= (ACCESS3_MODIFY | ACCESS3_EXTEND); - -uint32_t -nfs3_stat_to_accessbits (struct iatt *buf, uint32_t request, uid_t uid, - gid_t gid, gid_t *auxgids, int gids) -{ - uint32_t accresult = 0; - ia_prot_t prot = {0, }; - ia_type_t type = 0; - int testgid = -1; - int x = 0; - - prot = buf->ia_prot; - type = buf->ia_type; - - if (buf->ia_gid == gid) - testgid = gid; - else { - for (; x < gids; ++x) { - if (buf->ia_gid == auxgids[x]) { - testgid = buf->ia_gid; - break; - } - } - } - - if (uid == 0) - accresult = nfs3_superuser_accessbits (prot, type, request); - else if (buf->ia_uid == uid) - accresult = nfs3_owner_accessbits (prot, type, request); - else if ((testgid != -1) && (buf->ia_gid == testgid)) - accresult = nfs3_group_accessbits (prot, type, request); - else - accresult = nfs3_other_accessbits (prot, type, request); + if (accbits & POSIX_EXEC) + accresult |= ACCESS3_EXECUTE; return accresult; } void -nfs3_fill_access3res (access3res *res, nfsstat3 status, struct iatt *buf, - uint32_t accbits, uid_t uid, gid_t gid, - uint64_t deviceid, gid_t *gidarr, int gids) +nfs3_fill_access3res (access3res *res, nfsstat3 status, int32_t accbits) { - post_op_attr objattr; uint32_t accres = 0; memset (res, 0, sizeof (*res)); @@ -737,11 +597,8 @@ nfs3_fill_access3res (access3res *res, nfsstat3 status, struct iatt *buf, if (status != NFS3_OK) return; - nfs3_map_deviceid_to_statdev (buf, deviceid); - objattr = nfs3_stat_to_post_op_attr (buf); - accres = nfs3_stat_to_accessbits (buf, accbits, uid, gid, gidarr, gids); + accres = nfs3_accessbits (accbits); - res->access3res_u.resok.obj_attributes = objattr; res->access3res_u.resok.access = accres; } diff --git a/xlators/nfs/server/src/nfs3-helpers.h b/xlators/nfs/server/src/nfs3-helpers.h index 8fb11ff15..73bb4b720 100644 --- a/xlators/nfs/server/src/nfs3-helpers.h +++ b/xlators/nfs/server/src/nfs3-helpers.h @@ -99,9 +99,7 @@ extern void nfs3_prep_access3args (access3args *args, struct nfs3_fh *fh); extern void -nfs3_fill_access3res (access3res *res, nfsstat3 status, struct iatt *buf, - uint32_t accbits, uid_t uid, gid_t gid, - uint64_t deviceid, gid_t *auxgids, int gids); +nfs3_fill_access3res (access3res *res, nfsstat3 status, int32_t accbits); extern char * nfs3_fhcache_getpath (struct nfs3_state *nfs3, struct nfs3_fh *fh); diff --git a/xlators/nfs/server/src/nfs3.c b/xlators/nfs/server/src/nfs3.c index cd0a543f6..70ce23a39 100644 --- a/xlators/nfs/server/src/nfs3.c +++ b/xlators/nfs/server/src/nfs3.c @@ -1367,20 +1367,13 @@ rpcerr: int -nfs3_access_reply (rpcsvc_request_t *req, nfsstat3 status, struct iatt *buf, - uint32_t accbits) +nfs3_access_reply (rpcsvc_request_t *req, nfsstat3 status, int32_t accbits) { access3res res; uint64_t deviceid = 0; - gid_t *gidarr = NULL; - int gids = 0; deviceid = nfs3_request_xlator_deviceid (req); - gidarr = nfs_rpcsvc_auth_unix_auxgids (req, &gids); - nfs3_fill_access3res (&res, status, buf, accbits, - nfs_rpcsvc_request_uid (req), - nfs_rpcsvc_request_gid (req), deviceid, gidarr, - gids); + nfs3_fill_access3res (&res, status, accbits); nfs3svc_submit_reply (req, &res, (nfs3_serializer)xdr_serialize_access3res); return 0; @@ -1389,7 +1382,7 @@ nfs3_access_reply (rpcsvc_request_t *req, nfsstat3 status, struct iatt *buf, int32_t nfs3svc_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct iatt *buf) + int32_t op_ret, int32_t op_errno) { nfsstat3 status = NFS3_OK; nfs3_call_state_t *cs = NULL; @@ -1401,7 +1394,7 @@ nfs3svc_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this, nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "ACCESS", status, op_errno); - nfs3_access_reply (cs->req, status, buf, cs->accessbits); + nfs3_access_reply (cs->req, status, op_errno); nfs3_call_state_wipe (cs); return 0; @@ -1422,8 +1415,8 @@ nfs3_access_resume (void *carg) nfs3_check_fh_resolve_status (cs, stat, nfs3err); cs->fh = cs->resolvefh; nfs_request_user_init (&nfu, cs->req); - ret = nfs_stat (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc, - nfs3svc_access_cbk, cs); + ret = nfs_access (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc, + cs->accessbits, nfs3svc_access_cbk, cs); if (ret < 0) stat = nfs3_errno_to_nfsstat3 (-ret); @@ -1431,7 +1424,7 @@ nfs3err: if (ret < 0) { nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "ACCESS", stat, -ret); - nfs3_access_reply (cs->req, stat, NULL, 0); + nfs3_access_reply (cs->req, stat, 0); nfs3_call_state_wipe (cs); ret = 0; } @@ -1468,7 +1461,7 @@ nfs3err: if (ret < 0) { nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "ACCESS", stat, -ret); - nfs3_access_reply (req, stat, NULL, 0); + nfs3_access_reply (req, stat, 0); nfs3_call_state_wipe (cs); ret = 0; } -- cgit