Cache the user & channel acces in session

Instead of querying the user & channel access for every time
cache the same during session creation, and use it for
enforcements.

Tested-by:
Verified that RMCP+ session establishment works as expected
including INSUFFICIENT_PRIVILEGE error.

Change-Id: Ib5a05bd07cc9aabf2625a18090fd905d93489b24
Signed-off-by: Richard Marian Thomaiyar <richard.marian.thomaiyar@linux.intel.com>
diff --git a/command/rakp12.cpp b/command/rakp12.cpp
index a8d5171..562a450 100644
--- a/command/rakp12.cpp
+++ b/command/rakp12.cpp
@@ -11,8 +11,6 @@
 #include <cstring>
 #include <iomanip>
 #include <phosphor-logging/log.hpp>
-#include <user_channel/channel_layer.hpp>
-#include <user_channel/user_layer.hpp>
 
 using namespace phosphor::logging;
 
@@ -174,20 +172,20 @@
             static_cast<uint8_t>(RAKP_ReturnCode::UNAUTH_NAME);
         return outPayload;
     }
-    ipmi::PrivAccess userAccess{};
-    ipmi::ChannelAccess chAccess{};
     // TODO Replace with proper calls.
     uint8_t chNum = static_cast<uint8_t>(ipmi::EChannelID::chanLan1);
     // Get channel based access information
-    if ((ipmi::ipmiUserGetPrivilegeAccess(userId, chNum, userAccess) !=
-         IPMI_CC_OK) ||
-        (ipmi::getChannelAccessData(chNum, chAccess) != IPMI_CC_OK))
+    if ((ipmi::ipmiUserGetPrivilegeAccess(
+             userId, chNum, session->sessionUserPrivAccess) != IPMI_CC_OK) ||
+        (ipmi::getChannelAccessData(chNum, session->sessionChannelAccess) !=
+         IPMI_CC_OK))
     {
         response->rmcpStatusCode =
             static_cast<uint8_t>(RAKP_ReturnCode::INACTIVE_ROLE);
         return outPayload;
     }
-    if (userAccess.privilege > static_cast<uint8_t>(session::Privilege::OEM))
+    if (session->sessionUserPrivAccess.privilege >
+        static_cast<uint8_t>(session::Privilege::OEM))
     {
         response->rmcpStatusCode =
             static_cast<uint8_t>(RAKP_ReturnCode::INACTIVE_ROLE);
@@ -197,13 +195,14 @@
     // minimum privilege of Channel / User / session::privilege::USER/CALLBACK /
     // has to be used as session current privilege level
     uint8_t minPriv = 0;
-    if (chAccess.privLimit < userAccess.privilege)
+    if (session->sessionChannelAccess.privLimit <
+        session->sessionUserPrivAccess.privilege)
     {
-        minPriv = chAccess.privLimit;
+        minPriv = session->sessionChannelAccess.privLimit;
     }
     else
     {
-        minPriv = userAccess.privilege;
+        minPriv = session->sessionUserPrivAccess.privilege;
     }
     if (session->curPrivLevel > static_cast<session::Privilege>(minPriv))
     {
@@ -214,7 +213,7 @@
     if (((request->req_max_privilege_level & userNameOnlyLookupMask) ==
          userNamePrivLookup) &&
         ((request->req_max_privilege_level & session::reqMaxPrivMask) !=
-         userAccess.privilege))
+         session->sessionUserPrivAccess.privilege))
     {
         log<level::INFO>(
             "Username/Privilege lookup failed for requested privilege");
diff --git a/command/session_cmds.cpp b/command/session_cmds.cpp
index 3b9fa0e..8606ce5 100644
--- a/command/session_cmds.cpp
+++ b/command/session_cmds.cpp
@@ -5,9 +5,6 @@
 
 #include <ipmid/api.h>
 
-#include <user_channel/channel_layer.hpp>
-#include <user_channel/user_layer.hpp>
-
 namespace command
 {
 
@@ -39,31 +36,16 @@
         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)
+    if (session->sessionChannelAccess.privLimit <
+        session->sessionUserPrivAccess.privilege)
     {
-        minPriv = chAccess.privLimit;
+        minPriv = session->sessionChannelAccess.privLimit;
     }
     else
     {
-        minPriv = userAccess.privilege;
+        minPriv = session->sessionUserPrivAccess.privilege;
     }
     if (reqPrivilegeLevel > minPriv)
     {
diff --git a/session.hpp b/session.hpp
index bc48971..7b02221 100644
--- a/session.hpp
+++ b/session.hpp
@@ -12,6 +12,8 @@
 #include <list>
 #include <memory>
 #include <string>
+#include <user_channel/channel_layer.hpp>
+#include <user_channel/user_layer.hpp>
 #include <vector>
 
 namespace session
@@ -272,6 +274,12 @@
      */
     Privilege reqMaxPrivLevel;
 
+    /**
+     * @brief session's user & channel access details
+     */
+    ipmi::PrivAccess sessionUserPrivAccess{};
+    ipmi::ChannelAccess sessionChannelAccess{};
+
     SequenceNumbers sequenceNums;  // Session Sequence Numbers
     State state = State::INACTIVE; // Session State
     std::string userName{};        // User Name