From: Radoslaw Zarzynski Date: Wed, 11 Jan 2017 15:08:39 +0000 (+0100) Subject: rgw: implement the rgw::auth::SysReqApplier over IdentityApplier. X-Git-Tag: v12.0.2~305^2~19 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=89d813a3927f564f1d6f5e97b1c2fb20df507a58;p=ceph.git rgw: implement the rgw::auth::SysReqApplier over IdentityApplier. Signed-off-by: Radoslaw Zarzynski --- diff --git a/src/rgw/rgw_auth.cc b/src/rgw/rgw_auth.cc index 7ae215a85267..27840f28490b 100644 --- a/src/rgw/rgw_auth.cc +++ b/src/rgw/rgw_auth.cc @@ -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); } diff --git a/src/rgw/rgw_auth.h b/src/rgw/rgw_auth.h index c38a905e2e01..6755c8812b0f 100644 --- a/src/rgw/rgw_auth.h +++ b/src/rgw/rgw_auth.h @@ -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; }; diff --git a/src/rgw/rgw_auth_filters.h b/src/rgw/rgw_auth_filters.h index 1a442648c4bc..204a43e73f80 100644 --- a/src/rgw/rgw_auth_filters.h +++ b/src/rgw/rgw_auth_filters.h @@ -6,6 +6,7 @@ #include +#include #include #include "rgw_common.h" @@ -175,6 +176,85 @@ ThirdPartyAccountApplier add_3rdparty(RGWRados* const store, std::forward(t)); } + +template +class SysReqApplier : public DecoratedApplier { + CephContext* const cct; + /*const*/ RGWRados* const store; + const RGWHTTPArgs& args; + mutable boost::tribool is_system; + +public: + template + SysReqApplier(CephContext* const cct, + /*const*/ RGWRados* const store, + const req_state* const s, + U&& decoratee) + : DecoratedApplier(std::forward(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 +void SysReqApplier::to_str(std::ostream& out) const +{ + out << "rgw::auth::SysReqApplier" << " -> "; + DecoratedApplier::to_str(out); +} + +template +void SysReqApplier::load_acct_info(RGWUserInfo& user_info) const +{ + DecoratedApplier::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 +void SysReqApplier::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 static inline +SysReqApplier add_sysreq(CephContext* const cct, + /* const */ RGWRados* const store, + const req_state* const s, + T&& t) { + return SysReqApplier(cct, store, s, std::forward(t)); +} + } /* namespace auth */ } /* namespace rgw */ diff --git a/src/rgw/rgw_auth_keystone.cc b/src/rgw/rgw_auth_keystone.cc index e715982644d5..a789cb22472f 100644 --- a/src/rgw/rgw_auth_keystone.cc +++ b/src/rgw/rgw_auth_keystone.cc @@ -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. */ diff --git a/src/rgw/rgw_auth_keystone.h b/src/rgw/rgw_auth_keystone.h index eae1012bec1a..3307b4865d88 100644 --- a/src/rgw/rgw_auth_keystone.h +++ b/src/rgw/rgw_auth_keystone.h @@ -39,7 +39,8 @@ class TokenEngine : public rgw::auth::Engine { auth_info_t get_creds_info(const token_envelope_t& token, const std::vector& 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, diff --git a/src/rgw/rgw_auth_s3.h b/src/rgw/rgw_auth_s3.h index 345ac0ce840f..7e5205cf5544 100644 --- a/src/rgw/rgw_auth_s3.h +++ b/src/rgw/rgw_auth_s3.h @@ -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 { diff --git a/src/rgw/rgw_common.cc b/src/rgw/rgw_common.cc index 6ff0d0753113..cce203b0faab 100644 --- a/src/rgw/rgw_common.cc +++ b/src/rgw/rgw_common.cc @@ -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()); diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h index 6a9b7ec9f454..06e30f2e0523 100644 --- a/src/rgw/rgw_common.h +++ b/src/rgw/rgw_common.h @@ -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 { diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index ef11286ca522..a902c614029f 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -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); } diff --git a/src/rgw/rgw_rest_s3.h b/src/rgw/rgw_rest_s3.h index 6276df239086..de2023c2a83a 100644 --- a/src/rgw/rgw_rest_s3.h +++ b/src/rgw/rgw_rest_s3.h @@ -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( diff --git a/src/rgw/rgw_swift_auth.cc b/src/rgw/rgw_swift_auth.cc index 594d7dbbcdaf..005d839045ab 100644 --- a/src/rgw/rgw_swift_auth.cc +++ b/src/rgw/rgw_swift_auth.cc @@ -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); } diff --git a/src/rgw/rgw_swift_auth.h b/src/rgw/rgw_swift_auth.h index 541ec99fa2f5..e11e87f19a98 100644 --- a/src/rgw/rgw_swift_auth.h +++ b/src/rgw/rgw_swift_auth.h @@ -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