From fa7742927afd665bd5e50493eb5c706a58c5b2a0 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Tue, 20 Oct 2009 16:43:03 -0700 Subject: [PATCH] auth: add osd caps parser --- src/osd/OSD.cc | 190 +++++++++++++++++++++++++++++++++++++++++++++++-- src/osd/OSD.h | 23 ++++++ src/vstart.sh | 6 +- 3 files changed, 210 insertions(+), 9 deletions(-) diff --git a/src/osd/OSD.cc b/src/osd/OSD.cc index 6524629c1fd48..2e9344ecda0df 100644 --- a/src/osd/OSD.cc +++ b/src/osd/OSD.cc @@ -1538,6 +1538,21 @@ bool OSD::ms_verify_authorizer(Connection *con, int peer_type, int ret = verify_authorizer(g_keyring, iter, auth_ticket_info, authorizer_reply); dout(0) << "OSD::verify_authorizer returns " << ret << dendl; + Mutex::Locker l(session_lock); + + Session *s = _get_session(con); + + if (s) { + if (auth_ticket_info.ticket.caps.length() > 0) { + bufferlist::iterator iter = auth_ticket_info.ticket.caps.begin(); + s->caps.parse(iter); + } + + s->put(); + } else { + derr(0) << "got a NULL session" << dendl; + } + isvalid = (ret >= 0); return true; @@ -4145,18 +4160,26 @@ void OSD::init_op_flags(MOSDOp *op) } } +OSD::Session *OSD::_get_session(Connection *c) +{ + Session *s = (Session *)c->get_priv(); + if (!s) { + s = new Session; + c->set_priv(s->get()); + dout(10) << " new session " << s << dendl; + } + + return s; +} + + void OSD::handle_auth(MAuth *m) { dout(10) << "handle_auth " << *m << dendl; Mutex::Locker l(session_lock); - Session *s = (Session *)m->get_connection()->get_priv(); - if (!s) { - s = new Session; - m->get_connection()->set_priv(s->get()); - dout(10) << " new session " << s << dendl; - } + Session *s = _get_session(m->get_connection()); /* bufferlist::iterator p = m->auth_payload.begin(); @@ -4172,3 +4195,158 @@ void OSD::handle_auth(MAuth *m) s->put(); delete m; } + +bool OSD::OSDCaps::get_next_token(string s, size_t& pos, string& token) +{ + int start = s.find_first_not_of(" \t", pos); + int end; + + if (s[start] == '=' || s[start] == ',' || s[start] == ';') { + end = pos + 1; + } else { + end = s.find_first_of(";,= \t", start+1); + } + + if (start < 0) { + return false; + } + + if (end < 0) { + end=s.size(); + } + + token = s.substr(start, end - start); + + pos = end; + + return true; +} + +bool OSD::OSDCaps::parse(bufferlist::iterator& iter) +{ + string s; + + try { + ::decode(s, iter); + + *_dout << "decoded caps: " << s << std::endl; + + size_t pos = 0; + string token; + bool init = true; + + bool op_allow = false; + bool op_deny = false; + bool cmd_pool = false; + bool any_cmd = false; + bool got_eq = false; + list num_list; + bool last_is_comma = false; + int cap_val = 0; + + while (pos < s.size()) { + if (init) { + op_allow = false; + op_deny = false; + cmd_pool = false; + any_cmd = false; + got_eq = false; + last_is_comma = false; + cap_val = 0; + init = false; + num_list.clear(); + } + +#define ASSERT_STATE(x) \ +do { \ + if (!(x)) { \ + *_dout << "error parsing caps at pos=" << pos << " (" #x ")" << std::endl; \ + } \ +} while (0) + + if (get_next_token(s, pos, token)) { + if (token.compare("=") == 0) { + ASSERT_STATE(any_cmd); + got_eq = true; + } else if (token.compare("allow") == 0) { + ASSERT_STATE((!op_allow) && (!op_deny)); + op_allow = true; + } else if (token.compare("deny") == 0) { + ASSERT_STATE((!op_allow) && (!op_deny)); + op_deny = true; + } else if (token.compare("pools") == 0) { + ASSERT_STATE(op_allow || op_deny); + cmd_pool = true; + any_cmd = true; + } else if (token.compare("r") == 0) { + ASSERT_STATE(op_allow || op_deny); + cap_val = OSD_POOL_CAP_R; + } else if (token.compare("w") == 0) { + ASSERT_STATE(op_allow || op_deny); + cap_val = OSD_POOL_CAP_W; + } else if (token.compare("rw") == 0) { + ASSERT_STATE(op_allow || op_deny); + cap_val = OSD_POOL_CAP_RW; + } else if (token.compare(";") != 0) { + ASSERT_STATE(got_eq); + if (token.compare(",") == 0) { + ASSERT_STATE(!last_is_comma); + } else { + last_is_comma = false; + int num = strtol(token.c_str(), NULL, 10); + num_list.push_back(num); + } + } + + if (token.compare(";") == 0 || pos >= s.size()) { + if (got_eq) { + ASSERT_STATE(num_list.size() > 0); + list::iterator iter; + for (iter = num_list.begin(); iter != num_list.end(); ++iter) { + OSDPoolCap& cap = pools_map[*iter]; + if (op_allow) { + cap.allow |= cap_val; + } else { + cap.deny |= cap_val; + } + } + } else { + if (op_allow) { + default_action |= cap_val; + } else { + default_action &= ~cap_val; + } + } + init = true; + } + + } + } + } catch (buffer::error *err) { + return false; + } + + *_dout << "default=" << default_action << std::endl; + map::iterator it; + for (it = pools_map.begin(); it != pools_map.end(); ++it) { + *_dout << it->first << " -> (" << it->second.allow << "." << it->second.deny << ")" << std::endl; + } + + + return true; +} + +int OSD::OSDCaps::get_pool_cap(int pool_id) +{ + int cap = default_action; + + map::iterator iter = pools_map.find(pool_id); + if (iter != pools_map.end()) { + OSDPoolCap& c = iter->second; + cap |= c.allow; + cap &= ~c.deny; + } + + return cap; +} + diff --git a/src/osd/OSD.h b/src/osd/OSD.h index 3e58af2001092..5b51d78ad5e69 100644 --- a/src/osd/OSD.h +++ b/src/osd/OSD.h @@ -41,6 +41,11 @@ using namespace std; using namespace __gnu_cxx; + +#define OSD_POOL_CAP_R 0x1 +#define OSD_POOL_CAP_W 0x2 +#define OSD_POOL_CAP_RW (OSD_POOL_CAP_R | OSD_POOL_CAP_W) + enum { l_osd_first = 10000, l_osd_opq, @@ -178,12 +183,30 @@ private: // -- sessions -- public: + struct OSDPoolCap { + int allow; + int deny; + OSDPoolCap() : allow(0), deny(0) {} + }; + + class OSDCaps { + map pools_map; + int default_action; + bool get_next_token(string s, size_t& pos, string& token); + public: + OSDCaps() : default_action(0) {} + bool parse(bufferlist::iterator& iter); + int get_pool_cap(int pool_id); + }; struct Session : public RefCountedObject { AuthTicket ticket; + OSDCaps caps; }; private: Mutex session_lock; + + Session *_get_session(Connection *c); void handle_auth(MAuth *m); diff --git a/src/vstart.sh b/src/vstart.sh index eaa38e33f4741..163b93efa8380 100755 --- a/src/vstart.sh +++ b/src/vstart.sh @@ -226,7 +226,7 @@ EOF cat < $admin_caps ; generated by vstart.sh on `date` mon = "allow" - osd = "allow" + osd = "allow rw" mds = "allow" EOF $SUDO $CEPH_BIN/authtool --gen-key --name=mon. $monkeys_fn @@ -283,7 +283,7 @@ EOF cat < $osd_caps ; generated by vstart.sh on `date` mon = "allow" - osd = "allow" + osd = "allow rw" EOF $SUDO $CEPH_BIN/authtool --gen-key --name=osd.$osd --caps=$osd_caps $key_fn $SUDO $CEPH_ADM -i $key_fn auth add osd.$osd @@ -307,7 +307,7 @@ EOF cat < $mds_caps ; generated by vstart.sh on `date` mon = "allow" - osd = "allow" + osd = "allow rw" mds = "allow" EOF $SUDO $CEPH_BIN/authtool --gen-key --name=mds.$name --caps=$mds_caps $key_fn -- 2.39.5