]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: implement the rgw::auth::SysReqApplier over IdentityApplier.
authorRadoslaw Zarzynski <rzarzynski@mirantis.com>
Wed, 11 Jan 2017 15:08:39 +0000 (16:08 +0100)
committerRadoslaw Zarzynski <rzarzynski@mirantis.com>
Fri, 24 Mar 2017 15:55:26 +0000 (16:55 +0100)
Signed-off-by: Radoslaw Zarzynski <rzarzynski@mirantis.com>
12 files changed:
src/rgw/rgw_auth.cc
src/rgw/rgw_auth.h
src/rgw/rgw_auth_filters.h
src/rgw/rgw_auth_keystone.cc
src/rgw/rgw_auth_keystone.h
src/rgw/rgw_auth_s3.h
src/rgw/rgw_common.cc
src/rgw/rgw_common.h
src/rgw/rgw_rest_s3.cc
src/rgw/rgw_rest_s3.h
src/rgw/rgw_swift_auth.cc
src/rgw/rgw_swift_auth.h

index 7ae215a852671c8246b902b60c390f9ecb596fd1..27840f28490b7982b822cd1d30ce9370eb36019c 100644 (file)
@@ -753,7 +753,7 @@ rgw::auth::AnonymousEngine::authenticate(const req_state* const s) const
     rgw_get_anon_user(user_info);
 
     // FIXME: over 80 columns
-    auto apl = apl_factory->create_apl_local(cct, user_info,
+    auto apl = apl_factory->create_apl_local(cct, s, user_info,
                                              rgw::auth::LocalApplier::NO_SUBUSER);
     return std::make_pair(std::move(apl), nullptr);
   }
index c38a905e2e0156350044230300ff8c1b34556c4e..6755c8812b0fca73fb3199dcf2d3d78da6974fed 100644 (file)
@@ -647,7 +647,8 @@ public:
     /* Providing r-value reference here is required intensionally. Callee is
      * thus disallowed to handle std::function in a way that could inhibit
      * the move behaviour (like forgetting about std::moving a l-value). */
-    virtual aplptr_t create_apl_remote(CephContext * const cct,
+    virtual aplptr_t create_apl_remote(CephContext* cct,
+                                       const req_state* s,
                                        acl_strategy_t&& extra_acl_strategy,
                                        const AuthInfo info) const = 0;
   };
@@ -690,7 +691,8 @@ public:
 
   struct Factory {
     virtual ~Factory() {}
-    virtual aplptr_t create_apl_local(CephContext* const cct,
+    virtual aplptr_t create_apl_local(CephContext* cct,
+                                      const req_state* s,
                                       const RGWUserInfo& user_info,
                                       const std::string& subuser) const = 0;
     };
index 1a442648c4bcae0b8e7dec5d07d2f1d7df5cb534..204a43e73f80e4bd01bebf228c30a9641643719c 100644 (file)
@@ -6,6 +6,7 @@
 
 #include <type_traits>
 
+#include <boost/logic/tribool.hpp>
 #include <boost/optional.hpp>
 
 #include "rgw_common.h"
@@ -175,6 +176,85 @@ ThirdPartyAccountApplier<T> add_3rdparty(RGWRados* const store,
                                      std::forward<T>(t));
 }
 
