]> git.proxmox.com Git - ceph.git/blame - ceph/src/rgw/rgw_user.cc
import 15.2.0 Octopus source
[ceph.git] / ceph / src / rgw / rgw_user.cc
CommitLineData
7c673cae 1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
9f95a23c 2// vim: ts=8 sw=2 smarttab ft=cpp
7c673cae
FG
3
4#include <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"
9f95a23c 14#include "rgw_sal.h"
11fdf7f2 15#include "rgw_zone.h"
7c673cae
FG
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"
f64942e4 26#include "rgw_quota.h"
7c673cae 27
11fdf7f2
TL
28#include "services/svc_zone.h"
29#include "services/svc_sys_obj.h"
30#include "services/svc_sys_obj_cache.h"
9f95a23c
TL
31#include "services/svc_user.h"
32#include "services/svc_meta.h"
11fdf7f2 33
7c673cae
FG
34#define dout_subsys ceph_subsys_rgw
35
7c673cae
FG
36
37
11fdf7f2 38extern void op_type_to_str(uint32_t mask, char *buf, int len);
7c673cae
FG
39
40/**
41 * Get the anonymous (ie, unauthenticated) user info.
42 */
43void 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
9f95a23c 50int rgw_user_sync_all_stats(rgw::sal::RGWRadosStore *store, const rgw_user& user_id)
7c673cae 51{
9f95a23c
TL
52 rgw::sal::RGWBucketList user_buckets;
53 rgw::sal::RGWRadosUser user(store, user_id);
54
7c673cae
FG
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;
7c673cae
FG
60
61 do {
9f95a23c 62 ret = user.list_buckets(marker, string(), max_entries, false, user_buckets);
7c673cae
FG
63 if (ret < 0) {
64 ldout(cct, 0) << "failed to read user buckets: ret=" << ret << dendl;
65 return ret;
66 }
9f95a23c
TL
67 map<string, rgw::sal::RGWBucket*>& buckets = user_buckets.get_buckets();
68 for (map<string, rgw::sal::RGWBucket*>::iterator i = buckets.begin();
7c673cae
FG
69 i != buckets.end();
70 ++i) {
71 marker = i->first;
72
9f95a23c 73 rgw::sal::RGWBucket* bucket = i->second;
7c673cae 74
9f95a23c 75 ret = bucket->get_bucket_info(null_yield);
7c673cae 76 if (ret < 0) {
9f95a23c 77 ldout(cct, 0) << "ERROR: could not read bucket info: bucket=" << bucket << " ret=" << ret << dendl;
7c673cae
FG
78 continue;
79 }
9f95a23c 80 ret = bucket->sync_user_stats();
7c673cae
FG
81 if (ret < 0) {
82 ldout(cct, 0) << "ERROR: could not sync bucket stats: ret=" << ret << dendl;
83 return ret;
84 }
9f95a23c 85 ret = bucket->check_bucket_shards();
224ce89b
WB
86 if (ret < 0) {
87 ldout(cct, 0) << "ERROR in check_bucket_shards: " << cpp_strerror(-ret)<< dendl;
88 }
7c673cae
FG
89 }
90 } while (is_truncated);
91
9f95a23c 92 ret = store->ctl()->user->complete_flush_stats(user.get_user());
7c673cae
FG
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
9f95a23c 101int rgw_user_get_all_buckets_stats(rgw::sal::RGWRadosStore *store, const rgw_user& user_id, map<string, cls_user_bucket_entry>& buckets_usage_map)
c07f9fc5
FG
102{
103 CephContext *cct = store->ctx();
104 size_t max_entries = cct->_conf->rgw_list_buckets_max_chunk;
105 bool done;
c07f9fc5
FG
106 string marker;
107 int ret;
108
109 do {
9f95a23c
TL
110 rgw::sal::RGWBucketList buckets;
111 ret = rgw_read_user_buckets(store, user_id, buckets, marker,
112 string(), max_entries, false);
c07f9fc5
FG
113 if (ret < 0) {
114 ldout(cct, 0) << "failed to read user buckets: ret=" << ret << dendl;
115 return ret;
116 }
9f95a23c
TL
117 std::map<std::string, rgw::sal::RGWBucket*>& m = buckets.get_buckets();
118 for (const auto& i : m) {
c07f9fc5
FG
119 marker = i.first;
120
9f95a23c
TL
121 rgw::sal::RGWBucket* bucket_ent = i.second;
122 ret = bucket_ent->read_bucket_stats(null_yield);
c07f9fc5
FG
123 if (ret < 0) {
124 ldout(cct, 0) << "ERROR: could not get bucket stats: ret=" << ret << dendl;
125 return ret;
126 }
9f95a23c
TL
127 cls_user_bucket_entry entry;
128 bucket_ent->convert(&entry);
129 buckets_usage_map.emplace(bucket_ent->get_name(), entry);
c07f9fc5 130 }
9f95a23c 131 done = (buckets.count() < max_entries);
c07f9fc5
FG
132 } while (!done);
133
134 return 0;
135}
136
7c673cae
FG
137/**
138 * Save the given user information to storage.
139 * Returns: 0 on success, -ERR# on failure.
140 */
9f95a23c 141int rgw_store_user_info(RGWUserCtl *user_ctl,
7c673cae
FG
142 RGWUserInfo& info,
143 RGWUserInfo *old_info,
144 RGWObjVersionTracker *objv_tracker,
145 real_time mtime,
146 bool exclusive,
147 map<string, bufferlist> *pattrs)
148{
9f95a23c
TL
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));
7c673cae
FG
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 */
9f95a23c 162int rgw_get_user_info_by_uid(RGWUserCtl *user_ctl,
7c673cae
FG
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{
9f95a23c
TL
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));
7c673cae
FG
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 */
9f95a23c 182int rgw_get_user_info_by_email(RGWUserCtl *user_ctl, string& email, RGWUserInfo& info,
7c673cae
FG
183 RGWObjVersionTracker *objv_tracker, real_time *pmtime)
184{
9f95a23c
TL
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));
7c673cae
FG
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 */
9f95a23c 195extern int rgw_get_user_info_by_swift(RGWUserCtl *user_ctl,
7c673cae
FG
196 const string& swift_name,
197 RGWUserInfo& info, /* out */
198 RGWObjVersionTracker * const objv_tracker,
199 real_time * const pmtime)
200{
9f95a23c
TL
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));
7c673cae
FG
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 */
9f95a23c 211extern int rgw_get_user_info_by_access_key(RGWUserCtl *user_ctl,
7c673cae
FG
212 const std::string& access_key,
213 RGWUserInfo& info,
214 RGWObjVersionTracker* objv_tracker,
215 real_time *pmtime)
216{
9f95a23c
TL
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));
7c673cae
FG
221}
222
223static 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
239struct rgw_flags_desc {
240 uint32_t mask;
241 const char *str;
242};
243
244static 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" },
11fdf7f2 250 { RGW_PERM_WRITE_ACP, "write-acp" },
7c673cae
FG
251 { 0, NULL }
252};
253
254void 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
281uint32_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
d2e6a577
FG
297int 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
7c673cae
FG
309static 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
320static void set_err_msg(std::string *sink, std::string msg)
321{
322 if (sink && !msg.empty())
323 *sink = msg;
324}
325
7c673cae
FG
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
333static 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
352static 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
371static 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
389static void dump_user_info(Formatter *f, RGWUserInfo &info,
390 RGWStorageStats *stats = NULL)
391{
392 f->open_object_section("user_info");
11fdf7f2
TL
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);
7c673cae
FG
399
400 dump_subusers_info(f, info);
401 dump_access_keys_info(f, info);
402 dump_swift_keys_info(f, info);
11fdf7f2
TL
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);
eafe8130 410 encode_json("admin", (bool)info.admin, f);
11fdf7f2
TL
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);
7c673cae
FG
438 if (stats) {
439 encode_json("stats", *stats, f);
440 }
7c673cae
FG
441 f->close_section();
442}
443
444
445RGWAccessKeyPool::RGWAccessKeyPool(RGWUser* usr)
446{
9f95a23c 447 if (!usr) {
7c673cae
FG
448 return;
449 }
450
9f95a23c 451 user = usr;
7c673cae
FG
452
453 store = user->get_store();
9f95a23c 454 user_ctl = user->get_user_ctl();
7c673cae
FG
455}
456
457int 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
484bool 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
547int 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
590int 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
7c673cae
FG
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:
9f95a23c 620 if (rgw_get_user_info_by_swift(user_ctl, id, duplicate_check) >= 0) {
7c673cae
FG
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:
9f95a23c 626 if (rgw_get_user_info_by_access_key(user_ctl, id, duplicate_check) >= 0) {
7c673cae
FG
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];
11fdf7f2 651 gen_rand_alphanumeric_plain(g_ceph_context, secret_key_buf, sizeof(secret_key_buf));
7c673cae
FG
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);
11fdf7f2 661 gen_rand_alphanumeric_upper(g_ceph_context, public_id_buf, id_buf_size);
7c673cae
FG
662 id = public_id_buf;
663 if (!validate_access_key(id))
664 continue;
665
9f95a23c 666 } while (!rgw_get_user_info_by_access_key(user_ctl, id, duplicate_check));
7c673cae
FG
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
9f95a23c 677 if (rgw_get_user_info_by_swift(user_ctl, id, duplicate_check) >= 0) {
7c673cae
FG
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
700int 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];
7c673cae 750 int key_buf_size = sizeof(secret_key_buf);
11fdf7f2 751 gen_rand_alphanumeric_plain(g_ceph_context, secret_key_buf, key_buf_size);
7c673cae
FG
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
775int 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
811int RGWAccessKeyPool::add(RGWUserAdminOpState& op_state, std::string *err_msg)
812{
813 return add(op_state, err_msg, false);
814}
815
816int 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
836int 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
7c673cae
FG
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
877int RGWAccessKeyPool::remove(RGWUserAdminOpState& op_state, std::string *err_msg)
878{
879 return remove(op_state, err_msg, false);
880}
881
882int 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
904int 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()) {
7c673cae
FG
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();
9f95a23c 939 auto user_kiter = user_info.access_keys.begin();
7c673cae
FG
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()) {
7c673cae
FG
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
958RGWSubUserPool::RGWSubUserPool(RGWUser *usr)
959{
9f95a23c
TL
960 if (!usr) {
961 return;
962 }
7c673cae 963
9f95a23c 964 user = usr;
7c673cae 965
9f95a23c
TL
966 subusers_allowed = true;
967 store = user->get_store();
968 user_ctl = user->get_user_ctl();
7c673cae
FG
969}
970
971int 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
995bool 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
1009int 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
1050int 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
1091int RGWSubUserPool::add(RGWUserAdminOpState& op_state, std::string *err_msg)
1092{
1093 return add(op_state, err_msg, false);
1094}
1095
1096int 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
1125int 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);
224ce89b 1137 return -ERR_NO_SUCH_SUBUSER;
7c673cae
FG
1138 }
1139 if (!op_state.has_existing_subuser()) {
1140 set_err_msg(err_msg, "subuser not found: " + subuser_str);
224ce89b 1141 return -ERR_NO_SUCH_SUBUSER;
7c673cae
FG
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
1160int RGWSubUserPool::remove(RGWUserAdminOpState& op_state, std::string *err_msg)
1161{
1162 return remove(op_state, err_msg, false);
1163}
1164
1165int 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
1185int 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");
224ce89b 1197 return -ERR_NO_SUCH_SUBUSER;
7c673cae
FG
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
1231int RGWSubUserPool::modify(RGWUserAdminOpState& op_state, std::string *err_msg)
1232{
1233 return RGWSubUserPool::modify(op_state, err_msg, false);
1234}
1235
1236int 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
1258RGWUserCapPool::RGWUserCapPool(RGWUser *usr)
1259{
9f95a23c
TL
1260 if (!usr) {
1261 return;
1262 }
7c673cae 1263 user = usr;
9f95a23c 1264 caps_allowed = true;
7c673cae
FG
1265}
1266
1267int 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
1291int RGWUserCapPool::add(RGWUserAdminOpState& op_state, std::string *err_msg)
1292{
1293 return add(op_state, err_msg, false);
1294}
1295
1296int 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
1331int RGWUserCapPool::remove(RGWUserAdminOpState& op_state, std::string *err_msg)
1332{
1333 return remove(op_state, err_msg, false);
1334}
1335
1336int 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
9f95a23c 1372RGWUser::RGWUser() : caps(this), keys(this), subusers(this)
7c673cae
FG
1373{
1374 init_default();
1375}
1376
9f95a23c 1377int RGWUser::init(rgw::sal::RGWRadosStore *storage, RGWUserAdminOpState& op_state)
7c673cae
FG
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
7c673cae
FG
1391void 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
9f95a23c 1400int RGWUser::init_storage(rgw::sal::RGWRadosStore *storage)
7c673cae
FG
1401{
1402 if (!storage) {
1403 return -EINVAL;
1404 }
1405
1406 store = storage;
9f95a23c 1407 user_ctl = store->ctl()->user;
7c673cae
FG
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
1419int RGWUser::init(RGWUserAdminOpState& op_state)
1420{
1421 bool found = false;
1422 std::string swift_user;
3efd9988 1423 user_id = op_state.get_user_id();
7c673cae
FG
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
3efd9988 1438 if (user_id.empty() && !subuser.empty()) {
7c673cae
FG
1439 size_t pos = subuser.find(':');
1440 if (pos != string::npos) {
3efd9988
FG
1441 user_id = subuser.substr(0, pos);
1442 op_state.set_user_id(user_id);
7c673cae
FG
1443 }
1444 }
1445
3efd9988 1446 if (!user_id.empty() && (user_id.compare(RGW_USER_ANON_ID) != 0)) {
9f95a23c 1447 found = (rgw_get_user_info_by_uid(user_ctl, user_id, user_info, &op_state.objv) >= 0);
7c673cae
FG
1448 op_state.found_by_uid = found;
1449 }
494da23a
TL
1450 if (store->ctx()->_conf.get_val<bool>("rgw_user_unique_email")) {
1451 if (!user_email.empty() && !found) {
9f95a23c 1452 found = (rgw_get_user_info_by_email(user_ctl, user_email, user_info, &op_state.objv) >= 0);
494da23a
TL
1453 op_state.found_by_email = found;
1454 }
7c673cae
FG
1455 }
1456 if (!swift_user.empty() && !found) {
9f95a23c 1457 found = (rgw_get_user_info_by_swift(user_ctl, swift_user, user_info, &op_state.objv) >= 0);
7c673cae
FG
1458 op_state.found_by_key = found;
1459 }
1460 if (!access_key.empty() && !found) {
9f95a23c 1461 found = (rgw_get_user_info_by_access_key(user_ctl, access_key, user_info, &op_state.objv) >= 0);
7c673cae
FG
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
3efd9988
FG
1474 if (user_id.empty()) {
1475 user_id = user_info.user_id;
1476 }
7c673cae
FG
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
1487int 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
1506int 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
9f95a23c 1517 RGWUserInfo *pold_info = (is_populated() ? &old_info : nullptr);
7c673cae 1518
9f95a23c
TL
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;
7c673cae
FG
1523 }
1524
1525 old_info = user_info;
1526 set_populated();
1527
1528 return 0;
1529}
1530
1531int 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
d2e6a577
FG
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
7c673cae
FG
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
9f95a23c
TL
1570// update swift_keys with new user id
1571static 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
1585int 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
7c673cae
FG
1692int 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()) {
7c673cae
FG
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 = cct->_conf->rgw_user_max_buckets;
1747 }
1748
1749 user_info.suspended = op_state.get_suspension_status();
1750 user_info.admin = op_state.admin;
1751 user_info.system = op_state.system;
1752
1753 if (op_state.op_mask_specified)
1754 user_info.op_mask = op_state.get_op_mask();
1755
1756 if (op_state.has_bucket_quota()) {
1757 user_info.bucket_quota = op_state.get_bucket_quota();
1758 } else {
11fdf7f2 1759 rgw_apply_default_bucket_quota(user_info.bucket_quota, cct->_conf);
7c673cae
FG
1760 }
1761
1762 if (op_state.temp_url_key_specified) {
1763 map<int, string>::iterator iter;
1764 for (iter = op_state.temp_url_keys.begin();
1765 iter != op_state.temp_url_keys.end(); ++iter) {
1766 user_info.temp_url_keys[iter->first] = iter->second;
1767 }
1768 }
1769
1770 if (op_state.has_user_quota()) {
1771 user_info.user_quota = op_state.get_user_quota();
1772 } else {
11fdf7f2 1773 rgw_apply_default_user_quota(user_info.user_quota, cct->_conf);
7c673cae
FG
1774 }
1775
9f95a23c
TL
1776 if (op_state.default_placement_specified) {
1777 user_info.default_placement = op_state.default_placement;
1778 }
1779
1780 if (op_state.placement_tags_specified) {
1781 user_info.placement_tags = op_state.placement_tags;
1782 }
1783
7c673cae
FG
1784 // update the request
1785 op_state.set_user_info(user_info);
1786 op_state.set_populated();
1787
1788 // update the helper objects
1789 ret = init_members(op_state);
1790 if (ret < 0) {
1791 set_err_msg(err_msg, "unable to initialize user");
1792 return ret;
1793 }
1794
1795 // see if we need to add an access key
1796 if (op_state.has_key_op()) {
1797 ret = keys.add(op_state, &subprocess_msg, defer_user_update);
1798 if (ret < 0) {
1799 set_err_msg(err_msg, "unable to create access key, " + subprocess_msg);
1800 return ret;
1801 }
1802 }
1803
1804 // see if we need to add some caps
1805 if (op_state.has_caps_op()) {
1806 ret = caps.add(op_state, &subprocess_msg, defer_user_update);
1807 if (ret < 0) {
1808 set_err_msg(err_msg, "unable to add user capabilities, " + subprocess_msg);
1809 return ret;
1810 }
1811 }
1812
1813 ret = update(op_state, err_msg);
1814 if (ret < 0)
1815 return ret;
1816
1817 return 0;
1818}
1819
9f95a23c 1820
7c673cae
FG
1821int RGWUser::add(RGWUserAdminOpState& op_state, std::string *err_msg)
1822{
1823 std::string subprocess_msg;
1824 int ret;
1825
1826 ret = check_op(op_state, &subprocess_msg);
1827 if (ret < 0) {
1828 set_err_msg(err_msg, "unable to parse parameters, " + subprocess_msg);
1829 return ret;
1830 }
1831
1832 ret = execute_add(op_state, &subprocess_msg);
1833 if (ret < 0) {
1834 set_err_msg(err_msg, "unable to create user, " + subprocess_msg);
1835 return ret;
1836 }
1837
1838 return 0;
1839}
1840
9f95a23c
TL
1841int RGWUser::rename(RGWUserAdminOpState& op_state, std::string *err_msg)
1842{
1843 std::string subprocess_msg;
1844 int ret;
1845
1846 ret = check_op(op_state, &subprocess_msg);
1847 if (ret < 0) {
1848 set_err_msg(err_msg, "unable to parse parameters, " + subprocess_msg);
1849 return ret;
1850 }
1851
1852 ret = execute_rename(op_state, &subprocess_msg);
1853 if (ret < 0) {
1854 set_err_msg(err_msg, "unable to rename user, " + subprocess_msg);
1855 return ret;
1856 }
1857
1858 return 0;
1859}
1860
1861int RGWUser::execute_remove(RGWUserAdminOpState& op_state, std::string *err_msg, optional_yield y)
7c673cae
FG
1862{
1863 int ret;
1864
1865 bool purge_data = op_state.will_purge_data();
1866 rgw_user& uid = op_state.get_user_id();
1867 RGWUserInfo user_info = op_state.get_user_info();
1868
1869 if (!op_state.has_existing_user()) {
1870 set_err_msg(err_msg, "user does not exist");
1871 return -ENOENT;
1872 }
1873
9f95a23c 1874 rgw::sal::RGWBucketList buckets;
7c673cae
FG
1875 string marker;
1876 CephContext *cct = store->ctx();
1877 size_t max_buckets = cct->_conf->rgw_list_buckets_max_chunk;
1878 do {
7c673cae 1879 ret = rgw_read_user_buckets(store, uid, buckets, marker, string(),
9f95a23c 1880 max_buckets, false);
7c673cae
FG
1881 if (ret < 0) {
1882 set_err_msg(err_msg, "unable to read user bucket info");
1883 return ret;
1884 }
1885
9f95a23c 1886 std::map<std::string, rgw::sal::RGWBucket*>& m = buckets.get_buckets();
7c673cae
FG
1887 if (!m.empty() && !purge_data) {
1888 set_err_msg(err_msg, "must specify purge data to remove user with buckets");
1889 return -EEXIST; // change to code that maps to 409: conflict
1890 }
1891
9f95a23c 1892 std::map<std::string, rgw::sal::RGWBucket*>::iterator it;
7c673cae 1893 for (it = m.begin(); it != m.end(); ++it) {
9f95a23c 1894 ret = it->second->remove_bucket(true, y);
7c673cae
FG
1895 if (ret < 0) {
1896 set_err_msg(err_msg, "unable to delete user data");
1897 return ret;
1898 }
1899
1900 marker = it->first;
1901 }
1902
9f95a23c 1903 } while (buckets.is_truncated());
7c673cae 1904
9f95a23c
TL
1905 ret = user_ctl->remove_info(user_info, y, RGWUserCtl::RemoveParams()
1906 .set_objv_tracker(&op_state.objv));
7c673cae
FG
1907 if (ret < 0) {
1908 set_err_msg(err_msg, "unable to remove user from RADOS");
1909 return ret;
1910 }
1911
1912 op_state.clear_populated();
1913 clear_populated();
1914
1915 return 0;
1916}
1917
9f95a23c 1918int RGWUser::remove(RGWUserAdminOpState& op_state, optional_yield y, std::string *err_msg)
7c673cae
FG
1919{
1920 std::string subprocess_msg;
1921 int ret;
1922
1923 ret = check_op(op_state, &subprocess_msg);
1924 if (ret < 0) {
1925 set_err_msg(err_msg, "unable to parse parameters, " + subprocess_msg);
1926 return ret;
1927 }
1928
9f95a23c 1929 ret = execute_remove(op_state, &subprocess_msg, y);
7c673cae
FG
1930 if (ret < 0) {
1931 set_err_msg(err_msg, "unable to remove user, " + subprocess_msg);
1932 return ret;
1933 }
1934
1935 return 0;
1936}
1937
1938int RGWUser::execute_modify(RGWUserAdminOpState& op_state, std::string *err_msg)
1939{
1940 bool populated = op_state.is_populated();
1941 int ret = 0;
1942 std::string subprocess_msg;
1943 std::string op_email = op_state.get_user_email();
1944 std::string display_name = op_state.get_display_name();
1945
1946 RGWUserInfo user_info;
1947 RGWUserInfo duplicate_check;
1948
1949 // ensure that the user info has been populated or is populate-able
1950 if (!op_state.has_existing_user() && !populated) {
1951 set_err_msg(err_msg, "user not found");
1952 return -ENOENT;
1953 }
1954
1955 // if the user hasn't already been populated...attempt to
1956 if (!populated) {
1957 ret = init(op_state);
1958 if (ret < 0) {
1959 set_err_msg(err_msg, "unable to retrieve user info");
1960 return ret;
1961 }
1962 }
1963
1964 // ensure that we can modify the user's attributes
1965 if (user_id.compare(RGW_USER_ANON_ID) == 0) {
1966 set_err_msg(err_msg, "unable to modify anonymous user's info");
1967 return -EACCES;
1968 }
1969
1970 user_info = old_info;
1971
1972 std::string old_email = old_info.user_email;
1973 if (!op_email.empty()) {
1974 // make sure we are not adding a duplicate email
9f95a23c
TL
1975 if (old_email != op_email) {
1976 ret = rgw_get_user_info_by_email(user_ctl, op_email, duplicate_check);
7c673cae
FG
1977 if (ret >= 0 && duplicate_check.user_id.compare(user_id) != 0) {
1978 set_err_msg(err_msg, "cannot add duplicate email");
1979 return -ERR_EMAIL_EXIST;
1980 }
1981 }
1982 user_info.user_email = op_email;
1983 } else if (op_email.empty() && op_state.user_email_specified) {
7c673cae 1984 ldout(store->ctx(), 10) << "removing email index: " << user_info.user_email << dendl;
9f95a23c
TL
1985 /* will be physically removed later when calling update() */
1986 user_info.user_email.clear();
7c673cae
FG
1987 }
1988
1989 // update the remaining user info
1990 if (!display_name.empty())
1991 user_info.display_name = display_name;
1992
1993 if (op_state.max_buckets_specified)
1994 user_info.max_buckets = op_state.get_max_buckets();
1995
1996 if (op_state.admin_specified)
1997 user_info.admin = op_state.admin;
1998
1999 if (op_state.system_specified)
2000 user_info.system = op_state.system;
2001
2002 if (op_state.temp_url_key_specified) {
2003 map<int, string>::iterator iter;
2004 for (iter = op_state.temp_url_keys.begin();
2005 iter != op_state.temp_url_keys.end(); ++iter) {
2006 user_info.temp_url_keys[iter->first] = iter->second;
2007 }
2008 }
2009
2010 if (op_state.op_mask_specified)
2011 user_info.op_mask = op_state.get_op_mask();
2012
2013 if (op_state.has_bucket_quota())
2014 user_info.bucket_quota = op_state.get_bucket_quota();
2015
2016 if (op_state.has_user_quota())
2017 user_info.user_quota = op_state.get_user_quota();
2018
2019 if (op_state.has_suspension_op()) {
2020 __u8 suspended = op_state.get_suspension_status();
2021 user_info.suspended = suspended;
2022
9f95a23c 2023 rgw::sal::RGWBucketList buckets;
7c673cae
FG
2024
2025 if (user_id.empty()) {
2026 set_err_msg(err_msg, "empty user id passed...aborting");
2027 return -EINVAL;
2028 }
2029
7c673cae
FG
2030 string marker;
2031 CephContext *cct = store->ctx();
2032 size_t max_buckets = cct->_conf->rgw_list_buckets_max_chunk;
2033 do {
2034 ret = rgw_read_user_buckets(store, user_id, buckets, marker, string(),
9f95a23c 2035 max_buckets, false);
7c673cae
FG
2036 if (ret < 0) {
2037 set_err_msg(err_msg, "could not get buckets for uid: " + user_id.to_str());
2038 return ret;
2039 }
2040
9f95a23c
TL
2041 std::map<std::string, rgw::sal::RGWBucket*>& m = buckets.get_buckets();
2042 std::map<std::string, rgw::sal::RGWBucket*>::iterator iter;
7c673cae
FG
2043
2044 vector<rgw_bucket> bucket_names;
2045 for (iter = m.begin(); iter != m.end(); ++iter) {
9f95a23c
TL
2046 rgw::sal::RGWBucket* obj = iter->second;
2047 bucket_names.push_back(obj->get_bi());
7c673cae
FG
2048
2049 marker = iter->first;
2050 }
2051
9f95a23c 2052 ret = store->getRados()->set_buckets_enabled(bucket_names, !suspended);
7c673cae
FG
2053 if (ret < 0) {
2054 set_err_msg(err_msg, "failed to modify bucket");
2055 return ret;
2056 }
2057
9f95a23c 2058 } while (buckets.is_truncated());
7c673cae 2059 }
11fdf7f2
TL
2060
2061 if (op_state.mfa_ids_specified) {
2062 user_info.mfa_ids = op_state.mfa_ids;
2063 }
9f95a23c
TL
2064
2065 if (op_state.default_placement_specified) {
2066 user_info.default_placement = op_state.default_placement;
2067 }
2068
2069 if (op_state.placement_tags_specified) {
2070 user_info.placement_tags = op_state.placement_tags;
2071 }
2072
7c673cae
FG
2073 op_state.set_user_info(user_info);
2074
2075 // if we're supposed to modify keys, do so
2076 if (op_state.has_key_op()) {
2077 ret = keys.add(op_state, &subprocess_msg, true);
2078 if (ret < 0) {
2079 set_err_msg(err_msg, "unable to create or modify keys, " + subprocess_msg);
2080 return ret;
2081 }
2082 }
2083
2084 ret = update(op_state, err_msg);
2085 if (ret < 0)
2086 return ret;
2087
2088 return 0;
2089}
2090
2091int RGWUser::modify(RGWUserAdminOpState& op_state, std::string *err_msg)
2092{
2093 std::string subprocess_msg;
2094 int ret;
2095
2096 ret = check_op(op_state, &subprocess_msg);
2097 if (ret < 0) {
2098 set_err_msg(err_msg, "unable to parse parameters, " + subprocess_msg);
2099 return ret;
2100 }
2101
2102 ret = execute_modify(op_state, &subprocess_msg);
2103 if (ret < 0) {
2104 set_err_msg(err_msg, "unable to modify user, " + subprocess_msg);
2105 return ret;
2106 }
2107
2108 return 0;
2109}
2110
2111int RGWUser::info(RGWUserAdminOpState& op_state, RGWUserInfo& fetched_info, std::string *err_msg)
2112{
2113 int ret = init(op_state);
2114 if (ret < 0) {
2115 set_err_msg(err_msg, "unable to fetch user info");
2116 return ret;
2117 }
2118
2119 fetched_info = op_state.get_user_info();
2120
2121 return 0;
2122}
2123
2124int RGWUser::info(RGWUserInfo& fetched_info, std::string *err_msg)
2125{
2126 if (!is_populated()) {
2127 set_err_msg(err_msg, "no user info saved");
2128 return -EINVAL;
2129 }
2130
2131 fetched_info = old_info;
2132
2133 return 0;
2134}
2135
11fdf7f2
TL
2136int RGWUser::list(RGWUserAdminOpState& op_state, RGWFormatterFlusher& flusher)
2137{
2138 Formatter *formatter = flusher.get_formatter();
2139 void *handle = nullptr;
2140 std::string metadata_key = "user";
2141 if (op_state.max_entries > 1000) {
2142 op_state.max_entries = 1000;
2143 }
2144
9f95a23c
TL
2145 auto meta_mgr = store->ctl()->meta.mgr;
2146
2147 int ret = meta_mgr->list_keys_init(metadata_key, op_state.marker, &handle);
11fdf7f2
TL
2148 if (ret < 0) {
2149 return ret;
2150 }
2151
2152 bool truncated = false;
2153 uint64_t count = 0;
2154 uint64_t left = 0;
2155 flusher.start(0);
2156
2157 // open the result object section
2158 formatter->open_object_section("result");
2159
2160 // open the user id list array section
2161 formatter->open_array_section("keys");
2162 do {
2163 std::list<std::string> keys;
2164 left = op_state.max_entries - count;
9f95a23c 2165 ret = meta_mgr->list_keys_next(handle, left, keys, &truncated);
11fdf7f2
TL
2166 if (ret < 0 && ret != -ENOENT) {
2167 return ret;
2168 } if (ret != -ENOENT) {
2169 for (std::list<std::string>::iterator iter = keys.begin(); iter != keys.end(); ++iter) {
2170 formatter->dump_string("key", *iter);
2171 ++count;
2172 }
2173 }
2174 } while (truncated && left > 0);
2175 // close user id list section
2176 formatter->close_section();
2177
2178 formatter->dump_bool("truncated", truncated);
2179 formatter->dump_int("count", count);
2180 if (truncated) {
9f95a23c 2181 formatter->dump_string("marker", meta_mgr->get_marker(handle));
11fdf7f2
TL
2182 }
2183
2184 // close result object section
2185 formatter->close_section();
2186
9f95a23c 2187 meta_mgr->list_keys_complete(handle);
11fdf7f2
TL
2188
2189 flusher.flush();
2190 return 0;
2191}
2192
9f95a23c 2193int RGWUserAdminOp_User::list(rgw::sal::RGWRadosStore *store, RGWUserAdminOpState& op_state,
11fdf7f2
TL
2194 RGWFormatterFlusher& flusher)
2195{
2196 RGWUser user;
2197
2198 int ret = user.init_storage(store);
2199 if (ret < 0)
2200 return ret;
2201
2202 ret = user.list(op_state, flusher);
2203 if (ret < 0)
2204 return ret;
2205
2206 return 0;
2207}
2208
9f95a23c 2209int RGWUserAdminOp_User::info(rgw::sal::RGWRadosStore *store, RGWUserAdminOpState& op_state,
7c673cae
FG
2210 RGWFormatterFlusher& flusher)
2211{
2212 RGWUserInfo info;
2213 RGWUser user;
2214
2215 int ret = user.init(store, op_state);
2216 if (ret < 0)
2217 return ret;
2218
2219 if (!op_state.has_existing_user())
224ce89b 2220 return -ERR_NO_SUCH_USER;
7c673cae
FG
2221
2222 Formatter *formatter = flusher.get_formatter();
2223
2224 ret = user.info(info, NULL);
2225 if (ret < 0)
2226 return ret;
2227
3efd9988
FG
2228 if (op_state.sync_stats) {
2229 ret = rgw_user_sync_all_stats(store, info.user_id);
2230 if (ret < 0) {
2231 return ret;
2232 }
2233 }
2234
7c673cae
FG
2235 RGWStorageStats stats;
2236 RGWStorageStats *arg_stats = NULL;
2237 if (op_state.fetch_stats) {
9f95a23c 2238 int ret = store->ctl()->user->read_stats(info.user_id, &stats);
28e407b8 2239 if (ret < 0 && ret != -ENOENT) {
7c673cae
FG
2240 return ret;
2241 }
2242
2243 arg_stats = &stats;
2244 }
2245
11fdf7f2
TL
2246 if (formatter) {
2247 flusher.start(0);
7c673cae 2248
11fdf7f2
TL
2249 dump_user_info(formatter, info, arg_stats);
2250 flusher.flush();
2251 }
7c673cae
FG
2252
2253 return 0;
2254}
2255
9f95a23c 2256int RGWUserAdminOp_User::create(rgw::sal::RGWRadosStore *store, RGWUserAdminOpState& op_state,
7c673cae
FG
2257 RGWFormatterFlusher& flusher)
2258{
2259 RGWUserInfo info;
2260 RGWUser user;
2261 int ret = user.init(store, op_state);
2262 if (ret < 0)
2263 return ret;
2264
2265 Formatter *formatter = flusher.get_formatter();
2266
2267 ret = user.add(op_state, NULL);
2268 if (ret < 0) {
2269 if (ret == -EEXIST)
2270 ret = -ERR_USER_EXIST;
2271 return ret;
2272 }
2273
2274 ret = user.info(info, NULL);
2275 if (ret < 0)
2276 return ret;
2277
11fdf7f2
TL
2278 if (formatter) {
2279 flusher.start(0);
7c673cae 2280
11fdf7f2
TL
2281 dump_user_info(formatter, info);
2282 flusher.flush();
2283 }
7c673cae
FG
2284
2285 return 0;
2286}
2287
9f95a23c 2288int RGWUserAdminOp_User::modify(rgw::sal::RGWRadosStore *store, RGWUserAdminOpState& op_state,
7c673cae
FG
2289 RGWFormatterFlusher& flusher)
2290{
2291 RGWUserInfo info;
2292 RGWUser user;
2293 int ret = user.init(store, op_state);
2294 if (ret < 0)
2295 return ret;
2296 Formatter *formatter = flusher.get_formatter();
2297
2298 ret = user.modify(op_state, NULL);
224ce89b
WB
2299 if (ret < 0) {
2300 if (ret == -ENOENT)
2301 ret = -ERR_NO_SUCH_USER;
7c673cae 2302 return ret;
224ce89b 2303 }
7c673cae
FG
2304
2305 ret = user.info(info, NULL);
2306 if (ret < 0)
2307 return ret;
2308
11fdf7f2
TL
2309 if (formatter) {
2310 flusher.start(0);
7c673cae 2311
11fdf7f2
TL
2312 dump_user_info(formatter, info);
2313 flusher.flush();
2314 }
7c673cae
FG
2315
2316 return 0;
2317}
2318
9f95a23c
TL
2319int RGWUserAdminOp_User::remove(rgw::sal::RGWRadosStore *store, RGWUserAdminOpState& op_state,
2320 RGWFormatterFlusher& flusher, optional_yield y)
7c673cae
FG
2321{
2322 RGWUserInfo info;
2323 RGWUser user;
2324 int ret = user.init(store, op_state);
2325 if (ret < 0)
2326 return ret;
2327
2328
9f95a23c 2329 ret = user.remove(op_state, y, NULL);
7c673cae 2330
224ce89b
WB
2331 if (ret == -ENOENT)
2332 ret = -ERR_NO_SUCH_USER;
7c673cae
FG
2333 return ret;
2334}
2335
9f95a23c 2336int RGWUserAdminOp_Subuser::create(rgw::sal::RGWRadosStore *store, RGWUserAdminOpState& op_state,
7c673cae
FG
2337 RGWFormatterFlusher& flusher)
2338{
2339 RGWUserInfo info;
2340 RGWUser user;
2341 int ret = user.init(store, op_state);
2342 if (ret < 0)
2343 return ret;
2344
224ce89b
WB
2345 if (!op_state.has_existing_user())
2346 return -ERR_NO_SUCH_USER;
2347
7c673cae
FG
2348 Formatter *formatter = flusher.get_formatter();
2349
2350 ret = user.subusers.add(op_state, NULL);
2351 if (ret < 0)
2352 return ret;
2353
2354 ret = user.info(info, NULL);
2355 if (ret < 0)
2356 return ret;
2357
11fdf7f2
TL
2358 if (formatter) {
2359 flusher.start(0);
7c673cae 2360
11fdf7f2
TL
2361 dump_subusers_info(formatter, info);
2362 flusher.flush();
2363 }
7c673cae
FG
2364
2365 return 0;
2366}
2367
9f95a23c 2368int RGWUserAdminOp_Subuser::modify(rgw::sal::RGWRadosStore *store, RGWUserAdminOpState& op_state,
7c673cae
FG
2369 RGWFormatterFlusher& flusher)
2370{
2371 RGWUserInfo info;
2372 RGWUser user;
2373 int ret = user.init(store, op_state);
2374 if (ret < 0)
2375 return ret;
2376
224ce89b
WB
2377 if (!op_state.has_existing_user())
2378 return -ERR_NO_SUCH_USER;
2379
7c673cae
FG
2380 Formatter *formatter = flusher.get_formatter();
2381
2382 ret = user.subusers.modify(op_state, NULL);
2383 if (ret < 0)
2384 return ret;
2385
2386 ret = user.info(info, NULL);
2387 if (ret < 0)
2388 return ret;
11fdf7f2
TL
2389
2390 if (formatter) {
2391 flusher.start(0);
7c673cae 2392
11fdf7f2
TL
2393 dump_subusers_info(formatter, info);
2394 flusher.flush();
2395 }
7c673cae
FG
2396
2397 return 0;
2398}
2399
9f95a23c 2400int RGWUserAdminOp_Subuser::remove(rgw::sal::RGWRadosStore *store, RGWUserAdminOpState& op_state,
7c673cae
FG
2401 RGWFormatterFlusher& flusher)
2402{
2403 RGWUserInfo info;
2404 RGWUser user;
2405 int ret = user.init(store, op_state);
2406 if (ret < 0)
2407 return ret;
2408
2409
224ce89b
WB
2410 if (!op_state.has_existing_user())
2411 return -ERR_NO_SUCH_USER;
2412
7c673cae
FG
2413 ret = user.subusers.remove(op_state, NULL);
2414 if (ret < 0)
2415 return ret;
2416
2417 return 0;
2418}
2419
9f95a23c 2420int RGWUserAdminOp_Key::create(rgw::sal::RGWRadosStore *store, RGWUserAdminOpState& op_state,
7c673cae
FG
2421 RGWFormatterFlusher& flusher)
2422{
2423 RGWUserInfo info;
2424 RGWUser user;
2425 int ret = user.init(store, op_state);
2426 if (ret < 0)
2427 return ret;
2428
224ce89b
WB
2429 if (!op_state.has_existing_user())
2430 return -ERR_NO_SUCH_USER;
2431
7c673cae
FG
2432 Formatter *formatter = flusher.get_formatter();
2433
2434 ret = user.keys.add(op_state, NULL);
2435 if (ret < 0)
2436 return ret;
2437
2438 ret = user.info(info, NULL);
2439 if (ret < 0)
2440 return ret;
2441
11fdf7f2
TL
2442 if (formatter) {
2443 flusher.start(0);
7c673cae 2444
11fdf7f2 2445 int key_type = op_state.get_key_type();
7c673cae 2446
11fdf7f2
TL
2447 if (key_type == KEY_TYPE_SWIFT)
2448 dump_swift_keys_info(formatter, info);
7c673cae 2449
11fdf7f2
TL
2450 else if (key_type == KEY_TYPE_S3)
2451 dump_access_keys_info(formatter, info);
7c673cae 2452
11fdf7f2
TL
2453 flusher.flush();
2454 }
7c673cae
FG
2455
2456 return 0;
2457}
2458
9f95a23c 2459int RGWUserAdminOp_Key::remove(rgw::sal::RGWRadosStore *store, RGWUserAdminOpState& op_state,
7c673cae
FG
2460 RGWFormatterFlusher& flusher)
2461{
2462 RGWUserInfo info;
2463 RGWUser user;
2464 int ret = user.init(store, op_state);
2465 if (ret < 0)
2466 return ret;
2467
224ce89b
WB
2468 if (!op_state.has_existing_user())
2469 return -ERR_NO_SUCH_USER;
2470
7c673cae
FG
2471
2472 ret = user.keys.remove(op_state, NULL);
2473 if (ret < 0)
2474 return ret;
2475
2476 return 0;
2477}
2478
9f95a23c 2479int RGWUserAdminOp_Caps::add(rgw::sal::RGWRadosStore *store, RGWUserAdminOpState& op_state,
7c673cae
FG
2480 RGWFormatterFlusher& flusher)
2481{
2482 RGWUserInfo info;
2483 RGWUser user;
2484 int ret = user.init(store, op_state);
2485 if (ret < 0)
2486 return ret;
2487
224ce89b
WB
2488 if (!op_state.has_existing_user())
2489 return -ERR_NO_SUCH_USER;
2490
7c673cae
FG
2491 Formatter *formatter = flusher.get_formatter();
2492
2493 ret = user.caps.add(op_state, NULL);
2494 if (ret < 0)
2495 return ret;
2496
2497 ret = user.info(info, NULL);
2498 if (ret < 0)
2499 return ret;
2500
11fdf7f2
TL
2501 if (formatter) {
2502 flusher.start(0);
7c673cae 2503
11fdf7f2
TL
2504 info.caps.dump(formatter);
2505 flusher.flush();
2506 }
7c673cae
FG
2507
2508 return 0;
2509}
2510
2511
9f95a23c 2512int RGWUserAdminOp_Caps::remove(rgw::sal::RGWRadosStore *store, RGWUserAdminOpState& op_state,
7c673cae
FG
2513 RGWFormatterFlusher& flusher)
2514{
2515 RGWUserInfo info;
2516 RGWUser user;
2517 int ret = user.init(store, op_state);
2518 if (ret < 0)
2519 return ret;
2520
224ce89b
WB
2521 if (!op_state.has_existing_user())
2522 return -ERR_NO_SUCH_USER;
2523
7c673cae
FG
2524 Formatter *formatter = flusher.get_formatter();
2525
2526 ret = user.caps.remove(op_state, NULL);
2527 if (ret < 0)
2528 return ret;
2529
2530 ret = user.info(info, NULL);
2531 if (ret < 0)
2532 return ret;
2533
11fdf7f2
TL
2534 if (formatter) {
2535 flusher.start(0);
7c673cae 2536
11fdf7f2
TL
2537 info.caps.dump(formatter);
2538 flusher.flush();
2539 }
7c673cae
FG
2540
2541 return 0;
2542}
2543
9f95a23c 2544class RGWUserMetadataHandler : public RGWMetadataHandler_GenericMetaBE {
7c673cae 2545public:
9f95a23c
TL
2546 struct Svc {
2547 RGWSI_User *user{nullptr};
2548 } svc;
7c673cae 2549
9f95a23c
TL
2550 RGWUserMetadataHandler(RGWSI_User *user_svc) {
2551 base_init(user_svc->ctx(), user_svc->get_be_handler());
2552 svc.user = user_svc;
7c673cae 2553 }
7c673cae 2554
7c673cae
FG
2555 string get_type() override { return "user"; }
2556
9f95a23c 2557 int do_get(RGWSI_MetaBackend_Handler::Op *op, string& entry, RGWMetadataObject **obj, optional_yield y) override {
7c673cae
FG
2558 RGWUserCompleteInfo uci;
2559 RGWObjVersionTracker objv_tracker;
2560 real_time mtime;
2561
9f95a23c 2562 rgw_user user = RGWSI_User::user_from_meta_key(entry);
7c673cae 2563
9f95a23c
TL
2564 int ret = svc.user->read_user_info(op->ctx(), user, &uci.info, &objv_tracker,
2565 &mtime, nullptr, &uci.attrs,
2566 y);
7c673cae
FG
2567 if (ret < 0) {
2568 return ret;
2569 }
2570
2571 RGWUserMetadataObject *mdo = new RGWUserMetadataObject(uci, objv_tracker.read_version, mtime);
2572 *obj = mdo;
2573
2574 return 0;
2575 }
2576
9f95a23c 2577 RGWMetadataObject *get_meta_obj(JSONObj *jo, const obj_version& objv, const ceph::real_time& mtime) override {
7c673cae
FG
2578 RGWUserCompleteInfo uci;
2579
2580 try {
9f95a23c 2581 decode_json_obj(uci, jo);
7c673cae 2582 } catch (JSONDecoder::err& e) {
9f95a23c 2583 return nullptr;
7c673cae
FG
2584 }
2585
9f95a23c
TL
2586 return new RGWUserMetadataObject(uci, objv, mtime);
2587 }
7c673cae 2588
9f95a23c
TL
2589 int do_put(RGWSI_MetaBackend_Handler::Op *op, string& entry,
2590 RGWMetadataObject *obj,
2591 RGWObjVersionTracker& objv_tracker,
2592 optional_yield y,
2593 RGWMDLogSyncType type) override;
7c673cae 2594
9f95a23c
TL
2595 int do_remove(RGWSI_MetaBackend_Handler::Op *op, string& entry, RGWObjVersionTracker& objv_tracker,
2596 optional_yield y) {
2597 RGWUserInfo info;
7c673cae 2598
9f95a23c 2599 rgw_user user = RGWSI_User::user_from_meta_key(entry);
7c673cae 2600
9f95a23c
TL
2601 int ret = svc.user->read_user_info(op->ctx(), user, &info, nullptr,
2602 nullptr, nullptr, nullptr,
2603 y);
7c673cae
FG
2604 if (ret < 0) {
2605 return ret;
2606 }
2607
9f95a23c
TL
2608 return svc.user->remove_user_info(op->ctx(), info, &objv_tracker,
2609 y);
7c673cae 2610 }
9f95a23c 2611};
7c673cae 2612
9f95a23c
TL
2613class RGWMetadataHandlerPut_User : public RGWMetadataHandlerPut_SObj
2614{
2615 RGWUserMetadataHandler *uhandler;
2616 RGWUserMetadataObject *uobj;
2617public:
2618 RGWMetadataHandlerPut_User(RGWUserMetadataHandler *_handler,
2619 RGWSI_MetaBackend_Handler::Op *op, string& entry,
2620 RGWMetadataObject *obj, RGWObjVersionTracker& objv_tracker,
2621 optional_yield y,
2622 RGWMDLogSyncType type) : RGWMetadataHandlerPut_SObj(_handler, op, entry, obj, objv_tracker, y, type),
2623 uhandler(_handler) {
2624 uobj = static_cast<RGWUserMetadataObject *>(obj);
2625 }
7c673cae 2626
9f95a23c
TL
2627 int put_checked() override;
2628};
7c673cae 2629
9f95a23c
TL
2630int RGWUserMetadataHandler::do_put(RGWSI_MetaBackend_Handler::Op *op, string& entry,
2631 RGWMetadataObject *obj,
2632 RGWObjVersionTracker& objv_tracker,
2633 optional_yield y,
2634 RGWMDLogSyncType type)
2635{
2636 RGWMetadataHandlerPut_User put_op(this, op, entry, obj, objv_tracker, y, type);
2637 return do_put_operate(&put_op);
2638}
7c673cae 2639
9f95a23c
TL
2640int RGWMetadataHandlerPut_User::put_checked()
2641{
2642 RGWUserMetadataObject *orig_obj = static_cast<RGWUserMetadataObject *>(old_obj);
2643 RGWUserCompleteInfo& uci = uobj->get_uci();
7c673cae 2644
9f95a23c
TL
2645 map<string, bufferlist> *pattrs{nullptr};
2646 if (uci.has_attrs) {
2647 pattrs = &uci.attrs;
7c673cae
FG
2648 }
2649
9f95a23c
TL
2650 RGWUserInfo *pold_info = (orig_obj ? &orig_obj->get_uci().info : nullptr);
2651
2652 auto mtime = obj->get_mtime();
2653
2654 int ret = uhandler->svc.user->store_user_info(op->ctx(), uci.info, pold_info,
2655 &objv_tracker, mtime,
2656 false, pattrs, y);
2657 if (ret < 0) {
2658 return ret;
7c673cae
FG
2659 }
2660
9f95a23c
TL
2661 return STATUS_APPLIED;
2662}
7c673cae 2663
7c673cae 2664
9f95a23c
TL
2665RGWUserCtl::RGWUserCtl(RGWSI_Zone *zone_svc,
2666 RGWSI_User *user_svc,
2667 RGWUserMetadataHandler *_umhandler) : umhandler(_umhandler) {
2668 svc.zone = zone_svc;
2669 svc.user = user_svc;
2670 be_handler = umhandler->get_be_handler();
2671}
2672
2673template <class T>
2674class optional_default
2675{
2676 const std::optional<T>& opt;
2677 std::optional<T> def;
2678 const T *p;
2679public:
2680 optional_default(const std::optional<T>& _o) : opt(_o) {
2681 if (opt) {
2682 p = &(*opt);
2683 } else {
2684 def = T();
2685 p = &(*def);
181888fb 2686 }
9f95a23c 2687 }
181888fb 2688
9f95a23c
TL
2689 const T *operator->() {
2690 return p;
2691 }
7c673cae 2692
9f95a23c
TL
2693 const T& operator*() {
2694 return *p;
7c673cae 2695 }
9f95a23c 2696};
7c673cae 2697
9f95a23c
TL
2698int RGWUserCtl::get_info_by_uid(const rgw_user& uid,
2699 RGWUserInfo *info,
2700 optional_yield y,
2701 const GetParams& params)
2702
2703{
2704 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
2705 return svc.user->read_user_info(op->ctx(),
2706 uid,
2707 info,
2708 params.objv_tracker,
2709 params.mtime,
2710 params.cache_info,
2711 params.attrs,
2712 y);
2713 });
2714}
2715
2716int RGWUserCtl::get_info_by_email(const string& email,
2717 RGWUserInfo *info,
2718 optional_yield y,
2719 const GetParams& params)
2720{
2721 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
2722 return svc.user->get_user_info_by_email(op->ctx(), email,
2723 info,
2724 params.objv_tracker,
2725 params.mtime,
2726 y);
2727 });
2728}
2729
2730int RGWUserCtl::get_info_by_swift(const string& swift_name,
2731 RGWUserInfo *info,
2732 optional_yield y,
2733 const GetParams& params)
2734{
2735 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
2736 return svc.user->get_user_info_by_swift(op->ctx(), swift_name,
2737 info,
2738 params.objv_tracker,
2739 params.mtime,
2740 y);
2741 });
2742}
2743
2744int RGWUserCtl::get_info_by_access_key(const string& access_key,
2745 RGWUserInfo *info,
2746 optional_yield y,
2747 const GetParams& params)
2748{
2749 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
2750 return svc.user->get_user_info_by_access_key(op->ctx(), access_key,
2751 info,
2752 params.objv_tracker,
2753 params.mtime,
2754 y);
2755 });
2756}
2757
2758int RGWUserCtl::get_attrs_by_uid(const rgw_user& user_id,
2759 map<string, bufferlist> *pattrs,
2760 optional_yield y,
2761 RGWObjVersionTracker *objv_tracker)
2762{
2763 RGWUserInfo user_info;
7c673cae 2764
9f95a23c
TL
2765 return get_info_by_uid(user_id, &user_info, y, RGWUserCtl::GetParams()
2766 .set_attrs(pattrs)
2767 .set_objv_tracker(objv_tracker));
2768}
7c673cae 2769
9f95a23c
TL
2770int RGWUserCtl::store_info(const RGWUserInfo& info, optional_yield y,
2771 const PutParams& params)
2772{
2773 string key = RGWSI_User::get_meta_key(info.user_id);
7c673cae 2774
9f95a23c
TL
2775 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
2776 return svc.user->store_user_info(op->ctx(), info,
2777 params.old_info,
2778 params.objv_tracker,
2779 params.mtime,
2780 params.exclusive,
2781 params.attrs,
2782 y);
2783 });
2784}
7c673cae 2785
9f95a23c
TL
2786int RGWUserCtl::remove_info(const RGWUserInfo& info, optional_yield y,
2787 const RemoveParams& params)
7c673cae 2788
9f95a23c
TL
2789{
2790 string key = RGWSI_User::get_meta_key(info.user_id);
7c673cae 2791
9f95a23c
TL
2792 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
2793 return svc.user->remove_user_info(op->ctx(), info,
2794 params.objv_tracker,
2795 y);
2796 });
2797}
2798
2799int RGWUserCtl::add_bucket(const rgw_user& user,
2800 const rgw_bucket& bucket,
2801 ceph::real_time creation_time)
2802
2803{
2804 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
2805 return svc.user->add_bucket(op->ctx(), user, bucket, creation_time);
2806 });
2807}
2808
2809int RGWUserCtl::remove_bucket(const rgw_user& user,
2810 const rgw_bucket& bucket)
2811
2812{
2813 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
2814 return svc.user->remove_bucket(op->ctx(), user, bucket);
2815 });
2816}
2817
2818int RGWUserCtl::list_buckets(const rgw_user& user,
2819 const string& marker,
2820 const string& end_marker,
2821 uint64_t max,
2822 bool need_stats,
2823 RGWUserBuckets *buckets,
2824 bool *is_truncated,
2825 uint64_t default_max)
2826{
2827 if (!max) {
2828 max = default_max;
2829 }
7c673cae 2830
9f95a23c
TL
2831 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
2832 int ret = svc.user->list_buckets(op->ctx(), user, marker, end_marker,
2833 max, buckets, is_truncated);
2834 if (ret < 0) {
2835 return ret;
2836 }
2837 if (need_stats) {
2838 map<string, RGWBucketEnt>& m = buckets->get_buckets();
2839 ret = ctl.bucket->read_buckets_stats(m, null_yield);
2840 if (ret < 0 && ret != -ENOENT) {
2841 ldout(svc.user->ctx(), 0) << "ERROR: could not get stats for buckets" << dendl;
2842 return ret;
7c673cae
FG
2843 }
2844 }
7c673cae 2845 return 0;
9f95a23c
TL
2846 });
2847}
7c673cae 2848
9f95a23c
TL
2849int RGWUserCtl::flush_bucket_stats(const rgw_user& user,
2850 const RGWBucketEnt& ent)
2851{
2852 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
2853 return svc.user->flush_bucket_stats(op->ctx(), user, ent);
2854 });
2855}
181888fb 2856
9f95a23c
TL
2857int RGWUserCtl::complete_flush_stats(const rgw_user& user)
2858{
2859 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
2860 return svc.user->complete_flush_stats(op->ctx(), user);
2861 });
2862}
7c673cae 2863
9f95a23c 2864int RGWUserCtl::reset_stats(const rgw_user& user)
7c673cae 2865{
9f95a23c
TL
2866 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
2867 return svc.user->reset_bucket_stats(op->ctx(), user);
2868 });
2869}
7c673cae 2870
9f95a23c
TL
2871int RGWUserCtl::read_stats(const rgw_user& user, RGWStorageStats *stats,
2872 ceph::real_time *last_stats_sync,
2873 ceph::real_time *last_stats_update)
2874{
2875 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
2876 return svc.user->read_stats(op->ctx(), user, stats,
2877 last_stats_sync, last_stats_update);
2878 });
7c673cae 2879}
9f95a23c
TL
2880
2881int RGWUserCtl::read_stats_async(const rgw_user& user, RGWGetUserStats_CB *cb)
2882{
2883 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
2884 return svc.user->read_stats_async(op->ctx(), user, cb);
2885 });
2886}
2887
2888RGWMetadataHandler *RGWUserMetaHandlerAllocator::alloc(RGWSI_User *user_svc) {
2889 return new RGWUserMetadataHandler(user_svc);
2890}
2891