From: Venky Shankar Date: Wed, 23 Dec 2020 11:34:22 +0000 (-0500) Subject: client: optionally check client permission on rmsnap() X-Git-Tag: v16.1.0~142^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=d27a9fe63343e54649a1e632c5062e308ec11e27;p=ceph.git client: optionally check client permission on rmsnap() 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 --- diff --git a/src/client/Client.cc b/src/client/Client.cc index 3d3c3db0b7a..62dda03f03f 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -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); } diff --git a/src/client/Client.h b/src/client/Client.h index be6480b824d..782a2eb87b7 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -477,7 +477,7 @@ public: int mksnap(const char *path, const char *name, const UserPerm& perm, mode_t mode=0, const std::map &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); diff --git a/src/libcephfs.cc b/src/libcephfs.cc index 15f1472a2b4..678865fb1a3 100644 --- a/src/libcephfs.cc +++ b/src/libcephfs.cc @@ -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)