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     std::cout << ">> setSessionPrivilegeLevel\n";
16 
17     std::vector<uint8_t> outPayload(sizeof(SetSessionPrivLevelResp));
18     auto request = reinterpret_cast<const SetSessionPrivLevelReq*>
19                    (inPayload.data());
20     auto response = reinterpret_cast<SetSessionPrivLevelResp*>
21                     (outPayload.data());
22     response->completionCode = IPMI_CC_OK;
23     uint8_t reqPrivilegeLevel = request->reqPrivLevel;
24 
25     auto session = (std::get<session::Manager&>(singletonPool).getSession(
26                        handler.sessionID)).lock();
27 
28     if (reqPrivilegeLevel == 0) // Just return present privilege level
29     {
30         response->newPrivLevel = static_cast<uint8_t>(session->curPrivLevel);
31     }
32     else if (reqPrivilegeLevel <= static_cast<uint8_t>(session->maxPrivLevel))
33     {
34         session->curPrivLevel = static_cast<session::Privilege>
35                                 (reqPrivilegeLevel);
36         response->newPrivLevel = reqPrivilegeLevel;
37     }
38     else
39     {
40         // Requested level exceeds Channel and/or User Privilege Limit
41         response->completionCode = IPMI_CC_EXCEEDS_USER_PRIV;
42     }
43 
44     std::cout << "<< setSessionPrivilegeLevel\n";
45     return outPayload;
46 }
47 
48 std::vector<uint8_t> closeSession(const std::vector<uint8_t>& inPayload,
49                                   const message::Handler& handler)
50 {
51     std::cout << ">> closeSession\n";
52 
53     std::vector<uint8_t> outPayload(sizeof(CloseSessionResponse));
54     auto request = reinterpret_cast<const CloseSessionRequest*>
55                    (inPayload.data());
56     auto response = reinterpret_cast<CloseSessionResponse*>(outPayload.data());
57     response->completionCode = IPMI_CC_OK ;
58 
59     auto bmcSessionID = endian::from_ipmi(request->sessionID);
60 
61     // Session 0 is needed to handle session setup, so session zero is never
62     // closed
63     if (bmcSessionID == session::SESSION_ZERO)
64     {
65         response->completionCode = IPMI_CC_INVALID_SESSIONID;
66     }
67     else
68     {
69         auto status = std::get<session::Manager&>(singletonPool).stopSession
70                         (bmcSessionID);
71         if(!status)
72         {
73             response->completionCode = IPMI_CC_INVALID_SESSIONID;
74         }
75     }
76 
77     std::cout << "<< closeSession\n";
78     return outPayload;
79 }
80 
81 } // namespace command
82