]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw/auth: Identity matches paths in user principals
authorCasey Bodley <cbodley@redhat.com>
Tue, 2 Jan 2024 22:44:02 +0000 (17:44 -0500)
committerCasey Bodley <cbodley@redhat.com>
Fri, 12 Apr 2024 19:34:27 +0000 (15:34 -0400)
when RGWUserInfo::path is present, use it when matching user principals

Signed-off-by: Casey Bodley <cbodley@redhat.com>
(cherry picked from commit ea33bfb784c72cbc4d198c9f5139e54504466f54)

src/rgw/driver/rados/rgw_data_sync.cc
src/rgw/rgw_auth.cc
src/rgw/rgw_auth.h

index 4a57a268f08e0d4f42bc93c025b66e68c6920cd2..4e6295cc48acbcb35b6886f87cc451f1fdcb4a12 100644 (file)
@@ -2647,6 +2647,7 @@ class RGWUserPermHandler {
 
       info->identity = rgw::auth::transform_old_authinfo(sync_env->cct, uid,
                                                          info->user_info.display_name,
+                                                         info->user_info.path,
                                                          info->user_info.account_id,
                                                          RGW_PERM_FULL_CONTROL,
                                                          false, /* system_request? */
index ab93cf0961d0a41c6964d44c2a1907e263e56fb2..5899b65b73625badcc5f716ed1a9e1f6394d6925 100644 (file)
@@ -25,21 +25,33 @@ using namespace std;
 namespace rgw {
 namespace auth {
 
-// match a tenant user principal by userid[:subuser]
-static bool match_user_principal(std::string_view userid,
-                                 std::string_view subuser,
-                                 std::string_view expected)
+// match a principal by path/name[:subuser]
+static bool match_principal(std::string_view path,
+                            std::string_view name,
+                            std::string_view subuser,
+                            std::string_view expected)
 {
+  // leading / was already matched by ":user/" in parse_principal()
+  if (!path.empty()) {
+    path.remove_prefix(1);
+  }
+
+  // match user path
+  if (!expected.starts_with(path)) {
+    return false;
+  }
+  expected.remove_prefix(path.size());
+
   // match user by id
-  if (!expected.starts_with(userid)) {
+  if (!expected.starts_with(name)) {
     return false;
   }
-  expected.remove_prefix(userid.size());
+  expected.remove_prefix(name.size());
   if (expected.empty()) { // exact match
     return true;
   }
 
-  // try to match userid:subuser
+  // try to match name:subuser
   if (!expected.starts_with(":")) {
     return false;
   }
@@ -63,6 +75,7 @@ std::unique_ptr<rgw::auth::Identity>
 transform_old_authinfo(CephContext* const cct,
                        const rgw_user& auth_id,
                        const std::string& display_name,
+                       const std::string& path,
                        const rgw_account_id& account_id,
                        const int perm_mask,
                        const bool is_admin,
@@ -79,6 +92,7 @@ transform_old_authinfo(CephContext* const cct,
      * new auth. */
     const rgw_user id;
     const std::string display_name;
+    const std::string path;
     const rgw_account_id account_id;
     const int perm_mask;
     const bool is_admin;
@@ -87,6 +101,7 @@ transform_old_authinfo(CephContext* const cct,
     DummyIdentityApplier(CephContext* const cct,
                          const rgw_user& auth_id,
                          const std::string display_name,
+                         const std::string path,
                          const rgw_account_id& account_id,
                          const int perm_mask,
                          const bool is_admin,
@@ -94,6 +109,7 @@ transform_old_authinfo(CephContext* const cct,
       : cct(cct),
         id(auth_id),
         display_name(display_name),
+        path(path),
         account_id(account_id),
         perm_mask(perm_mask),
         is_admin(is_admin),
@@ -129,8 +145,9 @@ transform_old_authinfo(CephContext* const cct,
       } else if (p.is_account()) {
         return p.get_account() == id.tenant;
       } else if (p.is_user()) {
+        std::string_view no_subuser;
         return p.get_account() == id.tenant
-            && p.get_id() == id.id;
+            && match_principal(path, id.id, no_subuser, p.get_id());
       }
       return false;
     }
@@ -162,7 +179,7 @@ transform_old_authinfo(CephContext* const cct,
   };
 
   return std::make_unique<DummyIdentityApplier>(
-      cct, auth_id, display_name, account_id,
+      cct, auth_id, display_name, path, account_id,
       perm_mask, is_admin, type);
 }
 
@@ -173,6 +190,7 @@ transform_old_authinfo(const req_state* const s)
   return transform_old_authinfo(s->cct,
                                 info.user_id,
                                 info.display_name,
+                                info.path,
                                 info.account_id,
                                 s->perm_mask,
   /* System user has admin permissions by default - it's supposed to pass
@@ -850,7 +868,8 @@ bool rgw::auth::LocalApplier::is_identity(const Principal& p) const {
     return p.get_account() == user_info.user_id.tenant;
   } else if (p.is_user()) {
     return p.get_account() == user_info.user_id.tenant
-        && match_user_principal(user_info.user_id.id, subuser, p.get_id());
+        && match_principal(user_info.path, user_info.user_id.id,
+                           subuser, p.get_id());
   }
   return false;
 }
@@ -915,7 +934,7 @@ bool rgw::auth::RoleApplier::is_identity(const Principal& p) const {
   if (p.is_wildcard()) {
     return true;
   } else if (p.is_role()) {
-    return p.get_id() == role.name
+    return p.get_id() == role.name // TODO: match path/name
         && p.get_account() == role.tenant;
   } else if (p.is_assumed_role()) {
     string role_session = role.name + "/" + token_attrs.role_session_name; //role/role-session
index 796d501f0e8094df9ff714dd6bd7b212859bcc71..ddca72f84e4aeb7eb10a4665281756d52f838436 100644 (file)
@@ -101,6 +101,7 @@ std::unique_ptr<rgw::auth::Identity>
 transform_old_authinfo(CephContext* const cct,
                        const rgw_user& auth_id,
                        const std::string& display_name,
+                       const std::string& path,
                        const rgw_account_id& account_id,
                        const int perm_mask,
                        const bool is_admin,