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