]> git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_rest_user_policy.cc
import ceph 14.2.5
[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
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
19 #define dout_subsys ceph_subsys_rgw
20
21 using rgw::IAM::Policy;
22
23 void RGWRestUserPolicy::dump(Formatter *f) const
24 {
25 encode_json("policyname", policy_name , f);
26 encode_json("username", user_name , f);
27 encode_json("policydocument", policy, f);
28 }
29
30 void RGWRestUserPolicy::send_response()
31 {
32 if (op_ret) {
33 set_req_state_err(s, op_ret);
34 }
35 dump_errno(s);
36 end_header(s);
37 }
38
39 int RGWRestUserPolicy::verify_permission()
40 {
41 if (s->auth.identity->is_anonymous()) {
42 return -EACCES;
43 }
44
45 if(int ret = check_caps(s->user->caps); ret == 0) {
46 return ret;
47 }
48
49 uint64_t op = get_op();
50 string user_name = s->info.args.get("UserName");
51 rgw_user user_id(user_name);
52 if (! verify_user_permission(this, s, rgw::ARN(rgw::ARN(user_id.id,
53 "user",
54 user_id.tenant)), op)) {
55 return -EACCES;
56 }
57 return 0;
58 }
59
60 bool RGWRestUserPolicy::validate_input()
61 {
62 if (policy_name.length() > MAX_POLICY_NAME_LEN) {
63 ldout(s->cct, 0) << "ERROR: Invalid policy name length " << dendl;
64 return false;
65 }
66
67 std::regex regex_policy_name("[A-Za-z0-9:=,.@-]+");
68 if (! std::regex_match(policy_name, regex_policy_name)) {
69 ldout(s->cct, 0) << "ERROR: Invalid chars in policy name " << dendl;
70 return false;
71 }
72
73 return true;
74 }
75
76 int RGWUserPolicyRead::check_caps(RGWUserCaps& caps)
77 {
78 return caps.check_cap("user-policy", RGW_CAP_READ);
79 }
80
81 int RGWUserPolicyWrite::check_caps(RGWUserCaps& caps)
82 {
83 return caps.check_cap("user-policy", RGW_CAP_WRITE);
84 }
85
86 uint64_t RGWPutUserPolicy::get_op()
87 {
88 return rgw::IAM::iamPutUserPolicy;
89 }
90
91 int RGWPutUserPolicy::get_params()
92 {
93 policy_name = url_decode(s->info.args.get("PolicyName"), true);
94 user_name = url_decode(s->info.args.get("UserName"), true);
95 policy = url_decode(s->info.args.get("PolicyDocument"), true);
96
97 if (policy_name.empty() || user_name.empty() || policy.empty()) {
98 ldout(s->cct, 20) << "ERROR: one of policy name, user name or policy document is empty"
99 << dendl;
100 return -EINVAL;
101 }
102
103 if (! validate_input()) {
104 return -EINVAL;
105 }
106
107 return 0;
108 }
109
110 void RGWPutUserPolicy::execute()
111 {
112 op_ret = get_params();
113 if (op_ret < 0) {
114 return;
115 }
116
117 bufferlist bl = bufferlist::static_from_string(policy);
118
119 RGWUserInfo info;
120 rgw_user user_id(user_name);
121 op_ret = rgw_get_user_info_by_uid(store, user_id, info);
122 if (op_ret < 0) {
123 op_ret = -ERR_NO_SUCH_ENTITY;
124 return;
125 }
126
127 map<string, bufferlist> uattrs;
128 op_ret = rgw_get_user_attrs_by_uid(store, user_id, uattrs);
129 if (op_ret == -ENOENT) {
130 op_ret = -ERR_NO_SUCH_ENTITY;
131 return;
132 }
133
134 try {
135 const Policy p(s->cct, s->user->user_id.tenant, bl);
136 map<string, string> policies;
137 if (auto it = uattrs.find(RGW_ATTR_USER_POLICY); it != uattrs.end()) {
138 bufferlist out_bl = uattrs[RGW_ATTR_USER_POLICY];
139 decode(policies, out_bl);
140 }
141 bufferlist in_bl;
142 policies[policy_name] = policy;
143 encode(policies, in_bl);
144 uattrs[RGW_ATTR_USER_POLICY] = in_bl;
145
146 RGWObjVersionTracker objv_tracker;
147 op_ret = rgw_store_user_info(store, info, &info, &objv_tracker, real_time(), false, &uattrs);
148 if (op_ret < 0) {
149 op_ret = -ERR_INTERNAL_ERROR;
150 }
151 } catch (rgw::IAM::PolicyParseException& e) {
152 ldout(s->cct, 20) << "failed to parse policy: " << e.what() << dendl;
153 op_ret = -ERR_MALFORMED_DOC;
154 }
155 }
156
157 uint64_t RGWGetUserPolicy::get_op()
158 {
159 return rgw::IAM::iamGetUserPolicy;
160 }
161
162 int RGWGetUserPolicy::get_params()
163 {
164 policy_name = s->info.args.get("PolicyName");
165 user_name = s->info.args.get("UserName");
166
167 if (policy_name.empty() || user_name.empty()) {
168 ldout(s->cct, 20) << "ERROR: one of policy name or user name is empty"
169 << dendl;
170 return -EINVAL;
171 }
172
173 return 0;
174 }
175
176 void RGWGetUserPolicy::execute()
177 {
178 op_ret = get_params();
179 if (op_ret < 0) {
180 return;
181 }
182
183 rgw_user user_id(user_name);
184 map<string, bufferlist> uattrs;
185 op_ret = rgw_get_user_attrs_by_uid(store, user_id, uattrs);
186 if (op_ret == -ENOENT) {
187 ldout(s->cct, 0) << "ERROR: attrs not found for user" << user_name << dendl;
188 op_ret = -ERR_NO_SUCH_ENTITY;
189 return;
190 }
191
192 if (op_ret == 0) {
193 map<string, string> policies;
194 if (auto it = uattrs.find(RGW_ATTR_USER_POLICY); it != uattrs.end()) {
195 bufferlist bl = uattrs[RGW_ATTR_USER_POLICY];
196 decode(policies, bl);
197 if (auto it = policies.find(policy_name); it != policies.end()) {
198 policy = policies[policy_name];
199 s->formatter->open_object_section("userpolicy");
200 dump(s->formatter);
201 s->formatter->close_section();
202 } else {
203 ldout(s->cct, 0) << "ERROR: policy not found" << policy << dendl;
204 op_ret = -ERR_NO_SUCH_ENTITY;
205 return;
206 }
207 } else {
208 ldout(s->cct, 0) << "ERROR: RGW_ATTR_USER_POLICY not found" << dendl;
209 op_ret = -ERR_NO_SUCH_ENTITY;
210 return;
211 }
212 }
213 if (op_ret < 0) {
214 op_ret = -ERR_INTERNAL_ERROR;
215 }
216 }
217
218 uint64_t RGWListUserPolicies::get_op()
219 {
220 return rgw::IAM::iamListUserPolicies;
221 }
222
223 int RGWListUserPolicies::get_params()
224 {
225 user_name = s->info.args.get("UserName");
226
227 if (user_name.empty()) {
228 ldout(s->cct, 20) << "ERROR: user name is empty" << dendl;
229 return -EINVAL;
230 }
231
232 return 0;
233 }
234
235 void RGWListUserPolicies::execute()
236 {
237 op_ret = get_params();
238 if (op_ret < 0) {
239 return;
240 }
241
242 rgw_user user_id(user_name);
243 map<string, bufferlist> uattrs;
244 op_ret = rgw_get_user_attrs_by_uid(store, user_id, uattrs);
245 if (op_ret == -ENOENT) {
246 ldout(s->cct, 0) << "ERROR: attrs not found for user" << user_name << dendl;
247 op_ret = -ERR_NO_SUCH_ENTITY;
248 return;
249 }
250
251 if (op_ret == 0) {
252 map<string, string> policies;
253 if (auto it = uattrs.find(RGW_ATTR_USER_POLICY); it != uattrs.end()) {
254 bufferlist bl = uattrs[RGW_ATTR_USER_POLICY];
255 decode(policies, bl);
256 for (const auto& p : policies) {
257 s->formatter->open_object_section("policies");
258 s->formatter->dump_string("policy", p.first);
259 s->formatter->close_section();
260 }
261 } else {
262 ldout(s->cct, 0) << "ERROR: RGW_ATTR_USER_POLICY not found" << dendl;
263 op_ret = -ERR_NO_SUCH_ENTITY;
264 return;
265 }
266 }
267 if (op_ret < 0) {
268 op_ret = -ERR_INTERNAL_ERROR;
269 }
270 }
271
272 uint64_t RGWDeleteUserPolicy::get_op()
273 {
274 return rgw::IAM::iamDeleteUserPolicy;
275 }
276
277 int RGWDeleteUserPolicy::get_params()
278 {
279 policy_name = s->info.args.get("PolicyName");
280 user_name = s->info.args.get("UserName");
281
282 if (policy_name.empty() || user_name.empty()) {
283 ldout(s->cct, 20) << "ERROR: One of policy name or user name is empty"<< dendl;
284 return -EINVAL;
285 }
286
287 return 0;
288 }
289
290 void RGWDeleteUserPolicy::execute()
291 {
292 op_ret = get_params();
293 if (op_ret < 0) {
294 return;
295 }
296
297 RGWUserInfo info;
298 rgw_user user_id(user_name);
299 op_ret = rgw_get_user_info_by_uid(store, user_id, info);
300 if (op_ret < 0) {
301 op_ret = -ERR_NO_SUCH_ENTITY;
302 return;
303 }
304
305 map<string, bufferlist> uattrs;
306 op_ret = rgw_get_user_attrs_by_uid(store, user_id, uattrs);
307 if (op_ret == -ENOENT) {
308 op_ret = -ERR_NO_SUCH_ENTITY;
309 return;
310 }
311
312 map<string, string> policies;
313 if (auto it = uattrs.find(RGW_ATTR_USER_POLICY); it != uattrs.end()) {
314 bufferlist out_bl = uattrs[RGW_ATTR_USER_POLICY];
315 decode(policies, out_bl);
316
317 if (auto p = policies.find(policy_name); p != policies.end()) {
318 bufferlist in_bl;
319 policies.erase(p);
320 encode(policies, in_bl);
321 uattrs[RGW_ATTR_USER_POLICY] = in_bl;
322
323 RGWObjVersionTracker objv_tracker;
324 op_ret = rgw_store_user_info(store, info, &info, &objv_tracker, real_time(), false, &uattrs);
325 if (op_ret < 0) {
326 op_ret = -ERR_INTERNAL_ERROR;
327 }
328 } else {
329 op_ret = -ERR_NO_SUCH_ENTITY;
330 return;
331 }
332 } else {
333 op_ret = -ERR_NO_SUCH_ENTITY;
334 return;
335 }
336 }