Add privilege check in activate payload

When a user's privilege is lower than sol privilege level, payload
activate and deactivate command will be executed failed with this user.
Refer to ipmi spec v2.0 Appendix G, The configuration parameters for a
given payload type determine the privilege level required to activate
and deactivate the payload.

Tested:
1. Check sol privilege level
```
~# ipmitool -I lanplus -H $ip -U $username -P $password sol activate
[SOL Session operational.  Use ~? for help]
SOL session closed by BMC
```
~# ipmitool -I lanplus -H $ip -U $username -P $password sol info
```
Info: SOL parameter 'Nonvolatile Bitrate (5)' not supported
Info: SOL parameter 'Volatile Bitrate (6)' not supported
Set in progress                 : set-complete
Enabled                         : true
Force Encryption                : false
Force Authentication            : false
Privilege Level                 : ADMINISTRATOR
Character Accumulate Level (ms) : 60
Character Send Threshold        : 96
Retry Count                     : 7
Retry Interval (ms)             : 500
Volatile Bit Rate (kbps)        : IPMI-Over-Serial-Setting
Non-Volatile Bit Rate (kbps)    : IPMI-Over-Serial-Setting
Payload Channel                 : 1 (0x01)
Payload Port                    : 623
```

2. Set the privilege of user to 'Operator', run 'sol activate'
and 'sol deactivate'
```
~# ipmitool -I lanplus -H $ip -U $username -P $password sol activate -L OPERATOR
Error activating SOL payload: Insufficient privilege level
~# ipmitool -I lanplus -H $ip -U $username -P $password sol deactivate -L OPERATOR
Error de-activating SOL payload: Insufficient privilege level
```
3. Set the privilege of user to 'ReadOnly', run 'sol activate'
and 'sol deactivate'
```
~# ipmitool -I lanplus -H $ip -U $username -P $password sol activate -L USER
Error activating SOL payload: Insufficient privilege level
~# ipmitool -I lanplus -H $ip -U $username -P $password sol deactivate -L USER
Error de-activating SOL payload: Insufficient privilege level
```
4. Create new users test1 and test2 with 'ReadOnly' privilege,
set sol privilege to 'ReadOnly', run 'sol activate' with test1
```
~# ipmitool -I lanplus -H $ip -U $username -P $password sol set privilege-level user
~# ipmitool -I lanplus -H $ip -U test1 -P $password sol activate -L USER
[SOL Session operational.  Use ~? for help]
```
On another console, deactivate session owned by test1
```
~# ipmitool -I lanplus -H $ip -U test2 -P $password sol deactivate -L USER
Error de-activating SOL payload: Insufficient privilege level
~# ipmitool -I lanplus -H $ip -U test1 -P $password sol deactivate -L USER
```
Session owned by test1 cannot be deactivated by test2, can be
deactivated by test1

Signed-off-by: Tang Yiwei <tangyiwei.2022@bytedance.com>
Change-Id: Ie5ca60c9891140614b701392c94245e916cd97ab
diff --git a/command/payload_cmds.cpp b/command/payload_cmds.cpp
index b3bcca2..e38473c 100644
--- a/command/payload_cmds.cpp
+++ b/command/payload_cmds.cpp
@@ -62,6 +62,13 @@
         return outPayload;
     }
 
+    if (session->currentPrivilege() <
+        static_cast<uint8_t>(sol::Manager::get().solMinPrivilege))
+    {
+        response->completionCode = IPMI_CC_INSUFFICIENT_PRIVILEGE;
+        return outPayload;
+    }
+
     // Is SOL Payload enabled for this user & channel.
     auto userId = ipmi::ipmiUserGetUserId(session->userName);
     ipmi::PayloadAccess payloadAccess = {};
@@ -109,7 +116,7 @@
 
 std::vector<uint8_t>
     deactivatePayload(const std::vector<uint8_t>& inPayload,
-                      std::shared_ptr<message::Handler>& /* handler */)
+                      std::shared_ptr<message::Handler>& handler)
 {
     auto request =
         reinterpret_cast<const DeactivatePayloadRequest*>(inPayload.data());
@@ -145,17 +152,27 @@
         return outPayload;
     }
 
+    auto currentSession =
+        session::Manager::get().getSession(handler->sessionID);
+    auto solSessionID =
+        sol::Manager::get().getContext(request->payloadInstance).sessionID;
+    auto solActiveSession = session::Manager::get().getSession(solSessionID);
+    // The session owner or the ADMIN could deactivate the session
+    if (currentSession->userName != solActiveSession->userName &&
+        currentSession->currentPrivilege() !=
+            static_cast<uint8_t>(session::Privilege::ADMIN))
+    {
+        response->completionCode = IPMI_CC_INSUFFICIENT_PRIVILEGE;
+        return outPayload;
+    }
+
     try
     {
-        auto& context =
-            sol::Manager::get().getContext(request->payloadInstance);
-        auto sessionID = context.sessionID;
-
         sol::Manager::get().stopPayloadInstance(request->payloadInstance);
 
         try
         {
-            activating(request->payloadInstance, sessionID);
+            activating(request->payloadInstance, solSessionID);
         }
         catch (const std::exception& e)
         {
@@ -164,7 +181,7 @@
             /*
              * In case session has been closed (like in the case of inactivity
              * timeout), then activating function would throw an exception,
-             * since sessionID is not found. IPMI success completion code is
+             * since solSessionID is not found. IPMI success completion code is
              * returned, since the session is closed.
              */
             return outPayload;