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 <ipmid/api.h>
20 
21 #include <boost/interprocess/sync/file_lock.hpp>
22 #include <boost/interprocess/sync/named_recursive_mutex.hpp>
23 #include <cstdint>
24 #include <ctime>
25 #include <sdbusplus/bus.hpp>
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 };
79 
80 /** @struct UsersTbl
81  *
82  *  Structure for array of user related information
83  */
84 struct UsersTbl
85 {
86     //+1 to map with UserId directly. UserId 0 is reserved.
87     UserInfo user[ipmiMaxUsers + 1];
88 };
89 
90 class UserAccess;
91 
92 UserAccess& getUserAccessObject();
93 
94 class UserAccess
95 {
96   public:
97     UserAccess(const UserAccess&) = delete;
98     UserAccess& operator=(const UserAccess&) = delete;
99     UserAccess(UserAccess&&) = delete;
100     UserAccess& operator=(UserAccess&&) = delete;
101 
102     ~UserAccess();
103     UserAccess();
104 
105     /** @brief determines valid channel
106      *
107      *  @param[in] chNum - channel number
108      *
109      *  @return true if valid, false otherwise
110      */
111     static bool isValidChannel(const uint8_t chNum);
112 
113     /** @brief determines valid userId
114      *
115      *  @param[in] userId - user id
116      *
117      *  @return true if valid, false otherwise
118      */
119     static bool isValidUserId(const uint8_t userId);
120 
121     /** @brief determines valid user privilege
122      *
123      *  @param[in] priv - Privilege
124      *
125      *  @return true if valid, false otherwise
126      */
127     static bool isValidPrivilege(const uint8_t priv);
128 
129     /** @brief determines sync index to be mapped with common-user-management
130      *
131      *  @return Index which will be used as sync index
132      */
133     static uint8_t getUsrMgmtSyncIndex();
134 
135     /** @brief Converts system privilege to IPMI privilege
136      *
137      *  @param[in] value - Privilege in string
138      *
139      *  @return CommandPrivilege - IPMI privilege type
140      */
141     static CommandPrivilege convertToIPMIPrivilege(const std::string& value);
142 
143     /** @brief Converts IPMI privilege to system privilege
144      *
145      *  @param[in] value - IPMI privilege
146      *
147      *  @return System privilege in string
148      */
149     static std::string convertToSystemPrivilege(const CommandPrivilege& value);
150 
151     /** @brief determines whether user name is valid
152      *
153      *  @param[in] userNameInChar - user name
154      *
155      *  @return true if valid, false otherwise
156      */
157     bool isValidUserName(const char* userNameInChar);
158 
159     /** @brief provides user id of the user
160      *
161      *  @param[in] userName - user name
162      *
163      *  @return user id of the user, else invalid user id (0xFF), if user not
164      * found
165      */
166     uint8_t getUserId(const std::string& userName);
167 
168     /** @brief provides user information
169      *
170      *  @param[in] userId - user id
171      *
172      *  @return UserInfo for the specified user id
173      */
174     UserInfo* getUserInfo(const uint8_t userId);
175 
176     /** @brief sets user information
177      *
178      *  @param[in] userId - user id
179      *  @param[in] userInfo - user information
180      *
181      */
182     void setUserInfo(const uint8_t userId, UserInfo* userInfo);
183 
184     /** @brief provides user name
185      *
186      *  @param[in] userId - user id
187      *  @param[out] userName - user name
188      *
189      *  @return IPMI_CC_OK for success, others for failure.
190      */
191     ipmi_ret_t getUserName(const uint8_t userId, std::string& userName);
192 
193     /** @brief to set user name
194      *
195      *  @param[in] userId - user id
196      *  @param[in] userNameInChar - user name
197      *
198      *  @return IPMI_CC_OK for success, others for failure.
199      */
200     ipmi_ret_t setUserName(const uint8_t userId, const char* userNameInChar);
201 
202     /** @brief to set user enabled state
203      *
204      *  @param[in] userId - user id
205      *  @param[in] enabledState - enabled state of the user
206      *
207      *  @return IPMI_CC_OK for success, others for failure.
208      */
209     ipmi_ret_t setUserEnabledState(const uint8_t userId,
210                                    const bool& enabledState);
211 
212     /** @brief to set user password
213      *
214      *  @param[in] userId - user id
215      *  @param[in] userPassword  - new password of the user
216      *
217      *  @return IPMI_CC_OK for success, others for failure.
218      */
219     ipmi_ret_t setUserPassword(const uint8_t userId, const char* userPassword);
220 
221     /** @brief to set special user password
222      *
223      *  @param[in] userName - user name
224      *  @param[in] userPassword  - new password of the user
225      *
226      *  @return IPMI_CC_OK for success, others for failure.
227      */
228     ipmi_ret_t setSpecialUserPassword(const std::string& userName,
229                                       const std::string& userPassword);
230 
231     /** @brief to set user privilege and access details
232      *
233      *  @param[in] userId - user id
234      *  @param[in] chNum - channel number
235      *  @param[in] privAccess - privilege access
236      *  @param[in] otherPrivUpdates - other privilege update flag to update ipmi
237      * enable, link authentication and access callback
238      *
239      *  @return IPMI_CC_OK for success, others for failure.
240      */
241     ipmi_ret_t setUserPrivilegeAccess(const uint8_t userId, const uint8_t chNum,
242                                       const UserPrivAccess& privAccess,
243                                       const bool& otherPrivUpdates);
244 
245     /** @brief reads user management related data from configuration file
246      *
247      */
248     void readUserData();
249 
250     /** @brief writes user management related data to configuration file
251      *
252      */
253     void writeUserData();
254 
255     /** @brief Funtion which checks and reload configuration file data if
256      * needed.
257      *
258      */
259     void checkAndReloadUserData();
260 
261     /** @brief provides user details from D-Bus user property data
262      *
263      *  @param[in] properties - D-Bus user property
264      *  @param[out] usrGrps - user group details
265      *  @param[out] usrPriv - user privilege
266      *  @param[out] usrEnabled - enabled state of the user.
267      *
268      *  @return 0 for success, -errno for failure.
269      */
270     void getUserProperties(const DbusUserObjProperties& properties,
271                            std::vector<std::string>& usrGrps,
272                            std::string& usrPriv, bool& usrEnabled);
273 
274     /** @brief provides user details from D-Bus user object data
275      *
276      *  @param[in] userObjs - D-Bus user object
277      *  @param[out] usrGrps - user group details
278      *  @param[out] usrPriv - user privilege
279      *  @param[out] usrEnabled - enabled state of the user.
280      *
281      *  @return 0 for success, -errno for failure.
282      */
283     int getUserObjProperties(const DbusUserObjValue& userObjs,
284                              std::vector<std::string>& usrGrps,
285                              std::string& usrPriv, bool& usrEnabled);
286 
287     /** @brief function to add user entry information to the configuration
288      *
289      *  @param[in] userName - user name
290      *  @param[in] priv - privilege of the user
291      *  @param[in] enabled - enabled state of the user
292      *
293      *  @return true for success, false for failure
294      */
295     bool addUserEntry(const std::string& userName, const std::string& priv,
296                       const bool& enabled);
297 
298     /** @brief function to delete user entry based on user index
299      *
300      *  @param[in] usrIdx - user index
301      *
302      */
303     void deleteUserIndex(const size_t& usrIdx);
304 
305     /** @brief function to get users table
306      *
307      */
308     UsersTbl* getUsersTblPtr();
309 
310     std::unique_ptr<boost::interprocess::named_recursive_mutex> userMutex{
311         nullptr};
312 
313   private:
314     UsersTbl usersTbl;
315     std::vector<std::string> availablePrivileges;
316     std::vector<std::string> availableGroups;
317     sdbusplus::bus::bus bus;
318     std::time_t fileLastUpdatedTime;
319     bool signalHndlrObject = false;
320     boost::interprocess::file_lock sigHndlrLock;
321     boost::interprocess::file_lock mutexCleanupLock;
322 
323     /** @brief function to get user configuration file timestamp
324      *
325      *  @return time stamp or -EIO for failure
326      */
327     std::time_t getUpdatedFileTime();
328 
329     /** @brief function to available system privileges and groups
330      *
331      */
332     void getSystemPrivAndGroups();
333 
334     /** @brief function to init user data from configuration & D-Bus objects
335      *
336      */
337     void initUserDataFile();
338 };
339 } // namespace ipmi
340