1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
7 #include "common/errno.h"
8 #include "common/Formatter.h"
9 #include "common/ceph_json.h"
11 #include "include/types.h"
12 #include "rgw_string.h"
14 #include "rgw_common.h"
17 #include "rgw_rest_user_policy.h"
19 #include "services/svc_zone.h"
21 #define dout_subsys ceph_subsys_rgw
24 void RGWRestUserPolicy::dump(Formatter
*f
) const
26 encode_json("PolicyName", policy_name
, f
);
27 encode_json("UserName", user_name
, f
);
28 encode_json("PolicyDocument", policy
, f
);
31 void RGWRestUserPolicy::send_response()
34 set_req_state_err(s
, op_ret
);
40 int RGWRestUserPolicy::verify_permission(optional_yield y
)
42 if (s
->auth
.identity
->is_anonymous()) {
46 if(int ret
= check_caps(s
->user
->get_caps()); ret
== 0) {
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
,
55 user_id
.tenant
)), op
)) {
61 bool RGWRestUserPolicy::validate_input()
63 if (policy_name
.length() > MAX_POLICY_NAME_LEN
) {
64 ldpp_dout(this, 0) << "ERROR: Invalid policy name length " << dendl
;
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
;
77 int RGWUserPolicyRead::check_caps(const RGWUserCaps
& caps
)
79 return caps
.check_cap("user-policy", RGW_CAP_READ
);
82 int RGWUserPolicyWrite::check_caps(const RGWUserCaps
& caps
)
84 return caps
.check_cap("user-policy", RGW_CAP_WRITE
);
87 uint64_t RGWPutUserPolicy::get_op()
89 return rgw::IAM::iamPutUserPolicy
;
92 int RGWPutUserPolicy::get_params()
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);
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"
104 if (! validate_input()) {
111 void RGWPutUserPolicy::execute(optional_yield y
)
113 op_ret
= get_params();
118 bufferlist bl
= bufferlist::static_from_string(policy
);
120 std::unique_ptr
<rgw::sal::User
> user
= driver
->get_user(rgw_user(user_name
));
122 op_ret
= user
->load_user(s
, s
->yield
);
124 op_ret
= -ERR_NO_SUCH_ENTITY
;
128 op_ret
= user
->read_attrs(s
, s
->yield
);
129 if (op_ret
== -ENOENT
) {
130 op_ret
= -ERR_NO_SUCH_ENTITY
;
134 ceph::bufferlist in_data
;
135 op_ret
= driver
->forward_request_to_master(this, s
->user
.get(), nullptr, in_data
, nullptr, s
->info
, y
);
137 ldpp_dout(this, 0) << "ERROR: forward_request_to_master returned ret=" << op_ret
<< dendl
;
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
);
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
;
160 "The number of IAM user policies should not exceed allowed limit "
162 std::to_string(max_num
) + " policies.";
165 encode(policies
, in_bl
);
166 user
->get_attrs()[RGW_ATTR_USER_POLICY
] = in_bl
;
168 op_ret
= user
->store_user(s
, s
->yield
, false);
170 op_ret
= -ERR_INTERNAL_ERROR
;
172 } catch (buffer::error
& err
) {
173 ldpp_dout(this, 0) << "ERROR: failed to decode user policies" << dendl
;
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
;
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();
190 uint64_t RGWGetUserPolicy::get_op()
192 return rgw::IAM::iamGetUserPolicy
;
195 int RGWGetUserPolicy::get_params()
197 policy_name
= s
->info
.args
.get("PolicyName");
198 user_name
= s
->info
.args
.get("UserName");
200 if (policy_name
.empty() || user_name
.empty()) {
201 ldpp_dout(this, 20) << "ERROR: one of policy name or user name is empty"
209 void RGWGetUserPolicy::execute(optional_yield y
)
211 op_ret
= get_params();
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
;
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
;
234 decode(policies
, bl
);
235 } catch (buffer::error
& err
) {
236 ldpp_dout(this, 0) << "ERROR: failed to decode user policies" << dendl
;
240 if (auto it
= policies
.find(policy_name
); it
!= policies
.end()) {
241 policy
= policies
[policy_name
];
244 ldpp_dout(this, 0) << "ERROR: policy not found" << policy
<< dendl
;
245 op_ret
= -ERR_NO_SUCH_ENTITY
;
249 ldpp_dout(this, 0) << "ERROR: RGW_ATTR_USER_POLICY not found" << dendl
;
250 op_ret
= -ERR_NO_SUCH_ENTITY
;
253 s
->formatter
->close_section();
254 s
->formatter
->close_section();
257 op_ret
= -ERR_INTERNAL_ERROR
;
261 uint64_t RGWListUserPolicies::get_op()
263 return rgw::IAM::iamListUserPolicies
;
266 int RGWListUserPolicies::get_params()
268 user_name
= s
->info
.args
.get("UserName");
270 if (user_name
.empty()) {
271 ldpp_dout(this, 20) << "ERROR: user name is empty" << dendl
;
278 void RGWListUserPolicies::execute(optional_yield y
)
280 op_ret
= get_params();
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
;
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
;
303 decode(policies
, bl
);
304 } catch (buffer::error
& err
) {
305 ldpp_dout(this, 0) << "ERROR: failed to decode user policies" << dendl
;
309 s
->formatter
->open_object_section("PolicyNames");
310 for (const auto& p
: policies
) {
311 s
->formatter
->dump_string("member", p
.first
);
313 s
->formatter
->close_section();
314 s
->formatter
->close_section();
315 s
->formatter
->close_section();
317 ldpp_dout(this, 0) << "ERROR: RGW_ATTR_USER_POLICY not found" << dendl
;
318 op_ret
= -ERR_NO_SUCH_ENTITY
;
323 op_ret
= -ERR_INTERNAL_ERROR
;
327 uint64_t RGWDeleteUserPolicy::get_op()
329 return rgw::IAM::iamDeleteUserPolicy
;
332 int RGWDeleteUserPolicy::get_params()
334 policy_name
= s
->info
.args
.get("PolicyName");
335 user_name
= s
->info
.args
.get("UserName");
337 if (policy_name
.empty() || user_name
.empty()) {
338 ldpp_dout(this, 20) << "ERROR: One of policy name or user name is empty"<< dendl
;
345 void RGWDeleteUserPolicy::execute(optional_yield y
)
347 op_ret
= get_params();
352 std::unique_ptr
<rgw::sal::User
> user
= driver
->get_user(rgw_user(user_name
));
353 op_ret
= user
->load_user(s
, s
->yield
);
355 op_ret
= -ERR_NO_SUCH_ENTITY
;
359 op_ret
= user
->read_attrs(this, s
->yield
);
360 if (op_ret
== -ENOENT
) {
361 op_ret
= -ERR_NO_SUCH_ENTITY
;
365 ceph::bufferlist in_data
;
366 op_ret
= driver
->forward_request_to_master(this, s
->user
.get(), nullptr, in_data
, nullptr, s
->info
, y
);
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
;
374 ldpp_dout(this, 0) << "ERROR: forward_request_to_master returned ret=" << op_ret
<< dendl
;
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
;
381 decode(policies
, out_bl
);
382 } catch (buffer::error
& err
) {
383 ldpp_dout(this, 0) << "ERROR: failed to decode user policies" << dendl
;
388 if (auto p
= policies
.find(policy_name
); p
!= policies
.end()) {
391 encode(policies
, in_bl
);
392 user
->get_attrs()[RGW_ATTR_USER_POLICY
] = in_bl
;
394 op_ret
= user
->store_user(s
, s
->yield
, false);
396 op_ret
= -ERR_INTERNAL_ERROR
;
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();
406 op_ret
= -ERR_NO_SUCH_ENTITY
;
410 op_ret
= -ERR_NO_SUCH_ENTITY
;