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