From d912f9e0aea9b7200e424f2d569ece5435c3e4fd Mon Sep 17 00:00:00 2001 From: Radoslaw Zarzynski Date: Wed, 11 Jan 2017 15:57:40 +0100 Subject: [PATCH] rgw: add Control::FALLBACK mode to rgw::auth::AuthStrategy. Signed-off-by: Radoslaw Zarzynski --- src/rgw/rgw_auth.cc | 7 +++++-- src/rgw/rgw_auth.h | 8 +++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/rgw/rgw_auth.cc b/src/rgw/rgw_auth.cc index 879eb3c015c4..7ae215a85267 100644 --- a/src/rgw/rgw_auth.cc +++ b/src/rgw/rgw_auth.cc @@ -522,6 +522,7 @@ RGWAuthApplier::aplptr_t RGWKeystoneAuthEngine::authenticate() const rgw::auth::Engine::result_t rgw::auth::Strategy::authenticate(const req_state* const s) const { + int previous_error = 0; for (const stack_item_t& kv : auth_stack) { const rgw::auth::Engine& engine = kv.first; const auto& policy = kv.second; @@ -529,8 +530,8 @@ rgw::auth::Strategy::authenticate(const req_state* const s) const rgw::auth::Engine::result_t res; try { res = engine.authenticate(s); - } catch (int err) { - /* NOP */ + } catch (const int err) { + previous_error = err; } const auto& applier = res.first; @@ -544,6 +545,8 @@ rgw::auth::Strategy::authenticate(const req_state* const s) const case Control::SUFFICIENT: /* Just try next. */ continue; + case Control::FALLBACK: + throw previous_error; default: /* Huh, memory corruption? */ abort(); diff --git a/src/rgw/rgw_auth.h b/src/rgw/rgw_auth.h index 1e2f0c12eab6..c38a905e2e01 100644 --- a/src/rgw/rgw_auth.h +++ b/src/rgw/rgw_auth.h @@ -534,7 +534,7 @@ public: class Strategy : public Engine { public: /* Specifiers controlling what happens when an associated engine fails. - * The names and semantic has been borrowed from libpam. */ + * The names and semantic has been borrowed mostly from libpam. */ enum class Control { /* Failure of an engine injected with the REQUISITE specifier aborts * the whole authentication process immediately. No other engine will @@ -546,6 +546,12 @@ public: * doesn't abort it - there will be fall-back to following engine * it the one that failed wasn't the last. */ SUFFICIENT, + + /* Like SUFFICIENT with the exception that on failure the reason code + * is not overridden. Instead, it's taken directly from the last tried + * non-FALLBACK engine. If there was no previous non-FALLBACK engine + * in a Strategy, then the result_t::deny(reason = -EACCES) is used. */ + FALLBACK, }; Engine::result_t authenticate(const req_state* s) const override final; -- 2.47.3