blob: 624b2bacdbdd0e6892d459325bc29c5cc3049fc4 [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
Nan Zhou49c81362022-10-25 00:07:08 +000019#include <boost/process/child.hpp>
20#include <boost/process/io.hpp>
21#include <phosphor-logging/elog-errors.hpp>
22#include <phosphor-logging/elog.hpp>
Jiaqing Zhao11ec6662022-07-05 20:55:34 +080023#include <phosphor-logging/lg2.hpp>
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +053024#include <sdbusplus/bus.hpp>
25#include <sdbusplus/server/object.hpp>
Nan Zhou49c81362022-10-25 00:07:08 +000026#include <xyz/openbmc_project/Common/error.hpp>
Richard Marian Thomaiyar9164fd92018-06-13 16:51:00 +053027#include <xyz/openbmc_project/User/AccountPolicy/server.hpp>
Patrick Williams9638afb2021-02-22 17:16:24 -060028#include <xyz/openbmc_project/User/Manager/server.hpp>
Abhilash Rajua1a754c2024-07-25 05:43:40 -050029#include <xyz/openbmc_project/User/MultiFactorAuthConfiguration/server.hpp>
30#include <xyz/openbmc_project/User/TOTPState/server.hpp>
Patrick Williams9638afb2021-02-22 17:16:24 -060031
Nan Zhoue47c09d2022-10-25 00:06:41 +000032#include <span>
33#include <string>
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +053034#include <unordered_map>
Ratan Guptaaeaf9412019-02-11 04:41:52 -060035#include <variant>
Nan Zhoue47c09d2022-10-25 00:06:41 +000036#include <vector>
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +053037
38namespace phosphor
39{
40namespace user
41{
42
Nan Zhou49c81362022-10-25 00:07:08 +000043inline constexpr size_t ipmiMaxUsers = 15;
44inline constexpr size_t maxSystemUsers = 30;
Nan Zhou4bc69812022-10-25 00:07:13 +000045inline constexpr uint8_t minPasswdLength = 8;
Nan Zhouda401fe2022-10-25 00:07:18 +000046inline constexpr size_t maxSystemGroupNameLength = 32;
47inline constexpr size_t maxSystemGroupCount = 64;
Nan Zhou49c81362022-10-25 00:07:08 +000048
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +053049using UserMgrIface = sdbusplus::xyz::openbmc_project::User::server::Manager;
50using UserSSHLists =
51 std::pair<std::vector<std::string>, std::vector<std::string>>;
Richard Marian Thomaiyar9164fd92018-06-13 16:51:00 +053052using AccountPolicyIface =
53 sdbusplus::xyz::openbmc_project::User::server::AccountPolicy;
54
Abhilash Rajua1a754c2024-07-25 05:43:40 -050055using MultiFactorAuthConfigurationIface =
56 sdbusplus::xyz::openbmc_project::User::server::MultiFactorAuthConfiguration;
57
58using TOTPStateIface = sdbusplus::xyz::openbmc_project::User::server::TOTPState;
59
60using Ifaces = sdbusplus::server::object_t<UserMgrIface, AccountPolicyIface,
61 MultiFactorAuthConfigurationIface,
62 TOTPStateIface>;
Ratan Gupta1af12232018-11-03 00:35:38 +053063
Ratan Guptaaeaf9412019-02-11 04:41:52 -060064using Privilege = std::string;
65using GroupList = std::vector<std::string>;
66using UserEnabled = bool;
67using PropertyName = std::string;
Ravi Teja5fe724a2019-05-07 05:14:42 -050068using ServiceEnabled = bool;
Ratan Guptaaeaf9412019-02-11 04:41:52 -060069
70using UserInfo = std::variant<Privilege, GroupList, UserEnabled>;
71using UserInfoMap = std::map<PropertyName, UserInfo>;
72
73using DbusUserObjPath = sdbusplus::message::object_path;
74
Patrick Williamsfdf09372020-05-13 18:01:45 -050075using DbusUserPropVariant = std::variant<Privilege, ServiceEnabled>;
Ratan Guptaaeaf9412019-02-11 04:41:52 -060076
Alexander Filippov75626582022-02-09 18:42:37 +030077using DbusUserObjProperties = std::map<PropertyName, DbusUserPropVariant>;
Ratan Guptaaeaf9412019-02-11 04:41:52 -060078
79using Interface = std::string;
80
81using DbusUserObjValue = std::map<Interface, DbusUserObjProperties>;
82
83using DbusUserObj = std::map<DbusUserObjPath, DbusUserObjValue>;
84
Abhilash Rajua1a754c2024-07-25 05:43:40 -050085using MultiFactorAuthType = sdbusplus::common::xyz::openbmc_project::user::
86 MultiFactorAuthConfiguration::Type;
Nan Zhoue47c09d2022-10-25 00:06:41 +000087std::string getCSVFromVector(std::span<const std::string> vec);
88
Nan Zhou332fb9d2022-10-25 00:07:03 +000089bool removeStringFromCSV(std::string& csvStr, const std::string& delStr);
90
Nan Zhou8a11d992022-10-25 00:07:06 +000091template <typename... ArgTypes>
Nan Zhou49c81362022-10-25 00:07:08 +000092std::vector<std::string> executeCmd(const char* path, ArgTypes&&... tArgs)
93{
94 std::vector<std::string> stdOutput;
95 boost::process::ipstream stdOutStream;
96 boost::process::child execProg(path, const_cast<char*>(tArgs)...,
97 boost::process::std_out > stdOutStream);
98 std::string stdOutLine;
99
100 while (stdOutStream && std::getline(stdOutStream, stdOutLine) &&
101 !stdOutLine.empty())
102 {
103 stdOutput.emplace_back(stdOutLine);
104 }
105
106 execProg.wait();
107
108 int retCode = execProg.exit_code();
109 if (retCode)
110 {
Jiaqing Zhao11ec6662022-07-05 20:55:34 +0800111 lg2::error("Command {PATH} execution failed, return code {RETCODE}",
112 "PATH", path, "RETCODE", retCode);
Nan Zhou49c81362022-10-25 00:07:08 +0000113 phosphor::logging::elog<
114 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure>();
115 }
116
117 return stdOutput;
118}
Nan Zhou8a11d992022-10-25 00:07:06 +0000119
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +0530120/** @class UserMgr
121 * @brief Responsible for managing user accounts over the D-Bus interface.
122 */
Ratan Gupta1af12232018-11-03 00:35:38 +0530123class UserMgr : public Ifaces
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +0530124{
125 public:
126 UserMgr() = delete;
127 ~UserMgr() = default;
Patrick Williams9638afb2021-02-22 17:16:24 -0600128 UserMgr(const UserMgr&) = delete;
129 UserMgr& operator=(const UserMgr&) = delete;
130 UserMgr(UserMgr&&) = delete;
131 UserMgr& operator=(UserMgr&&) = delete;
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +0530132
133 /** @brief Constructs UserMgr object.
134 *
135 * @param[in] bus - sdbusplus handler
136 * @param[in] path - D-Bus path
137 */
Patrick Williamsb3ef4e12022-07-22 19:26:55 -0500138 UserMgr(sdbusplus::bus_t& bus, const char* path);
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +0530139
140 /** @brief create user method.
141 * This method creates a new user as requested
142 *
143 * @param[in] userName - Name of the user which has to be created
144 * @param[in] groupNames - Group names list, to which user has to be added.
145 * @param[in] priv - Privilege of the user.
146 * @param[in] enabled - State of the user enabled / disabled.
147 */
148 void createUser(std::string userName, std::vector<std::string> groupNames,
149 std::string priv, bool enabled) override;
150
151 /** @brief rename user method.
152 * This method renames the user as requested
153 *
154 * @param[in] userName - current name of the user
155 * @param[in] newUserName - new user name to which it has to be renamed.
156 */
157 void renameUser(std::string userName, std::string newUserName) override;
158
159 /** @brief delete user method.
160 * This method deletes the user as requested
161 *
162 * @param[in] userName - Name of the user which has to be deleted
163 */
164 void deleteUser(std::string userName);
165
166 /** @brief Update user groups & privilege.
167 * This method updates user groups & privilege
168 *
169 * @param[in] userName - user name, for which update is requested
170 * @param[in] groupName - Group to be updated..
171 * @param[in] priv - Privilege to be updated.
172 */
Patrick Williams9638afb2021-02-22 17:16:24 -0600173 void updateGroupsAndPriv(const std::string& userName,
Nan Zhoufef63032022-10-25 00:07:12 +0000174 std::vector<std::string> groups,
Patrick Williams9638afb2021-02-22 17:16:24 -0600175 const std::string& priv);
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +0530176
177 /** @brief Update user enabled state.
178 * This method enables / disables user
179 *
180 * @param[in] userName - user name, for which update is requested
181 * @param[in] enabled - enable / disable the user
182 */
Patrick Williams9638afb2021-02-22 17:16:24 -0600183 void userEnable(const std::string& userName, bool enabled);
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +0530184
Denis Zlobine8edab52023-09-06 12:26:45 +0000185 /** @brief get user enabled state
186 * method to get user enabled state.
187 *
188 * @param[in] userName - name of the user
189 * @return - user enabled status (true/false)
190 */
191 virtual bool isUserEnabled(const std::string& userName);
192
Richard Marian Thomaiyar9164fd92018-06-13 16:51:00 +0530193 /** @brief update minimum password length requirement
194 *
195 * @param[in] val - minimum password length
196 * @return - minimum password length
197 */
198 uint8_t minPasswordLength(uint8_t val) override;
199
200 /** @brief update old password history count
201 *
202 * @param[in] val - number of times old passwords has to be avoided
203 * @return - number of times old password has to be avoided
204 */
205 uint8_t rememberOldPasswordTimes(uint8_t val) override;
206
207 /** @brief update maximum number of failed login attempt before locked
208 * out.
209 *
210 * @param[in] val - number of allowed attempt
211 * @return - number of allowed attempt
212 */
213 uint16_t maxLoginAttemptBeforeLockout(uint16_t val) override;
214
215 /** @brief update timeout to unlock the account
216 *
217 * @param[in] val - value in seconds
218 * @return - value in seconds
219 */
220 uint32_t accountUnlockTimeout(uint32_t val) override;
221
Jason M. Bills2d042d12023-03-28 15:32:45 -0700222 /** @brief parses the faillock output for locked user status
223 *
224 * @param[in] - output from faillock for the user
225 * @return - true / false indicating user locked / un-locked
226 **/
Patrick Williams88a82db2025-02-01 08:22:37 -0500227 bool parseFaillockForLockout(
228 const std::vector<std::string>& faillockOutput);
Jason M. Bills2d042d12023-03-28 15:32:45 -0700229
Richard Marian Thomaiyarc7045192018-06-13 16:51:00 +0530230 /** @brief lists user locked state for failed attempt
231 *
232 * @param[in] - user name
233 * @return - true / false indicating user locked / un-locked
234 **/
Patrick Williams9638afb2021-02-22 17:16:24 -0600235 virtual bool userLockedForFailedAttempt(const std::string& userName);
Richard Marian Thomaiyarc7045192018-06-13 16:51:00 +0530236
237 /** @brief lists user locked state for failed attempt
238 *
239 * @param[in]: user name
240 * @param[in]: value - false -unlock user account, true - no action taken
241 **/
Patrick Williams9638afb2021-02-22 17:16:24 -0600242 bool userLockedForFailedAttempt(const std::string& userName,
243 const bool& value);
Richard Marian Thomaiyarc7045192018-06-13 16:51:00 +0530244
Joseph Reynolds3ab6cc22020-03-03 14:09:03 -0600245 /** @brief shows if the user's password is expired
246 *
247 * @param[in]: user name
248 * @return - true / false indicating user password expired
249 **/
Patrick Williams9638afb2021-02-22 17:16:24 -0600250 virtual bool userPasswordExpired(const std::string& userName);
Joseph Reynolds3ab6cc22020-03-03 14:09:03 -0600251
Ratan Guptaaeaf9412019-02-11 04:41:52 -0600252 /** @brief returns user info
253 * Checks if user is local user, then returns map of properties of user.
254 * like user privilege, list of user groups, user enabled state and user
255 * locked state. If its not local user, then it checks if its a ldap user,
256 * then it gets the privilege mapping of the LDAP group.
257 *
258 * @param[in] - user name
259 * @return - map of user properties
260 **/
261 UserInfoMap getUserInfo(std::string userName) override;
262
Nan Zhou49c81362022-10-25 00:07:08 +0000263 /** @brief get IPMI user count
264 * method to get IPMI user count
265 *
266 * @return - returns user count
267 */
268 virtual size_t getIpmiUsersCount(void);
269
Nan Zhouda401fe2022-10-25 00:07:18 +0000270 void createGroup(std::string groupName) override;
271
272 void deleteGroup(std::string groupName) override;
Abhilash Rajua1a754c2024-07-25 05:43:40 -0500273 MultiFactorAuthType enabled() const override
274 {
275 return MultiFactorAuthConfigurationIface::enabled();
276 }
277 MultiFactorAuthType enabled(MultiFactorAuthType value,
278 bool skipSignal) override;
279 bool secretKeyRequired(std::string userName) override;
Nan Zhouda401fe2022-10-25 00:07:18 +0000280 static std::vector<std::string> readAllGroupsOnSystem();
281
Nan Zhoue48085d2022-10-25 00:07:04 +0000282 protected:
283 /** @brief get pam argument value
284 * method to get argument value from pam configuration
285 *
286 * @param[in] moduleName - name of the module from where arg has to be read
287 * @param[in] argName - argument name
288 * @param[out] argValue - argument value
289 *
290 * @return 0 - success state of the function
291 */
292 int getPamModuleArgValue(const std::string& moduleName,
293 const std::string& argName, std::string& argValue);
294
Jason M. Bills2d042d12023-03-28 15:32:45 -0700295 /** @brief get pam argument value
296 * method to get argument value from pam configuration
297 *
298 * @param[in] confFile - path of the module config file from where arg has
299 * to be read
300 * @param[in] argName - argument name
301 * @param[out] argValue - argument value
302 *
303 * @return 0 - success state of the function
304 */
305 int getPamModuleConfValue(const std::string& confFile,
306 const std::string& argName,
307 std::string& argValue);
308
Nan Zhoue48085d2022-10-25 00:07:04 +0000309 /** @brief set pam argument value
310 * method to set argument value in pam configuration
311 *
312 * @param[in] moduleName - name of the module in which argument value has
313 * to be set
314 * @param[in] argName - argument name
315 * @param[out] argValue - argument value
316 *
317 * @return 0 - success state of the function
318 */
319 int setPamModuleArgValue(const std::string& moduleName,
320 const std::string& argName,
321 const std::string& argValue);
322
Jason M. Bills2d042d12023-03-28 15:32:45 -0700323 /** @brief set pam argument value
324 * method to set argument value in pam configuration
325 *
326 * @param[in] confFile - path of the module config file in which argument
327 * value has to be set
328 * @param[in] argName - argument name
329 * @param[out] argValue - argument value
330 *
331 * @return 0 - success state of the function
332 */
333 int setPamModuleConfValue(const std::string& confFile,
334 const std::string& argName,
335 const std::string& argValue);
336
Nan Zhou8a11d992022-10-25 00:07:06 +0000337 /** @brief check for user presence
338 * method to check for user existence
339 *
340 * @param[in] userName - name of the user
341 * @return -true if user exists and false if not.
342 */
343 bool isUserExist(const std::string& userName);
344
Nan Zhou49c81362022-10-25 00:07:08 +0000345 size_t getNonIpmiUsersCount();
346
Nan Zhou8a11d992022-10-25 00:07:06 +0000347 /** @brief check user exists
348 * method to check whether user exist, and throw if not.
349 *
350 * @param[in] userName - name of the user
351 */
352 void throwForUserDoesNotExist(const std::string& userName);
353
354 /** @brief check user does not exist
355 * method to check whether does not exist, and throw if exists.
356 *
357 * @param[in] userName - name of the user
358 */
359 void throwForUserExists(const std::string& userName);
360
Nan Zhou40e44972022-10-25 00:07:07 +0000361 /** @brief check user name constraints
362 * method to check user name constraints and throw if failed.
363 *
364 * @param[in] userName - name of the user
365 * @param[in] groupNames - user groups
366 */
Patrick Williams88a82db2025-02-01 08:22:37 -0500367 void throwForUserNameConstraints(
368 const std::string& userName,
369 const std::vector<std::string>& groupNames);
Nan Zhou40e44972022-10-25 00:07:07 +0000370
Nan Zhou49c81362022-10-25 00:07:08 +0000371 /** @brief check group user count
372 * method to check max group user count, and throw if limit reached
373 *
374 * @param[in] groupNames - group name
375 */
376 void throwForMaxGrpUserCount(const std::vector<std::string>& groupNames);
377
378 virtual void executeUserAdd(const char* userName, const char* groups,
379 bool sshRequested, bool enabled);
380
381 virtual void executeUserDelete(const char* userName);
382
Jayanth Othayothac921a52023-07-21 03:48:55 -0500383 /** @brief clear user's failure records
384 * method to clear user fail records and throw if failed.
385 *
386 * @param[in] userName - name of the user
387 */
388 virtual void executeUserClearFailRecords(const char* userName);
389
Nan Zhouf25443e2022-10-25 00:07:11 +0000390 virtual void executeUserRename(const char* userName,
391 const char* newUserName);
392
Nan Zhoufef63032022-10-25 00:07:12 +0000393 virtual void executeUserModify(const char* userName, const char* newGroups,
394 bool sshRequested);
395
Nan Zhou6b6f2d82022-10-25 00:07:17 +0000396 virtual void executeUserModifyUserEnable(const char* userName,
397 bool enabled);
398
Nan Zhouda401fe2022-10-25 00:07:18 +0000399 virtual void executeGroupCreation(const char* groupName);
Nan Zhou86040c22022-11-17 02:08:24 +0000400
Nan Zhouda401fe2022-10-25 00:07:18 +0000401 virtual void executeGroupDeletion(const char* groupName);
Nan Zhou86040c22022-11-17 02:08:24 +0000402
Nan Zhoua2953032022-11-11 21:50:32 +0000403 virtual std::vector<std::string> getFailedAttempt(const char* userName);
404
Nan Zhou589aeb42022-10-25 00:07:09 +0000405 /** @brief check for valid privielge
406 * method to check valid privilege, and throw if invalid
407 *
408 * @param[in] priv - privilege of the user
409 */
410 void throwForInvalidPrivilege(const std::string& priv);
411
Nan Zhouecf88762022-10-25 00:07:10 +0000412 /** @brief check for valid groups
413 * method to check valid groups, and throw if invalid
414 *
415 * @param[in] groupNames - user groups
416 */
417 void throwForInvalidGroups(const std::vector<std::string>& groupName);
418
Nan Zhou4bc69812022-10-25 00:07:13 +0000419 void initializeAccountPolicy();
420
Nan Zhouda401fe2022-10-25 00:07:18 +0000421 /** @brief checks if the group creation meets all constraints
422 * @param groupName - group to check
423 */
424 void checkCreateGroupConstraints(const std::string& groupName);
425
426 /** @brief checks if the group deletion meets all constraints
427 * @param groupName - group to check
428 */
429 void checkDeleteGroupConstraints(const std::string& groupName);
430
431 /** @brief checks if the group name is legal and whether it's allowed to
432 * change. The daemon doesn't allow arbitrary group to be created
433 * @param groupName - group to check
434 */
435 void checkAndThrowForDisallowedGroupCreation(const std::string& groupName);
436
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +0530437 private:
438 /** @brief sdbusplus handler */
Patrick Williamsb3ef4e12022-07-22 19:26:55 -0500439 sdbusplus::bus_t& bus;
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +0530440
441 /** @brief object path */
442 const std::string path;
443
444 /** @brief privilege manager container */
Nan Zhouda401fe2022-10-25 00:07:18 +0000445 const std::vector<std::string> privMgr = {"priv-admin", "priv-operator",
446 "priv-user"};
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +0530447
448 /** @brief groups manager container */
Nan Zhouda401fe2022-10-25 00:07:18 +0000449 std::vector<std::string> groupsMgr;
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +0530450
451 /** @brief map container to hold users object */
452 using UserName = std::string;
453 std::unordered_map<UserName, std::unique_ptr<phosphor::user::Users>>
454 usersList;
455
456 /** @brief get users in group
457 * method to get group user list
458 *
459 * @param[in] groupName - group name
460 *
461 * @return userList - list of users in the group.
462 */
Patrick Williams9638afb2021-02-22 17:16:24 -0600463 std::vector<std::string> getUsersInGroup(const std::string& groupName);
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +0530464
465 /** @brief get user & SSH users list
466 * method to get the users and ssh users list.
467 *
468 *@return - vector of User & SSH user lists
469 */
470 UserSSHLists getUserAndSshGrpList(void);
471
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +0530472 /** @brief initialize the user manager objects
473 * method to initialize the user manager objects accordingly
474 *
475 */
476 void initUserObjects(void);
477
Ratan Guptaaeaf9412019-02-11 04:41:52 -0600478 /** @brief get service name
479 * method to get dbus service name
480 *
481 * @param[in] path - object path
482 * @param[in] intf - interface
483 * @return - service name
484 */
Patrick Williams9638afb2021-02-22 17:16:24 -0600485 std::string getServiceName(std::string&& path, std::string&& intf);
Ratan Guptaaeaf9412019-02-11 04:41:52 -0600486
Alexander Filippov75626582022-02-09 18:42:37 +0300487 /** @brief get primary group ID of specified user
Ratan Guptaaeaf9412019-02-11 04:41:52 -0600488 *
Alexander Filippov75626582022-02-09 18:42:37 +0300489 * @param[in] - userName
490 * @return - primary group ID
Ratan Guptaaeaf9412019-02-11 04:41:52 -0600491 */
Alexander Filippov75626582022-02-09 18:42:37 +0300492 virtual gid_t getPrimaryGroup(const std::string& userName) const;
Ratan Guptaaeaf9412019-02-11 04:41:52 -0600493
Alexander Filippov75626582022-02-09 18:42:37 +0300494 /** @brief check whether if the user is a member of the group
495 *
496 * @param[in] - userName
497 * @param[in] - ID of the user's primary group
498 * @param[in] - groupName
499 * @return - true if the user is a member of the group
500 */
501 virtual bool isGroupMember(const std::string& userName, gid_t primaryGid,
502 const std::string& groupName) const;
503
504 protected:
Ratan Guptaaeaf9412019-02-11 04:41:52 -0600505 /** @brief get privilege mapper object
506 * method to get dbus privilege mapper object
507 *
508 * @return - map of user object
509 */
raviteja-b8cc44052019-02-27 23:29:36 -0600510 virtual DbusUserObj getPrivilegeMapperObject(void);
511
512 friend class TestUserMgr;
Nan Zhoue48085d2022-10-25 00:07:04 +0000513
Jason M. Bills2d042d12023-03-28 15:32:45 -0700514 std::string faillockConfigFile;
Jason M. Bills3b280ec2023-08-15 16:15:48 -0700515 std::string pwHistoryConfigFile;
Jason M. Bills2d042d12023-03-28 15:32:45 -0700516 std::string pwQualityConfigFile;
Richard Marian Thomaiyar9f630d92018-05-24 10:49:10 +0530517};
518
519} // namespace user
520} // namespace phosphor