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