#include "rgw_arn.h"
#include "rgw_data_sync.h"
+#include "global/global_init.h"
#include "common/ceph_crypto.h"
#include "common/armor.h"
#include "common/errno.h"
#include <sstream>
#define dout_context g_ceph_context
-#define dout_subsys ceph_subsys_rgw
+
+static constexpr auto dout_subsys = ceph_subsys_rgw;
using rgw::ARN;
using rgw::IAM::Effect;
{ ERR_SERVICE_UNAVAILABLE, {503, "ServiceUnavailable"}},
{ ERR_RATE_LIMITED, {503, "SlowDown"}},
{ ERR_ZERO_IN_URL, {400, "InvalidRequest" }},
- { ERR_NO_SUCH_TAG_SET, {404, "NoSuchTagSetError"}},
+ { ERR_NO_SUCH_TAG_SET, {404, "NoSuchTagSet"}},
{ ERR_NO_SUCH_BUCKET_ENCRYPTION_CONFIGURATION, {404, "ServerSideEncryptionConfigurationNotFoundError"}},
});
using namespace std;
using namespace ceph::crypto;
+thread_local bool is_asio_thread = false;
+
rgw_err::
rgw_err()
{
}
-req_state::req_state(CephContext* _cct, RGWEnv* e, uint64_t id)
- : cct(_cct), info(_cct, e), id(id)
+req_state::req_state(CephContext* _cct, const RGWProcessEnv& penv,
+ RGWEnv* e, uint64_t id)
+ : cct(_cct), penv(penv), info(_cct, e), id(id)
{
enable_ops_log = e->get_enable_ops_log();
enable_usage_log = e->get_enable_usage_log();
err.err_code = "UnknownError";
}
-void set_req_state_err(struct req_state* s, int err_no, const string& err_msg)
+void set_req_state_err(req_state* s, int err_no, const string& err_msg)
{
if (s) {
set_req_state_err(s, err_no);
}
}
-void set_req_state_err(struct req_state* s, int err_no)
+void set_req_state_err(req_state* s, int err_no)
{
if (s) {
set_req_state_err(s->err, err_no, s->prot_flags);
}
}
-void dump(struct req_state* s)
+void dump(req_state* s)
{
- if (s->format != RGW_FORMAT_HTML)
+ if (s->format != RGWFormat::HTML)
s->formatter->open_object_section("Error");
if (!s->err.err_code.empty())
s->formatter->dump_string("Code", s->err.err_code);
- if (!s->err.message.empty())
- s->formatter->dump_string("Message", s->err.message);
+ s->formatter->dump_string("Message", s->err.message);
if (!s->bucket_name.empty()) // TODO: connect to expose_bucket
s->formatter->dump_string("BucketName", s->bucket_name);
if (!s->trans_id.empty()) // TODO: connect to expose_bucket or another toggle
s->formatter->dump_string("RequestId", s->trans_id);
s->formatter->dump_string("HostId", s->host_id);
- if (s->format != RGW_FORMAT_HTML)
+ if (s->format != RGWFormat::HTML)
s->formatter->close_section();
}
}
};
-Effect eval_or_pass(const boost::optional<Policy>& policy,
+Effect eval_or_pass(const DoutPrefixProvider* dpp,
+ const boost::optional<Policy>& policy,
const rgw::IAM::Environment& env,
boost::optional<const rgw::auth::Identity&> id,
const uint64_t op,
}
-Effect eval_identity_or_session_policies(const vector<Policy>& policies,
+Effect eval_identity_or_session_policies(const DoutPrefixProvider* dpp,
+ const vector<Policy>& policies,
const rgw::IAM::Environment& env,
const uint64_t op,
const ARN& arn) {
auto policy_res = Effect::Pass, prev_res = Effect::Pass;
for (auto& policy : policies) {
- if (policy_res = eval_or_pass(policy, env, boost::none, op, arn); policy_res == Effect::Deny)
+ if (policy_res = eval_or_pass(dpp, policy, env, boost::none, op, arn); policy_res == Effect::Deny)
return policy_res;
else if (policy_res == Effect::Allow)
prev_res = Effect::Allow;
const vector<rgw::IAM::Policy>& user_policies,
const vector<rgw::IAM::Policy>& session_policies,
const rgw::ARN& res,
- const uint64_t op)
+ const uint64_t op,
+ bool mandatory_policy)
{
- auto identity_policy_res = eval_identity_or_session_policies(user_policies, s->env, op, res);
+ auto identity_policy_res = eval_identity_or_session_policies(dpp, user_policies, s->env, op, res);
if (identity_policy_res == Effect::Deny) {
return false;
}
if (! session_policies.empty()) {
- auto session_policy_res = eval_identity_or_session_policies(session_policies, s->env, op, res);
+ auto session_policy_res = eval_identity_or_session_policies(dpp, session_policies, s->env, op, res);
if (session_policy_res == Effect::Deny) {
return false;
}
return true;
}
- if (op == rgw::IAM::s3CreateBucket || op == rgw::IAM::s3ListAllMyBuckets) {
- auto perm = op_to_perm(op);
-
- return verify_user_permission_no_policy(dpp, s, user_acl, perm);
+ if (mandatory_policy) {
+ // no policies, and policy is mandatory
+ ldpp_dout(dpp, 20) << "no policies for a policy mandatory op " << op << dendl;
+ return false;
}
- return false;
+ auto perm = op_to_perm(op);
+
+ return verify_user_permission_no_policy(dpp, s, user_acl, perm);
}
bool verify_user_permission_no_policy(const DoutPrefixProvider* dpp,
}
bool verify_user_permission(const DoutPrefixProvider* dpp,
- struct req_state * const s,
+ req_state * const s,
const rgw::ARN& res,
- const uint64_t op)
+ const uint64_t op,
+ bool mandatory_policy)
{
perm_state_from_req_state ps(s);
- return verify_user_permission(dpp, &ps, s->user_acl.get(), s->iam_user_policies, s->session_policies, res, op);
+ return verify_user_permission(dpp, &ps, s->user_acl.get(), s->iam_user_policies, s->session_policies, res, op, mandatory_policy);
}
bool verify_user_permission_no_policy(const DoutPrefixProvider* dpp,
- struct req_state * const s,
+ req_state * const s,
const int perm)
{
perm_state_from_req_state ps(s);
if (!verify_requester_payer_permission(s))
return false;
- auto identity_policy_res = eval_identity_or_session_policies(identity_policies, s->env, op, ARN(bucket));
+ auto identity_policy_res = eval_identity_or_session_policies(dpp, identity_policies, s->env, op, ARN(bucket));
if (identity_policy_res == Effect::Deny)
return false;
rgw::IAM::PolicyPrincipal princ_type = rgw::IAM::PolicyPrincipal::Other;
- auto r = eval_or_pass(bucket_policy, s->env, *s->identity,
+ if (bucket_policy) {
+ ldpp_dout(dpp, 16) << __func__ << ": policy: " << bucket_policy.get()
+ << "resource: " << ARN(bucket) << dendl;
+ }
+ auto r = eval_or_pass(dpp, bucket_policy, s->env, *s->identity,
op, ARN(bucket), princ_type);
if (r == Effect::Deny)
return false;
//Take into account session policies, if the identity making a request is a role
if (!session_policies.empty()) {
- auto session_policy_res = eval_identity_or_session_policies(session_policies, s->env, op, ARN(bucket));
+ auto session_policy_res = eval_identity_or_session_policies(dpp, session_policies, s->env, op, ARN(bucket));
if (session_policy_res == Effect::Deny) {
return false;
}
}
bool verify_bucket_permission(const DoutPrefixProvider* dpp,
- struct req_state * const s,
+ req_state * const s,
const rgw_bucket& bucket,
RGWAccessControlPolicy * const user_acl,
RGWAccessControlPolicy * const bucket_acl,
return user_acl->verify_permission(dpp, *s->identity, perm, perm);
}
-bool verify_bucket_permission_no_policy(const DoutPrefixProvider* dpp, struct req_state * const s,
+bool verify_bucket_permission_no_policy(const DoutPrefixProvider* dpp, req_state * const s,
RGWAccessControlPolicy * const user_acl,
RGWAccessControlPolicy * const bucket_acl,
const int perm)
perm);
}
-bool verify_bucket_permission_no_policy(const DoutPrefixProvider* dpp, struct req_state * const s, const int perm)
+bool verify_bucket_permission_no_policy(const DoutPrefixProvider* dpp, req_state * const s, const int perm)
{
perm_state_from_req_state ps(s);
perm);
}
-bool verify_bucket_permission(const DoutPrefixProvider* dpp, struct req_state * const s, const uint64_t op)
+bool verify_bucket_permission(const DoutPrefixProvider* dpp, req_state * const s, const uint64_t op)
{
if (rgw::sal::Bucket::empty(s->bucket)) {
// request is missing a bucket name
// Authorize anyone permitted by the bucket policy, identity policies, session policies and the bucket owner
// unless explicitly denied by the policy.
-int verify_bucket_owner_or_policy(struct req_state* const s,
+int verify_bucket_owner_or_policy(req_state* const s,
const uint64_t op)
{
- auto identity_policy_res = eval_identity_or_session_policies(s->iam_user_policies, s->env, op, ARN(s->bucket->get_key()));
+ auto identity_policy_res = eval_identity_or_session_policies(s, s->iam_user_policies, s->env, op, ARN(s->bucket->get_key()));
if (identity_policy_res == Effect::Deny) {
return -EACCES;
}
rgw::IAM::PolicyPrincipal princ_type = rgw::IAM::PolicyPrincipal::Other;
- auto e = eval_or_pass(s->iam_policy,
+ auto e = eval_or_pass(s, s->iam_policy,
s->env, *s->auth.identity,
op, ARN(s->bucket->get_key()), princ_type);
if (e == Effect::Deny) {
}
if (!s->session_policies.empty()) {
- auto session_policy_res = eval_identity_or_session_policies(s->session_policies, s->env, op, ARN(s->bucket->get_key()));
+ auto session_policy_res = eval_identity_or_session_policies(s, s->session_policies, s->env, op,
+ ARN(s->bucket->get_key()));
if (session_policy_res == Effect::Deny) {
return -EACCES;
}
if (!verify_requester_payer_permission(s))
return false;
- auto identity_policy_res = eval_identity_or_session_policies(identity_policies, s->env, op, ARN(obj));
+ auto identity_policy_res = eval_identity_or_session_policies(dpp, identity_policies, s->env, op, ARN(obj));
if (identity_policy_res == Effect::Deny)
return false;
rgw::IAM::PolicyPrincipal princ_type = rgw::IAM::PolicyPrincipal::Other;
- auto r = eval_or_pass(bucket_policy, s->env, *s->identity, op, ARN(obj), princ_type);
+ auto r = eval_or_pass(dpp, bucket_policy, s->env, *s->identity, op, ARN(obj), princ_type);
if (r == Effect::Deny)
return false;
if (!session_policies.empty()) {
- auto session_policy_res = eval_identity_or_session_policies(session_policies, s->env, op, ARN(obj));
+ auto session_policy_res = eval_identity_or_session_policies(dpp, session_policies, s->env, op, ARN(obj));
if (session_policy_res == Effect::Deny) {
return false;
}
return user_acl->verify_permission(dpp, *s->identity, swift_perm, swift_perm);
}
-bool verify_object_permission(const DoutPrefixProvider* dpp, struct req_state * const s,
+bool verify_object_permission(const DoutPrefixProvider* dpp, req_state * const s,
const rgw_obj& obj,
RGWAccessControlPolicy * const user_acl,
RGWAccessControlPolicy * const bucket_acl,
return user_acl->verify_permission(dpp, *s->identity, swift_perm, swift_perm);
}
-bool verify_object_permission_no_policy(const DoutPrefixProvider* dpp, struct req_state *s, int perm)
+bool verify_object_permission_no_policy(const DoutPrefixProvider* dpp, req_state *s, int perm)
{
perm_state_from_req_state ps(s);
perm);
}
-bool verify_object_permission(const DoutPrefixProvider* dpp, struct req_state *s, uint64_t op)
+bool verify_object_permission(const DoutPrefixProvider* dpp, req_state *s, uint64_t op)
{
perm_state_from_req_state ps(s);
{"write", RGW_CAP_WRITE},
{NULL, 0} };
+static int rgw_parse_list_of_flags(struct rgw_name_to_flag *mapping,
+ const string& str, uint32_t *perm)
+{
+ list<string> strs;
+ get_str_list(str, strs);
+ list<string>::iterator iter;
+ uint32_t v = 0;
+ for (iter = strs.begin(); iter != strs.end(); ++iter) {
+ string& s = *iter;
+ for (int i = 0; mapping[i].type_name; i++) {
+ if (s.compare(mapping[i].type_name) == 0)
+ v |= mapping[i].flag;
+ }
+ }
+
+ *perm = v;
+ return 0;
+}
+
int RGWUserCaps::parse_cap_perm(const string& str, uint32_t *perm)
{
return rgw_parse_list_of_flags(cap_names, str, perm);
decode(swift_versioning, bl);
if (swift_versioning) {
decode(swift_ver_location, bl);
- }
+ }
}
if (struct_v >= 17) {
decode(creation_time, bl);
if (layout.logs.empty() &&
layout.current_index.layout.type == rgw::BucketIndexType::Normal) {
- layout.logs.push_back(rgw::log_layout_from_index(0, layout.current_index.layout.normal));
+ layout.logs.push_back(rgw::log_layout_from_index(0, layout.current_index));
}
DECODE_FINISH(bl);
}
l.current_index.layout.normal.num_shards = 11;
l.logs.push_back(log_layout_from_index(
l.current_index.gen,
- l.current_index.layout.normal));
+ l.current_index));
};
encode_json("default_placement", default_placement.name, f);
encode_json("default_storage_class", default_placement.storage_class, f);
encode_json("placement_tags", placement_tags, f);
- encode_json("bucket_quota", bucket_quota, f);
- encode_json("user_quota", user_quota, f);
+ encode_json("bucket_quota", quota.bucket_quota, f);
+ encode_json("user_quota", quota.user_quota, f);
encode_json("temp_url_keys", temp_url_keys, f);
string user_source_type;
JSONDecoder::decode_json("default_placement", default_placement.name, obj);
JSONDecoder::decode_json("default_storage_class", default_placement.storage_class, obj);
JSONDecoder::decode_json("placement_tags", placement_tags, obj);
- JSONDecoder::decode_json("bucket_quota", bucket_quota, obj);
- JSONDecoder::decode_json("user_quota", user_quota, obj);
+ JSONDecoder::decode_json("bucket_quota", quota.bucket_quota, obj);
+ JSONDecoder::decode_json("user_quota", quota.user_quota, obj);
JSONDecoder::decode_json("temp_url_keys", temp_url_keys, obj);
string user_source_type;
encode_json("key", key, f);
}
+int rgw_bucket_parse_bucket_instance(const string& bucket_instance, string *bucket_name, string *bucket_id, int *shard_id)
+{
+ auto pos = bucket_instance.rfind(':');
+ if (pos == string::npos) {
+ return -EINVAL;
+ }
+
+ string first = bucket_instance.substr(0, pos);
+ string second = bucket_instance.substr(pos + 1);
+
+ pos = first.find(':');
+
+ if (pos == string::npos) {
+ *shard_id = -1;
+ *bucket_name = first;
+ *bucket_id = second;
+ return 0;
+ }
+
+ *bucket_name = first.substr(0, pos);
+ *bucket_id = first.substr(pos + 1);
+
+ string err;
+ *shard_id = strict_strtol(second.c_str(), 10, &err);
+ if (!err.empty()) {
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+boost::intrusive_ptr<CephContext>
+rgw_global_init(const std::map<std::string,std::string> *defaults,
+ std::vector < const char* >& args,
+ uint32_t module_type, code_environment_t code_env,
+ int flags)
+{
+ // Load the config from the files, but not the mon
+ global_pre_init(defaults, args, module_type, code_env, flags);
+
+ // Get the store backend
+ const auto& config_store = g_conf().get_val<std::string>("rgw_backend_store");
+
+ if ((config_store == "dbstore") ||
+ (config_store == "motr") ||
+ (config_store == "daos")) {
+ // These stores don't use the mon
+ flags |= CINIT_FLAG_NO_MON_CONFIG;
+ }
+
+ // Finish global init, indicating we already ran pre-init
+ return global_init(defaults, args, module_type, code_env, flags, false);
+}
+
+void RGWObjVersionTracker::generate_new_write_ver(CephContext *cct)
+{
+ write_version.ver = 1;
+#define TAG_LEN 24
+
+ write_version.tag.clear();
+ append_rand_alpha(cct, write_version.tag, write_version.tag, TAG_LEN);
+}