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
;
97 int rgw_user_get_all_buckets_stats(RGWRados
*store
, const rgw_user
& user_id
, map
<string
, cls_user_bucket_entry
>&buckets_usage_map
)
99 CephContext
*cct
= store
->ctx();
100 size_t max_entries
= cct
->_conf
->rgw_list_buckets_max_chunk
;
107 RGWUserBuckets user_buckets
;
108 ret
= rgw_read_user_buckets(store
, user_id
, user_buckets
, marker
,
109 string(), max_entries
, false, &is_truncated
);
111 ldout(cct
, 0) << "failed to read user buckets: ret=" << ret
<< dendl
;
114 map
<string
, RGWBucketEnt
>& buckets
= user_buckets
.get_buckets();
115 for (const auto& i
: buckets
) {
118 const RGWBucketEnt
& bucket_ent
= i
.second
;
119 cls_user_bucket_entry entry
;
120 ret
= store
->cls_user_get_bucket_stats(bucket_ent
.bucket
, entry
);
122 ldout(cct
, 0) << "ERROR: could not get bucket stats: ret=" << ret
<< dendl
;
125 buckets_usage_map
.emplace(bucket_ent
.bucket
.name
, entry
);
127 done
= (buckets
.size() < max_entries
);
134 * Save the given user information to storage.
135 * Returns: 0 on success, -ERR# on failure.
137 int rgw_store_user_info(RGWRados
*store
,
139 RGWUserInfo
*old_info
,
140 RGWObjVersionTracker
*objv_tracker
,
143 map
<string
, bufferlist
> *pattrs
)
146 RGWObjVersionTracker ot
;
152 if (ot
.write_version
.tag
.empty()) {
153 if (ot
.read_version
.tag
.empty()) {
154 ot
.generate_new_write_ver(store
->ctx());
156 ot
.write_version
= ot
.read_version
;
157 ot
.write_version
.ver
++;
161 map
<string
, RGWAccessKey
>::iterator iter
;
162 for (iter
= info
.swift_keys
.begin(); iter
!= info
.swift_keys
.end(); ++iter
) {
163 if (old_info
&& old_info
->swift_keys
.count(iter
->first
) != 0)
165 RGWAccessKey
& k
= iter
->second
;
166 /* check if swift mapping exists */
168 int r
= rgw_get_user_info_by_swift(store
, k
.id
, inf
);
169 if (r
>= 0 && inf
.user_id
.compare(info
.user_id
) != 0) {
170 ldout(store
->ctx(), 0) << "WARNING: can't store user info, swift id (" << k
.id
171 << ") already mapped to another user (" << info
.user_id
<< ")" << dendl
;
176 if (!info
.access_keys
.empty()) {
177 /* check if access keys already exist */
179 map
<string
, RGWAccessKey
>::iterator iter
= info
.access_keys
.begin();
180 for (; iter
!= info
.access_keys
.end(); ++iter
) {
181 RGWAccessKey
& k
= iter
->second
;
182 if (old_info
&& old_info
->access_keys
.count(iter
->first
) != 0)
184 int r
= rgw_get_user_info_by_access_key(store
, k
.id
, inf
);
185 if (r
>= 0 && inf
.user_id
.compare(info
.user_id
) != 0) {
186 ldout(store
->ctx(), 0) << "WARNING: can't store user info, access key already mapped to another user" << dendl
;
193 ui
.user_id
= info
.user_id
;
196 ::encode(ui
, link_bl
);
199 ::encode(ui
, data_bl
);
200 ::encode(info
, data_bl
);
203 info
.user_id
.to_str(key
);
205 ret
= store
->meta_mgr
->put_entry(user_meta_handler
, key
, data_bl
, exclusive
, &ot
, mtime
, pattrs
);
209 if (!info
.user_email
.empty()) {
211 old_info
->user_email
.compare(info
.user_email
) != 0) { /* only if new index changed */
212 ret
= rgw_put_system_obj(store
, store
->get_zone_params().user_email_pool
, info
.user_email
,
213 link_bl
.c_str(), link_bl
.length(), exclusive
, NULL
, real_time());
219 if (!info
.access_keys
.empty()) {
220 map
<string
, RGWAccessKey
>::iterator iter
= info
.access_keys
.begin();
221 for (; iter
!= info
.access_keys
.end(); ++iter
) {
222 RGWAccessKey
& k
= iter
->second
;
223 if (old_info
&& old_info
->access_keys
.count(iter
->first
) != 0)
226 ret
= rgw_put_system_obj(store
, store
->get_zone_params().user_keys_pool
, k
.id
,
227 link_bl
.c_str(), link_bl
.length(), exclusive
,
234 map
<string
, RGWAccessKey
>::iterator siter
;
235 for (siter
= info
.swift_keys
.begin(); siter
!= info
.swift_keys
.end(); ++siter
) {
236 RGWAccessKey
& k
= siter
->second
;
237 if (old_info
&& old_info
->swift_keys
.count(siter
->first
) != 0)
240 ret
= rgw_put_system_obj(store
, store
->get_zone_params().user_swift_pool
, k
.id
,
241 link_bl
.c_str(), link_bl
.length(), exclusive
,
250 struct user_info_entry
{
252 RGWObjVersionTracker objv_tracker
;
256 static RGWChainedCacheImpl
<user_info_entry
> uinfo_cache
;
258 int rgw_get_user_info_from_index(RGWRados
* const store
,
262 RGWObjVersionTracker
* const objv_tracker
,
263 real_time
* const pmtime
)
266 if (uinfo_cache
.find(key
, &e
)) {
269 *objv_tracker
= e
.objv_tracker
;
277 RGWObjectCtx
obj_ctx(store
);
279 int ret
= rgw_get_system_obj(store
, obj_ctx
, pool
, key
, bl
, NULL
, &e
.mtime
);
283 rgw_cache_entry_info cache_info
;
285 bufferlist::iterator iter
= bl
.begin();
288 int ret
= rgw_get_user_info_by_uid(store
, uid
.user_id
, e
.info
, &e
.objv_tracker
, NULL
, &cache_info
);
292 } catch (buffer::error
& err
) {
293 ldout(store
->ctx(), 0) << "ERROR: failed to decode user info, caught buffer::error" << dendl
;
297 list
<rgw_cache_entry_info
*> cache_info_entries
;
298 cache_info_entries
.push_back(&cache_info
);
300 uinfo_cache
.put(store
, key
, &e
, cache_info_entries
);
304 *objv_tracker
= e
.objv_tracker
;
312 * Given a uid, finds the user info associated with it.
313 * returns: 0 on success, -ERR# on failure (including nonexistence)
315 int rgw_get_user_info_by_uid(RGWRados
*store
,
318 RGWObjVersionTracker
* const objv_tracker
,
319 real_time
* const pmtime
,
320 rgw_cache_entry_info
* const cache_info
,
321 map
<string
, bufferlist
> * const pattrs
)
326 RGWObjectCtx
obj_ctx(store
);
327 string oid
= uid
.to_str();
328 int ret
= rgw_get_system_obj(store
, obj_ctx
, store
->get_zone_params().user_uid_pool
, oid
, bl
, objv_tracker
, pmtime
, pattrs
, cache_info
);
333 bufferlist::iterator iter
= bl
.begin();
335 ::decode(user_id
, iter
);
336 if (user_id
.user_id
.compare(uid
) != 0) {
337 lderr(store
->ctx()) << "ERROR: rgw_get_user_info_by_uid(): user id mismatch: " << user_id
.user_id
<< " != " << uid
<< dendl
;
341 ::decode(info
, iter
);
343 } catch (buffer::error
& err
) {
344 ldout(store
->ctx(), 0) << "ERROR: failed to decode user info, caught buffer::error" << dendl
;
352 * Given an email, finds the user info associated with it.
353 * returns: 0 on success, -ERR# on failure (including nonexistence)
355 int rgw_get_user_info_by_email(RGWRados
*store
, string
& email
, RGWUserInfo
& info
,
356 RGWObjVersionTracker
*objv_tracker
, real_time
*pmtime
)
358 return rgw_get_user_info_from_index(store
, email
, store
->get_zone_params().user_email_pool
, info
, objv_tracker
, pmtime
);
362 * Given an swift username, finds the user_info associated with it.
363 * returns: 0 on success, -ERR# on failure (including nonexistence)
365 extern int rgw_get_user_info_by_swift(RGWRados
* const store
,
366 const string
& swift_name
,
367 RGWUserInfo
& info
, /* out */
368 RGWObjVersionTracker
* const objv_tracker
,
369 real_time
* const pmtime
)
371 return rgw_get_user_info_from_index(store
, swift_name
,
372 store
->get_zone_params().user_swift_pool
,
373 info
, objv_tracker
, pmtime
);
377 * Given an access key, finds the user info associated with it.
378 * returns: 0 on success, -ERR# on failure (including nonexistence)
380 extern int rgw_get_user_info_by_access_key(RGWRados
* store
,
381 const std::string
& access_key
,
383 RGWObjVersionTracker
* objv_tracker
,
386 return rgw_get_user_info_from_index(store
, access_key
,
387 store
->get_zone_params().user_keys_pool
,
388 info
, objv_tracker
, pmtime
);
391 int rgw_get_user_attrs_by_uid(RGWRados
*store
,
392 const rgw_user
& user_id
,
393 map
<string
, bufferlist
>& attrs
,
394 RGWObjVersionTracker
*objv_tracker
)
396 RGWObjectCtx
obj_ctx(store
);
397 rgw_raw_obj
obj(store
->get_zone_params().user_uid_pool
, user_id
.to_str());
398 RGWRados::SystemObject
src(store
, obj_ctx
, obj
);
399 RGWRados::SystemObject::Read
rop(&src
);
401 rop
.stat_params
.attrs
= &attrs
;
402 return rop
.stat(objv_tracker
);
405 int rgw_remove_key_index(RGWRados
*store
, RGWAccessKey
& access_key
)
407 rgw_raw_obj
obj(store
->get_zone_params().user_keys_pool
, access_key
.id
);
408 int ret
= store
->delete_system_obj(obj
);
412 int rgw_remove_uid_index(RGWRados
*store
, rgw_user
& uid
)
414 RGWObjVersionTracker objv_tracker
;
416 int ret
= rgw_get_user_info_by_uid(store
, uid
, info
, &objv_tracker
, NULL
);
420 string oid
= uid
.to_str();
421 ret
= store
->meta_mgr
->remove_entry(user_meta_handler
, oid
, &objv_tracker
);
428 int rgw_remove_email_index(RGWRados
*store
, string
& email
)
433 rgw_raw_obj
obj(store
->get_zone_params().user_email_pool
, email
);
434 return store
->delete_system_obj(obj
);
437 int rgw_remove_swift_name_index(RGWRados
*store
, string
& swift_name
)
439 rgw_raw_obj
obj(store
->get_zone_params().user_swift_pool
, swift_name
);
440 int ret
= store
->delete_system_obj(obj
);
445 * delete a user's presence from the RGW system.
446 * First remove their bucket ACLs, then delete them
447 * from the user and user email pools. This leaves the pools
448 * themselves alone, as well as any ACLs embedded in object xattrs.
450 int rgw_delete_user(RGWRados
*store
, RGWUserInfo
& info
, RGWObjVersionTracker
& objv_tracker
) {
453 map
<string
, RGWAccessKey
>::iterator kiter
= info
.access_keys
.begin();
454 for (; kiter
!= info
.access_keys
.end(); ++kiter
) {
455 ldout(store
->ctx(), 10) << "removing key index: " << kiter
->first
<< dendl
;
456 ret
= rgw_remove_key_index(store
, kiter
->second
);
457 if (ret
< 0 && ret
!= -ENOENT
) {
458 ldout(store
->ctx(), 0) << "ERROR: could not remove " << kiter
->first
<< " (access key object), should be fixed (err=" << ret
<< ")" << dendl
;
463 map
<string
, RGWAccessKey
>::iterator siter
= info
.swift_keys
.begin();
464 for (; siter
!= info
.swift_keys
.end(); ++siter
) {
465 RGWAccessKey
& k
= siter
->second
;
466 ldout(store
->ctx(), 10) << "removing swift subuser index: " << k
.id
<< dendl
;
467 /* check if swift mapping exists */
468 ret
= rgw_remove_swift_name_index(store
, k
.id
);
469 if (ret
< 0 && ret
!= -ENOENT
) {
470 ldout(store
->ctx(), 0) << "ERROR: could not remove " << k
.id
<< " (swift name object), should be fixed (err=" << ret
<< ")" << dendl
;
475 ldout(store
->ctx(), 10) << "removing email index: " << info
.user_email
<< dendl
;
476 ret
= rgw_remove_email_index(store
, info
.user_email
);
477 if (ret
< 0 && ret
!= -ENOENT
) {
478 ldout(store
->ctx(), 0) << "ERROR: could not remove email index object for "
479 << info
.user_email
<< ", should be fixed (err=" << ret
<< ")" << dendl
;
483 string buckets_obj_id
;
484 rgw_get_buckets_obj(info
.user_id
, buckets_obj_id
);
485 rgw_raw_obj
uid_bucks(store
->get_zone_params().user_uid_pool
, buckets_obj_id
);
486 ldout(store
->ctx(), 10) << "removing user buckets index" << dendl
;
487 ret
= store
->delete_system_obj(uid_bucks
);
488 if (ret
< 0 && ret
!= -ENOENT
) {
489 ldout(store
->ctx(), 0) << "ERROR: could not remove " << info
.user_id
<< ":" << uid_bucks
<< ", should be fixed (err=" << ret
<< ")" << dendl
;
494 info
.user_id
.to_str(key
);
496 rgw_raw_obj
uid_obj(store
->get_zone_params().user_uid_pool
, key
);
497 ldout(store
->ctx(), 10) << "removing user index: " << info
.user_id
<< dendl
;
498 ret
= store
->meta_mgr
->remove_entry(user_meta_handler
, key
, &objv_tracker
);
499 if (ret
< 0 && ret
!= -ENOENT
&& ret
!= -ECANCELED
) {
500 ldout(store
->ctx(), 0) << "ERROR: could not remove " << info
.user_id
<< ":" << uid_obj
<< ", should be fixed (err=" << ret
<< ")" << dendl
;
507 static bool char_is_unreserved_url(char c
)
523 struct rgw_flags_desc
{
528 static struct rgw_flags_desc rgw_perms
[] = {
529 { RGW_PERM_FULL_CONTROL
, "full-control" },
530 { RGW_PERM_READ
| RGW_PERM_WRITE
, "read-write" },
531 { RGW_PERM_READ
, "read" },
532 { RGW_PERM_WRITE
, "write" },
533 { RGW_PERM_READ_ACP
, "read-acp" },
534 { RGW_PERM_WRITE_ACP
, "read-acp" },
538 void rgw_perm_to_str(uint32_t mask
, char *buf
, int len
)
540 const char *sep
= "";
543 snprintf(buf
, len
, "<none>");
547 uint32_t orig_mask
= mask
;
548 for (int i
= 0; rgw_perms
[i
].mask
; i
++) {
549 struct rgw_flags_desc
*desc
= &rgw_perms
[i
];
550 if ((mask
& desc
->mask
) == desc
->mask
) {
551 pos
+= snprintf(buf
+ pos
, len
- pos
, "%s%s", sep
, desc
->str
);
560 if (mask
== orig_mask
) // no change
565 uint32_t rgw_str_to_perm(const char *str
)
567 if (strcasecmp(str
, "") == 0)
568 return RGW_PERM_NONE
;
569 else if (strcasecmp(str
, "read") == 0)
570 return RGW_PERM_READ
;
571 else if (strcasecmp(str
, "write") == 0)
572 return RGW_PERM_WRITE
;
573 else if (strcasecmp(str
, "readwrite") == 0)
574 return RGW_PERM_READ
| RGW_PERM_WRITE
;
575 else if (strcasecmp(str
, "full") == 0)
576 return RGW_PERM_FULL_CONTROL
;
578 return RGW_PERM_INVALID
;
581 int rgw_validate_tenant_name(const string
& t
)
584 static bool is_good(char ch
) {
585 return isalnum(ch
) || ch
== '_';
588 std::string::const_iterator it
=
589 std::find_if_not(t
.begin(), t
.end(), tench::is_good
);
590 return (it
== t
.end())? 0: -ERR_INVALID_TENANT_NAME
;
593 static bool validate_access_key(string
& key
)
595 const char *p
= key
.c_str();
597 if (!char_is_unreserved_url(*p
))
604 static void set_err_msg(std::string
*sink
, std::string msg
)
606 if (sink
&& !msg
.empty())
610 static bool remove_old_indexes(RGWRados
*store
,
611 RGWUserInfo
& old_info
, RGWUserInfo
& new_info
, std::string
*err_msg
)
616 if (!old_info
.user_id
.empty() &&
617 old_info
.user_id
.compare(new_info
.user_id
) != 0) {
618 if (old_info
.user_id
.tenant
!= new_info
.user_id
.tenant
) {
619 ldout(store
->ctx(), 0) << "ERROR: tenant mismatch: " << old_info
.user_id
.tenant
<< " != " << new_info
.user_id
.tenant
<< dendl
;
622 ret
= rgw_remove_uid_index(store
, old_info
.user_id
);
623 if (ret
< 0 && ret
!= -ENOENT
) {
624 set_err_msg(err_msg
, "ERROR: could not remove index for uid " + old_info
.user_id
.to_str());
629 if (!old_info
.user_email
.empty() &&
630 old_info
.user_email
.compare(new_info
.user_email
) != 0) {
631 ret
= rgw_remove_email_index(store
, old_info
.user_email
);
632 if (ret
< 0 && ret
!= -ENOENT
) {
633 set_err_msg(err_msg
, "ERROR: could not remove index for email " + old_info
.user_email
);
638 map
<string
, RGWAccessKey
>::iterator old_iter
;
639 for (old_iter
= old_info
.swift_keys
.begin(); old_iter
!= old_info
.swift_keys
.end(); ++old_iter
) {
640 RGWAccessKey
& swift_key
= old_iter
->second
;
641 map
<string
, RGWAccessKey
>::iterator new_iter
= new_info
.swift_keys
.find(swift_key
.id
);
642 if (new_iter
== new_info
.swift_keys
.end()) {
643 ret
= rgw_remove_swift_name_index(store
, swift_key
.id
);
644 if (ret
< 0 && ret
!= -ENOENT
) {
645 set_err_msg(err_msg
, "ERROR: could not remove index for swift_name " + swift_key
.id
);
655 * Dump either the full user info or a subset to a formatter.
657 * NOTE: It is the caller's respnsibility to ensure that the
658 * formatter is flushed at the correct time.
661 static void dump_subusers_info(Formatter
*f
, RGWUserInfo
&info
)
663 map
<string
, RGWSubUser
>::iterator uiter
;
665 f
->open_array_section("subusers");
666 for (uiter
= info
.subusers
.begin(); uiter
!= info
.subusers
.end(); ++uiter
) {
667 RGWSubUser
& u
= uiter
->second
;
668 f
->open_object_section("user");
670 info
.user_id
.to_str(s
);
671 f
->dump_format("id", "%s:%s", s
.c_str(), u
.name
.c_str());
673 rgw_perm_to_str(u
.perm_mask
, buf
, sizeof(buf
));
674 f
->dump_string("permissions", buf
);
680 static void dump_access_keys_info(Formatter
*f
, RGWUserInfo
&info
)
682 map
<string
, RGWAccessKey
>::iterator kiter
;
683 f
->open_array_section("keys");
684 for (kiter
= info
.access_keys
.begin(); kiter
!= info
.access_keys
.end(); ++kiter
) {
685 RGWAccessKey
& k
= kiter
->second
;
686 const char *sep
= (k
.subuser
.empty() ? "" : ":");
687 const char *subuser
= (k
.subuser
.empty() ? "" : k
.subuser
.c_str());
688 f
->open_object_section("key");
690 info
.user_id
.to_str(s
);
691 f
->dump_format("user", "%s%s%s", s
.c_str(), sep
, subuser
);
692 f
->dump_string("access_key", k
.id
);
693 f
->dump_string("secret_key", k
.key
);
699 static void dump_swift_keys_info(Formatter
*f
, RGWUserInfo
&info
)
701 map
<string
, RGWAccessKey
>::iterator kiter
;
702 f
->open_array_section("swift_keys");
703 for (kiter
= info
.swift_keys
.begin(); kiter
!= info
.swift_keys
.end(); ++kiter
) {
704 RGWAccessKey
& k
= kiter
->second
;
705 const char *sep
= (k
.subuser
.empty() ? "" : ":");
706 const char *subuser
= (k
.subuser
.empty() ? "" : k
.subuser
.c_str());
707 f
->open_object_section("key");
709 info
.user_id
.to_str(s
);
710 f
->dump_format("user", "%s%s%s", s
.c_str(), sep
, subuser
);
711 f
->dump_string("secret_key", k
.key
);
717 static void dump_user_info(Formatter
*f
, RGWUserInfo
&info
,
718 RGWStorageStats
*stats
= NULL
)
720 f
->open_object_section("user_info");
722 f
->dump_string("tenant", info
.user_id
.tenant
);
723 f
->dump_string("user_id", info
.user_id
.id
);
724 f
->dump_string("display_name", info
.display_name
);
725 f
->dump_string("email", info
.user_email
);
726 f
->dump_int("suspended", (int)info
.suspended
);
727 f
->dump_int("max_buckets", (int)info
.max_buckets
);
729 dump_subusers_info(f
, info
);
730 dump_access_keys_info(f
, info
);
731 dump_swift_keys_info(f
, info
);
734 encode_json("stats", *stats
, f
);
741 RGWAccessKeyPool::RGWAccessKeyPool(RGWUser
* usr
)
748 keys_allowed
= false;
755 store
= user
->get_store();
758 RGWAccessKeyPool::~RGWAccessKeyPool()
763 int RGWAccessKeyPool::init(RGWUserAdminOpState
& op_state
)
765 if (!op_state
.is_initialized()) {
766 keys_allowed
= false;
770 rgw_user
& uid
= op_state
.get_user_id();
771 if (uid
.compare(RGW_USER_ANON_ID
) == 0) {
772 keys_allowed
= false;
776 swift_keys
= op_state
.get_swift_keys();
777 access_keys
= op_state
.get_access_keys();
785 * Do a fairly exhaustive search for an existing key matching the parameters
786 * given. Also handles the case where no key type was specified and updates
787 * the operation state if needed.
790 bool RGWAccessKeyPool::check_existing_key(RGWUserAdminOpState
& op_state
)
792 bool existing_key
= false;
794 int key_type
= op_state
.get_key_type();
795 std::string kid
= op_state
.get_access_key();
796 std::map
<std::string
, RGWAccessKey
>::iterator kiter
;
797 std::string swift_kid
= op_state
.build_default_swift_kid();
799 RGWUserInfo dup_info
;
801 if (kid
.empty() && swift_kid
.empty())
806 kiter
= swift_keys
->find(swift_kid
);
808 existing_key
= (kiter
!= swift_keys
->end());
810 op_state
.set_access_key(swift_kid
);
814 kiter
= access_keys
->find(kid
);
815 existing_key
= (kiter
!= access_keys
->end());
819 kiter
= access_keys
->find(kid
);
821 existing_key
= (kiter
!= access_keys
->end());
823 op_state
.set_key_type(KEY_TYPE_S3
);
827 kiter
= swift_keys
->find(kid
);
829 existing_key
= (kiter
!= swift_keys
->end());
831 op_state
.set_key_type(KEY_TYPE_SWIFT
);
835 // handle the case where the access key was not provided in user:key format
836 if (swift_kid
.empty())
839 kiter
= swift_keys
->find(swift_kid
);
841 existing_key
= (kiter
!= swift_keys
->end());
843 op_state
.set_access_key(swift_kid
);
844 op_state
.set_key_type(KEY_TYPE_SWIFT
);
848 op_state
.set_existing_key(existing_key
);
853 int RGWAccessKeyPool::check_op(RGWUserAdminOpState
& op_state
,
854 std::string
*err_msg
)
856 RGWUserInfo dup_info
;
858 if (!op_state
.is_populated()) {
859 set_err_msg(err_msg
, "user info was not populated");
864 set_err_msg(err_msg
, "keys not allowed for this user");
868 int32_t key_type
= op_state
.get_key_type();
870 // if a key type wasn't specified
872 if (op_state
.has_subuser()) {
873 key_type
= KEY_TYPE_SWIFT
;
875 key_type
= KEY_TYPE_S3
;
879 op_state
.set_key_type(key_type
);
881 /* see if the access key was specified */
882 if (key_type
== KEY_TYPE_S3
&& !op_state
.will_gen_access() &&
883 op_state
.get_access_key().empty()) {
884 set_err_msg(err_msg
, "empty access key");
885 return -ERR_INVALID_ACCESS_KEY
;
888 // don't check for secret key because we may be doing a removal
890 check_existing_key(op_state
);
895 // Generate a new random key
896 int RGWAccessKeyPool::generate_key(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
901 std::pair
<std::string
, RGWAccessKey
> key_pair
;
902 RGWAccessKey new_key
;
903 RGWUserInfo duplicate_check
;
906 int key_type
= op_state
.get_key_type();
907 bool gen_access
= op_state
.will_gen_access();
908 bool gen_secret
= op_state
.will_gen_secret();
911 set_err_msg(err_msg
, "access keys not allowed for this user");
915 if (op_state
.has_existing_key()) {
916 set_err_msg(err_msg
, "cannot create existing key");
917 return -ERR_KEY_EXIST
;
921 id
= op_state
.get_access_key();
927 if (rgw_get_user_info_by_swift(store
, id
, duplicate_check
) >= 0) {
928 set_err_msg(err_msg
, "existing swift key in RGW system:" + id
);
929 return -ERR_KEY_EXIST
;
933 if (rgw_get_user_info_by_access_key(store
, id
, duplicate_check
) >= 0) {
934 set_err_msg(err_msg
, "existing S3 key in RGW system:" + id
);
935 return -ERR_KEY_EXIST
;
941 if (op_state
.has_subuser()) {
942 //create user and subuser at the same time, user's s3 key should not be set this
943 if (!op_state
.key_type_setbycontext
|| (key_type
== KEY_TYPE_SWIFT
)) {
944 new_key
.subuser
= op_state
.get_subuser();
950 if (op_state
.get_secret_key().empty()) {
951 set_err_msg(err_msg
, "empty secret key");
952 return -ERR_INVALID_SECRET_KEY
;
955 key
= op_state
.get_secret_key();
957 char secret_key_buf
[SECRET_KEY_LEN
+ 1];
959 ret
= gen_rand_alphanumeric_plain(g_ceph_context
, secret_key_buf
, sizeof(secret_key_buf
));
961 set_err_msg(err_msg
, "unable to generate secret key");
965 key
= secret_key_buf
;
968 // Generate the access key
969 if (key_type
== KEY_TYPE_S3
&& gen_access
) {
970 char public_id_buf
[PUBLIC_ID_LEN
+ 1];
973 int id_buf_size
= sizeof(public_id_buf
);
974 ret
= gen_rand_alphanumeric_upper(g_ceph_context
,
975 public_id_buf
, id_buf_size
);
978 set_err_msg(err_msg
, "unable to generate access key");
983 if (!validate_access_key(id
))
986 } while (!rgw_get_user_info_by_access_key(store
, id
, duplicate_check
));
989 if (key_type
== KEY_TYPE_SWIFT
) {
990 id
= op_state
.build_default_swift_kid();
992 set_err_msg(err_msg
, "empty swift access key");
993 return -ERR_INVALID_ACCESS_KEY
;
996 // check that the access key doesn't exist
997 if (rgw_get_user_info_by_swift(store
, id
, duplicate_check
) >= 0) {
998 set_err_msg(err_msg
, "cannot create existing swift key");
999 return -ERR_KEY_EXIST
;
1003 // finally create the new key
1007 key_pair
.first
= id
;
1008 key_pair
.second
= new_key
;
1010 if (key_type
== KEY_TYPE_S3
) {
1011 access_keys
->insert(key_pair
);
1012 } else if (key_type
== KEY_TYPE_SWIFT
) {
1013 swift_keys
->insert(key_pair
);
1019 // modify an existing key
1020 int RGWAccessKeyPool::modify_key(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1023 std::string key
= op_state
.get_secret_key();
1024 int key_type
= op_state
.get_key_type();
1026 RGWAccessKey modify_key
;
1028 pair
<string
, RGWAccessKey
> key_pair
;
1029 map
<std::string
, RGWAccessKey
>::iterator kiter
;
1033 id
= op_state
.get_access_key();
1035 set_err_msg(err_msg
, "no access key specified");
1036 return -ERR_INVALID_ACCESS_KEY
;
1039 case KEY_TYPE_SWIFT
:
1040 id
= op_state
.build_default_swift_kid();
1042 set_err_msg(err_msg
, "no subuser specified");
1047 set_err_msg(err_msg
, "invalid key type");
1048 return -ERR_INVALID_KEY_TYPE
;
1051 if (!op_state
.has_existing_key()) {
1052 set_err_msg(err_msg
, "key does not exist");
1053 return -ERR_INVALID_ACCESS_KEY
;
1056 key_pair
.first
= id
;
1058 if (key_type
== KEY_TYPE_SWIFT
) {
1060 modify_key
.subuser
= op_state
.get_subuser();
1061 } else if (key_type
== KEY_TYPE_S3
) {
1062 kiter
= access_keys
->find(id
);
1063 if (kiter
!= access_keys
->end()) {
1064 modify_key
= kiter
->second
;
1068 if (op_state
.will_gen_secret()) {
1069 char secret_key_buf
[SECRET_KEY_LEN
+ 1];
1072 int key_buf_size
= sizeof(secret_key_buf
);
1073 ret
= gen_rand_alphanumeric_plain(g_ceph_context
, secret_key_buf
, key_buf_size
);
1075 set_err_msg(err_msg
, "unable to generate secret key");
1079 key
= secret_key_buf
;
1083 set_err_msg(err_msg
, "empty secret key");
1084 return -ERR_INVALID_SECRET_KEY
;
1087 // update the access key with the new secret key
1088 modify_key
.key
= key
;
1090 key_pair
.second
= modify_key
;
1093 if (key_type
== KEY_TYPE_S3
) {
1094 (*access_keys
)[id
] = modify_key
;
1095 } else if (key_type
== KEY_TYPE_SWIFT
) {
1096 (*swift_keys
)[id
] = modify_key
;
1102 int RGWAccessKeyPool::execute_add(RGWUserAdminOpState
& op_state
,
1103 std::string
*err_msg
, bool defer_user_update
)
1107 std::string subprocess_msg
;
1108 int key_op
= GENERATE_KEY
;
1111 if (op_state
.has_existing_key())
1112 key_op
= MODIFY_KEY
;
1116 ret
= generate_key(op_state
, &subprocess_msg
);
1119 ret
= modify_key(op_state
, &subprocess_msg
);
1124 set_err_msg(err_msg
, subprocess_msg
);
1128 // store the updated info
1129 if (!defer_user_update
)
1130 ret
= user
->update(op_state
, err_msg
);
1138 int RGWAccessKeyPool::add(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1140 return add(op_state
, err_msg
, false);
1143 int RGWAccessKeyPool::add(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_user_update
)
1146 std::string subprocess_msg
;
1148 ret
= check_op(op_state
, &subprocess_msg
);
1150 set_err_msg(err_msg
, "unable to parse request, " + subprocess_msg
);
1154 ret
= execute_add(op_state
, &subprocess_msg
, defer_user_update
);
1156 set_err_msg(err_msg
, "unable to add access key, " + subprocess_msg
);
1163 int RGWAccessKeyPool::execute_remove(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_user_update
)
1167 int key_type
= op_state
.get_key_type();
1168 std::string id
= op_state
.get_access_key();
1169 map
<std::string
, RGWAccessKey
>::iterator kiter
;
1170 map
<std::string
, RGWAccessKey
> *keys_map
;
1172 if (!op_state
.has_existing_key()) {
1173 set_err_msg(err_msg
, "unable to find access key");
1174 return -ERR_INVALID_ACCESS_KEY
;
1177 if (key_type
== KEY_TYPE_S3
) {
1178 keys_map
= access_keys
;
1179 } else if (key_type
== KEY_TYPE_SWIFT
) {
1180 keys_map
= swift_keys
;
1183 set_err_msg(err_msg
, "invalid access key");
1184 return -ERR_INVALID_ACCESS_KEY
;
1187 kiter
= keys_map
->find(id
);
1188 if (kiter
== keys_map
->end()) {
1189 set_err_msg(err_msg
, "key not found");
1190 return -ERR_INVALID_ACCESS_KEY
;
1193 rgw_remove_key_index(store
, kiter
->second
);
1194 keys_map
->erase(kiter
);
1196 if (!defer_user_update
)
1197 ret
= user
->update(op_state
, err_msg
);
1205 int RGWAccessKeyPool::remove(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1207 return remove(op_state
, err_msg
, false);
1210 int RGWAccessKeyPool::remove(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_user_update
)
1214 std::string subprocess_msg
;
1216 ret
= check_op(op_state
, &subprocess_msg
);
1218 set_err_msg(err_msg
, "unable to parse request, " + subprocess_msg
);
1222 ret
= execute_remove(op_state
, &subprocess_msg
, defer_user_update
);
1224 set_err_msg(err_msg
, "unable to remove access key, " + subprocess_msg
);
1231 // remove all keys associated with a subuser
1232 int RGWAccessKeyPool::remove_subuser_keys(RGWUserAdminOpState
& op_state
,
1233 std::string
*err_msg
, bool defer_user_update
)
1237 if (!op_state
.is_populated()) {
1238 set_err_msg(err_msg
, "user info was not populated");
1242 if (!op_state
.has_subuser()) {
1243 set_err_msg(err_msg
, "no subuser specified");
1247 std::string swift_kid
= op_state
.build_default_swift_kid();
1248 if (swift_kid
.empty()) {
1249 set_err_msg(err_msg
, "empty swift access key");
1253 map
<std::string
, RGWAccessKey
>::iterator kiter
;
1254 map
<std::string
, RGWAccessKey
> *keys_map
;
1256 // a subuser can have at most one swift key
1257 keys_map
= swift_keys
;
1258 kiter
= keys_map
->find(swift_kid
);
1259 if (kiter
!= keys_map
->end()) {
1260 rgw_remove_key_index(store
, kiter
->second
);
1261 keys_map
->erase(kiter
);
1264 // a subuser may have multiple s3 key pairs
1265 std::string subuser_str
= op_state
.get_subuser();
1266 keys_map
= access_keys
;
1267 RGWUserInfo user_info
= op_state
.get_user_info();
1268 map
<std::string
, RGWAccessKey
>::iterator user_kiter
= user_info
.access_keys
.begin();
1269 for (; user_kiter
!= user_info
.access_keys
.end(); ++user_kiter
) {
1270 if (user_kiter
->second
.subuser
== subuser_str
) {
1271 kiter
= keys_map
->find(user_kiter
->first
);
1272 if (kiter
!= keys_map
->end()) {
1273 rgw_remove_key_index(store
, kiter
->second
);
1274 keys_map
->erase(kiter
);
1279 if (!defer_user_update
)
1280 ret
= user
->update(op_state
, err_msg
);
1288 RGWSubUserPool::RGWSubUserPool(RGWUser
*usr
)
1290 subusers_allowed
= (usr
!= NULL
);
1292 store
= usr
->get_store();
1299 RGWSubUserPool::~RGWSubUserPool()
1304 int RGWSubUserPool::init(RGWUserAdminOpState
& op_state
)
1306 if (!op_state
.is_initialized()) {
1307 subusers_allowed
= false;
1311 rgw_user
& uid
= op_state
.get_user_id();
1312 if (uid
.compare(RGW_USER_ANON_ID
) == 0) {
1313 subusers_allowed
= false;
1317 subuser_map
= op_state
.get_subusers();
1318 if (subuser_map
== NULL
) {
1319 subusers_allowed
= false;
1323 subusers_allowed
= true;
1328 bool RGWSubUserPool::exists(std::string subuser
)
1330 if (subuser
.empty())
1336 if (subuser_map
->count(subuser
))
1342 int RGWSubUserPool::check_op(RGWUserAdminOpState
& op_state
,
1343 std::string
*err_msg
)
1345 bool existing
= false;
1346 std::string subuser
= op_state
.get_subuser();
1348 if (!op_state
.is_populated()) {
1349 set_err_msg(err_msg
, "user info was not populated");
1353 if (!subusers_allowed
) {
1354 set_err_msg(err_msg
, "subusers not allowed for this user");
1358 if (subuser
.empty() && !op_state
.will_gen_subuser()) {
1359 set_err_msg(err_msg
, "empty subuser name");
1363 if (op_state
.get_subuser_perm() == RGW_PERM_INVALID
) {
1364 set_err_msg(err_msg
, "invaild subuser access");
1368 //set key type when it not set or set by context
1369 if ((op_state
.get_key_type() < 0) || op_state
.key_type_setbycontext
) {
1370 op_state
.set_key_type(KEY_TYPE_SWIFT
);
1371 op_state
.key_type_setbycontext
= true;
1374 // check if the subuser exists
1375 if (!subuser
.empty())
1376 existing
= exists(subuser
);
1378 op_state
.set_existing_subuser(existing
);
1383 int RGWSubUserPool::execute_add(RGWUserAdminOpState
& op_state
,
1384 std::string
*err_msg
, bool defer_user_update
)
1387 std::string subprocess_msg
;
1390 std::pair
<std::string
, RGWSubUser
> subuser_pair
;
1391 std::string subuser_str
= op_state
.get_subuser();
1393 subuser_pair
.first
= subuser_str
;
1395 // assumes key should be created
1396 if (op_state
.has_key_op()) {
1397 ret
= user
->keys
.add(op_state
, &subprocess_msg
, true);
1399 set_err_msg(err_msg
, "unable to create subuser key, " + subprocess_msg
);
1404 // create the subuser
1405 subuser
.name
= subuser_str
;
1407 if (op_state
.has_subuser_perm())
1408 subuser
.perm_mask
= op_state
.get_subuser_perm();
1410 // insert the subuser into user info
1411 subuser_pair
.second
= subuser
;
1412 subuser_map
->insert(subuser_pair
);
1414 // attempt to save the subuser
1415 if (!defer_user_update
)
1416 ret
= user
->update(op_state
, err_msg
);
1424 int RGWSubUserPool::add(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1426 return add(op_state
, err_msg
, false);
1429 int RGWSubUserPool::add(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_user_update
)
1431 std::string subprocess_msg
;
1433 int32_t key_type
= op_state
.get_key_type();
1435 ret
= check_op(op_state
, &subprocess_msg
);
1437 set_err_msg(err_msg
, "unable to parse request, " + subprocess_msg
);
1441 if (key_type
== KEY_TYPE_S3
&& op_state
.get_access_key().empty()) {
1442 op_state
.set_gen_access();
1445 if (op_state
.get_secret_key().empty()) {
1446 op_state
.set_gen_secret();
1449 ret
= execute_add(op_state
, &subprocess_msg
, defer_user_update
);
1451 set_err_msg(err_msg
, "unable to create subuser, " + subprocess_msg
);
1458 int RGWSubUserPool::execute_remove(RGWUserAdminOpState
& op_state
,
1459 std::string
*err_msg
, bool defer_user_update
)
1462 std::string subprocess_msg
;
1464 std::string subuser_str
= op_state
.get_subuser();
1466 map
<std::string
, RGWSubUser
>::iterator siter
;
1467 siter
= subuser_map
->find(subuser_str
);
1468 if (siter
== subuser_map
->end()){
1469 set_err_msg(err_msg
, "subuser not found: " + subuser_str
);
1470 return -ERR_NO_SUCH_SUBUSER
;
1472 if (!op_state
.has_existing_subuser()) {
1473 set_err_msg(err_msg
, "subuser not found: " + subuser_str
);
1474 return -ERR_NO_SUCH_SUBUSER
;
1477 // always purge all associate keys
1478 user
->keys
.remove_subuser_keys(op_state
, &subprocess_msg
, true);
1480 // remove the subuser from the user info
1481 subuser_map
->erase(siter
);
1483 // attempt to save the subuser
1484 if (!defer_user_update
)
1485 ret
= user
->update(op_state
, err_msg
);
1493 int RGWSubUserPool::remove(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1495 return remove(op_state
, err_msg
, false);
1498 int RGWSubUserPool::remove(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_user_update
)
1500 std::string subprocess_msg
;
1503 ret
= check_op(op_state
, &subprocess_msg
);
1505 set_err_msg(err_msg
, "unable to parse request, " + subprocess_msg
);
1509 ret
= execute_remove(op_state
, &subprocess_msg
, defer_user_update
);
1511 set_err_msg(err_msg
, "unable to remove subuser, " + subprocess_msg
);
1518 int RGWSubUserPool::execute_modify(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_user_update
)
1521 std::string subprocess_msg
;
1522 std::map
<std::string
, RGWSubUser
>::iterator siter
;
1523 std::pair
<std::string
, RGWSubUser
> subuser_pair
;
1525 std::string subuser_str
= op_state
.get_subuser();
1528 if (!op_state
.has_existing_subuser()) {
1529 set_err_msg(err_msg
, "subuser does not exist");
1530 return -ERR_NO_SUCH_SUBUSER
;
1533 subuser_pair
.first
= subuser_str
;
1535 siter
= subuser_map
->find(subuser_str
);
1536 subuser
= siter
->second
;
1538 if (op_state
.has_key_op()) {
1539 ret
= user
->keys
.add(op_state
, &subprocess_msg
, true);
1541 set_err_msg(err_msg
, "unable to create subuser keys, " + subprocess_msg
);
1546 if (op_state
.has_subuser_perm())
1547 subuser
.perm_mask
= op_state
.get_subuser_perm();
1549 subuser_pair
.second
= subuser
;
1551 subuser_map
->erase(siter
);
1552 subuser_map
->insert(subuser_pair
);
1554 // attempt to save the subuser
1555 if (!defer_user_update
)
1556 ret
= user
->update(op_state
, err_msg
);
1564 int RGWSubUserPool::modify(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1566 return RGWSubUserPool::modify(op_state
, err_msg
, false);
1569 int RGWSubUserPool::modify(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_user_update
)
1571 std::string subprocess_msg
;
1576 ret
= check_op(op_state
, &subprocess_msg
);
1578 set_err_msg(err_msg
, "unable to parse request, " + subprocess_msg
);
1582 ret
= execute_modify(op_state
, &subprocess_msg
, defer_user_update
);
1584 set_err_msg(err_msg
, "unable to modify subuser, " + subprocess_msg
);
1591 RGWUserCapPool::RGWUserCapPool(RGWUser
*usr
)
1595 caps_allowed
= (user
!= NULL
);
1598 RGWUserCapPool::~RGWUserCapPool()
1603 int RGWUserCapPool::init(RGWUserAdminOpState
& op_state
)
1605 if (!op_state
.is_initialized()) {
1606 caps_allowed
= false;
1610 rgw_user
& uid
= op_state
.get_user_id();
1611 if (uid
.compare(RGW_USER_ANON_ID
) == 0) {
1612 caps_allowed
= false;
1616 caps
= op_state
.get_caps_obj();
1618 caps_allowed
= false;
1619 return -ERR_INVALID_CAP
;
1622 caps_allowed
= true;
1627 int RGWUserCapPool::add(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1629 return add(op_state
, err_msg
, false);
1632 int RGWUserCapPool::add(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_save
)
1635 std::string caps_str
= op_state
.get_caps();
1637 if (!op_state
.is_populated()) {
1638 set_err_msg(err_msg
, "user info was not populated");
1642 if (!caps_allowed
) {
1643 set_err_msg(err_msg
, "caps not allowed for this user");
1647 if (caps_str
.empty()) {
1648 set_err_msg(err_msg
, "empty user caps");
1649 return -ERR_INVALID_CAP
;
1652 int r
= caps
->add_from_string(caps_str
);
1654 set_err_msg(err_msg
, "unable to add caps: " + caps_str
);
1659 ret
= user
->update(op_state
, err_msg
);
1667 int RGWUserCapPool::remove(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1669 return remove(op_state
, err_msg
, false);
1672 int RGWUserCapPool::remove(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_save
)
1676 std::string caps_str
= op_state
.get_caps();
1678 if (!op_state
.is_populated()) {
1679 set_err_msg(err_msg
, "user info was not populated");
1683 if (!caps_allowed
) {
1684 set_err_msg(err_msg
, "caps not allowed for this user");
1688 if (caps_str
.empty()) {
1689 set_err_msg(err_msg
, "empty user caps");
1690 return -ERR_INVALID_CAP
;
1693 int r
= caps
->remove_from_string(caps_str
);
1695 set_err_msg(err_msg
, "unable to remove caps: " + caps_str
);
1700 ret
= user
->update(op_state
, err_msg
);
1708 RGWUser::RGWUser() : store(NULL
), info_stored(false), caps(this), keys(this), subusers(this)
1713 int RGWUser::init(RGWRados
*storage
, RGWUserAdminOpState
& op_state
)
1716 int ret
= init_storage(storage
);
1720 ret
= init(op_state
);
1731 void RGWUser::init_default()
1733 // use anonymous user info as a placeholder
1734 rgw_get_anon_user(old_info
);
1735 user_id
= RGW_USER_ANON_ID
;
1740 int RGWUser::init_storage(RGWRados
*storage
)
1751 keys
= RGWAccessKeyPool(this);
1752 caps
= RGWUserCapPool(this);
1753 subusers
= RGWSubUserPool(this);
1758 int RGWUser::init(RGWUserAdminOpState
& op_state
)
1761 std::string swift_user
;
1762 rgw_user
& uid
= op_state
.get_user_id();
1763 std::string user_email
= op_state
.get_user_email();
1764 std::string access_key
= op_state
.get_access_key();
1765 std::string subuser
= op_state
.get_subuser();
1767 int key_type
= op_state
.get_key_type();
1768 if (key_type
== KEY_TYPE_SWIFT
) {
1769 swift_user
= op_state
.get_access_key();
1773 RGWUserInfo user_info
;
1777 if (uid
.empty() && !subuser
.empty()) {
1778 size_t pos
= subuser
.find(':');
1779 if (pos
!= string::npos
) {
1780 uid
= subuser
.substr(0, pos
);
1781 op_state
.set_user_id(uid
);
1785 if (!uid
.empty() && (uid
.compare(RGW_USER_ANON_ID
) != 0)) {
1786 found
= (rgw_get_user_info_by_uid(store
, uid
, user_info
, &op_state
.objv
) >= 0);
1787 op_state
.found_by_uid
= found
;
1789 if (!user_email
.empty() && !found
) {
1790 found
= (rgw_get_user_info_by_email(store
, user_email
, user_info
, &op_state
.objv
) >= 0);
1791 op_state
.found_by_email
= found
;
1793 if (!swift_user
.empty() && !found
) {
1794 found
= (rgw_get_user_info_by_swift(store
, swift_user
, user_info
, &op_state
.objv
) >= 0);
1795 op_state
.found_by_key
= found
;
1797 if (!access_key
.empty() && !found
) {
1798 found
= (rgw_get_user_info_by_access_key(store
, access_key
, user_info
, &op_state
.objv
) >= 0);
1799 op_state
.found_by_key
= found
;
1802 op_state
.set_existing_user(found
);
1804 op_state
.set_user_info(user_info
);
1805 op_state
.set_populated();
1807 old_info
= user_info
;
1811 user_id
= user_info
.user_id
;
1812 op_state
.set_initialized();
1814 // this may have been called by a helper object
1815 int ret
= init_members(op_state
);
1822 int RGWUser::init_members(RGWUserAdminOpState
& op_state
)
1826 ret
= keys
.init(op_state
);
1830 ret
= subusers
.init(op_state
);
1834 ret
= caps
.init(op_state
);
1841 int RGWUser::update(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1844 std::string subprocess_msg
;
1845 RGWUserInfo user_info
= op_state
.get_user_info();
1848 set_err_msg(err_msg
, "couldn't initialize storage");
1852 if (is_populated()) {
1853 ret
= rgw_store_user_info(store
, user_info
, &old_info
, &op_state
.objv
, real_time(), false);
1855 set_err_msg(err_msg
, "unable to store user info");
1859 ret
= remove_old_indexes(store
, old_info
, user_info
, &subprocess_msg
);
1861 set_err_msg(err_msg
, "unable to remove old user info, " + subprocess_msg
);
1865 ret
= rgw_store_user_info(store
, user_info
, NULL
, &op_state
.objv
, real_time(), false);
1867 set_err_msg(err_msg
, "unable to store user info");
1872 old_info
= user_info
;
1878 int RGWUser::check_op(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1882 rgw_user
& op_id
= op_state
.get_user_id();
1884 RGWUserInfo user_info
;
1886 same_id
= (user_id
.compare(op_id
) == 0);
1887 populated
= is_populated();
1889 if (op_id
.compare(RGW_USER_ANON_ID
) == 0) {
1890 set_err_msg(err_msg
, "unable to perform operations on the anonymous user");
1894 if (populated
&& !same_id
) {
1895 set_err_msg(err_msg
, "user id mismatch, operation id: " + op_id
.to_str()
1896 + " does not match: " + user_id
.to_str());
1901 int ret
= rgw_validate_tenant_name(op_id
.tenant
);
1903 set_err_msg(err_msg
,
1904 "invalid tenant only alphanumeric and _ characters are allowed");
1908 //set key type when it not set or set by context
1909 if ((op_state
.get_key_type() < 0) || op_state
.key_type_setbycontext
) {
1910 op_state
.set_key_type(KEY_TYPE_S3
);
1911 op_state
.key_type_setbycontext
= true;
1917 int RGWUser::execute_add(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1919 std::string subprocess_msg
;
1921 bool defer_user_update
= true;
1923 RGWUserInfo user_info
;
1925 rgw_user
& uid
= op_state
.get_user_id();
1926 std::string user_email
= op_state
.get_user_email();
1927 std::string display_name
= op_state
.get_display_name();
1929 // fail if the user exists already
1930 if (op_state
.has_existing_user()) {
1931 if (!op_state
.exclusive
&&
1932 (user_email
.empty() ||
1933 boost::iequals(user_email
, old_info
.user_email
)) &&
1934 old_info
.display_name
== display_name
) {
1935 return execute_modify(op_state
, err_msg
);
1938 if (op_state
.found_by_email
) {
1939 set_err_msg(err_msg
, "email: " + user_email
+
1940 " is the email address an existing user");
1941 ret
= -ERR_EMAIL_EXIST
;
1942 } else if (op_state
.found_by_key
) {
1943 set_err_msg(err_msg
, "duplicate key provided");
1944 ret
= -ERR_KEY_EXIST
;
1946 set_err_msg(err_msg
, "user: " + op_state
.user_id
.to_str() + " exists");
1952 // fail if the user_info has already been populated
1953 if (op_state
.is_populated()) {
1954 set_err_msg(err_msg
, "cannot overwrite already populated user");
1958 // fail if the display name was not included
1959 if (display_name
.empty()) {
1960 set_err_msg(err_msg
, "no display name specified");
1965 // set the user info
1967 user_info
.user_id
= user_id
;
1968 user_info
.display_name
= display_name
;
1969 user_info
.type
= TYPE_RGW
;
1971 if (!user_email
.empty())
1972 user_info
.user_email
= user_email
;
1974 CephContext
*cct
= store
->ctx();
1975 if (op_state
.max_buckets_specified
) {
1976 user_info
.max_buckets
= op_state
.get_max_buckets();
1978 user_info
.max_buckets
= cct
->_conf
->rgw_user_max_buckets
;
1981 user_info
.suspended
= op_state
.get_suspension_status();
1982 user_info
.admin
= op_state
.admin
;
1983 user_info
.system
= op_state
.system
;
1985 if (op_state
.op_mask_specified
)
1986 user_info
.op_mask
= op_state
.get_op_mask();
1988 if (op_state
.has_bucket_quota()) {
1989 user_info
.bucket_quota
= op_state
.get_bucket_quota();
1991 if (cct
->_conf
->rgw_bucket_default_quota_max_objects
>= 0) {
1992 user_info
.bucket_quota
.max_objects
= cct
->_conf
->rgw_bucket_default_quota_max_objects
;
1993 user_info
.bucket_quota
.enabled
= true;
1995 if (cct
->_conf
->rgw_bucket_default_quota_max_size
>= 0) {
1996 user_info
.bucket_quota
.max_size
= cct
->_conf
->rgw_bucket_default_quota_max_size
;
1997 user_info
.bucket_quota
.enabled
= true;
2001 if (op_state
.temp_url_key_specified
) {
2002 map
<int, string
>::iterator iter
;
2003 for (iter
= op_state
.temp_url_keys
.begin();
2004 iter
!= op_state
.temp_url_keys
.end(); ++iter
) {
2005 user_info
.temp_url_keys
[iter
->first
] = iter
->second
;
2009 if (op_state
.has_user_quota()) {
2010 user_info
.user_quota
= op_state
.get_user_quota();
2012 if (cct
->_conf
->rgw_user_default_quota_max_objects
>= 0) {
2013 user_info
.user_quota
.max_objects
= cct
->_conf
->rgw_user_default_quota_max_objects
;
2014 user_info
.user_quota
.enabled
= true;
2016 if (cct
->_conf
->rgw_user_default_quota_max_size
>= 0) {
2017 user_info
.user_quota
.max_size
= cct
->_conf
->rgw_user_default_quota_max_size
;
2018 user_info
.user_quota
.enabled
= true;
2022 // update the request
2023 op_state
.set_user_info(user_info
);
2024 op_state
.set_populated();
2026 // update the helper objects
2027 ret
= init_members(op_state
);
2029 set_err_msg(err_msg
, "unable to initialize user");
2033 // see if we need to add an access key
2034 if (op_state
.has_key_op()) {
2035 ret
= keys
.add(op_state
, &subprocess_msg
, defer_user_update
);
2037 set_err_msg(err_msg
, "unable to create access key, " + subprocess_msg
);
2042 // see if we need to add some caps
2043 if (op_state
.has_caps_op()) {
2044 ret
= caps
.add(op_state
, &subprocess_msg
, defer_user_update
);
2046 set_err_msg(err_msg
, "unable to add user capabilities, " + subprocess_msg
);
2051 ret
= update(op_state
, err_msg
);
2058 int RGWUser::add(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
2060 std::string subprocess_msg
;
2063 ret
= check_op(op_state
, &subprocess_msg
);
2065 set_err_msg(err_msg
, "unable to parse parameters, " + subprocess_msg
);
2069 ret
= execute_add(op_state
, &subprocess_msg
);
2071 set_err_msg(err_msg
, "unable to create user, " + subprocess_msg
);
2078 int RGWUser::execute_remove(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
2082 bool purge_data
= op_state
.will_purge_data();
2083 rgw_user
& uid
= op_state
.get_user_id();
2084 RGWUserInfo user_info
= op_state
.get_user_info();
2086 if (!op_state
.has_existing_user()) {
2087 set_err_msg(err_msg
, "user does not exist");
2091 bool is_truncated
= false;
2093 CephContext
*cct
= store
->ctx();
2094 size_t max_buckets
= cct
->_conf
->rgw_list_buckets_max_chunk
;
2096 RGWUserBuckets buckets
;
2097 ret
= rgw_read_user_buckets(store
, uid
, buckets
, marker
, string(),
2098 max_buckets
, false, &is_truncated
);
2100 set_err_msg(err_msg
, "unable to read user bucket info");
2104 map
<std::string
, RGWBucketEnt
>& m
= buckets
.get_buckets();
2105 if (!m
.empty() && !purge_data
) {
2106 set_err_msg(err_msg
, "must specify purge data to remove user with buckets");
2107 return -EEXIST
; // change to code that maps to 409: conflict
2110 std::map
<std::string
, RGWBucketEnt
>::iterator it
;
2111 for (it
= m
.begin(); it
!= m
.end(); ++it
) {
2112 ret
= rgw_remove_bucket(store
, ((*it
).second
).bucket
, true);
2114 set_err_msg(err_msg
, "unable to delete user data");
2121 } while (is_truncated
);
2123 ret
= rgw_delete_user(store
, user_info
, op_state
.objv
);
2125 set_err_msg(err_msg
, "unable to remove user from RADOS");
2129 op_state
.clear_populated();
2135 int RGWUser::remove(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
2137 std::string subprocess_msg
;
2140 ret
= check_op(op_state
, &subprocess_msg
);
2142 set_err_msg(err_msg
, "unable to parse parameters, " + subprocess_msg
);
2146 ret
= execute_remove(op_state
, &subprocess_msg
);
2148 set_err_msg(err_msg
, "unable to remove user, " + subprocess_msg
);
2155 int RGWUser::execute_modify(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
2157 bool populated
= op_state
.is_populated();
2159 std::string subprocess_msg
;
2160 std::string op_email
= op_state
.get_user_email();
2161 std::string display_name
= op_state
.get_display_name();
2163 RGWUserInfo user_info
;
2164 RGWUserInfo duplicate_check
;
2166 // ensure that the user info has been populated or is populate-able
2167 if (!op_state
.has_existing_user() && !populated
) {
2168 set_err_msg(err_msg
, "user not found");
2172 // if the user hasn't already been populated...attempt to
2174 ret
= init(op_state
);
2176 set_err_msg(err_msg
, "unable to retrieve user info");
2181 // ensure that we can modify the user's attributes
2182 if (user_id
.compare(RGW_USER_ANON_ID
) == 0) {
2183 set_err_msg(err_msg
, "unable to modify anonymous user's info");
2187 user_info
= old_info
;
2189 std::string old_email
= old_info
.user_email
;
2190 if (!op_email
.empty()) {
2191 // make sure we are not adding a duplicate email
2192 if (old_email
.compare(op_email
) != 0) {
2193 ret
= rgw_get_user_info_by_email(store
, op_email
, duplicate_check
);
2194 if (ret
>= 0 && duplicate_check
.user_id
.compare(user_id
) != 0) {
2195 set_err_msg(err_msg
, "cannot add duplicate email");
2196 return -ERR_EMAIL_EXIST
;
2199 user_info
.user_email
= op_email
;
2200 } else if (op_email
.empty() && op_state
.user_email_specified
) {
2202 ldout(store
->ctx(), 10) << "removing email index: " << user_info
.user_email
<< dendl
;
2203 ret
= rgw_remove_email_index(store
, user_info
.user_email
);
2204 if (ret
< 0 && ret
!= -ENOENT
) {
2205 ldout(store
->ctx(), 0) << "ERROR: could not remove " << user_info
.user_id
<< " index (err=" << ret
<< ")" << dendl
;
2208 user_info
.user_email
= "";
2211 // update the remaining user info
2212 if (!display_name
.empty())
2213 user_info
.display_name
= display_name
;
2215 if (op_state
.max_buckets_specified
)
2216 user_info
.max_buckets
= op_state
.get_max_buckets();
2218 if (op_state
.admin_specified
)
2219 user_info
.admin
= op_state
.admin
;
2221 if (op_state
.system_specified
)
2222 user_info
.system
= op_state
.system
;
2224 if (op_state
.temp_url_key_specified
) {
2225 map
<int, string
>::iterator iter
;
2226 for (iter
= op_state
.temp_url_keys
.begin();
2227 iter
!= op_state
.temp_url_keys
.end(); ++iter
) {
2228 user_info
.temp_url_keys
[iter
->first
] = iter
->second
;
2232 if (op_state
.op_mask_specified
)
2233 user_info
.op_mask
= op_state
.get_op_mask();
2235 if (op_state
.has_bucket_quota())
2236 user_info
.bucket_quota
= op_state
.get_bucket_quota();
2238 if (op_state
.has_user_quota())
2239 user_info
.user_quota
= op_state
.get_user_quota();
2241 if (op_state
.has_suspension_op()) {
2242 __u8 suspended
= op_state
.get_suspension_status();
2243 user_info
.suspended
= suspended
;
2245 RGWUserBuckets buckets
;
2247 if (user_id
.empty()) {
2248 set_err_msg(err_msg
, "empty user id passed...aborting");
2252 bool is_truncated
= false;
2254 CephContext
*cct
= store
->ctx();
2255 size_t max_buckets
= cct
->_conf
->rgw_list_buckets_max_chunk
;
2257 ret
= rgw_read_user_buckets(store
, user_id
, buckets
, marker
, string(),
2258 max_buckets
, false, &is_truncated
);
2260 set_err_msg(err_msg
, "could not get buckets for uid: " + user_id
.to_str());
2264 map
<string
, RGWBucketEnt
>& m
= buckets
.get_buckets();
2265 map
<string
, RGWBucketEnt
>::iterator iter
;
2267 vector
<rgw_bucket
> bucket_names
;
2268 for (iter
= m
.begin(); iter
!= m
.end(); ++iter
) {
2269 RGWBucketEnt obj
= iter
->second
;
2270 bucket_names
.push_back(obj
.bucket
);
2272 marker
= iter
->first
;
2275 ret
= store
->set_buckets_enabled(bucket_names
, !suspended
);
2277 set_err_msg(err_msg
, "failed to modify bucket");
2281 } while (is_truncated
);
2283 op_state
.set_user_info(user_info
);
2285 // if we're supposed to modify keys, do so
2286 if (op_state
.has_key_op()) {
2287 ret
= keys
.add(op_state
, &subprocess_msg
, true);
2289 set_err_msg(err_msg
, "unable to create or modify keys, " + subprocess_msg
);
2294 ret
= update(op_state
, err_msg
);
2301 int RGWUser::modify(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
2303 std::string subprocess_msg
;
2306 ret
= check_op(op_state
, &subprocess_msg
);
2308 set_err_msg(err_msg
, "unable to parse parameters, " + subprocess_msg
);
2312 ret
= execute_modify(op_state
, &subprocess_msg
);
2314 set_err_msg(err_msg
, "unable to modify user, " + subprocess_msg
);
2321 int RGWUser::info(RGWUserAdminOpState
& op_state
, RGWUserInfo
& fetched_info
, std::string
*err_msg
)
2323 int ret
= init(op_state
);
2325 set_err_msg(err_msg
, "unable to fetch user info");
2329 fetched_info
= op_state
.get_user_info();
2334 int RGWUser::info(RGWUserInfo
& fetched_info
, std::string
*err_msg
)
2336 if (!is_populated()) {
2337 set_err_msg(err_msg
, "no user info saved");
2341 fetched_info
= old_info
;
2346 int RGWUserAdminOp_User::info(RGWRados
*store
, RGWUserAdminOpState
& op_state
,
2347 RGWFormatterFlusher
& flusher
)
2352 int ret
= user
.init(store
, op_state
);
2356 if (!op_state
.has_existing_user())
2357 return -ERR_NO_SUCH_USER
;
2359 Formatter
*formatter
= flusher
.get_formatter();
2361 ret
= user
.info(info
, NULL
);
2365 RGWStorageStats stats
;
2366 RGWStorageStats
*arg_stats
= NULL
;
2367 if (op_state
.fetch_stats
) {
2368 int ret
= store
->get_user_stats(info
.user_id
, stats
);
2378 dump_user_info(formatter
, info
, arg_stats
);
2384 int RGWUserAdminOp_User::create(RGWRados
*store
, RGWUserAdminOpState
& op_state
,
2385 RGWFormatterFlusher
& flusher
)
2389 int ret
= user
.init(store
, op_state
);
2393 Formatter
*formatter
= flusher
.get_formatter();
2395 ret
= user
.add(op_state
, NULL
);
2398 ret
= -ERR_USER_EXIST
;
2402 ret
= user
.info(info
, NULL
);
2408 dump_user_info(formatter
, info
);
2414 int RGWUserAdminOp_User::modify(RGWRados
*store
, RGWUserAdminOpState
& op_state
,
2415 RGWFormatterFlusher
& flusher
)
2419 int ret
= user
.init(store
, op_state
);
2422 Formatter
*formatter
= flusher
.get_formatter();
2424 ret
= user
.modify(op_state
, NULL
);
2427 ret
= -ERR_NO_SUCH_USER
;
2431 ret
= user
.info(info
, NULL
);
2437 dump_user_info(formatter
, info
);
2443 int RGWUserAdminOp_User::remove(RGWRados
*store
, RGWUserAdminOpState
& op_state
,
2444 RGWFormatterFlusher
& flusher
)
2448 int ret
= user
.init(store
, op_state
);
2453 ret
= user
.remove(op_state
, NULL
);
2456 ret
= -ERR_NO_SUCH_USER
;
2460 int RGWUserAdminOp_Subuser::create(RGWRados
*store
, RGWUserAdminOpState
& op_state
,
2461 RGWFormatterFlusher
& flusher
)
2465 int ret
= user
.init(store
, op_state
);
2469 if (!op_state
.has_existing_user())
2470 return -ERR_NO_SUCH_USER
;
2472 Formatter
*formatter
= flusher
.get_formatter();
2474 ret
= user
.subusers
.add(op_state
, NULL
);
2478 ret
= user
.info(info
, NULL
);
2484 dump_subusers_info(formatter
, info
);
2490 int RGWUserAdminOp_Subuser::modify(RGWRados
*store
, RGWUserAdminOpState
& op_state
,
2491 RGWFormatterFlusher
& flusher
)
2495 int ret
= user
.init(store
, op_state
);
2499 if (!op_state
.has_existing_user())
2500 return -ERR_NO_SUCH_USER
;
2502 Formatter
*formatter
= flusher
.get_formatter();
2504 ret
= user
.subusers
.modify(op_state
, NULL
);
2508 ret
= user
.info(info
, NULL
);
2514 dump_subusers_info(formatter
, info
);
2520 int RGWUserAdminOp_Subuser::remove(RGWRados
*store
, RGWUserAdminOpState
& op_state
,
2521 RGWFormatterFlusher
& flusher
)
2525 int ret
= user
.init(store
, op_state
);
2530 if (!op_state
.has_existing_user())
2531 return -ERR_NO_SUCH_USER
;
2533 ret
= user
.subusers
.remove(op_state
, NULL
);
2540 int RGWUserAdminOp_Key::create(RGWRados
*store
, RGWUserAdminOpState
& op_state
,
2541 RGWFormatterFlusher
& flusher
)
2545 int ret
= user
.init(store
, op_state
);
2549 if (!op_state
.has_existing_user())
2550 return -ERR_NO_SUCH_USER
;
2552 Formatter
*formatter
= flusher
.get_formatter();
2554 ret
= user
.keys
.add(op_state
, NULL
);
2558 ret
= user
.info(info
, NULL
);
2564 int key_type
= op_state
.get_key_type();
2566 if (key_type
== KEY_TYPE_SWIFT
)
2567 dump_swift_keys_info(formatter
, info
);
2569 else if (key_type
== KEY_TYPE_S3
)
2570 dump_access_keys_info(formatter
, info
);
2577 int RGWUserAdminOp_Key::remove(RGWRados
*store
, RGWUserAdminOpState
& op_state
,
2578 RGWFormatterFlusher
& flusher
)
2582 int ret
= user
.init(store
, op_state
);
2586 if (!op_state
.has_existing_user())
2587 return -ERR_NO_SUCH_USER
;
2590 ret
= user
.keys
.remove(op_state
, NULL
);
2597 int RGWUserAdminOp_Caps::add(RGWRados
*store
, RGWUserAdminOpState
& op_state
,
2598 RGWFormatterFlusher
& flusher
)
2602 int ret
= user
.init(store
, op_state
);
2606 if (!op_state
.has_existing_user())
2607 return -ERR_NO_SUCH_USER
;
2609 Formatter
*formatter
= flusher
.get_formatter();
2611 ret
= user
.caps
.add(op_state
, NULL
);
2615 ret
= user
.info(info
, NULL
);
2621 info
.caps
.dump(formatter
);
2628 int RGWUserAdminOp_Caps::remove(RGWRados
*store
, RGWUserAdminOpState
& op_state
,
2629 RGWFormatterFlusher
& flusher
)
2633 int ret
= user
.init(store
, op_state
);
2637 if (!op_state
.has_existing_user())
2638 return -ERR_NO_SUCH_USER
;
2640 Formatter
*formatter
= flusher
.get_formatter();
2642 ret
= user
.caps
.remove(op_state
, NULL
);
2646 ret
= user
.info(info
, NULL
);
2652 info
.caps
.dump(formatter
);
2658 struct RGWUserCompleteInfo
{
2660 map
<string
, bufferlist
> attrs
;
2663 RGWUserCompleteInfo()
2667 void dump(Formatter
* const f
) const {
2669 encode_json("attrs", attrs
, f
);
2672 void decode_json(JSONObj
*obj
) {
2673 decode_json_obj(info
, obj
);
2674 has_attrs
= JSONDecoder::decode_json("attrs", attrs
, obj
);
2678 class RGWUserMetadataObject
: public RGWMetadataObject
{
2679 RGWUserCompleteInfo uci
;
2681 RGWUserMetadataObject(const RGWUserCompleteInfo
& _uci
, obj_version
& v
, real_time m
)
2687 void dump(Formatter
*f
) const override
{
2692 class RGWUserMetadataHandler
: public RGWMetadataHandler
{
2694 string
get_type() override
{ return "user"; }
2696 int get(RGWRados
*store
, string
& entry
, RGWMetadataObject
**obj
) override
{
2697 RGWUserCompleteInfo uci
;
2698 RGWObjVersionTracker objv_tracker
;
2701 rgw_user
uid(entry
);
2703 int ret
= rgw_get_user_info_by_uid(store
, uid
, uci
.info
, &objv_tracker
,
2704 &mtime
, NULL
, &uci
.attrs
);
2709 RGWUserMetadataObject
*mdo
= new RGWUserMetadataObject(uci
, objv_tracker
.read_version
, mtime
);
2715 int put(RGWRados
*store
, string
& entry
, RGWObjVersionTracker
& objv_tracker
,
2716 real_time mtime
, JSONObj
*obj
, sync_type_t sync_mode
) override
{
2717 RGWUserCompleteInfo uci
;
2720 decode_json_obj(uci
, obj
);
2721 } catch (JSONDecoder::err
& e
) {
2725 map
<string
, bufferlist
> *pattrs
= NULL
;
2726 if (uci
.has_attrs
) {
2727 pattrs
= &uci
.attrs
;
2730 rgw_user
uid(entry
);
2732 RGWUserInfo old_info
;
2733 real_time orig_mtime
;
2734 int ret
= rgw_get_user_info_by_uid(store
, uid
, old_info
, &objv_tracker
, &orig_mtime
);
2735 if (ret
< 0 && ret
!= -ENOENT
)
2738 // are we actually going to perform this put, or is it too old?
2739 if (ret
!= -ENOENT
&&
2740 !check_versions(objv_tracker
.read_version
, orig_mtime
,
2741 objv_tracker
.write_version
, mtime
, sync_mode
)) {
2742 return STATUS_NO_APPLY
;
2745 ret
= rgw_store_user_info(store
, uci
.info
, &old_info
, &objv_tracker
, mtime
, false, pattrs
);
2750 return STATUS_APPLIED
;
2753 struct list_keys_info
{
2755 RGWListRawObjsCtx ctx
;
2758 int remove(RGWRados
*store
, string
& entry
, RGWObjVersionTracker
& objv_tracker
) override
{
2761 rgw_user
uid(entry
);
2763 int ret
= rgw_get_user_info_by_uid(store
, uid
, info
, &objv_tracker
);
2767 return rgw_delete_user(store
, info
, objv_tracker
);
2770 void get_pool_and_oid(RGWRados
*store
, const string
& key
, rgw_pool
& pool
, string
& oid
) override
{
2772 pool
= store
->get_zone_params().user_uid_pool
;
2775 int list_keys_init(RGWRados
*store
, void **phandle
) override
2777 list_keys_info
*info
= new list_keys_info
;
2779 info
->store
= store
;
2781 *phandle
= (void *)info
;
2786 int list_keys_next(void *handle
, int max
, list
<string
>& keys
, bool *truncated
) override
{
2787 list_keys_info
*info
= static_cast<list_keys_info
*>(handle
);
2793 RGWRados
*store
= info
->store
;
2795 list
<string
> unfiltered_keys
;
2797 int ret
= store
->list_raw_objects(store
->get_zone_params().user_uid_pool
, no_filter
,
2798 max
, info
->ctx
, unfiltered_keys
, truncated
);
2799 if (ret
< 0 && ret
!= -ENOENT
)
2801 if (ret
== -ENOENT
) {
2807 // now filter out the buckets entries
2808 list
<string
>::iterator iter
;
2809 for (iter
= unfiltered_keys
.begin(); iter
!= unfiltered_keys
.end(); ++iter
) {
2812 if (k
.find(".buckets") == string::npos
) {
2820 void list_keys_complete(void *handle
) override
{
2821 list_keys_info
*info
= static_cast<list_keys_info
*>(handle
);
2826 void rgw_user_init(RGWRados
*store
)
2828 uinfo_cache
.init(store
);
2830 user_meta_handler
= new RGWUserMetadataHandler
;
2831 store
->meta_mgr
->register_handler(user_meta_handler
);