From 5b2535f89023d0ea220ccc24200a9b51c142c08d Mon Sep 17 00:00:00 2001 From: Richard Marian Thomaiyar Date: Thu, 4 Apr 2019 22:01:36 +0530 Subject: Rewrite set & get user access cmd to new provider Rewritten Get & Set user access command to new provider API. Note: This is ready for channel number 0xE handling. Tested: 1. Verified ipmitool user list command in both host & netipmid 2. verified ipmitool raw get & set user access command and cross verified it with negative cases Change-Id: Idbe19bc5a73decb9868663bd12683b826956fe4f Signed-off-by: Richard Marian Thomaiyar --- user_channel/usercommands.cpp | 264 +++++++++++++++++++----------------------- 1 file changed, 118 insertions(+), 146 deletions(-) diff --git a/user_channel/usercommands.cpp b/user_channel/usercommands.cpp index 1c94182..489eeaf 100644 --- a/user_channel/usercommands.cpp +++ b/user_channel/usercommands.cpp @@ -38,86 +38,6 @@ static constexpr uint8_t testPassword = 0x03; static constexpr uint8_t passwordKeySize20 = 1; static constexpr uint8_t passwordKeySize16 = 0; -/** @struct SetUserAccessReq - * - * Structure for set user access request command (refer spec sec 22.26) - */ -struct SetUserAccessReq -{ -#if BYTE_ORDER == LITTLE_ENDIAN - uint8_t chNum : 4; - uint8_t ipmiEnabled : 1; - uint8_t linkAuthEnabled : 1; - uint8_t accessCallback : 1; - uint8_t bitsUpdate : 1; - uint8_t userId : 6; - uint8_t reserved1 : 2; - uint8_t privilege : 4; - uint8_t reserved2 : 4; - uint8_t sessLimit : 4; // optional byte 4 - uint8_t reserved3 : 4; -#endif -#if BYTE_ORDER == BIG_ENDIAN - uint8_t bitsUpdate : 1; - uint8_t accessCallback : 1; - uint8_t linkAuthEnabled : 1; - uint8_t ipmiEnabled : 1; - uint8_t chNum : 4; - uint8_t reserved1 : 2; - uint8_t userId : 6; - uint8_t reserved2 : 4; - uint8_t privilege : 4; - uint8_t reserved3 : 4; - uint8_t sessLimit : 4; // optional byte 4 -#endif - -} __attribute__((packed)); - -/** @struct GetUserAccessReq - * - * Structure for get user access request command (refer spec sec 22.27) - */ -struct GetUserAccessReq -{ -#if BYTE_ORDER == LITTLE_ENDIAN - uint8_t chNum : 4; - uint8_t reserved1 : 4; - uint8_t userId : 6; - uint8_t reserved2 : 2; -#endif -#if BYTE_ORDER == BIG_ENDIAN - uint8_t reserved1 : 4; - uint8_t chNum : 4; - uint8_t reserved2 : 2; - uint8_t userId : 6; -#endif -} __attribute__((packed)); - -/** @struct GetUserAccessResp - * - * Structure for get user access response command (refer spec sec 22.27) - */ -struct GetUserAccessResp -{ -#if BYTE_ORDER == LITTLE_ENDIAN - uint8_t maxChUsers : 6; - uint8_t reserved1 : 2; - uint8_t enabledUsers : 6; - uint8_t enabledStatus : 2; - uint8_t fixedUsers : 6; - uint8_t reserved2 : 2; -#endif -#if BYTE_ORDER == BIG_ENDIAN - uint8_t reserved1 : 2; - uint8_t maxChUsers : 6; - uint8_t enabledStatus : 2; - uint8_t enabledUsers : 6; - uint8_t reserved2 : 2; - uint8_t fixedUsers : 6; -#endif - PrivAccess privAccess; -} __attribute__((packed)); - /** @struct SetUserNameReq * * Structure for set user name request command (refer spec sec 22.28) @@ -183,103 +103,153 @@ struct SetUserPasswordReq uint8_t userPassword[maxIpmi20PasswordSize]; } __attribute__((packed)); -ipmi_ret_t ipmiSetUserAccess(ipmi_netfn_t netfn, ipmi_cmd_t cmd, - ipmi_request_t request, ipmi_response_t response, - ipmi_data_len_t dataLen, ipmi_context_t context) -{ - const SetUserAccessReq* req = static_cast(request); - size_t reqLength = *dataLen; - *dataLen = 0; +/** @brief implements the set user access command + * @param ctx - IPMI context pointer (for channel) + * @param channel - channel number + * @param ipmiEnabled - indicates ipmi messaging state + * @param linkAuthEnabled - indicates link authentication state + * @param accessCallback - indicates callback state + * @param bitsUpdate - indicates update request + * @param userId - user id + * @param reserved1 - skip 2 bits + * @param privilege - user privilege + * @param reserved2 - skip 4 bits + * @param sessionLimit - optional - unused for now + * + * @returns ipmi completion code + */ +ipmi::RspType<> ipmiSetUserAccess(ipmi::Context::ptr ctx, uint4_t channel, + uint1_t ipmiEnabled, uint1_t linkAuthEnabled, + uint1_t accessCallback, uint1_t bitsUpdate, - if (!(reqLength == sizeof(*req) || - (reqLength == (sizeof(*req) - sizeof(uint8_t) /* skip optional*/)))) - { - log("Set user access - Invalid Length"); - return IPMI_CC_REQ_DATA_LEN_INVALID; - } - uint8_t chNum = convertCurrentChannelNum(req->chNum); - if (req->reserved1 != 0 || req->reserved2 != 0 || req->reserved3 != 0 || - req->sessLimit != 0 || (!isValidChannel(chNum)) || - (!ipmiUserIsValidPrivilege(req->privilege)) || + uint6_t userId, uint2_t reserved1, + + uint4_t privilege, uint4_t reserved2, + + std::optional sessionLimit) +{ + uint8_t sessLimit = sessionLimit.value_or(0); + uint8_t chNum = + convertCurrentChannelNum(static_cast(channel), ctx); + if (reserved1 != 0 || reserved2 != 0 || sessLimit != 0 || + (!isValidChannel(chNum)) || + (!ipmiUserIsValidPrivilege(static_cast(privilege))) || (EChannelSessSupported::none == getChannelSessionSupport(chNum))) { log("Set user access - Invalid field in request"); - return IPMI_CC_INVALID_FIELD_REQUEST; + return ipmi::responseInvalidFieldRequest(); } - if (!ipmiUserIsValidUserId(req->userId)) + if (!ipmiUserIsValidUserId(static_cast(userId))) { log("Set user access - Parameter out of range"); - return IPMI_CC_PARM_OUT_OF_RANGE; + return ipmi::responseParmOutOfRange(); } PrivAccess privAccess = {0}; - if (req->bitsUpdate) + if (bitsUpdate) { - privAccess.ipmiEnabled = req->ipmiEnabled; - privAccess.linkAuthEnabled = req->linkAuthEnabled; - privAccess.accessCallback = req->accessCallback; + privAccess.ipmiEnabled = static_cast(ipmiEnabled); + privAccess.linkAuthEnabled = static_cast(linkAuthEnabled); + privAccess.accessCallback = static_cast(accessCallback); } - privAccess.privilege = req->privilege; - return ipmiUserSetPrivilegeAccess(req->userId, chNum, privAccess, - req->bitsUpdate); + privAccess.privilege = static_cast(privilege); + return ipmi::response( + ipmiUserSetPrivilegeAccess(static_cast(userId), chNum, + privAccess, static_cast(bitsUpdate))); } -ipmi_ret_t ipmiGetUserAccess(ipmi_netfn_t netfn, ipmi_cmd_t cmd, - ipmi_request_t request, ipmi_response_t response, - ipmi_data_len_t dataLen, ipmi_context_t context) -{ - const GetUserAccessReq* req = static_cast(request); - size_t reqLength = *dataLen; - ipmi_ret_t retStatus = IPMI_CC_OK; +/** @brief implements the set user 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 + * - maxChUsers - max channel users + * - reserved1 - skip 2 bits + * - enabledUsers - enabled users count + * - enabledStatus - enabled status + * - fixedUsers - fixed users count + * - reserved2 - skip 2 bits + * - privilege - user privilege + * - ipmiEnabled - ipmi messaging state + * - linkAuthEnabled - link authenticatin state + * - accessCallback - callback state + * - reserved - skip 1 bit + */ +ipmi::RspType("Get user access - Invalid Length"); - return IPMI_CC_REQ_DATA_LEN_INVALID; - } - uint8_t chNum = convertCurrentChannelNum(req->chNum); - if (req->reserved1 != 0 || req->reserved2 != 0 || - (!isValidChannel(chNum)) || + uint6_t, // fixed users count + uint2_t, // reserved2 + + uint4_t, // privilege + uint1_t, // ipmi messaging state + uint1_t, // link authentication state + uint1_t, // access callback state + uint1_t // reserved3 + > + ipmiGetUserAccess(ipmi::Context::ptr ctx, uint4_t channel, + uint4_t reserved1, + + uint6_t userId, uint2_t reserved2) +{ + uint8_t chNum = + convertCurrentChannelNum(static_cast(channel), ctx); + if (reserved1 != 0 || reserved2 != 0 || (!isValidChannel(chNum)) || (EChannelSessSupported::none == getChannelSessionSupport(chNum))) { log("Get user access - Invalid field in request"); - return IPMI_CC_INVALID_FIELD_REQUEST; + return ipmi::responseInvalidFieldRequest(); } - if (!ipmiUserIsValidUserId(req->userId)) + if (!ipmiUserIsValidUserId(static_cast(userId))) { log("Get user access - Parameter out of range"); - return IPMI_CC_PARM_OUT_OF_RANGE; + return ipmi::responseParmOutOfRange(); } uint8_t maxChUsers = 0, enabledUsers = 0, fixedUsers = 0; - bool enabledState = false; - GetUserAccessResp* resp = static_cast(response); - - std::fill(reinterpret_cast(resp), - reinterpret_cast(resp) + sizeof(*resp), 0); - + ipmi::Cc retStatus; retStatus = ipmiUserGetAllCounts(maxChUsers, enabledUsers, fixedUsers); if (retStatus != IPMI_CC_OK) { - return retStatus; + return ipmi::response(retStatus); } - resp->maxChUsers = maxChUsers; - resp->enabledUsers = enabledUsers; - resp->fixedUsers = fixedUsers; + bool enabledState = false; + retStatus = + ipmiUserCheckEnabled(static_cast(userId), enabledState); + if (retStatus != IPMI_CC_OK) + { + return ipmi::response(retStatus); + } - retStatus = ipmiUserCheckEnabled(req->userId, enabledState); + uint2_t enabledStatus = enabledState ? userIdEnabledViaSetPassword + : userIdDisabledViaSetPassword; + PrivAccess privAccess{}; + retStatus = ipmiUserGetPrivilegeAccess(static_cast(userId), chNum, + privAccess); if (retStatus != IPMI_CC_OK) { - return retStatus; + return ipmi::response(retStatus); } + constexpr uint2_t res2Bits = 0; + return ipmi::responseSuccess( + static_cast(maxChUsers), res2Bits, - resp->enabledStatus = enabledState ? userIdEnabledViaSetPassword - : userIdDisabledViaSetPassword; - *dataLen = sizeof(*resp); - return ipmiUserGetPrivilegeAccess(req->userId, chNum, resp->privAccess); + static_cast(enabledUsers), enabledStatus, + + static_cast(fixedUsers), res2Bits, + + static_cast(privAccess.privilege), + static_cast(privAccess.ipmiEnabled), + static_cast(privAccess.linkAuthEnabled), + static_cast(privAccess.accessCallback), + static_cast(privAccess.reserved)); } ipmi_ret_t ipmiSetUserName(ipmi_netfn_t netfn, ipmi_cmd_t cmd, @@ -519,11 +489,13 @@ void registerUserIpmiFunctions() __attribute__((constructor)); void registerUserIpmiFunctions() { ipmiUserInit(); - ipmi_register_callback(NETFUN_APP, IPMI_CMD_SET_USER_ACCESS, NULL, - ipmiSetUserAccess, PRIVILEGE_ADMIN); + ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp, + ipmi::app::cmdSetUserAccessCommand, + ipmi::Privilege::Admin, ipmiSetUserAccess); - ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_USER_ACCESS, NULL, - ipmiGetUserAccess, PRIVILEGE_OPERATOR); + ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp, + ipmi::app::cmdGetUserAccessCommand, + ipmi::Privilege::Operator, ipmiGetUserAccess); ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_USER_NAME, NULL, ipmiGetUserName, PRIVILEGE_OPERATOR); -- cgit v1.2.1