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 <sdbusplus/bus.hpp>
18 #include <sdbusplus/server/object.hpp>
19 #include <xyz/openbmc_project/User/Manager/server.hpp>
20 #include <xyz/openbmc_project/User/AccountPolicy/server.hpp>
21 #include <unordered_map>
22 #include <variant>
23 #include "users.hpp"
24 
25 namespace phosphor
26 {
27 namespace user
28 {
29 
30 using UserMgrIface = sdbusplus::xyz::openbmc_project::User::server::Manager;
31 using UserSSHLists =
32     std::pair<std::vector<std::string>, std::vector<std::string>>;
33 using AccountPolicyIface =
34     sdbusplus::xyz::openbmc_project::User::server::AccountPolicy;
35 
36 using Privilege = std::string;
37 using GroupList = std::vector<std::string>;
38 using UserEnabled = bool;
39 using PropertyName = std::string;
40 using ServiceEnabled = bool;
41 
42 using UserInfo = std::variant<Privilege, GroupList, UserEnabled>;
43 using UserInfoMap = std::map<PropertyName, UserInfo>;
44 
45 using DbusUserObjPath = sdbusplus::message::object_path;
46 
47 using DbusUserPropVariant =
48     sdbusplus::message::variant<Privilege, ServiceEnabled>;
49 
50 using DbusUserObjProperties =
51     std::vector<std::pair<PropertyName, DbusUserPropVariant>>;
52 
53 using Interface = std::string;
54 
55 using DbusUserObjValue = std::map<Interface, DbusUserObjProperties>;
56 
57 using DbusUserObj = std::map<DbusUserObjPath, DbusUserObjValue>;
58 
59 /** @class UserMgr
60  *  @brief Responsible for managing user accounts over the D-Bus interface.
61  */
62 class UserMgr : public UserMgrIface, AccountPolicyIface
63 {
64   public:
65     UserMgr() = delete;
66     ~UserMgr() = default;
67     UserMgr(const UserMgr &) = delete;
68     UserMgr &operator=(const UserMgr &) = delete;
69     UserMgr(UserMgr &&) = delete;
70     UserMgr &operator=(UserMgr &&) = delete;
71 
72     /** @brief Constructs UserMgr object.
73      *
74      *  @param[in] bus  - sdbusplus handler
75      *  @param[in] path - D-Bus path
76      */
77     UserMgr(sdbusplus::bus::bus &bus, const char *path);
78 
79     /** @brief create user method.
80      *  This method creates a new user as requested
81      *
82      *  @param[in] userName - Name of the user which has to be created
83      *  @param[in] groupNames - Group names list, to which user has to be added.
84      *  @param[in] priv - Privilege of the user.
85      *  @param[in] enabled - State of the user enabled / disabled.
86      */
87     void createUser(std::string userName, std::vector<std::string> groupNames,
88                     std::string priv, bool enabled) override;
89 
90     /** @brief rename user method.
91      *  This method renames the user as requested
92      *
93      *  @param[in] userName - current name of the user
94      *  @param[in] newUserName - new user name to which it has to be renamed.
95      */
96     void renameUser(std::string userName, std::string newUserName) override;
97 
98     /** @brief delete user method.
99      *  This method deletes the user as requested
100      *
101      *  @param[in] userName - Name of the user which has to be deleted
102      */
103     void deleteUser(std::string userName);
104 
105     /** @brief Update user groups & privilege.
106      *  This method updates user groups & privilege
107      *
108      *  @param[in] userName - user name, for which update is requested
109      *  @param[in] groupName - Group to be updated..
110      *  @param[in] priv - Privilege to be updated.
111      */
112     void updateGroupsAndPriv(const std::string &userName,
113                              const std::vector<std::string> &groups,
114                              const std::string &priv);
115 
116     /** @brief Update user enabled state.
117      *  This method enables / disables user
118      *
119      *  @param[in] userName - user name, for which update is requested
120      *  @param[in] enabled - enable / disable the user
121      */
122     void userEnable(const std::string &userName, bool enabled);
123 
124     /** @brief update minimum password length requirement
125      *
126      *  @param[in] val - minimum password length
127      *  @return - minimum password length
128      */
129     uint8_t minPasswordLength(uint8_t val) override;
130 
131     /** @brief update old password history count
132      *
133      *  @param[in] val - number of times old passwords has to be avoided
134      *  @return - number of times old password has to be avoided
135      */
136     uint8_t rememberOldPasswordTimes(uint8_t val) override;
137 
138     /** @brief update maximum number of failed login attempt before locked
139      *  out.
140      *
141      *  @param[in] val - number of allowed attempt
142      *  @return - number of allowed attempt
143      */
144     uint16_t maxLoginAttemptBeforeLockout(uint16_t val) override;
145 
146     /** @brief update timeout to unlock the account
147      *
148      *  @param[in] val - value in seconds
149      *  @return - value in seconds
150      */
151     uint32_t accountUnlockTimeout(uint32_t val) override;
152 
153     /** @brief lists user locked state for failed attempt
154      *
155      * @param[in] - user name
156      * @return - true / false indicating user locked / un-locked
157      **/
158     virtual bool userLockedForFailedAttempt(const std::string &userName);
159 
160     /** @brief lists user locked state for failed attempt
161      *
162      * @param[in]: user name
163      * @param[in]: value - false -unlock user account, true - no action taken
164      **/
165     bool userLockedForFailedAttempt(const std::string &userName,
166                                     const bool &value);
167 
168     /** @brief returns user info
169      * Checks if user is local user, then returns map of properties of user.
170      * like user privilege, list of user groups, user enabled state and user
171      * locked state. If its not local user, then it checks if its a ldap user,
172      * then it gets the privilege mapping of the LDAP group.
173      *
174      * @param[in] - user name
175      * @return -  map of user properties
176      **/
177     UserInfoMap getUserInfo(std::string userName) override;
178 
179   private:
180     /** @brief sdbusplus handler */
181     sdbusplus::bus::bus &bus;
182 
183     /** @brief object path */
184     const std::string path;
185 
186     /** @brief privilege manager container */
187     std::vector<std::string> privMgr = {"priv-admin", "priv-operator",
188                                         "priv-user", "priv-callback"};
189 
190     /** @brief groups manager container */
191     std::vector<std::string> groupsMgr = {"web", "redfish", "ipmi", "ssh"};
192 
193     /** @brief map container to hold users object */
194     using UserName = std::string;
195     std::unordered_map<UserName, std::unique_ptr<phosphor::user::Users>>
196         usersList;
197 
198     /** @brief get users in group
199      *  method to get group user list
200      *
201      *  @param[in] groupName - group name
202      *
203      *  @return userList  - list of users in the group.
204      */
205     std::vector<std::string> getUsersInGroup(const std::string &groupName);
206 
207     /** @brief get user & SSH users list
208      *  method to get the users and ssh users list.
209      *
210      *@return - vector of User & SSH user lists
211      */
212     UserSSHLists getUserAndSshGrpList(void);
213 
214     /** @brief check for user presence
215      *  method to check for user existence
216      *
217      *  @param[in] userName - name of the user
218      *  @return -true if user exists and false if not.
219      */
220     bool isUserExist(const std::string &userName);
221 
222     /** @brief check user exists
223      *  method to check whether user exist, and throw if not.
224      *
225      *  @param[in] userName - name of the user
226      */
227     void throwForUserDoesNotExist(const std::string &userName);
228 
229     /** @brief check user does not exist
230      *  method to check whether does not exist, and throw if exists.
231      *
232      *  @param[in] userName - name of the user
233      */
234     void throwForUserExists(const std::string &userName);
235 
236     /** @brief check user name constraints
237      *  method to check user name constraints and throw if failed.
238      *
239      *  @param[in] userName - name of the user
240      *  @param[in] groupNames - user groups
241      */
242     void
243         throwForUserNameConstraints(const std::string &userName,
244                                     const std::vector<std::string> &groupNames);
245 
246     /** @brief check group user count
247      *  method to check max group user count, and throw if limit reached
248      *
249      *  @param[in] groupNames - group name
250      */
251     void throwForMaxGrpUserCount(const std::vector<std::string> &groupNames);
252 
253     /** @brief check for valid privielge
254      *  method to check valid privilege, and throw if invalid
255      *
256      *  @param[in] priv - privilege of the user
257      */
258     void throwForInvalidPrivilege(const std::string &priv);
259 
260     /** @brief check for valid groups
261      *  method to check valid groups, and throw if invalid
262      *
263      *  @param[in] groupNames - user groups
264      */
265     void throwForInvalidGroups(const std::vector<std::string> &groupName);
266 
267     /** @brief get user enabled state
268      *  method to get user enabled state.
269      *
270      *  @param[in] userName - name of the user
271      *  @return - user enabled status (true/false)
272      */
273     bool isUserEnabled(const std::string &userName);
274 
275     /** @brief initialize the user manager objects
276      *  method to initialize the user manager objects accordingly
277      *
278      */
279     void initUserObjects(void);
280 
281     /** @brief get IPMI user count
282      *  method to get IPMI user count
283      *
284      * @return - returns user count
285      */
286     size_t getIpmiUsersCount(void);
287 
288     /** @brief get pam argument value
289      *  method to get argument value from pam configuration
290      *
291      *  @param[in] moduleName - name of the module from where arg has to be read
292      *  @param[in] argName - argument name
293      *  @param[out] argValue - argument value
294      *
295      *  @return 0 - success state of the function
296      */
297     int getPamModuleArgValue(const std::string &moduleName,
298                              const std::string &argName, std::string &argValue);
299 
300     /** @brief set pam argument value
301      *  method to set argument value in pam configuration
302      *
303      *  @param[in] moduleName - name of the module in which argument value has
304      * to be set
305      *  @param[in] argName - argument name
306      *  @param[out] argValue - argument value
307      *
308      *  @return 0 - success state of the function
309      */
310     int setPamModuleArgValue(const std::string &moduleName,
311                              const std::string &argName,
312                              const std::string &argValue);
313 
314     /** @brief get service name
315      *  method to get dbus service name
316      *
317      *  @param[in] path - object path
318      *  @param[in] intf - interface
319      *  @return - service name
320      */
321     std::string getServiceName(std::string &&path, std::string &&intf);
322 
323   protected:
324     /** @brief get LDAP group name
325      *  method to get LDAP group name for the given LDAP user
326      *
327      *  @param[in] - userName
328      *  @return - group name
329      */
330     virtual std::string getLdapGroupName(const std::string &userName);
331 
332     /** @brief get privilege mapper object
333      *  method to get dbus privilege mapper object
334      *
335      *  @return - map of user object
336      */
337     virtual DbusUserObj getPrivilegeMapperObject(void);
338 
339     friend class TestUserMgr;
340 };
341 
342 } // namespace user
343 } // namespace phosphor
344