summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Kosenkov <NKosenkov@IBS.RU>2022-09-12 09:50:37 +0300
committerNikita Kosenkov <NKosenkov@IBS.RU>2022-09-12 09:50:37 +0300
commit95ce5a8350ad118a0505a2323189520464cc0713 (patch)
treed2e5822e43950fb02d8e99ef98a4001d93406fe0
parent9be6af0cafe2e4de90a2bc0010bef07fb8e86999 (diff)
downloadopenbmc-95ce5a8350ad118a0505a2323189520464cc0713.tar.xz
SILABMC-295: Added detailed information about incorrect user password
-rw-r--r--meta-ibs/meta-cp2-5422/recipes-phosphor/interfaces/bmcweb/0014-Additional-details-about-errors-when-change-user-pw.patch227
-rw-r--r--meta-ibs/meta-cp2-5422/recipes-phosphor/interfaces/bmcweb_%.bbappend1
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 += "\