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