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