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