From f28684ef3ca7c16aab06d0f8ff001ad951b94f82 Mon Sep 17 00:00:00 2001 From: Radoslaw Zarzynski Date: Sat, 23 Apr 2016 16:59:18 +0200 Subject: [PATCH] rgw: the Keystone backend does support now Swift's cross-tenant ACLs. Signed-off-by: Radoslaw Zarzynski --- src/rgw/rgw_auth.cc | 47 +++++++++++++++++++++++++++++++++++++++++++++ src/rgw/rgw_auth.h | 2 ++ 2 files changed, 49 insertions(+) diff --git a/src/rgw/rgw_auth.cc b/src/rgw/rgw_auth.cc index d5d37ffb4e15d..1089fd283df0f 100644 --- a/src/rgw/rgw_auth.cc +++ b/src/rgw/rgw_auth.cc @@ -399,6 +399,51 @@ RGWKeystoneAuthEngine::get_creds_info(const KeystoneToken& token, }; } +static inline const std::string make_spec_item(const std::string tenant, + const std::string id) +{ + return tenant + ":" + id; +} + +RGWKeystoneAuthEngine::acl_strategy_t +RGWKeystoneAuthEngine::get_acl_strategy(const KeystoneToken& token) const +{ + /* The primary identity is constructed upon UUIDs. */ + const auto tenant_uuid = token.get_project_id(); + const auto user_uuid = token.get_user_id(); + + /* For Keystone v2 an alias may be also used. */ + const auto tenant_name = token.get_project_name(); + const auto user_name = token.get_user_name(); + + /* Construct all possible combinations including Swift's wildcards. */ + const std::vector allowed_items = { + make_spec_item(tenant_uuid, user_uuid), + make_spec_item(tenant_name, user_name), + + /* Wildcards. */ + make_spec_item(tenant_uuid, "*"), + make_spec_item(tenant_name, "*"), + make_spec_item("*", user_uuid), + make_spec_item("*", user_name), + }; + + /* Lambda will obtain a copy of (not a reference to!) allowed_items. */ + return [allowed_items](const RGWIdentityApplier::aclspec_t& aclspec) { + int perm = 0; + + for (const auto& allowed_item : allowed_items) { + const auto iter = aclspec.find(allowed_item); + + if (std::end(aclspec) != iter) { + perm |= iter->second; + } + } + + return perm; + }; +} + RGWAuthApplier::aplptr_t RGWKeystoneAuthEngine::authenticate() const { KeystoneToken t; @@ -428,6 +473,7 @@ RGWAuthApplier::aplptr_t RGWKeystoneAuthEngine::authenticate() const ldout(cct, 20) << "cached token.project.id=" << t.get_project_id() << dendl; return apl_factory->create_apl_remote(cct, + get_acl_strategy(t), get_creds_info(t, roles.admin)); } @@ -460,6 +506,7 @@ RGWAuthApplier::aplptr_t RGWKeystoneAuthEngine::authenticate() const << " expires: " << t.get_expires() << dendl; RGWKeystoneTokenCache::get_instance().add(token_id, t); return apl_factory->create_apl_remote(cct, + get_acl_strategy(t), get_creds_info(t, roles.admin)); } } diff --git a/src/rgw/rgw_auth.h b/src/rgw/rgw_auth.h index f4f7ae6d5d999..b9bc01943ef18 100644 --- a/src/rgw/rgw_auth.h +++ b/src/rgw/rgw_auth.h @@ -287,11 +287,13 @@ public: /* Keystone. */ class RGWKeystoneAuthEngine : public RGWTokenBasedAuthEngine { protected: + using acl_strategy_t = RGWRemoteAuthApplier::acl_strategy_t; const RGWRemoteAuthApplier::Factory * const apl_factory; /* Helper methods. */ KeystoneToken decode_pki_token(const std::string token) const; KeystoneToken get_from_keystone(const std::string token) const; + acl_strategy_t get_acl_strategy(const KeystoneToken& token) const; RGWRemoteAuthApplier::AuthInfo get_creds_info(const KeystoneToken& token, const std::vector& admin_roles ) const noexcept; -- 2.39.5