#include "session_cmds.hpp" #include "endian.hpp" #include "main.hpp" #include namespace command { std::vector setSessionPrivilegeLevel(const std::vector& inPayload, const message::Handler& handler) { std::vector outPayload(sizeof(SetSessionPrivLevelResp)); auto request = reinterpret_cast(inPayload.data()); auto response = reinterpret_cast(outPayload.data()); response->completionCode = IPMI_CC_OK; uint8_t reqPrivilegeLevel = request->reqPrivLevel; auto session = std::get(singletonPool) .getSession(handler.sessionID); if (reqPrivilegeLevel == 0) // Just return present privilege level { response->newPrivLevel = static_cast(session->curPrivLevel); return outPayload; } if (reqPrivilegeLevel > (static_cast(session->reqMaxPrivLevel) & session::reqMaxPrivMask)) { // Requested level exceeds Channel and/or User Privilege Limit response->completionCode = IPMI_CC_EXCEEDS_USER_PRIV; return outPayload; } // Use the minimum privilege of user or channel uint8_t minPriv = 0; if (session->sessionChannelAccess.privLimit < session->sessionUserPrivAccess.privilege) { minPriv = session->sessionChannelAccess.privLimit; } else { minPriv = session->sessionUserPrivAccess.privilege; } if (reqPrivilegeLevel > minPriv) { // Requested level exceeds Channel and/or User Privilege Limit response->completionCode = IPMI_CC_EXCEEDS_USER_PRIV; } else { // update current privilege of the session. session->curPrivLevel = static_cast(reqPrivilegeLevel); response->newPrivLevel = reqPrivilegeLevel; } return outPayload; } std::vector closeSession(const std::vector& inPayload, const message::Handler& handler) { std::vector outPayload(sizeof(CloseSessionResponse)); auto request = reinterpret_cast(inPayload.data()); auto response = reinterpret_cast(outPayload.data()); response->completionCode = IPMI_CC_OK; auto bmcSessionID = endian::from_ipmi(request->sessionID); // Session 0 is needed to handle session setup, so session zero is never // closed if (bmcSessionID == session::SESSION_ZERO) { response->completionCode = IPMI_CC_INVALID_SESSIONID; } else { auto status = std::get(singletonPool) .stopSession(bmcSessionID); if (!status) { response->completionCode = IPMI_CC_INVALID_SESSIONID; } } return outPayload; } } // namespace command