summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoseph Reynolds <joseph-reynolds@charter.net>2020-01-14 16:34:09 -0600
committerJoseph Reynolds <joseph-reynolds@charter.net>2020-01-30 16:24:12 +0000
commitd887fff197b2fc3357bcbb1adb028521699a204a (patch)
treecd2038b1dfd796becf9444d27b1024ca5dc4b7d7
parentd04ba325f3ef4e60eb4fd8e7477af78d1be0d79d (diff)
downloadbmcweb-d887fff197b2fc3357bcbb1adb028521699a204a.tar.gz
bmcweb-d887fff197b2fc3357bcbb1adb028521699a204a.zip
Enhance return value from pamAuthenticateUser
This enhances the return value from the pamAuthenticateUser function so callers can articulate PAM error codes like PAM_NEW_AUTHTOK_REQD which means the credentials are correct, but the password must be changed. Tested: Yes, scenarios via both Redfish login and Basic Auth: - correct username and password, password is not expired - correct username and password, password is expired - correct username and incorrect password, password is not expired - correct username and incorrect password, password is expired - non-existent user (passsword is not relevant) Signed-off-by: Joseph Reynolds <joseph-reynolds@charter.net> Change-Id: I1114d6c9cc591fb0a1853cb4edea32ad22f7b015
-rw-r--r--include/pam_authenticate.hpp39
-rw-r--r--include/token_authorization_middleware.hpp4
-rw-r--r--redfish-core/lib/redfish_sessions.hpp2
3 files changed, 23 insertions, 22 deletions
diff --git a/include/pam_authenticate.hpp b/include/pam_authenticate.hpp
index 234246d..f8afbb1 100644
--- a/include/pam_authenticate.hpp
+++ b/include/pam_authenticate.hpp
@@ -47,8 +47,13 @@ inline int pamFunctionConversation(int numMsg, const struct pam_message** msg,
return PAM_SUCCESS;
}
-inline bool pamAuthenticateUser(const std::string_view username,
- const std::string_view password)
+/**
+ * @brief Attempt username/password authentication via PAM.
+ * @param username The provided username aka account name.
+ * @param password The provided password.
+ * @returns PAM error code or PAM_SUCCESS for success. */
+inline int pamAuthenticateUser(const std::string_view username,
+ const std::string_view password)
{
std::string userStr(username);
std::string passStr(password);
@@ -56,34 +61,30 @@ inline bool pamAuthenticateUser(const std::string_view username,
pamFunctionConversation, const_cast<char*>(passStr.c_str())};
pam_handle_t* localAuthHandle = nullptr; // this gets set by pam_start
- if (pam_start("webserver", userStr.c_str(), &localConversation,
- &localAuthHandle) != PAM_SUCCESS)
+ int retval = pam_start("webserver", userStr.c_str(), &localConversation,
+ &localAuthHandle);
+ if (retval != PAM_SUCCESS)
{
- return false;
+ return retval;
}
- int retval = pam_authenticate(localAuthHandle,
- PAM_SILENT | PAM_DISALLOW_NULL_AUTHTOK);
+ retval = pam_authenticate(localAuthHandle,
+ PAM_SILENT | PAM_DISALLOW_NULL_AUTHTOK);
if (retval != PAM_SUCCESS)
{
- pam_end(localAuthHandle, PAM_SUCCESS);
- return false;
+ pam_end(localAuthHandle, PAM_SUCCESS); // ignore retval
+ return retval;
}
/* check that the account is healthy */
- if (pam_acct_mgmt(localAuthHandle, PAM_DISALLOW_NULL_AUTHTOK) !=
- PAM_SUCCESS)
- {
- pam_end(localAuthHandle, PAM_SUCCESS);
- return false;
- }
-
- if (pam_end(localAuthHandle, PAM_SUCCESS) != PAM_SUCCESS)
+ retval = pam_acct_mgmt(localAuthHandle, PAM_DISALLOW_NULL_AUTHTOK);
+ if (retval != PAM_SUCCESS)
{
- return false;
+ pam_end(localAuthHandle, PAM_SUCCESS); // ignore retval
+ return retval;
}
- return true;
+ return pam_end(localAuthHandle, PAM_SUCCESS);
}
inline int pamUpdatePassword(const std::string& username,
diff --git a/include/token_authorization_middleware.hpp b/include/token_authorization_middleware.hpp
index 4d7cc08..abdedaf 100644
--- a/include/token_authorization_middleware.hpp
+++ b/include/token_authorization_middleware.hpp
@@ -138,7 +138,7 @@ class Middleware
BMCWEB_LOG_DEBUG << "[AuthMiddleware] Authenticating user: " << user;
- if (!pamAuthenticateUser(user, pass))
+ if (pamAuthenticateUser(user, pass) != PAM_SUCCESS)
{
return nullptr;
}
@@ -395,7 +395,7 @@ template <typename... Middlewares> void requestRoutes(Crow<Middlewares...>& app)
if (!username.empty() && !password.empty())
{
- if (!pamAuthenticateUser(username, password))
+ if (pamAuthenticateUser(username, password) != PAM_SUCCESS)
{
res.result(boost::beast::http::status::unauthorized);
}
diff --git a/redfish-core/lib/redfish_sessions.hpp b/redfish-core/lib/redfish_sessions.hpp
index 88f250b..0094858 100644
--- a/redfish-core/lib/redfish_sessions.hpp
+++ b/redfish-core/lib/redfish_sessions.hpp
@@ -196,7 +196,7 @@ class SessionCollection : public Node
return;
}
- if (!pamAuthenticateUser(username, password))
+ if (pamAuthenticateUser(username, password) != PAM_SUCCESS)
{
messages::resourceAtUriUnauthorized(res, std::string(req.url),
"Invalid username or password");
OpenPOWER on IntegriCloud