diff options
author | Joao Eduardo Luis <joao.luis@inktank.com> | 2013-07-26 19:56:44 +0100 |
---|---|---|
committer | Joao Eduardo Luis <joao.luis@inktank.com> | 2013-08-02 22:47:21 +0100 |
commit | be815c0182f7da23f3ac4a0293ecd02a315fcd6d (patch) | |
tree | 869291f98de54e447e3fc4c6c28579ab4b30e79b | |
parent | 4aeb73a5e6d46f970dbd684a58f795d379a04bd9 (diff) | |
download | ceph-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.cc | 39 | ||||
-rw-r--r-- | src/mon/Monitor.h | 2 |
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); |