diff options
author | jayaprakash Mutyala <mutyalax.jayaprakash@intel.com> | 2019-08-07 20:26:37 +0000 |
---|---|---|
committer | mutyalax.jayaprakash <mutyalax.jayaprakash@intel.com> | 2019-11-05 10:42:18 +0000 |
commit | 66b5ca76ccbad5ff6a51189c9b984d4b0e1ba18a (patch) | |
tree | 96e26c33fd6e27aa60ff560e45e63150e0ce0960 | |
parent | eecd51a46e6d44ae3408d889ed037f4e4270d653 (diff) | |
download | bmcweb-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.hpp | 23 | ||||
-rw-r--r-- | redfish-core/lib/account_service.hpp | 109 |
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( |