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