From: Pritha Srivastava Date: Mon, 10 Dec 2018 06:19:06 +0000 (+0530) Subject: rgw: Adding a new applier for Roles. X-Git-Tag: v14.1.0~510^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=a5fcd2fe5d72ffc1f9fb6ecc093b6624178d7718;p=ceph.git rgw: Adding a new applier for Roles. Signed-off-by: Pritha Srivastava --- diff --git a/src/rgw/rgw_auth.cc b/src/rgw/rgw_auth.cc index e8799c449450..11de9a7791ed 100644 --- a/src/rgw/rgw_auth.cc +++ b/src/rgw/rgw_auth.cc @@ -535,7 +535,39 @@ void rgw::auth::LocalApplier::load_acct_info(const DoutPrefixProvider* dpp, RGWU user_info = this->user_info; } -void rgw::auth::LocalApplier::modify_request_state(const DoutPrefixProvider *dpp, req_state* s) const +void rgw::auth::RoleApplier::to_str(std::ostream& out) const { + out << "rgw::auth::LocalApplier(role name =" << role_name; + for (auto policy : role_policies) { + out << ", role policy =" << policy; + } + out << ")"; +} + +bool rgw::auth::RoleApplier::is_identity(const idset_t& ids) const { + for (auto& p : ids) { + string name; + string tenant = p.get_tenant(); + if (tenant.empty()) { + name = p.get_id(); + } else { + name = tenant + "$" + p.get_id(); + } + if (p.is_wildcard()) { + return true; + } else if (p.is_role() && name == role_name) { + return true; + } + } + return false; +} + +void rgw::auth::RoleApplier::load_acct_info(const DoutPrefixProvider* dpp, RGWUserInfo& user_info) const /* out */ +{ + /* Load the user id */ + user_info.user_id = this->user_id; +} + +void rgw::auth::RoleApplier::modify_request_state(const DoutPrefixProvider *dpp, req_state* s) const { for (auto it : role_policies) { try { @@ -562,7 +594,7 @@ rgw::auth::AnonymousEngine::authenticate(const DoutPrefixProvider* dpp, const re auto apl = \ apl_factory->create_apl_local(cct, s, user_info, rgw::auth::LocalApplier::NO_SUBUSER, - boost::none, boost::none); + boost::none); return result_t::grant(std::move(apl)); } } diff --git a/src/rgw/rgw_auth.h b/src/rgw/rgw_auth.h index 194ce53ddba2..d141479a767b 100644 --- a/src/rgw/rgw_auth.h +++ b/src/rgw/rgw_auth.h @@ -455,7 +455,6 @@ class LocalApplier : public IdentityApplier { protected: const RGWUserInfo user_info; const std::string subuser; - vector role_policies; uint32_t perm_mask; uint32_t get_perm_mask(const std::string& subuser_name, @@ -467,13 +466,9 @@ public: LocalApplier(CephContext* const cct, const RGWUserInfo& user_info, std::string subuser, - const boost::optional >& role_policies, const boost::optional& perm_mask) : user_info(user_info), subuser(std::move(subuser)) { - if (role_policies) { - this->role_policies = role_policies.get(); - } if (perm_mask) { this->perm_mask = perm_mask.get(); } else { @@ -497,7 +492,6 @@ public: void load_acct_info(const DoutPrefixProvider* dpp, RGWUserInfo& user_info) const override; /* out */ uint32_t get_identity_type() const override { return TYPE_RGW; } string get_acct_name() const override { return {}; } - void modify_request_state(const DoutPrefixProvider* dpp, req_state* s) const override; struct Factory { virtual ~Factory() {} @@ -505,11 +499,54 @@ public: const req_state* s, const RGWUserInfo& user_info, const std::string& subuser, - const boost::optional >& role_policies, const boost::optional& perm_mask) const = 0; }; }; +class RoleApplier : public IdentityApplier { +protected: + const string role_name; + const rgw_user user_id; + vector role_policies; + +public: + + RoleApplier(CephContext* const cct, + const string& role_name, + const rgw_user& user_id, + const vector& role_policies) + : role_name(role_name), + user_id(user_id), + role_policies(role_policies) {} + + uint32_t get_perms_from_aclspec(const DoutPrefixProvider* dpp, const aclspec_t& aclspec) const override { + return 0; + } + bool is_admin_of(const rgw_user& uid) const override { + return false; + } + bool is_owner_of(const rgw_user& uid) const override { + return false; + } + bool is_identity(const idset_t& ids) const override; + uint32_t get_perm_mask() const override { + return RGW_PERM_NONE; + } + void to_str(std::ostream& out) const override; + void load_acct_info(const DoutPrefixProvider* dpp, RGWUserInfo& user_info) const override; /* out */ + uint32_t get_identity_type() const override { return TYPE_ROLE; } + string get_acct_name() const override { return {}; } + void modify_request_state(const DoutPrefixProvider* dpp, req_state* s) const override; + + struct Factory { + virtual ~Factory() {} + virtual aplptr_t create_apl_role( CephContext* cct, + const req_state* s, + const string& role_name, + const rgw_user& user_id, + const vector& role_policies) const = 0; + }; +}; /* The anonymous abstract engine. */ class AnonymousEngine : public Engine { diff --git a/src/rgw/rgw_auth_s3.h b/src/rgw/rgw_auth_s3.h index f8ea7480be69..2afbe31c07bc 100644 --- a/src/rgw/rgw_auth_s3.h +++ b/src/rgw/rgw_auth_s3.h @@ -34,7 +34,8 @@ bool is_time_skew_ok(time_t t); class STSAuthStrategy : public rgw::auth::Strategy, public rgw::auth::RemoteApplier::Factory, - public rgw::auth::LocalApplier::Factory { + public rgw::auth::LocalApplier::Factory, + public rgw::auth::RoleApplier::Factory { typedef rgw::auth::IdentityApplier::aplptr_t aplptr_t; RGWRados* const store; @@ -55,13 +56,21 @@ class STSAuthStrategy : public rgw::auth::Strategy, const req_state* const s, const RGWUserInfo& user_info, const std::string& subuser, - const boost::optional >& role_policies, const boost::optional& perm_mask) const override { auto apl = rgw::auth::add_sysreq(cct, store, s, - rgw::auth::LocalApplier(cct, user_info, subuser, role_policies, perm_mask)); + rgw::auth::LocalApplier(cct, user_info, subuser, perm_mask)); return aplptr_t(new decltype(apl)(std::move(apl))); } + aplptr_t create_apl_role(CephContext* const cct, + const req_state* const s, + const string& role_name, + const rgw_user& user_id, + const vector& role_policies) const override { + auto apl = rgw::auth::add_sysreq(cct, store, s, + rgw::auth::RoleApplier(cct, role_name, user_id, role_policies)); + return aplptr_t(new decltype(apl)(std::move(apl))); + } public: STSAuthStrategy(CephContext* const cct, RGWRados* const store, @@ -69,7 +78,8 @@ public: : store(store), sts_engine(cct, store, *ver_abstractor, static_cast(this), - static_cast(this)) { + static_cast(this), + static_cast(this)) { if (cct->_conf->rgw_s3_auth_use_sts) { add_engine(Control::SUFFICIENT, sts_engine); } @@ -157,10 +167,9 @@ class AWSAuthStrategy : public rgw::auth::Strategy, const req_state* const s, const RGWUserInfo& user_info, const std::string& subuser, - const boost::optional >& role_policies, const boost::optional& perm_mask) const override { auto apl = rgw::auth::add_sysreq(cct, store, s, - rgw::auth::LocalApplier(cct, user_info, subuser, role_policies, perm_mask)); + rgw::auth::LocalApplier(cct, user_info, subuser, perm_mask)); /* TODO(rzarzynski): replace with static_ptr. */ return aplptr_t(new decltype(apl)(std::move(apl))); } diff --git a/src/rgw/rgw_common.cc b/src/rgw/rgw_common.cc index afe1f3ada36e..e1f62cb12a86 100644 --- a/src/rgw/rgw_common.cc +++ b/src/rgw/rgw_common.cc @@ -1123,10 +1123,6 @@ bool verify_user_permission(const DoutPrefixProvider* dpp, return verify_user_permission_no_policy(dpp, s, user_acl, perm); } - if (usr_policy_res == Effect::Pass) { - return false; - } - return false; } @@ -1134,7 +1130,7 @@ bool verify_user_permission_no_policy(const DoutPrefixProvider* dpp, struct req_ RGWAccessControlPolicy * const user_acl, const int perm) { - if (s->user->type == TYPE_ROLE) + if (s->auth.identity->get_identity_type() == TYPE_ROLE) return false; /* S3 doesn't support account ACLs. */ diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h index 0a002fd4a25a..549b3a36f7b3 100644 --- a/src/rgw/rgw_common.h +++ b/src/rgw/rgw_common.h @@ -629,7 +629,9 @@ void encode_json(const char *name, const RGWUserCaps& val, Formatter *f); void decode_json_obj(obj_version& v, JSONObj *obj); -enum RGWUserSourceType + + +enum RGWIdentityType { TYPE_NONE=0, TYPE_RGW=1, diff --git a/src/rgw/rgw_json_enc.cc b/src/rgw/rgw_json_enc.cc index 1b7f7b2ed6cb..c9f50941111b 100644 --- a/src/rgw/rgw_json_enc.cc +++ b/src/rgw/rgw_json_enc.cc @@ -478,7 +478,7 @@ void RGWUserInfo::dump(Formatter *f) const encode_json("temp_url_keys", temp_url_keys, f); string user_source_type; - switch ((RGWUserSourceType)type) { + switch ((RGWIdentityType)type) { case TYPE_RGW: user_source_type = "rgw"; break; diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index c76cfd0f6122..98869f9a78e3 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -572,7 +572,7 @@ int rgw_build_bucket_policies(RGWRados* store, struct req_state* s) } // We don't need user policies in case of STS token returned by AssumeRole, // hence the check for user type - if (! s->user->user_id.empty() && s->user->type != TYPE_ROLE) { + if (! s->user->user_id.empty() && s->auth.identity->get_identity_type() != TYPE_ROLE) { try { map uattrs; if (ret = rgw_get_user_attrs_by_uid(store, s->user->user_id, uattrs); ! ret) { diff --git a/src/rgw/rgw_rest.cc b/src/rgw/rgw_rest.cc index f7142731b41d..4c0130d9d4a1 100644 --- a/src/rgw/rgw_rest.cc +++ b/src/rgw/rgw_rest.cc @@ -1816,7 +1816,7 @@ int RGWHandler_REST::init_permissions(RGWOp* op) { if (op->get_type() == RGW_OP_CREATE_BUCKET) { // We don't need user policies in case of STS token returned by AssumeRole, hence the check for user type - if (! s->user->user_id.empty() && s->user->type != TYPE_ROLE) { + if (! s->user->user_id.empty() && s->auth.identity->get_identity_type() != TYPE_ROLE) { try { map uattrs; if (auto ret = rgw_get_user_attrs_by_uid(store, s->user->user_id, uattrs); ! ret) { diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index 686b5f370094..b4201765b8e2 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -4345,7 +4345,7 @@ rgw::auth::s3::LocalEngine::authenticate( return result_t::deny(-ERR_SIGNATURE_NO_MATCH); } - auto apl = apl_factory->create_apl_local(cct, s, user_info, k.subuser, boost::none, boost::none); + auto apl = apl_factory->create_apl_local(cct, s, user_info, k.subuser, boost::none); return result_t::grant(std::move(apl), completer_factory(k.key)); } @@ -4465,7 +4465,9 @@ rgw::auth::s3::STSEngine::authenticate( // Get all the authorization info RGWUserInfo user_info; + rgw_user user_id; vector role_policies; + string role_name; if (! token.roleId.empty()) { RGWRole role(s->cct, store, token.roleId); if (role.get_by_id() < 0) { @@ -4482,9 +4484,10 @@ rgw::auth::s3::STSEngine::authenticate( role_policies.push_back(std::move(token.policy)); } // This is mostly needed to assign the owner of a bucket during its creation - user_info.user_id = token.user; - user_info.type = token.acct_type; + user_id = token.user; + role_name = role.get_name(); } + if (! token.user.empty() && token.acct_type != TYPE_ROLE) { // get user info int ret = rgw_get_user_info_by_uid(store, token.user, user_info, NULL); @@ -4498,9 +4501,12 @@ rgw::auth::s3::STSEngine::authenticate( auto apl = remote_apl_factory->create_apl_remote(cct, s, get_acl_strategy(), get_creds_info(token)); return result_t::grant(std::move(apl), completer_factory(boost::none)); - } else { + } else if (token.acct_type == TYPE_ROLE) { + auto apl = role_apl_factory->create_apl_role(cct, s, role_name, user_id, role_policies); + return result_t::grant(std::move(apl), completer_factory(token.secret_access_key)); + } else { // This is for all local users of type TYPE_RGW or TYPE_NONE string subuser; - auto apl = local_apl_factory->create_apl_local(cct, s, user_info, subuser, role_policies, token.perm_mask); + auto apl = local_apl_factory->create_apl_local(cct, s, user_info, subuser, token.perm_mask); return result_t::grant(std::move(apl), completer_factory(token.secret_access_key)); } } diff --git a/src/rgw/rgw_rest_s3.h b/src/rgw/rgw_rest_s3.h index 1decd9bf59ac..c425f97c7f3c 100644 --- a/src/rgw/rgw_rest_s3.h +++ b/src/rgw/rgw_rest_s3.h @@ -892,6 +892,7 @@ class STSEngine : public AWSEngine { RGWRados* const store; const rgw::auth::LocalApplier::Factory* const local_apl_factory; const rgw::auth::RemoteApplier::Factory* const remote_apl_factory; + const rgw::auth::RoleApplier::Factory* const role_apl_factory; using acl_strategy_t = rgw::auth::RemoteApplier::acl_strategy_t; using auth_info_t = rgw::auth::RemoteApplier::AuthInfo; @@ -915,11 +916,13 @@ public: RGWRados* const store, const VersionAbstractor& ver_abstractor, const rgw::auth::LocalApplier::Factory* const local_apl_factory, - const rgw::auth::RemoteApplier::Factory* const remote_apl_factory) + const rgw::auth::RemoteApplier::Factory* const remote_apl_factory, + const rgw::auth::RoleApplier::Factory* const role_apl_factory) : AWSEngine(cct, ver_abstractor), store(store), local_apl_factory(local_apl_factory), - remote_apl_factory(remote_apl_factory) { + remote_apl_factory(remote_apl_factory), + role_apl_factory(role_apl_factory) { } using AWSEngine::authenticate; @@ -966,10 +969,9 @@ public: const req_state* const s, const RGWUserInfo& user_info, const std::string& subuser, - const boost::optional >& role_policies, const boost::optional& perm_mask) const override { return aplptr_t( - new rgw::auth::LocalApplier(cct, user_info, subuser, role_policies, perm_mask)); + new rgw::auth::LocalApplier(cct, user_info, subuser, perm_mask)); } }; diff --git a/src/rgw/rgw_swift_auth.cc b/src/rgw/rgw_swift_auth.cc index 4acd8fc82608..36248cf492af 100644 --- a/src/rgw/rgw_swift_auth.cc +++ b/src/rgw/rgw_swift_auth.cc @@ -434,7 +434,7 @@ ExternalTokenEngine::authenticate(const DoutPrefixProvider* dpp, auto apl = apl_factory->create_apl_local(cct, s, tmp_uinfo, extract_swift_subuser(swift_user), - boost::none, boost::none); + boost::none); return result_t::grant(std::move(apl)); } @@ -585,7 +585,7 @@ SignedTokenEngine::authenticate(const DoutPrefixProvider* dpp, auto apl = apl_factory->create_apl_local(cct, s, user_info, extract_swift_subuser(swift_user), - boost::none, boost::none); + boost::none); return result_t::grant(std::move(apl)); } diff --git a/src/rgw/rgw_swift_auth.h b/src/rgw/rgw_swift_auth.h index 5bfd2749a57c..38377764b52e 100644 --- a/src/rgw/rgw_swift_auth.h +++ b/src/rgw/rgw_swift_auth.h @@ -21,7 +21,7 @@ class TempURLApplier : public rgw::auth::LocalApplier { public: TempURLApplier(CephContext* const cct, const RGWUserInfo& user_info) - : LocalApplier(cct, user_info, LocalApplier::NO_SUBUSER, boost::none, boost::none) { + : LocalApplier(cct, user_info, LocalApplier::NO_SUBUSER, boost::none) { }; void modify_request_state(const DoutPrefixProvider* dpp, req_state * s) const override; /* in/out */ @@ -205,12 +205,11 @@ class DefaultStrategy : public rgw::auth::Strategy, const req_state* const s, const RGWUserInfo& user_info, const std::string& subuser, - const boost::optional >& role_policies, const boost::optional& perm_mask) const override { auto apl = \ rgw::auth::add_3rdparty(store, s->account_name, rgw::auth::add_sysreq(cct, store, s, - rgw::auth::LocalApplier(cct, user_info, subuser, role_policies, perm_mask))); + rgw::auth::LocalApplier(cct, user_info, subuser, perm_mask))); /* TODO(rzarzynski): replace with static_ptr. */ return aplptr_t(new decltype(apl)(std::move(apl))); }