blob: 833f6a11019cedf3772adca1439272be937022e1 [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>
21#include <cstdint>
22#include <ctime>
jayaprakash Mutyala9fc5fa12019-08-29 15:14:06 +000023#include <ipmid/api.hpp>
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +053024#include <sdbusplus/bus.hpp>
Vernon Mauery16b86932019-05-01 08:36:11 -070025#include <variant>
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +053026
27namespace ipmi
28{
29
30using DbusUserPropVariant =
Vernon Mauery16b86932019-05-01 08:36:11 -070031 std::variant<std::vector<std::string>, std::string, bool>;
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +053032
33using DbusUserObjPath = sdbusplus::message::object_path;
34
35using DbusUserObjProperties =
36 std::vector<std::pair<std::string, DbusUserPropVariant>>;
37
38using DbusUserObjValue = std::map<std::string, DbusUserObjProperties>;
39
Richard Marian Thomaiyar6e1ba9e2018-11-29 06:29:21 +053040/**
41 * @enum User update events.
42 */
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +053043enum class UserUpdateEvent
44{
45 reservedEvent,
46 userCreated,
47 userDeleted,
48 userRenamed,
49 userGrpUpdated,
50 userPrivUpdated,
51 userStateUpdated
52};
53
Richard Marian Thomaiyar6e1ba9e2018-11-29 06:29:21 +053054/** @struct UserPrivAccess
55 *
56 * Structure for user privilege access (refer spec sec 22.22)
57 */
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +053058struct UserPrivAccess
59{
60 uint8_t privilege;
61 bool ipmiEnabled;
62 bool linkAuthEnabled;
63 bool accessCallback;
64};
65
Richard Marian Thomaiyar6e1ba9e2018-11-29 06:29:21 +053066/** @struct UserInfo
67 *
68 * Structure for user related information
69 */
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +053070struct UserInfo
71{
72 uint8_t userName[ipmiMaxUserName];
73 UserPrivAccess userPrivAccess[ipmiMaxChannels];
74 bool userEnabled;
75 bool userInSystem;
76 bool fixedUserName;
Saravanan Palanisamy77381f12019-05-15 22:33:17 +000077 PayloadAccess payloadAccess[ipmiMaxChannels];
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +053078};
79
Richard Marian Thomaiyar6e1ba9e2018-11-29 06:29:21 +053080/** @struct UsersTbl
81 *
82 * Structure for array of user related information
83 */
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +053084struct UsersTbl
85{
86 //+1 to map with UserId directly. UserId 0 is reserved.
87 UserInfo user[ipmiMaxUsers + 1];
88};
89
Ayushi Smriti02650d52019-05-15 11:59:09 +000090/** @brief PAM User Authentication check
91 *
92 * @param[in] username - username in string
93 * @param[in] password - password in string
94 *
95 * @return status
96 */
97bool pamUserCheckAuthenticate(std::string_view username,
98 std::string_view password);
99
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530100class UserAccess;
101
102UserAccess& getUserAccessObject();
103
104class UserAccess
105{
106 public:
107 UserAccess(const UserAccess&) = delete;
108 UserAccess& operator=(const UserAccess&) = delete;
109 UserAccess(UserAccess&&) = delete;
110 UserAccess& operator=(UserAccess&&) = delete;
111
112 ~UserAccess();
113 UserAccess();
114
115 /** @brief determines valid channel
116 *
117 * @param[in] chNum - channel number
118 *
119 * @return true if valid, false otherwise
120 */
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530121 static bool isValidChannel(const uint8_t chNum);
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530122
123 /** @brief determines valid userId
124 *
125 * @param[in] userId - user id
126 *
127 * @return true if valid, false otherwise
128 */
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530129 static bool isValidUserId(const uint8_t userId);
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530130
131 /** @brief determines valid user privilege
132 *
133 * @param[in] priv - Privilege
134 *
135 * @return true if valid, false otherwise
136 */
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530137 static bool isValidPrivilege(const uint8_t priv);
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530138
139 /** @brief determines sync index to be mapped with common-user-management
140 *
141 * @return Index which will be used as sync index
142 */
143 static uint8_t getUsrMgmtSyncIndex();
144
145 /** @brief Converts system privilege to IPMI privilege
146 *
147 * @param[in] value - Privilege in string
148 *
149 * @return CommandPrivilege - IPMI privilege type
150 */
151 static CommandPrivilege convertToIPMIPrivilege(const std::string& value);
152
153 /** @brief Converts IPMI privilege to system privilege
154 *
155 * @param[in] value - IPMI privilege
156 *
157 * @return System privilege in string
158 */
159 static std::string convertToSystemPrivilege(const CommandPrivilege& value);
160
161 /** @brief determines whether user name is valid
162 *
163 * @param[in] userNameInChar - user name
164 *
165 * @return true if valid, false otherwise
166 */
jayaprakash Mutyala76363302020-02-14 23:50:38 +0000167 bool isValidUserName(const std::string& userName);
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530168
Richard Marian Thomaiyar489a4ed2020-01-17 11:48:40 +0530169 /** @brief determines whether ipmi is in available groups list
170 *
171 * @return true if ipmi group is present, false otherwise
172 */
173 bool isIpmiInAvailableGroupList();
174
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530175 /** @brief provides user id of the user
176 *
177 * @param[in] userName - user name
178 *
179 * @return user id of the user, else invalid user id (0xFF), if user not
180 * found
181 */
182 uint8_t getUserId(const std::string& userName);
183
184 /** @brief provides user information
185 *
186 * @param[in] userId - user id
187 *
188 * @return UserInfo for the specified user id
189 */
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530190 UserInfo* getUserInfo(const uint8_t userId);
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530191
192 /** @brief sets user information
193 *
194 * @param[in] userId - user id
195 * @param[in] userInfo - user information
196 *
197 */
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530198 void setUserInfo(const uint8_t userId, UserInfo* userInfo);
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530199
200 /** @brief provides user name
201 *
202 * @param[in] userId - user id
203 * @param[out] userName - user name
204 *
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000205 * @return ccSuccess for success, others for failure.
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530206 */
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000207 Cc getUserName(const uint8_t userId, std::string& userName);
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530208
209 /** @brief to set user name
210 *
211 * @param[in] userId - user id
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000212 * @param[in] userName - user name
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530213 *
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000214 * @return ccSuccess for success, others for failure.
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530215 */
jayaprakash Mutyala76363302020-02-14 23:50:38 +0000216 Cc setUserName(const uint8_t userId, const std::string& userName);
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530217
Richard Marian Thomaiyar282e79b2018-11-13 19:00:58 +0530218 /** @brief to set user enabled state
219 *
220 * @param[in] userId - user id
221 * @param[in] enabledState - enabled state of the user
222 *
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000223 * @return ccSuccess for success, others for failure.
Richard Marian Thomaiyar282e79b2018-11-13 19:00:58 +0530224 */
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000225 Cc setUserEnabledState(const uint8_t userId, const bool& enabledState);
Richard Marian Thomaiyar282e79b2018-11-13 19:00:58 +0530226
Suryakanth Sekar90b00c72019-01-16 10:37:57 +0530227 /** @brief to set user password
228 *
229 * @param[in] userId - user id
230 * @param[in] userPassword - new password of the user
231 *
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000232 * @return ccSuccess for success, others for failure.
Suryakanth Sekar90b00c72019-01-16 10:37:57 +0530233 */
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000234 Cc setUserPassword(const uint8_t userId, const char* userPassword);
Suryakanth Sekar90b00c72019-01-16 10:37:57 +0530235
Richard Marian Thomaiyar788362c2019-04-14 15:12:47 +0530236 /** @brief to set special user password
237 *
238 * @param[in] userName - user name
239 * @param[in] userPassword - new password of the user
240 *
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000241 * @return ccSuccess for success, others for failure.
Richard Marian Thomaiyar788362c2019-04-14 15:12:47 +0530242 */
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000243 Cc setSpecialUserPassword(const std::string& userName,
Vernon Mauery1e22a0f2021-07-30 13:36:54 -0700244 const SecureString& userPassword);
Richard Marian Thomaiyar788362c2019-04-14 15:12:47 +0530245
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530246 /** @brief to set user privilege and access details
247 *
248 * @param[in] userId - user id
249 * @param[in] chNum - channel number
250 * @param[in] privAccess - privilege access
251 * @param[in] otherPrivUpdates - other privilege update flag to update ipmi
252 * enable, link authentication and access callback
253 *
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000254 * @return ccSuccess for success, others for failure.
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530255 */
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000256 Cc setUserPrivilegeAccess(const uint8_t userId, const uint8_t chNum,
257 const UserPrivAccess& privAccess,
258 const bool& otherPrivUpdates);
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530259
Saravanan Palanisamy77381f12019-05-15 22:33:17 +0000260 /** @brief to get user payload access details from userInfo entry.
261 *
262 * @param[in] userInfo - userInfo entry in usersTbl.
263 * @param[out] stdPayload - stdPayloadEnables1 in a 2D-array.
264 * @param[out] oemPayload - oemPayloadEnables1 in a 2D-array.
265 *
266 * @details Update the given 2D-arrays using the payload access details
267 * available in the given userInfo entry (from usersTbl).
268 * This 2D-array will be mapped to a JSON object (which will be written to
269 * a JSON file subsequently).
270 */
271 void readPayloadAccessFromUserInfo(
272 const UserInfo& userInfo,
273 std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>&
274 stdPayload,
275 std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>&
276 oemPayload);
277
278 /** @brief to update user payload access details in userInfo entry.
279 *
280 * @param[in] stdPayload - stdPayloadEnables1 in a 2D-array.
281 * @param[in] oemPayload - oemPayloadEnables1 in a 2D-array.
282 * @param[out] userInfo - userInfo entry in usersTbl.
283 *
284 * @details Update user payload access details of a given userInfo
285 * entry (in usersTbl) with the information provided in given 2D-arrays.
286 * This 2D-array was created out of a JSON object (which was created by
287 * parsing a JSON file).
288 */
289 void updatePayloadAccessInUserInfo(
290 const std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>&
291 stdPayload,
292 const std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>&
293 oemPayload,
294 UserInfo& userInfo);
295
296 /** @brief to set user payload access details
297 *
298 * @param[in] chNum - channel number
299 * @param[in] operation - Enable / Disable
300 * @param[in] userId - user id
301 * @param[in] payloadAccess - payload access
302 *
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000303 * @return ccSuccess for success, others for failure.
Saravanan Palanisamy77381f12019-05-15 22:33:17 +0000304 */
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000305 Cc setUserPayloadAccess(const uint8_t chNum, const uint8_t operation,
306 const uint8_t userId,
307 const PayloadAccess& payloadAccess);
Saravanan Palanisamy77381f12019-05-15 22:33:17 +0000308
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530309 /** @brief reads user management related data from configuration file
310 *
311 */
312 void readUserData();
313
314 /** @brief writes user management related data to configuration file
315 *
316 */
317 void writeUserData();
318
319 /** @brief Funtion which checks and reload configuration file data if
320 * needed.
321 *
322 */
323 void checkAndReloadUserData();
324
325 /** @brief provides user details from D-Bus user property data
326 *
327 * @param[in] properties - D-Bus user property
328 * @param[out] usrGrps - user group details
329 * @param[out] usrPriv - user privilege
330 * @param[out] usrEnabled - enabled state of the user.
331 *
332 * @return 0 for success, -errno for failure.
333 */
334 void getUserProperties(const DbusUserObjProperties& properties,
335 std::vector<std::string>& usrGrps,
336 std::string& usrPriv, bool& usrEnabled);
337
338 /** @brief provides user details from D-Bus user object data
339 *
340 * @param[in] userObjs - D-Bus user object
341 * @param[out] usrGrps - user group details
342 * @param[out] usrPriv - user privilege
343 * @param[out] usrEnabled - enabled state of the user.
344 *
345 * @return 0 for success, -errno for failure.
346 */
347 int getUserObjProperties(const DbusUserObjValue& userObjs,
348 std::vector<std::string>& usrGrps,
349 std::string& usrPriv, bool& usrEnabled);
350
351 /** @brief function to add user entry information to the configuration
352 *
353 * @param[in] userName - user name
354 * @param[in] priv - privilege of the user
355 * @param[in] enabled - enabled state of the user
356 *
357 * @return true for success, false for failure
358 */
359 bool addUserEntry(const std::string& userName, const std::string& priv,
360 const bool& enabled);
361
362 /** @brief function to delete user entry based on user index
363 *
364 * @param[in] usrIdx - user index
365 *
366 */
367 void deleteUserIndex(const size_t& usrIdx);
368
369 /** @brief function to get users table
370 *
371 */
372 UsersTbl* getUsersTblPtr();
373
374 std::unique_ptr<boost::interprocess::named_recursive_mutex> userMutex{
375 nullptr};
376
377 private:
378 UsersTbl usersTbl;
379 std::vector<std::string> availablePrivileges;
380 std::vector<std::string> availableGroups;
381 sdbusplus::bus::bus bus;
382 std::time_t fileLastUpdatedTime;
383 bool signalHndlrObject = false;
384 boost::interprocess::file_lock sigHndlrLock;
385 boost::interprocess::file_lock mutexCleanupLock;
386
387 /** @brief function to get user configuration file timestamp
388 *
389 * @return time stamp or -EIO for failure
390 */
391 std::time_t getUpdatedFileTime();
392
393 /** @brief function to available system privileges and groups
394 *
395 */
396 void getSystemPrivAndGroups();
397
398 /** @brief function to init user data from configuration & D-Bus objects
arun-pmbbe728c2020-01-10 15:18:04 +0530399 * and to register for signals
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530400 *
401 */
arun-pmbbe728c2020-01-10 15:18:04 +0530402 void cacheUserDataFile();
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530403};
Snehalatha Venkatesh61024d72021-04-08 16:24:39 +0000404
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530405} // namespace ipmi