]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: Fixed several bugs in policies related to IP Addresses.
authorJohn Gibson <jgibson@mitre.org>
Sun, 24 Dec 2017 20:44:54 +0000 (15:44 -0500)
committerAdam C. Emerson <aemerson@redhat.com>
Sun, 7 Jan 2018 10:12:55 +0000 (05:12 -0500)
Comparisons of two individual IP addresses caused an assertion error.
The text conversion of IPv4 addresses was using raw byte values instead of
the converted number.
NotIpAddress condition now works with multiple values.

http://tracker.ceph.com/issues/20991

Signed-off-by: John Gibson <jgibson@mitre.org>
(cherry picked from commit ca21596c95aa3871d14ac9112840d3b1101a8635)

src/rgw/rgw_iam_policy.cc
src/rgw/rgw_iam_policy.h

index 745d28afffb78aab5349729e714f923b3d3e9721..435df059c8f40e37f4d4fa8b9a59c8f1527b2b68 100644 (file)
@@ -932,7 +932,7 @@ ostream& operator <<(ostream& m, const MaskedIP& ip) {
       for (int j = 7; j >= 0; --j) {
        b |= (ip.addr[(i * 8) + j] << j);
       }
-      m << b;
+      m << (unsigned int) b;
       if (i != 0) {
        m << ".";
       }
@@ -1039,8 +1039,24 @@ bool Condition::eval(const Environment& env) const {
     return shortible(std::equal_to<MaskedIP>(), as_network, s, vals);
 
   case TokenID::NotIpAddress:
-    return shortible(ceph::not_fn(std::equal_to<MaskedIP>()), as_network, s,
-                    vals);
+    {
+      auto xc = as_network(s);
+      if (!xc) {
+       return false;
+      }
+
+      for (const string& d : vals) {
+       auto xd = as_network(d);
+       if (!xd) {
+         continue;
+       }
+
+       if (xc == xd) {
+         return false;
+       }
+      }
+      return true;
+    }
 
 #if 0
     // Amazon Resource Names! (Does S3 need this?)
@@ -1060,7 +1076,6 @@ optional<MaskedIP> Condition::as_network(const string& s) {
   }
 
   m.v6 = (s.find(':') == string::npos) ? false : true;
-
   auto slash = s.find('/');
   if (slash == string::npos) {
     m.prefix = m.v6 ? 128 : 32;
@@ -1104,11 +1119,12 @@ optional<MaskedIP> Condition::as_network(const string& s) {
     m.addr |= Address(a.sin6_addr.s6_addr[14]) << 112;
     m.addr |= Address(a.sin6_addr.s6_addr[15]) << 120;
   } else {
-    struct sockaddr_in a;
-    if (inet_pton(AF_INET, p->c_str(), static_cast<void*>(&a.sin_addr)) != 1) {
+    struct in_addr a;
+    if (inet_pton(AF_INET, p->c_str(), static_cast<void*>(&a)) != 1) {
       return none;
     }
-    m.addr = ntohl(a.sin_addr.s_addr);
+
+    m.addr = ntohl(a.s_addr);
   }
 
   return m;
index 59117456e0cc4a11c59213e29f7f37fe8fc9146d..032840151a6ff083a2c6015d8127d306f6d0a201 100644 (file)
@@ -250,8 +250,9 @@ std::ostream& operator <<(std::ostream& m, const MaskedIP& ip);
 string to_string(const MaskedIP& m);
 
 inline bool operator ==(const MaskedIP& l, const MaskedIP& r) {
-  auto shift = std::max((l.v6 ? 128 : 32) - l.prefix,
-                       (r.v6 ? 128 : 32) - r.prefix);
+  auto shift = std::max((l.v6 ? 128 : 32) - ((int) l.prefix),
+                       (r.v6 ? 128 : 32) - ((int) r.prefix));
+  ceph_assert(shift >= 0);
   return (l.addr >> shift) == (r.addr >> shift);
 }