From b3fdbb666ac2b996c5718a8a629dbf171040f7cf Mon Sep 17 00:00:00 2001 From: Nishtha Rai Date: Wed, 29 Jul 2015 19:50:25 +0530 Subject: [PATCH] mds/Server: add chown and chgrp check access to setattr --- src/mds/MDSAuthCaps.h | 4 +++- src/mds/Server.cc | 31 ++++++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/mds/MDSAuthCaps.h b/src/mds/MDSAuthCaps.h index 291a971ce7dbe..88beeff1e6fd4 100644 --- a/src/mds/MDSAuthCaps.h +++ b/src/mds/MDSAuthCaps.h @@ -27,7 +27,9 @@ enum { MAY_READ = 1, MAY_WRITE = 2, MAY_EXECUTE = 4, - MAY_CREATE = 8 + MAY_CREATE = 8, + MAY_CHOWN = 16, + MAY_CHGRP = 32 }; class CephContext; diff --git a/src/mds/Server.cc b/src/mds/Server.cc index bbd12b80ddf34..d5c59e4a4a902 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -2112,6 +2112,21 @@ bool Server::check_access(MDRequestRef& mdr, CInode *in, unsigned mask) uid_t uid = mdr->client_request->get_caller_uid(); gid_t gid = mdr->client_request->get_caller_gid(); + uid_t new_uid; + gid_t new_gid; + + if (mask & MAY_CHOWN) { + new_uid = mdr->client_request->head.args.setattr.uid; + } else { + new_uid = mdr->client_request->get_caller_uid(); + } + + if (mask & MAY_CHGRP) { + new_gid = mdr->client_request->head.args.setattr.gid; + } else { + new_gid = mdr->client_request->get_caller_gid(); + } + // FIXME: behave with inodes in stray dir // FIXME: behave with hard links string path; @@ -2119,6 +2134,13 @@ bool Server::check_access(MDRequestRef& mdr, CInode *in, unsigned mask) if (path.length()) path = path.substr(1); // drop leading / + if ((mask & (MAY_CHOWN|MAY_CHGRP)) && + !(s->auth_caps.is_capable(path, in->inode.uid, in->inode.gid, in->inode.mode, + new_uid, new_gid, mask))) { + respond_to_request(mdr, -EACCES); + return false; + } + if (s->auth_caps.is_capable(path, in->inode.uid, in->inode.gid, in->inode.mode, uid, gid, mask)) { return true; @@ -3596,6 +3618,7 @@ void Server::handle_client_setattr(MDRequestRef& mdr) } __u32 mask = req->head.args.setattr.mask; + __u32 access_mask = MAY_WRITE; // xlock inode if (mask & (CEPH_SETATTR_MODE|CEPH_SETATTR_UID|CEPH_SETATTR_GID)) @@ -3608,7 +3631,13 @@ void Server::handle_client_setattr(MDRequestRef& mdr) if (!mds->locker->acquire_locks(mdr, rdlocks, wrlocks, xlocks)) return; - if (!check_access(mdr, cur, MAY_WRITE)) + if ((mask & CEPH_SETATTR_UID) && (cur->inode.uid != req->head.args.setattr.uid)) + access_mask |= MAY_CHOWN; + + if ((mask & CEPH_SETATTR_GID) && (cur->inode.gid != req->head.args.setattr.gid)) + access_mask |= MAY_CHGRP; + + if (!check_access(mdr, cur, access_mask)) return; // trunc from bigger -> smaller? -- 2.39.5