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