10
map<string, OSDCap>::iterator it;
11
for (it = pools_map.begin(); it != pools_map.end(); ++it) {
12
generic_dout(0) << it->first << " -> (" << (int)it->second.allow << "." << (int)it->second.deny << ")" << dendl;
16
void PoolsMap::apply_caps(string& name, int& cap)
18
map<string, OSDCap>::iterator iter;
20
if ((iter = pools_map.find(name)) != pools_map.end()) {
21
OSDCap& c = iter->second;
27
void AuidMap::apply_caps(uint64_t uid, int& cap)
29
map<uint64_t, OSDCap>::iterator iter;
31
if ((iter = auid_map.find(uid)) != auid_map.end()) {
32
OSDCap& auid_cap = iter->second;
33
cap |= auid_cap.allow;
34
cap &= ~auid_cap.deny;
38
bool OSDCaps::get_next_token(string s, size_t& pos, string& token)
40
int start = s.find_first_not_of(" \t", pos);
43
if (s[start] == '=' || s[start] == ',' || s[start] == ';') {
46
end = s.find_first_of(";,= \t", start+1);
57
token = s.substr(start, end - start);
64
bool OSDCaps::is_rwx(string& token, rwx_t& cap_val)
66
const char *t = token.c_str();
72
val |= OSD_POOL_CAP_R;
75
val |= OSD_POOL_CAP_W;
78
val |= OSD_POOL_CAP_X;
90
bool OSDCaps::parse(bufferlist::iterator& iter)
97
generic_dout(0) << "decoded caps: " << s << dendl;
103
bool op_allow = false;
104
bool op_deny = false;
105
bool cmd_pool = false;
106
bool cmd_uid = false;
107
bool any_cmd = false;
109
list<string> name_list;
110
bool last_is_comma = false;
113
while (pos < s.size()) {
121
last_is_comma = false;
127
#define ASSERT_STATE(x) \
130
*_dout << "error parsing caps at pos=" << pos << " (" #x ")" << std::endl; \
134
if (get_next_token(s, pos, token)) {
135
if (token.compare("*") == 0) { //allow all operations
136
ASSERT_STATE(op_allow);
138
} else if (token.compare("=") == 0) {
139
ASSERT_STATE(any_cmd);
141
} else if (token.compare("allow") == 0) {
142
ASSERT_STATE((!op_allow) && (!op_deny));
144
} else if (token.compare("deny") == 0) {
145
ASSERT_STATE((!op_allow) && (!op_deny));
147
} else if ((token.compare("pools") == 0) ||
148
(token.compare("pool") == 0)) {
149
ASSERT_STATE(!cmd_uid && (op_allow || op_deny));
152
} else if (token.compare("uid") == 0) {
153
ASSERT_STATE(!cmd_pool && (op_allow || op_deny));
156
} else if (is_rwx(token, cap_val)) {
157
ASSERT_STATE(op_allow || op_deny);
158
} else if (token.compare(";") != 0) {
159
ASSERT_STATE(got_eq);
160
if (token.compare(",") == 0) {
161
ASSERT_STATE(!last_is_comma);
162
last_is_comma = true;
164
last_is_comma = false;
165
name_list.push_back(token);
169
if (token.compare(";") == 0 || pos >= s.size()) {
171
ASSERT_STATE(name_list.size() > 0);
172
list<string>::iterator iter;
173
CapMap *working_map = &pools_map;
174
if (cmd_uid) working_map = &auid_map;
175
for (iter = name_list.begin(); iter != name_list.end(); ++iter) {
176
OSDCap& cap = working_map->get_cap(*iter);
178
cap.allow |= cap_val;
185
default_allow |= cap_val;
187
default_deny |= cap_val;
195
} catch (buffer::error *err) {
199
generic_dout(0) << "default allow=" << (int)default_allow << " default_deny=" << (int) default_deny << dendl;
205
* Get the caps given this OSDCaps object for a given pool id
206
* and uid (the pool's owner).
208
* Basic strategy: chain of permissions: default allow -> auid
209
* -> pool -> default_deny.
211
* Starting with default allowed caps. Next check if you have caps on
212
* the auid and apply, then apply any caps granted on the pool
213
* (this lets users give out caps to their auid but keep one pool
214
* private, for instance).
215
* If these two steps haven't given you explicit caps
216
* on the pool, check if you're the pool owner and grant full.
218
int OSDCaps::get_pool_cap(string& pool_name, uint64_t uid)
221
return OSD_POOL_CAP_ALL;
223
int explicit_cap = default_allow; //explicitly granted caps
225
//if the owner is granted permissions on the pool owner's auid, grant them
226
auid_map.apply_caps(uid, explicit_cap);
228
//check for explicitly granted caps and apply if needed
229
pools_map.apply_caps(pool_name, explicit_cap);
231
//owner gets full perms by default:
232
if (uid != CEPH_AUTH_UID_DEFAULT
234
&& explicit_cap == 0) {
235
explicit_cap = OSD_POOL_CAP_ALL;
238
explicit_cap &= ~default_deny;