]>
git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_auth.cc
c23eaee0e3429ea6c0c6912d118197c7d1117e53
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
7 #include "rgw_common.h"
11 #include "rgw_http_client.h"
12 #include "rgw_keystone.h"
15 #include "include/str_list.h"
17 #define dout_context g_ceph_context
18 #define dout_subsys ceph_subsys_rgw
24 std::unique_ptr
<rgw::auth::Identity
>
25 transform_old_authinfo(CephContext
* const cct
,
26 const rgw_user
& auth_id
,
31 /* This class is not intended for public use. Should be removed altogether
32 * with this function after moving all our APIs to the new authentication
34 class DummyIdentityApplier
: public rgw::auth::Identity
{
35 CephContext
* const cct
;
37 /* For this particular case it's OK to use rgw_user structure to convey
38 * the identity info as this was the policy for doing that before the
45 DummyIdentityApplier(CephContext
* const cct
,
46 const rgw_user
& auth_id
,
57 uint32_t get_perms_from_aclspec(const DoutPrefixProvider
* dpp
, const aclspec_t
& aclspec
) const override
{
58 return rgw_perms_from_aclspec_default_strategy(id
, aclspec
);
61 bool is_admin_of(const rgw_user
& acct_id
) const override
{
65 bool is_owner_of(const rgw_user
& acct_id
) const override
{
69 bool is_identity(const idset_t
& ids
) const override
{
71 if (p
.is_wildcard()) {
73 } else if (p
.is_tenant() && p
.get_tenant() == id
.tenant
) {
75 } else if (p
.is_user() &&
76 (p
.get_tenant() == id
.tenant
) &&
77 (p
.get_id() == id
.id
)) {
84 uint32_t get_perm_mask() const override
{
88 uint32_t get_identity_type() const override
{
92 string
get_acct_name() const override
{
96 string
get_subuser() const override
{
100 void to_str(std::ostream
& out
) const override
{
101 out
<< "RGWDummyIdentityApplier(auth_id=" << id
102 << ", perm_mask=" << perm_mask
103 << ", is_admin=" << is_admin
<< ")";
107 return std::unique_ptr
<rgw::auth::Identity
>(
108 new DummyIdentityApplier(cct
,
115 std::unique_ptr
<rgw::auth::Identity
>
116 transform_old_authinfo(const req_state
* const s
)
118 return transform_old_authinfo(s
->cct
,
121 /* System user has admin permissions by default - it's supposed to pass
122 * through any security check. */
124 s
->user
->get_type());
127 } /* namespace auth */
128 } /* namespace rgw */
131 uint32_t rgw_perms_from_aclspec_default_strategy(
133 const rgw::auth::Identity::aclspec_t
& aclspec
)
135 dout(5) << "Searching permissions for uid=" << uid
<< dendl
;
137 const auto iter
= aclspec
.find(uid
.to_str());
138 if (std::end(aclspec
) != iter
) {
139 dout(5) << "Found permission: " << iter
->second
<< dendl
;
143 dout(5) << "Permissions for user not found" << dendl
;
148 static inline const std::string
make_spec_item(const std::string
& tenant
,
149 const std::string
& id
)
151 return tenant
+ ":" + id
;
155 static inline std::pair
<bool, rgw::auth::Engine::result_t
>
156 strategy_handle_rejected(rgw::auth::Engine::result_t
&& engine_result
,
157 const rgw::auth::Strategy::Control policy
,
158 rgw::auth::Engine::result_t
&& strategy_result
)
160 using Control
= rgw::auth::Strategy::Control
;
162 case Control::REQUISITE
:
163 /* Don't try next. */
164 return std::make_pair(false, std::move(engine_result
));
166 case Control::SUFFICIENT
:
167 /* Don't try next. */
168 return std::make_pair(false, std::move(engine_result
));
170 case Control::FALLBACK
:
171 /* Don't try next. */
172 return std::make_pair(false, std::move(strategy_result
));
175 /* Huh, memory corruption? */
180 static inline std::pair
<bool, rgw::auth::Engine::result_t
>
181 strategy_handle_denied(rgw::auth::Engine::result_t
&& engine_result
,
182 const rgw::auth::Strategy::Control policy
,
183 rgw::auth::Engine::result_t
&& strategy_result
)
185 using Control
= rgw::auth::Strategy::Control
;
187 case Control::REQUISITE
:
188 /* Don't try next. */
189 return std::make_pair(false, std::move(engine_result
));
191 case Control::SUFFICIENT
:
193 return std::make_pair(true, std::move(engine_result
));
195 case Control::FALLBACK
:
196 return std::make_pair(true, std::move(strategy_result
));
199 /* Huh, memory corruption? */
204 static inline std::pair
<bool, rgw::auth::Engine::result_t
>
205 strategy_handle_granted(rgw::auth::Engine::result_t
&& engine_result
,
206 const rgw::auth::Strategy::Control policy
,
207 rgw::auth::Engine::result_t
&& strategy_result
)
209 using Control
= rgw::auth::Strategy::Control
;
211 case Control::REQUISITE
:
213 return std::make_pair(true, std::move(engine_result
));
215 case Control::SUFFICIENT
:
216 /* Don't try next. */
217 return std::make_pair(false, std::move(engine_result
));
219 case Control::FALLBACK
:
220 /* Don't try next. */
221 return std::make_pair(false, std::move(engine_result
));
224 /* Huh, memory corruption? */
229 rgw::auth::Engine::result_t
230 rgw::auth::Strategy::authenticate(const DoutPrefixProvider
* dpp
, const req_state
* const s
, optional_yield y
) const
232 result_t strategy_result
= result_t::deny();
234 for (const stack_item_t
& kv
: auth_stack
) {
235 const rgw::auth::Engine
& engine
= kv
.first
;
236 const auto& policy
= kv
.second
;
238 ldpp_dout(dpp
, 20) << get_name() << ": trying " << engine
.get_name() << dendl
;
240 result_t engine_result
= result_t::deny();
242 engine_result
= engine
.authenticate(dpp
, s
, y
);
243 } catch (const int err
) {
244 engine_result
= result_t::deny(err
);
247 bool try_next
= true;
248 switch (engine_result
.get_status()) {
249 case result_t::Status::REJECTED
: {
250 ldpp_dout(dpp
, 20) << engine
.get_name() << " rejected with reason="
251 << engine_result
.get_reason() << dendl
;
253 std::tie(try_next
, strategy_result
) = \
254 strategy_handle_rejected(std::move(engine_result
), policy
,
255 std::move(strategy_result
));
258 case result_t::Status::DENIED
: {
259 ldpp_dout(dpp
, 20) << engine
.get_name() << " denied with reason="
260 << engine_result
.get_reason() << dendl
;
262 std::tie(try_next
, strategy_result
) = \
263 strategy_handle_denied(std::move(engine_result
), policy
,
264 std::move(strategy_result
));
267 case result_t::Status::GRANTED
: {
268 ldpp_dout(dpp
, 20) << engine
.get_name() << " granted access" << dendl
;
270 std::tie(try_next
, strategy_result
) = \
271 strategy_handle_granted(std::move(engine_result
), policy
,
272 std::move(strategy_result
));
285 return strategy_result
;
289 rgw::auth::Strategy::apply(const DoutPrefixProvider
*dpp
, const rgw::auth::Strategy
& auth_strategy
,
290 req_state
* const s
, optional_yield y
) noexcept
293 auto result
= auth_strategy
.authenticate(dpp
, s
, y
);
294 if (result
.get_status() != decltype(result
)::Status::GRANTED
) {
295 /* Access denied is acknowledged by returning a std::unique_ptr with
297 ldpp_dout(dpp
, 5) << "Failed the auth strategy, reason="
298 << result
.get_reason() << dendl
;
299 return result
.get_reason();
303 rgw::auth::IdentityApplier::aplptr_t applier
= result
.get_applier();
304 rgw::auth::Completer::cmplptr_t completer
= result
.get_completer();
306 /* Account used by a given RGWOp is decoupled from identity employed
307 * in the authorization phase (RGWOp::verify_permissions). */
308 applier
->load_acct_info(dpp
, s
->user
->get_info());
309 s
->perm_mask
= applier
->get_perm_mask();
311 /* This is the single place where we pass req_state as a pointer
312 * to non-const and thus its modification is allowed. In the time
313 * of writing only RGWTempURLEngine needed that feature. */
314 applier
->modify_request_state(dpp
, s
);
316 completer
->modify_request_state(dpp
, s
);
319 s
->auth
.identity
= std::move(applier
);
320 s
->auth
.completer
= std::move(completer
);
323 } catch (const int err
) {
324 ldpp_dout(dpp
, 5) << "applier throwed err=" << err
<< dendl
;
326 } catch (const std::exception
& e
) {
327 ldpp_dout(dpp
, 5) << "applier throwed unexpected err: " << e
.what()
331 } catch (const int err
) {
332 ldpp_dout(dpp
, 5) << "auth engine throwed err=" << err
<< dendl
;
334 } catch (const std::exception
& e
) {
335 ldpp_dout(dpp
, 5) << "auth engine throwed unexpected err: " << e
.what()
339 /* We never should be here. */
344 rgw::auth::Strategy::add_engine(const Control ctrl_flag
,
345 const Engine
& engine
) noexcept
347 auth_stack
.push_back(std::make_pair(std::cref(engine
), ctrl_flag
));
350 void rgw::auth::WebIdentityApplier::to_str(std::ostream
& out
) const
352 out
<< "rgw::auth::WebIdentityApplier(sub =" << token_claims
.sub
353 << ", user_name=" << token_claims
.user_name
354 << ", aud =" << token_claims
.aud
355 << ", provider_id =" << token_claims
.iss
<< ")";
358 string
rgw::auth::WebIdentityApplier::get_idp_url() const
360 string idp_url
= token_claims
.iss
;
361 idp_url
= url_remove_prefix(idp_url
);
365 void rgw::auth::WebIdentityApplier::create_account(const DoutPrefixProvider
* dpp
,
366 const rgw_user
& acct_user
,
367 const string
& display_name
,
368 RGWUserInfo
& user_info
) const /* out */
370 user_info
.user_id
= acct_user
;
371 user_info
.display_name
= display_name
;
372 user_info
.type
= TYPE_WEB
;
374 user_info
.max_buckets
=
375 cct
->_conf
.get_val
<int64_t>("rgw_user_max_buckets");
376 rgw_apply_default_bucket_quota(user_info
.bucket_quota
, cct
->_conf
);
377 rgw_apply_default_user_quota(user_info
.user_quota
, cct
->_conf
);
379 int ret
= ctl
->user
->store_info(user_info
, null_yield
,
380 RGWUserCtl::PutParams().set_exclusive(true));
382 ldpp_dout(dpp
, 0) << "ERROR: failed to store new user info: user="
383 << user_info
.user_id
<< " ret=" << ret
<< dendl
;
388 void rgw::auth::WebIdentityApplier::load_acct_info(const DoutPrefixProvider
* dpp
, RGWUserInfo
& user_info
) const {
389 rgw_user federated_user
;
390 federated_user
.id
= token_claims
.sub
;
391 federated_user
.tenant
= role_tenant
;
392 federated_user
.ns
= "oidc";
394 //Check in oidc namespace
395 if (ctl
->user
->get_info_by_uid(federated_user
, &user_info
, null_yield
) >= 0) {
400 federated_user
.ns
.clear();
401 //Check for old users which wouldn't have been created in oidc namespace
402 if (ctl
->user
->get_info_by_uid(federated_user
, &user_info
, null_yield
) >= 0) {
407 //Check if user_id.buckets already exists, may have been from the time, when shadow users didnt exist
408 RGWStorageStats stats
;
409 int ret
= ctl
->user
->read_stats(federated_user
, &stats
, null_yield
);
410 if (ret
< 0 && ret
!= -ENOENT
) {
411 ldpp_dout(dpp
, 0) << "ERROR: reading stats for the user returned error " << ret
<< dendl
;
414 if (ret
== -ENOENT
) { /* in case of ENOENT, which means user doesnt have buckets */
415 //In this case user will be created in oidc namespace
416 ldpp_dout(dpp
, 5) << "NOTICE: incoming user has no buckets " << federated_user
<< dendl
;
417 federated_user
.ns
= "oidc";
419 //User already has buckets associated, hence wont be created in oidc namespace.
420 ldpp_dout(dpp
, 5) << "NOTICE: incoming user already has buckets associated " << federated_user
<< ", won't be created in oidc namespace"<< dendl
;
421 federated_user
.ns
= "";
424 ldpp_dout(dpp
, 0) << "NOTICE: couldn't map oidc federated user " << federated_user
<< dendl
;
425 create_account(dpp
, federated_user
, token_claims
.user_name
, user_info
);
428 void rgw::auth::WebIdentityApplier::modify_request_state(const DoutPrefixProvider
*dpp
, req_state
* s
) const
430 s
->info
.args
.append("sub", token_claims
.sub
);
431 s
->info
.args
.append("aud", token_claims
.aud
);
432 s
->info
.args
.append("provider_id", token_claims
.iss
);
433 s
->info
.args
.append("client_id", token_claims
.client_id
);
435 string idp_url
= get_idp_url();
436 string condition
= idp_url
+ ":app_id";
438 s
->env
.emplace(condition
, token_claims
.aud
);
441 condition
= idp_url
+ ":sub";
442 s
->env
.emplace(condition
, token_claims
.sub
);
445 bool rgw::auth::WebIdentityApplier::is_identity(const idset_t
& ids
) const
447 if (ids
.size() > 1) {
451 for (auto id
: ids
) {
452 string idp_url
= get_idp_url();
453 if (id
.is_oidc_provider() && id
.get_idp_url() == idp_url
) {
460 /* rgw::auth::RemoteAuthApplier */
461 uint32_t rgw::auth::RemoteApplier::get_perms_from_aclspec(const DoutPrefixProvider
* dpp
, const aclspec_t
& aclspec
) const
465 /* For backward compatibility with ACLOwner. */
466 perm
|= rgw_perms_from_aclspec_default_strategy(info
.acct_user
,
469 /* We also need to cover cases where rgw_keystone_implicit_tenants
471 if (info
.acct_user
.tenant
.empty()) {
472 const rgw_user
tenanted_acct_user(info
.acct_user
.id
, info
.acct_user
.id
);
474 perm
|= rgw_perms_from_aclspec_default_strategy(tenanted_acct_user
,
478 /* Now it's a time for invoking additional strategy that was supplied by
479 * a specific auth engine. */
480 if (extra_acl_strategy
) {
481 perm
|= extra_acl_strategy(aclspec
);
484 ldpp_dout(dpp
, 20) << "from ACL got perm=" << perm
<< dendl
;
488 bool rgw::auth::RemoteApplier::is_admin_of(const rgw_user
& uid
) const
490 return info
.is_admin
;
493 bool rgw::auth::RemoteApplier::is_owner_of(const rgw_user
& uid
) const
495 if (info
.acct_user
.tenant
.empty()) {
496 const rgw_user
tenanted_acct_user(info
.acct_user
.id
, info
.acct_user
.id
);
498 if (tenanted_acct_user
== uid
) {
503 return info
.acct_user
== uid
;
506 bool rgw::auth::RemoteApplier::is_identity(const idset_t
& ids
) const {
507 for (auto& id
: ids
) {
508 if (id
.is_wildcard()) {
511 // We also need to cover cases where rgw_keystone_implicit_tenants
513 } else if (id
.is_tenant() &&
514 (info
.acct_user
.tenant
.empty() ?
516 info
.acct_user
.tenant
) == id
.get_tenant()) {
518 } else if (id
.is_user() &&
519 info
.acct_user
.id
== id
.get_id() &&
520 (info
.acct_user
.tenant
.empty() ?
522 info
.acct_user
.tenant
) == id
.get_tenant()) {
529 void rgw::auth::RemoteApplier::to_str(std::ostream
& out
) const
531 out
<< "rgw::auth::RemoteApplier(acct_user=" << info
.acct_user
532 << ", acct_name=" << info
.acct_name
533 << ", perm_mask=" << info
.perm_mask
534 << ", is_admin=" << info
.is_admin
<< ")";
537 void rgw::auth::ImplicitTenants::recompute_value(const ConfigProxy
& c
)
539 std::string s
= c
.get_val
<std::string
>("rgw_keystone_implicit_tenants");
541 if (boost::iequals(s
, "both")
542 || boost::iequals(s
, "true")
543 || boost::iequals(s
, "1")) {
544 v
= IMPLICIT_TENANTS_S3
|IMPLICIT_TENANTS_SWIFT
;
545 } else if (boost::iequals(s
, "0")
546 || boost::iequals(s
, "none")
547 || boost::iequals(s
, "false")) {
549 } else if (boost::iequals(s
, "s3")) {
550 v
= IMPLICIT_TENANTS_S3
;
551 } else if (boost::iequals(s
, "swift")) {
552 v
= IMPLICIT_TENANTS_SWIFT
;
553 } else { /* "" (and anything else) */
554 v
= IMPLICIT_TENANTS_BAD
;
560 const char **rgw::auth::ImplicitTenants::get_tracked_conf_keys() const
562 static const char *keys
[] = {
563 "rgw_keystone_implicit_tenants",
568 void rgw::auth::ImplicitTenants::handle_conf_change(const ConfigProxy
& c
,
569 const std::set
<std::string
> &changed
)
571 if (changed
.count("rgw_keystone_implicit_tenants")) {
576 void rgw::auth::RemoteApplier::create_account(const DoutPrefixProvider
* dpp
,
577 const rgw_user
& acct_user
,
578 bool implicit_tenant
,
579 RGWUserInfo
& user_info
) const /* out */
581 rgw_user new_acct_user
= acct_user
;
583 if (info
.acct_type
) {
584 //ldap/keystone for s3 users
585 user_info
.type
= info
.acct_type
;
588 /* An upper layer may enforce creating new accounts within their own
590 if (new_acct_user
.tenant
.empty() && implicit_tenant
) {
591 new_acct_user
.tenant
= new_acct_user
.id
;
594 user_info
.user_id
= new_acct_user
;
595 user_info
.display_name
= info
.acct_name
;
597 user_info
.max_buckets
=
598 cct
->_conf
.get_val
<int64_t>("rgw_user_max_buckets");
599 rgw_apply_default_bucket_quota(user_info
.bucket_quota
, cct
->_conf
);
600 rgw_apply_default_user_quota(user_info
.user_quota
, cct
->_conf
);
602 int ret
= ctl
->user
->store_info(user_info
, null_yield
,
603 RGWUserCtl::PutParams().set_exclusive(true));
605 ldpp_dout(dpp
, 0) << "ERROR: failed to store new user info: user="
606 << user_info
.user_id
<< " ret=" << ret
<< dendl
;
611 /* TODO(rzarzynski): we need to handle display_name changes. */
612 void rgw::auth::RemoteApplier::load_acct_info(const DoutPrefixProvider
* dpp
, RGWUserInfo
& user_info
) const /* out */
614 /* It's supposed that RGWRemoteAuthApplier tries to load account info
615 * that belongs to the authenticated identity. Another policy may be
616 * applied by using a RGWThirdPartyAccountAuthApplier decorator. */
617 const rgw_user
& acct_user
= info
.acct_user
;
618 auto implicit_value
= implicit_tenant_context
.get_value();
619 bool implicit_tenant
= implicit_value
.implicit_tenants_for_(implicit_tenant_bit
);
620 bool split_mode
= implicit_value
.is_split_mode();
622 /* Normally, empty "tenant" field of acct_user means the authenticated
623 * identity has the legacy, global tenant. However, due to inclusion
624 * of multi-tenancy, we got some special compatibility kludge for remote
625 * backends like Keystone.
626 * If the global tenant is the requested one, we try the same tenant as
627 * the user name first. If that RGWUserInfo exists, we use it. This way,
628 * migrated OpenStack users can get their namespaced containers and nobody's
630 * If that fails, we look up in the requested (possibly empty) tenant.
631 * If that fails too, we create the account within the global or separated
632 * namespace depending on rgw_keystone_implicit_tenants.
633 * For compatibility with previous versions of ceph, it is possible
634 * to enable implicit_tenants for only s3 or only swift.
635 * in this mode ("split_mode"), we must constrain the id lookups to
636 * only use the identifier space that would be used if the id were
639 if (split_mode
&& !implicit_tenant
)
640 ; /* suppress lookup for id used by "other" protocol */
641 else if (acct_user
.tenant
.empty()) {
642 const rgw_user
tenanted_uid(acct_user
.id
, acct_user
.id
);
644 if (ctl
->user
->get_info_by_uid(tenanted_uid
, &user_info
, null_yield
) >= 0) {
650 if (split_mode
&& implicit_tenant
)
651 ; /* suppress lookup for id used by "other" protocol */
652 else if (ctl
->user
->get_info_by_uid(acct_user
, &user_info
, null_yield
) >= 0) {
657 ldpp_dout(dpp
, 0) << "NOTICE: couldn't map swift user " << acct_user
<< dendl
;
658 create_account(dpp
, acct_user
, implicit_tenant
, user_info
);
660 /* Succeeded if we are here (create_account() hasn't throwed). */
663 /* rgw::auth::LocalApplier */
664 /* static declaration */
665 const std::string
rgw::auth::LocalApplier::NO_SUBUSER
;
667 uint32_t rgw::auth::LocalApplier::get_perms_from_aclspec(const DoutPrefixProvider
* dpp
, const aclspec_t
& aclspec
) const
669 return rgw_perms_from_aclspec_default_strategy(user_info
.user_id
, aclspec
);
672 bool rgw::auth::LocalApplier::is_admin_of(const rgw_user
& uid
) const
674 return user_info
.admin
|| user_info
.system
;
677 bool rgw::auth::LocalApplier::is_owner_of(const rgw_user
& uid
) const
679 return uid
== user_info
.user_id
;
682 bool rgw::auth::LocalApplier::is_identity(const idset_t
& ids
) const {
683 for (auto& id
: ids
) {
684 if (id
.is_wildcard()) {
686 } else if (id
.is_tenant() &&
687 id
.get_tenant() == user_info
.user_id
.tenant
) {
689 } else if (id
.is_user() &&
690 (id
.get_tenant() == user_info
.user_id
.tenant
)) {
691 if (id
.get_id() == user_info
.user_id
.id
) {
694 std::string wildcard_subuser
= user_info
.user_id
.id
;
695 wildcard_subuser
.append(":*");
696 if (wildcard_subuser
== id
.get_id()) {
698 } else if (subuser
!= NO_SUBUSER
) {
699 std::string user
= user_info
.user_id
.id
;
701 user
.append(subuser
);
702 if (user
== id
.get_id()) {
711 void rgw::auth::LocalApplier::to_str(std::ostream
& out
) const {
712 out
<< "rgw::auth::LocalApplier(acct_user=" << user_info
.user_id
713 << ", acct_name=" << user_info
.display_name
714 << ", subuser=" << subuser
715 << ", perm_mask=" << get_perm_mask()
716 << ", is_admin=" << static_cast<bool>(user_info
.admin
) << ")";
719 uint32_t rgw::auth::LocalApplier::get_perm_mask(const std::string
& subuser_name
,
720 const RGWUserInfo
&uinfo
) const
722 if (! subuser_name
.empty() && subuser_name
!= NO_SUBUSER
) {
723 const auto iter
= uinfo
.subusers
.find(subuser_name
);
725 if (iter
!= std::end(uinfo
.subusers
)) {
726 return iter
->second
.perm_mask
;
728 /* Subuser specified but not found. */
729 return RGW_PERM_NONE
;
732 /* Due to backward compatibility. */
733 return RGW_PERM_FULL_CONTROL
;
737 void rgw::auth::LocalApplier::load_acct_info(const DoutPrefixProvider
* dpp
, RGWUserInfo
& user_info
) const /* out */
739 /* Load the account that belongs to the authenticated identity. An extra call
740 * to RADOS may be safely skipped in this case. */
741 user_info
= this->user_info
;
744 void rgw::auth::RoleApplier::to_str(std::ostream
& out
) const {
745 out
<< "rgw::auth::LocalApplier(role name =" << role
.name
;
746 for (auto& policy
: role
.role_policies
) {
747 out
<< ", role policy =" << policy
;
749 out
<< ", token policy =" << token_policy
;
753 bool rgw::auth::RoleApplier::is_identity(const idset_t
& ids
) const {
754 for (auto& p
: ids
) {
755 if (p
.is_wildcard()) {
757 } else if (p
.is_role()) {
758 string name
= p
.get_id();
759 string tenant
= p
.get_tenant();
760 if (name
== role
.name
&& tenant
== role
.tenant
) {
763 } else if (p
.is_assumed_role()) {
764 string tenant
= p
.get_tenant();
765 string role_session
= role
.name
+ "/" + role_session_name
; //role/role-session
766 if (role
.tenant
== tenant
&& role_session
== p
.get_role_session()) {
770 string id
= p
.get_id();
771 string tenant
= p
.get_tenant();
773 if (user_id
.ns
.empty()) {
774 oidc_id
= user_id
.id
;
776 oidc_id
= user_id
.ns
+ "$" + user_id
.id
;
778 if (oidc_id
== id
&& user_id
.tenant
== tenant
) {
786 void rgw::auth::RoleApplier::load_acct_info(const DoutPrefixProvider
* dpp
, RGWUserInfo
& user_info
) const /* out */
788 /* Load the user id */
789 user_info
.user_id
= this->user_id
;
792 void rgw::auth::RoleApplier::modify_request_state(const DoutPrefixProvider
*dpp
, req_state
* s
) const
794 for (auto it
: role
.role_policies
) {
796 bufferlist bl
= bufferlist::static_from_string(it
);
797 const rgw::IAM::Policy
p(s
->cct
, role
.tenant
, bl
);
798 s
->iam_user_policies
.push_back(std::move(p
));
799 } catch (rgw::IAM::PolicyParseException
& e
) {
800 //Control shouldn't reach here as the policy has already been
802 ldpp_dout(dpp
, 20) << "failed to parse role policy: " << e
.what() << dendl
;
807 string policy
= this->token_policy
;
808 bufferlist bl
= bufferlist::static_from_string(policy
);
809 const rgw::IAM::Policy
p(s
->cct
, role
.tenant
, bl
);
810 s
->iam_user_policies
.push_back(std::move(p
));
811 } catch (rgw::IAM::PolicyParseException
& e
) {
812 //Control shouldn't reach here as the policy has already been
814 ldpp_dout(dpp
, 20) << "failed to parse token policy: " << e
.what() << dendl
;
817 string condition
= "aws:userid";
818 string value
= role
.id
+ ":" + role_session_name
;
819 s
->env
.emplace(condition
, value
);
821 s
->env
.emplace("aws:TokenIssueTime", token_issued_at
);
823 s
->token_claims
.emplace_back("sts");
824 for (auto& it
: token_claims
) {
825 s
->token_claims
.emplace_back(it
);
829 rgw::auth::Engine::result_t
830 rgw::auth::AnonymousEngine::authenticate(const DoutPrefixProvider
* dpp
, const req_state
* const s
, optional_yield y
) const
832 if (! is_applicable(s
)) {
833 return result_t::deny(-EPERM
);
835 RGWUserInfo user_info
;
836 rgw_get_anon_user(user_info
);
839 apl_factory
->create_apl_local(cct
, s
, user_info
,
840 rgw::auth::LocalApplier::NO_SUBUSER
,
842 return result_t::grant(std::move(apl
));