]> git.proxmox.com Git - ceph.git/blame - ceph/src/rgw/rgw_user.cc
import ceph 15.2.10
[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 {
f6b5b4d7
TL
1746 user_info.max_buckets =
1747 cct->_conf.get_val<int64_t>("rgw_user_max_buckets");
7c673cae
FG
1748 }
1749
1750 user_info.suspended = op_state.get_suspension_status();
1751 user_info.admin = op_state.admin;
1752 user_info.system = op_state.system;
1753
1754 if (op_state.op_mask_specified)
1755 user_info.op_mask = op_state.get_op_mask();
1756
1757 if (op_state.has_bucket_quota()) {
1758 user_info.bucket_quota = op_state.get_bucket_quota();
1759 } else {
11fdf7f2 1760 rgw_apply_default_bucket_quota(user_info.bucket_quota, cct->_conf);
7c673cae
FG
1761 }
1762
1763 if (op_state.temp_url_key_specified) {
1764 map<int, string>::iterator iter;
1765 for (iter = op_state.temp_url_keys.begin();
1766 iter != op_state.temp_url_keys.end(); ++iter) {
1767 user_info.temp_url_keys[iter->first] = iter->second;
1768 }
1769 }
1770
1771 if (op_state.has_user_quota()) {
1772 user_info.user_quota = op_state.get_user_quota();
1773 } else {
11fdf7f2 1774 rgw_apply_default_user_quota(user_info.user_quota, cct->_conf);
7c673cae
FG
1775 }
1776
9f95a23c
TL
1777 if (op_state.default_placement_specified) {
1778 user_info.default_placement = op_state.default_placement;
1779 }
1780
1781 if (op_state.placement_tags_specified) {
1782 user_info.placement_tags = op_state.placement_tags;
1783 }
1784
7c673cae
FG
1785 // update the request
1786 op_state.set_user_info(user_info);
1787 op_state.set_populated();
1788
1789 // update the helper objects
1790 ret = init_members(op_state);
1791 if (ret < 0) {
1792 set_err_msg(err_msg, "unable to initialize user");
1793 return ret;
1794 }
1795
1796 // see if we need to add an access key
1797 if (op_state.has_key_op()) {
1798 ret = keys.add(op_state, &subprocess_msg, defer_user_update);
1799 if (ret < 0) {
1800 set_err_msg(err_msg, "unable to create access key, " + subprocess_msg);
1801 return ret;
1802 }
1803 }
1804
1805 // see if we need to add some caps
1806 if (op_state.has_caps_op()) {
1807 ret = caps.add(op_state, &subprocess_msg, defer_user_update);
1808 if (ret < 0) {
1809 set_err_msg(err_msg, "unable to add user capabilities, " + subprocess_msg);
1810 return ret;
1811 }
1812 }
1813
1814 ret = update(op_state, err_msg);
1815 if (ret < 0)
1816 return ret;
1817
1818 return 0;
1819}
1820
9f95a23c 1821
7c673cae
FG
1822int RGWUser::add(RGWUserAdminOpState& op_state, std::string *err_msg)
1823{
1824 std::string subprocess_msg;
1825 int ret;
1826
1827 ret = check_op(op_state, &subprocess_msg);
1828 if (ret < 0) {
1829 set_err_msg(err_msg, "unable to parse parameters, " + subprocess_msg);
1830 return ret;
1831 }
1832
1833 ret = execute_add(op_state, &subprocess_msg);
1834 if (ret < 0) {
1835 set_err_msg(err_msg, "unable to create user, " + subprocess_msg);
1836 return ret;
1837 }
1838
1839 return 0;
1840}
1841
9f95a23c
TL
1842int RGWUser::rename(RGWUserAdminOpState& op_state, std::string *err_msg)
1843{
1844 std::string subprocess_msg;
1845 int ret;
1846
1847 ret = check_op(op_state, &subprocess_msg);
1848 if (ret < 0) {
1849 set_err_msg(err_msg, "unable to parse parameters, " + subprocess_msg);
1850 return ret;
1851 }
1852
1853 ret = execute_rename(op_state, &subprocess_msg);
1854 if (ret < 0) {
1855 set_err_msg(err_msg, "unable to rename user, " + subprocess_msg);
1856 return ret;
1857 }
1858
1859 return 0;
1860}
1861
1862int RGWUser::execute_remove(RGWUserAdminOpState& op_state, std::string *err_msg, optional_yield y)
7c673cae
FG
1863{
1864 int ret;
1865
1866 bool purge_data = op_state.will_purge_data();
1867 rgw_user& uid = op_state.get_user_id();
1868 RGWUserInfo user_info = op_state.get_user_info();
1869
1870 if (!op_state.has_existing_user()) {
1871 set_err_msg(err_msg, "user does not exist");
1872 return -ENOENT;
1873 }
1874
9f95a23c 1875 rgw::sal::RGWBucketList buckets;
7c673cae
FG
1876 string marker;
1877 CephContext *cct = store->ctx();
1878 size_t max_buckets = cct->_conf->rgw_list_buckets_max_chunk;
1879 do {
7c673cae 1880 ret = rgw_read_user_buckets(store, uid, buckets, marker, string(),
9f95a23c 1881 max_buckets, false);
7c673cae
FG
1882 if (ret < 0) {
1883 set_err_msg(err_msg, "unable to read user bucket info");
1884 return ret;
1885 }
1886
9f95a23c 1887 std::map<std::string, rgw::sal::RGWBucket*>& m = buckets.get_buckets();
7c673cae
FG
1888 if (!m.empty() && !purge_data) {
1889 set_err_msg(err_msg, "must specify purge data to remove user with buckets");
1890 return -EEXIST; // change to code that maps to 409: conflict
1891 }
1892
9f95a23c 1893 std::map<std::string, rgw::sal::RGWBucket*>::iterator it;
7c673cae 1894 for (it = m.begin(); it != m.end(); ++it) {
9f95a23c 1895 ret = it->second->remove_bucket(true, y);
7c673cae
FG
1896 if (ret < 0) {
1897 set_err_msg(err_msg, "unable to delete user data");
1898 return ret;
1899 }
1900
1901 marker = it->first;
1902 }
1903
9f95a23c 1904 } while (buckets.is_truncated());
7c673cae 1905
9f95a23c
TL
1906 ret = user_ctl->remove_info(user_info, y, RGWUserCtl::RemoveParams()
1907 .set_objv_tracker(&op_state.objv));
7c673cae
FG
1908 if (ret < 0) {
1909 set_err_msg(err_msg, "unable to remove user from RADOS");
1910 return ret;
1911 }
1912
1913 op_state.clear_populated();
1914 clear_populated();
1915
1916 return 0;
1917}
1918
9f95a23c 1919int RGWUser::remove(RGWUserAdminOpState& op_state, optional_yield y, std::string *err_msg)
7c673cae
FG
1920{
1921 std::string subprocess_msg;
1922 int ret;
1923
1924 ret = check_op(op_state, &subprocess_msg);
1925 if (ret < 0) {
1926 set_err_msg(err_msg, "unable to parse parameters, " + subprocess_msg);
1927 return ret;
1928 }
1929
9f95a23c 1930 ret = execute_remove(op_state, &subprocess_msg, y);
7c673cae
FG
1931 if (ret < 0) {
1932 set_err_msg(err_msg, "unable to remove user, " + subprocess_msg);
1933 return ret;
1934 }
1935
1936 return 0;
1937}
1938
1939int RGWUser::execute_modify(RGWUserAdminOpState& op_state, std::string *err_msg)
1940{
1941 bool populated = op_state.is_populated();
1942 int ret = 0;
1943 std::string subprocess_msg;
1944 std::string op_email = op_state.get_user_email();
1945 std::string display_name = op_state.get_display_name();
1946
1947 RGWUserInfo user_info;
1948 RGWUserInfo duplicate_check;
1949
1950 // ensure that the user info has been populated or is populate-able
1951 if (!op_state.has_existing_user() && !populated) {
1952 set_err_msg(err_msg, "user not found");
1953 return -ENOENT;
1954 }
1955
1956 // if the user hasn't already been populated...attempt to
1957 if (!populated) {
1958 ret = init(op_state);
1959 if (ret < 0) {
1960 set_err_msg(err_msg, "unable to retrieve user info");
1961 return ret;
1962 }
1963 }
1964
1965 // ensure that we can modify the user's attributes
1966 if (user_id.compare(RGW_USER_ANON_ID) == 0) {
1967 set_err_msg(err_msg, "unable to modify anonymous user's info");
1968 return -EACCES;
1969 }
1970
1971 user_info = old_info;
1972
1973 std::string old_email = old_info.user_email;
1974 if (!op_email.empty()) {
1975 // make sure we are not adding a duplicate email
9f95a23c
TL
1976 if (old_email != op_email) {
1977 ret = rgw_get_user_info_by_email(user_ctl, op_email, duplicate_check);
7c673cae
FG
1978 if (ret >= 0 && duplicate_check.user_id.compare(user_id) != 0) {
1979 set_err_msg(err_msg, "cannot add duplicate email");
1980 return -ERR_EMAIL_EXIST;
1981 }
1982 }
1983 user_info.user_email = op_email;
1984 } else if (op_email.empty() && op_state.user_email_specified) {
7c673cae 1985 ldout(store->ctx(), 10) << "removing email index: " << user_info.user_email << dendl;
9f95a23c
TL
1986 /* will be physically removed later when calling update() */
1987 user_info.user_email.clear();
7c673cae
FG
1988 }
1989
1990 // update the remaining user info
1991 if (!display_name.empty())
1992 user_info.display_name = display_name;
1993
1994 if (op_state.max_buckets_specified)
1995 user_info.max_buckets = op_state.get_max_buckets();
1996
1997 if (op_state.admin_specified)
1998 user_info.admin = op_state.admin;
1999
2000 if (op_state.system_specified)
2001 user_info.system = op_state.system;
2002
2003 if (op_state.temp_url_key_specified) {
2004 map<int, string>::iterator iter;
2005 for (iter = op_state.temp_url_keys.begin();
2006 iter != op_state.temp_url_keys.end(); ++iter) {
2007 user_info.temp_url_keys[iter->first] = iter->second;
2008 }
2009 }
2010
2011 if (op_state.op_mask_specified)
2012 user_info.op_mask = op_state.get_op_mask();
2013
2014 if (op_state.has_bucket_quota())
2015 user_info.bucket_quota = op_state.get_bucket_quota();
2016
2017 if (op_state.has_user_quota())
2018 user_info.user_quota = op_state.get_user_quota();
2019
2020 if (op_state.has_suspension_op()) {
2021 __u8 suspended = op_state.get_suspension_status();
2022 user_info.suspended = suspended;
2023
9f95a23c 2024 rgw::sal::RGWBucketList buckets;
7c673cae
FG
2025
2026 if (user_id.empty()) {
2027 set_err_msg(err_msg, "empty user id passed...aborting");
2028 return -EINVAL;
2029 }
2030
7c673cae
FG
2031 string marker;
2032 CephContext *cct = store->ctx();
2033 size_t max_buckets = cct->_conf->rgw_list_buckets_max_chunk;
2034 do {
2035 ret = rgw_read_user_buckets(store, user_id, buckets, marker, string(),
9f95a23c 2036 max_buckets, false);
7c673cae
FG
2037 if (ret < 0) {
2038 set_err_msg(err_msg, "could not get buckets for uid: " + user_id.to_str());
2039 return ret;
2040 }
2041
9f95a23c
TL
2042 std::map<std::string, rgw::sal::RGWBucket*>& m = buckets.get_buckets();
2043 std::map<std::string, rgw::sal::RGWBucket*>::iterator iter;
7c673cae
FG
2044
2045 vector<rgw_bucket> bucket_names;
2046 for (iter = m.begin(); iter != m.end(); ++iter) {
9f95a23c
TL
2047 rgw::sal::RGWBucket* obj = iter->second;
2048 bucket_names.push_back(obj->get_bi());
7c673cae
FG
2049
2050 marker = iter->first;
2051 }
2052
9f95a23c 2053 ret = store->getRados()->set_buckets_enabled(bucket_names, !suspended);
7c673cae
FG
2054 if (ret < 0) {
2055 set_err_msg(err_msg, "failed to modify bucket");
2056 return ret;
2057 }
2058
9f95a23c 2059 } while (buckets.is_truncated());
7c673cae 2060 }
11fdf7f2
TL
2061
2062 if (op_state.mfa_ids_specified) {
2063 user_info.mfa_ids = op_state.mfa_ids;
2064 }
9f95a23c
TL
2065
2066 if (op_state.default_placement_specified) {
2067 user_info.default_placement = op_state.default_placement;
2068 }
2069
2070 if (op_state.placement_tags_specified) {
2071 user_info.placement_tags = op_state.placement_tags;
2072 }
2073
7c673cae
FG
2074 op_state.set_user_info(user_info);
2075
2076 // if we're supposed to modify keys, do so
2077 if (op_state.has_key_op()) {
2078 ret = keys.add(op_state, &subprocess_msg, true);
2079 if (ret < 0) {
2080 set_err_msg(err_msg, "unable to create or modify keys, " + subprocess_msg);
2081 return ret;
2082 }
2083 }
2084
2085 ret = update(op_state, err_msg);
2086 if (ret < 0)
2087 return ret;
2088
2089 return 0;
2090}
2091
2092int RGWUser::modify(RGWUserAdminOpState& op_state, std::string *err_msg)
2093{
2094 std::string subprocess_msg;
2095 int ret;
2096
2097 ret = check_op(op_state, &subprocess_msg);
2098 if (ret < 0) {
cd265ab1
TL
2099 if (is_populated() && (user_id.compare(op_state.get_user_id()) != 0)) {
2100 set_err_msg(err_msg, "unable to create user " + user_id.to_str()
2101 + " because user id " + op_state.get_user_id().to_str()
2102 + " already exists with email "
2103 + op_state.get_user_email());
2104 } else {
2105 set_err_msg(err_msg, "unable to parse parameters, " + subprocess_msg);
2106 }
7c673cae
FG
2107 return ret;
2108 }
2109
2110 ret = execute_modify(op_state, &subprocess_msg);
2111 if (ret < 0) {
2112 set_err_msg(err_msg, "unable to modify user, " + subprocess_msg);
2113 return ret;
2114 }
2115
2116 return 0;
2117}
2118
2119int RGWUser::info(RGWUserAdminOpState& op_state, RGWUserInfo& fetched_info, std::string *err_msg)
2120{
2121 int ret = init(op_state);
2122 if (ret < 0) {
2123 set_err_msg(err_msg, "unable to fetch user info");
2124 return ret;
2125 }
2126
2127 fetched_info = op_state.get_user_info();
2128
2129 return 0;
2130}
2131
2132int RGWUser::info(RGWUserInfo& fetched_info, std::string *err_msg)
2133{
2134 if (!is_populated()) {
2135 set_err_msg(err_msg, "no user info saved");
2136 return -EINVAL;
2137 }
2138
2139 fetched_info = old_info;
2140
2141 return 0;
2142}
2143
11fdf7f2
TL
2144int RGWUser::list(RGWUserAdminOpState& op_state, RGWFormatterFlusher& flusher)
2145{
2146 Formatter *formatter = flusher.get_formatter();
2147 void *handle = nullptr;
2148 std::string metadata_key = "user";
2149 if (op_state.max_entries > 1000) {
2150 op_state.max_entries = 1000;
2151 }
2152
9f95a23c
TL
2153 auto meta_mgr = store->ctl()->meta.mgr;
2154
2155 int ret = meta_mgr->list_keys_init(metadata_key, op_state.marker, &handle);
11fdf7f2
TL
2156 if (ret < 0) {
2157 return ret;
2158 }
2159
2160 bool truncated = false;
2161 uint64_t count = 0;
2162 uint64_t left = 0;
2163 flusher.start(0);
2164
2165 // open the result object section
2166 formatter->open_object_section("result");
2167
2168 // open the user id list array section
2169 formatter->open_array_section("keys");
2170 do {
2171 std::list<std::string> keys;
2172 left = op_state.max_entries - count;
9f95a23c 2173 ret = meta_mgr->list_keys_next(handle, left, keys, &truncated);
11fdf7f2
TL
2174 if (ret < 0 && ret != -ENOENT) {
2175 return ret;
2176 } if (ret != -ENOENT) {
2177 for (std::list<std::string>::iterator iter = keys.begin(); iter != keys.end(); ++iter) {
2178 formatter->dump_string("key", *iter);
2179 ++count;
2180 }
2181 }
2182 } while (truncated && left > 0);
2183 // close user id list section
2184 formatter->close_section();
2185
2186 formatter->dump_bool("truncated", truncated);
2187 formatter->dump_int("count", count);
2188 if (truncated) {
9f95a23c 2189 formatter->dump_string("marker", meta_mgr->get_marker(handle));
11fdf7f2
TL
2190 }
2191
2192 // close result object section
2193 formatter->close_section();
2194
9f95a23c 2195 meta_mgr->list_keys_complete(handle);
11fdf7f2
TL
2196
2197 flusher.flush();
2198 return 0;
2199}
2200
9f95a23c 2201int RGWUserAdminOp_User::list(rgw::sal::RGWRadosStore *store, RGWUserAdminOpState& op_state,
11fdf7f2
TL
2202 RGWFormatterFlusher& flusher)
2203{
2204 RGWUser user;
2205
2206 int ret = user.init_storage(store);
2207 if (ret < 0)
2208 return ret;
2209
2210 ret = user.list(op_state, flusher);
2211 if (ret < 0)
2212 return ret;
2213
2214 return 0;
2215}
2216
9f95a23c 2217int RGWUserAdminOp_User::info(rgw::sal::RGWRadosStore *store, RGWUserAdminOpState& op_state,
7c673cae
FG
2218 RGWFormatterFlusher& flusher)
2219{
2220 RGWUserInfo info;
2221 RGWUser user;
2222
2223 int ret = user.init(store, op_state);
2224 if (ret < 0)
2225 return ret;
2226
2227 if (!op_state.has_existing_user())
224ce89b 2228 return -ERR_NO_SUCH_USER;
7c673cae
FG
2229
2230 Formatter *formatter = flusher.get_formatter();
2231
2232 ret = user.info(info, NULL);
2233 if (ret < 0)
2234 return ret;
2235
3efd9988
FG
2236 if (op_state.sync_stats) {
2237 ret = rgw_user_sync_all_stats(store, info.user_id);
2238 if (ret < 0) {
2239 return ret;
2240 }
2241 }
2242
7c673cae
FG
2243 RGWStorageStats stats;
2244 RGWStorageStats *arg_stats = NULL;
2245 if (op_state.fetch_stats) {
9f95a23c 2246 int ret = store->ctl()->user->read_stats(info.user_id, &stats);
28e407b8 2247 if (ret < 0 && ret != -ENOENT) {
7c673cae
FG
2248 return ret;
2249 }
2250
2251 arg_stats = &stats;
2252 }
2253
11fdf7f2
TL
2254 if (formatter) {
2255 flusher.start(0);
7c673cae 2256
11fdf7f2
TL
2257 dump_user_info(formatter, info, arg_stats);
2258 flusher.flush();
2259 }
7c673cae
FG
2260
2261 return 0;
2262}
2263
9f95a23c 2264int RGWUserAdminOp_User::create(rgw::sal::RGWRadosStore *store, RGWUserAdminOpState& op_state,
7c673cae
FG
2265 RGWFormatterFlusher& flusher)
2266{
2267 RGWUserInfo info;
2268 RGWUser user;
2269 int ret = user.init(store, op_state);
2270 if (ret < 0)
2271 return ret;
2272
2273 Formatter *formatter = flusher.get_formatter();
2274
2275 ret = user.add(op_state, NULL);
2276 if (ret < 0) {
2277 if (ret == -EEXIST)
2278 ret = -ERR_USER_EXIST;
2279 return ret;
2280 }
2281
2282 ret = user.info(info, NULL);
2283 if (ret < 0)
2284 return ret;
2285
11fdf7f2
TL
2286 if (formatter) {
2287 flusher.start(0);
7c673cae 2288
11fdf7f2
TL
2289 dump_user_info(formatter, info);
2290 flusher.flush();
2291 }
7c673cae
FG
2292
2293 return 0;
2294}
2295
9f95a23c 2296int RGWUserAdminOp_User::modify(rgw::sal::RGWRadosStore *store, RGWUserAdminOpState& op_state,
7c673cae
FG
2297 RGWFormatterFlusher& flusher)
2298{
2299 RGWUserInfo info;
2300 RGWUser user;
2301 int ret = user.init(store, op_state);
2302 if (ret < 0)
2303 return ret;
2304 Formatter *formatter = flusher.get_formatter();
2305
2306 ret = user.modify(op_state, NULL);
224ce89b
WB
2307 if (ret < 0) {
2308 if (ret == -ENOENT)
2309 ret = -ERR_NO_SUCH_USER;
7c673cae 2310 return ret;
224ce89b 2311 }
7c673cae
FG
2312
2313 ret = user.info(info, NULL);
2314 if (ret < 0)
2315 return ret;
2316
11fdf7f2
TL
2317 if (formatter) {
2318 flusher.start(0);
7c673cae 2319
11fdf7f2
TL
2320 dump_user_info(formatter, info);
2321 flusher.flush();
2322 }
7c673cae
FG
2323
2324 return 0;
2325}
2326
9f95a23c
TL
2327int RGWUserAdminOp_User::remove(rgw::sal::RGWRadosStore *store, RGWUserAdminOpState& op_state,
2328 RGWFormatterFlusher& flusher, optional_yield y)
7c673cae
FG
2329{
2330 RGWUserInfo info;
2331 RGWUser user;
2332 int ret = user.init(store, op_state);
2333 if (ret < 0)
2334 return ret;
2335
2336
9f95a23c 2337 ret = user.remove(op_state, y, NULL);
7c673cae 2338
224ce89b
WB
2339 if (ret == -ENOENT)
2340 ret = -ERR_NO_SUCH_USER;
7c673cae
FG
2341 return ret;
2342}
2343
9f95a23c 2344int RGWUserAdminOp_Subuser::create(rgw::sal::RGWRadosStore *store, RGWUserAdminOpState& op_state,
7c673cae
FG
2345 RGWFormatterFlusher& flusher)
2346{
2347 RGWUserInfo info;
2348 RGWUser user;
2349 int ret = user.init(store, op_state);
2350 if (ret < 0)
2351 return ret;
2352
224ce89b
WB
2353 if (!op_state.has_existing_user())
2354 return -ERR_NO_SUCH_USER;
2355
7c673cae
FG
2356 Formatter *formatter = flusher.get_formatter();
2357
2358 ret = user.subusers.add(op_state, NULL);
2359 if (ret < 0)
2360 return ret;
2361
2362 ret = user.info(info, NULL);
2363 if (ret < 0)
2364 return ret;
2365
11fdf7f2
TL
2366 if (formatter) {
2367 flusher.start(0);
7c673cae 2368
11fdf7f2
TL
2369 dump_subusers_info(formatter, info);
2370 flusher.flush();
2371 }
7c673cae
FG
2372
2373 return 0;
2374}
2375
9f95a23c 2376int RGWUserAdminOp_Subuser::modify(rgw::sal::RGWRadosStore *store, RGWUserAdminOpState& op_state,
7c673cae
FG
2377 RGWFormatterFlusher& flusher)
2378{
2379 RGWUserInfo info;
2380 RGWUser user;
2381 int ret = user.init(store, op_state);
2382 if (ret < 0)
2383 return ret;
2384
224ce89b
WB
2385 if (!op_state.has_existing_user())
2386 return -ERR_NO_SUCH_USER;
2387
7c673cae
FG
2388 Formatter *formatter = flusher.get_formatter();
2389
2390 ret = user.subusers.modify(op_state, NULL);
2391 if (ret < 0)
2392 return ret;
2393
2394 ret = user.info(info, NULL);
2395 if (ret < 0)
2396 return ret;
11fdf7f2
TL
2397
2398 if (formatter) {
2399 flusher.start(0);
7c673cae 2400
11fdf7f2
TL
2401 dump_subusers_info(formatter, info);
2402 flusher.flush();
2403 }
7c673cae
FG
2404
2405 return 0;
2406}
2407
9f95a23c 2408int RGWUserAdminOp_Subuser::remove(rgw::sal::RGWRadosStore *store, RGWUserAdminOpState& op_state,
7c673cae
FG
2409 RGWFormatterFlusher& flusher)
2410{
2411 RGWUserInfo info;
2412 RGWUser user;
2413 int ret = user.init(store, op_state);
2414 if (ret < 0)
2415 return ret;
2416
2417
224ce89b
WB
2418 if (!op_state.has_existing_user())
2419 return -ERR_NO_SUCH_USER;
2420
7c673cae
FG
2421 ret = user.subusers.remove(op_state, NULL);
2422 if (ret < 0)
2423 return ret;
2424
2425 return 0;
2426}
2427
9f95a23c 2428int RGWUserAdminOp_Key::create(rgw::sal::RGWRadosStore *store, RGWUserAdminOpState& op_state,
7c673cae
FG
2429 RGWFormatterFlusher& flusher)
2430{
2431 RGWUserInfo info;
2432 RGWUser user;
2433 int ret = user.init(store, op_state);
2434 if (ret < 0)
2435 return ret;
2436
224ce89b
WB
2437 if (!op_state.has_existing_user())
2438 return -ERR_NO_SUCH_USER;
2439
7c673cae
FG
2440 Formatter *formatter = flusher.get_formatter();
2441
2442 ret = user.keys.add(op_state, NULL);
2443 if (ret < 0)
2444 return ret;
2445
2446 ret = user.info(info, NULL);
2447 if (ret < 0)
2448 return ret;
2449
11fdf7f2
TL
2450 if (formatter) {
2451 flusher.start(0);
7c673cae 2452
11fdf7f2 2453 int key_type = op_state.get_key_type();
7c673cae 2454
11fdf7f2
TL
2455 if (key_type == KEY_TYPE_SWIFT)
2456 dump_swift_keys_info(formatter, info);
7c673cae 2457
11fdf7f2
TL
2458 else if (key_type == KEY_TYPE_S3)
2459 dump_access_keys_info(formatter, info);
7c673cae 2460
11fdf7f2
TL
2461 flusher.flush();
2462 }
7c673cae
FG
2463
2464 return 0;
2465}
2466
9f95a23c 2467int RGWUserAdminOp_Key::remove(rgw::sal::RGWRadosStore *store, RGWUserAdminOpState& op_state,
7c673cae
FG
2468 RGWFormatterFlusher& flusher)
2469{
2470 RGWUserInfo info;
2471 RGWUser user;
2472 int ret = user.init(store, op_state);
2473 if (ret < 0)
2474 return ret;
2475
224ce89b
WB
2476 if (!op_state.has_existing_user())
2477 return -ERR_NO_SUCH_USER;
2478
7c673cae
FG
2479
2480 ret = user.keys.remove(op_state, NULL);
2481 if (ret < 0)
2482 return ret;
2483
2484 return 0;
2485}
2486
9f95a23c 2487int RGWUserAdminOp_Caps::add(rgw::sal::RGWRadosStore *store, RGWUserAdminOpState& op_state,
7c673cae
FG
2488 RGWFormatterFlusher& flusher)
2489{
2490 RGWUserInfo info;
2491 RGWUser user;
2492 int ret = user.init(store, op_state);
2493 if (ret < 0)
2494 return ret;
2495
224ce89b
WB
2496 if (!op_state.has_existing_user())
2497 return -ERR_NO_SUCH_USER;
2498
7c673cae
FG
2499 Formatter *formatter = flusher.get_formatter();
2500
2501 ret = user.caps.add(op_state, NULL);
2502 if (ret < 0)
2503 return ret;
2504
2505 ret = user.info(info, NULL);
2506 if (ret < 0)
2507 return ret;
2508
11fdf7f2
TL
2509 if (formatter) {
2510 flusher.start(0);
7c673cae 2511
11fdf7f2
TL
2512 info.caps.dump(formatter);
2513 flusher.flush();
2514 }
7c673cae
FG
2515
2516 return 0;
2517}
2518
2519
9f95a23c 2520int RGWUserAdminOp_Caps::remove(rgw::sal::RGWRadosStore *store, RGWUserAdminOpState& op_state,
7c673cae
FG
2521 RGWFormatterFlusher& flusher)
2522{
2523 RGWUserInfo info;
2524 RGWUser user;
2525 int ret = user.init(store, op_state);
2526 if (ret < 0)
2527 return ret;
2528
224ce89b
WB
2529 if (!op_state.has_existing_user())
2530 return -ERR_NO_SUCH_USER;
2531
7c673cae
FG
2532 Formatter *formatter = flusher.get_formatter();
2533
2534 ret = user.caps.remove(op_state, NULL);
2535 if (ret < 0)
2536 return ret;
2537
2538 ret = user.info(info, NULL);
2539 if (ret < 0)
2540 return ret;
2541
11fdf7f2
TL
2542 if (formatter) {
2543 flusher.start(0);
7c673cae 2544
11fdf7f2
TL
2545 info.caps.dump(formatter);
2546 flusher.flush();
2547 }
7c673cae
FG
2548
2549 return 0;
2550}
2551
9f95a23c 2552class RGWUserMetadataHandler : public RGWMetadataHandler_GenericMetaBE {
7c673cae 2553public:
9f95a23c
TL
2554 struct Svc {
2555 RGWSI_User *user{nullptr};
2556 } svc;
7c673cae 2557
9f95a23c
TL
2558 RGWUserMetadataHandler(RGWSI_User *user_svc) {
2559 base_init(user_svc->ctx(), user_svc->get_be_handler());
2560 svc.user = user_svc;
7c673cae 2561 }
7c673cae 2562
7c673cae
FG
2563 string get_type() override { return "user"; }
2564
9f95a23c 2565 int do_get(RGWSI_MetaBackend_Handler::Op *op, string& entry, RGWMetadataObject **obj, optional_yield y) override {
7c673cae
FG
2566 RGWUserCompleteInfo uci;
2567 RGWObjVersionTracker objv_tracker;
2568 real_time mtime;
2569
9f95a23c 2570 rgw_user user = RGWSI_User::user_from_meta_key(entry);
7c673cae 2571
9f95a23c
TL
2572 int ret = svc.user->read_user_info(op->ctx(), user, &uci.info, &objv_tracker,
2573 &mtime, nullptr, &uci.attrs,
2574 y);
7c673cae
FG
2575 if (ret < 0) {
2576 return ret;
2577 }
2578
2579 RGWUserMetadataObject *mdo = new RGWUserMetadataObject(uci, objv_tracker.read_version, mtime);
2580 *obj = mdo;
2581
2582 return 0;
2583 }
2584
9f95a23c 2585 RGWMetadataObject *get_meta_obj(JSONObj *jo, const obj_version& objv, const ceph::real_time& mtime) override {
7c673cae
FG
2586 RGWUserCompleteInfo uci;
2587
2588 try {
9f95a23c 2589 decode_json_obj(uci, jo);
7c673cae 2590 } catch (JSONDecoder::err& e) {
9f95a23c 2591 return nullptr;
7c673cae
FG
2592 }
2593
9f95a23c
TL
2594 return new RGWUserMetadataObject(uci, objv, mtime);
2595 }
7c673cae 2596
9f95a23c
TL
2597 int do_put(RGWSI_MetaBackend_Handler::Op *op, string& entry,
2598 RGWMetadataObject *obj,
2599 RGWObjVersionTracker& objv_tracker,
2600 optional_yield y,
2601 RGWMDLogSyncType type) override;
7c673cae 2602
9f95a23c
TL
2603 int do_remove(RGWSI_MetaBackend_Handler::Op *op, string& entry, RGWObjVersionTracker& objv_tracker,
2604 optional_yield y) {
2605 RGWUserInfo info;
7c673cae 2606
9f95a23c 2607 rgw_user user = RGWSI_User::user_from_meta_key(entry);
7c673cae 2608
9f95a23c
TL
2609 int ret = svc.user->read_user_info(op->ctx(), user, &info, nullptr,
2610 nullptr, nullptr, nullptr,
2611 y);
7c673cae
FG
2612 if (ret < 0) {
2613 return ret;
2614 }
2615
9f95a23c
TL
2616 return svc.user->remove_user_info(op->ctx(), info, &objv_tracker,
2617 y);
7c673cae 2618 }
9f95a23c 2619};
7c673cae 2620
9f95a23c
TL
2621class RGWMetadataHandlerPut_User : public RGWMetadataHandlerPut_SObj
2622{
2623 RGWUserMetadataHandler *uhandler;
2624 RGWUserMetadataObject *uobj;
2625public:
2626 RGWMetadataHandlerPut_User(RGWUserMetadataHandler *_handler,
2627 RGWSI_MetaBackend_Handler::Op *op, string& entry,
2628 RGWMetadataObject *obj, RGWObjVersionTracker& objv_tracker,
2629 optional_yield y,
2630 RGWMDLogSyncType type) : RGWMetadataHandlerPut_SObj(_handler, op, entry, obj, objv_tracker, y, type),
2631 uhandler(_handler) {
2632 uobj = static_cast<RGWUserMetadataObject *>(obj);
2633 }
7c673cae 2634
9f95a23c
TL
2635 int put_checked() override;
2636};
7c673cae 2637
9f95a23c
TL
2638int RGWUserMetadataHandler::do_put(RGWSI_MetaBackend_Handler::Op *op, string& entry,
2639 RGWMetadataObject *obj,
2640 RGWObjVersionTracker& objv_tracker,
2641 optional_yield y,
2642 RGWMDLogSyncType type)
2643{
2644 RGWMetadataHandlerPut_User put_op(this, op, entry, obj, objv_tracker, y, type);
2645 return do_put_operate(&put_op);
2646}
7c673cae 2647
9f95a23c
TL
2648int RGWMetadataHandlerPut_User::put_checked()
2649{
2650 RGWUserMetadataObject *orig_obj = static_cast<RGWUserMetadataObject *>(old_obj);
2651 RGWUserCompleteInfo& uci = uobj->get_uci();
7c673cae 2652
9f95a23c
TL
2653 map<string, bufferlist> *pattrs{nullptr};
2654 if (uci.has_attrs) {
2655 pattrs = &uci.attrs;
7c673cae
FG
2656 }
2657
9f95a23c
TL
2658 RGWUserInfo *pold_info = (orig_obj ? &orig_obj->get_uci().info : nullptr);
2659
2660 auto mtime = obj->get_mtime();
2661
2662 int ret = uhandler->svc.user->store_user_info(op->ctx(), uci.info, pold_info,
2663 &objv_tracker, mtime,
2664 false, pattrs, y);
2665 if (ret < 0) {
2666 return ret;
7c673cae
FG
2667 }
2668
9f95a23c
TL
2669 return STATUS_APPLIED;
2670}
7c673cae 2671
7c673cae 2672
9f95a23c
TL
2673RGWUserCtl::RGWUserCtl(RGWSI_Zone *zone_svc,
2674 RGWSI_User *user_svc,
2675 RGWUserMetadataHandler *_umhandler) : umhandler(_umhandler) {
2676 svc.zone = zone_svc;
2677 svc.user = user_svc;
2678 be_handler = umhandler->get_be_handler();
2679}
2680
2681template <class T>
2682class optional_default
2683{
2684 const std::optional<T>& opt;
2685 std::optional<T> def;
2686 const T *p;
2687public:
2688 optional_default(const std::optional<T>& _o) : opt(_o) {
2689 if (opt) {
2690 p = &(*opt);
2691 } else {
2692 def = T();
2693 p = &(*def);
181888fb 2694 }
9f95a23c 2695 }
181888fb 2696
9f95a23c
TL
2697 const T *operator->() {
2698 return p;
2699 }
7c673cae 2700
9f95a23c
TL
2701 const T& operator*() {
2702 return *p;
7c673cae 2703 }
9f95a23c 2704};
7c673cae 2705
9f95a23c
TL
2706int RGWUserCtl::get_info_by_uid(const rgw_user& uid,
2707 RGWUserInfo *info,
2708 optional_yield y,
2709 const GetParams& params)
2710
2711{
2712 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
2713 return svc.user->read_user_info(op->ctx(),
2714 uid,
2715 info,
2716 params.objv_tracker,
2717 params.mtime,
2718 params.cache_info,
2719 params.attrs,
2720 y);
2721 });
2722}
2723
2724int RGWUserCtl::get_info_by_email(const string& email,
2725 RGWUserInfo *info,
2726 optional_yield y,
2727 const GetParams& params)
2728{
2729 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
2730 return svc.user->get_user_info_by_email(op->ctx(), email,
2731 info,
2732 params.objv_tracker,
2733 params.mtime,
2734 y);
2735 });
2736}
2737
2738int RGWUserCtl::get_info_by_swift(const string& swift_name,
2739 RGWUserInfo *info,
2740 optional_yield y,
2741 const GetParams& params)
2742{
2743 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
2744 return svc.user->get_user_info_by_swift(op->ctx(), swift_name,
2745 info,
2746 params.objv_tracker,
2747 params.mtime,
2748 y);
2749 });
2750}
2751
2752int RGWUserCtl::get_info_by_access_key(const string& access_key,
2753 RGWUserInfo *info,
2754 optional_yield y,
2755 const GetParams& params)
2756{
2757 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
2758 return svc.user->get_user_info_by_access_key(op->ctx(), access_key,
2759 info,
2760 params.objv_tracker,
2761 params.mtime,
2762 y);
2763 });
2764}
2765
2766int RGWUserCtl::get_attrs_by_uid(const rgw_user& user_id,
2767 map<string, bufferlist> *pattrs,
2768 optional_yield y,
2769 RGWObjVersionTracker *objv_tracker)
2770{
2771 RGWUserInfo user_info;
7c673cae 2772
9f95a23c
TL
2773 return get_info_by_uid(user_id, &user_info, y, RGWUserCtl::GetParams()
2774 .set_attrs(pattrs)
2775 .set_objv_tracker(objv_tracker));
2776}
7c673cae 2777
9f95a23c
TL
2778int RGWUserCtl::store_info(const RGWUserInfo& info, optional_yield y,
2779 const PutParams& params)
2780{
2781 string key = RGWSI_User::get_meta_key(info.user_id);
7c673cae 2782
9f95a23c
TL
2783 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
2784 return svc.user->store_user_info(op->ctx(), info,
2785 params.old_info,
2786 params.objv_tracker,
2787 params.mtime,
2788 params.exclusive,
2789 params.attrs,
2790 y);
2791 });
2792}
7c673cae 2793
9f95a23c
TL
2794int RGWUserCtl::remove_info(const RGWUserInfo& info, optional_yield y,
2795 const RemoveParams& params)
7c673cae 2796
9f95a23c
TL
2797{
2798 string key = RGWSI_User::get_meta_key(info.user_id);
7c673cae 2799
9f95a23c
TL
2800 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
2801 return svc.user->remove_user_info(op->ctx(), info,
2802 params.objv_tracker,
2803 y);
2804 });
2805}
2806
2807int RGWUserCtl::add_bucket(const rgw_user& user,
2808 const rgw_bucket& bucket,
2809 ceph::real_time creation_time)
2810
2811{
2812 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
2813 return svc.user->add_bucket(op->ctx(), user, bucket, creation_time);
2814 });
2815}
2816
2817int RGWUserCtl::remove_bucket(const rgw_user& user,
2818 const rgw_bucket& bucket)
2819
2820{
2821 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
2822 return svc.user->remove_bucket(op->ctx(), user, bucket);
2823 });
2824}
2825
2826int RGWUserCtl::list_buckets(const rgw_user& user,
2827 const string& marker,
2828 const string& end_marker,
2829 uint64_t max,
2830 bool need_stats,
2831 RGWUserBuckets *buckets,
2832 bool *is_truncated,
2833 uint64_t default_max)
2834{
2835 if (!max) {
2836 max = default_max;
2837 }
7c673cae 2838
9f95a23c
TL
2839 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
2840 int ret = svc.user->list_buckets(op->ctx(), user, marker, end_marker,
2841 max, buckets, is_truncated);
2842 if (ret < 0) {
2843 return ret;
2844 }
2845 if (need_stats) {
2846 map<string, RGWBucketEnt>& m = buckets->get_buckets();
2847 ret = ctl.bucket->read_buckets_stats(m, null_yield);
2848 if (ret < 0 && ret != -ENOENT) {
2849 ldout(svc.user->ctx(), 0) << "ERROR: could not get stats for buckets" << dendl;
2850 return ret;
7c673cae
FG
2851 }
2852 }
7c673cae 2853 return 0;
9f95a23c
TL
2854 });
2855}
7c673cae 2856
9f95a23c
TL
2857int RGWUserCtl::flush_bucket_stats(const rgw_user& user,
2858 const RGWBucketEnt& ent)
2859{
2860 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
2861 return svc.user->flush_bucket_stats(op->ctx(), user, ent);
2862 });
2863}
181888fb 2864
9f95a23c
TL
2865int RGWUserCtl::complete_flush_stats(const rgw_user& user)
2866{
2867 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
2868 return svc.user->complete_flush_stats(op->ctx(), user);
2869 });
2870}
7c673cae 2871
9f95a23c 2872int RGWUserCtl::reset_stats(const rgw_user& user)
7c673cae 2873{
9f95a23c
TL
2874 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
2875 return svc.user->reset_bucket_stats(op->ctx(), user);
2876 });
2877}
7c673cae 2878
9f95a23c
TL
2879int RGWUserCtl::read_stats(const rgw_user& user, RGWStorageStats *stats,
2880 ceph::real_time *last_stats_sync,
2881 ceph::real_time *last_stats_update)
2882{
2883 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
2884 return svc.user->read_stats(op->ctx(), user, stats,
2885 last_stats_sync, last_stats_update);
2886 });
7c673cae 2887}
9f95a23c
TL
2888
2889int RGWUserCtl::read_stats_async(const rgw_user& user, RGWGetUserStats_CB *cb)
2890{
2891 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
2892 return svc.user->read_stats_async(op->ctx(), user, cb);
2893 });
2894}
2895
2896RGWMetadataHandler *RGWUserMetaHandlerAllocator::alloc(RGWSI_User *user_svc) {
2897 return new RGWUserMetadataHandler(user_svc);
2898}
2899