From 64b9fd8b5826985a79ffc137335ac540f4db36a1 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 22 Oct 2019 10:10:14 -0500 Subject: [PATCH] mon: allow mgr to tell mon.foo smart The mgr profile needs to do a tell command to the mon, which was restricted to *only* allow_all (*) caps. Additionally allow whitelisted commands, and whitelist 'smart'. This is somewhat imprecise since it conflates tell vs cli commands in the MonCap, but since those don't overlap it should be fine. Signed-off-by: Sage Weil --- src/mon/MonCap.cc | 2 ++ src/mon/Monitor.cc | 22 +++++++++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/mon/MonCap.cc b/src/mon/MonCap.cc index 4cfc13ece81ff..3fb5723323a56 100644 --- a/src/mon/MonCap.cc +++ b/src/mon/MonCap.cc @@ -224,6 +224,8 @@ void MonCapGrant::expand_profile_mon(const EntityName& name) const // ssh orchestrator provisions new daemon keys profile_grants.push_back(MonCapGrant("auth get-or-create")); profile_grants.push_back(MonCapGrant("auth rm")); + // tell commands (this is a bit of a kludge) + profile_grants.push_back(MonCapGrant("smart")); } if (profile == "osd" || profile == "mds" || profile == "mon" || profile == "mgr") { diff --git a/src/mon/Monitor.cc b/src/mon/Monitor.cc index 68362eb069cd0..6e9a817f7f723 100644 --- a/src/mon/Monitor.cc +++ b/src/mon/Monitor.cc @@ -3161,7 +3161,27 @@ void Monitor::handle_tell_command(MonOpRequestRef op) return; } if (!session->caps.is_allow_all()) { - reply_tell_command(op, -EPERM, "insufficient caps"); + // see if command is whitelisted + cmdmap_t cmdmap; + stringstream ss; + if (!cmdmap_from_json(m->cmd, &cmdmap, ss)) { + reply_command(op, -EINVAL, ss.str(), 0); + } + map param_str_map; + _generate_command_map(cmdmap, param_str_map); + string prefix; + if (!cmd_getval(g_ceph_context, cmdmap, "prefix", prefix)) { + reply_command(op, -EINVAL, "no prefix", 0); + } + if (!session->caps.is_capable( + g_ceph_context, + CEPH_ENTITY_TYPE_MON, + session->entity_name, + "mon", prefix, param_str_map, + true, true, true, + session->get_peer_socket_addr())) { + reply_tell_command(op, -EPERM, "insufficient caps"); + } } // pass it to asok cct->get_admin_socket()->queue_tell_command(m); -- 2.39.5