blob: 74166c2f41b8c52f2584cf0b87a9f87012c4e93a [file] [log] [blame]
Snehalatha Venkatesh61024d72021-04-08 16:24:39 +00001/*.
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +05302// 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
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +053019#include <boost/interprocess/sync/file_lock.hpp>
20#include <boost/interprocess/sync/named_recursive_mutex.hpp>
jayaprakash Mutyala9fc5fa12019-08-29 15:14:06 +000021#include <ipmid/api.hpp>
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +053022#include <sdbusplus/bus.hpp>
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -050023
24#include <cstdint>
25#include <ctime>
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 */
jayaprakash Mutyala76363302020-02-14 23:50:38 +0000168 bool isValidUserName(const std::string& userName);
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530169
Richard Marian Thomaiyar489a4ed2020-01-17 11:48:40 +0530170 /** @brief determines whether ipmi is in available groups list
171 *
172 * @return true if ipmi group is present, false otherwise
173 */
174 bool isIpmiInAvailableGroupList();
175
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530176 /** @brief provides user id of the user
177 *
178 * @param[in] userName - user name
179 *
180 * @return user id of the user, else invalid user id (0xFF), if user not
181 * found
182 */
183 uint8_t getUserId(const std::string& userName);
184
185 /** @brief provides user information
186 *
187 * @param[in] userId - user id
188 *
189 * @return UserInfo for the specified user id
190 */
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530191 UserInfo* getUserInfo(const uint8_t userId);
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530192
193 /** @brief sets user information
194 *
195 * @param[in] userId - user id
196 * @param[in] userInfo - user information
197 *
198 */
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530199 void setUserInfo(const uint8_t userId, UserInfo* userInfo);
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530200
201 /** @brief provides user name
202 *
203 * @param[in] userId - user id
204 * @param[out] userName - user name
205 *
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000206 * @return ccSuccess for success, others for failure.
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530207 */
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000208 Cc getUserName(const uint8_t userId, std::string& userName);
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530209
210 /** @brief to set user name
211 *
212 * @param[in] userId - user id
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000213 * @param[in] userName - user name
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530214 *
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000215 * @return ccSuccess for success, others for failure.
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530216 */
jayaprakash Mutyala76363302020-02-14 23:50:38 +0000217 Cc setUserName(const uint8_t userId, const std::string& userName);
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530218
Richard Marian Thomaiyar282e79b2018-11-13 19:00:58 +0530219 /** @brief to set user enabled state
220 *
221 * @param[in] userId - user id
222 * @param[in] enabledState - enabled state of the user
223 *
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000224 * @return ccSuccess for success, others for failure.
Richard Marian Thomaiyar282e79b2018-11-13 19:00:58 +0530225 */
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000226 Cc setUserEnabledState(const uint8_t userId, const bool& enabledState);
Richard Marian Thomaiyar282e79b2018-11-13 19:00:58 +0530227
Suryakanth Sekar90b00c72019-01-16 10:37:57 +0530228 /** @brief to set user password
229 *
230 * @param[in] userId - user id
231 * @param[in] userPassword - new password of the user
232 *
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000233 * @return ccSuccess for success, others for failure.
Suryakanth Sekar90b00c72019-01-16 10:37:57 +0530234 */
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000235 Cc setUserPassword(const uint8_t userId, const char* userPassword);
Suryakanth Sekar90b00c72019-01-16 10:37:57 +0530236
Richard Marian Thomaiyar788362c2019-04-14 15:12:47 +0530237 /** @brief to set special user password
238 *
239 * @param[in] userName - user name
240 * @param[in] userPassword - new password of the user
241 *
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000242 * @return ccSuccess for success, others for failure.
Richard Marian Thomaiyar788362c2019-04-14 15:12:47 +0530243 */
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000244 Cc setSpecialUserPassword(const std::string& userName,
Vernon Mauery1e22a0f2021-07-30 13:36:54 -0700245 const SecureString& userPassword);
Richard Marian Thomaiyar788362c2019-04-14 15:12:47 +0530246
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530247 /** @brief to set user privilege and access details
248 *
249 * @param[in] userId - user id
250 * @param[in] chNum - channel number
251 * @param[in] privAccess - privilege access
252 * @param[in] otherPrivUpdates - other privilege update flag to update ipmi
253 * enable, link authentication and access callback
254 *
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000255 * @return ccSuccess for success, others for failure.
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530256 */
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000257 Cc setUserPrivilegeAccess(const uint8_t userId, const uint8_t chNum,
258 const UserPrivAccess& privAccess,
259 const bool& otherPrivUpdates);
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530260
Saravanan Palanisamy77381f12019-05-15 22:33:17 +0000261 /** @brief to get user payload access details from userInfo entry.
262 *
263 * @param[in] userInfo - userInfo entry in usersTbl.
264 * @param[out] stdPayload - stdPayloadEnables1 in a 2D-array.
265 * @param[out] oemPayload - oemPayloadEnables1 in a 2D-array.
266 *
267 * @details Update the given 2D-arrays using the payload access details
268 * available in the given userInfo entry (from usersTbl).
269 * This 2D-array will be mapped to a JSON object (which will be written to
270 * a JSON file subsequently).
271 */
272 void readPayloadAccessFromUserInfo(
273 const UserInfo& userInfo,
274 std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>&
275 stdPayload,
276 std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>&
277 oemPayload);
278
279 /** @brief to update user payload access details in userInfo entry.
280 *
281 * @param[in] stdPayload - stdPayloadEnables1 in a 2D-array.
282 * @param[in] oemPayload - oemPayloadEnables1 in a 2D-array.
283 * @param[out] userInfo - userInfo entry in usersTbl.
284 *
285 * @details Update user payload access details of a given userInfo
286 * entry (in usersTbl) with the information provided in given 2D-arrays.
287 * This 2D-array was created out of a JSON object (which was created by
288 * parsing a JSON file).
289 */
290 void updatePayloadAccessInUserInfo(
291 const std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>&
292 stdPayload,
293 const std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>&
294 oemPayload,
295 UserInfo& userInfo);
296
297 /** @brief to set user payload access details
298 *
299 * @param[in] chNum - channel number
300 * @param[in] operation - Enable / Disable
301 * @param[in] userId - user id
302 * @param[in] payloadAccess - payload access
303 *
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000304 * @return ccSuccess for success, others for failure.
Saravanan Palanisamy77381f12019-05-15 22:33:17 +0000305 */
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000306 Cc setUserPayloadAccess(const uint8_t chNum, const uint8_t operation,
307 const uint8_t userId,
308 const PayloadAccess& payloadAccess);
Saravanan Palanisamy77381f12019-05-15 22:33:17 +0000309
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530310 /** @brief reads user management related data from configuration file
311 *
312 */
313 void readUserData();
314
315 /** @brief writes user management related data to configuration file
316 *
317 */
318 void writeUserData();
319
320 /** @brief Funtion which checks and reload configuration file data if
321 * needed.
322 *
323 */
324 void checkAndReloadUserData();
325
326 /** @brief provides user details from D-Bus user property data
327 *
328 * @param[in] properties - D-Bus user property
329 * @param[out] usrGrps - user group details
330 * @param[out] usrPriv - user privilege
331 * @param[out] usrEnabled - enabled state of the user.
332 *
333 * @return 0 for success, -errno for failure.
334 */
335 void getUserProperties(const DbusUserObjProperties& properties,
336 std::vector<std::string>& usrGrps,
337 std::string& usrPriv, bool& usrEnabled);
338
339 /** @brief provides user details from D-Bus user object data
340 *
341 * @param[in] userObjs - D-Bus user object
342 * @param[out] usrGrps - user group details
343 * @param[out] usrPriv - user privilege
344 * @param[out] usrEnabled - enabled state of the user.
345 *
346 * @return 0 for success, -errno for failure.
347 */
348 int getUserObjProperties(const DbusUserObjValue& userObjs,
349 std::vector<std::string>& usrGrps,
350 std::string& usrPriv, bool& usrEnabled);
351
352 /** @brief function to add user entry information to the configuration
353 *
354 * @param[in] userName - user name
355 * @param[in] priv - privilege of the user
356 * @param[in] enabled - enabled state of the user
357 *
358 * @return true for success, false for failure
359 */
360 bool addUserEntry(const std::string& userName, const std::string& priv,
361 const bool& enabled);
362
363 /** @brief function to delete user entry based on user index
364 *
365 * @param[in] usrIdx - user index
366 *
367 */
368 void deleteUserIndex(const size_t& usrIdx);
369
370 /** @brief function to get users table
371 *
372 */
373 UsersTbl* getUsersTblPtr();
374
375 std::unique_ptr<boost::interprocess::named_recursive_mutex> userMutex{
376 nullptr};
377
378 private:
379 UsersTbl usersTbl;
380 std::vector<std::string> availablePrivileges;
381 std::vector<std::string> availableGroups;
Patrick Williams5d82f472022-07-22 19:26:53 -0500382 sdbusplus::bus_t bus;
Jayaprakash Mutyala08d3d062021-10-01 16:01:57 +0000383 std::timespec fileLastUpdatedTime;
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530384 bool signalHndlrObject = false;
385 boost::interprocess::file_lock sigHndlrLock;
386 boost::interprocess::file_lock mutexCleanupLock;
387
388 /** @brief function to get user configuration file timestamp
389 *
390 * @return time stamp or -EIO for failure
391 */
Jayaprakash Mutyala08d3d062021-10-01 16:01:57 +0000392 std::timespec getUpdatedFileTime();
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530393
394 /** @brief function to available system privileges and groups
395 *
396 */
397 void getSystemPrivAndGroups();
398
399 /** @brief function to init user data from configuration & D-Bus objects
arun-pmbbe728c2020-01-10 15:18:04 +0530400 * and to register for signals
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530401 *
402 */
arun-pmbbe728c2020-01-10 15:18:04 +0530403 void cacheUserDataFile();
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530404};
Snehalatha Venkatesh61024d72021-04-08 16:24:39 +0000405
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530406} // namespace ipmi