]> git.proxmox.com Git - ceph.git/blame - ceph/src/rgw/rgw_user.cc
update sources to v12.2.1
[ceph.git] / ceph / src / rgw / rgw_user.cc
CommitLineData
7c673cae
FG
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3
4#include <errno.h>
5
6#include <string>
7#include <map>
8#include <boost/algorithm/string.hpp>
9
10#include "common/errno.h"
11#include "common/Formatter.h"
12#include "common/ceph_json.h"
13#include "common/RWLock.h"
181888fb 14#include "common/backport14.h"
7c673cae
FG
15#include "rgw_rados.h"
16#include "rgw_acl.h"
17
18#include "include/types.h"
19#include "rgw_user.h"
20#include "rgw_string.h"
21
22// until everything is moved from rgw_common
23#include "rgw_common.h"
24
25#include "rgw_bucket.h"
26
27#define dout_subsys ceph_subsys_rgw
28
29using namespace std;
30
31
32static RGWMetadataHandler *user_meta_handler = NULL;
33
34
35/**
36 * Get the anonymous (ie, unauthenticated) user info.
37 */
38void rgw_get_anon_user(RGWUserInfo& info)
39{
40 info.user_id = RGW_USER_ANON_ID;
41 info.display_name.clear();
42 info.access_keys.clear();
43}
44
45int rgw_user_sync_all_stats(RGWRados *store, const rgw_user& user_id)
46{
47 CephContext *cct = store->ctx();
48 size_t max_entries = cct->_conf->rgw_list_buckets_max_chunk;
49 bool is_truncated = false;
50 string marker;
51 int ret;
52 RGWObjectCtx obj_ctx(store);
53
54 do {
55 RGWUserBuckets user_buckets;
56 ret = rgw_read_user_buckets(store, user_id, user_buckets, marker,
57 string(), max_entries, false, &is_truncated);
58 if (ret < 0) {
59 ldout(cct, 0) << "failed to read user buckets: ret=" << ret << dendl;
60 return ret;
61 }
62 map<string, RGWBucketEnt>& buckets = user_buckets.get_buckets();
63 for (map<string, RGWBucketEnt>::iterator i = buckets.begin();
64 i != buckets.end();
65 ++i) {
66 marker = i->first;
67
68 RGWBucketEnt& bucket_ent = i->second;
69 RGWBucketInfo bucket_info;
70
71 ret = store->get_bucket_instance_info(obj_ctx, bucket_ent.bucket, bucket_info, NULL, NULL);
72 if (ret < 0) {
73 ldout(cct, 0) << "ERROR: could not read bucket info: bucket=" << bucket_ent.bucket << " ret=" << ret << dendl;
74 continue;
75 }
76 ret = rgw_bucket_sync_user_stats(store, user_id, bucket_info);
77 if (ret < 0) {
78 ldout(cct, 0) << "ERROR: could not sync bucket stats: ret=" << ret << dendl;
79 return ret;
80 }
224ce89b
WB
81 RGWQuotaInfo bucket_quota;
82 ret = store->check_bucket_shards(bucket_info, bucket_info.bucket, bucket_quota);
83 if (ret < 0) {
84 ldout(cct, 0) << "ERROR in check_bucket_shards: " << cpp_strerror(-ret)<< dendl;
85 }
7c673cae
FG
86 }
87 } while (is_truncated);
88
89 ret = store->complete_sync_user_stats(user_id);
90 if (ret < 0) {
91 cerr << "ERROR: failed to complete syncing user stats: ret=" << ret << std::endl;
92 return ret;
93 }
94
95 return 0;
96}
97
c07f9fc5
FG
98int rgw_user_get_all_buckets_stats(RGWRados *store, const rgw_user& user_id, map<string, cls_user_bucket_entry>&buckets_usage_map)
99{
100 CephContext *cct = store->ctx();
101 size_t max_entries = cct->_conf->rgw_list_buckets_max_chunk;
102 bool done;
103 bool is_truncated;
104 string marker;
105 int ret;
106
107 do {
108 RGWUserBuckets user_buckets;
109 ret = rgw_read_user_buckets(store, user_id, user_buckets, marker,
110 string(), max_entries, false, &is_truncated);
111 if (ret < 0) {
112 ldout(cct, 0) << "failed to read user buckets: ret=" << ret << dendl;
113 return ret;
114 }
115 map<string, RGWBucketEnt>& buckets = user_buckets.get_buckets();
116 for (const auto& i : buckets) {
117 marker = i.first;
118
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);
122 if (ret < 0) {
123 ldout(cct, 0) << "ERROR: could not get bucket stats: ret=" << ret << dendl;
124 return ret;
125 }
126 buckets_usage_map.emplace(bucket_ent.bucket.name, entry);
127 }
128 done = (buckets.size() < max_entries);
129 } while (!done);
130
131 return 0;
132}
133
7c673cae
FG
134/**
135 * Save the given user information to storage.
136 * Returns: 0 on success, -ERR# on failure.
137 */
138int rgw_store_user_info(RGWRados *store,
139 RGWUserInfo& info,
140 RGWUserInfo *old_info,
141 RGWObjVersionTracker *objv_tracker,
142 real_time mtime,
143 bool exclusive,
144 map<string, bufferlist> *pattrs)
145{
146 int ret;
147 RGWObjVersionTracker ot;
148
149 if (objv_tracker) {
150 ot = *objv_tracker;
151 }
152
153 if (ot.write_version.tag.empty()) {
154 if (ot.read_version.tag.empty()) {
155 ot.generate_new_write_ver(store->ctx());
156 } else {
157 ot.write_version = ot.read_version;
158 ot.write_version.ver++;
159 }
160 }
161
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)
165 continue;
166 RGWAccessKey& k = iter->second;
167 /* check if swift mapping exists */
168 RGWUserInfo inf;
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;
173 return -EEXIST;
174 }
175 }
176
177 if (!info.access_keys.empty()) {
178 /* check if access keys already exist */
179 RGWUserInfo inf;
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)
184 continue;
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;
188 return -EEXIST;
189 }
190 }
191 }
192
193 RGWUID ui;
194 ui.user_id = info.user_id;
195
196 bufferlist link_bl;
197 ::encode(ui, link_bl);
198
199 bufferlist data_bl;
200 ::encode(ui, data_bl);
201 ::encode(info, data_bl);
202
203 string key;
204 info.user_id.to_str(key);
205
206 ret = store->meta_mgr->put_entry(user_meta_handler, key, data_bl, exclusive, &ot, mtime, pattrs);
207 if (ret < 0)
208 return ret;
209
210 if (!info.user_email.empty()) {
211 if (!old_info ||
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());
215 if (ret < 0)
216 return ret;
217 }
218 }
219
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)
225 continue;
226
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,
229 NULL, real_time());
230 if (ret < 0)
231 return ret;
232 }
233 }
234
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)
239 continue;
240
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,
243 NULL, real_time());
244 if (ret < 0)
245 return ret;
246 }
247
248 return ret;
249}
250
251struct user_info_entry {
252 RGWUserInfo info;
253 RGWObjVersionTracker objv_tracker;
254 real_time mtime;
255};
256
257static RGWChainedCacheImpl<user_info_entry> uinfo_cache;
258
259int rgw_get_user_info_from_index(RGWRados * const store,
260 const string& key,
261 rgw_pool& pool,
262 RGWUserInfo& info,
263 RGWObjVersionTracker * const objv_tracker,
264 real_time * const pmtime)
265{
266 user_info_entry e;
267 if (uinfo_cache.find(key, &e)) {
268 info = e.info;
269 if (objv_tracker)
270 *objv_tracker = e.objv_tracker;
271 if (pmtime)
272 *pmtime = e.mtime;
273 return 0;
274 }
275
276 bufferlist bl;
277 RGWUID uid;
278 RGWObjectCtx obj_ctx(store);
279
280 int ret = rgw_get_system_obj(store, obj_ctx, pool, key, bl, NULL, &e.mtime);
281 if (ret < 0)
282 return ret;
283
284 rgw_cache_entry_info cache_info;
285
286 bufferlist::iterator iter = bl.begin();
287 try {
288 ::decode(uid, iter);
289 int ret = rgw_get_user_info_by_uid(store, uid.user_id, e.info, &e.objv_tracker, NULL, &cache_info);
290 if (ret < 0) {
291 return ret;
292 }
293 } catch (buffer::error& err) {
294 ldout(store->ctx(), 0) << "ERROR: failed to decode user info, caught buffer::error" << dendl;
295 return -EIO;
296 }
297
298 list<rgw_cache_entry_info *> cache_info_entries;
299 cache_info_entries.push_back(&cache_info);
300
301 uinfo_cache.put(store, key, &e, cache_info_entries);
302
303 info = e.info;
304 if (objv_tracker)
305 *objv_tracker = e.objv_tracker;
306 if (pmtime)
307 *pmtime = e.mtime;
308
309 return 0;
310}
311
312/**
313 * Given a uid, finds the user info associated with it.
314 * returns: 0 on success, -ERR# on failure (including nonexistence)
315 */
316int rgw_get_user_info_by_uid(RGWRados *store,
317 const rgw_user& uid,
318 RGWUserInfo& info,
319 RGWObjVersionTracker * const objv_tracker,
320 real_time * const pmtime,
321 rgw_cache_entry_info * const cache_info,
322 map<string, bufferlist> * const pattrs)
323{
324 bufferlist bl;
325 RGWUID user_id;
326
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);
330 if (ret < 0) {
331 return ret;
332 }
333
334 bufferlist::iterator iter = bl.begin();
335 try {
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;
339 return -EIO;
340 }
341 if (!iter.end()) {
342 ::decode(info, iter);
343 }
344 } catch (buffer::error& err) {
345 ldout(store->ctx(), 0) << "ERROR: failed to decode user info, caught buffer::error" << dendl;
346 return -EIO;
347 }
348
349 return 0;
350}
351
352/**
353 * Given an email, finds the user info associated with it.
354 * returns: 0 on success, -ERR# on failure (including nonexistence)
355 */
356int rgw_get_user_info_by_email(RGWRados *store, string& email, RGWUserInfo& info,
357 RGWObjVersionTracker *objv_tracker, real_time *pmtime)
358{
359 return rgw_get_user_info_from_index(store, email, store->get_zone_params().user_email_pool, info, objv_tracker, pmtime);
360}
361
362/**
363 * Given an swift username, finds the user_info associated with it.
364 * returns: 0 on success, -ERR# on failure (including nonexistence)
365 */
366extern 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)
371{
372 return rgw_get_user_info_from_index(store, swift_name,
373 store->get_zone_params().user_swift_pool,
374 info, objv_tracker, pmtime);
375}
376
377/**
378 * Given an access key, finds the user info associated with it.
379 * returns: 0 on success, -ERR# on failure (including nonexistence)
380 */
381extern int rgw_get_user_info_by_access_key(RGWRados* store,
382 const std::string& access_key,
383 RGWUserInfo& info,
384 RGWObjVersionTracker* objv_tracker,
385 real_time *pmtime)
386{
387 return rgw_get_user_info_from_index(store, access_key,
388 store->get_zone_params().user_keys_pool,
389 info, objv_tracker, pmtime);
390}
391
392int rgw_get_user_attrs_by_uid(RGWRados *store,
393 const rgw_user& user_id,
394 map<string, bufferlist>& attrs,
395 RGWObjVersionTracker *objv_tracker)
396{
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);
401
402 rop.stat_params.attrs = &attrs;
403 return rop.stat(objv_tracker);
404}
405
406int rgw_remove_key_index(RGWRados *store, RGWAccessKey& access_key)
407{
408 rgw_raw_obj obj(store->get_zone_params().user_keys_pool, access_key.id);
409 int ret = store->delete_system_obj(obj);
410 return ret;
411}
412
413int rgw_remove_uid_index(RGWRados *store, rgw_user& uid)
414{
415 RGWObjVersionTracker objv_tracker;
416 RGWUserInfo info;
417 int ret = rgw_get_user_info_by_uid(store, uid, info, &objv_tracker, NULL);
418 if (ret < 0)
419 return ret;
420
421 string oid = uid.to_str();
422 ret = store->meta_mgr->remove_entry(user_meta_handler, oid, &objv_tracker);
423 if (ret < 0)
424 return ret;
425
426 return 0;
427}
428
429int rgw_remove_email_index(RGWRados *store, string& email)
430{
431 if (email.empty()) {
432 return 0;
433 }
434 rgw_raw_obj obj(store->get_zone_params().user_email_pool, email);
435 return store->delete_system_obj(obj);
436}
437
438int rgw_remove_swift_name_index(RGWRados *store, string& swift_name)
439{
440 rgw_raw_obj obj(store->get_zone_params().user_swift_pool, swift_name);
441 int ret = store->delete_system_obj(obj);
442 return ret;
443}
444
445/**
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.
450 */
451int rgw_delete_user(RGWRados *store, RGWUserInfo& info, RGWObjVersionTracker& objv_tracker) {
452 int ret;
453
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;
460 return ret;
461 }
462 }
463
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;
472 return ret;
473 }
474 }
475
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;
481 return ret;
482 }
483
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;
491 return ret;
492 }
493
494 string key;
495 info.user_id.to_str(key);
496
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;
502 return ret;
503 }
504
505 return 0;
506}
507
508static bool char_is_unreserved_url(char c)
509{
510 if (isalnum(c))
511 return true;
512
513 switch (c) {
514 case '-':
515 case '.':
516 case '_':
517 case '~':
518 return true;
519 default:
520 return false;
521 }
522}
523
524struct rgw_flags_desc {
525 uint32_t mask;
526 const char *str;
527};
528
529static 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" },
536 { 0, NULL }
537};
538
539void rgw_perm_to_str(uint32_t mask, char *buf, int len)
540{
541 const char *sep = "";
542 int pos = 0;
543 if (!mask) {
544 snprintf(buf, len, "<none>");
545 return;
546 }
547 while (mask) {
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);
553 if (pos == len)
554 return;
555 sep = ", ";
556 mask &= ~desc->mask;
557 if (!mask)
558 return;
559 }
560 }
561 if (mask == orig_mask) // no change
562 break;
563 }
564}
565
566uint32_t rgw_str_to_perm(const char *str)
567{
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;
578
579 return RGW_PERM_INVALID;
580}
581
d2e6a577
FG
582int rgw_validate_tenant_name(const string& t)
583{
584 struct tench {
585 static bool is_good(char ch) {
586 return isalnum(ch) || ch == '_';
587 }
588 };
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;
592}
593
7c673cae
FG
594static bool validate_access_key(string& key)
595{
596 const char *p = key.c_str();
597 while (*p) {
598 if (!char_is_unreserved_url(*p))
599 return false;
600 p++;
601 }
602 return true;
603}
604
605static void set_err_msg(std::string *sink, std::string msg)
606{
607 if (sink && !msg.empty())
608 *sink = msg;
609}
610
611static bool remove_old_indexes(RGWRados *store,
612 RGWUserInfo& old_info, RGWUserInfo& new_info, std::string *err_msg)
613{
614 int ret;
615 bool success = true;
616
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;
621 return false;
622 }
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());
626 success = false;
627 }
628 }
629
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);
635 success = false;
636 }
637 }
638
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);
647 success = false;
648 }
649 }
650 }
651
652 return success;
653}
654
655/*
656 * Dump either the full user info or a subset to a formatter.
657 *
658 * NOTE: It is the caller's respnsibility to ensure that the
659 * formatter is flushed at the correct time.
660 */
661
662static void dump_subusers_info(Formatter *f, RGWUserInfo &info)
663{
664 map<string, RGWSubUser>::iterator uiter;
665
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");
670 string s;
671 info.user_id.to_str(s);
672 f->dump_format("id", "%s:%s", s.c_str(), u.name.c_str());
673 char buf[256];
674 rgw_perm_to_str(u.perm_mask, buf, sizeof(buf));
675 f->dump_string("permissions", buf);
676 f->close_section();
677 }
678 f->close_section();
679}
680
681static void dump_access_keys_info(Formatter *f, RGWUserInfo &info)
682{
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");
690 string s;
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);
695 f->close_section();
696 }
697 f->close_section();
698}
699
700static void dump_swift_keys_info(Formatter *f, RGWUserInfo &info)
701{
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");
709 string s;
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);
713 f->close_section();
714 }
715 f->close_section();
716}
717
718static void dump_user_info(Formatter *f, RGWUserInfo &info,
719 RGWStorageStats *stats = NULL)
720{
721 f->open_object_section("user_info");
722
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);
729
730 dump_subusers_info(f, info);
731 dump_access_keys_info(f, info);
732 dump_swift_keys_info(f, info);
733 info.caps.dump(f);
734 if (stats) {
735 encode_json("stats", *stats, f);
736 }
737
738 f->close_section();
739}
740
741
742RGWAccessKeyPool::RGWAccessKeyPool(RGWUser* usr)
743{
744 user = usr;
745 swift_keys = NULL;
746 access_keys = NULL;
747
748 if (!user) {
749 keys_allowed = false;
750 store = NULL;
751 return;
752 }
753
754 keys_allowed = true;
755
756 store = user->get_store();
757}
758
759RGWAccessKeyPool::~RGWAccessKeyPool()
760{
761
762}
763
764int RGWAccessKeyPool::init(RGWUserAdminOpState& op_state)
765{
766 if (!op_state.is_initialized()) {
767 keys_allowed = false;
768 return -EINVAL;
769 }
770
771 rgw_user& uid = op_state.get_user_id();
772 if (uid.compare(RGW_USER_ANON_ID) == 0) {
773 keys_allowed = false;
774 return -EACCES;
775 }
776
777 swift_keys = op_state.get_swift_keys();
778 access_keys = op_state.get_access_keys();
779
780 keys_allowed = true;
781
782 return 0;
783}
784
785/*
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.
789 */
790
791bool RGWAccessKeyPool::check_existing_key(RGWUserAdminOpState& op_state)
792{
793 bool existing_key = false;
794
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();
799
800 RGWUserInfo dup_info;
801
802 if (kid.empty() && swift_kid.empty())
803 return false;
804
805 switch (key_type) {
806 case KEY_TYPE_SWIFT:
807 kiter = swift_keys->find(swift_kid);
808
809 existing_key = (kiter != swift_keys->end());
810 if (existing_key)
811 op_state.set_access_key(swift_kid);
812
813 break;
814 case KEY_TYPE_S3:
815 kiter = access_keys->find(kid);
816 existing_key = (kiter != access_keys->end());
817
818 break;
819 default:
820 kiter = access_keys->find(kid);
821
822 existing_key = (kiter != access_keys->end());
823 if (existing_key) {
824 op_state.set_key_type(KEY_TYPE_S3);
825 break;
826 }
827
828 kiter = swift_keys->find(kid);
829
830 existing_key = (kiter != swift_keys->end());
831 if (existing_key) {
832 op_state.set_key_type(KEY_TYPE_SWIFT);
833 break;
834 }
835
836 // handle the case where the access key was not provided in user:key format
837 if (swift_kid.empty())
838 return false;
839
840 kiter = swift_keys->find(swift_kid);
841
842 existing_key = (kiter != swift_keys->end());
843 if (existing_key) {
844 op_state.set_access_key(swift_kid);
845 op_state.set_key_type(KEY_TYPE_SWIFT);
846 }
847 }
848
849 op_state.set_existing_key(existing_key);
850
851 return existing_key;
852}
853
854int RGWAccessKeyPool::check_op(RGWUserAdminOpState& op_state,
855 std::string *err_msg)
856{
857 RGWUserInfo dup_info;
858
859 if (!op_state.is_populated()) {
860 set_err_msg(err_msg, "user info was not populated");
861 return -EINVAL;
862 }
863
864 if (!keys_allowed) {
865 set_err_msg(err_msg, "keys not allowed for this user");
866 return -EACCES;
867 }
868
869 int32_t key_type = op_state.get_key_type();
870
871 // if a key type wasn't specified
872 if (key_type < 0) {
873 if (op_state.has_subuser()) {
874 key_type = KEY_TYPE_SWIFT;
875 } else {
876 key_type = KEY_TYPE_S3;
877 }
878 }
879
880 op_state.set_key_type(key_type);
881
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;
887 }
888
889 // don't check for secret key because we may be doing a removal
890
891 check_existing_key(op_state);
892
893 return 0;
894}
895
896// Generate a new random key
897int RGWAccessKeyPool::generate_key(RGWUserAdminOpState& op_state, std::string *err_msg)
898{
899 std::string id;
900 std::string key;
901
902 std::pair<std::string, RGWAccessKey> key_pair;
903 RGWAccessKey new_key;
904 RGWUserInfo duplicate_check;
905
906 int ret = 0;
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();
910
911 if (!keys_allowed) {
912 set_err_msg(err_msg, "access keys not allowed for this user");
913 return -EACCES;
914 }
915
916 if (op_state.has_existing_key()) {
917 set_err_msg(err_msg, "cannot create existing key");
918 return -ERR_KEY_EXIST;
919 }
920
921 if (!gen_access) {
922 id = op_state.get_access_key();
923 }
924
925 if (!id.empty()) {
926 switch (key_type) {
927 case KEY_TYPE_SWIFT:
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;
931 }
932 break;
933 case KEY_TYPE_S3:
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;
937 }
938 }
939 }
940
941 //key's subuser
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();
946 }
947 }
948
949 //Secret key
950 if (!gen_secret) {
951 if (op_state.get_secret_key().empty()) {
952 set_err_msg(err_msg, "empty secret key");
953 return -ERR_INVALID_SECRET_KEY;
954 }
955
956 key = op_state.get_secret_key();
957 } else {
958 char secret_key_buf[SECRET_KEY_LEN + 1];
959
960 ret = gen_rand_alphanumeric_plain(g_ceph_context, secret_key_buf, sizeof(secret_key_buf));
961 if (ret < 0) {
962 set_err_msg(err_msg, "unable to generate secret key");
963 return ret;
964 }
965
966 key = secret_key_buf;
967 }
968
969 // Generate the access key
970 if (key_type == KEY_TYPE_S3 && gen_access) {
971 char public_id_buf[PUBLIC_ID_LEN + 1];
972
973 do {
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);
977
978 if (ret < 0) {
979 set_err_msg(err_msg, "unable to generate access key");
980 return ret;
981 }
982
983 id = public_id_buf;
984 if (!validate_access_key(id))
985 continue;
986
987 } while (!rgw_get_user_info_by_access_key(store, id, duplicate_check));
988 }
989
990 if (key_type == KEY_TYPE_SWIFT) {
991 id = op_state.build_default_swift_kid();
992 if (id.empty()) {
993 set_err_msg(err_msg, "empty swift access key");
994 return -ERR_INVALID_ACCESS_KEY;
995 }
996
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;
1001 }
1002 }
1003
1004 // finally create the new key
1005 new_key.id = id;
1006 new_key.key = key;
1007
1008 key_pair.first = id;
1009 key_pair.second = new_key;
1010
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);
1015 }
1016
1017 return 0;
1018}
1019
1020// modify an existing key
1021int RGWAccessKeyPool::modify_key(RGWUserAdminOpState& op_state, std::string *err_msg)
1022{
1023 std::string id;
1024 std::string key = op_state.get_secret_key();
1025 int key_type = op_state.get_key_type();
1026
1027 RGWAccessKey modify_key;
1028
1029 pair<string, RGWAccessKey> key_pair;
1030 map<std::string, RGWAccessKey>::iterator kiter;
1031
1032 switch (key_type) {
1033 case KEY_TYPE_S3:
1034 id = op_state.get_access_key();
1035 if (id.empty()) {
1036 set_err_msg(err_msg, "no access key specified");
1037 return -ERR_INVALID_ACCESS_KEY;
1038 }
1039 break;
1040 case KEY_TYPE_SWIFT:
1041 id = op_state.build_default_swift_kid();
1042 if (id.empty()) {
1043 set_err_msg(err_msg, "no subuser specified");
1044 return -EINVAL;
1045 }
1046 break;
1047 default:
1048 set_err_msg(err_msg, "invalid key type");
1049 return -ERR_INVALID_KEY_TYPE;
1050 }
1051
1052 if (!op_state.has_existing_key()) {
1053 set_err_msg(err_msg, "key does not exist");
1054 return -ERR_INVALID_ACCESS_KEY;
1055 }
1056
1057 key_pair.first = id;
1058
1059 if (key_type == KEY_TYPE_SWIFT) {
1060 modify_key.id = id;
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;
1066 }
1067 }
1068
1069 if (op_state.will_gen_secret()) {
1070 char secret_key_buf[SECRET_KEY_LEN + 1];
1071
1072 int ret;
1073 int key_buf_size = sizeof(secret_key_buf);
1074 ret = gen_rand_alphanumeric_plain(g_ceph_context, secret_key_buf, key_buf_size);
1075 if (ret < 0) {
1076 set_err_msg(err_msg, "unable to generate secret key");
1077 return ret;
1078 }
1079
1080 key = secret_key_buf;
1081 }
1082
1083 if (key.empty()) {
1084 set_err_msg(err_msg, "empty secret key");
1085 return -ERR_INVALID_SECRET_KEY;
1086 }
1087
1088 // update the access key with the new secret key
1089 modify_key.key = key;
1090
1091 key_pair.second = modify_key;
1092
1093
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;
1098 }
1099
1100 return 0;
1101}
1102
1103int RGWAccessKeyPool::execute_add(RGWUserAdminOpState& op_state,
1104 std::string *err_msg, bool defer_user_update)
1105{
1106 int ret = 0;
1107
1108 std::string subprocess_msg;
1109 int key_op = GENERATE_KEY;
1110
1111 // set the op
1112 if (op_state.has_existing_key())
1113 key_op = MODIFY_KEY;
1114
1115 switch (key_op) {
1116 case GENERATE_KEY:
1117 ret = generate_key(op_state, &subprocess_msg);
1118 break;
1119 case MODIFY_KEY:
1120 ret = modify_key(op_state, &subprocess_msg);
1121 break;
1122 }
1123
1124 if (ret < 0) {
1125 set_err_msg(err_msg, subprocess_msg);
1126 return ret;
1127 }
1128
1129 // store the updated info
1130 if (!defer_user_update)
1131 ret = user->update(op_state, err_msg);
1132
1133 if (ret < 0)
1134 return ret;
1135
1136 return 0;
1137}
1138
1139int RGWAccessKeyPool::add(RGWUserAdminOpState& op_state, std::string *err_msg)
1140{
1141 return add(op_state, err_msg, false);
1142}
1143
1144int RGWAccessKeyPool::add(RGWUserAdminOpState& op_state, std::string *err_msg, bool defer_user_update)
1145{
1146 int ret;
1147 std::string subprocess_msg;
1148
1149 ret = check_op(op_state, &subprocess_msg);
1150 if (ret < 0) {
1151 set_err_msg(err_msg, "unable to parse request, " + subprocess_msg);
1152 return ret;
1153 }
1154
1155 ret = execute_add(op_state, &subprocess_msg, defer_user_update);
1156 if (ret < 0) {
1157 set_err_msg(err_msg, "unable to add access key, " + subprocess_msg);
1158 return ret;
1159 }
1160
1161 return 0;
1162}
1163
1164int RGWAccessKeyPool::execute_remove(RGWUserAdminOpState& op_state, std::string *err_msg, bool defer_user_update)
1165{
1166 int ret = 0;
1167
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;
1172
1173 if (!op_state.has_existing_key()) {
1174 set_err_msg(err_msg, "unable to find access key");
1175 return -ERR_INVALID_ACCESS_KEY;
1176 }
1177
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;
1182 } else {
1183 keys_map = NULL;
1184 set_err_msg(err_msg, "invalid access key");
1185 return -ERR_INVALID_ACCESS_KEY;
1186 }
1187
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;
1192 }
1193
1194 rgw_remove_key_index(store, kiter->second);
1195 keys_map->erase(kiter);
1196
1197 if (!defer_user_update)
1198 ret = user->update(op_state, err_msg);
1199
1200 if (ret < 0)
1201 return ret;
1202
1203 return 0;
1204}
1205
1206int RGWAccessKeyPool::remove(RGWUserAdminOpState& op_state, std::string *err_msg)
1207{
1208 return remove(op_state, err_msg, false);
1209}
1210
1211int RGWAccessKeyPool::remove(RGWUserAdminOpState& op_state, std::string *err_msg, bool defer_user_update)
1212{
1213 int ret;
1214
1215 std::string subprocess_msg;
1216
1217 ret = check_op(op_state, &subprocess_msg);
1218 if (ret < 0) {
1219 set_err_msg(err_msg, "unable to parse request, " + subprocess_msg);
1220 return ret;
1221 }
1222
1223 ret = execute_remove(op_state, &subprocess_msg, defer_user_update);
1224 if (ret < 0) {
1225 set_err_msg(err_msg, "unable to remove access key, " + subprocess_msg);
1226 return ret;
1227 }
1228
1229 return 0;
1230}
1231
1232// remove all keys associated with a subuser
1233int RGWAccessKeyPool::remove_subuser_keys(RGWUserAdminOpState& op_state,
1234 std::string *err_msg, bool defer_user_update)
1235{
1236 int ret = 0;
1237
1238 if (!op_state.is_populated()) {
1239 set_err_msg(err_msg, "user info was not populated");
1240 return -EINVAL;
1241 }
1242
1243 if (!op_state.has_subuser()) {
1244 set_err_msg(err_msg, "no subuser specified");
1245 return -EINVAL;
1246 }
1247
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");
1251 return -EINVAL;
1252 }
1253
1254 map<std::string, RGWAccessKey>::iterator kiter;
1255 map<std::string, RGWAccessKey> *keys_map;
1256
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);
1263 }
1264
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);
1276 }
1277 }
1278 }
1279
1280 if (!defer_user_update)
1281 ret = user->update(op_state, err_msg);
1282
1283 if (ret < 0)
1284 return ret;
1285
1286 return 0;
1287}
1288
1289RGWSubUserPool::RGWSubUserPool(RGWUser *usr)
1290{
1291 subusers_allowed = (usr != NULL);
1292 if (usr)
1293 store = usr->get_store();
1294 else
1295 store = NULL;
1296 user = usr;
1297 subuser_map = NULL;
1298}
1299
1300RGWSubUserPool::~RGWSubUserPool()
1301{
1302
1303}
1304
1305int RGWSubUserPool::init(RGWUserAdminOpState& op_state)
1306{
1307 if (!op_state.is_initialized()) {
1308 subusers_allowed = false;
1309 return -EINVAL;
1310 }
1311
1312 rgw_user& uid = op_state.get_user_id();
1313 if (uid.compare(RGW_USER_ANON_ID) == 0) {
1314 subusers_allowed = false;
1315 return -EACCES;
1316 }
1317
1318 subuser_map = op_state.get_subusers();
1319 if (subuser_map == NULL) {
1320 subusers_allowed = false;
1321 return -EINVAL;
1322 }
1323
1324 subusers_allowed = true;
1325
1326 return 0;
1327}
1328
1329bool RGWSubUserPool::exists(std::string subuser)
1330{
1331 if (subuser.empty())
1332 return false;
1333
1334 if (!subuser_map)
1335 return false;
1336
1337 if (subuser_map->count(subuser))
1338 return true;
1339
1340 return false;
1341}
1342
1343int RGWSubUserPool::check_op(RGWUserAdminOpState& op_state,
1344 std::string *err_msg)
1345{
1346 bool existing = false;
1347 std::string subuser = op_state.get_subuser();
1348
1349 if (!op_state.is_populated()) {
1350 set_err_msg(err_msg, "user info was not populated");
1351 return -EINVAL;
1352 }
1353
1354 if (!subusers_allowed) {
1355 set_err_msg(err_msg, "subusers not allowed for this user");
1356 return -EACCES;
1357 }
1358
1359 if (subuser.empty() && !op_state.will_gen_subuser()) {
1360 set_err_msg(err_msg, "empty subuser name");
1361 return -EINVAL;
1362 }
1363
1364 if (op_state.get_subuser_perm() == RGW_PERM_INVALID) {
1365 set_err_msg(err_msg, "invaild subuser access");
1366 return -EINVAL;
1367 }
1368
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;
1373 }
1374
1375 // check if the subuser exists
1376 if (!subuser.empty())
1377 existing = exists(subuser);
1378
1379 op_state.set_existing_subuser(existing);
1380
1381 return 0;
1382}
1383
1384int RGWSubUserPool::execute_add(RGWUserAdminOpState& op_state,
1385 std::string *err_msg, bool defer_user_update)
1386{
1387 int ret = 0;
1388 std::string subprocess_msg;
1389
1390 RGWSubUser subuser;
1391 std::pair<std::string, RGWSubUser> subuser_pair;
1392 std::string subuser_str = op_state.get_subuser();
1393
1394 subuser_pair.first = subuser_str;
1395
1396 // assumes key should be created
1397 if (op_state.has_key_op()) {
1398 ret = user->keys.add(op_state, &subprocess_msg, true);
1399 if (ret < 0) {
1400 set_err_msg(err_msg, "unable to create subuser key, " + subprocess_msg);
1401 return ret;
1402 }
1403 }
1404
1405 // create the subuser
1406 subuser.name = subuser_str;
1407
1408 if (op_state.has_subuser_perm())
1409 subuser.perm_mask = op_state.get_subuser_perm();
1410
1411 // insert the subuser into user info
1412 subuser_pair.second = subuser;
1413 subuser_map->insert(subuser_pair);
1414
1415 // attempt to save the subuser
1416 if (!defer_user_update)
1417 ret = user->update(op_state, err_msg);
1418
1419 if (ret < 0)
1420 return ret;
1421
1422 return 0;
1423}
1424
1425int RGWSubUserPool::add(RGWUserAdminOpState& op_state, std::string *err_msg)
1426{
1427 return add(op_state, err_msg, false);
1428}
1429
1430int RGWSubUserPool::add(RGWUserAdminOpState& op_state, std::string *err_msg, bool defer_user_update)
1431{
1432 std::string subprocess_msg;
1433 int ret;
1434 int32_t key_type = op_state.get_key_type();
1435
1436 ret = check_op(op_state, &subprocess_msg);
1437 if (ret < 0) {
1438 set_err_msg(err_msg, "unable to parse request, " + subprocess_msg);
1439 return ret;
1440 }
1441
1442 if (key_type == KEY_TYPE_S3 && op_state.get_access_key().empty()) {
1443 op_state.set_gen_access();
1444 }
1445
1446 if (op_state.get_secret_key().empty()) {
1447 op_state.set_gen_secret();
1448 }
1449
1450 ret = execute_add(op_state, &subprocess_msg, defer_user_update);
1451 if (ret < 0) {
1452 set_err_msg(err_msg, "unable to create subuser, " + subprocess_msg);
1453 return ret;
1454 }
1455
1456 return 0;
1457}
1458
1459int RGWSubUserPool::execute_remove(RGWUserAdminOpState& op_state,
1460 std::string *err_msg, bool defer_user_update)
1461{
1462 int ret = 0;
1463 std::string subprocess_msg;
1464
1465 std::string subuser_str = op_state.get_subuser();
1466
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);
224ce89b 1471 return -ERR_NO_SUCH_SUBUSER;
7c673cae
FG
1472 }
1473 if (!op_state.has_existing_subuser()) {
1474 set_err_msg(err_msg, "subuser not found: " + subuser_str);
224ce89b 1475 return -ERR_NO_SUCH_SUBUSER;
7c673cae
FG
1476 }
1477
1478 // always purge all associate keys
1479 user->keys.remove_subuser_keys(op_state, &subprocess_msg, true);
1480
1481 // remove the subuser from the user info
1482 subuser_map->erase(siter);
1483
1484 // attempt to save the subuser
1485 if (!defer_user_update)
1486 ret = user->update(op_state, err_msg);
1487
1488 if (ret < 0)
1489 return ret;
1490
1491 return 0;
1492}
1493
1494int RGWSubUserPool::remove(RGWUserAdminOpState& op_state, std::string *err_msg)
1495{
1496 return remove(op_state, err_msg, false);
1497}
1498
1499int RGWSubUserPool::remove(RGWUserAdminOpState& op_state, std::string *err_msg, bool defer_user_update)
1500{
1501 std::string subprocess_msg;
1502 int ret;
1503
1504 ret = check_op(op_state, &subprocess_msg);
1505 if (ret < 0) {
1506 set_err_msg(err_msg, "unable to parse request, " + subprocess_msg);
1507 return ret;
1508 }
1509
1510 ret = execute_remove(op_state, &subprocess_msg, defer_user_update);
1511 if (ret < 0) {
1512 set_err_msg(err_msg, "unable to remove subuser, " + subprocess_msg);
1513 return ret;
1514 }
1515
1516 return 0;
1517}
1518
1519int RGWSubUserPool::execute_modify(RGWUserAdminOpState& op_state, std::string *err_msg, bool defer_user_update)
1520{
1521 int ret = 0;
1522 std::string subprocess_msg;
1523 std::map<std::string, RGWSubUser>::iterator siter;
1524 std::pair<std::string, RGWSubUser> subuser_pair;
1525
1526 std::string subuser_str = op_state.get_subuser();
1527 RGWSubUser subuser;
1528
1529 if (!op_state.has_existing_subuser()) {
1530 set_err_msg(err_msg, "subuser does not exist");
224ce89b 1531 return -ERR_NO_SUCH_SUBUSER;
7c673cae
FG
1532 }
1533
1534 subuser_pair.first = subuser_str;
1535
1536 siter = subuser_map->find(subuser_str);
1537 subuser = siter->second;
1538
1539 if (op_state.has_key_op()) {
1540 ret = user->keys.add(op_state, &subprocess_msg, true);
1541 if (ret < 0) {
1542 set_err_msg(err_msg, "unable to create subuser keys, " + subprocess_msg);
1543 return ret;
1544 }
1545 }
1546
1547 if (op_state.has_subuser_perm())
1548 subuser.perm_mask = op_state.get_subuser_perm();
1549
1550 subuser_pair.second = subuser;
1551
1552 subuser_map->erase(siter);
1553 subuser_map->insert(subuser_pair);
1554
1555 // attempt to save the subuser
1556 if (!defer_user_update)
1557 ret = user->update(op_state, err_msg);
1558
1559 if (ret < 0)
1560 return ret;
1561
1562 return 0;
1563}
1564
1565int RGWSubUserPool::modify(RGWUserAdminOpState& op_state, std::string *err_msg)
1566{
1567 return RGWSubUserPool::modify(op_state, err_msg, false);
1568}
1569
1570int RGWSubUserPool::modify(RGWUserAdminOpState& op_state, std::string *err_msg, bool defer_user_update)
1571{
1572 std::string subprocess_msg;
1573 int ret;
1574
1575 RGWSubUser subuser;
1576
1577 ret = check_op(op_state, &subprocess_msg);
1578 if (ret < 0) {
1579 set_err_msg(err_msg, "unable to parse request, " + subprocess_msg);
1580 return ret;
1581 }
1582
1583 ret = execute_modify(op_state, &subprocess_msg, defer_user_update);
1584 if (ret < 0) {
1585 set_err_msg(err_msg, "unable to modify subuser, " + subprocess_msg);
1586 return ret;
1587 }
1588
1589 return 0;
1590}
1591
1592RGWUserCapPool::RGWUserCapPool(RGWUser *usr)
1593{
1594 user = usr;
1595 caps = NULL;
1596 caps_allowed = (user != NULL);
1597}
1598
1599RGWUserCapPool::~RGWUserCapPool()
1600{
1601
1602}
1603
1604int RGWUserCapPool::init(RGWUserAdminOpState& op_state)
1605{
1606 if (!op_state.is_initialized()) {
1607 caps_allowed = false;
1608 return -EINVAL;
1609 }
1610
1611 rgw_user& uid = op_state.get_user_id();
1612 if (uid.compare(RGW_USER_ANON_ID) == 0) {
1613 caps_allowed = false;
1614 return -EACCES;
1615 }
1616
1617 caps = op_state.get_caps_obj();
1618 if (!caps) {
1619 caps_allowed = false;
1620 return -ERR_INVALID_CAP;
1621 }
1622
1623 caps_allowed = true;
1624
1625 return 0;
1626}
1627
1628int RGWUserCapPool::add(RGWUserAdminOpState& op_state, std::string *err_msg)
1629{
1630 return add(op_state, err_msg, false);
1631}
1632
1633int RGWUserCapPool::add(RGWUserAdminOpState& op_state, std::string *err_msg, bool defer_save)
1634{
1635 int ret = 0;
1636 std::string caps_str = op_state.get_caps();
1637
1638 if (!op_state.is_populated()) {
1639 set_err_msg(err_msg, "user info was not populated");
1640 return -EINVAL;
1641 }
1642
1643 if (!caps_allowed) {
1644 set_err_msg(err_msg, "caps not allowed for this user");
1645 return -EACCES;
1646 }
1647
1648 if (caps_str.empty()) {
1649 set_err_msg(err_msg, "empty user caps");
1650 return -ERR_INVALID_CAP;
1651 }
1652
1653 int r = caps->add_from_string(caps_str);
1654 if (r < 0) {
1655 set_err_msg(err_msg, "unable to add caps: " + caps_str);
1656 return r;
1657 }
1658
1659 if (!defer_save)
1660 ret = user->update(op_state, err_msg);
1661
1662 if (ret < 0)
1663 return ret;
1664
1665 return 0;
1666}
1667
1668int RGWUserCapPool::remove(RGWUserAdminOpState& op_state, std::string *err_msg)
1669{
1670 return remove(op_state, err_msg, false);
1671}
1672
1673int RGWUserCapPool::remove(RGWUserAdminOpState& op_state, std::string *err_msg, bool defer_save)
1674{
1675 int ret = 0;
1676
1677 std::string caps_str = op_state.get_caps();
1678
1679 if (!op_state.is_populated()) {
1680 set_err_msg(err_msg, "user info was not populated");
1681 return -EINVAL;
1682 }
1683
1684 if (!caps_allowed) {
1685 set_err_msg(err_msg, "caps not allowed for this user");
1686 return -EACCES;
1687 }
1688
1689 if (caps_str.empty()) {
1690 set_err_msg(err_msg, "empty user caps");
1691 return -ERR_INVALID_CAP;
1692 }
1693
1694 int r = caps->remove_from_string(caps_str);
1695 if (r < 0) {
1696 set_err_msg(err_msg, "unable to remove caps: " + caps_str);
1697 return r;
1698 }
1699
1700 if (!defer_save)
1701 ret = user->update(op_state, err_msg);
1702
1703 if (ret < 0)
1704 return ret;
1705
1706 return 0;
1707}
1708
1709RGWUser::RGWUser() : store(NULL), info_stored(false), caps(this), keys(this), subusers(this)
1710{
1711 init_default();
1712}
1713
1714int RGWUser::init(RGWRados *storage, RGWUserAdminOpState& op_state)
1715{
1716 init_default();
1717 int ret = init_storage(storage);
1718 if (ret < 0)
1719 return ret;
1720
1721 ret = init(op_state);
1722 if (ret < 0)
1723 return ret;
1724
1725 return 0;
1726}
1727
1728RGWUser::~RGWUser()
1729{
1730}
1731
1732void RGWUser::init_default()
1733{
1734 // use anonymous user info as a placeholder
1735 rgw_get_anon_user(old_info);
1736 user_id = RGW_USER_ANON_ID;
1737
1738 clear_populated();
1739}
1740
1741int RGWUser::init_storage(RGWRados *storage)
1742{
1743 if (!storage) {
1744 return -EINVAL;
1745 }
1746
1747 store = storage;
1748
1749 clear_populated();
1750
1751 /* API wrappers */
1752 keys = RGWAccessKeyPool(this);
1753 caps = RGWUserCapPool(this);
1754 subusers = RGWSubUserPool(this);
1755
1756 return 0;
1757}
1758
1759int RGWUser::init(RGWUserAdminOpState& op_state)
1760{
1761 bool found = false;
1762 std::string swift_user;
1763 rgw_user& uid = 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();
1767
1768 int key_type = op_state.get_key_type();
1769 if (key_type == KEY_TYPE_SWIFT) {
1770 swift_user = op_state.get_access_key();
1771 access_key.clear();
1772 }
1773
1774 RGWUserInfo user_info;
1775
1776 clear_populated();
1777
1778 if (uid.empty() && !subuser.empty()) {
1779 size_t pos = subuser.find(':');
1780 if (pos != string::npos) {
1781 uid = subuser.substr(0, pos);
1782 op_state.set_user_id(uid);
1783 }
1784 }
1785
1786 if (!uid.empty() && (uid.compare(RGW_USER_ANON_ID) != 0)) {
1787 found = (rgw_get_user_info_by_uid(store, uid, user_info, &op_state.objv) >= 0);
1788 op_state.found_by_uid = found;
1789 }
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;
1793 }
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;
1797 }
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;
1801 }
1802
1803 op_state.set_existing_user(found);
1804 if (found) {
1805 op_state.set_user_info(user_info);
1806 op_state.set_populated();
1807
1808 old_info = user_info;
1809 set_populated();
1810 }
1811
1812 user_id = user_info.user_id;
1813 op_state.set_initialized();
1814
1815 // this may have been called by a helper object
1816 int ret = init_members(op_state);
1817 if (ret < 0)
1818 return ret;
1819
1820 return 0;
1821}
1822
1823int RGWUser::init_members(RGWUserAdminOpState& op_state)
1824{
1825 int ret = 0;
1826
1827 ret = keys.init(op_state);
1828 if (ret < 0)
1829 return ret;
1830
1831 ret = subusers.init(op_state);
1832 if (ret < 0)
1833 return ret;
1834
1835 ret = caps.init(op_state);
1836 if (ret < 0)
1837 return ret;
1838
1839 return 0;
1840}
1841
1842int RGWUser::update(RGWUserAdminOpState& op_state, std::string *err_msg)
1843{
1844 int ret;
1845 std::string subprocess_msg;
1846 RGWUserInfo user_info = op_state.get_user_info();
1847
1848 if (!store) {
1849 set_err_msg(err_msg, "couldn't initialize storage");
1850 return -EINVAL;
1851 }
1852
1853 if (is_populated()) {
1854 ret = rgw_store_user_info(store, user_info, &old_info, &op_state.objv, real_time(), false);
1855 if (ret < 0) {
1856 set_err_msg(err_msg, "unable to store user info");
1857 return ret;
1858 }
1859
1860 ret = remove_old_indexes(store, old_info, user_info, &subprocess_msg);
1861 if (ret < 0) {
1862 set_err_msg(err_msg, "unable to remove old user info, " + subprocess_msg);
1863 return ret;
1864 }
1865 } else {
1866 ret = rgw_store_user_info(store, user_info, NULL, &op_state.objv, real_time(), false);
1867 if (ret < 0) {
1868 set_err_msg(err_msg, "unable to store user info");
1869 return ret;
1870 }
1871 }
1872
1873 old_info = user_info;
1874 set_populated();
1875
1876 return 0;
1877}
1878
1879int RGWUser::check_op(RGWUserAdminOpState& op_state, std::string *err_msg)
1880{
1881 bool same_id;
1882 bool populated;
1883 rgw_user& op_id = op_state.get_user_id();
1884
1885 RGWUserInfo user_info;
1886
1887 same_id = (user_id.compare(op_id) == 0);
1888 populated = is_populated();
1889
1890 if (op_id.compare(RGW_USER_ANON_ID) == 0) {
1891 set_err_msg(err_msg, "unable to perform operations on the anonymous user");
1892 return -EINVAL;
1893 }
1894
1895 if (populated && !same_id) {
1896 set_err_msg(err_msg, "user id mismatch, operation id: " + op_id.to_str()
1897 + " does not match: " + user_id.to_str());
1898
1899 return -EINVAL;
1900 }
1901
d2e6a577
FG
1902 int ret = rgw_validate_tenant_name(op_id.tenant);
1903 if (ret) {
1904 set_err_msg(err_msg,
1905 "invalid tenant only alphanumeric and _ characters are allowed");
1906 return ret;
1907 }
1908
7c673cae
FG
1909 //set key type when it not set or set by context
1910 if ((op_state.get_key_type() < 0) || op_state.key_type_setbycontext) {
1911 op_state.set_key_type(KEY_TYPE_S3);
1912 op_state.key_type_setbycontext = true;
1913 }
1914
1915 return 0;
1916}
1917
1918int RGWUser::execute_add(RGWUserAdminOpState& op_state, std::string *err_msg)
1919{
1920 std::string subprocess_msg;
1921 int ret = 0;
1922 bool defer_user_update = true;
1923
1924 RGWUserInfo user_info;
1925
1926 rgw_user& uid = op_state.get_user_id();
1927 std::string user_email = op_state.get_user_email();
1928 std::string display_name = op_state.get_display_name();
1929
1930 // fail if the user exists already
1931 if (op_state.has_existing_user()) {
1932 if (!op_state.exclusive &&
1933 (user_email.empty() ||
1934 boost::iequals(user_email, old_info.user_email)) &&
1935 old_info.display_name == display_name) {
1936 return execute_modify(op_state, err_msg);
1937 }
1938
1939 if (op_state.found_by_email) {
1940 set_err_msg(err_msg, "email: " + user_email +
1941 " is the email address an existing user");
1942 ret = -ERR_EMAIL_EXIST;
1943 } else if (op_state.found_by_key) {
1944 set_err_msg(err_msg, "duplicate key provided");
1945 ret = -ERR_KEY_EXIST;
1946 } else {
1947 set_err_msg(err_msg, "user: " + op_state.user_id.to_str() + " exists");
1948 ret = -EEXIST;
1949 }
1950 return ret;
1951 }
1952
1953 // fail if the user_info has already been populated
1954 if (op_state.is_populated()) {
1955 set_err_msg(err_msg, "cannot overwrite already populated user");
1956 return -EEXIST;
1957 }
1958
1959 // fail if the display name was not included
1960 if (display_name.empty()) {
1961 set_err_msg(err_msg, "no display name specified");
1962 return -EINVAL;
1963 }
1964
1965
1966 // set the user info
1967 user_id = uid;
1968 user_info.user_id = user_id;
1969 user_info.display_name = display_name;
1970 user_info.type = TYPE_RGW;
1971
1972 if (!user_email.empty())
1973 user_info.user_email = user_email;
1974
1975 CephContext *cct = store->ctx();
1976 if (op_state.max_buckets_specified) {
1977 user_info.max_buckets = op_state.get_max_buckets();
1978 } else {
1979 user_info.max_buckets = cct->_conf->rgw_user_max_buckets;
1980 }
1981
1982 user_info.suspended = op_state.get_suspension_status();
1983 user_info.admin = op_state.admin;
1984 user_info.system = op_state.system;
1985
1986 if (op_state.op_mask_specified)
1987 user_info.op_mask = op_state.get_op_mask();
1988
1989 if (op_state.has_bucket_quota()) {
1990 user_info.bucket_quota = op_state.get_bucket_quota();
1991 } else {
1992 if (cct->_conf->rgw_bucket_default_quota_max_objects >= 0) {
1993 user_info.bucket_quota.max_objects = cct->_conf->rgw_bucket_default_quota_max_objects;
1994 user_info.bucket_quota.enabled = true;
1995 }
1996 if (cct->_conf->rgw_bucket_default_quota_max_size >= 0) {
1997 user_info.bucket_quota.max_size = cct->_conf->rgw_bucket_default_quota_max_size;
1998 user_info.bucket_quota.enabled = true;
1999 }
2000 }
2001
2002 if (op_state.temp_url_key_specified) {
2003 map<int, string>::iterator iter;
2004 for (iter = op_state.temp_url_keys.begin();
2005 iter != op_state.temp_url_keys.end(); ++iter) {
2006 user_info.temp_url_keys[iter->first] = iter->second;
2007 }
2008 }
2009
2010 if (op_state.has_user_quota()) {
2011 user_info.user_quota = op_state.get_user_quota();
2012 } else {
2013 if (cct->_conf->rgw_user_default_quota_max_objects >= 0) {
2014 user_info.user_quota.max_objects = cct->_conf->rgw_user_default_quota_max_objects;
2015 user_info.user_quota.enabled = true;
2016 }
2017 if (cct->_conf->rgw_user_default_quota_max_size >= 0) {
2018 user_info.user_quota.max_size = cct->_conf->rgw_user_default_quota_max_size;
2019 user_info.user_quota.enabled = true;
2020 }
2021 }
2022
2023 // update the request
2024 op_state.set_user_info(user_info);
2025 op_state.set_populated();
2026
2027 // update the helper objects
2028 ret = init_members(op_state);
2029 if (ret < 0) {
2030 set_err_msg(err_msg, "unable to initialize user");
2031 return ret;
2032 }
2033
2034 // see if we need to add an access key
2035 if (op_state.has_key_op()) {
2036 ret = keys.add(op_state, &subprocess_msg, defer_user_update);
2037 if (ret < 0) {
2038 set_err_msg(err_msg, "unable to create access key, " + subprocess_msg);
2039 return ret;
2040 }
2041 }
2042
2043 // see if we need to add some caps
2044 if (op_state.has_caps_op()) {
2045 ret = caps.add(op_state, &subprocess_msg, defer_user_update);
2046 if (ret < 0) {
2047 set_err_msg(err_msg, "unable to add user capabilities, " + subprocess_msg);
2048 return ret;
2049 }
2050 }
2051
2052 ret = update(op_state, err_msg);
2053 if (ret < 0)
2054 return ret;
2055
2056 return 0;
2057}
2058
2059int RGWUser::add(RGWUserAdminOpState& op_state, std::string *err_msg)
2060{
2061 std::string subprocess_msg;
2062 int ret;
2063
2064 ret = check_op(op_state, &subprocess_msg);
2065 if (ret < 0) {
2066 set_err_msg(err_msg, "unable to parse parameters, " + subprocess_msg);
2067 return ret;
2068 }
2069
2070 ret = execute_add(op_state, &subprocess_msg);
2071 if (ret < 0) {
2072 set_err_msg(err_msg, "unable to create user, " + subprocess_msg);
2073 return ret;
2074 }
2075
2076 return 0;
2077}
2078
2079int RGWUser::execute_remove(RGWUserAdminOpState& op_state, std::string *err_msg)
2080{
2081 int ret;
2082
2083 bool purge_data = op_state.will_purge_data();
2084 rgw_user& uid = op_state.get_user_id();
2085 RGWUserInfo user_info = op_state.get_user_info();
2086
2087 if (!op_state.has_existing_user()) {
2088 set_err_msg(err_msg, "user does not exist");
2089 return -ENOENT;
2090 }
2091
2092 bool is_truncated = false;
2093 string marker;
2094 CephContext *cct = store->ctx();
2095 size_t max_buckets = cct->_conf->rgw_list_buckets_max_chunk;
2096 do {
2097 RGWUserBuckets buckets;
2098 ret = rgw_read_user_buckets(store, uid, buckets, marker, string(),
2099 max_buckets, false, &is_truncated);
2100 if (ret < 0) {
2101 set_err_msg(err_msg, "unable to read user bucket info");
2102 return ret;
2103 }
2104
2105 map<std::string, RGWBucketEnt>& m = buckets.get_buckets();
2106 if (!m.empty() && !purge_data) {
2107 set_err_msg(err_msg, "must specify purge data to remove user with buckets");
2108 return -EEXIST; // change to code that maps to 409: conflict
2109 }
2110
2111 std::map<std::string, RGWBucketEnt>::iterator it;
2112 for (it = m.begin(); it != m.end(); ++it) {
2113 ret = rgw_remove_bucket(store, ((*it).second).bucket, true);
2114 if (ret < 0) {
2115 set_err_msg(err_msg, "unable to delete user data");
2116 return ret;
2117 }
2118
2119 marker = it->first;
2120 }
2121
2122 } while (is_truncated);
2123
2124 ret = rgw_delete_user(store, user_info, op_state.objv);
2125 if (ret < 0) {
2126 set_err_msg(err_msg, "unable to remove user from RADOS");
2127 return ret;
2128 }
2129
2130 op_state.clear_populated();
2131 clear_populated();
2132
2133 return 0;
2134}
2135
2136int RGWUser::remove(RGWUserAdminOpState& op_state, std::string *err_msg)
2137{
2138 std::string subprocess_msg;
2139 int ret;
2140
2141 ret = check_op(op_state, &subprocess_msg);
2142 if (ret < 0) {
2143 set_err_msg(err_msg, "unable to parse parameters, " + subprocess_msg);
2144 return ret;
2145 }
2146
2147 ret = execute_remove(op_state, &subprocess_msg);
2148 if (ret < 0) {
2149 set_err_msg(err_msg, "unable to remove user, " + subprocess_msg);
2150 return ret;
2151 }
2152
2153 return 0;
2154}
2155
2156int RGWUser::execute_modify(RGWUserAdminOpState& op_state, std::string *err_msg)
2157{
2158 bool populated = op_state.is_populated();
2159 int ret = 0;
2160 std::string subprocess_msg;
2161 std::string op_email = op_state.get_user_email();
2162 std::string display_name = op_state.get_display_name();
2163
2164 RGWUserInfo user_info;
2165 RGWUserInfo duplicate_check;
2166
2167 // ensure that the user info has been populated or is populate-able
2168 if (!op_state.has_existing_user() && !populated) {
2169 set_err_msg(err_msg, "user not found");
2170 return -ENOENT;
2171 }
2172
2173 // if the user hasn't already been populated...attempt to
2174 if (!populated) {
2175 ret = init(op_state);
2176 if (ret < 0) {
2177 set_err_msg(err_msg, "unable to retrieve user info");
2178 return ret;
2179 }
2180 }
2181
2182 // ensure that we can modify the user's attributes
2183 if (user_id.compare(RGW_USER_ANON_ID) == 0) {
2184 set_err_msg(err_msg, "unable to modify anonymous user's info");
2185 return -EACCES;
2186 }
2187
2188 user_info = old_info;
2189
2190 std::string old_email = old_info.user_email;
2191 if (!op_email.empty()) {
2192 // make sure we are not adding a duplicate email
2193 if (old_email.compare(op_email) != 0) {
2194 ret = rgw_get_user_info_by_email(store, op_email, duplicate_check);
2195 if (ret >= 0 && duplicate_check.user_id.compare(user_id) != 0) {
2196 set_err_msg(err_msg, "cannot add duplicate email");
2197 return -ERR_EMAIL_EXIST;
2198 }
2199 }
2200 user_info.user_email = op_email;
2201 } else if (op_email.empty() && op_state.user_email_specified) {
2202
2203 ldout(store->ctx(), 10) << "removing email index: " << user_info.user_email << dendl;
2204 ret = rgw_remove_email_index(store, user_info.user_email);
2205 if (ret < 0 && ret != -ENOENT) {
2206 ldout(store->ctx(), 0) << "ERROR: could not remove " << user_info.user_id << " index (err=" << ret << ")" << dendl;
2207 return ret;
2208 }
2209 user_info.user_email = "";
2210 }
2211
2212 // update the remaining user info
2213 if (!display_name.empty())
2214 user_info.display_name = display_name;
2215
2216 if (op_state.max_buckets_specified)
2217 user_info.max_buckets = op_state.get_max_buckets();
2218
2219 if (op_state.admin_specified)
2220 user_info.admin = op_state.admin;
2221
2222 if (op_state.system_specified)
2223 user_info.system = op_state.system;
2224
2225 if (op_state.temp_url_key_specified) {
2226 map<int, string>::iterator iter;
2227 for (iter = op_state.temp_url_keys.begin();
2228 iter != op_state.temp_url_keys.end(); ++iter) {
2229 user_info.temp_url_keys[iter->first] = iter->second;
2230 }
2231 }
2232
2233 if (op_state.op_mask_specified)
2234 user_info.op_mask = op_state.get_op_mask();
2235
2236 if (op_state.has_bucket_quota())
2237 user_info.bucket_quota = op_state.get_bucket_quota();
2238
2239 if (op_state.has_user_quota())
2240 user_info.user_quota = op_state.get_user_quota();
2241
2242 if (op_state.has_suspension_op()) {
2243 __u8 suspended = op_state.get_suspension_status();
2244 user_info.suspended = suspended;
2245
2246 RGWUserBuckets buckets;
2247
2248 if (user_id.empty()) {
2249 set_err_msg(err_msg, "empty user id passed...aborting");
2250 return -EINVAL;
2251 }
2252
2253 bool is_truncated = false;
2254 string marker;
2255 CephContext *cct = store->ctx();
2256 size_t max_buckets = cct->_conf->rgw_list_buckets_max_chunk;
2257 do {
2258 ret = rgw_read_user_buckets(store, user_id, buckets, marker, string(),
2259 max_buckets, false, &is_truncated);
2260 if (ret < 0) {
2261 set_err_msg(err_msg, "could not get buckets for uid: " + user_id.to_str());
2262 return ret;
2263 }
2264
2265 map<string, RGWBucketEnt>& m = buckets.get_buckets();
2266 map<string, RGWBucketEnt>::iterator iter;
2267
2268 vector<rgw_bucket> bucket_names;
2269 for (iter = m.begin(); iter != m.end(); ++iter) {
2270 RGWBucketEnt obj = iter->second;
2271 bucket_names.push_back(obj.bucket);
2272
2273 marker = iter->first;
2274 }
2275
2276 ret = store->set_buckets_enabled(bucket_names, !suspended);
2277 if (ret < 0) {
2278 set_err_msg(err_msg, "failed to modify bucket");
2279 return ret;
2280 }
2281
2282 } while (is_truncated);
2283 }
2284 op_state.set_user_info(user_info);
2285
2286 // if we're supposed to modify keys, do so
2287 if (op_state.has_key_op()) {
2288 ret = keys.add(op_state, &subprocess_msg, true);
2289 if (ret < 0) {
2290 set_err_msg(err_msg, "unable to create or modify keys, " + subprocess_msg);
2291 return ret;
2292 }
2293 }
2294
2295 ret = update(op_state, err_msg);
2296 if (ret < 0)
2297 return ret;
2298
2299 return 0;
2300}
2301
2302int RGWUser::modify(RGWUserAdminOpState& op_state, std::string *err_msg)
2303{
2304 std::string subprocess_msg;
2305 int ret;
2306
2307 ret = check_op(op_state, &subprocess_msg);
2308 if (ret < 0) {
2309 set_err_msg(err_msg, "unable to parse parameters, " + subprocess_msg);
2310 return ret;
2311 }
2312
2313 ret = execute_modify(op_state, &subprocess_msg);
2314 if (ret < 0) {
2315 set_err_msg(err_msg, "unable to modify user, " + subprocess_msg);
2316 return ret;
2317 }
2318
2319 return 0;
2320}
2321
2322int RGWUser::info(RGWUserAdminOpState& op_state, RGWUserInfo& fetched_info, std::string *err_msg)
2323{
2324 int ret = init(op_state);
2325 if (ret < 0) {
2326 set_err_msg(err_msg, "unable to fetch user info");
2327 return ret;
2328 }
2329
2330 fetched_info = op_state.get_user_info();
2331
2332 return 0;
2333}
2334
2335int RGWUser::info(RGWUserInfo& fetched_info, std::string *err_msg)
2336{
2337 if (!is_populated()) {
2338 set_err_msg(err_msg, "no user info saved");
2339 return -EINVAL;
2340 }
2341
2342 fetched_info = old_info;
2343
2344 return 0;
2345}
2346
2347int RGWUserAdminOp_User::info(RGWRados *store, RGWUserAdminOpState& op_state,
2348 RGWFormatterFlusher& flusher)
2349{
2350 RGWUserInfo info;
2351 RGWUser user;
2352
2353 int ret = user.init(store, op_state);
2354 if (ret < 0)
2355 return ret;
2356
2357 if (!op_state.has_existing_user())
224ce89b 2358 return -ERR_NO_SUCH_USER;
7c673cae
FG
2359
2360 Formatter *formatter = flusher.get_formatter();
2361
2362 ret = user.info(info, NULL);
2363 if (ret < 0)
2364 return ret;
2365
2366 RGWStorageStats stats;
2367 RGWStorageStats *arg_stats = NULL;
2368 if (op_state.fetch_stats) {
2369 int ret = store->get_user_stats(info.user_id, stats);
2370 if (ret < 0) {
2371 return ret;
2372 }
2373
2374 arg_stats = &stats;
2375 }
2376
2377 flusher.start(0);
2378
2379 dump_user_info(formatter, info, arg_stats);
2380 flusher.flush();
2381
2382 return 0;
2383}
2384
2385int RGWUserAdminOp_User::create(RGWRados *store, RGWUserAdminOpState& op_state,
2386 RGWFormatterFlusher& flusher)
2387{
2388 RGWUserInfo info;
2389 RGWUser user;
2390 int ret = user.init(store, op_state);
2391 if (ret < 0)
2392 return ret;
2393
2394 Formatter *formatter = flusher.get_formatter();
2395
2396 ret = user.add(op_state, NULL);
2397 if (ret < 0) {
2398 if (ret == -EEXIST)
2399 ret = -ERR_USER_EXIST;
2400 return ret;
2401 }
2402
2403 ret = user.info(info, NULL);
2404 if (ret < 0)
2405 return ret;
2406
2407 flusher.start(0);
2408
2409 dump_user_info(formatter, info);
2410 flusher.flush();
2411
2412 return 0;
2413}
2414
2415int RGWUserAdminOp_User::modify(RGWRados *store, RGWUserAdminOpState& op_state,
2416 RGWFormatterFlusher& flusher)
2417{
2418 RGWUserInfo info;
2419 RGWUser user;
2420 int ret = user.init(store, op_state);
2421 if (ret < 0)
2422 return ret;
2423 Formatter *formatter = flusher.get_formatter();
2424
2425 ret = user.modify(op_state, NULL);
224ce89b
WB
2426 if (ret < 0) {
2427 if (ret == -ENOENT)
2428 ret = -ERR_NO_SUCH_USER;
7c673cae 2429 return ret;
224ce89b 2430 }
7c673cae
FG
2431
2432 ret = user.info(info, NULL);
2433 if (ret < 0)
2434 return ret;
2435
2436 flusher.start(0);
2437
2438 dump_user_info(formatter, info);
2439 flusher.flush();
2440
2441 return 0;
2442}
2443
2444int RGWUserAdminOp_User::remove(RGWRados *store, RGWUserAdminOpState& op_state,
2445 RGWFormatterFlusher& flusher)
2446{
2447 RGWUserInfo info;
2448 RGWUser user;
2449 int ret = user.init(store, op_state);
2450 if (ret < 0)
2451 return ret;
2452
2453
2454 ret = user.remove(op_state, NULL);
2455
224ce89b
WB
2456 if (ret == -ENOENT)
2457 ret = -ERR_NO_SUCH_USER;
7c673cae
FG
2458 return ret;
2459}
2460
2461int RGWUserAdminOp_Subuser::create(RGWRados *store, RGWUserAdminOpState& op_state,
2462 RGWFormatterFlusher& flusher)
2463{
2464 RGWUserInfo info;
2465 RGWUser user;
2466 int ret = user.init(store, op_state);
2467 if (ret < 0)
2468 return ret;
2469
224ce89b
WB
2470 if (!op_state.has_existing_user())
2471 return -ERR_NO_SUCH_USER;
2472
7c673cae
FG
2473 Formatter *formatter = flusher.get_formatter();
2474
2475 ret = user.subusers.add(op_state, NULL);
2476 if (ret < 0)
2477 return ret;
2478
2479 ret = user.info(info, NULL);
2480 if (ret < 0)
2481 return ret;
2482
2483 flusher.start(0);
2484
2485 dump_subusers_info(formatter, info);
2486 flusher.flush();
2487
2488 return 0;
2489}
2490
2491int RGWUserAdminOp_Subuser::modify(RGWRados *store, RGWUserAdminOpState& op_state,
2492 RGWFormatterFlusher& flusher)
2493{
2494 RGWUserInfo info;
2495 RGWUser user;
2496 int ret = user.init(store, op_state);
2497 if (ret < 0)
2498 return ret;
2499
224ce89b
WB
2500 if (!op_state.has_existing_user())
2501 return -ERR_NO_SUCH_USER;
2502
7c673cae
FG
2503 Formatter *formatter = flusher.get_formatter();
2504
2505 ret = user.subusers.modify(op_state, NULL);
2506 if (ret < 0)
2507 return ret;
2508
2509 ret = user.info(info, NULL);
2510 if (ret < 0)
2511 return ret;
2512
2513 flusher.start(0);
2514
2515 dump_subusers_info(formatter, info);
2516 flusher.flush();
2517
2518 return 0;
2519}
2520
2521int RGWUserAdminOp_Subuser::remove(RGWRados *store, RGWUserAdminOpState& op_state,
2522 RGWFormatterFlusher& flusher)
2523{
2524 RGWUserInfo info;
2525 RGWUser user;
2526 int ret = user.init(store, op_state);
2527 if (ret < 0)
2528 return ret;
2529
2530
224ce89b
WB
2531 if (!op_state.has_existing_user())
2532 return -ERR_NO_SUCH_USER;
2533
7c673cae
FG
2534 ret = user.subusers.remove(op_state, NULL);
2535 if (ret < 0)
2536 return ret;
2537
2538 return 0;
2539}
2540
2541int RGWUserAdminOp_Key::create(RGWRados *store, RGWUserAdminOpState& op_state,
2542 RGWFormatterFlusher& flusher)
2543{
2544 RGWUserInfo info;
2545 RGWUser user;
2546 int ret = user.init(store, op_state);
2547 if (ret < 0)
2548 return ret;
2549
224ce89b
WB
2550 if (!op_state.has_existing_user())
2551 return -ERR_NO_SUCH_USER;
2552
7c673cae
FG
2553 Formatter *formatter = flusher.get_formatter();
2554
2555 ret = user.keys.add(op_state, NULL);
2556 if (ret < 0)
2557 return ret;
2558
2559 ret = user.info(info, NULL);
2560 if (ret < 0)
2561 return ret;
2562
2563 flusher.start(0);
2564
2565 int key_type = op_state.get_key_type();
2566
2567 if (key_type == KEY_TYPE_SWIFT)
2568 dump_swift_keys_info(formatter, info);
2569
2570 else if (key_type == KEY_TYPE_S3)
2571 dump_access_keys_info(formatter, info);
2572
2573 flusher.flush();
2574
2575 return 0;
2576}
2577
2578int RGWUserAdminOp_Key::remove(RGWRados *store, RGWUserAdminOpState& op_state,
2579 RGWFormatterFlusher& flusher)
2580{
2581 RGWUserInfo info;
2582 RGWUser user;
2583 int ret = user.init(store, op_state);
2584 if (ret < 0)
2585 return ret;
2586
224ce89b
WB
2587 if (!op_state.has_existing_user())
2588 return -ERR_NO_SUCH_USER;
2589
7c673cae
FG
2590
2591 ret = user.keys.remove(op_state, NULL);
2592 if (ret < 0)
2593 return ret;
2594
2595 return 0;
2596}
2597
2598int RGWUserAdminOp_Caps::add(RGWRados *store, RGWUserAdminOpState& op_state,
2599 RGWFormatterFlusher& flusher)
2600{
2601 RGWUserInfo info;
2602 RGWUser user;
2603 int ret = user.init(store, op_state);
2604 if (ret < 0)
2605 return ret;
2606
224ce89b
WB
2607 if (!op_state.has_existing_user())
2608 return -ERR_NO_SUCH_USER;
2609
7c673cae
FG
2610 Formatter *formatter = flusher.get_formatter();
2611
2612 ret = user.caps.add(op_state, NULL);
2613 if (ret < 0)
2614 return ret;
2615
2616 ret = user.info(info, NULL);
2617 if (ret < 0)
2618 return ret;
2619
2620 flusher.start(0);
2621
2622 info.caps.dump(formatter);
2623 flusher.flush();
2624
2625 return 0;
2626}
2627
2628
2629int RGWUserAdminOp_Caps::remove(RGWRados *store, RGWUserAdminOpState& op_state,
2630 RGWFormatterFlusher& flusher)
2631{
2632 RGWUserInfo info;
2633 RGWUser user;
2634 int ret = user.init(store, op_state);
2635 if (ret < 0)
2636 return ret;
2637
224ce89b
WB
2638 if (!op_state.has_existing_user())
2639 return -ERR_NO_SUCH_USER;
2640
7c673cae
FG
2641 Formatter *formatter = flusher.get_formatter();
2642
2643 ret = user.caps.remove(op_state, NULL);
2644 if (ret < 0)
2645 return ret;
2646
2647 ret = user.info(info, NULL);
2648 if (ret < 0)
2649 return ret;
2650
2651 flusher.start(0);
2652
2653 info.caps.dump(formatter);
2654 flusher.flush();
2655
2656 return 0;
2657}
2658
2659struct RGWUserCompleteInfo {
2660 RGWUserInfo info;
2661 map<string, bufferlist> attrs;
2662 bool has_attrs;
2663
2664 RGWUserCompleteInfo()
2665 : has_attrs(false)
2666 {}
2667
2668 void dump(Formatter * const f) const {
2669 info.dump(f);
2670 encode_json("attrs", attrs, f);
2671 }
2672
2673 void decode_json(JSONObj *obj) {
2674 decode_json_obj(info, obj);
2675 has_attrs = JSONDecoder::decode_json("attrs", attrs, obj);
2676 }
2677};
2678
2679class RGWUserMetadataObject : public RGWMetadataObject {
2680 RGWUserCompleteInfo uci;
2681public:
2682 RGWUserMetadataObject(const RGWUserCompleteInfo& _uci, obj_version& v, real_time m)
2683 : uci(_uci) {
2684 objv = v;
2685 mtime = m;
2686 }
2687
2688 void dump(Formatter *f) const override {
2689 uci.dump(f);
2690 }
2691};
2692
2693class RGWUserMetadataHandler : public RGWMetadataHandler {
2694public:
2695 string get_type() override { return "user"; }
2696
2697 int get(RGWRados *store, string& entry, RGWMetadataObject **obj) override {
2698 RGWUserCompleteInfo uci;
2699 RGWObjVersionTracker objv_tracker;
2700 real_time mtime;
2701
2702 rgw_user uid(entry);
2703
2704 int ret = rgw_get_user_info_by_uid(store, uid, uci.info, &objv_tracker,
2705 &mtime, NULL, &uci.attrs);
2706 if (ret < 0) {
2707 return ret;
2708 }
2709
2710 RGWUserMetadataObject *mdo = new RGWUserMetadataObject(uci, objv_tracker.read_version, mtime);
2711 *obj = mdo;
2712
2713 return 0;
2714 }
2715
2716 int put(RGWRados *store, string& entry, RGWObjVersionTracker& objv_tracker,
2717 real_time mtime, JSONObj *obj, sync_type_t sync_mode) override {
2718 RGWUserCompleteInfo uci;
2719
2720 try {
2721 decode_json_obj(uci, obj);
2722 } catch (JSONDecoder::err& e) {
2723 return -EINVAL;
2724 }
2725
2726 map<string, bufferlist> *pattrs = NULL;
2727 if (uci.has_attrs) {
2728 pattrs = &uci.attrs;
2729 }
2730
2731 rgw_user uid(entry);
2732
2733 RGWUserInfo old_info;
2734 real_time orig_mtime;
2735 int ret = rgw_get_user_info_by_uid(store, uid, old_info, &objv_tracker, &orig_mtime);
2736 if (ret < 0 && ret != -ENOENT)
2737 return ret;
2738
2739 // are we actually going to perform this put, or is it too old?
2740 if (ret != -ENOENT &&
2741 !check_versions(objv_tracker.read_version, orig_mtime,
2742 objv_tracker.write_version, mtime, sync_mode)) {
2743 return STATUS_NO_APPLY;
2744 }
2745
2746 ret = rgw_store_user_info(store, uci.info, &old_info, &objv_tracker, mtime, false, pattrs);
2747 if (ret < 0) {
2748 return ret;
2749 }
2750
2751 return STATUS_APPLIED;
2752 }
2753
2754 struct list_keys_info {
2755 RGWRados *store;
2756 RGWListRawObjsCtx ctx;
2757 };
2758
2759 int remove(RGWRados *store, string& entry, RGWObjVersionTracker& objv_tracker) override {
2760 RGWUserInfo info;
2761
2762 rgw_user uid(entry);
2763
2764 int ret = rgw_get_user_info_by_uid(store, uid, info, &objv_tracker);
2765 if (ret < 0)
2766 return ret;
2767
2768 return rgw_delete_user(store, info, objv_tracker);
2769 }
2770
2771 void get_pool_and_oid(RGWRados *store, const string& key, rgw_pool& pool, string& oid) override {
2772 oid = key;
2773 pool = store->get_zone_params().user_uid_pool;
2774 }
2775
181888fb 2776 int list_keys_init(RGWRados *store, const string& marker, void **phandle) override
7c673cae 2777 {
181888fb 2778 auto info = ceph::make_unique<list_keys_info>();
7c673cae
FG
2779
2780 info->store = store;
2781
181888fb
FG
2782 int ret = store->list_raw_objects_init(store->get_zone_params().user_uid_pool, marker,
2783 &info->ctx);
2784 if (ret < 0) {
2785 return ret;
2786 }
2787
2788 *phandle = (void *)info.release();
7c673cae
FG
2789
2790 return 0;
2791 }
2792
2793 int list_keys_next(void *handle, int max, list<string>& keys, bool *truncated) override {
2794 list_keys_info *info = static_cast<list_keys_info *>(handle);
2795
2796 string no_filter;
2797
2798 keys.clear();
2799
2800 RGWRados *store = info->store;
2801
2802 list<string> unfiltered_keys;
2803
181888fb
FG
2804 int ret = store->list_raw_objects_next(no_filter, max, info->ctx,
2805 unfiltered_keys, truncated);
7c673cae
FG
2806 if (ret < 0 && ret != -ENOENT)
2807 return ret;
2808 if (ret == -ENOENT) {
2809 if (truncated)
2810 *truncated = false;
2811 return -ENOENT;
2812 }
2813
2814 // now filter out the buckets entries
2815 list<string>::iterator iter;
2816 for (iter = unfiltered_keys.begin(); iter != unfiltered_keys.end(); ++iter) {
2817 string& k = *iter;
2818
2819 if (k.find(".buckets") == string::npos) {
2820 keys.push_back(k);
2821 }
2822 }
2823
2824 return 0;
2825 }
2826
2827 void list_keys_complete(void *handle) override {
2828 list_keys_info *info = static_cast<list_keys_info *>(handle);
2829 delete info;
2830 }
181888fb
FG
2831
2832 string get_marker(void *handle) {
2833 list_keys_info *info = static_cast<list_keys_info *>(handle);
2834 return info->store->list_raw_objs_get_cursor(info->ctx);
2835 }
7c673cae
FG
2836};
2837
2838void rgw_user_init(RGWRados *store)
2839{
2840 uinfo_cache.init(store);
2841
2842 user_meta_handler = new RGWUserMetadataHandler;
2843 store->meta_mgr->register_handler(user_meta_handler);
2844}