blob: 159b15c3b218afe48dd71425e58370575414c3af [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
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 */
167 bool isValidUserName(const char* userNameInChar);
168
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 *
205 * @return IPMI_CC_OK for success, others for failure.
206 */
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530207 ipmi_ret_t 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
212 * @param[in] userNameInChar - user name
213 *
214 * @return IPMI_CC_OK for success, others for failure.
215 */
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530216 ipmi_ret_t setUserName(const uint8_t userId, const char* userNameInChar);
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 *
223 * @return IPMI_CC_OK for success, others for failure.
224 */
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530225 ipmi_ret_t setUserEnabledState(const uint8_t userId,
Richard Marian Thomaiyar282e79b2018-11-13 19:00:58 +0530226 const bool& enabledState);
227
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 *
233 * @return IPMI_CC_OK for success, others for failure.
234 */
235 ipmi_ret_t setUserPassword(const uint8_t userId, const char* userPassword);
236
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 *
242 * @return IPMI_CC_OK for success, others for failure.
243 */
244 ipmi_ret_t setSpecialUserPassword(const std::string& userName,
245 const std::string& userPassword);
246
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 *
255 * @return IPMI_CC_OK for success, others for failure.
256 */
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530257 ipmi_ret_t setUserPrivilegeAccess(const uint8_t userId, const uint8_t chNum,
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530258 const UserPrivAccess& privAccess,
259 const bool& otherPrivUpdates);
260
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 *
304 * @return IPMI_CC_OK for success, others for failure.
305 */
306 ipmi_ret_t setUserPayloadAccess(const uint8_t chNum,
307 const uint8_t operation,
308 const uint8_t userId,
309 const PayloadAccess& payloadAccess);
310
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530311 /** @brief reads user management related data from configuration file
312 *
313 */
314 void readUserData();
315
316 /** @brief writes user management related data to configuration file
317 *
318 */
319 void writeUserData();
320
321 /** @brief Funtion which checks and reload configuration file data if
322 * needed.
323 *
324 */
325 void checkAndReloadUserData();
326
327 /** @brief provides user details from D-Bus user property data
328 *
329 * @param[in] properties - D-Bus user property
330 * @param[out] usrGrps - user group details
331 * @param[out] usrPriv - user privilege
332 * @param[out] usrEnabled - enabled state of the user.
333 *
334 * @return 0 for success, -errno for failure.
335 */
336 void getUserProperties(const DbusUserObjProperties& properties,
337 std::vector<std::string>& usrGrps,
338 std::string& usrPriv, bool& usrEnabled);
339
340 /** @brief provides user details from D-Bus user object data
341 *
342 * @param[in] userObjs - D-Bus user object
343 * @param[out] usrGrps - user group details
344 * @param[out] usrPriv - user privilege
345 * @param[out] usrEnabled - enabled state of the user.
346 *
347 * @return 0 for success, -errno for failure.
348 */
349 int getUserObjProperties(const DbusUserObjValue& userObjs,
350 std::vector<std::string>& usrGrps,
351 std::string& usrPriv, bool& usrEnabled);
352
353 /** @brief function to add user entry information to the configuration
354 *
355 * @param[in] userName - user name
356 * @param[in] priv - privilege of the user
357 * @param[in] enabled - enabled state of the user
358 *
359 * @return true for success, false for failure
360 */
361 bool addUserEntry(const std::string& userName, const std::string& priv,
362 const bool& enabled);
363
364 /** @brief function to delete user entry based on user index
365 *
366 * @param[in] usrIdx - user index
367 *
368 */
369 void deleteUserIndex(const size_t& usrIdx);
370
371 /** @brief function to get users table
372 *
373 */
374 UsersTbl* getUsersTblPtr();
375
376 std::unique_ptr<boost::interprocess::named_recursive_mutex> userMutex{
377 nullptr};
378
379 private:
380 UsersTbl usersTbl;
381 std::vector<std::string> availablePrivileges;
382 std::vector<std::string> availableGroups;
383 sdbusplus::bus::bus bus;
384 std::time_t fileLastUpdatedTime;
385 bool signalHndlrObject = false;
386 boost::interprocess::file_lock sigHndlrLock;
387 boost::interprocess::file_lock mutexCleanupLock;
388
389 /** @brief function to get user configuration file timestamp
390 *
391 * @return time stamp or -EIO for failure
392 */
393 std::time_t getUpdatedFileTime();
394
395 /** @brief function to available system privileges and groups
396 *
397 */
398 void getSystemPrivAndGroups();
399
400 /** @brief function to init user data from configuration & D-Bus objects
arun-pmbbe728c2020-01-10 15:18:04 +0530401 * and to register for signals
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530402 *
403 */
arun-pmbbe728c2020-01-10 15:18:04 +0530404 void cacheUserDataFile();
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530405};
406} // namespace ipmi