From f2131b8c79641c1bf9e20657757bcc9a62a0625a Mon Sep 17 00:00:00 2001 From: Niels de Vos Date: Mon, 29 Sep 2014 20:03:58 +0200 Subject: 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 Reviewed-on: http://review.gluster.org/8889 Tested-by: Gluster Build System Reviewed-by: Kaleb KEITHLEY Reviewed-by: soumya k --- xlators/system/posix-acl/src/posix-acl.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'xlators/system') 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; } -- cgit