1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
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"
14 #include "rgw_rados.h"
17 #include "include/types.h"
19 #include "rgw_string.h"
21 // until everything is moved from rgw_common
22 #include "rgw_common.h"
24 #include "rgw_bucket.h"
26 #define dout_subsys ceph_subsys_rgw
31 static RGWMetadataHandler
*user_meta_handler
= NULL
;
35 * Get the anonymous (ie, unauthenticated) user info.
37 void rgw_get_anon_user(RGWUserInfo
& info
)
39 info
.user_id
= RGW_USER_ANON_ID
;
40 info
.display_name
.clear();
41 info
.access_keys
.clear();
44 int rgw_user_sync_all_stats(RGWRados
*store
, const rgw_user
& user_id
)
46 CephContext
*cct
= store
->ctx();
47 size_t max_entries
= cct
->_conf
->rgw_list_buckets_max_chunk
;
48 bool is_truncated
= false;
51 RGWObjectCtx
obj_ctx(store
);
54 RGWUserBuckets user_buckets
;
55 ret
= rgw_read_user_buckets(store
, user_id
, user_buckets
, marker
,
56 string(), max_entries
, false, &is_truncated
);
58 ldout(cct
, 0) << "failed to read user buckets: ret=" << ret
<< dendl
;
61 map
<string
, RGWBucketEnt
>& buckets
= user_buckets
.get_buckets();
62 for (map
<string
, RGWBucketEnt
>::iterator i
= buckets
.begin();
67 RGWBucketEnt
& bucket_ent
= i
->second
;
68 RGWBucketInfo bucket_info
;
70 ret
= store
->get_bucket_instance_info(obj_ctx
, bucket_ent
.bucket
, bucket_info
, NULL
, NULL
);
72 ldout(cct
, 0) << "ERROR: could not read bucket info: bucket=" << bucket_ent
.bucket
<< " ret=" << ret
<< dendl
;
75 ret
= rgw_bucket_sync_user_stats(store
, user_id
, bucket_info
);
77 ldout(cct
, 0) << "ERROR: could not sync bucket stats: ret=" << ret
<< dendl
;
80 RGWQuotaInfo bucket_quota
;
81 ret
= store
->check_bucket_shards(bucket_info
, bucket_info
.bucket
, bucket_quota
);
83 ldout(cct
, 0) << "ERROR in check_bucket_shards: " << cpp_strerror(-ret
)<< dendl
;
86 } while (is_truncated
);
88 ret
= store
->complete_sync_user_stats(user_id
);
90 cerr
<< "ERROR: failed to complete syncing user stats: ret=" << ret
<< std::endl
;
98 * Save the given user information to storage.
99 * Returns: 0 on success, -ERR# on failure.
101 int rgw_store_user_info(RGWRados
*store
,
103 RGWUserInfo
*old_info
,
104 RGWObjVersionTracker
*objv_tracker
,
107 map
<string
, bufferlist
> *pattrs
)
110 RGWObjVersionTracker ot
;
116 if (ot
.write_version
.tag
.empty()) {
117 if (ot
.read_version
.tag
.empty()) {
118 ot
.generate_new_write_ver(store
->ctx());
120 ot
.write_version
= ot
.read_version
;
121 ot
.write_version
.ver
++;
125 map
<string
, RGWAccessKey
>::iterator iter
;
126 for (iter
= info
.swift_keys
.begin(); iter
!= info
.swift_keys
.end(); ++iter
) {
127 if (old_info
&& old_info
->swift_keys
.count(iter
->first
) != 0)
129 RGWAccessKey
& k
= iter
->second
;
130 /* check if swift mapping exists */
132 int r
= rgw_get_user_info_by_swift(store
, k
.id
, inf
);
133 if (r
>= 0 && inf
.user_id
.compare(info
.user_id
) != 0) {
134 ldout(store
->ctx(), 0) << "WARNING: can't store user info, swift id (" << k
.id
135 << ") already mapped to another user (" << info
.user_id
<< ")" << dendl
;
140 if (!info
.access_keys
.empty()) {
141 /* check if access keys already exist */
143 map
<string
, RGWAccessKey
>::iterator iter
= info
.access_keys
.begin();
144 for (; iter
!= info
.access_keys
.end(); ++iter
) {
145 RGWAccessKey
& k
= iter
->second
;
146 if (old_info
&& old_info
->access_keys
.count(iter
->first
) != 0)
148 int r
= rgw_get_user_info_by_access_key(store
, k
.id
, inf
);
149 if (r
>= 0 && inf
.user_id
.compare(info
.user_id
) != 0) {
150 ldout(store
->ctx(), 0) << "WARNING: can't store user info, access key already mapped to another user" << dendl
;
157 ui
.user_id
= info
.user_id
;
160 ::encode(ui
, link_bl
);
163 ::encode(ui
, data_bl
);
164 ::encode(info
, data_bl
);
167 info
.user_id
.to_str(key
);
169 ret
= store
->meta_mgr
->put_entry(user_meta_handler
, key
, data_bl
, exclusive
, &ot
, mtime
, pattrs
);
173 if (!info
.user_email
.empty()) {
175 old_info
->user_email
.compare(info
.user_email
) != 0) { /* only if new index changed */
176 ret
= rgw_put_system_obj(store
, store
->get_zone_params().user_email_pool
, info
.user_email
,
177 link_bl
.c_str(), link_bl
.length(), exclusive
, NULL
, real_time());
183 if (!info
.access_keys
.empty()) {
184 map
<string
, RGWAccessKey
>::iterator iter
= info
.access_keys
.begin();
185 for (; iter
!= info
.access_keys
.end(); ++iter
) {
186 RGWAccessKey
& k
= iter
->second
;
187 if (old_info
&& old_info
->access_keys
.count(iter
->first
) != 0)
190 ret
= rgw_put_system_obj(store
, store
->get_zone_params().user_keys_pool
, k
.id
,
191 link_bl
.c_str(), link_bl
.length(), exclusive
,
198 map
<string
, RGWAccessKey
>::iterator siter
;
199 for (siter
= info
.swift_keys
.begin(); siter
!= info
.swift_keys
.end(); ++siter
) {
200 RGWAccessKey
& k
= siter
->second
;
201 if (old_info
&& old_info
->swift_keys
.count(siter
->first
) != 0)
204 ret
= rgw_put_system_obj(store
, store
->get_zone_params().user_swift_pool
, k
.id
,
205 link_bl
.c_str(), link_bl
.length(), exclusive
,
214 struct user_info_entry
{
216 RGWObjVersionTracker objv_tracker
;
220 static RGWChainedCacheImpl
<user_info_entry
> uinfo_cache
;
222 int rgw_get_user_info_from_index(RGWRados
* const store
,
226 RGWObjVersionTracker
* const objv_tracker
,
227 real_time
* const pmtime
)
230 if (uinfo_cache
.find(key
, &e
)) {
233 *objv_tracker
= e
.objv_tracker
;
241 RGWObjectCtx
obj_ctx(store
);
243 int ret
= rgw_get_system_obj(store
, obj_ctx
, pool
, key
, bl
, NULL
, &e
.mtime
);
247 rgw_cache_entry_info cache_info
;
249 bufferlist::iterator iter
= bl
.begin();
252 int ret
= rgw_get_user_info_by_uid(store
, uid
.user_id
, e
.info
, &e
.objv_tracker
, NULL
, &cache_info
);
256 } catch (buffer::error
& err
) {
257 ldout(store
->ctx(), 0) << "ERROR: failed to decode user info, caught buffer::error" << dendl
;
261 list
<rgw_cache_entry_info
*> cache_info_entries
;
262 cache_info_entries
.push_back(&cache_info
);
264 uinfo_cache
.put(store
, key
, &e
, cache_info_entries
);
268 *objv_tracker
= e
.objv_tracker
;
276 * Given a uid, finds the user info associated with it.
277 * returns: 0 on success, -ERR# on failure (including nonexistence)
279 int rgw_get_user_info_by_uid(RGWRados
*store
,
282 RGWObjVersionTracker
* const objv_tracker
,
283 real_time
* const pmtime
,
284 rgw_cache_entry_info
* const cache_info
,
285 map
<string
, bufferlist
> * const pattrs
)
290 RGWObjectCtx
obj_ctx(store
);
291 string oid
= uid
.to_str();
292 int ret
= rgw_get_system_obj(store
, obj_ctx
, store
->get_zone_params().user_uid_pool
, oid
, bl
, objv_tracker
, pmtime
, pattrs
, cache_info
);
297 bufferlist::iterator iter
= bl
.begin();
299 ::decode(user_id
, iter
);
300 if (user_id
.user_id
.compare(uid
) != 0) {
301 lderr(store
->ctx()) << "ERROR: rgw_get_user_info_by_uid(): user id mismatch: " << user_id
.user_id
<< " != " << uid
<< dendl
;
305 ::decode(info
, iter
);
307 } catch (buffer::error
& err
) {
308 ldout(store
->ctx(), 0) << "ERROR: failed to decode user info, caught buffer::error" << dendl
;
316 * Given an email, finds the user info associated with it.
317 * returns: 0 on success, -ERR# on failure (including nonexistence)
319 int rgw_get_user_info_by_email(RGWRados
*store
, string
& email
, RGWUserInfo
& info
,
320 RGWObjVersionTracker
*objv_tracker
, real_time
*pmtime
)
322 return rgw_get_user_info_from_index(store
, email
, store
->get_zone_params().user_email_pool
, info
, objv_tracker
, pmtime
);
326 * Given an swift username, finds the user_info associated with it.
327 * returns: 0 on success, -ERR# on failure (including nonexistence)
329 extern int rgw_get_user_info_by_swift(RGWRados
* const store
,
330 const string
& swift_name
,
331 RGWUserInfo
& info
, /* out */
332 RGWObjVersionTracker
* const objv_tracker
,
333 real_time
* const pmtime
)
335 return rgw_get_user_info_from_index(store
, swift_name
,
336 store
->get_zone_params().user_swift_pool
,
337 info
, objv_tracker
, pmtime
);
341 * Given an access key, finds the user info associated with it.
342 * returns: 0 on success, -ERR# on failure (including nonexistence)
344 extern int rgw_get_user_info_by_access_key(RGWRados
* store
,
345 const std::string
& access_key
,
347 RGWObjVersionTracker
* objv_tracker
,
350 return rgw_get_user_info_from_index(store
, access_key
,
351 store
->get_zone_params().user_keys_pool
,
352 info
, objv_tracker
, pmtime
);
355 int rgw_get_user_attrs_by_uid(RGWRados
*store
,
356 const rgw_user
& user_id
,
357 map
<string
, bufferlist
>& attrs
,
358 RGWObjVersionTracker
*objv_tracker
)
360 RGWObjectCtx
obj_ctx(store
);
361 rgw_raw_obj
obj(store
->get_zone_params().user_uid_pool
, user_id
.to_str());
362 RGWRados::SystemObject
src(store
, obj_ctx
, obj
);
363 RGWRados::SystemObject::Read
rop(&src
);
365 rop
.stat_params
.attrs
= &attrs
;
366 return rop
.stat(objv_tracker
);
369 int rgw_remove_key_index(RGWRados
*store
, RGWAccessKey
& access_key
)
371 rgw_raw_obj
obj(store
->get_zone_params().user_keys_pool
, access_key
.id
);
372 int ret
= store
->delete_system_obj(obj
);
376 int rgw_remove_uid_index(RGWRados
*store
, rgw_user
& uid
)
378 RGWObjVersionTracker objv_tracker
;
380 int ret
= rgw_get_user_info_by_uid(store
, uid
, info
, &objv_tracker
, NULL
);
384 string oid
= uid
.to_str();
385 ret
= store
->meta_mgr
->remove_entry(user_meta_handler
, oid
, &objv_tracker
);
392 int rgw_remove_email_index(RGWRados
*store
, string
& email
)
397 rgw_raw_obj
obj(store
->get_zone_params().user_email_pool
, email
);
398 return store
->delete_system_obj(obj
);
401 int rgw_remove_swift_name_index(RGWRados
*store
, string
& swift_name
)
403 rgw_raw_obj
obj(store
->get_zone_params().user_swift_pool
, swift_name
);
404 int ret
= store
->delete_system_obj(obj
);
409 * delete a user's presence from the RGW system.
410 * First remove their bucket ACLs, then delete them
411 * from the user and user email pools. This leaves the pools
412 * themselves alone, as well as any ACLs embedded in object xattrs.
414 int rgw_delete_user(RGWRados
*store
, RGWUserInfo
& info
, RGWObjVersionTracker
& objv_tracker
) {
417 map
<string
, RGWAccessKey
>::iterator kiter
= info
.access_keys
.begin();
418 for (; kiter
!= info
.access_keys
.end(); ++kiter
) {
419 ldout(store
->ctx(), 10) << "removing key index: " << kiter
->first
<< dendl
;
420 ret
= rgw_remove_key_index(store
, kiter
->second
);
421 if (ret
< 0 && ret
!= -ENOENT
) {
422 ldout(store
->ctx(), 0) << "ERROR: could not remove " << kiter
->first
<< " (access key object), should be fixed (err=" << ret
<< ")" << dendl
;
427 map
<string
, RGWAccessKey
>::iterator siter
= info
.swift_keys
.begin();
428 for (; siter
!= info
.swift_keys
.end(); ++siter
) {
429 RGWAccessKey
& k
= siter
->second
;
430 ldout(store
->ctx(), 10) << "removing swift subuser index: " << k
.id
<< dendl
;
431 /* check if swift mapping exists */
432 ret
= rgw_remove_swift_name_index(store
, k
.id
);
433 if (ret
< 0 && ret
!= -ENOENT
) {
434 ldout(store
->ctx(), 0) << "ERROR: could not remove " << k
.id
<< " (swift name object), should be fixed (err=" << ret
<< ")" << dendl
;
439 ldout(store
->ctx(), 10) << "removing email index: " << info
.user_email
<< dendl
;
440 ret
= rgw_remove_email_index(store
, info
.user_email
);
441 if (ret
< 0 && ret
!= -ENOENT
) {
442 ldout(store
->ctx(), 0) << "ERROR: could not remove email index object for "
443 << info
.user_email
<< ", should be fixed (err=" << ret
<< ")" << dendl
;
447 string buckets_obj_id
;
448 rgw_get_buckets_obj(info
.user_id
, buckets_obj_id
);
449 rgw_raw_obj
uid_bucks(store
->get_zone_params().user_uid_pool
, buckets_obj_id
);
450 ldout(store
->ctx(), 10) << "removing user buckets index" << dendl
;
451 ret
= store
->delete_system_obj(uid_bucks
);
452 if (ret
< 0 && ret
!= -ENOENT
) {
453 ldout(store
->ctx(), 0) << "ERROR: could not remove " << info
.user_id
<< ":" << uid_bucks
<< ", should be fixed (err=" << ret
<< ")" << dendl
;
458 info
.user_id
.to_str(key
);
460 rgw_raw_obj
uid_obj(store
->get_zone_params().user_uid_pool
, key
);
461 ldout(store
->ctx(), 10) << "removing user index: " << info
.user_id
<< dendl
;
462 ret
= store
->meta_mgr
->remove_entry(user_meta_handler
, key
, &objv_tracker
);
463 if (ret
< 0 && ret
!= -ENOENT
&& ret
!= -ECANCELED
) {
464 ldout(store
->ctx(), 0) << "ERROR: could not remove " << info
.user_id
<< ":" << uid_obj
<< ", should be fixed (err=" << ret
<< ")" << dendl
;
471 static bool char_is_unreserved_url(char c
)
487 struct rgw_flags_desc
{
492 static struct rgw_flags_desc rgw_perms
[] = {
493 { RGW_PERM_FULL_CONTROL
, "full-control" },
494 { RGW_PERM_READ
| RGW_PERM_WRITE
, "read-write" },
495 { RGW_PERM_READ
, "read" },
496 { RGW_PERM_WRITE
, "write" },
497 { RGW_PERM_READ_ACP
, "read-acp" },
498 { RGW_PERM_WRITE_ACP
, "read-acp" },
502 void rgw_perm_to_str(uint32_t mask
, char *buf
, int len
)
504 const char *sep
= "";
507 snprintf(buf
, len
, "<none>");
511 uint32_t orig_mask
= mask
;
512 for (int i
= 0; rgw_perms
[i
].mask
; i
++) {
513 struct rgw_flags_desc
*desc
= &rgw_perms
[i
];
514 if ((mask
& desc
->mask
) == desc
->mask
) {
515 pos
+= snprintf(buf
+ pos
, len
- pos
, "%s%s", sep
, desc
->str
);
524 if (mask
== orig_mask
) // no change
529 uint32_t rgw_str_to_perm(const char *str
)
531 if (strcasecmp(str
, "") == 0)
532 return RGW_PERM_NONE
;
533 else if (strcasecmp(str
, "read") == 0)
534 return RGW_PERM_READ
;
535 else if (strcasecmp(str
, "write") == 0)
536 return RGW_PERM_WRITE
;
537 else if (strcasecmp(str
, "readwrite") == 0)
538 return RGW_PERM_READ
| RGW_PERM_WRITE
;
539 else if (strcasecmp(str
, "full") == 0)
540 return RGW_PERM_FULL_CONTROL
;
542 return RGW_PERM_INVALID
;
545 static bool validate_access_key(string
& key
)
547 const char *p
= key
.c_str();
549 if (!char_is_unreserved_url(*p
))
556 static void set_err_msg(std::string
*sink
, std::string msg
)
558 if (sink
&& !msg
.empty())
562 static bool remove_old_indexes(RGWRados
*store
,
563 RGWUserInfo
& old_info
, RGWUserInfo
& new_info
, std::string
*err_msg
)
568 if (!old_info
.user_id
.empty() &&
569 old_info
.user_id
.compare(new_info
.user_id
) != 0) {
570 if (old_info
.user_id
.tenant
!= new_info
.user_id
.tenant
) {
571 ldout(store
->ctx(), 0) << "ERROR: tenant mismatch: " << old_info
.user_id
.tenant
<< " != " << new_info
.user_id
.tenant
<< dendl
;
574 ret
= rgw_remove_uid_index(store
, old_info
.user_id
);
575 if (ret
< 0 && ret
!= -ENOENT
) {
576 set_err_msg(err_msg
, "ERROR: could not remove index for uid " + old_info
.user_id
.to_str());
581 if (!old_info
.user_email
.empty() &&
582 old_info
.user_email
.compare(new_info
.user_email
) != 0) {
583 ret
= rgw_remove_email_index(store
, old_info
.user_email
);
584 if (ret
< 0 && ret
!= -ENOENT
) {
585 set_err_msg(err_msg
, "ERROR: could not remove index for email " + old_info
.user_email
);
590 map
<string
, RGWAccessKey
>::iterator old_iter
;
591 for (old_iter
= old_info
.swift_keys
.begin(); old_iter
!= old_info
.swift_keys
.end(); ++old_iter
) {
592 RGWAccessKey
& swift_key
= old_iter
->second
;
593 map
<string
, RGWAccessKey
>::iterator new_iter
= new_info
.swift_keys
.find(swift_key
.id
);
594 if (new_iter
== new_info
.swift_keys
.end()) {
595 ret
= rgw_remove_swift_name_index(store
, swift_key
.id
);
596 if (ret
< 0 && ret
!= -ENOENT
) {
597 set_err_msg(err_msg
, "ERROR: could not remove index for swift_name " + swift_key
.id
);
607 * Dump either the full user info or a subset to a formatter.
609 * NOTE: It is the caller's respnsibility to ensure that the
610 * formatter is flushed at the correct time.
613 static void dump_subusers_info(Formatter
*f
, RGWUserInfo
&info
)
615 map
<string
, RGWSubUser
>::iterator uiter
;
617 f
->open_array_section("subusers");
618 for (uiter
= info
.subusers
.begin(); uiter
!= info
.subusers
.end(); ++uiter
) {
619 RGWSubUser
& u
= uiter
->second
;
620 f
->open_object_section("user");
622 info
.user_id
.to_str(s
);
623 f
->dump_format("id", "%s:%s", s
.c_str(), u
.name
.c_str());
625 rgw_perm_to_str(u
.perm_mask
, buf
, sizeof(buf
));
626 f
->dump_string("permissions", buf
);
632 static void dump_access_keys_info(Formatter
*f
, RGWUserInfo
&info
)
634 map
<string
, RGWAccessKey
>::iterator kiter
;
635 f
->open_array_section("keys");
636 for (kiter
= info
.access_keys
.begin(); kiter
!= info
.access_keys
.end(); ++kiter
) {
637 RGWAccessKey
& k
= kiter
->second
;
638 const char *sep
= (k
.subuser
.empty() ? "" : ":");
639 const char *subuser
= (k
.subuser
.empty() ? "" : k
.subuser
.c_str());
640 f
->open_object_section("key");
642 info
.user_id
.to_str(s
);
643 f
->dump_format("user", "%s%s%s", s
.c_str(), sep
, subuser
);
644 f
->dump_string("access_key", k
.id
);
645 f
->dump_string("secret_key", k
.key
);
651 static void dump_swift_keys_info(Formatter
*f
, RGWUserInfo
&info
)
653 map
<string
, RGWAccessKey
>::iterator kiter
;
654 f
->open_array_section("swift_keys");
655 for (kiter
= info
.swift_keys
.begin(); kiter
!= info
.swift_keys
.end(); ++kiter
) {
656 RGWAccessKey
& k
= kiter
->second
;
657 const char *sep
= (k
.subuser
.empty() ? "" : ":");
658 const char *subuser
= (k
.subuser
.empty() ? "" : k
.subuser
.c_str());
659 f
->open_object_section("key");
661 info
.user_id
.to_str(s
);
662 f
->dump_format("user", "%s%s%s", s
.c_str(), sep
, subuser
);
663 f
->dump_string("secret_key", k
.key
);
669 static void dump_user_info(Formatter
*f
, RGWUserInfo
&info
,
670 RGWStorageStats
*stats
= NULL
)
672 f
->open_object_section("user_info");
674 f
->dump_string("tenant", info
.user_id
.tenant
);
675 f
->dump_string("user_id", info
.user_id
.id
);
676 f
->dump_string("display_name", info
.display_name
);
677 f
->dump_string("email", info
.user_email
);
678 f
->dump_int("suspended", (int)info
.suspended
);
679 f
->dump_int("max_buckets", (int)info
.max_buckets
);
681 dump_subusers_info(f
, info
);
682 dump_access_keys_info(f
, info
);
683 dump_swift_keys_info(f
, info
);
686 encode_json("stats", *stats
, f
);
693 RGWAccessKeyPool::RGWAccessKeyPool(RGWUser
* usr
)
700 keys_allowed
= false;
707 store
= user
->get_store();
710 RGWAccessKeyPool::~RGWAccessKeyPool()
715 int RGWAccessKeyPool::init(RGWUserAdminOpState
& op_state
)
717 if (!op_state
.is_initialized()) {
718 keys_allowed
= false;
722 rgw_user
& uid
= op_state
.get_user_id();
723 if (uid
.compare(RGW_USER_ANON_ID
) == 0) {
724 keys_allowed
= false;
728 swift_keys
= op_state
.get_swift_keys();
729 access_keys
= op_state
.get_access_keys();
737 * Do a fairly exhaustive search for an existing key matching the parameters
738 * given. Also handles the case where no key type was specified and updates
739 * the operation state if needed.
742 bool RGWAccessKeyPool::check_existing_key(RGWUserAdminOpState
& op_state
)
744 bool existing_key
= false;
746 int key_type
= op_state
.get_key_type();
747 std::string kid
= op_state
.get_access_key();
748 std::map
<std::string
, RGWAccessKey
>::iterator kiter
;
749 std::string swift_kid
= op_state
.build_default_swift_kid();
751 RGWUserInfo dup_info
;
753 if (kid
.empty() && swift_kid
.empty())
758 kiter
= swift_keys
->find(swift_kid
);
760 existing_key
= (kiter
!= swift_keys
->end());
762 op_state
.set_access_key(swift_kid
);
766 kiter
= access_keys
->find(kid
);
767 existing_key
= (kiter
!= access_keys
->end());
771 kiter
= access_keys
->find(kid
);
773 existing_key
= (kiter
!= access_keys
->end());
775 op_state
.set_key_type(KEY_TYPE_S3
);
779 kiter
= swift_keys
->find(kid
);
781 existing_key
= (kiter
!= swift_keys
->end());
783 op_state
.set_key_type(KEY_TYPE_SWIFT
);
787 // handle the case where the access key was not provided in user:key format
788 if (swift_kid
.empty())
791 kiter
= swift_keys
->find(swift_kid
);
793 existing_key
= (kiter
!= swift_keys
->end());
795 op_state
.set_access_key(swift_kid
);
796 op_state
.set_key_type(KEY_TYPE_SWIFT
);
800 op_state
.set_existing_key(existing_key
);
805 int RGWAccessKeyPool::check_op(RGWUserAdminOpState
& op_state
,
806 std::string
*err_msg
)
808 RGWUserInfo dup_info
;
810 if (!op_state
.is_populated()) {
811 set_err_msg(err_msg
, "user info was not populated");
816 set_err_msg(err_msg
, "keys not allowed for this user");
820 int32_t key_type
= op_state
.get_key_type();
822 // if a key type wasn't specified
824 if (op_state
.has_subuser()) {
825 key_type
= KEY_TYPE_SWIFT
;
827 key_type
= KEY_TYPE_S3
;
831 op_state
.set_key_type(key_type
);
833 /* see if the access key was specified */
834 if (key_type
== KEY_TYPE_S3
&& !op_state
.will_gen_access() &&
835 op_state
.get_access_key().empty()) {
836 set_err_msg(err_msg
, "empty access key");
837 return -ERR_INVALID_ACCESS_KEY
;
840 // don't check for secret key because we may be doing a removal
842 check_existing_key(op_state
);
847 // Generate a new random key
848 int RGWAccessKeyPool::generate_key(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
853 std::pair
<std::string
, RGWAccessKey
> key_pair
;
854 RGWAccessKey new_key
;
855 RGWUserInfo duplicate_check
;
858 int key_type
= op_state
.get_key_type();
859 bool gen_access
= op_state
.will_gen_access();
860 bool gen_secret
= op_state
.will_gen_secret();
863 set_err_msg(err_msg
, "access keys not allowed for this user");
867 if (op_state
.has_existing_key()) {
868 set_err_msg(err_msg
, "cannot create existing key");
869 return -ERR_KEY_EXIST
;
873 id
= op_state
.get_access_key();
879 if (rgw_get_user_info_by_swift(store
, id
, duplicate_check
) >= 0) {
880 set_err_msg(err_msg
, "existing swift key in RGW system:" + id
);
881 return -ERR_KEY_EXIST
;
885 if (rgw_get_user_info_by_access_key(store
, id
, duplicate_check
) >= 0) {
886 set_err_msg(err_msg
, "existing S3 key in RGW system:" + id
);
887 return -ERR_KEY_EXIST
;
893 if (op_state
.has_subuser()) {
894 //create user and subuser at the same time, user's s3 key should not be set this
895 if (!op_state
.key_type_setbycontext
|| (key_type
== KEY_TYPE_SWIFT
)) {
896 new_key
.subuser
= op_state
.get_subuser();
902 if (op_state
.get_secret_key().empty()) {
903 set_err_msg(err_msg
, "empty secret key");
904 return -ERR_INVALID_SECRET_KEY
;
907 key
= op_state
.get_secret_key();
909 char secret_key_buf
[SECRET_KEY_LEN
+ 1];
911 ret
= gen_rand_alphanumeric_plain(g_ceph_context
, secret_key_buf
, sizeof(secret_key_buf
));
913 set_err_msg(err_msg
, "unable to generate secret key");
917 key
= secret_key_buf
;
920 // Generate the access key
921 if (key_type
== KEY_TYPE_S3
&& gen_access
) {
922 char public_id_buf
[PUBLIC_ID_LEN
+ 1];
925 int id_buf_size
= sizeof(public_id_buf
);
926 ret
= gen_rand_alphanumeric_upper(g_ceph_context
,
927 public_id_buf
, id_buf_size
);
930 set_err_msg(err_msg
, "unable to generate access key");
935 if (!validate_access_key(id
))
938 } while (!rgw_get_user_info_by_access_key(store
, id
, duplicate_check
));
941 if (key_type
== KEY_TYPE_SWIFT
) {
942 id
= op_state
.build_default_swift_kid();
944 set_err_msg(err_msg
, "empty swift access key");
945 return -ERR_INVALID_ACCESS_KEY
;
948 // check that the access key doesn't exist
949 if (rgw_get_user_info_by_swift(store
, id
, duplicate_check
) >= 0) {
950 set_err_msg(err_msg
, "cannot create existing swift key");
951 return -ERR_KEY_EXIST
;
955 // finally create the new key
960 key_pair
.second
= new_key
;
962 if (key_type
== KEY_TYPE_S3
) {
963 access_keys
->insert(key_pair
);
964 } else if (key_type
== KEY_TYPE_SWIFT
) {
965 swift_keys
->insert(key_pair
);
971 // modify an existing key
972 int RGWAccessKeyPool::modify_key(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
975 std::string key
= op_state
.get_secret_key();
976 int key_type
= op_state
.get_key_type();
978 RGWAccessKey modify_key
;
980 pair
<string
, RGWAccessKey
> key_pair
;
981 map
<std::string
, RGWAccessKey
>::iterator kiter
;
985 id
= op_state
.get_access_key();
987 set_err_msg(err_msg
, "no access key specified");
988 return -ERR_INVALID_ACCESS_KEY
;
992 id
= op_state
.build_default_swift_kid();
994 set_err_msg(err_msg
, "no subuser specified");
999 set_err_msg(err_msg
, "invalid key type");
1000 return -ERR_INVALID_KEY_TYPE
;
1003 if (!op_state
.has_existing_key()) {
1004 set_err_msg(err_msg
, "key does not exist");
1005 return -ERR_INVALID_ACCESS_KEY
;
1008 key_pair
.first
= id
;
1010 if (key_type
== KEY_TYPE_SWIFT
) {
1012 modify_key
.subuser
= op_state
.get_subuser();
1013 } else if (key_type
== KEY_TYPE_S3
) {
1014 kiter
= access_keys
->find(id
);
1015 if (kiter
!= access_keys
->end()) {
1016 modify_key
= kiter
->second
;
1020 if (op_state
.will_gen_secret()) {
1021 char secret_key_buf
[SECRET_KEY_LEN
+ 1];
1024 int key_buf_size
= sizeof(secret_key_buf
);
1025 ret
= gen_rand_alphanumeric_plain(g_ceph_context
, secret_key_buf
, key_buf_size
);
1027 set_err_msg(err_msg
, "unable to generate secret key");
1031 key
= secret_key_buf
;
1035 set_err_msg(err_msg
, "empty secret key");
1036 return -ERR_INVALID_SECRET_KEY
;
1039 // update the access key with the new secret key
1040 modify_key
.key
= key
;
1042 key_pair
.second
= modify_key
;
1045 if (key_type
== KEY_TYPE_S3
) {
1046 (*access_keys
)[id
] = modify_key
;
1047 } else if (key_type
== KEY_TYPE_SWIFT
) {
1048 (*swift_keys
)[id
] = modify_key
;
1054 int RGWAccessKeyPool::execute_add(RGWUserAdminOpState
& op_state
,
1055 std::string
*err_msg
, bool defer_user_update
)
1059 std::string subprocess_msg
;
1060 int key_op
= GENERATE_KEY
;
1063 if (op_state
.has_existing_key())
1064 key_op
= MODIFY_KEY
;
1068 ret
= generate_key(op_state
, &subprocess_msg
);
1071 ret
= modify_key(op_state
, &subprocess_msg
);
1076 set_err_msg(err_msg
, subprocess_msg
);
1080 // store the updated info
1081 if (!defer_user_update
)
1082 ret
= user
->update(op_state
, err_msg
);
1090 int RGWAccessKeyPool::add(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1092 return add(op_state
, err_msg
, false);
1095 int RGWAccessKeyPool::add(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_user_update
)
1098 std::string subprocess_msg
;
1100 ret
= check_op(op_state
, &subprocess_msg
);
1102 set_err_msg(err_msg
, "unable to parse request, " + subprocess_msg
);
1106 ret
= execute_add(op_state
, &subprocess_msg
, defer_user_update
);
1108 set_err_msg(err_msg
, "unable to add access key, " + subprocess_msg
);
1115 int RGWAccessKeyPool::execute_remove(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_user_update
)
1119 int key_type
= op_state
.get_key_type();
1120 std::string id
= op_state
.get_access_key();
1121 map
<std::string
, RGWAccessKey
>::iterator kiter
;
1122 map
<std::string
, RGWAccessKey
> *keys_map
;
1124 if (!op_state
.has_existing_key()) {
1125 set_err_msg(err_msg
, "unable to find access key");
1126 return -ERR_INVALID_ACCESS_KEY
;
1129 if (key_type
== KEY_TYPE_S3
) {
1130 keys_map
= access_keys
;
1131 } else if (key_type
== KEY_TYPE_SWIFT
) {
1132 keys_map
= swift_keys
;
1135 set_err_msg(err_msg
, "invalid access key");
1136 return -ERR_INVALID_ACCESS_KEY
;
1139 kiter
= keys_map
->find(id
);
1140 if (kiter
== keys_map
->end()) {
1141 set_err_msg(err_msg
, "key not found");
1142 return -ERR_INVALID_ACCESS_KEY
;
1145 rgw_remove_key_index(store
, kiter
->second
);
1146 keys_map
->erase(kiter
);
1148 if (!defer_user_update
)
1149 ret
= user
->update(op_state
, err_msg
);
1157 int RGWAccessKeyPool::remove(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1159 return remove(op_state
, err_msg
, false);
1162 int RGWAccessKeyPool::remove(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_user_update
)
1166 std::string subprocess_msg
;
1168 ret
= check_op(op_state
, &subprocess_msg
);
1170 set_err_msg(err_msg
, "unable to parse request, " + subprocess_msg
);
1174 ret
= execute_remove(op_state
, &subprocess_msg
, defer_user_update
);
1176 set_err_msg(err_msg
, "unable to remove access key, " + subprocess_msg
);
1183 // remove all keys associated with a subuser
1184 int RGWAccessKeyPool::remove_subuser_keys(RGWUserAdminOpState
& op_state
,
1185 std::string
*err_msg
, bool defer_user_update
)
1189 if (!op_state
.is_populated()) {
1190 set_err_msg(err_msg
, "user info was not populated");
1194 if (!op_state
.has_subuser()) {
1195 set_err_msg(err_msg
, "no subuser specified");
1199 std::string swift_kid
= op_state
.build_default_swift_kid();
1200 if (swift_kid
.empty()) {
1201 set_err_msg(err_msg
, "empty swift access key");
1205 map
<std::string
, RGWAccessKey
>::iterator kiter
;
1206 map
<std::string
, RGWAccessKey
> *keys_map
;
1208 // a subuser can have at most one swift key
1209 keys_map
= swift_keys
;
1210 kiter
= keys_map
->find(swift_kid
);
1211 if (kiter
!= keys_map
->end()) {
1212 rgw_remove_key_index(store
, kiter
->second
);
1213 keys_map
->erase(kiter
);
1216 // a subuser may have multiple s3 key pairs
1217 std::string subuser_str
= op_state
.get_subuser();
1218 keys_map
= access_keys
;
1219 RGWUserInfo user_info
= op_state
.get_user_info();
1220 map
<std::string
, RGWAccessKey
>::iterator user_kiter
= user_info
.access_keys
.begin();
1221 for (; user_kiter
!= user_info
.access_keys
.end(); ++user_kiter
) {
1222 if (user_kiter
->second
.subuser
== subuser_str
) {
1223 kiter
= keys_map
->find(user_kiter
->first
);
1224 if (kiter
!= keys_map
->end()) {
1225 rgw_remove_key_index(store
, kiter
->second
);
1226 keys_map
->erase(kiter
);
1231 if (!defer_user_update
)
1232 ret
= user
->update(op_state
, err_msg
);
1240 RGWSubUserPool::RGWSubUserPool(RGWUser
*usr
)
1242 subusers_allowed
= (usr
!= NULL
);
1244 store
= usr
->get_store();
1251 RGWSubUserPool::~RGWSubUserPool()
1256 int RGWSubUserPool::init(RGWUserAdminOpState
& op_state
)
1258 if (!op_state
.is_initialized()) {
1259 subusers_allowed
= false;
1263 rgw_user
& uid
= op_state
.get_user_id();
1264 if (uid
.compare(RGW_USER_ANON_ID
) == 0) {
1265 subusers_allowed
= false;
1269 subuser_map
= op_state
.get_subusers();
1270 if (subuser_map
== NULL
) {
1271 subusers_allowed
= false;
1275 subusers_allowed
= true;
1280 bool RGWSubUserPool::exists(std::string subuser
)
1282 if (subuser
.empty())
1288 if (subuser_map
->count(subuser
))
1294 int RGWSubUserPool::check_op(RGWUserAdminOpState
& op_state
,
1295 std::string
*err_msg
)
1297 bool existing
= false;
1298 std::string subuser
= op_state
.get_subuser();
1300 if (!op_state
.is_populated()) {
1301 set_err_msg(err_msg
, "user info was not populated");
1305 if (!subusers_allowed
) {
1306 set_err_msg(err_msg
, "subusers not allowed for this user");
1310 if (subuser
.empty() && !op_state
.will_gen_subuser()) {
1311 set_err_msg(err_msg
, "empty subuser name");
1315 if (op_state
.get_subuser_perm() == RGW_PERM_INVALID
) {
1316 set_err_msg(err_msg
, "invaild subuser access");
1320 //set key type when it not set or set by context
1321 if ((op_state
.get_key_type() < 0) || op_state
.key_type_setbycontext
) {
1322 op_state
.set_key_type(KEY_TYPE_SWIFT
);
1323 op_state
.key_type_setbycontext
= true;
1326 // check if the subuser exists
1327 if (!subuser
.empty())
1328 existing
= exists(subuser
);
1330 op_state
.set_existing_subuser(existing
);
1335 int RGWSubUserPool::execute_add(RGWUserAdminOpState
& op_state
,
1336 std::string
*err_msg
, bool defer_user_update
)
1339 std::string subprocess_msg
;
1342 std::pair
<std::string
, RGWSubUser
> subuser_pair
;
1343 std::string subuser_str
= op_state
.get_subuser();
1345 subuser_pair
.first
= subuser_str
;
1347 // assumes key should be created
1348 if (op_state
.has_key_op()) {
1349 ret
= user
->keys
.add(op_state
, &subprocess_msg
, true);
1351 set_err_msg(err_msg
, "unable to create subuser key, " + subprocess_msg
);
1356 // create the subuser
1357 subuser
.name
= subuser_str
;
1359 if (op_state
.has_subuser_perm())
1360 subuser
.perm_mask
= op_state
.get_subuser_perm();
1362 // insert the subuser into user info
1363 subuser_pair
.second
= subuser
;
1364 subuser_map
->insert(subuser_pair
);
1366 // attempt to save the subuser
1367 if (!defer_user_update
)
1368 ret
= user
->update(op_state
, err_msg
);
1376 int RGWSubUserPool::add(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1378 return add(op_state
, err_msg
, false);
1381 int RGWSubUserPool::add(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_user_update
)
1383 std::string subprocess_msg
;
1385 int32_t key_type
= op_state
.get_key_type();
1387 ret
= check_op(op_state
, &subprocess_msg
);
1389 set_err_msg(err_msg
, "unable to parse request, " + subprocess_msg
);
1393 if (key_type
== KEY_TYPE_S3
&& op_state
.get_access_key().empty()) {
1394 op_state
.set_gen_access();
1397 if (op_state
.get_secret_key().empty()) {
1398 op_state
.set_gen_secret();
1401 ret
= execute_add(op_state
, &subprocess_msg
, defer_user_update
);
1403 set_err_msg(err_msg
, "unable to create subuser, " + subprocess_msg
);
1410 int RGWSubUserPool::execute_remove(RGWUserAdminOpState
& op_state
,
1411 std::string
*err_msg
, bool defer_user_update
)
1414 std::string subprocess_msg
;
1416 std::string subuser_str
= op_state
.get_subuser();
1418 map
<std::string
, RGWSubUser
>::iterator siter
;
1419 siter
= subuser_map
->find(subuser_str
);
1420 if (siter
== subuser_map
->end()){
1421 set_err_msg(err_msg
, "subuser not found: " + subuser_str
);
1422 return -ERR_NO_SUCH_SUBUSER
;
1424 if (!op_state
.has_existing_subuser()) {
1425 set_err_msg(err_msg
, "subuser not found: " + subuser_str
);
1426 return -ERR_NO_SUCH_SUBUSER
;
1429 // always purge all associate keys
1430 user
->keys
.remove_subuser_keys(op_state
, &subprocess_msg
, true);
1432 // remove the subuser from the user info
1433 subuser_map
->erase(siter
);
1435 // attempt to save the subuser
1436 if (!defer_user_update
)
1437 ret
= user
->update(op_state
, err_msg
);
1445 int RGWSubUserPool::remove(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1447 return remove(op_state
, err_msg
, false);
1450 int RGWSubUserPool::remove(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_user_update
)
1452 std::string subprocess_msg
;
1455 ret
= check_op(op_state
, &subprocess_msg
);
1457 set_err_msg(err_msg
, "unable to parse request, " + subprocess_msg
);
1461 ret
= execute_remove(op_state
, &subprocess_msg
, defer_user_update
);
1463 set_err_msg(err_msg
, "unable to remove subuser, " + subprocess_msg
);
1470 int RGWSubUserPool::execute_modify(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_user_update
)
1473 std::string subprocess_msg
;
1474 std::map
<std::string
, RGWSubUser
>::iterator siter
;
1475 std::pair
<std::string
, RGWSubUser
> subuser_pair
;
1477 std::string subuser_str
= op_state
.get_subuser();
1480 if (!op_state
.has_existing_subuser()) {
1481 set_err_msg(err_msg
, "subuser does not exist");
1482 return -ERR_NO_SUCH_SUBUSER
;
1485 subuser_pair
.first
= subuser_str
;
1487 siter
= subuser_map
->find(subuser_str
);
1488 subuser
= siter
->second
;
1490 if (op_state
.has_key_op()) {
1491 ret
= user
->keys
.add(op_state
, &subprocess_msg
, true);
1493 set_err_msg(err_msg
, "unable to create subuser keys, " + subprocess_msg
);
1498 if (op_state
.has_subuser_perm())
1499 subuser
.perm_mask
= op_state
.get_subuser_perm();
1501 subuser_pair
.second
= subuser
;
1503 subuser_map
->erase(siter
);
1504 subuser_map
->insert(subuser_pair
);
1506 // attempt to save the subuser
1507 if (!defer_user_update
)
1508 ret
= user
->update(op_state
, err_msg
);
1516 int RGWSubUserPool::modify(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1518 return RGWSubUserPool::modify(op_state
, err_msg
, false);
1521 int RGWSubUserPool::modify(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_user_update
)
1523 std::string subprocess_msg
;
1528 ret
= check_op(op_state
, &subprocess_msg
);
1530 set_err_msg(err_msg
, "unable to parse request, " + subprocess_msg
);
1534 ret
= execute_modify(op_state
, &subprocess_msg
, defer_user_update
);
1536 set_err_msg(err_msg
, "unable to modify subuser, " + subprocess_msg
);
1543 RGWUserCapPool::RGWUserCapPool(RGWUser
*usr
)
1547 caps_allowed
= (user
!= NULL
);
1550 RGWUserCapPool::~RGWUserCapPool()
1555 int RGWUserCapPool::init(RGWUserAdminOpState
& op_state
)
1557 if (!op_state
.is_initialized()) {
1558 caps_allowed
= false;
1562 rgw_user
& uid
= op_state
.get_user_id();
1563 if (uid
.compare(RGW_USER_ANON_ID
) == 0) {
1564 caps_allowed
= false;
1568 caps
= op_state
.get_caps_obj();
1570 caps_allowed
= false;
1571 return -ERR_INVALID_CAP
;
1574 caps_allowed
= true;
1579 int RGWUserCapPool::add(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1581 return add(op_state
, err_msg
, false);
1584 int RGWUserCapPool::add(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_save
)
1587 std::string caps_str
= op_state
.get_caps();
1589 if (!op_state
.is_populated()) {
1590 set_err_msg(err_msg
, "user info was not populated");
1594 if (!caps_allowed
) {
1595 set_err_msg(err_msg
, "caps not allowed for this user");
1599 if (caps_str
.empty()) {
1600 set_err_msg(err_msg
, "empty user caps");
1601 return -ERR_INVALID_CAP
;
1604 int r
= caps
->add_from_string(caps_str
);
1606 set_err_msg(err_msg
, "unable to add caps: " + caps_str
);
1611 ret
= user
->update(op_state
, err_msg
);
1619 int RGWUserCapPool::remove(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1621 return remove(op_state
, err_msg
, false);
1624 int RGWUserCapPool::remove(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_save
)
1628 std::string caps_str
= op_state
.get_caps();
1630 if (!op_state
.is_populated()) {
1631 set_err_msg(err_msg
, "user info was not populated");
1635 if (!caps_allowed
) {
1636 set_err_msg(err_msg
, "caps not allowed for this user");
1640 if (caps_str
.empty()) {
1641 set_err_msg(err_msg
, "empty user caps");
1642 return -ERR_INVALID_CAP
;
1645 int r
= caps
->remove_from_string(caps_str
);
1647 set_err_msg(err_msg
, "unable to remove caps: " + caps_str
);
1652 ret
= user
->update(op_state
, err_msg
);
1660 RGWUser::RGWUser() : store(NULL
), info_stored(false), caps(this), keys(this), subusers(this)
1665 int RGWUser::init(RGWRados
*storage
, RGWUserAdminOpState
& op_state
)
1668 int ret
= init_storage(storage
);
1672 ret
= init(op_state
);
1683 void RGWUser::init_default()
1685 // use anonymous user info as a placeholder
1686 rgw_get_anon_user(old_info
);
1687 user_id
= RGW_USER_ANON_ID
;
1692 int RGWUser::init_storage(RGWRados
*storage
)
1703 keys
= RGWAccessKeyPool(this);
1704 caps
= RGWUserCapPool(this);
1705 subusers
= RGWSubUserPool(this);
1710 int RGWUser::init(RGWUserAdminOpState
& op_state
)
1713 std::string swift_user
;
1714 rgw_user
& uid
= op_state
.get_user_id();
1715 std::string user_email
= op_state
.get_user_email();
1716 std::string access_key
= op_state
.get_access_key();
1717 std::string subuser
= op_state
.get_subuser();
1719 int key_type
= op_state
.get_key_type();
1720 if (key_type
== KEY_TYPE_SWIFT
) {
1721 swift_user
= op_state
.get_access_key();
1725 RGWUserInfo user_info
;
1729 if (uid
.empty() && !subuser
.empty()) {
1730 size_t pos
= subuser
.find(':');
1731 if (pos
!= string::npos
) {
1732 uid
= subuser
.substr(0, pos
);
1733 op_state
.set_user_id(uid
);
1737 if (!uid
.empty() && (uid
.compare(RGW_USER_ANON_ID
) != 0)) {
1738 found
= (rgw_get_user_info_by_uid(store
, uid
, user_info
, &op_state
.objv
) >= 0);
1739 op_state
.found_by_uid
= found
;
1741 if (!user_email
.empty() && !found
) {
1742 found
= (rgw_get_user_info_by_email(store
, user_email
, user_info
, &op_state
.objv
) >= 0);
1743 op_state
.found_by_email
= found
;
1745 if (!swift_user
.empty() && !found
) {
1746 found
= (rgw_get_user_info_by_swift(store
, swift_user
, user_info
, &op_state
.objv
) >= 0);
1747 op_state
.found_by_key
= found
;
1749 if (!access_key
.empty() && !found
) {
1750 found
= (rgw_get_user_info_by_access_key(store
, access_key
, user_info
, &op_state
.objv
) >= 0);
1751 op_state
.found_by_key
= found
;
1754 op_state
.set_existing_user(found
);
1756 op_state
.set_user_info(user_info
);
1757 op_state
.set_populated();
1759 old_info
= user_info
;
1763 user_id
= user_info
.user_id
;
1764 op_state
.set_initialized();
1766 // this may have been called by a helper object
1767 int ret
= init_members(op_state
);
1774 int RGWUser::init_members(RGWUserAdminOpState
& op_state
)
1778 ret
= keys
.init(op_state
);
1782 ret
= subusers
.init(op_state
);
1786 ret
= caps
.init(op_state
);
1793 int RGWUser::update(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1796 std::string subprocess_msg
;
1797 RGWUserInfo user_info
= op_state
.get_user_info();
1800 set_err_msg(err_msg
, "couldn't initialize storage");
1804 if (is_populated()) {
1805 ret
= rgw_store_user_info(store
, user_info
, &old_info
, &op_state
.objv
, real_time(), false);
1807 set_err_msg(err_msg
, "unable to store user info");
1811 ret
= remove_old_indexes(store
, old_info
, user_info
, &subprocess_msg
);
1813 set_err_msg(err_msg
, "unable to remove old user info, " + subprocess_msg
);
1817 ret
= rgw_store_user_info(store
, user_info
, NULL
, &op_state
.objv
, real_time(), false);
1819 set_err_msg(err_msg
, "unable to store user info");
1824 old_info
= user_info
;
1830 int RGWUser::check_op(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1834 rgw_user
& op_id
= op_state
.get_user_id();
1836 RGWUserInfo user_info
;
1838 same_id
= (user_id
.compare(op_id
) == 0);
1839 populated
= is_populated();
1841 if (op_id
.compare(RGW_USER_ANON_ID
) == 0) {
1842 set_err_msg(err_msg
, "unable to perform operations on the anonymous user");
1846 if (populated
&& !same_id
) {
1847 set_err_msg(err_msg
, "user id mismatch, operation id: " + op_id
.to_str()
1848 + " does not match: " + user_id
.to_str());
1853 //set key type when it not set or set by context
1854 if ((op_state
.get_key_type() < 0) || op_state
.key_type_setbycontext
) {
1855 op_state
.set_key_type(KEY_TYPE_S3
);
1856 op_state
.key_type_setbycontext
= true;
1862 int RGWUser::execute_add(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1864 std::string subprocess_msg
;
1866 bool defer_user_update
= true;
1868 RGWUserInfo user_info
;
1870 rgw_user
& uid
= op_state
.get_user_id();
1871 std::string user_email
= op_state
.get_user_email();
1872 std::string display_name
= op_state
.get_display_name();
1874 // fail if the user exists already
1875 if (op_state
.has_existing_user()) {
1876 if (!op_state
.exclusive
&&
1877 (user_email
.empty() ||
1878 boost::iequals(user_email
, old_info
.user_email
)) &&
1879 old_info
.display_name
== display_name
) {
1880 return execute_modify(op_state
, err_msg
);
1883 if (op_state
.found_by_email
) {
1884 set_err_msg(err_msg
, "email: " + user_email
+
1885 " is the email address an existing user");
1886 ret
= -ERR_EMAIL_EXIST
;
1887 } else if (op_state
.found_by_key
) {
1888 set_err_msg(err_msg
, "duplicate key provided");
1889 ret
= -ERR_KEY_EXIST
;
1891 set_err_msg(err_msg
, "user: " + op_state
.user_id
.to_str() + " exists");
1897 // fail if the user_info has already been populated
1898 if (op_state
.is_populated()) {
1899 set_err_msg(err_msg
, "cannot overwrite already populated user");
1903 // fail if the display name was not included
1904 if (display_name
.empty()) {
1905 set_err_msg(err_msg
, "no display name specified");
1910 // set the user info
1912 user_info
.user_id
= user_id
;
1913 user_info
.display_name
= display_name
;
1914 user_info
.type
= TYPE_RGW
;
1916 if (!user_email
.empty())
1917 user_info
.user_email
= user_email
;
1919 CephContext
*cct
= store
->ctx();
1920 if (op_state
.max_buckets_specified
) {
1921 user_info
.max_buckets
= op_state
.get_max_buckets();
1923 user_info
.max_buckets
= cct
->_conf
->rgw_user_max_buckets
;
1926 user_info
.suspended
= op_state
.get_suspension_status();
1927 user_info
.admin
= op_state
.admin
;
1928 user_info
.system
= op_state
.system
;
1930 if (op_state
.op_mask_specified
)
1931 user_info
.op_mask
= op_state
.get_op_mask();
1933 if (op_state
.has_bucket_quota()) {
1934 user_info
.bucket_quota
= op_state
.get_bucket_quota();
1936 if (cct
->_conf
->rgw_bucket_default_quota_max_objects
>= 0) {
1937 user_info
.bucket_quota
.max_objects
= cct
->_conf
->rgw_bucket_default_quota_max_objects
;
1938 user_info
.bucket_quota
.enabled
= true;
1940 if (cct
->_conf
->rgw_bucket_default_quota_max_size
>= 0) {
1941 user_info
.bucket_quota
.max_size
= cct
->_conf
->rgw_bucket_default_quota_max_size
;
1942 user_info
.bucket_quota
.enabled
= true;
1946 if (op_state
.temp_url_key_specified
) {
1947 map
<int, string
>::iterator iter
;
1948 for (iter
= op_state
.temp_url_keys
.begin();
1949 iter
!= op_state
.temp_url_keys
.end(); ++iter
) {
1950 user_info
.temp_url_keys
[iter
->first
] = iter
->second
;
1954 if (op_state
.has_user_quota()) {
1955 user_info
.user_quota
= op_state
.get_user_quota();
1957 if (cct
->_conf
->rgw_user_default_quota_max_objects
>= 0) {
1958 user_info
.user_quota
.max_objects
= cct
->_conf
->rgw_user_default_quota_max_objects
;
1959 user_info
.user_quota
.enabled
= true;
1961 if (cct
->_conf
->rgw_user_default_quota_max_size
>= 0) {
1962 user_info
.user_quota
.max_size
= cct
->_conf
->rgw_user_default_quota_max_size
;
1963 user_info
.user_quota
.enabled
= true;
1967 // update the request
1968 op_state
.set_user_info(user_info
);
1969 op_state
.set_populated();
1971 // update the helper objects
1972 ret
= init_members(op_state
);
1974 set_err_msg(err_msg
, "unable to initialize user");
1978 // see if we need to add an access key
1979 if (op_state
.has_key_op()) {
1980 ret
= keys
.add(op_state
, &subprocess_msg
, defer_user_update
);
1982 set_err_msg(err_msg
, "unable to create access key, " + subprocess_msg
);
1987 // see if we need to add some caps
1988 if (op_state
.has_caps_op()) {
1989 ret
= caps
.add(op_state
, &subprocess_msg
, defer_user_update
);
1991 set_err_msg(err_msg
, "unable to add user capabilities, " + subprocess_msg
);
1996 ret
= update(op_state
, err_msg
);
2003 int RGWUser::add(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
2005 std::string subprocess_msg
;
2008 ret
= check_op(op_state
, &subprocess_msg
);
2010 set_err_msg(err_msg
, "unable to parse parameters, " + subprocess_msg
);
2014 ret
= execute_add(op_state
, &subprocess_msg
);
2016 set_err_msg(err_msg
, "unable to create user, " + subprocess_msg
);
2023 int RGWUser::execute_remove(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
2027 bool purge_data
= op_state
.will_purge_data();
2028 rgw_user
& uid
= op_state
.get_user_id();
2029 RGWUserInfo user_info
= op_state
.get_user_info();
2031 if (!op_state
.has_existing_user()) {
2032 set_err_msg(err_msg
, "user does not exist");
2036 bool is_truncated
= false;
2038 CephContext
*cct
= store
->ctx();
2039 size_t max_buckets
= cct
->_conf
->rgw_list_buckets_max_chunk
;
2041 RGWUserBuckets buckets
;
2042 ret
= rgw_read_user_buckets(store
, uid
, buckets
, marker
, string(),
2043 max_buckets
, false, &is_truncated
);
2045 set_err_msg(err_msg
, "unable to read user bucket info");
2049 map
<std::string
, RGWBucketEnt
>& m
= buckets
.get_buckets();
2050 if (!m
.empty() && !purge_data
) {
2051 set_err_msg(err_msg
, "must specify purge data to remove user with buckets");
2052 return -EEXIST
; // change to code that maps to 409: conflict
2055 std::map
<std::string
, RGWBucketEnt
>::iterator it
;
2056 for (it
= m
.begin(); it
!= m
.end(); ++it
) {
2057 ret
= rgw_remove_bucket(store
, ((*it
).second
).bucket
, true);
2059 set_err_msg(err_msg
, "unable to delete user data");
2066 } while (is_truncated
);
2068 ret
= rgw_delete_user(store
, user_info
, op_state
.objv
);
2070 set_err_msg(err_msg
, "unable to remove user from RADOS");
2074 op_state
.clear_populated();
2080 int RGWUser::remove(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
2082 std::string subprocess_msg
;
2085 ret
= check_op(op_state
, &subprocess_msg
);
2087 set_err_msg(err_msg
, "unable to parse parameters, " + subprocess_msg
);
2091 ret
= execute_remove(op_state
, &subprocess_msg
);
2093 set_err_msg(err_msg
, "unable to remove user, " + subprocess_msg
);
2100 int RGWUser::execute_modify(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
2102 bool populated
= op_state
.is_populated();
2104 std::string subprocess_msg
;
2105 std::string op_email
= op_state
.get_user_email();
2106 std::string display_name
= op_state
.get_display_name();
2108 RGWUserInfo user_info
;
2109 RGWUserInfo duplicate_check
;
2111 // ensure that the user info has been populated or is populate-able
2112 if (!op_state
.has_existing_user() && !populated
) {
2113 set_err_msg(err_msg
, "user not found");
2117 // if the user hasn't already been populated...attempt to
2119 ret
= init(op_state
);
2121 set_err_msg(err_msg
, "unable to retrieve user info");
2126 // ensure that we can modify the user's attributes
2127 if (user_id
.compare(RGW_USER_ANON_ID
) == 0) {
2128 set_err_msg(err_msg
, "unable to modify anonymous user's info");
2132 user_info
= old_info
;
2134 std::string old_email
= old_info
.user_email
;
2135 if (!op_email
.empty()) {
2136 // make sure we are not adding a duplicate email
2137 if (old_email
.compare(op_email
) != 0) {
2138 ret
= rgw_get_user_info_by_email(store
, op_email
, duplicate_check
);
2139 if (ret
>= 0 && duplicate_check
.user_id
.compare(user_id
) != 0) {
2140 set_err_msg(err_msg
, "cannot add duplicate email");
2141 return -ERR_EMAIL_EXIST
;
2144 user_info
.user_email
= op_email
;
2145 } else if (op_email
.empty() && op_state
.user_email_specified
) {
2147 ldout(store
->ctx(), 10) << "removing email index: " << user_info
.user_email
<< dendl
;
2148 ret
= rgw_remove_email_index(store
, user_info
.user_email
);
2149 if (ret
< 0 && ret
!= -ENOENT
) {
2150 ldout(store
->ctx(), 0) << "ERROR: could not remove " << user_info
.user_id
<< " index (err=" << ret
<< ")" << dendl
;
2153 user_info
.user_email
= "";
2156 // update the remaining user info
2157 if (!display_name
.empty())
2158 user_info
.display_name
= display_name
;
2160 if (op_state
.max_buckets_specified
)
2161 user_info
.max_buckets
= op_state
.get_max_buckets();
2163 if (op_state
.admin_specified
)
2164 user_info
.admin
= op_state
.admin
;
2166 if (op_state
.system_specified
)
2167 user_info
.system
= op_state
.system
;
2169 if (op_state
.temp_url_key_specified
) {
2170 map
<int, string
>::iterator iter
;
2171 for (iter
= op_state
.temp_url_keys
.begin();
2172 iter
!= op_state
.temp_url_keys
.end(); ++iter
) {
2173 user_info
.temp_url_keys
[iter
->first
] = iter
->second
;
2177 if (op_state
.op_mask_specified
)
2178 user_info
.op_mask
= op_state
.get_op_mask();
2180 if (op_state
.has_bucket_quota())
2181 user_info
.bucket_quota
= op_state
.get_bucket_quota();
2183 if (op_state
.has_user_quota())
2184 user_info
.user_quota
= op_state
.get_user_quota();
2186 if (op_state
.has_suspension_op()) {
2187 __u8 suspended
= op_state
.get_suspension_status();
2188 user_info
.suspended
= suspended
;
2190 RGWUserBuckets buckets
;
2192 if (user_id
.empty()) {
2193 set_err_msg(err_msg
, "empty user id passed...aborting");
2197 bool is_truncated
= false;
2199 CephContext
*cct
= store
->ctx();
2200 size_t max_buckets
= cct
->_conf
->rgw_list_buckets_max_chunk
;
2202 ret
= rgw_read_user_buckets(store
, user_id
, buckets
, marker
, string(),
2203 max_buckets
, false, &is_truncated
);
2205 set_err_msg(err_msg
, "could not get buckets for uid: " + user_id
.to_str());
2209 map
<string
, RGWBucketEnt
>& m
= buckets
.get_buckets();
2210 map
<string
, RGWBucketEnt
>::iterator iter
;
2212 vector
<rgw_bucket
> bucket_names
;
2213 for (iter
= m
.begin(); iter
!= m
.end(); ++iter
) {
2214 RGWBucketEnt obj
= iter
->second
;
2215 bucket_names
.push_back(obj
.bucket
);
2217 marker
= iter
->first
;
2220 ret
= store
->set_buckets_enabled(bucket_names
, !suspended
);
2222 set_err_msg(err_msg
, "failed to modify bucket");
2226 } while (is_truncated
);
2228 op_state
.set_user_info(user_info
);
2230 // if we're supposed to modify keys, do so
2231 if (op_state
.has_key_op()) {
2232 ret
= keys
.add(op_state
, &subprocess_msg
, true);
2234 set_err_msg(err_msg
, "unable to create or modify keys, " + subprocess_msg
);
2239 ret
= update(op_state
, err_msg
);
2246 int RGWUser::modify(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
2248 std::string subprocess_msg
;
2251 ret
= check_op(op_state
, &subprocess_msg
);
2253 set_err_msg(err_msg
, "unable to parse parameters, " + subprocess_msg
);
2257 ret
= execute_modify(op_state
, &subprocess_msg
);
2259 set_err_msg(err_msg
, "unable to modify user, " + subprocess_msg
);
2266 int RGWUser::info(RGWUserAdminOpState
& op_state
, RGWUserInfo
& fetched_info
, std::string
*err_msg
)
2268 int ret
= init(op_state
);
2270 set_err_msg(err_msg
, "unable to fetch user info");
2274 fetched_info
= op_state
.get_user_info();
2279 int RGWUser::info(RGWUserInfo
& fetched_info
, std::string
*err_msg
)
2281 if (!is_populated()) {
2282 set_err_msg(err_msg
, "no user info saved");
2286 fetched_info
= old_info
;
2291 int RGWUserAdminOp_User::info(RGWRados
*store
, RGWUserAdminOpState
& op_state
,
2292 RGWFormatterFlusher
& flusher
)
2297 int ret
= user
.init(store
, op_state
);
2301 if (!op_state
.has_existing_user())
2302 return -ERR_NO_SUCH_USER
;
2304 Formatter
*formatter
= flusher
.get_formatter();
2306 ret
= user
.info(info
, NULL
);
2310 RGWStorageStats stats
;
2311 RGWStorageStats
*arg_stats
= NULL
;
2312 if (op_state
.fetch_stats
) {
2313 int ret
= store
->get_user_stats(info
.user_id
, stats
);
2323 dump_user_info(formatter
, info
, arg_stats
);
2329 int RGWUserAdminOp_User::create(RGWRados
*store
, RGWUserAdminOpState
& op_state
,
2330 RGWFormatterFlusher
& flusher
)
2334 int ret
= user
.init(store
, op_state
);
2338 Formatter
*formatter
= flusher
.get_formatter();
2340 ret
= user
.add(op_state
, NULL
);
2343 ret
= -ERR_USER_EXIST
;
2347 ret
= user
.info(info
, NULL
);
2353 dump_user_info(formatter
, info
);
2359 int RGWUserAdminOp_User::modify(RGWRados
*store
, RGWUserAdminOpState
& op_state
,
2360 RGWFormatterFlusher
& flusher
)
2364 int ret
= user
.init(store
, op_state
);
2367 Formatter
*formatter
= flusher
.get_formatter();
2369 ret
= user
.modify(op_state
, NULL
);
2372 ret
= -ERR_NO_SUCH_USER
;
2376 ret
= user
.info(info
, NULL
);
2382 dump_user_info(formatter
, info
);
2388 int RGWUserAdminOp_User::remove(RGWRados
*store
, RGWUserAdminOpState
& op_state
,
2389 RGWFormatterFlusher
& flusher
)
2393 int ret
= user
.init(store
, op_state
);
2398 ret
= user
.remove(op_state
, NULL
);
2401 ret
= -ERR_NO_SUCH_USER
;
2405 int RGWUserAdminOp_Subuser::create(RGWRados
*store
, RGWUserAdminOpState
& op_state
,
2406 RGWFormatterFlusher
& flusher
)
2410 int ret
= user
.init(store
, op_state
);
2414 if (!op_state
.has_existing_user())
2415 return -ERR_NO_SUCH_USER
;
2417 Formatter
*formatter
= flusher
.get_formatter();
2419 ret
= user
.subusers
.add(op_state
, NULL
);
2423 ret
= user
.info(info
, NULL
);
2429 dump_subusers_info(formatter
, info
);
2435 int RGWUserAdminOp_Subuser::modify(RGWRados
*store
, RGWUserAdminOpState
& op_state
,
2436 RGWFormatterFlusher
& flusher
)
2440 int ret
= user
.init(store
, op_state
);
2444 if (!op_state
.has_existing_user())
2445 return -ERR_NO_SUCH_USER
;
2447 Formatter
*formatter
= flusher
.get_formatter();
2449 ret
= user
.subusers
.modify(op_state
, NULL
);
2453 ret
= user
.info(info
, NULL
);
2459 dump_subusers_info(formatter
, info
);
2465 int RGWUserAdminOp_Subuser::remove(RGWRados
*store
, RGWUserAdminOpState
& op_state
,
2466 RGWFormatterFlusher
& flusher
)
2470 int ret
= user
.init(store
, op_state
);
2475 if (!op_state
.has_existing_user())
2476 return -ERR_NO_SUCH_USER
;
2478 ret
= user
.subusers
.remove(op_state
, NULL
);
2485 int RGWUserAdminOp_Key::create(RGWRados
*store
, RGWUserAdminOpState
& op_state
,
2486 RGWFormatterFlusher
& flusher
)
2490 int ret
= user
.init(store
, op_state
);
2494 if (!op_state
.has_existing_user())
2495 return -ERR_NO_SUCH_USER
;
2497 Formatter
*formatter
= flusher
.get_formatter();
2499 ret
= user
.keys
.add(op_state
, NULL
);
2503 ret
= user
.info(info
, NULL
);
2509 int key_type
= op_state
.get_key_type();
2511 if (key_type
== KEY_TYPE_SWIFT
)
2512 dump_swift_keys_info(formatter
, info
);
2514 else if (key_type
== KEY_TYPE_S3
)
2515 dump_access_keys_info(formatter
, info
);
2522 int RGWUserAdminOp_Key::remove(RGWRados
*store
, RGWUserAdminOpState
& op_state
,
2523 RGWFormatterFlusher
& flusher
)
2527 int ret
= user
.init(store
, op_state
);
2531 if (!op_state
.has_existing_user())
2532 return -ERR_NO_SUCH_USER
;
2535 ret
= user
.keys
.remove(op_state
, NULL
);
2542 int RGWUserAdminOp_Caps::add(RGWRados
*store
, RGWUserAdminOpState
& op_state
,
2543 RGWFormatterFlusher
& flusher
)
2547 int ret
= user
.init(store
, op_state
);
2551 if (!op_state
.has_existing_user())
2552 return -ERR_NO_SUCH_USER
;
2554 Formatter
*formatter
= flusher
.get_formatter();
2556 ret
= user
.caps
.add(op_state
, NULL
);
2560 ret
= user
.info(info
, NULL
);
2566 info
.caps
.dump(formatter
);
2573 int RGWUserAdminOp_Caps::remove(RGWRados
*store
, RGWUserAdminOpState
& op_state
,
2574 RGWFormatterFlusher
& flusher
)
2578 int ret
= user
.init(store
, op_state
);
2582 if (!op_state
.has_existing_user())
2583 return -ERR_NO_SUCH_USER
;
2585 Formatter
*formatter
= flusher
.get_formatter();
2587 ret
= user
.caps
.remove(op_state
, NULL
);
2591 ret
= user
.info(info
, NULL
);
2597 info
.caps
.dump(formatter
);
2603 struct RGWUserCompleteInfo
{
2605 map
<string
, bufferlist
> attrs
;
2608 RGWUserCompleteInfo()
2612 void dump(Formatter
* const f
) const {
2614 encode_json("attrs", attrs
, f
);
2617 void decode_json(JSONObj
*obj
) {
2618 decode_json_obj(info
, obj
);
2619 has_attrs
= JSONDecoder::decode_json("attrs", attrs
, obj
);
2623 class RGWUserMetadataObject
: public RGWMetadataObject
{
2624 RGWUserCompleteInfo uci
;
2626 RGWUserMetadataObject(const RGWUserCompleteInfo
& _uci
, obj_version
& v
, real_time m
)
2632 void dump(Formatter
*f
) const override
{
2637 class RGWUserMetadataHandler
: public RGWMetadataHandler
{
2639 string
get_type() override
{ return "user"; }
2641 int get(RGWRados
*store
, string
& entry
, RGWMetadataObject
**obj
) override
{
2642 RGWUserCompleteInfo uci
;
2643 RGWObjVersionTracker objv_tracker
;
2646 rgw_user
uid(entry
);
2648 int ret
= rgw_get_user_info_by_uid(store
, uid
, uci
.info
, &objv_tracker
,
2649 &mtime
, NULL
, &uci
.attrs
);
2654 RGWUserMetadataObject
*mdo
= new RGWUserMetadataObject(uci
, objv_tracker
.read_version
, mtime
);
2660 int put(RGWRados
*store
, string
& entry
, RGWObjVersionTracker
& objv_tracker
,
2661 real_time mtime
, JSONObj
*obj
, sync_type_t sync_mode
) override
{
2662 RGWUserCompleteInfo uci
;
2665 decode_json_obj(uci
, obj
);
2666 } catch (JSONDecoder::err
& e
) {
2670 map
<string
, bufferlist
> *pattrs
= NULL
;
2671 if (uci
.has_attrs
) {
2672 pattrs
= &uci
.attrs
;
2675 rgw_user
uid(entry
);
2677 RGWUserInfo old_info
;
2678 real_time orig_mtime
;
2679 int ret
= rgw_get_user_info_by_uid(store
, uid
, old_info
, &objv_tracker
, &orig_mtime
);
2680 if (ret
< 0 && ret
!= -ENOENT
)
2683 // are we actually going to perform this put, or is it too old?
2684 if (ret
!= -ENOENT
&&
2685 !check_versions(objv_tracker
.read_version
, orig_mtime
,
2686 objv_tracker
.write_version
, mtime
, sync_mode
)) {
2687 return STATUS_NO_APPLY
;
2690 ret
= rgw_store_user_info(store
, uci
.info
, &old_info
, &objv_tracker
, mtime
, false, pattrs
);
2695 return STATUS_APPLIED
;
2698 struct list_keys_info
{
2700 RGWListRawObjsCtx ctx
;
2703 int remove(RGWRados
*store
, string
& entry
, RGWObjVersionTracker
& objv_tracker
) override
{
2706 rgw_user
uid(entry
);
2708 int ret
= rgw_get_user_info_by_uid(store
, uid
, info
, &objv_tracker
);
2712 return rgw_delete_user(store
, info
, objv_tracker
);
2715 void get_pool_and_oid(RGWRados
*store
, const string
& key
, rgw_pool
& pool
, string
& oid
) override
{
2717 pool
= store
->get_zone_params().user_uid_pool
;
2720 int list_keys_init(RGWRados
*store
, void **phandle
) override
2722 list_keys_info
*info
= new list_keys_info
;
2724 info
->store
= store
;
2726 *phandle
= (void *)info
;
2731 int list_keys_next(void *handle
, int max
, list
<string
>& keys
, bool *truncated
) override
{
2732 list_keys_info
*info
= static_cast<list_keys_info
*>(handle
);
2738 RGWRados
*store
= info
->store
;
2740 list
<string
> unfiltered_keys
;
2742 int ret
= store
->list_raw_objects(store
->get_zone_params().user_uid_pool
, no_filter
,
2743 max
, info
->ctx
, unfiltered_keys
, truncated
);
2744 if (ret
< 0 && ret
!= -ENOENT
)
2746 if (ret
== -ENOENT
) {
2752 // now filter out the buckets entries
2753 list
<string
>::iterator iter
;
2754 for (iter
= unfiltered_keys
.begin(); iter
!= unfiltered_keys
.end(); ++iter
) {
2757 if (k
.find(".buckets") == string::npos
) {
2765 void list_keys_complete(void *handle
) override
{
2766 list_keys_info
*info
= static_cast<list_keys_info
*>(handle
);
2771 void rgw_user_init(RGWRados
*store
)
2773 uinfo_cache
.init(store
);
2775 user_meta_handler
= new RGWUserMetadataHandler
;
2776 store
->meta_mgr
->register_handler(user_meta_handler
);