RMCP+ login support with privilege
Implementation of RMCP login support with appropriate
privilege level.
Unit Test:
1. Verified that user is able to login without any issues
2. Privilege of the user is minimum of requested, user & channel
3. Unable to set higher privilege using Set session commands
Change-Id: I5e9ef21dfc1f1b50aa815562a3a65d90c434877c
Signed-off-by: Richard Marian Thomaiyar <richard.marian.thomaiyar@linux.intel.com>
diff --git a/command/session_cmds.cpp b/command/session_cmds.cpp
index d363c1e..5c74d28 100644
--- a/command/session_cmds.cpp
+++ b/command/session_cmds.cpp
@@ -6,6 +6,8 @@
#include <host-ipmid/ipmid-api.h>
#include <iostream>
+#include <user_channel/channel_layer.hpp>
+#include <user_channel/user_layer.hpp>
namespace command
{
@@ -29,18 +31,54 @@
if (reqPrivilegeLevel == 0) // Just return present privilege level
{
response->newPrivLevel = static_cast<uint8_t>(session->curPrivLevel);
+ return outPayload;
}
- else if (reqPrivilegeLevel <= static_cast<uint8_t>(session->maxPrivLevel))
+ if (reqPrivilegeLevel >
+ (session->reqMaxPrivLevel & session::reqMaxPrivMask))
{
- session->curPrivLevel =
- static_cast<session::Privilege>(reqPrivilegeLevel);
- response->newPrivLevel = reqPrivilegeLevel;
+ // Requested level exceeds Channel and/or User Privilege Limit
+ response->completionCode = IPMI_CC_EXCEEDS_USER_PRIV;
+ return outPayload;
+ }
+
+ uint8_t userId = ipmi::ipmiUserGetUserId(session->userName);
+ if (userId == ipmi::invalidUserId)
+ {
+ response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
+ return outPayload;
+ }
+ ipmi::PrivAccess userAccess{};
+ ipmi::ChannelAccess chAccess{};
+ if ((ipmi::ipmiUserGetPrivilegeAccess(userId, session->chNum, userAccess) !=
+ IPMI_CC_OK) ||
+ (ipmi::getChannelAccessData(session->chNum, chAccess) != IPMI_CC_OK))
+ {
+ response->completionCode = IPMI_CC_INVALID_PRIV_LEVEL;
+ return outPayload;
+ }
+ // Use the minimum privilege of user or channel
+ uint8_t minPriv = 0;
+ if (chAccess.privLimit < userAccess.privilege)
+ {
+ minPriv = chAccess.privLimit;
}
else
{
+ minPriv = userAccess.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<session::Privilege>(reqPrivilegeLevel);
+ response->newPrivLevel = reqPrivilegeLevel;
+ }
+
return outPayload;
}