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