rgw::sal::Driver* driver;
Role role;
TokenAttrs token_attrs;
+ bool is_system_request;
public:
RoleApplier(CephContext* const cct,
rgw::sal::Driver* driver,
const Role& role,
- const TokenAttrs& token_attrs)
+ const TokenAttrs& token_attrs,
+ bool is_system_request)
: cct(cct),
driver(driver),
role(role),
- token_attrs(token_attrs) {}
+ token_attrs(token_attrs),
+ is_system_request(is_system_request) {}
ACLOwner get_aclowner() const override;
uint32_t get_perms_from_aclspec(const DoutPrefixProvider* dpp, const aclspec_t& aclspec) const override {
struct Factory {
virtual ~Factory() {}
- virtual aplptr_t create_apl_role(CephContext* cct,
- const req_state* s,
- Role role,
- TokenAttrs token_attrs) const = 0;
- };
+ virtual aplptr_t create_apl_role( CephContext* cct,
+ const req_state* s,
+ Role role,
+ TokenAttrs token_attrs,
+ bool is_system_request) const = 0;
+ };
};
class ServiceIdentity : public Identity {
aplptr_t create_apl_role(CephContext* const cct,
const req_state* const s,
RoleApplier::Role role,
- RoleApplier::TokenAttrs token_attrs) const override {
+ RoleApplier::TokenAttrs token_attrs,
+ bool is_system_request) const override {
auto apl = rgw::auth::add_sysreq(cct, driver, s,
- rgw::auth::RoleApplier(cct, driver, std::move(role), std::move(token_attrs)));
+ rgw::auth::RoleApplier(cct, driver, std::move(role), std::move(token_attrs), is_system_request));
return aplptr_t(new decltype(apl)(std::move(apl)));
}
const req_state* const s,
optional_yield y) const
{
+ bool is_system_request{false};
if (! s->info.args.exists("x-amz-security-token") &&
! s->info.env->exists("HTTP_X_AMZ_SECURITY_TOKEN") &&
s->auth.s3_postobj_creds.x_amz_security_token.empty()) {
return result_t::reject(ret);
}
//Authentication
+ std::string secret_access_key;
//Check if access key is not the same passed in by client
if (token.access_key_id != _access_key_id) {
- ldpp_dout(dpp, 0) << "Invalid access key" << dendl;
- return result_t::reject(-EPERM);
+ /* In case the request is forwarded from secondary in case of multi-site,
+ we by-pass authentication using the session token credentials,
+ instead we use the system user's credentials that was used to sign
+ this request */
+ std::unique_ptr<rgw::sal::User> user;
+ const std::string access_key_id(_access_key_id);
+ if (driver->get_user_by_access_key(dpp, access_key_id, y, &user) < 0) {
+ ldpp_dout(dpp, 5) << "error reading user info, uid=" << access_key_id
+ << " can't authenticate" << dendl;
+ return result_t::reject(-ERR_INVALID_ACCESS_KEY);
+ }
+ // only allow system users as this could be a forwarded request from secondary
+ if (user->get_info().system && driver->is_meta_master()) {
+ 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;
+ return result_t::reject(-EPERM);
+ }
+ const RGWAccessKey& k = iter->second;
+ secret_access_key = k.key;
+ is_system_request = true;
+ } else {
+ ldpp_dout(dpp, 0) << "Invalid access key" << dendl;
+ return result_t::reject(-EPERM);
+ }
+ } else {
+ secret_access_key = token.secret_access_key;
}
//Check if the token has expired
if (! token.expiration.empty()) {
}
//Check for signature mismatch
const VersionAbstractor::server_signature_t server_signature = \
- signature_factory(cct, token.secret_access_key, string_to_sign);
+ signature_factory(cct, secret_access_key, string_to_sign);
auto compare = signature.compare(server_signature);
ldpp_dout(dpp, 15) << "string_to_sign="
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, std::move(r),
- std::move(t_attrs));
+ std::move(t_attrs), is_system_request);
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()) {