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);
}
/* 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;
};
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;
};
#include <type_traits>
+#include <boost/logic/tribool.hpp>
#include <boost/optional.hpp>
#include "rgw_common.h"
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 */
}
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;
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);
}
<< ":" << 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);
}
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. */
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,
}
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 */
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,
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 {
}
}
-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());
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 {
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;
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);
}
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;
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);
}
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 {
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);
}
}
};
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,
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,
}
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 {
}
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(
<< 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
}
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);
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);
}
}
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);
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);
}
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;
};
};
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,
}
result_t authenticate(const req_state* const s) const override {
- return authenticate(extractor->get_token(s));
+ return authenticate(extractor->get_token(s), s);
}
};
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,
}
result_t authenticate(const req_state* const s) const override {
- return authenticate(extractor->get_token(s));
+ return authenticate(extractor->get_token(s), s);
}
};
}
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(
}
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