xref: /openbmc/phosphor-host-ipmid/user_channel/user_mgmt.hpp (revision fbc6c9d743d22682f3753841071b8460ad50b5d9)
1  /*.
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  
19  #include <boost/interprocess/sync/file_lock.hpp>
20  #include <boost/interprocess/sync/named_recursive_mutex.hpp>
21  #include <ipmid/api.hpp>
22  #include <sdbusplus/bus.hpp>
23  
24  #include <cstdint>
25  #include <ctime>
26  #include <variant>
27  
28  namespace ipmi
29  {
30  
31  using DbusUserPropVariant =
32      std::variant<std::vector<std::string>, std::string, bool>;
33  
34  using DbusUserObjPath = sdbusplus::message::object_path;
35  
36  using DbusUserObjProperties =
37      std::vector<std::pair<std::string, DbusUserPropVariant>>;
38  
39  using DbusUserObjValue = std::map<std::string, DbusUserObjProperties>;
40  
41  /**
42   * @enum User update events.
43   */
44  enum class UserUpdateEvent
45  {
46      reservedEvent,
47      userCreated,
48      userDeleted,
49      userRenamed,
50      userGrpUpdated,
51      userPrivUpdated,
52      userStateUpdated
53  };
54  
55  /** @struct UserPrivAccess
56   *
57   *  Structure for user privilege access (refer spec sec 22.22)
58   */
59  struct UserPrivAccess
60  {
61      uint8_t privilege;
62      bool ipmiEnabled;
63      bool linkAuthEnabled;
64      bool accessCallback;
65  };
66  
67  /** @struct UserInfo
68   *
69   *  Structure for user related information
70   */
71  struct UserInfo
72  {
73      uint8_t userName[ipmiMaxUserName];
74      UserPrivAccess userPrivAccess[ipmiMaxChannels];
75      bool userEnabled;
76      bool userInSystem;
77      bool fixedUserName;
78      PayloadAccess payloadAccess[ipmiMaxChannels];
79  };
80  
81  /** @struct UsersTbl
82   *
83   *  Structure for array of user related information
84   */
85  struct UsersTbl
86  {
87      //+1 to map with UserId directly. UserId 0 is reserved.
88      UserInfo user[ipmiMaxUsers + 1];
89  };
90  
91  /** @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   */
98  bool pamUserCheckAuthenticate(std::string_view username,
99                                std::string_view password);
100  
101  class UserAccess;
102  
103  UserAccess& getUserAccessObject();
104  
105  class 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       */
122      static bool isValidChannel(const uint8_t chNum);
123  
124      /** @brief determines valid userId
125       *
126       *  @param[in] userId - user id
127       *
128       *  @return true if valid, false otherwise
129       */
130      static bool isValidUserId(const uint8_t userId);
131  
132      /** @brief determines valid user privilege
133       *
134       *  @param[in] priv - Privilege
135       *
136       *  @return true if valid, false otherwise
137       */
138      static bool isValidPrivilege(const uint8_t priv);
139  
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       */
168      bool isValidUserName(const std::string& userName);
169  
170      /** @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  
176      /** @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       */
191      UserInfo* getUserInfo(const uint8_t userId);
192  
193      /** @brief sets user information
194       *
195       *  @param[in] userId - user id
196       *  @param[in] userInfo - user information
197       *
198       */
199      void setUserInfo(const uint8_t userId, UserInfo* userInfo);
200  
201      /** @brief provides user name
202       *
203       *  @param[in] userId - user id
204       *  @param[out] userName - user name
205       *
206       *  @return ccSuccess for success, others for failure.
207       */
208      Cc getUserName(const uint8_t userId, std::string& userName);
209  
210      /** @brief to set user name
211       *
212       *  @param[in] userId - user id
213       *  @param[in] userName - user name
214       *
215       *  @return ccSuccess for success, others for failure.
216       */
217      Cc setUserName(const uint8_t userId, const std::string& userName);
218  
219      /** @brief to set user enabled state
220       *
221       *  @param[in] userId - user id
222       *  @param[in] enabledState - enabled state of the user
223       *
224       *  @return ccSuccess for success, others for failure.
225       */
226      Cc setUserEnabledState(const uint8_t userId, const bool& enabledState);
227  
228      /** @brief to set user password
229       *
230       *  @param[in] userId - user id
231       *  @param[in] userPassword  - new password of the user
232       *
233       *  @return ccSuccess for success, others for failure.
234       */
235      Cc setUserPassword(const uint8_t userId, const char* userPassword);
236  
237      /** @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 ccSuccess for success, others for failure.
243       */
244      Cc setSpecialUserPassword(const std::string& userName,
245                                const SecureString& userPassword);
246  
247      /** @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 ccSuccess for success, others for failure.
256       */
257      Cc setUserPrivilegeAccess(const uint8_t userId, const uint8_t chNum,
258                                const UserPrivAccess& privAccess,
259                                const bool& otherPrivUpdates);
260  
261      /** @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 ccSuccess for success, others for failure.
305       */
306      Cc setUserPayloadAccess(const uint8_t chNum, const uint8_t operation,
307                              const uint8_t userId,
308                              const PayloadAccess& payloadAccess);
309  
310      /** @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;
382      sdbusplus::bus_t bus;
383      std::timespec fileLastUpdatedTime;
384      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       */
392      std::timespec getUpdatedFileTime();
393  
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
400       * and to register for signals
401       *
402       */
403      void cacheUserDataFile();
404  };
405  
406  } // namespace ipmi
407