]> git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_auth.h
a08a7f3024e2a20f27e07b5e386646c956590c78
[ceph.git] / ceph / src / rgw / rgw_auth.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
3
4
5 #ifndef CEPH_RGW_AUTH_H
6 #define CEPH_RGW_AUTH_H
7
8 #include <functional>
9 #include <ostream>
10 #include <type_traits>
11 #include <system_error>
12 #include <utility>
13
14 #include "rgw_common.h"
15 #include "rgw_web_idp.h"
16
17 #define RGW_USER_ANON_ID "anonymous"
18
19 class RGWCtl;
20
21 namespace rgw {
22 namespace auth {
23
24 using Exception = std::system_error;
25
26
27 /* Load information about identity that will be used by RGWOp to authorize
28 * any operation that comes from an authenticated user. */
29 class Identity {
30 public:
31 typedef std::map<std::string, int> aclspec_t;
32 using idset_t = boost::container::flat_set<Principal>;
33
34 virtual ~Identity() = default;
35
36 /* Translate the ACL provided in @aclspec into concrete permission set that
37 * can be used during the authorization phase (RGWOp::verify_permission).
38 * On error throws rgw::auth::Exception storing the reason.
39 *
40 * NOTE: an implementation is responsible for giving the real semantic to
41 * the items in @aclspec. That is, their meaning may depend on particular
42 * applier that is being used. */
43 virtual uint32_t get_perms_from_aclspec(const DoutPrefixProvider* dpp, const aclspec_t& aclspec) const = 0;
44
45 /* Verify whether a given identity *can be treated as* an admin of rgw_user
46 * (account in Swift's terminology) specified in @uid. On error throws
47 * rgw::auth::Exception storing the reason. */
48 virtual bool is_admin_of(const rgw_user& uid) const = 0;
49
50 /* Verify whether a given identity *is* the owner of the rgw_user (account
51 * in the Swift's terminology) specified in @uid. On internal error throws
52 * rgw::auth::Exception storing the reason. */
53 virtual bool is_owner_of(const rgw_user& uid) const = 0;
54
55 /* Return the permission mask that is used to narrow down the set of
56 * operations allowed for a given identity. This method reflects the idea
57 * of subuser tied to RGWUserInfo. On error throws rgw::auth::Exception
58 * with the reason. */
59 virtual uint32_t get_perm_mask() const = 0;
60
61 virtual bool is_anonymous() const final {
62 /* If the identity owns the anonymous account (rgw_user), it's considered
63 * the anonymous identity. On error throws rgw::auth::Exception storing
64 * the reason. */
65 return is_owner_of(rgw_user(RGW_USER_ANON_ID));
66 }
67
68 virtual void to_str(std::ostream& out) const = 0;
69
70 /* Verify whether a given identity corresponds to an identity in the
71 provided set */
72 virtual bool is_identity(const idset_t& ids) const = 0;
73
74 /* Identity Type: RGW/ LDAP/ Keystone */
75 virtual uint32_t get_identity_type() const = 0;
76
77 /* Name of Account */
78 virtual string get_acct_name() const = 0;
79 };
80
81 inline std::ostream& operator<<(std::ostream& out,
82 const rgw::auth::Identity& id) {
83 id.to_str(out);
84 return out;
85 }
86
87
88 std::unique_ptr<rgw::auth::Identity>
89 transform_old_authinfo(CephContext* const cct,
90 const rgw_user& auth_id,
91 const int perm_mask,
92 const bool is_admin,
93 const uint32_t type);
94 std::unique_ptr<Identity> transform_old_authinfo(const req_state* const s);
95
96
97 /* Interface for classes applying changes to request state/RADOS store
98 * imposed by a particular rgw::auth::Engine.
99 *
100 * In contrast to rgw::auth::Engine, implementations of this interface
101 * are allowed to handle req_state or RGWUserCtl in the read-write manner.
102 *
103 * It's expected that most (if not all) of implementations will also
104 * conform to rgw::auth::Identity interface to provide authorization
105 * policy (ACLs, account's ownership and entitlement). */
106 class IdentityApplier : public Identity {
107 public:
108 typedef std::unique_ptr<IdentityApplier> aplptr_t;
109
110 virtual ~IdentityApplier() {};
111
112 /* Fill provided RGWUserInfo with information about the account that
113 * RGWOp will operate on. Errors are handled solely through exceptions.
114 *
115 * XXX: be aware that the "account" term refers to rgw_user. The naming
116 * is legacy. */
117 virtual void load_acct_info(const DoutPrefixProvider* dpp, RGWUserInfo& user_info) const = 0; /* out */
118
119 /* Apply any changes to request state. This method will be most useful for
120 * TempURL of Swift API. */
121 virtual void modify_request_state(const DoutPrefixProvider* dpp, req_state* s) const {} /* in/out */
122 };
123
124
125 /* Interface class for completing the two-step authentication process.
126 * Completer provides the second step - the complete() method that should
127 * be called after Engine::authenticate() but before *committing* results
128 * of an RGWOp (or sending a response in the case of non-mutating ops).
129 *
130 * The motivation driving the interface is to address those authentication
131 * schemas that require message integrity verification *without* in-memory
132 * data buffering. Typical examples are AWS Auth v4 and the auth mechanism
133 * of browser uploads facilities both in S3 and Swift APIs (see RGWPostObj).
134 * The workflow of request from the authentication point-of-view does look
135 * like following one:
136 * A. authenticate (Engine::authenticate),
137 * B. authorize (see RGWOp::verify_permissions),
138 * C. execute-prepare (init potential data modifications),
139 * D. authenticate-complete - (Completer::complete),
140 * E. execute-commit - commit the modifications from point C. */
141 class Completer {
142 public:
143 /* It's expected that Completers would tend to implement many interfaces
144 * and be used not only in req_state::auth::completer. Ref counting their
145 * instances would be helpful. */
146 typedef std::shared_ptr<Completer> cmplptr_t;
147
148 virtual ~Completer() = default;
149
150 /* Complete the authentication process. Return boolean indicating whether
151 * the completion succeeded. On error throws rgw::auth::Exception storing
152 * the reason. */
153 virtual bool complete() = 0;
154
155 /* Apply any changes to request state. The initial use case was injecting
156 * the AWSv4 filter over rgw::io::RestfulClient in req_state. */
157 virtual void modify_request_state(const DoutPrefixProvider* dpp, req_state* s) = 0; /* in/out */
158 };
159
160
161 /* Interface class for authentication backends (auth engines) in RadosGW.
162 *
163 * An engine is supposed only to authenticate (not authorize!) requests
164 * basing on their req_state and - if access has been granted - provide
165 * an upper layer with:
166 * - rgw::auth::IdentityApplier to commit all changes to the request state as
167 * well as to the RADOS store (creating an account, synchronizing
168 * user-related information with external databases and so on).
169 * - rgw::auth::Completer (optionally) to finish the authentication
170 * of the request. Typical use case is verifying message integrity
171 * in AWS Auth v4 and browser uploads (RGWPostObj).
172 *
173 * Both of them are supposed to be wrapped in Engine::AuthResult.
174 *
175 * The authentication process consists of two steps:
176 * - Engine::authenticate() which should be called before *initiating*
177 * any modifications to RADOS store that are related to an operation
178 * a client wants to perform (RGWOp::execute).
179 * - Completer::complete() supposed to be called, if completer has been
180 * returned, after the authenticate() step but before *committing*
181 * those modifications or sending a response (RGWOp::complete).
182 *
183 * An engine outlives both Applier and Completer. It's intended to live
184 * since RadosGW's initialization and handle multiple requests till
185 * a reconfiguration.
186 *
187 * Auth engine MUST NOT make any changes to req_state nor RADOS store.
188 * This is solely an Applier's responsibility!
189 *
190 * Separation between authentication and global state modification has
191 * been introduced because many auth engines are orthogonal to appliers
192 * and thus they can be decoupled. Additional motivation is to clearly
193 * distinguish all portions of code modifying data structures. */
194 class Engine {
195 public:
196 virtual ~Engine() = default;
197
198 class AuthResult {
199 struct rejection_mark_t {};
200 bool is_rejected = false;
201 int reason = 0;
202
203 std::pair<IdentityApplier::aplptr_t, Completer::cmplptr_t> result_pair;
204
205 explicit AuthResult(const int reason)
206 : reason(reason) {
207 }
208
209 AuthResult(rejection_mark_t&&, const int reason)
210 : is_rejected(true),
211 reason(reason) {
212 }
213
214 /* Allow only the reasonable combintations - returning just Completer
215 * without accompanying IdentityApplier is strictly prohibited! */
216 explicit AuthResult(IdentityApplier::aplptr_t&& applier)
217 : result_pair(std::move(applier), nullptr) {
218 }
219
220 AuthResult(IdentityApplier::aplptr_t&& applier,
221 Completer::cmplptr_t&& completer)
222 : result_pair(std::move(applier), std::move(completer)) {
223 }
224
225 public:
226 enum class Status {
227 /* Engine doesn't grant the access but also doesn't reject it. */
228 DENIED,
229
230 /* Engine successfully authenicated requester. */
231 GRANTED,
232
233 /* Engine strictly indicates that a request should be rejected
234 * without trying any further engine. */
235 REJECTED
236 };
237
238 Status get_status() const {
239 if (is_rejected) {
240 return Status::REJECTED;
241 } else if (! result_pair.first) {
242 return Status::DENIED;
243 } else {
244 return Status::GRANTED;
245 }
246 }
247
248 int get_reason() const {
249 return reason;
250 }
251
252 IdentityApplier::aplptr_t get_applier() {
253 return std::move(result_pair.first);
254 }
255
256 Completer::cmplptr_t&& get_completer() {
257 return std::move(result_pair.second);
258 }
259
260 static AuthResult reject(const int reason = -EACCES) {
261 return AuthResult(rejection_mark_t(), reason);
262 }
263
264 static AuthResult deny(const int reason = -EACCES) {
265 return AuthResult(reason);
266 }
267
268 static AuthResult grant(IdentityApplier::aplptr_t&& applier) {
269 return AuthResult(std::move(applier));
270 }
271
272 static AuthResult grant(IdentityApplier::aplptr_t&& applier,
273 Completer::cmplptr_t&& completer) {
274 return AuthResult(std::move(applier), std::move(completer));
275 }
276 };
277
278 using result_t = AuthResult;
279
280 /* Get name of the auth engine. */
281 virtual const char* get_name() const noexcept = 0;
282
283 /* Throwing method for identity verification. When the check is positive
284 * an implementation should return Engine::result_t containing:
285 * - a non-null pointer to an object conforming the Applier interface.
286 * Otherwise, the authentication is treated as failed.
287 * - a (potentially null) pointer to an object conforming the Completer
288 * interface.
289 *
290 * On error throws rgw::auth::Exception containing the reason. */
291 virtual result_t authenticate(const DoutPrefixProvider* dpp, const req_state* s) const = 0;
292 };
293
294
295 /* Interface for extracting a token basing from data carried by req_state. */
296 class TokenExtractor {
297 public:
298 virtual ~TokenExtractor() = default;
299 virtual std::string get_token(const req_state* s) const = 0;
300 };
301
302
303 /* Abstract class for stacking sub-engines to expose them as a single
304 * Engine. It is responsible for ordering its sub-engines and managing
305 * fall-backs between them. Derivatee is supposed to encapsulate engine
306 * instances and add them using the add_engine() method in the order it
307 * wants to be tried during the call to authenticate().
308 *
309 * Each new Strategy should be exposed to StrategyRegistry for handling
310 * the dynamic reconfiguration. */
311 class Strategy : public Engine {
312 public:
313 /* Specifiers controlling what happens when an associated engine fails.
314 * The names and semantic has been borrowed mostly from libpam. */
315 enum class Control {
316 /* Failure of an engine injected with the REQUISITE specifier aborts
317 * the strategy's authentication process immediately. No other engine
318 * will be tried. */
319 REQUISITE,
320
321 /* Success of an engine injected with the SUFFICIENT specifier ends
322 * strategy's authentication process successfully. However, denying
323 * doesn't abort it -- there will be fall-back to following engine
324 * if the one that failed wasn't the last one. */
325 SUFFICIENT,
326
327 /* Like SUFFICIENT with the exception that on failure the reason code
328 * is not overridden. Instead, it's taken directly from the last tried
329 * non-FALLBACK engine. If there was no previous non-FALLBACK engine
330 * in a Strategy, then the result_t::deny(reason = -EACCES) is used. */
331 FALLBACK,
332 };
333
334 Engine::result_t authenticate(const DoutPrefixProvider* dpp, const req_state* s) const override final;
335
336 bool is_empty() const {
337 return auth_stack.empty();
338 }
339
340 static int apply(const DoutPrefixProvider* dpp, const Strategy& auth_strategy, req_state* s) noexcept;
341
342 private:
343 /* Using the reference wrapper here to explicitly point out we are not
344 * interested in storing nulls while preserving the dynamic polymorphism. */
345 using stack_item_t = std::pair<std::reference_wrapper<const Engine>,
346 Control>;
347 std::vector<stack_item_t> auth_stack;
348
349 protected:
350 void add_engine(Control ctrl_flag, const Engine& engine) noexcept;
351 };
352
353
354 /* A class aggregating the knowledge about all Strategies in RadosGW. It is
355 * responsible for handling the dynamic reconfiguration on e.g. realm update.
356 * The definition is in rgw/rgw_auth_registry.h,
357 *
358 * Each new Strategy should be exposed to it. */
359 class StrategyRegistry;
360
361 class WebIdentityApplier : public IdentityApplier {
362 protected:
363 CephContext* const cct;
364 RGWCtl* const ctl;
365 rgw::web_idp::WebTokenClaims token_claims;
366
367 string get_idp_url() const;
368
369 public:
370 WebIdentityApplier( CephContext* const cct,
371 RGWCtl* const ctl,
372 const rgw::web_idp::WebTokenClaims& token_claims)
373 : cct(cct),
374 ctl(ctl),
375 token_claims(token_claims) {
376 }
377
378 void load_acct_info(const DoutPrefixProvider* dpp, RGWUserInfo& user_info) const override {
379 user_info.user_id = rgw_user(token_claims.sub);
380 user_info.display_name = token_claims.user_name;
381 }
382
383 void modify_request_state(const DoutPrefixProvider *dpp, req_state* s) const override;
384
385 uint32_t get_perms_from_aclspec(const DoutPrefixProvider* dpp, const aclspec_t& aclspec) const override {
386 return RGW_PERM_NONE;
387 }
388
389 bool is_admin_of(const rgw_user& uid) const override {
390 return false;
391 }
392
393 bool is_owner_of(const rgw_user& uid) const override {
394 return false;
395 }
396
397 uint32_t get_perm_mask() const override {
398 return RGW_PERM_NONE;
399 }
400
401 void to_str(std::ostream& out) const override;
402
403 bool is_identity(const idset_t& ids) const override;
404
405 uint32_t get_identity_type() const override {
406 return TYPE_WEB;
407 }
408
409 string get_acct_name() const override {
410 return token_claims.user_name;
411 }
412
413 struct Factory {
414 virtual ~Factory() {}
415
416 virtual aplptr_t create_apl_web_identity( CephContext* cct,
417 const req_state* s,
418 const rgw::web_idp::WebTokenClaims& token) const = 0;
419 };
420 };
421
422 class ImplicitTenants: public md_config_obs_t {
423 public:
424 enum implicit_tenant_flag_bits {IMPLICIT_TENANTS_SWIFT=1,
425 IMPLICIT_TENANTS_S3=2, IMPLICIT_TENANTS_BAD = -1, };
426 private:
427 int saved;
428 void recompute_value(const ConfigProxy& );
429 class ImplicitTenantValue {
430 friend class ImplicitTenants;
431 int v;
432 ImplicitTenantValue(int v) : v(v) {};
433 public:
434 bool inline is_split_mode()
435 {
436 assert(v != IMPLICIT_TENANTS_BAD);
437 return v == IMPLICIT_TENANTS_SWIFT || v == IMPLICIT_TENANTS_S3;
438 }
439 bool inline implicit_tenants_for_(const implicit_tenant_flag_bits bit)
440 {
441 assert(v != IMPLICIT_TENANTS_BAD);
442 return static_cast<bool>(v&bit);
443 }
444 };
445 public:
446 ImplicitTenants(const ConfigProxy& c) { recompute_value(c);}
447 ImplicitTenantValue get_value() {
448 return ImplicitTenantValue(saved);
449 }
450 private:
451 const char** get_tracked_conf_keys() const override;
452 void handle_conf_change(const ConfigProxy& conf,
453 const std::set <std::string> &changed) override;
454 };
455
456 std::tuple<bool,bool> implicit_tenants_enabled_for_swift(CephContext * const cct);
457 std::tuple<bool,bool> implicit_tenants_enabled_for_s3(CephContext * const cct);
458
459 /* rgw::auth::RemoteApplier targets those authentication engines which don't
460 * need to ask the RADOS store while performing the auth process. Instead,
461 * they obtain credentials from an external source like Keystone or LDAP.
462 *
463 * As the authenticated user may not have an account yet, RGWRemoteAuthApplier
464 * must be able to create it basing on data passed by an auth engine. Those
465 * data will be used to fill RGWUserInfo structure. */
466 class RemoteApplier : public IdentityApplier {
467 public:
468 class AuthInfo {
469 friend class RemoteApplier;
470 protected:
471 const rgw_user acct_user;
472 const std::string acct_name;
473 const uint32_t perm_mask;
474 const bool is_admin;
475 const uint32_t acct_type;
476
477 public:
478 enum class acct_privilege_t {
479 IS_ADMIN_ACCT,
480 IS_PLAIN_ACCT
481 };
482
483 AuthInfo(const rgw_user& acct_user,
484 const std::string& acct_name,
485 const uint32_t perm_mask,
486 const acct_privilege_t level,
487 const uint32_t acct_type=TYPE_NONE)
488 : acct_user(acct_user),
489 acct_name(acct_name),
490 perm_mask(perm_mask),
491 is_admin(acct_privilege_t::IS_ADMIN_ACCT == level),
492 acct_type(acct_type) {
493 }
494 bool is_anon() const {return (acct_name.compare(RGW_USER_ANON_ID) == 0);}
495 };
496
497 using aclspec_t = rgw::auth::Identity::aclspec_t;
498 typedef std::function<uint32_t(const aclspec_t&)> acl_strategy_t;
499
500 protected:
501 CephContext* const cct;
502
503 /* Read-write is intensional here due to RGWUserInfo creation process. */
504 RGWCtl* const ctl;
505
506 /* Supplemental strategy for extracting permissions from ACLs. Its results
507 * will be combined (ORed) with a default strategy that is responsible for
508 * handling backward compatibility. */
509 const acl_strategy_t extra_acl_strategy;
510
511 const AuthInfo info;
512 rgw::auth::ImplicitTenants& implicit_tenant_context;
513 const rgw::auth::ImplicitTenants::implicit_tenant_flag_bits implicit_tenant_bit;
514
515 virtual void create_account(const DoutPrefixProvider* dpp,
516 const rgw_user& acct_user,
517 bool implicit_tenant,
518 RGWUserInfo& user_info) const; /* out */
519
520 public:
521 RemoteApplier(CephContext* const cct,
522 RGWCtl* const ctl,
523 acl_strategy_t&& extra_acl_strategy,
524 const AuthInfo& info,
525 rgw::auth::ImplicitTenants& implicit_tenant_context,
526 rgw::auth::ImplicitTenants::implicit_tenant_flag_bits implicit_tenant_bit)
527 : cct(cct),
528 ctl(ctl),
529 extra_acl_strategy(std::move(extra_acl_strategy)),
530 info(info),
531 implicit_tenant_context(implicit_tenant_context),
532 implicit_tenant_bit(implicit_tenant_bit) {
533 }
534
535 uint32_t get_perms_from_aclspec(const DoutPrefixProvider* dpp, const aclspec_t& aclspec) const override;
536 bool is_admin_of(const rgw_user& uid) const override;
537 bool is_owner_of(const rgw_user& uid) const override;
538 bool is_identity(const idset_t& ids) const override;
539
540 uint32_t get_perm_mask() const override { return info.perm_mask; }
541 void to_str(std::ostream& out) const override;
542 void load_acct_info(const DoutPrefixProvider* dpp, RGWUserInfo& user_info) const override; /* out */
543 uint32_t get_identity_type() const override { return info.acct_type; }
544 string get_acct_name() const override { return info.acct_name; }
545
546 struct Factory {
547 virtual ~Factory() {}
548 /* Providing r-value reference here is required intensionally. Callee is
549 * thus disallowed to handle std::function in a way that could inhibit
550 * the move behaviour (like forgetting about std::moving a l-value). */
551 virtual aplptr_t create_apl_remote(CephContext* cct,
552 const req_state* s,
553 acl_strategy_t&& extra_acl_strategy,
554 const AuthInfo &info) const = 0;
555 };
556 };
557
558
559 /* rgw::auth::LocalApplier targets those auth engines that base on the data
560 * enclosed in the RGWUserInfo control structure. As a side effect of doing
561 * the authentication process, they must have it loaded. Leveraging this is
562 * a way to avoid unnecessary calls to underlying RADOS store. */
563 class LocalApplier : public IdentityApplier {
564 using aclspec_t = rgw::auth::Identity::aclspec_t;
565
566 protected:
567 const RGWUserInfo user_info;
568 const std::string subuser;
569 uint32_t perm_mask;
570
571 uint32_t get_perm_mask(const std::string& subuser_name,
572 const RGWUserInfo &uinfo) const;
573
574 public:
575 static const std::string NO_SUBUSER;
576
577 LocalApplier(CephContext* const cct,
578 const RGWUserInfo& user_info,
579 std::string subuser,
580 const boost::optional<uint32_t>& perm_mask)
581 : user_info(user_info),
582 subuser(std::move(subuser)) {
583 if (perm_mask) {
584 this->perm_mask = perm_mask.get();
585 } else {
586 this->perm_mask = RGW_PERM_INVALID;
587 }
588 }
589
590
591 uint32_t get_perms_from_aclspec(const DoutPrefixProvider* dpp, const aclspec_t& aclspec) const override;
592 bool is_admin_of(const rgw_user& uid) const override;
593 bool is_owner_of(const rgw_user& uid) const override;
594 bool is_identity(const idset_t& ids) const override;
595 uint32_t get_perm_mask() const override {
596 if (this->perm_mask == RGW_PERM_INVALID) {
597 return get_perm_mask(subuser, user_info);
598 } else {
599 return this->perm_mask;
600 }
601 }
602 void to_str(std::ostream& out) const override;
603 void load_acct_info(const DoutPrefixProvider* dpp, RGWUserInfo& user_info) const override; /* out */
604 uint32_t get_identity_type() const override { return TYPE_RGW; }
605 string get_acct_name() const override { return {}; }
606
607 struct Factory {
608 virtual ~Factory() {}
609 virtual aplptr_t create_apl_local(CephContext* cct,
610 const req_state* s,
611 const RGWUserInfo& user_info,
612 const std::string& subuser,
613 const boost::optional<uint32_t>& perm_mask) const = 0;
614 };
615 };
616
617 class RoleApplier : public IdentityApplier {
618 protected:
619 const string role_name;
620 const rgw_user user_id;
621 vector<std::string> role_policies;
622
623 public:
624
625 RoleApplier(CephContext* const cct,
626 const string& role_name,
627 const rgw_user& user_id,
628 const vector<std::string>& role_policies)
629 : role_name(role_name),
630 user_id(user_id),
631 role_policies(role_policies) {}
632
633 uint32_t get_perms_from_aclspec(const DoutPrefixProvider* dpp, const aclspec_t& aclspec) const override {
634 return 0;
635 }
636 bool is_admin_of(const rgw_user& uid) const override {
637 return false;
638 }
639 bool is_owner_of(const rgw_user& uid) const override {
640 return false;
641 }
642 bool is_identity(const idset_t& ids) const override;
643 uint32_t get_perm_mask() const override {
644 return RGW_PERM_NONE;
645 }
646 void to_str(std::ostream& out) const override;
647 void load_acct_info(const DoutPrefixProvider* dpp, RGWUserInfo& user_info) const override; /* out */
648 uint32_t get_identity_type() const override { return TYPE_ROLE; }
649 string get_acct_name() const override { return {}; }
650 void modify_request_state(const DoutPrefixProvider* dpp, req_state* s) const override;
651
652 struct Factory {
653 virtual ~Factory() {}
654 virtual aplptr_t create_apl_role( CephContext* cct,
655 const req_state* s,
656 const string& role_name,
657 const rgw_user& user_id,
658 const vector<std::string>& role_policies) const = 0;
659 };
660 };
661
662 /* The anonymous abstract engine. */
663 class AnonymousEngine : public Engine {
664 CephContext* const cct;
665 const rgw::auth::LocalApplier::Factory* const apl_factory;
666
667 public:
668 AnonymousEngine(CephContext* const cct,
669 const rgw::auth::LocalApplier::Factory* const apl_factory)
670 : cct(cct),
671 apl_factory(apl_factory) {
672 }
673
674 const char* get_name() const noexcept override {
675 return "rgw::auth::AnonymousEngine";
676 }
677
678 Engine::result_t authenticate(const DoutPrefixProvider* dpp, const req_state* s) const override final;
679
680 protected:
681 virtual bool is_applicable(const req_state*) const noexcept {
682 return true;
683 }
684 };
685
686 } /* namespace auth */
687 } /* namespace rgw */
688
689
690 uint32_t rgw_perms_from_aclspec_default_strategy(
691 const rgw_user& uid,
692 const rgw::auth::Identity::aclspec_t& aclspec);
693
694 #endif /* CEPH_RGW_AUTH_H */