1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
8 #include <boost/algorithm/string.hpp>
10 #include "common/errno.h"
11 #include "common/Formatter.h"
12 #include "common/ceph_json.h"
13 #include "common/RWLock.h"
18 #include "include/types.h"
20 #include "rgw_string.h"
22 // until everything is moved from rgw_common
23 #include "rgw_common.h"
25 #include "rgw_bucket.h"
26 #include "rgw_quota.h"
28 #include "services/svc_zone.h"
29 #include "services/svc_sys_obj.h"
30 #include "services/svc_sys_obj_cache.h"
31 #include "services/svc_user.h"
32 #include "services/svc_meta.h"
34 #define dout_subsys ceph_subsys_rgw
38 extern void op_type_to_str(uint32_t mask
, char *buf
, int len
);
41 * Get the anonymous (ie, unauthenticated) user info.
43 void rgw_get_anon_user(RGWUserInfo
& info
)
45 info
.user_id
= RGW_USER_ANON_ID
;
46 info
.display_name
.clear();
47 info
.access_keys
.clear();
50 int rgw_user_sync_all_stats(rgw::sal::RGWRadosStore
*store
, const rgw_user
& user_id
)
52 rgw::sal::RGWBucketList user_buckets
;
53 rgw::sal::RGWRadosUser
user(store
, user_id
);
55 CephContext
*cct
= store
->ctx();
56 size_t max_entries
= cct
->_conf
->rgw_list_buckets_max_chunk
;
57 bool is_truncated
= false;
62 ret
= user
.list_buckets(marker
, string(), max_entries
, false, user_buckets
);
64 ldout(cct
, 0) << "failed to read user buckets: ret=" << ret
<< dendl
;
67 map
<string
, rgw::sal::RGWBucket
*>& buckets
= user_buckets
.get_buckets();
68 for (map
<string
, rgw::sal::RGWBucket
*>::iterator i
= buckets
.begin();
73 rgw::sal::RGWBucket
* bucket
= i
->second
;
75 ret
= bucket
->get_bucket_info(null_yield
);
77 ldout(cct
, 0) << "ERROR: could not read bucket info: bucket=" << bucket
<< " ret=" << ret
<< dendl
;
80 ret
= bucket
->sync_user_stats();
82 ldout(cct
, 0) << "ERROR: could not sync bucket stats: ret=" << ret
<< dendl
;
85 ret
= bucket
->check_bucket_shards();
87 ldout(cct
, 0) << "ERROR in check_bucket_shards: " << cpp_strerror(-ret
)<< dendl
;
90 } while (is_truncated
);
92 ret
= store
->ctl()->user
->complete_flush_stats(user
.get_user());
94 cerr
<< "ERROR: failed to complete syncing user stats: ret=" << ret
<< std::endl
;
101 int rgw_user_get_all_buckets_stats(rgw::sal::RGWRadosStore
*store
, const rgw_user
& user_id
, map
<string
, cls_user_bucket_entry
>& buckets_usage_map
)
103 CephContext
*cct
= store
->ctx();
104 size_t max_entries
= cct
->_conf
->rgw_list_buckets_max_chunk
;
110 rgw::sal::RGWBucketList buckets
;
111 ret
= rgw_read_user_buckets(store
, user_id
, buckets
, marker
,
112 string(), max_entries
, false);
114 ldout(cct
, 0) << "failed to read user buckets: ret=" << ret
<< dendl
;
117 std::map
<std::string
, rgw::sal::RGWBucket
*>& m
= buckets
.get_buckets();
118 for (const auto& i
: m
) {
121 rgw::sal::RGWBucket
* bucket_ent
= i
.second
;
122 ret
= bucket_ent
->read_bucket_stats(null_yield
);
124 ldout(cct
, 0) << "ERROR: could not get bucket stats: ret=" << ret
<< dendl
;
127 cls_user_bucket_entry entry
;
128 bucket_ent
->convert(&entry
);
129 buckets_usage_map
.emplace(bucket_ent
->get_name(), entry
);
131 done
= (buckets
.count() < max_entries
);
138 * Save the given user information to storage.
139 * Returns: 0 on success, -ERR# on failure.
141 int rgw_store_user_info(RGWUserCtl
*user_ctl
,
143 RGWUserInfo
*old_info
,
144 RGWObjVersionTracker
*objv_tracker
,
147 map
<string
, bufferlist
> *pattrs
)
149 return user_ctl
->store_info(info
, null_yield
,
150 RGWUserCtl::PutParams()
151 .set_old_info(old_info
)
152 .set_objv_tracker(objv_tracker
)
154 .set_exclusive(exclusive
)
159 * Given a uid, finds the user info associated with it.
160 * returns: 0 on success, -ERR# on failure (including nonexistence)
162 int rgw_get_user_info_by_uid(RGWUserCtl
*user_ctl
,
165 RGWObjVersionTracker
* const objv_tracker
,
166 real_time
* const pmtime
,
167 rgw_cache_entry_info
* const cache_info
,
168 map
<string
, bufferlist
> * const pattrs
)
170 return user_ctl
->get_info_by_uid(uid
, &info
, null_yield
,
171 RGWUserCtl::GetParams()
172 .set_objv_tracker(objv_tracker
)
174 .set_cache_info(cache_info
)
179 * Given an email, finds the user info associated with it.
180 * returns: 0 on success, -ERR# on failure (including nonexistence)
182 int rgw_get_user_info_by_email(RGWUserCtl
*user_ctl
, string
& email
, RGWUserInfo
& info
,
183 RGWObjVersionTracker
*objv_tracker
, real_time
*pmtime
)
185 return user_ctl
->get_info_by_email(email
, &info
, null_yield
,
186 RGWUserCtl::GetParams()
187 .set_objv_tracker(objv_tracker
)
192 * Given an swift username, finds the user_info associated with it.
193 * returns: 0 on success, -ERR# on failure (including nonexistence)
195 extern int rgw_get_user_info_by_swift(RGWUserCtl
*user_ctl
,
196 const string
& swift_name
,
197 RGWUserInfo
& info
, /* out */
198 RGWObjVersionTracker
* const objv_tracker
,
199 real_time
* const pmtime
)
201 return user_ctl
->get_info_by_swift(swift_name
, &info
, null_yield
,
202 RGWUserCtl::GetParams()
203 .set_objv_tracker(objv_tracker
)
208 * Given an access key, finds the user info associated with it.
209 * returns: 0 on success, -ERR# on failure (including nonexistence)
211 extern int rgw_get_user_info_by_access_key(RGWUserCtl
*user_ctl
,
212 const std::string
& access_key
,
214 RGWObjVersionTracker
* objv_tracker
,
217 return user_ctl
->get_info_by_access_key(access_key
, &info
, null_yield
,
218 RGWUserCtl::GetParams()
219 .set_objv_tracker(objv_tracker
)
223 static bool char_is_unreserved_url(char c
)
239 struct rgw_flags_desc
{
244 static struct rgw_flags_desc rgw_perms
[] = {
245 { RGW_PERM_FULL_CONTROL
, "full-control" },
246 { RGW_PERM_READ
| RGW_PERM_WRITE
, "read-write" },
247 { RGW_PERM_READ
, "read" },
248 { RGW_PERM_WRITE
, "write" },
249 { RGW_PERM_READ_ACP
, "read-acp" },
250 { RGW_PERM_WRITE_ACP
, "write-acp" },
254 void rgw_perm_to_str(uint32_t mask
, char *buf
, int len
)
256 const char *sep
= "";
259 snprintf(buf
, len
, "<none>");
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
);
276 if (mask
== orig_mask
) // no change
281 uint32_t rgw_str_to_perm(const char *str
)
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
;
294 return RGW_PERM_INVALID
;
297 int rgw_validate_tenant_name(const string
& t
)
300 static bool is_good(char ch
) {
301 return isalnum(ch
) || ch
== '_';
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
;
309 static bool validate_access_key(string
& key
)
311 const char *p
= key
.c_str();
313 if (!char_is_unreserved_url(*p
))
320 static void set_err_msg(std::string
*sink
, std::string msg
)
322 if (sink
&& !msg
.empty())
327 * Dump either the full user info or a subset to a formatter.
329 * NOTE: It is the caller's respnsibility to ensure that the
330 * formatter is flushed at the correct time.
333 static void dump_subusers_info(Formatter
*f
, RGWUserInfo
&info
)
335 map
<string
, RGWSubUser
>::iterator uiter
;
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");
342 info
.user_id
.to_str(s
);
343 f
->dump_format("id", "%s:%s", s
.c_str(), u
.name
.c_str());
345 rgw_perm_to_str(u
.perm_mask
, buf
, sizeof(buf
));
346 f
->dump_string("permissions", buf
);
352 static void dump_access_keys_info(Formatter
*f
, RGWUserInfo
&info
)
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");
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
);
371 static void dump_swift_keys_info(Formatter
*f
, RGWUserInfo
&info
)
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");
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
);
389 static void dump_user_info(Formatter
*f
, RGWUserInfo
&info
,
390 RGWStorageStats
*stats
= NULL
)
392 f
->open_object_section("user_info");
393 encode_json("tenant", info
.user_id
.tenant
, f
);
394 encode_json("user_id", info
.user_id
.id
, f
);
395 encode_json("display_name", info
.display_name
, f
);
396 encode_json("email", info
.user_email
, f
);
397 encode_json("suspended", (int)info
.suspended
, f
);
398 encode_json("max_buckets", (int)info
.max_buckets
, f
);
400 dump_subusers_info(f
, info
);
401 dump_access_keys_info(f
, info
);
402 dump_swift_keys_info(f
, info
);
404 encode_json("caps", info
.caps
, f
);
407 op_type_to_str(info
.op_mask
, buf
, sizeof(buf
));
408 encode_json("op_mask", (const char *)buf
, f
);
409 encode_json("system", (bool)info
.system
, f
);
410 encode_json("admin", (bool)info
.admin
, f
);
411 encode_json("default_placement", info
.default_placement
.name
, f
);
412 encode_json("default_storage_class", info
.default_placement
.storage_class
, f
);
413 encode_json("placement_tags", info
.placement_tags
, f
);
414 encode_json("bucket_quota", info
.bucket_quota
, f
);
415 encode_json("user_quota", info
.user_quota
, f
);
416 encode_json("temp_url_keys", info
.temp_url_keys
, f
);
418 string user_source_type
;
419 switch ((RGWIdentityType
)info
.type
) {
421 user_source_type
= "rgw";
424 user_source_type
= "keystone";
427 user_source_type
= "ldap";
430 user_source_type
= "none";
433 user_source_type
= "none";
436 encode_json("type", user_source_type
, f
);
437 encode_json("mfa_ids", info
.mfa_ids
, f
);
439 encode_json("stats", *stats
, f
);
445 RGWAccessKeyPool::RGWAccessKeyPool(RGWUser
* usr
)
453 store
= user
->get_store();
454 user_ctl
= user
->get_user_ctl();
457 int RGWAccessKeyPool::init(RGWUserAdminOpState
& op_state
)
459 if (!op_state
.is_initialized()) {
460 keys_allowed
= false;
464 rgw_user
& uid
= op_state
.get_user_id();
465 if (uid
.compare(RGW_USER_ANON_ID
) == 0) {
466 keys_allowed
= false;
470 swift_keys
= op_state
.get_swift_keys();
471 access_keys
= op_state
.get_access_keys();
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.
484 bool RGWAccessKeyPool::check_existing_key(RGWUserAdminOpState
& op_state
)
486 bool existing_key
= false;
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();
493 RGWUserInfo dup_info
;
495 if (kid
.empty() && swift_kid
.empty())
500 kiter
= swift_keys
->find(swift_kid
);
502 existing_key
= (kiter
!= swift_keys
->end());
504 op_state
.set_access_key(swift_kid
);
508 kiter
= access_keys
->find(kid
);
509 existing_key
= (kiter
!= access_keys
->end());
513 kiter
= access_keys
->find(kid
);
515 existing_key
= (kiter
!= access_keys
->end());
517 op_state
.set_key_type(KEY_TYPE_S3
);
521 kiter
= swift_keys
->find(kid
);
523 existing_key
= (kiter
!= swift_keys
->end());
525 op_state
.set_key_type(KEY_TYPE_SWIFT
);
529 // handle the case where the access key was not provided in user:key format
530 if (swift_kid
.empty())
533 kiter
= swift_keys
->find(swift_kid
);
535 existing_key
= (kiter
!= swift_keys
->end());
537 op_state
.set_access_key(swift_kid
);
538 op_state
.set_key_type(KEY_TYPE_SWIFT
);
542 op_state
.set_existing_key(existing_key
);
547 int RGWAccessKeyPool::check_op(RGWUserAdminOpState
& op_state
,
548 std::string
*err_msg
)
550 RGWUserInfo dup_info
;
552 if (!op_state
.is_populated()) {
553 set_err_msg(err_msg
, "user info was not populated");
558 set_err_msg(err_msg
, "keys not allowed for this user");
562 int32_t key_type
= op_state
.get_key_type();
564 // if a key type wasn't specified
566 if (op_state
.has_subuser()) {
567 key_type
= KEY_TYPE_SWIFT
;
569 key_type
= KEY_TYPE_S3
;
573 op_state
.set_key_type(key_type
);
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
;
582 // don't check for secret key because we may be doing a removal
584 check_existing_key(op_state
);
589 // Generate a new random key
590 int RGWAccessKeyPool::generate_key(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
595 std::pair
<std::string
, RGWAccessKey
> key_pair
;
596 RGWAccessKey new_key
;
597 RGWUserInfo duplicate_check
;
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();
604 set_err_msg(err_msg
, "access keys not allowed for this user");
608 if (op_state
.has_existing_key()) {
609 set_err_msg(err_msg
, "cannot create existing key");
610 return -ERR_KEY_EXIST
;
614 id
= op_state
.get_access_key();
620 if (rgw_get_user_info_by_swift(user_ctl
, id
, duplicate_check
) >= 0) {
621 set_err_msg(err_msg
, "existing swift key in RGW system:" + id
);
622 return -ERR_KEY_EXIST
;
626 if (rgw_get_user_info_by_access_key(user_ctl
, id
, duplicate_check
) >= 0) {
627 set_err_msg(err_msg
, "existing S3 key in RGW system:" + id
);
628 return -ERR_KEY_EXIST
;
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();
643 if (op_state
.get_secret_key().empty()) {
644 set_err_msg(err_msg
, "empty secret key");
645 return -ERR_INVALID_SECRET_KEY
;
648 key
= op_state
.get_secret_key();
650 char secret_key_buf
[SECRET_KEY_LEN
+ 1];
651 gen_rand_alphanumeric_plain(g_ceph_context
, secret_key_buf
, sizeof(secret_key_buf
));
652 key
= secret_key_buf
;
655 // Generate the access key
656 if (key_type
== KEY_TYPE_S3
&& gen_access
) {
657 char public_id_buf
[PUBLIC_ID_LEN
+ 1];
660 int id_buf_size
= sizeof(public_id_buf
);
661 gen_rand_alphanumeric_upper(g_ceph_context
, public_id_buf
, id_buf_size
);
663 if (!validate_access_key(id
))
666 } while (!rgw_get_user_info_by_access_key(user_ctl
, id
, duplicate_check
));
669 if (key_type
== KEY_TYPE_SWIFT
) {
670 id
= op_state
.build_default_swift_kid();
672 set_err_msg(err_msg
, "empty swift access key");
673 return -ERR_INVALID_ACCESS_KEY
;
676 // check that the access key doesn't exist
677 if (rgw_get_user_info_by_swift(user_ctl
, id
, duplicate_check
) >= 0) {
678 set_err_msg(err_msg
, "cannot create existing swift key");
679 return -ERR_KEY_EXIST
;
683 // finally create the new key
688 key_pair
.second
= new_key
;
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
);
699 // modify an existing key
700 int RGWAccessKeyPool::modify_key(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
703 std::string key
= op_state
.get_secret_key();
704 int key_type
= op_state
.get_key_type();
706 RGWAccessKey modify_key
;
708 pair
<string
, RGWAccessKey
> key_pair
;
709 map
<std::string
, RGWAccessKey
>::iterator kiter
;
713 id
= op_state
.get_access_key();
715 set_err_msg(err_msg
, "no access key specified");
716 return -ERR_INVALID_ACCESS_KEY
;
720 id
= op_state
.build_default_swift_kid();
722 set_err_msg(err_msg
, "no subuser specified");
727 set_err_msg(err_msg
, "invalid key type");
728 return -ERR_INVALID_KEY_TYPE
;
731 if (!op_state
.has_existing_key()) {
732 set_err_msg(err_msg
, "key does not exist");
733 return -ERR_INVALID_ACCESS_KEY
;
738 if (key_type
== KEY_TYPE_SWIFT
) {
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
;
748 if (op_state
.will_gen_secret()) {
749 char secret_key_buf
[SECRET_KEY_LEN
+ 1];
750 int key_buf_size
= sizeof(secret_key_buf
);
751 gen_rand_alphanumeric_plain(g_ceph_context
, secret_key_buf
, key_buf_size
);
752 key
= secret_key_buf
;
756 set_err_msg(err_msg
, "empty secret key");
757 return -ERR_INVALID_SECRET_KEY
;
760 // update the access key with the new secret key
761 modify_key
.key
= key
;
763 key_pair
.second
= modify_key
;
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
;
775 int RGWAccessKeyPool::execute_add(RGWUserAdminOpState
& op_state
,
776 std::string
*err_msg
, bool defer_user_update
)
780 std::string subprocess_msg
;
781 int key_op
= GENERATE_KEY
;
784 if (op_state
.has_existing_key())
789 ret
= generate_key(op_state
, &subprocess_msg
);
792 ret
= modify_key(op_state
, &subprocess_msg
);
797 set_err_msg(err_msg
, subprocess_msg
);
801 // store the updated info
802 if (!defer_user_update
)
803 ret
= user
->update(op_state
, err_msg
);
811 int RGWAccessKeyPool::add(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
813 return add(op_state
, err_msg
, false);
816 int RGWAccessKeyPool::add(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_user_update
)
819 std::string subprocess_msg
;
821 ret
= check_op(op_state
, &subprocess_msg
);
823 set_err_msg(err_msg
, "unable to parse request, " + subprocess_msg
);
827 ret
= execute_add(op_state
, &subprocess_msg
, defer_user_update
);
829 set_err_msg(err_msg
, "unable to add access key, " + subprocess_msg
);
836 int RGWAccessKeyPool::execute_remove(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_user_update
)
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
;
845 if (!op_state
.has_existing_key()) {
846 set_err_msg(err_msg
, "unable to find access key");
847 return -ERR_INVALID_ACCESS_KEY
;
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
;
856 set_err_msg(err_msg
, "invalid access key");
857 return -ERR_INVALID_ACCESS_KEY
;
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
;
866 keys_map
->erase(kiter
);
868 if (!defer_user_update
)
869 ret
= user
->update(op_state
, err_msg
);
877 int RGWAccessKeyPool::remove(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
879 return remove(op_state
, err_msg
, false);
882 int RGWAccessKeyPool::remove(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_user_update
)
886 std::string subprocess_msg
;
888 ret
= check_op(op_state
, &subprocess_msg
);
890 set_err_msg(err_msg
, "unable to parse request, " + subprocess_msg
);
894 ret
= execute_remove(op_state
, &subprocess_msg
, defer_user_update
);
896 set_err_msg(err_msg
, "unable to remove access key, " + subprocess_msg
);
903 // remove all keys associated with a subuser
904 int RGWAccessKeyPool::remove_subuser_keys(RGWUserAdminOpState
& op_state
,
905 std::string
*err_msg
, bool defer_user_update
)
909 if (!op_state
.is_populated()) {
910 set_err_msg(err_msg
, "user info was not populated");
914 if (!op_state
.has_subuser()) {
915 set_err_msg(err_msg
, "no subuser specified");
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");
925 map
<std::string
, RGWAccessKey
>::iterator kiter
;
926 map
<std::string
, RGWAccessKey
> *keys_map
;
928 // a subuser can have at most one swift key
929 keys_map
= swift_keys
;
930 kiter
= keys_map
->find(swift_kid
);
931 if (kiter
!= keys_map
->end()) {
932 keys_map
->erase(kiter
);
935 // a subuser may have multiple s3 key pairs
936 std::string subuser_str
= op_state
.get_subuser();
937 keys_map
= access_keys
;
938 RGWUserInfo user_info
= op_state
.get_user_info();
939 auto user_kiter
= user_info
.access_keys
.begin();
940 for (; user_kiter
!= user_info
.access_keys
.end(); ++user_kiter
) {
941 if (user_kiter
->second
.subuser
== subuser_str
) {
942 kiter
= keys_map
->find(user_kiter
->first
);
943 if (kiter
!= keys_map
->end()) {
944 keys_map
->erase(kiter
);
949 if (!defer_user_update
)
950 ret
= user
->update(op_state
, err_msg
);
958 RGWSubUserPool::RGWSubUserPool(RGWUser
*usr
)
966 subusers_allowed
= true;
967 store
= user
->get_store();
968 user_ctl
= user
->get_user_ctl();
971 int RGWSubUserPool::init(RGWUserAdminOpState
& op_state
)
973 if (!op_state
.is_initialized()) {
974 subusers_allowed
= false;
978 rgw_user
& uid
= op_state
.get_user_id();
979 if (uid
.compare(RGW_USER_ANON_ID
) == 0) {
980 subusers_allowed
= false;
984 subuser_map
= op_state
.get_subusers();
985 if (subuser_map
== NULL
) {
986 subusers_allowed
= false;
990 subusers_allowed
= true;
995 bool RGWSubUserPool::exists(std::string subuser
)
1003 if (subuser_map
->count(subuser
))
1009 int RGWSubUserPool::check_op(RGWUserAdminOpState
& op_state
,
1010 std::string
*err_msg
)
1012 bool existing
= false;
1013 std::string subuser
= op_state
.get_subuser();
1015 if (!op_state
.is_populated()) {
1016 set_err_msg(err_msg
, "user info was not populated");
1020 if (!subusers_allowed
) {
1021 set_err_msg(err_msg
, "subusers not allowed for this user");
1025 if (subuser
.empty() && !op_state
.will_gen_subuser()) {
1026 set_err_msg(err_msg
, "empty subuser name");
1030 if (op_state
.get_subuser_perm() == RGW_PERM_INVALID
) {
1031 set_err_msg(err_msg
, "invaild subuser access");
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;
1041 // check if the subuser exists
1042 if (!subuser
.empty())
1043 existing
= exists(subuser
);
1045 op_state
.set_existing_subuser(existing
);
1050 int RGWSubUserPool::execute_add(RGWUserAdminOpState
& op_state
,
1051 std::string
*err_msg
, bool defer_user_update
)
1054 std::string subprocess_msg
;
1057 std::pair
<std::string
, RGWSubUser
> subuser_pair
;
1058 std::string subuser_str
= op_state
.get_subuser();
1060 subuser_pair
.first
= subuser_str
;
1062 // assumes key should be created
1063 if (op_state
.has_key_op()) {
1064 ret
= user
->keys
.add(op_state
, &subprocess_msg
, true);
1066 set_err_msg(err_msg
, "unable to create subuser key, " + subprocess_msg
);
1071 // create the subuser
1072 subuser
.name
= subuser_str
;
1074 if (op_state
.has_subuser_perm())
1075 subuser
.perm_mask
= op_state
.get_subuser_perm();
1077 // insert the subuser into user info
1078 subuser_pair
.second
= subuser
;
1079 subuser_map
->insert(subuser_pair
);
1081 // attempt to save the subuser
1082 if (!defer_user_update
)
1083 ret
= user
->update(op_state
, err_msg
);
1091 int RGWSubUserPool::add(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1093 return add(op_state
, err_msg
, false);
1096 int RGWSubUserPool::add(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_user_update
)
1098 std::string subprocess_msg
;
1100 int32_t key_type
= op_state
.get_key_type();
1102 ret
= check_op(op_state
, &subprocess_msg
);
1104 set_err_msg(err_msg
, "unable to parse request, " + subprocess_msg
);
1108 if (key_type
== KEY_TYPE_S3
&& op_state
.get_access_key().empty()) {
1109 op_state
.set_gen_access();
1112 if (op_state
.get_secret_key().empty()) {
1113 op_state
.set_gen_secret();
1116 ret
= execute_add(op_state
, &subprocess_msg
, defer_user_update
);
1118 set_err_msg(err_msg
, "unable to create subuser, " + subprocess_msg
);
1125 int RGWSubUserPool::execute_remove(RGWUserAdminOpState
& op_state
,
1126 std::string
*err_msg
, bool defer_user_update
)
1129 std::string subprocess_msg
;
1131 std::string subuser_str
= op_state
.get_subuser();
1133 map
<std::string
, RGWSubUser
>::iterator siter
;
1134 siter
= subuser_map
->find(subuser_str
);
1135 if (siter
== subuser_map
->end()){
1136 set_err_msg(err_msg
, "subuser not found: " + subuser_str
);
1137 return -ERR_NO_SUCH_SUBUSER
;
1139 if (!op_state
.has_existing_subuser()) {
1140 set_err_msg(err_msg
, "subuser not found: " + subuser_str
);
1141 return -ERR_NO_SUCH_SUBUSER
;
1144 // always purge all associate keys
1145 user
->keys
.remove_subuser_keys(op_state
, &subprocess_msg
, true);
1147 // remove the subuser from the user info
1148 subuser_map
->erase(siter
);
1150 // attempt to save the subuser
1151 if (!defer_user_update
)
1152 ret
= user
->update(op_state
, err_msg
);
1160 int RGWSubUserPool::remove(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1162 return remove(op_state
, err_msg
, false);
1165 int RGWSubUserPool::remove(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_user_update
)
1167 std::string subprocess_msg
;
1170 ret
= check_op(op_state
, &subprocess_msg
);
1172 set_err_msg(err_msg
, "unable to parse request, " + subprocess_msg
);
1176 ret
= execute_remove(op_state
, &subprocess_msg
, defer_user_update
);
1178 set_err_msg(err_msg
, "unable to remove subuser, " + subprocess_msg
);
1185 int RGWSubUserPool::execute_modify(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_user_update
)
1188 std::string subprocess_msg
;
1189 std::map
<std::string
, RGWSubUser
>::iterator siter
;
1190 std::pair
<std::string
, RGWSubUser
> subuser_pair
;
1192 std::string subuser_str
= op_state
.get_subuser();
1195 if (!op_state
.has_existing_subuser()) {
1196 set_err_msg(err_msg
, "subuser does not exist");
1197 return -ERR_NO_SUCH_SUBUSER
;
1200 subuser_pair
.first
= subuser_str
;
1202 siter
= subuser_map
->find(subuser_str
);
1203 subuser
= siter
->second
;
1205 if (op_state
.has_key_op()) {
1206 ret
= user
->keys
.add(op_state
, &subprocess_msg
, true);
1208 set_err_msg(err_msg
, "unable to create subuser keys, " + subprocess_msg
);
1213 if (op_state
.has_subuser_perm())
1214 subuser
.perm_mask
= op_state
.get_subuser_perm();
1216 subuser_pair
.second
= subuser
;
1218 subuser_map
->erase(siter
);
1219 subuser_map
->insert(subuser_pair
);
1221 // attempt to save the subuser
1222 if (!defer_user_update
)
1223 ret
= user
->update(op_state
, err_msg
);
1231 int RGWSubUserPool::modify(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1233 return RGWSubUserPool::modify(op_state
, err_msg
, false);
1236 int RGWSubUserPool::modify(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_user_update
)
1238 std::string subprocess_msg
;
1243 ret
= check_op(op_state
, &subprocess_msg
);
1245 set_err_msg(err_msg
, "unable to parse request, " + subprocess_msg
);
1249 ret
= execute_modify(op_state
, &subprocess_msg
, defer_user_update
);
1251 set_err_msg(err_msg
, "unable to modify subuser, " + subprocess_msg
);
1258 RGWUserCapPool::RGWUserCapPool(RGWUser
*usr
)
1264 caps_allowed
= true;
1267 int RGWUserCapPool::init(RGWUserAdminOpState
& op_state
)
1269 if (!op_state
.is_initialized()) {
1270 caps_allowed
= false;
1274 rgw_user
& uid
= op_state
.get_user_id();
1275 if (uid
.compare(RGW_USER_ANON_ID
) == 0) {
1276 caps_allowed
= false;
1280 caps
= op_state
.get_caps_obj();
1282 caps_allowed
= false;
1283 return -ERR_INVALID_CAP
;
1286 caps_allowed
= true;
1291 int RGWUserCapPool::add(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1293 return add(op_state
, err_msg
, false);
1296 int RGWUserCapPool::add(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_save
)
1299 std::string caps_str
= op_state
.get_caps();
1301 if (!op_state
.is_populated()) {
1302 set_err_msg(err_msg
, "user info was not populated");
1306 if (!caps_allowed
) {
1307 set_err_msg(err_msg
, "caps not allowed for this user");
1311 if (caps_str
.empty()) {
1312 set_err_msg(err_msg
, "empty user caps");
1313 return -ERR_INVALID_CAP
;
1316 int r
= caps
->add_from_string(caps_str
);
1318 set_err_msg(err_msg
, "unable to add caps: " + caps_str
);
1323 ret
= user
->update(op_state
, err_msg
);
1331 int RGWUserCapPool::remove(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1333 return remove(op_state
, err_msg
, false);
1336 int RGWUserCapPool::remove(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_save
)
1340 std::string caps_str
= op_state
.get_caps();
1342 if (!op_state
.is_populated()) {
1343 set_err_msg(err_msg
, "user info was not populated");
1347 if (!caps_allowed
) {
1348 set_err_msg(err_msg
, "caps not allowed for this user");
1352 if (caps_str
.empty()) {
1353 set_err_msg(err_msg
, "empty user caps");
1354 return -ERR_INVALID_CAP
;
1357 int r
= caps
->remove_from_string(caps_str
);
1359 set_err_msg(err_msg
, "unable to remove caps: " + caps_str
);
1364 ret
= user
->update(op_state
, err_msg
);
1372 RGWUser::RGWUser() : caps(this), keys(this), subusers(this)
1377 int RGWUser::init(rgw::sal::RGWRadosStore
*storage
, RGWUserAdminOpState
& op_state
)
1380 int ret
= init_storage(storage
);
1384 ret
= init(op_state
);
1391 void RGWUser::init_default()
1393 // use anonymous user info as a placeholder
1394 rgw_get_anon_user(old_info
);
1395 user_id
= RGW_USER_ANON_ID
;
1400 int RGWUser::init_storage(rgw::sal::RGWRadosStore
*storage
)
1407 user_ctl
= store
->ctl()->user
;
1412 keys
= RGWAccessKeyPool(this);
1413 caps
= RGWUserCapPool(this);
1414 subusers
= RGWSubUserPool(this);
1419 int RGWUser::init(RGWUserAdminOpState
& op_state
)
1422 std::string swift_user
;
1423 user_id
= op_state
.get_user_id();
1424 std::string user_email
= op_state
.get_user_email();
1425 std::string access_key
= op_state
.get_access_key();
1426 std::string subuser
= op_state
.get_subuser();
1428 int key_type
= op_state
.get_key_type();
1429 if (key_type
== KEY_TYPE_SWIFT
) {
1430 swift_user
= op_state
.get_access_key();
1434 RGWUserInfo user_info
;
1438 if (user_id
.empty() && !subuser
.empty()) {
1439 size_t pos
= subuser
.find(':');
1440 if (pos
!= string::npos
) {
1441 user_id
= subuser
.substr(0, pos
);
1442 op_state
.set_user_id(user_id
);
1446 if (!user_id
.empty() && (user_id
.compare(RGW_USER_ANON_ID
) != 0)) {
1447 found
= (rgw_get_user_info_by_uid(user_ctl
, user_id
, user_info
, &op_state
.objv
) >= 0);
1448 op_state
.found_by_uid
= found
;
1450 if (store
->ctx()->_conf
.get_val
<bool>("rgw_user_unique_email")) {
1451 if (!user_email
.empty() && !found
) {
1452 found
= (rgw_get_user_info_by_email(user_ctl
, user_email
, user_info
, &op_state
.objv
) >= 0);
1453 op_state
.found_by_email
= found
;
1456 if (!swift_user
.empty() && !found
) {
1457 found
= (rgw_get_user_info_by_swift(user_ctl
, swift_user
, user_info
, &op_state
.objv
) >= 0);
1458 op_state
.found_by_key
= found
;
1460 if (!access_key
.empty() && !found
) {
1461 found
= (rgw_get_user_info_by_access_key(user_ctl
, access_key
, user_info
, &op_state
.objv
) >= 0);
1462 op_state
.found_by_key
= found
;
1465 op_state
.set_existing_user(found
);
1467 op_state
.set_user_info(user_info
);
1468 op_state
.set_populated();
1470 old_info
= user_info
;
1474 if (user_id
.empty()) {
1475 user_id
= user_info
.user_id
;
1477 op_state
.set_initialized();
1479 // this may have been called by a helper object
1480 int ret
= init_members(op_state
);
1487 int RGWUser::init_members(RGWUserAdminOpState
& op_state
)
1491 ret
= keys
.init(op_state
);
1495 ret
= subusers
.init(op_state
);
1499 ret
= caps
.init(op_state
);
1506 int RGWUser::update(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1509 std::string subprocess_msg
;
1510 RGWUserInfo user_info
= op_state
.get_user_info();
1513 set_err_msg(err_msg
, "couldn't initialize storage");
1517 RGWUserInfo
*pold_info
= (is_populated() ? &old_info
: nullptr);
1519 ret
= rgw_store_user_info(user_ctl
, user_info
, pold_info
, &op_state
.objv
, real_time(), false);
1521 set_err_msg(err_msg
, "unable to store user info");
1525 old_info
= user_info
;
1531 int RGWUser::check_op(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1535 rgw_user
& op_id
= op_state
.get_user_id();
1537 RGWUserInfo user_info
;
1539 same_id
= (user_id
.compare(op_id
) == 0);
1540 populated
= is_populated();
1542 if (op_id
.compare(RGW_USER_ANON_ID
) == 0) {
1543 set_err_msg(err_msg
, "unable to perform operations on the anonymous user");
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());
1554 int ret
= rgw_validate_tenant_name(op_id
.tenant
);
1556 set_err_msg(err_msg
,
1557 "invalid tenant only alphanumeric and _ characters are allowed");
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;
1570 // update swift_keys with new user id
1571 static void rename_swift_keys(const rgw_user
& user
,
1572 std::map
<std::string
, RGWAccessKey
>& keys
)
1574 std::string user_id
;
1575 user
.to_str(user_id
);
1577 auto modify_keys
= std::move(keys
);
1578 for ([[maybe_unused
]] auto& [k
, key
] : modify_keys
) {
1579 std::string id
= user_id
+ ":" + key
.subuser
;
1581 keys
[id
] = std::move(key
);
1585 int RGWUser::execute_rename(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1588 bool populated
= op_state
.is_populated();
1590 if (!op_state
.has_existing_user() && !populated
) {
1591 set_err_msg(err_msg
, "user not found");
1596 ret
= init(op_state
);
1598 set_err_msg(err_msg
, "unable to retrieve user info");
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());
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();
1615 RGWObjVersionTracker objv
;
1616 const bool exclusive
= !op_state
.get_overwrite_new_user(); // overwrite if requested
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");
1627 set_err_msg(err_msg
, "unable to store new user info");
1631 RGWAccessControlPolicy policy_instance
;
1632 policy_instance
.create_default(new_user
.get_user(), old_user
.get_display_name());
1634 //unlink and link buckets to new user
1636 CephContext
*cct
= store
->ctx();
1637 size_t max_buckets
= cct
->_conf
->rgw_list_buckets_max_chunk
;
1638 rgw::sal::RGWBucketList buckets
;
1641 ret
= old_user
.list_buckets(marker
, "", max_buckets
, false, buckets
);
1643 set_err_msg(err_msg
, "unable to list user buckets");
1647 map
<std::string
, rgw::sal::RGWBucket
*>& m
= buckets
.get_buckets();
1648 std::map
<std::string
, rgw::sal::RGWBucket
*>::iterator it
;
1650 for (it
= m
.begin(); it
!= m
.end(); ++it
) {
1651 rgw::sal::RGWBucket
* bucket
= it
->second
;
1654 ret
= bucket
->get_bucket_info(null_yield
);
1656 set_err_msg(err_msg
, "failed to fetch bucket info for bucket=" + bucket
->get_name());
1660 ret
= bucket
->set_acl(policy_instance
, null_yield
);
1662 set_err_msg(err_msg
, "failed to set acl on bucket " + bucket
->get_name());
1666 ret
= bucket
->link(&new_user
, null_yield
);
1668 set_err_msg(err_msg
, "failed to link bucket " + bucket
->get_name());
1672 ret
= bucket
->chown(&new_user
, &old_user
, null_yield
);
1674 set_err_msg(err_msg
, "failed to run bucket chown" + cpp_strerror(-ret
));
1679 } while (buckets
.is_truncated());
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
;
1687 rename_swift_keys(new_user
.get_user(), user_info
.swift_keys
);
1689 return update(op_state
, err_msg
);
1692 int RGWUser::execute_add(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1694 std::string subprocess_msg
;
1696 bool defer_user_update
= true;
1698 RGWUserInfo user_info
;
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();
1704 // fail if the user exists already
1705 if (op_state
.has_existing_user()) {
1706 if (op_state
.found_by_email
) {
1707 set_err_msg(err_msg
, "email: " + user_email
+
1708 " is the email address an existing user");
1709 ret
= -ERR_EMAIL_EXIST
;
1710 } else if (op_state
.found_by_key
) {
1711 set_err_msg(err_msg
, "duplicate key provided");
1712 ret
= -ERR_KEY_EXIST
;
1714 set_err_msg(err_msg
, "user: " + op_state
.user_id
.to_str() + " exists");
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");
1726 // fail if the display name was not included
1727 if (display_name
.empty()) {
1728 set_err_msg(err_msg
, "no display name specified");
1733 // set the user info
1735 user_info
.user_id
= user_id
;
1736 user_info
.display_name
= display_name
;
1737 user_info
.type
= TYPE_RGW
;
1739 if (!user_email
.empty())
1740 user_info
.user_email
= user_email
;
1742 CephContext
*cct
= store
->ctx();
1743 if (op_state
.max_buckets_specified
) {
1744 user_info
.max_buckets
= op_state
.get_max_buckets();
1746 user_info
.max_buckets
=
1747 cct
->_conf
.get_val
<int64_t>("rgw_user_max_buckets");
1750 user_info
.suspended
= op_state
.get_suspension_status();
1751 user_info
.admin
= op_state
.admin
;
1752 user_info
.system
= op_state
.system
;
1754 if (op_state
.op_mask_specified
)
1755 user_info
.op_mask
= op_state
.get_op_mask();
1757 if (op_state
.has_bucket_quota()) {
1758 user_info
.bucket_quota
= op_state
.get_bucket_quota();
1760 rgw_apply_default_bucket_quota(user_info
.bucket_quota
, cct
->_conf
);
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
;
1771 if (op_state
.has_user_quota()) {
1772 user_info
.user_quota
= op_state
.get_user_quota();
1774 rgw_apply_default_user_quota(user_info
.user_quota
, cct
->_conf
);
1777 if (op_state
.default_placement_specified
) {
1778 user_info
.default_placement
= op_state
.default_placement
;
1781 if (op_state
.placement_tags_specified
) {
1782 user_info
.placement_tags
= op_state
.placement_tags
;
1785 // update the request
1786 op_state
.set_user_info(user_info
);
1787 op_state
.set_populated();
1789 // update the helper objects
1790 ret
= init_members(op_state
);
1792 set_err_msg(err_msg
, "unable to initialize user");
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
);
1800 set_err_msg(err_msg
, "unable to create access key, " + subprocess_msg
);
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
);
1809 set_err_msg(err_msg
, "unable to add user capabilities, " + subprocess_msg
);
1814 ret
= update(op_state
, err_msg
);
1822 int RGWUser::add(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1824 std::string subprocess_msg
;
1827 ret
= check_op(op_state
, &subprocess_msg
);
1829 set_err_msg(err_msg
, "unable to parse parameters, " + subprocess_msg
);
1833 ret
= execute_add(op_state
, &subprocess_msg
);
1835 set_err_msg(err_msg
, "unable to create user, " + subprocess_msg
);
1842 int RGWUser::rename(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1844 std::string subprocess_msg
;
1847 ret
= check_op(op_state
, &subprocess_msg
);
1849 set_err_msg(err_msg
, "unable to parse parameters, " + subprocess_msg
);
1853 ret
= execute_rename(op_state
, &subprocess_msg
);
1855 set_err_msg(err_msg
, "unable to rename user, " + subprocess_msg
);
1862 int RGWUser::execute_remove(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, optional_yield y
)
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();
1870 if (!op_state
.has_existing_user()) {
1871 set_err_msg(err_msg
, "user does not exist");
1875 rgw::sal::RGWBucketList buckets
;
1877 CephContext
*cct
= store
->ctx();
1878 size_t max_buckets
= cct
->_conf
->rgw_list_buckets_max_chunk
;
1880 ret
= rgw_read_user_buckets(store
, uid
, buckets
, marker
, string(),
1881 max_buckets
, false);
1883 set_err_msg(err_msg
, "unable to read user bucket info");
1887 std::map
<std::string
, rgw::sal::RGWBucket
*>& m
= buckets
.get_buckets();
1888 if (!m
.empty() && !purge_data
) {
1889 set_err_msg(err_msg
, "must specify purge data to remove user with buckets");
1890 return -EEXIST
; // change to code that maps to 409: conflict
1893 std::map
<std::string
, rgw::sal::RGWBucket
*>::iterator it
;
1894 for (it
= m
.begin(); it
!= m
.end(); ++it
) {
1895 ret
= it
->second
->remove_bucket(true, y
);
1897 set_err_msg(err_msg
, "unable to delete user data");
1904 } while (buckets
.is_truncated());
1906 ret
= user_ctl
->remove_info(user_info
, y
, RGWUserCtl::RemoveParams()
1907 .set_objv_tracker(&op_state
.objv
));
1909 set_err_msg(err_msg
, "unable to remove user from RADOS");
1913 op_state
.clear_populated();
1919 int RGWUser::remove(RGWUserAdminOpState
& op_state
, optional_yield y
, std::string
*err_msg
)
1921 std::string subprocess_msg
;
1924 ret
= check_op(op_state
, &subprocess_msg
);
1926 set_err_msg(err_msg
, "unable to parse parameters, " + subprocess_msg
);
1930 ret
= execute_remove(op_state
, &subprocess_msg
, y
);
1932 set_err_msg(err_msg
, "unable to remove user, " + subprocess_msg
);
1939 int RGWUser::execute_modify(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1941 bool populated
= op_state
.is_populated();
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();
1947 RGWUserInfo user_info
;
1948 RGWUserInfo duplicate_check
;
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");
1956 // if the user hasn't already been populated...attempt to
1958 ret
= init(op_state
);
1960 set_err_msg(err_msg
, "unable to retrieve user info");
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");
1971 user_info
= old_info
;
1973 std::string old_email
= old_info
.user_email
;
1974 if (!op_email
.empty()) {
1975 // make sure we are not adding a duplicate email
1976 if (old_email
!= op_email
) {
1977 ret
= rgw_get_user_info_by_email(user_ctl
, op_email
, duplicate_check
);
1978 if (ret
>= 0 && duplicate_check
.user_id
.compare(user_id
) != 0) {
1979 set_err_msg(err_msg
, "cannot add duplicate email");
1980 return -ERR_EMAIL_EXIST
;
1983 user_info
.user_email
= op_email
;
1984 } else if (op_email
.empty() && op_state
.user_email_specified
) {
1985 ldout(store
->ctx(), 10) << "removing email index: " << user_info
.user_email
<< dendl
;
1986 /* will be physically removed later when calling update() */
1987 user_info
.user_email
.clear();
1990 // update the remaining user info
1991 if (!display_name
.empty())
1992 user_info
.display_name
= display_name
;
1994 if (op_state
.max_buckets_specified
)
1995 user_info
.max_buckets
= op_state
.get_max_buckets();
1997 if (op_state
.admin_specified
)
1998 user_info
.admin
= op_state
.admin
;
2000 if (op_state
.system_specified
)
2001 user_info
.system
= op_state
.system
;
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
;
2011 if (op_state
.op_mask_specified
)
2012 user_info
.op_mask
= op_state
.get_op_mask();
2014 if (op_state
.has_bucket_quota())
2015 user_info
.bucket_quota
= op_state
.get_bucket_quota();
2017 if (op_state
.has_user_quota())
2018 user_info
.user_quota
= op_state
.get_user_quota();
2020 if (op_state
.has_suspension_op()) {
2021 __u8 suspended
= op_state
.get_suspension_status();
2022 user_info
.suspended
= suspended
;
2024 rgw::sal::RGWBucketList buckets
;
2026 if (user_id
.empty()) {
2027 set_err_msg(err_msg
, "empty user id passed...aborting");
2032 CephContext
*cct
= store
->ctx();
2033 size_t max_buckets
= cct
->_conf
->rgw_list_buckets_max_chunk
;
2035 ret
= rgw_read_user_buckets(store
, user_id
, buckets
, marker
, string(),
2036 max_buckets
, false);
2038 set_err_msg(err_msg
, "could not get buckets for uid: " + user_id
.to_str());
2042 std::map
<std::string
, rgw::sal::RGWBucket
*>& m
= buckets
.get_buckets();
2043 std::map
<std::string
, rgw::sal::RGWBucket
*>::iterator iter
;
2045 vector
<rgw_bucket
> bucket_names
;
2046 for (iter
= m
.begin(); iter
!= m
.end(); ++iter
) {
2047 rgw::sal::RGWBucket
* obj
= iter
->second
;
2048 bucket_names
.push_back(obj
->get_bi());
2050 marker
= iter
->first
;
2053 ret
= store
->getRados()->set_buckets_enabled(bucket_names
, !suspended
);
2055 set_err_msg(err_msg
, "failed to modify bucket");
2059 } while (buckets
.is_truncated());
2062 if (op_state
.mfa_ids_specified
) {
2063 user_info
.mfa_ids
= op_state
.mfa_ids
;
2066 if (op_state
.default_placement_specified
) {
2067 user_info
.default_placement
= op_state
.default_placement
;
2070 if (op_state
.placement_tags_specified
) {
2071 user_info
.placement_tags
= op_state
.placement_tags
;
2074 op_state
.set_user_info(user_info
);
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);
2080 set_err_msg(err_msg
, "unable to create or modify keys, " + subprocess_msg
);
2085 ret
= update(op_state
, err_msg
);
2092 int RGWUser::modify(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
2094 std::string subprocess_msg
;
2097 ret
= check_op(op_state
, &subprocess_msg
);
2099 set_err_msg(err_msg
, "unable to parse parameters, " + subprocess_msg
);
2103 ret
= execute_modify(op_state
, &subprocess_msg
);
2105 set_err_msg(err_msg
, "unable to modify user, " + subprocess_msg
);
2112 int RGWUser::info(RGWUserAdminOpState
& op_state
, RGWUserInfo
& fetched_info
, std::string
*err_msg
)
2114 int ret
= init(op_state
);
2116 set_err_msg(err_msg
, "unable to fetch user info");
2120 fetched_info
= op_state
.get_user_info();
2125 int RGWUser::info(RGWUserInfo
& fetched_info
, std::string
*err_msg
)
2127 if (!is_populated()) {
2128 set_err_msg(err_msg
, "no user info saved");
2132 fetched_info
= old_info
;
2137 int RGWUser::list(RGWUserAdminOpState
& op_state
, RGWFormatterFlusher
& flusher
)
2139 Formatter
*formatter
= flusher
.get_formatter();
2140 void *handle
= nullptr;
2141 std::string metadata_key
= "user";
2142 if (op_state
.max_entries
> 1000) {
2143 op_state
.max_entries
= 1000;
2146 auto meta_mgr
= store
->ctl()->meta
.mgr
;
2148 int ret
= meta_mgr
->list_keys_init(metadata_key
, op_state
.marker
, &handle
);
2153 bool truncated
= false;
2158 // open the result object section
2159 formatter
->open_object_section("result");
2161 // open the user id list array section
2162 formatter
->open_array_section("keys");
2164 std::list
<std::string
> keys
;
2165 left
= op_state
.max_entries
- count
;
2166 ret
= meta_mgr
->list_keys_next(handle
, left
, keys
, &truncated
);
2167 if (ret
< 0 && ret
!= -ENOENT
) {
2169 } if (ret
!= -ENOENT
) {
2170 for (std::list
<std::string
>::iterator iter
= keys
.begin(); iter
!= keys
.end(); ++iter
) {
2171 formatter
->dump_string("key", *iter
);
2175 } while (truncated
&& left
> 0);
2176 // close user id list section
2177 formatter
->close_section();
2179 formatter
->dump_bool("truncated", truncated
);
2180 formatter
->dump_int("count", count
);
2182 formatter
->dump_string("marker", meta_mgr
->get_marker(handle
));
2185 // close result object section
2186 formatter
->close_section();
2188 meta_mgr
->list_keys_complete(handle
);
2194 int RGWUserAdminOp_User::list(rgw::sal::RGWRadosStore
*store
, RGWUserAdminOpState
& op_state
,
2195 RGWFormatterFlusher
& flusher
)
2199 int ret
= user
.init_storage(store
);
2203 ret
= user
.list(op_state
, flusher
);
2210 int RGWUserAdminOp_User::info(rgw::sal::RGWRadosStore
*store
, RGWUserAdminOpState
& op_state
,
2211 RGWFormatterFlusher
& flusher
)
2216 int ret
= user
.init(store
, op_state
);
2220 if (!op_state
.has_existing_user())
2221 return -ERR_NO_SUCH_USER
;
2223 Formatter
*formatter
= flusher
.get_formatter();
2225 ret
= user
.info(info
, NULL
);
2229 if (op_state
.sync_stats
) {
2230 ret
= rgw_user_sync_all_stats(store
, info
.user_id
);
2236 RGWStorageStats stats
;
2237 RGWStorageStats
*arg_stats
= NULL
;
2238 if (op_state
.fetch_stats
) {
2239 int ret
= store
->ctl()->user
->read_stats(info
.user_id
, &stats
);
2240 if (ret
< 0 && ret
!= -ENOENT
) {
2250 dump_user_info(formatter
, info
, arg_stats
);
2257 int RGWUserAdminOp_User::create(rgw::sal::RGWRadosStore
*store
, RGWUserAdminOpState
& op_state
,
2258 RGWFormatterFlusher
& flusher
)
2262 int ret
= user
.init(store
, op_state
);
2266 Formatter
*formatter
= flusher
.get_formatter();
2268 ret
= user
.add(op_state
, NULL
);
2271 ret
= -ERR_USER_EXIST
;
2275 ret
= user
.info(info
, NULL
);
2282 dump_user_info(formatter
, info
);
2289 int RGWUserAdminOp_User::modify(rgw::sal::RGWRadosStore
*store
, RGWUserAdminOpState
& op_state
,
2290 RGWFormatterFlusher
& flusher
)
2294 int ret
= user
.init(store
, op_state
);
2297 Formatter
*formatter
= flusher
.get_formatter();
2299 ret
= user
.modify(op_state
, NULL
);
2302 ret
= -ERR_NO_SUCH_USER
;
2306 ret
= user
.info(info
, NULL
);
2313 dump_user_info(formatter
, info
);
2320 int RGWUserAdminOp_User::remove(rgw::sal::RGWRadosStore
*store
, RGWUserAdminOpState
& op_state
,
2321 RGWFormatterFlusher
& flusher
, optional_yield y
)
2325 int ret
= user
.init(store
, op_state
);
2330 ret
= user
.remove(op_state
, y
, NULL
);
2333 ret
= -ERR_NO_SUCH_USER
;
2337 int RGWUserAdminOp_Subuser::create(rgw::sal::RGWRadosStore
*store
, RGWUserAdminOpState
& op_state
,
2338 RGWFormatterFlusher
& flusher
)
2342 int ret
= user
.init(store
, op_state
);
2346 if (!op_state
.has_existing_user())
2347 return -ERR_NO_SUCH_USER
;
2349 Formatter
*formatter
= flusher
.get_formatter();
2351 ret
= user
.subusers
.add(op_state
, NULL
);
2355 ret
= user
.info(info
, NULL
);
2362 dump_subusers_info(formatter
, info
);
2369 int RGWUserAdminOp_Subuser::modify(rgw::sal::RGWRadosStore
*store
, RGWUserAdminOpState
& op_state
,
2370 RGWFormatterFlusher
& flusher
)
2374 int ret
= user
.init(store
, op_state
);
2378 if (!op_state
.has_existing_user())
2379 return -ERR_NO_SUCH_USER
;
2381 Formatter
*formatter
= flusher
.get_formatter();
2383 ret
= user
.subusers
.modify(op_state
, NULL
);
2387 ret
= user
.info(info
, NULL
);
2394 dump_subusers_info(formatter
, info
);
2401 int RGWUserAdminOp_Subuser::remove(rgw::sal::RGWRadosStore
*store
, RGWUserAdminOpState
& op_state
,
2402 RGWFormatterFlusher
& flusher
)
2406 int ret
= user
.init(store
, op_state
);
2411 if (!op_state
.has_existing_user())
2412 return -ERR_NO_SUCH_USER
;
2414 ret
= user
.subusers
.remove(op_state
, NULL
);
2421 int RGWUserAdminOp_Key::create(rgw::sal::RGWRadosStore
*store
, RGWUserAdminOpState
& op_state
,
2422 RGWFormatterFlusher
& flusher
)
2426 int ret
= user
.init(store
, op_state
);
2430 if (!op_state
.has_existing_user())
2431 return -ERR_NO_SUCH_USER
;
2433 Formatter
*formatter
= flusher
.get_formatter();
2435 ret
= user
.keys
.add(op_state
, NULL
);
2439 ret
= user
.info(info
, NULL
);
2446 int key_type
= op_state
.get_key_type();
2448 if (key_type
== KEY_TYPE_SWIFT
)
2449 dump_swift_keys_info(formatter
, info
);
2451 else if (key_type
== KEY_TYPE_S3
)
2452 dump_access_keys_info(formatter
, info
);
2460 int RGWUserAdminOp_Key::remove(rgw::sal::RGWRadosStore
*store
, RGWUserAdminOpState
& op_state
,
2461 RGWFormatterFlusher
& flusher
)
2465 int ret
= user
.init(store
, op_state
);
2469 if (!op_state
.has_existing_user())
2470 return -ERR_NO_SUCH_USER
;
2473 ret
= user
.keys
.remove(op_state
, NULL
);
2480 int RGWUserAdminOp_Caps::add(rgw::sal::RGWRadosStore
*store
, RGWUserAdminOpState
& op_state
,
2481 RGWFormatterFlusher
& flusher
)
2485 int ret
= user
.init(store
, op_state
);
2489 if (!op_state
.has_existing_user())
2490 return -ERR_NO_SUCH_USER
;
2492 Formatter
*formatter
= flusher
.get_formatter();
2494 ret
= user
.caps
.add(op_state
, NULL
);
2498 ret
= user
.info(info
, NULL
);
2505 info
.caps
.dump(formatter
);
2513 int RGWUserAdminOp_Caps::remove(rgw::sal::RGWRadosStore
*store
, RGWUserAdminOpState
& op_state
,
2514 RGWFormatterFlusher
& flusher
)
2518 int ret
= user
.init(store
, op_state
);
2522 if (!op_state
.has_existing_user())
2523 return -ERR_NO_SUCH_USER
;
2525 Formatter
*formatter
= flusher
.get_formatter();
2527 ret
= user
.caps
.remove(op_state
, NULL
);
2531 ret
= user
.info(info
, NULL
);
2538 info
.caps
.dump(formatter
);
2545 class RGWUserMetadataHandler
: public RGWMetadataHandler_GenericMetaBE
{
2548 RGWSI_User
*user
{nullptr};
2551 RGWUserMetadataHandler(RGWSI_User
*user_svc
) {
2552 base_init(user_svc
->ctx(), user_svc
->get_be_handler());
2553 svc
.user
= user_svc
;
2556 string
get_type() override
{ return "user"; }
2558 int do_get(RGWSI_MetaBackend_Handler::Op
*op
, string
& entry
, RGWMetadataObject
**obj
, optional_yield y
) override
{
2559 RGWUserCompleteInfo uci
;
2560 RGWObjVersionTracker objv_tracker
;
2563 rgw_user user
= RGWSI_User::user_from_meta_key(entry
);
2565 int ret
= svc
.user
->read_user_info(op
->ctx(), user
, &uci
.info
, &objv_tracker
,
2566 &mtime
, nullptr, &uci
.attrs
,
2572 RGWUserMetadataObject
*mdo
= new RGWUserMetadataObject(uci
, objv_tracker
.read_version
, mtime
);
2578 RGWMetadataObject
*get_meta_obj(JSONObj
*jo
, const obj_version
& objv
, const ceph::real_time
& mtime
) override
{
2579 RGWUserCompleteInfo uci
;
2582 decode_json_obj(uci
, jo
);
2583 } catch (JSONDecoder::err
& e
) {
2587 return new RGWUserMetadataObject(uci
, objv
, mtime
);
2590 int do_put(RGWSI_MetaBackend_Handler::Op
*op
, string
& entry
,
2591 RGWMetadataObject
*obj
,
2592 RGWObjVersionTracker
& objv_tracker
,
2594 RGWMDLogSyncType type
) override
;
2596 int do_remove(RGWSI_MetaBackend_Handler::Op
*op
, string
& entry
, RGWObjVersionTracker
& objv_tracker
,
2600 rgw_user user
= RGWSI_User::user_from_meta_key(entry
);
2602 int ret
= svc
.user
->read_user_info(op
->ctx(), user
, &info
, nullptr,
2603 nullptr, nullptr, nullptr,
2609 return svc
.user
->remove_user_info(op
->ctx(), info
, &objv_tracker
,
2614 class RGWMetadataHandlerPut_User
: public RGWMetadataHandlerPut_SObj
2616 RGWUserMetadataHandler
*uhandler
;
2617 RGWUserMetadataObject
*uobj
;
2619 RGWMetadataHandlerPut_User(RGWUserMetadataHandler
*_handler
,
2620 RGWSI_MetaBackend_Handler::Op
*op
, string
& entry
,
2621 RGWMetadataObject
*obj
, RGWObjVersionTracker
& objv_tracker
,
2623 RGWMDLogSyncType type
) : RGWMetadataHandlerPut_SObj(_handler
, op
, entry
, obj
, objv_tracker
, y
, type
),
2624 uhandler(_handler
) {
2625 uobj
= static_cast<RGWUserMetadataObject
*>(obj
);
2628 int put_checked() override
;
2631 int RGWUserMetadataHandler::do_put(RGWSI_MetaBackend_Handler::Op
*op
, string
& entry
,
2632 RGWMetadataObject
*obj
,
2633 RGWObjVersionTracker
& objv_tracker
,
2635 RGWMDLogSyncType type
)
2637 RGWMetadataHandlerPut_User
put_op(this, op
, entry
, obj
, objv_tracker
, y
, type
);
2638 return do_put_operate(&put_op
);
2641 int RGWMetadataHandlerPut_User::put_checked()
2643 RGWUserMetadataObject
*orig_obj
= static_cast<RGWUserMetadataObject
*>(old_obj
);
2644 RGWUserCompleteInfo
& uci
= uobj
->get_uci();
2646 map
<string
, bufferlist
> *pattrs
{nullptr};
2647 if (uci
.has_attrs
) {
2648 pattrs
= &uci
.attrs
;
2651 RGWUserInfo
*pold_info
= (orig_obj
? &orig_obj
->get_uci().info
: nullptr);
2653 auto mtime
= obj
->get_mtime();
2655 int ret
= uhandler
->svc
.user
->store_user_info(op
->ctx(), uci
.info
, pold_info
,
2656 &objv_tracker
, mtime
,
2662 return STATUS_APPLIED
;
2666 RGWUserCtl::RGWUserCtl(RGWSI_Zone
*zone_svc
,
2667 RGWSI_User
*user_svc
,
2668 RGWUserMetadataHandler
*_umhandler
) : umhandler(_umhandler
) {
2669 svc
.zone
= zone_svc
;
2670 svc
.user
= user_svc
;
2671 be_handler
= umhandler
->get_be_handler();
2675 class optional_default
2677 const std::optional
<T
>& opt
;
2678 std::optional
<T
> def
;
2681 optional_default(const std::optional
<T
>& _o
) : opt(_o
) {
2690 const T
*operator->() {
2694 const T
& operator*() {
2699 int RGWUserCtl::get_info_by_uid(const rgw_user
& uid
,
2702 const GetParams
& params
)
2705 return be_handler
->call([&](RGWSI_MetaBackend_Handler::Op
*op
) {
2706 return svc
.user
->read_user_info(op
->ctx(),
2709 params
.objv_tracker
,
2717 int RGWUserCtl::get_info_by_email(const string
& email
,
2720 const GetParams
& params
)
2722 return be_handler
->call([&](RGWSI_MetaBackend_Handler::Op
*op
) {
2723 return svc
.user
->get_user_info_by_email(op
->ctx(), email
,
2725 params
.objv_tracker
,
2731 int RGWUserCtl::get_info_by_swift(const string
& swift_name
,
2734 const GetParams
& params
)
2736 return be_handler
->call([&](RGWSI_MetaBackend_Handler::Op
*op
) {
2737 return svc
.user
->get_user_info_by_swift(op
->ctx(), swift_name
,
2739 params
.objv_tracker
,
2745 int RGWUserCtl::get_info_by_access_key(const string
& access_key
,
2748 const GetParams
& params
)
2750 return be_handler
->call([&](RGWSI_MetaBackend_Handler::Op
*op
) {
2751 return svc
.user
->get_user_info_by_access_key(op
->ctx(), access_key
,
2753 params
.objv_tracker
,
2759 int RGWUserCtl::get_attrs_by_uid(const rgw_user
& user_id
,
2760 map
<string
, bufferlist
> *pattrs
,
2762 RGWObjVersionTracker
*objv_tracker
)
2764 RGWUserInfo user_info
;
2766 return get_info_by_uid(user_id
, &user_info
, y
, RGWUserCtl::GetParams()
2768 .set_objv_tracker(objv_tracker
));
2771 int RGWUserCtl::store_info(const RGWUserInfo
& info
, optional_yield y
,
2772 const PutParams
& params
)
2774 string key
= RGWSI_User::get_meta_key(info
.user_id
);
2776 return be_handler
->call([&](RGWSI_MetaBackend_Handler::Op
*op
) {
2777 return svc
.user
->store_user_info(op
->ctx(), info
,
2779 params
.objv_tracker
,
2787 int RGWUserCtl::remove_info(const RGWUserInfo
& info
, optional_yield y
,
2788 const RemoveParams
& params
)
2791 string key
= RGWSI_User::get_meta_key(info
.user_id
);
2793 return be_handler
->call([&](RGWSI_MetaBackend_Handler::Op
*op
) {
2794 return svc
.user
->remove_user_info(op
->ctx(), info
,
2795 params
.objv_tracker
,
2800 int RGWUserCtl::add_bucket(const rgw_user
& user
,
2801 const rgw_bucket
& bucket
,
2802 ceph::real_time creation_time
)
2805 return be_handler
->call([&](RGWSI_MetaBackend_Handler::Op
*op
) {
2806 return svc
.user
->add_bucket(op
->ctx(), user
, bucket
, creation_time
);
2810 int RGWUserCtl::remove_bucket(const rgw_user
& user
,
2811 const rgw_bucket
& bucket
)
2814 return be_handler
->call([&](RGWSI_MetaBackend_Handler::Op
*op
) {
2815 return svc
.user
->remove_bucket(op
->ctx(), user
, bucket
);
2819 int RGWUserCtl::list_buckets(const rgw_user
& user
,
2820 const string
& marker
,
2821 const string
& end_marker
,
2824 RGWUserBuckets
*buckets
,
2826 uint64_t default_max
)
2832 return be_handler
->call([&](RGWSI_MetaBackend_Handler::Op
*op
) {
2833 int ret
= svc
.user
->list_buckets(op
->ctx(), user
, marker
, end_marker
,
2834 max
, buckets
, is_truncated
);
2839 map
<string
, RGWBucketEnt
>& m
= buckets
->get_buckets();
2840 ret
= ctl
.bucket
->read_buckets_stats(m
, null_yield
);
2841 if (ret
< 0 && ret
!= -ENOENT
) {
2842 ldout(svc
.user
->ctx(), 0) << "ERROR: could not get stats for buckets" << dendl
;
2850 int RGWUserCtl::flush_bucket_stats(const rgw_user
& user
,
2851 const RGWBucketEnt
& ent
)
2853 return be_handler
->call([&](RGWSI_MetaBackend_Handler::Op
*op
) {
2854 return svc
.user
->flush_bucket_stats(op
->ctx(), user
, ent
);
2858 int RGWUserCtl::complete_flush_stats(const rgw_user
& user
)
2860 return be_handler
->call([&](RGWSI_MetaBackend_Handler::Op
*op
) {
2861 return svc
.user
->complete_flush_stats(op
->ctx(), user
);
2865 int RGWUserCtl::reset_stats(const rgw_user
& user
)
2867 return be_handler
->call([&](RGWSI_MetaBackend_Handler::Op
*op
) {
2868 return svc
.user
->reset_bucket_stats(op
->ctx(), user
);
2872 int RGWUserCtl::read_stats(const rgw_user
& user
, RGWStorageStats
*stats
,
2873 ceph::real_time
*last_stats_sync
,
2874 ceph::real_time
*last_stats_update
)
2876 return be_handler
->call([&](RGWSI_MetaBackend_Handler::Op
*op
) {
2877 return svc
.user
->read_stats(op
->ctx(), user
, stats
,
2878 last_stats_sync
, last_stats_update
);
2882 int RGWUserCtl::read_stats_async(const rgw_user
& user
, RGWGetUserStats_CB
*cb
)
2884 return be_handler
->call([&](RGWSI_MetaBackend_Handler::Op
*op
) {
2885 return svc
.user
->read_stats_async(op
->ctx(), user
, cb
);
2889 RGWMetadataHandler
*RGWUserMetaHandlerAllocator::alloc(RGWSI_User
*user_svc
) {
2890 return new RGWUserMetadataHandler(user_svc
);