]> git.proxmox.com Git - ceph.git/blame - ceph/src/rgw/rgw_user.h
update sources to 12.2.2
[ceph.git] / ceph / src / rgw / rgw_user.h
CommitLineData
7c673cae
FG
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3
4#ifndef CEPH_RGW_USER_H
5#define CEPH_RGW_USER_H
6
7#include <string>
8#include <boost/algorithm/string.hpp>
9#include "include/assert.h"
10
11#include "include/types.h"
12#include "rgw_common.h"
13#include "rgw_tools.h"
14
15#include "rgw_rados.h"
16
17#include "rgw_string.h"
18
19#include "common/Formatter.h"
20#include "rgw_formats.h"
21
7c673cae
FG
22#define RGW_USER_ANON_ID "anonymous"
23
24#define SECRET_KEY_LEN 40
25#define PUBLIC_ID_LEN 20
26#define RAND_SUBUSER_LEN 5
27
28#define XMLNS_AWS_S3 "http://s3.amazonaws.com/doc/2006-03-01/"
29
30/**
31 * A string wrapper that includes encode/decode functions
32 * for easily accessing a UID in all forms
33 */
34struct RGWUID
35{
36 rgw_user user_id;
37 void encode(bufferlist& bl) const {
38 string s;
39 user_id.to_str(s);
40 ::encode(s, bl);
41 }
42 void decode(bufferlist::iterator& bl) {
43 string s;
44 ::decode(s, bl);
45 user_id.from_str(s);
46 }
47};
48WRITE_CLASS_ENCODER(RGWUID)
49
50extern int rgw_user_sync_all_stats(RGWRados *store, const rgw_user& user_id);
c07f9fc5
FG
51extern int rgw_user_get_all_buckets_stats(RGWRados *store, const rgw_user& user_id, map<string, cls_user_bucket_entry>&buckets_usage_map);
52
7c673cae
FG
53/**
54 * Get the anonymous (ie, unauthenticated) user info.
55 */
56extern void rgw_get_anon_user(RGWUserInfo& info);
57
58/**
59 * Save the given user information to storage.
60 * Returns: 0 on success, -ERR# on failure.
61 */
62extern int rgw_store_user_info(RGWRados *store,
63 RGWUserInfo& info,
64 RGWUserInfo *old_info,
65 RGWObjVersionTracker *objv_tracker,
66 real_time mtime,
67 bool exclusive,
68 map<string, bufferlist> *pattrs = NULL);
69
70/**
71 * Given an user_id, finds the user info associated with it.
72 * returns: 0 on success, -ERR# on failure (including nonexistence)
73 */
74extern int rgw_get_user_info_by_uid(RGWRados *store,
75 const rgw_user& user_id,
76 RGWUserInfo& info,
77 RGWObjVersionTracker *objv_tracker = NULL,
78 real_time *pmtime = NULL,
79 rgw_cache_entry_info *cache_info = NULL,
80 map<string, bufferlist> *pattrs = NULL);
81/**
82 * Given an email, finds the user info associated with it.
83 * returns: 0 on success, -ERR# on failure (including nonexistence)
84 */
85extern int rgw_get_user_info_by_email(RGWRados *store, string& email, RGWUserInfo& info,
86 RGWObjVersionTracker *objv_tracker = NULL, real_time *pmtime = NULL);
87/**
88 * Given an swift username, finds the user info associated with it.
89 * returns: 0 on success, -ERR# on failure (including nonexistence)
90 */
91extern int rgw_get_user_info_by_swift(RGWRados *store,
92 const string& swift_name,
93 RGWUserInfo& info, /* out */
94 RGWObjVersionTracker *objv_tracker = nullptr,
95 real_time *pmtime = nullptr);
96/**
97 * Given an access key, finds the user info associated with it.
98 * returns: 0 on success, -ERR# on failure (including nonexistence)
99 */
100extern int rgw_get_user_info_by_access_key(RGWRados* store,
101 const std::string& access_key,
102 RGWUserInfo& info,
103 RGWObjVersionTracker* objv_tracker = nullptr,
104 real_time* pmtime = nullptr);
105/**
106 * Get all the custom metadata stored for user specified in @user_id
107 * and put it into @attrs.
108 * Returns: 0 on success, -ERR# on failure.
109 */
110extern int rgw_get_user_attrs_by_uid(RGWRados *store,
111 const rgw_user& user_id,
112 map<string, bufferlist>& attrs,
113 RGWObjVersionTracker *objv_tracker = NULL);
114/**
115 * Given an RGWUserInfo, deletes the user and its bucket ACLs.
116 */
117extern int rgw_delete_user(RGWRados *store, RGWUserInfo& user, RGWObjVersionTracker& objv_tracker);
7c673cae
FG
118
119/*
120 * remove the different indexes
121 */
122extern int rgw_remove_key_index(RGWRados *store, RGWAccessKey& access_key);
123extern int rgw_remove_uid_index(RGWRados *store, rgw_user& uid);
124extern int rgw_remove_email_index(RGWRados *store, string& email);
125extern int rgw_remove_swift_name_index(RGWRados *store, string& swift_name);
126
7c673cae
FG
127extern void rgw_perm_to_str(uint32_t mask, char *buf, int len);
128extern uint32_t rgw_str_to_perm(const char *str);
129
d2e6a577
FG
130extern int rgw_validate_tenant_name(const string& t);
131
7c673cae
FG
132enum ObjectKeyType {
133 KEY_TYPE_SWIFT,
134 KEY_TYPE_S3,
135 KEY_TYPE_UNDEFINED
136};
137
138enum RGWKeyPoolOp {
139 GENERATE_KEY,
140 MODIFY_KEY
141};
142
143enum RGWUserId {
144 RGW_USER_ID,
145 RGW_SWIFT_USERNAME,
146 RGW_USER_EMAIL,
147 RGW_ACCESS_KEY,
148};
149
d2e6a577
FG
150/*
151 * An RGWUser class along with supporting classes created
152 * to support the creation of an RESTful administrative API
153 */
7c673cae
FG
154struct RGWUserAdminOpState {
155 // user attributes
156 RGWUserInfo info;
157 rgw_user user_id;
158 std::string user_email;
159 std::string display_name;
160 int32_t max_buckets;
161 __u8 suspended;
162 __u8 admin;
163 __u8 system;
164 __u8 exclusive;
165 __u8 fetch_stats;
3efd9988 166 __u8 sync_stats;
7c673cae
FG
167 std::string caps;
168 RGWObjVersionTracker objv;
169 uint32_t op_mask;
170 map<int, string> temp_url_keys;
171
172 // subuser attributes
173 std::string subuser;
174 uint32_t perm_mask;
175
176 // key_attributes
177 std::string id; // access key
178 std::string key; // secret key
179 int32_t key_type;
180
181 // operation attributes
182 bool existing_user;
183 bool existing_key;
184 bool existing_subuser;
185 bool existing_email;
186 bool subuser_specified;
187 bool gen_secret;
188 bool gen_access;
189 bool gen_subuser;
190 bool id_specified;
191 bool key_specified;
192 bool type_specified;
193 bool key_type_setbycontext; // key type set by user or subuser context
194 bool purge_data;
195 bool purge_keys;
196 bool display_name_specified;
197 bool user_email_specified;
198 bool max_buckets_specified;
199 bool perm_specified;
200 bool op_mask_specified;
201 bool caps_specified;
202 bool suspension_op;
d2e6a577 203 bool admin_specified = false;
7c673cae
FG
204 bool system_specified;
205 bool key_op;
206 bool temp_url_key_specified;
207 bool found_by_uid;
208 bool found_by_email;
209 bool found_by_key;
210
211 // req parameters
212 bool populated;
213 bool initialized;
214 bool key_params_checked;
215 bool subuser_params_checked;
216 bool user_params_checked;
217
218 bool bucket_quota_specified;
219 bool user_quota_specified;
220
221 RGWQuotaInfo bucket_quota;
222 RGWQuotaInfo user_quota;
223
224 void set_access_key(std::string& access_key) {
225 if (access_key.empty())
226 return;
227
228 id = access_key;
229 id_specified = true;
230 gen_access = false;
231 key_op = true;
232 }
233
234 void set_secret_key(std::string& secret_key) {
235 if (secret_key.empty())
236 return;
237
238 key = secret_key;
239 key_specified = true;
240 gen_secret = false;
241 key_op = true;
242 }
243
244 void set_user_id(rgw_user& id) {
245 if (id.empty())
246 return;
247
248 user_id = id;
249 }
250
251 void set_user_email(std::string& email) {
c07f9fc5 252 /* always lowercase email address */
7c673cae
FG
253 boost::algorithm::to_lower(email);
254 user_email = email;
255 user_email_specified = true;
256 }
257
258 void set_display_name(std::string& name) {
259 if (name.empty())
260 return;
261
262 display_name = name;
263 display_name_specified = true;
264 }
265
266 void set_subuser(std::string& _subuser) {
267 if (_subuser.empty())
268 return;
269
270 size_t pos = _subuser.find(":");
271 if (pos != string::npos) {
272 rgw_user tmp_id;
273 tmp_id.from_str(_subuser.substr(0, pos));
274 if (tmp_id.tenant.empty()) {
275 user_id.id = tmp_id.id;
276 } else {
277 user_id = tmp_id;
278 }
279 subuser = _subuser.substr(pos+1);
280 } else {
281 subuser = _subuser;
282 }
283
284 subuser_specified = true;
285 }
286
287 void set_caps(std::string& _caps) {
288 if (_caps.empty())
289 return;
290
291 caps = _caps;
292 caps_specified = true;
293 }
294
295 void set_perm(uint32_t perm) {
296 perm_mask = perm;
297 perm_specified = true;
298 }
299
300 void set_op_mask(uint32_t mask) {
301 op_mask = mask;
302 op_mask_specified = true;
303 }
304
305 void set_temp_url_key(const string& key, int index) {
306 temp_url_keys[index] = key;
307 temp_url_key_specified = true;
308 }
309
310 void set_key_type(int32_t type) {
311 key_type = type;
312 type_specified = true;
313 }
314
315 void set_suspension(__u8 is_suspended) {
316 suspended = is_suspended;
317 suspension_op = true;
318 }
319
320 void set_admin(__u8 is_admin) {
321 admin = is_admin;
322 admin_specified = true;
323 }
324
325 void set_system(__u8 is_system) {
326 system = is_system;
327 system_specified = true;
328 }
329
330 void set_exclusive(__u8 is_exclusive) {
331 exclusive = is_exclusive;
332 }
333
334 void set_fetch_stats(__u8 is_fetch_stats) {
335 fetch_stats = is_fetch_stats;
336 }
337
3efd9988
FG
338 void set_sync_stats(__u8 is_sync_stats) {
339 sync_stats = is_sync_stats;
340 }
341
7c673cae
FG
342 void set_user_info(RGWUserInfo& user_info) {
343 user_id = user_info.user_id;
344 info = user_info;
345 }
346
347 void set_max_buckets(int32_t mb) {
348 max_buckets = mb;
349 max_buckets_specified = true;
350 }
351
352 void set_gen_access() {
353 gen_access = true;
354 key_op = true;
355 }
356
357 void set_gen_secret() {
358 gen_secret = true;
359 key_op = true;
360 }
361
362 void set_generate_key() {
363 if (id.empty())
364 gen_access = true;
365 if (key.empty())
366 gen_secret = true;
367 key_op = true;
368 }
369
370 void clear_generate_key() {
371 gen_access = false;
372 gen_secret = false;
373 }
374
375 void set_purge_keys() {
376 purge_keys = true;
377 key_op = true;
378 }
379
380 void set_bucket_quota(RGWQuotaInfo& quota) {
381 bucket_quota = quota;
382 bucket_quota_specified = true;
383 }
384
385 void set_user_quota(RGWQuotaInfo& quota) {
386 user_quota = quota;
387 user_quota_specified = true;
388 }
389
390 bool is_populated() { return populated; }
391 bool is_initialized() { return initialized; }
392 bool has_existing_user() { return existing_user; }
393 bool has_existing_key() { return existing_key; }
394 bool has_existing_subuser() { return existing_subuser; }
395 bool has_existing_email() { return existing_email; }
396 bool has_subuser() { return subuser_specified; }
397 bool has_key_op() { return key_op; }
398 bool has_caps_op() { return caps_specified; }
399 bool has_suspension_op() { return suspension_op; }
400 bool has_subuser_perm() { return perm_specified; }
401 bool has_op_mask() { return op_mask_specified; }
402 bool will_gen_access() { return gen_access; }
403 bool will_gen_secret() { return gen_secret; }
404 bool will_gen_subuser() { return gen_subuser; }
405 bool will_purge_keys() { return purge_keys; }
406 bool will_purge_data() { return purge_data; }
407 bool will_generate_subuser() { return gen_subuser; }
408 bool has_bucket_quota() { return bucket_quota_specified; }
409 bool has_user_quota() { return user_quota_specified; }
410 void set_populated() { populated = true; }
411 void clear_populated() { populated = false; }
412 void set_initialized() { initialized = true; }
413 void set_existing_user(bool flag) { existing_user = flag; }
414 void set_existing_key(bool flag) { existing_key = flag; }
415 void set_existing_subuser(bool flag) { existing_subuser = flag; }
416 void set_existing_email(bool flag) { existing_email = flag; }
417 void set_purge_data(bool flag) { purge_data = flag; }
418 void set_generate_subuser(bool flag) { gen_subuser = flag; }
419 __u8 get_suspension_status() { return suspended; }
420 int32_t get_key_type() {return key_type; }
421 uint32_t get_subuser_perm() { return perm_mask; }
422 int32_t get_max_buckets() { return max_buckets; }
423 uint32_t get_op_mask() { return op_mask; }
424 RGWQuotaInfo& get_bucket_quota() { return bucket_quota; }
425 RGWQuotaInfo& get_user_quota() { return user_quota; }
426
427 rgw_user& get_user_id() { return user_id; }
428 std::string get_subuser() { return subuser; }
429 std::string get_access_key() { return id; }
430 std::string get_secret_key() { return key; }
431 std::string get_caps() { return caps; }
432 std::string get_user_email() { return user_email; }
433 std::string get_display_name() { return display_name; }
434 map<int, std::string>& get_temp_url_keys() { return temp_url_keys; }
435
436 RGWUserInfo& get_user_info() { return info; }
437
438 map<std::string, RGWAccessKey> *get_swift_keys() { return &info.swift_keys; }
439 map<std::string, RGWAccessKey> *get_access_keys() { return &info.access_keys; }
440 map<std::string, RGWSubUser> *get_subusers() { return &info.subusers; }
441
442 RGWUserCaps *get_caps_obj() { return &info.caps; }
443
444 std::string build_default_swift_kid() {
445 if (user_id.empty() || subuser.empty())
446 return "";
447
448 std::string kid;
449 user_id.to_str(kid);
450 kid.append(":");
451 kid.append(subuser);
452
453 return kid;
454 }
455
456 std::string generate_subuser() {
457 if (user_id.empty())
458 return "";
459
460 std::string generated_subuser;
461 user_id.to_str(generated_subuser);
462 std::string rand_suffix;
463
464 int sub_buf_size = RAND_SUBUSER_LEN + 1;
465 char sub_buf[RAND_SUBUSER_LEN + 1];
466
467 if (gen_rand_alphanumeric_upper(g_ceph_context, sub_buf, sub_buf_size) < 0)
468 return "";
469
470 rand_suffix = sub_buf;
471 if (rand_suffix.empty())
472 return "";
473
474 generated_subuser.append(rand_suffix);
475 subuser = generated_subuser;
476
477 return generated_subuser;
478 }
479
480 RGWUserAdminOpState() : user_id(RGW_USER_ANON_ID)
481 {
482 max_buckets = RGW_DEFAULT_MAX_BUCKETS;
483 key_type = -1;
484 perm_mask = RGW_PERM_NONE;
485 suspended = 0;
486 admin = 0;
487 system = 0;
488 exclusive = 0;
489 fetch_stats = 0;
490 op_mask = 0;
491
492 existing_user = false;
493 existing_key = false;
494 existing_subuser = false;
495 existing_email = false;
496 subuser_specified = false;
497 caps_specified = false;
498 purge_keys = false;
499 gen_secret = false;
500 gen_access = false;
501 gen_subuser = false;
502 id_specified = false;
503 key_specified = false;
504 type_specified = false;
505 key_type_setbycontext = false;
506 purge_data = false;
507 display_name_specified = false;
508 user_email_specified = false;
509 max_buckets_specified = false;
510 perm_specified = false;
511 op_mask_specified = false;
512 suspension_op = false;
513 system_specified = false;
514 key_op = false;
515 populated = false;
516 initialized = false;
517 key_params_checked = false;
518 subuser_params_checked = false;
519 user_params_checked = false;
520 bucket_quota_specified = false;
521 temp_url_key_specified = false;
522 user_quota_specified = false;
523 found_by_uid = false;
524 found_by_email = false;
525 found_by_key = false;
526 }
527};
528
529class RGWUser;
530
531class RGWAccessKeyPool
532{
533 RGWUser *user;
534
535 std::map<std::string, int, ltstr_nocase> key_type_map;
536 rgw_user user_id;
537 RGWRados *store;
538
539 map<std::string, RGWAccessKey> *swift_keys;
540 map<std::string, RGWAccessKey> *access_keys;
541
542 // we don't want to allow keys for the anonymous user or a null user
543 bool keys_allowed;
544
545private:
546 int create_key(RGWUserAdminOpState& op_state, std::string *err_msg = NULL);
547 int generate_key(RGWUserAdminOpState& op_state, std::string *err_msg = NULL);
548 int modify_key(RGWUserAdminOpState& op_state, std::string *err_msg = NULL);
549
550 int check_key_owner(RGWUserAdminOpState& op_state);
551 bool check_existing_key(RGWUserAdminOpState& op_state);
552 int check_op(RGWUserAdminOpState& op_state, std::string *err_msg = NULL);
553
554 /* API Contract Fulfilment */
555 int execute_add(RGWUserAdminOpState& op_state, std::string *err_msg, bool defer_save);
556 int execute_remove(RGWUserAdminOpState& op_state, std::string *err_msg, bool defer_save);
557 int remove_subuser_keys(RGWUserAdminOpState& op_state, std::string *err_msg, bool defer_save);
558
559 int add(RGWUserAdminOpState& op_state, std::string *err_msg, bool defer_save);
560 int remove(RGWUserAdminOpState& op_state, std::string *err_msg, bool defer_save);
561public:
562 explicit RGWAccessKeyPool(RGWUser* usr);
563 ~RGWAccessKeyPool();
564
565 int init(RGWUserAdminOpState& op_state);
566
567 /* API Contracted Methods */
568 int add(RGWUserAdminOpState& op_state, std::string *err_msg = NULL);
569 int remove(RGWUserAdminOpState& op_state, std::string *err_msg = NULL);
570
571 friend class RGWUser;
572 friend class RGWSubUserPool;
573};
574
575class RGWSubUserPool
576{
577 RGWUser *user;
578
579 rgw_user user_id;
580 RGWRados *store;
581 bool subusers_allowed;
582
583 map<string, RGWSubUser> *subuser_map;
584
585private:
586 int check_op(RGWUserAdminOpState& op_state, std::string *err_msg = NULL);
587
588 /* API Contract Fulfillment */
589 int execute_add(RGWUserAdminOpState& op_state, std::string *err_msg, bool defer_save);
590 int execute_remove(RGWUserAdminOpState& op_state, std::string *err_msg, bool defer_save);
591 int execute_modify(RGWUserAdminOpState& op_state, std::string *err_msg, bool defer_save);
592
593 int add(RGWUserAdminOpState& op_state, std::string *err_msg, bool defer_save);
594 int remove(RGWUserAdminOpState& op_state, std::string *err_msg, bool defer_save);
595 int modify(RGWUserAdminOpState& op_state, std::string *err_msg, bool defer_save);
596public:
597 explicit RGWSubUserPool(RGWUser *user);
598 ~RGWSubUserPool();
599
600 bool exists(std::string subuser);
601 int init(RGWUserAdminOpState& op_state);
602
603 /* API contracted methods */
604 int add(RGWUserAdminOpState& op_state, std::string *err_msg = NULL);
605 int remove(RGWUserAdminOpState& op_state, std::string *err_msg = NULL);
606 int modify(RGWUserAdminOpState& op_state, std::string *err_msg = NULL);
607
608 friend class RGWUser;
609};
610
611class RGWUserCapPool
612{
613 RGWUserCaps *caps;
614 bool caps_allowed;
615 RGWUser *user;
616
617private:
618 int add(RGWUserAdminOpState& op_state, std::string *err_msg, bool defer_save);
619 int remove(RGWUserAdminOpState& op_state, std::string *err_msg, bool defer_save);
620
621public:
622 explicit RGWUserCapPool(RGWUser *user);
623 ~RGWUserCapPool();
624
625 int init(RGWUserAdminOpState& op_state);
626
627 /* API contracted methods */
628 int add(RGWUserAdminOpState& op_state, std::string *err_msg = NULL);
629 int remove(RGWUserAdminOpState& op_state, std::string *err_msg = NULL);
630
631 friend class RGWUser;
632};
633
634class RGWUser
635{
636
637private:
638 RGWUserInfo old_info;
639 RGWRados *store;
640
641 rgw_user user_id;
642 bool info_stored;
643
644 void set_populated() { info_stored = true; }
645 void clear_populated() { info_stored = false; }
646 bool is_populated() { return info_stored; }
647
648 int check_op(RGWUserAdminOpState& req, std::string *err_msg);
649 int update(RGWUserAdminOpState& op_state, std::string *err_msg);
650
651 void clear_members();
652 void init_default();
653
654 /* API Contract Fulfillment */
655 int execute_add(RGWUserAdminOpState& op_state, std::string *err_msg);
656 int execute_remove(RGWUserAdminOpState& op_state, std::string *err_msg);
657 int execute_modify(RGWUserAdminOpState& op_state, std::string *err_msg);
658
659public:
660 RGWUser();
661 ~RGWUser();
662
663 int init(RGWRados *storage, RGWUserAdminOpState& op_state);
664
665 int init_storage(RGWRados *storage);
666 int init(RGWUserAdminOpState& op_state);
667 int init_members(RGWUserAdminOpState& op_state);
668
669 RGWRados *get_store() { return store; }
670
671 /* API Contracted Members */
672 RGWUserCapPool caps;
673 RGWAccessKeyPool keys;
674 RGWSubUserPool subusers;
675
676 /* API Contracted Methods */
677 int add(RGWUserAdminOpState& op_state, std::string *err_msg = NULL);
678 int remove(RGWUserAdminOpState& op_state, std::string *err_msg = NULL);
679
680 /* remove an already populated RGWUser */
681 int remove(std::string *err_msg = NULL);
682
683 int modify(RGWUserAdminOpState& op_state, std::string *err_msg = NULL);
684
685 /* retrieve info from an existing user in the RGW system */
686 int info(RGWUserAdminOpState& op_state, RGWUserInfo& fetched_info, std::string *err_msg = NULL);
687
688 /* info from an already populated RGWUser */
689 int info (RGWUserInfo& fetched_info, std::string *err_msg = NULL);
690
691 friend class RGWAccessKeyPool;
692 friend class RGWSubUserPool;
693 friend class RGWUserCapPool;
694};
695
696/* Wrapers for admin API functionality */
697
698class RGWUserAdminOp_User
699{
700public:
701 static int info(RGWRados *store,
702 RGWUserAdminOpState& op_state, RGWFormatterFlusher& flusher);
703
704 static int create(RGWRados *store,
705 RGWUserAdminOpState& op_state, RGWFormatterFlusher& flusher);
706
707 static int modify(RGWRados *store,
708 RGWUserAdminOpState& op_state, RGWFormatterFlusher& flusher);
709
710 static int remove(RGWRados *store,
711 RGWUserAdminOpState& op_state, RGWFormatterFlusher& flusher);
712};
713
714class RGWUserAdminOp_Subuser
715{
716public:
717 static int create(RGWRados *store,
718 RGWUserAdminOpState& op_state, RGWFormatterFlusher& flusher);
719
720 static int modify(RGWRados *store,
721 RGWUserAdminOpState& op_state, RGWFormatterFlusher& flusher);
722
723 static int remove(RGWRados *store,
724 RGWUserAdminOpState& op_state, RGWFormatterFlusher& flusher);
725};
726
727class RGWUserAdminOp_Key
728{
729public:
730 static int create(RGWRados *store,
731 RGWUserAdminOpState& op_state, RGWFormatterFlusher& flusher);
732
733 static int remove(RGWRados *store,
734 RGWUserAdminOpState& op_state, RGWFormatterFlusher& flusher);
735};
736
737class RGWUserAdminOp_Caps
738{
739public:
740 static int add(RGWRados *store,
741 RGWUserAdminOpState& op_state, RGWFormatterFlusher& flusher);
742
743 static int remove(RGWRados *store,
744 RGWUserAdminOpState& op_state, RGWFormatterFlusher& flusher);
745};
746
747class RGWMetadataManager;
748
749extern void rgw_user_init(RGWRados *store);
750
751#endif