blob: 0c38374170d39bbe57babd8c4851ee28b1243f6f [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
169 /** @brief provides user id of the user
170 *
171 * @param[in] userName - user name
172 *
173 * @return user id of the user, else invalid user id (0xFF), if user not
174 * found
175 */
176 uint8_t getUserId(const std::string& userName);
177
178 /** @brief provides user information
179 *
180 * @param[in] userId - user id
181 *
182 * @return UserInfo for the specified user id
183 */
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530184 UserInfo* getUserInfo(const uint8_t userId);
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530185
186 /** @brief sets user information
187 *
188 * @param[in] userId - user id
189 * @param[in] userInfo - user information
190 *
191 */
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530192 void setUserInfo(const uint8_t userId, UserInfo* userInfo);
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530193
194 /** @brief provides user name
195 *
196 * @param[in] userId - user id
197 * @param[out] userName - user name
198 *
199 * @return IPMI_CC_OK for success, others for failure.
200 */
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530201 ipmi_ret_t getUserName(const uint8_t userId, std::string& userName);
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530202
203 /** @brief to set user name
204 *
205 * @param[in] userId - user id
206 * @param[in] userNameInChar - user name
207 *
208 * @return IPMI_CC_OK for success, others for failure.
209 */
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530210 ipmi_ret_t setUserName(const uint8_t userId, const char* userNameInChar);
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530211
Richard Marian Thomaiyar282e79b2018-11-13 19:00:58 +0530212 /** @brief to set user enabled state
213 *
214 * @param[in] userId - user id
215 * @param[in] enabledState - enabled state of the user
216 *
217 * @return IPMI_CC_OK for success, others for failure.
218 */
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530219 ipmi_ret_t setUserEnabledState(const uint8_t userId,
Richard Marian Thomaiyar282e79b2018-11-13 19:00:58 +0530220 const bool& enabledState);
221
Suryakanth Sekar90b00c72019-01-16 10:37:57 +0530222 /** @brief to set user password
223 *
224 * @param[in] userId - user id
225 * @param[in] userPassword - new password of the user
226 *
227 * @return IPMI_CC_OK for success, others for failure.
228 */
229 ipmi_ret_t setUserPassword(const uint8_t userId, const char* userPassword);
230
Richard Marian Thomaiyar788362c2019-04-14 15:12:47 +0530231 /** @brief to set special user password
232 *
233 * @param[in] userName - user name
234 * @param[in] userPassword - new password of the user
235 *
236 * @return IPMI_CC_OK for success, others for failure.
237 */
238 ipmi_ret_t setSpecialUserPassword(const std::string& userName,
239 const std::string& userPassword);
240
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530241 /** @brief to set user privilege and access details
242 *
243 * @param[in] userId - user id
244 * @param[in] chNum - channel number
245 * @param[in] privAccess - privilege access
246 * @param[in] otherPrivUpdates - other privilege update flag to update ipmi
247 * enable, link authentication and access callback
248 *
249 * @return IPMI_CC_OK for success, others for failure.
250 */
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530251 ipmi_ret_t setUserPrivilegeAccess(const uint8_t userId, const uint8_t chNum,
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530252 const UserPrivAccess& privAccess,
253 const bool& otherPrivUpdates);
254
Saravanan Palanisamy77381f12019-05-15 22:33:17 +0000255 /** @brief to get user payload access details from userInfo entry.
256 *
257 * @param[in] userInfo - userInfo entry in usersTbl.
258 * @param[out] stdPayload - stdPayloadEnables1 in a 2D-array.
259 * @param[out] oemPayload - oemPayloadEnables1 in a 2D-array.
260 *
261 * @details Update the given 2D-arrays using the payload access details
262 * available in the given userInfo entry (from usersTbl).
263 * This 2D-array will be mapped to a JSON object (which will be written to
264 * a JSON file subsequently).
265 */
266 void readPayloadAccessFromUserInfo(
267 const UserInfo& userInfo,
268 std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>&
269 stdPayload,
270 std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>&
271 oemPayload);
272
273 /** @brief to update user payload access details in userInfo entry.
274 *
275 * @param[in] stdPayload - stdPayloadEnables1 in a 2D-array.
276 * @param[in] oemPayload - oemPayloadEnables1 in a 2D-array.
277 * @param[out] userInfo - userInfo entry in usersTbl.
278 *
279 * @details Update user payload access details of a given userInfo
280 * entry (in usersTbl) with the information provided in given 2D-arrays.
281 * This 2D-array was created out of a JSON object (which was created by
282 * parsing a JSON file).
283 */
284 void updatePayloadAccessInUserInfo(
285 const std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>&
286 stdPayload,
287 const std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>&
288 oemPayload,
289 UserInfo& userInfo);
290
291 /** @brief to set user payload access details
292 *
293 * @param[in] chNum - channel number
294 * @param[in] operation - Enable / Disable
295 * @param[in] userId - user id
296 * @param[in] payloadAccess - payload access
297 *
298 * @return IPMI_CC_OK for success, others for failure.
299 */
300 ipmi_ret_t setUserPayloadAccess(const uint8_t chNum,
301 const uint8_t operation,
302 const uint8_t userId,
303 const PayloadAccess& payloadAccess);
304
Richard Marian Thomaiyar5a6b6362018-03-12 23:42:34 +0530305 /** @brief reads user management related data from configuration file
306 *
307 */
308 void readUserData();
309
310 /** @brief writes user management related data to configuration file
311 *
312 */
313 void writeUserData();
314
315 /** @brief Funtion which checks and reload configuration file data if
316 * needed.
317 *
318 */
319 void checkAndReloadUserData();
320
321 /** @brief provides user details from D-Bus user property data
322 *
323 * @param[in] properties - D-Bus user property
324 * @param[out] usrGrps - user group details
325 * @param[out] usrPriv - user privilege
326 * @param[out] usrEnabled - enabled state of the user.
327 *
328 * @return 0 for success, -errno for failure.
329 */
330 void getUserProperties(const DbusUserObjProperties& properties,
331 std::vector<std::string>& usrGrps,
332 std::string& usrPriv, bool& usrEnabled);
333
334 /** @brief provides user details from D-Bus user object data
335 *
336 * @param[in] userObjs - D-Bus user object
337 * @param[out] usrGrps - user group details
338 * @param[out] usrPriv - user privilege
339 * @param[out] usrEnabled - enabled state of the user.
340 *
341 * @return 0 for success, -errno for failure.
342 */
343 int getUserObjProperties(const DbusUserObjValue& userObjs,
344 std::vector<std::string>& usrGrps,
345 std::string& usrPriv, bool& usrEnabled);
346
347 /** @brief function to add user entry information to the configuration
348 *
349 * @param[in] userName - user name
350 * @param[in] priv - privilege of the user
351 * @param[in] enabled - enabled state of the user
352 *
353 * @return true for success, false for failure
354 */
355 bool addUserEntry(const std::string& userName, const std::string& priv,
356 const bool& enabled);
357
358 /** @brief function to delete user entry based on user index
359 *
360 * @param[in] usrIdx - user index
361 *
362 */
363 void deleteUserIndex(const size_t& usrIdx);
364
365 /** @brief function to get users table
366 *
367 */
368 UsersTbl* getUsersTblPtr();
369
370 std::unique_ptr<boost::interprocess::named_recursive_mutex> userMutex{
371 nullptr};
372
373 private:
374 UsersTbl usersTbl;
375 std::vector<std::string> availablePrivileges;
376 std::vector<std::string> availableGroups;
377 sdbusplus::bus::bus bus;
378 std::time_t fileLastUpdatedTime;
379 bool signalHndlrObject = false;
380 boost::interprocess::file_lock sigHndlrLock;
381 boost::interprocess::file_lock mutexCleanupLock;
382
383 /** @brief function to get user configuration file timestamp
384 *
385 * @return time stamp or -EIO for failure
386 */
387 std::time_t getUpdatedFileTime();
388
389 /** @brief function to available system privileges and groups
390 *
391 */
392 void getSystemPrivAndGroups();
393
394 /** @brief function to init user data from configuration & D-Bus objects
395 *
396 */
397 void initUserDataFile();
398};
399} // namespace ipmi