]>
Commit | Line | Data |
---|---|---|
7c673cae | 1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
9f95a23c | 2 | // vim: ts=8 sw=2 smarttab ft=cpp |
7c673cae FG |
3 | |
4 | #include <string.h> | |
5 | ||
6 | #include <iostream> | |
7 | #include <map> | |
8 | ||
9 | #include "include/types.h" | |
10 | ||
11 | #include "rgw_acl_s3.h" | |
12 | #include "rgw_user.h" | |
13 | ||
14 | #define dout_subsys ceph_subsys_rgw | |
15 | ||
7c673cae FG |
16 | |
17 | ||
18 | #define RGW_URI_ALL_USERS "http://acs.amazonaws.com/groups/global/AllUsers" | |
19 | #define RGW_URI_AUTH_USERS "http://acs.amazonaws.com/groups/global/AuthenticatedUsers" | |
20 | ||
21 | static string rgw_uri_all_users = RGW_URI_ALL_USERS; | |
22 | static string rgw_uri_auth_users = RGW_URI_AUTH_USERS; | |
23 | ||
24 | void ACLPermission_S3::to_xml(ostream& out) | |
25 | { | |
26 | if ((flags & RGW_PERM_FULL_CONTROL) == RGW_PERM_FULL_CONTROL) { | |
27 | out << "<Permission>FULL_CONTROL</Permission>"; | |
28 | } else { | |
29 | if (flags & RGW_PERM_READ) | |
30 | out << "<Permission>READ</Permission>"; | |
31 | if (flags & RGW_PERM_WRITE) | |
32 | out << "<Permission>WRITE</Permission>"; | |
33 | if (flags & RGW_PERM_READ_ACP) | |
34 | out << "<Permission>READ_ACP</Permission>"; | |
35 | if (flags & RGW_PERM_WRITE_ACP) | |
36 | out << "<Permission>WRITE_ACP</Permission>"; | |
37 | } | |
38 | } | |
39 | ||
40 | bool ACLPermission_S3:: | |
41 | xml_end(const char *el) | |
42 | { | |
43 | const char *s = data.c_str(); | |
44 | if (strcasecmp(s, "READ") == 0) { | |
45 | flags |= RGW_PERM_READ; | |
46 | return true; | |
47 | } else if (strcasecmp(s, "WRITE") == 0) { | |
48 | flags |= RGW_PERM_WRITE; | |
49 | return true; | |
50 | } else if (strcasecmp(s, "READ_ACP") == 0) { | |
51 | flags |= RGW_PERM_READ_ACP; | |
52 | return true; | |
53 | } else if (strcasecmp(s, "WRITE_ACP") == 0) { | |
54 | flags |= RGW_PERM_WRITE_ACP; | |
55 | return true; | |
56 | } else if (strcasecmp(s, "FULL_CONTROL") == 0) { | |
57 | flags |= RGW_PERM_FULL_CONTROL; | |
58 | return true; | |
59 | } | |
60 | return false; | |
61 | } | |
62 | ||
63 | ||
64 | class ACLGranteeType_S3 { | |
65 | public: | |
66 | static const char *to_string(ACLGranteeType& type) { | |
67 | switch (type.get_type()) { | |
68 | case ACL_TYPE_CANON_USER: | |
69 | return "CanonicalUser"; | |
70 | case ACL_TYPE_EMAIL_USER: | |
71 | return "AmazonCustomerByEmail"; | |
72 | case ACL_TYPE_GROUP: | |
73 | return "Group"; | |
74 | default: | |
75 | return "unknown"; | |
76 | } | |
77 | } | |
78 | ||
79 | static void set(const char *s, ACLGranteeType& type) { | |
80 | if (!s) { | |
81 | type.set(ACL_TYPE_UNKNOWN); | |
82 | return; | |
83 | } | |
84 | if (strcmp(s, "CanonicalUser") == 0) | |
85 | type.set(ACL_TYPE_CANON_USER); | |
86 | else if (strcmp(s, "AmazonCustomerByEmail") == 0) | |
87 | type.set(ACL_TYPE_EMAIL_USER); | |
88 | else if (strcmp(s, "Group") == 0) | |
89 | type.set(ACL_TYPE_GROUP); | |
90 | else | |
91 | type.set(ACL_TYPE_UNKNOWN); | |
92 | } | |
93 | }; | |
94 | ||
95 | class ACLID_S3 : public XMLObj | |
96 | { | |
97 | public: | |
98 | ACLID_S3() {} | |
99 | ~ACLID_S3() override {} | |
100 | string& to_str() { return data; } | |
101 | }; | |
102 | ||
103 | class ACLURI_S3 : public XMLObj | |
104 | { | |
105 | public: | |
106 | ACLURI_S3() {} | |
107 | ~ACLURI_S3() override {} | |
108 | }; | |
109 | ||
110 | class ACLEmail_S3 : public XMLObj | |
111 | { | |
112 | public: | |
113 | ACLEmail_S3() {} | |
114 | ~ACLEmail_S3() override {} | |
115 | }; | |
116 | ||
117 | class ACLDisplayName_S3 : public XMLObj | |
118 | { | |
119 | public: | |
120 | ACLDisplayName_S3() {} | |
121 | ~ACLDisplayName_S3() override {} | |
122 | }; | |
123 | ||
124 | bool ACLOwner_S3::xml_end(const char *el) { | |
125 | ACLID_S3 *acl_id = static_cast<ACLID_S3 *>(find_first("ID")); | |
126 | ACLID_S3 *acl_name = static_cast<ACLID_S3 *>(find_first("DisplayName")); | |
127 | ||
128 | // ID is mandatory | |
129 | if (!acl_id) | |
130 | return false; | |
131 | id = acl_id->get_data(); | |
132 | ||
133 | // DisplayName is optional | |
134 | if (acl_name) | |
135 | display_name = acl_name->get_data(); | |
136 | else | |
137 | display_name = ""; | |
138 | ||
139 | return true; | |
140 | } | |
141 | ||
142 | void ACLOwner_S3::to_xml(ostream& out) { | |
143 | string s; | |
144 | id.to_str(s); | |
145 | if (s.empty()) | |
146 | return; | |
147 | out << "<Owner>" << "<ID>" << s << "</ID>"; | |
148 | if (!display_name.empty()) | |
149 | out << "<DisplayName>" << display_name << "</DisplayName>"; | |
150 | out << "</Owner>"; | |
151 | } | |
152 | ||
153 | bool ACLGrant_S3::xml_end(const char *el) { | |
154 | ACLGrantee_S3 *acl_grantee; | |
155 | ACLID_S3 *acl_id; | |
156 | ACLURI_S3 *acl_uri; | |
157 | ACLEmail_S3 *acl_email; | |
158 | ACLPermission_S3 *acl_permission; | |
159 | ACLDisplayName_S3 *acl_name; | |
160 | string uri; | |
161 | ||
162 | acl_grantee = static_cast<ACLGrantee_S3 *>(find_first("Grantee")); | |
163 | if (!acl_grantee) | |
164 | return false; | |
165 | string type_str; | |
166 | if (!acl_grantee->get_attr("xsi:type", type_str)) | |
167 | return false; | |
168 | ACLGranteeType_S3::set(type_str.c_str(), type); | |
169 | ||
170 | acl_permission = static_cast<ACLPermission_S3 *>(find_first("Permission")); | |
171 | if (!acl_permission) | |
172 | return false; | |
173 | ||
174 | permission = *acl_permission; | |
175 | ||
176 | id.clear(); | |
177 | name.clear(); | |
178 | email.clear(); | |
179 | ||
180 | switch (type.get_type()) { | |
181 | case ACL_TYPE_CANON_USER: | |
182 | acl_id = static_cast<ACLID_S3 *>(acl_grantee->find_first("ID")); | |
183 | if (!acl_id) | |
184 | return false; | |
185 | id = acl_id->to_str(); | |
186 | acl_name = static_cast<ACLDisplayName_S3 *>(acl_grantee->find_first("DisplayName")); | |
187 | if (acl_name) | |
188 | name = acl_name->get_data(); | |
189 | break; | |
190 | case ACL_TYPE_GROUP: | |
191 | acl_uri = static_cast<ACLURI_S3 *>(acl_grantee->find_first("URI")); | |
192 | if (!acl_uri) | |
193 | return false; | |
194 | uri = acl_uri->get_data(); | |
195 | group = uri_to_group(uri); | |
196 | break; | |
197 | case ACL_TYPE_EMAIL_USER: | |
198 | acl_email = static_cast<ACLEmail_S3 *>(acl_grantee->find_first("EmailAddress")); | |
199 | if (!acl_email) | |
200 | return false; | |
201 | email = acl_email->get_data(); | |
202 | break; | |
203 | default: | |
204 | // unknown user type | |
205 | return false; | |
206 | }; | |
207 | return true; | |
208 | } | |
209 | ||
210 | void ACLGrant_S3::to_xml(CephContext *cct, ostream& out) { | |
211 | ACLPermission_S3& perm = static_cast<ACLPermission_S3 &>(permission); | |
212 | ||
213 | /* only show s3 compatible permissions */ | |
214 | if (!(perm.get_permissions() & RGW_PERM_ALL_S3)) | |
215 | return; | |
216 | ||
217 | string uri; | |
218 | ||
219 | out << "<Grant>" << | |
220 | "<Grantee xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"" << ACLGranteeType_S3::to_string(type) << "\">"; | |
221 | switch (type.get_type()) { | |
222 | case ACL_TYPE_CANON_USER: | |
223 | out << "<ID>" << id << "</ID>"; | |
224 | if (name.size()) { | |
225 | out << "<DisplayName>" << name << "</DisplayName>"; | |
226 | } | |
227 | break; | |
228 | case ACL_TYPE_EMAIL_USER: | |
229 | out << "<EmailAddress>" << email << "</EmailAddress>"; | |
230 | break; | |
231 | case ACL_TYPE_GROUP: | |
232 | if (!group_to_uri(group, uri)) { | |
233 | ldout(cct, 0) << "ERROR: group_to_uri failed with group=" << (int)group << dendl; | |
234 | break; | |
235 | } | |
236 | out << "<URI>" << uri << "</URI>"; | |
237 | break; | |
238 | default: | |
239 | break; | |
240 | } | |
241 | out << "</Grantee>"; | |
242 | perm.to_xml(out); | |
243 | out << "</Grant>"; | |
244 | } | |
245 | ||
246 | bool ACLGrant_S3::group_to_uri(ACLGroupTypeEnum group, string& uri) | |
247 | { | |
248 | switch (group) { | |
249 | case ACL_GROUP_ALL_USERS: | |
250 | uri = rgw_uri_all_users; | |
251 | return true; | |
252 | case ACL_GROUP_AUTHENTICATED_USERS: | |
253 | uri = rgw_uri_auth_users; | |
254 | return true; | |
255 | default: | |
256 | return false; | |
257 | } | |
258 | } | |
259 | ||
260 | bool RGWAccessControlList_S3::xml_end(const char *el) { | |
261 | XMLObjIter iter = find("Grant"); | |
262 | ACLGrant_S3 *grant = static_cast<ACLGrant_S3 *>(iter.get_next()); | |
263 | while (grant) { | |
264 | add_grant(grant); | |
265 | grant = static_cast<ACLGrant_S3 *>(iter.get_next()); | |
266 | } | |
267 | return true; | |
268 | } | |
269 | ||
270 | void RGWAccessControlList_S3::to_xml(ostream& out) { | |
271 | multimap<string, ACLGrant>::iterator iter; | |
272 | out << "<AccessControlList>"; | |
273 | for (iter = grant_map.begin(); iter != grant_map.end(); ++iter) { | |
274 | ACLGrant_S3& grant = static_cast<ACLGrant_S3 &>(iter->second); | |
275 | grant.to_xml(cct, out); | |
276 | } | |
277 | out << "</AccessControlList>"; | |
278 | } | |
279 | ||
280 | struct s3_acl_header { | |
281 | int rgw_perm; | |
282 | const char *http_header; | |
283 | }; | |
284 | ||
31f18b77 | 285 | static const char *get_acl_header(const RGWEnv *env, |
7c673cae FG |
286 | const struct s3_acl_header *perm) |
287 | { | |
288 | const char *header = perm->http_header; | |
289 | ||
290 | return env->get(header, NULL); | |
291 | } | |
292 | ||
9f95a23c | 293 | static int parse_grantee_str(RGWUserCtl *user_ctl, string& grantee_str, |
7c673cae FG |
294 | const struct s3_acl_header *perm, ACLGrant& grant) |
295 | { | |
296 | string id_type, id_val_quoted; | |
297 | int rgw_perm = perm->rgw_perm; | |
298 | int ret; | |
299 | ||
300 | RGWUserInfo info; | |
301 | ||
302 | ret = parse_key_value(grantee_str, id_type, id_val_quoted); | |
303 | if (ret < 0) | |
304 | return ret; | |
305 | ||
306 | string id_val = rgw_trim_quotes(id_val_quoted); | |
307 | ||
308 | if (strcasecmp(id_type.c_str(), "emailAddress") == 0) { | |
9f95a23c | 309 | ret = user_ctl->get_info_by_email(id_val, &info, null_yield); |
7c673cae FG |
310 | if (ret < 0) |
311 | return ret; | |
312 | ||
313 | grant.set_canon(info.user_id, info.display_name, rgw_perm); | |
314 | } else if (strcasecmp(id_type.c_str(), "id") == 0) { | |
315 | rgw_user user(id_val); | |
9f95a23c | 316 | ret = user_ctl->get_info_by_uid(user, &info, null_yield); |
7c673cae FG |
317 | if (ret < 0) |
318 | return ret; | |
319 | ||
320 | grant.set_canon(info.user_id, info.display_name, rgw_perm); | |
321 | } else if (strcasecmp(id_type.c_str(), "uri") == 0) { | |
322 | ACLGroupTypeEnum gid = grant.uri_to_group(id_val); | |
323 | if (gid == ACL_GROUP_NONE) | |
324 | return -EINVAL; | |
325 | ||
326 | grant.set_group(gid, rgw_perm); | |
327 | } else { | |
328 | return -EINVAL; | |
329 | } | |
330 | ||
331 | return 0; | |
332 | } | |
333 | ||
9f95a23c | 334 | static int parse_acl_header(RGWUserCtl *user_ctl, const RGWEnv *env, |
7c673cae FG |
335 | const struct s3_acl_header *perm, std::list<ACLGrant>& _grants) |
336 | { | |
337 | std::list<string> grantees; | |
338 | std::string hacl_str; | |
339 | ||
340 | const char *hacl = get_acl_header(env, perm); | |
341 | if (hacl == NULL) | |
342 | return 0; | |
343 | ||
344 | hacl_str = hacl; | |
345 | get_str_list(hacl_str, ",", grantees); | |
346 | ||
347 | for (list<string>::iterator it = grantees.begin(); it != grantees.end(); ++it) { | |
348 | ACLGrant grant; | |
9f95a23c | 349 | int ret = parse_grantee_str(user_ctl, *it, perm, grant); |
7c673cae FG |
350 | if (ret < 0) |
351 | return ret; | |
352 | ||
353 | _grants.push_back(grant); | |
354 | } | |
355 | ||
356 | return 0; | |
357 | } | |
358 | ||
359 | int RGWAccessControlList_S3::create_canned(ACLOwner& owner, ACLOwner& bucket_owner, const string& canned_acl) | |
360 | { | |
361 | acl_user_map.clear(); | |
362 | grant_map.clear(); | |
363 | ||
364 | ACLGrant owner_grant; | |
365 | ||
366 | rgw_user bid = bucket_owner.get_id(); | |
367 | string bname = bucket_owner.get_display_name(); | |
368 | ||
369 | /* owner gets full control */ | |
370 | owner_grant.set_canon(owner.get_id(), owner.get_display_name(), RGW_PERM_FULL_CONTROL); | |
371 | add_grant(&owner_grant); | |
372 | ||
373 | if (canned_acl.size() == 0 || canned_acl.compare("private") == 0) { | |
374 | return 0; | |
375 | } | |
376 | ||
377 | ACLGrant bucket_owner_grant; | |
378 | ACLGrant group_grant; | |
379 | if (canned_acl.compare("public-read") == 0) { | |
380 | group_grant.set_group(ACL_GROUP_ALL_USERS, RGW_PERM_READ); | |
381 | add_grant(&group_grant); | |
382 | } else if (canned_acl.compare("public-read-write") == 0) { | |
383 | group_grant.set_group(ACL_GROUP_ALL_USERS, RGW_PERM_READ); | |
384 | add_grant(&group_grant); | |
385 | group_grant.set_group(ACL_GROUP_ALL_USERS, RGW_PERM_WRITE); | |
386 | add_grant(&group_grant); | |
387 | } else if (canned_acl.compare("authenticated-read") == 0) { | |
388 | group_grant.set_group(ACL_GROUP_AUTHENTICATED_USERS, RGW_PERM_READ); | |
389 | add_grant(&group_grant); | |
390 | } else if (canned_acl.compare("bucket-owner-read") == 0) { | |
391 | bucket_owner_grant.set_canon(bid, bname, RGW_PERM_READ); | |
392 | if (bid.compare(owner.get_id()) != 0) | |
393 | add_grant(&bucket_owner_grant); | |
394 | } else if (canned_acl.compare("bucket-owner-full-control") == 0) { | |
395 | bucket_owner_grant.set_canon(bid, bname, RGW_PERM_FULL_CONTROL); | |
396 | if (bid.compare(owner.get_id()) != 0) | |
397 | add_grant(&bucket_owner_grant); | |
398 | } else { | |
399 | return -EINVAL; | |
400 | } | |
401 | ||
402 | return 0; | |
403 | } | |
404 | ||
405 | int RGWAccessControlList_S3::create_from_grants(std::list<ACLGrant>& grants) | |
406 | { | |
407 | if (grants.empty()) | |
408 | return -EINVAL; | |
409 | ||
410 | acl_user_map.clear(); | |
411 | grant_map.clear(); | |
412 | ||
413 | for (std::list<ACLGrant>::iterator it = grants.begin(); it != grants.end(); ++it) { | |
414 | ACLGrant g = *it; | |
415 | add_grant(&g); | |
416 | } | |
417 | ||
418 | return 0; | |
419 | } | |
420 | ||
421 | bool RGWAccessControlPolicy_S3::xml_end(const char *el) { | |
422 | RGWAccessControlList_S3 *s3acl = | |
423 | static_cast<RGWAccessControlList_S3 *>(find_first("AccessControlList")); | |
424 | if (!s3acl) | |
425 | return false; | |
426 | ||
427 | acl = *s3acl; | |
428 | ||
429 | ACLOwner *owner_p = static_cast<ACLOwner_S3 *>(find_first("Owner")); | |
430 | if (!owner_p) | |
431 | return false; | |
432 | owner = *owner_p; | |
433 | return true; | |
434 | } | |
435 | ||
436 | void RGWAccessControlPolicy_S3::to_xml(ostream& out) { | |
437 | out << "<AccessControlPolicy xmlns=\"" << XMLNS_AWS_S3 << "\">"; | |
438 | ACLOwner_S3& _owner = static_cast<ACLOwner_S3 &>(owner); | |
439 | RGWAccessControlList_S3& _acl = static_cast<RGWAccessControlList_S3 &>(acl); | |
440 | _owner.to_xml(out); | |
441 | _acl.to_xml(out); | |
442 | out << "</AccessControlPolicy>"; | |
443 | } | |
444 | ||
445 | static const s3_acl_header acl_header_perms[] = { | |
446 | {RGW_PERM_READ, "HTTP_X_AMZ_GRANT_READ"}, | |
447 | {RGW_PERM_WRITE, "HTTP_X_AMZ_GRANT_WRITE"}, | |
448 | {RGW_PERM_READ_ACP,"HTTP_X_AMZ_GRANT_READ_ACP"}, | |
449 | {RGW_PERM_WRITE_ACP, "HTTP_X_AMZ_GRANT_WRITE_ACP"}, | |
450 | {RGW_PERM_FULL_CONTROL, "HTTP_X_AMZ_GRANT_FULL_CONTROL"}, | |
451 | {0, NULL} | |
452 | }; | |
453 | ||
9f95a23c | 454 | int RGWAccessControlPolicy_S3::create_from_headers(RGWUserCtl *user_ctl, const RGWEnv *env, ACLOwner& _owner) |
7c673cae FG |
455 | { |
456 | std::list<ACLGrant> grants; | |
11fdf7f2 | 457 | int r = 0; |
7c673cae FG |
458 | |
459 | for (const struct s3_acl_header *p = acl_header_perms; p->rgw_perm; p++) { | |
9f95a23c | 460 | r = parse_acl_header(user_ctl, env, p, grants); |
11fdf7f2 TL |
461 | if (r < 0) { |
462 | return r; | |
463 | } | |
7c673cae FG |
464 | } |
465 | ||
466 | RGWAccessControlList_S3& _acl = static_cast<RGWAccessControlList_S3 &>(acl); | |
11fdf7f2 | 467 | r = _acl.create_from_grants(grants); |
7c673cae FG |
468 | |
469 | owner = _owner; | |
470 | ||
471 | return r; | |
472 | } | |
473 | ||
474 | /* | |
475 | can only be called on object that was parsed | |
476 | */ | |
9f95a23c TL |
477 | int RGWAccessControlPolicy_S3::rebuild(RGWUserCtl *user_ctl, ACLOwner *owner, RGWAccessControlPolicy& dest, |
478 | std::string &err_msg) | |
7c673cae FG |
479 | { |
480 | if (!owner) | |
481 | return -EINVAL; | |
482 | ||
483 | ACLOwner *requested_owner = static_cast<ACLOwner_S3 *>(find_first("Owner")); | |
484 | if (requested_owner) { | |
485 | rgw_user& requested_id = requested_owner->get_id(); | |
486 | if (!requested_id.empty() && requested_id.compare(owner->get_id()) != 0) | |
487 | return -EPERM; | |
488 | } | |
489 | ||
490 | RGWUserInfo owner_info; | |
9f95a23c | 491 | if (user_ctl->get_info_by_uid(owner->get_id(), &owner_info, null_yield) < 0) { |
7c673cae | 492 | ldout(cct, 10) << "owner info does not exist" << dendl; |
9f95a23c | 493 | err_msg = "Invalid id"; |
7c673cae FG |
494 | return -EINVAL; |
495 | } | |
496 | ACLOwner& dest_owner = dest.get_owner(); | |
497 | dest_owner.set_id(owner->get_id()); | |
498 | dest_owner.set_name(owner_info.display_name); | |
499 | ||
500 | ldout(cct, 20) << "owner id=" << owner->get_id() << dendl; | |
501 | ldout(cct, 20) << "dest owner id=" << dest.get_owner().get_id() << dendl; | |
502 | ||
503 | RGWAccessControlList& dst_acl = dest.get_acl(); | |
504 | ||
505 | multimap<string, ACLGrant>& grant_map = acl.get_grant_map(); | |
506 | multimap<string, ACLGrant>::iterator iter; | |
507 | for (iter = grant_map.begin(); iter != grant_map.end(); ++iter) { | |
508 | ACLGrant& src_grant = iter->second; | |
509 | ACLGranteeType& type = src_grant.get_type(); | |
510 | ACLGrant new_grant; | |
511 | bool grant_ok = false; | |
512 | rgw_user uid; | |
513 | RGWUserInfo grant_user; | |
514 | switch (type.get_type()) { | |
515 | case ACL_TYPE_EMAIL_USER: | |
516 | { | |
517 | string email; | |
518 | rgw_user u; | |
519 | if (!src_grant.get_id(u)) { | |
520 | ldout(cct, 0) << "ERROR: src_grant.get_id() failed" << dendl; | |
521 | return -EINVAL; | |
522 | } | |
523 | email = u.id; | |
524 | ldout(cct, 10) << "grant user email=" << email << dendl; | |
9f95a23c | 525 | if (user_ctl->get_info_by_email(email, &grant_user, null_yield) < 0) { |
7c673cae | 526 | ldout(cct, 10) << "grant user email not found or other error" << dendl; |
9f95a23c | 527 | err_msg = "The e-mail address you provided does not match any account on record."; |
7c673cae FG |
528 | return -ERR_UNRESOLVABLE_EMAIL; |
529 | } | |
530 | uid = grant_user.user_id; | |
531 | } | |
532 | case ACL_TYPE_CANON_USER: | |
533 | { | |
534 | if (type.get_type() == ACL_TYPE_CANON_USER) { | |
535 | if (!src_grant.get_id(uid)) { | |
536 | ldout(cct, 0) << "ERROR: src_grant.get_id() failed" << dendl; | |
9f95a23c | 537 | err_msg = "Invalid id"; |
7c673cae FG |
538 | return -EINVAL; |
539 | } | |
540 | } | |
541 | ||
9f95a23c | 542 | if (grant_user.user_id.empty() && user_ctl->get_info_by_uid(uid, &grant_user, null_yield) < 0) { |
7c673cae | 543 | ldout(cct, 10) << "grant user does not exist:" << uid << dendl; |
9f95a23c | 544 | err_msg = "Invalid id"; |
7c673cae FG |
545 | return -EINVAL; |
546 | } else { | |
547 | ACLPermission& perm = src_grant.get_permission(); | |
548 | new_grant.set_canon(uid, grant_user.display_name, perm.get_permissions()); | |
549 | grant_ok = true; | |
550 | rgw_user new_id; | |
551 | new_grant.get_id(new_id); | |
552 | ldout(cct, 10) << "new grant: " << new_id << ":" << grant_user.display_name << dendl; | |
553 | } | |
554 | } | |
555 | break; | |
556 | case ACL_TYPE_GROUP: | |
557 | { | |
558 | string uri; | |
559 | if (ACLGrant_S3::group_to_uri(src_grant.get_group(), uri)) { | |
560 | new_grant = src_grant; | |
561 | grant_ok = true; | |
562 | ldout(cct, 10) << "new grant: " << uri << dendl; | |
563 | } else { | |
564 | ldout(cct, 10) << "bad grant group:" << (int)src_grant.get_group() << dendl; | |
9f95a23c | 565 | err_msg = "Invalid group uri"; |
7c673cae FG |
566 | return -EINVAL; |
567 | } | |
568 | } | |
569 | default: | |
570 | break; | |
571 | } | |
572 | if (grant_ok) { | |
573 | dst_acl.add_grant(&new_grant); | |
574 | } | |
575 | } | |
576 | ||
577 | return 0; | |
578 | } | |
579 | ||
580 | bool RGWAccessControlPolicy_S3::compare_group_name(string& id, ACLGroupTypeEnum group) | |
581 | { | |
582 | switch (group) { | |
583 | case ACL_GROUP_ALL_USERS: | |
584 | return (id.compare(RGW_USER_ANON_ID) == 0); | |
585 | case ACL_GROUP_AUTHENTICATED_USERS: | |
586 | return (id.compare(rgw_uri_auth_users) == 0); | |
587 | default: | |
588 | return id.empty(); | |
589 | } | |
590 | ||
591 | // shouldn't get here | |
592 | return false; | |
593 | } | |
594 | ||
595 | XMLObj *RGWACLXMLParser_S3::alloc_obj(const char *el) | |
596 | { | |
597 | XMLObj * obj = NULL; | |
598 | if (strcmp(el, "AccessControlPolicy") == 0) { | |
599 | obj = new RGWAccessControlPolicy_S3(cct); | |
600 | } else if (strcmp(el, "Owner") == 0) { | |
601 | obj = new ACLOwner_S3(); | |
602 | } else if (strcmp(el, "AccessControlList") == 0) { | |
603 | obj = new RGWAccessControlList_S3(cct); | |
604 | } else if (strcmp(el, "ID") == 0) { | |
605 | obj = new ACLID_S3(); | |
606 | } else if (strcmp(el, "DisplayName") == 0) { | |
607 | obj = new ACLDisplayName_S3(); | |
608 | } else if (strcmp(el, "Grant") == 0) { | |
609 | obj = new ACLGrant_S3(); | |
610 | } else if (strcmp(el, "Grantee") == 0) { | |
611 | obj = new ACLGrantee_S3(); | |
612 | } else if (strcmp(el, "Permission") == 0) { | |
613 | obj = new ACLPermission_S3(); | |
614 | } else if (strcmp(el, "URI") == 0) { | |
615 | obj = new ACLURI_S3(); | |
616 | } else if (strcmp(el, "EmailAddress") == 0) { | |
617 | obj = new ACLEmail_S3(); | |
618 | } | |
619 | ||
620 | return obj; | |
621 | } | |
622 |