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 "common/backport14.h"
15 #include "rgw_rados.h"
18 #include "include/types.h"
20 #include "rgw_string.h"
22 // until everything is moved from rgw_common
23 #include "rgw_common.h"
25 #include "rgw_bucket.h"
27 #define dout_subsys ceph_subsys_rgw
32 static RGWMetadataHandler
*user_meta_handler
= NULL
;
36 * Get the anonymous (ie, unauthenticated) user info.
38 void rgw_get_anon_user(RGWUserInfo
& info
)
40 info
.user_id
= RGW_USER_ANON_ID
;
41 info
.display_name
.clear();
42 info
.access_keys
.clear();
45 int rgw_user_sync_all_stats(RGWRados
*store
, const rgw_user
& user_id
)
47 CephContext
*cct
= store
->ctx();
48 size_t max_entries
= cct
->_conf
->rgw_list_buckets_max_chunk
;
49 bool is_truncated
= false;
52 RGWObjectCtx
obj_ctx(store
);
55 RGWUserBuckets user_buckets
;
56 ret
= rgw_read_user_buckets(store
, user_id
, user_buckets
, marker
,
57 string(), max_entries
, false, &is_truncated
);
59 ldout(cct
, 0) << "failed to read user buckets: ret=" << ret
<< dendl
;
62 map
<string
, RGWBucketEnt
>& buckets
= user_buckets
.get_buckets();
63 for (map
<string
, RGWBucketEnt
>::iterator i
= buckets
.begin();
68 RGWBucketEnt
& bucket_ent
= i
->second
;
69 RGWBucketInfo bucket_info
;
71 ret
= store
->get_bucket_instance_info(obj_ctx
, bucket_ent
.bucket
, bucket_info
, NULL
, NULL
);
73 ldout(cct
, 0) << "ERROR: could not read bucket info: bucket=" << bucket_ent
.bucket
<< " ret=" << ret
<< dendl
;
76 ret
= rgw_bucket_sync_user_stats(store
, user_id
, bucket_info
);
78 ldout(cct
, 0) << "ERROR: could not sync bucket stats: ret=" << ret
<< dendl
;
81 RGWQuotaInfo bucket_quota
;
82 ret
= store
->check_bucket_shards(bucket_info
, bucket_info
.bucket
, bucket_quota
);
84 ldout(cct
, 0) << "ERROR in check_bucket_shards: " << cpp_strerror(-ret
)<< dendl
;
87 } while (is_truncated
);
89 ret
= store
->complete_sync_user_stats(user_id
);
91 cerr
<< "ERROR: failed to complete syncing user stats: ret=" << ret
<< std::endl
;
98 int rgw_user_get_all_buckets_stats(RGWRados
*store
, const rgw_user
& user_id
, map
<string
, cls_user_bucket_entry
>&buckets_usage_map
)
100 CephContext
*cct
= store
->ctx();
101 size_t max_entries
= cct
->_conf
->rgw_list_buckets_max_chunk
;
108 RGWUserBuckets user_buckets
;
109 ret
= rgw_read_user_buckets(store
, user_id
, user_buckets
, marker
,
110 string(), max_entries
, false, &is_truncated
);
112 ldout(cct
, 0) << "failed to read user buckets: ret=" << ret
<< dendl
;
115 map
<string
, RGWBucketEnt
>& buckets
= user_buckets
.get_buckets();
116 for (const auto& i
: buckets
) {
119 const RGWBucketEnt
& bucket_ent
= i
.second
;
120 cls_user_bucket_entry entry
;
121 ret
= store
->cls_user_get_bucket_stats(bucket_ent
.bucket
, entry
);
123 ldout(cct
, 0) << "ERROR: could not get bucket stats: ret=" << ret
<< dendl
;
126 buckets_usage_map
.emplace(bucket_ent
.bucket
.name
, entry
);
128 done
= (buckets
.size() < max_entries
);
135 * Save the given user information to storage.
136 * Returns: 0 on success, -ERR# on failure.
138 int rgw_store_user_info(RGWRados
*store
,
140 RGWUserInfo
*old_info
,
141 RGWObjVersionTracker
*objv_tracker
,
144 map
<string
, bufferlist
> *pattrs
)
147 RGWObjVersionTracker ot
;
153 if (ot
.write_version
.tag
.empty()) {
154 if (ot
.read_version
.tag
.empty()) {
155 ot
.generate_new_write_ver(store
->ctx());
157 ot
.write_version
= ot
.read_version
;
158 ot
.write_version
.ver
++;
162 map
<string
, RGWAccessKey
>::iterator iter
;
163 for (iter
= info
.swift_keys
.begin(); iter
!= info
.swift_keys
.end(); ++iter
) {
164 if (old_info
&& old_info
->swift_keys
.count(iter
->first
) != 0)
166 RGWAccessKey
& k
= iter
->second
;
167 /* check if swift mapping exists */
169 int r
= rgw_get_user_info_by_swift(store
, k
.id
, inf
);
170 if (r
>= 0 && inf
.user_id
.compare(info
.user_id
) != 0) {
171 ldout(store
->ctx(), 0) << "WARNING: can't store user info, swift id (" << k
.id
172 << ") already mapped to another user (" << info
.user_id
<< ")" << dendl
;
177 if (!info
.access_keys
.empty()) {
178 /* check if access keys already exist */
180 map
<string
, RGWAccessKey
>::iterator iter
= info
.access_keys
.begin();
181 for (; iter
!= info
.access_keys
.end(); ++iter
) {
182 RGWAccessKey
& k
= iter
->second
;
183 if (old_info
&& old_info
->access_keys
.count(iter
->first
) != 0)
185 int r
= rgw_get_user_info_by_access_key(store
, k
.id
, inf
);
186 if (r
>= 0 && inf
.user_id
.compare(info
.user_id
) != 0) {
187 ldout(store
->ctx(), 0) << "WARNING: can't store user info, access key already mapped to another user" << dendl
;
194 ui
.user_id
= info
.user_id
;
197 ::encode(ui
, link_bl
);
200 ::encode(ui
, data_bl
);
201 ::encode(info
, data_bl
);
204 info
.user_id
.to_str(key
);
206 ret
= store
->meta_mgr
->put_entry(user_meta_handler
, key
, data_bl
, exclusive
, &ot
, mtime
, pattrs
);
210 if (!info
.user_email
.empty()) {
212 old_info
->user_email
.compare(info
.user_email
) != 0) { /* only if new index changed */
213 ret
= rgw_put_system_obj(store
, store
->get_zone_params().user_email_pool
, info
.user_email
,
214 link_bl
.c_str(), link_bl
.length(), exclusive
, NULL
, real_time());
220 if (!info
.access_keys
.empty()) {
221 map
<string
, RGWAccessKey
>::iterator iter
= info
.access_keys
.begin();
222 for (; iter
!= info
.access_keys
.end(); ++iter
) {
223 RGWAccessKey
& k
= iter
->second
;
224 if (old_info
&& old_info
->access_keys
.count(iter
->first
) != 0)
227 ret
= rgw_put_system_obj(store
, store
->get_zone_params().user_keys_pool
, k
.id
,
228 link_bl
.c_str(), link_bl
.length(), exclusive
,
235 map
<string
, RGWAccessKey
>::iterator siter
;
236 for (siter
= info
.swift_keys
.begin(); siter
!= info
.swift_keys
.end(); ++siter
) {
237 RGWAccessKey
& k
= siter
->second
;
238 if (old_info
&& old_info
->swift_keys
.count(siter
->first
) != 0)
241 ret
= rgw_put_system_obj(store
, store
->get_zone_params().user_swift_pool
, k
.id
,
242 link_bl
.c_str(), link_bl
.length(), exclusive
,
251 struct user_info_entry
{
253 RGWObjVersionTracker objv_tracker
;
257 static RGWChainedCacheImpl
<user_info_entry
> uinfo_cache
;
259 int rgw_get_user_info_from_index(RGWRados
* const store
,
263 RGWObjVersionTracker
* const objv_tracker
,
264 real_time
* const pmtime
)
267 if (uinfo_cache
.find(key
, &e
)) {
270 *objv_tracker
= e
.objv_tracker
;
278 RGWObjectCtx
obj_ctx(store
);
280 int ret
= rgw_get_system_obj(store
, obj_ctx
, pool
, key
, bl
, NULL
, &e
.mtime
);
284 rgw_cache_entry_info cache_info
;
286 bufferlist::iterator iter
= bl
.begin();
289 int ret
= rgw_get_user_info_by_uid(store
, uid
.user_id
, e
.info
, &e
.objv_tracker
, NULL
, &cache_info
);
293 } catch (buffer::error
& err
) {
294 ldout(store
->ctx(), 0) << "ERROR: failed to decode user info, caught buffer::error" << dendl
;
298 list
<rgw_cache_entry_info
*> cache_info_entries
;
299 cache_info_entries
.push_back(&cache_info
);
301 uinfo_cache
.put(store
, key
, &e
, cache_info_entries
);
305 *objv_tracker
= e
.objv_tracker
;
313 * Given a uid, finds the user info associated with it.
314 * returns: 0 on success, -ERR# on failure (including nonexistence)
316 int rgw_get_user_info_by_uid(RGWRados
*store
,
319 RGWObjVersionTracker
* const objv_tracker
,
320 real_time
* const pmtime
,
321 rgw_cache_entry_info
* const cache_info
,
322 map
<string
, bufferlist
> * const pattrs
)
327 RGWObjectCtx
obj_ctx(store
);
328 string oid
= uid
.to_str();
329 int ret
= rgw_get_system_obj(store
, obj_ctx
, store
->get_zone_params().user_uid_pool
, oid
, bl
, objv_tracker
, pmtime
, pattrs
, cache_info
);
334 bufferlist::iterator iter
= bl
.begin();
336 ::decode(user_id
, iter
);
337 if (user_id
.user_id
.compare(uid
) != 0) {
338 lderr(store
->ctx()) << "ERROR: rgw_get_user_info_by_uid(): user id mismatch: " << user_id
.user_id
<< " != " << uid
<< dendl
;
342 ::decode(info
, iter
);
344 } catch (buffer::error
& err
) {
345 ldout(store
->ctx(), 0) << "ERROR: failed to decode user info, caught buffer::error" << dendl
;
353 * Given an email, finds the user info associated with it.
354 * returns: 0 on success, -ERR# on failure (including nonexistence)
356 int rgw_get_user_info_by_email(RGWRados
*store
, string
& email
, RGWUserInfo
& info
,
357 RGWObjVersionTracker
*objv_tracker
, real_time
*pmtime
)
359 return rgw_get_user_info_from_index(store
, email
, store
->get_zone_params().user_email_pool
, info
, objv_tracker
, pmtime
);
363 * Given an swift username, finds the user_info associated with it.
364 * returns: 0 on success, -ERR# on failure (including nonexistence)
366 extern int rgw_get_user_info_by_swift(RGWRados
* const store
,
367 const string
& swift_name
,
368 RGWUserInfo
& info
, /* out */
369 RGWObjVersionTracker
* const objv_tracker
,
370 real_time
* const pmtime
)
372 return rgw_get_user_info_from_index(store
, swift_name
,
373 store
->get_zone_params().user_swift_pool
,
374 info
, objv_tracker
, pmtime
);
378 * Given an access key, finds the user info associated with it.
379 * returns: 0 on success, -ERR# on failure (including nonexistence)
381 extern int rgw_get_user_info_by_access_key(RGWRados
* store
,
382 const std::string
& access_key
,
384 RGWObjVersionTracker
* objv_tracker
,
387 return rgw_get_user_info_from_index(store
, access_key
,
388 store
->get_zone_params().user_keys_pool
,
389 info
, objv_tracker
, pmtime
);
392 int rgw_get_user_attrs_by_uid(RGWRados
*store
,
393 const rgw_user
& user_id
,
394 map
<string
, bufferlist
>& attrs
,
395 RGWObjVersionTracker
*objv_tracker
)
397 RGWObjectCtx
obj_ctx(store
);
398 rgw_raw_obj
obj(store
->get_zone_params().user_uid_pool
, user_id
.to_str());
399 RGWRados::SystemObject
src(store
, obj_ctx
, obj
);
400 RGWRados::SystemObject::Read
rop(&src
);
402 rop
.stat_params
.attrs
= &attrs
;
403 return rop
.stat(objv_tracker
);
406 int rgw_remove_key_index(RGWRados
*store
, RGWAccessKey
& access_key
)
408 rgw_raw_obj
obj(store
->get_zone_params().user_keys_pool
, access_key
.id
);
409 int ret
= store
->delete_system_obj(obj
);
413 int rgw_remove_uid_index(RGWRados
*store
, rgw_user
& uid
)
415 RGWObjVersionTracker objv_tracker
;
417 int ret
= rgw_get_user_info_by_uid(store
, uid
, info
, &objv_tracker
, NULL
);
421 string oid
= uid
.to_str();
422 ret
= store
->meta_mgr
->remove_entry(user_meta_handler
, oid
, &objv_tracker
);
429 int rgw_remove_email_index(RGWRados
*store
, string
& email
)
434 rgw_raw_obj
obj(store
->get_zone_params().user_email_pool
, email
);
435 return store
->delete_system_obj(obj
);
438 int rgw_remove_swift_name_index(RGWRados
*store
, string
& swift_name
)
440 rgw_raw_obj
obj(store
->get_zone_params().user_swift_pool
, swift_name
);
441 int ret
= store
->delete_system_obj(obj
);
446 * delete a user's presence from the RGW system.
447 * First remove their bucket ACLs, then delete them
448 * from the user and user email pools. This leaves the pools
449 * themselves alone, as well as any ACLs embedded in object xattrs.
451 int rgw_delete_user(RGWRados
*store
, RGWUserInfo
& info
, RGWObjVersionTracker
& objv_tracker
) {
454 map
<string
, RGWAccessKey
>::iterator kiter
= info
.access_keys
.begin();
455 for (; kiter
!= info
.access_keys
.end(); ++kiter
) {
456 ldout(store
->ctx(), 10) << "removing key index: " << kiter
->first
<< dendl
;
457 ret
= rgw_remove_key_index(store
, kiter
->second
);
458 if (ret
< 0 && ret
!= -ENOENT
) {
459 ldout(store
->ctx(), 0) << "ERROR: could not remove " << kiter
->first
<< " (access key object), should be fixed (err=" << ret
<< ")" << dendl
;
464 map
<string
, RGWAccessKey
>::iterator siter
= info
.swift_keys
.begin();
465 for (; siter
!= info
.swift_keys
.end(); ++siter
) {
466 RGWAccessKey
& k
= siter
->second
;
467 ldout(store
->ctx(), 10) << "removing swift subuser index: " << k
.id
<< dendl
;
468 /* check if swift mapping exists */
469 ret
= rgw_remove_swift_name_index(store
, k
.id
);
470 if (ret
< 0 && ret
!= -ENOENT
) {
471 ldout(store
->ctx(), 0) << "ERROR: could not remove " << k
.id
<< " (swift name object), should be fixed (err=" << ret
<< ")" << dendl
;
476 ldout(store
->ctx(), 10) << "removing email index: " << info
.user_email
<< dendl
;
477 ret
= rgw_remove_email_index(store
, info
.user_email
);
478 if (ret
< 0 && ret
!= -ENOENT
) {
479 ldout(store
->ctx(), 0) << "ERROR: could not remove email index object for "
480 << info
.user_email
<< ", should be fixed (err=" << ret
<< ")" << dendl
;
484 string buckets_obj_id
;
485 rgw_get_buckets_obj(info
.user_id
, buckets_obj_id
);
486 rgw_raw_obj
uid_bucks(store
->get_zone_params().user_uid_pool
, buckets_obj_id
);
487 ldout(store
->ctx(), 10) << "removing user buckets index" << dendl
;
488 ret
= store
->delete_system_obj(uid_bucks
);
489 if (ret
< 0 && ret
!= -ENOENT
) {
490 ldout(store
->ctx(), 0) << "ERROR: could not remove " << info
.user_id
<< ":" << uid_bucks
<< ", should be fixed (err=" << ret
<< ")" << dendl
;
495 info
.user_id
.to_str(key
);
497 rgw_raw_obj
uid_obj(store
->get_zone_params().user_uid_pool
, key
);
498 ldout(store
->ctx(), 10) << "removing user index: " << info
.user_id
<< dendl
;
499 ret
= store
->meta_mgr
->remove_entry(user_meta_handler
, key
, &objv_tracker
);
500 if (ret
< 0 && ret
!= -ENOENT
&& ret
!= -ECANCELED
) {
501 ldout(store
->ctx(), 0) << "ERROR: could not remove " << info
.user_id
<< ":" << uid_obj
<< ", should be fixed (err=" << ret
<< ")" << dendl
;
508 static bool char_is_unreserved_url(char c
)
524 struct rgw_flags_desc
{
529 static struct rgw_flags_desc rgw_perms
[] = {
530 { RGW_PERM_FULL_CONTROL
, "full-control" },
531 { RGW_PERM_READ
| RGW_PERM_WRITE
, "read-write" },
532 { RGW_PERM_READ
, "read" },
533 { RGW_PERM_WRITE
, "write" },
534 { RGW_PERM_READ_ACP
, "read-acp" },
535 { RGW_PERM_WRITE_ACP
, "read-acp" },
539 void rgw_perm_to_str(uint32_t mask
, char *buf
, int len
)
541 const char *sep
= "";
544 snprintf(buf
, len
, "<none>");
548 uint32_t orig_mask
= mask
;
549 for (int i
= 0; rgw_perms
[i
].mask
; i
++) {
550 struct rgw_flags_desc
*desc
= &rgw_perms
[i
];
551 if ((mask
& desc
->mask
) == desc
->mask
) {
552 pos
+= snprintf(buf
+ pos
, len
- pos
, "%s%s", sep
, desc
->str
);
561 if (mask
== orig_mask
) // no change
566 uint32_t rgw_str_to_perm(const char *str
)
568 if (strcasecmp(str
, "") == 0)
569 return RGW_PERM_NONE
;
570 else if (strcasecmp(str
, "read") == 0)
571 return RGW_PERM_READ
;
572 else if (strcasecmp(str
, "write") == 0)
573 return RGW_PERM_WRITE
;
574 else if (strcasecmp(str
, "readwrite") == 0)
575 return RGW_PERM_READ
| RGW_PERM_WRITE
;
576 else if (strcasecmp(str
, "full") == 0)
577 return RGW_PERM_FULL_CONTROL
;
579 return RGW_PERM_INVALID
;
582 int rgw_validate_tenant_name(const string
& t
)
585 static bool is_good(char ch
) {
586 return isalnum(ch
) || ch
== '_';
589 std::string::const_iterator it
=
590 std::find_if_not(t
.begin(), t
.end(), tench::is_good
);
591 return (it
== t
.end())? 0: -ERR_INVALID_TENANT_NAME
;
594 static bool validate_access_key(string
& key
)
596 const char *p
= key
.c_str();
598 if (!char_is_unreserved_url(*p
))
605 static void set_err_msg(std::string
*sink
, std::string msg
)
607 if (sink
&& !msg
.empty())
611 static bool remove_old_indexes(RGWRados
*store
,
612 RGWUserInfo
& old_info
, RGWUserInfo
& new_info
, std::string
*err_msg
)
617 if (!old_info
.user_id
.empty() &&
618 old_info
.user_id
.compare(new_info
.user_id
) != 0) {
619 if (old_info
.user_id
.tenant
!= new_info
.user_id
.tenant
) {
620 ldout(store
->ctx(), 0) << "ERROR: tenant mismatch: " << old_info
.user_id
.tenant
<< " != " << new_info
.user_id
.tenant
<< dendl
;
623 ret
= rgw_remove_uid_index(store
, old_info
.user_id
);
624 if (ret
< 0 && ret
!= -ENOENT
) {
625 set_err_msg(err_msg
, "ERROR: could not remove index for uid " + old_info
.user_id
.to_str());
630 if (!old_info
.user_email
.empty() &&
631 old_info
.user_email
.compare(new_info
.user_email
) != 0) {
632 ret
= rgw_remove_email_index(store
, old_info
.user_email
);
633 if (ret
< 0 && ret
!= -ENOENT
) {
634 set_err_msg(err_msg
, "ERROR: could not remove index for email " + old_info
.user_email
);
639 map
<string
, RGWAccessKey
>::iterator old_iter
;
640 for (old_iter
= old_info
.swift_keys
.begin(); old_iter
!= old_info
.swift_keys
.end(); ++old_iter
) {
641 RGWAccessKey
& swift_key
= old_iter
->second
;
642 map
<string
, RGWAccessKey
>::iterator new_iter
= new_info
.swift_keys
.find(swift_key
.id
);
643 if (new_iter
== new_info
.swift_keys
.end()) {
644 ret
= rgw_remove_swift_name_index(store
, swift_key
.id
);
645 if (ret
< 0 && ret
!= -ENOENT
) {
646 set_err_msg(err_msg
, "ERROR: could not remove index for swift_name " + swift_key
.id
);
656 * Dump either the full user info or a subset to a formatter.
658 * NOTE: It is the caller's respnsibility to ensure that the
659 * formatter is flushed at the correct time.
662 static void dump_subusers_info(Formatter
*f
, RGWUserInfo
&info
)
664 map
<string
, RGWSubUser
>::iterator uiter
;
666 f
->open_array_section("subusers");
667 for (uiter
= info
.subusers
.begin(); uiter
!= info
.subusers
.end(); ++uiter
) {
668 RGWSubUser
& u
= uiter
->second
;
669 f
->open_object_section("user");
671 info
.user_id
.to_str(s
);
672 f
->dump_format("id", "%s:%s", s
.c_str(), u
.name
.c_str());
674 rgw_perm_to_str(u
.perm_mask
, buf
, sizeof(buf
));
675 f
->dump_string("permissions", buf
);
681 static void dump_access_keys_info(Formatter
*f
, RGWUserInfo
&info
)
683 map
<string
, RGWAccessKey
>::iterator kiter
;
684 f
->open_array_section("keys");
685 for (kiter
= info
.access_keys
.begin(); kiter
!= info
.access_keys
.end(); ++kiter
) {
686 RGWAccessKey
& k
= kiter
->second
;
687 const char *sep
= (k
.subuser
.empty() ? "" : ":");
688 const char *subuser
= (k
.subuser
.empty() ? "" : k
.subuser
.c_str());
689 f
->open_object_section("key");
691 info
.user_id
.to_str(s
);
692 f
->dump_format("user", "%s%s%s", s
.c_str(), sep
, subuser
);
693 f
->dump_string("access_key", k
.id
);
694 f
->dump_string("secret_key", k
.key
);
700 static void dump_swift_keys_info(Formatter
*f
, RGWUserInfo
&info
)
702 map
<string
, RGWAccessKey
>::iterator kiter
;
703 f
->open_array_section("swift_keys");
704 for (kiter
= info
.swift_keys
.begin(); kiter
!= info
.swift_keys
.end(); ++kiter
) {
705 RGWAccessKey
& k
= kiter
->second
;
706 const char *sep
= (k
.subuser
.empty() ? "" : ":");
707 const char *subuser
= (k
.subuser
.empty() ? "" : k
.subuser
.c_str());
708 f
->open_object_section("key");
710 info
.user_id
.to_str(s
);
711 f
->dump_format("user", "%s%s%s", s
.c_str(), sep
, subuser
);
712 f
->dump_string("secret_key", k
.key
);
718 static void dump_user_info(Formatter
*f
, RGWUserInfo
&info
,
719 RGWStorageStats
*stats
= NULL
)
721 f
->open_object_section("user_info");
723 f
->dump_string("tenant", info
.user_id
.tenant
);
724 f
->dump_string("user_id", info
.user_id
.id
);
725 f
->dump_string("display_name", info
.display_name
);
726 f
->dump_string("email", info
.user_email
);
727 f
->dump_int("suspended", (int)info
.suspended
);
728 f
->dump_int("max_buckets", (int)info
.max_buckets
);
730 dump_subusers_info(f
, info
);
731 dump_access_keys_info(f
, info
);
732 dump_swift_keys_info(f
, info
);
735 encode_json("stats", *stats
, f
);
742 RGWAccessKeyPool::RGWAccessKeyPool(RGWUser
* usr
)
749 keys_allowed
= false;
756 store
= user
->get_store();
759 RGWAccessKeyPool::~RGWAccessKeyPool()
764 int RGWAccessKeyPool::init(RGWUserAdminOpState
& op_state
)
766 if (!op_state
.is_initialized()) {
767 keys_allowed
= false;
771 rgw_user
& uid
= op_state
.get_user_id();
772 if (uid
.compare(RGW_USER_ANON_ID
) == 0) {
773 keys_allowed
= false;
777 swift_keys
= op_state
.get_swift_keys();
778 access_keys
= op_state
.get_access_keys();
786 * Do a fairly exhaustive search for an existing key matching the parameters
787 * given. Also handles the case where no key type was specified and updates
788 * the operation state if needed.
791 bool RGWAccessKeyPool::check_existing_key(RGWUserAdminOpState
& op_state
)
793 bool existing_key
= false;
795 int key_type
= op_state
.get_key_type();
796 std::string kid
= op_state
.get_access_key();
797 std::map
<std::string
, RGWAccessKey
>::iterator kiter
;
798 std::string swift_kid
= op_state
.build_default_swift_kid();
800 RGWUserInfo dup_info
;
802 if (kid
.empty() && swift_kid
.empty())
807 kiter
= swift_keys
->find(swift_kid
);
809 existing_key
= (kiter
!= swift_keys
->end());
811 op_state
.set_access_key(swift_kid
);
815 kiter
= access_keys
->find(kid
);
816 existing_key
= (kiter
!= access_keys
->end());
820 kiter
= access_keys
->find(kid
);
822 existing_key
= (kiter
!= access_keys
->end());
824 op_state
.set_key_type(KEY_TYPE_S3
);
828 kiter
= swift_keys
->find(kid
);
830 existing_key
= (kiter
!= swift_keys
->end());
832 op_state
.set_key_type(KEY_TYPE_SWIFT
);
836 // handle the case where the access key was not provided in user:key format
837 if (swift_kid
.empty())
840 kiter
= swift_keys
->find(swift_kid
);
842 existing_key
= (kiter
!= swift_keys
->end());
844 op_state
.set_access_key(swift_kid
);
845 op_state
.set_key_type(KEY_TYPE_SWIFT
);
849 op_state
.set_existing_key(existing_key
);
854 int RGWAccessKeyPool::check_op(RGWUserAdminOpState
& op_state
,
855 std::string
*err_msg
)
857 RGWUserInfo dup_info
;
859 if (!op_state
.is_populated()) {
860 set_err_msg(err_msg
, "user info was not populated");
865 set_err_msg(err_msg
, "keys not allowed for this user");
869 int32_t key_type
= op_state
.get_key_type();
871 // if a key type wasn't specified
873 if (op_state
.has_subuser()) {
874 key_type
= KEY_TYPE_SWIFT
;
876 key_type
= KEY_TYPE_S3
;
880 op_state
.set_key_type(key_type
);
882 /* see if the access key was specified */
883 if (key_type
== KEY_TYPE_S3
&& !op_state
.will_gen_access() &&
884 op_state
.get_access_key().empty()) {
885 set_err_msg(err_msg
, "empty access key");
886 return -ERR_INVALID_ACCESS_KEY
;
889 // don't check for secret key because we may be doing a removal
891 check_existing_key(op_state
);
896 // Generate a new random key
897 int RGWAccessKeyPool::generate_key(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
902 std::pair
<std::string
, RGWAccessKey
> key_pair
;
903 RGWAccessKey new_key
;
904 RGWUserInfo duplicate_check
;
907 int key_type
= op_state
.get_key_type();
908 bool gen_access
= op_state
.will_gen_access();
909 bool gen_secret
= op_state
.will_gen_secret();
912 set_err_msg(err_msg
, "access keys not allowed for this user");
916 if (op_state
.has_existing_key()) {
917 set_err_msg(err_msg
, "cannot create existing key");
918 return -ERR_KEY_EXIST
;
922 id
= op_state
.get_access_key();
928 if (rgw_get_user_info_by_swift(store
, id
, duplicate_check
) >= 0) {
929 set_err_msg(err_msg
, "existing swift key in RGW system:" + id
);
930 return -ERR_KEY_EXIST
;
934 if (rgw_get_user_info_by_access_key(store
, id
, duplicate_check
) >= 0) {
935 set_err_msg(err_msg
, "existing S3 key in RGW system:" + id
);
936 return -ERR_KEY_EXIST
;
942 if (op_state
.has_subuser()) {
943 //create user and subuser at the same time, user's s3 key should not be set this
944 if (!op_state
.key_type_setbycontext
|| (key_type
== KEY_TYPE_SWIFT
)) {
945 new_key
.subuser
= op_state
.get_subuser();
951 if (op_state
.get_secret_key().empty()) {
952 set_err_msg(err_msg
, "empty secret key");
953 return -ERR_INVALID_SECRET_KEY
;
956 key
= op_state
.get_secret_key();
958 char secret_key_buf
[SECRET_KEY_LEN
+ 1];
960 ret
= gen_rand_alphanumeric_plain(g_ceph_context
, secret_key_buf
, sizeof(secret_key_buf
));
962 set_err_msg(err_msg
, "unable to generate secret key");
966 key
= secret_key_buf
;
969 // Generate the access key
970 if (key_type
== KEY_TYPE_S3
&& gen_access
) {
971 char public_id_buf
[PUBLIC_ID_LEN
+ 1];
974 int id_buf_size
= sizeof(public_id_buf
);
975 ret
= gen_rand_alphanumeric_upper(g_ceph_context
,
976 public_id_buf
, id_buf_size
);
979 set_err_msg(err_msg
, "unable to generate access key");
984 if (!validate_access_key(id
))
987 } while (!rgw_get_user_info_by_access_key(store
, id
, duplicate_check
));
990 if (key_type
== KEY_TYPE_SWIFT
) {
991 id
= op_state
.build_default_swift_kid();
993 set_err_msg(err_msg
, "empty swift access key");
994 return -ERR_INVALID_ACCESS_KEY
;
997 // check that the access key doesn't exist
998 if (rgw_get_user_info_by_swift(store
, id
, duplicate_check
) >= 0) {
999 set_err_msg(err_msg
, "cannot create existing swift key");
1000 return -ERR_KEY_EXIST
;
1004 // finally create the new key
1008 key_pair
.first
= id
;
1009 key_pair
.second
= new_key
;
1011 if (key_type
== KEY_TYPE_S3
) {
1012 access_keys
->insert(key_pair
);
1013 } else if (key_type
== KEY_TYPE_SWIFT
) {
1014 swift_keys
->insert(key_pair
);
1020 // modify an existing key
1021 int RGWAccessKeyPool::modify_key(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1024 std::string key
= op_state
.get_secret_key();
1025 int key_type
= op_state
.get_key_type();
1027 RGWAccessKey modify_key
;
1029 pair
<string
, RGWAccessKey
> key_pair
;
1030 map
<std::string
, RGWAccessKey
>::iterator kiter
;
1034 id
= op_state
.get_access_key();
1036 set_err_msg(err_msg
, "no access key specified");
1037 return -ERR_INVALID_ACCESS_KEY
;
1040 case KEY_TYPE_SWIFT
:
1041 id
= op_state
.build_default_swift_kid();
1043 set_err_msg(err_msg
, "no subuser specified");
1048 set_err_msg(err_msg
, "invalid key type");
1049 return -ERR_INVALID_KEY_TYPE
;
1052 if (!op_state
.has_existing_key()) {
1053 set_err_msg(err_msg
, "key does not exist");
1054 return -ERR_INVALID_ACCESS_KEY
;
1057 key_pair
.first
= id
;
1059 if (key_type
== KEY_TYPE_SWIFT
) {
1061 modify_key
.subuser
= op_state
.get_subuser();
1062 } else if (key_type
== KEY_TYPE_S3
) {
1063 kiter
= access_keys
->find(id
);
1064 if (kiter
!= access_keys
->end()) {
1065 modify_key
= kiter
->second
;
1069 if (op_state
.will_gen_secret()) {
1070 char secret_key_buf
[SECRET_KEY_LEN
+ 1];
1073 int key_buf_size
= sizeof(secret_key_buf
);
1074 ret
= gen_rand_alphanumeric_plain(g_ceph_context
, secret_key_buf
, key_buf_size
);
1076 set_err_msg(err_msg
, "unable to generate secret key");
1080 key
= secret_key_buf
;
1084 set_err_msg(err_msg
, "empty secret key");
1085 return -ERR_INVALID_SECRET_KEY
;
1088 // update the access key with the new secret key
1089 modify_key
.key
= key
;
1091 key_pair
.second
= modify_key
;
1094 if (key_type
== KEY_TYPE_S3
) {
1095 (*access_keys
)[id
] = modify_key
;
1096 } else if (key_type
== KEY_TYPE_SWIFT
) {
1097 (*swift_keys
)[id
] = modify_key
;
1103 int RGWAccessKeyPool::execute_add(RGWUserAdminOpState
& op_state
,
1104 std::string
*err_msg
, bool defer_user_update
)
1108 std::string subprocess_msg
;
1109 int key_op
= GENERATE_KEY
;
1112 if (op_state
.has_existing_key())
1113 key_op
= MODIFY_KEY
;
1117 ret
= generate_key(op_state
, &subprocess_msg
);
1120 ret
= modify_key(op_state
, &subprocess_msg
);
1125 set_err_msg(err_msg
, subprocess_msg
);
1129 // store the updated info
1130 if (!defer_user_update
)
1131 ret
= user
->update(op_state
, err_msg
);
1139 int RGWAccessKeyPool::add(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1141 return add(op_state
, err_msg
, false);
1144 int RGWAccessKeyPool::add(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_user_update
)
1147 std::string subprocess_msg
;
1149 ret
= check_op(op_state
, &subprocess_msg
);
1151 set_err_msg(err_msg
, "unable to parse request, " + subprocess_msg
);
1155 ret
= execute_add(op_state
, &subprocess_msg
, defer_user_update
);
1157 set_err_msg(err_msg
, "unable to add access key, " + subprocess_msg
);
1164 int RGWAccessKeyPool::execute_remove(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_user_update
)
1168 int key_type
= op_state
.get_key_type();
1169 std::string id
= op_state
.get_access_key();
1170 map
<std::string
, RGWAccessKey
>::iterator kiter
;
1171 map
<std::string
, RGWAccessKey
> *keys_map
;
1173 if (!op_state
.has_existing_key()) {
1174 set_err_msg(err_msg
, "unable to find access key");
1175 return -ERR_INVALID_ACCESS_KEY
;
1178 if (key_type
== KEY_TYPE_S3
) {
1179 keys_map
= access_keys
;
1180 } else if (key_type
== KEY_TYPE_SWIFT
) {
1181 keys_map
= swift_keys
;
1184 set_err_msg(err_msg
, "invalid access key");
1185 return -ERR_INVALID_ACCESS_KEY
;
1188 kiter
= keys_map
->find(id
);
1189 if (kiter
== keys_map
->end()) {
1190 set_err_msg(err_msg
, "key not found");
1191 return -ERR_INVALID_ACCESS_KEY
;
1194 rgw_remove_key_index(store
, kiter
->second
);
1195 keys_map
->erase(kiter
);
1197 if (!defer_user_update
)
1198 ret
= user
->update(op_state
, err_msg
);
1206 int RGWAccessKeyPool::remove(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1208 return remove(op_state
, err_msg
, false);
1211 int RGWAccessKeyPool::remove(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_user_update
)
1215 std::string subprocess_msg
;
1217 ret
= check_op(op_state
, &subprocess_msg
);
1219 set_err_msg(err_msg
, "unable to parse request, " + subprocess_msg
);
1223 ret
= execute_remove(op_state
, &subprocess_msg
, defer_user_update
);
1225 set_err_msg(err_msg
, "unable to remove access key, " + subprocess_msg
);
1232 // remove all keys associated with a subuser
1233 int RGWAccessKeyPool::remove_subuser_keys(RGWUserAdminOpState
& op_state
,
1234 std::string
*err_msg
, bool defer_user_update
)
1238 if (!op_state
.is_populated()) {
1239 set_err_msg(err_msg
, "user info was not populated");
1243 if (!op_state
.has_subuser()) {
1244 set_err_msg(err_msg
, "no subuser specified");
1248 std::string swift_kid
= op_state
.build_default_swift_kid();
1249 if (swift_kid
.empty()) {
1250 set_err_msg(err_msg
, "empty swift access key");
1254 map
<std::string
, RGWAccessKey
>::iterator kiter
;
1255 map
<std::string
, RGWAccessKey
> *keys_map
;
1257 // a subuser can have at most one swift key
1258 keys_map
= swift_keys
;
1259 kiter
= keys_map
->find(swift_kid
);
1260 if (kiter
!= keys_map
->end()) {
1261 rgw_remove_key_index(store
, kiter
->second
);
1262 keys_map
->erase(kiter
);
1265 // a subuser may have multiple s3 key pairs
1266 std::string subuser_str
= op_state
.get_subuser();
1267 keys_map
= access_keys
;
1268 RGWUserInfo user_info
= op_state
.get_user_info();
1269 map
<std::string
, RGWAccessKey
>::iterator user_kiter
= user_info
.access_keys
.begin();
1270 for (; user_kiter
!= user_info
.access_keys
.end(); ++user_kiter
) {
1271 if (user_kiter
->second
.subuser
== subuser_str
) {
1272 kiter
= keys_map
->find(user_kiter
->first
);
1273 if (kiter
!= keys_map
->end()) {
1274 rgw_remove_key_index(store
, kiter
->second
);
1275 keys_map
->erase(kiter
);
1280 if (!defer_user_update
)
1281 ret
= user
->update(op_state
, err_msg
);
1289 RGWSubUserPool::RGWSubUserPool(RGWUser
*usr
)
1291 subusers_allowed
= (usr
!= NULL
);
1293 store
= usr
->get_store();
1300 RGWSubUserPool::~RGWSubUserPool()
1305 int RGWSubUserPool::init(RGWUserAdminOpState
& op_state
)
1307 if (!op_state
.is_initialized()) {
1308 subusers_allowed
= false;
1312 rgw_user
& uid
= op_state
.get_user_id();
1313 if (uid
.compare(RGW_USER_ANON_ID
) == 0) {
1314 subusers_allowed
= false;
1318 subuser_map
= op_state
.get_subusers();
1319 if (subuser_map
== NULL
) {
1320 subusers_allowed
= false;
1324 subusers_allowed
= true;
1329 bool RGWSubUserPool::exists(std::string subuser
)
1331 if (subuser
.empty())
1337 if (subuser_map
->count(subuser
))
1343 int RGWSubUserPool::check_op(RGWUserAdminOpState
& op_state
,
1344 std::string
*err_msg
)
1346 bool existing
= false;
1347 std::string subuser
= op_state
.get_subuser();
1349 if (!op_state
.is_populated()) {
1350 set_err_msg(err_msg
, "user info was not populated");
1354 if (!subusers_allowed
) {
1355 set_err_msg(err_msg
, "subusers not allowed for this user");
1359 if (subuser
.empty() && !op_state
.will_gen_subuser()) {
1360 set_err_msg(err_msg
, "empty subuser name");
1364 if (op_state
.get_subuser_perm() == RGW_PERM_INVALID
) {
1365 set_err_msg(err_msg
, "invaild subuser access");
1369 //set key type when it not set or set by context
1370 if ((op_state
.get_key_type() < 0) || op_state
.key_type_setbycontext
) {
1371 op_state
.set_key_type(KEY_TYPE_SWIFT
);
1372 op_state
.key_type_setbycontext
= true;
1375 // check if the subuser exists
1376 if (!subuser
.empty())
1377 existing
= exists(subuser
);
1379 op_state
.set_existing_subuser(existing
);
1384 int RGWSubUserPool::execute_add(RGWUserAdminOpState
& op_state
,
1385 std::string
*err_msg
, bool defer_user_update
)
1388 std::string subprocess_msg
;
1391 std::pair
<std::string
, RGWSubUser
> subuser_pair
;
1392 std::string subuser_str
= op_state
.get_subuser();
1394 subuser_pair
.first
= subuser_str
;
1396 // assumes key should be created
1397 if (op_state
.has_key_op()) {
1398 ret
= user
->keys
.add(op_state
, &subprocess_msg
, true);
1400 set_err_msg(err_msg
, "unable to create subuser key, " + subprocess_msg
);
1405 // create the subuser
1406 subuser
.name
= subuser_str
;
1408 if (op_state
.has_subuser_perm())
1409 subuser
.perm_mask
= op_state
.get_subuser_perm();
1411 // insert the subuser into user info
1412 subuser_pair
.second
= subuser
;
1413 subuser_map
->insert(subuser_pair
);
1415 // attempt to save the subuser
1416 if (!defer_user_update
)
1417 ret
= user
->update(op_state
, err_msg
);
1425 int RGWSubUserPool::add(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1427 return add(op_state
, err_msg
, false);
1430 int RGWSubUserPool::add(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_user_update
)
1432 std::string subprocess_msg
;
1434 int32_t key_type
= op_state
.get_key_type();
1436 ret
= check_op(op_state
, &subprocess_msg
);
1438 set_err_msg(err_msg
, "unable to parse request, " + subprocess_msg
);
1442 if (key_type
== KEY_TYPE_S3
&& op_state
.get_access_key().empty()) {
1443 op_state
.set_gen_access();
1446 if (op_state
.get_secret_key().empty()) {
1447 op_state
.set_gen_secret();
1450 ret
= execute_add(op_state
, &subprocess_msg
, defer_user_update
);
1452 set_err_msg(err_msg
, "unable to create subuser, " + subprocess_msg
);
1459 int RGWSubUserPool::execute_remove(RGWUserAdminOpState
& op_state
,
1460 std::string
*err_msg
, bool defer_user_update
)
1463 std::string subprocess_msg
;
1465 std::string subuser_str
= op_state
.get_subuser();
1467 map
<std::string
, RGWSubUser
>::iterator siter
;
1468 siter
= subuser_map
->find(subuser_str
);
1469 if (siter
== subuser_map
->end()){
1470 set_err_msg(err_msg
, "subuser not found: " + subuser_str
);
1471 return -ERR_NO_SUCH_SUBUSER
;
1473 if (!op_state
.has_existing_subuser()) {
1474 set_err_msg(err_msg
, "subuser not found: " + subuser_str
);
1475 return -ERR_NO_SUCH_SUBUSER
;
1478 // always purge all associate keys
1479 user
->keys
.remove_subuser_keys(op_state
, &subprocess_msg
, true);
1481 // remove the subuser from the user info
1482 subuser_map
->erase(siter
);
1484 // attempt to save the subuser
1485 if (!defer_user_update
)
1486 ret
= user
->update(op_state
, err_msg
);
1494 int RGWSubUserPool::remove(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1496 return remove(op_state
, err_msg
, false);
1499 int RGWSubUserPool::remove(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_user_update
)
1501 std::string subprocess_msg
;
1504 ret
= check_op(op_state
, &subprocess_msg
);
1506 set_err_msg(err_msg
, "unable to parse request, " + subprocess_msg
);
1510 ret
= execute_remove(op_state
, &subprocess_msg
, defer_user_update
);
1512 set_err_msg(err_msg
, "unable to remove subuser, " + subprocess_msg
);
1519 int RGWSubUserPool::execute_modify(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_user_update
)
1522 std::string subprocess_msg
;
1523 std::map
<std::string
, RGWSubUser
>::iterator siter
;
1524 std::pair
<std::string
, RGWSubUser
> subuser_pair
;
1526 std::string subuser_str
= op_state
.get_subuser();
1529 if (!op_state
.has_existing_subuser()) {
1530 set_err_msg(err_msg
, "subuser does not exist");
1531 return -ERR_NO_SUCH_SUBUSER
;
1534 subuser_pair
.first
= subuser_str
;
1536 siter
= subuser_map
->find(subuser_str
);
1537 subuser
= siter
->second
;
1539 if (op_state
.has_key_op()) {
1540 ret
= user
->keys
.add(op_state
, &subprocess_msg
, true);
1542 set_err_msg(err_msg
, "unable to create subuser keys, " + subprocess_msg
);
1547 if (op_state
.has_subuser_perm())
1548 subuser
.perm_mask
= op_state
.get_subuser_perm();
1550 subuser_pair
.second
= subuser
;
1552 subuser_map
->erase(siter
);
1553 subuser_map
->insert(subuser_pair
);
1555 // attempt to save the subuser
1556 if (!defer_user_update
)
1557 ret
= user
->update(op_state
, err_msg
);
1565 int RGWSubUserPool::modify(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1567 return RGWSubUserPool::modify(op_state
, err_msg
, false);
1570 int RGWSubUserPool::modify(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_user_update
)
1572 std::string subprocess_msg
;
1577 ret
= check_op(op_state
, &subprocess_msg
);
1579 set_err_msg(err_msg
, "unable to parse request, " + subprocess_msg
);
1583 ret
= execute_modify(op_state
, &subprocess_msg
, defer_user_update
);
1585 set_err_msg(err_msg
, "unable to modify subuser, " + subprocess_msg
);
1592 RGWUserCapPool::RGWUserCapPool(RGWUser
*usr
)
1596 caps_allowed
= (user
!= NULL
);
1599 RGWUserCapPool::~RGWUserCapPool()
1604 int RGWUserCapPool::init(RGWUserAdminOpState
& op_state
)
1606 if (!op_state
.is_initialized()) {
1607 caps_allowed
= false;
1611 rgw_user
& uid
= op_state
.get_user_id();
1612 if (uid
.compare(RGW_USER_ANON_ID
) == 0) {
1613 caps_allowed
= false;
1617 caps
= op_state
.get_caps_obj();
1619 caps_allowed
= false;
1620 return -ERR_INVALID_CAP
;
1623 caps_allowed
= true;
1628 int RGWUserCapPool::add(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1630 return add(op_state
, err_msg
, false);
1633 int RGWUserCapPool::add(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_save
)
1636 std::string caps_str
= op_state
.get_caps();
1638 if (!op_state
.is_populated()) {
1639 set_err_msg(err_msg
, "user info was not populated");
1643 if (!caps_allowed
) {
1644 set_err_msg(err_msg
, "caps not allowed for this user");
1648 if (caps_str
.empty()) {
1649 set_err_msg(err_msg
, "empty user caps");
1650 return -ERR_INVALID_CAP
;
1653 int r
= caps
->add_from_string(caps_str
);
1655 set_err_msg(err_msg
, "unable to add caps: " + caps_str
);
1660 ret
= user
->update(op_state
, err_msg
);
1668 int RGWUserCapPool::remove(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1670 return remove(op_state
, err_msg
, false);
1673 int RGWUserCapPool::remove(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_save
)
1677 std::string caps_str
= op_state
.get_caps();
1679 if (!op_state
.is_populated()) {
1680 set_err_msg(err_msg
, "user info was not populated");
1684 if (!caps_allowed
) {
1685 set_err_msg(err_msg
, "caps not allowed for this user");
1689 if (caps_str
.empty()) {
1690 set_err_msg(err_msg
, "empty user caps");
1691 return -ERR_INVALID_CAP
;
1694 int r
= caps
->remove_from_string(caps_str
);
1696 set_err_msg(err_msg
, "unable to remove caps: " + caps_str
);
1701 ret
= user
->update(op_state
, err_msg
);
1709 RGWUser::RGWUser() : store(NULL
), info_stored(false), caps(this), keys(this), subusers(this)
1714 int RGWUser::init(RGWRados
*storage
, RGWUserAdminOpState
& op_state
)
1717 int ret
= init_storage(storage
);
1721 ret
= init(op_state
);
1732 void RGWUser::init_default()
1734 // use anonymous user info as a placeholder
1735 rgw_get_anon_user(old_info
);
1736 user_id
= RGW_USER_ANON_ID
;
1741 int RGWUser::init_storage(RGWRados
*storage
)
1752 keys
= RGWAccessKeyPool(this);
1753 caps
= RGWUserCapPool(this);
1754 subusers
= RGWSubUserPool(this);
1759 int RGWUser::init(RGWUserAdminOpState
& op_state
)
1762 std::string swift_user
;
1763 user_id
= op_state
.get_user_id();
1764 std::string user_email
= op_state
.get_user_email();
1765 std::string access_key
= op_state
.get_access_key();
1766 std::string subuser
= op_state
.get_subuser();
1768 int key_type
= op_state
.get_key_type();
1769 if (key_type
== KEY_TYPE_SWIFT
) {
1770 swift_user
= op_state
.get_access_key();
1774 RGWUserInfo user_info
;
1778 if (user_id
.empty() && !subuser
.empty()) {
1779 size_t pos
= subuser
.find(':');
1780 if (pos
!= string::npos
) {
1781 user_id
= subuser
.substr(0, pos
);
1782 op_state
.set_user_id(user_id
);
1786 if (!user_id
.empty() && (user_id
.compare(RGW_USER_ANON_ID
) != 0)) {
1787 found
= (rgw_get_user_info_by_uid(store
, user_id
, user_info
, &op_state
.objv
) >= 0);
1788 op_state
.found_by_uid
= found
;
1790 if (!user_email
.empty() && !found
) {
1791 found
= (rgw_get_user_info_by_email(store
, user_email
, user_info
, &op_state
.objv
) >= 0);
1792 op_state
.found_by_email
= found
;
1794 if (!swift_user
.empty() && !found
) {
1795 found
= (rgw_get_user_info_by_swift(store
, swift_user
, user_info
, &op_state
.objv
) >= 0);
1796 op_state
.found_by_key
= found
;
1798 if (!access_key
.empty() && !found
) {
1799 found
= (rgw_get_user_info_by_access_key(store
, access_key
, user_info
, &op_state
.objv
) >= 0);
1800 op_state
.found_by_key
= found
;
1803 op_state
.set_existing_user(found
);
1805 op_state
.set_user_info(user_info
);
1806 op_state
.set_populated();
1808 old_info
= user_info
;
1812 if (user_id
.empty()) {
1813 user_id
= user_info
.user_id
;
1815 op_state
.set_initialized();
1817 // this may have been called by a helper object
1818 int ret
= init_members(op_state
);
1825 int RGWUser::init_members(RGWUserAdminOpState
& op_state
)
1829 ret
= keys
.init(op_state
);
1833 ret
= subusers
.init(op_state
);
1837 ret
= caps
.init(op_state
);
1844 int RGWUser::update(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1847 std::string subprocess_msg
;
1848 RGWUserInfo user_info
= op_state
.get_user_info();
1851 set_err_msg(err_msg
, "couldn't initialize storage");
1855 if (is_populated()) {
1856 ret
= rgw_store_user_info(store
, user_info
, &old_info
, &op_state
.objv
, real_time(), false);
1858 set_err_msg(err_msg
, "unable to store user info");
1862 ret
= remove_old_indexes(store
, old_info
, user_info
, &subprocess_msg
);
1864 set_err_msg(err_msg
, "unable to remove old user info, " + subprocess_msg
);
1868 ret
= rgw_store_user_info(store
, user_info
, NULL
, &op_state
.objv
, real_time(), false);
1870 set_err_msg(err_msg
, "unable to store user info");
1875 old_info
= user_info
;
1881 int RGWUser::check_op(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1885 rgw_user
& op_id
= op_state
.get_user_id();
1887 RGWUserInfo user_info
;
1889 same_id
= (user_id
.compare(op_id
) == 0);
1890 populated
= is_populated();
1892 if (op_id
.compare(RGW_USER_ANON_ID
) == 0) {
1893 set_err_msg(err_msg
, "unable to perform operations on the anonymous user");
1897 if (populated
&& !same_id
) {
1898 set_err_msg(err_msg
, "user id mismatch, operation id: " + op_id
.to_str()
1899 + " does not match: " + user_id
.to_str());
1904 int ret
= rgw_validate_tenant_name(op_id
.tenant
);
1906 set_err_msg(err_msg
,
1907 "invalid tenant only alphanumeric and _ characters are allowed");
1911 //set key type when it not set or set by context
1912 if ((op_state
.get_key_type() < 0) || op_state
.key_type_setbycontext
) {
1913 op_state
.set_key_type(KEY_TYPE_S3
);
1914 op_state
.key_type_setbycontext
= true;
1920 int RGWUser::execute_add(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1922 std::string subprocess_msg
;
1924 bool defer_user_update
= true;
1926 RGWUserInfo user_info
;
1928 rgw_user
& uid
= op_state
.get_user_id();
1929 std::string user_email
= op_state
.get_user_email();
1930 std::string display_name
= op_state
.get_display_name();
1932 // fail if the user exists already
1933 if (op_state
.has_existing_user()) {
1934 if (!op_state
.exclusive
&&
1935 (user_email
.empty() ||
1936 boost::iequals(user_email
, old_info
.user_email
)) &&
1937 old_info
.display_name
== display_name
) {
1938 return execute_modify(op_state
, err_msg
);
1941 if (op_state
.found_by_email
) {
1942 set_err_msg(err_msg
, "email: " + user_email
+
1943 " is the email address an existing user");
1944 ret
= -ERR_EMAIL_EXIST
;
1945 } else if (op_state
.found_by_key
) {
1946 set_err_msg(err_msg
, "duplicate key provided");
1947 ret
= -ERR_KEY_EXIST
;
1949 set_err_msg(err_msg
, "user: " + op_state
.user_id
.to_str() + " exists");
1955 // fail if the user_info has already been populated
1956 if (op_state
.is_populated()) {
1957 set_err_msg(err_msg
, "cannot overwrite already populated user");
1961 // fail if the display name was not included
1962 if (display_name
.empty()) {
1963 set_err_msg(err_msg
, "no display name specified");
1968 // set the user info
1970 user_info
.user_id
= user_id
;
1971 user_info
.display_name
= display_name
;
1972 user_info
.type
= TYPE_RGW
;
1974 if (!user_email
.empty())
1975 user_info
.user_email
= user_email
;
1977 CephContext
*cct
= store
->ctx();
1978 if (op_state
.max_buckets_specified
) {
1979 user_info
.max_buckets
= op_state
.get_max_buckets();
1981 user_info
.max_buckets
= cct
->_conf
->rgw_user_max_buckets
;
1984 user_info
.suspended
= op_state
.get_suspension_status();
1985 user_info
.admin
= op_state
.admin
;
1986 user_info
.system
= op_state
.system
;
1988 if (op_state
.op_mask_specified
)
1989 user_info
.op_mask
= op_state
.get_op_mask();
1991 if (op_state
.has_bucket_quota()) {
1992 user_info
.bucket_quota
= op_state
.get_bucket_quota();
1994 if (cct
->_conf
->rgw_bucket_default_quota_max_objects
>= 0) {
1995 user_info
.bucket_quota
.max_objects
= cct
->_conf
->rgw_bucket_default_quota_max_objects
;
1996 user_info
.bucket_quota
.enabled
= true;
1998 if (cct
->_conf
->rgw_bucket_default_quota_max_size
>= 0) {
1999 user_info
.bucket_quota
.max_size
= cct
->_conf
->rgw_bucket_default_quota_max_size
;
2000 user_info
.bucket_quota
.enabled
= true;
2004 if (op_state
.temp_url_key_specified
) {
2005 map
<int, string
>::iterator iter
;
2006 for (iter
= op_state
.temp_url_keys
.begin();
2007 iter
!= op_state
.temp_url_keys
.end(); ++iter
) {
2008 user_info
.temp_url_keys
[iter
->first
] = iter
->second
;
2012 if (op_state
.has_user_quota()) {
2013 user_info
.user_quota
= op_state
.get_user_quota();
2015 if (cct
->_conf
->rgw_user_default_quota_max_objects
>= 0) {
2016 user_info
.user_quota
.max_objects
= cct
->_conf
->rgw_user_default_quota_max_objects
;
2017 user_info
.user_quota
.enabled
= true;
2019 if (cct
->_conf
->rgw_user_default_quota_max_size
>= 0) {
2020 user_info
.user_quota
.max_size
= cct
->_conf
->rgw_user_default_quota_max_size
;
2021 user_info
.user_quota
.enabled
= true;
2025 // update the request
2026 op_state
.set_user_info(user_info
);
2027 op_state
.set_populated();
2029 // update the helper objects
2030 ret
= init_members(op_state
);
2032 set_err_msg(err_msg
, "unable to initialize user");
2036 // see if we need to add an access key
2037 if (op_state
.has_key_op()) {
2038 ret
= keys
.add(op_state
, &subprocess_msg
, defer_user_update
);
2040 set_err_msg(err_msg
, "unable to create access key, " + subprocess_msg
);
2045 // see if we need to add some caps
2046 if (op_state
.has_caps_op()) {
2047 ret
= caps
.add(op_state
, &subprocess_msg
, defer_user_update
);
2049 set_err_msg(err_msg
, "unable to add user capabilities, " + subprocess_msg
);
2054 ret
= update(op_state
, err_msg
);
2061 int RGWUser::add(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
2063 std::string subprocess_msg
;
2066 ret
= check_op(op_state
, &subprocess_msg
);
2068 set_err_msg(err_msg
, "unable to parse parameters, " + subprocess_msg
);
2072 ret
= execute_add(op_state
, &subprocess_msg
);
2074 set_err_msg(err_msg
, "unable to create user, " + subprocess_msg
);
2081 int RGWUser::execute_remove(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
2085 bool purge_data
= op_state
.will_purge_data();
2086 rgw_user
& uid
= op_state
.get_user_id();
2087 RGWUserInfo user_info
= op_state
.get_user_info();
2089 if (!op_state
.has_existing_user()) {
2090 set_err_msg(err_msg
, "user does not exist");
2094 bool is_truncated
= false;
2096 CephContext
*cct
= store
->ctx();
2097 size_t max_buckets
= cct
->_conf
->rgw_list_buckets_max_chunk
;
2099 RGWUserBuckets buckets
;
2100 ret
= rgw_read_user_buckets(store
, uid
, buckets
, marker
, string(),
2101 max_buckets
, false, &is_truncated
);
2103 set_err_msg(err_msg
, "unable to read user bucket info");
2107 map
<std::string
, RGWBucketEnt
>& m
= buckets
.get_buckets();
2108 if (!m
.empty() && !purge_data
) {
2109 set_err_msg(err_msg
, "must specify purge data to remove user with buckets");
2110 return -EEXIST
; // change to code that maps to 409: conflict
2113 std::map
<std::string
, RGWBucketEnt
>::iterator it
;
2114 for (it
= m
.begin(); it
!= m
.end(); ++it
) {
2115 ret
= rgw_remove_bucket(store
, ((*it
).second
).bucket
, true);
2117 set_err_msg(err_msg
, "unable to delete user data");
2124 } while (is_truncated
);
2126 ret
= rgw_delete_user(store
, user_info
, op_state
.objv
);
2128 set_err_msg(err_msg
, "unable to remove user from RADOS");
2132 op_state
.clear_populated();
2138 int RGWUser::remove(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
2140 std::string subprocess_msg
;
2143 ret
= check_op(op_state
, &subprocess_msg
);
2145 set_err_msg(err_msg
, "unable to parse parameters, " + subprocess_msg
);
2149 ret
= execute_remove(op_state
, &subprocess_msg
);
2151 set_err_msg(err_msg
, "unable to remove user, " + subprocess_msg
);
2158 int RGWUser::execute_modify(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
2160 bool populated
= op_state
.is_populated();
2162 std::string subprocess_msg
;
2163 std::string op_email
= op_state
.get_user_email();
2164 std::string display_name
= op_state
.get_display_name();
2166 RGWUserInfo user_info
;
2167 RGWUserInfo duplicate_check
;
2169 // ensure that the user info has been populated or is populate-able
2170 if (!op_state
.has_existing_user() && !populated
) {
2171 set_err_msg(err_msg
, "user not found");
2175 // if the user hasn't already been populated...attempt to
2177 ret
= init(op_state
);
2179 set_err_msg(err_msg
, "unable to retrieve user info");
2184 // ensure that we can modify the user's attributes
2185 if (user_id
.compare(RGW_USER_ANON_ID
) == 0) {
2186 set_err_msg(err_msg
, "unable to modify anonymous user's info");
2190 user_info
= old_info
;
2192 std::string old_email
= old_info
.user_email
;
2193 if (!op_email
.empty()) {
2194 // make sure we are not adding a duplicate email
2195 if (old_email
.compare(op_email
) != 0) {
2196 ret
= rgw_get_user_info_by_email(store
, op_email
, duplicate_check
);
2197 if (ret
>= 0 && duplicate_check
.user_id
.compare(user_id
) != 0) {
2198 set_err_msg(err_msg
, "cannot add duplicate email");
2199 return -ERR_EMAIL_EXIST
;
2202 user_info
.user_email
= op_email
;
2203 } else if (op_email
.empty() && op_state
.user_email_specified
) {
2205 ldout(store
->ctx(), 10) << "removing email index: " << user_info
.user_email
<< dendl
;
2206 ret
= rgw_remove_email_index(store
, user_info
.user_email
);
2207 if (ret
< 0 && ret
!= -ENOENT
) {
2208 ldout(store
->ctx(), 0) << "ERROR: could not remove " << user_info
.user_id
<< " index (err=" << ret
<< ")" << dendl
;
2211 user_info
.user_email
= "";
2214 // update the remaining user info
2215 if (!display_name
.empty())
2216 user_info
.display_name
= display_name
;
2218 if (op_state
.max_buckets_specified
)
2219 user_info
.max_buckets
= op_state
.get_max_buckets();
2221 if (op_state
.admin_specified
)
2222 user_info
.admin
= op_state
.admin
;
2224 if (op_state
.system_specified
)
2225 user_info
.system
= op_state
.system
;
2227 if (op_state
.temp_url_key_specified
) {
2228 map
<int, string
>::iterator iter
;
2229 for (iter
= op_state
.temp_url_keys
.begin();
2230 iter
!= op_state
.temp_url_keys
.end(); ++iter
) {
2231 user_info
.temp_url_keys
[iter
->first
] = iter
->second
;
2235 if (op_state
.op_mask_specified
)
2236 user_info
.op_mask
= op_state
.get_op_mask();
2238 if (op_state
.has_bucket_quota())
2239 user_info
.bucket_quota
= op_state
.get_bucket_quota();
2241 if (op_state
.has_user_quota())
2242 user_info
.user_quota
= op_state
.get_user_quota();
2244 if (op_state
.has_suspension_op()) {
2245 __u8 suspended
= op_state
.get_suspension_status();
2246 user_info
.suspended
= suspended
;
2248 RGWUserBuckets buckets
;
2250 if (user_id
.empty()) {
2251 set_err_msg(err_msg
, "empty user id passed...aborting");
2255 bool is_truncated
= false;
2257 CephContext
*cct
= store
->ctx();
2258 size_t max_buckets
= cct
->_conf
->rgw_list_buckets_max_chunk
;
2260 ret
= rgw_read_user_buckets(store
, user_id
, buckets
, marker
, string(),
2261 max_buckets
, false, &is_truncated
);
2263 set_err_msg(err_msg
, "could not get buckets for uid: " + user_id
.to_str());
2267 map
<string
, RGWBucketEnt
>& m
= buckets
.get_buckets();
2268 map
<string
, RGWBucketEnt
>::iterator iter
;
2270 vector
<rgw_bucket
> bucket_names
;
2271 for (iter
= m
.begin(); iter
!= m
.end(); ++iter
) {
2272 RGWBucketEnt obj
= iter
->second
;
2273 bucket_names
.push_back(obj
.bucket
);
2275 marker
= iter
->first
;
2278 ret
= store
->set_buckets_enabled(bucket_names
, !suspended
);
2280 set_err_msg(err_msg
, "failed to modify bucket");
2284 } while (is_truncated
);
2286 op_state
.set_user_info(user_info
);
2288 // if we're supposed to modify keys, do so
2289 if (op_state
.has_key_op()) {
2290 ret
= keys
.add(op_state
, &subprocess_msg
, true);
2292 set_err_msg(err_msg
, "unable to create or modify keys, " + subprocess_msg
);
2297 ret
= update(op_state
, err_msg
);
2304 int RGWUser::modify(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
2306 std::string subprocess_msg
;
2309 ret
= check_op(op_state
, &subprocess_msg
);
2311 set_err_msg(err_msg
, "unable to parse parameters, " + subprocess_msg
);
2315 ret
= execute_modify(op_state
, &subprocess_msg
);
2317 set_err_msg(err_msg
, "unable to modify user, " + subprocess_msg
);
2324 int RGWUser::info(RGWUserAdminOpState
& op_state
, RGWUserInfo
& fetched_info
, std::string
*err_msg
)
2326 int ret
= init(op_state
);
2328 set_err_msg(err_msg
, "unable to fetch user info");
2332 fetched_info
= op_state
.get_user_info();
2337 int RGWUser::info(RGWUserInfo
& fetched_info
, std::string
*err_msg
)
2339 if (!is_populated()) {
2340 set_err_msg(err_msg
, "no user info saved");
2344 fetched_info
= old_info
;
2349 int RGWUserAdminOp_User::info(RGWRados
*store
, RGWUserAdminOpState
& op_state
,
2350 RGWFormatterFlusher
& flusher
)
2355 int ret
= user
.init(store
, op_state
);
2359 if (!op_state
.has_existing_user())
2360 return -ERR_NO_SUCH_USER
;
2362 Formatter
*formatter
= flusher
.get_formatter();
2364 ret
= user
.info(info
, NULL
);
2368 if (op_state
.sync_stats
) {
2369 ret
= rgw_user_sync_all_stats(store
, info
.user_id
);
2375 RGWStorageStats stats
;
2376 RGWStorageStats
*arg_stats
= NULL
;
2377 if (op_state
.fetch_stats
) {
2378 int ret
= store
->get_user_stats(info
.user_id
, stats
);
2388 dump_user_info(formatter
, info
, arg_stats
);
2394 int RGWUserAdminOp_User::create(RGWRados
*store
, RGWUserAdminOpState
& op_state
,
2395 RGWFormatterFlusher
& flusher
)
2399 int ret
= user
.init(store
, op_state
);
2403 Formatter
*formatter
= flusher
.get_formatter();
2405 ret
= user
.add(op_state
, NULL
);
2408 ret
= -ERR_USER_EXIST
;
2412 ret
= user
.info(info
, NULL
);
2418 dump_user_info(formatter
, info
);
2424 int RGWUserAdminOp_User::modify(RGWRados
*store
, RGWUserAdminOpState
& op_state
,
2425 RGWFormatterFlusher
& flusher
)
2429 int ret
= user
.init(store
, op_state
);
2432 Formatter
*formatter
= flusher
.get_formatter();
2434 ret
= user
.modify(op_state
, NULL
);
2437 ret
= -ERR_NO_SUCH_USER
;
2441 ret
= user
.info(info
, NULL
);
2447 dump_user_info(formatter
, info
);
2453 int RGWUserAdminOp_User::remove(RGWRados
*store
, RGWUserAdminOpState
& op_state
,
2454 RGWFormatterFlusher
& flusher
)
2458 int ret
= user
.init(store
, op_state
);
2463 ret
= user
.remove(op_state
, NULL
);
2466 ret
= -ERR_NO_SUCH_USER
;
2470 int RGWUserAdminOp_Subuser::create(RGWRados
*store
, RGWUserAdminOpState
& op_state
,
2471 RGWFormatterFlusher
& flusher
)
2475 int ret
= user
.init(store
, op_state
);
2479 if (!op_state
.has_existing_user())
2480 return -ERR_NO_SUCH_USER
;
2482 Formatter
*formatter
= flusher
.get_formatter();
2484 ret
= user
.subusers
.add(op_state
, NULL
);
2488 ret
= user
.info(info
, NULL
);
2494 dump_subusers_info(formatter
, info
);
2500 int RGWUserAdminOp_Subuser::modify(RGWRados
*store
, RGWUserAdminOpState
& op_state
,
2501 RGWFormatterFlusher
& flusher
)
2505 int ret
= user
.init(store
, op_state
);
2509 if (!op_state
.has_existing_user())
2510 return -ERR_NO_SUCH_USER
;
2512 Formatter
*formatter
= flusher
.get_formatter();
2514 ret
= user
.subusers
.modify(op_state
, NULL
);
2518 ret
= user
.info(info
, NULL
);
2524 dump_subusers_info(formatter
, info
);
2530 int RGWUserAdminOp_Subuser::remove(RGWRados
*store
, RGWUserAdminOpState
& op_state
,
2531 RGWFormatterFlusher
& flusher
)
2535 int ret
= user
.init(store
, op_state
);
2540 if (!op_state
.has_existing_user())
2541 return -ERR_NO_SUCH_USER
;
2543 ret
= user
.subusers
.remove(op_state
, NULL
);
2550 int RGWUserAdminOp_Key::create(RGWRados
*store
, RGWUserAdminOpState
& op_state
,
2551 RGWFormatterFlusher
& flusher
)
2555 int ret
= user
.init(store
, op_state
);
2559 if (!op_state
.has_existing_user())
2560 return -ERR_NO_SUCH_USER
;
2562 Formatter
*formatter
= flusher
.get_formatter();
2564 ret
= user
.keys
.add(op_state
, NULL
);
2568 ret
= user
.info(info
, NULL
);
2574 int key_type
= op_state
.get_key_type();
2576 if (key_type
== KEY_TYPE_SWIFT
)
2577 dump_swift_keys_info(formatter
, info
);
2579 else if (key_type
== KEY_TYPE_S3
)
2580 dump_access_keys_info(formatter
, info
);
2587 int RGWUserAdminOp_Key::remove(RGWRados
*store
, RGWUserAdminOpState
& op_state
,
2588 RGWFormatterFlusher
& flusher
)
2592 int ret
= user
.init(store
, op_state
);
2596 if (!op_state
.has_existing_user())
2597 return -ERR_NO_SUCH_USER
;
2600 ret
= user
.keys
.remove(op_state
, NULL
);
2607 int RGWUserAdminOp_Caps::add(RGWRados
*store
, RGWUserAdminOpState
& op_state
,
2608 RGWFormatterFlusher
& flusher
)
2612 int ret
= user
.init(store
, op_state
);
2616 if (!op_state
.has_existing_user())
2617 return -ERR_NO_SUCH_USER
;
2619 Formatter
*formatter
= flusher
.get_formatter();
2621 ret
= user
.caps
.add(op_state
, NULL
);
2625 ret
= user
.info(info
, NULL
);
2631 info
.caps
.dump(formatter
);
2638 int RGWUserAdminOp_Caps::remove(RGWRados
*store
, RGWUserAdminOpState
& op_state
,
2639 RGWFormatterFlusher
& flusher
)
2643 int ret
= user
.init(store
, op_state
);
2647 if (!op_state
.has_existing_user())
2648 return -ERR_NO_SUCH_USER
;
2650 Formatter
*formatter
= flusher
.get_formatter();
2652 ret
= user
.caps
.remove(op_state
, NULL
);
2656 ret
= user
.info(info
, NULL
);
2662 info
.caps
.dump(formatter
);
2668 struct RGWUserCompleteInfo
{
2670 map
<string
, bufferlist
> attrs
;
2673 RGWUserCompleteInfo()
2677 void dump(Formatter
* const f
) const {
2679 encode_json("attrs", attrs
, f
);
2682 void decode_json(JSONObj
*obj
) {
2683 decode_json_obj(info
, obj
);
2684 has_attrs
= JSONDecoder::decode_json("attrs", attrs
, obj
);
2688 class RGWUserMetadataObject
: public RGWMetadataObject
{
2689 RGWUserCompleteInfo uci
;
2691 RGWUserMetadataObject(const RGWUserCompleteInfo
& _uci
, obj_version
& v
, real_time m
)
2697 void dump(Formatter
*f
) const override
{
2702 class RGWUserMetadataHandler
: public RGWMetadataHandler
{
2704 string
get_type() override
{ return "user"; }
2706 int get(RGWRados
*store
, string
& entry
, RGWMetadataObject
**obj
) override
{
2707 RGWUserCompleteInfo uci
;
2708 RGWObjVersionTracker objv_tracker
;
2711 rgw_user
uid(entry
);
2713 int ret
= rgw_get_user_info_by_uid(store
, uid
, uci
.info
, &objv_tracker
,
2714 &mtime
, NULL
, &uci
.attrs
);
2719 RGWUserMetadataObject
*mdo
= new RGWUserMetadataObject(uci
, objv_tracker
.read_version
, mtime
);
2725 int put(RGWRados
*store
, string
& entry
, RGWObjVersionTracker
& objv_tracker
,
2726 real_time mtime
, JSONObj
*obj
, sync_type_t sync_mode
) override
{
2727 RGWUserCompleteInfo uci
;
2730 decode_json_obj(uci
, obj
);
2731 } catch (JSONDecoder::err
& e
) {
2735 map
<string
, bufferlist
> *pattrs
= NULL
;
2736 if (uci
.has_attrs
) {
2737 pattrs
= &uci
.attrs
;
2740 rgw_user
uid(entry
);
2742 RGWUserInfo old_info
;
2743 real_time orig_mtime
;
2744 int ret
= rgw_get_user_info_by_uid(store
, uid
, old_info
, &objv_tracker
, &orig_mtime
);
2745 if (ret
< 0 && ret
!= -ENOENT
)
2748 // are we actually going to perform this put, or is it too old?
2749 if (ret
!= -ENOENT
&&
2750 !check_versions(objv_tracker
.read_version
, orig_mtime
,
2751 objv_tracker
.write_version
, mtime
, sync_mode
)) {
2752 return STATUS_NO_APPLY
;
2755 ret
= rgw_store_user_info(store
, uci
.info
, &old_info
, &objv_tracker
, mtime
, false, pattrs
);
2760 return STATUS_APPLIED
;
2763 struct list_keys_info
{
2765 RGWListRawObjsCtx ctx
;
2768 int remove(RGWRados
*store
, string
& entry
, RGWObjVersionTracker
& objv_tracker
) override
{
2771 rgw_user
uid(entry
);
2773 int ret
= rgw_get_user_info_by_uid(store
, uid
, info
, &objv_tracker
);
2777 return rgw_delete_user(store
, info
, objv_tracker
);
2780 void get_pool_and_oid(RGWRados
*store
, const string
& key
, rgw_pool
& pool
, string
& oid
) override
{
2782 pool
= store
->get_zone_params().user_uid_pool
;
2785 int list_keys_init(RGWRados
*store
, const string
& marker
, void **phandle
) override
2787 auto info
= ceph::make_unique
<list_keys_info
>();
2789 info
->store
= store
;
2791 int ret
= store
->list_raw_objects_init(store
->get_zone_params().user_uid_pool
, marker
,
2797 *phandle
= (void *)info
.release();
2802 int list_keys_next(void *handle
, int max
, list
<string
>& keys
, bool *truncated
) override
{
2803 list_keys_info
*info
= static_cast<list_keys_info
*>(handle
);
2809 RGWRados
*store
= info
->store
;
2811 list
<string
> unfiltered_keys
;
2813 int ret
= store
->list_raw_objects_next(no_filter
, max
, info
->ctx
,
2814 unfiltered_keys
, truncated
);
2815 if (ret
< 0 && ret
!= -ENOENT
)
2817 if (ret
== -ENOENT
) {
2823 // now filter out the buckets entries
2824 list
<string
>::iterator iter
;
2825 for (iter
= unfiltered_keys
.begin(); iter
!= unfiltered_keys
.end(); ++iter
) {
2828 if (k
.find(".buckets") == string::npos
) {
2836 void list_keys_complete(void *handle
) override
{
2837 list_keys_info
*info
= static_cast<list_keys_info
*>(handle
);
2841 string
get_marker(void *handle
) {
2842 list_keys_info
*info
= static_cast<list_keys_info
*>(handle
);
2843 return info
->store
->list_raw_objs_get_cursor(info
->ctx
);
2847 void rgw_user_init(RGWRados
*store
)
2849 uinfo_cache
.init(store
);
2851 user_meta_handler
= new RGWUserMetadataHandler
;
2852 store
->meta_mgr
->register_handler(user_meta_handler
);