1 /*
2 // Copyright (c) 2018 Intel Corporation
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 */
16 #pragma once
17 
18 #include <ipmid/api.hpp>
19 #include <ipmid/types.hpp>
20 
21 #include <bitset>
22 #include <string>
23 
24 namespace ipmi
25 {
26 
27 // TODO: Has to be replaced with proper channel number assignment logic
28 /**
29  * @enum Channel Id
30  */
31 enum class EChannelID : uint8_t
32 {
33     chanLan1 = 0x01
34 };
35 
36 static constexpr uint8_t invalidUserId = 0xFF;
37 static constexpr uint8_t reservedUserId = 0x0;
38 static constexpr uint8_t ipmiMaxUserName = 16;
39 static constexpr uint8_t ipmiMaxUsers = 15;
40 static constexpr uint8_t ipmiMaxChannels = 16;
41 static constexpr uint8_t maxIpmi20PasswordSize = 20;
42 static constexpr uint8_t maxIpmi15PasswordSize = 16;
43 static constexpr uint8_t payloadsPerByte = 8;
44 
45 /** @struct PrivAccess
46  *
47  *  User privilege related access data as per IPMI specification.(refer spec
48  * sec 22.26)
49  */
50 struct PrivAccess
51 {
52 #if BYTE_ORDER == LITTLE_ENDIAN
53     uint8_t privilege:4;
54     uint8_t ipmiEnabled:1;
55     uint8_t linkAuthEnabled:1;
56     uint8_t accessCallback:1;
57     uint8_t reserved:1;
58 #endif
59 #if BYTE_ORDER == BIG_ENDIAN
60     uint8_t reserved:1;
61     uint8_t accessCallback:1;
62     uint8_t linkAuthEnabled:1;
63     uint8_t ipmiEnabled:1;
64     uint8_t privilege:4;
65 #endif
66 } __attribute__((packed));
67 
68 /** @struct UserPayloadAccess
69  *
70  *  Structure to denote payload access restrictions applicable for a
71  *  given user and channel. (refer spec sec 24.6)
72  */
73 struct PayloadAccess
74 {
75     std::bitset<payloadsPerByte> stdPayloadEnables1;
76     std::bitset<payloadsPerByte> stdPayloadEnables2Reserved;
77     std::bitset<payloadsPerByte> oemPayloadEnables1;
78     std::bitset<payloadsPerByte> oemPayloadEnables2Reserved;
79 };
80 
81 /** @brief initializes user management
82  *
83  *  @return ccSuccess for success, others for failure.
84  */
85 Cc ipmiUserInit();
86 
87 /** @brief The ipmi get user password layer call
88  *
89  *  @param[in] userName - user name
90  *
91  *  @return password or empty string
92  */
93 SecureString ipmiUserGetPassword(const std::string& userName);
94 
95 /** @brief The IPMI call to clear password entry associated with specified
96  * username
97  *
98  *  @param[in] userName - user name to be removed
99  *
100  *  @return 0 on success, non-zero otherwise.
101  */
102 Cc ipmiClearUserEntryPassword(const std::string& userName);
103 
104 /** @brief The IPMI call to reuse password entry for the renamed user
105  *  to another one
106  *
107  *  @param[in] userName - user name which has to be renamed
108  *  @param[in] newUserName - new user name
109  *
110  *  @return 0 on success, non-zero otherwise.
111  */
112 Cc ipmiRenameUserEntryPassword(const std::string& userName,
113                                const std::string& newUserName);
114 
115 /** @brief determines valid userId
116  *
117  *  @param[in] userId - user id
118  *
119  *  @return true if valid, false otherwise
120  */
121 bool ipmiUserIsValidUserId(const uint8_t userId);
122 
123 /** @brief determines valid privilege level
124  *
125  *  @param[in] priv - privilege level
126  *
127  *  @return true if valid, false otherwise
128  */
129 bool ipmiUserIsValidPrivilege(const uint8_t priv);
130 
131 /** @brief get user id corresponding to the user name
132  *
133  *  @param[in] userName - user name
134  *
135  *  @return userid. Will return 0xff if no user id found
136  */
137 uint8_t ipmiUserGetUserId(const std::string& userName);
138 
139 /** @brief set's user name
140  *  This API is deprecated
141  */
142 Cc ipmiUserSetUserName(const uint8_t userId, const char* userName)
143     __attribute__((deprecated));
144 
145 /** @brief set's user name
146  *
147  *  @param[in] userId - user id
148  *  @param[in] userName - user name
149  *
150  *  @return ccSuccess for success, others for failure.
151  */
152 Cc ipmiUserSetUserName(const uint8_t userId, const std::string& userName);
153 
154 /** @brief set user password
155  *
156  *  @param[in] userId - user id
157  *  @param[in] userPassword - New Password
158  *
159  *  @return ccSuccess for success, others for failure.
160  */
161 Cc ipmiUserSetUserPassword(const uint8_t userId, const char* userPassword);
162 
163 /** @brief set special user password (non-ipmi accounts)
164  *
165  *  @param[in] userName - user name
166  *  @param[in] userPassword - New Password
167  *
168  *  @return ccSuccess for success, others for failure.
169  */
170 Cc ipmiSetSpecialUserPassword(const std::string& userName,
171                               const SecureString& userPassword);
172 
173 /** @brief get user name
174  *
175  *  @param[in] userId - user id
176  *  @param[out] userName - user name
177  *
178  *  @return ccSuccess for success, others for failure.
179  */
180 Cc ipmiUserGetUserName(const uint8_t userId, std::string& userName);
181 
182 /** @brief provides available fixed, max, and enabled user counts
183  *
184  *  @param[out] maxChUsers - max channel users
185  *  @param[out] enabledUsers - enabled user count
186  *  @param[out] fixedUsers - fixed user count
187  *
188  *  @return ccSuccess for success, others for failure.
189  */
190 Cc ipmiUserGetAllCounts(uint8_t& maxChUsers, uint8_t& enabledUsers,
191                         uint8_t& fixedUsers);
192 
193 /** @brief function to update user enabled state
194  *
195  *  @param[in] userId - user id
196  *..@param[in] state - state of the user to be updated, true - user enabled.
197  *
198  *  @return ccSuccess for success, others for failure.
199  */
200 Cc ipmiUserUpdateEnabledState(const uint8_t userId, const bool& state);
201 
202 /** @brief determines whether user is enabled
203  *
204  *  @param[in] userId - user id
205  *..@param[out] state - state of the user
206  *
207  *  @return ccSuccess for success, others for failure.
208  */
209 Cc ipmiUserCheckEnabled(const uint8_t userId, bool& state);
210 
211 /** @brief provides user privilege access data
212  *
213  *  @param[in] userId - user id
214  *  @param[in] chNum - channel number
215  *  @param[out] privAccess - privilege access data
216  *
217  *  @return ccSuccess for success, others for failure.
218  */
219 Cc ipmiUserGetPrivilegeAccess(const uint8_t userId, const uint8_t chNum,
220                               PrivAccess& privAccess);
221 
222 /** @brief sets user privilege access data
223  *
224  *  @param[in] userId - user id
225  *  @param[in] chNum - channel number
226  *  @param[in] privAccess - privilege access data
227  *  @param[in] otherPrivUpdate - flags to indicate other fields update
228  *
229  *  @return ccSuccess for success, others for failure.
230  */
231 Cc ipmiUserSetPrivilegeAccess(const uint8_t userId, const uint8_t chNum,
232                               const PrivAccess& privAccess,
233                               const bool& otherPrivUpdate);
234 
235 /** @brief check for user pam authentication. This is to determine, whether user
236  * is already locked out for failed login attempt
237  *
238  *  @param[in] username - username
239  *  @param[in] password - password
240  *
241  *  @return status
242  */
243 bool ipmiUserPamAuthenticate(std::string_view userName,
244                              std::string_view userPassword);
245 
246 /** @brief sets user payload access data
247  *
248  *  @param[in] chNum - channel number
249  *  @param[in] operation - ENABLE / DISABLE operation
250  *  @param[in] userId - user id
251  *  @param[in] payloadAccess - payload access data
252  *
253  *  @return ccSuccess for success, others for failure.
254  */
255 Cc ipmiUserSetUserPayloadAccess(const uint8_t chNum, const uint8_t operation,
256                                 const uint8_t userId,
257                                 const PayloadAccess& payloadAccess);
258 
259 /** @brief provides user payload access data
260  *
261  *  @param[in] chNum - channel number
262  *  @param[in] userId - user id
263  *  @param[out] payloadAccess - payload access data
264  *
265  *  @return ccSuccess for success, others for failure.
266  */
267 Cc ipmiUserGetUserPayloadAccess(const uint8_t chNum, const uint8_t userId,
268                                 PayloadAccess& payloadAccess);
269 
270 } // namespace ipmi
271