OSDCaps& caps = session->caps;
session->put();
int pool = pgid.pool();
- int perm = caps.get_pool_cap(pool, osdmap->get_pg_pool(pool)->v.auid);
+
+ // get and lock *pg.
+ PG *pg = _have_pg(pgid) ? _lookup_lock_pg(pgid):0;
+
+ string pool_name = pg->pool->name;
+ int perm = caps.get_pool_cap(pool_name, osdmap->get_pg_pool(pool)->v.auid);
dout(10) << "request for pool=" << pool << " owner="
<< osdmap->get_pg_pool(pool)->v.auid
<< " may_exec=" << op->may_exec()
<< " require_exec_caps=" << op->require_exec_caps() << dendl;
- if (op->may_read()) {
- if (!(perm & OSD_POOL_CAP_R)) {
- dout(0) << "no READ permission to access pool " << pool << dendl;
- reply_op_error(op, -EPERM);
- return;
- }
- }
-
- if (op->may_write()) {
- if (!(perm & OSD_POOL_CAP_W)) {
- dout(0) << "no WRITE permission to access pool " << pool << dendl;
- reply_op_error(op, -EPERM);
- return;
- }
+ int err = -EPERM;
+ if (op->may_read() && !(perm & OSD_POOL_CAP_R)) {
+ dout(0) << "no READ permission to access pool " << pool_name << dendl;
+ } else if (op->may_write() && !(perm & OSD_POOL_CAP_W)) {
+ dout(0) << "no WRITE permission to access pool " << pool_name << dendl;
+ } else if (op->require_exec_caps() && !(perm & OSD_POOL_CAP_X)) {
+ dout(0) << "no EXEC permission to access pool " << pool_name << dendl;
+ } else {
+ err = 0;
}
- if (op->require_exec_caps()) {
- if (!(perm & OSD_POOL_CAP_X)) {
- dout(0) << "no EXEC permission to access pool " << pool << dendl;
- reply_op_error(op, -EPERM);
- return;
- }
+ if (err < 0) {
+ reply_op_error(op, err);
+ pg->unlock();
+ return;
}
- // get and lock *pg.
- PG *pg = _have_pg(pgid) ? _lookup_lock_pg(pgid):0;
-
// update qlen stats
stat_oprate.hit(now, decayrate);
stat_ops++;
#include "config.h"
+
+void PoolsMap::dump()
+{
+ map<string, OSDCap>::iterator it;
+ for (it = pools_map.begin(); it != pools_map.end(); ++it) {
+ generic_dout(0) << it->first << " -> (" << (int)it->second.allow << "." << (int)it->second.deny << ")" << dendl;
+ }
+}
+
+void PoolsMap::apply_caps(string& name, int& cap)
+{
+ map<string, OSDCap>::iterator iter;
+
+ if ((iter = pools_map.find(name)) != pools_map.end()) {
+ OSDCap& c = iter->second;
+ cap |= c.allow;
+ cap &= ~c.deny;
+ }
+}
+
+void AuidMap::apply_caps(uint64_t uid, int& cap)
+{
+ map<uint64_t, OSDCap>::iterator iter;
+
+ if ((iter = auid_map.find(uid)) != auid_map.end()) {
+ OSDCap& auid_cap = iter->second;
+ cap |= auid_cap.allow;
+ cap &= ~auid_cap.deny;
+ }
+}
+
bool OSDCaps::get_next_token(string s, size_t& pos, string& token)
{
int start = s.find_first_not_of(" \t", pos);
bool cmd_uid = false;
bool any_cmd = false;
bool got_eq = false;
- list<int> num_list;
+ list<string> name_list;
bool last_is_comma = false;
rwx_t cap_val = 0;
last_is_comma = false;
cap_val = 0;
init = false;
- num_list.clear();
+ name_list.clear();
}
#define ASSERT_STATE(x) \
last_is_comma = true;
} else {
last_is_comma = false;
- int num = strtol(token.c_str(), NULL, 10);
- num_list.push_back(num);
+ name_list.push_back(token);
}
}
if (token.compare(";") == 0 || pos >= s.size()) {
if (got_eq) {
- ASSERT_STATE(num_list.size() > 0);
- list<int>::iterator iter;
- map<int, OSDCap> *working_map = &pools_map;
+ ASSERT_STATE(name_list.size() > 0);
+ list<string>::iterator iter;
+ CapMap *working_map = &pools_map;
if (cmd_uid) working_map = &auid_map;
- for (iter = num_list.begin(); iter != num_list.end(); ++iter) {
- OSDCap& cap = (*working_map)[*iter];
+ for (iter = name_list.begin(); iter != name_list.end(); ++iter) {
+ OSDCap& cap = working_map->get_cap(*iter);
if (op_allow) {
cap.allow |= cap_val;
} else {
}
generic_dout(0) << "default allow=" << (int)default_allow << " default_deny=" << (int) default_deny << dendl;
- map<int, OSDCap>::iterator it;
- for (it = pools_map.begin(); it != pools_map.end(); ++it) {
- generic_dout(0) << it->first << " -> (" << (int)it->second.allow << "." << (int)it->second.deny << ")" << dendl;
- }
-
+ pools_map.dump();
return true;
}
* If these two steps haven't given you explicit caps
* on the pool, check if you're the pool owner and grant full.
*/
-int OSDCaps::get_pool_cap(int pool_id, uint64_t uid)
+int OSDCaps::get_pool_cap(string& pool_name, uint64_t uid)
{
if (allow_all)
return OSD_POOL_CAP_ALL;
int explicit_cap = default_allow; //explicitly granted caps
- map<int, OSDCap>::iterator iter;
//if the owner is granted permissions on the pool owner's auid, grant them
- if ((iter = auid_map.find(uid)) != pools_map.end()) {
- OSDCap& auid_cap = iter->second;
- explicit_cap |= auid_cap.allow;
- explicit_cap &= ~auid_cap.deny;
- }
+ auid_map.apply_caps(uid, explicit_cap);
+
//check for explicitly granted caps and apply if needed
- if ((iter = pools_map.find(pool_id)) != pools_map.end()) {
- OSDCap& c = iter->second;
- explicit_cap |= c.allow;
- explicit_cap &= ~c.deny;
- }
+ pools_map.apply_caps(pool_name, explicit_cap);
//owner gets full perms by default:
if (uid != CEPH_AUTH_UID_DEFAULT
return out << "(allow " << pc.allow << ", deny " << pc.deny << ")";
}
+struct CapMap {
+ virtual OSDCap& get_cap(string& name) = 0;
+};
+
+struct PoolsMap : public CapMap {
+ map<string, OSDCap> pools_map;
+
+ OSDCap& get_cap(string& name) { return pools_map[name]; }
+
+ void dump();
+ void apply_caps(string& name, int& cap);
+};
+
+struct AuidMap : public CapMap {
+ map<uint64_t, OSDCap> auid_map;
+
+ OSDCap& get_cap(string& name) {
+ uint64_t num = strtoll(name.c_str(), NULL, 10);
+ return auid_map[num];
+ }
+
+ void apply_caps(uint64_t uid, int& cap);
+};
+
struct OSDCaps {
- map<int, OSDCap> pools_map;
- map<int, OSDCap> auid_map;
+ PoolsMap pools_map;
+ AuidMap auid_map;
rwx_t default_allow;
rwx_t default_deny;
bool allow_all;
OSDCaps() : default_allow(0), default_deny(0), allow_all(false),
auid(CEPH_AUTH_UID_DEFAULT) {}
bool parse(bufferlist::iterator& iter);
- int get_pool_cap(int pool_id, uint64_t uid = CEPH_AUTH_UID_DEFAULT);
+ int get_pool_cap(string& pool_name, uint64_t uid = CEPH_AUTH_UID_DEFAULT);
bool is_mon() { return CEPH_ENTITY_TYPE_MON == peer_type; }
bool is_osd() { return CEPH_ENTITY_TYPE_OSD == peer_type; }
bool is_mds() { return CEPH_ENTITY_TYPE_MDS == peer_type; }
};
static inline ostream& operator<<(ostream& out, const OSDCaps& c) {
- return out << "osdcaps(pools=" << c.pools_map << " default allow=" << c.default_allow << " default_deny=" << c.default_deny << ")";
+ return out << "osdcaps(pools=" << c.pools_map.pools_map << " default allow=" << c.default_allow << " default_deny=" << c.default_deny << ")";
}
#endif