]> git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_rest_role.cc
0fa0f8f011554cf755b1aaf36f69ec2edcf3ad25
[ceph.git] / ceph / src / rgw / rgw_rest_role.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
3
4 #include <errno.h>
5 #include <regex>
6
7 #include "common/errno.h"
8 #include "common/Formatter.h"
9 #include "common/ceph_json.h"
10
11 #include "include/types.h"
12 #include "rgw_string.h"
13
14 #include "rgw_common.h"
15 #include "rgw_op.h"
16 #include "rgw_rest.h"
17 #include "rgw_role.h"
18 #include "rgw_rest_role.h"
19 #include "rgw_sal.h"
20
21 #define dout_subsys ceph_subsys_rgw
22
23 using namespace std;
24
25 int RGWRestRole::verify_permission(optional_yield y)
26 {
27 if (s->auth.identity->is_anonymous()) {
28 return -EACCES;
29 }
30
31 string role_name = s->info.args.get("RoleName");
32 std::unique_ptr<rgw::sal::RGWRole> role = store->get_role(role_name,
33 s->user->get_tenant());
34 if (op_ret = role->get(s, y); op_ret < 0) {
35 if (op_ret == -ENOENT) {
36 op_ret = -ERR_NO_ROLE_FOUND;
37 }
38 return op_ret;
39 }
40
41 if (int ret = check_caps(s->user->get_caps()); ret == 0) {
42 _role = std::move(role);
43 return ret;
44 }
45
46 string resource_name = role->get_path() + role_name;
47 uint64_t op = get_op();
48 if (!verify_user_permission(this,
49 s,
50 rgw::ARN(resource_name,
51 "role",
52 s->user->get_tenant(), true),
53 op)) {
54 return -EACCES;
55 }
56
57 _role = std::move(role);
58
59 return 0;
60 }
61
62 int RGWRestRole::parse_tags()
63 {
64 vector<string> keys, vals;
65 auto val_map = s->info.args.get_params();
66 const regex pattern_key("Tags.member.([0-9]+).Key");
67 const regex pattern_value("Tags.member.([0-9]+).Value");
68 for (auto& v : val_map) {
69 string key_index="", value_index="";
70 for(sregex_iterator it = sregex_iterator(
71 v.first.begin(), v.first.end(), pattern_key);
72 it != sregex_iterator(); it++) {
73 smatch match;
74 match = *it;
75 key_index = match.str(1);
76 ldout(s->cct, 20) << "Key index: " << match.str(1) << dendl;
77 if (!key_index.empty()) {
78 int index = stoi(key_index);
79 auto pos = keys.begin() + (index-1);
80 keys.insert(pos, v.second);
81 }
82 }
83 for(sregex_iterator it = sregex_iterator(
84 v.first.begin(), v.first.end(), pattern_value);
85 it != sregex_iterator(); it++) {
86 smatch match;
87 match = *it;
88 value_index = match.str(1);
89 ldout(s->cct, 20) << "Value index: " << match.str(1) << dendl;
90 if (!value_index.empty()) {
91 int index = stoi(value_index);
92 auto pos = vals.begin() + (index-1);
93 vals.insert(pos, v.second);
94 }
95 }
96 }
97 if (keys.size() != vals.size()) {
98 ldout(s->cct, 0) << "No. of keys doesn't match with no. of values in tags" << dendl;
99 return -EINVAL;
100 }
101 for (size_t i = 0; i < keys.size(); i++) {
102 tags.emplace(keys[i], vals[i]);
103 ldout(s->cct, 0) << "Tag Key: " << keys[i] << " Tag Value is: " << vals[i] << dendl;
104 }
105 return 0;
106 }
107
108 void RGWRestRole::send_response()
109 {
110 if (op_ret) {
111 set_req_state_err(s, op_ret);
112 }
113 dump_errno(s);
114 end_header(s, this);
115 }
116
117 int RGWRoleRead::check_caps(const RGWUserCaps& caps)
118 {
119 return caps.check_cap("roles", RGW_CAP_READ);
120 }
121
122 int RGWRoleWrite::check_caps(const RGWUserCaps& caps)
123 {
124 return caps.check_cap("roles", RGW_CAP_WRITE);
125 }
126
127 int RGWCreateRole::verify_permission(optional_yield y)
128 {
129 if (s->auth.identity->is_anonymous()) {
130 return -EACCES;
131 }
132
133 if (int ret = check_caps(s->user->get_caps()); ret == 0) {
134 return ret;
135 }
136
137 string role_name = s->info.args.get("RoleName");
138 string role_path = s->info.args.get("Path");
139
140 string resource_name = role_path + role_name;
141 if (!verify_user_permission(this,
142 s,
143 rgw::ARN(resource_name,
144 "role",
145 s->user->get_tenant(), true),
146 get_op())) {
147 return -EACCES;
148 }
149 return 0;
150 }
151
152 int RGWCreateRole::get_params()
153 {
154 role_name = s->info.args.get("RoleName");
155 role_path = s->info.args.get("Path");
156 trust_policy = s->info.args.get("AssumeRolePolicyDocument");
157 max_session_duration = s->info.args.get("MaxSessionDuration");
158
159 if (role_name.empty() || trust_policy.empty()) {
160 ldpp_dout(this, 20) << "ERROR: one of role name or assume role policy document is empty"
161 << dendl;
162 return -EINVAL;
163 }
164
165 bufferlist bl = bufferlist::static_from_string(trust_policy);
166 try {
167 const rgw::IAM::Policy p(s->cct, s->user->get_tenant(), bl);
168 }
169 catch (rgw::IAM::PolicyParseException& e) {
170 ldpp_dout(this, 20) << "failed to parse policy: " << e.what() << dendl;
171 return -ERR_MALFORMED_DOC;
172 }
173
174 int ret = parse_tags();
175 if (ret < 0) {
176 return ret;
177 }
178
179 if (tags.size() > 50) {
180 ldout(s->cct, 0) << "No. tags is greater than 50" << dendl;
181 return -EINVAL;
182 }
183
184 return 0;
185 }
186
187 void RGWCreateRole::execute(optional_yield y)
188 {
189 op_ret = get_params();
190 if (op_ret < 0) {
191 return;
192 }
193 std::string user_tenant = s->user->get_tenant();
194 std::unique_ptr<rgw::sal::RGWRole> role = store->get_role(role_name,
195 user_tenant,
196 role_path,
197 trust_policy,
198 max_session_duration,
199 tags);
200 if (!user_tenant.empty() && role->get_tenant() != user_tenant) {
201 ldpp_dout(this, 20) << "ERROR: the tenant provided in the role name does not match with the tenant of the user creating the role"
202 << dendl;
203 op_ret = -EINVAL;
204 return;
205 }
206 op_ret = role->create(s, true, y);
207 if (op_ret == -EEXIST) {
208 op_ret = -ERR_ROLE_EXISTS;
209 }
210
211 if (op_ret == 0) {
212 s->formatter->open_object_section("CreateRoleResponse");
213 s->formatter->open_object_section("CreateRoleResult");
214 s->formatter->open_object_section("Role");
215 role->dump(s->formatter);
216 s->formatter->close_section();
217 s->formatter->close_section();
218 s->formatter->open_object_section("ResponseMetadata");
219 s->formatter->dump_string("RequestId", s->trans_id);
220 s->formatter->close_section();
221 s->formatter->close_section();
222 }
223 }
224
225 int RGWDeleteRole::get_params()
226 {
227 role_name = s->info.args.get("RoleName");
228
229 if (role_name.empty()) {
230 ldpp_dout(this, 20) << "ERROR: Role name is empty"<< dendl;
231 return -EINVAL;
232 }
233
234 return 0;
235 }
236
237 void RGWDeleteRole::execute(optional_yield y)
238 {
239 op_ret = get_params();
240 if (op_ret < 0) {
241 return;
242 }
243
244 op_ret = _role->delete_obj(s, y);
245
246 if (op_ret == -ENOENT) {
247 op_ret = -ERR_NO_ROLE_FOUND;
248 }
249 if (!op_ret) {
250 s->formatter->open_object_section("DeleteRoleResponse");
251 s->formatter->open_object_section("ResponseMetadata");
252 s->formatter->dump_string("RequestId", s->trans_id);
253 s->formatter->close_section();
254 s->formatter->close_section();
255 }
256 }
257
258 int RGWGetRole::verify_permission(optional_yield y)
259 {
260 return 0;
261 }
262
263 int RGWGetRole::_verify_permission(const rgw::sal::RGWRole* role)
264 {
265 if (s->auth.identity->is_anonymous()) {
266 return -EACCES;
267 }
268
269 if (int ret = check_caps(s->user->get_caps()); ret == 0) {
270 return ret;
271 }
272
273 string resource_name = role->get_path() + role->get_name();
274 if (!verify_user_permission(this,
275 s,
276 rgw::ARN(resource_name,
277 "role",
278 s->user->get_tenant(), true),
279 get_op())) {
280 return -EACCES;
281 }
282 return 0;
283 }
284
285 int RGWGetRole::get_params()
286 {
287 role_name = s->info.args.get("RoleName");
288
289 if (role_name.empty()) {
290 ldpp_dout(this, 20) << "ERROR: Role name is empty"<< dendl;
291 return -EINVAL;
292 }
293
294 return 0;
295 }
296
297 void RGWGetRole::execute(optional_yield y)
298 {
299 op_ret = get_params();
300 if (op_ret < 0) {
301 return;
302 }
303 std::unique_ptr<rgw::sal::RGWRole> role = store->get_role(role_name,
304 s->user->get_tenant());
305 op_ret = role->get(s, y);
306
307 if (op_ret == -ENOENT) {
308 op_ret = -ERR_NO_ROLE_FOUND;
309 return;
310 }
311
312 op_ret = _verify_permission(role.get());
313
314 if (op_ret == 0) {
315 s->formatter->open_object_section("GetRoleResponse");
316 s->formatter->open_object_section("ResponseMetadata");
317 s->formatter->dump_string("RequestId", s->trans_id);
318 s->formatter->close_section();
319 s->formatter->open_object_section("GetRoleResult");
320 s->formatter->open_object_section("Role");
321 role->dump(s->formatter);
322 s->formatter->close_section();
323 s->formatter->close_section();
324 s->formatter->close_section();
325 }
326 }
327
328 int RGWModifyRole::get_params()
329 {
330 role_name = s->info.args.get("RoleName");
331 trust_policy = s->info.args.get("PolicyDocument");
332
333 if (role_name.empty() || trust_policy.empty()) {
334 ldpp_dout(this, 20) << "ERROR: One of role name or trust policy is empty"<< dendl;
335 return -EINVAL;
336 }
337 JSONParser p;
338 if (!p.parse(trust_policy.c_str(), trust_policy.length())) {
339 ldpp_dout(this, 20) << "ERROR: failed to parse assume role policy doc" << dendl;
340 return -ERR_MALFORMED_DOC;
341 }
342
343 return 0;
344 }
345
346 void RGWModifyRole::execute(optional_yield y)
347 {
348 op_ret = get_params();
349 if (op_ret < 0) {
350 return;
351 }
352
353 _role->update_trust_policy(trust_policy);
354 op_ret = _role->update(this, y);
355
356 s->formatter->open_object_section("UpdateAssumeRolePolicyResponse");
357 s->formatter->open_object_section("ResponseMetadata");
358 s->formatter->dump_string("RequestId", s->trans_id);
359 s->formatter->close_section();
360 s->formatter->close_section();
361 }
362
363 int RGWListRoles::verify_permission(optional_yield y)
364 {
365 if (s->auth.identity->is_anonymous()) {
366 return -EACCES;
367 }
368
369 if (int ret = check_caps(s->user->get_caps()); ret == 0) {
370 return ret;
371 }
372
373 if (!verify_user_permission(this,
374 s,
375 rgw::ARN(),
376 get_op())) {
377 return -EACCES;
378 }
379
380 return 0;
381 }
382
383 int RGWListRoles::get_params()
384 {
385 path_prefix = s->info.args.get("PathPrefix");
386
387 return 0;
388 }
389
390 void RGWListRoles::execute(optional_yield y)
391 {
392 op_ret = get_params();
393 if (op_ret < 0) {
394 return;
395 }
396 vector<std::unique_ptr<rgw::sal::RGWRole>> result;
397 op_ret = store->get_roles(s, y, path_prefix, s->user->get_tenant(), result);
398
399 if (op_ret == 0) {
400 s->formatter->open_array_section("ListRolesResponse");
401 s->formatter->open_array_section("ListRolesResult");
402 s->formatter->open_object_section("Roles");
403 for (const auto& it : result) {
404 s->formatter->open_object_section("member");
405 it->dump(s->formatter);
406 s->formatter->close_section();
407 }
408 s->formatter->close_section();
409 s->formatter->close_section();
410 s->formatter->open_object_section("ResponseMetadata");
411 s->formatter->dump_string("RequestId", s->trans_id);
412 s->formatter->close_section();
413 s->formatter->close_section();
414 }
415 }
416
417 int RGWPutRolePolicy::get_params()
418 {
419 role_name = s->info.args.get("RoleName");
420 policy_name = s->info.args.get("PolicyName");
421 perm_policy = s->info.args.get("PolicyDocument");
422
423 if (role_name.empty() || policy_name.empty() || perm_policy.empty()) {
424 ldpp_dout(this, 20) << "ERROR: One of role name, policy name or perm policy is empty"<< dendl;
425 return -EINVAL;
426 }
427 bufferlist bl = bufferlist::static_from_string(perm_policy);
428 try {
429 const rgw::IAM::Policy p(s->cct, s->user->get_tenant(), bl);
430 }
431 catch (rgw::IAM::PolicyParseException& e) {
432 ldpp_dout(this, 20) << "failed to parse policy: " << e.what() << dendl;
433 return -ERR_MALFORMED_DOC;
434 }
435 return 0;
436 }
437
438 void RGWPutRolePolicy::execute(optional_yield y)
439 {
440 op_ret = get_params();
441 if (op_ret < 0) {
442 return;
443 }
444
445 _role->set_perm_policy(policy_name, perm_policy);
446 op_ret = _role->update(this, y);
447
448 if (op_ret == 0) {
449 s->formatter->open_object_section("PutRolePolicyResponse");
450 s->formatter->open_object_section("ResponseMetadata");
451 s->formatter->dump_string("RequestId", s->trans_id);
452 s->formatter->close_section();
453 s->formatter->close_section();
454 }
455 }
456
457 int RGWGetRolePolicy::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()) {
463 ldpp_dout(this, 20) << "ERROR: One of role name or policy name is empty"<< dendl;
464 return -EINVAL;
465 }
466 return 0;
467 }
468
469 void RGWGetRolePolicy::execute(optional_yield y)
470 {
471 op_ret = get_params();
472 if (op_ret < 0) {
473 return;
474 }
475
476 string perm_policy;
477 op_ret = _role->get_role_policy(this, policy_name, perm_policy);
478 if (op_ret == -ENOENT) {
479 op_ret = -ERR_NO_SUCH_ENTITY;
480 }
481
482 if (op_ret == 0) {
483 s->formatter->open_object_section("GetRolePolicyResponse");
484 s->formatter->open_object_section("ResponseMetadata");
485 s->formatter->dump_string("RequestId", s->trans_id);
486 s->formatter->close_section();
487 s->formatter->open_object_section("GetRolePolicyResult");
488 s->formatter->dump_string("PolicyName", policy_name);
489 s->formatter->dump_string("RoleName", role_name);
490 s->formatter->dump_string("PolicyDocument", perm_policy);
491 s->formatter->close_section();
492 s->formatter->close_section();
493 }
494 }
495
496 int RGWListRolePolicies::get_params()
497 {
498 role_name = s->info.args.get("RoleName");
499
500 if (role_name.empty()) {
501 ldpp_dout(this, 20) << "ERROR: Role name is empty"<< dendl;
502 return -EINVAL;
503 }
504 return 0;
505 }
506
507 void RGWListRolePolicies::execute(optional_yield y)
508 {
509 op_ret = get_params();
510 if (op_ret < 0) {
511 return;
512 }
513
514 std::vector<string> policy_names = _role->get_role_policy_names();
515 s->formatter->open_object_section("ListRolePoliciesResponse");
516 s->formatter->open_object_section("ResponseMetadata");
517 s->formatter->dump_string("RequestId", s->trans_id);
518 s->formatter->close_section();
519 s->formatter->open_object_section("ListRolePoliciesResult");
520 s->formatter->open_array_section("PolicyNames");
521 for (const auto& it : policy_names) {
522 s->formatter->dump_string("member", it);
523 }
524 s->formatter->close_section();
525 s->formatter->close_section();
526 s->formatter->close_section();
527 }
528
529 int RGWDeleteRolePolicy::get_params()
530 {
531 role_name = s->info.args.get("RoleName");
532 policy_name = s->info.args.get("PolicyName");
533
534 if (role_name.empty() || policy_name.empty()) {
535 ldpp_dout(this, 20) << "ERROR: One of role name or policy name is empty"<< dendl;
536 return -EINVAL;
537 }
538 return 0;
539 }
540
541 void RGWDeleteRolePolicy::execute(optional_yield y)
542 {
543 op_ret = get_params();
544 if (op_ret < 0) {
545 return;
546 }
547
548 op_ret = _role->delete_policy(this, policy_name);
549 if (op_ret == -ENOENT) {
550 op_ret = -ERR_NO_ROLE_FOUND;
551 }
552
553 if (op_ret == 0) {
554 op_ret = _role->update(this, y);
555 }
556
557 s->formatter->open_object_section("DeleteRolePoliciesResponse");
558 s->formatter->open_object_section("ResponseMetadata");
559 s->formatter->dump_string("RequestId", s->trans_id);
560 s->formatter->close_section();
561 s->formatter->close_section();
562 }
563
564 int RGWTagRole::get_params()
565 {
566 role_name = s->info.args.get("RoleName");
567
568 if (role_name.empty()) {
569 ldout(s->cct, 0) << "ERROR: Role name is empty" << dendl;
570 return -EINVAL;
571 }
572 int ret = parse_tags();
573 if (ret < 0) {
574 return ret;
575 }
576
577 return 0;
578 }
579
580 void RGWTagRole::execute(optional_yield y)
581 {
582 op_ret = get_params();
583 if (op_ret < 0) {
584 return;
585 }
586
587 op_ret = _role->set_tags(this, tags);
588 if (op_ret == 0) {
589 op_ret = _role->update(this, y);
590 }
591
592 if (op_ret == 0) {
593 s->formatter->open_object_section("TagRoleResponse");
594 s->formatter->open_object_section("ResponseMetadata");
595 s->formatter->dump_string("RequestId", s->trans_id);
596 s->formatter->close_section();
597 s->formatter->close_section();
598 }
599 }
600
601 int RGWListRoleTags::get_params()
602 {
603 role_name = s->info.args.get("RoleName");
604
605 if (role_name.empty()) {
606 ldout(s->cct, 0) << "ERROR: Role name is empty" << dendl;
607 return -EINVAL;
608 }
609
610 return 0;
611 }
612
613 void RGWListRoleTags::execute(optional_yield y)
614 {
615 op_ret = get_params();
616 if (op_ret < 0) {
617 return;
618 }
619
620 boost::optional<multimap<string,string>> tag_map = _role->get_tags();
621 s->formatter->open_object_section("ListRoleTagsResponse");
622 s->formatter->open_object_section("ListRoleTagsResult");
623 if (tag_map) {
624 s->formatter->open_array_section("Tags");
625 for (const auto& it : tag_map.get()) {
626 s->formatter->open_object_section("Key");
627 encode_json("Key", it.first, s->formatter);
628 s->formatter->close_section();
629 s->formatter->open_object_section("Value");
630 encode_json("Value", it.second, s->formatter);
631 s->formatter->close_section();
632 }
633 s->formatter->close_section();
634 }
635 s->formatter->close_section();
636 s->formatter->open_object_section("ResponseMetadata");
637 s->formatter->dump_string("RequestId", s->trans_id);
638 s->formatter->close_section();
639 s->formatter->close_section();
640 }
641
642 int RGWUntagRole::get_params()
643 {
644 role_name = s->info.args.get("RoleName");
645
646 if (role_name.empty()) {
647 ldout(s->cct, 0) << "ERROR: Role name is empty" << dendl;
648 return -EINVAL;
649 }
650
651 auto val_map = s->info.args.get_params();
652 for (auto& it : val_map) {
653 if (it.first.find("TagKeys.member.") != string::npos) {
654 tagKeys.emplace_back(it.second);
655 }
656 }
657 return 0;
658 }
659
660 void RGWUntagRole::execute(optional_yield y)
661 {
662 op_ret = get_params();
663 if (op_ret < 0) {
664 return;
665 }
666
667 _role->erase_tags(tagKeys);
668 op_ret = _role->update(this, y);
669
670 if (op_ret == 0) {
671 s->formatter->open_object_section("UntagRoleResponse");
672 s->formatter->open_object_section("ResponseMetadata");
673 s->formatter->dump_string("RequestId", s->trans_id);
674 s->formatter->close_section();
675 s->formatter->close_section();
676 }
677 }