OPTION(rgw_website_routing_rules_max_num, OPT_INT) // According to AWS S3, An website routing config can have up to 50 rules.
OPTION(rgw_sts_entry, OPT_STR)
OPTION(rgw_sts_key, OPT_STR)
+OPTION(rgw_s3_auth_use_sts, OPT_BOOL) // should we try to use sts for s3?
.set_description("Should S3 authentication use Keystone."),
Option("rgw_s3_auth_order", Option::TYPE_STR, Option::LEVEL_ADVANCED)
- .set_default("external, local")
+ .set_default("external, local, sts")
.set_description("Authentication strategy order to use for s3 authentication")
.set_long_description(
"Order of authentication strategies to try for s3 authentication, the allowed "
Option("rgw_sts_key", Option::TYPE_STR, Option::LEVEL_ADVANCED)
.set_default("sts")
.set_description("STS Key")
- .set_long_description("Key used for encrypting/ decrypting session token.")
+ .set_long_description("Key used for encrypting/ decrypting session token."),
+
+ Option("rgw_s3_auth_use_sts", Option::TYPE_BOOL, Option::LEVEL_ADVANCED)
+ .set_default(false)
+ .set_description("Should S3 authentication use STS."),
});
}
user_info = this->user_info;
}
+void rgw::auth::LocalApplier::modify_request_state(req_state* s) const
+{
+ for (auto it : role_policies) {
+ try {
+ bufferlist bl = bufferlist::static_from_string(it);
+ const rgw::IAM::Policy p(s->cct, s->user->user_id.tenant, bl);
+ s->iam_user_policies.push_back(std::move(p));
+ } catch (rgw::IAM::PolicyParseException& e) {
+ //Control shouldn't reach here as the policy has already been
+ //verified earlier
+ ldout(s->cct, 20) << "failed to parse policy: " << e.what() << dendl;
+ }
+ }
+}
+
rgw::auth::Engine::result_t
rgw::auth::AnonymousEngine::authenticate(const req_state* const s) const
{
auto apl = \
apl_factory->create_apl_local(cct, s, user_info,
- rgw::auth::LocalApplier::NO_SUBUSER);
+ rgw::auth::LocalApplier::NO_SUBUSER,
+ boost::none);
return result_t::grant(std::move(apl));
}
}
protected:
const RGWUserInfo user_info;
const std::string subuser;
+ vector<std::string> role_policies;
uint32_t get_perm_mask(const std::string& subuser_name,
const RGWUserInfo &uinfo) const;
LocalApplier(CephContext* const cct,
const RGWUserInfo& user_info,
- std::string subuser)
+ std::string subuser,
+ const boost::optional<vector<std::string> >& role_policies)
: user_info(user_info),
- subuser(std::move(subuser)) {
+ subuser(std::move(subuser)){
+ if (role_policies) {
+ this->role_policies = role_policies.get();
+ }
}
void load_acct_info(RGWUserInfo& user_info) const override; /* out */
uint32_t get_identity_type() const override { return TYPE_RGW; }
string get_acct_name() const override { return {}; }
+ void modify_request_state(req_state* s) const override;
struct Factory {
virtual ~Factory() {}
virtual aplptr_t create_apl_local(CephContext* cct,
const req_state* s,
const RGWUserInfo& user_info,
- const std::string& subuser) const = 0;
+ const std::string& subuser,
+ const boost::optional<vector<std::string> >& role_policies) const = 0;
};
};
s->info.args.set_system();
s->system_request = true;
}
+ DecoratedApplier<T>::modify_request_state(s);
}
template <typename T> static inline
rgw::auth::Engine::result_t EC2Engine::authenticate(
const boost::string_view& access_key_id,
const boost::string_view& signature,
+ const boost::string_view& session_token,
const string_to_sign_t& string_to_sign,
const signature_factory_t&,
const completer_factory_t& completer_factory,
/* Passthorugh only! */
const req_state* s) const
{
+ //If Keystone is enabled and the request has a session token, then Keystone shouldn't authenticate it.
+ if (s->info.args.exists("X-Amz-Security-Token") ||
+ s->info.env->exists("HTTP_X_AMZ_SECURITY_TOKEN")) {
+ return result_t::deny();
+ }
+
/* This will be initialized on the first call to this method. In C++11 it's
* also thread-safe. */
static const struct RolesCacher {
const boost::string_view& signature) const;
result_t authenticate(const boost::string_view& access_key_id,
const boost::string_view& signature,
+ const boost::string_view& session_token,
const string_to_sign_t& string_to_sign,
const signature_factory_t&,
const completer_factory_t& completer_factory,
boost::string_view& credential, /* out */
boost::string_view& signedheaders, /* out */
boost::string_view& signature, /* out */
- boost::string_view& date) /* out */
+ boost::string_view& date, /* out */
+ boost::string_view& sessiontoken) /* out */
{
/* auth ships with req params ... */
return -EPERM;
}
+ if (info.args.exists("X-Amz-Security-Token")) {
+ sessiontoken = info.args.get("X-Amz-Security-Token");
+ if (sessiontoken.size() == 0) {
+ return -EPERM;
+ }
+ }
+
return 0;
}
boost::string_view& credential, /* out */
boost::string_view& signedheaders, /* out */
boost::string_view& signature, /* out */
- boost::string_view& date) /* out */
+ boost::string_view& date, /* out */
+ boost::string_view& sessiontoken) /* out */
{
boost::string_view input(info.env->get("HTTP_AUTHORIZATION", ""));
try {
return -ERR_REQUEST_TIME_SKEWED;
}
+ if (info.env->exists("HTTP_X_AMZ_SECURITY_TOKEN")) {
+ sessiontoken = info.env->get("HTTP_X_AMZ_SECURITY_TOKEN");
+ }
+
return 0;
}
boost::string_view& signedheaders, /* out */
boost::string_view& signature, /* out */
boost::string_view& date, /* out */
+ boost::string_view& session_token, /* out */
const bool using_qs) /* in */
{
boost::string_view credential;
int ret;
if (using_qs) {
ret = parse_v4_query_string(info, credential, signedheaders,
- signature, date);
+ signature, date, session_token);
} else {
ret = parse_v4_auth_header(info, credential, signedheaders,
- signature, date);
+ signature, date, session_token);
}
if (ret < 0) {
// returns true if the request time is within RGW_AUTH_GRACE of the current time
bool is_time_skew_ok(time_t t);
+class STSAuthStrategy : public rgw::auth::Strategy,
+ public rgw::auth::RemoteApplier::Factory,
+ public rgw::auth::LocalApplier::Factory {
+ typedef rgw::auth::IdentityApplier::aplptr_t aplptr_t;
+ RGWRados* const store;
+
+ STSEngine sts_engine;
+
+ aplptr_t create_apl_remote(CephContext* const cct,
+ const req_state* const s,
+ rgw::auth::RemoteApplier::acl_strategy_t&& acl_alg,
+ const rgw::auth::RemoteApplier::AuthInfo &info
+ ) const override {
+ auto apl = rgw::auth::add_sysreq(cct, store, s,
+ rgw::auth::RemoteApplier(cct, store, std::move(acl_alg), info,
+ cct->_conf->rgw_keystone_implicit_tenants));
+ 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,
+ const std::string& subuser,
+ const boost::optional<vector<std::string> >& role_policies) const override {
+ auto apl = rgw::auth::add_sysreq(cct, store, s,
+ rgw::auth::LocalApplier(cct, user_info, subuser, role_policies));
+ return aplptr_t(new decltype(apl)(std::move(apl)));
+ }
+
+public:
+ STSAuthStrategy(CephContext* const cct,
+ RGWRados* const store,
+ AWSEngine::VersionAbstractor* const ver_abstractor)
+ : store(store),
+ sts_engine(cct, store, *ver_abstractor,
+ static_cast<rgw::auth::LocalApplier::Factory*>(this),
+ static_cast<rgw::auth::RemoteApplier::Factory*>(this)) {
+ if (cct->_conf->rgw_s3_auth_use_sts) {
+ add_engine(Control::SUFFICIENT, sts_engine);
+ }
+ }
+
+ const char* get_name() const noexcept override {
+ return "rgw::auth::s3::STSAuthStrategy";
+ }
+};
+
class ExternalAuthStrategy : public rgw::auth::Strategy,
public rgw::auth::RemoteApplier::Factory {
typedef rgw::auth::IdentityApplier::aplptr_t aplptr_t;
S3AnonymousEngine anonymous_engine;
ExternalAuthStrategy external_engines;
+ STSAuthStrategy sts_engine;
LocalEngine local_engine;
aplptr_t create_apl_local(CephContext* const cct,
const req_state* const s,
const RGWUserInfo& user_info,
- const std::string& subuser) const override {
+ const std::string& subuser,
+ const boost::optional<vector<std::string> >& role_policies) const override {
auto apl = rgw::auth::add_sysreq(cct, store, s,
- rgw::auth::LocalApplier(cct, user_info, subuser));
+ rgw::auth::LocalApplier(cct, user_info, subuser, role_policies));
/* TODO(rzarzynski): replace with static_ptr. */
return aplptr_t(new decltype(apl)(std::move(apl)));
}
{
std::vector <std::string> result;
- const std::set <std::string_view> allowed_auth = { "external", "local" };
- std::vector <std::string> default_order = { "external", "local"};
+ const std::set <std::string_view> allowed_auth = { "external", "local", "sts" };
+ std::vector <std::string> default_order = { "external", "local", "sts"};
// supplied strings may contain a space, so let's bypass that
boost::split(result, cct->_conf->rgw_s3_auth_order,
boost::is_any_of(", "), boost::token_compress_on);
anonymous_engine(cct,
static_cast<rgw::auth::LocalApplier::Factory*>(this)),
external_engines(cct, store, &ver_abstractor),
+ sts_engine(cct, store, &ver_abstractor),
local_engine(cct, store, ver_abstractor,
static_cast<rgw::auth::LocalApplier::Factory*>(this)) {
/* The anonymous auth. */
if (cct->_conf->rgw_s3_auth_use_rados) {
engine_map.insert(std::make_pair("local", std::cref(local_engine)));
}
+
+ /* STS Auth*/
+ if (! sts_engine.is_empty()) {
+ engine_map.insert(std::make_pair("sts", std::cref(sts_engine)));
+ }
+
add_engines(auth_order, engine_map);
}
boost::string_view& signedheaders, /* out */
boost::string_view& signature, /* out */
boost::string_view& date, /* out */
+ boost::string_view& session_token, /* out */
const bool using_qs); /* in */
static inline bool char_needs_aws4_escaping(const char c, bool encode_slash)
std::string x_amz_algorithm;
std::string x_amz_credential;
std::string x_amz_date;
+ std::string x_amz_security_token;
ceph::bufferlist encoded_policy;
} s3_postobj_creds;
} auth;
#include "common/utf8.h"
#include "common/ceph_json.h"
#include "common/safe_io.h"
+#include "auth/Crypto.h"
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/utility/string_view.hpp>
+#include <boost/tokenizer.hpp>
#include <liboath/oath.h>
#include "rgw_crypt_sanitize.h"
#include "rgw_rest_user_policy.h"
#include "include/ceph_assert.h"
+#include "include/assert.h"
+#include "rgw_role.h"
+#include "rgw_sts.h"
#define dout_context g_ceph_context
#define dout_subsys ceph_subsys_rgw
}
}
+ part_str(parts, "x-amz-security-token", &s->auth.s3_postobj_creds.x_amz_security_token);
+
/* FIXME: this is a makeshift solution. The browser upload authentication will be
* handled by an instance of rgw::auth::Completer spawned in Handler's authorize()
* method. */
boost::string_view date;
boost::string_view credential_scope;
boost::string_view client_signature;
+ boost::string_view session_token;
int ret = rgw::auth::s3::parse_credentials(s->info,
access_key_id,
signed_hdrs,
client_signature,
date,
+ session_token,
using_qs);
if (ret < 0) {
throw ret;
return {
access_key_id,
client_signature,
+ session_token,
std::move(string_to_sign),
sig_factory,
null_completer_factory
return {
access_key_id,
client_signature,
+ session_token,
std::move(string_to_sign),
sig_factory,
cmpl_factory
return {
access_key_id,
client_signature,
+ session_token,
std::move(string_to_sign),
sig_factory,
cmpl_factory
{
boost::string_view access_key_id;
boost::string_view signature;
+ boost::string_view session_token;
bool qsr = false;
const char* http_auth = s->info.env->get("HTTP_AUTHORIZATION");
if (now >= exp) {
throw -EPERM;
}
+ if (s->info.args.exists("X-Amz-Security-Token")) {
+ session_token = s->info.args.get("X-Amz-Security-Token");
+ if (session_token.size() == 0) {
+ throw -EPERM;
+ }
+ }
+
} else {
/* The "Authorization" HTTP header is being used. */
const boost::string_view auth_str(http_auth + strlen("AWS "));
access_key_id = auth_str.substr(0, pos);
signature = auth_str.substr(pos + 1);
}
+
+ if (s->info.env->exists("HTTP_X_AMZ_SECURITY_TOKEN")) {
+ session_token = s->info.env->get("HTTP_X_AMZ_SECURITY_TOKEN");
+ if (session_token.size() == 0) {
+ throw -EPERM;
+ }
+ }
}
/* Let's canonize the HTTP headers that are covered by the AWS auth v2. */
return {
std::move(access_key_id),
std::move(signature),
+ std::move(session_token),
std::move(string_to_sign),
rgw::auth::s3::get_v2_signature,
null_completer_factory
return {
s->auth.s3_postobj_creds.access_key,
s->auth.s3_postobj_creds.signature,
+ s->auth.s3_postobj_creds.x_amz_security_token,
s->auth.s3_postobj_creds.encoded_policy.to_str(),
rgw::auth::s3::get_v2_signature,
null_completer_factory
return {
access_key_id,
s->auth.s3_postobj_creds.signature,
+ s->auth.s3_postobj_creds.x_amz_security_token,
s->auth.s3_postobj_creds.encoded_policy.to_str(),
sig_factory,
null_completer_factory
}
}
-
AWSEngine::result_t
AWSEngine::authenticate(const req_state* const s) const
{
} else {
return authenticate(auth_data.access_key_id,
auth_data.client_signature,
+ auth_data.session_token,
auth_data.string_to_sign,
auth_data.signature_factory,
auth_data.completer_factory,
rgw::auth::s3::LDAPEngine::authenticate(
const boost::string_view& access_key_id,
const boost::string_view& signature,
+ const boost::string_view& session_token,
const string_to_sign_t& string_to_sign,
const signature_factory_t&,
const completer_factory_t& completer_factory,
const req_state* const s) const
{
+ //If LDAP is enabled and the request has a session token, then LDAP shouldn't authenticate it.
+ if (s->info.args.exists("X-Amz-Security-Token") ||
+ s->info.env->exists("HTTP_X_AMZ_SECURITY_TOKEN")) {
+ return result_t::deny();
+ }
+
/* boost filters and/or string_ref may throw on invalid input */
rgw::RGWToken base64_token;
try {
rgw::auth::s3::LocalEngine::authenticate(
const boost::string_view& _access_key_id,
const boost::string_view& signature,
+ const boost::string_view& session_token,
const string_to_sign_t& string_to_sign,
const signature_factory_t& signature_factory,
const completer_factory_t& completer_factory,
const req_state* const s) const
{
+ //If LocalAuth is enabled and the request has a session token, then LocalEngine shouldn't authenticate it.
+ if (s->info.args.exists("X-Amz-Security-Token") ||
+ s->info.env->exists("HTTP_X_AMZ_SECURITY_TOKEN")) {
+ return result_t::deny();
+ }
+
/* get the user info */
RGWUserInfo user_info;
/* TODO(rzarzynski): we need to have string-view taking variant. */
return result_t::deny(-ERR_SIGNATURE_NO_MATCH);
}
- auto apl = apl_factory->create_apl_local(cct, s, user_info, k.subuser);
+ auto apl = apl_factory->create_apl_local(cct, s, user_info, k.subuser, boost::none);
return result_t::grant(std::move(apl), completer_factory(k.key));
}
+rgw::auth::RemoteApplier::AuthInfo
+rgw::auth::s3::STSEngine::get_creds_info(const STS::SessionToken& token) const noexcept
+{
+ using acct_privilege_t = \
+ rgw::auth::RemoteApplier::AuthInfo::acct_privilege_t;
+
+ return rgw::auth::RemoteApplier::AuthInfo {
+ token.user,
+ token.acct_name,
+ token.perm_mask,
+ (token.is_admin) ? acct_privilege_t::IS_ADMIN_ACCT: acct_privilege_t::IS_PLAIN_ACCT,
+ token.acct_type
+ };
+}
+
+int
+rgw::auth::s3::STSEngine::get_session_token(const boost::string_view& session_token,
+ STS::SessionToken& token) const
+{
+ string decodedSessionToken = rgw::from_base64(session_token);
+
+ auto* cryptohandler = cct->get_crypto_handler(CEPH_CRYPTO_AES);
+ if (! cryptohandler) {
+ return -EINVAL;
+ }
+ string secret_s = cct->_conf->rgw_sts_key;
+ buffer::ptr secret(secret_s.c_str(), secret_s.length());
+ int ret = 0;
+ if (ret = cryptohandler->validate_secret(secret); ret < 0) {
+ ldout(cct, 0) << "ERROR: Invalid secret key" << dendl;
+ return -EINVAL;
+ }
+ string error;
+ auto* keyhandler = cryptohandler->get_key_handler(secret, error);
+ if (! keyhandler) {
+ return -EINVAL;
+ }
+ error.clear();
+
+ string decrypted_str;
+ buffer::list en_input, dec_output;
+ en_input = buffer::list::static_from_string(decodedSessionToken);
+
+ ret = keyhandler->decrypt(en_input, dec_output, &error);
+ if (ret < 0) {
+ ldout(cct, 0) << "ERROR: Decryption failed: " << error << dendl;
+ return -EPERM;
+ } else {
+ dec_output.append('\0');
+ auto iter = dec_output.cbegin();
+ decode(token, iter);
+ }
+ return 0;
+}
+
+rgw::auth::Engine::result_t
+rgw::auth::s3::STSEngine::authenticate(
+ const boost::string_view& _access_key_id,
+ const boost::string_view& signature,
+ const boost::string_view& session_token,
+ const string_to_sign_t& string_to_sign,
+ const signature_factory_t& signature_factory,
+ const completer_factory_t& completer_factory,
+ const req_state* const s) const
+{
+ STS::SessionToken token;
+ if (int ret = get_session_token(session_token, token); ret < 0) {
+ return result_t::deny(ret);
+ }
+ //Authentication
+ //Check if the token has expired
+ if (! token.expiration.empty()) {
+ std::string expiration = token.expiration;
+ if (! expiration.empty()) {
+ boost::optional<real_clock::time_point> exp = ceph::from_iso_8601(expiration, false);
+ if (exp) {
+ real_clock::time_point now = real_clock::now();
+ if (now >= *exp) {
+ ldout(cct, 0) << "ERROR: Token expired" << dendl;
+ return result_t::deny(-EPERM);
+ }
+ } else {
+ ldout(cct, 0) << "ERROR: Invalid expiration: " << expiration << dendl;
+ return result_t::deny(-EPERM);
+ }
+ }
+ }
+ //Check for signature mismatch
+ const VersionAbstractor::server_signature_t server_signature = \
+ signature_factory(cct, token.secret_access_key, string_to_sign);
+ auto compare = signature.compare(server_signature);
+
+ ldout(cct, 15) << "string_to_sign="
+ << rgw::crypt_sanitize::log_content{string_to_sign}
+ << dendl;
+ ldout(cct, 15) << "server signature=" << server_signature << dendl;
+ ldout(cct, 15) << "client signature=" << signature << dendl;
+ ldout(cct, 15) << "compare=" << compare << dendl;
+
+ if (compare != 0) {
+ return result_t::deny(-ERR_SIGNATURE_NO_MATCH);
+ }
+
+ // Get all the authorization info
+ RGWUserInfo user_info;
+ vector<string> role_policies;
+ if (! token.roleId.empty()) {
+ RGWRole role(s->cct, store, token.roleId);
+ if (role.get_by_id() < 0) {
+ return result_t::deny(-EPERM);
+ }
+ vector<string> role_policy_names = role.get_role_policy_names();
+ for (auto& policy_name : role_policy_names) {
+ string perm_policy;
+ if (int ret = role.get_role_policy(policy_name, perm_policy); ret == 0) {
+ role_policies.push_back(std::move(perm_policy));
+ }
+ }
+ role_policies.push_back(std::move(token.policy));
+ }
+ if (! token.user.empty()) {
+ // get user info
+ int ret = rgw_get_user_info_by_uid(store, token.user, user_info, NULL);
+ if (ret < 0) {
+ ldout(cct, 5) << "ERROR: failed reading user info: uid=" << token.user << dendl;
+ return result_t::deny(-EPERM);
+ }
+ }
+ if (token.acct_type == TYPE_RGW) {
+ string subuser;
+ auto apl = local_apl_factory->create_apl_local(cct, s, user_info, subuser, role_policies);
+ return result_t::grant(std::move(apl), completer_factory(token.secret_access_key));
+ } else 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));
+ return result_t::grant(std::move(apl), completer_factory(boost::none));
+ }
+
+ return result_t::deny(-EPERM);
+}
+
bool rgw::auth::s3::S3AnonymousEngine::is_applicable(
const req_state* s
) const noexcept {
#include "rgw_auth.h"
#include "rgw_auth_filters.h"
+#include "rgw_sts.h"
struct rgw_http_error {
int http_ret;
using access_key_id_t = boost::string_view;
using client_signature_t = boost::string_view;
+ using session_token_t = boost::string_view;
using server_signature_t = basic_sstring<char, uint16_t, SIGNATURE_MAX_SIZE>;
using string_to_sign_t = std::string;
struct auth_data_t {
access_key_id_t access_key_id;
client_signature_t client_signature;
+ session_token_t session_token;
string_to_sign_t string_to_sign;
signature_factory_t signature_factory;
completer_factory_t completer_factory;
* Replace these thing with a simple, dedicated structure. */
virtual result_t authenticate(const boost::string_view& access_key_id,
const boost::string_view& signature,
+ const boost::string_view& session_token,
const string_to_sign_t& string_to_sign,
const signature_factory_t& signature_factory,
const completer_factory_t& completer_factory,
result_t authenticate(const boost::string_view& access_key_id,
const boost::string_view& signature,
+ const boost::string_view& session_token,
const string_to_sign_t& string_to_sign,
const signature_factory_t&,
const completer_factory_t& completer_factory,
result_t authenticate(const boost::string_view& access_key_id,
const boost::string_view& signature,
+ const boost::string_view& session_token,
const string_to_sign_t& string_to_sign,
const signature_factory_t& signature_factory,
const completer_factory_t& completer_factory,
}
};
+class STSEngine : public AWSEngine {
+ RGWRados* const store;
+ const rgw::auth::LocalApplier::Factory* const local_apl_factory;
+ const rgw::auth::RemoteApplier::Factory* const remote_apl_factory;
+
+ using acl_strategy_t = rgw::auth::RemoteApplier::acl_strategy_t;
+ using auth_info_t = rgw::auth::RemoteApplier::AuthInfo;
+
+ acl_strategy_t get_acl_strategy() const { return nullptr; };
+ auth_info_t get_creds_info(const STS::SessionToken& token) const noexcept;
+
+ int get_session_token(const boost::string_view& session_token,
+ STS::SessionToken& token) const;
+
+ result_t authenticate(const boost::string_view& access_key_id,
+ const boost::string_view& signature,
+ const boost::string_view& session_token,
+ const string_to_sign_t& string_to_sign,
+ const signature_factory_t& signature_factory,
+ const completer_factory_t& completer_factory,
+ const req_state* s) const override;
+public:
+ STSEngine(CephContext* const cct,
+ RGWRados* const store,
+ const VersionAbstractor& ver_abstractor,
+ const rgw::auth::LocalApplier::Factory* const local_apl_factory,
+ const rgw::auth::RemoteApplier::Factory* const remote_apl_factory)
+ : AWSEngine(cct, ver_abstractor),
+ store(store),
+ local_apl_factory(local_apl_factory),
+ remote_apl_factory(remote_apl_factory) {
+ }
+
+ using AWSEngine::authenticate;
+
+ const char* get_name() const noexcept override {
+ return "rgw::auth::s3::STSEngine";
+ }
+};
class S3AnonymousEngine : public rgw::auth::AnonymousEngine {
bool is_applicable(const req_state* s) const noexcept override;
aplptr_t create_apl_local(CephContext* const cct,
const req_state* const s,
const RGWUserInfo& user_info,
- const std::string& subuser) const override {
+ const std::string& subuser,
+ const boost::optional<vector<std::string> >& role_policies) const override {
return aplptr_t(
- new rgw::auth::LocalApplier(cct, user_info, subuser));
+ new rgw::auth::LocalApplier(cct, user_info, subuser, role_policies));
}
};
}
auto apl = apl_factory->create_apl_local(cct, s, tmp_uinfo,
- extract_swift_subuser(swift_user));
+ extract_swift_subuser(swift_user),
+ boost::none);
return result_t::grant(std::move(apl));
}
}
auto apl = apl_factory->create_apl_local(cct, s, user_info,
- extract_swift_subuser(swift_user));
+ extract_swift_subuser(swift_user),
+ boost::none);
return result_t::grant(std::move(apl));
}
public:
TempURLApplier(CephContext* const cct,
const RGWUserInfo& user_info)
- : LocalApplier(cct, user_info, LocalApplier::NO_SUBUSER) {
+ : LocalApplier(cct, user_info, LocalApplier::NO_SUBUSER, boost::none) {
};
void modify_request_state(req_state * s) const override; /* in/out */
aplptr_t create_apl_local(CephContext* const cct,
const req_state* const s,
const RGWUserInfo& user_info,
- const std::string& subuser) const override {
+ const std::string& subuser,
+ const boost::optional<vector<std::string> >& role_policies) const override {
auto apl = \
rgw::auth::add_3rdparty(store, s->account_name,
rgw::auth::add_sysreq(cct, store, s,
- rgw::auth::LocalApplier(cct, user_info, subuser)));
+ rgw::auth::LocalApplier(cct, user_info, subuser, boost::none)));
/* TODO(rzarzynski): replace with static_ptr. */
return aplptr_t(new decltype(apl)(std::move(apl)));
}