Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / rgw / rgw_user.h
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
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  */
34 struct 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 };
48 WRITE_CLASS_ENCODER(RGWUID)
49
50 extern int rgw_user_sync_all_stats(RGWRados *store, const rgw_user& user_id);
51 extern int rgw_user_get_all_buckets_stats(RGWRados *store, const rgw_user& user_id, map<string, cls_user_bucket_entry>&buckets_usage_map);
52
53 /**
54  * Get the anonymous (ie, unauthenticated) user info.
55  */
56 extern 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  */
62 extern 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  */
74 extern 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  */
85 extern 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  */
91 extern 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  */
100 extern 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  */
110 extern 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  */
117 extern int rgw_delete_user(RGWRados *store, RGWUserInfo& user, RGWObjVersionTracker& objv_tracker);
118
119 /*
120  * remove the different indexes
121  */
122 extern int rgw_remove_key_index(RGWRados *store, RGWAccessKey& access_key);
123 extern int rgw_remove_uid_index(RGWRados *store, rgw_user& uid);
124 extern int rgw_remove_email_index(RGWRados *store, string& email);
125 extern int rgw_remove_swift_name_index(RGWRados *store, string& swift_name);
126
127 extern void rgw_perm_to_str(uint32_t mask, char *buf, int len);
128 extern uint32_t rgw_str_to_perm(const char *str);
129
130 extern int rgw_validate_tenant_name(const string& t);
131
132 enum ObjectKeyType {
133   KEY_TYPE_SWIFT,
134   KEY_TYPE_S3,
135   KEY_TYPE_UNDEFINED
136 };
137
138 enum RGWKeyPoolOp {
139   GENERATE_KEY,
140   MODIFY_KEY
141 };
142
143 enum RGWUserId {
144   RGW_USER_ID,
145   RGW_SWIFT_USERNAME,
146   RGW_USER_EMAIL,
147   RGW_ACCESS_KEY,
148 };
149
150 /*
151  * An RGWUser class along with supporting classes created
152  * to support the creation of an RESTful administrative API
153  */
154 struct 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;
166   __u8 sync_stats;
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;
203   bool admin_specified = false;
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) {
252    /* always lowercase email address */
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
338   void set_sync_stats(__u8 is_sync_stats) {
339     sync_stats = is_sync_stats;
340   }
341
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
529 class RGWUser;
530
531 class 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
545 private:
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);
561 public:
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
575 class 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
585 private:
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);
596 public:
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
611 class RGWUserCapPool
612 {
613   RGWUserCaps *caps;
614   bool caps_allowed;
615   RGWUser *user;
616
617 private:
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
621 public:
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
634 class RGWUser
635 {
636
637 private:
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
659 public:
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
698 class RGWUserAdminOp_User
699 {
700 public:
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
714 class RGWUserAdminOp_Subuser
715 {
716 public:
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
727 class RGWUserAdminOp_Key
728 {
729 public:
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
737 class RGWUserAdminOp_Caps
738 {
739 public:
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
747 class RGWMetadataManager;
748
749 extern void rgw_user_init(RGWRados *store);
750
751 #endif