]> git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_user.cc
b57987e2c1129dcdb5e983c3a0e08b7875faf5ca
[ceph.git] / ceph / src / rgw / rgw_user.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
6 #include <string>
7 #include <map>
8 #include <boost/algorithm/string.hpp>
9
10 #include "common/errno.h"
11 #include "common/Formatter.h"
12 #include "common/ceph_json.h"
13 #include "common/RWLock.h"
14 #include "rgw_sal.h"
15 #include "rgw_zone.h"
16 #include "rgw_acl.h"
17
18 #include "include/types.h"
19 #include "rgw_user.h"
20 #include "rgw_string.h"
21
22 // until everything is moved from rgw_common
23 #include "rgw_common.h"
24
25 #include "rgw_bucket.h"
26 #include "rgw_quota.h"
27
28 #include "services/svc_zone.h"
29 #include "services/svc_sys_obj.h"
30 #include "services/svc_sys_obj_cache.h"
31 #include "services/svc_user.h"
32 #include "services/svc_meta.h"
33
34 #define dout_subsys ceph_subsys_rgw
35
36
37
38 extern void op_type_to_str(uint32_t mask, char *buf, int len);
39
40 /**
41 * Get the anonymous (ie, unauthenticated) user info.
42 */
43 void rgw_get_anon_user(RGWUserInfo& info)
44 {
45 info.user_id = RGW_USER_ANON_ID;
46 info.display_name.clear();
47 info.access_keys.clear();
48 }
49
50 int rgw_user_sync_all_stats(rgw::sal::RGWRadosStore *store, const rgw_user& user_id)
51 {
52 rgw::sal::RGWBucketList user_buckets;
53 rgw::sal::RGWRadosUser user(store, user_id);
54
55 CephContext *cct = store->ctx();
56 size_t max_entries = cct->_conf->rgw_list_buckets_max_chunk;
57 bool is_truncated = false;
58 string marker;
59 int ret;
60
61 do {
62 ret = user.list_buckets(marker, string(), max_entries, false, user_buckets);
63 if (ret < 0) {
64 ldout(cct, 0) << "failed to read user buckets: ret=" << ret << dendl;
65 return ret;
66 }
67 map<string, rgw::sal::RGWBucket*>& buckets = user_buckets.get_buckets();
68 for (map<string, rgw::sal::RGWBucket*>::iterator i = buckets.begin();
69 i != buckets.end();
70 ++i) {
71 marker = i->first;
72
73 rgw::sal::RGWBucket* bucket = i->second;
74
75 ret = bucket->get_bucket_info(null_yield);
76 if (ret < 0) {
77 ldout(cct, 0) << "ERROR: could not read bucket info: bucket=" << bucket << " ret=" << ret << dendl;
78 continue;
79 }
80 ret = bucket->sync_user_stats();
81 if (ret < 0) {
82 ldout(cct, 0) << "ERROR: could not sync bucket stats: ret=" << ret << dendl;
83 return ret;
84 }
85 ret = bucket->check_bucket_shards();
86 if (ret < 0) {
87 ldout(cct, 0) << "ERROR in check_bucket_shards: " << cpp_strerror(-ret)<< dendl;
88 }
89 }
90 } while (is_truncated);
91
92 ret = store->ctl()->user->complete_flush_stats(user.get_user());
93 if (ret < 0) {
94 cerr << "ERROR: failed to complete syncing user stats: ret=" << ret << std::endl;
95 return ret;
96 }
97
98 return 0;
99 }
100
101 int rgw_user_get_all_buckets_stats(rgw::sal::RGWRadosStore *store, const rgw_user& user_id, map<string, cls_user_bucket_entry>& buckets_usage_map)
102 {
103 CephContext *cct = store->ctx();
104 size_t max_entries = cct->_conf->rgw_list_buckets_max_chunk;
105 bool done;
106 string marker;
107 int ret;
108
109 do {
110 rgw::sal::RGWBucketList buckets;
111 ret = rgw_read_user_buckets(store, user_id, buckets, marker,
112 string(), max_entries, false);
113 if (ret < 0) {
114 ldout(cct, 0) << "failed to read user buckets: ret=" << ret << dendl;
115 return ret;
116 }
117 std::map<std::string, rgw::sal::RGWBucket*>& m = buckets.get_buckets();
118 for (const auto& i : m) {
119 marker = i.first;
120
121 rgw::sal::RGWBucket* bucket_ent = i.second;
122 ret = bucket_ent->read_bucket_stats(null_yield);
123 if (ret < 0) {
124 ldout(cct, 0) << "ERROR: could not get bucket stats: ret=" << ret << dendl;
125 return ret;
126 }
127 cls_user_bucket_entry entry;
128 bucket_ent->convert(&entry);
129 buckets_usage_map.emplace(bucket_ent->get_name(), entry);
130 }
131 done = (buckets.count() < max_entries);
132 } while (!done);
133
134 return 0;
135 }
136
137 /**
138 * Save the given user information to storage.
139 * Returns: 0 on success, -ERR# on failure.
140 */
141 int rgw_store_user_info(RGWUserCtl *user_ctl,
142 RGWUserInfo& info,
143 RGWUserInfo *old_info,
144 RGWObjVersionTracker *objv_tracker,
145 real_time mtime,
146 bool exclusive,
147 map<string, bufferlist> *pattrs)
148 {
149 return user_ctl->store_info(info, null_yield,
150 RGWUserCtl::PutParams()
151 .set_old_info(old_info)
152 .set_objv_tracker(objv_tracker)
153 .set_mtime(mtime)
154 .set_exclusive(exclusive)
155 .set_attrs(pattrs));
156 }
157
158 /**
159 * Given a uid, finds the user info associated with it.
160 * returns: 0 on success, -ERR# on failure (including nonexistence)
161 */
162 int rgw_get_user_info_by_uid(RGWUserCtl *user_ctl,
163 const rgw_user& uid,
164 RGWUserInfo& info,
165 RGWObjVersionTracker * const objv_tracker,
166 real_time * const pmtime,
167 rgw_cache_entry_info * const cache_info,
168 map<string, bufferlist> * const pattrs)
169 {
170 return user_ctl->get_info_by_uid(uid, &info, null_yield,
171 RGWUserCtl::GetParams()
172 .set_objv_tracker(objv_tracker)
173 .set_mtime(pmtime)
174 .set_cache_info(cache_info)
175 .set_attrs(pattrs));
176 }
177
178 /**
179 * Given an email, finds the user info associated with it.
180 * returns: 0 on success, -ERR# on failure (including nonexistence)
181 */
182 int rgw_get_user_info_by_email(RGWUserCtl *user_ctl, string& email, RGWUserInfo& info,
183 RGWObjVersionTracker *objv_tracker, real_time *pmtime)
184 {
185 return user_ctl->get_info_by_email(email, &info, null_yield,
186 RGWUserCtl::GetParams()
187 .set_objv_tracker(objv_tracker)
188 .set_mtime(pmtime));
189 }
190
191 /**
192 * Given an swift username, finds the user_info associated with it.
193 * returns: 0 on success, -ERR# on failure (including nonexistence)
194 */
195 extern int rgw_get_user_info_by_swift(RGWUserCtl *user_ctl,
196 const string& swift_name,
197 RGWUserInfo& info, /* out */
198 RGWObjVersionTracker * const objv_tracker,
199 real_time * const pmtime)
200 {
201 return user_ctl->get_info_by_swift(swift_name, &info, null_yield,
202 RGWUserCtl::GetParams()
203 .set_objv_tracker(objv_tracker)
204 .set_mtime(pmtime));
205 }
206
207 /**
208 * Given an access key, finds the user info associated with it.
209 * returns: 0 on success, -ERR# on failure (including nonexistence)
210 */
211 extern int rgw_get_user_info_by_access_key(RGWUserCtl *user_ctl,
212 const std::string& access_key,
213 RGWUserInfo& info,
214 RGWObjVersionTracker* objv_tracker,
215 real_time *pmtime)
216 {
217 return user_ctl->get_info_by_access_key(access_key, &info, null_yield,
218 RGWUserCtl::GetParams()
219 .set_objv_tracker(objv_tracker)
220 .set_mtime(pmtime));
221 }
222
223 static bool char_is_unreserved_url(char c)
224 {
225 if (isalnum(c))
226 return true;
227
228 switch (c) {
229 case '-':
230 case '.':
231 case '_':
232 case '~':
233 return true;
234 default:
235 return false;
236 }
237 }
238
239 struct rgw_flags_desc {
240 uint32_t mask;
241 const char *str;
242 };
243
244 static struct rgw_flags_desc rgw_perms[] = {
245 { RGW_PERM_FULL_CONTROL, "full-control" },
246 { RGW_PERM_READ | RGW_PERM_WRITE, "read-write" },
247 { RGW_PERM_READ, "read" },
248 { RGW_PERM_WRITE, "write" },
249 { RGW_PERM_READ_ACP, "read-acp" },
250 { RGW_PERM_WRITE_ACP, "write-acp" },
251 { 0, NULL }
252 };
253
254 void rgw_perm_to_str(uint32_t mask, char *buf, int len)
255 {
256 const char *sep = "";
257 int pos = 0;
258 if (!mask) {
259 snprintf(buf, len, "<none>");
260 return;
261 }
262 while (mask) {
263 uint32_t orig_mask = mask;
264 for (int i = 0; rgw_perms[i].mask; i++) {
265 struct rgw_flags_desc *desc = &rgw_perms[i];
266 if ((mask & desc->mask) == desc->mask) {
267 pos += snprintf(buf + pos, len - pos, "%s%s", sep, desc->str);
268 if (pos == len)
269 return;
270 sep = ", ";
271 mask &= ~desc->mask;
272 if (!mask)
273 return;
274 }
275 }
276 if (mask == orig_mask) // no change
277 break;
278 }
279 }
280
281 uint32_t rgw_str_to_perm(const char *str)
282 {
283 if (strcasecmp(str, "") == 0)
284 return RGW_PERM_NONE;
285 else if (strcasecmp(str, "read") == 0)
286 return RGW_PERM_READ;
287 else if (strcasecmp(str, "write") == 0)
288 return RGW_PERM_WRITE;
289 else if (strcasecmp(str, "readwrite") == 0)
290 return RGW_PERM_READ | RGW_PERM_WRITE;
291 else if (strcasecmp(str, "full") == 0)
292 return RGW_PERM_FULL_CONTROL;
293
294 return RGW_PERM_INVALID;
295 }
296
297 int rgw_validate_tenant_name(const string& t)
298 {
299 struct tench {
300 static bool is_good(char ch) {
301 return isalnum(ch) || ch == '_';
302 }
303 };
304 std::string::const_iterator it =
305 std::find_if_not(t.begin(), t.end(), tench::is_good);
306 return (it == t.end())? 0: -ERR_INVALID_TENANT_NAME;
307 }
308
309 static bool validate_access_key(string& key)
310 {
311 const char *p = key.c_str();
312 while (*p) {
313 if (!char_is_unreserved_url(*p))
314 return false;
315 p++;
316 }
317 return true;
318 }
319
320 static void set_err_msg(std::string *sink, std::string msg)
321 {
322 if (sink && !msg.empty())
323 *sink = msg;
324 }
325
326 /*
327 * Dump either the full user info or a subset to a formatter.
328 *
329 * NOTE: It is the caller's respnsibility to ensure that the
330 * formatter is flushed at the correct time.
331 */
332
333 static void dump_subusers_info(Formatter *f, RGWUserInfo &info)
334 {
335 map<string, RGWSubUser>::iterator uiter;
336
337 f->open_array_section("subusers");
338 for (uiter = info.subusers.begin(); uiter != info.subusers.end(); ++uiter) {
339 RGWSubUser& u = uiter->second;
340 f->open_object_section("user");
341 string s;
342 info.user_id.to_str(s);
343 f->dump_format("id", "%s:%s", s.c_str(), u.name.c_str());
344 char buf[256];
345 rgw_perm_to_str(u.perm_mask, buf, sizeof(buf));
346 f->dump_string("permissions", buf);
347 f->close_section();
348 }
349 f->close_section();
350 }
351
352 static void dump_access_keys_info(Formatter *f, RGWUserInfo &info)
353 {
354 map<string, RGWAccessKey>::iterator kiter;
355 f->open_array_section("keys");
356 for (kiter = info.access_keys.begin(); kiter != info.access_keys.end(); ++kiter) {
357 RGWAccessKey& k = kiter->second;
358 const char *sep = (k.subuser.empty() ? "" : ":");
359 const char *subuser = (k.subuser.empty() ? "" : k.subuser.c_str());
360 f->open_object_section("key");
361 string s;
362 info.user_id.to_str(s);
363 f->dump_format("user", "%s%s%s", s.c_str(), sep, subuser);
364 f->dump_string("access_key", k.id);
365 f->dump_string("secret_key", k.key);
366 f->close_section();
367 }
368 f->close_section();
369 }
370
371 static void dump_swift_keys_info(Formatter *f, RGWUserInfo &info)
372 {
373 map<string, RGWAccessKey>::iterator kiter;
374 f->open_array_section("swift_keys");
375 for (kiter = info.swift_keys.begin(); kiter != info.swift_keys.end(); ++kiter) {
376 RGWAccessKey& k = kiter->second;
377 const char *sep = (k.subuser.empty() ? "" : ":");
378 const char *subuser = (k.subuser.empty() ? "" : k.subuser.c_str());
379 f->open_object_section("key");
380 string s;
381 info.user_id.to_str(s);
382 f->dump_format("user", "%s%s%s", s.c_str(), sep, subuser);
383 f->dump_string("secret_key", k.key);
384 f->close_section();
385 }
386 f->close_section();
387 }
388
389 static void dump_user_info(Formatter *f, RGWUserInfo &info,
390 RGWStorageStats *stats = NULL)
391 {
392 f->open_object_section("user_info");
393 encode_json("tenant", info.user_id.tenant, f);
394 encode_json("user_id", info.user_id.id, f);
395 encode_json("display_name", info.display_name, f);
396 encode_json("email", info.user_email, f);
397 encode_json("suspended", (int)info.suspended, f);
398 encode_json("max_buckets", (int)info.max_buckets, f);
399
400 dump_subusers_info(f, info);
401 dump_access_keys_info(f, info);
402 dump_swift_keys_info(f, info);
403
404 encode_json("caps", info.caps, f);
405
406 char buf[256];
407 op_type_to_str(info.op_mask, buf, sizeof(buf));
408 encode_json("op_mask", (const char *)buf, f);
409 encode_json("system", (bool)info.system, f);
410 encode_json("admin", (bool)info.admin, f);
411 encode_json("default_placement", info.default_placement.name, f);
412 encode_json("default_storage_class", info.default_placement.storage_class, f);
413 encode_json("placement_tags", info.placement_tags, f);
414 encode_json("bucket_quota", info.bucket_quota, f);
415 encode_json("user_quota", info.user_quota, f);
416 encode_json("temp_url_keys", info.temp_url_keys, f);
417
418 string user_source_type;
419 switch ((RGWIdentityType)info.type) {
420 case TYPE_RGW:
421 user_source_type = "rgw";
422 break;
423 case TYPE_KEYSTONE:
424 user_source_type = "keystone";
425 break;
426 case TYPE_LDAP:
427 user_source_type = "ldap";
428 break;
429 case TYPE_NONE:
430 user_source_type = "none";
431 break;
432 default:
433 user_source_type = "none";
434 break;
435 }
436 encode_json("type", user_source_type, f);
437 encode_json("mfa_ids", info.mfa_ids, f);
438 if (stats) {
439 encode_json("stats", *stats, f);
440 }
441 f->close_section();
442 }
443
444
445 RGWAccessKeyPool::RGWAccessKeyPool(RGWUser* usr)
446 {
447 if (!usr) {
448 return;
449 }
450
451 user = usr;
452
453 store = user->get_store();
454 user_ctl = user->get_user_ctl();
455 }
456
457 int RGWAccessKeyPool::init(RGWUserAdminOpState& op_state)
458 {
459 if (!op_state.is_initialized()) {
460 keys_allowed = false;
461 return -EINVAL;
462 }
463
464 rgw_user& uid = op_state.get_user_id();
465 if (uid.compare(RGW_USER_ANON_ID) == 0) {
466 keys_allowed = false;
467 return -EACCES;
468 }
469
470 swift_keys = op_state.get_swift_keys();
471 access_keys = op_state.get_access_keys();
472
473 keys_allowed = true;
474
475 return 0;
476 }
477
478 /*
479 * Do a fairly exhaustive search for an existing key matching the parameters
480 * given. Also handles the case where no key type was specified and updates
481 * the operation state if needed.
482 */
483
484 bool RGWAccessKeyPool::check_existing_key(RGWUserAdminOpState& op_state)
485 {
486 bool existing_key = false;
487
488 int key_type = op_state.get_key_type();
489 std::string kid = op_state.get_access_key();
490 std::map<std::string, RGWAccessKey>::iterator kiter;
491 std::string swift_kid = op_state.build_default_swift_kid();
492
493 RGWUserInfo dup_info;
494
495 if (kid.empty() && swift_kid.empty())
496 return false;
497
498 switch (key_type) {
499 case KEY_TYPE_SWIFT:
500 kiter = swift_keys->find(swift_kid);
501
502 existing_key = (kiter != swift_keys->end());
503 if (existing_key)
504 op_state.set_access_key(swift_kid);
505
506 break;
507 case KEY_TYPE_S3:
508 kiter = access_keys->find(kid);
509 existing_key = (kiter != access_keys->end());
510
511 break;
512 default:
513 kiter = access_keys->find(kid);
514
515 existing_key = (kiter != access_keys->end());
516 if (existing_key) {
517 op_state.set_key_type(KEY_TYPE_S3);
518 break;
519 }
520
521 kiter = swift_keys->find(kid);
522
523 existing_key = (kiter != swift_keys->end());
524 if (existing_key) {
525 op_state.set_key_type(KEY_TYPE_SWIFT);
526 break;
527 }
528
529 // handle the case where the access key was not provided in user:key format
530 if (swift_kid.empty())
531 return false;
532
533 kiter = swift_keys->find(swift_kid);
534
535 existing_key = (kiter != swift_keys->end());
536 if (existing_key) {
537 op_state.set_access_key(swift_kid);
538 op_state.set_key_type(KEY_TYPE_SWIFT);
539 }
540 }
541
542 op_state.set_existing_key(existing_key);
543
544 return existing_key;
545 }
546
547 int RGWAccessKeyPool::check_op(RGWUserAdminOpState& op_state,
548 std::string *err_msg)
549 {
550 RGWUserInfo dup_info;
551
552 if (!op_state.is_populated()) {
553 set_err_msg(err_msg, "user info was not populated");
554 return -EINVAL;
555 }
556
557 if (!keys_allowed) {
558 set_err_msg(err_msg, "keys not allowed for this user");
559 return -EACCES;
560 }
561
562 int32_t key_type = op_state.get_key_type();
563
564 // if a key type wasn't specified
565 if (key_type < 0) {
566 if (op_state.has_subuser()) {
567 key_type = KEY_TYPE_SWIFT;
568 } else {
569 key_type = KEY_TYPE_S3;
570 }
571 }
572
573 op_state.set_key_type(key_type);
574
575 /* see if the access key was specified */
576 if (key_type == KEY_TYPE_S3 && !op_state.will_gen_access() &&
577 op_state.get_access_key().empty()) {
578 set_err_msg(err_msg, "empty access key");
579 return -ERR_INVALID_ACCESS_KEY;
580 }
581
582 // don't check for secret key because we may be doing a removal
583
584 check_existing_key(op_state);
585
586 return 0;
587 }
588
589 // Generate a new random key
590 int RGWAccessKeyPool::generate_key(RGWUserAdminOpState& op_state, std::string *err_msg)
591 {
592 std::string id;
593 std::string key;
594
595 std::pair<std::string, RGWAccessKey> key_pair;
596 RGWAccessKey new_key;
597 RGWUserInfo duplicate_check;
598
599 int key_type = op_state.get_key_type();
600 bool gen_access = op_state.will_gen_access();
601 bool gen_secret = op_state.will_gen_secret();
602
603 if (!keys_allowed) {
604 set_err_msg(err_msg, "access keys not allowed for this user");
605 return -EACCES;
606 }
607
608 if (op_state.has_existing_key()) {
609 set_err_msg(err_msg, "cannot create existing key");
610 return -ERR_KEY_EXIST;
611 }
612
613 if (!gen_access) {
614 id = op_state.get_access_key();
615 }
616
617 if (!id.empty()) {
618 switch (key_type) {
619 case KEY_TYPE_SWIFT:
620 if (rgw_get_user_info_by_swift(user_ctl, id, duplicate_check) >= 0) {
621 set_err_msg(err_msg, "existing swift key in RGW system:" + id);
622 return -ERR_KEY_EXIST;
623 }
624 break;
625 case KEY_TYPE_S3:
626 if (rgw_get_user_info_by_access_key(user_ctl, id, duplicate_check) >= 0) {
627 set_err_msg(err_msg, "existing S3 key in RGW system:" + id);
628 return -ERR_KEY_EXIST;
629 }
630 }
631 }
632
633 //key's subuser
634 if (op_state.has_subuser()) {
635 //create user and subuser at the same time, user's s3 key should not be set this
636 if (!op_state.key_type_setbycontext || (key_type == KEY_TYPE_SWIFT)) {
637 new_key.subuser = op_state.get_subuser();
638 }
639 }
640
641 //Secret key
642 if (!gen_secret) {
643 if (op_state.get_secret_key().empty()) {
644 set_err_msg(err_msg, "empty secret key");
645 return -ERR_INVALID_SECRET_KEY;
646 }
647
648 key = op_state.get_secret_key();
649 } else {
650 char secret_key_buf[SECRET_KEY_LEN + 1];
651 gen_rand_alphanumeric_plain(g_ceph_context, secret_key_buf, sizeof(secret_key_buf));
652 key = secret_key_buf;
653 }
654
655 // Generate the access key
656 if (key_type == KEY_TYPE_S3 && gen_access) {
657 char public_id_buf[PUBLIC_ID_LEN + 1];
658
659 do {
660 int id_buf_size = sizeof(public_id_buf);
661 gen_rand_alphanumeric_upper(g_ceph_context, public_id_buf, id_buf_size);
662 id = public_id_buf;
663 if (!validate_access_key(id))
664 continue;
665
666 } while (!rgw_get_user_info_by_access_key(user_ctl, id, duplicate_check));
667 }
668
669 if (key_type == KEY_TYPE_SWIFT) {
670 id = op_state.build_default_swift_kid();
671 if (id.empty()) {
672 set_err_msg(err_msg, "empty swift access key");
673 return -ERR_INVALID_ACCESS_KEY;
674 }
675
676 // check that the access key doesn't exist
677 if (rgw_get_user_info_by_swift(user_ctl, id, duplicate_check) >= 0) {
678 set_err_msg(err_msg, "cannot create existing swift key");
679 return -ERR_KEY_EXIST;
680 }
681 }
682
683 // finally create the new key
684 new_key.id = id;
685 new_key.key = key;
686
687 key_pair.first = id;
688 key_pair.second = new_key;
689
690 if (key_type == KEY_TYPE_S3) {
691 access_keys->insert(key_pair);
692 } else if (key_type == KEY_TYPE_SWIFT) {
693 swift_keys->insert(key_pair);
694 }
695
696 return 0;
697 }
698
699 // modify an existing key
700 int RGWAccessKeyPool::modify_key(RGWUserAdminOpState& op_state, std::string *err_msg)
701 {
702 std::string id;
703 std::string key = op_state.get_secret_key();
704 int key_type = op_state.get_key_type();
705
706 RGWAccessKey modify_key;
707
708 pair<string, RGWAccessKey> key_pair;
709 map<std::string, RGWAccessKey>::iterator kiter;
710
711 switch (key_type) {
712 case KEY_TYPE_S3:
713 id = op_state.get_access_key();
714 if (id.empty()) {
715 set_err_msg(err_msg, "no access key specified");
716 return -ERR_INVALID_ACCESS_KEY;
717 }
718 break;
719 case KEY_TYPE_SWIFT:
720 id = op_state.build_default_swift_kid();
721 if (id.empty()) {
722 set_err_msg(err_msg, "no subuser specified");
723 return -EINVAL;
724 }
725 break;
726 default:
727 set_err_msg(err_msg, "invalid key type");
728 return -ERR_INVALID_KEY_TYPE;
729 }
730
731 if (!op_state.has_existing_key()) {
732 set_err_msg(err_msg, "key does not exist");
733 return -ERR_INVALID_ACCESS_KEY;
734 }
735
736 key_pair.first = id;
737
738 if (key_type == KEY_TYPE_SWIFT) {
739 modify_key.id = id;
740 modify_key.subuser = op_state.get_subuser();
741 } else if (key_type == KEY_TYPE_S3) {
742 kiter = access_keys->find(id);
743 if (kiter != access_keys->end()) {
744 modify_key = kiter->second;
745 }
746 }
747
748 if (op_state.will_gen_secret()) {
749 char secret_key_buf[SECRET_KEY_LEN + 1];
750 int key_buf_size = sizeof(secret_key_buf);
751 gen_rand_alphanumeric_plain(g_ceph_context, secret_key_buf, key_buf_size);
752 key = secret_key_buf;
753 }
754
755 if (key.empty()) {
756 set_err_msg(err_msg, "empty secret key");
757 return -ERR_INVALID_SECRET_KEY;
758 }
759
760 // update the access key with the new secret key
761 modify_key.key = key;
762
763 key_pair.second = modify_key;
764
765
766 if (key_type == KEY_TYPE_S3) {
767 (*access_keys)[id] = modify_key;
768 } else if (key_type == KEY_TYPE_SWIFT) {
769 (*swift_keys)[id] = modify_key;
770 }
771
772 return 0;
773 }
774
775 int RGWAccessKeyPool::execute_add(RGWUserAdminOpState& op_state,
776 std::string *err_msg, bool defer_user_update)
777 {
778 int ret = 0;
779
780 std::string subprocess_msg;
781 int key_op = GENERATE_KEY;
782
783 // set the op
784 if (op_state.has_existing_key())
785 key_op = MODIFY_KEY;
786
787 switch (key_op) {
788 case GENERATE_KEY:
789 ret = generate_key(op_state, &subprocess_msg);
790 break;
791 case MODIFY_KEY:
792 ret = modify_key(op_state, &subprocess_msg);
793 break;
794 }
795
796 if (ret < 0) {
797 set_err_msg(err_msg, subprocess_msg);
798 return ret;
799 }
800
801 // store the updated info
802 if (!defer_user_update)
803 ret = user->update(op_state, err_msg);
804
805 if (ret < 0)
806 return ret;
807
808 return 0;
809 }
810
811 int RGWAccessKeyPool::add(RGWUserAdminOpState& op_state, std::string *err_msg)
812 {
813 return add(op_state, err_msg, false);
814 }
815
816 int RGWAccessKeyPool::add(RGWUserAdminOpState& op_state, std::string *err_msg, bool defer_user_update)
817 {
818 int ret;
819 std::string subprocess_msg;
820
821 ret = check_op(op_state, &subprocess_msg);
822 if (ret < 0) {
823 set_err_msg(err_msg, "unable to parse request, " + subprocess_msg);
824 return ret;
825 }
826
827 ret = execute_add(op_state, &subprocess_msg, defer_user_update);
828 if (ret < 0) {
829 set_err_msg(err_msg, "unable to add access key, " + subprocess_msg);
830 return ret;
831 }
832
833 return 0;
834 }
835
836 int RGWAccessKeyPool::execute_remove(RGWUserAdminOpState& op_state, std::string *err_msg, bool defer_user_update)
837 {
838 int ret = 0;
839
840 int key_type = op_state.get_key_type();
841 std::string id = op_state.get_access_key();
842 map<std::string, RGWAccessKey>::iterator kiter;
843 map<std::string, RGWAccessKey> *keys_map;
844
845 if (!op_state.has_existing_key()) {
846 set_err_msg(err_msg, "unable to find access key");
847 return -ERR_INVALID_ACCESS_KEY;
848 }
849
850 if (key_type == KEY_TYPE_S3) {
851 keys_map = access_keys;
852 } else if (key_type == KEY_TYPE_SWIFT) {
853 keys_map = swift_keys;
854 } else {
855 keys_map = NULL;
856 set_err_msg(err_msg, "invalid access key");
857 return -ERR_INVALID_ACCESS_KEY;
858 }
859
860 kiter = keys_map->find(id);
861 if (kiter == keys_map->end()) {
862 set_err_msg(err_msg, "key not found");
863 return -ERR_INVALID_ACCESS_KEY;
864 }
865
866 keys_map->erase(kiter);
867
868 if (!defer_user_update)
869 ret = user->update(op_state, err_msg);
870
871 if (ret < 0)
872 return ret;
873
874 return 0;
875 }
876
877 int RGWAccessKeyPool::remove(RGWUserAdminOpState& op_state, std::string *err_msg)
878 {
879 return remove(op_state, err_msg, false);
880 }
881
882 int RGWAccessKeyPool::remove(RGWUserAdminOpState& op_state, std::string *err_msg, bool defer_user_update)
883 {
884 int ret;
885
886 std::string subprocess_msg;
887
888 ret = check_op(op_state, &subprocess_msg);
889 if (ret < 0) {
890 set_err_msg(err_msg, "unable to parse request, " + subprocess_msg);
891 return ret;
892 }
893
894 ret = execute_remove(op_state, &subprocess_msg, defer_user_update);
895 if (ret < 0) {
896 set_err_msg(err_msg, "unable to remove access key, " + subprocess_msg);
897 return ret;
898 }
899
900 return 0;
901 }
902
903 // remove all keys associated with a subuser
904 int RGWAccessKeyPool::remove_subuser_keys(RGWUserAdminOpState& op_state,
905 std::string *err_msg, bool defer_user_update)
906 {
907 int ret = 0;
908
909 if (!op_state.is_populated()) {
910 set_err_msg(err_msg, "user info was not populated");
911 return -EINVAL;
912 }
913
914 if (!op_state.has_subuser()) {
915 set_err_msg(err_msg, "no subuser specified");
916 return -EINVAL;
917 }
918
919 std::string swift_kid = op_state.build_default_swift_kid();
920 if (swift_kid.empty()) {
921 set_err_msg(err_msg, "empty swift access key");
922 return -EINVAL;
923 }
924
925 map<std::string, RGWAccessKey>::iterator kiter;
926 map<std::string, RGWAccessKey> *keys_map;
927
928 // a subuser can have at most one swift key
929 keys_map = swift_keys;
930 kiter = keys_map->find(swift_kid);
931 if (kiter != keys_map->end()) {
932 keys_map->erase(kiter);
933 }
934
935 // a subuser may have multiple s3 key pairs
936 std::string subuser_str = op_state.get_subuser();
937 keys_map = access_keys;
938 RGWUserInfo user_info = op_state.get_user_info();
939 auto user_kiter = user_info.access_keys.begin();
940 for (; user_kiter != user_info.access_keys.end(); ++user_kiter) {
941 if (user_kiter->second.subuser == subuser_str) {
942 kiter = keys_map->find(user_kiter->first);
943 if (kiter != keys_map->end()) {
944 keys_map->erase(kiter);
945 }
946 }
947 }
948
949 if (!defer_user_update)
950 ret = user->update(op_state, err_msg);
951
952 if (ret < 0)
953 return ret;
954
955 return 0;
956 }
957
958 RGWSubUserPool::RGWSubUserPool(RGWUser *usr)
959 {
960 if (!usr) {
961 return;
962 }
963
964 user = usr;
965
966 subusers_allowed = true;
967 store = user->get_store();
968 user_ctl = user->get_user_ctl();
969 }
970
971 int RGWSubUserPool::init(RGWUserAdminOpState& op_state)
972 {
973 if (!op_state.is_initialized()) {
974 subusers_allowed = false;
975 return -EINVAL;
976 }
977
978 rgw_user& uid = op_state.get_user_id();
979 if (uid.compare(RGW_USER_ANON_ID) == 0) {
980 subusers_allowed = false;
981 return -EACCES;
982 }
983
984 subuser_map = op_state.get_subusers();
985 if (subuser_map == NULL) {
986 subusers_allowed = false;
987 return -EINVAL;
988 }
989
990 subusers_allowed = true;
991
992 return 0;
993 }
994
995 bool RGWSubUserPool::exists(std::string subuser)
996 {
997 if (subuser.empty())
998 return false;
999
1000 if (!subuser_map)
1001 return false;
1002
1003 if (subuser_map->count(subuser))
1004 return true;
1005
1006 return false;
1007 }
1008
1009 int RGWSubUserPool::check_op(RGWUserAdminOpState& op_state,
1010 std::string *err_msg)
1011 {
1012 bool existing = false;
1013 std::string subuser = op_state.get_subuser();
1014
1015 if (!op_state.is_populated()) {
1016 set_err_msg(err_msg, "user info was not populated");
1017 return -EINVAL;
1018 }
1019
1020 if (!subusers_allowed) {
1021 set_err_msg(err_msg, "subusers not allowed for this user");
1022 return -EACCES;
1023 }
1024
1025 if (subuser.empty() && !op_state.will_gen_subuser()) {
1026 set_err_msg(err_msg, "empty subuser name");
1027 return -EINVAL;
1028 }
1029
1030 if (op_state.get_subuser_perm() == RGW_PERM_INVALID) {
1031 set_err_msg(err_msg, "invaild subuser access");
1032 return -EINVAL;
1033 }
1034
1035 //set key type when it not set or set by context
1036 if ((op_state.get_key_type() < 0) || op_state.key_type_setbycontext) {
1037 op_state.set_key_type(KEY_TYPE_SWIFT);
1038 op_state.key_type_setbycontext = true;
1039 }
1040
1041 // check if the subuser exists
1042 if (!subuser.empty())
1043 existing = exists(subuser);
1044
1045 op_state.set_existing_subuser(existing);
1046
1047 return 0;
1048 }
1049
1050 int RGWSubUserPool::execute_add(RGWUserAdminOpState& op_state,
1051 std::string *err_msg, bool defer_user_update)
1052 {
1053 int ret = 0;
1054 std::string subprocess_msg;
1055
1056 RGWSubUser subuser;
1057 std::pair<std::string, RGWSubUser> subuser_pair;
1058 std::string subuser_str = op_state.get_subuser();
1059
1060 subuser_pair.first = subuser_str;
1061
1062 // assumes key should be created
1063 if (op_state.has_key_op()) {
1064 ret = user->keys.add(op_state, &subprocess_msg, true);
1065 if (ret < 0) {
1066 set_err_msg(err_msg, "unable to create subuser key, " + subprocess_msg);
1067 return ret;
1068 }
1069 }
1070
1071 // create the subuser
1072 subuser.name = subuser_str;
1073
1074 if (op_state.has_subuser_perm())
1075 subuser.perm_mask = op_state.get_subuser_perm();
1076
1077 // insert the subuser into user info
1078 subuser_pair.second = subuser;
1079 subuser_map->insert(subuser_pair);
1080
1081 // attempt to save the subuser
1082 if (!defer_user_update)
1083 ret = user->update(op_state, err_msg);
1084
1085 if (ret < 0)
1086 return ret;
1087
1088 return 0;
1089 }
1090
1091 int RGWSubUserPool::add(RGWUserAdminOpState& op_state, std::string *err_msg)
1092 {
1093 return add(op_state, err_msg, false);
1094 }
1095
1096 int RGWSubUserPool::add(RGWUserAdminOpState& op_state, std::string *err_msg, bool defer_user_update)
1097 {
1098 std::string subprocess_msg;
1099 int ret;
1100 int32_t key_type = op_state.get_key_type();
1101
1102 ret = check_op(op_state, &subprocess_msg);
1103 if (ret < 0) {
1104 set_err_msg(err_msg, "unable to parse request, " + subprocess_msg);
1105 return ret;
1106 }
1107
1108 if (key_type == KEY_TYPE_S3 && op_state.get_access_key().empty()) {
1109 op_state.set_gen_access();
1110 }
1111
1112 if (op_state.get_secret_key().empty()) {
1113 op_state.set_gen_secret();
1114 }
1115
1116 ret = execute_add(op_state, &subprocess_msg, defer_user_update);
1117 if (ret < 0) {
1118 set_err_msg(err_msg, "unable to create subuser, " + subprocess_msg);
1119 return ret;
1120 }
1121
1122 return 0;
1123 }
1124
1125 int RGWSubUserPool::execute_remove(RGWUserAdminOpState& op_state,
1126 std::string *err_msg, bool defer_user_update)
1127 {
1128 int ret = 0;
1129 std::string subprocess_msg;
1130
1131 std::string subuser_str = op_state.get_subuser();
1132
1133 map<std::string, RGWSubUser>::iterator siter;
1134 siter = subuser_map->find(subuser_str);
1135 if (siter == subuser_map->end()){
1136 set_err_msg(err_msg, "subuser not found: " + subuser_str);
1137 return -ERR_NO_SUCH_SUBUSER;
1138 }
1139 if (!op_state.has_existing_subuser()) {
1140 set_err_msg(err_msg, "subuser not found: " + subuser_str);
1141 return -ERR_NO_SUCH_SUBUSER;
1142 }
1143
1144 // always purge all associate keys
1145 user->keys.remove_subuser_keys(op_state, &subprocess_msg, true);
1146
1147 // remove the subuser from the user info
1148 subuser_map->erase(siter);
1149
1150 // attempt to save the subuser
1151 if (!defer_user_update)
1152 ret = user->update(op_state, err_msg);
1153
1154 if (ret < 0)
1155 return ret;
1156
1157 return 0;
1158 }
1159
1160 int RGWSubUserPool::remove(RGWUserAdminOpState& op_state, std::string *err_msg)
1161 {
1162 return remove(op_state, err_msg, false);
1163 }
1164
1165 int RGWSubUserPool::remove(RGWUserAdminOpState& op_state, std::string *err_msg, bool defer_user_update)
1166 {
1167 std::string subprocess_msg;
1168 int ret;
1169
1170 ret = check_op(op_state, &subprocess_msg);
1171 if (ret < 0) {
1172 set_err_msg(err_msg, "unable to parse request, " + subprocess_msg);
1173 return ret;
1174 }
1175
1176 ret = execute_remove(op_state, &subprocess_msg, defer_user_update);
1177 if (ret < 0) {
1178 set_err_msg(err_msg, "unable to remove subuser, " + subprocess_msg);
1179 return ret;
1180 }
1181
1182 return 0;
1183 }
1184
1185 int RGWSubUserPool::execute_modify(RGWUserAdminOpState& op_state, std::string *err_msg, bool defer_user_update)
1186 {
1187 int ret = 0;
1188 std::string subprocess_msg;
1189 std::map<std::string, RGWSubUser>::iterator siter;
1190 std::pair<std::string, RGWSubUser> subuser_pair;
1191
1192 std::string subuser_str = op_state.get_subuser();
1193 RGWSubUser subuser;
1194
1195 if (!op_state.has_existing_subuser()) {
1196 set_err_msg(err_msg, "subuser does not exist");
1197 return -ERR_NO_SUCH_SUBUSER;
1198 }
1199
1200 subuser_pair.first = subuser_str;
1201
1202 siter = subuser_map->find(subuser_str);
1203 subuser = siter->second;
1204
1205 if (op_state.has_key_op()) {
1206 ret = user->keys.add(op_state, &subprocess_msg, true);
1207 if (ret < 0) {
1208 set_err_msg(err_msg, "unable to create subuser keys, " + subprocess_msg);
1209 return ret;
1210 }
1211 }
1212
1213 if (op_state.has_subuser_perm())
1214 subuser.perm_mask = op_state.get_subuser_perm();
1215
1216 subuser_pair.second = subuser;
1217
1218 subuser_map->erase(siter);
1219 subuser_map->insert(subuser_pair);
1220
1221 // attempt to save the subuser
1222 if (!defer_user_update)
1223 ret = user->update(op_state, err_msg);
1224
1225 if (ret < 0)
1226 return ret;
1227
1228 return 0;
1229 }
1230
1231 int RGWSubUserPool::modify(RGWUserAdminOpState& op_state, std::string *err_msg)
1232 {
1233 return RGWSubUserPool::modify(op_state, err_msg, false);
1234 }
1235
1236 int RGWSubUserPool::modify(RGWUserAdminOpState& op_state, std::string *err_msg, bool defer_user_update)
1237 {
1238 std::string subprocess_msg;
1239 int ret;
1240
1241 RGWSubUser subuser;
1242
1243 ret = check_op(op_state, &subprocess_msg);
1244 if (ret < 0) {
1245 set_err_msg(err_msg, "unable to parse request, " + subprocess_msg);
1246 return ret;
1247 }
1248
1249 ret = execute_modify(op_state, &subprocess_msg, defer_user_update);
1250 if (ret < 0) {
1251 set_err_msg(err_msg, "unable to modify subuser, " + subprocess_msg);
1252 return ret;
1253 }
1254
1255 return 0;
1256 }
1257
1258 RGWUserCapPool::RGWUserCapPool(RGWUser *usr)
1259 {
1260 if (!usr) {
1261 return;
1262 }
1263 user = usr;
1264 caps_allowed = true;
1265 }
1266
1267 int RGWUserCapPool::init(RGWUserAdminOpState& op_state)
1268 {
1269 if (!op_state.is_initialized()) {
1270 caps_allowed = false;
1271 return -EINVAL;
1272 }
1273
1274 rgw_user& uid = op_state.get_user_id();
1275 if (uid.compare(RGW_USER_ANON_ID) == 0) {
1276 caps_allowed = false;
1277 return -EACCES;
1278 }
1279
1280 caps = op_state.get_caps_obj();
1281 if (!caps) {
1282 caps_allowed = false;
1283 return -ERR_INVALID_CAP;
1284 }
1285
1286 caps_allowed = true;
1287
1288 return 0;
1289 }
1290
1291 int RGWUserCapPool::add(RGWUserAdminOpState& op_state, std::string *err_msg)
1292 {
1293 return add(op_state, err_msg, false);
1294 }
1295
1296 int RGWUserCapPool::add(RGWUserAdminOpState& op_state, std::string *err_msg, bool defer_save)
1297 {
1298 int ret = 0;
1299 std::string caps_str = op_state.get_caps();
1300
1301 if (!op_state.is_populated()) {
1302 set_err_msg(err_msg, "user info was not populated");
1303 return -EINVAL;
1304 }
1305
1306 if (!caps_allowed) {
1307 set_err_msg(err_msg, "caps not allowed for this user");
1308 return -EACCES;
1309 }
1310
1311 if (caps_str.empty()) {
1312 set_err_msg(err_msg, "empty user caps");
1313 return -ERR_INVALID_CAP;
1314 }
1315
1316 int r = caps->add_from_string(caps_str);
1317 if (r < 0) {
1318 set_err_msg(err_msg, "unable to add caps: " + caps_str);
1319 return r;
1320 }
1321
1322 if (!defer_save)
1323 ret = user->update(op_state, err_msg);
1324
1325 if (ret < 0)
1326 return ret;
1327
1328 return 0;
1329 }
1330
1331 int RGWUserCapPool::remove(RGWUserAdminOpState& op_state, std::string *err_msg)
1332 {
1333 return remove(op_state, err_msg, false);
1334 }
1335
1336 int RGWUserCapPool::remove(RGWUserAdminOpState& op_state, std::string *err_msg, bool defer_save)
1337 {
1338 int ret = 0;
1339
1340 std::string caps_str = op_state.get_caps();
1341
1342 if (!op_state.is_populated()) {
1343 set_err_msg(err_msg, "user info was not populated");
1344 return -EINVAL;
1345 }
1346
1347 if (!caps_allowed) {
1348 set_err_msg(err_msg, "caps not allowed for this user");
1349 return -EACCES;
1350 }
1351
1352 if (caps_str.empty()) {
1353 set_err_msg(err_msg, "empty user caps");
1354 return -ERR_INVALID_CAP;
1355 }
1356
1357 int r = caps->remove_from_string(caps_str);
1358 if (r < 0) {
1359 set_err_msg(err_msg, "unable to remove caps: " + caps_str);
1360 return r;
1361 }
1362
1363 if (!defer_save)
1364 ret = user->update(op_state, err_msg);
1365
1366 if (ret < 0)
1367 return ret;
1368
1369 return 0;
1370 }
1371
1372 RGWUser::RGWUser() : caps(this), keys(this), subusers(this)
1373 {
1374 init_default();
1375 }
1376
1377 int RGWUser::init(rgw::sal::RGWRadosStore *storage, RGWUserAdminOpState& op_state)
1378 {
1379 init_default();
1380 int ret = init_storage(storage);
1381 if (ret < 0)
1382 return ret;
1383
1384 ret = init(op_state);
1385 if (ret < 0)
1386 return ret;
1387
1388 return 0;
1389 }
1390
1391 void RGWUser::init_default()
1392 {
1393 // use anonymous user info as a placeholder
1394 rgw_get_anon_user(old_info);
1395 user_id = RGW_USER_ANON_ID;
1396
1397 clear_populated();
1398 }
1399
1400 int RGWUser::init_storage(rgw::sal::RGWRadosStore *storage)
1401 {
1402 if (!storage) {
1403 return -EINVAL;
1404 }
1405
1406 store = storage;
1407 user_ctl = store->ctl()->user;
1408
1409 clear_populated();
1410
1411 /* API wrappers */
1412 keys = RGWAccessKeyPool(this);
1413 caps = RGWUserCapPool(this);
1414 subusers = RGWSubUserPool(this);
1415
1416 return 0;
1417 }
1418
1419 int RGWUser::init(RGWUserAdminOpState& op_state)
1420 {
1421 bool found = false;
1422 std::string swift_user;
1423 user_id = op_state.get_user_id();
1424 std::string user_email = op_state.get_user_email();
1425 std::string access_key = op_state.get_access_key();
1426 std::string subuser = op_state.get_subuser();
1427
1428 int key_type = op_state.get_key_type();
1429 if (key_type == KEY_TYPE_SWIFT) {
1430 swift_user = op_state.get_access_key();
1431 access_key.clear();
1432 }
1433
1434 RGWUserInfo user_info;
1435
1436 clear_populated();
1437
1438 if (user_id.empty() && !subuser.empty()) {
1439 size_t pos = subuser.find(':');
1440 if (pos != string::npos) {
1441 user_id = subuser.substr(0, pos);
1442 op_state.set_user_id(user_id);
1443 }
1444 }
1445
1446 if (!user_id.empty() && (user_id.compare(RGW_USER_ANON_ID) != 0)) {
1447 found = (rgw_get_user_info_by_uid(user_ctl, user_id, user_info, &op_state.objv) >= 0);
1448 op_state.found_by_uid = found;
1449 }
1450 if (store->ctx()->_conf.get_val<bool>("rgw_user_unique_email")) {
1451 if (!user_email.empty() && !found) {
1452 found = (rgw_get_user_info_by_email(user_ctl, user_email, user_info, &op_state.objv) >= 0);
1453 op_state.found_by_email = found;
1454 }
1455 }
1456 if (!swift_user.empty() && !found) {
1457 found = (rgw_get_user_info_by_swift(user_ctl, swift_user, user_info, &op_state.objv) >= 0);
1458 op_state.found_by_key = found;
1459 }
1460 if (!access_key.empty() && !found) {
1461 found = (rgw_get_user_info_by_access_key(user_ctl, access_key, user_info, &op_state.objv) >= 0);
1462 op_state.found_by_key = found;
1463 }
1464
1465 op_state.set_existing_user(found);
1466 if (found) {
1467 op_state.set_user_info(user_info);
1468 op_state.set_populated();
1469
1470 old_info = user_info;
1471 set_populated();
1472 }
1473
1474 if (user_id.empty()) {
1475 user_id = user_info.user_id;
1476 }
1477 op_state.set_initialized();
1478
1479 // this may have been called by a helper object
1480 int ret = init_members(op_state);
1481 if (ret < 0)
1482 return ret;
1483
1484 return 0;
1485 }
1486
1487 int RGWUser::init_members(RGWUserAdminOpState& op_state)
1488 {
1489 int ret = 0;
1490
1491 ret = keys.init(op_state);
1492 if (ret < 0)
1493 return ret;
1494
1495 ret = subusers.init(op_state);
1496 if (ret < 0)
1497 return ret;
1498
1499 ret = caps.init(op_state);
1500 if (ret < 0)
1501 return ret;
1502
1503 return 0;
1504 }
1505
1506 int RGWUser::update(RGWUserAdminOpState& op_state, std::string *err_msg)
1507 {
1508 int ret;
1509 std::string subprocess_msg;
1510 RGWUserInfo user_info = op_state.get_user_info();
1511
1512 if (!store) {
1513 set_err_msg(err_msg, "couldn't initialize storage");
1514 return -EINVAL;
1515 }
1516
1517 RGWUserInfo *pold_info = (is_populated() ? &old_info : nullptr);
1518
1519 ret = rgw_store_user_info(user_ctl, user_info, pold_info, &op_state.objv, real_time(), false);
1520 if (ret < 0) {
1521 set_err_msg(err_msg, "unable to store user info");
1522 return ret;
1523 }
1524
1525 old_info = user_info;
1526 set_populated();
1527
1528 return 0;
1529 }
1530
1531 int RGWUser::check_op(RGWUserAdminOpState& op_state, std::string *err_msg)
1532 {
1533 bool same_id;
1534 bool populated;
1535 rgw_user& op_id = op_state.get_user_id();
1536
1537 RGWUserInfo user_info;
1538
1539 same_id = (user_id.compare(op_id) == 0);
1540 populated = is_populated();
1541
1542 if (op_id.compare(RGW_USER_ANON_ID) == 0) {
1543 set_err_msg(err_msg, "unable to perform operations on the anonymous user");
1544 return -EINVAL;
1545 }
1546
1547 if (populated && !same_id) {
1548 set_err_msg(err_msg, "user id mismatch, operation id: " + op_id.to_str()
1549 + " does not match: " + user_id.to_str());
1550
1551 return -EINVAL;
1552 }
1553
1554 int ret = rgw_validate_tenant_name(op_id.tenant);
1555 if (ret) {
1556 set_err_msg(err_msg,
1557 "invalid tenant only alphanumeric and _ characters are allowed");
1558 return ret;
1559 }
1560
1561 //set key type when it not set or set by context
1562 if ((op_state.get_key_type() < 0) || op_state.key_type_setbycontext) {
1563 op_state.set_key_type(KEY_TYPE_S3);
1564 op_state.key_type_setbycontext = true;
1565 }
1566
1567 return 0;
1568 }
1569
1570 // update swift_keys with new user id
1571 static void rename_swift_keys(const rgw_user& user,
1572 std::map<std::string, RGWAccessKey>& keys)
1573 {
1574 std::string user_id;
1575 user.to_str(user_id);
1576
1577 auto modify_keys = std::move(keys);
1578 for ([[maybe_unused]] auto& [k, key] : modify_keys) {
1579 std::string id = user_id + ":" + key.subuser;
1580 key.id = id;
1581 keys[id] = std::move(key);
1582 }
1583 }
1584
1585 int RGWUser::execute_rename(RGWUserAdminOpState& op_state, std::string *err_msg)
1586 {
1587 int ret;
1588 bool populated = op_state.is_populated();
1589
1590 if (!op_state.has_existing_user() && !populated) {
1591 set_err_msg(err_msg, "user not found");
1592 return -ENOENT;
1593 }
1594
1595 if (!populated) {
1596 ret = init(op_state);
1597 if (ret < 0) {
1598 set_err_msg(err_msg, "unable to retrieve user info");
1599 return ret;
1600 }
1601 }
1602
1603 rgw::sal::RGWRadosUser old_user(store, op_state.get_user_info());
1604 rgw::sal::RGWRadosUser new_user(store, op_state.get_new_uid());
1605 if (old_user.get_tenant() != new_user.get_tenant()) {
1606 set_err_msg(err_msg, "users have to be under the same tenant namespace "
1607 + old_user.get_tenant() + " != " + new_user.get_tenant());
1608 return -EINVAL;
1609 }
1610
1611 // create a stub user and write only the uid index and buckets object
1612 RGWUserInfo stub_user_info;
1613 stub_user_info.user_id = new_user.get_user();
1614
1615 RGWObjVersionTracker objv;
1616 const bool exclusive = !op_state.get_overwrite_new_user(); // overwrite if requested
1617
1618 ret = user_ctl->store_info(stub_user_info, null_yield,
1619 RGWUserCtl::PutParams()
1620 .set_objv_tracker(&objv)
1621 .set_exclusive(exclusive));
1622 if (ret == -EEXIST) {
1623 set_err_msg(err_msg, "user name given by --new-uid already exists");
1624 return ret;
1625 }
1626 if (ret < 0) {
1627 set_err_msg(err_msg, "unable to store new user info");
1628 return ret;
1629 }
1630
1631 RGWAccessControlPolicy policy_instance;
1632 policy_instance.create_default(new_user.get_user(), old_user.get_display_name());
1633
1634 //unlink and link buckets to new user
1635 string marker;
1636 CephContext *cct = store->ctx();
1637 size_t max_buckets = cct->_conf->rgw_list_buckets_max_chunk;
1638 rgw::sal::RGWBucketList buckets;
1639
1640 do {
1641 ret = old_user.list_buckets(marker, "", max_buckets, false, buckets);
1642 if (ret < 0) {
1643 set_err_msg(err_msg, "unable to list user buckets");
1644 return ret;
1645 }
1646
1647 map<std::string, rgw::sal::RGWBucket*>& m = buckets.get_buckets();
1648 std::map<std::string, rgw::sal::RGWBucket*>::iterator it;
1649
1650 for (it = m.begin(); it != m.end(); ++it) {
1651 rgw::sal::RGWBucket* bucket = it->second;
1652 marker = it->first;
1653
1654 ret = bucket->get_bucket_info(null_yield);
1655 if (ret < 0) {
1656 set_err_msg(err_msg, "failed to fetch bucket info for bucket=" + bucket->get_name());
1657 return ret;
1658 }
1659
1660 ret = bucket->set_acl(policy_instance, null_yield);
1661 if (ret < 0) {
1662 set_err_msg(err_msg, "failed to set acl on bucket " + bucket->get_name());
1663 return ret;
1664 }
1665
1666 ret = bucket->link(&new_user, null_yield);
1667 if (ret < 0) {
1668 set_err_msg(err_msg, "failed to link bucket " + bucket->get_name());
1669 return ret;
1670 }
1671
1672 ret = bucket->chown(&new_user, &old_user, null_yield);
1673 if (ret < 0) {
1674 set_err_msg(err_msg, "failed to run bucket chown" + cpp_strerror(-ret));
1675 return ret;
1676 }
1677 }
1678
1679 } while (buckets.is_truncated());
1680
1681 // update the 'stub user' with all of the other fields and rewrite all of the
1682 // associated index objects
1683 RGWUserInfo& user_info = op_state.get_user_info();
1684 user_info.user_id = new_user.get_user();
1685 op_state.objv = objv;
1686
1687 rename_swift_keys(new_user.get_user(), user_info.swift_keys);
1688
1689 return update(op_state, err_msg);
1690 }
1691
1692 int RGWUser::execute_add(RGWUserAdminOpState& op_state, std::string *err_msg)
1693 {
1694 std::string subprocess_msg;
1695 int ret = 0;
1696 bool defer_user_update = true;
1697
1698 RGWUserInfo user_info;
1699
1700 rgw_user& uid = op_state.get_user_id();
1701 std::string user_email = op_state.get_user_email();
1702 std::string display_name = op_state.get_display_name();
1703
1704 // fail if the user exists already
1705 if (op_state.has_existing_user()) {
1706 if (op_state.found_by_email) {
1707 set_err_msg(err_msg, "email: " + user_email +
1708 " is the email address an existing user");
1709 ret = -ERR_EMAIL_EXIST;
1710 } else if (op_state.found_by_key) {
1711 set_err_msg(err_msg, "duplicate key provided");
1712 ret = -ERR_KEY_EXIST;
1713 } else {
1714 set_err_msg(err_msg, "user: " + op_state.user_id.to_str() + " exists");
1715 ret = -EEXIST;
1716 }
1717 return ret;
1718 }
1719
1720 // fail if the user_info has already been populated
1721 if (op_state.is_populated()) {
1722 set_err_msg(err_msg, "cannot overwrite already populated user");
1723 return -EEXIST;
1724 }
1725
1726 // fail if the display name was not included
1727 if (display_name.empty()) {
1728 set_err_msg(err_msg, "no display name specified");
1729 return -EINVAL;
1730 }
1731
1732
1733 // set the user info
1734 user_id = uid;
1735 user_info.user_id = user_id;
1736 user_info.display_name = display_name;
1737 user_info.type = TYPE_RGW;
1738
1739 if (!user_email.empty())
1740 user_info.user_email = user_email;
1741
1742 CephContext *cct = store->ctx();
1743 if (op_state.max_buckets_specified) {
1744 user_info.max_buckets = op_state.get_max_buckets();
1745 } else {
1746 user_info.max_buckets =
1747 cct->_conf.get_val<int64_t>("rgw_user_max_buckets");
1748 }
1749
1750 user_info.suspended = op_state.get_suspension_status();
1751 user_info.admin = op_state.admin;
1752 user_info.system = op_state.system;
1753
1754 if (op_state.op_mask_specified)
1755 user_info.op_mask = op_state.get_op_mask();
1756
1757 if (op_state.has_bucket_quota()) {
1758 user_info.bucket_quota = op_state.get_bucket_quota();
1759 } else {
1760 rgw_apply_default_bucket_quota(user_info.bucket_quota, cct->_conf);
1761 }
1762
1763 if (op_state.temp_url_key_specified) {
1764 map<int, string>::iterator iter;
1765 for (iter = op_state.temp_url_keys.begin();
1766 iter != op_state.temp_url_keys.end(); ++iter) {
1767 user_info.temp_url_keys[iter->first] = iter->second;
1768 }
1769 }
1770
1771 if (op_state.has_user_quota()) {
1772 user_info.user_quota = op_state.get_user_quota();
1773 } else {
1774 rgw_apply_default_user_quota(user_info.user_quota, cct->_conf);
1775 }
1776
1777 if (op_state.default_placement_specified) {
1778 user_info.default_placement = op_state.default_placement;
1779 }
1780
1781 if (op_state.placement_tags_specified) {
1782 user_info.placement_tags = op_state.placement_tags;
1783 }
1784
1785 // update the request
1786 op_state.set_user_info(user_info);
1787 op_state.set_populated();
1788
1789 // update the helper objects
1790 ret = init_members(op_state);
1791 if (ret < 0) {
1792 set_err_msg(err_msg, "unable to initialize user");
1793 return ret;
1794 }
1795
1796 // see if we need to add an access key
1797 if (op_state.has_key_op()) {
1798 ret = keys.add(op_state, &subprocess_msg, defer_user_update);
1799 if (ret < 0) {
1800 set_err_msg(err_msg, "unable to create access key, " + subprocess_msg);
1801 return ret;
1802 }
1803 }
1804
1805 // see if we need to add some caps
1806 if (op_state.has_caps_op()) {
1807 ret = caps.add(op_state, &subprocess_msg, defer_user_update);
1808 if (ret < 0) {
1809 set_err_msg(err_msg, "unable to add user capabilities, " + subprocess_msg);
1810 return ret;
1811 }
1812 }
1813
1814 ret = update(op_state, err_msg);
1815 if (ret < 0)
1816 return ret;
1817
1818 return 0;
1819 }
1820
1821
1822 int RGWUser::add(RGWUserAdminOpState& op_state, std::string *err_msg)
1823 {
1824 std::string subprocess_msg;
1825 int ret;
1826
1827 ret = check_op(op_state, &subprocess_msg);
1828 if (ret < 0) {
1829 set_err_msg(err_msg, "unable to parse parameters, " + subprocess_msg);
1830 return ret;
1831 }
1832
1833 ret = execute_add(op_state, &subprocess_msg);
1834 if (ret < 0) {
1835 set_err_msg(err_msg, "unable to create user, " + subprocess_msg);
1836 return ret;
1837 }
1838
1839 return 0;
1840 }
1841
1842 int RGWUser::rename(RGWUserAdminOpState& op_state, std::string *err_msg)
1843 {
1844 std::string subprocess_msg;
1845 int ret;
1846
1847 ret = check_op(op_state, &subprocess_msg);
1848 if (ret < 0) {
1849 set_err_msg(err_msg, "unable to parse parameters, " + subprocess_msg);
1850 return ret;
1851 }
1852
1853 ret = execute_rename(op_state, &subprocess_msg);
1854 if (ret < 0) {
1855 set_err_msg(err_msg, "unable to rename user, " + subprocess_msg);
1856 return ret;
1857 }
1858
1859 return 0;
1860 }
1861
1862 int RGWUser::execute_remove(RGWUserAdminOpState& op_state, std::string *err_msg, optional_yield y)
1863 {
1864 int ret;
1865
1866 bool purge_data = op_state.will_purge_data();
1867 rgw_user& uid = op_state.get_user_id();
1868 RGWUserInfo user_info = op_state.get_user_info();
1869
1870 if (!op_state.has_existing_user()) {
1871 set_err_msg(err_msg, "user does not exist");
1872 return -ENOENT;
1873 }
1874
1875 rgw::sal::RGWBucketList buckets;
1876 string marker;
1877 CephContext *cct = store->ctx();
1878 size_t max_buckets = cct->_conf->rgw_list_buckets_max_chunk;
1879 do {
1880 ret = rgw_read_user_buckets(store, uid, buckets, marker, string(),
1881 max_buckets, false);
1882 if (ret < 0) {
1883 set_err_msg(err_msg, "unable to read user bucket info");
1884 return ret;
1885 }
1886
1887 std::map<std::string, rgw::sal::RGWBucket*>& m = buckets.get_buckets();
1888 if (!m.empty() && !purge_data) {
1889 set_err_msg(err_msg, "must specify purge data to remove user with buckets");
1890 return -EEXIST; // change to code that maps to 409: conflict
1891 }
1892
1893 std::map<std::string, rgw::sal::RGWBucket*>::iterator it;
1894 for (it = m.begin(); it != m.end(); ++it) {
1895 ret = it->second->remove_bucket(true, y);
1896 if (ret < 0) {
1897 set_err_msg(err_msg, "unable to delete user data");
1898 return ret;
1899 }
1900
1901 marker = it->first;
1902 }
1903
1904 } while (buckets.is_truncated());
1905
1906 ret = user_ctl->remove_info(user_info, y, RGWUserCtl::RemoveParams()
1907 .set_objv_tracker(&op_state.objv));
1908 if (ret < 0) {
1909 set_err_msg(err_msg, "unable to remove user from RADOS");
1910 return ret;
1911 }
1912
1913 op_state.clear_populated();
1914 clear_populated();
1915
1916 return 0;
1917 }
1918
1919 int RGWUser::remove(RGWUserAdminOpState& op_state, optional_yield y, std::string *err_msg)
1920 {
1921 std::string subprocess_msg;
1922 int ret;
1923
1924 ret = check_op(op_state, &subprocess_msg);
1925 if (ret < 0) {
1926 set_err_msg(err_msg, "unable to parse parameters, " + subprocess_msg);
1927 return ret;
1928 }
1929
1930 ret = execute_remove(op_state, &subprocess_msg, y);
1931 if (ret < 0) {
1932 set_err_msg(err_msg, "unable to remove user, " + subprocess_msg);
1933 return ret;
1934 }
1935
1936 return 0;
1937 }
1938
1939 int RGWUser::execute_modify(RGWUserAdminOpState& op_state, std::string *err_msg)
1940 {
1941 bool populated = op_state.is_populated();
1942 int ret = 0;
1943 std::string subprocess_msg;
1944 std::string op_email = op_state.get_user_email();
1945 std::string display_name = op_state.get_display_name();
1946
1947 RGWUserInfo user_info;
1948 RGWUserInfo duplicate_check;
1949
1950 // ensure that the user info has been populated or is populate-able
1951 if (!op_state.has_existing_user() && !populated) {
1952 set_err_msg(err_msg, "user not found");
1953 return -ENOENT;
1954 }
1955
1956 // if the user hasn't already been populated...attempt to
1957 if (!populated) {
1958 ret = init(op_state);
1959 if (ret < 0) {
1960 set_err_msg(err_msg, "unable to retrieve user info");
1961 return ret;
1962 }
1963 }
1964
1965 // ensure that we can modify the user's attributes
1966 if (user_id.compare(RGW_USER_ANON_ID) == 0) {
1967 set_err_msg(err_msg, "unable to modify anonymous user's info");
1968 return -EACCES;
1969 }
1970
1971 user_info = old_info;
1972
1973 std::string old_email = old_info.user_email;
1974 if (!op_email.empty()) {
1975 // make sure we are not adding a duplicate email
1976 if (old_email != op_email) {
1977 ret = rgw_get_user_info_by_email(user_ctl, op_email, duplicate_check);
1978 if (ret >= 0 && duplicate_check.user_id.compare(user_id) != 0) {
1979 set_err_msg(err_msg, "cannot add duplicate email");
1980 return -ERR_EMAIL_EXIST;
1981 }
1982 }
1983 user_info.user_email = op_email;
1984 } else if (op_email.empty() && op_state.user_email_specified) {
1985 ldout(store->ctx(), 10) << "removing email index: " << user_info.user_email << dendl;
1986 /* will be physically removed later when calling update() */
1987 user_info.user_email.clear();
1988 }
1989
1990 // update the remaining user info
1991 if (!display_name.empty())
1992 user_info.display_name = display_name;
1993
1994 if (op_state.max_buckets_specified)
1995 user_info.max_buckets = op_state.get_max_buckets();
1996
1997 if (op_state.admin_specified)
1998 user_info.admin = op_state.admin;
1999
2000 if (op_state.system_specified)
2001 user_info.system = op_state.system;
2002
2003 if (op_state.temp_url_key_specified) {
2004 map<int, string>::iterator iter;
2005 for (iter = op_state.temp_url_keys.begin();
2006 iter != op_state.temp_url_keys.end(); ++iter) {
2007 user_info.temp_url_keys[iter->first] = iter->second;
2008 }
2009 }
2010
2011 if (op_state.op_mask_specified)
2012 user_info.op_mask = op_state.get_op_mask();
2013
2014 if (op_state.has_bucket_quota())
2015 user_info.bucket_quota = op_state.get_bucket_quota();
2016
2017 if (op_state.has_user_quota())
2018 user_info.user_quota = op_state.get_user_quota();
2019
2020 if (op_state.has_suspension_op()) {
2021 __u8 suspended = op_state.get_suspension_status();
2022 user_info.suspended = suspended;
2023
2024 rgw::sal::RGWBucketList buckets;
2025
2026 if (user_id.empty()) {
2027 set_err_msg(err_msg, "empty user id passed...aborting");
2028 return -EINVAL;
2029 }
2030
2031 string marker;
2032 CephContext *cct = store->ctx();
2033 size_t max_buckets = cct->_conf->rgw_list_buckets_max_chunk;
2034 do {
2035 ret = rgw_read_user_buckets(store, user_id, buckets, marker, string(),
2036 max_buckets, false);
2037 if (ret < 0) {
2038 set_err_msg(err_msg, "could not get buckets for uid: " + user_id.to_str());
2039 return ret;
2040 }
2041
2042 std::map<std::string, rgw::sal::RGWBucket*>& m = buckets.get_buckets();
2043 std::map<std::string, rgw::sal::RGWBucket*>::iterator iter;
2044
2045 vector<rgw_bucket> bucket_names;
2046 for (iter = m.begin(); iter != m.end(); ++iter) {
2047 rgw::sal::RGWBucket* obj = iter->second;
2048 bucket_names.push_back(obj->get_bi());
2049
2050 marker = iter->first;
2051 }
2052
2053 ret = store->getRados()->set_buckets_enabled(bucket_names, !suspended);
2054 if (ret < 0) {
2055 set_err_msg(err_msg, "failed to modify bucket");
2056 return ret;
2057 }
2058
2059 } while (buckets.is_truncated());
2060 }
2061
2062 if (op_state.mfa_ids_specified) {
2063 user_info.mfa_ids = op_state.mfa_ids;
2064 }
2065
2066 if (op_state.default_placement_specified) {
2067 user_info.default_placement = op_state.default_placement;
2068 }
2069
2070 if (op_state.placement_tags_specified) {
2071 user_info.placement_tags = op_state.placement_tags;
2072 }
2073
2074 op_state.set_user_info(user_info);
2075
2076 // if we're supposed to modify keys, do so
2077 if (op_state.has_key_op()) {
2078 ret = keys.add(op_state, &subprocess_msg, true);
2079 if (ret < 0) {
2080 set_err_msg(err_msg, "unable to create or modify keys, " + subprocess_msg);
2081 return ret;
2082 }
2083 }
2084
2085 ret = update(op_state, err_msg);
2086 if (ret < 0)
2087 return ret;
2088
2089 return 0;
2090 }
2091
2092 int RGWUser::modify(RGWUserAdminOpState& op_state, std::string *err_msg)
2093 {
2094 std::string subprocess_msg;
2095 int ret;
2096
2097 ret = check_op(op_state, &subprocess_msg);
2098 if (ret < 0) {
2099 set_err_msg(err_msg, "unable to parse parameters, " + subprocess_msg);
2100 return ret;
2101 }
2102
2103 ret = execute_modify(op_state, &subprocess_msg);
2104 if (ret < 0) {
2105 set_err_msg(err_msg, "unable to modify user, " + subprocess_msg);
2106 return ret;
2107 }
2108
2109 return 0;
2110 }
2111
2112 int RGWUser::info(RGWUserAdminOpState& op_state, RGWUserInfo& fetched_info, std::string *err_msg)
2113 {
2114 int ret = init(op_state);
2115 if (ret < 0) {
2116 set_err_msg(err_msg, "unable to fetch user info");
2117 return ret;
2118 }
2119
2120 fetched_info = op_state.get_user_info();
2121
2122 return 0;
2123 }
2124
2125 int RGWUser::info(RGWUserInfo& fetched_info, std::string *err_msg)
2126 {
2127 if (!is_populated()) {
2128 set_err_msg(err_msg, "no user info saved");
2129 return -EINVAL;
2130 }
2131
2132 fetched_info = old_info;
2133
2134 return 0;
2135 }
2136
2137 int RGWUser::list(RGWUserAdminOpState& op_state, RGWFormatterFlusher& flusher)
2138 {
2139 Formatter *formatter = flusher.get_formatter();
2140 void *handle = nullptr;
2141 std::string metadata_key = "user";
2142 if (op_state.max_entries > 1000) {
2143 op_state.max_entries = 1000;
2144 }
2145
2146 auto meta_mgr = store->ctl()->meta.mgr;
2147
2148 int ret = meta_mgr->list_keys_init(metadata_key, op_state.marker, &handle);
2149 if (ret < 0) {
2150 return ret;
2151 }
2152
2153 bool truncated = false;
2154 uint64_t count = 0;
2155 uint64_t left = 0;
2156 flusher.start(0);
2157
2158 // open the result object section
2159 formatter->open_object_section("result");
2160
2161 // open the user id list array section
2162 formatter->open_array_section("keys");
2163 do {
2164 std::list<std::string> keys;
2165 left = op_state.max_entries - count;
2166 ret = meta_mgr->list_keys_next(handle, left, keys, &truncated);
2167 if (ret < 0 && ret != -ENOENT) {
2168 return ret;
2169 } if (ret != -ENOENT) {
2170 for (std::list<std::string>::iterator iter = keys.begin(); iter != keys.end(); ++iter) {
2171 formatter->dump_string("key", *iter);
2172 ++count;
2173 }
2174 }
2175 } while (truncated && left > 0);
2176 // close user id list section
2177 formatter->close_section();
2178
2179 formatter->dump_bool("truncated", truncated);
2180 formatter->dump_int("count", count);
2181 if (truncated) {
2182 formatter->dump_string("marker", meta_mgr->get_marker(handle));
2183 }
2184
2185 // close result object section
2186 formatter->close_section();
2187
2188 meta_mgr->list_keys_complete(handle);
2189
2190 flusher.flush();
2191 return 0;
2192 }
2193
2194 int RGWUserAdminOp_User::list(rgw::sal::RGWRadosStore *store, RGWUserAdminOpState& op_state,
2195 RGWFormatterFlusher& flusher)
2196 {
2197 RGWUser user;
2198
2199 int ret = user.init_storage(store);
2200 if (ret < 0)
2201 return ret;
2202
2203 ret = user.list(op_state, flusher);
2204 if (ret < 0)
2205 return ret;
2206
2207 return 0;
2208 }
2209
2210 int RGWUserAdminOp_User::info(rgw::sal::RGWRadosStore *store, RGWUserAdminOpState& op_state,
2211 RGWFormatterFlusher& flusher)
2212 {
2213 RGWUserInfo info;
2214 RGWUser user;
2215
2216 int ret = user.init(store, op_state);
2217 if (ret < 0)
2218 return ret;
2219
2220 if (!op_state.has_existing_user())
2221 return -ERR_NO_SUCH_USER;
2222
2223 Formatter *formatter = flusher.get_formatter();
2224
2225 ret = user.info(info, NULL);
2226 if (ret < 0)
2227 return ret;
2228
2229 if (op_state.sync_stats) {
2230 ret = rgw_user_sync_all_stats(store, info.user_id);
2231 if (ret < 0) {
2232 return ret;
2233 }
2234 }
2235
2236 RGWStorageStats stats;
2237 RGWStorageStats *arg_stats = NULL;
2238 if (op_state.fetch_stats) {
2239 int ret = store->ctl()->user->read_stats(info.user_id, &stats);
2240 if (ret < 0 && ret != -ENOENT) {
2241 return ret;
2242 }
2243
2244 arg_stats = &stats;
2245 }
2246
2247 if (formatter) {
2248 flusher.start(0);
2249
2250 dump_user_info(formatter, info, arg_stats);
2251 flusher.flush();
2252 }
2253
2254 return 0;
2255 }
2256
2257 int RGWUserAdminOp_User::create(rgw::sal::RGWRadosStore *store, RGWUserAdminOpState& op_state,
2258 RGWFormatterFlusher& flusher)
2259 {
2260 RGWUserInfo info;
2261 RGWUser user;
2262 int ret = user.init(store, op_state);
2263 if (ret < 0)
2264 return ret;
2265
2266 Formatter *formatter = flusher.get_formatter();
2267
2268 ret = user.add(op_state, NULL);
2269 if (ret < 0) {
2270 if (ret == -EEXIST)
2271 ret = -ERR_USER_EXIST;
2272 return ret;
2273 }
2274
2275 ret = user.info(info, NULL);
2276 if (ret < 0)
2277 return ret;
2278
2279 if (formatter) {
2280 flusher.start(0);
2281
2282 dump_user_info(formatter, info);
2283 flusher.flush();
2284 }
2285
2286 return 0;
2287 }
2288
2289 int RGWUserAdminOp_User::modify(rgw::sal::RGWRadosStore *store, RGWUserAdminOpState& op_state,
2290 RGWFormatterFlusher& flusher)
2291 {
2292 RGWUserInfo info;
2293 RGWUser user;
2294 int ret = user.init(store, op_state);
2295 if (ret < 0)
2296 return ret;
2297 Formatter *formatter = flusher.get_formatter();
2298
2299 ret = user.modify(op_state, NULL);
2300 if (ret < 0) {
2301 if (ret == -ENOENT)
2302 ret = -ERR_NO_SUCH_USER;
2303 return ret;
2304 }
2305
2306 ret = user.info(info, NULL);
2307 if (ret < 0)
2308 return ret;
2309
2310 if (formatter) {
2311 flusher.start(0);
2312
2313 dump_user_info(formatter, info);
2314 flusher.flush();
2315 }
2316
2317 return 0;
2318 }
2319
2320 int RGWUserAdminOp_User::remove(rgw::sal::RGWRadosStore *store, RGWUserAdminOpState& op_state,
2321 RGWFormatterFlusher& flusher, optional_yield y)
2322 {
2323 RGWUserInfo info;
2324 RGWUser user;
2325 int ret = user.init(store, op_state);
2326 if (ret < 0)
2327 return ret;
2328
2329
2330 ret = user.remove(op_state, y, NULL);
2331
2332 if (ret == -ENOENT)
2333 ret = -ERR_NO_SUCH_USER;
2334 return ret;
2335 }
2336
2337 int RGWUserAdminOp_Subuser::create(rgw::sal::RGWRadosStore *store, RGWUserAdminOpState& op_state,
2338 RGWFormatterFlusher& flusher)
2339 {
2340 RGWUserInfo info;
2341 RGWUser user;
2342 int ret = user.init(store, op_state);
2343 if (ret < 0)
2344 return ret;
2345
2346 if (!op_state.has_existing_user())
2347 return -ERR_NO_SUCH_USER;
2348
2349 Formatter *formatter = flusher.get_formatter();
2350
2351 ret = user.subusers.add(op_state, NULL);
2352 if (ret < 0)
2353 return ret;
2354
2355 ret = user.info(info, NULL);
2356 if (ret < 0)
2357 return ret;
2358
2359 if (formatter) {
2360 flusher.start(0);
2361
2362 dump_subusers_info(formatter, info);
2363 flusher.flush();
2364 }
2365
2366 return 0;
2367 }
2368
2369 int RGWUserAdminOp_Subuser::modify(rgw::sal::RGWRadosStore *store, RGWUserAdminOpState& op_state,
2370 RGWFormatterFlusher& flusher)
2371 {
2372 RGWUserInfo info;
2373 RGWUser user;
2374 int ret = user.init(store, op_state);
2375 if (ret < 0)
2376 return ret;
2377
2378 if (!op_state.has_existing_user())
2379 return -ERR_NO_SUCH_USER;
2380
2381 Formatter *formatter = flusher.get_formatter();
2382
2383 ret = user.subusers.modify(op_state, NULL);
2384 if (ret < 0)
2385 return ret;
2386
2387 ret = user.info(info, NULL);
2388 if (ret < 0)
2389 return ret;
2390
2391 if (formatter) {
2392 flusher.start(0);
2393
2394 dump_subusers_info(formatter, info);
2395 flusher.flush();
2396 }
2397
2398 return 0;
2399 }
2400
2401 int RGWUserAdminOp_Subuser::remove(rgw::sal::RGWRadosStore *store, RGWUserAdminOpState& op_state,
2402 RGWFormatterFlusher& flusher)
2403 {
2404 RGWUserInfo info;
2405 RGWUser user;
2406 int ret = user.init(store, op_state);
2407 if (ret < 0)
2408 return ret;
2409
2410
2411 if (!op_state.has_existing_user())
2412 return -ERR_NO_SUCH_USER;
2413
2414 ret = user.subusers.remove(op_state, NULL);
2415 if (ret < 0)
2416 return ret;
2417
2418 return 0;
2419 }
2420
2421 int RGWUserAdminOp_Key::create(rgw::sal::RGWRadosStore *store, RGWUserAdminOpState& op_state,
2422 RGWFormatterFlusher& flusher)
2423 {
2424 RGWUserInfo info;
2425 RGWUser user;
2426 int ret = user.init(store, op_state);
2427 if (ret < 0)
2428 return ret;
2429
2430 if (!op_state.has_existing_user())
2431 return -ERR_NO_SUCH_USER;
2432
2433 Formatter *formatter = flusher.get_formatter();
2434
2435 ret = user.keys.add(op_state, NULL);
2436 if (ret < 0)
2437 return ret;
2438
2439 ret = user.info(info, NULL);
2440 if (ret < 0)
2441 return ret;
2442
2443 if (formatter) {
2444 flusher.start(0);
2445
2446 int key_type = op_state.get_key_type();
2447
2448 if (key_type == KEY_TYPE_SWIFT)
2449 dump_swift_keys_info(formatter, info);
2450
2451 else if (key_type == KEY_TYPE_S3)
2452 dump_access_keys_info(formatter, info);
2453
2454 flusher.flush();
2455 }
2456
2457 return 0;
2458 }
2459
2460 int RGWUserAdminOp_Key::remove(rgw::sal::RGWRadosStore *store, RGWUserAdminOpState& op_state,
2461 RGWFormatterFlusher& flusher)
2462 {
2463 RGWUserInfo info;
2464 RGWUser user;
2465 int ret = user.init(store, op_state);
2466 if (ret < 0)
2467 return ret;
2468
2469 if (!op_state.has_existing_user())
2470 return -ERR_NO_SUCH_USER;
2471
2472
2473 ret = user.keys.remove(op_state, NULL);
2474 if (ret < 0)
2475 return ret;
2476
2477 return 0;
2478 }
2479
2480 int RGWUserAdminOp_Caps::add(rgw::sal::RGWRadosStore *store, RGWUserAdminOpState& op_state,
2481 RGWFormatterFlusher& flusher)
2482 {
2483 RGWUserInfo info;
2484 RGWUser user;
2485 int ret = user.init(store, op_state);
2486 if (ret < 0)
2487 return ret;
2488
2489 if (!op_state.has_existing_user())
2490 return -ERR_NO_SUCH_USER;
2491
2492 Formatter *formatter = flusher.get_formatter();
2493
2494 ret = user.caps.add(op_state, NULL);
2495 if (ret < 0)
2496 return ret;
2497
2498 ret = user.info(info, NULL);
2499 if (ret < 0)
2500 return ret;
2501
2502 if (formatter) {
2503 flusher.start(0);
2504
2505 info.caps.dump(formatter);
2506 flusher.flush();
2507 }
2508
2509 return 0;
2510 }
2511
2512
2513 int RGWUserAdminOp_Caps::remove(rgw::sal::RGWRadosStore *store, RGWUserAdminOpState& op_state,
2514 RGWFormatterFlusher& flusher)
2515 {
2516 RGWUserInfo info;
2517 RGWUser user;
2518 int ret = user.init(store, op_state);
2519 if (ret < 0)
2520 return ret;
2521
2522 if (!op_state.has_existing_user())
2523 return -ERR_NO_SUCH_USER;
2524
2525 Formatter *formatter = flusher.get_formatter();
2526
2527 ret = user.caps.remove(op_state, NULL);
2528 if (ret < 0)
2529 return ret;
2530
2531 ret = user.info(info, NULL);
2532 if (ret < 0)
2533 return ret;
2534
2535 if (formatter) {
2536 flusher.start(0);
2537
2538 info.caps.dump(formatter);
2539 flusher.flush();
2540 }
2541
2542 return 0;
2543 }
2544
2545 class RGWUserMetadataHandler : public RGWMetadataHandler_GenericMetaBE {
2546 public:
2547 struct Svc {
2548 RGWSI_User *user{nullptr};
2549 } svc;
2550
2551 RGWUserMetadataHandler(RGWSI_User *user_svc) {
2552 base_init(user_svc->ctx(), user_svc->get_be_handler());
2553 svc.user = user_svc;
2554 }
2555
2556 string get_type() override { return "user"; }
2557
2558 int do_get(RGWSI_MetaBackend_Handler::Op *op, string& entry, RGWMetadataObject **obj, optional_yield y) override {
2559 RGWUserCompleteInfo uci;
2560 RGWObjVersionTracker objv_tracker;
2561 real_time mtime;
2562
2563 rgw_user user = RGWSI_User::user_from_meta_key(entry);
2564
2565 int ret = svc.user->read_user_info(op->ctx(), user, &uci.info, &objv_tracker,
2566 &mtime, nullptr, &uci.attrs,
2567 y);
2568 if (ret < 0) {
2569 return ret;
2570 }
2571
2572 RGWUserMetadataObject *mdo = new RGWUserMetadataObject(uci, objv_tracker.read_version, mtime);
2573 *obj = mdo;
2574
2575 return 0;
2576 }
2577
2578 RGWMetadataObject *get_meta_obj(JSONObj *jo, const obj_version& objv, const ceph::real_time& mtime) override {
2579 RGWUserCompleteInfo uci;
2580
2581 try {
2582 decode_json_obj(uci, jo);
2583 } catch (JSONDecoder::err& e) {
2584 return nullptr;
2585 }
2586
2587 return new RGWUserMetadataObject(uci, objv, mtime);
2588 }
2589
2590 int do_put(RGWSI_MetaBackend_Handler::Op *op, string& entry,
2591 RGWMetadataObject *obj,
2592 RGWObjVersionTracker& objv_tracker,
2593 optional_yield y,
2594 RGWMDLogSyncType type) override;
2595
2596 int do_remove(RGWSI_MetaBackend_Handler::Op *op, string& entry, RGWObjVersionTracker& objv_tracker,
2597 optional_yield y) {
2598 RGWUserInfo info;
2599
2600 rgw_user user = RGWSI_User::user_from_meta_key(entry);
2601
2602 int ret = svc.user->read_user_info(op->ctx(), user, &info, nullptr,
2603 nullptr, nullptr, nullptr,
2604 y);
2605 if (ret < 0) {
2606 return ret;
2607 }
2608
2609 return svc.user->remove_user_info(op->ctx(), info, &objv_tracker,
2610 y);
2611 }
2612 };
2613
2614 class RGWMetadataHandlerPut_User : public RGWMetadataHandlerPut_SObj
2615 {
2616 RGWUserMetadataHandler *uhandler;
2617 RGWUserMetadataObject *uobj;
2618 public:
2619 RGWMetadataHandlerPut_User(RGWUserMetadataHandler *_handler,
2620 RGWSI_MetaBackend_Handler::Op *op, string& entry,
2621 RGWMetadataObject *obj, RGWObjVersionTracker& objv_tracker,
2622 optional_yield y,
2623 RGWMDLogSyncType type) : RGWMetadataHandlerPut_SObj(_handler, op, entry, obj, objv_tracker, y, type),
2624 uhandler(_handler) {
2625 uobj = static_cast<RGWUserMetadataObject *>(obj);
2626 }
2627
2628 int put_checked() override;
2629 };
2630
2631 int RGWUserMetadataHandler::do_put(RGWSI_MetaBackend_Handler::Op *op, string& entry,
2632 RGWMetadataObject *obj,
2633 RGWObjVersionTracker& objv_tracker,
2634 optional_yield y,
2635 RGWMDLogSyncType type)
2636 {
2637 RGWMetadataHandlerPut_User put_op(this, op, entry, obj, objv_tracker, y, type);
2638 return do_put_operate(&put_op);
2639 }
2640
2641 int RGWMetadataHandlerPut_User::put_checked()
2642 {
2643 RGWUserMetadataObject *orig_obj = static_cast<RGWUserMetadataObject *>(old_obj);
2644 RGWUserCompleteInfo& uci = uobj->get_uci();
2645
2646 map<string, bufferlist> *pattrs{nullptr};
2647 if (uci.has_attrs) {
2648 pattrs = &uci.attrs;
2649 }
2650
2651 RGWUserInfo *pold_info = (orig_obj ? &orig_obj->get_uci().info : nullptr);
2652
2653 auto mtime = obj->get_mtime();
2654
2655 int ret = uhandler->svc.user->store_user_info(op->ctx(), uci.info, pold_info,
2656 &objv_tracker, mtime,
2657 false, pattrs, y);
2658 if (ret < 0) {
2659 return ret;
2660 }
2661
2662 return STATUS_APPLIED;
2663 }
2664
2665
2666 RGWUserCtl::RGWUserCtl(RGWSI_Zone *zone_svc,
2667 RGWSI_User *user_svc,
2668 RGWUserMetadataHandler *_umhandler) : umhandler(_umhandler) {
2669 svc.zone = zone_svc;
2670 svc.user = user_svc;
2671 be_handler = umhandler->get_be_handler();
2672 }
2673
2674 template <class T>
2675 class optional_default
2676 {
2677 const std::optional<T>& opt;
2678 std::optional<T> def;
2679 const T *p;
2680 public:
2681 optional_default(const std::optional<T>& _o) : opt(_o) {
2682 if (opt) {
2683 p = &(*opt);
2684 } else {
2685 def = T();
2686 p = &(*def);
2687 }
2688 }
2689
2690 const T *operator->() {
2691 return p;
2692 }
2693
2694 const T& operator*() {
2695 return *p;
2696 }
2697 };
2698
2699 int RGWUserCtl::get_info_by_uid(const rgw_user& uid,
2700 RGWUserInfo *info,
2701 optional_yield y,
2702 const GetParams& params)
2703
2704 {
2705 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
2706 return svc.user->read_user_info(op->ctx(),
2707 uid,
2708 info,
2709 params.objv_tracker,
2710 params.mtime,
2711 params.cache_info,
2712 params.attrs,
2713 y);
2714 });
2715 }
2716
2717 int RGWUserCtl::get_info_by_email(const string& email,
2718 RGWUserInfo *info,
2719 optional_yield y,
2720 const GetParams& params)
2721 {
2722 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
2723 return svc.user->get_user_info_by_email(op->ctx(), email,
2724 info,
2725 params.objv_tracker,
2726 params.mtime,
2727 y);
2728 });
2729 }
2730
2731 int RGWUserCtl::get_info_by_swift(const string& swift_name,
2732 RGWUserInfo *info,
2733 optional_yield y,
2734 const GetParams& params)
2735 {
2736 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
2737 return svc.user->get_user_info_by_swift(op->ctx(), swift_name,
2738 info,
2739 params.objv_tracker,
2740 params.mtime,
2741 y);
2742 });
2743 }
2744
2745 int RGWUserCtl::get_info_by_access_key(const string& access_key,
2746 RGWUserInfo *info,
2747 optional_yield y,
2748 const GetParams& params)
2749 {
2750 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
2751 return svc.user->get_user_info_by_access_key(op->ctx(), access_key,
2752 info,
2753 params.objv_tracker,
2754 params.mtime,
2755 y);
2756 });
2757 }
2758
2759 int RGWUserCtl::get_attrs_by_uid(const rgw_user& user_id,
2760 map<string, bufferlist> *pattrs,
2761 optional_yield y,
2762 RGWObjVersionTracker *objv_tracker)
2763 {
2764 RGWUserInfo user_info;
2765
2766 return get_info_by_uid(user_id, &user_info, y, RGWUserCtl::GetParams()
2767 .set_attrs(pattrs)
2768 .set_objv_tracker(objv_tracker));
2769 }
2770
2771 int RGWUserCtl::store_info(const RGWUserInfo& info, optional_yield y,
2772 const PutParams& params)
2773 {
2774 string key = RGWSI_User::get_meta_key(info.user_id);
2775
2776 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
2777 return svc.user->store_user_info(op->ctx(), info,
2778 params.old_info,
2779 params.objv_tracker,
2780 params.mtime,
2781 params.exclusive,
2782 params.attrs,
2783 y);
2784 });
2785 }
2786
2787 int RGWUserCtl::remove_info(const RGWUserInfo& info, optional_yield y,
2788 const RemoveParams& params)
2789
2790 {
2791 string key = RGWSI_User::get_meta_key(info.user_id);
2792
2793 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
2794 return svc.user->remove_user_info(op->ctx(), info,
2795 params.objv_tracker,
2796 y);
2797 });
2798 }
2799
2800 int RGWUserCtl::add_bucket(const rgw_user& user,
2801 const rgw_bucket& bucket,
2802 ceph::real_time creation_time)
2803
2804 {
2805 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
2806 return svc.user->add_bucket(op->ctx(), user, bucket, creation_time);
2807 });
2808 }
2809
2810 int RGWUserCtl::remove_bucket(const rgw_user& user,
2811 const rgw_bucket& bucket)
2812
2813 {
2814 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
2815 return svc.user->remove_bucket(op->ctx(), user, bucket);
2816 });
2817 }
2818
2819 int RGWUserCtl::list_buckets(const rgw_user& user,
2820 const string& marker,
2821 const string& end_marker,
2822 uint64_t max,
2823 bool need_stats,
2824 RGWUserBuckets *buckets,
2825 bool *is_truncated,
2826 uint64_t default_max)
2827 {
2828 if (!max) {
2829 max = default_max;
2830 }
2831
2832 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
2833 int ret = svc.user->list_buckets(op->ctx(), user, marker, end_marker,
2834 max, buckets, is_truncated);
2835 if (ret < 0) {
2836 return ret;
2837 }
2838 if (need_stats) {
2839 map<string, RGWBucketEnt>& m = buckets->get_buckets();
2840 ret = ctl.bucket->read_buckets_stats(m, null_yield);
2841 if (ret < 0 && ret != -ENOENT) {
2842 ldout(svc.user->ctx(), 0) << "ERROR: could not get stats for buckets" << dendl;
2843 return ret;
2844 }
2845 }
2846 return 0;
2847 });
2848 }
2849
2850 int RGWUserCtl::flush_bucket_stats(const rgw_user& user,
2851 const RGWBucketEnt& ent)
2852 {
2853 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
2854 return svc.user->flush_bucket_stats(op->ctx(), user, ent);
2855 });
2856 }
2857
2858 int RGWUserCtl::complete_flush_stats(const rgw_user& user)
2859 {
2860 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
2861 return svc.user->complete_flush_stats(op->ctx(), user);
2862 });
2863 }
2864
2865 int RGWUserCtl::reset_stats(const rgw_user& user)
2866 {
2867 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
2868 return svc.user->reset_bucket_stats(op->ctx(), user);
2869 });
2870 }
2871
2872 int RGWUserCtl::read_stats(const rgw_user& user, RGWStorageStats *stats,
2873 ceph::real_time *last_stats_sync,
2874 ceph::real_time *last_stats_update)
2875 {
2876 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
2877 return svc.user->read_stats(op->ctx(), user, stats,
2878 last_stats_sync, last_stats_update);
2879 });
2880 }
2881
2882 int RGWUserCtl::read_stats_async(const rgw_user& user, RGWGetUserStats_CB *cb)
2883 {
2884 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
2885 return svc.user->read_stats_async(op->ctx(), user, cb);
2886 });
2887 }
2888
2889 RGWMetadataHandler *RGWUserMetaHandlerAllocator::alloc(RGWSI_User *user_svc) {
2890 return new RGWUserMetadataHandler(user_svc);
2891 }
2892