diff options
author | Joseph Reynolds <joseph-reynolds@charter.net> | 2020-01-14 16:34:09 -0600 |
---|---|---|
committer | Joseph Reynolds <joseph-reynolds@charter.net> | 2020-01-30 16:24:12 +0000 |
commit | d887fff197b2fc3357bcbb1adb028521699a204a (patch) | |
tree | cd2038b1dfd796becf9444d27b1024ca5dc4b7d7 | |
parent | d04ba325f3ef4e60eb4fd8e7477af78d1be0d79d (diff) | |
download | bmcweb-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.hpp | 39 | ||||
-rw-r--r-- | include/token_authorization_middleware.hpp | 4 | ||||
-rw-r--r-- | redfish-core/lib/redfish_sessions.hpp | 2 |
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"); |