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