summaryrefslogtreecommitdiffstats
path: root/xlators/system/posix-acl/src
diff options
context:
space:
mode:
authorNiels de Vos <ndevos@redhat.com>2014-09-29 20:03:58 +0200
committerNiels de Vos <ndevos@redhat.com>2014-10-02 00:24:36 -0700
commitf2131b8c79641c1bf9e20657757bcc9a62a0625a (patch)
tree7511e8da0d8e6216b5be619ac1118d00254a1c1b /xlators/system/posix-acl/src
parent0e1419d6fbf008b6384236d6103066afbc92dd77 (diff)
gNFS: allow truncate() from SETATTR over NFS for owner
NFSv3 does not have a TRUNCATE procedure, instead it is part of the SETATTR (change the 'size' attribute). SETATTR with a new 'size' succeeds on other NFS-servers, even when the owner of the file does not have write permissions. Make Gluster/NFS behave the same way, by checking if the RPC/pid comes from the NFS-server, and allow truncate() when the file is owned by the user calling SETATTR. BUG: 955753 Change-Id: I4b7cb8efe5a2032c6cd2eef6af610032f76d8b39 Signed-off-by: Niels de Vos <ndevos@redhat.com> Reviewed-on: http://review.gluster.org/8889 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Kaleb KEITHLEY <kkeithle@redhat.com> Reviewed-by: soumya k <skoduri@redhat.com>
Diffstat (limited to 'xlators/system/posix-acl/src')
-rw-r--r--xlators/system/posix-acl/src/posix-acl.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/xlators/system/posix-acl/src/posix-acl.c b/xlators/system/posix-acl/src/posix-acl.c
index 947c71c7707..500bd6c3c79 100644
--- a/xlators/system/posix-acl/src/posix-acl.c
+++ b/xlators/system/posix-acl/src/posix-acl.c
@@ -945,18 +945,29 @@ int
posix_acl_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t off,
dict_t *xdata)
{
+ struct posix_acl_ctx *ctx = NULL;
+
if (acl_permits (frame, loc->inode, POSIX_ACL_WRITE))
goto green;
- else
- goto red;
+ /* NFS does a truncate through SETATTR, the owner does not need write
+ * permissions for this. Group permissions and root are checked above.
+ */
+ else if (frame->root->pid == NFS_PID) {
+ ctx = posix_acl_ctx_get (loc->inode, frame->this);
+
+ if (ctx && frame_is_user (frame, ctx->uid))
+ goto green;
+ }
+
+ /* fail by default */
+ STACK_UNWIND_STRICT (truncate, frame, -1, EACCES, NULL, NULL, NULL);
+ return 0;
+
green:
STACK_WIND (frame, posix_acl_truncate_cbk,
FIRST_CHILD(this), FIRST_CHILD(this)->fops->truncate,
loc, off, xdata);
return 0;
-red:
- STACK_UNWIND_STRICT (truncate, frame, -1, EACCES, NULL, NULL, NULL);
- return 0;
}