return ret;
}
- info->identity = rgw::auth::transform_old_authinfo(sync_env->cct, uid,
- info->user_info.display_name,
- info->user_info.path,
- info->user_info.account_id,
- RGW_PERM_FULL_CONTROL,
- false, /* system_request? */
- info->user_info.type);
+ auto result = rgw::auth::transform_old_authinfo(
+ sync_env->dpp, null_yield, sync_env->driver, info->user_info);
+ if (!result) {
+ return result.error();
+ }
+ info->identity = std::move(result).value();
map<string, bufferlist> uattrs;
#include <string>
#include <variant>
+#include "common/errno.h"
#include "rgw_common.h"
#include "rgw_auth.h"
#include "rgw_quota.h"
}
static bool match_owner(const rgw_owner& owner, const rgw_user& uid,
- std::string_view account_id)
+ const std::optional<RGWAccountInfo>& account)
{
return std::visit(fu2::overload(
[&uid] (const rgw_user& u) { return u == uid; },
- [&account_id] (const rgw_account_id& a) { return a == account_id; }
- ), owner);
+ [&account] (const rgw_account_id& a) {
+ return account && a == account->id;
+ }), owner);
}
-static bool match_account_or_tenant(const rgw_account_id& account_id,
+static bool match_account_or_tenant(const std::optional<RGWAccountInfo>& account,
std::string_view tenant,
std::string_view expected)
{
- if (!account_id.empty()) {
- return account_id == expected;
- } else {
- return tenant == expected;
- }
+ return (account && account->id == expected)
+ || (tenant == expected);
}
-std::unique_ptr<rgw::auth::Identity>
-transform_old_authinfo(CephContext* const cct,
- const rgw_user& auth_id,
- const std::string& display_name,
- const std::string& path,
- const rgw_account_id& account_id,
- const int perm_mask,
- const bool is_admin,
- const uint32_t type)
+auto transform_old_authinfo(const RGWUserInfo& user,
+ std::optional<RGWAccountInfo> account)
+ -> std::unique_ptr<rgw::auth::Identity>
{
/* This class is not intended for public use. Should be removed altogether
* with this function after moving all our APIs to the new authentication
* infrastructure. */
class DummyIdentityApplier : public rgw::auth::Identity {
- CephContext* const cct;
-
/* For this particular case it's OK to use rgw_user structure to convey
* the identity info as this was the policy for doing that before the
* new auth. */
const rgw_user id;
const std::string display_name;
const std::string path;
- const rgw_account_id account_id;
- const int perm_mask;
const bool is_admin;
const uint32_t type;
+ const std::optional<RGWAccountInfo> account;
public:
- DummyIdentityApplier(CephContext* const cct,
- const rgw_user& auth_id,
- const std::string display_name,
- const std::string path,
- const rgw_account_id& account_id,
- const int perm_mask,
- const bool is_admin,
- const uint32_t type)
- : cct(cct),
- id(auth_id),
- display_name(display_name),
- path(path),
- account_id(account_id),
- perm_mask(perm_mask),
- is_admin(is_admin),
- type(type) {
- }
+ DummyIdentityApplier(const RGWUserInfo& user,
+ std::optional<RGWAccountInfo> account)
+ : id(user.user_id),
+ display_name(user.display_name),
+ path(user.path),
+ is_admin(user.admin),
+ type(user.type),
+ account(std::move(account))
+ {}
ACLOwner get_aclowner() const {
ACLOwner owner;
- if (!account_id.empty()) {
- owner.id.emplace<rgw_account_id>(account_id);
+ if (account) {
+ owner.id = account->id;
+ owner.display_name = account->name;
} else {
owner.id = id;
+ owner.display_name = display_name;
}
- owner.display_name = display_name;
return owner;
}
}
bool is_owner_of(const rgw_owner& o) const override {
- return match_owner(o, id, account_id);
+ return match_owner(o, id, account);
}
bool is_identity(const Principal& p) const override {
if (p.is_wildcard()) {
return true;
} else if (p.is_account()) {
- return match_account_or_tenant(account_id, id.tenant,
+ return match_account_or_tenant(account, id.tenant,
p.get_account());
} else if (p.is_user()) {
std::string_view no_subuser;
// account users can match both account- and tenant-based arns
- if (!account_id.empty() && p.get_account() == account_id) {
+ if (account && p.get_account() == account->id) {
return match_principal(path, display_name, no_subuser, p.get_id());
} else {
return p.get_account() == id.tenant
}
uint32_t get_perm_mask() const override {
- return perm_mask;
+ return RGW_PERM_FULL_CONTROL;
}
uint32_t get_identity_type() const override {
void to_str(std::ostream& out) const override {
out << "RGWDummyIdentityApplier(auth_id=" << id
- << ", perm_mask=" << perm_mask
<< ", is_admin=" << is_admin << ")";
}
};
- return std::make_unique<DummyIdentityApplier>(
- cct, auth_id, display_name, path, account_id,
- perm_mask, is_admin, type);
+ return std::make_unique<DummyIdentityApplier>(user, std::move(account));
}
-std::unique_ptr<rgw::auth::Identity>
-transform_old_authinfo(const req_state* const s)
+auto transform_old_authinfo(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ rgw::sal::Driver* driver,
+ const RGWUserInfo& user)
+ -> tl::expected<std::unique_ptr<Identity>, int>
{
- const RGWUserInfo& info = s->user->get_info();
- return transform_old_authinfo(s->cct,
- info.user_id,
- info.display_name,
- info.path,
- info.account_id,
- s->perm_mask,
- /* System user has admin permissions by default - it's supposed to pass
- * through any security check. */
- s->system_request,
- info.type);
+ std::optional<RGWAccountInfo> account;
+ if (!user.account_id.empty()) {
+ account.emplace();
+ rgw::sal::Attrs attrs; // ignored
+ RGWObjVersionTracker objv; // ignored
+ int r = driver->load_account_by_id(dpp, y, user.account_id,
+ *account, attrs, objv);
+ if (r < 0) {
+ ldpp_dout(dpp, 1) << "ERROR: failed to load account "
+ << user.account_id << " for user " << user.user_id
+ << ": " << cpp_strerror(r) << dendl;
+ return tl::unexpected(r);
+ }
+ }
+
+ return transform_old_authinfo(user, std::move(account));
}
} /* namespace auth */
auth_stack.push_back(std::make_pair(std::cref(engine), ctrl_flag));
}
+ACLOwner rgw::auth::WebIdentityApplier::get_aclowner() const
+{
+ ACLOwner owner;
+ if (account) {
+ owner.id = account->id;
+ owner.display_name = account->name;
+ } else {
+ owner.id = rgw_user{role_tenant, sub, "oidc"};
+ owner.display_name = user_name;
+ }
+ return owner;
+}
+
+bool rgw::auth::WebIdentityApplier::is_owner_of(const rgw_owner& o) const
+{
+ return match_owner(o, rgw_user{role_tenant, sub, "oidc"}, account);
+}
+
void rgw::auth::WebIdentityApplier::to_str(std::ostream& out) const
{
out << "rgw::auth::WebIdentityApplier(sub =" << sub
<< ", user_name=" << user_name
+ << ", role_id=" << role_id
<< ", provider_id =" << iss << ")";
}
ACLOwner rgw::auth::RemoteApplier::get_aclowner() const
{
ACLOwner owner;
+ // TODO: handle account ownership
owner.id = info.acct_user;
owner.display_name = info.acct_name;
return owner;
ACLOwner rgw::auth::LocalApplier::get_aclowner() const
{
ACLOwner owner;
- if (!user_info.account_id.empty()) {
- owner.id = user_info.account_id;
+ if (account) {
+ owner.id = account->id;
+ owner.display_name = account->name;
} else {
owner.id = user_info.user_id;
+ owner.display_name = user_info.display_name;
}
- owner.display_name = user_info.display_name;
return owner;
}
uint32_t mask = rgw_perms_from_aclspec_default_strategy(
user_info.user_id.to_str(), aclspec, dpp);
- if (!user_info.account_id.empty()) {
+ if (account) {
// account users also match acl grants to the account id. in aws, grantees
// ONLY refer to accounts. but we continue to match user grants to preserve
// access when moving legacy users into new accounts
- mask |= rgw_perms_from_aclspec_default_strategy(
- user_info.account_id, aclspec, dpp);
+ mask |= rgw_perms_from_aclspec_default_strategy(account->id, aclspec, dpp);
}
return mask;
bool rgw::auth::LocalApplier::is_owner_of(const rgw_owner& o) const
{
- return match_owner(o, user_info.user_id, user_info.account_id);
+ return match_owner(o, user_info.user_id, account);
}
bool rgw::auth::LocalApplier::is_identity(const Principal& p) const {
if (p.is_wildcard()) {
return true;
} else if (p.is_account()) {
- return match_account_or_tenant(user_info.account_id,
- user_info.user_id.tenant,
+ return match_account_or_tenant(account, user_info.user_id.tenant,
p.get_account());
} else if (p.is_user()) {
// account users can match both account- and tenant-based arns
- if (!user_info.account_id.empty() &&
- p.get_account() == user_info.account_id) {
+ if (account && p.get_account() == account->id) {
return match_principal(user_info.path, user_info.display_name,
subuser, p.get_id());
} else {
ACLOwner rgw::auth::RoleApplier::get_aclowner() const
{
ACLOwner owner;
- if (!role.account_id.empty()) {
- owner.id = role.account_id;
+ if (role.account) {
+ owner.id = role.account->id;
+ owner.display_name = role.account->name;
} else {
owner.id = token_attrs.user_id;
+ owner.display_name = role.name;
}
- owner.display_name = role.name;
return owner;
}
bool rgw::auth::RoleApplier::is_owner_of(const rgw_owner& o) const
{
- return match_owner(o, token_attrs.user_id, role.account_id);
+ return match_owner(o, token_attrs.user_id, role.account);
}
void rgw::auth::RoleApplier::to_str(std::ostream& out) const {
if (p.is_wildcard()) {
return true;
} else if (p.is_account()) {
- return match_account_or_tenant(role.account_id, role.tenant,
+ return match_account_or_tenant(role.account, role.tenant,
p.get_account());
} else if (p.is_role()) {
std::string_view no_subuser;
// account roles can match both account- and tenant-based arns
- return match_account_or_tenant(role.account_id, role.tenant, p.get_account())
+ return match_account_or_tenant(role.account, role.tenant, p.get_account())
&& match_principal(role.path, role.name, no_subuser, p.get_id());
} else if (p.is_assumed_role()) {
string role_session = role.name + "/" + token_attrs.role_session_name; //role/role-session
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;
+ const std::string* policy_tenant = role.account ? nullptr : &role.tenant;
for (const auto& policy : role.inline_policies) {
try {
rgw_get_anon_user(user_info);
auto apl = \
- apl_factory->create_apl_local(cct, s, user_info,
+ apl_factory->create_apl_local(cct, s, user_info, std::nullopt,
rgw::auth::LocalApplier::NO_SUBUSER,
std::nullopt, rgw::auth::LocalApplier::NO_ACCESS_KEY);
return result_t::grant(std::move(apl));
#include <system_error>
#include <utility>
+#include "include/expected.hpp"
#include "include/function2.hpp"
#include "rgw_common.h"
}
-std::unique_ptr<rgw::auth::Identity>
-transform_old_authinfo(CephContext* const cct,
- const rgw_user& auth_id,
- const std::string& display_name,
- const std::string& path,
- const rgw_account_id& account_id,
- const int perm_mask,
- const bool is_admin,
- const uint32_t type);
-std::unique_ptr<Identity> transform_old_authinfo(const req_state* const s);
+// Return an identity for the given user and account.
+auto transform_old_authinfo(const RGWUserInfo& user,
+ std::optional<RGWAccountInfo> account)
+ -> std::unique_ptr<rgw::auth::Identity>;
+
+// Return an identity for the given user, loading its account if necessary.
+auto transform_old_authinfo(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ rgw::sal::Driver* driver,
+ const RGWUserInfo& user)
+ -> tl::expected<std::unique_ptr<Identity>, int>;
/* Interface for classes applying changes to request state/RADOS store
protected:
CephContext* const cct;
rgw::sal::Driver* driver;
+ std::string role_id;
std::string role_session;
std::string role_tenant;
std::unordered_multimap<std::string, std::string> token_claims;
boost::optional<std::multimap<std::string,std::string>> role_tags;
boost::optional<std::set<std::pair<std::string, std::string>>> principal_tags;
+ std::optional<RGWAccountInfo> account;
std::string get_idp_url() const;
public:
WebIdentityApplier( CephContext* const cct,
rgw::sal::Driver* driver,
+ const std::string& role_id,
const std::string& role_session,
const std::string& role_tenant,
const std::unordered_multimap<std::string, std::string>& token_claims,
boost::optional<std::multimap<std::string,std::string>> role_tags,
- boost::optional<std::set<std::pair<std::string, std::string>>> principal_tags)
+ boost::optional<std::set<std::pair<std::string, std::string>>> principal_tags,
+ std::optional<RGWAccountInfo> account)
: cct(cct),
driver(driver),
+ role_id(role_id),
role_session(role_session),
role_tenant(role_tenant),
token_claims(token_claims),
role_tags(role_tags),
- principal_tags(principal_tags) {
+ principal_tags(principal_tags),
+ account(std::move(account))
+ {
const auto& sub = token_claims.find("sub");
if(sub != token_claims.end()) {
this->sub = sub->second;
void modify_request_state(const DoutPrefixProvider *dpp, req_state* s) const override;
- ACLOwner get_aclowner() const override {
- ACLOwner owner;
- owner.id = rgw_user{role_tenant, sub, "oidc"};
- owner.display_name = user_name;
- return owner;
- }
+ ACLOwner get_aclowner() const override;
uint32_t get_perms_from_aclspec(const DoutPrefixProvider* dpp, const aclspec_t& aclspec) const override {
return RGW_PERM_NONE;
return false;
}
- bool is_owner_of(const rgw_owner& o) const override {
- auto* uid = std::get_if<rgw_user>(&o);
- return uid && uid->id == sub && uid->tenant == role_tenant && uid->ns == "oidc";
- }
+ bool is_owner_of(const rgw_owner& o) const override;
uint32_t get_perm_mask() const override {
return RGW_PERM_NONE;
virtual aplptr_t create_apl_web_identity( CephContext* cct,
const req_state* s,
+ const std::string& role_id,
const std::string& role_session,
const std::string& role_tenant,
const std::unordered_multimap<std::string, std::string>& token,
boost::optional<std::multimap<std::string, std::string>>,
- boost::optional<std::set<std::pair<std::string, std::string>>> principal_tags) const = 0;
+ boost::optional<std::set<std::pair<std::string, std::string>>> principal_tags,
+ std::optional<RGWAccountInfo> account) const = 0;
};
};
protected:
const RGWUserInfo user_info;
+ const std::optional<RGWAccountInfo> account;
const std::string subuser;
uint32_t perm_mask;
const std::string access_key_id;
LocalApplier(CephContext* const cct,
const RGWUserInfo& user_info,
+ std::optional<RGWAccountInfo> account,
std::string subuser,
const std::optional<uint32_t>& perm_mask,
const std::string access_key_id)
: user_info(user_info),
+ account(std::move(account)),
subuser(std::move(subuser)),
perm_mask(perm_mask.value_or(RGW_PERM_INVALID)),
access_key_id(access_key_id) {
virtual aplptr_t create_apl_local(CephContext* cct,
const req_state* s,
const RGWUserInfo& user_info,
+ std::optional<RGWAccountInfo> account,
const std::string& subuser,
const std::optional<uint32_t>& perm_mask,
const std::string& access_key_id) const = 0;
std::string name;
std::string path;
std::string tenant;
- rgw_account_id account_id;
+ std::optional<RGWAccountInfo> account;
std::vector<std::string> inline_policies;
std::vector<std::string> managed_policies;
};
struct Factory {
virtual ~Factory() {}
- virtual aplptr_t create_apl_role( CephContext* cct,
- const req_state* s,
- const rgw::auth::RoleApplier::Role& role,
- const rgw::auth::RoleApplier::TokenAttrs& token_attrs) const = 0;
- };
+ virtual aplptr_t create_apl_role(CephContext* cct,
+ const req_state* s,
+ Role role,
+ TokenAttrs token_attrs) const = 0;
+ };
};
/* The anonymous abstract engine. */
aplptr_t create_apl_local(CephContext* const cct,
const req_state* const s,
const RGWUserInfo& user_info,
+ std::optional<RGWAccountInfo> account,
const std::string& subuser,
const std::optional<uint32_t>& perm_mask,
const std::string& access_key_id) const override {
auto apl = rgw::auth::add_sysreq(cct, driver, s,
- rgw::auth::LocalApplier(cct, user_info, subuser, perm_mask, access_key_id));
+ rgw::auth::LocalApplier(cct, user_info, std::move(account),
+ subuser, perm_mask, access_key_id));
return aplptr_t(new decltype(apl)(std::move(apl)));
}
aplptr_t create_apl_role(CephContext* const cct,
const req_state* const s,
- const rgw::auth::RoleApplier::Role& role,
- const rgw::auth::RoleApplier::TokenAttrs& token_attrs) const override {
+ RoleApplier::Role role,
+ RoleApplier::TokenAttrs token_attrs) const override {
auto apl = rgw::auth::add_sysreq(cct, driver, s,
- rgw::auth::RoleApplier(cct, role, token_attrs));
+ rgw::auth::RoleApplier(cct, std::move(role), std::move(token_attrs)));
return aplptr_t(new decltype(apl)(std::move(apl)));
}
rgw::auth::RemoteApplier::acl_strategy_t&& acl_alg,
const rgw::auth::RemoteApplier::AuthInfo &info) const override {
auto apl = rgw::auth::add_sysreq(cct, driver, s,
- rgw::auth::RemoteApplier(cct, driver, std::move(acl_alg), info,
- implicit_tenant_context,
+ rgw::auth::RemoteApplier(cct, driver, std::move(acl_alg),
+ info, implicit_tenant_context,
rgw::auth::ImplicitTenants::IMPLICIT_TENANTS_S3));
/* TODO(rzarzynski): replace with static_ptr. */
return aplptr_t(new decltype(apl)(std::move(apl)));
aplptr_t create_apl_local(CephContext* const cct,
const req_state* const s,
const RGWUserInfo& user_info,
+ std::optional<RGWAccountInfo> account,
const std::string& subuser,
const std::optional<uint32_t>& perm_mask,
const std::string& access_key_id) const override {
auto apl = rgw::auth::add_sysreq(cct, driver, s,
- rgw::auth::LocalApplier(cct, user_info, subuser, perm_mask, access_key_id));
+ rgw::auth::LocalApplier(cct, user_info, std::move(account),
+ subuser, perm_mask, access_key_id));
/* TODO(rzarzynski): replace with static_ptr. */
return aplptr_t(new decltype(apl)(std::move(apl)));
}
/* FIXME: remove this after switching all handlers to the new
* authentication infrastructure. */
if (! s->auth.identity) {
- s->auth.identity = rgw::auth::transform_old_authinfo(s);
+ s->auth.identity = rgw::auth::transform_old_authinfo(
+ io->get_user(), std::nullopt);
}
ldpp_dout(s, 2) << "reading op permissions" << dendl;
/* FIXME: remove this after switching all handlers to the new authentication
* infrastructure. */
if (! s->auth.identity) {
- s->auth.identity = rgw::auth::transform_old_authinfo(s);
+ s->auth.identity = rgw::auth::transform_old_authinfo(
+ io_ctx.get_user(), std::nullopt);
}
ldpp_dout(s, 2) << "reading op permissions" << dendl;
if (ret < 0) {
derr << "ERROR: failed reading user info: uid=" << uid << " ret="
<< ret << dendl;
+ return ret;
}
user_info = user->get_info();
- return ret;
+ return 0;
}
int RGWLibRequest::read_permissions(RGWOp* op, optional_yield y) {
#pragma once
#include <mutex>
+#include <optional>
#include "rgw_common.h"
#include "rgw_client_io.h"
#include "rgw_rest.h"
/* FIXME: remove this after switching all handlers to the new authentication
* infrastructure. */
if (nullptr == s->auth.identity) {
- s->auth.identity = rgw::auth::transform_old_authinfo(s);
+ auto result = rgw::auth::transform_old_authinfo(
+ op, yield, driver, s->user->get_info());
+ if (!result) {
+ abort_early(s, op, result.error(), handler, yield);
+ goto done;
+ }
+ s->auth.identity = std::move(result).value();
}
ldpp_dout(op, 2) << "normalizing buckets and tenants" << dendl;
}
}*/
+ std::optional<RGWAccountInfo> account;
+ if (!user->get_info().account_id.empty()) {
+ account.emplace();
+ rgw::sal::Attrs attrs; // ignored
+ RGWObjVersionTracker objv; // ignored
+ int r = driver->load_account_by_id(dpp, y, user->get_info().account_id,
+ *account, attrs, objv);
+ if (r < 0) {
+ ldpp_dout(dpp, 1) << "ERROR: failed to load account "
+ << user->get_info().account_id << " for user " << *user
+ << ": " << cpp_strerror(r) << dendl;
+ return result_t::deny(-EPERM);
+ }
+ }
+
const auto iter = user->get_info().access_keys.find(access_key_id);
if (iter == std::end(user->get_info().access_keys)) {
ldpp_dout(dpp, 0) << "ERROR: access key not encoded in user info" << dendl;
/* Ignore signature for HTTP OPTIONS */
if (s->op_type == RGW_OP_OPTIONS_CORS) {
- auto apl = apl_factory->create_apl_local(cct, s, user->get_info(),
+ auto apl = apl_factory->create_apl_local(cct, s, user->get_info(), std::move(account),
k.subuser, std::nullopt, access_key_id);
return result_t::grant(std::move(apl), completer_factory(k.key));
}
return result_t::reject(-ERR_SIGNATURE_NO_MATCH);
}
- auto apl = apl_factory->create_apl_local(cct, s, user->get_info(),
+ auto apl = apl_factory->create_apl_local(cct, s, user->get_info(), std::move(account),
k.subuser, std::nullopt, access_key_id);
return result_t::grant(std::move(apl), completer_factory(k.key));
}
}
// Get all the authorization info
- std::unique_ptr<rgw::sal::User> user;
rgw_user user_id;
string role_id;
rgw::auth::RoleApplier::Role r;
r.name = role->get_name();
r.path = role->get_path();
r.tenant = role->get_tenant();
- r.account_id = role->get_account_id();
+
+ const auto& account_id = role->get_account_id();
+ if (!account_id.empty()) {
+ r.account.emplace();
+ rgw::sal::Attrs attrs; // ignored
+ RGWObjVersionTracker objv; // ignored
+ int ret = driver->load_account_by_id(dpp, y, account_id,
+ *r.account, attrs, objv);
+ if (ret < 0) {
+ ldpp_dout(dpp, 1) << "ERROR: failed to load account "
+ << account_id << " for role " << r.name
+ << ": " << cpp_strerror(ret) << dendl;
+ return result_t::deny(-EPERM);
+ }
+ }
for (auto& [name, policy] : role->get_info().perm_policy_map) {
r.inline_policies.push_back(std::move(policy));
}
}
- user = driver->get_user(token.user);
- if (! token.user.empty() && token.acct_type != TYPE_ROLE) {
- // get user info
- int ret = user->load_user(dpp, y);
- if (ret < 0) {
- ldpp_dout(dpp, 5) << "ERROR: failed reading user info: uid=" << token.user << dendl;
- return result_t::reject(-EPERM);
- }
- }
-
if (token.acct_type == TYPE_KEYSTONE || token.acct_type == TYPE_LDAP) {
auto apl = remote_apl_factory->create_apl_remote(cct, s, get_acl_strategy(),
get_creds_info(token));
t_attrs.token_claims = std::move(token.token_claims);
t_attrs.token_issued_at = std::move(token.issued_at);
t_attrs.principal_tags = std::move(token.principal_tags);
- auto apl = role_apl_factory->create_apl_role(cct, s, r, t_attrs);
+ auto apl = role_apl_factory->create_apl_role(cct, s, std::move(r),
+ std::move(t_attrs));
return result_t::grant(std::move(apl), completer_factory(token.secret_access_key));
} else { // This is for all local users of type TYPE_RGW|ROOT|NONE
+ if (token.user.empty()) {
+ ldpp_dout(dpp, 5) << "ERROR: got session token with empty user id" << dendl;
+ return result_t::reject(-EPERM);
+ }
+ // load user info
+ auto user = driver->get_user(token.user);
+ int ret = user->load_user(dpp, y);
+ if (ret < 0) {
+ ldpp_dout(dpp, 5) << "ERROR: failed reading user info: uid=" << token.user << dendl;
+ return result_t::reject(-EPERM);
+ }
+
+ std::optional<RGWAccountInfo> account;
+ if (!user->get_info().account_id.empty()) {
+ account.emplace();
+ rgw::sal::Attrs attrs; // ignored
+ RGWObjVersionTracker objv; // ignored
+ int r = driver->load_account_by_id(dpp, y, user->get_info().account_id,
+ *account, attrs, objv);
+ if (r < 0) {
+ ldpp_dout(dpp, 1) << "ERROR: failed to load account "
+ << user->get_info().account_id << " for user " << *user
+ << ": " << cpp_strerror(r) << dendl;
+ return result_t::deny(-EPERM);
+ }
+ }
+
string subuser;
- auto apl = local_apl_factory->create_apl_local(cct, s, user->get_info(), subuser, token.perm_mask, std::string(_access_key_id));
+ auto apl = local_apl_factory->create_apl_local(cct, s, user->get_info(),
+ std::move(account), subuser,
+ token.perm_mask, std::string(_access_key_id));
return result_t::grant(std::move(apl), completer_factory(token.secret_access_key));
}
}
ldpp_dout(dpp, 0) << "Role not found: name:" << role_name << " tenant: " << role_tenant << dendl;
return result_t::deny(-EACCES);
}
+
+ std::optional<RGWAccountInfo> account;
+ if (!role_account.empty()) {
+ account.emplace();
+ rgw::sal::Attrs attrs; // ignored
+ RGWObjVersionTracker objv; // ignored
+ ret = driver->load_account_by_id(dpp, y, role_account,
+ *account, attrs, objv);
+ if (ret < 0) {
+ ldpp_dout(dpp, 0) << "Role account " << role_account << " not found" << dendl;
+ return result_t::deny(-EACCES);
+ }
+ }
+
boost::optional<multimap<string,string>> role_tags = role->get_tags();
- auto apl = apl_factory->create_apl_web_identity(cct, s, role_session, role->get_tenant(), *t, role_tags, princ_tags);
+ auto apl = apl_factory->create_apl_web_identity(
+ cct, s, role->get_id(), role_session, role_tenant,
+ *t, role_tags, princ_tags, std::move(account));
return result_t::grant(std::move(apl));
}
return result_t::deny(-EACCES);
aplptr_t create_apl_web_identity( CephContext* cct,
const req_state* s,
+ const std::string& role_id,
const std::string& role_session,
const std::string& role_tenant,
const std::unordered_multimap<std::string, std::string>& token,
boost::optional<std::multimap<std::string, std::string>> role_tags,
- boost::optional<std::set<std::pair<std::string, std::string>>> principal_tags) const override {
+ boost::optional<std::set<std::pair<std::string, std::string>>> principal_tags,
+ std::optional<RGWAccountInfo> account) const override {
auto apl = rgw::auth::add_sysreq(cct, driver, s,
- rgw::auth::WebIdentityApplier(cct, driver, role_session, role_tenant, token, role_tags, principal_tags));
+ rgw::auth::WebIdentityApplier(cct, driver, role_id, role_session,
+ role_tenant, token, role_tags,
+ principal_tags, std::move(account)));
return aplptr_t(new decltype(apl)(std::move(apl)));
}
try {
get_owner_info(s, s->user->get_info());
- s->auth.identity = rgw::auth::transform_old_authinfo(s);
+ s->auth.identity = rgw::auth::transform_old_authinfo(
+ s->user->get_info(), std::nullopt);
} catch (...) {
ldpp_dout(this, 5) << "cannot get user_info of account's owner" << dendl;
return false;
throw ret;
}
+ std::optional<RGWAccountInfo> account;
+ if (!user->get_info().account_id.empty()) {
+ account.emplace();
+ rgw::sal::Attrs attrs; // ignored
+ RGWObjVersionTracker objv; // ignored
+ int r = driver->load_account_by_id(dpp, y, user->get_info().account_id,
+ *account, attrs, objv);
+ if (r < 0) {
+ ldpp_dout(dpp, 1) << "ERROR: failed to load account "
+ << user->get_info().account_id << " for user " << *user
+ << ": " << cpp_strerror(r) << dendl;
+ return result_t::deny(-EPERM);
+ }
+ }
+
auto apl = apl_factory->create_apl_local(cct, s, user->get_info(),
+ std::move(account),
extract_swift_subuser(swift_user),
std::nullopt, rgw::auth::LocalApplier::NO_ACCESS_KEY);
return result_t::grant(std::move(apl));
throw ret;
}
+ std::optional<RGWAccountInfo> account;
+ if (!user->get_info().account_id.empty()) {
+ account.emplace();
+ rgw::sal::Attrs attrs; // ignored
+ RGWObjVersionTracker objv; // ignored
+ int r = driver->load_account_by_id(dpp, s->yield, user->get_info().account_id,
+ *account, attrs, objv);
+ if (r < 0) {
+ ldpp_dout(dpp, 1) << "ERROR: failed to load account "
+ << user->get_info().account_id << " for user " << *user
+ << ": " << cpp_strerror(r) << dendl;
+ return result_t::deny(-EPERM);
+ }
+ }
+
ldpp_dout(dpp, 10) << "swift_user=" << swift_user << dendl;
const auto siter = user->get_info().swift_keys.find(swift_user);
}
auto apl = apl_factory->create_apl_local(cct, s, user->get_info(),
+ std::move(account),
extract_swift_subuser(swift_user),
std::nullopt, rgw::auth::LocalApplier::NO_ACCESS_KEY);
return result_t::grant(std::move(apl));
public:
TempURLApplier(CephContext* const cct,
const RGWUserInfo& user_info)
- : LocalApplier(cct, user_info, LocalApplier::NO_SUBUSER, std::nullopt, LocalApplier::NO_ACCESS_KEY) {
- };
+ : LocalApplier(cct, user_info, std::nullopt, LocalApplier::NO_SUBUSER,
+ std::nullopt, LocalApplier::NO_ACCESS_KEY)
+ {}
void modify_request_state(const DoutPrefixProvider* dpp, req_state * s) const override; /* in/out */
void write_ops_log_entry(rgw_log_entry& entry) const override;
public:
SwiftAnonymousApplier(CephContext* const cct,
const RGWUserInfo& user_info)
- : LocalApplier(cct, user_info, LocalApplier::NO_SUBUSER, std::nullopt, LocalApplier::NO_ACCESS_KEY) {
+ : LocalApplier(cct, user_info, std::nullopt, LocalApplier::NO_SUBUSER,
+ std::nullopt, LocalApplier::NO_ACCESS_KEY) {
}
bool is_admin_of(const rgw_owner& o) const {return false;}
bool is_owner_of(const rgw_owner& o) const {
aplptr_t create_apl_local(CephContext* const cct,
const req_state* const s,
const RGWUserInfo& user_info,
+ std::optional<RGWAccountInfo> account,
const std::string& subuser,
const std::optional<uint32_t>& perm_mask,
const std::string& access_key_id) const override {
auto apl = \
rgw::auth::add_3rdparty(driver, rgw_user(s->account_name),
rgw::auth::add_sysreq(cct, driver, s,
- rgw::auth::LocalApplier(cct, user_info, subuser, perm_mask, access_key_id)));
+ rgw::auth::LocalApplier(cct, user_info, std::move(account),
+ subuser, perm_mask, access_key_id)));
/* TODO(rzarzynski): replace with static_ptr. */
return aplptr_t(new decltype(apl)(std::move(apl)));
}