]>
git.proxmox.com Git - ceph.git/blob - 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
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 using rgw::IAM::Policy
;
26 void RGWRestUserPolicy::dump(Formatter
*f
) const
28 encode_json("PolicyName", policy_name
, f
);
29 encode_json("UserName", user_name
, f
);
30 encode_json("PolicyDocument", policy
, f
);
33 void RGWRestUserPolicy::send_response()
36 set_req_state_err(s
, op_ret
);
42 int RGWRestUserPolicy::verify_permission(optional_yield y
)
44 if (s
->auth
.identity
->is_anonymous()) {
48 if(int ret
= check_caps(s
->user
->get_caps()); ret
== 0) {
52 uint64_t op
= get_op();
53 string user_name
= s
->info
.args
.get("UserName");
54 rgw_user
user_id(user_name
);
55 if (! verify_user_permission(this, s
, rgw::ARN(rgw::ARN(user_id
.id
,
57 user_id
.tenant
)), op
)) {
63 bool RGWRestUserPolicy::validate_input()
65 if (policy_name
.length() > MAX_POLICY_NAME_LEN
) {
66 ldpp_dout(this, 0) << "ERROR: Invalid policy name length " << dendl
;
70 std::regex
regex_policy_name("[A-Za-z0-9:=,.@-]+");
71 if (! std::regex_match(policy_name
, regex_policy_name
)) {
72 ldpp_dout(this, 0) << "ERROR: Invalid chars in policy name " << dendl
;
79 int RGWUserPolicyRead::check_caps(const RGWUserCaps
& caps
)
81 return caps
.check_cap("user-policy", RGW_CAP_READ
);
84 int RGWUserPolicyWrite::check_caps(const RGWUserCaps
& caps
)
86 return caps
.check_cap("user-policy", RGW_CAP_WRITE
);
89 uint64_t RGWPutUserPolicy::get_op()
91 return rgw::IAM::iamPutUserPolicy
;
94 int RGWPutUserPolicy::get_params()
96 policy_name
= url_decode(s
->info
.args
.get("PolicyName"), true);
97 user_name
= url_decode(s
->info
.args
.get("UserName"), true);
98 policy
= url_decode(s
->info
.args
.get("PolicyDocument"), true);
100 if (policy_name
.empty() || user_name
.empty() || policy
.empty()) {
101 ldpp_dout(this, 20) << "ERROR: one of policy name, user name or policy document is empty"
106 if (! validate_input()) {
113 void RGWPutUserPolicy::execute(optional_yield y
)
115 op_ret
= get_params();
120 bufferlist bl
= bufferlist::static_from_string(policy
);
122 std::unique_ptr
<rgw::sal::User
> user
= store
->get_user(rgw_user(user_name
));
124 op_ret
= user
->load_user(s
, s
->yield
);
126 op_ret
= -ERR_NO_SUCH_ENTITY
;
130 op_ret
= user
->read_attrs(s
, s
->yield
);
131 if (op_ret
== -ENOENT
) {
132 op_ret
= -ERR_NO_SUCH_ENTITY
;
136 ceph::bufferlist in_data
;
137 op_ret
= store
->forward_request_to_master(this, s
->user
.get(), nullptr, in_data
, nullptr, s
->info
, y
);
139 ldpp_dout(this, 0) << "ERROR: forward_request_to_master returned ret=" << op_ret
<< dendl
;
144 const Policy
p(s
->cct
, s
->user
->get_tenant(), bl
);
145 map
<string
, 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 encode(policies
, in_bl
);
153 user
->get_attrs()[RGW_ATTR_USER_POLICY
] = in_bl
;
155 op_ret
= user
->store_user(s
, s
->yield
, false);
157 op_ret
= -ERR_INTERNAL_ERROR
;
159 } catch (rgw::IAM::PolicyParseException
& e
) {
160 ldpp_dout(this, 20) << "failed to parse policy: " << e
.what() << dendl
;
161 op_ret
= -ERR_MALFORMED_DOC
;
165 s
->formatter
->open_object_section("PutUserPolicyResponse");
166 s
->formatter
->open_object_section("ResponseMetadata");
167 s
->formatter
->dump_string("RequestId", s
->trans_id
);
168 s
->formatter
->close_section();
169 s
->formatter
->close_section();
173 uint64_t RGWGetUserPolicy::get_op()
175 return rgw::IAM::iamGetUserPolicy
;
178 int RGWGetUserPolicy::get_params()
180 policy_name
= s
->info
.args
.get("PolicyName");
181 user_name
= s
->info
.args
.get("UserName");
183 if (policy_name
.empty() || user_name
.empty()) {
184 ldpp_dout(this, 20) << "ERROR: one of policy name or user name is empty"
192 void RGWGetUserPolicy::execute(optional_yield y
)
194 op_ret
= get_params();
199 std::unique_ptr
<rgw::sal::User
> user
= store
->get_user(rgw_user(user_name
));
200 op_ret
= user
->read_attrs(s
, s
->yield
);
201 if (op_ret
== -ENOENT
) {
202 ldpp_dout(this, 0) << "ERROR: attrs not found for user" << user_name
<< dendl
;
203 op_ret
= -ERR_NO_SUCH_ENTITY
;
208 s
->formatter
->open_object_section("GetUserPolicyResponse");
209 s
->formatter
->open_object_section("ResponseMetadata");
210 s
->formatter
->dump_string("RequestId", s
->trans_id
);
211 s
->formatter
->close_section();
212 s
->formatter
->open_object_section("GetUserPolicyResult");
213 map
<string
, string
> policies
;
214 if (auto it
= user
->get_attrs().find(RGW_ATTR_USER_POLICY
); it
!= user
->get_attrs().end()) {
215 bufferlist bl
= it
->second
;
216 decode(policies
, bl
);
217 if (auto it
= policies
.find(policy_name
); it
!= policies
.end()) {
218 policy
= policies
[policy_name
];
221 ldpp_dout(this, 0) << "ERROR: policy not found" << policy
<< dendl
;
222 op_ret
= -ERR_NO_SUCH_ENTITY
;
226 ldpp_dout(this, 0) << "ERROR: RGW_ATTR_USER_POLICY not found" << dendl
;
227 op_ret
= -ERR_NO_SUCH_ENTITY
;
230 s
->formatter
->close_section();
231 s
->formatter
->close_section();
234 op_ret
= -ERR_INTERNAL_ERROR
;
238 uint64_t RGWListUserPolicies::get_op()
240 return rgw::IAM::iamListUserPolicies
;
243 int RGWListUserPolicies::get_params()
245 user_name
= s
->info
.args
.get("UserName");
247 if (user_name
.empty()) {
248 ldpp_dout(this, 20) << "ERROR: user name is empty" << dendl
;
255 void RGWListUserPolicies::execute(optional_yield y
)
257 op_ret
= get_params();
262 std::unique_ptr
<rgw::sal::User
> user
= store
->get_user(rgw_user(user_name
));
263 op_ret
= user
->read_attrs(s
, s
->yield
);
264 if (op_ret
== -ENOENT
) {
265 ldpp_dout(this, 0) << "ERROR: attrs not found for user" << user_name
<< dendl
;
266 op_ret
= -ERR_NO_SUCH_ENTITY
;
271 map
<string
, string
> policies
;
272 if (auto it
= user
->get_attrs().find(RGW_ATTR_USER_POLICY
); it
!= user
->get_attrs().end()) {
273 s
->formatter
->open_object_section("ListUserPoliciesResponse");
274 s
->formatter
->open_object_section("ResponseMetadata");
275 s
->formatter
->dump_string("RequestId", s
->trans_id
);
276 s
->formatter
->close_section();
277 s
->formatter
->open_object_section("ListUserPoliciesResult");
278 bufferlist bl
= it
->second
;
280 decode(policies
, bl
);
281 } catch (buffer::error
& err
) {
282 ldpp_dout(this, 0) << "ERROR: failed to decode user policies" << dendl
;
286 s
->formatter
->open_object_section("PolicyNames");
287 for (const auto& p
: policies
) {
288 s
->formatter
->dump_string("member", p
.first
);
290 s
->formatter
->close_section();
291 s
->formatter
->close_section();
292 s
->formatter
->close_section();
294 ldpp_dout(this, 0) << "ERROR: RGW_ATTR_USER_POLICY not found" << dendl
;
295 op_ret
= -ERR_NO_SUCH_ENTITY
;
300 op_ret
= -ERR_INTERNAL_ERROR
;
304 uint64_t RGWDeleteUserPolicy::get_op()
306 return rgw::IAM::iamDeleteUserPolicy
;
309 int RGWDeleteUserPolicy::get_params()
311 policy_name
= s
->info
.args
.get("PolicyName");
312 user_name
= s
->info
.args
.get("UserName");
314 if (policy_name
.empty() || user_name
.empty()) {
315 ldpp_dout(this, 20) << "ERROR: One of policy name or user name is empty"<< dendl
;
322 void RGWDeleteUserPolicy::execute(optional_yield y
)
324 op_ret
= get_params();
329 std::unique_ptr
<rgw::sal::User
> user
= store
->get_user(rgw_user(user_name
));
330 op_ret
= user
->load_user(s
, s
->yield
);
332 op_ret
= -ERR_NO_SUCH_ENTITY
;
336 op_ret
= user
->read_attrs(this, s
->yield
);
337 if (op_ret
== -ENOENT
) {
338 op_ret
= -ERR_NO_SUCH_ENTITY
;
342 ceph::bufferlist in_data
;
343 op_ret
= store
->forward_request_to_master(this, s
->user
.get(), nullptr, in_data
, nullptr, s
->info
, y
);
345 // a policy might've been uploaded to this site when there was no sync
346 // req. in earlier releases, proceed deletion
347 if (op_ret
!= -ENOENT
) {
348 ldpp_dout(this, 5) << "forward_request_to_master returned ret=" << op_ret
<< dendl
;
351 ldpp_dout(this, 0) << "ERROR: forward_request_to_master returned ret=" << op_ret
<< dendl
;
354 map
<string
, string
> policies
;
355 if (auto it
= user
->get_attrs().find(RGW_ATTR_USER_POLICY
); it
!= user
->get_attrs().end()) {
356 bufferlist out_bl
= it
->second
;
357 decode(policies
, out_bl
);
359 if (auto p
= policies
.find(policy_name
); p
!= policies
.end()) {
362 encode(policies
, in_bl
);
363 user
->get_attrs()[RGW_ATTR_USER_POLICY
] = in_bl
;
365 op_ret
= user
->store_user(s
, s
->yield
, false);
367 op_ret
= -ERR_INTERNAL_ERROR
;
370 s
->formatter
->open_object_section("DeleteUserPoliciesResponse");
371 s
->formatter
->open_object_section("ResponseMetadata");
372 s
->formatter
->dump_string("RequestId", s
->trans_id
);
373 s
->formatter
->close_section();
374 s
->formatter
->close_section();
377 op_ret
= -ERR_NO_SUCH_ENTITY
;
381 op_ret
= -ERR_NO_SUCH_ENTITY
;