1 #include "session_cmds.hpp"
2 
3 #include <iostream>
4 
5 #include "endian.hpp"
6 #include "main.hpp"
7 #include <host-ipmid/ipmid-api.h>
8 
9 namespace command
10 {
11 
12 std::vector<uint8_t> setSessionPrivilegeLevel(
13         const std::vector<uint8_t>& inPayload, const message::Handler& handler)
14 {
15 
16     std::vector<uint8_t> outPayload(sizeof(SetSessionPrivLevelResp));
17     auto request = reinterpret_cast<const SetSessionPrivLevelReq*>
18                    (inPayload.data());
19     auto response = reinterpret_cast<SetSessionPrivLevelResp*>
20                     (outPayload.data());
21     response->completionCode = IPMI_CC_OK;
22     uint8_t reqPrivilegeLevel = request->reqPrivLevel;
23 
24     auto session = (std::get<session::Manager&>(singletonPool).getSession(
25                        handler.sessionID)).lock();
26 
27     if (reqPrivilegeLevel == 0) // Just return present privilege level
28     {
29         response->newPrivLevel = static_cast<uint8_t>(session->curPrivLevel);
30     }
31     else if (reqPrivilegeLevel <= static_cast<uint8_t>(session->maxPrivLevel))
32     {
33         session->curPrivLevel = static_cast<session::Privilege>
34                                 (reqPrivilegeLevel);
35         response->newPrivLevel = reqPrivilegeLevel;
36     }
37     else
38     {
39         // Requested level exceeds Channel and/or User Privilege Limit
40         response->completionCode = IPMI_CC_EXCEEDS_USER_PRIV;
41     }
42     return outPayload;
43 }
44 
45 std::vector<uint8_t> closeSession(const std::vector<uint8_t>& inPayload,
46                                   const message::Handler& handler)
47 {
48     std::vector<uint8_t> outPayload(sizeof(CloseSessionResponse));
49     auto request = reinterpret_cast<const CloseSessionRequest*>
50                    (inPayload.data());
51     auto response = reinterpret_cast<CloseSessionResponse*>(outPayload.data());
52     response->completionCode = IPMI_CC_OK ;
53 
54     auto bmcSessionID = endian::from_ipmi(request->sessionID);
55 
56     // Session 0 is needed to handle session setup, so session zero is never
57     // closed
58     if (bmcSessionID == session::SESSION_ZERO)
59     {
60         response->completionCode = IPMI_CC_INVALID_SESSIONID;
61     }
62     else
63     {
64         auto status = std::get<session::Manager&>(singletonPool).stopSession
65                         (bmcSessionID);
66         if(!status)
67         {
68             response->completionCode = IPMI_CC_INVALID_SESSIONID;
69         }
70     }
71     return outPayload;
72 }
73 
74 } // namespace command
75