1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
5 #ifndef CEPH_RGW_AUTH_H
6 #define CEPH_RGW_AUTH_H
11 #include <type_traits>
12 #include <system_error>
15 #include "rgw_common.h"
16 #include "rgw_web_idp.h"
18 #define RGW_USER_ANON_ID "anonymous"
26 using Exception
= std::system_error
;
29 /* Load information about identity that will be used by RGWOp to authorize
30 * any operation that comes from an authenticated user. */
33 typedef std::map
<std::string
, int> aclspec_t
;
34 using idset_t
= boost::container::flat_set
<Principal
>;
36 virtual ~Identity() = default;
38 /* Translate the ACL provided in @aclspec into concrete permission set that
39 * can be used during the authorization phase (RGWOp::verify_permission).
40 * On error throws rgw::auth::Exception storing the reason.
42 * NOTE: an implementation is responsible for giving the real semantic to
43 * the items in @aclspec. That is, their meaning may depend on particular
44 * applier that is being used. */
45 virtual uint32_t get_perms_from_aclspec(const DoutPrefixProvider
* dpp
, const aclspec_t
& aclspec
) const = 0;
47 /* Verify whether a given identity *can be treated as* an admin of rgw_user
48 * (account in Swift's terminology) specified in @uid. On error throws
49 * rgw::auth::Exception storing the reason. */
50 virtual bool is_admin_of(const rgw_user
& uid
) const = 0;
52 /* Verify whether a given identity *is* the owner of the rgw_user (account
53 * in the Swift's terminology) specified in @uid. On internal error throws
54 * rgw::auth::Exception storing the reason. */
55 virtual bool is_owner_of(const rgw_user
& uid
) const = 0;
57 /* Return the permission mask that is used to narrow down the set of
58 * operations allowed for a given identity. This method reflects the idea
59 * of subuser tied to RGWUserInfo. On error throws rgw::auth::Exception
61 virtual uint32_t get_perm_mask() const = 0;
63 virtual bool is_anonymous() const {
64 /* If the identity owns the anonymous account (rgw_user), it's considered
65 * the anonymous identity. On error throws rgw::auth::Exception storing
67 return is_owner_of(rgw_user(RGW_USER_ANON_ID
));
70 virtual void to_str(std::ostream
& out
) const = 0;
72 /* Verify whether a given identity corresponds to an identity in the
74 virtual bool is_identity(const idset_t
& ids
) const = 0;
76 /* Identity Type: RGW/ LDAP/ Keystone */
77 virtual uint32_t get_identity_type() const = 0;
80 virtual std::string
get_acct_name() const = 0;
82 /* Subuser of Account */
83 virtual std::string
get_subuser() const = 0;
85 virtual std::string
get_role_tenant() const { return ""; }
87 /* write any auth-specific fields that are safe to expose in the ops log */
88 virtual void write_ops_log_entry(rgw_log_entry
& entry
) const {};
91 inline std::ostream
& operator<<(std::ostream
& out
,
92 const rgw::auth::Identity
& id
) {
98 std::unique_ptr
<rgw::auth::Identity
>
99 transform_old_authinfo(CephContext
* const cct
,
100 const rgw_user
& auth_id
,
103 const uint32_t type
);
104 std::unique_ptr
<Identity
> transform_old_authinfo(const req_state
* const s
);
107 /* Interface for classes applying changes to request state/RADOS store
108 * imposed by a particular rgw::auth::Engine.
110 * In contrast to rgw::auth::Engine, implementations of this interface
111 * are allowed to handle req_state or RGWUserCtl in the read-write manner.
113 * It's expected that most (if not all) of implementations will also
114 * conform to rgw::auth::Identity interface to provide authorization
115 * policy (ACLs, account's ownership and entitlement). */
116 class IdentityApplier
: public Identity
{
118 typedef std::unique_ptr
<IdentityApplier
> aplptr_t
;
120 virtual ~IdentityApplier() {};
122 /* Fill provided RGWUserInfo with information about the account that
123 * RGWOp will operate on. Errors are handled solely through exceptions.
125 * XXX: be aware that the "account" term refers to rgw_user. The naming
127 virtual void load_acct_info(const DoutPrefixProvider
* dpp
, RGWUserInfo
& user_info
) const = 0; /* out */
129 /* Apply any changes to request state. This method will be most useful for
130 * TempURL of Swift API. */
131 virtual void modify_request_state(const DoutPrefixProvider
* dpp
, req_state
* s
) const {} /* in/out */
135 /* Interface class for completing the two-step authentication process.
136 * Completer provides the second step - the complete() method that should
137 * be called after Engine::authenticate() but before *committing* results
138 * of an RGWOp (or sending a response in the case of non-mutating ops).
140 * The motivation driving the interface is to address those authentication
141 * schemas that require message integrity verification *without* in-memory
142 * data buffering. Typical examples are AWS Auth v4 and the auth mechanism
143 * of browser uploads facilities both in S3 and Swift APIs (see RGWPostObj).
144 * The workflow of request from the authentication point-of-view does look
145 * like following one:
146 * A. authenticate (Engine::authenticate),
147 * B. authorize (see RGWOp::verify_permissions),
148 * C. execute-prepare (init potential data modifications),
149 * D. authenticate-complete - (Completer::complete),
150 * E. execute-commit - commit the modifications from point C. */
153 /* It's expected that Completers would tend to implement many interfaces
154 * and be used not only in req_state::auth::completer. Ref counting their
155 * instances would be helpful. */
156 typedef std::shared_ptr
<Completer
> cmplptr_t
;
158 virtual ~Completer() = default;
160 /* Complete the authentication process. Return boolean indicating whether
161 * the completion succeeded. On error throws rgw::auth::Exception storing
163 virtual bool complete() = 0;
165 /* Apply any changes to request state. The initial use case was injecting
166 * the AWSv4 filter over rgw::io::RestfulClient in req_state. */
167 virtual void modify_request_state(const DoutPrefixProvider
* dpp
, req_state
* s
) = 0; /* in/out */
171 /* Interface class for authentication backends (auth engines) in RadosGW.
173 * An engine is supposed only to authenticate (not authorize!) requests
174 * basing on their req_state and - if access has been granted - provide
175 * an upper layer with:
176 * - rgw::auth::IdentityApplier to commit all changes to the request state as
177 * well as to the RADOS store (creating an account, synchronizing
178 * user-related information with external databases and so on).
179 * - rgw::auth::Completer (optionally) to finish the authentication
180 * of the request. Typical use case is verifying message integrity
181 * in AWS Auth v4 and browser uploads (RGWPostObj).
183 * Both of them are supposed to be wrapped in Engine::AuthResult.
185 * The authentication process consists of two steps:
186 * - Engine::authenticate() which should be called before *initiating*
187 * any modifications to RADOS store that are related to an operation
188 * a client wants to perform (RGWOp::execute).
189 * - Completer::complete() supposed to be called, if completer has been
190 * returned, after the authenticate() step but before *committing*
191 * those modifications or sending a response (RGWOp::complete).
193 * An engine outlives both Applier and Completer. It's intended to live
194 * since RadosGW's initialization and handle multiple requests till
197 * Auth engine MUST NOT make any changes to req_state nor RADOS store.
198 * This is solely an Applier's responsibility!
200 * Separation between authentication and global state modification has
201 * been introduced because many auth engines are orthogonal to appliers
202 * and thus they can be decoupled. Additional motivation is to clearly
203 * distinguish all portions of code modifying data structures. */
206 virtual ~Engine() = default;
209 struct rejection_mark_t
{};
210 bool is_rejected
= false;
213 std::pair
<IdentityApplier::aplptr_t
, Completer::cmplptr_t
> result_pair
;
215 explicit AuthResult(const int reason
)
219 AuthResult(rejection_mark_t
&&, const int reason
)
224 /* Allow only the reasonable combintations - returning just Completer
225 * without accompanying IdentityApplier is strictly prohibited! */
226 explicit AuthResult(IdentityApplier::aplptr_t
&& applier
)
227 : result_pair(std::move(applier
), nullptr) {
230 AuthResult(IdentityApplier::aplptr_t
&& applier
,
231 Completer::cmplptr_t
&& completer
)
232 : result_pair(std::move(applier
), std::move(completer
)) {
237 /* Engine doesn't grant the access but also doesn't reject it. */
240 /* Engine successfully authenicated requester. */
243 /* Engine strictly indicates that a request should be rejected
244 * without trying any further engine. */
248 Status
get_status() const {
250 return Status::REJECTED
;
251 } else if (! result_pair
.first
) {
252 return Status::DENIED
;
254 return Status::GRANTED
;
258 int get_reason() const {
262 IdentityApplier::aplptr_t
get_applier() {
263 return std::move(result_pair
.first
);
266 Completer::cmplptr_t
&& get_completer() {
267 return std::move(result_pair
.second
);
270 static AuthResult
reject(const int reason
= -EACCES
) {
271 return AuthResult(rejection_mark_t(), reason
);
274 static AuthResult
deny(const int reason
= -EACCES
) {
275 return AuthResult(reason
);
278 static AuthResult
grant(IdentityApplier::aplptr_t
&& applier
) {
279 return AuthResult(std::move(applier
));
282 static AuthResult
grant(IdentityApplier::aplptr_t
&& applier
,
283 Completer::cmplptr_t
&& completer
) {
284 return AuthResult(std::move(applier
), std::move(completer
));
288 using result_t
= AuthResult
;
290 /* Get name of the auth engine. */
291 virtual const char* get_name() const noexcept
= 0;
293 /* Throwing method for identity verification. When the check is positive
294 * an implementation should return Engine::result_t containing:
295 * - a non-null pointer to an object conforming the Applier interface.
296 * Otherwise, the authentication is treated as failed.
297 * - a (potentially null) pointer to an object conforming the Completer
300 * On error throws rgw::auth::Exception containing the reason. */
301 virtual result_t
authenticate(const DoutPrefixProvider
* dpp
, const req_state
* s
, optional_yield y
) const = 0;
305 /* Interface for extracting a token basing from data carried by req_state. */
306 class TokenExtractor
{
308 virtual ~TokenExtractor() = default;
309 virtual std::string
get_token(const req_state
* s
) const = 0;
313 /* Abstract class for stacking sub-engines to expose them as a single
314 * Engine. It is responsible for ordering its sub-engines and managing
315 * fall-backs between them. Derivatee is supposed to encapsulate engine
316 * instances and add them using the add_engine() method in the order it
317 * wants to be tried during the call to authenticate().
319 * Each new Strategy should be exposed to StrategyRegistry for handling
320 * the dynamic reconfiguration. */
321 class Strategy
: public Engine
{
323 /* Specifiers controlling what happens when an associated engine fails.
324 * The names and semantic has been borrowed mostly from libpam. */
326 /* Failure of an engine injected with the REQUISITE specifier aborts
327 * the strategy's authentication process immediately. No other engine
331 /* Success of an engine injected with the SUFFICIENT specifier ends
332 * strategy's authentication process successfully. However, denying
333 * doesn't abort it -- there will be fall-back to following engine
334 * if the one that failed wasn't the last one. */
337 /* Like SUFFICIENT with the exception that on failure the reason code
338 * is not overridden. Instead, it's taken directly from the last tried
339 * non-FALLBACK engine. If there was no previous non-FALLBACK engine
340 * in a Strategy, then the result_t::deny(reason = -EACCES) is used. */
344 Engine::result_t
authenticate(const DoutPrefixProvider
* dpp
, const req_state
* s
, optional_yield y
) const override final
;
346 bool is_empty() const {
347 return auth_stack
.empty();
350 static int apply(const DoutPrefixProvider
* dpp
, const Strategy
& auth_strategy
, req_state
* s
, optional_yield y
) noexcept
;
353 /* Using the reference wrapper here to explicitly point out we are not
354 * interested in storing nulls while preserving the dynamic polymorphism. */
355 using stack_item_t
= std::pair
<std::reference_wrapper
<const Engine
>,
357 std::vector
<stack_item_t
> auth_stack
;
360 void add_engine(Control ctrl_flag
, const Engine
& engine
) noexcept
;
364 /* A class aggregating the knowledge about all Strategies in RadosGW. It is
365 * responsible for handling the dynamic reconfiguration on e.g. realm update.
366 * The definition is in rgw/rgw_auth_registry.h,
368 * Each new Strategy should be exposed to it. */
369 class StrategyRegistry
;
371 class WebIdentityApplier
: public IdentityApplier
{
375 std::string client_id
;
376 std::string user_name
;
378 CephContext
* const cct
;
379 rgw::sal::Store
* store
;
380 std::string role_session
;
381 std::string role_tenant
;
382 std::unordered_multimap
<std::string
, std::string
> token_claims
;
383 boost::optional
<std::multimap
<std::string
,std::string
>> role_tags
;
384 boost::optional
<std::set
<std::pair
<std::string
, std::string
>>> principal_tags
;
386 std::string
get_idp_url() const;
388 void create_account(const DoutPrefixProvider
* dpp
,
389 const rgw_user
& acct_user
,
390 const std::string
& display_name
,
391 RGWUserInfo
& user_info
) const; /* out */
393 WebIdentityApplier( CephContext
* const cct
,
394 rgw::sal::Store
* store
,
395 const std::string
& role_session
,
396 const std::string
& role_tenant
,
397 const std::unordered_multimap
<std::string
, std::string
>& token_claims
,
398 boost::optional
<std::multimap
<std::string
,std::string
>> role_tags
,
399 boost::optional
<std::set
<std::pair
<std::string
, std::string
>>> principal_tags
)
402 role_session(role_session
),
403 role_tenant(role_tenant
),
404 token_claims(token_claims
),
405 role_tags(role_tags
),
406 principal_tags(principal_tags
) {
407 const auto& sub
= token_claims
.find("sub");
408 if(sub
!= token_claims
.end()) {
409 this->sub
= sub
->second
;
412 const auto& iss
= token_claims
.find("iss");
413 if(iss
!= token_claims
.end()) {
414 this->iss
= iss
->second
;
417 const auto& aud
= token_claims
.find("aud");
418 if(aud
!= token_claims
.end()) {
419 this->aud
= aud
->second
;
422 const auto& client_id
= token_claims
.find("client_id");
423 if(client_id
!= token_claims
.end()) {
424 this->client_id
= client_id
->second
;
426 const auto& azp
= token_claims
.find("azp");
427 if (azp
!= token_claims
.end()) {
428 this->client_id
= azp
->second
;
432 const auto& user_name
= token_claims
.find("username");
433 if(user_name
!= token_claims
.end()) {
434 this->user_name
= user_name
->second
;
436 const auto& given_username
= token_claims
.find("given_username");
437 if (given_username
!= token_claims
.end()) {
438 this->user_name
= given_username
->second
;
443 void modify_request_state(const DoutPrefixProvider
*dpp
, req_state
* s
) const override
;
445 uint32_t get_perms_from_aclspec(const DoutPrefixProvider
* dpp
, const aclspec_t
& aclspec
) const override
{
446 return RGW_PERM_NONE
;
449 bool is_admin_of(const rgw_user
& uid
) const override
{
453 bool is_owner_of(const rgw_user
& uid
) const override
{
454 if (uid
.id
== this->sub
&& uid
.tenant
== role_tenant
&& uid
.ns
== "oidc") {
460 uint32_t get_perm_mask() const override
{
461 return RGW_PERM_NONE
;
464 void to_str(std::ostream
& out
) const override
;
466 bool is_identity(const idset_t
& ids
) const override
;
468 void load_acct_info(const DoutPrefixProvider
* dpp
, RGWUserInfo
& user_info
) const override
;
470 uint32_t get_identity_type() const override
{
474 std::string
get_acct_name() const override
{
475 return this->user_name
;
478 std::string
get_subuser() const override
{
483 virtual ~Factory() {}
485 virtual aplptr_t
create_apl_web_identity( CephContext
* cct
,
487 const std::string
& role_session
,
488 const std::string
& role_tenant
,
489 const std::unordered_multimap
<std::string
, std::string
>& token
,
490 boost::optional
<std::multimap
<std::string
, std::string
>>,
491 boost::optional
<std::set
<std::pair
<std::string
, std::string
>>> principal_tags
) const = 0;
495 class ImplicitTenants
: public md_config_obs_t
{
497 enum implicit_tenant_flag_bits
{IMPLICIT_TENANTS_SWIFT
=1,
498 IMPLICIT_TENANTS_S3
=2, IMPLICIT_TENANTS_BAD
= -1, };
501 void recompute_value(const ConfigProxy
& );
502 class ImplicitTenantValue
{
503 friend class ImplicitTenants
;
505 ImplicitTenantValue(int v
) : v(v
) {};
507 bool inline is_split_mode()
509 assert(v
!= IMPLICIT_TENANTS_BAD
);
510 return v
== IMPLICIT_TENANTS_SWIFT
|| v
== IMPLICIT_TENANTS_S3
;
512 bool inline implicit_tenants_for_(const implicit_tenant_flag_bits bit
)
514 assert(v
!= IMPLICIT_TENANTS_BAD
);
515 return static_cast<bool>(v
&bit
);
519 ImplicitTenants(const ConfigProxy
& c
) { recompute_value(c
);}
520 ImplicitTenantValue
get_value() {
521 return ImplicitTenantValue(saved
);
524 const char** get_tracked_conf_keys() const override
;
525 void handle_conf_change(const ConfigProxy
& conf
,
526 const std::set
<std::string
> &changed
) override
;
529 std::tuple
<bool,bool> implicit_tenants_enabled_for_swift(CephContext
* const cct
);
530 std::tuple
<bool,bool> implicit_tenants_enabled_for_s3(CephContext
* const cct
);
532 /* rgw::auth::RemoteApplier targets those authentication engines which don't
533 * need to ask the RADOS store while performing the auth process. Instead,
534 * they obtain credentials from an external source like Keystone or LDAP.
536 * As the authenticated user may not have an account yet, RGWRemoteAuthApplier
537 * must be able to create it basing on data passed by an auth engine. Those
538 * data will be used to fill RGWUserInfo structure. */
539 class RemoteApplier
: public IdentityApplier
{
542 friend class RemoteApplier
;
544 const rgw_user acct_user
;
545 const std::string acct_name
;
546 const uint32_t perm_mask
;
548 const uint32_t acct_type
;
549 const std::string access_key_id
;
550 const std::string subuser
;
553 enum class acct_privilege_t
{
558 static const std::string NO_SUBUSER
;
559 static const std::string NO_ACCESS_KEY
;
561 AuthInfo(const rgw_user
& acct_user
,
562 const std::string
& acct_name
,
563 const uint32_t perm_mask
,
564 const acct_privilege_t level
,
565 const std::string access_key_id
,
566 const std::string subuser
,
567 const uint32_t acct_type
=TYPE_NONE
)
568 : acct_user(acct_user
),
569 acct_name(acct_name
),
570 perm_mask(perm_mask
),
571 is_admin(acct_privilege_t::IS_ADMIN_ACCT
== level
),
572 acct_type(acct_type
),
573 access_key_id(access_key_id
),
578 using aclspec_t
= rgw::auth::Identity::aclspec_t
;
579 typedef std::function
<uint32_t(const aclspec_t
&)> acl_strategy_t
;
582 CephContext
* const cct
;
584 /* Read-write is intensional here due to RGWUserInfo creation process. */
585 rgw::sal::Store
* store
;
587 /* Supplemental strategy for extracting permissions from ACLs. Its results
588 * will be combined (ORed) with a default strategy that is responsible for
589 * handling backward compatibility. */
590 const acl_strategy_t extra_acl_strategy
;
593 rgw::auth::ImplicitTenants
& implicit_tenant_context
;
594 const rgw::auth::ImplicitTenants::implicit_tenant_flag_bits implicit_tenant_bit
;
596 virtual void create_account(const DoutPrefixProvider
* dpp
,
597 const rgw_user
& acct_user
,
598 bool implicit_tenant
,
599 RGWUserInfo
& user_info
) const; /* out */
602 RemoteApplier(CephContext
* const cct
,
603 rgw::sal::Store
* store
,
604 acl_strategy_t
&& extra_acl_strategy
,
605 const AuthInfo
& info
,
606 rgw::auth::ImplicitTenants
& implicit_tenant_context
,
607 rgw::auth::ImplicitTenants::implicit_tenant_flag_bits implicit_tenant_bit
)
610 extra_acl_strategy(std::move(extra_acl_strategy
)),
612 implicit_tenant_context(implicit_tenant_context
),
613 implicit_tenant_bit(implicit_tenant_bit
) {
616 uint32_t get_perms_from_aclspec(const DoutPrefixProvider
* dpp
, const aclspec_t
& aclspec
) const override
;
617 bool is_admin_of(const rgw_user
& uid
) const override
;
618 bool is_owner_of(const rgw_user
& uid
) const override
;
619 bool is_identity(const idset_t
& ids
) const override
;
621 uint32_t get_perm_mask() const override
{ return info
.perm_mask
; }
622 void to_str(std::ostream
& out
) const override
;
623 void load_acct_info(const DoutPrefixProvider
* dpp
, RGWUserInfo
& user_info
) const override
; /* out */
624 void write_ops_log_entry(rgw_log_entry
& entry
) const override
;
625 uint32_t get_identity_type() const override
{ return info
.acct_type
; }
626 std::string
get_acct_name() const override
{ return info
.acct_name
; }
627 std::string
get_subuser() const override
{ return {}; }
630 virtual ~Factory() {}
631 /* Providing r-value reference here is required intensionally. Callee is
632 * thus disallowed to handle std::function in a way that could inhibit
633 * the move behaviour (like forgetting about std::moving a l-value). */
634 virtual aplptr_t
create_apl_remote(CephContext
* cct
,
636 acl_strategy_t
&& extra_acl_strategy
,
637 const AuthInfo
&info
) const = 0;
642 /* rgw::auth::LocalApplier targets those auth engines that base on the data
643 * enclosed in the RGWUserInfo control structure. As a side effect of doing
644 * the authentication process, they must have it loaded. Leveraging this is
645 * a way to avoid unnecessary calls to underlying RADOS store. */
646 class LocalApplier
: public IdentityApplier
{
647 using aclspec_t
= rgw::auth::Identity::aclspec_t
;
650 const RGWUserInfo user_info
;
651 const std::string subuser
;
653 const std::string access_key_id
;
655 uint32_t get_perm_mask(const std::string
& subuser_name
,
656 const RGWUserInfo
&uinfo
) const;
659 static const std::string NO_SUBUSER
;
660 static const std::string NO_ACCESS_KEY
;
662 LocalApplier(CephContext
* const cct
,
663 const RGWUserInfo
& user_info
,
665 const std::optional
<uint32_t>& perm_mask
,
666 const std::string access_key_id
)
667 : user_info(user_info
),
668 subuser(std::move(subuser
)),
669 perm_mask(perm_mask
.value_or(RGW_PERM_INVALID
)),
670 access_key_id(access_key_id
) {
674 uint32_t get_perms_from_aclspec(const DoutPrefixProvider
* dpp
, const aclspec_t
& aclspec
) const override
;
675 bool is_admin_of(const rgw_user
& uid
) const override
;
676 bool is_owner_of(const rgw_user
& uid
) const override
;
677 bool is_identity(const idset_t
& ids
) const override
;
678 uint32_t get_perm_mask() const override
{
679 if (this->perm_mask
== RGW_PERM_INVALID
) {
680 return get_perm_mask(subuser
, user_info
);
682 return this->perm_mask
;
685 void to_str(std::ostream
& out
) const override
;
686 void load_acct_info(const DoutPrefixProvider
* dpp
, RGWUserInfo
& user_info
) const override
; /* out */
687 uint32_t get_identity_type() const override
{ return TYPE_RGW
; }
688 std::string
get_acct_name() const override
{ return {}; }
689 std::string
get_subuser() const override
{ return subuser
; }
690 void write_ops_log_entry(rgw_log_entry
& entry
) const override
;
693 virtual ~Factory() {}
694 virtual aplptr_t
create_apl_local(CephContext
* cct
,
696 const RGWUserInfo
& user_info
,
697 const std::string
& subuser
,
698 const std::optional
<uint32_t>& perm_mask
,
699 const std::string
& access_key_id
) const = 0;
703 class RoleApplier
: public IdentityApplier
{
709 std::vector
<std::string
> role_policies
;
713 std::string token_policy
;
714 std::string role_session_name
;
715 std::vector
<std::string
> token_claims
;
716 std::string token_issued_at
;
717 std::vector
<std::pair
<std::string
, std::string
>> principal_tags
;
721 TokenAttrs token_attrs
;
725 RoleApplier(CephContext
* const cct
,
727 const TokenAttrs
& token_attrs
)
729 token_attrs(token_attrs
) {}
731 uint32_t get_perms_from_aclspec(const DoutPrefixProvider
* dpp
, const aclspec_t
& aclspec
) const override
{
734 bool is_admin_of(const rgw_user
& uid
) const override
{
737 bool is_owner_of(const rgw_user
& uid
) const override
{
738 return (this->token_attrs
.user_id
.id
== uid
.id
&& this->token_attrs
.user_id
.tenant
== uid
.tenant
&& this->token_attrs
.user_id
.ns
== uid
.ns
);
740 bool is_identity(const idset_t
& ids
) const override
;
741 uint32_t get_perm_mask() const override
{
742 return RGW_PERM_NONE
;
744 void to_str(std::ostream
& out
) const override
;
745 void load_acct_info(const DoutPrefixProvider
* dpp
, RGWUserInfo
& user_info
) const override
; /* out */
746 uint32_t get_identity_type() const override
{ return TYPE_ROLE
; }
747 std::string
get_acct_name() const override
{ return {}; }
748 std::string
get_subuser() const override
{ return {}; }
749 void modify_request_state(const DoutPrefixProvider
* dpp
, req_state
* s
) const override
;
750 std::string
get_role_tenant() const override
{ return role
.tenant
; }
753 virtual ~Factory() {}
754 virtual aplptr_t
create_apl_role( CephContext
* cct
,
756 const rgw::auth::RoleApplier::Role
& role
,
757 const rgw::auth::RoleApplier::TokenAttrs
& token_attrs
) const = 0;
761 /* The anonymous abstract engine. */
762 class AnonymousEngine
: public Engine
{
763 CephContext
* const cct
;
764 const rgw::auth::LocalApplier::Factory
* const apl_factory
;
767 AnonymousEngine(CephContext
* const cct
,
768 const rgw::auth::LocalApplier::Factory
* const apl_factory
)
770 apl_factory(apl_factory
) {
773 const char* get_name() const noexcept override
{
774 return "rgw::auth::AnonymousEngine";
777 Engine::result_t
authenticate(const DoutPrefixProvider
* dpp
, const req_state
* s
, optional_yield y
) const override final
;
780 virtual bool is_applicable(const req_state
*) const noexcept
{
785 } /* namespace auth */
786 } /* namespace rgw */
789 uint32_t rgw_perms_from_aclspec_default_strategy(
791 const rgw::auth::Identity::aclspec_t
& aclspec
,
792 const DoutPrefixProvider
*dpp
);
794 #endif /* CEPH_RGW_AUTH_H */