]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
client: permission check for setxattr/removexattr
authorYan, Zheng <zyan@redhat.com>
Tue, 29 Sep 2015 08:41:19 +0000 (16:41 +0800)
committerYan, Zheng <zyan@redhat.com>
Tue, 12 Jan 2016 09:21:01 +0000 (17:21 +0800)
Signed-off-by: Yan, Zheng <zyan@redhat.com>
src/client/Client.cc
src/client/Client.h

index c1fe9c38825ccecb7ae3d797eb111bc424c8a84f..7ae066a53a4e13277f9861204b48e2f31bc8017a 100644 (file)
@@ -4847,6 +4847,30 @@ int Client::inode_permission(Inode *in, uid_t uid, UserGroups& groups, unsigned
   return 0;
 }
 
+int Client::xattr_permission(Inode *in, const char *name, unsigned want, int uid, int gid)
+{
+  if (uid < 0)
+    uid = get_uid();
+  if (gid < 0)
+    gid = get_gid();
+  RequestUserGroups groups(this, uid, gid);
+
+  int r = _getattr(in, CEPH_STAT_CAP_MODE, uid, gid);
+  if (r < 0)
+    goto out;
+
+  r = 0;
+  if (strncmp(name, "system.", 7) == 0) {
+    if ((want & MAY_WRITE) && (uid != 0 && (uid_t)uid != in->uid))
+      r = -EPERM;
+  } else {
+    r = inode_permission(in, uid, groups, want);
+  }
+out:
+  ldout(cct, 3) << __func__ << " " << in << " = " << r <<  dendl;
+  return r;
+}
+
 int Client::may_setattr(Inode *in, struct stat *st, int mask, int uid, int gid)
 {
   if (uid < 0)
@@ -9392,6 +9416,12 @@ int Client::ll_getxattr(Inode *in, const char *name, void *value,
   tout(cct) << vino.ino.val << std::endl;
   tout(cct) << name << std::endl;
 
+  if (!cct->_conf->fuse_default_permissions) {
+    int r = xattr_permission(in, name, MAY_READ, uid, gid);
+    if (r < 0)
+      return r;
+  }
+
   return _getxattr(in, name, value, size, uid, gid);
 }
 
@@ -9612,6 +9642,12 @@ int Client::ll_setxattr(Inode *in, const char *name, const void *value,
   tout(cct) << vino.ino.val << std::endl;
   tout(cct) << name << std::endl;
 
+  if (!cct->_conf->fuse_default_permissions) {
+    int r = xattr_permission(in, name, MAY_WRITE, uid, gid);
+    if (r < 0)
+      return r;
+  }
+
   return _setxattr(in, name, value, size, flags, uid, gid);
 }
 
@@ -9659,6 +9695,12 @@ int Client::ll_removexattr(Inode *in, const char *name, int uid, int gid)
   tout(cct) << vino.ino.val << std::endl;
   tout(cct) << name << std::endl;
 
+  if (!cct->_conf->fuse_default_permissions) {
+    int r = xattr_permission(in, name, MAY_WRITE, uid, gid);
+    if (r < 0)
+      return r;
+  }
+
   return _removexattr(in, name, uid, gid);
 }
 
index 38874f6ae6c1f3a8bc273729bd186c2161ab0296..b630b7a165accb5b65f6519296b17ed0eb766a66 100644 (file)
@@ -783,6 +783,7 @@ private:
   };
 
   int inode_permission(Inode *in, uid_t uid, UserGroups& groups, unsigned want);
+  int xattr_permission(Inode *in, const char *name, unsigned want, int uid=-1, int gid=-1);
   int may_setattr(Inode *in, struct stat *st, int mask, int uid=-1, int gid=-1);
   int may_open(Inode *in, int flags, int uid=-1, int gid=-1);
   int may_lookup(Inode *dir, int uid=-1, int gid=-1);