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