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