]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
mon: allow mgr to tell mon.foo smart
authorSage Weil <sage@redhat.com>
Tue, 22 Oct 2019 15:10:14 +0000 (10:10 -0500)
committerSage Weil <sage@redhat.com>
Tue, 22 Oct 2019 15:10:14 +0000 (10:10 -0500)
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 <sage@redhat.com>
src/mon/MonCap.cc
src/mon/Monitor.cc

index 4cfc13ece81ffb5573b3ba512d541f6ba0228903..3fb5723323a5604ef86d59d5cf57222e2c0a84b7 100644 (file)
@@ -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") {
index 68362eb069cd0a9430c9c6f768050f5a137d7a6c..6e9a817f7f7230297423573ec89bb2df2d6d185c 100644 (file)
@@ -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<string,string> 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);