blob: ebfec02d1798faba0c6b66e5d3f9d1f00da212cf [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
Orit Kashanyf7616312025-08-24 04:48:41 -070024#include <algorithm>
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -050025#include <cstdint>
Orit Kashanyf7616312025-08-24 04:48:41 -070026#include <cstring>
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -050027#include <ctime>
Vernon Mauery16b86932019-05-01 08:36:11 -070028#include <variant>
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +053029
30namespace ipmi
31{
32
Orit Kashanyf7616312025-08-24 04:48:41 -070033// Inline functions for safe username buffer operations
34inline size_t safeUsernameLength(const uint8_t* buf)
35{
36 return strnlen(reinterpret_cast<const char*>(buf), ipmiMaxUserName);
37}
38
39inline std::string safeUsernameString(const uint8_t* buf)
40{
41 return std::string(reinterpret_cast<const char*>(buf),
42 safeUsernameLength(buf));
43}
44
45inline void safeUsernameAssign(std::string& str, const uint8_t* buf)
46{
47 size_t len = safeUsernameLength(buf);
48 str.assign(reinterpret_cast<const char*>(buf), len);
49}
50
51inline void safeUsernameCopyToBuffer(uint8_t* buf, size_t bufSize,
52 const std::string& str)
53{
54 std::memset(buf, 0, bufSize);
55 const size_t n = std::min(str.size(), bufSize);
56 std::memcpy(buf, str.data(), n);
57}
58
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +053059using DbusUserPropVariant =
Vernon Mauery16b86932019-05-01 08:36:11 -070060 std::variant<std::vector<std::string>, std::string, bool>;
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +053061
62using DbusUserObjPath = sdbusplus::message::object_path;
63
64using DbusUserObjProperties =
65 std::vector<std::pair<std::string, DbusUserPropVariant>>;
66
67using DbusUserObjValue = std::map<std::string, DbusUserObjProperties>;
68
Richard Marian Thomaiyar6e1ba9e2018-11-29 06:29:21 +053069/**
70 * @enum User update events.
71 */
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +053072enum class UserUpdateEvent
73{
74 reservedEvent,
75 userCreated,
76 userDeleted,
77 userRenamed,
78 userGrpUpdated,
79 userPrivUpdated,
80 userStateUpdated
81};
82
Richard Marian Thomaiyar6e1ba9e2018-11-29 06:29:21 +053083/** @struct UserPrivAccess
84 *
85 * Structure for user privilege access (refer spec sec 22.22)
86 */
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +053087struct UserPrivAccess
88{
89 uint8_t privilege;
90 bool ipmiEnabled;
91 bool linkAuthEnabled;
92 bool accessCallback;
93};
94
Richard Marian Thomaiyar6e1ba9e2018-11-29 06:29:21 +053095/** @struct UserInfo
96 *
97 * Structure for user related information
98 */
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +053099struct UserInfo
100{
101 uint8_t userName[ipmiMaxUserName];
102 UserPrivAccess userPrivAccess[ipmiMaxChannels];
103 bool userEnabled;
104 bool userInSystem;
105 bool fixedUserName;
Saravanan Palanisamy77381f12019-05-15 22:33:17 +0000106 PayloadAccess payloadAccess[ipmiMaxChannels];
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530107};
108
Richard Marian Thomaiyar6e1ba9e2018-11-29 06:29:21 +0530109/** @struct UsersTbl
110 *
111 * Structure for array of user related information
112 */
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530113struct UsersTbl
114{
115 //+1 to map with UserId directly. UserId 0 is reserved.
116 UserInfo user[ipmiMaxUsers + 1];
117};
118
Ayushi Smriti02650d52019-05-15 11:59:09 +0000119/** @brief PAM User Authentication check
120 *
121 * @param[in] username - username in string
122 * @param[in] password - password in string
123 *
124 * @return status
125 */
126bool pamUserCheckAuthenticate(std::string_view username,
127 std::string_view password);
128
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530129class UserAccess;
130
131UserAccess& getUserAccessObject();
132
133class UserAccess
134{
135 public:
136 UserAccess(const UserAccess&) = delete;
137 UserAccess& operator=(const UserAccess&) = delete;
138 UserAccess(UserAccess&&) = delete;
139 UserAccess& operator=(UserAccess&&) = delete;
140
141 ~UserAccess();
142 UserAccess();
143
144 /** @brief determines valid channel
145 *
146 * @param[in] chNum - channel number
147 *
148 * @return true if valid, false otherwise
149 */
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530150 static bool isValidChannel(const uint8_t chNum);
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530151
152 /** @brief determines valid userId
153 *
154 * @param[in] userId - user id
155 *
156 * @return true if valid, false otherwise
157 */
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530158 static bool isValidUserId(const uint8_t userId);
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530159
160 /** @brief determines valid user privilege
161 *
162 * @param[in] priv - Privilege
163 *
164 * @return true if valid, false otherwise
165 */
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530166 static bool isValidPrivilege(const uint8_t priv);
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530167
168 /** @brief determines sync index to be mapped with common-user-management
169 *
170 * @return Index which will be used as sync index
171 */
172 static uint8_t getUsrMgmtSyncIndex();
173
174 /** @brief Converts system privilege to IPMI privilege
175 *
176 * @param[in] value - Privilege in string
177 *
178 * @return CommandPrivilege - IPMI privilege type
179 */
180 static CommandPrivilege convertToIPMIPrivilege(const std::string& value);
181
182 /** @brief Converts IPMI privilege to system privilege
183 *
184 * @param[in] value - IPMI privilege
185 *
186 * @return System privilege in string
187 */
188 static std::string convertToSystemPrivilege(const CommandPrivilege& value);
189
190 /** @brief determines whether user name is valid
191 *
192 * @param[in] userNameInChar - user name
193 *
194 * @return true if valid, false otherwise
195 */
jayaprakash Mutyala76363302020-02-14 23:50:38 +0000196 bool isValidUserName(const std::string& userName);
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530197
Richard Marian Thomaiyar489a4ed2020-01-17 11:48:40 +0530198 /** @brief determines whether ipmi is in available groups list
199 *
200 * @return true if ipmi group is present, false otherwise
201 */
202 bool isIpmiInAvailableGroupList();
203
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530204 /** @brief provides user id of the user
205 *
206 * @param[in] userName - user name
207 *
208 * @return user id of the user, else invalid user id (0xFF), if user not
209 * found
210 */
211 uint8_t getUserId(const std::string& userName);
212
213 /** @brief provides user information
214 *
215 * @param[in] userId - user id
216 *
217 * @return UserInfo for the specified user id
218 */
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530219 UserInfo* getUserInfo(const uint8_t userId);
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530220
221 /** @brief sets user information
222 *
223 * @param[in] userId - user id
224 * @param[in] userInfo - user information
225 *
226 */
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530227 void setUserInfo(const uint8_t userId, UserInfo* userInfo);
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530228
229 /** @brief provides user name
230 *
231 * @param[in] userId - user id
232 * @param[out] userName - user name
233 *
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000234 * @return ccSuccess for success, others for failure.
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530235 */
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000236 Cc getUserName(const uint8_t userId, std::string& userName);
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530237
238 /** @brief to set user name
239 *
240 * @param[in] userId - user id
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000241 * @param[in] userName - user name
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530242 *
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000243 * @return ccSuccess for success, others for failure.
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530244 */
jayaprakash Mutyala76363302020-02-14 23:50:38 +0000245 Cc setUserName(const uint8_t userId, const std::string& userName);
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530246
Richard Marian Thomaiyar282e79b2018-11-13 19:00:58 +0530247 /** @brief to set user enabled state
248 *
249 * @param[in] userId - user id
250 * @param[in] enabledState - enabled state of the user
251 *
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000252 * @return ccSuccess for success, others for failure.
Richard Marian Thomaiyar282e79b2018-11-13 19:00:58 +0530253 */
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000254 Cc setUserEnabledState(const uint8_t userId, const bool& enabledState);
Richard Marian Thomaiyar282e79b2018-11-13 19:00:58 +0530255
Suryakanth Sekar90b00c72019-01-16 10:37:57 +0530256 /** @brief to set user password
257 *
258 * @param[in] userId - user id
259 * @param[in] userPassword - new password of the user
260 *
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000261 * @return ccSuccess for success, others for failure.
Suryakanth Sekar90b00c72019-01-16 10:37:57 +0530262 */
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000263 Cc setUserPassword(const uint8_t userId, const char* userPassword);
Suryakanth Sekar90b00c72019-01-16 10:37:57 +0530264
Richard Marian Thomaiyar788362c2019-04-14 15:12:47 +0530265 /** @brief to set special user password
266 *
267 * @param[in] userName - user name
268 * @param[in] userPassword - new password of the user
269 *
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000270 * @return ccSuccess for success, others for failure.
Richard Marian Thomaiyar788362c2019-04-14 15:12:47 +0530271 */
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000272 Cc setSpecialUserPassword(const std::string& userName,
Vernon Mauery1e22a0f2021-07-30 13:36:54 -0700273 const SecureString& userPassword);
Richard Marian Thomaiyar788362c2019-04-14 15:12:47 +0530274
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530275 /** @brief to set user privilege and access details
276 *
277 * @param[in] userId - user id
278 * @param[in] chNum - channel number
279 * @param[in] privAccess - privilege access
280 * @param[in] otherPrivUpdates - other privilege update flag to update ipmi
281 * enable, link authentication and access callback
282 *
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000283 * @return ccSuccess for success, others for failure.
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530284 */
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000285 Cc setUserPrivilegeAccess(const uint8_t userId, const uint8_t chNum,
286 const UserPrivAccess& privAccess,
287 const bool& otherPrivUpdates);
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530288
Saravanan Palanisamy77381f12019-05-15 22:33:17 +0000289 /** @brief to get user payload access details from userInfo entry.
290 *
291 * @param[in] userInfo - userInfo entry in usersTbl.
292 * @param[out] stdPayload - stdPayloadEnables1 in a 2D-array.
293 * @param[out] oemPayload - oemPayloadEnables1 in a 2D-array.
294 *
295 * @details Update the given 2D-arrays using the payload access details
296 * available in the given userInfo entry (from usersTbl).
297 * This 2D-array will be mapped to a JSON object (which will be written to
298 * a JSON file subsequently).
299 */
300 void readPayloadAccessFromUserInfo(
301 const UserInfo& userInfo,
302 std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>&
303 stdPayload,
304 std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>&
305 oemPayload);
306
307 /** @brief to update user payload access details in userInfo entry.
308 *
309 * @param[in] stdPayload - stdPayloadEnables1 in a 2D-array.
310 * @param[in] oemPayload - oemPayloadEnables1 in a 2D-array.
311 * @param[out] userInfo - userInfo entry in usersTbl.
312 *
313 * @details Update user payload access details of a given userInfo
314 * entry (in usersTbl) with the information provided in given 2D-arrays.
315 * This 2D-array was created out of a JSON object (which was created by
316 * parsing a JSON file).
317 */
318 void updatePayloadAccessInUserInfo(
319 const std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>&
320 stdPayload,
321 const std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>&
322 oemPayload,
323 UserInfo& userInfo);
324
325 /** @brief to set user payload access details
326 *
327 * @param[in] chNum - channel number
328 * @param[in] operation - Enable / Disable
329 * @param[in] userId - user id
330 * @param[in] payloadAccess - payload access
331 *
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000332 * @return ccSuccess for success, others for failure.
Saravanan Palanisamy77381f12019-05-15 22:33:17 +0000333 */
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000334 Cc setUserPayloadAccess(const uint8_t chNum, const uint8_t operation,
335 const uint8_t userId,
336 const PayloadAccess& payloadAccess);
Saravanan Palanisamy77381f12019-05-15 22:33:17 +0000337
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530338 /** @brief reads user management related data from configuration file
339 *
340 */
341 void readUserData();
342
343 /** @brief writes user management related data to configuration file
344 *
345 */
346 void writeUserData();
347
348 /** @brief Funtion which checks and reload configuration file data if
349 * needed.
350 *
351 */
352 void checkAndReloadUserData();
353
354 /** @brief provides user details from D-Bus user property data
355 *
356 * @param[in] properties - D-Bus user property
357 * @param[out] usrGrps - user group details
358 * @param[out] usrPriv - user privilege
359 * @param[out] usrEnabled - enabled state of the user.
360 *
361 * @return 0 for success, -errno for failure.
362 */
363 void getUserProperties(const DbusUserObjProperties& properties,
364 std::vector<std::string>& usrGrps,
365 std::string& usrPriv, bool& usrEnabled);
366
367 /** @brief provides user details from D-Bus user object data
368 *
369 * @param[in] userObjs - D-Bus user object
370 * @param[out] usrGrps - user group details
371 * @param[out] usrPriv - user privilege
372 * @param[out] usrEnabled - enabled state of the user.
373 *
374 * @return 0 for success, -errno for failure.
375 */
376 int getUserObjProperties(const DbusUserObjValue& userObjs,
377 std::vector<std::string>& usrGrps,
378 std::string& usrPriv, bool& usrEnabled);
379
380 /** @brief function to add user entry information to the configuration
381 *
382 * @param[in] userName - user name
383 * @param[in] priv - privilege of the user
384 * @param[in] enabled - enabled state of the user
385 *
386 * @return true for success, false for failure
387 */
388 bool addUserEntry(const std::string& userName, const std::string& priv,
389 const bool& enabled);
390
391 /** @brief function to delete user entry based on user index
392 *
393 * @param[in] usrIdx - user index
394 *
395 */
396 void deleteUserIndex(const size_t& usrIdx);
397
398 /** @brief function to get users table
399 *
400 */
401 UsersTbl* getUsersTblPtr();
402
403 std::unique_ptr<boost::interprocess::named_recursive_mutex> userMutex{
404 nullptr};
405
406 private:
407 UsersTbl usersTbl;
408 std::vector<std::string> availablePrivileges;
409 std::vector<std::string> availableGroups;
Patrick Williams5d82f472022-07-22 19:26:53 -0500410 sdbusplus::bus_t bus;
Jayaprakash Mutyala08d3d062021-10-01 16:01:57 +0000411 std::timespec fileLastUpdatedTime;
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530412 bool signalHndlrObject = false;
413 boost::interprocess::file_lock sigHndlrLock;
414 boost::interprocess::file_lock mutexCleanupLock;
415
416 /** @brief function to get user configuration file timestamp
417 *
418 * @return time stamp or -EIO for failure
419 */
Jayaprakash Mutyala08d3d062021-10-01 16:01:57 +0000420 std::timespec getUpdatedFileTime();
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530421
422 /** @brief function to available system privileges and groups
423 *
424 */
425 void getSystemPrivAndGroups();
426
427 /** @brief function to init user data from configuration & D-Bus objects
arun-pmbbe728c2020-01-10 15:18:04 +0530428 * and to register for signals
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530429 *
430 */
arun-pmbbe728c2020-01-10 15:18:04 +0530431 void cacheUserDataFile();
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530432};
Snehalatha Venkatesh61024d72021-04-08 16:24:39 +0000433
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530434} // namespace ipmi