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"
18 #include "include/types.h"
20 #include "rgw_string.h"
22 // until everything is moved from rgw_common
23 #include "rgw_common.h"
25 #include "rgw_bucket.h"
26 #include "rgw_quota.h"
28 #include "services/svc_zone.h"
29 #include "services/svc_sys_obj.h"
30 #include "services/svc_sys_obj_cache.h"
32 #define dout_subsys ceph_subsys_rgw
36 static RGWMetadataHandler
*user_meta_handler
= NULL
;
37 extern void op_type_to_str(uint32_t mask
, char *buf
, int len
);
40 * Get the anonymous (ie, unauthenticated) user info.
42 void rgw_get_anon_user(RGWUserInfo
& info
)
44 info
.user_id
= RGW_USER_ANON_ID
;
45 info
.display_name
.clear();
46 info
.access_keys
.clear();
49 int rgw_user_sync_all_stats(RGWRados
*store
, const rgw_user
& user_id
)
51 CephContext
*cct
= store
->ctx();
52 size_t max_entries
= cct
->_conf
->rgw_list_buckets_max_chunk
;
53 bool is_truncated
= false;
56 RGWSysObjectCtx obj_ctx
= store
->svc
.sysobj
->init_obj_ctx();
59 RGWUserBuckets user_buckets
;
60 ret
= rgw_read_user_buckets(store
, user_id
, user_buckets
, marker
,
61 string(), max_entries
, false, &is_truncated
);
63 ldout(cct
, 0) << "failed to read user buckets: ret=" << ret
<< dendl
;
66 map
<string
, RGWBucketEnt
>& buckets
= user_buckets
.get_buckets();
67 for (map
<string
, RGWBucketEnt
>::iterator i
= buckets
.begin();
72 RGWBucketEnt
& bucket_ent
= i
->second
;
73 RGWBucketInfo bucket_info
;
75 ret
= store
->get_bucket_info(obj_ctx
, user_id
.tenant
, bucket_ent
.bucket
.name
,
76 bucket_info
, nullptr, nullptr);
78 ldout(cct
, 0) << "ERROR: could not read bucket info: bucket=" << bucket_ent
.bucket
<< " ret=" << ret
<< dendl
;
81 ret
= rgw_bucket_sync_user_stats(store
, user_id
, bucket_info
);
83 ldout(cct
, 0) << "ERROR: could not sync bucket stats: ret=" << ret
<< dendl
;
86 RGWQuotaInfo bucket_quota
;
87 ret
= store
->check_bucket_shards(bucket_info
, bucket_info
.bucket
, bucket_quota
);
89 ldout(cct
, 0) << "ERROR in check_bucket_shards: " << cpp_strerror(-ret
)<< dendl
;
92 } while (is_truncated
);
94 ret
= store
->complete_sync_user_stats(user_id
);
96 cerr
<< "ERROR: failed to complete syncing user stats: ret=" << ret
<< std::endl
;
103 int rgw_user_get_all_buckets_stats(RGWRados
*store
, const rgw_user
& user_id
, map
<string
, cls_user_bucket_entry
>&buckets_usage_map
)
105 CephContext
*cct
= store
->ctx();
106 size_t max_entries
= cct
->_conf
->rgw_list_buckets_max_chunk
;
113 RGWUserBuckets user_buckets
;
114 ret
= rgw_read_user_buckets(store
, user_id
, user_buckets
, marker
,
115 string(), max_entries
, false, &is_truncated
);
117 ldout(cct
, 0) << "failed to read user buckets: ret=" << ret
<< dendl
;
120 map
<string
, RGWBucketEnt
>& buckets
= user_buckets
.get_buckets();
121 for (const auto& i
: buckets
) {
124 const RGWBucketEnt
& bucket_ent
= i
.second
;
125 cls_user_bucket_entry entry
;
126 ret
= store
->cls_user_get_bucket_stats(bucket_ent
.bucket
, entry
);
128 ldout(cct
, 0) << "ERROR: could not get bucket stats: ret=" << ret
<< dendl
;
131 buckets_usage_map
.emplace(bucket_ent
.bucket
.name
, entry
);
133 done
= (buckets
.size() < max_entries
);
140 * Save the given user information to storage.
141 * Returns: 0 on success, -ERR# on failure.
143 int rgw_store_user_info(RGWRados
*store
,
145 RGWUserInfo
*old_info
,
146 RGWObjVersionTracker
*objv_tracker
,
149 map
<string
, bufferlist
> *pattrs
)
152 RGWObjVersionTracker ot
;
158 if (ot
.write_version
.tag
.empty()) {
159 if (ot
.read_version
.tag
.empty()) {
160 ot
.generate_new_write_ver(store
->ctx());
162 ot
.write_version
= ot
.read_version
;
163 ot
.write_version
.ver
++;
167 map
<string
, RGWAccessKey
>::iterator iter
;
168 for (iter
= info
.swift_keys
.begin(); iter
!= info
.swift_keys
.end(); ++iter
) {
169 if (old_info
&& old_info
->swift_keys
.count(iter
->first
) != 0)
171 RGWAccessKey
& k
= iter
->second
;
172 /* check if swift mapping exists */
174 int r
= rgw_get_user_info_by_swift(store
, k
.id
, inf
);
175 if (r
>= 0 && inf
.user_id
.compare(info
.user_id
) != 0) {
176 ldout(store
->ctx(), 0) << "WARNING: can't store user info, swift id (" << k
.id
177 << ") already mapped to another user (" << info
.user_id
<< ")" << dendl
;
182 if (!info
.access_keys
.empty()) {
183 /* check if access keys already exist */
185 map
<string
, RGWAccessKey
>::iterator iter
= info
.access_keys
.begin();
186 for (; iter
!= info
.access_keys
.end(); ++iter
) {
187 RGWAccessKey
& k
= iter
->second
;
188 if (old_info
&& old_info
->access_keys
.count(iter
->first
) != 0)
190 int r
= rgw_get_user_info_by_access_key(store
, k
.id
, inf
);
191 if (r
>= 0 && inf
.user_id
.compare(info
.user_id
) != 0) {
192 ldout(store
->ctx(), 0) << "WARNING: can't store user info, access key already mapped to another user" << dendl
;
199 ui
.user_id
= info
.user_id
;
206 encode(info
, data_bl
);
209 info
.user_id
.to_str(key
);
211 ret
= store
->meta_mgr
->put_entry(user_meta_handler
, key
, data_bl
, exclusive
, &ot
, mtime
, pattrs
);
215 if (!info
.user_email
.empty()) {
217 old_info
->user_email
.compare(info
.user_email
) != 0) { /* only if new index changed */
218 ret
= rgw_put_system_obj(store
, store
->svc
.zone
->get_zone_params().user_email_pool
, info
.user_email
,
219 link_bl
, exclusive
, NULL
, real_time());
225 if (!info
.access_keys
.empty()) {
226 map
<string
, RGWAccessKey
>::iterator iter
= info
.access_keys
.begin();
227 for (; iter
!= info
.access_keys
.end(); ++iter
) {
228 RGWAccessKey
& k
= iter
->second
;
229 if (old_info
&& old_info
->access_keys
.count(iter
->first
) != 0)
232 ret
= rgw_put_system_obj(store
, store
->svc
.zone
->get_zone_params().user_keys_pool
, k
.id
,
233 link_bl
, exclusive
, NULL
, real_time());
239 map
<string
, RGWAccessKey
>::iterator siter
;
240 for (siter
= info
.swift_keys
.begin(); siter
!= info
.swift_keys
.end(); ++siter
) {
241 RGWAccessKey
& k
= siter
->second
;
242 if (old_info
&& old_info
->swift_keys
.count(siter
->first
) != 0)
245 ret
= rgw_put_system_obj(store
, store
->svc
.zone
->get_zone_params().user_swift_pool
, k
.id
,
246 link_bl
, exclusive
, NULL
, real_time());
254 struct user_info_entry
{
256 RGWObjVersionTracker objv_tracker
;
260 static RGWChainedCacheImpl
<user_info_entry
> uinfo_cache
;
262 int rgw_get_user_info_from_index(RGWRados
* const store
,
264 const rgw_pool
& pool
,
266 RGWObjVersionTracker
* const objv_tracker
,
267 real_time
* const pmtime
)
269 if (auto e
= uinfo_cache
.find(key
)) {
272 *objv_tracker
= e
->objv_tracker
;
281 auto obj_ctx
= store
->svc
.sysobj
->init_obj_ctx();
283 int ret
= rgw_get_system_obj(store
, obj_ctx
, pool
, key
, bl
, NULL
, &e
.mtime
);
287 rgw_cache_entry_info cache_info
;
289 auto iter
= bl
.cbegin();
292 int ret
= rgw_get_user_info_by_uid(store
, uid
.user_id
, e
.info
, &e
.objv_tracker
, NULL
, &cache_info
);
296 } catch (buffer::error
& err
) {
297 ldout(store
->ctx(), 0) << "ERROR: failed to decode user info, caught buffer::error" << dendl
;
301 uinfo_cache
.put(store
->svc
.cache
, key
, &e
, { &cache_info
});
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 auto obj_ctx
= store
->svc
.sysobj
->init_obj_ctx();
328 string oid
= uid
.to_str();
329 int ret
= rgw_get_system_obj(store
, obj_ctx
, store
->svc
.zone
->get_zone_params().user_uid_pool
, oid
, bl
, objv_tracker
, pmtime
, pattrs
, cache_info
);
334 auto iter
= bl
.cbegin();
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
;
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
->svc
.zone
->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
->svc
.zone
->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
->svc
.zone
->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 auto obj_ctx
= store
->svc
.sysobj
->init_obj_ctx();
398 rgw_raw_obj
obj(store
->svc
.zone
->get_zone_params().user_uid_pool
, user_id
.to_str());
399 auto src
= obj_ctx
.get_obj(obj
);
403 .set_objv_tracker(objv_tracker
)
407 int rgw_remove_key_index(RGWRados
*store
, RGWAccessKey
& access_key
)
409 rgw_raw_obj
obj(store
->svc
.zone
->get_zone_params().user_keys_pool
, access_key
.id
);
410 auto obj_ctx
= store
->svc
.sysobj
->init_obj_ctx();
411 auto sysobj
= obj_ctx
.get_obj(obj
);
412 return sysobj
.wop().remove();
415 int rgw_remove_uid_index(RGWRados
*store
, rgw_user
& uid
)
417 RGWObjVersionTracker objv_tracker
;
419 int ret
= rgw_get_user_info_by_uid(store
, uid
, info
, &objv_tracker
, NULL
);
423 string oid
= uid
.to_str();
424 ret
= store
->meta_mgr
->remove_entry(user_meta_handler
, oid
, &objv_tracker
);
431 int rgw_remove_email_index(RGWRados
*store
, string
& email
)
436 rgw_raw_obj
obj(store
->svc
.zone
->get_zone_params().user_email_pool
, email
);
437 auto obj_ctx
= store
->svc
.sysobj
->init_obj_ctx();
438 auto sysobj
= obj_ctx
.get_obj(obj
);
439 return sysobj
.wop().remove();
442 int rgw_remove_swift_name_index(RGWRados
*store
, string
& swift_name
)
444 rgw_raw_obj
obj(store
->svc
.zone
->get_zone_params().user_swift_pool
, swift_name
);
445 auto obj_ctx
= store
->svc
.sysobj
->init_obj_ctx();
446 auto sysobj
= obj_ctx
.get_obj(obj
);
447 return sysobj
.wop().remove();
451 * delete a user's presence from the RGW system.
452 * First remove their bucket ACLs, then delete them
453 * from the user and user email pools. This leaves the pools
454 * themselves alone, as well as any ACLs embedded in object xattrs.
456 int rgw_delete_user(RGWRados
*store
, RGWUserInfo
& info
, RGWObjVersionTracker
& objv_tracker
) {
459 map
<string
, RGWAccessKey
>::iterator kiter
= info
.access_keys
.begin();
460 for (; kiter
!= info
.access_keys
.end(); ++kiter
) {
461 ldout(store
->ctx(), 10) << "removing key index: " << kiter
->first
<< dendl
;
462 ret
= rgw_remove_key_index(store
, kiter
->second
);
463 if (ret
< 0 && ret
!= -ENOENT
) {
464 ldout(store
->ctx(), 0) << "ERROR: could not remove " << kiter
->first
<< " (access key object), should be fixed (err=" << ret
<< ")" << dendl
;
469 map
<string
, RGWAccessKey
>::iterator siter
= info
.swift_keys
.begin();
470 for (; siter
!= info
.swift_keys
.end(); ++siter
) {
471 RGWAccessKey
& k
= siter
->second
;
472 ldout(store
->ctx(), 10) << "removing swift subuser index: " << k
.id
<< dendl
;
473 /* check if swift mapping exists */
474 ret
= rgw_remove_swift_name_index(store
, k
.id
);
475 if (ret
< 0 && ret
!= -ENOENT
) {
476 ldout(store
->ctx(), 0) << "ERROR: could not remove " << k
.id
<< " (swift name object), should be fixed (err=" << ret
<< ")" << dendl
;
481 ldout(store
->ctx(), 10) << "removing email index: " << info
.user_email
<< dendl
;
482 ret
= rgw_remove_email_index(store
, info
.user_email
);
483 if (ret
< 0 && ret
!= -ENOENT
) {
484 ldout(store
->ctx(), 0) << "ERROR: could not remove email index object for "
485 << info
.user_email
<< ", should be fixed (err=" << ret
<< ")" << dendl
;
489 string buckets_obj_id
;
490 rgw_get_buckets_obj(info
.user_id
, buckets_obj_id
);
491 rgw_raw_obj
uid_bucks(store
->svc
.zone
->get_zone_params().user_uid_pool
, buckets_obj_id
);
492 ldout(store
->ctx(), 10) << "removing user buckets index" << dendl
;
493 auto obj_ctx
= store
->svc
.sysobj
->init_obj_ctx();
494 auto sysobj
= obj_ctx
.get_obj(uid_bucks
);
495 ret
= sysobj
.wop().remove();
496 if (ret
< 0 && ret
!= -ENOENT
) {
497 ldout(store
->ctx(), 0) << "ERROR: could not remove " << info
.user_id
<< ":" << uid_bucks
<< ", should be fixed (err=" << ret
<< ")" << dendl
;
502 info
.user_id
.to_str(key
);
504 rgw_raw_obj
uid_obj(store
->svc
.zone
->get_zone_params().user_uid_pool
, key
);
505 ldout(store
->ctx(), 10) << "removing user index: " << info
.user_id
<< dendl
;
506 ret
= store
->meta_mgr
->remove_entry(user_meta_handler
, key
, &objv_tracker
);
507 if (ret
< 0 && ret
!= -ENOENT
&& ret
!= -ECANCELED
) {
508 ldout(store
->ctx(), 0) << "ERROR: could not remove " << info
.user_id
<< ":" << uid_obj
<< ", should be fixed (err=" << ret
<< ")" << dendl
;
515 static bool char_is_unreserved_url(char c
)
531 struct rgw_flags_desc
{
536 static struct rgw_flags_desc rgw_perms
[] = {
537 { RGW_PERM_FULL_CONTROL
, "full-control" },
538 { RGW_PERM_READ
| RGW_PERM_WRITE
, "read-write" },
539 { RGW_PERM_READ
, "read" },
540 { RGW_PERM_WRITE
, "write" },
541 { RGW_PERM_READ_ACP
, "read-acp" },
542 { RGW_PERM_WRITE_ACP
, "write-acp" },
546 void rgw_perm_to_str(uint32_t mask
, char *buf
, int len
)
548 const char *sep
= "";
551 snprintf(buf
, len
, "<none>");
555 uint32_t orig_mask
= mask
;
556 for (int i
= 0; rgw_perms
[i
].mask
; i
++) {
557 struct rgw_flags_desc
*desc
= &rgw_perms
[i
];
558 if ((mask
& desc
->mask
) == desc
->mask
) {
559 pos
+= snprintf(buf
+ pos
, len
- pos
, "%s%s", sep
, desc
->str
);
568 if (mask
== orig_mask
) // no change
573 uint32_t rgw_str_to_perm(const char *str
)
575 if (strcasecmp(str
, "") == 0)
576 return RGW_PERM_NONE
;
577 else if (strcasecmp(str
, "read") == 0)
578 return RGW_PERM_READ
;
579 else if (strcasecmp(str
, "write") == 0)
580 return RGW_PERM_WRITE
;
581 else if (strcasecmp(str
, "readwrite") == 0)
582 return RGW_PERM_READ
| RGW_PERM_WRITE
;
583 else if (strcasecmp(str
, "full") == 0)
584 return RGW_PERM_FULL_CONTROL
;
586 return RGW_PERM_INVALID
;
589 int rgw_validate_tenant_name(const string
& t
)
592 static bool is_good(char ch
) {
593 return isalnum(ch
) || ch
== '_';
596 std::string::const_iterator it
=
597 std::find_if_not(t
.begin(), t
.end(), tench::is_good
);
598 return (it
== t
.end())? 0: -ERR_INVALID_TENANT_NAME
;
601 static bool validate_access_key(string
& key
)
603 const char *p
= key
.c_str();
605 if (!char_is_unreserved_url(*p
))
612 static void set_err_msg(std::string
*sink
, std::string msg
)
614 if (sink
&& !msg
.empty())
618 static bool remove_old_indexes(RGWRados
*store
,
619 RGWUserInfo
& old_info
, RGWUserInfo
& new_info
, std::string
*err_msg
)
624 if (!old_info
.user_id
.empty() &&
625 old_info
.user_id
.compare(new_info
.user_id
) != 0) {
626 if (old_info
.user_id
.tenant
!= new_info
.user_id
.tenant
) {
627 ldout(store
->ctx(), 0) << "ERROR: tenant mismatch: " << old_info
.user_id
.tenant
<< " != " << new_info
.user_id
.tenant
<< dendl
;
630 ret
= rgw_remove_uid_index(store
, old_info
.user_id
);
631 if (ret
< 0 && ret
!= -ENOENT
) {
632 set_err_msg(err_msg
, "ERROR: could not remove index for uid " + old_info
.user_id
.to_str());
637 if (!old_info
.user_email
.empty() &&
638 old_info
.user_email
.compare(new_info
.user_email
) != 0) {
639 ret
= rgw_remove_email_index(store
, old_info
.user_email
);
640 if (ret
< 0 && ret
!= -ENOENT
) {
641 set_err_msg(err_msg
, "ERROR: could not remove index for email " + old_info
.user_email
);
646 map
<string
, RGWAccessKey
>::iterator old_iter
;
647 for (old_iter
= old_info
.swift_keys
.begin(); old_iter
!= old_info
.swift_keys
.end(); ++old_iter
) {
648 RGWAccessKey
& swift_key
= old_iter
->second
;
649 map
<string
, RGWAccessKey
>::iterator new_iter
= new_info
.swift_keys
.find(swift_key
.id
);
650 if (new_iter
== new_info
.swift_keys
.end()) {
651 ret
= rgw_remove_swift_name_index(store
, swift_key
.id
);
652 if (ret
< 0 && ret
!= -ENOENT
) {
653 set_err_msg(err_msg
, "ERROR: could not remove index for swift_name " + swift_key
.id
);
663 * Dump either the full user info or a subset to a formatter.
665 * NOTE: It is the caller's respnsibility to ensure that the
666 * formatter is flushed at the correct time.
669 static void dump_subusers_info(Formatter
*f
, RGWUserInfo
&info
)
671 map
<string
, RGWSubUser
>::iterator uiter
;
673 f
->open_array_section("subusers");
674 for (uiter
= info
.subusers
.begin(); uiter
!= info
.subusers
.end(); ++uiter
) {
675 RGWSubUser
& u
= uiter
->second
;
676 f
->open_object_section("user");
678 info
.user_id
.to_str(s
);
679 f
->dump_format("id", "%s:%s", s
.c_str(), u
.name
.c_str());
681 rgw_perm_to_str(u
.perm_mask
, buf
, sizeof(buf
));
682 f
->dump_string("permissions", buf
);
688 static void dump_access_keys_info(Formatter
*f
, RGWUserInfo
&info
)
690 map
<string
, RGWAccessKey
>::iterator kiter
;
691 f
->open_array_section("keys");
692 for (kiter
= info
.access_keys
.begin(); kiter
!= info
.access_keys
.end(); ++kiter
) {
693 RGWAccessKey
& k
= kiter
->second
;
694 const char *sep
= (k
.subuser
.empty() ? "" : ":");
695 const char *subuser
= (k
.subuser
.empty() ? "" : k
.subuser
.c_str());
696 f
->open_object_section("key");
698 info
.user_id
.to_str(s
);
699 f
->dump_format("user", "%s%s%s", s
.c_str(), sep
, subuser
);
700 f
->dump_string("access_key", k
.id
);
701 f
->dump_string("secret_key", k
.key
);
707 static void dump_swift_keys_info(Formatter
*f
, RGWUserInfo
&info
)
709 map
<string
, RGWAccessKey
>::iterator kiter
;
710 f
->open_array_section("swift_keys");
711 for (kiter
= info
.swift_keys
.begin(); kiter
!= info
.swift_keys
.end(); ++kiter
) {
712 RGWAccessKey
& k
= kiter
->second
;
713 const char *sep
= (k
.subuser
.empty() ? "" : ":");
714 const char *subuser
= (k
.subuser
.empty() ? "" : k
.subuser
.c_str());
715 f
->open_object_section("key");
717 info
.user_id
.to_str(s
);
718 f
->dump_format("user", "%s%s%s", s
.c_str(), sep
, subuser
);
719 f
->dump_string("secret_key", k
.key
);
725 static void dump_user_info(Formatter
*f
, RGWUserInfo
&info
,
726 RGWStorageStats
*stats
= NULL
)
728 f
->open_object_section("user_info");
729 encode_json("tenant", info
.user_id
.tenant
, f
);
730 encode_json("user_id", info
.user_id
.id
, f
);
731 encode_json("display_name", info
.display_name
, f
);
732 encode_json("email", info
.user_email
, f
);
733 encode_json("suspended", (int)info
.suspended
, f
);
734 encode_json("max_buckets", (int)info
.max_buckets
, f
);
736 dump_subusers_info(f
, info
);
737 dump_access_keys_info(f
, info
);
738 dump_swift_keys_info(f
, info
);
740 encode_json("caps", info
.caps
, f
);
743 op_type_to_str(info
.op_mask
, buf
, sizeof(buf
));
744 encode_json("op_mask", (const char *)buf
, f
);
745 encode_json("system", (bool)info
.system
, f
);
746 encode_json("admin", (bool)info
.admin
, f
);
747 encode_json("default_placement", info
.default_placement
.name
, f
);
748 encode_json("default_storage_class", info
.default_placement
.storage_class
, f
);
749 encode_json("placement_tags", info
.placement_tags
, f
);
750 encode_json("bucket_quota", info
.bucket_quota
, f
);
751 encode_json("user_quota", info
.user_quota
, f
);
752 encode_json("temp_url_keys", info
.temp_url_keys
, f
);
754 string user_source_type
;
755 switch ((RGWIdentityType
)info
.type
) {
757 user_source_type
= "rgw";
760 user_source_type
= "keystone";
763 user_source_type
= "ldap";
766 user_source_type
= "none";
769 user_source_type
= "none";
772 encode_json("type", user_source_type
, f
);
773 encode_json("mfa_ids", info
.mfa_ids
, f
);
775 encode_json("stats", *stats
, f
);
781 RGWAccessKeyPool::RGWAccessKeyPool(RGWUser
* usr
)
788 keys_allowed
= false;
795 store
= user
->get_store();
798 RGWAccessKeyPool::~RGWAccessKeyPool()
803 int RGWAccessKeyPool::init(RGWUserAdminOpState
& op_state
)
805 if (!op_state
.is_initialized()) {
806 keys_allowed
= false;
810 rgw_user
& uid
= op_state
.get_user_id();
811 if (uid
.compare(RGW_USER_ANON_ID
) == 0) {
812 keys_allowed
= false;
816 swift_keys
= op_state
.get_swift_keys();
817 access_keys
= op_state
.get_access_keys();
825 * Do a fairly exhaustive search for an existing key matching the parameters
826 * given. Also handles the case where no key type was specified and updates
827 * the operation state if needed.
830 bool RGWAccessKeyPool::check_existing_key(RGWUserAdminOpState
& op_state
)
832 bool existing_key
= false;
834 int key_type
= op_state
.get_key_type();
835 std::string kid
= op_state
.get_access_key();
836 std::map
<std::string
, RGWAccessKey
>::iterator kiter
;
837 std::string swift_kid
= op_state
.build_default_swift_kid();
839 RGWUserInfo dup_info
;
841 if (kid
.empty() && swift_kid
.empty())
846 kiter
= swift_keys
->find(swift_kid
);
848 existing_key
= (kiter
!= swift_keys
->end());
850 op_state
.set_access_key(swift_kid
);
854 kiter
= access_keys
->find(kid
);
855 existing_key
= (kiter
!= access_keys
->end());
859 kiter
= access_keys
->find(kid
);
861 existing_key
= (kiter
!= access_keys
->end());
863 op_state
.set_key_type(KEY_TYPE_S3
);
867 kiter
= swift_keys
->find(kid
);
869 existing_key
= (kiter
!= swift_keys
->end());
871 op_state
.set_key_type(KEY_TYPE_SWIFT
);
875 // handle the case where the access key was not provided in user:key format
876 if (swift_kid
.empty())
879 kiter
= swift_keys
->find(swift_kid
);
881 existing_key
= (kiter
!= swift_keys
->end());
883 op_state
.set_access_key(swift_kid
);
884 op_state
.set_key_type(KEY_TYPE_SWIFT
);
888 op_state
.set_existing_key(existing_key
);
893 int RGWAccessKeyPool::check_op(RGWUserAdminOpState
& op_state
,
894 std::string
*err_msg
)
896 RGWUserInfo dup_info
;
898 if (!op_state
.is_populated()) {
899 set_err_msg(err_msg
, "user info was not populated");
904 set_err_msg(err_msg
, "keys not allowed for this user");
908 int32_t key_type
= op_state
.get_key_type();
910 // if a key type wasn't specified
912 if (op_state
.has_subuser()) {
913 key_type
= KEY_TYPE_SWIFT
;
915 key_type
= KEY_TYPE_S3
;
919 op_state
.set_key_type(key_type
);
921 /* see if the access key was specified */
922 if (key_type
== KEY_TYPE_S3
&& !op_state
.will_gen_access() &&
923 op_state
.get_access_key().empty()) {
924 set_err_msg(err_msg
, "empty access key");
925 return -ERR_INVALID_ACCESS_KEY
;
928 // don't check for secret key because we may be doing a removal
930 check_existing_key(op_state
);
935 // Generate a new random key
936 int RGWAccessKeyPool::generate_key(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
941 std::pair
<std::string
, RGWAccessKey
> key_pair
;
942 RGWAccessKey new_key
;
943 RGWUserInfo duplicate_check
;
945 int key_type
= op_state
.get_key_type();
946 bool gen_access
= op_state
.will_gen_access();
947 bool gen_secret
= op_state
.will_gen_secret();
950 set_err_msg(err_msg
, "access keys not allowed for this user");
954 if (op_state
.has_existing_key()) {
955 set_err_msg(err_msg
, "cannot create existing key");
956 return -ERR_KEY_EXIST
;
960 id
= op_state
.get_access_key();
966 if (rgw_get_user_info_by_swift(store
, id
, duplicate_check
) >= 0) {
967 set_err_msg(err_msg
, "existing swift key in RGW system:" + id
);
968 return -ERR_KEY_EXIST
;
972 if (rgw_get_user_info_by_access_key(store
, id
, duplicate_check
) >= 0) {
973 set_err_msg(err_msg
, "existing S3 key in RGW system:" + id
);
974 return -ERR_KEY_EXIST
;
980 if (op_state
.has_subuser()) {
981 //create user and subuser at the same time, user's s3 key should not be set this
982 if (!op_state
.key_type_setbycontext
|| (key_type
== KEY_TYPE_SWIFT
)) {
983 new_key
.subuser
= op_state
.get_subuser();
989 if (op_state
.get_secret_key().empty()) {
990 set_err_msg(err_msg
, "empty secret key");
991 return -ERR_INVALID_SECRET_KEY
;
994 key
= op_state
.get_secret_key();
996 char secret_key_buf
[SECRET_KEY_LEN
+ 1];
997 gen_rand_alphanumeric_plain(g_ceph_context
, secret_key_buf
, sizeof(secret_key_buf
));
998 key
= secret_key_buf
;
1001 // Generate the access key
1002 if (key_type
== KEY_TYPE_S3
&& gen_access
) {
1003 char public_id_buf
[PUBLIC_ID_LEN
+ 1];
1006 int id_buf_size
= sizeof(public_id_buf
);
1007 gen_rand_alphanumeric_upper(g_ceph_context
, public_id_buf
, id_buf_size
);
1009 if (!validate_access_key(id
))
1012 } while (!rgw_get_user_info_by_access_key(store
, id
, duplicate_check
));
1015 if (key_type
== KEY_TYPE_SWIFT
) {
1016 id
= op_state
.build_default_swift_kid();
1018 set_err_msg(err_msg
, "empty swift access key");
1019 return -ERR_INVALID_ACCESS_KEY
;
1022 // check that the access key doesn't exist
1023 if (rgw_get_user_info_by_swift(store
, id
, duplicate_check
) >= 0) {
1024 set_err_msg(err_msg
, "cannot create existing swift key");
1025 return -ERR_KEY_EXIST
;
1029 // finally create the new key
1033 key_pair
.first
= id
;
1034 key_pair
.second
= new_key
;
1036 if (key_type
== KEY_TYPE_S3
) {
1037 access_keys
->insert(key_pair
);
1038 } else if (key_type
== KEY_TYPE_SWIFT
) {
1039 swift_keys
->insert(key_pair
);
1045 // modify an existing key
1046 int RGWAccessKeyPool::modify_key(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1049 std::string key
= op_state
.get_secret_key();
1050 int key_type
= op_state
.get_key_type();
1052 RGWAccessKey modify_key
;
1054 pair
<string
, RGWAccessKey
> key_pair
;
1055 map
<std::string
, RGWAccessKey
>::iterator kiter
;
1059 id
= op_state
.get_access_key();
1061 set_err_msg(err_msg
, "no access key specified");
1062 return -ERR_INVALID_ACCESS_KEY
;
1065 case KEY_TYPE_SWIFT
:
1066 id
= op_state
.build_default_swift_kid();
1068 set_err_msg(err_msg
, "no subuser specified");
1073 set_err_msg(err_msg
, "invalid key type");
1074 return -ERR_INVALID_KEY_TYPE
;
1077 if (!op_state
.has_existing_key()) {
1078 set_err_msg(err_msg
, "key does not exist");
1079 return -ERR_INVALID_ACCESS_KEY
;
1082 key_pair
.first
= id
;
1084 if (key_type
== KEY_TYPE_SWIFT
) {
1086 modify_key
.subuser
= op_state
.get_subuser();
1087 } else if (key_type
== KEY_TYPE_S3
) {
1088 kiter
= access_keys
->find(id
);
1089 if (kiter
!= access_keys
->end()) {
1090 modify_key
= kiter
->second
;
1094 if (op_state
.will_gen_secret()) {
1095 char secret_key_buf
[SECRET_KEY_LEN
+ 1];
1096 int key_buf_size
= sizeof(secret_key_buf
);
1097 gen_rand_alphanumeric_plain(g_ceph_context
, secret_key_buf
, key_buf_size
);
1098 key
= secret_key_buf
;
1102 set_err_msg(err_msg
, "empty secret key");
1103 return -ERR_INVALID_SECRET_KEY
;
1106 // update the access key with the new secret key
1107 modify_key
.key
= key
;
1109 key_pair
.second
= modify_key
;
1112 if (key_type
== KEY_TYPE_S3
) {
1113 (*access_keys
)[id
] = modify_key
;
1114 } else if (key_type
== KEY_TYPE_SWIFT
) {
1115 (*swift_keys
)[id
] = modify_key
;
1121 int RGWAccessKeyPool::execute_add(RGWUserAdminOpState
& op_state
,
1122 std::string
*err_msg
, bool defer_user_update
)
1126 std::string subprocess_msg
;
1127 int key_op
= GENERATE_KEY
;
1130 if (op_state
.has_existing_key())
1131 key_op
= MODIFY_KEY
;
1135 ret
= generate_key(op_state
, &subprocess_msg
);
1138 ret
= modify_key(op_state
, &subprocess_msg
);
1143 set_err_msg(err_msg
, subprocess_msg
);
1147 // store the updated info
1148 if (!defer_user_update
)
1149 ret
= user
->update(op_state
, err_msg
);
1157 int RGWAccessKeyPool::add(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1159 return add(op_state
, err_msg
, false);
1162 int RGWAccessKeyPool::add(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_user_update
)
1165 std::string subprocess_msg
;
1167 ret
= check_op(op_state
, &subprocess_msg
);
1169 set_err_msg(err_msg
, "unable to parse request, " + subprocess_msg
);
1173 ret
= execute_add(op_state
, &subprocess_msg
, defer_user_update
);
1175 set_err_msg(err_msg
, "unable to add access key, " + subprocess_msg
);
1182 int RGWAccessKeyPool::execute_remove(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_user_update
)
1186 int key_type
= op_state
.get_key_type();
1187 std::string id
= op_state
.get_access_key();
1188 map
<std::string
, RGWAccessKey
>::iterator kiter
;
1189 map
<std::string
, RGWAccessKey
> *keys_map
;
1191 if (!op_state
.has_existing_key()) {
1192 set_err_msg(err_msg
, "unable to find access key");
1193 return -ERR_INVALID_ACCESS_KEY
;
1196 if (key_type
== KEY_TYPE_S3
) {
1197 keys_map
= access_keys
;
1198 } else if (key_type
== KEY_TYPE_SWIFT
) {
1199 keys_map
= swift_keys
;
1202 set_err_msg(err_msg
, "invalid access key");
1203 return -ERR_INVALID_ACCESS_KEY
;
1206 kiter
= keys_map
->find(id
);
1207 if (kiter
== keys_map
->end()) {
1208 set_err_msg(err_msg
, "key not found");
1209 return -ERR_INVALID_ACCESS_KEY
;
1212 rgw_remove_key_index(store
, kiter
->second
);
1213 keys_map
->erase(kiter
);
1215 if (!defer_user_update
)
1216 ret
= user
->update(op_state
, err_msg
);
1224 int RGWAccessKeyPool::remove(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1226 return remove(op_state
, err_msg
, false);
1229 int RGWAccessKeyPool::remove(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_user_update
)
1233 std::string subprocess_msg
;
1235 ret
= check_op(op_state
, &subprocess_msg
);
1237 set_err_msg(err_msg
, "unable to parse request, " + subprocess_msg
);
1241 ret
= execute_remove(op_state
, &subprocess_msg
, defer_user_update
);
1243 set_err_msg(err_msg
, "unable to remove access key, " + subprocess_msg
);
1250 // remove all keys associated with a subuser
1251 int RGWAccessKeyPool::remove_subuser_keys(RGWUserAdminOpState
& op_state
,
1252 std::string
*err_msg
, bool defer_user_update
)
1256 if (!op_state
.is_populated()) {
1257 set_err_msg(err_msg
, "user info was not populated");
1261 if (!op_state
.has_subuser()) {
1262 set_err_msg(err_msg
, "no subuser specified");
1266 std::string swift_kid
= op_state
.build_default_swift_kid();
1267 if (swift_kid
.empty()) {
1268 set_err_msg(err_msg
, "empty swift access key");
1272 map
<std::string
, RGWAccessKey
>::iterator kiter
;
1273 map
<std::string
, RGWAccessKey
> *keys_map
;
1275 // a subuser can have at most one swift key
1276 keys_map
= swift_keys
;
1277 kiter
= keys_map
->find(swift_kid
);
1278 if (kiter
!= keys_map
->end()) {
1279 rgw_remove_key_index(store
, kiter
->second
);
1280 keys_map
->erase(kiter
);
1283 // a subuser may have multiple s3 key pairs
1284 std::string subuser_str
= op_state
.get_subuser();
1285 keys_map
= access_keys
;
1286 RGWUserInfo user_info
= op_state
.get_user_info();
1287 map
<std::string
, RGWAccessKey
>::iterator user_kiter
= user_info
.access_keys
.begin();
1288 for (; user_kiter
!= user_info
.access_keys
.end(); ++user_kiter
) {
1289 if (user_kiter
->second
.subuser
== subuser_str
) {
1290 kiter
= keys_map
->find(user_kiter
->first
);
1291 if (kiter
!= keys_map
->end()) {
1292 rgw_remove_key_index(store
, kiter
->second
);
1293 keys_map
->erase(kiter
);
1298 if (!defer_user_update
)
1299 ret
= user
->update(op_state
, err_msg
);
1307 RGWSubUserPool::RGWSubUserPool(RGWUser
*usr
)
1309 subusers_allowed
= (usr
!= NULL
);
1311 store
= usr
->get_store();
1318 RGWSubUserPool::~RGWSubUserPool()
1323 int RGWSubUserPool::init(RGWUserAdminOpState
& op_state
)
1325 if (!op_state
.is_initialized()) {
1326 subusers_allowed
= false;
1330 rgw_user
& uid
= op_state
.get_user_id();
1331 if (uid
.compare(RGW_USER_ANON_ID
) == 0) {
1332 subusers_allowed
= false;
1336 subuser_map
= op_state
.get_subusers();
1337 if (subuser_map
== NULL
) {
1338 subusers_allowed
= false;
1342 subusers_allowed
= true;
1347 bool RGWSubUserPool::exists(std::string subuser
)
1349 if (subuser
.empty())
1355 if (subuser_map
->count(subuser
))
1361 int RGWSubUserPool::check_op(RGWUserAdminOpState
& op_state
,
1362 std::string
*err_msg
)
1364 bool existing
= false;
1365 std::string subuser
= op_state
.get_subuser();
1367 if (!op_state
.is_populated()) {
1368 set_err_msg(err_msg
, "user info was not populated");
1372 if (!subusers_allowed
) {
1373 set_err_msg(err_msg
, "subusers not allowed for this user");
1377 if (subuser
.empty() && !op_state
.will_gen_subuser()) {
1378 set_err_msg(err_msg
, "empty subuser name");
1382 if (op_state
.get_subuser_perm() == RGW_PERM_INVALID
) {
1383 set_err_msg(err_msg
, "invaild subuser access");
1387 //set key type when it not set or set by context
1388 if ((op_state
.get_key_type() < 0) || op_state
.key_type_setbycontext
) {
1389 op_state
.set_key_type(KEY_TYPE_SWIFT
);
1390 op_state
.key_type_setbycontext
= true;
1393 // check if the subuser exists
1394 if (!subuser
.empty())
1395 existing
= exists(subuser
);
1397 op_state
.set_existing_subuser(existing
);
1402 int RGWSubUserPool::execute_add(RGWUserAdminOpState
& op_state
,
1403 std::string
*err_msg
, bool defer_user_update
)
1406 std::string subprocess_msg
;
1409 std::pair
<std::string
, RGWSubUser
> subuser_pair
;
1410 std::string subuser_str
= op_state
.get_subuser();
1412 subuser_pair
.first
= subuser_str
;
1414 // assumes key should be created
1415 if (op_state
.has_key_op()) {
1416 ret
= user
->keys
.add(op_state
, &subprocess_msg
, true);
1418 set_err_msg(err_msg
, "unable to create subuser key, " + subprocess_msg
);
1423 // create the subuser
1424 subuser
.name
= subuser_str
;
1426 if (op_state
.has_subuser_perm())
1427 subuser
.perm_mask
= op_state
.get_subuser_perm();
1429 // insert the subuser into user info
1430 subuser_pair
.second
= subuser
;
1431 subuser_map
->insert(subuser_pair
);
1433 // attempt to save the subuser
1434 if (!defer_user_update
)
1435 ret
= user
->update(op_state
, err_msg
);
1443 int RGWSubUserPool::add(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1445 return add(op_state
, err_msg
, false);
1448 int RGWSubUserPool::add(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_user_update
)
1450 std::string subprocess_msg
;
1452 int32_t key_type
= op_state
.get_key_type();
1454 ret
= check_op(op_state
, &subprocess_msg
);
1456 set_err_msg(err_msg
, "unable to parse request, " + subprocess_msg
);
1460 if (key_type
== KEY_TYPE_S3
&& op_state
.get_access_key().empty()) {
1461 op_state
.set_gen_access();
1464 if (op_state
.get_secret_key().empty()) {
1465 op_state
.set_gen_secret();
1468 ret
= execute_add(op_state
, &subprocess_msg
, defer_user_update
);
1470 set_err_msg(err_msg
, "unable to create subuser, " + subprocess_msg
);
1477 int RGWSubUserPool::execute_remove(RGWUserAdminOpState
& op_state
,
1478 std::string
*err_msg
, bool defer_user_update
)
1481 std::string subprocess_msg
;
1483 std::string subuser_str
= op_state
.get_subuser();
1485 map
<std::string
, RGWSubUser
>::iterator siter
;
1486 siter
= subuser_map
->find(subuser_str
);
1487 if (siter
== subuser_map
->end()){
1488 set_err_msg(err_msg
, "subuser not found: " + subuser_str
);
1489 return -ERR_NO_SUCH_SUBUSER
;
1491 if (!op_state
.has_existing_subuser()) {
1492 set_err_msg(err_msg
, "subuser not found: " + subuser_str
);
1493 return -ERR_NO_SUCH_SUBUSER
;
1496 // always purge all associate keys
1497 user
->keys
.remove_subuser_keys(op_state
, &subprocess_msg
, true);
1499 // remove the subuser from the user info
1500 subuser_map
->erase(siter
);
1502 // attempt to save the subuser
1503 if (!defer_user_update
)
1504 ret
= user
->update(op_state
, err_msg
);
1512 int RGWSubUserPool::remove(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1514 return remove(op_state
, err_msg
, false);
1517 int RGWSubUserPool::remove(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_user_update
)
1519 std::string subprocess_msg
;
1522 ret
= check_op(op_state
, &subprocess_msg
);
1524 set_err_msg(err_msg
, "unable to parse request, " + subprocess_msg
);
1528 ret
= execute_remove(op_state
, &subprocess_msg
, defer_user_update
);
1530 set_err_msg(err_msg
, "unable to remove subuser, " + subprocess_msg
);
1537 int RGWSubUserPool::execute_modify(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_user_update
)
1540 std::string subprocess_msg
;
1541 std::map
<std::string
, RGWSubUser
>::iterator siter
;
1542 std::pair
<std::string
, RGWSubUser
> subuser_pair
;
1544 std::string subuser_str
= op_state
.get_subuser();
1547 if (!op_state
.has_existing_subuser()) {
1548 set_err_msg(err_msg
, "subuser does not exist");
1549 return -ERR_NO_SUCH_SUBUSER
;
1552 subuser_pair
.first
= subuser_str
;
1554 siter
= subuser_map
->find(subuser_str
);
1555 subuser
= siter
->second
;
1557 if (op_state
.has_key_op()) {
1558 ret
= user
->keys
.add(op_state
, &subprocess_msg
, true);
1560 set_err_msg(err_msg
, "unable to create subuser keys, " + subprocess_msg
);
1565 if (op_state
.has_subuser_perm())
1566 subuser
.perm_mask
= op_state
.get_subuser_perm();
1568 subuser_pair
.second
= subuser
;
1570 subuser_map
->erase(siter
);
1571 subuser_map
->insert(subuser_pair
);
1573 // attempt to save the subuser
1574 if (!defer_user_update
)
1575 ret
= user
->update(op_state
, err_msg
);
1583 int RGWSubUserPool::modify(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1585 return RGWSubUserPool::modify(op_state
, err_msg
, false);
1588 int RGWSubUserPool::modify(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_user_update
)
1590 std::string subprocess_msg
;
1595 ret
= check_op(op_state
, &subprocess_msg
);
1597 set_err_msg(err_msg
, "unable to parse request, " + subprocess_msg
);
1601 ret
= execute_modify(op_state
, &subprocess_msg
, defer_user_update
);
1603 set_err_msg(err_msg
, "unable to modify subuser, " + subprocess_msg
);
1610 RGWUserCapPool::RGWUserCapPool(RGWUser
*usr
)
1614 caps_allowed
= (user
!= NULL
);
1617 RGWUserCapPool::~RGWUserCapPool()
1622 int RGWUserCapPool::init(RGWUserAdminOpState
& op_state
)
1624 if (!op_state
.is_initialized()) {
1625 caps_allowed
= false;
1629 rgw_user
& uid
= op_state
.get_user_id();
1630 if (uid
.compare(RGW_USER_ANON_ID
) == 0) {
1631 caps_allowed
= false;
1635 caps
= op_state
.get_caps_obj();
1637 caps_allowed
= false;
1638 return -ERR_INVALID_CAP
;
1641 caps_allowed
= true;
1646 int RGWUserCapPool::add(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1648 return add(op_state
, err_msg
, false);
1651 int RGWUserCapPool::add(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_save
)
1654 std::string caps_str
= op_state
.get_caps();
1656 if (!op_state
.is_populated()) {
1657 set_err_msg(err_msg
, "user info was not populated");
1661 if (!caps_allowed
) {
1662 set_err_msg(err_msg
, "caps not allowed for this user");
1666 if (caps_str
.empty()) {
1667 set_err_msg(err_msg
, "empty user caps");
1668 return -ERR_INVALID_CAP
;
1671 int r
= caps
->add_from_string(caps_str
);
1673 set_err_msg(err_msg
, "unable to add caps: " + caps_str
);
1678 ret
= user
->update(op_state
, err_msg
);
1686 int RGWUserCapPool::remove(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1688 return remove(op_state
, err_msg
, false);
1691 int RGWUserCapPool::remove(RGWUserAdminOpState
& op_state
, std::string
*err_msg
, bool defer_save
)
1695 std::string caps_str
= op_state
.get_caps();
1697 if (!op_state
.is_populated()) {
1698 set_err_msg(err_msg
, "user info was not populated");
1702 if (!caps_allowed
) {
1703 set_err_msg(err_msg
, "caps not allowed for this user");
1707 if (caps_str
.empty()) {
1708 set_err_msg(err_msg
, "empty user caps");
1709 return -ERR_INVALID_CAP
;
1712 int r
= caps
->remove_from_string(caps_str
);
1714 set_err_msg(err_msg
, "unable to remove caps: " + caps_str
);
1719 ret
= user
->update(op_state
, err_msg
);
1727 RGWUser::RGWUser() : store(NULL
), info_stored(false), caps(this), keys(this), subusers(this)
1732 int RGWUser::init(RGWRados
*storage
, RGWUserAdminOpState
& op_state
)
1735 int ret
= init_storage(storage
);
1739 ret
= init(op_state
);
1750 void RGWUser::init_default()
1752 // use anonymous user info as a placeholder
1753 rgw_get_anon_user(old_info
);
1754 user_id
= RGW_USER_ANON_ID
;
1759 int RGWUser::init_storage(RGWRados
*storage
)
1770 keys
= RGWAccessKeyPool(this);
1771 caps
= RGWUserCapPool(this);
1772 subusers
= RGWSubUserPool(this);
1777 int RGWUser::init(RGWUserAdminOpState
& op_state
)
1780 std::string swift_user
;
1781 user_id
= op_state
.get_user_id();
1782 std::string user_email
= op_state
.get_user_email();
1783 std::string access_key
= op_state
.get_access_key();
1784 std::string subuser
= op_state
.get_subuser();
1786 int key_type
= op_state
.get_key_type();
1787 if (key_type
== KEY_TYPE_SWIFT
) {
1788 swift_user
= op_state
.get_access_key();
1792 RGWUserInfo user_info
;
1796 if (user_id
.empty() && !subuser
.empty()) {
1797 size_t pos
= subuser
.find(':');
1798 if (pos
!= string::npos
) {
1799 user_id
= subuser
.substr(0, pos
);
1800 op_state
.set_user_id(user_id
);
1804 if (!user_id
.empty() && (user_id
.compare(RGW_USER_ANON_ID
) != 0)) {
1805 found
= (rgw_get_user_info_by_uid(store
, user_id
, user_info
, &op_state
.objv
) >= 0);
1806 op_state
.found_by_uid
= found
;
1808 if (store
->ctx()->_conf
.get_val
<bool>("rgw_user_unique_email")) {
1809 if (!user_email
.empty() && !found
) {
1810 found
= (rgw_get_user_info_by_email(store
, user_email
, user_info
, &op_state
.objv
) >= 0);
1811 op_state
.found_by_email
= found
;
1814 if (!swift_user
.empty() && !found
) {
1815 found
= (rgw_get_user_info_by_swift(store
, swift_user
, user_info
, &op_state
.objv
) >= 0);
1816 op_state
.found_by_key
= found
;
1818 if (!access_key
.empty() && !found
) {
1819 found
= (rgw_get_user_info_by_access_key(store
, access_key
, user_info
, &op_state
.objv
) >= 0);
1820 op_state
.found_by_key
= found
;
1823 op_state
.set_existing_user(found
);
1825 op_state
.set_user_info(user_info
);
1826 op_state
.set_populated();
1828 old_info
= user_info
;
1832 if (user_id
.empty()) {
1833 user_id
= user_info
.user_id
;
1835 op_state
.set_initialized();
1837 // this may have been called by a helper object
1838 int ret
= init_members(op_state
);
1845 int RGWUser::init_members(RGWUserAdminOpState
& op_state
)
1849 ret
= keys
.init(op_state
);
1853 ret
= subusers
.init(op_state
);
1857 ret
= caps
.init(op_state
);
1864 int RGWUser::update(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1867 std::string subprocess_msg
;
1868 RGWUserInfo user_info
= op_state
.get_user_info();
1871 set_err_msg(err_msg
, "couldn't initialize storage");
1875 if (is_populated()) {
1876 ret
= rgw_store_user_info(store
, user_info
, &old_info
, &op_state
.objv
, real_time(), false);
1878 set_err_msg(err_msg
, "unable to store user info");
1882 ret
= remove_old_indexes(store
, old_info
, user_info
, &subprocess_msg
);
1884 set_err_msg(err_msg
, "unable to remove old user info, " + subprocess_msg
);
1888 ret
= rgw_store_user_info(store
, user_info
, NULL
, &op_state
.objv
, real_time(), false);
1890 set_err_msg(err_msg
, "unable to store user info");
1895 old_info
= user_info
;
1901 int RGWUser::check_op(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1905 rgw_user
& op_id
= op_state
.get_user_id();
1907 RGWUserInfo user_info
;
1909 same_id
= (user_id
.compare(op_id
) == 0);
1910 populated
= is_populated();
1912 if (op_id
.compare(RGW_USER_ANON_ID
) == 0) {
1913 set_err_msg(err_msg
, "unable to perform operations on the anonymous user");
1917 if (populated
&& !same_id
) {
1918 set_err_msg(err_msg
, "user id mismatch, operation id: " + op_id
.to_str()
1919 + " does not match: " + user_id
.to_str());
1924 int ret
= rgw_validate_tenant_name(op_id
.tenant
);
1926 set_err_msg(err_msg
,
1927 "invalid tenant only alphanumeric and _ characters are allowed");
1931 //set key type when it not set or set by context
1932 if ((op_state
.get_key_type() < 0) || op_state
.key_type_setbycontext
) {
1933 op_state
.set_key_type(KEY_TYPE_S3
);
1934 op_state
.key_type_setbycontext
= true;
1940 int RGWUser::execute_add(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
1942 std::string subprocess_msg
;
1944 bool defer_user_update
= true;
1946 RGWUserInfo user_info
;
1948 rgw_user
& uid
= op_state
.get_user_id();
1949 std::string user_email
= op_state
.get_user_email();
1950 std::string display_name
= op_state
.get_display_name();
1952 // fail if the user exists already
1953 if (op_state
.has_existing_user()) {
1954 if (!op_state
.exclusive
&&
1955 (user_email
.empty() ||
1956 boost::iequals(user_email
, old_info
.user_email
)) &&
1957 old_info
.display_name
== display_name
) {
1958 return execute_modify(op_state
, err_msg
);
1961 if (op_state
.found_by_email
) {
1962 set_err_msg(err_msg
, "email: " + user_email
+
1963 " is the email address an existing user");
1964 ret
= -ERR_EMAIL_EXIST
;
1965 } else if (op_state
.found_by_key
) {
1966 set_err_msg(err_msg
, "duplicate key provided");
1967 ret
= -ERR_KEY_EXIST
;
1969 set_err_msg(err_msg
, "user: " + op_state
.user_id
.to_str() + " exists");
1975 // fail if the user_info has already been populated
1976 if (op_state
.is_populated()) {
1977 set_err_msg(err_msg
, "cannot overwrite already populated user");
1981 // fail if the display name was not included
1982 if (display_name
.empty()) {
1983 set_err_msg(err_msg
, "no display name specified");
1988 // set the user info
1990 user_info
.user_id
= user_id
;
1991 user_info
.display_name
= display_name
;
1992 user_info
.type
= TYPE_RGW
;
1994 if (!user_email
.empty())
1995 user_info
.user_email
= user_email
;
1997 CephContext
*cct
= store
->ctx();
1998 if (op_state
.max_buckets_specified
) {
1999 user_info
.max_buckets
= op_state
.get_max_buckets();
2001 user_info
.max_buckets
= cct
->_conf
->rgw_user_max_buckets
;
2004 user_info
.suspended
= op_state
.get_suspension_status();
2005 user_info
.admin
= op_state
.admin
;
2006 user_info
.system
= op_state
.system
;
2008 if (op_state
.op_mask_specified
)
2009 user_info
.op_mask
= op_state
.get_op_mask();
2011 if (op_state
.has_bucket_quota()) {
2012 user_info
.bucket_quota
= op_state
.get_bucket_quota();
2014 rgw_apply_default_bucket_quota(user_info
.bucket_quota
, cct
->_conf
);
2017 if (op_state
.temp_url_key_specified
) {
2018 map
<int, string
>::iterator iter
;
2019 for (iter
= op_state
.temp_url_keys
.begin();
2020 iter
!= op_state
.temp_url_keys
.end(); ++iter
) {
2021 user_info
.temp_url_keys
[iter
->first
] = iter
->second
;
2025 if (op_state
.has_user_quota()) {
2026 user_info
.user_quota
= op_state
.get_user_quota();
2028 rgw_apply_default_user_quota(user_info
.user_quota
, cct
->_conf
);
2031 // update the request
2032 op_state
.set_user_info(user_info
);
2033 op_state
.set_populated();
2035 // update the helper objects
2036 ret
= init_members(op_state
);
2038 set_err_msg(err_msg
, "unable to initialize user");
2042 // see if we need to add an access key
2043 if (op_state
.has_key_op()) {
2044 ret
= keys
.add(op_state
, &subprocess_msg
, defer_user_update
);
2046 set_err_msg(err_msg
, "unable to create access key, " + subprocess_msg
);
2051 // see if we need to add some caps
2052 if (op_state
.has_caps_op()) {
2053 ret
= caps
.add(op_state
, &subprocess_msg
, defer_user_update
);
2055 set_err_msg(err_msg
, "unable to add user capabilities, " + subprocess_msg
);
2060 ret
= update(op_state
, err_msg
);
2067 int RGWUser::add(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
2069 std::string subprocess_msg
;
2072 ret
= check_op(op_state
, &subprocess_msg
);
2074 set_err_msg(err_msg
, "unable to parse parameters, " + subprocess_msg
);
2078 ret
= execute_add(op_state
, &subprocess_msg
);
2080 set_err_msg(err_msg
, "unable to create user, " + subprocess_msg
);
2087 int RGWUser::execute_remove(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
2091 bool purge_data
= op_state
.will_purge_data();
2092 rgw_user
& uid
= op_state
.get_user_id();
2093 RGWUserInfo user_info
= op_state
.get_user_info();
2095 if (!op_state
.has_existing_user()) {
2096 set_err_msg(err_msg
, "user does not exist");
2100 bool is_truncated
= false;
2102 CephContext
*cct
= store
->ctx();
2103 size_t max_buckets
= cct
->_conf
->rgw_list_buckets_max_chunk
;
2105 RGWUserBuckets buckets
;
2106 ret
= rgw_read_user_buckets(store
, uid
, buckets
, marker
, string(),
2107 max_buckets
, false, &is_truncated
);
2109 set_err_msg(err_msg
, "unable to read user bucket info");
2113 map
<std::string
, RGWBucketEnt
>& m
= buckets
.get_buckets();
2114 if (!m
.empty() && !purge_data
) {
2115 set_err_msg(err_msg
, "must specify purge data to remove user with buckets");
2116 return -EEXIST
; // change to code that maps to 409: conflict
2119 std::map
<std::string
, RGWBucketEnt
>::iterator it
;
2120 for (it
= m
.begin(); it
!= m
.end(); ++it
) {
2121 ret
= rgw_remove_bucket(store
, ((*it
).second
).bucket
, true);
2123 set_err_msg(err_msg
, "unable to delete user data");
2130 } while (is_truncated
);
2132 ret
= rgw_delete_user(store
, user_info
, op_state
.objv
);
2134 set_err_msg(err_msg
, "unable to remove user from RADOS");
2138 op_state
.clear_populated();
2144 int RGWUser::remove(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
2146 std::string subprocess_msg
;
2149 ret
= check_op(op_state
, &subprocess_msg
);
2151 set_err_msg(err_msg
, "unable to parse parameters, " + subprocess_msg
);
2155 ret
= execute_remove(op_state
, &subprocess_msg
);
2157 set_err_msg(err_msg
, "unable to remove user, " + subprocess_msg
);
2164 int RGWUser::execute_modify(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
2166 bool populated
= op_state
.is_populated();
2168 std::string subprocess_msg
;
2169 std::string op_email
= op_state
.get_user_email();
2170 std::string display_name
= op_state
.get_display_name();
2172 RGWUserInfo user_info
;
2173 RGWUserInfo duplicate_check
;
2175 // ensure that the user info has been populated or is populate-able
2176 if (!op_state
.has_existing_user() && !populated
) {
2177 set_err_msg(err_msg
, "user not found");
2181 // if the user hasn't already been populated...attempt to
2183 ret
= init(op_state
);
2185 set_err_msg(err_msg
, "unable to retrieve user info");
2190 // ensure that we can modify the user's attributes
2191 if (user_id
.compare(RGW_USER_ANON_ID
) == 0) {
2192 set_err_msg(err_msg
, "unable to modify anonymous user's info");
2196 user_info
= old_info
;
2198 std::string old_email
= old_info
.user_email
;
2199 if (!op_email
.empty()) {
2200 // make sure we are not adding a duplicate email
2201 if (old_email
.compare(op_email
) != 0) {
2202 ret
= rgw_get_user_info_by_email(store
, op_email
, duplicate_check
);
2203 if (ret
>= 0 && duplicate_check
.user_id
.compare(user_id
) != 0) {
2204 set_err_msg(err_msg
, "cannot add duplicate email");
2205 return -ERR_EMAIL_EXIST
;
2208 user_info
.user_email
= op_email
;
2209 } else if (op_email
.empty() && op_state
.user_email_specified
) {
2211 ldout(store
->ctx(), 10) << "removing email index: " << user_info
.user_email
<< dendl
;
2212 ret
= rgw_remove_email_index(store
, user_info
.user_email
);
2213 if (ret
< 0 && ret
!= -ENOENT
) {
2214 ldout(store
->ctx(), 0) << "ERROR: could not remove " << user_info
.user_id
<< " index (err=" << ret
<< ")" << dendl
;
2217 user_info
.user_email
= "";
2220 // update the remaining user info
2221 if (!display_name
.empty())
2222 user_info
.display_name
= display_name
;
2224 if (op_state
.max_buckets_specified
)
2225 user_info
.max_buckets
= op_state
.get_max_buckets();
2227 if (op_state
.admin_specified
)
2228 user_info
.admin
= op_state
.admin
;
2230 if (op_state
.system_specified
)
2231 user_info
.system
= op_state
.system
;
2233 if (op_state
.temp_url_key_specified
) {
2234 map
<int, string
>::iterator iter
;
2235 for (iter
= op_state
.temp_url_keys
.begin();
2236 iter
!= op_state
.temp_url_keys
.end(); ++iter
) {
2237 user_info
.temp_url_keys
[iter
->first
] = iter
->second
;
2241 if (op_state
.op_mask_specified
)
2242 user_info
.op_mask
= op_state
.get_op_mask();
2244 if (op_state
.has_bucket_quota())
2245 user_info
.bucket_quota
= op_state
.get_bucket_quota();
2247 if (op_state
.has_user_quota())
2248 user_info
.user_quota
= op_state
.get_user_quota();
2250 if (op_state
.has_suspension_op()) {
2251 __u8 suspended
= op_state
.get_suspension_status();
2252 user_info
.suspended
= suspended
;
2254 RGWUserBuckets buckets
;
2256 if (user_id
.empty()) {
2257 set_err_msg(err_msg
, "empty user id passed...aborting");
2261 bool is_truncated
= false;
2263 CephContext
*cct
= store
->ctx();
2264 size_t max_buckets
= cct
->_conf
->rgw_list_buckets_max_chunk
;
2266 ret
= rgw_read_user_buckets(store
, user_id
, buckets
, marker
, string(),
2267 max_buckets
, false, &is_truncated
);
2269 set_err_msg(err_msg
, "could not get buckets for uid: " + user_id
.to_str());
2273 map
<string
, RGWBucketEnt
>& m
= buckets
.get_buckets();
2274 map
<string
, RGWBucketEnt
>::iterator iter
;
2276 vector
<rgw_bucket
> bucket_names
;
2277 for (iter
= m
.begin(); iter
!= m
.end(); ++iter
) {
2278 RGWBucketEnt obj
= iter
->second
;
2279 bucket_names
.push_back(obj
.bucket
);
2281 marker
= iter
->first
;
2284 ret
= store
->set_buckets_enabled(bucket_names
, !suspended
);
2286 set_err_msg(err_msg
, "failed to modify bucket");
2290 } while (is_truncated
);
2293 if (op_state
.mfa_ids_specified
) {
2294 user_info
.mfa_ids
= op_state
.mfa_ids
;
2296 op_state
.set_user_info(user_info
);
2298 // if we're supposed to modify keys, do so
2299 if (op_state
.has_key_op()) {
2300 ret
= keys
.add(op_state
, &subprocess_msg
, true);
2302 set_err_msg(err_msg
, "unable to create or modify keys, " + subprocess_msg
);
2307 ret
= update(op_state
, err_msg
);
2314 int RGWUser::modify(RGWUserAdminOpState
& op_state
, std::string
*err_msg
)
2316 std::string subprocess_msg
;
2319 ret
= check_op(op_state
, &subprocess_msg
);
2321 set_err_msg(err_msg
, "unable to parse parameters, " + subprocess_msg
);
2325 ret
= execute_modify(op_state
, &subprocess_msg
);
2327 set_err_msg(err_msg
, "unable to modify user, " + subprocess_msg
);
2334 int RGWUser::info(RGWUserAdminOpState
& op_state
, RGWUserInfo
& fetched_info
, std::string
*err_msg
)
2336 int ret
= init(op_state
);
2338 set_err_msg(err_msg
, "unable to fetch user info");
2342 fetched_info
= op_state
.get_user_info();
2347 int RGWUser::info(RGWUserInfo
& fetched_info
, std::string
*err_msg
)
2349 if (!is_populated()) {
2350 set_err_msg(err_msg
, "no user info saved");
2354 fetched_info
= old_info
;
2359 int RGWUser::list(RGWUserAdminOpState
& op_state
, RGWFormatterFlusher
& flusher
)
2361 Formatter
*formatter
= flusher
.get_formatter();
2362 void *handle
= nullptr;
2363 std::string metadata_key
= "user";
2364 if (op_state
.max_entries
> 1000) {
2365 op_state
.max_entries
= 1000;
2368 int ret
= store
->meta_mgr
->list_keys_init(metadata_key
, op_state
.marker
, &handle
);
2373 bool truncated
= false;
2378 // open the result object section
2379 formatter
->open_object_section("result");
2381 // open the user id list array section
2382 formatter
->open_array_section("keys");
2384 std::list
<std::string
> keys
;
2385 left
= op_state
.max_entries
- count
;
2386 ret
= store
->meta_mgr
->list_keys_next(handle
, left
, keys
, &truncated
);
2387 if (ret
< 0 && ret
!= -ENOENT
) {
2389 } if (ret
!= -ENOENT
) {
2390 for (std::list
<std::string
>::iterator iter
= keys
.begin(); iter
!= keys
.end(); ++iter
) {
2391 formatter
->dump_string("key", *iter
);
2395 } while (truncated
&& left
> 0);
2396 // close user id list section
2397 formatter
->close_section();
2399 formatter
->dump_bool("truncated", truncated
);
2400 formatter
->dump_int("count", count
);
2402 formatter
->dump_string("marker", store
->meta_mgr
->get_marker(handle
));
2405 // close result object section
2406 formatter
->close_section();
2408 store
->meta_mgr
->list_keys_complete(handle
);
2414 int RGWUserAdminOp_User::list(RGWRados
*store
, RGWUserAdminOpState
& op_state
,
2415 RGWFormatterFlusher
& flusher
)
2419 int ret
= user
.init_storage(store
);
2423 ret
= user
.list(op_state
, flusher
);
2430 int RGWUserAdminOp_User::info(RGWRados
*store
, RGWUserAdminOpState
& op_state
,
2431 RGWFormatterFlusher
& flusher
)
2436 int ret
= user
.init(store
, op_state
);
2440 if (!op_state
.has_existing_user())
2441 return -ERR_NO_SUCH_USER
;
2443 Formatter
*formatter
= flusher
.get_formatter();
2445 ret
= user
.info(info
, NULL
);
2449 if (op_state
.sync_stats
) {
2450 ret
= rgw_user_sync_all_stats(store
, info
.user_id
);
2456 RGWStorageStats stats
;
2457 RGWStorageStats
*arg_stats
= NULL
;
2458 if (op_state
.fetch_stats
) {
2459 int ret
= store
->get_user_stats(info
.user_id
, stats
);
2460 if (ret
< 0 && ret
!= -ENOENT
) {
2470 dump_user_info(formatter
, info
, arg_stats
);
2477 int RGWUserAdminOp_User::create(RGWRados
*store
, RGWUserAdminOpState
& op_state
,
2478 RGWFormatterFlusher
& flusher
)
2482 int ret
= user
.init(store
, op_state
);
2486 Formatter
*formatter
= flusher
.get_formatter();
2488 ret
= user
.add(op_state
, NULL
);
2491 ret
= -ERR_USER_EXIST
;
2495 ret
= user
.info(info
, NULL
);
2502 dump_user_info(formatter
, info
);
2509 int RGWUserAdminOp_User::modify(RGWRados
*store
, RGWUserAdminOpState
& op_state
,
2510 RGWFormatterFlusher
& flusher
)
2514 int ret
= user
.init(store
, op_state
);
2517 Formatter
*formatter
= flusher
.get_formatter();
2519 ret
= user
.modify(op_state
, NULL
);
2522 ret
= -ERR_NO_SUCH_USER
;
2526 ret
= user
.info(info
, NULL
);
2533 dump_user_info(formatter
, info
);
2540 int RGWUserAdminOp_User::remove(RGWRados
*store
, RGWUserAdminOpState
& op_state
,
2541 RGWFormatterFlusher
& flusher
)
2545 int ret
= user
.init(store
, op_state
);
2550 ret
= user
.remove(op_state
, NULL
);
2553 ret
= -ERR_NO_SUCH_USER
;
2557 int RGWUserAdminOp_Subuser::create(RGWRados
*store
, RGWUserAdminOpState
& op_state
,
2558 RGWFormatterFlusher
& flusher
)
2562 int ret
= user
.init(store
, op_state
);
2566 if (!op_state
.has_existing_user())
2567 return -ERR_NO_SUCH_USER
;
2569 Formatter
*formatter
= flusher
.get_formatter();
2571 ret
= user
.subusers
.add(op_state
, NULL
);
2575 ret
= user
.info(info
, NULL
);
2582 dump_subusers_info(formatter
, info
);
2589 int RGWUserAdminOp_Subuser::modify(RGWRados
*store
, RGWUserAdminOpState
& op_state
,
2590 RGWFormatterFlusher
& flusher
)
2594 int ret
= user
.init(store
, op_state
);
2598 if (!op_state
.has_existing_user())
2599 return -ERR_NO_SUCH_USER
;
2601 Formatter
*formatter
= flusher
.get_formatter();
2603 ret
= user
.subusers
.modify(op_state
, NULL
);
2607 ret
= user
.info(info
, NULL
);
2614 dump_subusers_info(formatter
, info
);
2621 int RGWUserAdminOp_Subuser::remove(RGWRados
*store
, RGWUserAdminOpState
& op_state
,
2622 RGWFormatterFlusher
& flusher
)
2626 int ret
= user
.init(store
, op_state
);
2631 if (!op_state
.has_existing_user())
2632 return -ERR_NO_SUCH_USER
;
2634 ret
= user
.subusers
.remove(op_state
, NULL
);
2641 int RGWUserAdminOp_Key::create(RGWRados
*store
, RGWUserAdminOpState
& op_state
,
2642 RGWFormatterFlusher
& flusher
)
2646 int ret
= user
.init(store
, op_state
);
2650 if (!op_state
.has_existing_user())
2651 return -ERR_NO_SUCH_USER
;
2653 Formatter
*formatter
= flusher
.get_formatter();
2655 ret
= user
.keys
.add(op_state
, NULL
);
2659 ret
= user
.info(info
, NULL
);
2666 int key_type
= op_state
.get_key_type();
2668 if (key_type
== KEY_TYPE_SWIFT
)
2669 dump_swift_keys_info(formatter
, info
);
2671 else if (key_type
== KEY_TYPE_S3
)
2672 dump_access_keys_info(formatter
, info
);
2680 int RGWUserAdminOp_Key::remove(RGWRados
*store
, RGWUserAdminOpState
& op_state
,
2681 RGWFormatterFlusher
& flusher
)
2685 int ret
= user
.init(store
, op_state
);
2689 if (!op_state
.has_existing_user())
2690 return -ERR_NO_SUCH_USER
;
2693 ret
= user
.keys
.remove(op_state
, NULL
);
2700 int RGWUserAdminOp_Caps::add(RGWRados
*store
, RGWUserAdminOpState
& op_state
,
2701 RGWFormatterFlusher
& flusher
)
2705 int ret
= user
.init(store
, op_state
);
2709 if (!op_state
.has_existing_user())
2710 return -ERR_NO_SUCH_USER
;
2712 Formatter
*formatter
= flusher
.get_formatter();
2714 ret
= user
.caps
.add(op_state
, NULL
);
2718 ret
= user
.info(info
, NULL
);
2725 info
.caps
.dump(formatter
);
2733 int RGWUserAdminOp_Caps::remove(RGWRados
*store
, RGWUserAdminOpState
& op_state
,
2734 RGWFormatterFlusher
& flusher
)
2738 int ret
= user
.init(store
, op_state
);
2742 if (!op_state
.has_existing_user())
2743 return -ERR_NO_SUCH_USER
;
2745 Formatter
*formatter
= flusher
.get_formatter();
2747 ret
= user
.caps
.remove(op_state
, NULL
);
2751 ret
= user
.info(info
, NULL
);
2758 info
.caps
.dump(formatter
);
2765 struct RGWUserCompleteInfo
{
2767 map
<string
, bufferlist
> attrs
;
2770 RGWUserCompleteInfo()
2774 void dump(Formatter
* const f
) const {
2776 encode_json("attrs", attrs
, f
);
2779 void decode_json(JSONObj
*obj
) {
2780 decode_json_obj(info
, obj
);
2781 has_attrs
= JSONDecoder::decode_json("attrs", attrs
, obj
);
2785 class RGWUserMetadataObject
: public RGWMetadataObject
{
2786 RGWUserCompleteInfo uci
;
2788 RGWUserMetadataObject(const RGWUserCompleteInfo
& _uci
, obj_version
& v
, real_time m
)
2794 void dump(Formatter
*f
) const override
{
2799 class RGWUserMetadataHandler
: public RGWMetadataHandler
{
2801 string
get_type() override
{ return "user"; }
2803 int get(RGWRados
*store
, string
& entry
, RGWMetadataObject
**obj
) override
{
2804 RGWUserCompleteInfo uci
;
2805 RGWObjVersionTracker objv_tracker
;
2808 rgw_user
uid(entry
);
2810 int ret
= rgw_get_user_info_by_uid(store
, uid
, uci
.info
, &objv_tracker
,
2811 &mtime
, NULL
, &uci
.attrs
);
2816 RGWUserMetadataObject
*mdo
= new RGWUserMetadataObject(uci
, objv_tracker
.read_version
, mtime
);
2822 int put(RGWRados
*store
, string
& entry
, RGWObjVersionTracker
& objv_tracker
,
2823 real_time mtime
, JSONObj
*obj
, sync_type_t sync_mode
) override
{
2824 RGWUserCompleteInfo uci
;
2827 decode_json_obj(uci
, obj
);
2828 } catch (JSONDecoder::err
& e
) {
2832 map
<string
, bufferlist
> *pattrs
= NULL
;
2833 if (uci
.has_attrs
) {
2834 pattrs
= &uci
.attrs
;
2837 rgw_user
uid(entry
);
2839 RGWUserInfo old_info
;
2840 real_time orig_mtime
;
2841 int ret
= rgw_get_user_info_by_uid(store
, uid
, old_info
, &objv_tracker
, &orig_mtime
);
2842 if (ret
< 0 && ret
!= -ENOENT
)
2845 // are we actually going to perform this put, or is it too old?
2846 if (ret
!= -ENOENT
&&
2847 !check_versions(objv_tracker
.read_version
, orig_mtime
,
2848 objv_tracker
.write_version
, mtime
, sync_mode
)) {
2849 return STATUS_NO_APPLY
;
2852 ret
= rgw_store_user_info(store
, uci
.info
, &old_info
, &objv_tracker
, mtime
, false, pattrs
);
2857 return STATUS_APPLIED
;
2860 struct list_keys_info
{
2862 RGWListRawObjsCtx ctx
;
2865 int remove(RGWRados
*store
, string
& entry
, RGWObjVersionTracker
& objv_tracker
) override
{
2868 rgw_user
uid(entry
);
2870 int ret
= rgw_get_user_info_by_uid(store
, uid
, info
, &objv_tracker
);
2874 return rgw_delete_user(store
, info
, objv_tracker
);
2877 void get_pool_and_oid(RGWRados
*store
, const string
& key
, rgw_pool
& pool
, string
& oid
) override
{
2879 pool
= store
->svc
.zone
->get_zone_params().user_uid_pool
;
2882 int list_keys_init(RGWRados
*store
, const string
& marker
, void **phandle
) override
2884 auto info
= std::make_unique
<list_keys_info
>();
2886 info
->store
= store
;
2888 int ret
= store
->list_raw_objects_init(store
->svc
.zone
->get_zone_params().user_uid_pool
, marker
,
2894 *phandle
= (void *)info
.release();
2899 int list_keys_next(void *handle
, int max
, list
<string
>& keys
, bool *truncated
) override
{
2900 list_keys_info
*info
= static_cast<list_keys_info
*>(handle
);
2906 RGWRados
*store
= info
->store
;
2908 list
<string
> unfiltered_keys
;
2910 int ret
= store
->list_raw_objects_next(no_filter
, max
, info
->ctx
,
2911 unfiltered_keys
, truncated
);
2912 if (ret
< 0 && ret
!= -ENOENT
)
2914 if (ret
== -ENOENT
) {
2920 // now filter out the buckets entries
2921 list
<string
>::iterator iter
;
2922 for (iter
= unfiltered_keys
.begin(); iter
!= unfiltered_keys
.end(); ++iter
) {
2925 if (k
.find(".buckets") == string::npos
) {
2933 void list_keys_complete(void *handle
) override
{
2934 list_keys_info
*info
= static_cast<list_keys_info
*>(handle
);
2938 string
get_marker(void *handle
) override
{
2939 list_keys_info
*info
= static_cast<list_keys_info
*>(handle
);
2940 return info
->store
->list_raw_objs_get_cursor(info
->ctx
);
2944 void rgw_user_init(RGWRados
*store
)
2946 uinfo_cache
.init(store
->svc
.cache
);
2948 user_meta_handler
= new RGWUserMetadataHandler
;
2949 store
->meta_mgr
->register_handler(user_meta_handler
);