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