summaryrefslogtreecommitdiffstats
path: root/user_channel
diff options
context:
space:
mode:
authorSaravanan Palanisamy <saravanan.palanisamy@intel.com>2019-05-15 22:33:17 +0000
committerSaravanan Palanisamy <saravanan.palanisamy@linux.intel.com>2019-07-19 21:09:37 +0000
commit77381f15bdee2bf867337a3ad6c7e2aaed93b2f5 (patch)
tree847d54194623e632f63cb1d3679d9f9cd7d365a7 /user_channel
parente5c9d2fbd8776c9ecbd27fe8849f307ca9bb777a (diff)
downloadphosphor-host-ipmid-77381f15bdee2bf867337a3ad6c7e2aaed93b2f5.tar.gz
phosphor-host-ipmid-77381f15bdee2bf867337a3ad6c7e2aaed93b2f5.zip
user_layer: Add get/set user payload access.
IPMI Spec reference: Section 24.6, 24.7. Support is added to get/set user access details for the unreserved, supported payload types defined by Spec. SOL is the only unreserved, supported payload currently. If support is needed for unreserved std/oem payload types in future, they can be enabled with minor source code changes to this implementation. All payload types are packed in a JSON object "payload_enabled" in ipmi_user.json file. Tested-by: 1. For user 8 in channel 3, Enable SOL payload. // Command - (channel 3 is of LAN channel type) ipmitool -I lanplus...raw 0x06 0x4C 3 0x8 0x02 0 0 0 // Verify it with Get User Payload Access Command ipmitool -I lanplus...raw 0x06 0x4D 3 8 02 00 00 00 // Response 2. Disable SOL payload. // Command ipmitool -I lanplus...raw 0x06 0x4C 3 0x48 0x02 0 0x00 0 // Verify it with Get User Payload Access Command ipmitool -I lanplus...raw 0x06 0x4D 3 8 00 00 00 00 // Response 3. Enable unsupported payload stdPayload7. // Command ipmitool -I lanplus...raw 0x06 0x4C 3 0x8 0x80 0 0 0 Error: Invalid data field in request // Response Change-Id: Idc57b04a747e55666407d928d8b2169223501e5b Signed-off-by: Saravanan Palanisamy <saravanan.palanisamy@linux.intel.com>
Diffstat (limited to 'user_channel')
-rw-r--r--user_channel/user_layer.cpp47
-rw-r--r--user_channel/user_layer.hpp41
-rw-r--r--user_channel/user_mgmt.cpp201
-rw-r--r--user_channel/user_mgmt.hpp51
-rw-r--r--user_channel/usercommands.cpp193
5 files changed, 533 insertions, 0 deletions
diff --git a/user_channel/user_layer.cpp b/user_channel/user_layer.cpp
index 00f6a7f..b309e86 100644
--- a/user_channel/user_layer.cpp
+++ b/user_channel/user_layer.cpp
@@ -176,4 +176,51 @@ bool ipmiUserPamAuthenticate(std::string_view userName,
return pamUserCheckAuthenticate(userName, userPassword);
}
+ipmi_ret_t ipmiUserSetUserPayloadAccess(const uint8_t chNum,
+ const uint8_t operation,
+ const uint8_t userId,
+ const PayloadAccess& payloadAccess)
+{
+
+ if (!UserAccess::isValidChannel(chNum))
+ {
+ return IPMI_CC_INVALID_FIELD_REQUEST;
+ }
+ if (!UserAccess::isValidUserId(userId))
+ {
+ return IPMI_CC_PARM_OUT_OF_RANGE;
+ }
+
+ return getUserAccessObject().setUserPayloadAccess(chNum, operation, userId,
+ payloadAccess);
+}
+
+ipmi_ret_t ipmiUserGetUserPayloadAccess(const uint8_t chNum,
+ const uint8_t userId,
+ PayloadAccess& payloadAccess)
+{
+
+ if (!UserAccess::isValidChannel(chNum))
+ {
+ return IPMI_CC_INVALID_FIELD_REQUEST;
+ }
+ if (!UserAccess::isValidUserId(userId))
+ {
+ return IPMI_CC_PARM_OUT_OF_RANGE;
+ }
+
+ UserInfo* userInfo = getUserAccessObject().getUserInfo(userId);
+
+ payloadAccess.stdPayloadEnables1 =
+ userInfo->payloadAccess[chNum].stdPayloadEnables1;
+ payloadAccess.stdPayloadEnables2Reserved =
+ userInfo->payloadAccess[chNum].stdPayloadEnables2Reserved;
+ payloadAccess.oemPayloadEnables1 =
+ userInfo->payloadAccess[chNum].oemPayloadEnables1;
+ payloadAccess.oemPayloadEnables2Reserved =
+ userInfo->payloadAccess[chNum].oemPayloadEnables2Reserved;
+
+ return IPMI_CC_OK;
+}
+
} // namespace ipmi
diff --git a/user_channel/user_layer.hpp b/user_channel/user_layer.hpp
index 7926c59..450d878 100644
--- a/user_channel/user_layer.hpp
+++ b/user_channel/user_layer.hpp
@@ -16,6 +16,7 @@
#pragma once
#include <ipmid/api.h>
+#include <bitset>
#include <string>
namespace ipmi
@@ -37,6 +38,7 @@ static constexpr uint8_t ipmiMaxUsers = 15;
static constexpr uint8_t ipmiMaxChannels = 16;
static constexpr uint8_t maxIpmi20PasswordSize = 20;
static constexpr uint8_t maxIpmi15PasswordSize = 16;
+static constexpr uint8_t payloadsPerByte = 8;
/** @struct PrivAccess
*
@@ -61,6 +63,19 @@ struct PrivAccess
#endif
} __attribute__((packed));
+/** @struct UserPayloadAccess
+ *
+ * Structure to denote payload access restrictions applicable for a
+ * given user and channel. (refer spec sec 24.6)
+ */
+struct PayloadAccess
+{
+ std::bitset<payloadsPerByte> stdPayloadEnables1;
+ std::bitset<payloadsPerByte> stdPayloadEnables2Reserved;
+ std::bitset<payloadsPerByte> oemPayloadEnables1;
+ std::bitset<payloadsPerByte> oemPayloadEnables2Reserved;
+};
+
/** @brief initializes user management
*
* @return IPMI_CC_OK for success, others for failure.
@@ -221,4 +236,30 @@ ipmi_ret_t ipmiUserSetPrivilegeAccess(const uint8_t userId, const uint8_t chNum,
bool ipmiUserPamAuthenticate(std::string_view userName,
std::string_view userPassword);
+/** @brief sets user payload access data
+ *
+ * @param[in] chNum - channel number
+ * @param[in] operation - ENABLE / DISABLE operation
+ * @param[in] userId - user id
+ * @param[in] payloadAccess - payload access data
+ *
+ * @return IPMI_CC_OK for success, others for failure.
+ */
+ipmi_ret_t ipmiUserSetUserPayloadAccess(const uint8_t chNum,
+ const uint8_t operation,
+ const uint8_t userId,
+ const PayloadAccess& payloadAccess);
+
+/** @brief provides user payload access data
+ *
+ * @param[in] chNum - channel number
+ * @param[in] userId - user id
+ * @param[out] payloadAccess - payload access data
+ *
+ * @return IPMI_CC_OK for success, others for failure.
+ */
+ipmi_ret_t ipmiUserGetUserPayloadAccess(const uint8_t chNum,
+ const uint8_t userId,
+ PayloadAccess& payloadAccess);
+
} // namespace ipmi
diff --git a/user_channel/user_mgmt.cpp b/user_channel/user_mgmt.cpp
index 9b40f6c..f877981 100644
--- a/user_channel/user_mgmt.cpp
+++ b/user_channel/user_mgmt.cpp
@@ -16,6 +16,7 @@
#include "user_mgmt.hpp"
#include "apphandler.hpp"
+#include "channel_layer.hpp"
#include <security/pam_appl.h>
#include <sys/stat.h>
@@ -833,6 +834,60 @@ ipmi_ret_t UserAccess::setUserEnabledState(const uint8_t userId,
return IPMI_CC_OK;
}
+ipmi_ret_t UserAccess::setUserPayloadAccess(const uint8_t chNum,
+ const uint8_t operation,
+ const uint8_t userId,
+ const PayloadAccess& payloadAccess)
+{
+ constexpr uint8_t enable = 0x0;
+ constexpr uint8_t disable = 0x1;
+
+ if (!isValidChannel(chNum))
+ {
+ return IPMI_CC_INVALID_FIELD_REQUEST;
+ }
+ if (!isValidUserId(userId))
+ {
+ return IPMI_CC_PARM_OUT_OF_RANGE;
+ }
+ if (operation != enable && operation != disable)
+ {
+ return IPMI_CC_INVALID_FIELD_REQUEST;
+ }
+ // Check operation & payloadAccess if required.
+ boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
+ userLock{*userMutex};
+ UserInfo* userInfo = getUserInfo(userId);
+
+ if (operation == enable)
+ {
+ userInfo->payloadAccess[chNum].stdPayloadEnables1 |=
+ payloadAccess.stdPayloadEnables1;
+
+ userInfo->payloadAccess[chNum].oemPayloadEnables1 |=
+ payloadAccess.oemPayloadEnables1;
+ }
+ else
+ {
+ userInfo->payloadAccess[chNum].stdPayloadEnables1 &=
+ ~(payloadAccess.stdPayloadEnables1);
+
+ userInfo->payloadAccess[chNum].oemPayloadEnables1 &=
+ ~(payloadAccess.oemPayloadEnables1);
+ }
+
+ try
+ {
+ writeUserData();
+ }
+ catch (const std::exception& e)
+ {
+ log<level::ERR>("Write user data failed");
+ return IPMI_CC_UNSPECIFIED_ERROR;
+ }
+ return IPMI_CC_OK;
+}
+
ipmi_ret_t UserAccess::setUserPrivilegeAccess(const uint8_t userId,
const uint8_t chNum,
const UserPrivAccess& privAccess,
@@ -1040,6 +1095,98 @@ static constexpr const char* jsonAccCallbk = "access_callback";
static constexpr const char* jsonUserEnabled = "user_enabled";
static constexpr const char* jsonUserInSys = "user_in_system";
static constexpr const char* jsonFixedUser = "fixed_user_name";
+static constexpr const char* payloadEnabledStr = "payload_enabled";
+static constexpr const char* stdPayloadStr = "std_payload";
+static constexpr const char* oemPayloadStr = "OEM_payload";
+
+/** @brief to construct a JSON object from the given payload access details.
+ *
+ * @param[in] stdPayload - stdPayloadEnables1 in a 2D-array. (input)
+ * @param[in] oemPayload - oemPayloadEnables1 in a 2D-array. (input)
+ *
+ * @details Sample output JSON object format :
+ * "payload_enabled":{
+ * "OEM_payload0":[false,...<repeat 'ipmiMaxChannels - 1' times>],
+ * "OEM_payload1":[false,...<repeat 'ipmiMaxChannels - 1' times>],
+ * "OEM_payload2":[false,...<repeat 'ipmiMaxChannels - 1' times>],
+ * "OEM_payload3":[false,...<repeat 'ipmiMaxChannels - 1' times>],
+ * "OEM_payload4":[false,...<repeat 'ipmiMaxChannels - 1' times>],
+ * "OEM_payload5":[false,...<repeat 'ipmiMaxChannels - 1' times>],
+ * "OEM_payload6":[false,...<repeat 'ipmiMaxChannels - 1' times>],
+ * "OEM_payload7":[false,...<repeat 'ipmiMaxChannels - 1' times>],
+ * "std_payload0":[false,...<repeat 'ipmiMaxChannels - 1' times>],
+ * "std_payload1":[false,...<repeat 'ipmiMaxChannels - 1' times>],
+ * "std_payload2":[false,...<repeat 'ipmiMaxChannels - 1' times>],
+ * "std_payload3":[false,...<repeat 'ipmiMaxChannels - 1' times>],
+ * "std_payload4":[false,...<repeat 'ipmiMaxChannels - 1' times>],
+ * "std_payload5":[false,...<repeat 'ipmiMaxChannels - 1' times>],
+ * "std_payload6":[false,...<repeat 'ipmiMaxChannels - 1' times>],
+ * "std_payload7":[false,...<repeat 'ipmiMaxChannels - 1' times>],
+ * }
+ */
+static const Json constructJsonPayloadEnables(
+ const std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>&
+ stdPayload,
+ const std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>&
+ oemPayload)
+{
+ Json jsonPayloadEnabled;
+
+ for (auto payloadNum = 0; payloadNum < payloadsPerByte; payloadNum++)
+ {
+ std::ostringstream stdPayloadStream;
+ std::ostringstream oemPayloadStream;
+
+ stdPayloadStream << stdPayloadStr << payloadNum;
+ oemPayloadStream << oemPayloadStr << payloadNum;
+
+ jsonPayloadEnabled.push_back(Json::object_t::value_type(
+ stdPayloadStream.str(), stdPayload[payloadNum]));
+
+ jsonPayloadEnabled.push_back(Json::object_t::value_type(
+ oemPayloadStream.str(), oemPayload[payloadNum]));
+ }
+ return jsonPayloadEnabled;
+}
+
+void UserAccess::readPayloadAccessFromUserInfo(
+ const UserInfo& userInfo,
+ std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>& stdPayload,
+ std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>& oemPayload)
+{
+ for (auto payloadNum = 0; payloadNum < payloadsPerByte; payloadNum++)
+ {
+ for (auto chIndex = 0; chIndex < ipmiMaxChannels; chIndex++)
+ {
+ stdPayload[payloadNum][chIndex] =
+ userInfo.payloadAccess[chIndex].stdPayloadEnables1[payloadNum];
+
+ oemPayload[payloadNum][chIndex] =
+ userInfo.payloadAccess[chIndex].oemPayloadEnables1[payloadNum];
+ }
+ }
+}
+
+void UserAccess::updatePayloadAccessInUserInfo(
+ const std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>&
+ stdPayload,
+ const std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>&
+ oemPayload,
+ UserInfo& userInfo)
+{
+ for (size_t chIndex = 0; chIndex < ipmiMaxChannels; ++chIndex)
+ {
+ // Ensure that reserved/unsupported payloads are marked to zero.
+ userInfo.payloadAccess[chIndex].stdPayloadEnables1.reset();
+ userInfo.payloadAccess[chIndex].oemPayloadEnables1.reset();
+ userInfo.payloadAccess[chIndex].stdPayloadEnables2Reserved.reset();
+ userInfo.payloadAccess[chIndex].oemPayloadEnables2Reserved.reset();
+ // Update SOL status as it is the only supported payload currently.
+ userInfo.payloadAccess[chIndex]
+ .stdPayloadEnables1[static_cast<uint8_t>(ipmi::PayloadType::SOL)] =
+ stdPayload[static_cast<uint8_t>(ipmi::PayloadType::SOL)][chIndex];
+ }
+}
void UserAccess::readUserData()
{
@@ -1063,6 +1210,15 @@ void UserAccess::readUserData()
throw std::runtime_error(
"Corrupted IPMI user data file - invalid user count");
}
+
+ // Construct a JSON object with default payload access values.
+ std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte> stdPayload =
+ {};
+ std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte> oemPayload =
+ {};
+ static const Json jsonPayloadEnabledDefault =
+ constructJsonPayloadEnables(stdPayload, oemPayload);
+
// user index 0 is reserved, starts with 1
for (size_t usrIndex = 1; usrIndex <= ipmiMaxUsers; ++usrIndex)
{
@@ -1086,6 +1242,36 @@ void UserAccess::readUserData()
userInfo[jsonLinkAuthEnabled].get<std::vector<bool>>();
std::vector<bool> accessCallback =
userInfo[jsonAccCallbk].get<std::vector<bool>>();
+
+ // Payload Enables Processing.
+ auto jsonPayloadEnabled =
+ userInfo.value<Json>(payloadEnabledStr, jsonPayloadEnabledDefault);
+
+ for (auto payloadNum = 0; payloadNum < payloadsPerByte; payloadNum++)
+ {
+ std::ostringstream stdPayloadStream;
+ std::ostringstream oemPayloadStream;
+
+ stdPayloadStream << stdPayloadStr << payloadNum;
+ oemPayloadStream << oemPayloadStr << payloadNum;
+
+ stdPayload[payloadNum] =
+ jsonPayloadEnabled[stdPayloadStream.str()]
+ .get<std::array<bool, ipmiMaxChannels>>();
+ oemPayload[payloadNum] =
+ jsonPayloadEnabled[oemPayloadStream.str()]
+ .get<std::array<bool, ipmiMaxChannels>>();
+
+ if (stdPayload[payloadNum].size() != ipmiMaxChannels ||
+ oemPayload[payloadNum].size() != ipmiMaxChannels)
+ {
+ log<level::ERR>("Error in reading IPMI user data file - "
+ "payload properties corrupted");
+ throw std::runtime_error(
+ "Corrupted IPMI user data file - payload properties");
+ }
+ }
+
if (privilege.size() != ipmiMaxChannels ||
ipmiEnabled.size() != ipmiMaxChannels ||
linkAuthEnabled.size() != ipmiMaxChannels ||
@@ -1108,6 +1294,8 @@ void UserAccess::readUserData()
usersTbl.user[usrIndex].userPrivAccess[chIndex].accessCallback =
accessCallback[chIndex];
}
+ updatePayloadAccessInUserInfo(stdPayload, oemPayload,
+ usersTbl.user[usrIndex]);
usersTbl.user[usrIndex].userEnabled =
userInfo[jsonUserEnabled].get<bool>();
usersTbl.user[usrIndex].userInSystem =
@@ -1140,6 +1328,12 @@ void UserAccess::writeUserData()
std::vector<bool> ipmiEnabled(ipmiMaxChannels);
std::vector<bool> linkAuthEnabled(ipmiMaxChannels);
std::vector<bool> accessCallback(ipmiMaxChannels);
+
+ std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>
+ stdPayload;
+ std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>
+ oemPayload;
+
for (size_t chIndex = 0; chIndex < ipmiMaxChannels; chIndex++)
{
privilege[chIndex] =
@@ -1159,6 +1353,13 @@ void UserAccess::writeUserData()
jsonUserInfo[jsonUserEnabled] = usersTbl.user[usrIndex].userEnabled;
jsonUserInfo[jsonUserInSys] = usersTbl.user[usrIndex].userInSystem;
jsonUserInfo[jsonFixedUser] = usersTbl.user[usrIndex].fixedUserName;
+
+ readPayloadAccessFromUserInfo(usersTbl.user[usrIndex], stdPayload,
+ oemPayload);
+ Json jsonPayloadEnabledInfo =
+ constructJsonPayloadEnables(stdPayload, oemPayload);
+ jsonUserInfo[payloadEnabledStr] = jsonPayloadEnabledInfo;
+
jsonUsersTbl.push_back(jsonUserInfo);
}
diff --git a/user_channel/user_mgmt.hpp b/user_channel/user_mgmt.hpp
index 8b650c8..773b18d 100644
--- a/user_channel/user_mgmt.hpp
+++ b/user_channel/user_mgmt.hpp
@@ -75,6 +75,7 @@ struct UserInfo
bool userEnabled;
bool userInSystem;
bool fixedUserName;
+ PayloadAccess payloadAccess[ipmiMaxChannels];
};
/** @struct UsersTbl
@@ -252,6 +253,56 @@ class UserAccess
const UserPrivAccess& privAccess,
const bool& otherPrivUpdates);
+ /** @brief to get user payload access details from userInfo entry.
+ *
+ * @param[in] userInfo - userInfo entry in usersTbl.
+ * @param[out] stdPayload - stdPayloadEnables1 in a 2D-array.
+ * @param[out] oemPayload - oemPayloadEnables1 in a 2D-array.
+ *
+ * @details Update the given 2D-arrays using the payload access details
+ * available in the given userInfo entry (from usersTbl).
+ * This 2D-array will be mapped to a JSON object (which will be written to
+ * a JSON file subsequently).
+ */
+ void readPayloadAccessFromUserInfo(
+ const UserInfo& userInfo,
+ std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>&
+ stdPayload,
+ std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>&
+ oemPayload);
+
+ /** @brief to update user payload access details in userInfo entry.
+ *
+ * @param[in] stdPayload - stdPayloadEnables1 in a 2D-array.
+ * @param[in] oemPayload - oemPayloadEnables1 in a 2D-array.
+ * @param[out] userInfo - userInfo entry in usersTbl.
+ *
+ * @details Update user payload access details of a given userInfo
+ * entry (in usersTbl) with the information provided in given 2D-arrays.
+ * This 2D-array was created out of a JSON object (which was created by
+ * parsing a JSON file).
+ */
+ void updatePayloadAccessInUserInfo(
+ const std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>&
+ stdPayload,
+ const std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>&
+ oemPayload,
+ UserInfo& userInfo);
+
+ /** @brief to set user payload access details
+ *
+ * @param[in] chNum - channel number
+ * @param[in] operation - Enable / Disable
+ * @param[in] userId - user id
+ * @param[in] payloadAccess - payload access
+ *
+ * @return IPMI_CC_OK for success, others for failure.
+ */
+ ipmi_ret_t setUserPayloadAccess(const uint8_t chNum,
+ const uint8_t operation,
+ const uint8_t userId,
+ const PayloadAccess& payloadAccess);
+
/** @brief reads user management related data from configuration file
*
*/
diff --git a/user_channel/usercommands.cpp b/user_channel/usercommands.cpp
index 5bdbbd3..50fb52b 100644
--- a/user_channel/usercommands.cpp
+++ b/user_channel/usercommands.cpp
@@ -37,6 +37,8 @@ static constexpr uint8_t setPassword = 0x02;
static constexpr uint8_t testPassword = 0x03;
static constexpr uint8_t passwordKeySize20 = 1;
static constexpr uint8_t passwordKeySize16 = 0;
+static constexpr uint8_t enableOperation = 0x00;
+static constexpr uint8_t disableOperation = 0x01;
/** @struct SetUserNameReq
*
@@ -485,6 +487,188 @@ ipmi::RspType<uint8_t, // channel number
rmcp, rmcpp, reserved5, oemID, oemAuxillary);
}
+/** @brief implements the set user payload access command.
+ * @param ctx - IPMI context pointer (for channel)
+ * @param channel - channel number (4 bits)
+ * @param reserved1 - skip 4 bits
+ * @param userId - user id (6 bits)
+ * @param operation - access ENABLE /DISABLE. (2 bits)
+ * @param stdPayload0 - IPMI - reserved. (1 bit)
+ * @param stdPayload1 - SOL. (1 bit)
+ * @param stdPayload2 - (1 bit)
+ * @param stdPayload3 - (1 bit)
+ * @param stdPayload4 - (1 bit)
+ * @param stdPayload5 - (1 bit)
+ * @param stdPayload6 - (1 bit)
+ * @param stdPayload7 - (1 bit)
+ * @param stdPayloadEnables2Reserved - (8 bits)
+ * @param oemPayload0 - (1 bit)
+ * @param oemPayload1 - (1 bit)
+ * @param oemPayload2 - (1 bit)
+ * @param oemPayload3 - (1 bit)
+ * @param oemPayload4 - (1 bit)
+ * @param oemPayload5 - (1 bit)
+ * @param oemPayload6 - (1 bit)
+ * @param oemPayload7 - (1 bit)
+ * @param oemPayloadEnables2Reserved - (8 bits)
+ *
+ * @returns IPMI completion code
+ */
+ipmi::RspType<> ipmiSetUserPayloadAccess(
+ ipmi::Context::ptr ctx,
+
+ uint4_t channel, uint4_t reserved,
+
+ uint6_t userId, uint2_t operation,
+
+ bool stdPayload0ipmiReserved, bool stdPayload1SOL, bool stdPayload2,
+ bool stdPayload3, bool stdPayload4, bool stdPayload5, bool stdPayload6,
+ bool stdPayload7,
+
+ uint8_t stdPayloadEnables2Reserved,
+
+ bool oemPayload0, bool oemPayload1, bool oemPayload2, bool oemPayload3,
+ bool oemPayload4, bool oemPayload5, bool oemPayload6, bool oemPayload7,
+
+ uint8_t oemPayloadEnables2Reserved)
+{
+ // Validate the reserved args. Only SOL payload is supported as on date.
+ if (reserved || stdPayload0ipmiReserved || stdPayload2 || stdPayload3 ||
+ stdPayload4 || stdPayload5 || stdPayload6 || stdPayload7 ||
+ oemPayload0 || oemPayload1 || oemPayload2 || oemPayload3 ||
+ oemPayload4 || oemPayload5 || oemPayload6 || oemPayload7 ||
+ stdPayloadEnables2Reserved || oemPayloadEnables2Reserved)
+ {
+ return ipmi::responseInvalidFieldRequest();
+ }
+
+ auto chNum =
+ convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel);
+ if ((operation != enableOperation && operation != disableOperation) ||
+ (!isValidChannel(chNum)) ||
+ (getChannelSessionSupport(chNum) == EChannelSessSupported::none))
+ {
+ return ipmi::responseInvalidFieldRequest();
+ }
+
+ if (!ipmiUserIsValidUserId(static_cast<uint8_t>(userId)))
+ {
+ return ipmi::responseParmOutOfRange();
+ }
+
+ PayloadAccess payloadAccess = {0};
+ payloadAccess.stdPayloadEnables1[1] = stdPayload1SOL;
+
+ return ipmi::response(ipmiUserSetUserPayloadAccess(
+ chNum, static_cast<uint8_t>(operation), static_cast<uint8_t>(userId),
+ payloadAccess));
+}
+
+/** @brief implements the get user payload access command
+ * This command returns information about user payload enable settings
+ * that were set using the 'Set User Payload Access' Command.
+ *
+ * @param ctx - IPMI context pointer (for channel)
+ * @param channel - channel number
+ * @param reserved1 - skip 4 bits
+ * @param userId - user id
+ * @param reserved2 - skip 2 bits
+ *
+ * @returns IPMI completion code plus response data
+ * - stdPayload0ipmiReserved - IPMI payload (reserved).
+ * - stdPayload1SOL - SOL payload
+ * - stdPayload2
+ * - stdPayload3
+ * - stdPayload4
+ * - stdPayload5
+ * - stdPayload6
+ * - stdPayload7
+
+ * - stdPayloadEnables2Reserved - Reserved.
+
+ * - oemPayload0
+ * - oemPayload1
+ * - oemPayload2
+ * - oemPayload3
+ * - oemPayload4
+ * - oemPayload5
+ * - oemPayload6
+ * - oemPayload7
+
+ * - oemPayloadEnables2Reserved - Reserved
+ */
+ipmi::RspType<bool, // stdPayload0ipmiReserved
+ bool, // stdPayload1SOL
+ bool, // stdPayload2
+ bool, // stdPayload3
+ bool, // stdPayload4
+ bool, // stdPayload5
+ bool, // stdPayload6
+ bool, // stdPayload7
+
+ uint8_t, // stdPayloadEnables2Reserved
+
+ bool, // oemPayload0
+ bool, // oemPayload1
+ bool, // oemPayload2
+ bool, // oemPayload3
+ bool, // oemPayload4
+ bool, // oemPayload5
+ bool, // oemPayload6
+ bool, // oemPayload7
+
+ uint8_t // oemPayloadEnables2Reserved
+ >
+ ipmiGetUserPayloadAccess(ipmi::Context::ptr ctx,
+
+ uint4_t channel, uint4_t reserved1,
+
+ uint6_t userId, uint2_t reserved2)
+{
+ uint8_t chNum =
+ convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel);
+ if (reserved1 != 0 || reserved2 != 0 || (!isValidChannel(chNum)) ||
+ (getChannelSessionSupport(chNum) == EChannelSessSupported::none))
+ {
+ return ipmi::responseInvalidFieldRequest();
+ }
+ if (!ipmiUserIsValidUserId(static_cast<uint8_t>(userId)))
+ {
+ return ipmi::responseParmOutOfRange();
+ }
+
+ ipmi::Cc retStatus;
+ PayloadAccess payloadAccess = {};
+ retStatus = ipmiUserGetUserPayloadAccess(
+ chNum, static_cast<uint8_t>(userId), payloadAccess);
+ if (retStatus != IPMI_CC_OK)
+ {
+ return ipmi::response(retStatus);
+ }
+ constexpr uint8_t res8bits = 0;
+ return ipmi::responseSuccess(payloadAccess.stdPayloadEnables1.test(0),
+ payloadAccess.stdPayloadEnables1.test(1),
+ payloadAccess.stdPayloadEnables1.test(2),
+ payloadAccess.stdPayloadEnables1.test(3),
+ payloadAccess.stdPayloadEnables1.test(4),
+ payloadAccess.stdPayloadEnables1.test(5),
+ payloadAccess.stdPayloadEnables1.test(6),
+ payloadAccess.stdPayloadEnables1.test(7),
+
+ res8bits,
+
+ payloadAccess.oemPayloadEnables1.test(0),
+ payloadAccess.oemPayloadEnables1.test(1),
+ payloadAccess.oemPayloadEnables1.test(2),
+ payloadAccess.oemPayloadEnables1.test(3),
+ payloadAccess.oemPayloadEnables1.test(4),
+ payloadAccess.oemPayloadEnables1.test(5),
+ payloadAccess.oemPayloadEnables1.test(6),
+ payloadAccess.oemPayloadEnables1.test(7),
+
+ res8bits);
+}
+
void registerUserIpmiFunctions() __attribute__((constructor));
void registerUserIpmiFunctions()
{
@@ -510,6 +694,15 @@ void registerUserIpmiFunctions()
ipmi::app::cmdGetChannelAuthCapabilities,
ipmi::Privilege::Callback,
ipmiGetChannelAuthenticationCapabilities);
+
+ ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
+ ipmi::app::cmdSetUserPayloadAccess,
+ ipmi::Privilege::Admin, ipmiSetUserPayloadAccess);
+
+ ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
+ ipmi::app::cmdGetUserPayloadAccess,
+ ipmi::Privilege::Operator, ipmiGetUserPayloadAccess);
+
return;
}
} // namespace ipmi
OpenPOWER on IntegriCloud