]>
Commit | Line | Data |
---|---|---|
31f18b77 | 1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
9f95a23c | 2 | // vim: ts=8 sw=2 smarttab ft=cpp |
11fdf7f2 | 3 | |
7c673cae FG |
4 | #include <errno.h> |
5 | ||
6 | #include "common/errno.h" | |
7 | #include "common/Formatter.h" | |
8 | #include "common/ceph_json.h" | |
9 | ||
10 | #include "include/types.h" | |
11 | #include "rgw_string.h" | |
12 | ||
13 | #include "rgw_common.h" | |
14 | #include "rgw_op.h" | |
15 | #include "rgw_rest.h" | |
16 | #include "rgw_role.h" | |
17 | #include "rgw_rest_role.h" | |
f67539c2 | 18 | #include "rgw_sal_rados.h" |
7c673cae FG |
19 | |
20 | #define dout_subsys ceph_subsys_rgw | |
21 | ||
f67539c2 | 22 | int RGWRestRole::verify_permission(optional_yield y) |
11fdf7f2 TL |
23 | { |
24 | if (s->auth.identity->is_anonymous()) { | |
25 | return -EACCES; | |
26 | } | |
27 | ||
28 | string role_name = s->info.args.get("RoleName"); | |
9f95a23c | 29 | RGWRole role(s->cct, store->getRados()->pctl, role_name, s->user->get_tenant()); |
b3b6e05e | 30 | if (op_ret = role.get(s, y); op_ret < 0) { |
11fdf7f2 TL |
31 | if (op_ret == -ENOENT) { |
32 | op_ret = -ERR_NO_ROLE_FOUND; | |
33 | } | |
34 | return op_ret; | |
35 | } | |
36 | ||
9f95a23c | 37 | if (int ret = check_caps(s->user->get_caps()); ret == 0) { |
11fdf7f2 TL |
38 | _role = std::move(role); |
39 | return ret; | |
40 | } | |
41 | ||
42 | string resource_name = role.get_path() + role_name; | |
43 | uint64_t op = get_op(); | |
44 | if (!verify_user_permission(this, | |
45 | s, | |
eafe8130 | 46 | rgw::ARN(resource_name, |
11fdf7f2 | 47 | "role", |
9f95a23c | 48 | s->user->get_tenant(), true), |
11fdf7f2 TL |
49 | op)) { |
50 | return -EACCES; | |
51 | } | |
52 | ||
53 | _role = std::move(role); | |
54 | ||
55 | return 0; | |
56 | } | |
57 | ||
7c673cae FG |
58 | void RGWRestRole::send_response() |
59 | { | |
60 | if (op_ret) { | |
61 | set_req_state_err(s, op_ret); | |
62 | } | |
63 | dump_errno(s); | |
92f5a8d4 | 64 | end_header(s, this); |
7c673cae FG |
65 | } |
66 | ||
9f95a23c | 67 | int RGWRoleRead::check_caps(const RGWUserCaps& caps) |
7c673cae | 68 | { |
11fdf7f2 TL |
69 | return caps.check_cap("roles", RGW_CAP_READ); |
70 | } | |
7c673cae | 71 | |
9f95a23c | 72 | int RGWRoleWrite::check_caps(const RGWUserCaps& caps) |
11fdf7f2 TL |
73 | { |
74 | return caps.check_cap("roles", RGW_CAP_WRITE); | |
7c673cae FG |
75 | } |
76 | ||
f67539c2 | 77 | int RGWCreateRole::verify_permission(optional_yield y) |
7c673cae FG |
78 | { |
79 | if (s->auth.identity->is_anonymous()) { | |
80 | return -EACCES; | |
81 | } | |
82 | ||
9f95a23c | 83 | if (int ret = check_caps(s->user->get_caps()); ret == 0) { |
11fdf7f2 | 84 | return ret; |
7c673cae FG |
85 | } |
86 | ||
11fdf7f2 TL |
87 | string role_name = s->info.args.get("RoleName"); |
88 | string role_path = s->info.args.get("Path"); | |
89 | ||
90 | string resource_name = role_path + role_name; | |
91 | if (!verify_user_permission(this, | |
92 | s, | |
eafe8130 | 93 | rgw::ARN(resource_name, |
11fdf7f2 | 94 | "role", |
9f95a23c | 95 | s->user->get_tenant(), true), |
11fdf7f2 TL |
96 | get_op())) { |
97 | return -EACCES; | |
98 | } | |
7c673cae FG |
99 | return 0; |
100 | } | |
101 | ||
102 | int RGWCreateRole::get_params() | |
103 | { | |
104 | role_name = s->info.args.get("RoleName"); | |
105 | role_path = s->info.args.get("Path"); | |
106 | trust_policy = s->info.args.get("AssumeRolePolicyDocument"); | |
11fdf7f2 | 107 | max_session_duration = s->info.args.get("MaxSessionDuration"); |
7c673cae FG |
108 | |
109 | if (role_name.empty() || trust_policy.empty()) { | |
b3b6e05e | 110 | ldpp_dout(this, 20) << "ERROR: one of role name or assume role policy document is empty" |
7c673cae FG |
111 | << dendl; |
112 | return -EINVAL; | |
113 | } | |
11fdf7f2 TL |
114 | |
115 | bufferlist bl = bufferlist::static_from_string(trust_policy); | |
116 | try { | |
9f95a23c | 117 | const rgw::IAM::Policy p(s->cct, s->user->get_tenant(), bl); |
11fdf7f2 TL |
118 | } |
119 | catch (rgw::IAM::PolicyParseException& e) { | |
b3b6e05e | 120 | ldpp_dout(this, 20) << "failed to parse policy: " << e.what() << dendl; |
7c673cae FG |
121 | return -ERR_MALFORMED_DOC; |
122 | } | |
11fdf7f2 | 123 | |
7c673cae FG |
124 | return 0; |
125 | } | |
126 | ||
f67539c2 | 127 | void RGWCreateRole::execute(optional_yield y) |
7c673cae FG |
128 | { |
129 | op_ret = get_params(); | |
130 | if (op_ret < 0) { | |
131 | return; | |
132 | } | |
9f95a23c TL |
133 | RGWRole role(s->cct, store->getRados()->pctl, role_name, role_path, trust_policy, |
134 | s->user->get_tenant(), max_session_duration); | |
b3b6e05e | 135 | op_ret = role.create(s, true, y); |
7c673cae FG |
136 | |
137 | if (op_ret == -EEXIST) { | |
138 | op_ret = -ERR_ROLE_EXISTS; | |
139 | } | |
140 | ||
141 | if (op_ret == 0) { | |
92f5a8d4 TL |
142 | s->formatter->open_object_section("CreateRoleResponse"); |
143 | s->formatter->open_object_section("CreateRoleResult"); | |
144 | s->formatter->open_object_section("Role"); | |
7c673cae FG |
145 | role.dump(s->formatter); |
146 | s->formatter->close_section(); | |
92f5a8d4 TL |
147 | s->formatter->close_section(); |
148 | s->formatter->open_object_section("ResponseMetadata"); | |
149 | s->formatter->dump_string("RequestId", s->trans_id); | |
150 | s->formatter->close_section(); | |
151 | s->formatter->close_section(); | |
7c673cae FG |
152 | } |
153 | } | |
154 | ||
155 | int RGWDeleteRole::get_params() | |
156 | { | |
157 | role_name = s->info.args.get("RoleName"); | |
158 | ||
159 | if (role_name.empty()) { | |
b3b6e05e | 160 | ldpp_dout(this, 20) << "ERROR: Role name is empty"<< dendl; |
7c673cae FG |
161 | return -EINVAL; |
162 | } | |
163 | ||
164 | return 0; | |
165 | } | |
166 | ||
f67539c2 | 167 | void RGWDeleteRole::execute(optional_yield y) |
7c673cae FG |
168 | { |
169 | op_ret = get_params(); | |
170 | if (op_ret < 0) { | |
171 | return; | |
172 | } | |
11fdf7f2 | 173 | |
b3b6e05e | 174 | op_ret = _role.delete_obj(s, y); |
7c673cae FG |
175 | |
176 | if (op_ret == -ENOENT) { | |
177 | op_ret = -ERR_NO_ROLE_FOUND; | |
178 | } | |
92f5a8d4 TL |
179 | |
180 | s->formatter->open_object_section("DeleteRoleResponse"); | |
181 | s->formatter->open_object_section("ResponseMetadata"); | |
182 | s->formatter->dump_string("RequestId", s->trans_id); | |
183 | s->formatter->close_section(); | |
184 | s->formatter->close_section(); | |
7c673cae FG |
185 | } |
186 | ||
f67539c2 | 187 | int RGWGetRole::verify_permission(optional_yield y) |
11fdf7f2 TL |
188 | { |
189 | return 0; | |
190 | } | |
191 | ||
192 | int RGWGetRole::_verify_permission(const RGWRole& role) | |
193 | { | |
194 | if (s->auth.identity->is_anonymous()) { | |
195 | return -EACCES; | |
196 | } | |
197 | ||
9f95a23c | 198 | if (int ret = check_caps(s->user->get_caps()); ret == 0) { |
11fdf7f2 TL |
199 | return ret; |
200 | } | |
201 | ||
202 | string resource_name = role.get_path() + role.get_name(); | |
203 | if (!verify_user_permission(this, | |
204 | s, | |
eafe8130 | 205 | rgw::ARN(resource_name, |
11fdf7f2 | 206 | "role", |
9f95a23c | 207 | s->user->get_tenant(), true), |
11fdf7f2 TL |
208 | get_op())) { |
209 | return -EACCES; | |
210 | } | |
211 | return 0; | |
212 | } | |
213 | ||
7c673cae FG |
214 | int RGWGetRole::get_params() |
215 | { | |
216 | role_name = s->info.args.get("RoleName"); | |
217 | ||
218 | if (role_name.empty()) { | |
b3b6e05e | 219 | ldpp_dout(this, 20) << "ERROR: Role name is empty"<< dendl; |
7c673cae FG |
220 | return -EINVAL; |
221 | } | |
222 | ||
223 | return 0; | |
224 | } | |
225 | ||
f67539c2 | 226 | void RGWGetRole::execute(optional_yield y) |
7c673cae FG |
227 | { |
228 | op_ret = get_params(); | |
229 | if (op_ret < 0) { | |
230 | return; | |
231 | } | |
9f95a23c | 232 | RGWRole role(s->cct, store->getRados()->pctl, role_name, s->user->get_tenant()); |
b3b6e05e | 233 | op_ret = role.get(s, y); |
7c673cae FG |
234 | |
235 | if (op_ret == -ENOENT) { | |
236 | op_ret = -ERR_NO_ROLE_FOUND; | |
11fdf7f2 | 237 | return; |
7c673cae FG |
238 | } |
239 | ||
11fdf7f2 TL |
240 | op_ret = _verify_permission(role); |
241 | ||
7c673cae | 242 | if (op_ret == 0) { |
92f5a8d4 TL |
243 | s->formatter->open_object_section("GetRoleResponse"); |
244 | s->formatter->open_object_section("ResponseMetadata"); | |
245 | s->formatter->dump_string("RequestId", s->trans_id); | |
246 | s->formatter->close_section(); | |
247 | s->formatter->open_object_section("GetRoleResult"); | |
248 | s->formatter->open_object_section("Role"); | |
7c673cae FG |
249 | role.dump(s->formatter); |
250 | s->formatter->close_section(); | |
92f5a8d4 TL |
251 | s->formatter->close_section(); |
252 | s->formatter->close_section(); | |
7c673cae FG |
253 | } |
254 | } | |
255 | ||
256 | int RGWModifyRole::get_params() | |
257 | { | |
258 | role_name = s->info.args.get("RoleName"); | |
259 | trust_policy = s->info.args.get("PolicyDocument"); | |
260 | ||
261 | if (role_name.empty() || trust_policy.empty()) { | |
b3b6e05e | 262 | ldpp_dout(this, 20) << "ERROR: One of role name or trust policy is empty"<< dendl; |
7c673cae FG |
263 | return -EINVAL; |
264 | } | |
265 | JSONParser p; | |
266 | if (!p.parse(trust_policy.c_str(), trust_policy.length())) { | |
b3b6e05e | 267 | ldpp_dout(this, 20) << "ERROR: failed to parse assume role policy doc" << dendl; |
7c673cae FG |
268 | return -ERR_MALFORMED_DOC; |
269 | } | |
270 | ||
271 | return 0; | |
272 | } | |
273 | ||
f67539c2 | 274 | void RGWModifyRole::execute(optional_yield y) |
7c673cae FG |
275 | { |
276 | op_ret = get_params(); | |
277 | if (op_ret < 0) { | |
278 | return; | |
279 | } | |
11fdf7f2 TL |
280 | |
281 | _role.update_trust_policy(trust_policy); | |
b3b6e05e | 282 | op_ret = _role.update(this, y); |
11fdf7f2 | 283 | |
92f5a8d4 TL |
284 | s->formatter->open_object_section("UpdateAssumeRolePolicyResponse"); |
285 | s->formatter->open_object_section("ResponseMetadata"); | |
286 | s->formatter->dump_string("RequestId", s->trans_id); | |
287 | s->formatter->close_section(); | |
288 | s->formatter->close_section(); | |
11fdf7f2 TL |
289 | } |
290 | ||
f67539c2 | 291 | int RGWListRoles::verify_permission(optional_yield y) |
11fdf7f2 TL |
292 | { |
293 | if (s->auth.identity->is_anonymous()) { | |
294 | return -EACCES; | |
7c673cae FG |
295 | } |
296 | ||
9f95a23c | 297 | if (int ret = check_caps(s->user->get_caps()); ret == 0) { |
11fdf7f2 | 298 | return ret; |
7c673cae | 299 | } |
11fdf7f2 TL |
300 | |
301 | if (!verify_user_permission(this, | |
302 | s, | |
eafe8130 | 303 | rgw::ARN(), |
11fdf7f2 TL |
304 | get_op())) { |
305 | return -EACCES; | |
306 | } | |
307 | ||
308 | return 0; | |
7c673cae FG |
309 | } |
310 | ||
311 | int RGWListRoles::get_params() | |
312 | { | |
313 | path_prefix = s->info.args.get("PathPrefix"); | |
314 | ||
315 | return 0; | |
316 | } | |
317 | ||
f67539c2 | 318 | void RGWListRoles::execute(optional_yield y) |
7c673cae FG |
319 | { |
320 | op_ret = get_params(); | |
321 | if (op_ret < 0) { | |
322 | return; | |
323 | } | |
324 | vector<RGWRole> result; | |
b3b6e05e | 325 | op_ret = RGWRole::get_roles_by_path_prefix(s, store->getRados(), s->cct, path_prefix, s->user->get_tenant(), result, y); |
7c673cae FG |
326 | |
327 | if (op_ret == 0) { | |
92f5a8d4 TL |
328 | s->formatter->open_array_section("ListRolesResponse"); |
329 | s->formatter->open_object_section("ResponseMetadata"); | |
330 | s->formatter->dump_string("RequestId", s->trans_id); | |
331 | s->formatter->close_section(); | |
332 | s->formatter->open_array_section("ListRolesResult"); | |
333 | s->formatter->open_object_section("Roles"); | |
7c673cae | 334 | for (const auto& it : result) { |
92f5a8d4 | 335 | s->formatter->open_object_section("member"); |
7c673cae FG |
336 | it.dump(s->formatter); |
337 | s->formatter->close_section(); | |
338 | } | |
339 | s->formatter->close_section(); | |
92f5a8d4 TL |
340 | s->formatter->close_section(); |
341 | s->formatter->close_section(); | |
7c673cae FG |
342 | } |
343 | } | |
344 | ||
345 | int RGWPutRolePolicy::get_params() | |
346 | { | |
347 | role_name = s->info.args.get("RoleName"); | |
348 | policy_name = s->info.args.get("PolicyName"); | |
349 | perm_policy = s->info.args.get("PolicyDocument"); | |
350 | ||
351 | if (role_name.empty() || policy_name.empty() || perm_policy.empty()) { | |
b3b6e05e | 352 | ldpp_dout(this, 20) << "ERROR: One of role name, policy name or perm policy is empty"<< dendl; |
7c673cae FG |
353 | return -EINVAL; |
354 | } | |
11fdf7f2 TL |
355 | bufferlist bl = bufferlist::static_from_string(perm_policy); |
356 | try { | |
9f95a23c | 357 | const rgw::IAM::Policy p(s->cct, s->user->get_tenant(), bl); |
11fdf7f2 TL |
358 | } |
359 | catch (rgw::IAM::PolicyParseException& e) { | |
b3b6e05e | 360 | ldpp_dout(this, 20) << "failed to parse policy: " << e.what() << dendl; |
7c673cae FG |
361 | return -ERR_MALFORMED_DOC; |
362 | } | |
7c673cae FG |
363 | return 0; |
364 | } | |
365 | ||
f67539c2 | 366 | void RGWPutRolePolicy::execute(optional_yield y) |
7c673cae FG |
367 | { |
368 | op_ret = get_params(); | |
369 | if (op_ret < 0) { | |
370 | return; | |
371 | } | |
372 | ||
11fdf7f2 | 373 | _role.set_perm_policy(policy_name, perm_policy); |
b3b6e05e | 374 | op_ret = _role.update(this, y); |
92f5a8d4 TL |
375 | |
376 | if (op_ret == 0) { | |
377 | s->formatter->open_object_section("PutRolePolicyResponse"); | |
378 | s->formatter->open_object_section("ResponseMetadata"); | |
379 | s->formatter->dump_string("RequestId", s->trans_id); | |
380 | s->formatter->close_section(); | |
381 | s->formatter->close_section(); | |
382 | } | |
7c673cae FG |
383 | } |
384 | ||
385 | int RGWGetRolePolicy::get_params() | |
386 | { | |
387 | role_name = s->info.args.get("RoleName"); | |
388 | policy_name = s->info.args.get("PolicyName"); | |
389 | ||
390 | if (role_name.empty() || policy_name.empty()) { | |
b3b6e05e | 391 | ldpp_dout(this, 20) << "ERROR: One of role name or policy name is empty"<< dendl; |
7c673cae FG |
392 | return -EINVAL; |
393 | } | |
394 | return 0; | |
395 | } | |
396 | ||
f67539c2 | 397 | void RGWGetRolePolicy::execute(optional_yield y) |
7c673cae FG |
398 | { |
399 | op_ret = get_params(); | |
400 | if (op_ret < 0) { | |
401 | return; | |
402 | } | |
403 | ||
11fdf7f2 TL |
404 | string perm_policy; |
405 | op_ret = _role.get_role_policy(policy_name, perm_policy); | |
92f5a8d4 TL |
406 | if (op_ret == -ENOENT) { |
407 | op_ret = -ERR_NO_SUCH_ENTITY; | |
408 | } | |
409 | ||
7c673cae | 410 | if (op_ret == 0) { |
92f5a8d4 TL |
411 | s->formatter->open_object_section("GetRolePolicyResponse"); |
412 | s->formatter->open_object_section("ResponseMetadata"); | |
413 | s->formatter->dump_string("RequestId", s->trans_id); | |
414 | s->formatter->close_section(); | |
11fdf7f2 TL |
415 | s->formatter->open_object_section("GetRolePolicyResult"); |
416 | s->formatter->dump_string("PolicyName", policy_name); | |
417 | s->formatter->dump_string("RoleName", role_name); | |
f6b5b4d7 | 418 | s->formatter->dump_string("PolicyDocument", perm_policy); |
11fdf7f2 | 419 | s->formatter->close_section(); |
92f5a8d4 | 420 | s->formatter->close_section(); |
7c673cae FG |
421 | } |
422 | } | |
423 | ||
424 | int RGWListRolePolicies::get_params() | |
425 | { | |
426 | role_name = s->info.args.get("RoleName"); | |
427 | ||
428 | if (role_name.empty()) { | |
b3b6e05e | 429 | ldpp_dout(this, 20) << "ERROR: Role name is empty"<< dendl; |
7c673cae FG |
430 | return -EINVAL; |
431 | } | |
432 | return 0; | |
433 | } | |
434 | ||
f67539c2 | 435 | void RGWListRolePolicies::execute(optional_yield y) |
7c673cae FG |
436 | { |
437 | op_ret = get_params(); | |
438 | if (op_ret < 0) { | |
439 | return; | |
440 | } | |
441 | ||
11fdf7f2 | 442 | std::vector<string> policy_names = _role.get_role_policy_names(); |
92f5a8d4 TL |
443 | s->formatter->open_object_section("ListRolePoliciesResponse"); |
444 | s->formatter->open_object_section("ResponseMetadata"); | |
445 | s->formatter->dump_string("RequestId", s->trans_id); | |
446 | s->formatter->close_section(); | |
447 | s->formatter->open_object_section("ListRolePoliciesResult"); | |
11fdf7f2 TL |
448 | s->formatter->open_array_section("PolicyNames"); |
449 | for (const auto& it : policy_names) { | |
450 | s->formatter->dump_string("member", it); | |
7c673cae | 451 | } |
11fdf7f2 | 452 | s->formatter->close_section(); |
92f5a8d4 TL |
453 | s->formatter->close_section(); |
454 | s->formatter->close_section(); | |
7c673cae FG |
455 | } |
456 | ||
457 | int RGWDeleteRolePolicy::get_params() | |
458 | { | |
459 | role_name = s->info.args.get("RoleName"); | |
460 | policy_name = s->info.args.get("PolicyName"); | |
461 | ||
462 | if (role_name.empty() || policy_name.empty()) { | |
b3b6e05e | 463 | ldpp_dout(this, 20) << "ERROR: One of role name or policy name is empty"<< dendl; |
7c673cae FG |
464 | return -EINVAL; |
465 | } | |
466 | return 0; | |
467 | } | |
468 | ||
f67539c2 | 469 | void RGWDeleteRolePolicy::execute(optional_yield y) |
7c673cae FG |
470 | { |
471 | op_ret = get_params(); | |
472 | if (op_ret < 0) { | |
473 | return; | |
474 | } | |
475 | ||
11fdf7f2 | 476 | op_ret = _role.delete_policy(policy_name); |
7c673cae FG |
477 | if (op_ret == -ENOENT) { |
478 | op_ret = -ERR_NO_ROLE_FOUND; | |
479 | } | |
480 | ||
481 | if (op_ret == 0) { | |
b3b6e05e | 482 | op_ret = _role.update(this, y); |
7c673cae | 483 | } |
92f5a8d4 TL |
484 | |
485 | s->formatter->open_object_section("DeleteRolePoliciesResponse"); | |
486 | s->formatter->open_object_section("ResponseMetadata"); | |
487 | s->formatter->dump_string("RequestId", s->trans_id); | |
488 | s->formatter->close_section(); | |
489 | s->formatter->close_section(); | |
7c673cae | 490 | } |