auto apl = \
apl_factory->create_apl_local(cct, s, std::move(user), std::nullopt, {},
rgw::auth::LocalApplier::NO_SUBUSER,
- std::nullopt, rgw::auth::LocalApplier::NO_ACCESS_KEY);
+ std::nullopt, rgw::auth::LocalApplier::NO_ACCESS_KEY,
+ false /* is_impersonating */);
return result_t::grant(std::move(apl));
}
}
std::vector<IAM::Policy> policies,
const std::string& subuser,
const std::optional<uint32_t>& perm_mask,
- const std::string& access_key_id) const = 0;
+ const std::string& access_key_id,
+ bool is_impersonating) const = 0;
};
};
CephContext* const cct;
rgw::sal::Driver* driver;
const RGWHTTPArgs& args;
- mutable boost::tribool is_system;
+ mutable boost::tribool is_system = boost::logic::indeterminate;
+ mutable bool is_impersonating;
mutable std::optional<ACLOwner> effective_owner;
mutable std::optional<std::string> effective_tenant;
SysReqApplier(CephContext* const cct,
rgw::sal::Driver* driver,
const req_state* const s,
- U&& decoratee)
+ U&& decoratee,
+ bool is_impersonating = false)
: DecoratedApplier<T>(std::forward<T>(decoratee)),
cct(cct),
driver(driver),
args(s->info.args),
- is_system(boost::logic::indeterminate) {
+ is_impersonating(is_impersonating) {
+ if (is_impersonating) {
+ // we only accept impersonated requests from a system user
+ is_system = true;
+ }
}
void to_str(std::ostream& out) const override;
return DecoratedApplier<T>::get_tenant();
}
+ bool is_admin_of(const rgw_owner& o) const override {
+ if (is_system && !is_impersonating) {
+ return true;
+ }
+
+ return DecoratedApplier<T>::is_admin_of(o);
+ }
};
template <typename T>
auto SysReqApplier<T>::load_acct_info(const DoutPrefixProvider* dpp) const -> std::unique_ptr<rgw::sal::User>
{
std::unique_ptr<rgw::sal::User> user = DecoratedApplier<T>::load_acct_info(dpp);
- is_system = user->get_info().system;
+ // skip loading the account info if we already have it through impersonation
+ if (is_impersonating) {
+ return user;
+ }
+
+ is_system = user->get_info().system;
if (is_system) {
//ldpp_dout(dpp, 20) << "system request" << dendl;
throw -EACCES;
}
effective_tenant = info.tenant;
- }
+ }
}
}
return user;
SysReqApplier<T> add_sysreq(CephContext* const cct,
rgw::sal::Driver* driver,
const req_state* const s,
- T&& t) {
- return SysReqApplier<T>(cct, driver, s, std::forward<T>(t));
+ T&& t,
+ bool is_impersonating = false) {
+ return SysReqApplier<T>(cct, driver, s, std::forward<T>(t), is_impersonating);
}
} /* namespace auth */
std::vector<IAM::Policy> policies,
const std::string& subuser,
const std::optional<uint32_t>& perm_mask,
- const std::string& access_key_id) const override {
+ const std::string& access_key_id,
+ bool is_impersonating) const override {
auto apl = rgw::auth::add_sysreq(cct, driver, s,
LocalApplier(cct, std::move(user), std::move(account), std::move(policies),
- subuser, perm_mask, access_key_id));
+ subuser, perm_mask, access_key_id), is_impersonating);
return aplptr_t(new decltype(apl)(std::move(apl)));
}
std::vector<IAM::Policy> policies,
const std::string& subuser,
const std::optional<uint32_t>& perm_mask,
- const std::string& access_key_id) const override {
+ const std::string& access_key_id,
+ bool is_impersonating) const override {
auto apl = rgw::auth::add_sysreq(cct, driver, s,
LocalApplier(cct, std::move(user), std::move(account), std::move(policies),
- subuser, perm_mask, access_key_id));
+ subuser, perm_mask, access_key_id), is_impersonating);
/* TODO(rzarzynski): replace with static_ptr. */
return aplptr_t(new decltype(apl)(std::move(apl)));
}
if (s->op_type == RGW_OP_OPTIONS_CORS) {
auto apl = apl_factory->create_apl_local(
cct, s, std::move(user), std::move(account), std::move(policies),
- k.subuser, std::nullopt, access_key_id);
+ k.subuser, std::nullopt, access_key_id, false /* is_impersonating */);
return result_t::grant(std::move(apl), completer_factory(k.key));
}
return result_t::deny(-ERR_SIGNATURE_NO_MATCH);
}
- auto apl = apl_factory->create_apl_local(
- cct, s, std::move(user), std::move(account), std::move(policies),
- k.subuser, std::nullopt, access_key_id);
+ aplptr_t apl;
+
+ // if this is a system request and we have rgwx-perm-check-uid passed,
+ // we do impersonation
+ if (user->get_info().system) {
+ const std::string perm_check_uid = s->info.args.get(RGW_SYS_PARAM_PREFIX "perm-check-uid");
+ if (!perm_check_uid.empty()) {
+ auto perm_check_user = driver->get_user(rgw_user(perm_check_uid));
+ if (int r = perm_check_user->load_user(dpp, y); r < 0) {
+ ldpp_dout(dpp, 0) << "ERROR: unable to load user info for "
+ << perm_check_uid << dendl;
+ return result_t::deny(r);
+ }
+
+ account.reset();
+ policies.clear();
+ // load account and policies for the impersonated user
+ int ret = load_account_and_policies(dpp, y, driver, perm_check_user->get_info(),
+ perm_check_user->get_attrs(), account, policies);
+ if (ret < 0) {
+ ldpp_dout(dpp, 0) << "ERROR: unable to load account and policies for "
+ << perm_check_uid << dendl;
+ return result_t::deny(ret);
+ }
+
+ apl = apl_factory->create_apl_local(
+ cct, s, std::move(perm_check_user), std::move(account), std::move(policies),
+ rgw::auth::LocalApplier::NO_SUBUSER, std::nullopt, rgw::auth::LocalApplier::NO_ACCESS_KEY,
+ true /* is_impersonating */);
+ }
+ }
+
+ if (!apl) {
+ // if we don't have impersonation, use the original user
+ // and the original access key id for logging
+ apl = apl_factory->create_apl_local(
+ cct, s, std::move(user), std::move(account), std::move(policies),
+ k.subuser, std::nullopt, access_key_id, false /* is_impersonating */);
+ }
+
return result_t::grant(std::move(apl), completer_factory(k.key));
}
string subuser;
auto apl = local_apl_factory->create_apl_local(
cct, s, std::move(user), std::move(account), std::move(policies),
- subuser, token.perm_mask, std::string(_access_key_id));
+ subuser, token.perm_mask, std::string(_access_key_id), false /* is_impersonating */);
return result_t::grant(std::move(apl), completer_factory(token.secret_access_key));
}
}
};
class LocalEngine : public AWSEngine {
+ typedef rgw::auth::IdentityApplier::aplptr_t aplptr_t;
rgw::sal::Driver* driver;
const rgw::auth::LocalApplier::Factory* const apl_factory;
auto apl = apl_factory->create_apl_local(
cct, s, std::move(user), std::move(account),
std::move(policies), extract_swift_subuser(swift_user),
- std::nullopt, LocalApplier::NO_ACCESS_KEY);
+ std::nullopt, LocalApplier::NO_ACCESS_KEY, false /* is_impersonating */);
return result_t::grant(std::move(apl));
}
auto apl = apl_factory->create_apl_local(
cct, s, std::move(user), std::move(account),
std::move(policies), extract_swift_subuser(swift_user),
- std::nullopt, LocalApplier::NO_ACCESS_KEY);
+ std::nullopt, LocalApplier::NO_ACCESS_KEY, false /* is_impersonating */);
return result_t::grant(std::move(apl));
}
std::vector<IAM::Policy> policies,
const std::string& subuser,
const std::optional<uint32_t>& perm_mask,
- const std::string& access_key_id) const override {
+ const std::string& access_key_id,
+ bool is_impersonating) const override {
auto apl = \
rgw::auth::add_3rdparty(driver, rgw_user(s->account_name),
rgw::auth::add_sysreq(cct, driver, s,
LocalApplier(cct, std::move(user), std::move(account), std::move(policies),
- subuser, perm_mask, access_key_id)));
+ subuser, perm_mask, access_key_id), is_impersonating));
/* TODO(rzarzynski): replace with static_ptr. */
return aplptr_t(new decltype(apl)(std::move(apl)));
}