diff options
Diffstat (limited to 'meta-ibs/meta-cp2-5422/recipes-phosphor')
2 files changed, 228 insertions, 0 deletions
diff --git a/meta-ibs/meta-cp2-5422/recipes-phosphor/interfaces/bmcweb/0014-Additional-details-about-errors-when-change-user-pw.patch b/meta-ibs/meta-cp2-5422/recipes-phosphor/interfaces/bmcweb/0014-Additional-details-about-errors-when-change-user-pw.patch new file mode 100644 index 0000000000..64905fcd46 --- /dev/null +++ b/meta-ibs/meta-cp2-5422/recipes-phosphor/interfaces/bmcweb/0014-Additional-details-about-errors-when-change-user-pw.patch @@ -0,0 +1,227 @@ +From eccdb0b99d8d79e53a75e879d1293cadfe03f50c Mon Sep 17 00:00:00 2001 +From: Nikita Kosenkov <NKosenkov@IBS.RU> +Date: Tue, 6 Sep 2022 16:30:03 +0300 +Subject: [PATCH] Additional details about errors when changing a user password + +--- + include/pam_authenticate.hpp | 54 +++++++++++++++++----- + redfish-core/lib/account_service.hpp | 68 +++++++++++++++++++++++++--- + 2 files changed, 105 insertions(+), 17 deletions(-) + +diff --git a/include/pam_authenticate.hpp b/include/pam_authenticate.hpp +index ca8c8d32..cf09dd1c 100644 +--- a/include/pam_authenticate.hpp ++++ b/include/pam_authenticate.hpp +@@ -7,6 +7,17 @@ + #include <cstring> + #include <memory> + ++/** ++ @brief Format of the appdata passed into the PAM conversation function. ++ @field password The password value. ++ @field messagesFromPamPtr Collected responses from PAM. ++ **/ ++struct PamConvAppData ++{ ++ const char* password; ++ std::vector<std::string>* messagesFromPamPtr; ++}; ++ + // function used to get user input + inline int pamFunctionConversation(int numMsg, const struct pam_message** msg, + struct pam_response** resp, void* appdataPtr) +@@ -21,12 +32,29 @@ inline int pamFunctionConversation(int numMsg, const struct pam_message** msg, + return PAM_CONV_ERR; + } + ++ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) ++ PamConvAppData* pamConvAppData = ++ reinterpret_cast<PamConvAppData*>(appdataPtr); ++ const char* appPass = pamConvAppData->password; ++ std::vector<std::string>* messagesFromPamPtr = ++ pamConvAppData->messagesFromPamPtr; ++ + for (int i = 0; i < numMsg; ++i) + { + /* Ignore all PAM messages except prompting for hidden input */ + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) + if (msg[i]->msg_style != PAM_PROMPT_ECHO_OFF) + { ++ if( msg[i]->msg_style == PAM_ERROR_MSG || ++ msg[i]->msg_style == PAM_TEXT_INFO) ++ { ++ /* Capture messages from PAM */ ++ if (messagesFromPamPtr) ++ { ++ messagesFromPamPtr->push_back(msg[i]->msg); ++ } ++ } ++ + continue; + } + +@@ -34,7 +62,6 @@ inline int pamFunctionConversation(int numMsg, const struct pam_message** msg, + /* Allocate memory only when PAM_PROMPT_ECHO_OFF is encounterred */ + + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) +- char* appPass = reinterpret_cast<char*>(appdataPtr); + size_t appPassSize = std::strlen(appPass); + + if ((appPassSize + 1) > PAM_MAX_RESP_SIZE) +@@ -88,11 +115,13 @@ inline int pamAuthenticateUser(const std::string_view username, + { + std::string userStr(username); + std::string passStr(password); ++ PamConvAppData pamConvAppData = {passStr.c_str(), nullptr}; + +- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast) +- char* passStrNoConst = const_cast<char*>(passStr.c_str()); +- const struct pam_conv localConversation = {pamFunctionConversation, +- passStrNoConst}; ++ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) ++ const struct pam_conv localConversation = { ++ pamFunctionConversation, ++ reinterpret_cast<char*>(&pamConvAppData) ++ }; + pam_handle_t* localAuthHandle = nullptr; // this gets set by pam_start + + int retval = pam_start("webserver", userStr.c_str(), &localConversation, +@@ -122,12 +151,15 @@ inline int pamAuthenticateUser(const std::string_view username, + } + + inline int pamUpdatePassword(const std::string& username, +- const std::string& password) ++ const std::string& password, ++ std::vector<std::string>& diagnosticInfo) + { +- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast) +- char* passStrNoConst = const_cast<char*>(password.c_str()); +- const struct pam_conv localConversation = {pamFunctionConversation, +- passStrNoConst}; ++ diagnosticInfo.clear(); ++ PamConvAppData pamConvAppData = {password.c_str(), &diagnosticInfo}; ++ struct pam_conv localConversation = { ++ pamFunctionConversation, reinterpret_cast<char*>(&pamConvAppData) ++ }; ++ + pam_handle_t* localAuthHandle = nullptr; // this gets set by pam_start + + int retval = pam_start("webserver", username.c_str(), &localConversation, +@@ -138,7 +170,7 @@ inline int pamUpdatePassword(const std::string& username, + return retval; + } + +- retval = pam_chauthtok(localAuthHandle, PAM_SILENT); ++ retval = pam_chauthtok(localAuthHandle, 0); + if (retval != PAM_SUCCESS) + { + pam_end(localAuthHandle, PAM_SUCCESS); +diff --git a/redfish-core/lib/account_service.hpp b/redfish-core/lib/account_service.hpp +index f8ba3225..f79dc1d7 100644 +--- a/redfish-core/lib/account_service.hpp ++++ b/redfish-core/lib/account_service.hpp +@@ -1131,7 +1131,9 @@ inline void updateUserProperties(std::shared_ptr<bmcweb::AsyncResp> asyncResp, + + if (password) + { +- int retval = pamUpdatePassword(username, *password); ++ std::vector<std::string> diagnosticMessagesFromPam; ++ int retval = pamUpdatePassword(username, *password, ++ diagnosticMessagesFromPam); + + if (retval == PAM_USER_UNKNOWN) + { +@@ -1143,8 +1145,34 @@ inline void updateUserProperties(std::shared_ptr<bmcweb::AsyncResp> asyncResp, + { + // If password is invalid + messages::propertyValueFormatError(asyncResp->res, *password, +- "Password"); ++ "Password"); ++ ++ if (!diagnosticMessagesFromPam.empty()) ++ { ++ asyncResp->res ++ .jsonValue["Password@Message.ExtendedInfo"][0] ++ ["Oem"] = { ++ {"OpenBMC", ++ {{"ErrorMessage", ++ nlohmann::json::array()}}}}; ++ auto& diags = ++ asyncResp->res ++ .jsonValue["Password@Message.ExtendedInfo"] ++ [0]["Oem"]["OpenBMC"] ++ ["ErrorMessage"]; ++ ++ for (const std::string& msg : diagnosticMessagesFromPam) ++ { ++ diags.push_back(msg); ++ } ++ } ++ + BMCWEB_LOG_ERROR << "pamUpdatePassword Failed"; ++ ++ for (const std::string& msg : diagnosticMessagesFromPam) ++ { ++ BMCWEB_LOG_INFO << "PAM msg: " << msg; ++ } + } + else if (retval != PAM_SUCCESS) + { +@@ -1591,7 +1619,9 @@ inline void handleAccountCollectionPost( + return; + } + +- if (pamUpdatePassword(username, password) != PAM_SUCCESS) ++ std::vector<std::string> diagnosticMessagesFromPam; ++ if (pamUpdatePassword(username, password, ++ diagnosticMessagesFromPam) != PAM_SUCCESS) + { + // At this point we have a user that's been + // created, but the password set +@@ -1609,14 +1639,40 @@ inline void handleAccountCollectionPost( + return; + } + +- // If password is invalid +- messages::propertyValueFormatError(asyncResp->res, password, +- "Password"); + }, + "xyz.openbmc_project.User.Manager", userPath, + "xyz.openbmc_project.Object.Delete", "Delete"); + ++ // If password is invalid ++ messages::propertyValueFormatError(asyncResp->res, password, ++ "Password"); ++ ++ if (!diagnosticMessagesFromPam.empty()) ++ { ++ asyncResp->res ++ .jsonValue["Password@Message.ExtendedInfo"][0] ++ ["Oem"] = { ++ {"OpenBMC", ++ {{"ErrorMessage", ++ nlohmann::json::array()}}}}; ++ auto& diags = ++ asyncResp->res ++ .jsonValue["Password@Message.ExtendedInfo"] ++ [0]["Oem"]["OpenBMC"] ++ ["ErrorMessage"]; ++ for (const std::string& msg : diagnosticMessagesFromPam) ++ { ++ diags.push_back(msg); ++ } ++ } ++ + BMCWEB_LOG_ERROR << "pamUpdatePassword Failed"; ++ ++ for (const std::string& msg : diagnosticMessagesFromPam) ++ { ++ BMCWEB_LOG_INFO << "PAM info: " << msg; ++ } ++ + return; + } + +-- +2.35.1 + diff --git a/meta-ibs/meta-cp2-5422/recipes-phosphor/interfaces/bmcweb_%.bbappend b/meta-ibs/meta-cp2-5422/recipes-phosphor/interfaces/bmcweb_%.bbappend index 38791694d6..eee9b4aa3d 100644 --- a/meta-ibs/meta-cp2-5422/recipes-phosphor/interfaces/bmcweb_%.bbappend +++ b/meta-ibs/meta-cp2-5422/recipes-phosphor/interfaces/bmcweb_%.bbappend @@ -10,6 +10,7 @@ SRC_URI += "\ file://0011-configure-telemetry.patch \ file://0012-add-telemetry-hour-data.patch \ file://0013-bugfix-telemetry-circular-buffer.patch \ + file://0014-Additional-details-about-errors-when-change-user-pw.patch \ " EXTRA_OEMESON += "\ |