summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjayaprakash Mutyala <mutyalax.jayaprakash@intel.com>2019-08-07 20:26:37 +0000
committermutyalax.jayaprakash <mutyalax.jayaprakash@intel.com>2019-11-05 10:42:18 +0000
commit66b5ca76ccbad5ff6a51189c9b984d4b0e1ba18a (patch)
tree96e26c33fd6e27aa60ff560e45e63150e0ce0960
parenteecd51a46e6d44ae3408d889ed037f4e4270d653 (diff)
downloadbmcweb-66b5ca76ccbad5ff6a51189c9b984d4b0e1ba18a.tar.gz
bmcweb-66b5ca76ccbad5ff6a51189c9b984d4b0e1ba18a.zip
account_service: redfish user Patch error handling
Modified doPatch method to populate redfish user update error codes. Tested: Tested user updates with below scenarios 1)Provided username is not exist 2)Replace username already user exists 3)Replace Username is NULL/Invalid 4)Replace username is not starting with alphabet 5)Replace username exceeds more than 16 characters 6)Password is not valid for Replace/existing username Redfish validator test results: 1 failProp errors in /redfish/v1/Systems/system/LogServices/EventLog 1 problemResource errors in /redfish/v1/Systems/system/LogServices/ EventLog/Entries Counter({'skipOptional': 17887, 'pass': 12133, 'passGet': 1285, 'metadataNamespaces': 1047, 'serviceNamespaces': 69, 'reflink': 9, 'passAction': 7, 'warningPresent': 6, 'optionalAction': 6, 'repeat': 3, 'invalidPropertyValue': 3, 'failErrorPresent': 1, 'err.LogEntryCollection.LogEntryCollection': 1, 'failProp': 1, 'unvalidated': 1, 'problemResource': 1, 'unverifiedComplexAdditional': 1, 'warnTrailingSlashLink': 1}) Validation has failed: 3 problems found Signed-off-by: jayaprakash Mutyala <mutyalax.jayaprakash@intel.com> Change-Id: Ibee448c5d5c4f38c5c4cacda757864593f6001fc
-rw-r--r--include/pam_authenticate.hpp23
-rw-r--r--redfish-core/lib/account_service.hpp109
2 files changed, 98 insertions, 34 deletions
diff --git a/include/pam_authenticate.hpp b/include/pam_authenticate.hpp
index 1469aef..464f171 100644
--- a/include/pam_authenticate.hpp
+++ b/include/pam_authenticate.hpp
@@ -86,30 +86,27 @@ inline bool pamAuthenticateUser(const std::string_view username,
return true;
}
-inline bool pamUpdatePassword(const std::string& username,
- const std::string& password)
+inline int pamUpdatePassword(const std::string& username,
+ const std::string& password)
{
const struct pam_conv localConversation = {
pamFunctionConversation, const_cast<char*>(password.c_str())};
pam_handle_t* localAuthHandle = NULL; // this gets set by pam_start
- if (pam_start("passwd", username.c_str(), &localConversation,
- &localAuthHandle) != PAM_SUCCESS)
- {
- return false;
- }
- int retval = pam_chauthtok(localAuthHandle, PAM_SILENT);
+ int retval = pam_start("passwd", username.c_str(), &localConversation,
+ &localAuthHandle);
if (retval != PAM_SUCCESS)
{
- pam_end(localAuthHandle, PAM_SUCCESS);
- return false;
+ return retval;
}
- if (pam_end(localAuthHandle, PAM_SUCCESS) != PAM_SUCCESS)
+ retval = pam_chauthtok(localAuthHandle, PAM_SILENT);
+ if (retval != PAM_SUCCESS)
{
- return false;
+ pam_end(localAuthHandle, PAM_SUCCESS);
+ return retval;
}
- return true;
+ return pam_end(localAuthHandle, PAM_SUCCESS);
}
diff --git a/redfish-core/lib/account_service.hpp b/redfish-core/lib/account_service.hpp
index 07efeb5..59e2d1c 100644
--- a/redfish-core/lib/account_service.hpp
+++ b/redfish-core/lib/account_service.hpp
@@ -113,6 +113,54 @@ inline std::string getPrivilegeFromRoleId(std::string_view role)
return "";
}
+void userErrorMessageHandler(const sd_bus_error* e,
+ std::shared_ptr<AsyncResp> asyncResp,
+ const std::string& newUser,
+ const std::string& username)
+{
+ const char* errorMessage = e->name;
+ if (e == nullptr)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+
+ if (strcmp(errorMessage,
+ "xyz.openbmc_project.User.Common.Error.UserNameExists") == 0)
+ {
+ messages::resourceAlreadyExists(asyncResp->res,
+ "#ManagerAccount.v1_0_3.ManagerAccount",
+ "UserName", newUser);
+ }
+ else if (strcmp(errorMessage, "xyz.openbmc_project.User.Common.Error."
+ "UserNameDoesNotExist") == 0)
+ {
+ messages::resourceNotFound(
+ asyncResp->res, "#ManagerAccount.v1_0_3.ManagerAccount", username);
+ }
+ else if (strcmp(errorMessage,
+ "xyz.openbmc_project.Common.Error.InvalidArgument") == 0)
+ {
+ messages::propertyValueFormatError(asyncResp->res, newUser, "UserName");
+ }
+ else if (strcmp(errorMessage,
+ "xyz.openbmc_project.User.Common.Error.NoResource") == 0)
+ {
+ messages::createLimitReachedForResource(asyncResp->res);
+ }
+ else if (strcmp(errorMessage, "xyz.openbmc_project.User.Common.Error."
+ "UserNameGroupFail") == 0)
+ {
+ messages::propertyValueFormatError(asyncResp->res, newUser, "UserName");
+ }
+ else
+ {
+ messages::internalError(asyncResp->res);
+ }
+
+ return;
+}
+
void parseLDAPConfigData(nlohmann::json& json_response,
const LDAPConfigData& confData,
const std::string& ldapType)
@@ -1298,7 +1346,8 @@ class AccountsCollection : public Node
return;
}
- if (!pamUpdatePassword(username, password))
+ if (pamUpdatePassword(username, password) !=
+ PAM_SUCCESS)
{
// At this point we have a user that's been created,
// but the password set failed.Something is wrong,
@@ -1505,10 +1554,12 @@ class ManagerAccount : public Node
const std::string& username = params[0];
- if (!newUserName)
+ // if user name is not provided in the patch method or if it
+ // matches the user name in the URI, then we are treating it as updating
+ // user properties other then username. If username provided doesn't
+ // match the URI, then we are treating this as user rename request.
+ if (!newUserName || (newUserName.value() == username))
{
- // If the username isn't being updated, we can update the
- // properties directly
updateUserProperties(asyncResp, username, password, enabled, roleId,
locked);
return;
@@ -1518,14 +1569,13 @@ class ManagerAccount : public Node
crow::connections::systemBus->async_method_call(
[this, asyncResp, username, password(std::move(password)),
roleId(std::move(roleId)), enabled(std::move(enabled)),
- newUser{*newUserName}, locked(std::move(locked))](
- const boost::system::error_code ec) {
+ newUser{std::string(*newUserName)},
+ locked(std::move(locked))](const boost::system::error_code ec,
+ sdbusplus::message::message& m) {
if (ec)
{
- BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
- messages::resourceNotFound(
- asyncResp->res,
- "#ManagerAccount.v1_0_3.ManagerAccount", username);
+ userErrorMessageHandler(m.get_error(), asyncResp,
+ newUser, username);
return;
}
@@ -1545,16 +1595,6 @@ class ManagerAccount : public Node
std::optional<std::string> roleId,
std::optional<bool> locked)
{
- if (password)
- {
- if (!pamUpdatePassword(username, *password))
- {
- BMCWEB_LOG_ERROR << "pamUpdatePassword Failed";
- messages::internalError(asyncResp->res);
- return;
- }
- }
-
std::string dbusObjectPath = "/xyz/openbmc_project/user/" + username;
dbus::utility::escapePathForDbus(dbusObjectPath);
@@ -1566,9 +1606,36 @@ class ManagerAccount : public Node
asyncResp{std::move(asyncResp)}](int rc) {
if (!rc)
{
- messages::invalidObject(asyncResp->res, username.c_str());
+ messages::resourceNotFound(
+ asyncResp->res, "#ManagerAccount.v1_0_3.ManagerAccount",
+ username);
return;
}
+
+ if (password)
+ {
+ int retval = pamUpdatePassword(username, *password);
+
+ if (retval == PAM_USER_UNKNOWN)
+ {
+ messages::resourceNotFound(
+ asyncResp->res,
+ "#ManagerAccount.v1_0_3.ManagerAccount", username);
+ }
+ else if (retval == PAM_AUTHTOK_ERR)
+ {
+ // If password is invalid
+ messages::propertyValueFormatError(
+ asyncResp->res, *password, "Password");
+ BMCWEB_LOG_ERROR << "pamUpdatePassword Failed";
+ }
+ else if (retval != PAM_SUCCESS)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ }
+
if (enabled)
{
crow::connections::systemBus->async_method_call(
OpenPOWER on IntegriCloud