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"
15 #include "rgw_sal_rados.h"
19 #include "include/types.h"
21 #include "rgw_string.h"
23 // until everything is moved from rgw_common
24 #include "rgw_common.h"
26 #include "rgw_bucket.h"
27 #include "rgw_quota.h"
29 #include "services/svc_zone.h"
30 #include "services/svc_sys_obj.h"
31 #include "services/svc_sys_obj_cache.h"
32 #include "services/svc_user.h"
33 #include "services/svc_meta.h"
35 #define dout_subsys ceph_subsys_rgw
39 extern void op_type_to_str(uint32_t mask
, char *buf
, int len
);
42 * Get the anonymous (ie, unauthenticated) user info.
44 void rgw_get_anon_user(RGWUserInfo
& info
)
46 info
.user_id
= RGW_USER_ANON_ID
;
47 info
.display_name
.clear();
48 info
.access_keys
.clear();
51 int rgw_user_sync_all_stats(const DoutPrefixProvider
*dpp
, rgw::sal::RGWRadosStore
*store
,
52 const rgw_user
& user_id
, optional_yield y
)
54 rgw::sal::RGWBucketList user_buckets
;
55 rgw::sal::RGWRadosUser
user(store
, user_id
);
57 CephContext
*cct
= store
->ctx();
58 size_t max_entries
= cct
->_conf
->rgw_list_buckets_max_chunk
;
63 ret
= user
.list_buckets(dpp
, marker
, string(), max_entries
, false, user_buckets
, y
);
65 ldpp_dout(dpp
, 0) << "failed to read user buckets: ret=" << ret
<< dendl
;
68 auto& buckets
= user_buckets
.get_buckets();
69 for (auto i
= buckets
.begin(); i
!= buckets
.end(); ++i
) {
72 auto& bucket
= i
->second
;
74 ret
= bucket
->get_bucket_info(dpp
, y
);
76 ldpp_dout(dpp
, 0) << "ERROR: could not read bucket info: bucket=" << bucket
<< " ret=" << ret
<< dendl
;
79 ret
= bucket
->sync_user_stats(dpp
, y
);
81 ldout(cct
, 0) << "ERROR: could not sync bucket stats: ret=" << ret
<< dendl
;
84 ret
= bucket
->check_bucket_shards(dpp
);
86 ldpp_dout(dpp
, 0) << "ERROR in check_bucket_shards: " << cpp_strerror(-ret
)<< dendl
;
89 } while (user_buckets
.is_truncated());
91 ret
= store
->ctl()->user
->complete_flush_stats(dpp
, user
.get_user(), y
);
93 cerr
<< "ERROR: failed to complete syncing user stats: ret=" << ret
<< std::endl
;
100 int rgw_user_get_all_buckets_stats(const DoutPrefixProvider
*dpp
,
101 rgw::sal::RGWRadosStore
*store
,
102 const rgw_user
& user_id
,
103 map
<string
, cls_user_bucket_entry
>& buckets_usage_map
,
106 CephContext
*cct
= store
->ctx();
107 size_t max_entries
= cct
->_conf
->rgw_list_buckets_max_chunk
;
113 rgw::sal::RGWBucketList buckets
;
114 ret
= rgw_read_user_buckets(dpp
, store
, user_id
, buckets
, marker
,
115 string(), max_entries
, false, y
);
117 ldpp_dout(dpp
, 0) << "failed to read user buckets: ret=" << ret
<< dendl
;
120 auto& m
= buckets
.get_buckets();
121 for (const auto& i
: m
) {
124 auto& bucket_ent
= i
.second
;
125 ret
= bucket_ent
->read_bucket_stats(dpp
, y
);
127 ldpp_dout(dpp
, 0) << "ERROR: could not get bucket stats: ret=" << ret
<< dendl
;
130 cls_user_bucket_entry entry
;
131 bucket_ent
->convert(&entry
);
132 buckets_usage_map
.emplace(bucket_ent
->get_name(), entry
);
134 done
= (buckets
.count() < max_entries
);
141 * Save the given user information to storage.
142 * Returns: 0 on success, -ERR# on failure.
144 int rgw_store_user_info(const DoutPrefixProvider
*dpp
,
145 RGWUserCtl
*user_ctl
,
147 RGWUserInfo
*old_info
,
148 RGWObjVersionTracker
*objv_tracker
,
152 map
<string
, bufferlist
> *pattrs
)
154 return user_ctl
->store_info(dpp
, info
, y
,
155 RGWUserCtl::PutParams()
156 .set_old_info(old_info
)
157 .set_objv_tracker(objv_tracker
)
159 .set_exclusive(exclusive
)
164 * Given a uid, finds the user info associated with it.
165 * returns: 0 on success, -ERR# on failure (including nonexistence)
167 int rgw_get_user_info_by_uid(const DoutPrefixProvider
*dpp
,
168 RGWUserCtl
*user_ctl
,
172 RGWObjVersionTracker
* const objv_tracker
,
173 real_time
* const pmtime
,
174 rgw_cache_entry_info
* const cache_info
,
175 map
<string
, bufferlist
> * const pattrs
)
177 return user_ctl
->get_info_by_uid(dpp
, uid
, &info
, y
,
178 RGWUserCtl::GetParams()
179 .set_objv_tracker(objv_tracker
)
181 .set_cache_info(cache_info
)
186 * Given an email, finds the user info associated with it.
187 * returns: 0 on success, -ERR# on failure (including nonexistence)
189 int rgw_get_user_info_by_email(const DoutPrefixProvider
*dpp
,
190 RGWUserCtl
*user_ctl
, string
& email
,
191 RGWUserInfo
& info
, optional_yield y
,
192 RGWObjVersionTracker
*objv_tracker
,
195 return user_ctl
->get_info_by_email(dpp
, email
, &info
, y
,
196 RGWUserCtl::GetParams()
197 .set_objv_tracker(objv_tracker
)
202 * Given an swift username, finds the user_info associated with it.
203 * returns: 0 on success, -ERR# on failure (including nonexistence)
205 int rgw_get_user_info_by_swift(const DoutPrefixProvider
*dpp
,
206 RGWUserCtl
*user_ctl
,
207 const string
& swift_name
,
208 RGWUserInfo
& info
, /* out */
210 RGWObjVersionTracker
* const objv_tracker
,
211 real_time
* const pmtime
)
213 return user_ctl
->get_info_by_swift(dpp
, swift_name
, &info
, y
,
214 RGWUserCtl::GetParams()
215 .set_objv_tracker(objv_tracker
)
220 * Given an access key, finds the user info associated with it.
221 * returns: 0 on success, -ERR# on failure (including nonexistence)
223 extern int rgw_get_user_info_by_access_key(const DoutPrefixProvider
*dpp
,
224 RGWUserCtl
*user_ctl
,
225 const std::string
& access_key
,
228 RGWObjVersionTracker
* objv_tracker
,
231 return user_ctl
->get_info_by_access_key(dpp
, access_key
, &info
, y
,
232 RGWUserCtl::GetParams()
233 .set_objv_tracker(objv_tracker
)
237 static bool char_is_unreserved_url(char c
)
253 struct rgw_flags_desc
{
258 static struct rgw_flags_desc rgw_perms
[] = {
259 { RGW_PERM_FULL_CONTROL
, "full-control" },
260 { RGW_PERM_READ
| RGW_PERM_WRITE
, "read-write" },
261 { RGW_PERM_READ
, "read" },
262 { RGW_PERM_WRITE
, "write" },
263 { RGW_PERM_READ_ACP
, "read-acp" },
264 { RGW_PERM_WRITE_ACP
, "write-acp" },
268 void rgw_perm_to_str(uint32_t mask
, char *buf
, int len
)
270 const char *sep
= "";
273 snprintf(buf
, len
, "<none>");
277 uint32_t orig_mask
= mask
;
278 for (int i
= 0; rgw_perms
[i
].mask
; i
++) {
279 struct rgw_flags_desc
*desc
= &rgw_perms
[i
];
280 if ((mask
& desc
->mask
) == desc
->mask
) {
281 pos
+= snprintf(buf
+ pos
, len
- pos
, "%s%s", sep
, desc
->str
);
290 if (mask
== orig_mask
) // no change
295 uint32_t rgw_str_to_perm(const char *str
)
297 if (strcasecmp(str
, "") == 0)
298 return RGW_PERM_NONE
;
299 else if (strcasecmp(str
, "read") == 0)
300 return RGW_PERM_READ
;
301 else if (strcasecmp(str
, "write") == 0)
302 return RGW_PERM_WRITE
;
303 else if (strcasecmp(str
, "readwrite") == 0)
304 return RGW_PERM_READ
| RGW_PERM_WRITE
;
305 else if (strcasecmp(str
, "full") == 0)
306 return RGW_PERM_FULL_CONTROL
;
308 return RGW_PERM_INVALID
;
311 int rgw_validate_tenant_name(const string
& t
)
314 static bool is_good(char ch
) {
315 return isalnum(ch
) || ch
== '_';
318 std::string::const_iterator it
=
319 std::find_if_not(t
.begin(), t
.end(), tench::is_good
);
320 return (it
== t
.end())? 0: -ERR_INVALID_TENANT_NAME
;
323 static bool validate_access_key(string
& key
)
325 const char *p
= key
.c_str();
327 if (!char_is_unreserved_url(*p
))
334 static void set_err_msg(std::string
*sink
, std::string msg
)
336 if (sink
&& !msg
.empty())
341 * Dump either the full user info or a subset to a formatter.
343 * NOTE: It is the caller's respnsibility to ensure that the
344 * formatter is flushed at the correct time.
347 static void dump_subusers_info(Formatter
*f
, RGWUserInfo
&info
)
349 map
<string
, RGWSubUser
>::iterator uiter
;
351 f
->open_array_section("subusers");
352 for (uiter
= info
.subusers
.begin(); uiter
!= info
.subusers
.end(); ++uiter
) {
353 RGWSubUser
& u
= uiter
->second
;
354 f
->open_object_section("user");
356 info
.user_id
.to_str(s
);
357 f
->dump_format("id", "%s:%s", s
.c_str(), u
.name
.c_str());
359 rgw_perm_to_str(u
.perm_mask
, buf
, sizeof(buf
));
360 f
->dump_string("permissions", buf
);
366 static void dump_access_keys_info(Formatter
*f
, RGWUserInfo
&info
)
368 map
<string
, RGWAccessKey
>::iterator kiter
;
369 f
->open_array_section("keys");
370 for (kiter
= info
.access_keys
.begin(); kiter
!= info
.access_keys
.end(); ++kiter
) {
371 RGWAccessKey
& k
= kiter
->second
;
372 const char *sep
= (k
.subuser
.empty() ? "" : ":");
373 const char *subuser
= (k
.subuser
.empty() ? "" : k
.subuser
.c_str());
374 f
->open_object_section("key");
376 info
.user_id
.to_str(s
);
377 f
->dump_format("user", "%s%s%s", s
.c_str(), sep
, subuser
);
378 f
->dump_string("access_key", k
.id
);
379 f
->dump_string("secret_key", k
.key
);
385 static void dump_swift_keys_info(Formatter
*f
, RGWUserInfo
&info
)
387 map
<string
, RGWAccessKey
>::iterator kiter
;
388 f
->open_array_section("swift_keys");
389 for (kiter
= info
.swift_keys
.begin(); kiter
!= info
.swift_keys
.end(); ++kiter
) {
390 RGWAccessKey
& k
= kiter
->second
;
391 const char *sep
= (k
.subuser
.empty() ? "" : ":");
392 const char *subuser
= (k
.subuser
.empty() ? "" : k
.subuser
.c_str());
393 f
->open_object_section("key");
395 info
.user_id
.to_str(s
);
396 f
->dump_format("user", "%s%s%s", s
.c_str(), sep
, subuser
);
397 f
->dump_string("secret_key", k
.key
);
403 static void dump_user_info(Formatter
*f
, RGWUserInfo
&info
,
404 RGWStorageStats
*stats
= NULL
)
406 f
->open_object_section("user_info");
407 encode_json("tenant", info
.user_id
.tenant
, f
);
408 encode_json("user_id", info
.user_id
.id
, f
);
409 encode_json("display_name", info
.display_name
, f
);
410 encode_json("email", info
.user_email
, f
);
411 encode_json("suspended", (int)info
.suspended
, f
);
412 encode_json("max_buckets", (int)info
.max_buckets
, f
);
414 dump_subusers_info(f
, info
);
415 dump_access_keys_info(f
, info
);
416 dump_swift_keys_info(f
, info
);
418 encode_json("caps", info
.caps
, f
);
421 op_type_to_str(info
.op_mask
, buf
, sizeof(buf
));
422 encode_json("op_mask", (const char *)buf
, f
);
423 encode_json("system", (bool)info
.system
, f
);
424 encode_json("admin", (bool)info
.admin
, f
);
425 encode_json("default_placement", info
.default_placement
.name
, f
);
426 encode_json("default_storage_class", info
.default_placement
.storage_class
, f
);
427 encode_json("placement_tags", info
.placement_tags
, f
);
428 encode_json("bucket_quota", info
.bucket_quota
, f
);
429 encode_json("user_quota", info
.user_quota
, f
);
430 encode_json("temp_url_keys", info
.temp_url_keys
, f
);
432 string user_source_type
;
433 switch ((RGWIdentityType
)info
.type
) {
435 user_source_type
= "rgw";
438 user_source_type
= "keystone";
441 user_source_type
= "ldap";
444 user_source_type
= "none";
447 user_source_type
= "none";
450 encode_json("type", user_source_type
, f
);
451 encode_json("mfa_ids", info
.mfa_ids
, f
);
453 encode_json("stats", *stats
, f
);
459 RGWAccessKeyPool::RGWAccessKeyPool(RGWUser
* usr
)
467 store
= user
->get_store();
468 user_ctl
= user
->get_user_ctl();
471 int RGWAccessKeyPool::init(RGWUserAdminOpState
& op_state
)
473 if (!op_state
.is_initialized()) {
474 keys_allowed
= false;
478 rgw_user
& uid
= op_state
.get_user_id();
479 if (uid
.compare(RGW_USER_ANON_ID
) == 0) {
480 keys_allowed
= false;
484 swift_keys
= op_state
.get_swift_keys();
485 access_keys
= op_state
.get_access_keys();
493 * Do a fairly exhaustive search for an existing key matching the parameters
494 * given. Also handles the case where no key type was specified and updates
495 * the operation state if needed.
498 bool RGWAccessKeyPool::check_existing_key(RGWUserAdminOpState
& op_state
)
500 bool existing_key
= false;
502 int key_type
= op_state
.get_key_type();
503 std::string kid
= op_state
.get_access_key();
504 std::map
<std::string
, RGWAccessKey
>::iterator kiter
;
505 std::string swift_kid
= op_state
.build_default_swift_kid();
507 RGWUserInfo dup_info
;
509 if (kid
.empty() && swift_kid
.empty())
514 kiter
= swift_keys
->find(swift_kid
);
516 existing_key
= (kiter
!= swift_keys
->end());
518 op_state
.set_access_key(swift_kid
);
522 kiter
= access_keys
->find(kid
);
523 existing_key
= (kiter
!= access_keys
->end());
527 kiter
= access_keys
->find(kid
);
529 existing_key
= (kiter
!= access_keys
->end());
531 op_state
.set_key_type(KEY_TYPE_S3
);
535 kiter
= swift_keys
->find(kid
);
537 existing_key
= (kiter
!= swift_keys
->end());
539 op_state
.set_key_type(KEY_TYPE_SWIFT
);
543 // handle the case where the access key was not provided in user:key format
544 if (swift_kid
.empty())
547 kiter
= swift_keys
->find(swift_kid
);
549 existing_key
= (kiter
!= swift_keys
->end());
551 op_state
.set_access_key(swift_kid
);
552 op_state
.set_key_type(KEY_TYPE_SWIFT
);
556 op_state
.set_existing_key(existing_key
);
561 int RGWAccessKeyPool::check_op(RGWUserAdminOpState
& op_state
,
562 std::string
*err_msg
)
564 RGWUserInfo dup_info
;
566 if (!op_state
.is_populated()) {
567 set_err_msg(err_msg
, "user info was not populated");
572 set_err_msg(err_msg
, "keys not allowed for this user");
576 int32_t key_type
= op_state
.get_key_type();
578 // if a key type wasn't specified
580 if (op_state
.has_subuser()) {
581 key_type
= KEY_TYPE_SWIFT
;
583 key_type
= KEY_TYPE_S3
;
587 op_state
.set_key_type(key_type
);
589 /* see if the access key was specified */
590 if (key_type
== KEY_TYPE_S3
&& !op_state
.will_gen_access() &&
591 op_state
.get_access_key().empty()) {
592 set_err_msg(err_msg
, "empty access key");
593 return -ERR_INVALID_ACCESS_KEY
;
596 // don't check for secret key because we may be doing a removal
598 check_existing_key(op_state
);
603 // Generate a new random key
604 int RGWAccessKeyPool::generate_key(const DoutPrefixProvider
*dpp
, RGWUserAdminOpState
& op_state
,
605 optional_yield y
, std::string
*err_msg
)
610 std::pair
<std::string
, RGWAccessKey
> key_pair
;
611 RGWAccessKey new_key
;
612 RGWUserInfo duplicate_check
;
614 int key_type
= op_state
.get_key_type();
615 bool gen_access
= op_state
.will_gen_access();
616 bool gen_secret
= op_state
.will_gen_secret();
619 set_err_msg(err_msg
, "access keys not allowed for this user");
623 if (op_state
.has_existing_key()) {
624 set_err_msg(err_msg
, "cannot create existing key");
625 return -ERR_KEY_EXIST
;
629 id
= op_state
.get_access_key();
635 if (rgw_get_user_info_by_swift(dpp
, user_ctl
, id
, duplicate_check
, y
) >= 0) {
636 set_err_msg(err_msg
, "existing swift key in RGW system:" + id
);
637 return -ERR_KEY_EXIST
;
641 if (rgw_get_user_info_by_access_key(dpp
, user_ctl
, id
, duplicate_check
, y
) >= 0) {
642 set_err_msg(err_msg
, "existing S3 key in RGW system:" + id
);
643 return -ERR_KEY_EXIST
;
649 if (op_state
.has_subuser()) {
650 //create user and subuser at the same time, user's s3 key should not be set this
651 if (!op_state
.key_type_setbycontext
|| (key_type
== KEY_TYPE_SWIFT
)) {
652 new_key
.subuser
= op_state
.get_subuser();
658 if (op_state
.get_secret_key().empty()) {
659 set_err_msg(err_msg
, "empty secret key");
660 return -ERR_INVALID_SECRET_KEY
;
663 key
= op_state
.get_secret_key();
665 char secret_key_buf
[SECRET_KEY_LEN
+ 1];
666 gen_rand_alphanumeric_plain(g_ceph_context
, secret_key_buf
, sizeof(secret_key_buf
));
667 key
= secret_key_buf
;
670 // Generate the access key
671 if (key_type
== KEY_TYPE_S3
&& gen_access
) {
672 char public_id_buf
[PUBLIC_ID_LEN
+ 1];
675 int id_buf_size
= sizeof(public_id_buf
);
676 gen_rand_alphanumeric_upper(g_ceph_context
, public_id_buf
, id_buf_size
);
678 if (!validate_access_key(id
))
681 } while (!rgw_get_user_info_by_access_key(dpp
, user_ctl
, id
, duplicate_check
, y
));
684 if (key_type
== KEY_TYPE_SWIFT
) {
685 id
= op_state
.build_default_swift_kid();
687 set_err_msg(err_msg
, "empty swift access key");
688 return -ERR_INVALID_ACCESS_KEY
;
691 // check that the access key doesn't exist
692 if (rgw_get_user_info_by_swift(dpp
, user_ctl
, id
, duplicate_check
, y
) >= 0) {
693 set_err_msg(err_msg
, "cannot create existing swift key");
694 return -ERR_KEY_EXIST
;
698 // finally create the new key
703 key_pair
.second
= new_key
;
705 if (key_type
== KEY_TYPE_S3
) {
706 access_keys
->insert(key_pair
);
707 } else if (key_type
== KEY_TYPE_SWIFT
) {
708 swift_keys
->insert(key_pair
);
714 // modify an existing key
715 int RGWAccessKeyPool::modify_key(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
718 std::string key
= op_state
.get_secret_key();
719 int key_type
= op_state
.get_key_type();
721 RGWAccessKey modify_key
;
723 pair
<string
, RGWAccessKey
> key_pair
;
724 map
<std::string
, RGWAccessKey
>::iterator kiter
;
728 id
= op_state
.get_access_key();
730 set_err_msg(err_msg
, "no access key specified");
731 return -ERR_INVALID_ACCESS_KEY
;
735 id
= op_state
.build_default_swift_kid();
737 set_err_msg(err_msg
, "no subuser specified");
742 set_err_msg(err_msg
, "invalid key type");
743 return -ERR_INVALID_KEY_TYPE
;
746 if (!op_state
.has_existing_key()) {
747 set_err_msg(err_msg
, "key does not exist");
748 return -ERR_INVALID_ACCESS_KEY
;
753 if (key_type
== KEY_TYPE_SWIFT
) {
755 modify_key
.subuser
= op_state
.get_subuser();
756 } else if (key_type
== KEY_TYPE_S3
) {
757 kiter
= access_keys
->find(id
);
758 if (kiter
!= access_keys
->end()) {
759 modify_key
= kiter
->second
;
763 if (op_state
.will_gen_secret()) {
764 char secret_key_buf
[SECRET_KEY_LEN
+ 1];
765 int key_buf_size
= sizeof(secret_key_buf
);
766 gen_rand_alphanumeric_plain(g_ceph_context
, secret_key_buf
, key_buf_size
);
767 key
= secret_key_buf
;
771 set_err_msg(err_msg
, "empty secret key");
772 return -ERR_INVALID_SECRET_KEY
;
775 // update the access key with the new secret key
776 modify_key
.key
= key
;
778 key_pair
.second
= modify_key
;
781 if (key_type
== KEY_TYPE_S3
) {
782 (*access_keys
)[id
] = modify_key
;
783 } else if (key_type
== KEY_TYPE_SWIFT
) {
784 (*swift_keys
)[id
] = modify_key
;
790 int RGWAccessKeyPool::execute_add(const DoutPrefixProvider
*dpp
,
791 RGWUserAdminOpState
& op_state
,
792 std::string
*err_msg
, bool defer_user_update
,
797 std::string subprocess_msg
;
798 int key_op
= GENERATE_KEY
;
801 if (op_state
.has_existing_key())
806 ret
= generate_key(dpp
, op_state
, y
, &subprocess_msg
);
809 ret
= modify_key(op_state
, &subprocess_msg
);
814 set_err_msg(err_msg
, subprocess_msg
);
818 // store the updated info
819 if (!defer_user_update
)
820 ret
= user
->update(dpp
, op_state
, err_msg
, y
);
828 int RGWAccessKeyPool::add(const DoutPrefixProvider
*dpp
,
829 RGWUserAdminOpState
& op_state
, optional_yield y
,
830 std::string
*err_msg
)
832 return add(dpp
, op_state
, err_msg
, false, y
);
835 int RGWAccessKeyPool::add(const DoutPrefixProvider
*dpp
,
836 RGWUserAdminOpState
& op_state
, std::string
*err_msg
,
837 bool defer_user_update
, optional_yield y
)
840 std::string subprocess_msg
;
842 ret
= check_op(op_state
, &subprocess_msg
);
844 set_err_msg(err_msg
, "unable to parse request, " + subprocess_msg
);
848 ret
= execute_add(dpp
, op_state
, &subprocess_msg
, defer_user_update
, y
);
850 set_err_msg(err_msg
, "unable to add access key, " + subprocess_msg
);
857 int RGWAccessKeyPool::execute_remove(const DoutPrefixProvider
*dpp
,
858 RGWUserAdminOpState
& op_state
,
859 std::string
*err_msg
,
860 bool defer_user_update
,
865 int key_type
= op_state
.get_key_type();
866 std::string id
= op_state
.get_access_key();
867 map
<std::string
, RGWAccessKey
>::iterator kiter
;
868 map
<std::string
, RGWAccessKey
> *keys_map
;
870 if (!op_state
.has_existing_key()) {
871 set_err_msg(err_msg
, "unable to find access key");
872 return -ERR_INVALID_ACCESS_KEY
;
875 if (key_type
== KEY_TYPE_S3
) {
876 keys_map
= access_keys
;
877 } else if (key_type
== KEY_TYPE_SWIFT
) {
878 keys_map
= swift_keys
;
881 set_err_msg(err_msg
, "invalid access key");
882 return -ERR_INVALID_ACCESS_KEY
;
885 kiter
= keys_map
->find(id
);
886 if (kiter
== keys_map
->end()) {
887 set_err_msg(err_msg
, "key not found");
888 return -ERR_INVALID_ACCESS_KEY
;
891 keys_map
->erase(kiter
);
893 if (!defer_user_update
)
894 ret
= user
->update(dpp
, op_state
, err_msg
, y
);
902 int RGWAccessKeyPool::remove(const DoutPrefixProvider
*dpp
, RGWUserAdminOpState
& op_state
, optional_yield y
,
903 std::string
*err_msg
)
905 return remove(dpp
, op_state
, err_msg
, false, y
);
908 int RGWAccessKeyPool::remove(const DoutPrefixProvider
*dpp
,
909 RGWUserAdminOpState
& op_state
,
910 std::string
*err_msg
, bool defer_user_update
,
915 std::string subprocess_msg
;
917 ret
= check_op(op_state
, &subprocess_msg
);
919 set_err_msg(err_msg
, "unable to parse request, " + subprocess_msg
);
923 ret
= execute_remove(dpp
, op_state
, &subprocess_msg
, defer_user_update
, y
);
925 set_err_msg(err_msg
, "unable to remove access key, " + subprocess_msg
);
932 // remove all keys associated with a subuser
933 int RGWAccessKeyPool::remove_subuser_keys(const DoutPrefixProvider
*dpp
,
934 RGWUserAdminOpState
& op_state
,
935 std::string
*err_msg
,
936 bool defer_user_update
,
941 if (!op_state
.is_populated()) {
942 set_err_msg(err_msg
, "user info was not populated");
946 if (!op_state
.has_subuser()) {
947 set_err_msg(err_msg
, "no subuser specified");
951 std::string swift_kid
= op_state
.build_default_swift_kid();
952 if (swift_kid
.empty()) {
953 set_err_msg(err_msg
, "empty swift access key");
957 map
<std::string
, RGWAccessKey
>::iterator kiter
;
958 map
<std::string
, RGWAccessKey
> *keys_map
;
960 // a subuser can have at most one swift key
961 keys_map
= swift_keys
;
962 kiter
= keys_map
->find(swift_kid
);
963 if (kiter
!= keys_map
->end()) {
964 keys_map
->erase(kiter
);
967 // a subuser may have multiple s3 key pairs
968 std::string subuser_str
= op_state
.get_subuser();
969 keys_map
= access_keys
;
970 RGWUserInfo user_info
= op_state
.get_user_info();
971 auto user_kiter
= user_info
.access_keys
.begin();
972 for (; user_kiter
!= user_info
.access_keys
.end(); ++user_kiter
) {
973 if (user_kiter
->second
.subuser
== subuser_str
) {
974 kiter
= keys_map
->find(user_kiter
->first
);
975 if (kiter
!= keys_map
->end()) {
976 keys_map
->erase(kiter
);
981 if (!defer_user_update
)
982 ret
= user
->update(dpp
, op_state
, err_msg
, y
);
990 RGWSubUserPool::RGWSubUserPool(RGWUser
*usr
)
998 subusers_allowed
= true;
999 store
= user
->get_store();
1000 user_ctl
= user
->get_user_ctl();
1003 int RGWSubUserPool::init(RGWUserAdminOpState
& op_state
)
1005 if (!op_state
.is_initialized()) {
1006 subusers_allowed
= false;
1010 rgw_user
& uid
= op_state
.get_user_id();
1011 if (uid
.compare(RGW_USER_ANON_ID
) == 0) {
1012 subusers_allowed
= false;
1016 subuser_map
= op_state
.get_subusers();
1017 if (subuser_map
== NULL
) {
1018 subusers_allowed
= false;
1022 subusers_allowed
= true;
1027 bool RGWSubUserPool::exists(std::string subuser
)
1029 if (subuser
.empty())
1035 if (subuser_map
->count(subuser
))
1041 int RGWSubUserPool::check_op(RGWUserAdminOpState
& op_state
,
1042 std::string
*err_msg
)
1044 bool existing
= false;
1045 std::string subuser
= op_state
.get_subuser();
1047 if (!op_state
.is_populated()) {
1048 set_err_msg(err_msg
, "user info was not populated");
1052 if (!subusers_allowed
) {
1053 set_err_msg(err_msg
, "subusers not allowed for this user");
1057 if (subuser
.empty() && !op_state
.will_gen_subuser()) {
1058 set_err_msg(err_msg
, "empty subuser name");
1062 if (op_state
.get_subuser_perm() == RGW_PERM_INVALID
) {
1063 set_err_msg(err_msg
, "invaild subuser access");
1067 //set key type when it not set or set by context
1068 if ((op_state
.get_key_type() < 0) || op_state
.key_type_setbycontext
) {
1069 op_state
.set_key_type(KEY_TYPE_SWIFT
);
1070 op_state
.key_type_setbycontext
= true;
1073 // check if the subuser exists
1074 if (!subuser
.empty())
1075 existing
= exists(subuser
);
1077 op_state
.set_existing_subuser(existing
);
1082 int RGWSubUserPool::execute_add(const DoutPrefixProvider
*dpp
,
1083 RGWUserAdminOpState
& op_state
,
1084 std::string
*err_msg
, bool defer_user_update
,
1088 std::string subprocess_msg
;
1091 std::pair
<std::string
, RGWSubUser
> subuser_pair
;
1092 std::string subuser_str
= op_state
.get_subuser();
1094 subuser_pair
.first
= subuser_str
;
1096 // assumes key should be created
1097 if (op_state
.has_key_op()) {
1098 ret
= user
->keys
.add(dpp
, op_state
, &subprocess_msg
, true, y
);
1100 set_err_msg(err_msg
, "unable to create subuser key, " + subprocess_msg
);
1105 // create the subuser
1106 subuser
.name
= subuser_str
;
1108 if (op_state
.has_subuser_perm())
1109 subuser
.perm_mask
= op_state
.get_subuser_perm();
1111 // insert the subuser into user info
1112 subuser_pair
.second
= subuser
;
1113 subuser_map
->insert(subuser_pair
);
1115 // attempt to save the subuser
1116 if (!defer_user_update
)
1117 ret
= user
->update(dpp
, op_state
, err_msg
, y
);
1125 int RGWSubUserPool::add(const DoutPrefixProvider
*dpp
, RGWUserAdminOpState
& op_state
, optional_yield y
,
1126 std::string
*err_msg
)
1128 return add(dpp
, op_state
, err_msg
, false, y
);
1131 int RGWSubUserPool::add(const DoutPrefixProvider
*dpp
, RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_user_update
, optional_yield y
)
1133 std::string subprocess_msg
;
1135 int32_t key_type
= op_state
.get_key_type();
1137 ret
= check_op(op_state
, &subprocess_msg
);
1139 set_err_msg(err_msg
, "unable to parse request, " + subprocess_msg
);
1143 if (key_type
== KEY_TYPE_S3
&& op_state
.get_access_key().empty()) {
1144 op_state
.set_gen_access();
1147 if (op_state
.get_secret_key().empty()) {
1148 op_state
.set_gen_secret();
1151 ret
= execute_add(dpp
, op_state
, &subprocess_msg
, defer_user_update
, y
);
1153 set_err_msg(err_msg
, "unable to create subuser, " + subprocess_msg
);
1160 int RGWSubUserPool::execute_remove(const DoutPrefixProvider
*dpp
,
1161 RGWUserAdminOpState
& op_state
,
1162 std::string
*err_msg
, bool defer_user_update
,
1166 std::string subprocess_msg
;
1168 std::string subuser_str
= op_state
.get_subuser();
1170 map
<std::string
, RGWSubUser
>::iterator siter
;
1171 siter
= subuser_map
->find(subuser_str
);
1172 if (siter
== subuser_map
->end()){
1173 set_err_msg(err_msg
, "subuser not found: " + subuser_str
);
1174 return -ERR_NO_SUCH_SUBUSER
;
1176 if (!op_state
.has_existing_subuser()) {
1177 set_err_msg(err_msg
, "subuser not found: " + subuser_str
);
1178 return -ERR_NO_SUCH_SUBUSER
;
1181 // always purge all associate keys
1182 user
->keys
.remove_subuser_keys(dpp
, op_state
, &subprocess_msg
, true, y
);
1184 // remove the subuser from the user info
1185 subuser_map
->erase(siter
);
1187 // attempt to save the subuser
1188 if (!defer_user_update
)
1189 ret
= user
->update(dpp
, op_state
, err_msg
, y
);
1197 int RGWSubUserPool::remove(const DoutPrefixProvider
*dpp
, RGWUserAdminOpState
& op_state
, optional_yield y
,
1198 std::string
*err_msg
)
1200 return remove(dpp
, op_state
, err_msg
, false, y
);
1203 int RGWSubUserPool::remove(const DoutPrefixProvider
*dpp
, RGWUserAdminOpState
& op_state
, std::string
*err_msg
,
1204 bool defer_user_update
, optional_yield y
)
1206 std::string subprocess_msg
;
1209 ret
= check_op(op_state
, &subprocess_msg
);
1211 set_err_msg(err_msg
, "unable to parse request, " + subprocess_msg
);
1215 ret
= execute_remove(dpp
, op_state
, &subprocess_msg
, defer_user_update
, y
);
1217 set_err_msg(err_msg
, "unable to remove subuser, " + subprocess_msg
);
1224 int RGWSubUserPool::execute_modify(const DoutPrefixProvider
*dpp
, RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_user_update
, optional_yield y
)
1227 std::string subprocess_msg
;
1228 std::map
<std::string
, RGWSubUser
>::iterator siter
;
1229 std::pair
<std::string
, RGWSubUser
> subuser_pair
;
1231 std::string subuser_str
= op_state
.get_subuser();
1234 if (!op_state
.has_existing_subuser()) {
1235 set_err_msg(err_msg
, "subuser does not exist");
1236 return -ERR_NO_SUCH_SUBUSER
;
1239 subuser_pair
.first
= subuser_str
;
1241 siter
= subuser_map
->find(subuser_str
);
1242 subuser
= siter
->second
;
1244 if (op_state
.has_key_op()) {
1245 ret
= user
->keys
.add(dpp
, op_state
, &subprocess_msg
, true, y
);
1247 set_err_msg(err_msg
, "unable to create subuser keys, " + subprocess_msg
);
1252 if (op_state
.has_subuser_perm())
1253 subuser
.perm_mask
= op_state
.get_subuser_perm();
1255 subuser_pair
.second
= subuser
;
1257 subuser_map
->erase(siter
);
1258 subuser_map
->insert(subuser_pair
);
1260 // attempt to save the subuser
1261 if (!defer_user_update
)
1262 ret
= user
->update(dpp
, op_state
, err_msg
, y
);
1270 int RGWSubUserPool::modify(const DoutPrefixProvider
*dpp
, RGWUserAdminOpState
& op_state
, optional_yield y
, std::string
*err_msg
)
1272 return RGWSubUserPool::modify(dpp
, op_state
, y
, err_msg
, false);
1275 int RGWSubUserPool::modify(const DoutPrefixProvider
*dpp
, RGWUserAdminOpState
& op_state
, optional_yield y
, std::string
*err_msg
, bool defer_user_update
)
1277 std::string subprocess_msg
;
1282 ret
= check_op(op_state
, &subprocess_msg
);
1284 set_err_msg(err_msg
, "unable to parse request, " + subprocess_msg
);
1288 ret
= execute_modify(dpp
, op_state
, &subprocess_msg
, defer_user_update
, y
);
1290 set_err_msg(err_msg
, "unable to modify subuser, " + subprocess_msg
);
1297 RGWUserCapPool::RGWUserCapPool(RGWUser
*usr
)
1303 caps_allowed
= true;
1306 int RGWUserCapPool::init(RGWUserAdminOpState
& op_state
)
1308 if (!op_state
.is_initialized()) {
1309 caps_allowed
= false;
1313 rgw_user
& uid
= op_state
.get_user_id();
1314 if (uid
.compare(RGW_USER_ANON_ID
) == 0) {
1315 caps_allowed
= false;
1319 caps
= op_state
.get_caps_obj();
1321 caps_allowed
= false;
1322 return -ERR_INVALID_CAP
;
1325 caps_allowed
= true;
1330 int RGWUserCapPool::add(const DoutPrefixProvider
*dpp
, RGWUserAdminOpState
& op_state
, optional_yield y
,
1331 std::string
*err_msg
)
1333 return add(dpp
, op_state
, err_msg
, false, y
);
1336 int RGWUserCapPool::add(const DoutPrefixProvider
*dpp
, RGWUserAdminOpState
& op_state
, std::string
*err_msg
,
1337 bool defer_save
, optional_yield y
)
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
->add_from_string(caps_str
);
1359 set_err_msg(err_msg
, "unable to add caps: " + caps_str
);
1364 ret
= user
->update(dpp
, op_state
, err_msg
, y
);
1372 int RGWUserCapPool::remove(const DoutPrefixProvider
*dpp
, RGWUserAdminOpState
& op_state
, optional_yield y
,
1373 std::string
*err_msg
)
1375 return remove(dpp
, op_state
, err_msg
, false, y
);
1378 int RGWUserCapPool::remove(const DoutPrefixProvider
*dpp
, RGWUserAdminOpState
& op_state
, std::string
*err_msg
,
1379 bool defer_save
, optional_yield y
)
1383 std::string caps_str
= op_state
.get_caps();
1385 if (!op_state
.is_populated()) {
1386 set_err_msg(err_msg
, "user info was not populated");
1390 if (!caps_allowed
) {
1391 set_err_msg(err_msg
, "caps not allowed for this user");
1395 if (caps_str
.empty()) {
1396 set_err_msg(err_msg
, "empty user caps");
1397 return -ERR_INVALID_CAP
;
1400 int r
= caps
->remove_from_string(caps_str
);
1402 set_err_msg(err_msg
, "unable to remove caps: " + caps_str
);
1407 ret
= user
->update(dpp
, op_state
, err_msg
, y
);
1415 RGWUser::RGWUser() : caps(this), keys(this), subusers(this)
1420 int RGWUser::init(const DoutPrefixProvider
*dpp
, rgw::sal::RGWRadosStore
*storage
,
1421 RGWUserAdminOpState
& op_state
, optional_yield y
)
1424 int ret
= init_storage(storage
);
1428 ret
= init(dpp
, op_state
, y
);
1435 void RGWUser::init_default()
1437 // use anonymous user info as a placeholder
1438 rgw_get_anon_user(old_info
);
1439 user_id
= RGW_USER_ANON_ID
;
1444 int RGWUser::init_storage(rgw::sal::RGWRadosStore
*storage
)
1451 user_ctl
= store
->ctl()->user
;
1456 keys
= RGWAccessKeyPool(this);
1457 caps
= RGWUserCapPool(this);
1458 subusers
= RGWSubUserPool(this);
1463 int RGWUser::init(const DoutPrefixProvider
*dpp
, RGWUserAdminOpState
& op_state
, optional_yield y
)
1466 std::string swift_user
;
1467 user_id
= op_state
.get_user_id();
1468 std::string user_email
= op_state
.get_user_email();
1469 std::string access_key
= op_state
.get_access_key();
1470 std::string subuser
= op_state
.get_subuser();
1472 int key_type
= op_state
.get_key_type();
1473 if (key_type
== KEY_TYPE_SWIFT
) {
1474 swift_user
= op_state
.get_access_key();
1478 RGWUserInfo user_info
;
1482 if (user_id
.empty() && !subuser
.empty()) {
1483 size_t pos
= subuser
.find(':');
1484 if (pos
!= string::npos
) {
1485 user_id
= subuser
.substr(0, pos
);
1486 op_state
.set_user_id(user_id
);
1490 if (!user_id
.empty() && (user_id
.compare(RGW_USER_ANON_ID
) != 0)) {
1491 found
= (rgw_get_user_info_by_uid(dpp
, user_ctl
, user_id
, user_info
, y
, &op_state
.objv
) >= 0);
1492 op_state
.found_by_uid
= found
;
1494 if (store
->ctx()->_conf
.get_val
<bool>("rgw_user_unique_email")) {
1495 if (!user_email
.empty() && !found
) {
1496 found
= (rgw_get_user_info_by_email(dpp
, user_ctl
, user_email
, user_info
, y
, &op_state
.objv
) >= 0);
1497 op_state
.found_by_email
= found
;
1500 if (!swift_user
.empty() && !found
) {
1501 found
= (rgw_get_user_info_by_swift(dpp
, user_ctl
, swift_user
, user_info
, y
, &op_state
.objv
) >= 0);
1502 op_state
.found_by_key
= found
;
1504 if (!access_key
.empty() && !found
) {
1505 found
= (rgw_get_user_info_by_access_key(dpp
, user_ctl
, access_key
, user_info
, y
, &op_state
.objv
) >= 0);
1506 op_state
.found_by_key
= found
;
1509 op_state
.set_existing_user(found
);
1511 op_state
.set_user_info(user_info
);
1512 op_state
.set_populated();
1514 old_info
= user_info
;
1518 if (user_id
.empty()) {
1519 user_id
= user_info
.user_id
;
1521 op_state
.set_initialized();
1523 // this may have been called by a helper object
1524 int ret
= init_members(op_state
);
1531 int RGWUser::init_members(RGWUserAdminOpState
& op_state
)
1535 ret
= keys
.init(op_state
);
1539 ret
= subusers
.init(op_state
);
1543 ret
= caps
.init(op_state
);
1550 int RGWUser::update(const DoutPrefixProvider
*dpp
, RGWUserAdminOpState
& op_state
, std::string
*err_msg
,
1554 std::string subprocess_msg
;
1555 RGWUserInfo user_info
= op_state
.get_user_info();
1558 set_err_msg(err_msg
, "couldn't initialize storage");
1562 RGWUserInfo
*pold_info
= (is_populated() ? &old_info
: nullptr);
1564 ret
= rgw_store_user_info(dpp
, user_ctl
, user_info
, pold_info
, &op_state
.objv
,
1565 real_time(), false, y
);
1567 set_err_msg(err_msg
, "unable to store user info");
1571 old_info
= user_info
;
1577 int RGWUser::check_op(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1581 rgw_user
& op_id
= op_state
.get_user_id();
1583 RGWUserInfo user_info
;
1585 same_id
= (user_id
.compare(op_id
) == 0);
1586 populated
= is_populated();
1588 if (op_id
.compare(RGW_USER_ANON_ID
) == 0) {
1589 set_err_msg(err_msg
, "unable to perform operations on the anonymous user");
1593 if (populated
&& !same_id
) {
1594 set_err_msg(err_msg
, "user id mismatch, operation id: " + op_id
.to_str()
1595 + " does not match: " + user_id
.to_str());
1600 int ret
= rgw_validate_tenant_name(op_id
.tenant
);
1602 set_err_msg(err_msg
,
1603 "invalid tenant only alphanumeric and _ characters are allowed");
1607 //set key type when it not set or set by context
1608 if ((op_state
.get_key_type() < 0) || op_state
.key_type_setbycontext
) {
1609 op_state
.set_key_type(KEY_TYPE_S3
);
1610 op_state
.key_type_setbycontext
= true;
1616 // update swift_keys with new user id
1617 static void rename_swift_keys(const rgw_user
& user
,
1618 std::map
<std::string
, RGWAccessKey
>& keys
)
1620 std::string user_id
;
1621 user
.to_str(user_id
);
1623 auto modify_keys
= std::move(keys
);
1624 for ([[maybe_unused
]] auto& [k
, key
] : modify_keys
) {
1625 std::string id
= user_id
+ ":" + key
.subuser
;
1627 keys
[id
] = std::move(key
);
1631 int RGWUser::execute_rename(const DoutPrefixProvider
*dpp
, RGWUserAdminOpState
& op_state
, std::string
*err_msg
, optional_yield y
)
1634 bool populated
= op_state
.is_populated();
1636 if (!op_state
.has_existing_user() && !populated
) {
1637 set_err_msg(err_msg
, "user not found");
1642 ret
= init(dpp
, op_state
, y
);
1644 set_err_msg(err_msg
, "unable to retrieve user info");
1649 rgw::sal::RGWRadosUser
old_user(store
, op_state
.get_user_info());
1650 rgw::sal::RGWRadosUser
new_user(store
, op_state
.get_new_uid());
1651 if (old_user
.get_tenant() != new_user
.get_tenant()) {
1652 set_err_msg(err_msg
, "users have to be under the same tenant namespace "
1653 + old_user
.get_tenant() + " != " + new_user
.get_tenant());
1657 // create a stub user and write only the uid index and buckets object
1658 RGWUserInfo stub_user_info
;
1659 stub_user_info
.user_id
= new_user
.get_user();
1661 RGWObjVersionTracker objv
;
1662 const bool exclusive
= !op_state
.get_overwrite_new_user(); // overwrite if requested
1664 ret
= user_ctl
->store_info(dpp
, stub_user_info
, y
,
1665 RGWUserCtl::PutParams()
1666 .set_objv_tracker(&objv
)
1667 .set_exclusive(exclusive
));
1668 if (ret
== -EEXIST
) {
1669 set_err_msg(err_msg
, "user name given by --new-uid already exists");
1673 set_err_msg(err_msg
, "unable to store new user info");
1677 RGWAccessControlPolicy policy_instance
;
1678 policy_instance
.create_default(new_user
.get_user(), old_user
.get_display_name());
1680 //unlink and link buckets to new user
1682 CephContext
*cct
= store
->ctx();
1683 size_t max_buckets
= cct
->_conf
->rgw_list_buckets_max_chunk
;
1684 rgw::sal::RGWBucketList buckets
;
1687 ret
= old_user
.list_buckets(dpp
, marker
, "", max_buckets
, false, buckets
, y
);
1689 set_err_msg(err_msg
, "unable to list user buckets");
1693 auto& m
= buckets
.get_buckets();
1695 for (auto it
= m
.begin(); it
!= m
.end(); ++it
) {
1696 auto& bucket
= it
->second
;
1699 ret
= bucket
->get_bucket_info(dpp
, y
);
1701 set_err_msg(err_msg
, "failed to fetch bucket info for bucket=" + bucket
->get_name());
1705 ret
= bucket
->set_acl(dpp
, policy_instance
, y
);
1707 set_err_msg(err_msg
, "failed to set acl on bucket " + bucket
->get_name());
1711 ret
= bucket
->link(dpp
, &new_user
, y
);
1713 set_err_msg(err_msg
, "failed to link bucket " + bucket
->get_name());
1717 ret
= bucket
->chown(&new_user
, &old_user
, y
, dpp
);
1719 set_err_msg(err_msg
, "failed to run bucket chown" + cpp_strerror(-ret
));
1724 } while (buckets
.is_truncated());
1726 // update the 'stub user' with all of the other fields and rewrite all of the
1727 // associated index objects
1728 RGWUserInfo
& user_info
= op_state
.get_user_info();
1729 user_info
.user_id
= new_user
.get_user();
1730 op_state
.objv
= objv
;
1732 rename_swift_keys(new_user
.get_user(), user_info
.swift_keys
);
1734 return update(dpp
, op_state
, err_msg
, y
);
1737 int RGWUser::execute_add(const DoutPrefixProvider
*dpp
, RGWUserAdminOpState
& op_state
, std::string
*err_msg
,
1740 std::string subprocess_msg
;
1742 bool defer_user_update
= true;
1744 RGWUserInfo user_info
;
1746 rgw_user
& uid
= op_state
.get_user_id();
1747 std::string user_email
= op_state
.get_user_email();
1748 std::string display_name
= op_state
.get_display_name();
1750 // fail if the user exists already
1751 if (op_state
.has_existing_user()) {
1752 if (op_state
.found_by_email
) {
1753 set_err_msg(err_msg
, "email: " + user_email
+
1754 " is the email address an existing user");
1755 ret
= -ERR_EMAIL_EXIST
;
1756 } else if (op_state
.found_by_key
) {
1757 set_err_msg(err_msg
, "duplicate key provided");
1758 ret
= -ERR_KEY_EXIST
;
1760 set_err_msg(err_msg
, "user: " + op_state
.user_id
.to_str() + " exists");
1766 // fail if the user_info has already been populated
1767 if (op_state
.is_populated()) {
1768 set_err_msg(err_msg
, "cannot overwrite already populated user");
1772 // fail if the display name was not included
1773 if (display_name
.empty()) {
1774 set_err_msg(err_msg
, "no display name specified");
1779 // set the user info
1781 user_info
.user_id
= user_id
;
1782 user_info
.display_name
= display_name
;
1783 user_info
.type
= TYPE_RGW
;
1785 if (!user_email
.empty())
1786 user_info
.user_email
= user_email
;
1788 CephContext
*cct
= store
->ctx();
1789 if (op_state
.max_buckets_specified
) {
1790 user_info
.max_buckets
= op_state
.get_max_buckets();
1792 user_info
.max_buckets
=
1793 cct
->_conf
.get_val
<int64_t>("rgw_user_max_buckets");
1796 user_info
.suspended
= op_state
.get_suspension_status();
1797 user_info
.admin
= op_state
.admin
;
1798 user_info
.system
= op_state
.system
;
1800 if (op_state
.op_mask_specified
)
1801 user_info
.op_mask
= op_state
.get_op_mask();
1803 if (op_state
.has_bucket_quota()) {
1804 user_info
.bucket_quota
= op_state
.get_bucket_quota();
1806 rgw_apply_default_bucket_quota(user_info
.bucket_quota
, cct
->_conf
);
1809 if (op_state
.temp_url_key_specified
) {
1810 map
<int, string
>::iterator iter
;
1811 for (iter
= op_state
.temp_url_keys
.begin();
1812 iter
!= op_state
.temp_url_keys
.end(); ++iter
) {
1813 user_info
.temp_url_keys
[iter
->first
] = iter
->second
;
1817 if (op_state
.has_user_quota()) {
1818 user_info
.user_quota
= op_state
.get_user_quota();
1820 rgw_apply_default_user_quota(user_info
.user_quota
, cct
->_conf
);
1823 if (op_state
.default_placement_specified
) {
1824 user_info
.default_placement
= op_state
.default_placement
;
1827 if (op_state
.placement_tags_specified
) {
1828 user_info
.placement_tags
= op_state
.placement_tags
;
1831 // update the request
1832 op_state
.set_user_info(user_info
);
1833 op_state
.set_populated();
1835 // update the helper objects
1836 ret
= init_members(op_state
);
1838 set_err_msg(err_msg
, "unable to initialize user");
1842 // see if we need to add an access key
1843 if (op_state
.has_key_op()) {
1844 ret
= keys
.add(dpp
, op_state
, &subprocess_msg
, defer_user_update
, y
);
1846 set_err_msg(err_msg
, "unable to create access key, " + subprocess_msg
);
1851 // see if we need to add some caps
1852 if (op_state
.has_caps_op()) {
1853 ret
= caps
.add(dpp
, op_state
, &subprocess_msg
, defer_user_update
, y
);
1855 set_err_msg(err_msg
, "unable to add user capabilities, " + subprocess_msg
);
1860 ret
= update(dpp
, op_state
, err_msg
, y
);
1868 int RGWUser::add(const DoutPrefixProvider
*dpp
, RGWUserAdminOpState
& op_state
, optional_yield y
, std::string
*err_msg
)
1870 std::string subprocess_msg
;
1873 ret
= check_op(op_state
, &subprocess_msg
);
1875 set_err_msg(err_msg
, "unable to parse parameters, " + subprocess_msg
);
1879 ret
= execute_add(dpp
, op_state
, &subprocess_msg
, y
);
1881 set_err_msg(err_msg
, "unable to create user, " + subprocess_msg
);
1888 int RGWUser::rename(RGWUserAdminOpState
& op_state
, optional_yield y
, const DoutPrefixProvider
*dpp
, std::string
*err_msg
)
1890 std::string subprocess_msg
;
1893 ret
= check_op(op_state
, &subprocess_msg
);
1895 set_err_msg(err_msg
, "unable to parse parameters, " + subprocess_msg
);
1899 ret
= execute_rename(dpp
, op_state
, &subprocess_msg
, y
);
1901 set_err_msg(err_msg
, "unable to rename user, " + subprocess_msg
);
1908 int RGWUser::execute_remove(const DoutPrefixProvider
*dpp
, RGWUserAdminOpState
& op_state
, std::string
*err_msg
, optional_yield y
)
1912 bool purge_data
= op_state
.will_purge_data();
1913 rgw_user
& uid
= op_state
.get_user_id();
1914 RGWUserInfo user_info
= op_state
.get_user_info();
1916 if (!op_state
.has_existing_user()) {
1917 set_err_msg(err_msg
, "user does not exist");
1921 rgw::sal::RGWBucketList buckets
;
1923 CephContext
*cct
= store
->ctx();
1924 size_t max_buckets
= cct
->_conf
->rgw_list_buckets_max_chunk
;
1926 ret
= rgw_read_user_buckets(dpp
, store
, uid
, buckets
, marker
, string(),
1927 max_buckets
, false, y
);
1929 set_err_msg(err_msg
, "unable to read user bucket info");
1933 auto& m
= buckets
.get_buckets();
1934 if (!m
.empty() && !purge_data
) {
1935 set_err_msg(err_msg
, "must specify purge data to remove user with buckets");
1936 return -EEXIST
; // change to code that maps to 409: conflict
1939 std::string prefix
, delimiter
;
1940 for (auto it
= m
.begin(); it
!= m
.end(); ++it
) {
1941 ret
= it
->second
->remove_bucket(dpp
, true, prefix
, delimiter
, false, nullptr, y
);
1943 set_err_msg(err_msg
, "unable to delete user data");
1950 } while (buckets
.is_truncated());
1952 ret
= user_ctl
->remove_info(dpp
, user_info
, y
, RGWUserCtl::RemoveParams()
1953 .set_objv_tracker(&op_state
.objv
));
1955 set_err_msg(err_msg
, "unable to remove user from RADOS");
1959 op_state
.clear_populated();
1965 int RGWUser::remove(const DoutPrefixProvider
*dpp
, RGWUserAdminOpState
& op_state
, optional_yield y
, std::string
*err_msg
)
1967 std::string subprocess_msg
;
1970 ret
= check_op(op_state
, &subprocess_msg
);
1972 set_err_msg(err_msg
, "unable to parse parameters, " + subprocess_msg
);
1976 ret
= execute_remove(dpp
, op_state
, &subprocess_msg
, y
);
1978 set_err_msg(err_msg
, "unable to remove user, " + subprocess_msg
);
1985 int RGWUser::execute_modify(const DoutPrefixProvider
*dpp
, RGWUserAdminOpState
& op_state
, std::string
*err_msg
, optional_yield y
)
1987 bool populated
= op_state
.is_populated();
1989 std::string subprocess_msg
;
1990 std::string op_email
= op_state
.get_user_email();
1991 std::string display_name
= op_state
.get_display_name();
1993 RGWUserInfo user_info
;
1994 RGWUserInfo duplicate_check
;
1996 // ensure that the user info has been populated or is populate-able
1997 if (!op_state
.has_existing_user() && !populated
) {
1998 set_err_msg(err_msg
, "user not found");
2002 // if the user hasn't already been populated...attempt to
2004 ret
= init(dpp
, op_state
, y
);
2006 set_err_msg(err_msg
, "unable to retrieve user info");
2011 // ensure that we can modify the user's attributes
2012 if (user_id
.compare(RGW_USER_ANON_ID
) == 0) {
2013 set_err_msg(err_msg
, "unable to modify anonymous user's info");
2017 user_info
= old_info
;
2019 std::string old_email
= old_info
.user_email
;
2020 if (!op_email
.empty()) {
2021 // make sure we are not adding a duplicate email
2022 if (old_email
!= op_email
) {
2023 ret
= rgw_get_user_info_by_email(dpp
, user_ctl
, op_email
, duplicate_check
,y
);
2024 if (ret
>= 0 && duplicate_check
.user_id
.compare(user_id
) != 0) {
2025 set_err_msg(err_msg
, "cannot add duplicate email");
2026 return -ERR_EMAIL_EXIST
;
2029 user_info
.user_email
= op_email
;
2030 } else if (op_email
.empty() && op_state
.user_email_specified
) {
2031 ldpp_dout(dpp
, 10) << "removing email index: " << user_info
.user_email
<< dendl
;
2032 /* will be physically removed later when calling update() */
2033 user_info
.user_email
.clear();
2036 // update the remaining user info
2037 if (!display_name
.empty())
2038 user_info
.display_name
= display_name
;
2040 if (op_state
.max_buckets_specified
)
2041 user_info
.max_buckets
= op_state
.get_max_buckets();
2043 if (op_state
.admin_specified
)
2044 user_info
.admin
= op_state
.admin
;
2046 if (op_state
.system_specified
)
2047 user_info
.system
= op_state
.system
;
2049 if (op_state
.temp_url_key_specified
) {
2050 map
<int, string
>::iterator iter
;
2051 for (iter
= op_state
.temp_url_keys
.begin();
2052 iter
!= op_state
.temp_url_keys
.end(); ++iter
) {
2053 user_info
.temp_url_keys
[iter
->first
] = iter
->second
;
2057 if (op_state
.op_mask_specified
)
2058 user_info
.op_mask
= op_state
.get_op_mask();
2060 if (op_state
.has_bucket_quota())
2061 user_info
.bucket_quota
= op_state
.get_bucket_quota();
2063 if (op_state
.has_user_quota())
2064 user_info
.user_quota
= op_state
.get_user_quota();
2066 if (op_state
.has_suspension_op()) {
2067 __u8 suspended
= op_state
.get_suspension_status();
2068 user_info
.suspended
= suspended
;
2070 rgw::sal::RGWBucketList buckets
;
2072 if (user_id
.empty()) {
2073 set_err_msg(err_msg
, "empty user id passed...aborting");
2078 CephContext
*cct
= store
->ctx();
2079 size_t max_buckets
= cct
->_conf
->rgw_list_buckets_max_chunk
;
2081 ret
= rgw_read_user_buckets(dpp
, store
, user_id
, buckets
, marker
, string(),
2082 max_buckets
, false, y
);
2084 set_err_msg(err_msg
, "could not get buckets for uid: " + user_id
.to_str());
2088 auto& m
= buckets
.get_buckets();
2090 vector
<rgw_bucket
> bucket_names
;
2091 for (auto iter
= m
.begin(); iter
!= m
.end(); ++iter
) {
2092 auto& bucket
= iter
->second
;
2093 bucket_names
.push_back(bucket
->get_key());
2095 marker
= iter
->first
;
2098 ret
= store
->getRados()->set_buckets_enabled(bucket_names
, !suspended
, dpp
);
2100 set_err_msg(err_msg
, "failed to modify bucket");
2104 } while (buckets
.is_truncated());
2107 if (op_state
.mfa_ids_specified
) {
2108 user_info
.mfa_ids
= op_state
.mfa_ids
;
2111 if (op_state
.default_placement_specified
) {
2112 user_info
.default_placement
= op_state
.default_placement
;
2115 if (op_state
.placement_tags_specified
) {
2116 user_info
.placement_tags
= op_state
.placement_tags
;
2119 op_state
.set_user_info(user_info
);
2121 // if we're supposed to modify keys, do so
2122 if (op_state
.has_key_op()) {
2123 ret
= keys
.add(dpp
, op_state
, &subprocess_msg
, true, y
);
2125 set_err_msg(err_msg
, "unable to create or modify keys, " + subprocess_msg
);
2130 ret
= update(dpp
, op_state
, err_msg
, y
);
2137 int RGWUser::modify(const DoutPrefixProvider
*dpp
, RGWUserAdminOpState
& op_state
, optional_yield y
, std::string
*err_msg
)
2139 std::string subprocess_msg
;
2142 ret
= check_op(op_state
, &subprocess_msg
);
2144 if (is_populated() && (user_id
.compare(op_state
.get_user_id()) != 0)) {
2145 set_err_msg(err_msg
, "unable to create user " + user_id
.to_str()
2146 + " because user id " + op_state
.get_user_id().to_str()
2147 + " already exists with email "
2148 + op_state
.get_user_email());
2150 set_err_msg(err_msg
, "unable to parse parameters, " + subprocess_msg
);
2155 ret
= execute_modify(dpp
, op_state
, &subprocess_msg
, y
);
2157 set_err_msg(err_msg
, "unable to modify user, " + subprocess_msg
);
2164 int RGWUser::info(const DoutPrefixProvider
*dpp
, RGWUserAdminOpState
& op_state
, RGWUserInfo
& fetched_info
,
2165 optional_yield y
, std::string
*err_msg
)
2167 int ret
= init(dpp
, op_state
, y
);
2169 set_err_msg(err_msg
, "unable to fetch user info");
2173 fetched_info
= op_state
.get_user_info();
2178 int RGWUser::info(RGWUserInfo
& fetched_info
, std::string
*err_msg
)
2180 if (!is_populated()) {
2181 set_err_msg(err_msg
, "no user info saved");
2185 fetched_info
= old_info
;
2190 int RGWUser::list(const DoutPrefixProvider
*dpp
, RGWUserAdminOpState
& op_state
, RGWFormatterFlusher
& flusher
)
2192 Formatter
*formatter
= flusher
.get_formatter();
2193 void *handle
= nullptr;
2194 std::string metadata_key
= "user";
2195 if (op_state
.max_entries
> 1000) {
2196 op_state
.max_entries
= 1000;
2199 auto meta_mgr
= store
->ctl()->meta
.mgr
;
2201 int ret
= meta_mgr
->list_keys_init(dpp
, metadata_key
, op_state
.marker
, &handle
);
2206 bool truncated
= false;
2211 // open the result object section
2212 formatter
->open_object_section("result");
2214 // open the user id list array section
2215 formatter
->open_array_section("keys");
2217 std::list
<std::string
> keys
;
2218 left
= op_state
.max_entries
- count
;
2219 ret
= meta_mgr
->list_keys_next(handle
, left
, keys
, &truncated
);
2220 if (ret
< 0 && ret
!= -ENOENT
) {
2222 } if (ret
!= -ENOENT
) {
2223 for (std::list
<std::string
>::iterator iter
= keys
.begin(); iter
!= keys
.end(); ++iter
) {
2224 formatter
->dump_string("key", *iter
);
2228 } while (truncated
&& left
> 0);
2229 // close user id list section
2230 formatter
->close_section();
2232 formatter
->dump_bool("truncated", truncated
);
2233 formatter
->dump_int("count", count
);
2235 formatter
->dump_string("marker", meta_mgr
->get_marker(handle
));
2238 // close result object section
2239 formatter
->close_section();
2241 meta_mgr
->list_keys_complete(handle
);
2247 int RGWUserAdminOp_User::list(const DoutPrefixProvider
*dpp
, rgw::sal::RGWRadosStore
*store
, RGWUserAdminOpState
& op_state
,
2248 RGWFormatterFlusher
& flusher
)
2252 int ret
= user
.init_storage(store
);
2256 ret
= user
.list(dpp
, op_state
, flusher
);
2263 int RGWUserAdminOp_User::info(const DoutPrefixProvider
*dpp
,
2264 rgw::sal::RGWRadosStore
*store
, RGWUserAdminOpState
& op_state
,
2265 RGWFormatterFlusher
& flusher
,
2271 int ret
= user
.init(dpp
, store
, op_state
, y
);
2275 if (!op_state
.has_existing_user())
2276 return -ERR_NO_SUCH_USER
;
2278 Formatter
*formatter
= flusher
.get_formatter();
2280 ret
= user
.info(info
, NULL
);
2284 if (op_state
.sync_stats
) {
2285 ret
= rgw_user_sync_all_stats(dpp
, store
, info
.user_id
, y
);
2291 RGWStorageStats stats
;
2292 RGWStorageStats
*arg_stats
= NULL
;
2293 if (op_state
.fetch_stats
) {
2294 int ret
= store
->ctl()->user
->read_stats(dpp
, info
.user_id
, &stats
, y
);
2295 if (ret
< 0 && ret
!= -ENOENT
) {
2305 dump_user_info(formatter
, info
, arg_stats
);
2312 int RGWUserAdminOp_User::create(const DoutPrefixProvider
*dpp
,
2313 rgw::sal::RGWRadosStore
*store
,
2314 RGWUserAdminOpState
& op_state
,
2315 RGWFormatterFlusher
& flusher
, optional_yield y
)
2319 int ret
= user
.init(dpp
, store
, op_state
, y
);
2323 Formatter
*formatter
= flusher
.get_formatter();
2325 ret
= user
.add(dpp
, op_state
, y
, NULL
);
2328 ret
= -ERR_USER_EXIST
;
2332 ret
= user
.info(info
, NULL
);
2339 dump_user_info(formatter
, info
);
2346 int RGWUserAdminOp_User::modify(const DoutPrefixProvider
*dpp
,
2347 rgw::sal::RGWRadosStore
*store
,
2348 RGWUserAdminOpState
& op_state
,
2349 RGWFormatterFlusher
& flusher
, optional_yield y
)
2353 int ret
= user
.init(dpp
, store
, op_state
, y
);
2356 Formatter
*formatter
= flusher
.get_formatter();
2358 ret
= user
.modify(dpp
, op_state
, y
, NULL
);
2361 ret
= -ERR_NO_SUCH_USER
;
2365 ret
= user
.info(info
, NULL
);
2372 dump_user_info(formatter
, info
);
2379 int RGWUserAdminOp_User::remove(const DoutPrefixProvider
*dpp
, rgw::sal::RGWRadosStore
*store
, RGWUserAdminOpState
& op_state
,
2380 RGWFormatterFlusher
& flusher
, optional_yield y
)
2384 int ret
= user
.init(dpp
, store
, op_state
, y
);
2389 ret
= user
.remove(dpp
, op_state
, y
, NULL
);
2392 ret
= -ERR_NO_SUCH_USER
;
2396 int RGWUserAdminOp_Subuser::create(const DoutPrefixProvider
*dpp
,
2397 rgw::sal::RGWRadosStore
*store
,
2398 RGWUserAdminOpState
& op_state
,
2399 RGWFormatterFlusher
& flusher
,
2404 int ret
= user
.init(dpp
, store
, op_state
, y
);
2408 if (!op_state
.has_existing_user())
2409 return -ERR_NO_SUCH_USER
;
2411 Formatter
*formatter
= flusher
.get_formatter();
2413 ret
= user
.subusers
.add(dpp
, op_state
, y
, NULL
);
2417 ret
= user
.info(info
, NULL
);
2424 dump_subusers_info(formatter
, info
);
2431 int RGWUserAdminOp_Subuser::modify(const DoutPrefixProvider
*dpp
,
2432 rgw::sal::RGWRadosStore
*store
, RGWUserAdminOpState
& op_state
,
2433 RGWFormatterFlusher
& flusher
, optional_yield y
)
2437 int ret
= user
.init(dpp
, store
, op_state
, y
);
2441 if (!op_state
.has_existing_user())
2442 return -ERR_NO_SUCH_USER
;
2444 Formatter
*formatter
= flusher
.get_formatter();
2446 ret
= user
.subusers
.modify(dpp
, op_state
, y
, NULL
);
2450 ret
= user
.info(info
, NULL
);
2457 dump_subusers_info(formatter
, info
);
2464 int RGWUserAdminOp_Subuser::remove(const DoutPrefixProvider
*dpp
,
2465 rgw::sal::RGWRadosStore
*store
,
2466 RGWUserAdminOpState
& op_state
,
2467 RGWFormatterFlusher
& flusher
,
2472 int ret
= user
.init(dpp
, store
, op_state
, y
);
2477 if (!op_state
.has_existing_user())
2478 return -ERR_NO_SUCH_USER
;
2480 ret
= user
.subusers
.remove(dpp
, op_state
, y
, NULL
);
2487 int RGWUserAdminOp_Key::create(const DoutPrefixProvider
*dpp
,
2488 rgw::sal::RGWRadosStore
*store
, RGWUserAdminOpState
& op_state
,
2489 RGWFormatterFlusher
& flusher
,
2494 int ret
= user
.init(dpp
, store
, op_state
, y
);
2498 if (!op_state
.has_existing_user())
2499 return -ERR_NO_SUCH_USER
;
2501 Formatter
*formatter
= flusher
.get_formatter();
2503 ret
= user
.keys
.add(dpp
, op_state
, y
, NULL
);
2507 ret
= user
.info(info
, NULL
);
2514 int key_type
= op_state
.get_key_type();
2516 if (key_type
== KEY_TYPE_SWIFT
)
2517 dump_swift_keys_info(formatter
, info
);
2519 else if (key_type
== KEY_TYPE_S3
)
2520 dump_access_keys_info(formatter
, info
);
2528 int RGWUserAdminOp_Key::remove(const DoutPrefixProvider
*dpp
,
2529 rgw::sal::RGWRadosStore
*store
,
2530 RGWUserAdminOpState
& op_state
,
2531 RGWFormatterFlusher
& flusher
,
2536 int ret
= user
.init(dpp
, store
, op_state
, y
);
2540 if (!op_state
.has_existing_user())
2541 return -ERR_NO_SUCH_USER
;
2544 ret
= user
.keys
.remove(dpp
, op_state
, y
, NULL
);
2551 int RGWUserAdminOp_Caps::add(const DoutPrefixProvider
*dpp
,
2552 rgw::sal::RGWRadosStore
*store
,
2553 RGWUserAdminOpState
& op_state
,
2554 RGWFormatterFlusher
& flusher
, optional_yield y
)
2558 int ret
= user
.init(dpp
, store
, op_state
, y
);
2562 if (!op_state
.has_existing_user())
2563 return -ERR_NO_SUCH_USER
;
2565 Formatter
*formatter
= flusher
.get_formatter();
2567 ret
= user
.caps
.add(dpp
, op_state
, y
, NULL
);
2571 ret
= user
.info(info
, NULL
);
2578 info
.caps
.dump(formatter
);
2586 int RGWUserAdminOp_Caps::remove(const DoutPrefixProvider
*dpp
,
2587 rgw::sal::RGWRadosStore
*store
,
2588 RGWUserAdminOpState
& op_state
,
2589 RGWFormatterFlusher
& flusher
, optional_yield y
)
2593 int ret
= user
.init(dpp
, store
, op_state
, y
);
2597 if (!op_state
.has_existing_user())
2598 return -ERR_NO_SUCH_USER
;
2600 Formatter
*formatter
= flusher
.get_formatter();
2602 ret
= user
.caps
.remove(dpp
, op_state
, y
, NULL
);
2606 ret
= user
.info(info
, NULL
);
2613 info
.caps
.dump(formatter
);
2620 class RGWUserMetadataHandler
: public RGWMetadataHandler_GenericMetaBE
{
2623 RGWSI_User
*user
{nullptr};
2626 RGWUserMetadataHandler(RGWSI_User
*user_svc
) {
2627 base_init(user_svc
->ctx(), user_svc
->get_be_handler());
2628 svc
.user
= user_svc
;
2631 string
get_type() override
{ return "user"; }
2633 int do_get(RGWSI_MetaBackend_Handler::Op
*op
, string
& entry
, RGWMetadataObject
**obj
, optional_yield y
, const DoutPrefixProvider
*dpp
) override
{
2634 RGWUserCompleteInfo uci
;
2635 RGWObjVersionTracker objv_tracker
;
2638 rgw_user user
= RGWSI_User::user_from_meta_key(entry
);
2640 int ret
= svc
.user
->read_user_info(op
->ctx(), user
, &uci
.info
, &objv_tracker
,
2641 &mtime
, nullptr, &uci
.attrs
,
2647 RGWUserMetadataObject
*mdo
= new RGWUserMetadataObject(uci
, objv_tracker
.read_version
, mtime
);
2653 RGWMetadataObject
*get_meta_obj(JSONObj
*jo
, const obj_version
& objv
, const ceph::real_time
& mtime
) override
{
2654 RGWUserCompleteInfo uci
;
2657 decode_json_obj(uci
, jo
);
2658 } catch (JSONDecoder::err
& e
) {
2662 return new RGWUserMetadataObject(uci
, objv
, mtime
);
2665 int do_put(RGWSI_MetaBackend_Handler::Op
*op
, string
& entry
,
2666 RGWMetadataObject
*obj
,
2667 RGWObjVersionTracker
& objv_tracker
,
2668 optional_yield y
, const DoutPrefixProvider
*dpp
,
2669 RGWMDLogSyncType type
, bool from_remote_zone
) override
;
2671 int do_remove(RGWSI_MetaBackend_Handler::Op
*op
, string
& entry
, RGWObjVersionTracker
& objv_tracker
,
2672 optional_yield y
, const DoutPrefixProvider
*dpp
) override
{
2675 rgw_user user
= RGWSI_User::user_from_meta_key(entry
);
2677 int ret
= svc
.user
->read_user_info(op
->ctx(), user
, &info
, nullptr,
2678 nullptr, nullptr, nullptr,
2684 return svc
.user
->remove_user_info(op
->ctx(), info
, &objv_tracker
,
2689 class RGWMetadataHandlerPut_User
: public RGWMetadataHandlerPut_SObj
2691 RGWUserMetadataHandler
*uhandler
;
2692 RGWUserMetadataObject
*uobj
;
2694 RGWMetadataHandlerPut_User(RGWUserMetadataHandler
*_handler
,
2695 RGWSI_MetaBackend_Handler::Op
*op
, string
& entry
,
2696 RGWMetadataObject
*obj
, RGWObjVersionTracker
& objv_tracker
,
2698 RGWMDLogSyncType type
, bool from_remote_zone
) : RGWMetadataHandlerPut_SObj(_handler
, op
, entry
, obj
, objv_tracker
, y
, type
, from_remote_zone
),
2699 uhandler(_handler
) {
2700 uobj
= static_cast<RGWUserMetadataObject
*>(obj
);
2703 int put_checked(const DoutPrefixProvider
*dpp
) override
;
2706 int RGWUserMetadataHandler::do_put(RGWSI_MetaBackend_Handler::Op
*op
, string
& entry
,
2707 RGWMetadataObject
*obj
,
2708 RGWObjVersionTracker
& objv_tracker
,
2709 optional_yield y
, const DoutPrefixProvider
*dpp
,
2710 RGWMDLogSyncType type
, bool from_remote_zone
)
2712 RGWMetadataHandlerPut_User
put_op(this, op
, entry
, obj
, objv_tracker
, y
, type
, from_remote_zone
);
2713 return do_put_operate(&put_op
, dpp
);
2716 int RGWMetadataHandlerPut_User::put_checked(const DoutPrefixProvider
*dpp
)
2718 RGWUserMetadataObject
*orig_obj
= static_cast<RGWUserMetadataObject
*>(old_obj
);
2719 RGWUserCompleteInfo
& uci
= uobj
->get_uci();
2721 map
<string
, bufferlist
> *pattrs
{nullptr};
2722 if (uci
.has_attrs
) {
2723 pattrs
= &uci
.attrs
;
2726 RGWUserInfo
*pold_info
= (orig_obj
? &orig_obj
->get_uci().info
: nullptr);
2728 auto mtime
= obj
->get_mtime();
2730 int ret
= uhandler
->svc
.user
->store_user_info(op
->ctx(), uci
.info
, pold_info
,
2731 &objv_tracker
, mtime
,
2732 false, pattrs
, y
, dpp
);
2737 return STATUS_APPLIED
;
2741 RGWUserCtl::RGWUserCtl(RGWSI_Zone
*zone_svc
,
2742 RGWSI_User
*user_svc
,
2743 RGWUserMetadataHandler
*_umhandler
) : umhandler(_umhandler
) {
2744 svc
.zone
= zone_svc
;
2745 svc
.user
= user_svc
;
2746 be_handler
= umhandler
->get_be_handler();
2750 class optional_default
2752 const std::optional
<T
>& opt
;
2753 std::optional
<T
> def
;
2756 optional_default(const std::optional
<T
>& _o
) : opt(_o
) {
2765 const T
*operator->() {
2769 const T
& operator*() {
2774 int RGWUserCtl::get_info_by_uid(const DoutPrefixProvider
*dpp
,
2775 const rgw_user
& uid
,
2778 const GetParams
& params
)
2781 return be_handler
->call([&](RGWSI_MetaBackend_Handler::Op
*op
) {
2782 return svc
.user
->read_user_info(op
->ctx(),
2785 params
.objv_tracker
,
2794 int RGWUserCtl::get_info_by_email(const DoutPrefixProvider
*dpp
,
2795 const string
& email
,
2798 const GetParams
& params
)
2800 return be_handler
->call([&](RGWSI_MetaBackend_Handler::Op
*op
) {
2801 return svc
.user
->get_user_info_by_email(op
->ctx(), email
,
2803 params
.objv_tracker
,
2810 int RGWUserCtl::get_info_by_swift(const DoutPrefixProvider
*dpp
,
2811 const string
& swift_name
,
2814 const GetParams
& params
)
2816 return be_handler
->call([&](RGWSI_MetaBackend_Handler::Op
*op
) {
2817 return svc
.user
->get_user_info_by_swift(op
->ctx(), swift_name
,
2819 params
.objv_tracker
,
2826 int RGWUserCtl::get_info_by_access_key(const DoutPrefixProvider
*dpp
,
2827 const string
& access_key
,
2830 const GetParams
& params
)
2832 return be_handler
->call([&](RGWSI_MetaBackend_Handler::Op
*op
) {
2833 return svc
.user
->get_user_info_by_access_key(op
->ctx(), access_key
,
2835 params
.objv_tracker
,
2842 int RGWUserCtl::get_attrs_by_uid(const DoutPrefixProvider
*dpp
,
2843 const rgw_user
& user_id
,
2844 map
<string
, bufferlist
> *pattrs
,
2846 RGWObjVersionTracker
*objv_tracker
)
2848 RGWUserInfo user_info
;
2850 return get_info_by_uid(dpp
, user_id
, &user_info
, y
, RGWUserCtl::GetParams()
2852 .set_objv_tracker(objv_tracker
));
2855 int RGWUserCtl::store_info(const DoutPrefixProvider
*dpp
,
2856 const RGWUserInfo
& info
, optional_yield y
,
2857 const PutParams
& params
)
2859 string key
= RGWSI_User::get_meta_key(info
.user_id
);
2861 return be_handler
->call([&](RGWSI_MetaBackend_Handler::Op
*op
) {
2862 return svc
.user
->store_user_info(op
->ctx(), info
,
2864 params
.objv_tracker
,
2873 int RGWUserCtl::remove_info(const DoutPrefixProvider
*dpp
,
2874 const RGWUserInfo
& info
, optional_yield y
,
2875 const RemoveParams
& params
)
2878 string key
= RGWSI_User::get_meta_key(info
.user_id
);
2880 return be_handler
->call([&](RGWSI_MetaBackend_Handler::Op
*op
) {
2881 return svc
.user
->remove_user_info(op
->ctx(), info
,
2882 params
.objv_tracker
,
2887 int RGWUserCtl::add_bucket(const DoutPrefixProvider
*dpp
,
2888 const rgw_user
& user
,
2889 const rgw_bucket
& bucket
,
2890 ceph::real_time creation_time
,
2894 return be_handler
->call([&](RGWSI_MetaBackend_Handler::Op
*op
) {
2895 return svc
.user
->add_bucket(dpp
, op
->ctx(), user
, bucket
, creation_time
, y
);
2899 int RGWUserCtl::remove_bucket(const DoutPrefixProvider
*dpp
,
2900 const rgw_user
& user
,
2901 const rgw_bucket
& bucket
,
2905 return be_handler
->call([&](RGWSI_MetaBackend_Handler::Op
*op
) {
2906 return svc
.user
->remove_bucket(dpp
, op
->ctx(), user
, bucket
, y
);
2910 int RGWUserCtl::list_buckets(const DoutPrefixProvider
*dpp
,
2911 const rgw_user
& user
,
2912 const string
& marker
,
2913 const string
& end_marker
,
2916 RGWUserBuckets
*buckets
,
2919 uint64_t default_max
)
2925 return be_handler
->call([&](RGWSI_MetaBackend_Handler::Op
*op
) {
2926 int ret
= svc
.user
->list_buckets(dpp
, op
->ctx(), user
, marker
, end_marker
,
2927 max
, buckets
, is_truncated
, y
);
2932 map
<string
, RGWBucketEnt
>& m
= buckets
->get_buckets();
2933 ret
= ctl
.bucket
->read_buckets_stats(m
, y
, dpp
);
2934 if (ret
< 0 && ret
!= -ENOENT
) {
2935 ldpp_dout(dpp
, 0) << "ERROR: could not get stats for buckets" << dendl
;
2943 int RGWUserCtl::flush_bucket_stats(const DoutPrefixProvider
*dpp
,
2944 const rgw_user
& user
,
2945 const RGWBucketEnt
& ent
,
2948 return be_handler
->call([&](RGWSI_MetaBackend_Handler::Op
*op
) {
2949 return svc
.user
->flush_bucket_stats(dpp
, op
->ctx(), user
, ent
, y
);
2953 int RGWUserCtl::complete_flush_stats(const DoutPrefixProvider
*dpp
, const rgw_user
& user
, optional_yield y
)
2955 return be_handler
->call([&](RGWSI_MetaBackend_Handler::Op
*op
) {
2956 return svc
.user
->complete_flush_stats(dpp
, op
->ctx(), user
, y
);
2960 int RGWUserCtl::reset_stats(const DoutPrefixProvider
*dpp
, const rgw_user
& user
, optional_yield y
)
2962 return be_handler
->call([&](RGWSI_MetaBackend_Handler::Op
*op
) {
2963 return svc
.user
->reset_bucket_stats(dpp
, op
->ctx(), user
, y
);
2967 int RGWUserCtl::read_stats(const DoutPrefixProvider
*dpp
,
2968 const rgw_user
& user
, RGWStorageStats
*stats
,
2970 ceph::real_time
*last_stats_sync
,
2971 ceph::real_time
*last_stats_update
)
2973 return be_handler
->call([&](RGWSI_MetaBackend_Handler::Op
*op
) {
2974 return svc
.user
->read_stats(dpp
, op
->ctx(), user
, stats
,
2975 last_stats_sync
, last_stats_update
, y
);
2979 int RGWUserCtl::read_stats_async(const DoutPrefixProvider
*dpp
, const rgw_user
& user
, RGWGetUserStats_CB
*cb
)
2981 return be_handler
->call([&](RGWSI_MetaBackend_Handler::Op
*op
) {
2982 return svc
.user
->read_stats_async(dpp
, op
->ctx(), user
, cb
);
2986 RGWMetadataHandler
*RGWUserMetaHandlerAllocator::alloc(RGWSI_User
*user_svc
) {
2987 return new RGWUserMetadataHandler(user_svc
);