+
+template <typename T>
+class SysReqApplier : public DecoratedApplier<T> {
+  CephContext* const cct;
+  /*const*/ RGWRados* const store;
+  const RGWHTTPArgs& args;
+  mutable boost::tribool is_system;
+
+public:
+  template <typename U>
+  SysReqApplier(CephContext* const cct,
+                /*const*/ RGWRados* const store,
+                const req_state* const s,
+                U&& decoratee)
+    : DecoratedApplier<T>(std::forward<T>(decoratee)),
+      cct(cct),
+      store(store),
+      args(s->info.args),
+      is_system(boost::logic::indeterminate) {
+  }
+
+  void to_str(std::ostream& out) const override;
+  void load_acct_info(RGWUserInfo& user_info) const override;   /* out */
+  void modify_request_state(req_state* s) const override;       /* in/out */
+};
+
+template <typename T>
+void SysReqApplier<T>::to_str(std::ostream& out) const
+{
+  out << "rgw::auth::SysReqApplier" << " -> ";
+  DecoratedApplier<T>::to_str(out);
+}
+
+template <typename T>
+void SysReqApplier<T>::load_acct_info(RGWUserInfo& user_info) const
+{
+  DecoratedApplier<T>::load_acct_info(user_info);
+  is_system = user_info.system;
+
+  if (is_system) {
+    //dout(20) << "system request" << dendl;
+
+    rgw_user effective_uid(args.sys_get(RGW_SYS_PARAM_PREFIX "uid"));
+    if (! effective_uid.empty()) {
+      /* We aren't writing directly to user_info for consistency and security
+       * reasons. rgw_get_user_info_by_uid doesn't trigger the operator=() but
+       * calls ::decode instead. */
+      RGWUserInfo euser_info;
+      if (rgw_get_user_info_by_uid(store, effective_uid, euser_info) < 0) {
+        //ldout(s->cct, 0) << "User lookup failed!" << dendl;
+        throw -EACCES;
+      }
+      user_info = euser_info;
+    }
+  }
+}
+
+template <typename T>
+void SysReqApplier<T>::modify_request_state(req_state* const s) const
+{
+  if (boost::logic::indeterminate(is_system)) {
+    RGWUserInfo unused_info;
+    load_acct_info(unused_info);
+  }
+
+  if (is_system) {
+    s->info.args.set_system();
+    s->system_request = true;
+  }
+}
+
+template <typename T> static inline
+SysReqApplier<T> add_sysreq(CephContext* const cct,
+                            /* const */ RGWRados* const store,
+                            const req_state* const s,
+                            T&& t) {
+  return SysReqApplier<T>(cct, store, s, std::forward<T>(t));
+}
+
 } /* namespace auth */
 } /* namespace rgw */
 
index e715982644d57bdc8153f3e105b252b057ebb3ac..a789cb22472fb5c107588c647c68a0eb575eaed8 100644 (file)
@@ -199,7 +199,8 @@ TokenEngine::get_acl_strategy(const TokenEngine::token_envelope_t& token) const
 }
 
 TokenEngine::result_t
