]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: partially respect Swift's negative, HTTP referer-based ACLs.
authorRadoslaw Zarzynski <rzarzynski@mirantis.com>
Wed, 5 Apr 2017 12:57:06 +0000 (14:57 +0200)
committerRadoslaw Zarzynski <rzarzynski@mirantis.com>
Wed, 5 Apr 2017 19:30:12 +0000 (21:30 +0200)
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 <rzarzynski@mirantis.com>
src/rgw/rgw_acl.cc
src/rgw/rgw_acl.h

index 1cebae0d1862cc3301e0030ede229ff261b96a83..b4b8f8970a508fbfb8eef29866fcbf7eb980784b 100644 (file)
@@ -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
index 24567677e8e17058096718baf2b015114967eab0..c1711e7597f9f24dfb7255e3c51a38a4068980b2 100644 (file)
@@ -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;