summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/sessions.hpp19
-rw-r--r--include/token_authorization_middleware.hpp19
2 files changed, 29 insertions, 9 deletions
diff --git a/include/sessions.hpp b/include/sessions.hpp
index 9d24327eab..a7ffe28921 100644
--- a/include/sessions.hpp
+++ b/include/sessions.hpp
@@ -45,6 +45,15 @@ struct UserSession
std::chrono::time_point<std::chrono::steady_clock> lastUpdated;
PersistenceType persistence;
bool cookieAuth = false;
+ bool isConfigureSelfOnly = false;
+
+ // There are two sources of truth for isConfigureSelfOnly:
+ // 1. When pamAuthenticateUser() returns PAM_NEW_AUTHTOK_REQD.
+ // 2. D-Bus User.Manager.GetUserInfo property UserPasswordExpired.
+ // These should be in sync, but the underlying condition can change at any
+ // time. For example, a password can expire or be changed outside of
+ // bmcweb. The value stored here is updated at the start of each
+ // operation and used as the truth within bmcweb.
/**
* @brief Fills object with data from UserSession's JSON representation
@@ -196,7 +205,8 @@ class SessionStore
public:
std::shared_ptr<UserSession> generateUserSession(
const std::string_view username,
- PersistenceType persistence = PersistenceType::TIMEOUT)
+ PersistenceType persistence = PersistenceType::TIMEOUT,
+ bool isConfigureSelfOnly = false)
{
// TODO(ed) find a secure way to not generate session identifiers if
// persistence is set to SINGLE_REQUEST
@@ -244,9 +254,10 @@ class SessionStore
}
}
- auto session = std::make_shared<UserSession>(UserSession{
- uniqueId, sessionToken, std::string(username), csrfToken,
- std::chrono::steady_clock::now(), persistence});
+ auto session = std::make_shared<UserSession>(
+ UserSession{uniqueId, sessionToken, std::string(username),
+ csrfToken, std::chrono::steady_clock::now(),
+ persistence, false, isConfigureSelfOnly});
auto it = authTokens.emplace(std::make_pair(sessionToken, session));
// Only need to write to disk if session isn't about to be destroyed.
needWrite = persistence == PersistenceType::TIMEOUT;
diff --git a/include/token_authorization_middleware.hpp b/include/token_authorization_middleware.hpp
index aaa1325b7a..ccea929f6f 100644
--- a/include/token_authorization_middleware.hpp
+++ b/include/token_authorization_middleware.hpp
@@ -138,7 +138,9 @@ class Middleware
BMCWEB_LOG_DEBUG << "[AuthMiddleware] Authenticating user: " << user;
- if (pamAuthenticateUser(user, pass) != PAM_SUCCESS)
+ int pamrc = pamAuthenticateUser(user, pass);
+ bool isConfigureSelfOnly = pamrc == PAM_NEW_AUTHTOK_REQD;
+ if ((pamrc != PAM_SUCCESS) && !isConfigureSelfOnly)
{
return nullptr;
}
@@ -150,7 +152,8 @@ class Middleware
// This whole flow needs to be revisited anyway, as we can't be
// calling directly into pam for every request
return persistent_data::SessionStore::getInstance().generateUserSession(
- user, crow::persistent_data::PersistenceType::SINGLE_REQUEST);
+ user, crow::persistent_data::PersistenceType::SINGLE_REQUEST,
+ isConfigureSelfOnly);
}
const std::shared_ptr<crow::persistent_data::UserSession>
@@ -397,14 +400,20 @@ template <typename... Middlewares> void requestRoutes(Crow<Middlewares...>& app)
if (!username.empty() && !password.empty())
{
- if (pamAuthenticateUser(username, password) != PAM_SUCCESS)
+ int pamrc = pamAuthenticateUser(username, password);
+ bool isConfigureSelfOnly = pamrc == PAM_NEW_AUTHTOK_REQD;
+ if ((pamrc != PAM_SUCCESS) && !isConfigureSelfOnly)
{
res.result(boost::beast::http::status::unauthorized);
}
else
{
- auto session = persistent_data::SessionStore::getInstance()
- .generateUserSession(username);
+ auto session =
+ persistent_data::SessionStore::getInstance()
+ .generateUserSession(
+ username,
+ crow::persistent_data::PersistenceType::TIMEOUT,
+ isConfigureSelfOnly);
if (looksLikePhosphorRest)
{