]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mon/AuthMonitor: add osd w cap for superuser client
authorPatrick Donnelly <pdonnell@ibm.com>
Wed, 18 Feb 2026 20:27:30 +0000 (15:27 -0500)
committerJos Collin <jcollin@redhat.com>
Fri, 10 Apr 2026 10:49:13 +0000 (16:19 +0530)
Right now only a client with "rw" permissions on an MDS gets "rw" on an
OSD.

[@vshankar: fixed malformed OSD cap when authorizing multiple paths]

Reported-by: John Mulligan <jmulligan@redhat.com>
Fixes: https://tracker.ceph.com/issues/75013
Signed-off-by: Patrick Donnelly <pdonnell@ibm.com>
Signed-off-by: Venky Shankar <vshankar@redhat.com>
(cherry picked from commit 6e6e570f80480b9a310d10a96ad1e5682785c775)

src/mon/AuthMonitor.cc

index 0a60ab6d26dd3062003490b34fca6112759e4334..ac08e8011e3b3ab08f8c83830cf04ffc03b2b668 100644 (file)
@@ -42,6 +42,8 @@
 #define dout_prefix _prefix(_dout, mon, get_last_committed())
 using namespace TOPNSPC::common;
 
+using namespace std::string_view_literals;
+
 using std::list;
 using std::map;
 using std::make_pair;
@@ -1694,6 +1696,7 @@ bool AuthMonitor::prepare_command(MonOpRequestRef op)
     string mon_cap_string = "allow r";
     string mds_cap_string, osd_cap_string;
     string osd_cap_wanted = "r";
+    bool osd_cap_needs_w = false;
 
     const Filesystem* fs = nullptr;
     if (filesystem != "*" && filesystem != "all") {
@@ -1719,18 +1722,34 @@ bool AuthMonitor::prepare_command(MonOpRequestRef op)
        ++it;
       }
 
-      if (cap.compare(0, 2, "rw") == 0)
-       osd_cap_wanted = "rw";
-
-      char last='\0';
-      for (size_t i = 2; i < cap.size(); ++i) {
-       char c = cap.at(i);
+      char last = '\0';
+      for (char c : cap) {
+        dout(25) << "permission flag: " << c << dendl;
        if (last >= c) {
          ss << "Permission flags (except 'rw') must be specified in alphabetical order.";
          err = -EINVAL;
          goto done;
        }
+        if (last == 'r' && c == 'w') {
+          /* treat 'rw' as a unit permitted at beginning: */
+          last = '\0';
+        } else {
+          last = c;
+        }
        switch (c) {
+        case 'r':
+          break;
+        case '*':
+          if (cap != "*"sv) {
+           ss << "Permission '*' implies all, remove other caps.";
+           err = -EINVAL;
+           goto done;
+          }
+          osd_cap_needs_w = true;
+          break;
+        case 'w':
+          osd_cap_needs_w = true;
+          break;
        case 'p':
          break;
        case 's':
@@ -1758,6 +1777,9 @@ bool AuthMonitor::prepare_command(MonOpRequestRef op)
       }
     }
 
+    if (osd_cap_needs_w) {
+      osd_cap_wanted += 'w';
+    }
     osd_cap_string += osd_cap_string.empty() ? "" : ", ";
     osd_cap_string += "allow " + osd_cap_wanted
       + " tag " + pg_pool_t::APPLICATION_NAME_CEPHFS