summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoao Eduardo Luis <joao.luis@inktank.com>2013-07-26 19:56:44 +0100
committerJoao Eduardo Luis <joao.luis@inktank.com>2013-08-02 22:47:21 +0100
commitbe815c0182f7da23f3ac4a0293ecd02a315fcd6d (patch)
tree869291f98de54e447e3fc4c6c28579ab4b30e79b
parent4aeb73a5e6d46f970dbd684a58f795d379a04bd9 (diff)
downloadceph-be815c0182f7da23f3ac4a0293ecd02a315fcd6d.tar.gz
mon: Monitor: check caps considering command's requirements
Fixes: #5648 Signed-off-by: Joao Eduardo Luis <joao.luis@inktank.com>
-rw-r--r--src/mon/Monitor.cc39
-rw-r--r--src/mon/Monitor.h2
2 files changed, 41 insertions, 0 deletions
diff --git a/src/mon/Monitor.cc b/src/mon/Monitor.cc
index bf500dff218..441f01453a3 100644
--- a/src/mon/Monitor.cc
+++ b/src/mon/Monitor.cc
@@ -1878,6 +1878,40 @@ struct MonCommand {
#include <mon/MonCommands.h>
};
+bool Monitor::_allowed_command(MonSession *s, string &module, string &prefix,
+ map<string,cmd_vartype>& cmdmap) {
+
+ map<string,string> strmap;
+ for (map<string,cmd_vartype>::const_iterator p = cmdmap.begin();
+ p != cmdmap.end(); ++p) {
+ if (p->first == "prefix")
+ continue;
+ strmap[p->first] = cmd_vartype_stringify(p->second);
+ }
+
+ MonCommand *this_cmd = NULL;
+ for (MonCommand *cp = mon_commands;
+ cp < &mon_commands[ARRAY_SIZE(mon_commands)]; cp++) {
+ dout(0) << __func__ << " CAPSBAR >> matching against " << cp->cmdstring << dendl;
+ if (cp->cmdstring.find(prefix) != string::npos) {
+ this_cmd = cp;
+ break;
+ }
+ }
+ assert(this_cmd != NULL);
+ bool cmd_r = (this_cmd->req_perms.find('r') != string::npos);
+ bool cmd_w = (this_cmd->req_perms.find('w') != string::npos);
+ bool cmd_x = (this_cmd->req_perms.find('x') != string::npos);
+
+ bool capable = s->caps.is_capable(g_ceph_context, s->inst.name,
+ module, prefix, strmap,
+ cmd_r, cmd_w, cmd_x);
+
+ dout(10) << __func__ << " " << (capable ? "" : "not ") << "capable" << dendl;
+ return capable;
+}
+
+
void Monitor::handle_command(MMonCommand *m)
{
if (m->fsid != monmap->fsid) {
@@ -1964,6 +1998,11 @@ void Monitor::handle_command(MMonCommand *m)
access_r = (session->is_capable("mon", MON_CAP_R) || access_cmd);
access_all = (session->caps.is_allow_all() || access_cmd);
+ if (!_allowed_command(session, module, prefix, cmdmap)) {
+ dout(1) << __func__ << " access denied" << dendl;
+ reply_command(m, -EACCES, "access denied", 0);
+ }
+
if (module == "mds") {
mdsmon()->dispatch(m);
return;
diff --git a/src/mon/Monitor.h b/src/mon/Monitor.h
index 82b08816702..e72675917d5 100644
--- a/src/mon/Monitor.h
+++ b/src/mon/Monitor.h
@@ -579,6 +579,8 @@ public:
void handle_subscribe(MMonSubscribe *m);
void handle_mon_get_map(MMonGetMap *m);
bool _allowed_command(MonSession *s, map<std::string, cmd_vartype>& cmd);
+ bool _allowed_command(MonSession *s, string &module, string& prefix,
+ map<string,cmd_vartype>& cmdmap);
void _mon_status(Formatter *f, ostream& ss);
void _quorum_status(Formatter *f, ostream& ss);
void _add_bootstrap_peer_hint(string cmd, string args, ostream& ss);