From: Radoslaw Zarzynski Date: Wed, 5 Apr 2017 12:57:06 +0000 (+0200) Subject: rgw: partially respect Swift's negative, HTTP referer-based ACLs. X-Git-Tag: v12.1.0~156^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=11d4370eaf70bd48e582f658aae0f2120d04adf2;p=ceph.git rgw: partially respect Swift's negative, HTTP referer-based ACLs. For the sake of simplicity this patch doesn't handle the case of having multiple ".r:*" in a single ACL like: .r:*,.r:-.example.com,.r:* The global wildcard (.r:*) is handled specifically because of S3. Next patch will brings full support. Signed-off-by: Radoslaw Zarzynski --- diff --git a/src/rgw/rgw_acl.cc b/src/rgw/rgw_acl.cc index 1cebae0d186..b4b8f8970a5 100644 --- a/src/rgw/rgw_acl.cc +++ b/src/rgw/rgw_acl.cc @@ -71,27 +71,26 @@ uint32_t RGWAccessControlList::get_group_perm(ACLGroupTypeEnum group, return 0; } -uint32_t RGWAccessControlList::get_referer_perm(const std::string http_referer, +uint32_t RGWAccessControlList::get_referer_perm(const uint32_t current_perm, + const std::string http_referer, const uint32_t perm_mask) { ldout(cct, 5) << "Searching permissions for referer=" << http_referer << " mask=" << perm_mask << dendl; - /* FIXME: C++11 doesn't have std::rbegin nor std::rend. We would like to - * switch when C++14 becomes available. */ - const auto iter = std::find_if(referer_list.crbegin(), referer_list.crend(), - [&http_referer](const ACLReferer& r) -> bool { - return r.is_match(http_referer); + /* This function is bacically a transformation from current perm to + * a new one that takes into consideration the Swift's HTTP referer- + * based ACLs. We need to go through all items to respect negative + * grants. */ + uint32_t referer_perm = current_perm; + for (const auto& r : referer_list) { + if (r.is_match(http_referer)) { + referer_perm = r.perm; } - ); - - if (referer_list.crend() == iter) { - ldout(cct, 5) << "Permissions for referer not found" << dendl; - return 0; - } else { - ldout(cct, 5) << "Found referer permission=" << iter->perm << dendl; - return iter->perm & perm_mask; } + + ldout(cct, 5) << "Found referer permission=" << referer_perm << dendl; + return referer_perm & perm_mask; } uint32_t RGWAccessControlPolicy::get_perm(const rgw::auth::Identity& auth_identity, @@ -123,7 +122,7 @@ uint32_t RGWAccessControlPolicy::get_perm(const rgw::auth::Identity& auth_identi /* Should we continue looking up even deeper? */ if (nullptr != http_referer && (perm & perm_mask) != perm_mask) { - perm |= acl.get_referer_perm(http_referer, perm_mask); + perm = acl.get_referer_perm(perm, http_referer, perm_mask); } ldout(cct, 5) << "-- Getting permissions done for identity=" << auth_identity diff --git a/src/rgw/rgw_acl.h b/src/rgw/rgw_acl.h index 24567677e8e..c1711e7597f 100644 --- a/src/rgw/rgw_acl.h +++ b/src/rgw/rgw_acl.h @@ -302,7 +302,9 @@ public: uint32_t get_perm(const rgw::auth::Identity& auth_identity, uint32_t perm_mask); uint32_t get_group_perm(ACLGroupTypeEnum group, uint32_t perm_mask); - uint32_t get_referer_perm(const std::string http_referer, uint32_t perm_mask); + uint32_t get_referer_perm(uint32_t current_perm, + std::string http_referer, + uint32_t perm_mask); void encode(bufferlist& bl) const { ENCODE_START(4, 3, bl); bool maps_initialized = true;