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