#include "rgw_cr_tools.h"
+#include "rgw_bucket.h"
#include "rgw_user.h"
+#include "rgw_op.h"
+#include "rgw_acl_s3.h"
+
+#define dout_context g_ceph_context
+#define dout_subsys ceph_subsys_rgw
template<>
int RGWUserCreateCR::Request::_send_request()
return RGWUserAdminOp_User::create(store, op_state, flusher);
}
+template<>
+int RGWGetUserInfoCR::Request::_send_request()
+{
+ rgw_user user(params.tenant, params.uid);
+ return rgw_get_user_info_by_uid(store, user, result->user_info);
+}
+
+template<>
+int RGWBucketCreateLocalCR::Request::_send_request()
+{
+ CephContext *cct = store->ctx();
+
+ const auto& user_info = params.user_info.get();
+ const auto& user = user_info->user_id;
+ const auto& bucket_name = params.bucket_name;
+ auto& placement_rule = params.placement_rule;
+
+ const auto& zonegroup = store->get_zonegroup();
+
+ if (!placement_rule.empty() &&
+ !zonegroup.placement_targets.count(placement_rule)) {
+ ldout(cct, 0) << "placement target (" << placement_rule << ")"
+ << " doesn't exist in the placement targets of zonegroup"
+ << " (" << store->get_zonegroup().api_name << ")" << dendl;
+ return -ERR_INVALID_LOCATION_CONSTRAINT;
+ }
+
+ /* we need to make sure we read bucket info, it's not read before for this
+ * specific request */
+ RGWObjectCtx obj_ctx(store);
+ RGWBucketInfo bucket_info;
+ map<string, bufferlist> bucket_attrs;
+
+ int ret = store->get_bucket_info(obj_ctx, user.tenant, bucket_name,
+ bucket_info, nullptr, &bucket_attrs);
+ if (ret < 0 && ret != -ENOENT)
+ return ret;
+ bool bucket_exists = (ret != -ENOENT);
+
+ RGWAccessControlPolicy old_policy(cct);
+ ACLOwner bucket_owner;
+ bucket_owner.set_id(user);
+ bucket_owner.set_name(user_info->display_name);
+ if (bucket_exists) {
+ ret = rgw_op_get_bucket_policy_from_attr(cct, store, bucket_info,
+ bucket_attrs, &old_policy);
+ if (ret >= 0) {
+ if (old_policy.get_owner().get_id().compare(user) != 0) {
+ return -EEXIST;
+ }
+ }
+ }
+
+ RGWBucketInfo master_info;
+ rgw_bucket *pmaster_bucket = nullptr;
+ uint32_t *pmaster_num_shards = nullptr;
+ real_time creation_time;
+
+ string zonegroup_id = store->get_zonegroup().get_id();
+
+ if (bucket_exists) {
+ string selected_placement_rule;
+ rgw_bucket bucket;
+ bucket.tenant = user.tenant;
+ bucket.name = bucket_name;
+ ret = store->select_bucket_placement(*user_info, zonegroup_id,
+ placement_rule,
+ &selected_placement_rule, nullptr);
+ if (selected_placement_rule != bucket_info.placement_rule) {
+ ldout(cct, 0) << "bucket already exists on a different placement rule: "
+ << " selected_rule= " << selected_placement_rule
+ << " existing_rule= " << bucket_info.placement_rule << dendl;
+ return -EEXIST;
+ }
+ }
+
+ /* Encode special metadata first as we're using std::map::emplace under
+ * the hood. This method will add the new items only if the map doesn't
+ * contain such keys yet. */
+ RGWAccessControlPolicy_S3 policy(cct);
+ policy.create_canned(bucket_owner, bucket_owner, string()); /* default private policy */
+ bufferlist aclbl;
+ policy.encode(aclbl);
+ map<string, buffer::list> attrs;
+ attrs.emplace(std::move(RGW_ATTR_ACL), std::move(aclbl));
+
+ RGWQuotaInfo quota_info;
+ const RGWQuotaInfo * pquota_info = nullptr;
+
+ rgw_bucket bucket;
+ bucket.tenant = user.tenant;
+ bucket.name = bucket_name;
+
+ RGWBucketInfo info;
+ obj_version ep_objv;
+
+ ret = store->create_bucket(*user_info, bucket, zonegroup_id,
+ placement_rule, bucket_info.swift_ver_location,
+ pquota_info, attrs,
+ info, nullptr, &ep_objv, creation_time,
+ pmaster_bucket, pmaster_num_shards, true);
+
+
+ if (ret && ret != -EEXIST)
+ return ret;
+
+ bool existed = (ret == -EEXIST);
+
+ if (existed) {
+ if (info.owner != user) {
+ ldout(cct, 20) << "NOTICE: bucket already exists under a different user (bucket=" << bucket << " user=" << user << " bucket_owner=" << info.owner << dendl;
+ return -EEXIST;
+ }
+ bucket = info.bucket;
+ }
+
+ ret = rgw_link_bucket(store, user, bucket,
+ info.creation_time, false);
+ if (ret && !existed && ret != -EEXIST) {
+ /* if it exists (or previously existed), don't remove it! */
+ int r = rgw_unlink_bucket(store, user, bucket.tenant, bucket.name);
+ if (r < 0) {
+ ldout(cct, 0) << "WARNING: failed to unlink bucket: ret=" << r << dendl;
+ }
+ } else if (ret == -EEXIST || (ret == 0 && existed)) {
+ ret = -ERR_BUCKET_EXISTS;
+ }
+
+ if (ret < 0) {
+ ldout(cct, 0) << "ERROR: bucket creation (bucket=" << bucket << ") return ret=" << ret << dendl;
+ }
+
+ return ret;
+}
* object: name of the object to get the ACL for.
* Returns: 0 on success, -ERR# otherwise.
*/
-static int get_bucket_policy_from_attr(CephContext *cct,
- RGWRados *store,
- RGWBucketInfo& bucket_info,
- map<string, bufferlist>& bucket_attrs,
- RGWAccessControlPolicy *policy)
+int rgw_op_get_bucket_policy_from_attr(CephContext *cct,
+ RGWRados *store,
+ RGWBucketInfo& bucket_info,
+ map<string, bufferlist>& bucket_attrs,
+ RGWAccessControlPolicy *policy)
{
return get_bucket_instance_policy_from_attr(cct, store, bucket_info, bucket_attrs, policy);
}
return 0;
}
- int ret = get_bucket_policy_from_attr(s->cct, store, bucket_info, bucket_attrs, policy);
+ int ret = rgw_op_get_bucket_policy_from_attr(s->cct, store, bucket_info, bucket_attrs, policy);
if (ret == -ENOENT) {
ret = -ERR_NO_SUCH_BUCKET;
}
/* object does not exist checking the bucket's ACL to make sure
that we send a proper error code */
RGWAccessControlPolicy bucket_policy(s->cct);
- ret = get_bucket_policy_from_attr(s->cct, store, bucket_info, bucket_attrs, &bucket_policy);
+ ret = rgw_op_get_bucket_policy_from_attr(s->cct, store, bucket_info, bucket_attrs, &bucket_policy);
if (ret < 0) {
return ret;
}
s->bucket_owner.set_id(s->user->user_id);
s->bucket_owner.set_name(s->user->display_name);
if (s->bucket_exists) {
- int r = get_bucket_policy_from_attr(s->cct, store, s->bucket_info,
- s->bucket_attrs, &old_policy);
+ int r = rgw_op_get_bucket_policy_from_attr(s->cct, store, s->bucket_info,
+ s->bucket_attrs, &old_policy);
if (r >= 0) {
if (old_policy.get_owner().get_id().compare(s->user->user_id) != 0) {
op_ret = -EEXIST;
if (bucket_exists) {
RGWAccessControlPolicy old_policy(s->cct);
- int r = get_bucket_policy_from_attr(s->cct, store, binfo,
- battrs, &old_policy);
+ int r = rgw_op_get_bucket_policy_from_attr(s->cct, store, binfo,
+ battrs, &old_policy);
if (r >= 0) {
if (old_policy.get_owner().get_id().compare(s->user->user_id) != 0) {
op_ret = -EEXIST;