From 9888ec33d54613dd91fac05d30567daf14c6b31b Mon Sep 17 00:00:00 2001 From: Radoslaw Zarzynski Date: Mon, 20 Mar 2017 04:35:42 +0100 Subject: [PATCH] rgw: implement the dynamic reconfiguration of auth strategies. Signed-off-by: Radoslaw Zarzynski --- src/rgw/rgw_asio_frontend.cc | 18 ++++---- src/rgw/rgw_asio_frontend.h | 3 +- src/rgw/rgw_auth.h | 12 +++++- src/rgw/rgw_auth_registry.h | 71 ++++++++++++++++++++++++++++++++ src/rgw/rgw_civetweb_frontend.cc | 2 +- src/rgw/rgw_fcgi_process.cc | 3 +- src/rgw/rgw_frontend.h | 23 ++++++++--- src/rgw/rgw_loadgen_process.cc | 3 +- src/rgw/rgw_main.cc | 21 +++++----- src/rgw/rgw_op.h | 14 ++++++- src/rgw/rgw_process.cc | 7 +++- src/rgw/rgw_process.h | 9 +++- src/rgw/rgw_rest.cc | 18 ++++---- src/rgw/rgw_rest.h | 15 ++++++- src/rgw/rgw_rest_bucket.h | 7 ++-- src/rgw/rgw_rest_config.h | 7 ++-- src/rgw/rgw_rest_log.h | 7 ++-- src/rgw/rgw_rest_metadata.h | 7 ++-- src/rgw/rgw_rest_opstate.h | 7 ++-- src/rgw/rgw_rest_realm.cc | 14 +++++-- src/rgw/rgw_rest_realm.h | 1 + src/rgw/rgw_rest_replica_log.h | 7 ++-- src/rgw/rgw_rest_s3.cc | 35 +++++++++------- src/rgw/rgw_rest_s3.h | 51 ++++++++++++++++------- src/rgw/rgw_rest_s3website.h | 16 +++---- src/rgw/rgw_rest_swift.cc | 10 ++++- src/rgw/rgw_rest_swift.h | 21 ++++------ src/rgw/rgw_rest_usage.h | 7 ++-- src/rgw/rgw_rest_user.h | 7 ++-- src/rgw/rgw_swift_auth.h | 1 + 30 files changed, 301 insertions(+), 123 deletions(-) create mode 100644 src/rgw/rgw_auth_registry.h diff --git a/src/rgw/rgw_asio_frontend.cc b/src/rgw/rgw_asio_frontend.cc index b785e7b07b7..ff2d7806759 100644 --- a/src/rgw/rgw_asio_frontend.cc +++ b/src/rgw/rgw_asio_frontend.cc @@ -99,8 +99,8 @@ class AsioConnection : public std::enable_shared_from_this { rgw::io::add_conlen_controlling( &real_client)))); RGWRestfulIO client(&real_client_io); - process_request(env.store, env.rest, &req, env.uri_prefix, &client, - env.olog); + process_request(env.store, env.rest, &req, env.uri_prefix, + *env.auth_registry, &client, env.olog); } void write_bad_request() { @@ -160,7 +160,7 @@ class AsioFrontend { void stop(); void join(); void pause(); - void unpause(RGWRados *store); + void unpause(RGWRados* store, rgw_auth_registry_ptr_t); }; int AsioFrontend::init() @@ -253,9 +253,11 @@ void AsioFrontend::pause() ldout(ctx(), 4) << "frontend paused" << dendl; } -void AsioFrontend::unpause(RGWRados *store) +void AsioFrontend::unpause(RGWRados* const store, + rgw_auth_registry_ptr_t auth_registry) { env.store = store; + env.auth_registry = std::move(auth_registry); ldout(ctx(), 4) << "frontend unpaused" << dendl; service.reset(); acceptor.async_accept(peer_socket, @@ -304,7 +306,9 @@ void RGWAsioFrontend::pause_for_new_config() impl->pause(); } -void RGWAsioFrontend::unpause_with_new_config(RGWRados *store) -{ - impl->unpause(store); +void RGWAsioFrontend::unpause_with_new_config( + RGWRados* const store, + rgw_auth_registry_ptr_t auth_registry +) { + impl->unpause(store, std::move(auth_registry)); } diff --git a/src/rgw/rgw_asio_frontend.h b/src/rgw/rgw_asio_frontend.h index 1ffda891c25..4c32cada640 100644 --- a/src/rgw/rgw_asio_frontend.h +++ b/src/rgw/rgw_asio_frontend.h @@ -20,7 +20,8 @@ public: void join() override; void pause_for_new_config() override; - void unpause_with_new_config(RGWRados *store) override; + void unpause_with_new_config(RGWRados *store, + rgw_auth_registry_ptr_t auth_registry) override; }; #endif // RGW_ASIO_FRONTEND_H diff --git a/src/rgw/rgw_auth.h b/src/rgw/rgw_auth.h index b7346f65f5b..8dcd2e7b056 100644 --- a/src/rgw/rgw_auth.h +++ b/src/rgw/rgw_auth.h @@ -279,7 +279,10 @@ public: * Engine. It is responsible for ordering its sub-engines and managing * fall-backs between them. Derivatee is supposed to encapsulate engine * instances and add them using the add_engine() method in the order it - * wants to be tried during the call to authenticate(). */ + * wants to be tried during the call to authenticate(). + * + * Each new Strategy should be exposed to StrategyRegistry for handling + * the dynamic reconfiguration. */ class Strategy : public Engine { public: /* Specifiers controlling what happens when an associated engine fails. @@ -321,6 +324,13 @@ protected: }; +/* A class aggregating the knowledge about all Strategies in RadosGW. It is + * responsible for handling the dynamic reconfiguration on e.g. realm update. + * The definition is in rgw/rgw_auth_registry.h, + * + * Each new Strategy should be exposed to it. */ +class StrategyRegistry; + /* rgw::auth::RemoteApplier targets those authentication engines which don't * need to ask the RADOS store while performing the auth process. Instead, * they obtain credentials from an external source like Keystone or LDAP. diff --git a/src/rgw/rgw_auth_registry.h b/src/rgw/rgw_auth_registry.h new file mode 100644 index 00000000000..18add9ae3a4 --- /dev/null +++ b/src/rgw/rgw_auth_registry.h @@ -0,0 +1,71 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + + +#ifndef CEPH_RGW_AUTH_REGISTRY_H +#define CEPH_RGW_AUTH_REGISTRY_H + +#include +#include +#include +#include +#include + +#include "rgw_auth.h" +#include "rgw_auth_s3.h" +#include "rgw_swift_auth.h" + +namespace rgw { +namespace auth { + +/* A class aggregating the knowledge about all Strategies in RadosGW. It is + * responsible for handling the dynamic reconfiguration on e.g. realm update. */ +class StrategyRegistry { + template + using s3_strategy_t = rgw::auth::s3::AWSv2AuthStrategy; + + using s3_main_strategy_t = \ + s3_strategy_t; + using s3_post_strategy_t = \ + s3_strategy_t; + + s3_main_strategy_t s3_main_strategy; + s3_post_strategy_t s3_post_strategy; + + rgw::auth::swift::DefaultStrategy swift_strategy; + +public: + StrategyRegistry(CephContext* const cct, + RGWRados* const store) + : s3_main_strategy(cct, store), + s3_post_strategy(cct, store), + swift_strategy(cct, store) { + } + +public: + const s3_main_strategy_t& get_s3_main() const { + return s3_main_strategy; + } + + const s3_post_strategy_t& get_s3_post() const { + return s3_post_strategy; + } + + const rgw::auth::swift::DefaultStrategy& get_swift() const { + return swift_strategy; + } + + static std::shared_ptr + create(CephContext* const cct, + RGWRados* const store) { + return std::make_shared(cct, store); + } +}; + +} /* namespace auth */ +} /* namespace rgw */ + +using rgw_auth_registry_t = rgw::auth::StrategyRegistry; +using rgw_auth_registry_ptr_t = std::shared_ptr; + +#endif /* CEPH_RGW_AUTH_REGISTRY_H */ diff --git a/src/rgw/rgw_civetweb_frontend.cc b/src/rgw/rgw_civetweb_frontend.cc index 977883dc74d..c564d0e4920 100644 --- a/src/rgw/rgw_civetweb_frontend.cc +++ b/src/rgw/rgw_civetweb_frontend.cc @@ -32,7 +32,7 @@ int RGWCivetWebFrontend::process(struct mg_connection* const conn) RGWRequest req(env.store->get_new_req_id()); int ret = process_request(env.store, env.rest, &req, env.uri_prefix, - &client_io, env.olog); + *env.auth_registry, &client_io, env.olog); if (ret < 0) { /* We don't really care about return code. */ dout(20) << "process_request() returned " << ret << dendl; diff --git a/src/rgw/rgw_fcgi_process.cc b/src/rgw/rgw_fcgi_process.cc index fb918b646c2..332cde29719 100644 --- a/src/rgw/rgw_fcgi_process.cc +++ b/src/rgw/rgw_fcgi_process.cc @@ -124,7 +124,8 @@ void RGWFCGXProcess::handle_request(RGWRequest* r) RGWRestfulIO client_io(&real_client_io); - int ret = process_request(store, rest, req, uri_prefix, &client_io, olog); + int ret = process_request(store, rest, req, uri_prefix, + *auth_registry, &client_io, olog); if (ret < 0) { /* we don't really care about return code */ dout(20) << "process_request() returned " << ret << dendl; diff --git a/src/rgw/rgw_frontend.h b/src/rgw/rgw_frontend.h index c496d4fe1bd..1c999b4d68f 100644 --- a/src/rgw/rgw_frontend.h +++ b/src/rgw/rgw_frontend.h @@ -15,6 +15,8 @@ #include "rgw_civetweb_log.h" #include "civetweb/civetweb.h" +#include "rgw_auth_registry.h" + #define dout_context g_ceph_context #define dout_subsys ceph_subsys_rgw @@ -68,7 +70,8 @@ public: virtual void join() = 0; virtual void pause_for_new_config() = 0; - virtual void unpause_with_new_config(RGWRados* store) = 0; + virtual void unpause_with_new_config(RGWRados* store, + rgw_auth_registry_ptr_t auth_registry) = 0; }; @@ -129,8 +132,10 @@ public: env.mutex.get_write(); } - void unpause_with_new_config(RGWRados *store) override { + void unpause_with_new_config(RGWRados* const store, + rgw_auth_registry_ptr_t auth_registry) override { env.store = store; + env.auth_registry = std::move(auth_registry); // unpause callbacks env.mutex.put_write(); } @@ -170,9 +175,11 @@ public: pprocess->pause(); } - void unpause_with_new_config(RGWRados *store) override { + void unpause_with_new_config(RGWRados* const store, + rgw_auth_registry_ptr_t auth_registry) override { env.store = store; - pprocess->unpause_with_new_config(store); + env.auth_registry = auth_registry; + pprocess->unpause_with_new_config(store, std::move(auth_registry)); } }; /* RGWProcessFrontend */ @@ -235,6 +242,7 @@ public: class RGWFrontendPauser : public RGWRealmReloader::Pauser { std::list &frontends; RGWRealmReloader::Pauser* pauser; + public: RGWFrontendPauser(std::list &frontends, RGWRealmReloader::Pauser* pauser = nullptr) @@ -247,8 +255,13 @@ class RGWFrontendPauser : public RGWRealmReloader::Pauser { pauser->pause(); } void resume(RGWRados *store) override { + /* Initialize the registry of auth strategies which will coordinate + * the dynamic reconfiguration. */ + auto auth_registry = \ + rgw::auth::StrategyRegistry::create(g_ceph_context, store); + for (auto frontend : frontends) - frontend->unpause_with_new_config(store); + frontend->unpause_with_new_config(store, auth_registry); if (pauser) pauser->resume(store); } diff --git a/src/rgw/rgw_loadgen_process.cc b/src/rgw/rgw_loadgen_process.cc index d74688309b6..7f003facbb7 100644 --- a/src/rgw/rgw_loadgen_process.cc +++ b/src/rgw/rgw_loadgen_process.cc @@ -131,7 +131,8 @@ void RGWLoadGenProcess::handle_request(RGWRequest* r) RGWLoadGenIO real_client_io(&env); RGWRestfulIO client_io(&real_client_io); - int ret = process_request(store, rest, req, uri_prefix, &client_io, olog); + int ret = process_request(store, rest, req, uri_prefix, + *auth_registry, &client_io, olog); if (ret < 0) { /* we don't really care about return code */ dout(20) << "process_request() returned " << ret << dendl; diff --git a/src/rgw/rgw_main.cc b/src/rgw/rgw_main.cc index 733d4567003..1bec56553a6 100644 --- a/src/rgw/rgw_main.cc +++ b/src/rgw/rgw_main.cc @@ -385,11 +385,7 @@ int main(int argc, const char **argv) } if (apis_map.count("swift") > 0) { - static const rgw::auth::swift::DefaultStrategy auth_strategy(g_ceph_context, - store); - - RGWRESTMgr_SWIFT* const swift_resource = new RGWRESTMgr_SWIFT( - &auth_strategy); + RGWRESTMgr_SWIFT* const swift_resource = new RGWRESTMgr_SWIFT; if (! g_conf->rgw_cross_domain_policy.empty()) { swift_resource->register_resource("crossdomain.xml", @@ -400,7 +396,7 @@ int main(int argc, const char **argv) set_logging(new RGWRESTMgr_SWIFT_HealthCheck)); swift_resource->register_resource("info", - set_logging(new RGWRESTMgr_SWIFT_Info(&auth_strategy))); + set_logging(new RGWRESTMgr_SWIFT_Info)); if (! swift_at_root) { rest.register_resource(g_conf->rgw_swift_url_prefix, @@ -437,6 +433,11 @@ int main(int argc, const char **argv) rest.register_resource(g_conf->rgw_admin_entry, admin_resource); } + /* Initialize the registry of auth strategies which will coordinate + * the dynamic reconfiguration. */ + auto auth_registry = \ + rgw::auth::StrategyRegistry::create(g_ceph_context, store); + /* Header custom behavior */ rest.register_x_headers(g_conf->rgw_log_http_headers); @@ -474,7 +475,7 @@ int main(int argc, const char **argv) std::string uri_prefix; config->get_val("prefix", "", &uri_prefix); - RGWProcessEnv env = { store, &rest, olog, 0, uri_prefix }; + RGWProcessEnv env = { store, &rest, olog, 0, uri_prefix, auth_registry }; fe = new RGWCivetWebFrontend(env, config); } @@ -484,7 +485,7 @@ int main(int argc, const char **argv) std::string uri_prefix; config->get_val("prefix", "", &uri_prefix); - RGWProcessEnv env = { store, &rest, olog, port, uri_prefix }; + RGWProcessEnv env = { store, &rest, olog, port, uri_prefix, auth_registry }; fe = new RGWLoadGenFrontend(env, config); } @@ -495,7 +496,7 @@ int main(int argc, const char **argv) config->get_val("port", 80, &port); std::string uri_prefix; config->get_val("prefix", "", &uri_prefix); - RGWProcessEnv env{ store, &rest, olog, port, uri_prefix }; + RGWProcessEnv env{ store, &rest, olog, port, uri_prefix, auth_registry }; fe = new RGWAsioFrontend(env); } #endif /* WITH_RADOSGW_ASIO_FRONTEND */ @@ -503,7 +504,7 @@ int main(int argc, const char **argv) else if (framework == "fastcgi" || framework == "fcgi") { std::string uri_prefix; config->get_val("prefix", "", &uri_prefix); - RGWProcessEnv fcgi_pe = { store, &rest, olog, 0, uri_prefix }; + RGWProcessEnv fcgi_pe = { store, &rest, olog, 0, uri_prefix, auth_registry }; fe = new RGWFCGXFrontend(fcgi_pe, config); } diff --git a/src/rgw/rgw_op.h b/src/rgw/rgw_op.h index 4eff628b092..318340f6a29 100644 --- a/src/rgw/rgw_op.h +++ b/src/rgw/rgw_op.h @@ -47,6 +47,18 @@ using ceph::crypto::SHA1; struct req_state; class RGWOp; + +namespace rgw { +namespace auth { +namespace registry { + +class StrategyRegistry; + +} +} +} + + class RGWHandler { protected: RGWRados* store; @@ -140,7 +152,7 @@ public: * authentication. The alternative is to duplicate parts of the method- * dispatch logic in RGWHandler::authorize() and pollute it with a lot * of special cases. */ - virtual int verify_requester() { + virtual int verify_requester(const rgw::auth::StrategyRegistry& auth_registry) { /* TODO(rzarzynski): rename RGWHandler::authorize to generic_authenticate. */ return dialect_handler->authorize(); } diff --git a/src/rgw/rgw_process.cc b/src/rgw/rgw_process.cc index efe247ed472..6fbf2fdb594 100644 --- a/src/rgw/rgw_process.cc +++ b/src/rgw/rgw_process.cc @@ -113,6 +113,7 @@ int process_request(RGWRados* const store, RGWREST* const rest, RGWRequest* const req, const std::string& frontend_prefix, + const rgw_auth_registry_t& auth_registry, RGWRestfulIO* const client_io, OpsLogSocket* const olog) { @@ -146,7 +147,9 @@ int process_request(RGWRados* const store, int init_error = 0; bool should_log = false; RGWRESTMgr *mgr; - RGWHandler_REST *handler = rest->get_handler(store, s, frontend_prefix, + RGWHandler_REST *handler = rest->get_handler(store, s, + auth_registry, + frontend_prefix, client_io, &mgr, &init_error); if (init_error != 0) { abort_early(s, NULL, init_error, NULL); @@ -169,7 +172,7 @@ int process_request(RGWRados* const store, s->op_type = op->get_type(); req->log(s, "verifying requester"); - ret = op->verify_requester(); + ret = op->verify_requester(auth_registry); if (ret < 0) { dout(10) << "failed to authorize request" << dendl; abort_early(s, NULL, ret, handler); diff --git a/src/rgw/rgw_process.h b/src/rgw/rgw_process.h index bd3c46261f6..83c59a4cc37 100644 --- a/src/rgw/rgw_process.h +++ b/src/rgw/rgw_process.h @@ -7,6 +7,7 @@ #include "rgw_common.h" #include "rgw_rados.h" #include "rgw_acl.h" +#include "rgw_auth_registry.h" #include "rgw_user.h" #include "rgw_op.h" #include "rgw_rest.h" @@ -31,6 +32,7 @@ struct RGWProcessEnv { OpsLogSocket *olog; int port; std::string uri_prefix; + std::shared_ptr auth_registry; }; class RGWFrontendConfig; @@ -40,6 +42,7 @@ class RGWProcess { protected: CephContext *cct; RGWRados* store; + rgw_auth_registry_ptr_t auth_registry; OpsLogSocket* olog; ThreadPool m_tp; Throttle req_throttle; @@ -104,6 +107,7 @@ public: RGWFrontendConfig* const conf) : cct(cct), store(pe->store), + auth_registry(pe->auth_registry), olog(pe->olog), m_tp(cct, "RGWProcess::m_tp", "tp_rgw_process", num_threads), req_throttle(cct, "rgw_ops", num_threads * 2), @@ -124,8 +128,10 @@ public: m_tp.pause(); } - void unpause_with_new_config(RGWRados *store) { + void unpause_with_new_config(RGWRados* const store, + rgw_auth_registry_ptr_t auth_registry) { this->store = store; + this->auth_registry = std::move(auth_registry); m_tp.unpause(); } @@ -186,6 +192,7 @@ extern int process_request(RGWRados* store, RGWREST* rest, RGWRequest* req, const std::string& frontend_prefix, + const rgw_auth_registry_t& auth_registry, RGWRestfulIO* client_io, OpsLogSocket* olog); diff --git a/src/rgw/rgw_rest.cc b/src/rgw/rgw_rest.cc index c3c44fa4d04..0a5fac47aa7 100644 --- a/src/rgw/rgw_rest.cc +++ b/src/rgw/rgw_rest.cc @@ -2077,13 +2077,15 @@ int RGWREST::preprocess(struct req_state *s, rgw::io::BasicClient* cio) return 0; } -RGWHandler_REST* RGWREST::get_handler(RGWRados * const store, - struct req_state* const s, - const std::string& frontend_prefix, - RGWRestfulIO* const rio, - RGWRESTMgr** const pmgr, - int* const init_error) -{ +RGWHandler_REST* RGWREST::get_handler( + RGWRados * const store, + struct req_state* const s, + const rgw::auth::StrategyRegistry& auth_registry, + const std::string& frontend_prefix, + RGWRestfulIO* const rio, + RGWRESTMgr** const pmgr, + int* const init_error +) { *init_error = preprocess(s, rio); if (*init_error < 0) { return nullptr; @@ -2100,7 +2102,7 @@ RGWHandler_REST* RGWREST::get_handler(RGWRados * const store, *pmgr = m; } - RGWHandler_REST* handler = m->get_handler(s, frontend_prefix); + RGWHandler_REST* handler = m->get_handler(s, auth_registry, frontend_prefix); if (! handler) { *init_error = -ERR_METHOD_NOT_ALLOWED; return NULL; diff --git a/src/rgw/rgw_rest.h b/src/rgw/rgw_rest.h index 6e0a87ea4cb..1d530d05ee4 100644 --- a/src/rgw/rgw_rest.h +++ b/src/rgw/rgw_rest.h @@ -438,6 +438,13 @@ class RGWHandler_REST_SWIFT; class RGWHandler_SWIFT_Auth; class RGWHandler_REST_S3; +namespace rgw { +namespace auth { + +class StrategyRegistry; + +} +} class RGWRESTMgr { bool should_log; @@ -476,8 +483,11 @@ public: return get_resource_mgr(s, frontend_prefix + uri, out_uri); } - virtual RGWHandler_REST* get_handler(struct req_state* const s, - const std::string& frontend_prefix) { + virtual RGWHandler_REST* get_handler( + struct req_state* const s, + const rgw::auth::StrategyRegistry& auth_registry, + const std::string& frontend_prefix + ) { return nullptr; } @@ -507,6 +517,7 @@ public: RGWREST() {} RGWHandler_REST *get_handler(RGWRados *store, struct req_state *s, + const rgw::auth::StrategyRegistry& auth_registry, const std::string& frontend_prefix, RGWRestfulIO *rio, RGWRESTMgr **pmgr, diff --git a/src/rgw/rgw_rest_bucket.h b/src/rgw/rgw_rest_bucket.h index 108151500ba..19bfd7347f8 100644 --- a/src/rgw/rgw_rest_bucket.h +++ b/src/rgw/rgw_rest_bucket.h @@ -15,8 +15,8 @@ protected: RGWOp *op_post() override; RGWOp *op_delete() override; public: - RGWHandler_Bucket() {} - ~RGWHandler_Bucket() override {} + using RGWHandler_Auth_S3::RGWHandler_Auth_S3; + ~RGWHandler_Bucket() override = default; int read_permissions(RGWOp*) override { return 0; @@ -29,8 +29,9 @@ public: ~RGWRESTMgr_Bucket() override = default; RGWHandler_REST* get_handler(struct req_state*, + const rgw::auth::StrategyRegistry& auth_registry, const std::string&) override { - return new RGWHandler_Bucket; + return new RGWHandler_Bucket(auth_registry); } }; diff --git a/src/rgw/rgw_rest_config.h b/src/rgw/rgw_rest_config.h index a324334a995..5751f8b0687 100644 --- a/src/rgw/rgw_rest_config.h +++ b/src/rgw/rgw_rest_config.h @@ -62,8 +62,8 @@ protected: return 0; } public: - RGWHandler_Config() : RGWHandler_Auth_S3() {} - ~RGWHandler_Config() override {} + using RGWHandler_Auth_S3::RGWHandler_Auth_S3; + ~RGWHandler_Config() override = default; }; @@ -73,8 +73,9 @@ public: ~RGWRESTMgr_Config() override = default; RGWHandler_REST* get_handler(struct req_state*, + const rgw::auth::StrategyRegistry& auth_registry, const std::string&) override { - return new RGWHandler_Config; + return new RGWHandler_Config(auth_registry); } }; diff --git a/src/rgw/rgw_rest_log.h b/src/rgw/rgw_rest_log.h index 8c6cf5251d1..6fdce665231 100644 --- a/src/rgw/rgw_rest_log.h +++ b/src/rgw/rgw_rest_log.h @@ -315,8 +315,8 @@ protected: return 0; } public: - RGWHandler_Log() : RGWHandler_Auth_S3() {} - ~RGWHandler_Log() override {} + using RGWHandler_Auth_S3::RGWHandler_Auth_S3; + ~RGWHandler_Log() override = default; }; class RGWRESTMgr_Log : public RGWRESTMgr { @@ -325,8 +325,9 @@ public: ~RGWRESTMgr_Log() override = default; RGWHandler_REST* get_handler(struct req_state* const, + const rgw::auth::StrategyRegistry& auth_registry, const std::string& frontend_prefixs) override { - return new RGWHandler_Log; + return new RGWHandler_Log(auth_registry); } }; diff --git a/src/rgw/rgw_rest_metadata.h b/src/rgw/rgw_rest_metadata.h index ccd4b903637..bf29f0aab26 100644 --- a/src/rgw/rgw_rest_metadata.h +++ b/src/rgw/rgw_rest_metadata.h @@ -107,8 +107,8 @@ protected: return 0; } public: - RGWHandler_Metadata() : RGWHandler_Auth_S3() {} - ~RGWHandler_Metadata() override {} + using RGWHandler_Auth_S3::RGWHandler_Auth_S3; + ~RGWHandler_Metadata() override = default; }; class RGWRESTMgr_Metadata : public RGWRESTMgr { @@ -117,8 +117,9 @@ public: ~RGWRESTMgr_Metadata() override = default; RGWHandler_REST* get_handler(struct req_state* const s, + const rgw::auth::StrategyRegistry& auth_registry, const std::string& frontend_prefix) override { - return new RGWHandler_Metadata; + return new RGWHandler_Metadata(auth_registry); } }; diff --git a/src/rgw/rgw_rest_opstate.h b/src/rgw/rgw_rest_opstate.h index 8439f5ebbd2..82873e6bc6e 100644 --- a/src/rgw/rgw_rest_opstate.h +++ b/src/rgw/rgw_rest_opstate.h @@ -92,8 +92,8 @@ protected: return 0; } public: - RGWHandler_Opstate() : RGWHandler_Auth_S3() {} - ~RGWHandler_Opstate() override {} + using RGWHandler_Auth_S3::RGWHandler_Auth_S3; + ~RGWHandler_Opstate() override = default; }; class RGWRESTMgr_Opstate : public RGWRESTMgr { @@ -102,8 +102,9 @@ public: ~RGWRESTMgr_Opstate() override = default; RGWHandler_REST* get_handler(struct req_state*, + const rgw::auth::StrategyRegistry& auth_registry, const std::string&) override { - return new RGWHandler_Opstate; + return new RGWHandler_Opstate(auth_registry); } }; diff --git a/src/rgw/rgw_rest_realm.cc b/src/rgw/rgw_rest_realm.cc index b4cde344c8e..406f3d40a99 100644 --- a/src/rgw/rgw_rest_realm.cc +++ b/src/rgw/rgw_rest_realm.cc @@ -222,6 +222,8 @@ void RGWOp_Period_Post::execute() class RGWHandler_Period : public RGWHandler_Auth_S3 { protected: + using RGWHandler_Auth_S3::RGWHandler_Auth_S3; + RGWOp *op_get() override { return new RGWOp_Period_Get; } RGWOp *op_post() override { return new RGWOp_Period_Post; } }; @@ -229,8 +231,9 @@ class RGWHandler_Period : public RGWHandler_Auth_S3 { class RGWRESTMgr_Period : public RGWRESTMgr { public: RGWHandler_REST* get_handler(struct req_state*, + const rgw::auth::StrategyRegistry& auth_registry, const std::string&) override { - return new RGWHandler_Period; + return new RGWHandler_Period(auth_registry); } }; @@ -277,6 +280,7 @@ void RGWOp_Realm_Get::send_response() class RGWHandler_Realm : public RGWHandler_Auth_S3 { protected: + using RGWHandler_Auth_S3::RGWHandler_Auth_S3; RGWOp *op_get() override { return new RGWOp_Realm_Get; } }; @@ -286,8 +290,10 @@ RGWRESTMgr_Realm::RGWRESTMgr_Realm() register_resource("period", new RGWRESTMgr_Period); } -RGWHandler_REST* RGWRESTMgr_Realm::get_handler(struct req_state*, - const std::string&) +RGWHandler_REST* +RGWRESTMgr_Realm::get_handler(struct req_state*, + const rgw::auth::StrategyRegistry& auth_registry, + const std::string&) { - return new RGWHandler_Realm; + return new RGWHandler_Realm(auth_registry); } diff --git a/src/rgw/rgw_rest_realm.h b/src/rgw/rgw_rest_realm.h index 6d554949556..68566bcbfd1 100644 --- a/src/rgw/rgw_rest_realm.h +++ b/src/rgw/rgw_rest_realm.h @@ -11,6 +11,7 @@ public: RGWRESTMgr_Realm(); RGWHandler_REST* get_handler(struct req_state*, + const rgw::auth::StrategyRegistry& auth_registry, const std::string&) override; }; diff --git a/src/rgw/rgw_rest_replica_log.h b/src/rgw/rgw_rest_replica_log.h index aad920c4fd9..a6cb7ec0a3b 100644 --- a/src/rgw/rgw_rest_replica_log.h +++ b/src/rgw/rgw_rest_replica_log.h @@ -138,8 +138,8 @@ protected: return 0; } public: - RGWHandler_ReplicaLog() : RGWHandler_Auth_S3() {} - ~RGWHandler_ReplicaLog() override {} + using RGWHandler_Auth_S3::RGWHandler_Auth_S3; + ~RGWHandler_ReplicaLog() override = default; }; class RGWRESTMgr_ReplicaLog : public RGWRESTMgr { @@ -148,8 +148,9 @@ public: ~RGWRESTMgr_ReplicaLog() override = default; RGWHandler_REST* get_handler(struct req_state*, + const rgw::auth::StrategyRegistry& auth_registry, const std::string&) override { - return new RGWHandler_ReplicaLog; + return new RGWHandler_ReplicaLog(auth_registry); } }; diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index 5d18249e2f8..3223e646416 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -27,6 +27,7 @@ #include "rgw_keystone.h" #include "rgw_auth_keystone.h" +#include "rgw_auth_registry.h" #include // for 'typeid' @@ -1818,8 +1819,7 @@ int RGWPostObj_ObjStore_S3::get_policy() /* FIXME: this is a makeshift solution. The browser upload authentication will be * handled by an instance of rgw::auth::Completer spawned in Handler's authorize() * method. */ - static const rgw::auth::s3::AWSv2AuthStrategy< - rgw::auth::s3::RGWGetPolicyV2Extractor> strategy(g_ceph_context, store); + const auto& strategy = auth_registry_ptr->get_s3_post(); try { auto result = strategy.authenticate(s); if (result.get_status() != decltype(result)::Status::GRANTED) { @@ -3220,7 +3220,9 @@ static void init_anon_user(struct req_state *s) * * it tries AWS v4 before AWS v2 */ -int RGW_Auth_S3::authorize(RGWRados *store, struct req_state *s) +int RGW_Auth_S3::authorize(RGWRados* const store, + const rgw::auth::StrategyRegistry& auth_registry, + struct req_state* const s) { /* neither keystone and rados enabled; warn and exit! */ @@ -3259,7 +3261,7 @@ int RGW_Auth_S3::authorize(RGWRados *store, struct req_state *s) string auth_id = s->info.args.get("AWSAccessKeyId"); if (auth_id.size()) { - return authorize_v2(store, s); + return authorize_v2(store, auth_registry, s); } /* anonymous access */ @@ -3279,7 +3281,7 @@ int RGW_Auth_S3::authorize(RGWRados *store, struct req_state *s) /* AWS2 */ if (!strncmp(s->http_auth, "AWS ", 4)) { - return authorize_v2(store, s); + return authorize_v2(store, auth_registry, s); } } @@ -3881,13 +3883,13 @@ int RGW_Auth_S3::authorize_v4(RGWRados *store, struct req_state *s, bool force_b /* * handle v2 signatures */ -int RGW_Auth_S3::authorize_v2(RGWRados *store, struct req_state *s) +int RGW_Auth_S3::authorize_v2(RGWRados* const store, + const rgw::auth::StrategyRegistry& auth_registry, + struct req_state* const s) { - /* TODO(rzarzynski): this will be moved to the S3 handlers -- in exactly - * way like we currently have in the case of Swift API. */ - static const rgw::auth::s3::AWSv2AuthStrategy strategy(g_ceph_context, store); + const auto& auth_strategy = auth_registry.get_s3_main(); try { - auto result = strategy.authenticate(s); + auto result = auth_strategy.authenticate(s); if (result.get_status() != decltype(result)::Status::GRANTED) { ldout(s->cct, 5) << "Failed the S3 auth strategy, reason=" << result.get_reason() << dendl; @@ -3931,6 +3933,7 @@ int RGWHandler_Auth_S3::init(RGWRados *store, struct req_state *state, } RGWHandler_REST* RGWRESTMgr_S3::get_handler(struct req_state* const s, + const rgw::auth::StrategyRegistry& auth_registry, const std::string& frontend_prefix) { bool is_s3website = enable_s3website && (s->prot_flags & RGW_REST_WEBSITE); @@ -3945,19 +3948,19 @@ RGWHandler_REST* RGWRESTMgr_S3::get_handler(struct req_state* const s, // TODO: Make this more readable if (is_s3website) { if (s->init_state.url_bucket.empty()) { - handler = new RGWHandler_REST_Service_S3Website; + handler = new RGWHandler_REST_Service_S3Website(auth_registry); } else if (s->object.empty()) { - handler = new RGWHandler_REST_Bucket_S3Website; + handler = new RGWHandler_REST_Bucket_S3Website(auth_registry); } else { - handler = new RGWHandler_REST_Obj_S3Website; + handler = new RGWHandler_REST_Obj_S3Website(auth_registry); } } else { if (s->init_state.url_bucket.empty()) { - handler = new RGWHandler_REST_Service_S3; + handler = new RGWHandler_REST_Service_S3(auth_registry); } else if (s->object.empty()) { - handler = new RGWHandler_REST_Bucket_S3; + handler = new RGWHandler_REST_Bucket_S3(auth_registry); } else { - handler = new RGWHandler_REST_Obj_S3; + handler = new RGWHandler_REST_Obj_S3(auth_registry); } } diff --git a/src/rgw/rgw_rest_s3.h b/src/rgw/rgw_rest_s3.h index 863195b35b1..94048ba3a52 100644 --- a/src/rgw/rgw_rest_s3.h +++ b/src/rgw/rgw_rest_s3.h @@ -200,6 +200,8 @@ class RGWPostObj_ObjStore_S3 : public RGWPostObj_ObjStore { RGWPolicy post_policy; string err_msg; + const rgw::auth::StrategyRegistry* auth_registry_ptr = nullptr; + int read_with_boundary(bufferlist& bl, uint64_t max, bool check_eol, bool *reached_boundary, bool *done); @@ -220,6 +222,11 @@ public: RGWPostObj_ObjStore_S3() {} ~RGWPostObj_ObjStore_S3() override {} + int verify_requester(const rgw::auth::StrategyRegistry& auth_registry) { + auth_registry_ptr = &auth_registry; + return RGWPostObj_ObjStore::verify_requester(auth_registry); + } + int get_params() override; int complete_get_params(); void send_response() override; @@ -410,21 +417,31 @@ public: class RGW_Auth_S3 { private: - static int authorize_v2(RGWRados *store, struct req_state *s); + static int authorize_v2(RGWRados *store, + const rgw::auth::StrategyRegistry& auth_registry, + struct req_state *s); static int authorize_v4(RGWRados *store, struct req_state *s, bool force_boto2_compat = true); static int authorize_v4_complete(RGWRados *store, struct req_state *s, const string& request_payload, bool unsigned_payload); public: - static int authorize(RGWRados *store, struct req_state *s); + static int authorize(RGWRados *store, + const rgw::auth::StrategyRegistry& auth_registry, + struct req_state *s); static int authorize_aws4_auth_complete(RGWRados *store, struct req_state *s); }; class RGWHandler_Auth_S3 : public RGWHandler_REST { friend class RGWRESTMgr_S3; + + const rgw::auth::StrategyRegistry& auth_registry; + public: - RGWHandler_Auth_S3() : RGWHandler_REST() {} - ~RGWHandler_Auth_S3() override {} + RGWHandler_Auth_S3(const rgw::auth::StrategyRegistry& auth_registry) + : RGWHandler_REST(), + auth_registry(auth_registry) { + } + ~RGWHandler_Auth_S3() override = default; static int validate_bucket_name(const string& bucket); static int validate_object_name(const string& bucket); @@ -433,24 +450,29 @@ public: struct req_state *s, rgw::io::BasicClient *cio) override; int authorize() override { - return RGW_Auth_S3::authorize(store, s); + return RGW_Auth_S3::authorize(store, auth_registry, s); } int postauth_init() override { return 0; } }; class RGWHandler_REST_S3 : public RGWHandler_REST { friend class RGWRESTMgr_S3; + + const rgw::auth::StrategyRegistry& auth_registry; public: static int init_from_header(struct req_state *s, int default_formatter, bool configurable_format); - RGWHandler_REST_S3() : RGWHandler_REST() {} - ~RGWHandler_REST_S3() override {} + RGWHandler_REST_S3(const rgw::auth::StrategyRegistry& auth_registry) + : RGWHandler_REST(), + auth_registry(auth_registry) { + } + ~RGWHandler_REST_S3() override = default; int init(RGWRados *store, struct req_state *s, rgw::io::BasicClient *cio) override; int authorize() override { - return RGW_Auth_S3::authorize(store, s); + return RGW_Auth_S3::authorize(store, auth_registry, s); } int postauth_init() override; }; @@ -464,8 +486,8 @@ protected: RGWOp *op_head() override; RGWOp *op_post() override; public: - RGWHandler_REST_Service_S3() {} - ~RGWHandler_REST_Service_S3() override {} + using RGWHandler_REST_S3::RGWHandler_REST_S3; + ~RGWHandler_REST_Service_S3() override = default; }; class RGWHandler_REST_Bucket_S3 : public RGWHandler_REST_S3 { @@ -494,8 +516,8 @@ protected: RGWOp *op_post() override; RGWOp *op_options() override; public: - RGWHandler_REST_Bucket_S3() {} - ~RGWHandler_REST_Bucket_S3() override {} + using RGWHandler_REST_S3::RGWHandler_REST_S3; + ~RGWHandler_REST_Bucket_S3() override = default; }; class RGWHandler_REST_Obj_S3 : public RGWHandler_REST_S3 { @@ -518,8 +540,8 @@ protected: RGWOp *op_post() override; RGWOp *op_options() override; public: - RGWHandler_REST_Obj_S3() {} - ~RGWHandler_REST_Obj_S3() override {} + using RGWHandler_REST_S3::RGWHandler_REST_S3; + ~RGWHandler_REST_Obj_S3() override = default; }; class RGWRESTMgr_S3 : public RGWRESTMgr { @@ -533,6 +555,7 @@ public: ~RGWRESTMgr_S3() override = default; RGWHandler_REST *get_handler(struct req_state* s, + const rgw::auth::StrategyRegistry& auth_registry, const std::string& frontend_prefix) override; }; diff --git a/src/rgw/rgw_rest_s3website.h b/src/rgw/rgw_rest_s3website.h index c248b9f2963..3a87c5eefd9 100644 --- a/src/rgw/rgw_rest_s3website.h +++ b/src/rgw/rgw_rest_s3website.h @@ -34,8 +34,8 @@ protected: int serve_errordoc(int http_ret, const string &errordoc_key); public: - RGWHandler_REST_S3Website() : RGWHandler_REST_S3() {} - ~RGWHandler_REST_S3Website() override {} + using RGWHandler_REST_S3::RGWHandler_REST_S3; + ~RGWHandler_REST_S3Website() override = default; int error_handler(int err_no, string *error_content) override; }; @@ -43,16 +43,16 @@ class RGWHandler_REST_Service_S3Website : public RGWHandler_REST_S3Website { protected: RGWOp *get_obj_op(bool get_data) override; public: - RGWHandler_REST_Service_S3Website() {} - ~RGWHandler_REST_Service_S3Website() override {} + using RGWHandler_REST_S3Website::RGWHandler_REST_S3Website; + ~RGWHandler_REST_Service_S3Website() override = default; }; class RGWHandler_REST_Obj_S3Website : public RGWHandler_REST_S3Website { protected: RGWOp *get_obj_op(bool get_data) override; public: - RGWHandler_REST_Obj_S3Website() {} - ~RGWHandler_REST_Obj_S3Website() override {} + using RGWHandler_REST_S3Website::RGWHandler_REST_S3Website; + ~RGWHandler_REST_Obj_S3Website() override = default; }; /* The cross-inheritance from Obj to Bucket is deliberate! @@ -62,8 +62,8 @@ class RGWHandler_REST_Bucket_S3Website : public RGWHandler_REST_S3Website { protected: RGWOp *get_obj_op(bool get_data) override; public: - RGWHandler_REST_Bucket_S3Website() {} - ~RGWHandler_REST_Bucket_S3Website() override {} + using RGWHandler_REST_S3Website::RGWHandler_REST_S3Website; + ~RGWHandler_REST_Bucket_S3Website() override = default; }; // TODO: do we actually need this? diff --git a/src/rgw/rgw_rest_swift.cc b/src/rgw/rgw_rest_swift.cc index 9f06fa46187..40c940b47bf 100644 --- a/src/rgw/rgw_rest_swift.cc +++ b/src/rgw/rgw_rest_swift.cc @@ -2329,8 +2329,10 @@ int RGWHandler_REST_SWIFT::init(RGWRados* store, struct req_state* s, return RGWHandler_REST::init(store, s, cio); } -RGWHandler_REST* RGWRESTMgr_SWIFT::get_handler(struct req_state* const s, - const std::string& frontend_prefix) +RGWHandler_REST* +RGWRESTMgr_SWIFT::get_handler(struct req_state* const s, + const rgw::auth::StrategyRegistry& auth_registry, + const std::string& frontend_prefix) { int ret = RGWHandler_REST_SWIFT::init_from_header(s, frontend_prefix); if (ret < 0) { @@ -2338,6 +2340,8 @@ RGWHandler_REST* RGWRESTMgr_SWIFT::get_handler(struct req_state* const s, return nullptr; } + const auto& auth_strategy = auth_registry.get_swift(); + if (s->init_state.url_bucket.empty()) { return new RGWHandler_REST_Service_SWIFT(auth_strategy); } @@ -2351,8 +2355,10 @@ RGWHandler_REST* RGWRESTMgr_SWIFT::get_handler(struct req_state* const s, RGWHandler_REST* RGWRESTMgr_SWIFT_Info::get_handler( struct req_state* const s, + const rgw::auth::StrategyRegistry& auth_registry, const std::string& frontend_prefix) { s->prot_flags |= RGW_REST_SWIFT; + const auto& auth_strategy = auth_registry.get_swift(); return new RGWHandler_REST_SWIFT_Info(auth_strategy); } diff --git a/src/rgw/rgw_rest_swift.h b/src/rgw/rgw_rest_swift.h index a28fc2836c0..d2a1d72d8f1 100644 --- a/src/rgw/rgw_rest_swift.h +++ b/src/rgw/rgw_rest_swift.h @@ -368,8 +368,6 @@ public: }; class RGWRESTMgr_SWIFT : public RGWRESTMgr { - const rgw::auth::Strategy& auth_strategy; - protected: RGWRESTMgr* get_resource_mgr_as_default(struct req_state* const s, const std::string& uri, @@ -378,12 +376,11 @@ protected: } public: - RGWRESTMgr_SWIFT(const rgw::auth::Strategy* const auth_strategy) - : auth_strategy(*auth_strategy) { - } + RGWRESTMgr_SWIFT() = default; ~RGWRESTMgr_SWIFT() override = default; RGWHandler_REST *get_handler(struct req_state *s, + const rgw::auth::StrategyRegistry& auth_registry, const std::string& frontend_prefix) override; }; @@ -454,6 +451,7 @@ public: ~RGWRESTMgr_SWIFT_CrossDomain() override = default; RGWHandler_REST* get_handler(struct req_state* const s, + const rgw::auth::StrategyRegistry&, const std::string&) override { s->prot_flags |= RGW_REST_SWIFT; return new RGWHandler_SWIFT_CrossDomain; @@ -509,6 +507,7 @@ public: ~RGWRESTMgr_SWIFT_HealthCheck() override = default; RGWHandler_REST* get_handler(struct req_state* const s, + const rgw::auth::StrategyRegistry&, const std::string&) override { s->prot_flags |= RGW_REST_SWIFT; return new RGWHandler_SWIFT_HealthCheck; @@ -518,10 +517,7 @@ public: class RGWHandler_REST_SWIFT_Info : public RGWHandler_REST_SWIFT { public: - //using RGWHandler_REST_SWIFT::RGWHandler_REST_SWIFT; - RGWHandler_REST_SWIFT_Info(const rgw::auth::Strategy& auth_strategy) - : RGWHandler_REST_SWIFT(auth_strategy) { - } + using RGWHandler_REST_SWIFT::RGWHandler_REST_SWIFT; ~RGWHandler_REST_SWIFT_Info() override = default; RGWOp *op_get() override { @@ -552,15 +548,12 @@ public: }; class RGWRESTMgr_SWIFT_Info : public RGWRESTMgr { - const rgw::auth::Strategy& auth_strategy; - public: - RGWRESTMgr_SWIFT_Info(const rgw::auth::Strategy* const auth_strategy) - : auth_strategy(*auth_strategy) { - } + RGWRESTMgr_SWIFT_Info() = default; ~RGWRESTMgr_SWIFT_Info() override = default; RGWHandler_REST *get_handler(struct req_state* s, + const rgw::auth::StrategyRegistry& auth_registry, const std::string& frontend_prefix) override; }; diff --git a/src/rgw/rgw_rest_usage.h b/src/rgw/rgw_rest_usage.h index 14c37da1cb1..a09f32d0fe9 100644 --- a/src/rgw/rgw_rest_usage.h +++ b/src/rgw/rgw_rest_usage.h @@ -13,8 +13,8 @@ protected: RGWOp *op_get() override; RGWOp *op_delete() override; public: - RGWHandler_Usage() {} - ~RGWHandler_Usage() override {} + using RGWHandler_Auth_S3::RGWHandler_Auth_S3; + ~RGWHandler_Usage() override = default; int read_permissions(RGWOp*) override { return 0; @@ -27,8 +27,9 @@ public: ~RGWRESTMgr_Usage() override = default; RGWHandler_REST* get_handler(struct req_state*, + const rgw::auth::StrategyRegistry& auth_registry, const std::string&) override { - return new RGWHandler_Usage; + return new RGWHandler_Usage(auth_registry); } }; diff --git a/src/rgw/rgw_rest_user.h b/src/rgw/rgw_rest_user.h index 4a69ee55939..047fe5ffd60 100644 --- a/src/rgw/rgw_rest_user.h +++ b/src/rgw/rgw_rest_user.h @@ -15,8 +15,8 @@ protected: RGWOp *op_post() override; RGWOp *op_delete() override; public: - RGWHandler_User() {} - ~RGWHandler_User() override {} + using RGWHandler_Auth_S3::RGWHandler_Auth_S3; + ~RGWHandler_User() override = default; int read_permissions(RGWOp*) override { return 0; @@ -29,8 +29,9 @@ public: ~RGWRESTMgr_User() override = default; RGWHandler_REST *get_handler(struct req_state*, + const rgw::auth::StrategyRegistry& auth_registry, const std::string&) override { - return new RGWHandler_User; + return new RGWHandler_User(auth_registry); } }; diff --git a/src/rgw/rgw_swift_auth.h b/src/rgw/rgw_swift_auth.h index d4ed3c29155..055d541d327 100644 --- a/src/rgw/rgw_swift_auth.h +++ b/src/rgw/rgw_swift_auth.h @@ -306,6 +306,7 @@ public: } RGWHandler_REST* get_handler(struct req_state*, + const rgw::auth::StrategyRegistry&, const std::string&) override { return new RGWHandler_SWIFT_Auth; } -- 2.39.5