From: Jason Dillaman Date: Mon, 14 Oct 2019 14:54:44 +0000 (-0400) Subject: mgr: added 'profile rbd/rbd-read-only' cap X-Git-Tag: v14.2.8~20^2~55^2~8 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=6ae3efd2a079cd91182b06abcbe887a76b403a0d;p=ceph.git mgr: added 'profile rbd/rbd-read-only' cap These profiles can be further restricted via 'pool' and 'namespace' argument optionals. Signed-off-by: Jason Dillaman (cherry picked from commit b0d73aed19a9f3f242d5a13757016759835c164c) Conflicts: doc/rados/operations/user-management.rst: trivial resolution --- diff --git a/doc/rados/operations/user-management.rst b/doc/rados/operations/user-management.rst index 737a0cf912e1..0bd13582536d 100644 --- a/doc/rados/operations/user-management.rst +++ b/doc/rados/operations/user-management.rst @@ -269,12 +269,15 @@ The following entries describe valid capability profiles: so they have permissions to add keys, etc. when bootstrapping an ``rbd-mirror`` daemon. -``profile rbd`` (Monitor and OSD) +``profile rbd`` (Manager, Monitor, and OSD) :Description: Gives a user permissions to manipulate RBD images. When used as a Monitor cap, it provides the minimal privileges required - by an RBD client application. When used as an OSD cap, it - provides read-write access to an RBD client application. + by an RBD client application; this includes the ability + to blacklist other client users. When used as an OSD cap, it + provides read-write access to the specified pool to an + RBD client application. The Manager cap supports optional + ``pool`` and ``namespace`` keyword arguments. ``profile rbd-mirror`` (Monitor only) @@ -282,9 +285,11 @@ The following entries describe valid capability profiles: RBD mirroring config-key secrets. It provides the minimal privileges required for the ``rbd-mirror`` daemon. -``profile rbd-read-only`` (OSD only) +``profile rbd-read-only`` (Manager and OSD) -:Description: Gives a user read-only permissions to RBD images. +:Description: Gives a user read-only permissions to RBD images. The Manager + cap supports optional ``pool`` and ``namespace`` keyword + arguments. Pool diff --git a/src/mgr/MgrCap.cc b/src/mgr/MgrCap.cc index 37a256f3fe47..ed5ed46d62c2 100644 --- a/src/mgr/MgrCap.cc +++ b/src/mgr/MgrCap.cc @@ -154,6 +154,26 @@ void MgrCapGrant::expand_profile() const { profile_grants.push_back({{}, {}, {}, "crash post", {}, {}}); return; } + + if (profile == "rbd" || profile == "rbd-read-only") { + Arguments filtered_arguments; + for (auto& [key, constraint] : arguments) { + if (key == "pool" || key == "namespace") { + filtered_arguments[key] = std::move(constraint); + } + } + + mgr_rwxa_t perms = mgr_rwxa_t{MGR_CAP_R}; + if (profile == "rbd") { + perms = mgr_rwxa_t{MGR_CAP_R | MGR_CAP_W}; + } + + // whitelist all 'rbd_support' commands (restricted by optional + // pool/namespace constraints) + profile_grants.push_back({{}, "rbd_support", {}, {}, + std::move(filtered_arguments), perms}); + return; + } } bool MgrCapGrant::validate_arguments( diff --git a/src/test/mgr/test_mgrcap.cc b/src/test/mgr/test_mgrcap.cc index c6c73b885ba6..3c79d87906e9 100644 --- a/src/test/mgr/test_mgrcap.cc +++ b/src/test/mgr/test_mgrcap.cc @@ -262,3 +262,34 @@ TEST(MgrCap, Module) { ASSERT_TRUE(cap.is_capable(nullptr, {}, "", "bcd", "", {}, false, true, false, {})); } + +TEST(MgrCap, Profile) { + MgrCap cap; + ASSERT_FALSE(cap.is_allow_all()); + + ASSERT_TRUE(cap.parse("profile rbd", nullptr)); + ASSERT_FALSE(cap.is_capable(nullptr, {}, "", "abc", "", {}, true, false, + false, {})); + ASSERT_TRUE(cap.is_capable(nullptr, {}, "", "rbd_support", "", {}, true, + true, false, {})); + ASSERT_TRUE(cap.is_capable(nullptr, {}, "", "rbd_support", "", {}, true, + false, false, {})); + + ASSERT_TRUE(cap.parse("profile rbd pool=abc namespace prefix def", nullptr)); + ASSERT_FALSE(cap.is_capable(nullptr, {}, "", "rbd_support", "", {}, + true, true, false, {})); + ASSERT_FALSE(cap.is_capable(nullptr, {}, "", "rbd_support", "", + {{"pool", "abc"}}, + true, true, false, {})); + ASSERT_TRUE(cap.is_capable(nullptr, {}, "", "rbd_support", "", + {{"pool", "abc"}, {"namespace", "defghi"}}, + true, true, false, {})); + + ASSERT_TRUE(cap.parse("profile rbd-read-only", nullptr)); + ASSERT_FALSE(cap.is_capable(nullptr, {}, "", "abc", "", {}, true, false, + false, {})); + ASSERT_FALSE(cap.is_capable(nullptr, {}, "", "rbd_support", "", {}, true, + true, false, {})); + ASSERT_TRUE(cap.is_capable(nullptr, {}, "", "rbd_support", "", {}, true, + false, false, {})); +}