blob: 773b18d31f3a10e304a83612e6ae2858d36a40b5 [file] [log] [blame]
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +05301/*
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#include "user_layer.hpp"
18
William A. Kennington III194375f2018-12-14 02:14:33 -080019#include <ipmid/api.h>
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +053020
21#include <boost/interprocess/sync/file_lock.hpp>
22#include <boost/interprocess/sync/named_recursive_mutex.hpp>
23#include <cstdint>
24#include <ctime>
25#include <sdbusplus/bus.hpp>
Vernon Mauery16b86932019-05-01 08:36:11 -070026#include <variant>
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +053027
28namespace ipmi
29{
30
31using DbusUserPropVariant =
Vernon Mauery16b86932019-05-01 08:36:11 -070032 std::variant<std::vector<std::string>, std::string, bool>;
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +053033
34using DbusUserObjPath = sdbusplus::message::object_path;
35
36using DbusUserObjProperties =
37 std::vector<std::pair<std::string, DbusUserPropVariant>>;
38
39using DbusUserObjValue = std::map<std::string, DbusUserObjProperties>;
40
Richard Marian Thomaiyar6e1ba9e2018-11-29 06:29:21 +053041/**
42 * @enum User update events.
43 */
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +053044enum class UserUpdateEvent
45{
46 reservedEvent,
47 userCreated,
48 userDeleted,
49 userRenamed,
50 userGrpUpdated,
51 userPrivUpdated,
52 userStateUpdated
53};
54
Richard Marian Thomaiyar6e1ba9e2018-11-29 06:29:21 +053055/** @struct UserPrivAccess
56 *
57 * Structure for user privilege access (refer spec sec 22.22)
58 */
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +053059struct UserPrivAccess
60{
61 uint8_t privilege;
62 bool ipmiEnabled;
63 bool linkAuthEnabled;
64 bool accessCallback;
65};
66
Richard Marian Thomaiyar6e1ba9e2018-11-29 06:29:21 +053067/** @struct UserInfo
68 *
69 * Structure for user related information
70 */
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +053071struct UserInfo
72{
73 uint8_t userName[ipmiMaxUserName];
74 UserPrivAccess userPrivAccess[ipmiMaxChannels];
75 bool userEnabled;
76 bool userInSystem;
77 bool fixedUserName;
Saravanan Palanisamy77381f12019-05-15 22:33:17 +000078 PayloadAccess payloadAccess[ipmiMaxChannels];
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +053079};
80
Richard Marian Thomaiyar6e1ba9e2018-11-29 06:29:21 +053081/** @struct UsersTbl
82 *
83 * Structure for array of user related information
84 */
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +053085struct UsersTbl
86{
87 //+1 to map with UserId directly. UserId 0 is reserved.
88 UserInfo user[ipmiMaxUsers + 1];
89};
90
Ayushi Smriti02650d52019-05-15 11:59:09 +000091/** @brief PAM User Authentication check
92 *
93 * @param[in] username - username in string
94 * @param[in] password - password in string
95 *
96 * @return status
97 */
98bool pamUserCheckAuthenticate(std::string_view username,
99 std::string_view password);
100
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530101class UserAccess;
102
103UserAccess& getUserAccessObject();
104
105class UserAccess
106{
107 public:
108 UserAccess(const UserAccess&) = delete;
109 UserAccess& operator=(const UserAccess&) = delete;
110 UserAccess(UserAccess&&) = delete;
111 UserAccess& operator=(UserAccess&&) = delete;
112
113 ~UserAccess();
114 UserAccess();
115
116 /** @brief determines valid channel
117 *
118 * @param[in] chNum - channel number
119 *
120 * @return true if valid, false otherwise
121 */
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530122 static bool isValidChannel(const uint8_t chNum);
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530123
124 /** @brief determines valid userId
125 *
126 * @param[in] userId - user id
127 *
128 * @return true if valid, false otherwise
129 */
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530130 static bool isValidUserId(const uint8_t userId);
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530131
132 /** @brief determines valid user privilege
133 *
134 * @param[in] priv - Privilege
135 *
136 * @return true if valid, false otherwise
137 */
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530138 static bool isValidPrivilege(const uint8_t priv);
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530139
140 /** @brief determines sync index to be mapped with common-user-management
141 *
142 * @return Index which will be used as sync index
143 */
144 static uint8_t getUsrMgmtSyncIndex();
145
146 /** @brief Converts system privilege to IPMI privilege
147 *
148 * @param[in] value - Privilege in string
149 *
150 * @return CommandPrivilege - IPMI privilege type
151 */
152 static CommandPrivilege convertToIPMIPrivilege(const std::string& value);
153
154 /** @brief Converts IPMI privilege to system privilege
155 *
156 * @param[in] value - IPMI privilege
157 *
158 * @return System privilege in string
159 */
160 static std::string convertToSystemPrivilege(const CommandPrivilege& value);
161
162 /** @brief determines whether user name is valid
163 *
164 * @param[in] userNameInChar - user name
165 *
166 * @return true if valid, false otherwise
167 */
168 bool isValidUserName(const char* userNameInChar);
169
170 /** @brief provides user id of the user
171 *
172 * @param[in] userName - user name
173 *
174 * @return user id of the user, else invalid user id (0xFF), if user not
175 * found
176 */
177 uint8_t getUserId(const std::string& userName);
178
179 /** @brief provides user information
180 *
181 * @param[in] userId - user id
182 *
183 * @return UserInfo for the specified user id
184 */
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530185 UserInfo* getUserInfo(const uint8_t userId);
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530186
187 /** @brief sets user information
188 *
189 * @param[in] userId - user id
190 * @param[in] userInfo - user information
191 *
192 */
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530193 void setUserInfo(const uint8_t userId, UserInfo* userInfo);
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530194
195 /** @brief provides user name
196 *
197 * @param[in] userId - user id
198 * @param[out] userName - user name
199 *
200 * @return IPMI_CC_OK for success, others for failure.
201 */
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530202 ipmi_ret_t getUserName(const uint8_t userId, std::string& userName);
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530203
204 /** @brief to set user name
205 *
206 * @param[in] userId - user id
207 * @param[in] userNameInChar - user name
208 *
209 * @return IPMI_CC_OK for success, others for failure.
210 */
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530211 ipmi_ret_t setUserName(const uint8_t userId, const char* userNameInChar);
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530212
Richard Marian Thomaiyar282e79b2018-11-13 19:00:58 +0530213 /** @brief to set user enabled state
214 *
215 * @param[in] userId - user id
216 * @param[in] enabledState - enabled state of the user
217 *
218 * @return IPMI_CC_OK for success, others for failure.
219 */
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530220 ipmi_ret_t setUserEnabledState(const uint8_t userId,
Richard Marian Thomaiyar282e79b2018-11-13 19:00:58 +0530221 const bool& enabledState);
222
Suryakanth Sekar90b00c72019-01-16 10:37:57 +0530223 /** @brief to set user password
224 *
225 * @param[in] userId - user id
226 * @param[in] userPassword - new password of the user
227 *
228 * @return IPMI_CC_OK for success, others for failure.
229 */
230 ipmi_ret_t setUserPassword(const uint8_t userId, const char* userPassword);
231
Richard Marian Thomaiyar788362c2019-04-14 15:12:47 +0530232 /** @brief to set special user password
233 *
234 * @param[in] userName - user name
235 * @param[in] userPassword - new password of the user
236 *
237 * @return IPMI_CC_OK for success, others for failure.
238 */
239 ipmi_ret_t setSpecialUserPassword(const std::string& userName,
240 const std::string& userPassword);
241
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530242 /** @brief to set user privilege and access details
243 *
244 * @param[in] userId - user id
245 * @param[in] chNum - channel number
246 * @param[in] privAccess - privilege access
247 * @param[in] otherPrivUpdates - other privilege update flag to update ipmi
248 * enable, link authentication and access callback
249 *
250 * @return IPMI_CC_OK for success, others for failure.
251 */
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530252 ipmi_ret_t setUserPrivilegeAccess(const uint8_t userId, const uint8_t chNum,
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530253 const UserPrivAccess& privAccess,
254 const bool& otherPrivUpdates);
255
Saravanan Palanisamy77381f12019-05-15 22:33:17 +0000256 /** @brief to get user payload access details from userInfo entry.
257 *
258 * @param[in] userInfo - userInfo entry in usersTbl.
259 * @param[out] stdPayload - stdPayloadEnables1 in a 2D-array.
260 * @param[out] oemPayload - oemPayloadEnables1 in a 2D-array.
261 *
262 * @details Update the given 2D-arrays using the payload access details
263 * available in the given userInfo entry (from usersTbl).
264 * This 2D-array will be mapped to a JSON object (which will be written to
265 * a JSON file subsequently).
266 */
267 void readPayloadAccessFromUserInfo(
268 const UserInfo& userInfo,
269 std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>&
270 stdPayload,
271 std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>&
272 oemPayload);
273
274 /** @brief to update user payload access details in userInfo entry.
275 *
276 * @param[in] stdPayload - stdPayloadEnables1 in a 2D-array.
277 * @param[in] oemPayload - oemPayloadEnables1 in a 2D-array.
278 * @param[out] userInfo - userInfo entry in usersTbl.
279 *
280 * @details Update user payload access details of a given userInfo
281 * entry (in usersTbl) with the information provided in given 2D-arrays.
282 * This 2D-array was created out of a JSON object (which was created by
283 * parsing a JSON file).
284 */
285 void updatePayloadAccessInUserInfo(
286 const std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>&
287 stdPayload,
288 const std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>&
289 oemPayload,
290 UserInfo& userInfo);
291
292 /** @brief to set user payload access details
293 *
294 * @param[in] chNum - channel number
295 * @param[in] operation - Enable / Disable
296 * @param[in] userId - user id
297 * @param[in] payloadAccess - payload access
298 *
299 * @return IPMI_CC_OK for success, others for failure.
300 */
301 ipmi_ret_t setUserPayloadAccess(const uint8_t chNum,
302 const uint8_t operation,
303 const uint8_t userId,
304 const PayloadAccess& payloadAccess);
305
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530306 /** @brief reads user management related data from configuration file
307 *
308 */
309 void readUserData();
310
311 /** @brief writes user management related data to configuration file
312 *
313 */
314 void writeUserData();
315
316 /** @brief Funtion which checks and reload configuration file data if
317 * needed.
318 *
319 */
320 void checkAndReloadUserData();
321
322 /** @brief provides user details from D-Bus user property data
323 *
324 * @param[in] properties - D-Bus user property
325 * @param[out] usrGrps - user group details
326 * @param[out] usrPriv - user privilege
327 * @param[out] usrEnabled - enabled state of the user.
328 *
329 * @return 0 for success, -errno for failure.
330 */
331 void getUserProperties(const DbusUserObjProperties& properties,
332 std::vector<std::string>& usrGrps,
333 std::string& usrPriv, bool& usrEnabled);
334
335 /** @brief provides user details from D-Bus user object data
336 *
337 * @param[in] userObjs - D-Bus user object
338 * @param[out] usrGrps - user group details
339 * @param[out] usrPriv - user privilege
340 * @param[out] usrEnabled - enabled state of the user.
341 *
342 * @return 0 for success, -errno for failure.
343 */
344 int getUserObjProperties(const DbusUserObjValue& userObjs,
345 std::vector<std::string>& usrGrps,
346 std::string& usrPriv, bool& usrEnabled);
347
348 /** @brief function to add user entry information to the configuration
349 *
350 * @param[in] userName - user name
351 * @param[in] priv - privilege of the user
352 * @param[in] enabled - enabled state of the user
353 *
354 * @return true for success, false for failure
355 */
356 bool addUserEntry(const std::string& userName, const std::string& priv,
357 const bool& enabled);
358
359 /** @brief function to delete user entry based on user index
360 *
361 * @param[in] usrIdx - user index
362 *
363 */
364 void deleteUserIndex(const size_t& usrIdx);
365
366 /** @brief function to get users table
367 *
368 */
369 UsersTbl* getUsersTblPtr();
370
371 std::unique_ptr<boost::interprocess::named_recursive_mutex> userMutex{
372 nullptr};
373
374 private:
375 UsersTbl usersTbl;
376 std::vector<std::string> availablePrivileges;
377 std::vector<std::string> availableGroups;
378 sdbusplus::bus::bus bus;
379 std::time_t fileLastUpdatedTime;
380 bool signalHndlrObject = false;
381 boost::interprocess::file_lock sigHndlrLock;
382 boost::interprocess::file_lock mutexCleanupLock;
383
384 /** @brief function to get user configuration file timestamp
385 *
386 * @return time stamp or -EIO for failure
387 */
388 std::time_t getUpdatedFileTime();
389
390 /** @brief function to available system privileges and groups
391 *
392 */
393 void getSystemPrivAndGroups();
394
395 /** @brief function to init user data from configuration & D-Bus objects
396 *
397 */
398 void initUserDataFile();
399};
400} // namespace ipmi