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