]> git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_rest_user_policy.cc
bump version to 18.2.2-pve1
[ceph.git] / ceph / src / rgw / rgw_rest_user_policy.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_rest_user_policy.h"
18 #include "rgw_sal.h"
19 #include "services/svc_zone.h"
20
21 #define dout_subsys ceph_subsys_rgw
22
23
24 void RGWRestUserPolicy::dump(Formatter *f) const
25 {
26 encode_json("PolicyName", policy_name , f);
27 encode_json("UserName", user_name , f);
28 encode_json("PolicyDocument", policy, f);
29 }
30
31 void RGWRestUserPolicy::send_response()
32 {
33 if (op_ret) {
34 set_req_state_err(s, op_ret);
35 }
36 dump_errno(s);
37 end_header(s);
38 }
39
40 int RGWRestUserPolicy::verify_permission(optional_yield y)
41 {
42 if (s->auth.identity->is_anonymous()) {
43 return -EACCES;
44 }
45
46 if(int ret = check_caps(s->user->get_caps()); ret == 0) {
47 return ret;
48 }
49
50 uint64_t op = get_op();
51 std::string user_name = s->info.args.get("UserName");
52 rgw_user user_id(user_name);
53 if (! verify_user_permission(this, s, rgw::ARN(rgw::ARN(user_id.id,
54 "user",
55 user_id.tenant)), op)) {
56 return -EACCES;
57 }
58 return 0;
59 }
60
61 bool RGWRestUserPolicy::validate_input()
62 {
63 if (policy_name.length() > MAX_POLICY_NAME_LEN) {
64 ldpp_dout(this, 0) << "ERROR: Invalid policy name length " << dendl;
65 return false;
66 }
67
68 std::regex regex_policy_name("[A-Za-z0-9:=,.@-]+");
69 if (! std::regex_match(policy_name, regex_policy_name)) {
70 ldpp_dout(this, 0) << "ERROR: Invalid chars in policy name " << dendl;
71 return false;
72 }
73
74 return true;
75 }
76
77 int RGWUserPolicyRead::check_caps(const RGWUserCaps& caps)
78 {
79 return caps.check_cap("user-policy", RGW_CAP_READ);
80 }
81
82 int RGWUserPolicyWrite::check_caps(const RGWUserCaps& caps)
83 {
84 return caps.check_cap("user-policy", RGW_CAP_WRITE);
85 }
86
87 uint64_t RGWPutUserPolicy::get_op()
88 {
89 return rgw::IAM::iamPutUserPolicy;
90 }
91
92 int RGWPutUserPolicy::get_params()
93 {
94 policy_name = url_decode(s->info.args.get("PolicyName"), true);
95 user_name = url_decode(s->info.args.get("UserName"), true);
96 policy = url_decode(s->info.args.get("PolicyDocument"), true);
97
98 if (policy_name.empty() || user_name.empty() || policy.empty()) {
99 ldpp_dout(this, 20) << "ERROR: one of policy name, user name or policy document is empty"
100 << dendl;
101 return -EINVAL;
102 }
103
104 if (! validate_input()) {
105 return -EINVAL;
106 }
107
108 return 0;
109 }
110
111 void RGWPutUserPolicy::execute(optional_yield y)
112 {
113 op_ret = get_params();
114 if (op_ret < 0) {
115 return;
116 }
117
118 bufferlist bl = bufferlist::static_from_string(policy);
119
120 std::unique_ptr<rgw::sal::User> user = driver->get_user(rgw_user(user_name));
121
122 op_ret = user->load_user(s, s->yield);
123 if (op_ret < 0) {
124 op_ret = -ERR_NO_SUCH_ENTITY;
125 return;
126 }
127
128 op_ret = user->read_attrs(s, s->yield);
129 if (op_ret == -ENOENT) {
130 op_ret = -ERR_NO_SUCH_ENTITY;
131 return;
132 }
133
134 ceph::bufferlist in_data;
135 op_ret = driver->forward_request_to_master(this, s->user.get(), nullptr, in_data, nullptr, s->info, y);
136 if (op_ret < 0) {
137 ldpp_dout(this, 0) << "ERROR: forward_request_to_master returned ret=" << op_ret << dendl;
138 return;
139 }
140
141 try {
142 const rgw::IAM::Policy p(
143 s->cct, s->user->get_tenant(), bl,
144 s->cct->_conf.get_val<bool>("rgw_policy_reject_invalid_principals"));
145 std::map<std::string, std::string> policies;
146 if (auto it = user->get_attrs().find(RGW_ATTR_USER_POLICY); it != user->get_attrs().end()) {
147 bufferlist out_bl = it->second;
148 decode(policies, out_bl);
149 }
150 bufferlist in_bl;
151 policies[policy_name] = policy;
152 constexpr unsigned int USER_POLICIES_MAX_NUM = 100;
153 const unsigned int max_num = s->cct->_conf->rgw_user_policies_max_num < 0 ?
154 USER_POLICIES_MAX_NUM : s->cct->_conf->rgw_user_policies_max_num;
155 if (policies.size() > max_num) {
156 ldpp_dout(this, 4) << "IAM user policies has reached the num config: "
157 << max_num << ", cant add another" << dendl;
158 op_ret = -ERR_INVALID_REQUEST;
159 s->err.message =
160 "The number of IAM user policies should not exceed allowed limit "
161 "of " +
162 std::to_string(max_num) + " policies.";
163 return;
164 }
165 encode(policies, in_bl);
166 user->get_attrs()[RGW_ATTR_USER_POLICY] = in_bl;
167
168 op_ret = user->store_user(s, s->yield, false);
169 if (op_ret < 0) {
170 op_ret = -ERR_INTERNAL_ERROR;
171 }
172 } catch (buffer::error& err) {
173 ldpp_dout(this, 0) << "ERROR: failed to decode user policies" << dendl;
174 op_ret = -EIO;
175 } catch (rgw::IAM::PolicyParseException& e) {
176 ldpp_dout(this, 5) << "failed to parse policy: " << e.what() << dendl;
177 s->err.message = e.what();
178 op_ret = -ERR_MALFORMED_DOC;
179 }
180
181 if (op_ret == 0) {
182 s->formatter->open_object_section("PutUserPolicyResponse");
183 s->formatter->open_object_section("ResponseMetadata");
184 s->formatter->dump_string("RequestId", s->trans_id);
185 s->formatter->close_section();
186 s->formatter->close_section();
187 }
188 }
189
190 uint64_t RGWGetUserPolicy::get_op()
191 {
192 return rgw::IAM::iamGetUserPolicy;
193 }
194
195 int RGWGetUserPolicy::get_params()
196 {
197 policy_name = s->info.args.get("PolicyName");
198 user_name = s->info.args.get("UserName");
199
200 if (policy_name.empty() || user_name.empty()) {
201 ldpp_dout(this, 20) << "ERROR: one of policy name or user name is empty"
202 << dendl;
203 return -EINVAL;
204 }
205
206 return 0;
207 }
208
209 void RGWGetUserPolicy::execute(optional_yield y)
210 {
211 op_ret = get_params();
212 if (op_ret < 0) {
213 return;
214 }
215
216 std::unique_ptr<rgw::sal::User> user = driver->get_user(rgw_user(user_name));
217 op_ret = user->read_attrs(s, s->yield);
218 if (op_ret == -ENOENT) {
219 ldpp_dout(this, 0) << "ERROR: attrs not found for user" << user_name << dendl;
220 op_ret = -ERR_NO_SUCH_ENTITY;
221 return;
222 }
223
224 if (op_ret == 0) {
225 s->formatter->open_object_section("GetUserPolicyResponse");
226 s->formatter->open_object_section("ResponseMetadata");
227 s->formatter->dump_string("RequestId", s->trans_id);
228 s->formatter->close_section();
229 s->formatter->open_object_section("GetUserPolicyResult");
230 std::map<std::string, std::string> policies;
231 if (auto it = user->get_attrs().find(RGW_ATTR_USER_POLICY); it != user->get_attrs().end()) {
232 bufferlist bl = it->second;
233 try {
234 decode(policies, bl);
235 } catch (buffer::error& err) {
236 ldpp_dout(this, 0) << "ERROR: failed to decode user policies" << dendl;
237 op_ret = -EIO;
238 return;
239 }
240 if (auto it = policies.find(policy_name); it != policies.end()) {
241 policy = policies[policy_name];
242 dump(s->formatter);
243 } else {
244 ldpp_dout(this, 0) << "ERROR: policy not found" << policy << dendl;
245 op_ret = -ERR_NO_SUCH_ENTITY;
246 return;
247 }
248 } else {
249 ldpp_dout(this, 0) << "ERROR: RGW_ATTR_USER_POLICY not found" << dendl;
250 op_ret = -ERR_NO_SUCH_ENTITY;
251 return;
252 }
253 s->formatter->close_section();
254 s->formatter->close_section();
255 }
256 if (op_ret < 0) {
257 op_ret = -ERR_INTERNAL_ERROR;
258 }
259 }
260
261 uint64_t RGWListUserPolicies::get_op()
262 {
263 return rgw::IAM::iamListUserPolicies;
264 }
265
266 int RGWListUserPolicies::get_params()
267 {
268 user_name = s->info.args.get("UserName");
269
270 if (user_name.empty()) {
271 ldpp_dout(this, 20) << "ERROR: user name is empty" << dendl;
272 return -EINVAL;
273 }
274
275 return 0;
276 }
277
278 void RGWListUserPolicies::execute(optional_yield y)
279 {
280 op_ret = get_params();
281 if (op_ret < 0) {
282 return;
283 }
284
285 std::unique_ptr<rgw::sal::User> user = driver->get_user(rgw_user(user_name));
286 op_ret = user->read_attrs(s, s->yield);
287 if (op_ret == -ENOENT) {
288 ldpp_dout(this, 0) << "ERROR: attrs not found for user" << user_name << dendl;
289 op_ret = -ERR_NO_SUCH_ENTITY;
290 return;
291 }
292
293 if (op_ret == 0) {
294 std::map<std::string, std::string> policies;
295 if (auto it = user->get_attrs().find(RGW_ATTR_USER_POLICY); it != user->get_attrs().end()) {
296 s->formatter->open_object_section("ListUserPoliciesResponse");
297 s->formatter->open_object_section("ResponseMetadata");
298 s->formatter->dump_string("RequestId", s->trans_id);
299 s->formatter->close_section();
300 s->formatter->open_object_section("ListUserPoliciesResult");
301 bufferlist bl = it->second;
302 try {
303 decode(policies, bl);
304 } catch (buffer::error& err) {
305 ldpp_dout(this, 0) << "ERROR: failed to decode user policies" << dendl;
306 op_ret = -EIO;
307 return;
308 }
309 s->formatter->open_object_section("PolicyNames");
310 for (const auto& p : policies) {
311 s->formatter->dump_string("member", p.first);
312 }
313 s->formatter->close_section();
314 s->formatter->close_section();
315 s->formatter->close_section();
316 } else {
317 ldpp_dout(this, 0) << "ERROR: RGW_ATTR_USER_POLICY not found" << dendl;
318 op_ret = -ERR_NO_SUCH_ENTITY;
319 return;
320 }
321 }
322 if (op_ret < 0) {
323 op_ret = -ERR_INTERNAL_ERROR;
324 }
325 }
326
327 uint64_t RGWDeleteUserPolicy::get_op()
328 {
329 return rgw::IAM::iamDeleteUserPolicy;
330 }
331
332 int RGWDeleteUserPolicy::get_params()
333 {
334 policy_name = s->info.args.get("PolicyName");
335 user_name = s->info.args.get("UserName");
336
337 if (policy_name.empty() || user_name.empty()) {
338 ldpp_dout(this, 20) << "ERROR: One of policy name or user name is empty"<< dendl;
339 return -EINVAL;
340 }
341
342 return 0;
343 }
344
345 void RGWDeleteUserPolicy::execute(optional_yield y)
346 {
347 op_ret = get_params();
348 if (op_ret < 0) {
349 return;
350 }
351
352 std::unique_ptr<rgw::sal::User> user = driver->get_user(rgw_user(user_name));
353 op_ret = user->load_user(s, s->yield);
354 if (op_ret < 0) {
355 op_ret = -ERR_NO_SUCH_ENTITY;
356 return;
357 }
358
359 op_ret = user->read_attrs(this, s->yield);
360 if (op_ret == -ENOENT) {
361 op_ret = -ERR_NO_SUCH_ENTITY;
362 return;
363 }
364
365 ceph::bufferlist in_data;
366 op_ret = driver->forward_request_to_master(this, s->user.get(), nullptr, in_data, nullptr, s->info, y);
367 if (op_ret < 0) {
368 // a policy might've been uploaded to this site when there was no sync
369 // req. in earlier releases, proceed deletion
370 if (op_ret != -ENOENT) {
371 ldpp_dout(this, 5) << "forward_request_to_master returned ret=" << op_ret << dendl;
372 return;
373 }
374 ldpp_dout(this, 0) << "ERROR: forward_request_to_master returned ret=" << op_ret << dendl;
375 }
376
377 std::map<std::string, std::string> policies;
378 if (auto it = user->get_attrs().find(RGW_ATTR_USER_POLICY); it != user->get_attrs().end()) {
379 bufferlist out_bl = it->second;
380 try {
381 decode(policies, out_bl);
382 } catch (buffer::error& err) {
383 ldpp_dout(this, 0) << "ERROR: failed to decode user policies" << dendl;
384 op_ret = -EIO;
385 return;
386 }
387
388 if (auto p = policies.find(policy_name); p != policies.end()) {
389 bufferlist in_bl;
390 policies.erase(p);
391 encode(policies, in_bl);
392 user->get_attrs()[RGW_ATTR_USER_POLICY] = in_bl;
393
394 op_ret = user->store_user(s, s->yield, false);
395 if (op_ret < 0) {
396 op_ret = -ERR_INTERNAL_ERROR;
397 }
398 if (op_ret == 0) {
399 s->formatter->open_object_section("DeleteUserPoliciesResponse");
400 s->formatter->open_object_section("ResponseMetadata");
401 s->formatter->dump_string("RequestId", s->trans_id);
402 s->formatter->close_section();
403 s->formatter->close_section();
404 }
405 } else {
406 op_ret = -ERR_NO_SUCH_ENTITY;
407 return;
408 }
409 } else {
410 op_ret = -ERR_NO_SUCH_ENTITY;
411 return;
412 }
413 }