]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
client: optionally check client permission on rmsnap()
authorVenky Shankar <vshankar@redhat.com>
Wed, 23 Dec 2020 11:34:22 +0000 (06:34 -0500)
committerVenky Shankar <vshankar@redhat.com>
Wed, 23 Dec 2020 13:06:08 +0000 (08:06 -0500)
By default, Client::rmsnap() skips checking client permissions.
This was ok till now since it was not a user facing API (via
libcephfs).

With PR #37721 ("mds: store custom metadata on snapshot creation"),
rmsnap can be invoked via ceph_rmsnap() libcephfs call. Therefore,
the usual client side permission checks should be performed before
calling out to the MDS.

Signed-off-by: Venky Shankar <vshankar@redhat.com>
src/client/Client.cc
src/client/Client.h
src/libcephfs.cc

index 3d3c3db0b7ae9e008462c626ef3d73b9bad331bd..62dda03f03f0f5b61a510eba7ccf70eeb8856ab1 100644 (file)
@@ -5717,7 +5717,7 @@ int Client::may_delete(Inode *dir, const char *name, const UserPerm& perms)
   if (r < 0)
     goto out;
 
-  /* 'name == NULL' means rmsnap */
+  /* 'name == NULL' means rmsnap w/o permission checks */
   if (perms.uid() != 0 && name && (dir->mode & S_ISVTX)) {
     InodeRef otherin;
     r = _lookup(dir, name, CEPH_CAP_AUTH_SHARED, &otherin, perms);
@@ -11099,7 +11099,7 @@ int Client::mksnap(const char *relpath, const char *name, const UserPerm& perm,
   return _mkdir(snapdir, name, mode, perm, nullptr, metadata);
 }
 
-int Client::rmsnap(const char *relpath, const char *name, const UserPerm& perms)
+int Client::rmsnap(const char *relpath, const char *name, const UserPerm& perms, bool check_perms)
 {
   RWRef_t mref_reader(mount_state, CLIENT_MOUNTING);
   if (!mref_reader.is_state_satisfied())
@@ -11112,12 +11112,12 @@ int Client::rmsnap(const char *relpath, const char *name, const UserPerm& perms)
   int r = path_walk(path, &in, perms);
   if (r < 0)
     return r;
+  Inode *snapdir = open_snapdir(in.get());
   if (cct->_conf->client_permissions) {
-    r = may_delete(in.get(), NULL, perms);
+    r = may_delete(snapdir, check_perms ? name : NULL, perms);
     if (r < 0)
       return r;
   }
-  Inode *snapdir = open_snapdir(in.get());
   return _rmdir(snapdir, name, perms);
 }
 
index be6480b824d1808644ebee4091bac01c8a7c8924..782a2eb87b7290213f07caf21f13878a7ff3469a 100644 (file)
@@ -477,7 +477,7 @@ public:
 
   int mksnap(const char *path, const char *name, const UserPerm& perm,
              mode_t mode=0, const std::map<std::string, std::string> &metadata={});
-  int rmsnap(const char *path, const char *name, const UserPerm& perm);
+  int rmsnap(const char *path, const char *name, const UserPerm& perm, bool check_perms=false);
 
   // Inode permission checking
   int inode_permission(Inode *in, const UserPerm& perms, unsigned want);
index 15f1472a2b400d51661cba689d42f5f75d60da17..678865fb1a3fdca6ae3606917a5ffcfe25dacd05 100644 (file)
@@ -733,7 +733,7 @@ extern "C" int ceph_rmsnap(struct ceph_mount_info *cmount, const char *path, con
 {
   if (!cmount->is_mounted())
     return -ENOTCONN;
-  return cmount->get_client()->rmsnap(path, name, cmount->default_perms);
+  return cmount->get_client()->rmsnap(path, name, cmount->default_perms, true);
 }
 
 extern "C" int ceph_mkdirs(struct ceph_mount_info *cmount, const char *path, mode_t mode)