blob: 5c1553b3bd79a3026d11811189c00333fc673cca [file] [log] [blame]
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +05301/*
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
Patrick Williams9638afb2021-02-22 17:16:24 -060017#include "users.hpp"
18
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +053019#include <sdbusplus/bus.hpp>
20#include <sdbusplus/server/object.hpp>
Richard Marian Thomaiyar9164fd92018-06-13 16:51:00 +053021#include <xyz/openbmc_project/User/AccountPolicy/server.hpp>
Patrick Williams9638afb2021-02-22 17:16:24 -060022#include <xyz/openbmc_project/User/Manager/server.hpp>
23
Nan Zhoue47c09d2022-10-25 00:06:41 +000024#include <span>
25#include <string>
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +053026#include <unordered_map>
Ratan Guptaaeaf9412019-02-11 04:41:52 -060027#include <variant>
Nan Zhoue47c09d2022-10-25 00:06:41 +000028#include <vector>
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +053029
30namespace phosphor
31{
32namespace user
33{
34
35using UserMgrIface = sdbusplus::xyz::openbmc_project::User::server::Manager;
36using UserSSHLists =
37 std::pair<std::vector<std::string>, std::vector<std::string>>;
Richard Marian Thomaiyar9164fd92018-06-13 16:51:00 +053038using AccountPolicyIface =
39 sdbusplus::xyz::openbmc_project::User::server::AccountPolicy;
40
Patrick Williamsb3ef4e12022-07-22 19:26:55 -050041using Ifaces = sdbusplus::server::object_t<UserMgrIface, AccountPolicyIface>;
Ratan Gupta1af12232018-11-03 00:35:38 +053042
Ratan Guptaaeaf9412019-02-11 04:41:52 -060043using Privilege = std::string;
44using GroupList = std::vector<std::string>;
45using UserEnabled = bool;
46using PropertyName = std::string;
Ravi Teja5fe724a2019-05-07 05:14:42 -050047using ServiceEnabled = bool;
Ratan Guptaaeaf9412019-02-11 04:41:52 -060048
49using UserInfo = std::variant<Privilege, GroupList, UserEnabled>;
50using UserInfoMap = std::map<PropertyName, UserInfo>;
51
52using DbusUserObjPath = sdbusplus::message::object_path;
53
Patrick Williamsfdf09372020-05-13 18:01:45 -050054using DbusUserPropVariant = std::variant<Privilege, ServiceEnabled>;
Ratan Guptaaeaf9412019-02-11 04:41:52 -060055
56using DbusUserObjProperties =
57 std::vector<std::pair<PropertyName, DbusUserPropVariant>>;
58
59using Interface = std::string;
60
61using DbusUserObjValue = std::map<Interface, DbusUserObjProperties>;
62
63using DbusUserObj = std::map<DbusUserObjPath, DbusUserObjValue>;
64
Nan Zhoue47c09d2022-10-25 00:06:41 +000065std::string getCSVFromVector(std::span<const std::string> vec);
66
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +053067/** @class UserMgr
68 * @brief Responsible for managing user accounts over the D-Bus interface.
69 */
Ratan Gupta1af12232018-11-03 00:35:38 +053070class UserMgr : public Ifaces
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +053071{
72 public:
73 UserMgr() = delete;
74 ~UserMgr() = default;
Patrick Williams9638afb2021-02-22 17:16:24 -060075 UserMgr(const UserMgr&) = delete;
76 UserMgr& operator=(const UserMgr&) = delete;
77 UserMgr(UserMgr&&) = delete;
78 UserMgr& operator=(UserMgr&&) = delete;
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +053079
80 /** @brief Constructs UserMgr object.
81 *
82 * @param[in] bus - sdbusplus handler
83 * @param[in] path - D-Bus path
84 */
Patrick Williamsb3ef4e12022-07-22 19:26:55 -050085 UserMgr(sdbusplus::bus_t& bus, const char* path);
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +053086
87 /** @brief create user method.
88 * This method creates a new user as requested
89 *
90 * @param[in] userName - Name of the user which has to be created
91 * @param[in] groupNames - Group names list, to which user has to be added.
92 * @param[in] priv - Privilege of the user.
93 * @param[in] enabled - State of the user enabled / disabled.
94 */
95 void createUser(std::string userName, std::vector<std::string> groupNames,
96 std::string priv, bool enabled) override;
97
98 /** @brief rename user method.
99 * This method renames the user as requested
100 *
101 * @param[in] userName - current name of the user
102 * @param[in] newUserName - new user name to which it has to be renamed.
103 */
104 void renameUser(std::string userName, std::string newUserName) override;
105
106 /** @brief delete user method.
107 * This method deletes the user as requested
108 *
109 * @param[in] userName - Name of the user which has to be deleted
110 */
111 void deleteUser(std::string userName);
112
113 /** @brief Update user groups & privilege.
114 * This method updates user groups & privilege
115 *
116 * @param[in] userName - user name, for which update is requested
117 * @param[in] groupName - Group to be updated..
118 * @param[in] priv - Privilege to be updated.
119 */
Patrick Williams9638afb2021-02-22 17:16:24 -0600120 void updateGroupsAndPriv(const std::string& userName,
121 const std::vector<std::string>& groups,
122 const std::string& priv);
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +0530123
124 /** @brief Update user enabled state.
125 * This method enables / disables user
126 *
127 * @param[in] userName - user name, for which update is requested
128 * @param[in] enabled - enable / disable the user
129 */
Patrick Williams9638afb2021-02-22 17:16:24 -0600130 void userEnable(const std::string& userName, bool enabled);
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +0530131
Richard Marian Thomaiyar9164fd92018-06-13 16:51:00 +0530132 /** @brief update minimum password length requirement
133 *
134 * @param[in] val - minimum password length
135 * @return - minimum password length
136 */
137 uint8_t minPasswordLength(uint8_t val) override;
138
139 /** @brief update old password history count
140 *
141 * @param[in] val - number of times old passwords has to be avoided
142 * @return - number of times old password has to be avoided
143 */
144 uint8_t rememberOldPasswordTimes(uint8_t val) override;
145
146 /** @brief update maximum number of failed login attempt before locked
147 * out.
148 *
149 * @param[in] val - number of allowed attempt
150 * @return - number of allowed attempt
151 */
152 uint16_t maxLoginAttemptBeforeLockout(uint16_t val) override;
153
154 /** @brief update timeout to unlock the account
155 *
156 * @param[in] val - value in seconds
157 * @return - value in seconds
158 */
159 uint32_t accountUnlockTimeout(uint32_t val) override;
160
Richard Marian Thomaiyarc7045192018-06-13 16:51:00 +0530161 /** @brief lists user locked state for failed attempt
162 *
163 * @param[in] - user name
164 * @return - true / false indicating user locked / un-locked
165 **/
Patrick Williams9638afb2021-02-22 17:16:24 -0600166 virtual bool userLockedForFailedAttempt(const std::string& userName);
Richard Marian Thomaiyarc7045192018-06-13 16:51:00 +0530167
168 /** @brief lists user locked state for failed attempt
169 *
170 * @param[in]: user name
171 * @param[in]: value - false -unlock user account, true - no action taken
172 **/
Patrick Williams9638afb2021-02-22 17:16:24 -0600173 bool userLockedForFailedAttempt(const std::string& userName,
174 const bool& value);
Richard Marian Thomaiyarc7045192018-06-13 16:51:00 +0530175
Joseph Reynolds3ab6cc22020-03-03 14:09:03 -0600176 /** @brief shows if the user's password is expired
177 *
178 * @param[in]: user name
179 * @return - true / false indicating user password expired
180 **/
Patrick Williams9638afb2021-02-22 17:16:24 -0600181 virtual bool userPasswordExpired(const std::string& userName);
Joseph Reynolds3ab6cc22020-03-03 14:09:03 -0600182
Ratan Guptaaeaf9412019-02-11 04:41:52 -0600183 /** @brief returns user info
184 * Checks if user is local user, then returns map of properties of user.
185 * like user privilege, list of user groups, user enabled state and user
186 * locked state. If its not local user, then it checks if its a ldap user,
187 * then it gets the privilege mapping of the LDAP group.
188 *
189 * @param[in] - user name
190 * @return - map of user properties
191 **/
192 UserInfoMap getUserInfo(std::string userName) override;
193
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +0530194 private:
195 /** @brief sdbusplus handler */
Patrick Williamsb3ef4e12022-07-22 19:26:55 -0500196 sdbusplus::bus_t& bus;
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +0530197
198 /** @brief object path */
199 const std::string path;
200
201 /** @brief privilege manager container */
202 std::vector<std::string> privMgr = {"priv-admin", "priv-operator",
Richard Marian Thomaiyar32be2962019-11-08 17:21:53 +0530203 "priv-user", "priv-noaccess"};
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +0530204
205 /** @brief groups manager container */
206 std::vector<std::string> groupsMgr = {"web", "redfish", "ipmi", "ssh"};
207
208 /** @brief map container to hold users object */
209 using UserName = std::string;
210 std::unordered_map<UserName, std::unique_ptr<phosphor::user::Users>>
211 usersList;
212
213 /** @brief get users in group
214 * method to get group user list
215 *
216 * @param[in] groupName - group name
217 *
218 * @return userList - list of users in the group.
219 */
Patrick Williams9638afb2021-02-22 17:16:24 -0600220 std::vector<std::string> getUsersInGroup(const std::string& groupName);
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +0530221
222 /** @brief get user & SSH users list
223 * method to get the users and ssh users list.
224 *
225 *@return - vector of User & SSH user lists
226 */
227 UserSSHLists getUserAndSshGrpList(void);
228
229 /** @brief check for user presence
230 * method to check for user existence
231 *
232 * @param[in] userName - name of the user
233 * @return -true if user exists and false if not.
234 */
Patrick Williams9638afb2021-02-22 17:16:24 -0600235 bool isUserExist(const std::string& userName);
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +0530236
237 /** @brief check user exists
238 * method to check whether user exist, and throw if not.
239 *
240 * @param[in] userName - name of the user
241 */
Patrick Williams9638afb2021-02-22 17:16:24 -0600242 void throwForUserDoesNotExist(const std::string& userName);
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +0530243
244 /** @brief check user does not exist
245 * method to check whether does not exist, and throw if exists.
246 *
247 * @param[in] userName - name of the user
248 */
Patrick Williams9638afb2021-02-22 17:16:24 -0600249 void throwForUserExists(const std::string& userName);
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +0530250
251 /** @brief check user name constraints
252 * method to check user name constraints and throw if failed.
253 *
254 * @param[in] userName - name of the user
255 * @param[in] groupNames - user groups
256 */
257 void
Patrick Williams9638afb2021-02-22 17:16:24 -0600258 throwForUserNameConstraints(const std::string& userName,
259 const std::vector<std::string>& groupNames);
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +0530260
261 /** @brief check group user count
262 * method to check max group user count, and throw if limit reached
263 *
264 * @param[in] groupNames - group name
265 */
Patrick Williams9638afb2021-02-22 17:16:24 -0600266 void throwForMaxGrpUserCount(const std::vector<std::string>& groupNames);
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +0530267
268 /** @brief check for valid privielge
269 * method to check valid privilege, and throw if invalid
270 *
271 * @param[in] priv - privilege of the user
272 */
Patrick Williams9638afb2021-02-22 17:16:24 -0600273 void throwForInvalidPrivilege(const std::string& priv);
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +0530274
275 /** @brief check for valid groups
276 * method to check valid groups, and throw if invalid
277 *
278 * @param[in] groupNames - user groups
279 */
Patrick Williams9638afb2021-02-22 17:16:24 -0600280 void throwForInvalidGroups(const std::vector<std::string>& groupName);
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +0530281
282 /** @brief get user enabled state
283 * method to get user enabled state.
284 *
285 * @param[in] userName - name of the user
286 * @return - user enabled status (true/false)
287 */
Patrick Williams9638afb2021-02-22 17:16:24 -0600288 bool isUserEnabled(const std::string& userName);
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +0530289
290 /** @brief initialize the user manager objects
291 * method to initialize the user manager objects accordingly
292 *
293 */
294 void initUserObjects(void);
295
296 /** @brief get IPMI user count
297 * method to get IPMI user count
298 *
299 * @return - returns user count
300 */
301 size_t getIpmiUsersCount(void);
Richard Marian Thomaiyar9164fd92018-06-13 16:51:00 +0530302
303 /** @brief get pam argument value
304 * method to get argument value from pam configuration
305 *
306 * @param[in] moduleName - name of the module from where arg has to be read
307 * @param[in] argName - argument name
308 * @param[out] argValue - argument value
309 *
310 * @return 0 - success state of the function
311 */
Patrick Williams9638afb2021-02-22 17:16:24 -0600312 int getPamModuleArgValue(const std::string& moduleName,
313 const std::string& argName, std::string& argValue);
Richard Marian Thomaiyar9164fd92018-06-13 16:51:00 +0530314
315 /** @brief set pam argument value
316 * method to set argument value in pam configuration
317 *
318 * @param[in] moduleName - name of the module in which argument value has
319 * to be set
320 * @param[in] argName - argument name
321 * @param[out] argValue - argument value
322 *
323 * @return 0 - success state of the function
324 */
Patrick Williams9638afb2021-02-22 17:16:24 -0600325 int setPamModuleArgValue(const std::string& moduleName,
326 const std::string& argName,
327 const std::string& argValue);
Ratan Guptaaeaf9412019-02-11 04:41:52 -0600328
329 /** @brief get service name
330 * method to get dbus service name
331 *
332 * @param[in] path - object path
333 * @param[in] intf - interface
334 * @return - service name
335 */
Patrick Williams9638afb2021-02-22 17:16:24 -0600336 std::string getServiceName(std::string&& path, std::string&& intf);
Ratan Guptaaeaf9412019-02-11 04:41:52 -0600337
raviteja-b8cc44052019-02-27 23:29:36 -0600338 protected:
Ratan Guptaaeaf9412019-02-11 04:41:52 -0600339 /** @brief get LDAP group name
340 * method to get LDAP group name for the given LDAP user
341 *
342 * @param[in] - userName
343 * @return - group name
344 */
Patrick Williams9638afb2021-02-22 17:16:24 -0600345 virtual std::string getLdapGroupName(const std::string& userName);
Ratan Guptaaeaf9412019-02-11 04:41:52 -0600346
347 /** @brief get privilege mapper object
348 * method to get dbus privilege mapper object
349 *
350 * @return - map of user object
351 */
raviteja-b8cc44052019-02-27 23:29:36 -0600352 virtual DbusUserObj getPrivilegeMapperObject(void);
353
354 friend class TestUserMgr;
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +0530355};
356
357} // namespace user
358} // namespace phosphor