-TokenEngine::authenticate(const std::string& token) const
+TokenEngine::authenticate(const std::string& token,
+                          const req_state* const s) const
 {
   TokenEngine::token_envelope_t t;
 
@@ -231,7 +232,7 @@ TokenEngine::authenticate(const std::string& token) const
   if (token_cache.find(token_id, t)) {
     ldout(cct, 20) << "cached token.project.id=" << t.get_project_id()
                    << dendl;
-    auto apl = apl_factory->create_apl_remote(cct, get_acl_strategy(t),
+    auto apl = apl_factory->create_apl_remote(cct, s, get_acl_strategy(t),
                                               get_creds_info(t, roles.admin));
     return std::make_pair(std::move(apl), nullptr);
   }
@@ -264,7 +265,7 @@ TokenEngine::authenticate(const std::string& token) const
                     << ":" << t.get_user_name()
                     << " expires: " << t.get_expires() << dendl;
       token_cache.add(token_id, t);
-      auto apl = apl_factory->create_apl_remote(cct, get_acl_strategy(t),
+      auto apl = apl_factory->create_apl_remote(cct, s, get_acl_strategy(t),
                                             get_creds_info(t, roles.admin));
       return std::make_pair(std::move(apl), nullptr);
     }
@@ -432,7 +433,9 @@ rgw::auth::Engine::result_t EC2Engine::authenticate(std::string access_key_id,
                                                     std::string signature,
                                                     std::string expires,
                                                     bool qsr,
-                                                    const req_info& info) const
+                                                    const req_info& info,
+                                                    /* Passthorugh only! */
+                                                    const req_state* s) const
 {
   /* This will be initialized on the first call to this method. In C++11 it's
    * also thread-safe. */
index eae1012bec1a5177a9b53b78ccaace03803ede33..3307b4865d8808c66d4f7a72e72515d040bb83e2 100644 (file)
@@ -39,7 +39,8 @@ class TokenEngine : public rgw::auth::Engine {
   auth_info_t get_creds_info(const token_envelope_t& token,
                              const std::vector<std::string>& admin_roles
                             ) const noexcept;
-  result_t authenticate(const std::string& token) const;
+  result_t authenticate(const std::string& token,
+                        const req_state* s) const;
 
 public:
   TokenEngine(CephContext* const cct,
@@ -59,7 +60,7 @@ public:
   }
 
   result_t authenticate(const req_state* const s) const override {
-    return authenticate(extractor->get_token(s));
+    return authenticate(extractor->get_token(s), s);
   }
 }; /* class TokenEngine */
 
@@ -88,7 +89,8 @@ class EC2Engine : public rgw::auth::s3::Version2ndEngine {
                         std::string signature,
                         std::string expires,
                         bool qsr,
-                        const req_info& info) const override;
+                        const req_info& info,
+                        const req_state* s) const override;
 public:
   EC2Engine(CephContext* const cct,
             const rgw::auth::s3::Version2ndEngine::Extractor* const extractor,
index 345ac0ce840f628d8ec1a759f9267722fb530f2d..7e5205cf5544b9144f136e477af6d0836bb4cbf1 100644 (file)
@@ -31,6 +31,7 @@ class ExternalAuthStrategy : public rgw::auth::Strategy,
   LDAPEngine ldap_engine;
 
   aplptr_t create_apl_remote(CephContext* const cct,
+                             const req_state* const s,
                              rgw::auth::RemoteApplier::acl_strategy_t&& acl_alg,
                              const rgw::auth::RemoteApplier::AuthInfo info
                             ) const override {
index 6ff0d07531136cecd330c574863935534b63b941..cce203b0faabbe755eca1daae126906b83370b00 100644 (file)
@@ -876,7 +876,7 @@ void RGWHTTPArgs::get_bool(const char *name, bool *val, bool def_val)
   }
 }
 
-string RGWHTTPArgs::sys_get(const string& name, bool * const exists)
+string RGWHTTPArgs::sys_get(const string& name, bool * const exists) const
 {
   const auto iter = sys_val_map.find(name);
   const bool e = (iter != sys_val_map.end());
index 6a9b7ec9f454a7931330adf28d022c3ca675b0fb..06e30f2e0523e64a89c335ce1162449e75ff1625 100644 (file)
@@ -325,7 +325,7 @@ class RGWHTTPArgs
   void get_bool(const char *name, bool *val, bool def_val);
 
   /** Get the value for specific system argument parameter */
-  string sys_get(const string& name, bool *exists = nullptr);
+  std::string sys_get(const string& name, bool *exists = nullptr) const;
 
   /** see if a parameter is contained in this RGWHTTPArgs */
   bool exists(const char *name) const {
index ef11286ca522148c11fd1fcc1dc4acbdb2911cff..a902c614029f1e4a41c0a4ee2d730e79f15e92ae 100644 (file)
@@ -4390,7 +4390,8 @@ rgw::auth::s3::LDAPEngine::authenticate(const std::string access_key_id,
                                         const std::string signature,
                                         const std::string expires,
                                         const bool qsr,
-                                        const req_info& /* unused */) const
+                                        const req_info& /* unused */,
+                                        const req_state* const s) const
 {
   /* boost filters and/or string_ref may throw on invalid input */
   rgw::RGWToken base64_token;
@@ -4420,7 +4421,7 @@ rgw::auth::s3::LDAPEngine::authenticate(const std::string access_key_id,
     return std::make_pair(nullptr, nullptr);
   }
 
-  auto apl = apl_factory->create_apl_remote(cct, get_acl_strategy(),
+  auto apl = apl_factory->create_apl_remote(cct, s, get_acl_strategy(),
                                             get_creds_info(base64_token));
   return std::make_pair(std::move(apl), nullptr);
 }
@@ -4432,7 +4433,8 @@ rgw::auth::s3::LocalVersion2ndEngine::authenticate(std::string access_key_id,
                                                    std::string signature,
                                                    std::string expires,
                                                    bool qsr,
-                                                   const req_info& info) const
+                                                   const req_info& info,
+                                                   const req_state* const s) const
 {
   if (access_key_id.empty() || signature.empty()) {
     ldout(cct, 5) << "access_key_id or signature is empty" << dendl;
@@ -4506,6 +4508,6 @@ rgw::auth::s3::LocalVersion2ndEngine::authenticate(std::string access_key_id,
     throw -ERR_SIGNATURE_NO_MATCH;
   }
 
-  auto apl = apl_factory->create_apl_local(cct, user_info, k.subuser);
+  auto apl = apl_factory->create_apl_local(cct, s, user_info, k.subuser);
   return std::make_pair(std::move(apl), nullptr);
 }
index 6276df239086f72e4fcbb36ea9196b23feea5a09..de2023c2a83a66974da2a0a1e57080338a5a0b6a 100644 (file)
@@ -648,7 +648,8 @@ protected:
                                 std::string signature,
                                 std::string expires,
                                 bool qsr,
-                                const req_info& info) const = 0;
+                                const req_info& info,
+                                const req_state* s) const = 0;
 
 public:
   result_t authenticate(const req_state* const s) const final {
@@ -664,7 +665,7 @@ public:
       return std::make_pair(nullptr, nullptr);
     } else {
       return authenticate(std::move(access_key_id), std::move(signature),
-                          std::move(expires), qsr, s->info);
+                          std::move(expires), qsr, s->info, s);
     }
   }
 };
