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