diff options
Diffstat (limited to 'user_channel/usercommands.cpp')
-rw-r--r-- | user_channel/usercommands.cpp | 207 |
1 files changed, 200 insertions, 7 deletions
diff --git a/user_channel/usercommands.cpp b/user_channel/usercommands.cpp index 489eeaf..3396d2d 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 * @@ -130,7 +132,7 @@ ipmi::RspType<> ipmiSetUserAccess(ipmi::Context::ptr ctx, uint4_t channel, { uint8_t sessLimit = sessionLimit.value_or(0); uint8_t chNum = - convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx); + convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel); if (reserved1 != 0 || reserved2 != 0 || sessLimit != 0 || (!isValidChannel(chNum)) || (!ipmiUserIsValidPrivilege(static_cast<uint8_t>(privilege))) || @@ -199,7 +201,7 @@ ipmi::RspType<uint6_t, // max channel users uint6_t userId, uint2_t reserved2) { uint8_t chNum = - convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx); + convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel); if (reserved1 != 0 || reserved2 != 0 || (!isValidChannel(chNum)) || (EChannelSessSupported::none == getChannelSessionSupport(chNum))) { @@ -307,7 +309,7 @@ ipmi_ret_t ipmiGetUserName(ipmi_netfn_t netfn, ipmi_cmd_t cmd, if (ipmiUserGetUserName(req->userId, userName) != IPMI_CC_OK) { // Invalid User ID log<level::DEBUG>("User Name not found", - entry("USER-ID:%d", (uint8_t)req->userId)); + entry("USER-ID=%d", (uint8_t)req->userId)); return IPMI_CC_PARM_OUT_OF_RANGE; } GetUserNameResp* resp = static_cast<GetUserNameResp*>(response); @@ -366,7 +368,7 @@ ipmi_ret_t ipmiSetUserPassword(ipmi_netfn_t netfn, ipmi_cmd_t cmd, if (ipmiUserGetUserName(req->userId, userName) != IPMI_CC_OK) { log<level::DEBUG>("User Name not found", - entry("USER-ID:%d", (uint8_t)req->userId)); + entry("USER-ID=%d", (uint8_t)req->userId)); return IPMI_CC_PARM_OUT_OF_RANGE; } if (req->operation == setPassword) @@ -391,7 +393,7 @@ ipmi_ret_t ipmiSetUserPassword(ipmi_netfn_t netfn, ipmi_cmd_t cmd, if (password != testPassword) { log<level::DEBUG>("Test password failed", - entry("USER-ID:%d", (uint8_t)req->userId)); + entry("USER-ID=%d", (uint8_t)req->userId)); return static_cast<ipmi_ret_t>( IPMISetPasswordReturnCodes::ipmiCCPasswdFailMismatch); } @@ -450,7 +452,7 @@ ipmi::RspType<uint8_t, // channel number { uint8_t channel = - convertCurrentChannelNum(static_cast<uint8_t>(chNum), ctx); + convertCurrentChannelNum(static_cast<uint8_t>(chNum), ctx->channel); if (reserved1 || reserved2 || !isValidChannel(channel) || !isValidPrivLimit(static_cast<uint8_t>(privLevel)) || @@ -485,10 +487,192 @@ 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() { - ipmiUserInit(); + post_work([]() { ipmiUserInit(); }); ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp, ipmi::app::cmdSetUserAccessCommand, ipmi::Privilege::Admin, ipmiSetUserAccess); @@ -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 |