@@ -719,7 +720,8 @@ protected:
                         std::string signature,
                         std::string expires,
                         bool qsr,
-                        const req_info& info) const override;
+                        const req_info& info,
+                        const req_state* s) const override;
 public:
   LDAPEngine(CephContext* const cct,
              RGWRados* const store,
@@ -747,7 +749,8 @@ class LocalVersion2ndEngine : public Version2ndEngine {
                         std::string signature,
                         std::string expires,
                         bool qsr,
-                        const req_info& info) const override;
+                        const req_info& info,
+                        const req_state* s) const override;
 public:
   LocalVersion2ndEngine(CephContext* const cct,
                         RGWRados* const store,
@@ -777,6 +780,7 @@ public:
   }
 
   aplptr_t create_apl_remote(CephContext* const cct,
+                             const req_state* const s,
                              rgw::auth::RemoteApplier::acl_strategy_t&& acl_alg,
                              const rgw::auth::RemoteApplier::AuthInfo info
                             ) const override {
@@ -785,6 +789,7 @@ public:
   }
 
   aplptr_t create_apl_local(CephContext* const cct,
+                            const req_state* const s,
                             const RGWUserInfo& user_info,
                             const std::string& subuser) const override {
       return aplptr_t(
index 594d7dbbcdafcc8fa339754175058ef5def015df..005d839045abfd2524d7f31f2ebc8cb3889a2711 100644 (file)
@@ -269,7 +269,7 @@ TempURLEngine::authenticate(const req_state* const s) const
                           << dendl;
 
         if (sig_helper.is_equal_to(temp_url_sig)) {
-          auto apl = apl_factory->create_apl_turl(cct, owner_info);
+          auto apl = apl_factory->create_apl_turl(cct, s, owner_info);
           return std::make_pair(std::move(apl), nullptr);
         } else {
           ldout(s->cct,  5) << "temp url signature mismatch: " << local_sig
@@ -296,7 +296,8 @@ bool ExternalTokenEngine::is_applicable(const std::string& token) const noexcept
 }
 
 ExternalTokenEngine::result_t
-ExternalTokenEngine::authenticate(const std::string& token) const
+ExternalTokenEngine::authenticate(const std::string& token,
+                                  const req_state* const s) const
 {
   if (! is_applicable(token)) {
     return std::make_pair(nullptr, nullptr);
@@ -349,7 +350,7 @@ ExternalTokenEngine::authenticate(const std::string& token) const
     throw ret;
   }
 
-  auto apl = apl_factory->create_apl_local(cct, tmp_uinfo,
+  auto apl = apl_factory->create_apl_local(cct, s, tmp_uinfo,
                                            extract_swift_subuser(swift_user));
   return std::make_pair(std::move(apl), nullptr);
 }
@@ -411,7 +412,8 @@ bool SignedTokenEngine::is_applicable(const std::string& token) const noexcept
 }
 
 SignedTokenEngine::result_t
-SignedTokenEngine::authenticate(const std::string& token) const
+SignedTokenEngine::authenticate(const std::string& token,
+                                const req_state* const s) const
 {
   if (! is_applicable(token)) {
     return std::make_pair(nullptr, nullptr);
@@ -499,7 +501,7 @@ SignedTokenEngine::authenticate(const std::string& token) const
     return std::make_pair(nullptr, nullptr);
   }
 
-  auto apl = apl_factory->create_apl_local(cct, user_info,
+  auto apl = apl_factory->create_apl_local(cct, s, user_info,
                                            extract_swift_subuser(swift_user));
   return std::make_pair(std::move(apl), nullptr);
 }
index 541ec99fa2f559291a1b718588619b0f7f65e8f6..e11e87f19a9805b31d4f51f4a81471582ef2b51a 100644 (file)
@@ -28,7 +28,8 @@ public:
 
   struct Factory {
     virtual ~Factory() {}
-    virtual aplptr_t create_apl_turl(CephContext * const cct,
+    virtual aplptr_t create_apl_turl(CephContext* cct,
+                                     const req_state* s,
                                      const RGWUserInfo& user_info) const = 0;
   };
 };
@@ -77,7 +78,8 @@ class SignedTokenEngine : public rgw::auth::Engine {
   const rgw::auth::LocalApplier::Factory* const apl_factory;
 
   bool is_applicable(const std::string& token) const noexcept;
-  result_t authenticate(const std::string& token) const;
+  result_t authenticate(const std::string& token,
+                        const req_state* s) const;
 
 public:
   SignedTokenEngine(CephContext* const cct,
@@ -95,7 +97,7 @@ public:
   }
 
   result_t authenticate(const req_state* const s) const override {
-    return authenticate(extractor->get_token(s));
+    return authenticate(extractor->get_token(s), s);
   }
 };
 
@@ -110,7 +112,8 @@ class ExternalTokenEngine : public rgw::auth::Engine {
   const rgw::auth::LocalApplier::Factory* const apl_factory;
 
   bool is_applicable(const std::string& token) const noexcept;
-  result_t authenticate(const std::string& token) const;
+  result_t authenticate(const std::string& token,
+                        const req_state* s) const;
 
 public:
   ExternalTokenEngine(CephContext* const cct,
@@ -128,7 +131,7 @@ public:
   }
 
   result_t authenticate(const req_state* const s) const override {
-    return authenticate(extractor->get_token(s));
+    return authenticate(extractor->get_token(s), s);
   }
 };
 
@@ -159,6 +162,7 @@ class DefaultStrategy : public rgw::auth::Strategy,
   }
 
   aplptr_t create_apl_remote(CephContext* const cct,
+                             const req_state* const s,
                              acl_strategy_t&& extra_acl_strategy,
                              const rgw::auth::RemoteApplier::AuthInfo info) const override {
     return aplptr_t(
@@ -166,12 +170,14 @@ class DefaultStrategy : public rgw::auth::Strategy,
   }
 
   aplptr_t create_apl_local(CephContext* const cct,
+                            const req_state* const s,
                             const RGWUserInfo& user_info,
                             const std::string& subuser) const override {
     return aplptr_t(new rgw::auth::LocalApplier(cct, user_info, subuser));
   }
 
   aplptr_t create_apl_turl(CephContext* const cct,
+                           const req_state* const s,
                            const RGWUserInfo& user_info) const override {
     /* TempURL doesn't need any user account override. It's a Swift-specific
      * mechanism that requires  account name internally, so there is no