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