]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds/Server: add chown and chgrp check access to setattr
authorNishtha Rai <nishtha3rai@gmail.com>
Wed, 29 Jul 2015 14:20:25 +0000 (19:50 +0530)
committerSage Weil <sage@redhat.com>
Thu, 1 Oct 2015 13:39:34 +0000 (09:39 -0400)
src/mds/MDSAuthCaps.h
src/mds/Server.cc

index 291a971ce7dbe74fb1778df0a00308afb0f443ac..88beeff1e6fd455fc13b92058eab2ce743a440b7 100644 (file)
@@ -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;
index bbd12b80ddf348e249d09f1f5697113088c4dc0c..d5c59e4a4a9025181078a6aba732858dc50ba713 100644 (file)
@@ -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?