]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mon/AuthMonitor: 'auth {get-or-create,clear,commit}-pending'
authorSage Weil <sage@newdream.net>
Fri, 22 Oct 2021 16:52:36 +0000 (11:52 -0500)
committerRadoslaw Zarzynski <rzarzyns@redhat.com>
Mon, 12 Sep 2022 17:02:59 +0000 (17:02 +0000)
Add commands to create, clear, or commit pending_key.

Signed-off-by: Sage Weil <sage@newdream.net>
src/auth/KeyRing.h
src/mon/AuthMonitor.cc
src/mon/MonCommands.h

index ed15af4eccec3f85d23f2087bdfd5c1210ccf575..c0fa28615ae192a39f5c82dc407f22a4460451f7 100644 (file)
@@ -72,14 +72,20 @@ public:
   }
 
   // modifiers
-  void add(const EntityName& name, EntityAuth &a) {
+  void add(const EntityName& name, const EntityAuth &a) {
     keys[name] = a;
   }
-  void add(const EntityName& name, CryptoKey &k) {
+  void add(const EntityName& name, const CryptoKey &k) {
     EntityAuth a;
     a.key = k;
     keys[name] = a;
   }
+  void add(const EntityName& name, const CryptoKey &k, const CryptoKey &pk) {
+    EntityAuth a;
+    a.key = k;
+    a.pending_key = pk;
+    keys[name] = a;
+  }
   void remove(const EntityName& name) {
     keys.erase(name);
   }
index f6b035fb2eb35e70222482af0b5176c31e2ff32c..38d340d8ad8d4ec8507c4c04f256953f805b16cb 100644 (file)
@@ -819,6 +819,9 @@ bool AuthMonitor::preprocess_command(MonOpRequestRef op)
       prefix == "auth rm" ||
       prefix == "auth get-or-create" ||
       prefix == "auth get-or-create-key" ||
+      prefix == "auth get-or-create-pending" ||
+      prefix == "auth clear-pending" ||
+      prefix == "auth commit-pending" ||
       prefix == "fs authorize" ||
       prefix == "auth import" ||
       prefix == "auth caps") {
@@ -1506,6 +1509,90 @@ bool AuthMonitor::prepare_command(MonOpRequestRef op)
     wait_for_finished_proposal(op, new Monitor::C_Command(mon, op, 0, rs,
                                                   get_last_committed() + 1));
     return true;
+  } else if ((prefix == "auth get-or-create-pending" ||
+             prefix == "auth clear-pending" ||
+             prefix == "auth commit-pending")) {
+    if (mon.monmap->min_mon_release < ceph_release_t::quincy) {
+      err = -EPERM;
+      ss << "pending_keys are not available until after upgrading to quincy";
+      goto done;
+    }
+
+    EntityAuth entity_auth;
+    if (!mon.key_server.get_auth(entity, entity_auth)) {
+      ss << "entity " << entity << " does not exist";
+      err = -ENOENT;
+      goto done;
+    }
+
+    // is there an uncommitted pending_key? (or any change for this entity)
+    for (auto& p : pending_auth) {
+      if (p.inc_type == AUTH_DATA) {
+       KeyServerData::Incremental auth_inc;
+       auto q = p.auth_data.cbegin();
+       decode(auth_inc, q);
+       if (auth_inc.op == KeyServerData::AUTH_INC_ADD &&
+           auth_inc.name == entity) {
+         wait_for_finished_proposal(op, new Monitor::C_Command(mon, op, 0, rs,
+                                               get_last_committed() + 1));
+         return true;
+       }
+      }
+    }
+
+    if (prefix == "auth get-or-create-pending") {
+      KeyRing kr;
+      bool exists = false;
+      if (!entity_auth.pending_key.empty()) {
+       kr.add(entity, entity_auth.key, entity_auth.pending_key);
+       err = 0;
+       exists = true;
+      } else {
+       KeyServerData::Incremental auth_inc;
+       auth_inc.op = KeyServerData::AUTH_INC_ADD;
+       auth_inc.name = entity;
+       auth_inc.auth = entity_auth;
+       auth_inc.auth.pending_key.create(g_ceph_context, CEPH_CRYPTO_AES);
+       push_cephx_inc(auth_inc);
+       kr.add(entity, auth_inc.auth.key, auth_inc.auth.pending_key);
+        push_cephx_inc(auth_inc);
+      }
+      if (f) {
+       kr.encode_formatted("auth", f.get(), rdata);
+      } else {
+       kr.encode_plaintext(rdata);
+      }
+      if (exists) {
+       goto done;
+      }
+    } else if (prefix == "auth clear-pending") {
+      if (entity_auth.pending_key.empty()) {
+       err = 0;
+       goto done;
+      }
+      KeyServerData::Incremental auth_inc;
+      auth_inc.op = KeyServerData::AUTH_INC_ADD;
+      auth_inc.name = entity;
+      auth_inc.auth = entity_auth;
+      auth_inc.auth.pending_key.clear();
+      push_cephx_inc(auth_inc);
+    } else if (prefix == "auth commit-pending") {
+      if (entity_auth.pending_key.empty()) {
+       err = 0;
+       ss << "no pending key";
+       goto done;
+      }
+      KeyServerData::Incremental auth_inc;
+      auth_inc.op = KeyServerData::AUTH_INC_ADD;
+      auth_inc.name = entity;
+      auth_inc.auth = entity_auth;
+      auth_inc.auth.key = auth_inc.auth.pending_key;
+      auth_inc.auth.pending_key.clear();
+      push_cephx_inc(auth_inc);
+    }
+    wait_for_finished_proposal(op, new Monitor::C_Command(mon, op, 0, rs, rdata,
+                                             get_last_committed() + 1));
+    return true;
   } else if ((prefix == "auth get-or-create-key" ||
              prefix == "auth get-or-create") &&
             !entity_name.empty()) {
index 0ed51e9f46d700ed93a57043200570106cd9b565..b4465a9893ec7fd148e15fca1e991c3722689fce 100644 (file)
@@ -173,6 +173,18 @@ COMMAND("auth get-or-create "
        "name=caps,type=CephString,n=N,req=false",
        "add auth info for <entity> from input file, or random key if no input given, and/or any caps specified in the command",
        "auth", "rwx")
+COMMAND("auth get-or-create-pending "
+       "name=entity,type=CephString",
+       "generate and/or retrieve existing pending key (rotated into place on first use)",
+       "auth", "rwx")
+COMMAND("auth clear-pending "
+       "name=entity,type=CephString",
+       "clear pending key",
+       "auth", "rwx")
+COMMAND("auth commit-pending "
+       "name=entity,type=CephString",
+       "rotate pending key into active position",
+       "auth", "rwx")
 COMMAND("fs authorize "
    "name=filesystem,type=CephString "
    "name=entity,type=CephString "