From 9ed2162c804a27a04078a08b8385aff77bae5af8 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 22 Oct 2021 11:52:36 -0500 Subject: [PATCH] mon/AuthMonitor: 'auth {get-or-create,clear,commit}-pending' Add commands to create, clear, or commit pending_key. Signed-off-by: Sage Weil --- src/auth/KeyRing.h | 10 ++++- src/mon/AuthMonitor.cc | 87 ++++++++++++++++++++++++++++++++++++++++++ src/mon/MonCommands.h | 12 ++++++ 3 files changed, 107 insertions(+), 2 deletions(-) diff --git a/src/auth/KeyRing.h b/src/auth/KeyRing.h index ed15af4ecce..c0fa28615ae 100644 --- a/src/auth/KeyRing.h +++ b/src/auth/KeyRing.h @@ -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); } diff --git a/src/mon/AuthMonitor.cc b/src/mon/AuthMonitor.cc index f6b035fb2eb..38d340d8ad8 100644 --- a/src/mon/AuthMonitor.cc +++ b/src/mon/AuthMonitor.cc @@ -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()) { diff --git a/src/mon/MonCommands.h b/src/mon/MonCommands.h index 0ed51e9f46d..b4465a9893e 100644 --- a/src/mon/MonCommands.h +++ b/src/mon/MonCommands.h @@ -173,6 +173,18 @@ COMMAND("auth get-or-create " "name=caps,type=CephString,n=N,req=false", "add auth info for 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 " -- 2.39.5