summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--user_channel/user_layer.cpp5
-rw-r--r--user_channel/user_layer.hpp9
-rw-r--r--user_channel/user_mgmt.cpp27
-rw-r--r--user_channel/user_mgmt.hpp10
-rw-r--r--user_channel/usercommands.cpp39
-rw-r--r--user_channel/usercommands.hpp6
6 files changed, 85 insertions, 11 deletions
diff --git a/user_channel/user_layer.cpp b/user_channel/user_layer.cpp
index 3e4490c..5a4d7ad 100644
--- a/user_channel/user_layer.cpp
+++ b/user_channel/user_layer.cpp
@@ -109,6 +109,11 @@ ipmi_ret_t ipmiUserGetAllCounts(uint8_t& maxChUsers, uint8_t& enabledUsers,
return IPMI_CC_OK;
}
+ipmi_ret_t ipmiUserUpdateEnabledState(const uint8_t& userId, const bool& state)
+{
+ return getUserAccessObject().setUserEnabledState(userId, state);
+}
+
ipmi_ret_t ipmiUserCheckEnabled(const uint8_t& userId, bool& state)
{
if (!UserAccess::isValidUserId(userId))
diff --git a/user_channel/user_layer.hpp b/user_channel/user_layer.hpp
index 5136e86..8c81188 100644
--- a/user_channel/user_layer.hpp
+++ b/user_channel/user_layer.hpp
@@ -146,6 +146,15 @@ ipmi_ret_t ipmiUserGetUserName(const uint8_t& userId, std::string& userName);
ipmi_ret_t ipmiUserGetAllCounts(uint8_t& maxChUsers, uint8_t& enabledUsers,
uint8_t& fixedUsers);
+/** @brief function to update user enabled state
+ *
+ * @param[in] userId - user id
+ *..@param[in] state - state of the user to be updated, true - user enabled.
+ *
+ * @return IPMI_CC_OK for success, others for failure.
+ */
+ipmi_ret_t ipmiUserUpdateEnabledState(const uint8_t& userId, const bool& state);
+
/** @brief determines whether user is enabled
*
* @param[in] userId - user id
diff --git a/user_channel/user_mgmt.cpp b/user_channel/user_mgmt.cpp
index e320e3f..e90bff6 100644
--- a/user_channel/user_mgmt.cpp
+++ b/user_channel/user_mgmt.cpp
@@ -631,6 +631,33 @@ bool UserAccess::isValidUserName(const char* userNameInChar)
return true;
}
+ipmi_ret_t UserAccess::setUserEnabledState(const uint8_t& userId,
+ const bool& enabledState)
+{
+ if (!isValidUserId(userId))
+ {
+ return IPMI_CC_PARM_OUT_OF_RANGE;
+ }
+ boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
+ userLock{*userMutex};
+ UserInfo* userInfo = getUserInfo(userId);
+ std::string userName;
+ userName.assign(reinterpret_cast<char*>(userInfo->userName), 0,
+ ipmiMaxUserName);
+ if (userName.empty())
+ {
+ log<level::DEBUG>("User name not set / invalid");
+ return IPMI_CC_UNSPECIFIED_ERROR;
+ }
+ if (userInfo->userEnabled != enabledState)
+ {
+ std::string userPath = std::string(userObjBasePath) + "/" + userName;
+ setDbusProperty(bus, getUserServiceName().c_str(), userPath.c_str(),
+ usersInterface, userEnabledProperty, enabledState);
+ }
+ return IPMI_CC_OK;
+}
+
ipmi_ret_t UserAccess::setUserPrivilegeAccess(const uint8_t& userId,
const uint8_t& chNum,
const UserPrivAccess& privAccess,
diff --git a/user_channel/user_mgmt.hpp b/user_channel/user_mgmt.hpp
index 16dbd31..5755fa0 100644
--- a/user_channel/user_mgmt.hpp
+++ b/user_channel/user_mgmt.hpp
@@ -183,6 +183,16 @@ class UserAccess
*/
ipmi_ret_t setUserName(const uint8_t& userId, const char* userNameInChar);
+ /** @brief to set user enabled state
+ *
+ * @param[in] userId - user id
+ * @param[in] enabledState - enabled state of the user
+ *
+ * @return IPMI_CC_OK for success, others for failure.
+ */
+ ipmi_ret_t setUserEnabledState(const uint8_t& userId,
+ const bool& enabledState);
+
/** @brief to set user privilege and access details
*
* @param[in] userId - user id
diff --git a/user_channel/usercommands.cpp b/user_channel/usercommands.cpp
index 0ed5b8f..84e9456 100644
--- a/user_channel/usercommands.cpp
+++ b/user_channel/usercommands.cpp
@@ -429,25 +429,42 @@ ipmi_ret_t ipmiSetUserPassword(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
if (!std::regex_match(passwd.c_str(),
std::regex("[a-zA-z_0-9][a-zA-Z_0-9,?:`!\"]*")))
{
- log<level::DEBUG>("Invalid password fields",
- entry("USER-ID:%d", (uint8_t)req->userId));
+ log<level::ERR>("Invalid password fields",
+ entry("USER-ID:%d", (uint8_t)req->userId));
return IPMI_CC_INVALID_FIELD_REQUEST;
}
if (!pamUpdatePasswd(userName.c_str(), passwd.c_str()))
{
- log<level::DEBUG>("Failed to update password",
- entry("USER-ID:%d", (uint8_t)req->userId));
- return IPMI_CC_UNSPECIFIED_ERROR;
+ log<level::ERR>("Failed to update password",
+ entry("USER-ID:%d", (uint8_t)req->userId));
+ return IPMI_CC_INVALID_FIELD_REQUEST;
}
+ return IPMI_CC_OK;
}
- else
+ else if (req->operation == enableUser || req->operation == disableUser)
{
- // TODO: test the password by reading the encrypted file
- log<level::ERR>(
- "Other operations not implemented - TODO yet to implement");
- return IPMI_CC_INVALID_FIELD_REQUEST;
+ return ipmiUserUpdateEnabledState(req->userId,
+ static_cast<bool>(req->operation));
}
- return IPMI_CC_OK;
+ else if (req->operation == testPassword)
+ {
+ auto password = ipmiUserGetPassword(userName);
+ std::string testPassword(
+ reinterpret_cast<const char*>(req->userPassword), 0,
+ passwordLength);
+ // Note: For security reasons password size won't be compared and
+ // wrong password size completion code will not be returned if size
+ // doesn't match as specified in IPMI specification.
+ if (password != testPassword)
+ {
+ log<level::DEBUG>("Test password failed",
+ entry("USER-ID:%d", (uint8_t)req->userId));
+ return static_cast<ipmi_ret_t>(
+ IPMISetPasswordReturnCodes::ipmiCCPasswdFailMismatch);
+ }
+ return IPMI_CC_OK;
+ }
+ return IPMI_CC_INVALID_FIELD_REQUEST;
}
void registerUserIpmiFunctions()
diff --git a/user_channel/usercommands.hpp b/user_channel/usercommands.hpp
index ee33b5a..afbe67a 100644
--- a/user_channel/usercommands.hpp
+++ b/user_channel/usercommands.hpp
@@ -29,6 +29,12 @@ enum ipmi_netfn_user_cmds
IPMI_CMD_SET_USER_PASSWORD = 0x47,
};
+enum class IPMISetPasswordReturnCodes
+{
+ ipmiCCPasswdFailMismatch = 0x80,
+ ipmiCCPasswdFailWrongSize = 0x81,
+};
+
static constexpr uint8_t userIdEnabledViaSetPassword = 0x1;
static constexpr uint8_t userIdDisabledViaSetPassword = 0x2;
OpenPOWER on IntegriCloud