blob: ac163f7bb979babad679f539320b16478c7c61d0 [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
Nan Zhou332fb9d2022-10-25 00:07:03 +000067bool removeStringFromCSV(std::string& csvStr, const std::string& delStr);
68
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +053069/** @class UserMgr
70 * @brief Responsible for managing user accounts over the D-Bus interface.
71 */
Ratan Gupta1af12232018-11-03 00:35:38 +053072class UserMgr : public Ifaces
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +053073{
74 public:
75 UserMgr() = delete;
76 ~UserMgr() = default;
Patrick Williams9638afb2021-02-22 17:16:24 -060077 UserMgr(const UserMgr&) = delete;
78 UserMgr& operator=(const UserMgr&) = delete;
79 UserMgr(UserMgr&&) = delete;
80 UserMgr& operator=(UserMgr&&) = delete;
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +053081
82 /** @brief Constructs UserMgr object.
83 *
84 * @param[in] bus - sdbusplus handler
85 * @param[in] path - D-Bus path
86 */
Patrick Williamsb3ef4e12022-07-22 19:26:55 -050087 UserMgr(sdbusplus::bus_t& bus, const char* path);
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +053088
89 /** @brief create user method.
90 * This method creates a new user as requested
91 *
92 * @param[in] userName - Name of the user which has to be created
93 * @param[in] groupNames - Group names list, to which user has to be added.
94 * @param[in] priv - Privilege of the user.
95 * @param[in] enabled - State of the user enabled / disabled.
96 */
97 void createUser(std::string userName, std::vector<std::string> groupNames,
98 std::string priv, bool enabled) override;
99
100 /** @brief rename user method.
101 * This method renames the user as requested
102 *
103 * @param[in] userName - current name of the user
104 * @param[in] newUserName - new user name to which it has to be renamed.
105 */
106 void renameUser(std::string userName, std::string newUserName) override;
107
108 /** @brief delete user method.
109 * This method deletes the user as requested
110 *
111 * @param[in] userName - Name of the user which has to be deleted
112 */
113 void deleteUser(std::string userName);
114
115 /** @brief Update user groups & privilege.
116 * This method updates user groups & privilege
117 *
118 * @param[in] userName - user name, for which update is requested
119 * @param[in] groupName - Group to be updated..
120 * @param[in] priv - Privilege to be updated.
121 */
Patrick Williams9638afb2021-02-22 17:16:24 -0600122 void updateGroupsAndPriv(const std::string& userName,
123 const std::vector<std::string>& groups,
124 const std::string& priv);
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +0530125
126 /** @brief Update user enabled state.
127 * This method enables / disables user
128 *
129 * @param[in] userName - user name, for which update is requested
130 * @param[in] enabled - enable / disable the user
131 */
Patrick Williams9638afb2021-02-22 17:16:24 -0600132 void userEnable(const std::string& userName, bool enabled);
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +0530133
Richard Marian Thomaiyar9164fd92018-06-13 16:51:00 +0530134 /** @brief update minimum password length requirement
135 *
136 * @param[in] val - minimum password length
137 * @return - minimum password length
138 */
139 uint8_t minPasswordLength(uint8_t val) override;
140
141 /** @brief update old password history count
142 *
143 * @param[in] val - number of times old passwords has to be avoided
144 * @return - number of times old password has to be avoided
145 */
146 uint8_t rememberOldPasswordTimes(uint8_t val) override;
147
148 /** @brief update maximum number of failed login attempt before locked
149 * out.
150 *
151 * @param[in] val - number of allowed attempt
152 * @return - number of allowed attempt
153 */
154 uint16_t maxLoginAttemptBeforeLockout(uint16_t val) override;
155
156 /** @brief update timeout to unlock the account
157 *
158 * @param[in] val - value in seconds
159 * @return - value in seconds
160 */
161 uint32_t accountUnlockTimeout(uint32_t val) override;
162
Richard Marian Thomaiyarc7045192018-06-13 16:51:00 +0530163 /** @brief lists user locked state for failed attempt
164 *
165 * @param[in] - user name
166 * @return - true / false indicating user locked / un-locked
167 **/
Patrick Williams9638afb2021-02-22 17:16:24 -0600168 virtual bool userLockedForFailedAttempt(const std::string& userName);
Richard Marian Thomaiyarc7045192018-06-13 16:51:00 +0530169
170 /** @brief lists user locked state for failed attempt
171 *
172 * @param[in]: user name
173 * @param[in]: value - false -unlock user account, true - no action taken
174 **/
Patrick Williams9638afb2021-02-22 17:16:24 -0600175 bool userLockedForFailedAttempt(const std::string& userName,
176 const bool& value);
Richard Marian Thomaiyarc7045192018-06-13 16:51:00 +0530177
Joseph Reynolds3ab6cc22020-03-03 14:09:03 -0600178 /** @brief shows if the user's password is expired
179 *
180 * @param[in]: user name
181 * @return - true / false indicating user password expired
182 **/
Patrick Williams9638afb2021-02-22 17:16:24 -0600183 virtual bool userPasswordExpired(const std::string& userName);
Joseph Reynolds3ab6cc22020-03-03 14:09:03 -0600184
Ratan Guptaaeaf9412019-02-11 04:41:52 -0600185 /** @brief returns user info
186 * Checks if user is local user, then returns map of properties of user.
187 * like user privilege, list of user groups, user enabled state and user
188 * locked state. If its not local user, then it checks if its a ldap user,
189 * then it gets the privilege mapping of the LDAP group.
190 *
191 * @param[in] - user name
192 * @return - map of user properties
193 **/
194 UserInfoMap getUserInfo(std::string userName) override;
195
Nan Zhoue48085d2022-10-25 00:07:04 +0000196 protected:
197 /** @brief get pam argument value
198 * method to get argument value from pam configuration
199 *
200 * @param[in] moduleName - name of the module from where arg has to be read
201 * @param[in] argName - argument name
202 * @param[out] argValue - argument value
203 *
204 * @return 0 - success state of the function
205 */
206 int getPamModuleArgValue(const std::string& moduleName,
207 const std::string& argName, std::string& argValue);
208
209 /** @brief set pam argument value
210 * method to set argument value in pam configuration
211 *
212 * @param[in] moduleName - name of the module in which argument value has
213 * to be set
214 * @param[in] argName - argument name
215 * @param[out] argValue - argument value
216 *
217 * @return 0 - success state of the function
218 */
219 int setPamModuleArgValue(const std::string& moduleName,
220 const std::string& argName,
221 const std::string& argValue);
222
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +0530223 private:
224 /** @brief sdbusplus handler */
Patrick Williamsb3ef4e12022-07-22 19:26:55 -0500225 sdbusplus::bus_t& bus;
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +0530226
227 /** @brief object path */
228 const std::string path;
229
230 /** @brief privilege manager container */
231 std::vector<std::string> privMgr = {"priv-admin", "priv-operator",
Richard Marian Thomaiyar32be2962019-11-08 17:21:53 +0530232 "priv-user", "priv-noaccess"};
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +0530233
234 /** @brief groups manager container */
235 std::vector<std::string> groupsMgr = {"web", "redfish", "ipmi", "ssh"};
236
237 /** @brief map container to hold users object */
238 using UserName = std::string;
239 std::unordered_map<UserName, std::unique_ptr<phosphor::user::Users>>
240 usersList;
241
242 /** @brief get users in group
243 * method to get group user list
244 *
245 * @param[in] groupName - group name
246 *
247 * @return userList - list of users in the group.
248 */
Patrick Williams9638afb2021-02-22 17:16:24 -0600249 std::vector<std::string> getUsersInGroup(const std::string& groupName);
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +0530250
251 /** @brief get user & SSH users list
252 * method to get the users and ssh users list.
253 *
254 *@return - vector of User & SSH user lists
255 */
256 UserSSHLists getUserAndSshGrpList(void);
257
258 /** @brief check for user presence
259 * method to check for user existence
260 *
261 * @param[in] userName - name of the user
262 * @return -true if user exists and false if not.
263 */
Patrick Williams9638afb2021-02-22 17:16:24 -0600264 bool isUserExist(const std::string& userName);
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +0530265
266 /** @brief check user exists
267 * method to check whether user exist, and throw if not.
268 *
269 * @param[in] userName - name of the user
270 */
Patrick Williams9638afb2021-02-22 17:16:24 -0600271 void throwForUserDoesNotExist(const std::string& userName);
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +0530272
273 /** @brief check user does not exist
274 * method to check whether does not exist, and throw if exists.
275 *
276 * @param[in] userName - name of the user
277 */
Patrick Williams9638afb2021-02-22 17:16:24 -0600278 void throwForUserExists(const std::string& userName);
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +0530279
280 /** @brief check user name constraints
281 * method to check user name constraints and throw if failed.
282 *
283 * @param[in] userName - name of the user
284 * @param[in] groupNames - user groups
285 */
286 void
Patrick Williams9638afb2021-02-22 17:16:24 -0600287 throwForUserNameConstraints(const std::string& userName,
288 const std::vector<std::string>& groupNames);
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +0530289
290 /** @brief check group user count
291 * method to check max group user count, and throw if limit reached
292 *
293 * @param[in] groupNames - group name
294 */
Patrick Williams9638afb2021-02-22 17:16:24 -0600295 void throwForMaxGrpUserCount(const std::vector<std::string>& groupNames);
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +0530296
297 /** @brief check for valid privielge
298 * method to check valid privilege, and throw if invalid
299 *
300 * @param[in] priv - privilege of the user
301 */
Patrick Williams9638afb2021-02-22 17:16:24 -0600302 void throwForInvalidPrivilege(const std::string& priv);
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +0530303
304 /** @brief check for valid groups
305 * method to check valid groups, and throw if invalid
306 *
307 * @param[in] groupNames - user groups
308 */
Patrick Williams9638afb2021-02-22 17:16:24 -0600309 void throwForInvalidGroups(const std::vector<std::string>& groupName);
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +0530310
311 /** @brief get user enabled state
312 * method to get user enabled state.
313 *
314 * @param[in] userName - name of the user
315 * @return - user enabled status (true/false)
316 */
Patrick Williams9638afb2021-02-22 17:16:24 -0600317 bool isUserEnabled(const std::string& userName);
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +0530318
319 /** @brief initialize the user manager objects
320 * method to initialize the user manager objects accordingly
321 *
322 */
323 void initUserObjects(void);
324
325 /** @brief get IPMI user count
326 * method to get IPMI user count
327 *
328 * @return - returns user count
329 */
330 size_t getIpmiUsersCount(void);
Richard Marian Thomaiyar9164fd92018-06-13 16:51:00 +0530331
Ratan Guptaaeaf9412019-02-11 04:41:52 -0600332 /** @brief get service name
333 * method to get dbus service name
334 *
335 * @param[in] path - object path
336 * @param[in] intf - interface
337 * @return - service name
338 */
Patrick Williams9638afb2021-02-22 17:16:24 -0600339 std::string getServiceName(std::string&& path, std::string&& intf);
Ratan Guptaaeaf9412019-02-11 04:41:52 -0600340
raviteja-b8cc44052019-02-27 23:29:36 -0600341 protected:
Ratan Guptaaeaf9412019-02-11 04:41:52 -0600342 /** @brief get LDAP group name
343 * method to get LDAP group name for the given LDAP user
344 *
345 * @param[in] - userName
346 * @return - group name
347 */
Patrick Williams9638afb2021-02-22 17:16:24 -0600348 virtual std::string getLdapGroupName(const std::string& userName);
Ratan Guptaaeaf9412019-02-11 04:41:52 -0600349
350 /** @brief get privilege mapper object
351 * method to get dbus privilege mapper object
352 *
353 * @return - map of user object
354 */
raviteja-b8cc44052019-02-27 23:29:36 -0600355 virtual DbusUserObj getPrivilegeMapperObject(void);
356
357 friend class TestUserMgr;
Nan Zhoue48085d2022-10-25 00:07:04 +0000358
359 std::string pamPasswdConfigFile;
360 std::string pamAuthConfigFile;
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +0530361};
362
363} // namespace user
364} // namespace phosphor