}
try {
const rgw::IAM::Policy p(
- g_ceph_context, tenant, assume_role_doc,
+ g_ceph_context, nullptr, assume_role_doc,
g_ceph_context->_conf.get_val<bool>(
"rgw_policy_reject_invalid_principals"));
} catch (rgw::IAM::PolicyParseException& e) {
}
try {
- const rgw::IAM::Policy p(g_ceph_context, tenant, assume_role_doc,
+ const rgw::IAM::Policy p(g_ceph_context, nullptr, assume_role_doc,
g_ceph_context->_conf.get_val<bool>(
"rgw_policy_reject_invalid_principals"));
} catch (rgw::IAM::PolicyParseException& e) {
perm_policy_doc = bl.to_str();
}
try {
- const rgw::IAM::Policy p(g_ceph_context, tenant, perm_policy_doc,
+ const rgw::IAM::Policy p(g_ceph_context, nullptr, perm_policy_doc,
g_ceph_context->_conf.get_val<bool>(
"rgw_policy_reject_invalid_principals"));
} catch (rgw::IAM::PolicyParseException& e) {
void rgw::auth::RoleApplier::modify_request_state(const DoutPrefixProvider *dpp, req_state* s) const
{
+ // non-account identity policy is restricted to the current tenant
+ const std::string* policy_tenant = role.account_id.empty() ? &role.tenant : nullptr;
+
for (const auto& policy : role.inline_policies) {
try {
- const rgw::IAM::Policy p(s->cct, role.tenant, policy, false);
+ const rgw::IAM::Policy p(s->cct, policy_tenant, policy, false);
s->iam_identity_policies.push_back(std::move(p));
} catch (rgw::IAM::PolicyParseException& e) {
//Control shouldn't reach here as the policy has already been
if (!this->token_attrs.token_policy.empty()) {
try {
string policy = this->token_attrs.token_policy;
- const rgw::IAM::Policy p(s->cct, role.tenant, policy, false);
+ const rgw::IAM::Policy p(s->cct, policy_tenant, policy, false);
s->session_policies.push_back(std::move(p));
} catch (rgw::IAM::PolicyParseException& e) {
//Control shouldn't reach here as the policy has already been
auto get_managed_policy(CephContext* cct, std::string_view arn)
-> std::optional<Policy>
{
- const std::string tenant; // empty tenant
+ const std::string* tenant = nullptr;
constexpr bool reject = false; // reject_invalid_principals
if (arn == "arn:aws:iam::aws:policy/IAMFullAccess") {
return Policy{cct, tenant, std::string{IAMFullAccess}, reject};
keyword_hash tokens;
std::vector<ParseState> s;
CephContext* cct;
- const string& tenant;
+ const string* tenant = nullptr;
Policy& policy;
uint32_t v = 0;
v = 0;
}
- PolicyParser(CephContext* cct, const string& tenant, Policy& policy,
+ PolicyParser(CephContext* cct, const string* tenant, Policy& policy,
bool reject_invalid_principals)
: cct(cct), tenant(tenant), policy(policy),
reject_invalid_principals(reject_invalid_principals) {}
return false;
}
// You can't specify resources for someone ELSE'S account.
- if (a->account.empty() || a->account == pp->tenant ||
- a->account == "*") {
- if (a->account.empty() || a->account == "*")
- a->account = pp->tenant;
+ if (a->account.empty() || pp->tenant == nullptr ||
+ a->account == *pp->tenant || a->account == "*") {
+ if (pp->tenant && (a->account.empty() || a->account == "*"))
+ a->account = *pp->tenant;
(w->id == TokenID::Resource ? t->resource : t->notresource)
.emplace(std::move(*a));
} else {
annotate(fmt::format("Policy owned by tenant `{}` cannot grant access to "
"resource owned by tenant `{}`.",
- pp->tenant, a->account));
+ *pp->tenant, a->account));
return false;
}
} else if (w->kind == TokenKind::cond_key) {
return m << " }";
}
-Policy::Policy(CephContext* cct, const string& tenant,
+Policy::Policy(CephContext* cct, const string* tenant,
std::string _text,
bool reject_invalid_principals)
: text(std::move(_text)) {
// when executing operations that *set* a bucket policy, but should
// be false when reading a stored bucket policy so as not to break
// backwards configuration.
- Policy(CephContext* cct, const std::string& tenant,
+ Policy(CephContext* cct, const std::string* tenant,
std::string text,
bool reject_invalid_principals);
static boost::optional<Policy>
get_iam_policy_from_attr(CephContext* cct,
- const map<string, bufferlist>& attrs,
- const string& tenant)
+ const map<string, bufferlist>& attrs)
{
if (auto i = attrs.find(RGW_ATTR_IAM_POLICY); i != attrs.end()) {
- return Policy(cct, tenant, i->second.to_str(), false);
+ // resource policy is not restricted to the current tenant
+ const std::string* policy_tenant = nullptr;
+
+ return Policy(cct, policy_tenant, i->second.to_str(), false);
} else {
return none;
}
}
static void load_inline_policy(CephContext* cct, const bufferlist& bl,
- const string& tenant,
+ const string* tenant,
std::vector<rgw::IAM::Policy>& policies)
{
map<string, string> policy_map;
}
static void load_managed_policy(CephContext* cct, const bufferlist& bl,
- const string& tenant,
std::vector<rgw::IAM::Policy>& policies)
{
rgw::IAM::ManagedPolicies policy_set;
static void load_iam_group_policies(const DoutPrefixProvider* dpp,
optional_yield y,
rgw::sal::Driver* driver,
- const std::string& tenant,
+ const std::string* tenant,
std::string_view group_id,
std::vector<rgw::IAM::Policy>& policies)
{
load_inline_policy(cct, bl->second, tenant, policies);
}
if (auto bl = attrs.find(RGW_ATTR_MANAGED_POLICY); bl != attrs.end()) {
- load_managed_policy(cct, bl->second, tenant, policies);
+ load_managed_policy(cct, bl->second, policies);
}
}
}
const rgw::sal::Attrs& attrs,
std::vector<rgw::IAM::Policy>& policies)
{
+ // non-account identity policy is restricted to the current tenant
+ const std::string* policy_tenant = info.account_id.empty()
+ ? &info.user_id.tenant : nullptr;
+
// load user policies from user attrs
CephContext* cct = dpp->get_cct();
if (auto bl = attrs.find(RGW_ATTR_USER_POLICY); bl != attrs.end()) {
- load_inline_policy(cct, bl->second, info.user_id.tenant, policies);
+ load_inline_policy(cct, bl->second, policy_tenant, policies);
}
if (auto bl = attrs.find(RGW_ATTR_MANAGED_POLICY); bl != attrs.end()) {
- load_managed_policy(cct, bl->second, info.user_id.tenant, policies);
+ load_managed_policy(cct, bl->second, policies);
}
// load each group and its policies
for (const auto& id : info.group_ids) {
- load_iam_group_policies(dpp, y, driver, info.user_id.tenant, id, policies);
+ load_iam_group_policies(dpp, y, driver, policy_tenant, id, policies);
}
}
mpobj->set_in_extra_data(true);
object = mpobj.get();
}
- policy = get_iam_policy_from_attr(s->cct, bucket_attrs, bucket->get_tenant());
+ policy = get_iam_policy_from_attr(s->cct, bucket_attrs);
int ret = get_obj_policy_from_attr(dpp, s->cct, driver, s->bucket_owner,
acl, storage_class, object, s->yield);
}
try {
- s->iam_policy = get_iam_policy_from_attr(s->cct, s->bucket_attrs, s->bucket_tenant);
+ s->iam_policy = get_iam_policy_from_attr(s->cct, s->bucket_attrs);
} catch (const std::exception& e) {
ldpp_dout(dpp, 0) << "Error reading IAM Policy: " << e.what() << dendl;
ldpp_dout(this, 0) << "failed to read bucket policy" << dendl;
return r;
}
- _bucket_policy = get_iam_policy_from_attr(s->cct, bucket_attrs, auth_tenant);
+ _bucket_policy = get_iam_policy_from_attr(s->cct, bucket_attrs);
bucket_policy = &_bucket_policy;
pbucket = ubucket.get();
} else {
return r;
}
auto _bucket_policy = get_iam_policy_from_attr(
- s->cct, tmp_bucket->get_attrs(), auth_tenant);
+ s->cct, tmp_bucket->get_attrs());
bucket_policy = _bucket_policy.get_ptr();
buckets[bucket_name].swap(tmp_bucket);
policies[bucket_name] = make_pair(bucket_acl, _bucket_policy);
if (op_ret < 0) {
return op_ret;
}
- auto dest_iam_policy = get_iam_policy_from_attr(s->cct, s->bucket->get_attrs(), s->bucket->get_tenant());
+ auto dest_iam_policy = get_iam_policy_from_attr(s->cct, s->bucket->get_attrs());
/* admin request overrides permission checks */
if (! s->auth.identity->is_admin_of(dest_policy.get_owner().id)){
if (dest_iam_policy != boost::none || ! s->iam_identity_policies.empty() || !s->session_policies.empty()) {
return false;
}
- auto policy = get_iam_policy_from_attr(s->cct, battrs, binfo.bucket.tenant);
+ auto policy = get_iam_policy_from_attr(s->cct, battrs);
bucket_owner = bacl.get_owner();
return false;
}
- auto policy = get_iam_policy_from_attr(s->cct, battrs, binfo.bucket.tenant);
+ auto policy = get_iam_policy_from_attr(s->cct, battrs);
bucket_owner = bacl.get_owner();
if (policy || ! s->iam_identity_policies.empty() || !s->session_policies.empty()) {
try {
const Policy p(
- s->cct, s->bucket_tenant, data.to_str(),
+ s->cct, nullptr, data.to_str(),
s->cct->_conf.get_val<bool>("rgw_policy_reject_invalid_principals"));
rgw::sal::Attrs attrs(s->bucket_attrs);
if (s->bucket_access_conf &&
#include <exception>
#include <fstream>
#include <iostream>
+#include <optional>
#include <string>
#include <string_view>
#include "rgw/rgw_iam_policy.h"
// Returns true on success
-bool parse(CephContext* cct, const std::string& tenant,
+bool parse(CephContext* cct, const std::string* tenant,
const std::string& fname, std::istream& in) noexcept
{
bufferlist bl;
int main(int argc, const char** argv)
{
std::string_view cmdname = argv[0];
- std::string tenant;
+ std::optional<std::string> tenant;
auto args = argv_to_vec(argc, argv);
if (ceph_argparse_need_usage(args)) {
}
bool success = true;
+ const std::string* t = tenant ? &*tenant : nullptr;
if (args.empty()) {
- success = parse(cct.get(), tenant, "(stdin)", std::cin);
+ success = parse(cct.get(), t, "(stdin)", std::cin);
} else {
for (const auto& file : args) {
std::ifstream in;
std::cerr << "Can't read " << file << std::endl;
success = false;
}
- if (!parse(cct.get(), tenant, file, in)) {
+ if (!parse(cct.get(), t, file, in)) {
success = false;
}
}
try {
// validate the document
const rgw::IAM::Policy p(
- s->cct, s->user->get_tenant(), policy_document,
+ s->cct, nullptr, policy_document,
s->cct->_conf.get_val<bool>("rgw_policy_reject_invalid_principals"));
} catch (rgw::IAM::PolicyParseException& e) {
s->err.message = std::move(e.msg);
const std::string& policy_text) {
try {
return rgw::IAM::Policy(
- s->cct, s->auth.identity->get_tenant(), policy_text,
+ s->cct, nullptr, policy_text,
s->cct->_conf.get_val<bool>("rgw_policy_reject_invalid_principals"));
} catch (rgw::IAM::PolicyParseException& e) {
ldout(s->cct, 1) << "failed to parse policy: '" << policy_text
}
try {
const rgw::IAM::Policy p(
- s->cct, s->user->get_tenant(), trust_policy,
+ s->cct, nullptr, trust_policy,
s->cct->_conf.get_val<bool>("rgw_policy_reject_invalid_principals"));
}
catch (rgw::IAM::PolicyParseException& e) {
s->err.message = "Missing required element PolicyDocument";
return -EINVAL;
}
+
+ int r = load_role(this, y, driver, s->owner.id, account_id,
+ s->user->get_tenant(), role_name, role, resource,
+ s->err.message);
+ if (r < 0) {
+ return r;
+ }
+
try {
+ // non-account identity policy is restricted to the current tenant
+ const rgw::sal::RGWRoleInfo& info = role->get_info();
+ const std::string* policy_tenant = account_id.empty() ? &info.tenant : nullptr;
const rgw::IAM::Policy p(
- s->cct, s->user->get_tenant(), perm_policy,
+ s->cct, policy_tenant, perm_policy,
s->cct->_conf.get_val<bool>("rgw_policy_reject_invalid_principals"));
}
catch (rgw::IAM::PolicyParseException& e) {
s->err.message = e.what();
return -ERR_MALFORMED_DOC;
}
-
- return load_role(this, y, driver, s->owner.id, account_id,
- s->user->get_tenant(), role_name, role, resource,
- s->err.message);
+ return 0;
}
void RGWPutRolePolicy::execute(optional_yield y)
//Parse the policy
//TODO - This step should be part of Role Creation
try {
- const rgw::IAM::Policy p(s->cct, s->user->get_tenant(), policy, false);
+ // resource policy is not restricted to the current tenant
+ const std::string* policy_tenant = nullptr;
+
+ const rgw::IAM::Policy p(s->cct, policy_tenant, policy, false);
if (!s->principal_tags.empty()) {
auto res = p.eval(s->env, *s->auth.identity, rgw::IAM::stsTagSession, boost::none);
if (res != rgw::IAM::Effect::Allow) {
if (! policy.empty()) {
try {
const rgw::IAM::Policy p(
- s->cct, s->user->get_tenant(), policy,
+ s->cct, nullptr, policy,
s->cct->_conf.get_val<bool>("rgw_policy_reject_invalid_principals"));
}
catch (rgw::IAM::PolicyParseException& e) {
if (! policy.empty()) {
try {
const rgw::IAM::Policy p(
- s->cct, s->user->get_tenant(), policy,
+ s->cct, nullptr, policy,
s->cct->_conf.get_val<bool>("rgw_policy_reject_invalid_principals"));
}
catch (rgw::IAM::PolicyParseException& e) {
{
// validate the policy document
try {
+ // non-account identity policy is restricted to the current tenant
+ const std::string* policy_tenant = account_id.empty() ?
+ &s->user->get_tenant() : nullptr;
+
const rgw::IAM::Policy p(
- s->cct, s->user->get_tenant(), policy,
+ s->cct, policy_tenant, policy,
s->cct->_conf.get_val<bool>("rgw_policy_reject_invalid_principals"));
} catch (const rgw::IAM::PolicyParseException& e) {
ldpp_dout(this, 5) << "failed to parse policy: " << e.what() << dendl;
TEST_F(PolicyTest, Parse1) {
boost::optional<Policy> p;
- ASSERT_NO_THROW(p = Policy(cct.get(), arbitrary_tenant, example1, true));
+ ASSERT_NO_THROW(p = Policy(cct.get(), &arbitrary_tenant, example1, true));
ASSERT_TRUE(p);
EXPECT_EQ(p->text, example1);
}
TEST_F(PolicyTest, Eval1) {
- auto p = Policy(cct.get(), arbitrary_tenant, example1, true);
+ auto p = Policy(cct.get(), &arbitrary_tenant, example1, true);
Environment e;
ARN arn1(Partition::aws, Service::s3,
TEST_F(PolicyTest, Parse2) {
boost::optional<Policy> p;
- ASSERT_NO_THROW(p = Policy(cct.get(), arbitrary_tenant, example2, true));
+ ASSERT_NO_THROW(p = Policy(cct.get(), &arbitrary_tenant, example2, true));
ASSERT_TRUE(p);
EXPECT_EQ(p->text, example2);
}
TEST_F(PolicyTest, Eval2) {
- auto p = Policy(cct.get(), arbitrary_tenant, example2, true);
+ auto p = Policy(cct.get(), &arbitrary_tenant, example2, true);
Environment e;
auto trueacct = FakeIdentity(
TEST_F(PolicyTest, Parse3) {
boost::optional<Policy> p;
- ASSERT_NO_THROW(p = Policy(cct.get(), arbitrary_tenant, example3, true));
+ ASSERT_NO_THROW(p = Policy(cct.get(), &arbitrary_tenant, example3, true));
ASSERT_TRUE(p);
EXPECT_EQ(p->text, example3);
}
TEST_F(PolicyTest, Eval3) {
- auto p = Policy(cct.get(), arbitrary_tenant, example3, true);
+ auto p = Policy(cct.get(), &arbitrary_tenant, example3, true);
Environment em;
Environment tr = { { "aws:MultiFactorAuthPresent", "true" } };
Environment fa = { { "aws:MultiFactorAuthPresent", "false" } };
TEST_F(PolicyTest, Parse4) {
boost::optional<Policy> p;
- ASSERT_NO_THROW(p = Policy(cct.get(), arbitrary_tenant, example4, true));
+ ASSERT_NO_THROW(p = Policy(cct.get(), &arbitrary_tenant, example4, true));
ASSERT_TRUE(p);
EXPECT_EQ(p->text, example4);
}
TEST_F(PolicyTest, Eval4) {
- auto p = Policy(cct.get(), arbitrary_tenant, example4, true);
+ auto p = Policy(cct.get(), &arbitrary_tenant, example4, true);
Environment e;
ARN arn1(Partition::aws, Service::iam,
TEST_F(PolicyTest, Parse5) {
boost::optional<Policy> p;
- ASSERT_NO_THROW(p = Policy(cct.get(), arbitrary_tenant, example5, true));
+ ASSERT_NO_THROW(p = Policy(cct.get(), &arbitrary_tenant, example5, true));
ASSERT_TRUE(p);
EXPECT_EQ(p->text, example5);
EXPECT_EQ(p->version, Version::v2012_10_17);
}
TEST_F(PolicyTest, Eval5) {
- auto p = Policy(cct.get(), arbitrary_tenant, example5, true);
+ auto p = Policy(cct.get(), &arbitrary_tenant, example5, true);
Environment e;
ARN arn1(Partition::aws, Service::iam,
TEST_F(PolicyTest, Parse6) {
boost::optional<Policy> p;
- ASSERT_NO_THROW(p = Policy(cct.get(), arbitrary_tenant, example6, true));
+ ASSERT_NO_THROW(p = Policy(cct.get(), &arbitrary_tenant, example6, true));
ASSERT_TRUE(p);
EXPECT_EQ(p->text, example6);
EXPECT_EQ(p->version, Version::v2012_10_17);
}
TEST_F(PolicyTest, Eval6) {
- auto p = Policy(cct.get(), arbitrary_tenant, example6, true);
+ auto p = Policy(cct.get(), &arbitrary_tenant, example6, true);
Environment e;
ARN arn1(Partition::aws, Service::iam,
TEST_F(PolicyTest, Parse7) {
boost::optional<Policy> p;
- ASSERT_NO_THROW(p = Policy(cct.get(), arbitrary_tenant, example7, true));
+ ASSERT_NO_THROW(p = Policy(cct.get(), &arbitrary_tenant, example7, true));
ASSERT_TRUE(p);
EXPECT_EQ(p->text, example7);
}
TEST_F(PolicyTest, Eval7) {
- auto p = Policy(cct.get(), arbitrary_tenant, example7, true);
+ auto p = Policy(cct.get(), &arbitrary_tenant, example7, true);
Environment e;
auto subacct = FakeIdentity(
boost::optional<Policy> p;
ASSERT_NO_THROW(
- p = Policy(cct.get(), arbitrary_tenant, ip_address_full_example, true));
+ p = Policy(cct.get(), &arbitrary_tenant, ip_address_full_example, true));
ASSERT_TRUE(p);
EXPECT_EQ(p->text, ip_address_full_example);
TEST_F(IPPolicyTest, EvalIPAddress) {
auto allowp =
- Policy(cct.get(), arbitrary_tenant, ip_address_allow_example, true);
+ Policy(cct.get(), &arbitrary_tenant, ip_address_allow_example, true);
auto denyp =
- Policy(cct.get(), arbitrary_tenant, ip_address_deny_example, true);
+ Policy(cct.get(), &arbitrary_tenant, ip_address_deny_example, true);
auto fullp =
- Policy(cct.get(), arbitrary_tenant, ip_address_full_example, true);
+ Policy(cct.get(), &arbitrary_tenant, ip_address_full_example, true);
Environment e;
Environment allowedIP, blocklistedIP, allowedIPv6, blocklistedIPv6;
allowedIP.emplace("aws:SourceIp","192.168.1.2");