diff --git a/Makefile.am b/Makefile.am
index 7be3bc9..5e03648 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -66,6 +66,7 @@
 libuserlayer_LTLIBRARIES = libuserlayer.la
 libuserlayer_la_SOURCES = \
         user_channel/user_layer.cpp \
+        user_channel/user_mgmt.cpp \
         user_channel/passwd_mgr.cpp
 
 libuserlayer_la_LDFLAGS = $(SYSTEMD_LIBS) $(libmapper_LIBS) \
@@ -97,6 +98,7 @@
 	ipmi_fru_info_area.cpp \
 	read_fru_data.cpp \
 	sensordatahandler.cpp \
+	user_channel/usercommands.cpp \
 	$(libipmi20_BUILT_LIST)
 
 @CODE_COVERAGE_RULES@
diff --git a/apphandler.cpp b/apphandler.cpp
index fd58218..ac06f50 100644
--- a/apphandler.cpp
+++ b/apphandler.cpp
@@ -6,6 +6,7 @@
 #include "sys_info_param.hpp"
 #include "transporthandler.hpp"
 #include "types.hpp"
+#include "user_channel/usercommands.hpp"
 #include "utils.hpp"
 
 #include <arpa/inet.h>
@@ -874,7 +875,6 @@
     // <Get Channel Cipher Suites Command>
     ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_CHAN_CIPHER_SUITES, NULL,
                            getChannelCipherSuites, PRIVILEGE_CALLBACK);
-
     // <Set Channel Access Command>
     ipmi_register_callback(NETFUN_APP, IPMI_CMD_SET_CHAN_ACCESS, NULL,
                            ipmi_set_channel_access, PRIVILEGE_ADMIN);
@@ -882,5 +882,6 @@
     // <Get System Info Command>
     ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_SYSTEM_INFO, NULL,
                            ipmi_app_get_system_info, PRIVILEGE_USER);
+    ipmi::registerUserIpmiFunctions();
     return;
 }
diff --git a/user_channel/user_layer.cpp b/user_channel/user_layer.cpp
index 06cdd68..3e4490c 100644
--- a/user_channel/user_layer.cpp
+++ b/user_channel/user_layer.cpp
@@ -17,6 +17,8 @@
 #include "user_layer.hpp"
 
 #include "passwd_mgr.hpp"
+#include "user_mgmt.hpp"
+
 namespace
 {
 ipmi::PasswdMgr passwdMgr;
@@ -24,6 +26,13 @@
 
 namespace ipmi
 {
+
+ipmi_ret_t ipmiUserInit()
+{
+    getUserAccessObject();
+    return IPMI_CC_OK;
+}
+
 std::string ipmiUserGetPassword(const std::string& userName)
 {
     return passwdMgr.getPasswdByUserName(userName);
@@ -48,4 +57,107 @@
     return IPMI_CC_OK;
 }
 
+bool ipmiUserIsValidUserId(const uint8_t& userId)
+{
+    return UserAccess::isValidUserId(userId);
+}
+
+bool ipmiUserIsValidChannel(const uint8_t& chNum)
+{
+    return UserAccess::isValidChannel(chNum);
+}
+
+bool ipmiUserIsValidPrivilege(const uint8_t& priv)
+{
+    return UserAccess::isValidPrivilege(priv);
+}
+
+uint8_t ipmiUserGetUserId(const std::string& userName)
+{
+    return getUserAccessObject().getUserId(userName);
+}
+
+ipmi_ret_t ipmiUserSetUserName(const uint8_t& userId, const char* userName)
+{
+    return getUserAccessObject().setUserName(userId, userName);
+}
+
+ipmi_ret_t ipmiUserGetUserName(const uint8_t& userId, std::string& userName)
+{
+    return getUserAccessObject().getUserName(userId, userName);
+}
+
+ipmi_ret_t ipmiUserGetAllCounts(uint8_t& maxChUsers, uint8_t& enabledUsers,
+                                uint8_t& fixedUsers)
+{
+    maxChUsers = ipmiMaxUsers;
+    UsersTbl* userData = getUserAccessObject().getUsersTblPtr();
+    enabledUsers = 0;
+    fixedUsers = 0;
+    // user index 0 is reserved, starts with 1
+    for (size_t count = 1; count <= ipmiMaxUsers; ++count)
+    {
+        if (userData->user[count].userEnabled)
+        {
+            enabledUsers++;
+        }
+        if (userData->user[count].fixedUserName)
+        {
+            fixedUsers++;
+        }
+    }
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t ipmiUserCheckEnabled(const uint8_t& userId, bool& state)
+{
+    if (!UserAccess::isValidUserId(userId))
+    {
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+    UserInfo* userInfo = getUserAccessObject().getUserInfo(userId);
+    state = userInfo->userEnabled;
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t ipmiUserGetPrivilegeAccess(const uint8_t& userId,
+                                      const uint8_t& chNum,
+                                      PrivAccess& privAccess)
+{
+
+    if (!UserAccess::isValidChannel(chNum))
+    {
+        return IPMI_CC_INVALID_FIELD_REQUEST;
+    }
+    if (!UserAccess::isValidUserId(userId))
+    {
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+    UserInfo* userInfo = getUserAccessObject().getUserInfo(userId);
+    privAccess.privilege = userInfo->userPrivAccess[chNum].privilege;
+    privAccess.ipmiEnabled = userInfo->userPrivAccess[chNum].ipmiEnabled;
+    privAccess.linkAuthEnabled =
+        userInfo->userPrivAccess[chNum].linkAuthEnabled;
+    privAccess.accessCallback = userInfo->userPrivAccess[chNum].accessCallback;
+
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t ipmiUserSetPrivilegeAccess(const uint8_t& userId,
+                                      const uint8_t& chNum,
+                                      const PrivAccess& privAccess,
+                                      const bool& otherPrivUpdates)
+{
+    UserPrivAccess userPrivAccess;
+    userPrivAccess.privilege = privAccess.privilege;
+    if (otherPrivUpdates)
+    {
+        userPrivAccess.ipmiEnabled = privAccess.ipmiEnabled;
+        userPrivAccess.linkAuthEnabled = privAccess.linkAuthEnabled;
+        userPrivAccess.accessCallback = privAccess.accessCallback;
+    }
+    return getUserAccessObject().setUserPrivilegeAccess(
+        userId, chNum, userPrivAccess, otherPrivUpdates);
+}
+
 } // namespace ipmi
diff --git a/user_channel/user_layer.hpp b/user_channel/user_layer.hpp
index a946e4c..5136e86 100644
--- a/user_channel/user_layer.hpp
+++ b/user_channel/user_layer.hpp
@@ -20,9 +20,46 @@
 
 namespace ipmi
 {
+
+// TODO: Has to be replaced with proper channel number assignment logic
+enum class EChannelID : uint8_t
+{
+    chanLan1 = 0x01
+};
+
+static constexpr uint8_t invalidUserId = 0xFF;
+static constexpr uint8_t reservedUserId = 0x0;
+static constexpr uint8_t ipmiMaxUserName = 16;
+static constexpr uint8_t ipmiMaxUsers = 15;
+static constexpr uint8_t ipmiMaxChannels = 16;
+
+struct PrivAccess
+{
+#if BYTE_ORDER == LITTLE_ENDIAN
+    uint8_t privilege : 4;
+    uint8_t ipmiEnabled : 1;
+    uint8_t linkAuthEnabled : 1;
+    uint8_t accessCallback : 1;
+    uint8_t reserved : 1;
+#endif
+#if BYTE_ORDER == BIG_ENDIAN
+    uint8_t reserved : 1;
+    uint8_t accessCallback : 1;
+    uint8_t linkAuthEnabled : 1;
+    uint8_t ipmiEnabled : 1;
+    uint8_t privilege : 4;
+#endif
+} __attribute__((packed));
+
+/** @brief initializes user management
+ *
+ *  @return IPMI_CC_OK for success, others for failure.
+ */
+ipmi_ret_t ipmiUserInit();
+
 /** @brief The ipmi get user password layer call
  *
- *  @param[in] userName
+ *  @param[in] userName - user name
  *
  *  @return password or empty string
  */
@@ -31,7 +68,7 @@
 /** @brief The IPMI call to clear password entry associated with specified
  * username
  *
- *  @param[in] userName
+ *  @param[in] userName - user name to be removed
  *
  *  @return 0 on success, non-zero otherwise.
  */
@@ -40,14 +77,108 @@
 /** @brief The IPMI call to reuse password entry for the renamed user
  *  to another one
  *
- *  @param[in] userName
- *  @param[in] newUserName
+ *  @param[in] userName - user name which has to be renamed
+ *  @param[in] newUserName - new user name
  *
  *  @return 0 on success, non-zero otherwise.
  */
 ipmi_ret_t ipmiRenameUserEntryPassword(const std::string& userName,
                                        const std::string& newUserName);
 
-// TODO: Define required user layer API Call's which user layer shared library
-// must implement.
+/** @brief determines valid userId
+ *
+ *  @param[in] userId - user id
+ *
+ *  @return true if valid, false otherwise
+ */
+bool ipmiUserIsValidUserId(const uint8_t& userId);
+
+/** @brief determines valid channel
+ *
+ *  @param[in] chNum- channel number
+ *
+ *  @return true if valid, false otherwise
+ */
+bool ipmiUserIsValidChannel(const uint8_t& chNum);
+
+/** @brief determines valid privilege level
+ *
+ *  @param[in] priv - privilege level
+ *
+ *  @return true if valid, false otherwise
+ */
+bool ipmiUserIsValidPrivilege(const uint8_t& priv);
+
+/** @brief get user id corresponding to the user name
+ *
+ *  @param[in] userName - user name
+ *
+ *  @return userid. Will return 0xff if no user id found
+ */
+uint8_t ipmiUserGetUserId(const std::string& userName);
+
+/** @brief set's user name
+ *
+ *  @param[in] userId - user id
+ *  @param[in] userName - user name
+ *
+ *  @return IPMI_CC_OK for success, others for failure.
+ */
+ipmi_ret_t ipmiUserSetUserName(const uint8_t& userId, const char* userName);
+
+/** @brief get user name
+ *
+ *  @param[in] userId - user id
+ *  @param[out] userName - user name
+ *
+ *  @return IPMI_CC_OK for success, others for failure.
+ */
+ipmi_ret_t ipmiUserGetUserName(const uint8_t& userId, std::string& userName);
+
+/** @brief provides available fixed, max, and enabled user counts
+ *
+ *  @param[out] maxChUsers - max channel users
+ *  @param[out] enabledUsers - enabled user count
+ *  @param[out] fixedUsers - fixed user count
+ *
+ *  @return IPMI_CC_OK for success, others for failure.
+ */
+ipmi_ret_t ipmiUserGetAllCounts(uint8_t& maxChUsers, uint8_t& enabledUsers,
+                                uint8_t& fixedUsers);
+
+/** @brief determines whether user is enabled
+ *
+ *  @param[in] userId - user id
+ *..@param[out] state - state of the user
+ *
+ *  @return IPMI_CC_OK for success, others for failure.
+ */
+ipmi_ret_t ipmiUserCheckEnabled(const uint8_t& userId, bool& state);
+
+/** @brief provides user privilege access data
+ *
+ *  @param[in] userId - user id
+ *  @param[in] chNum - channel number
+ *  @param[out] privAccess - privilege access data
+ *
+ *  @return IPMI_CC_OK for success, others for failure.
+ */
+ipmi_ret_t ipmiUserGetPrivilegeAccess(const uint8_t& userId,
+                                      const uint8_t& chNum,
+                                      PrivAccess& privAccess);
+
+/** @brief sets user privilege access data
+ *
+ *  @param[in] userId - user id
+ *  @param[in] chNum - channel number
+ *  @param[in] privAccess - privilege access data
+ *  @param[in] otherPrivUpdate - flags to indicate other fields update
+ *
+ *  @return IPMI_CC_OK for success, others for failure.
+ */
+ipmi_ret_t ipmiUserSetPrivilegeAccess(const uint8_t& userId,
+                                      const uint8_t& chNum,
+                                      const PrivAccess& privAccess,
+                                      const bool& otherPrivUpdate);
+
 } // namespace ipmi
diff --git a/user_channel/user_mgmt.cpp b/user_channel/user_mgmt.cpp
new file mode 100644
index 0000000..e320e3f
--- /dev/null
+++ b/user_channel/user_mgmt.cpp
@@ -0,0 +1,1304 @@
+/*
+// Copyright (c) 2018 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+#include "user_mgmt.hpp"
+
+#include "apphandler.hpp"
+
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <boost/interprocess/sync/named_recursive_mutex.hpp>
+#include <boost/interprocess/sync/scoped_lock.hpp>
+#include <cerrno>
+#include <fstream>
+#include <host-ipmid/ipmid-host-cmd.hpp>
+#include <nlohmann/json.hpp>
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/log.hpp>
+#include <regex>
+#include <sdbusplus/bus/match.hpp>
+#include <sdbusplus/server/object.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
+#include <xyz/openbmc_project/User/Common/error.hpp>
+
+namespace ipmi
+{
+
+// TODO: Move D-Bus & Object Manager related stuff, to common files
+// D-Bus property related
+static constexpr const char* dBusPropertiesInterface =
+    "org.freedesktop.DBus.Properties";
+static constexpr const char* getAllPropertiesMethod = "GetAll";
+static constexpr const char* propertiesChangedSignal = "PropertiesChanged";
+static constexpr const char* setPropertiesMethod = "Set";
+
+// Object Manager related
+static constexpr const char* dBusObjManager =
+    "org.freedesktop.DBus.ObjectManager";
+static constexpr const char* getManagedObjectsMethod = "GetManagedObjects";
+// Object Manager signals
+static constexpr const char* intfAddedSignal = "InterfacesAdded";
+static constexpr const char* intfRemovedSignal = "InterfacesRemoved";
+
+// Object Mapper related
+static constexpr const char* objMapperService =
+    "xyz.openbmc_project.ObjectMapper";
+static constexpr const char* objMapperPath =
+    "/xyz/openbmc_project/object_mapper";
+static constexpr const char* objMapperInterface =
+    "xyz.openbmc_project.ObjectMapper";
+static constexpr const char* getSubTreeMethod = "GetSubTree";
+static constexpr const char* getObjectMethod = "GetObject";
+
+static constexpr const char* ipmiUserMutex = "ipmi_usr_mutex";
+static constexpr const char* ipmiMutexCleanupLockFile =
+    "/var/lib/ipmi/ipmi_usr_mutex_cleanup";
+static constexpr const char* ipmiUserDataFile = "/var/lib/ipmi/ipmi_user.json";
+static constexpr const char* ipmiGrpName = "ipmi";
+static constexpr size_t privNoAccess = 0xF;
+static constexpr size_t privMask = 0xF;
+
+// User manager related
+static constexpr const char* userMgrObjBasePath = "/xyz/openbmc_project/user";
+static constexpr const char* userObjBasePath = "/xyz/openbmc_project/user";
+static constexpr const char* userMgrInterface =
+    "xyz.openbmc_project.User.Manager";
+static constexpr const char* usersInterface =
+    "xyz.openbmc_project.User.Attributes";
+static constexpr const char* deleteUserInterface =
+    "xyz.openbmc_project.Object.Delete";
+
+static constexpr const char* createUserMethod = "CreateUser";
+static constexpr const char* deleteUserMethod = "Delete";
+static constexpr const char* renameUserMethod = "RenameUser";
+// User manager signal memebers
+static constexpr const char* userRenamedSignal = "UserRenamed";
+// Mgr interface properties
+static constexpr const char* allPrivProperty = "AllPrivileges";
+static constexpr const char* allGrpProperty = "AllGroups";
+// User interface properties
+static constexpr const char* userPrivProperty = "UserPrivilege";
+static constexpr const char* userGrpProperty = "UserGroups";
+static constexpr const char* userEnabledProperty = "UserEnabled";
+
+static std::array<std::string, (PRIVILEGE_OEM + 1)> ipmiPrivIndex = {
+    "priv-reserved", // PRIVILEGE_RESERVED - 0
+    "priv-callback", // PRIVILEGE_CALLBACK - 1
+    "priv-user",     // PRIVILEGE_USER - 2
+    "priv-operator", // PRIVILEGE_OPERATOR - 3
+    "priv-admin",    // PRIVILEGE_ADMIN - 4
+    "priv-custom"    // PRIVILEGE_OEM - 5
+};
+
+using namespace phosphor::logging;
+using Json = nlohmann::json;
+
+using PrivAndGroupType =
+    sdbusplus::message::variant<std::string, std::vector<std::string>>;
+
+using NoResource =
+    sdbusplus::xyz::openbmc_project::User::Common::Error::NoResource;
+
+using InternalFailure =
+    sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
+
+std::unique_ptr<sdbusplus::bus::match_t> userUpdatedSignal(nullptr);
+std::unique_ptr<sdbusplus::bus::match_t> userMgrRenamedSignal(nullptr);
+std::unique_ptr<sdbusplus::bus::match_t> userPropertiesSignal(nullptr);
+
+// TODO:  Below code can be removed once it is moved to common layer libmiscutil
+std::string getUserService(sdbusplus::bus::bus& bus, const std::string& intf,
+                           const std::string& path)
+{
+    auto mapperCall = bus.new_method_call(objMapperService, objMapperPath,
+                                          objMapperInterface, getObjectMethod);
+
+    mapperCall.append(path);
+    mapperCall.append(std::vector<std::string>({intf}));
+
+    auto mapperResponseMsg = bus.call(mapperCall);
+
+    std::map<std::string, std::vector<std::string>> mapperResponse;
+    mapperResponseMsg.read(mapperResponse);
+
+    if (mapperResponse.begin() == mapperResponse.end())
+    {
+        throw sdbusplus::exception::SdBusError(
+            -EIO, "ERROR in reading the mapper response");
+    }
+
+    return mapperResponse.begin()->first;
+}
+
+void setDbusProperty(sdbusplus::bus::bus& bus, const std::string& service,
+                     const std::string& objPath, const std::string& interface,
+                     const std::string& property,
+                     const DbusUserPropVariant& value)
+{
+    try
+    {
+        auto method =
+            bus.new_method_call(service.c_str(), objPath.c_str(),
+                                dBusPropertiesInterface, setPropertiesMethod);
+        method.append(interface, property, value);
+        bus.call(method);
+    }
+    catch (const sdbusplus::exception::SdBusError& e)
+    {
+        log<level::ERR>("Failed to set property",
+                        entry("PROPERTY=%s", property.c_str()),
+                        entry("PATH=%s", objPath.c_str()),
+                        entry("INTERFACE=%s", interface.c_str()));
+        throw;
+    }
+}
+
+static std::string getUserServiceName()
+{
+    static sdbusplus::bus::bus bus(ipmid_get_sd_bus_connection());
+    static std::string userMgmtService;
+    if (userMgmtService.empty())
+    {
+        try
+        {
+            userMgmtService =
+                ipmi::getUserService(bus, userMgrInterface, userMgrObjBasePath);
+        }
+        catch (const sdbusplus::exception::SdBusError& e)
+        {
+            userMgmtService.clear();
+        }
+    }
+    return userMgmtService;
+}
+
+UserAccess& getUserAccessObject()
+{
+    static UserAccess userAccess;
+    return userAccess;
+}
+
+int getUserNameFromPath(const std::string& path, std::string& userName)
+{
+    static size_t pos = strlen(userObjBasePath) + 1;
+    if (path.find(userObjBasePath) == std::string::npos)
+    {
+        return -EINVAL;
+    }
+    userName.assign(path, pos, path.size());
+    return 0;
+}
+
+void userUpdateHelper(UserAccess& usrAccess, const UserUpdateEvent& userEvent,
+                      const std::string& userName, const std::string& priv,
+                      const bool& enabled, const std::string& newUserName)
+{
+    UsersTbl* userData = usrAccess.getUsersTblPtr();
+    if (userEvent == UserUpdateEvent::userCreated)
+    {
+        if (usrAccess.addUserEntry(userName, priv, enabled) == false)
+        {
+            return;
+        }
+    }
+    else
+    {
+        // user index 0 is reserved, starts with 1
+        size_t usrIndex = 1;
+        for (; usrIndex <= ipmiMaxUsers; ++usrIndex)
+        {
+            std::string curName(
+                reinterpret_cast<char*>(userData->user[usrIndex].userName), 0,
+                ipmiMaxUserName);
+            if (userName == curName)
+            {
+                break; // found the entry
+            }
+        }
+        if (usrIndex > ipmiMaxUsers)
+        {
+            log<level::DEBUG>("User not found for signal",
+                              entry("USER_NAME=%s", userName.c_str()),
+                              entry("USER_EVENT=%d", userEvent));
+            return;
+        }
+        switch (userEvent)
+        {
+            case UserUpdateEvent::userDeleted:
+            {
+                usrAccess.deleteUserIndex(usrIndex);
+                break;
+            }
+            case UserUpdateEvent::userPrivUpdated:
+            {
+                uint8_t userPriv =
+                    static_cast<uint8_t>(
+                        UserAccess::convertToIPMIPrivilege(priv)) &
+                    privMask;
+                // Update all channels privileges, only if it is not equivalent
+                // to getUsrMgmtSyncIndex()
+                if (userData->user[usrIndex]
+                        .userPrivAccess[UserAccess::getUsrMgmtSyncIndex()]
+                        .privilege != userPriv)
+                {
+                    for (size_t chIndex = 0; chIndex < ipmiMaxChannels;
+                         ++chIndex)
+                    {
+                        userData->user[usrIndex]
+                            .userPrivAccess[chIndex]
+                            .privilege = userPriv;
+                    }
+                }
+                break;
+            }
+            case UserUpdateEvent::userRenamed:
+            {
+                std::fill(
+                    static_cast<uint8_t*>(userData->user[usrIndex].userName),
+                    static_cast<uint8_t*>(userData->user[usrIndex].userName) +
+                        sizeof(userData->user[usrIndex].userName),
+                    0);
+                std::strncpy(
+                    reinterpret_cast<char*>(userData->user[usrIndex].userName),
+                    newUserName.c_str(), ipmiMaxUserName);
+                ipmiRenameUserEntryPassword(userName, newUserName);
+                break;
+            }
+            case UserUpdateEvent::userStateUpdated:
+            {
+                userData->user[usrIndex].userEnabled = enabled;
+                break;
+            }
+            default:
+            {
+                log<level::ERR>("Unhandled user event",
+                                entry("USER_EVENT=%d", userEvent));
+                return;
+            }
+        }
+    }
+    usrAccess.writeUserData();
+    log<level::DEBUG>("User event handled successfully",
+                      entry("USER_NAME=%s", userName.c_str()),
+                      entry("USER_EVENT=%d", userEvent));
+
+    return;
+}
+
+void userUpdatedSignalHandler(UserAccess& usrAccess,
+                              sdbusplus::message::message& msg)
+{
+    static sdbusplus::bus::bus bus(ipmid_get_sd_bus_connection());
+    std::string signal = msg.get_member();
+    std::string userName, update, priv, newUserName;
+    std::vector<std::string> groups;
+    bool enabled = false;
+    UserUpdateEvent userEvent = UserUpdateEvent::reservedEvent;
+    if (signal == intfAddedSignal)
+    {
+        DbusUserObjPath objPath;
+        DbusUserObjValue objValue;
+        msg.read(objPath, objValue);
+        getUserNameFromPath(objPath.str, userName);
+        if (usrAccess.getUserObjProperties(objValue, groups, priv, enabled) !=
+            0)
+        {
+            return;
+        }
+        if (std::find(groups.begin(), groups.end(), ipmiGrpName) ==
+            groups.end())
+        {
+            return;
+        }
+        userEvent = UserUpdateEvent::userCreated;
+    }
+    else if (signal == intfRemovedSignal)
+    {
+        DbusUserObjPath objPath;
+        std::vector<std::string> interfaces;
+        msg.read(objPath, interfaces);
+        getUserNameFromPath(objPath.str, userName);
+        userEvent = UserUpdateEvent::userDeleted;
+    }
+    else if (signal == userRenamedSignal)
+    {
+        msg.read(userName, newUserName);
+        userEvent = UserUpdateEvent::userRenamed;
+    }
+    else if (signal == propertiesChangedSignal)
+    {
+        getUserNameFromPath(msg.get_path(), userName);
+    }
+    else
+    {
+        log<level::ERR>("Unknown user update signal",
+                        entry("SIGNAL=%s", signal.c_str()));
+        return;
+    }
+
+    if (signal.empty() || userName.empty() ||
+        (signal == userRenamedSignal && newUserName.empty()))
+    {
+        log<level::ERR>("Invalid inputs received");
+        return;
+    }
+
+    boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
+        userLock{*(usrAccess.userMutex)};
+    usrAccess.checkAndReloadUserData();
+
+    if (signal == propertiesChangedSignal)
+    {
+        std::string intfName;
+        DbusUserObjProperties chProperties;
+        msg.read(intfName, chProperties); // skip reading 3rd argument.
+        for (const auto& prop : chProperties)
+        {
+            userEvent = UserUpdateEvent::reservedEvent;
+            std::string member = prop.first;
+            if (member == userPrivProperty)
+            {
+                priv = prop.second.get<std::string>();
+                userEvent = UserUpdateEvent::userPrivUpdated;
+            }
+            else if (member == userGrpProperty)
+            {
+                groups = prop.second.get<std::vector<std::string>>();
+                userEvent = UserUpdateEvent::userGrpUpdated;
+            }
+            else if (member == userEnabledProperty)
+            {
+                enabled = prop.second.get<bool>();
+                userEvent = UserUpdateEvent::userStateUpdated;
+            }
+            // Process based on event type.
+            if (userEvent == UserUpdateEvent::userGrpUpdated)
+            {
+                if (std::find(groups.begin(), groups.end(), ipmiGrpName) ==
+                    groups.end())
+                {
+                    // remove user from ipmi user list.
+                    userUpdateHelper(usrAccess, UserUpdateEvent::userDeleted,
+                                     userName, priv, enabled, newUserName);
+                }
+                else
+                {
+                    DbusUserObjProperties properties;
+                    try
+                    {
+                        auto method = bus.new_method_call(
+                            getUserServiceName().c_str(), msg.get_path(),
+                            dBusPropertiesInterface, getAllPropertiesMethod);
+                        method.append(usersInterface);
+                        auto reply = bus.call(method);
+                        reply.read(properties);
+                    }
+                    catch (const sdbusplus::exception::SdBusError& e)
+                    {
+                        log<level::DEBUG>(
+                            "Failed to excute method",
+                            entry("METHOD=%s", getAllPropertiesMethod),
+                            entry("PATH=%s", msg.get_path()));
+                        return;
+                    }
+                    usrAccess.getUserProperties(properties, groups, priv,
+                                                enabled);
+                    // add user to ipmi user list.
+                    userUpdateHelper(usrAccess, UserUpdateEvent::userCreated,
+                                     userName, priv, enabled, newUserName);
+                }
+            }
+            else if (userEvent != UserUpdateEvent::reservedEvent)
+            {
+                userUpdateHelper(usrAccess, userEvent, userName, priv, enabled,
+                                 newUserName);
+            }
+        }
+    }
+    else if (userEvent != UserUpdateEvent::reservedEvent)
+    {
+        userUpdateHelper(usrAccess, userEvent, userName, priv, enabled,
+                         newUserName);
+    }
+    return;
+}
+
+UserAccess::~UserAccess()
+{
+    if (signalHndlrObject)
+    {
+        userUpdatedSignal.reset();
+        userMgrRenamedSignal.reset();
+        userPropertiesSignal.reset();
+        sigHndlrLock.unlock();
+    }
+}
+
+UserAccess::UserAccess() : bus(ipmid_get_sd_bus_connection())
+{
+    std::ofstream mutexCleanUpFile;
+    mutexCleanUpFile.open(ipmiMutexCleanupLockFile,
+                          std::ofstream::out | std::ofstream::app);
+    if (!mutexCleanUpFile.good())
+    {
+        log<level::DEBUG>("Unable to open mutex cleanup file");
+        return;
+    }
+    mutexCleanUpFile.close();
+    mutexCleanupLock = boost::interprocess::file_lock(ipmiMutexCleanupLockFile);
+    if (mutexCleanupLock.try_lock())
+    {
+        boost::interprocess::named_recursive_mutex::remove(ipmiUserMutex);
+    }
+    mutexCleanupLock.lock_sharable();
+    userMutex = std::make_unique<boost::interprocess::named_recursive_mutex>(
+        boost::interprocess::open_or_create, ipmiUserMutex);
+
+    initUserDataFile();
+    getSystemPrivAndGroups();
+    sigHndlrLock = boost::interprocess::file_lock(ipmiUserDataFile);
+    // Register it for single object and single process either netipimd /
+    // host-ipmid
+    if (userUpdatedSignal == nullptr && sigHndlrLock.try_lock())
+    {
+        log<level::DEBUG>("Registering signal handler");
+        userUpdatedSignal = std::make_unique<sdbusplus::bus::match_t>(
+            bus,
+            sdbusplus::bus::match::rules::type::signal() +
+                sdbusplus::bus::match::rules::interface(dBusObjManager) +
+                sdbusplus::bus::match::rules::path(userMgrObjBasePath),
+            [&](sdbusplus::message::message& msg) {
+                userUpdatedSignalHandler(*this, msg);
+            });
+        userMgrRenamedSignal = std::make_unique<sdbusplus::bus::match_t>(
+            bus,
+            sdbusplus::bus::match::rules::type::signal() +
+                sdbusplus::bus::match::rules::interface(userMgrInterface) +
+                sdbusplus::bus::match::rules::path(userMgrObjBasePath),
+            [&](sdbusplus::message::message& msg) {
+                userUpdatedSignalHandler(*this, msg);
+            });
+        userPropertiesSignal = std::make_unique<sdbusplus::bus::match_t>(
+            bus,
+            sdbusplus::bus::match::rules::type::signal() +
+                sdbusplus::bus::match::rules::path_namespace(userObjBasePath) +
+                sdbusplus::bus::match::rules::interface(
+                    dBusPropertiesInterface) +
+                sdbusplus::bus::match::rules::member(propertiesChangedSignal) +
+                sdbusplus::bus::match::rules::argN(0, usersInterface),
+            [&](sdbusplus::message::message& msg) {
+                userUpdatedSignalHandler(*this, msg);
+            });
+        signalHndlrObject = true;
+    }
+}
+
+UserInfo* UserAccess::getUserInfo(const uint8_t& userId)
+{
+    checkAndReloadUserData();
+    return &usersTbl.user[userId];
+}
+
+void UserAccess::setUserInfo(const uint8_t& userId, UserInfo* userInfo)
+{
+    checkAndReloadUserData();
+    std::copy(reinterpret_cast<uint8_t*>(userInfo),
+              reinterpret_cast<uint8_t*>(userInfo) + sizeof(*userInfo),
+              reinterpret_cast<uint8_t*>(&usersTbl.user[userId]));
+    writeUserData();
+}
+
+bool UserAccess::isValidChannel(const uint8_t& chNum)
+{
+    return (chNum < ipmiMaxChannels);
+}
+
+bool UserAccess::isValidUserId(const uint8_t& userId)
+{
+    return ((userId <= ipmiMaxUsers) && (userId != reservedUserId));
+}
+
+bool UserAccess::isValidPrivilege(const uint8_t& priv)
+{
+    return ((priv >= PRIVILEGE_CALLBACK && priv <= PRIVILEGE_OEM) ||
+            priv == privNoAccess);
+}
+
+uint8_t UserAccess::getUsrMgmtSyncIndex()
+{
+    // TODO: Need to get LAN1 channel number dynamically,
+    // which has to be in sync with system user privilege
+    // level(Phosphor-user-manager). Note: For time being chanLan1 is marked as
+    // sync index to the user-manager privilege..
+    return static_cast<uint8_t>(EChannelID::chanLan1);
+}
+
+CommandPrivilege UserAccess::convertToIPMIPrivilege(const std::string& value)
+{
+    auto iter = std::find(ipmiPrivIndex.begin(), ipmiPrivIndex.end(), value);
+    if (iter == ipmiPrivIndex.end())
+    {
+        if (value == "")
+        {
+            return static_cast<CommandPrivilege>(privNoAccess);
+        }
+        log<level::ERR>("Error in converting to IPMI privilege",
+                        entry("PRIV=%s", value.c_str()));
+        throw std::out_of_range("Out of range - convertToIPMIPrivilege");
+    }
+    else
+    {
+        return static_cast<CommandPrivilege>(
+            std::distance(ipmiPrivIndex.begin(), iter));
+    }
+}
+
+std::string UserAccess::convertToSystemPrivilege(const CommandPrivilege& value)
+{
+    if (value == static_cast<CommandPrivilege>(privNoAccess))
+    {
+        return "";
+    }
+    try
+    {
+        return ipmiPrivIndex.at(value);
+    }
+    catch (const std::out_of_range& e)
+    {
+        log<level::ERR>("Error in converting to system privilege",
+                        entry("PRIV=%d", static_cast<uint8_t>(value)));
+        throw std::out_of_range("Out of range - convertToSystemPrivilege");
+    }
+}
+
+bool UserAccess::isValidUserName(const char* userNameInChar)
+{
+    if (!userNameInChar)
+    {
+        log<level::ERR>("null ptr");
+        return false;
+    }
+    std::string userName(userNameInChar, 0, ipmiMaxUserName);
+    if (!std::regex_match(userName.c_str(),
+                          std::regex("[a-zA-z_][a-zA-Z_0-9]*")))
+    {
+        log<level::ERR>("Unsupported characters in user name");
+        return false;
+    }
+    if (userName == "root")
+    {
+        log<level::ERR>("Invalid user name - root");
+        return false;
+    }
+    std::map<DbusUserObjPath, DbusUserObjValue> properties;
+    try
+    {
+        auto method = bus.new_method_call(getUserServiceName().c_str(),
+                                          userMgrObjBasePath, dBusObjManager,
+                                          getManagedObjectsMethod);
+        auto reply = bus.call(method);
+        reply.read(properties);
+    }
+    catch (const sdbusplus::exception::SdBusError& e)
+    {
+        log<level::ERR>("Failed to excute method",
+                        entry("METHOD=%s", getSubTreeMethod),
+                        entry("PATH=%s", userMgrObjBasePath));
+        return false;
+    }
+
+    std::string usersPath = std::string(userObjBasePath) + "/" + userName;
+    if (properties.find(usersPath) != properties.end())
+    {
+        log<level::DEBUG>("User name already exists",
+                          entry("USER_NAME=%s", userName.c_str()));
+        return false;
+    }
+
+    return true;
+}
+
+ipmi_ret_t UserAccess::setUserPrivilegeAccess(const uint8_t& userId,
+                                              const uint8_t& chNum,
+                                              const UserPrivAccess& privAccess,
+                                              const bool& otherPrivUpdates)
+{
+    if (!isValidChannel(chNum))
+    {
+        return IPMI_CC_INVALID_FIELD_REQUEST;
+    }
+    if (!isValidUserId(userId))
+    {
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+    boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
+        userLock{*userMutex};
+    UserInfo* userInfo = getUserInfo(userId);
+    std::string userName;
+    userName.assign(reinterpret_cast<char*>(userInfo->userName), 0,
+                    ipmiMaxUserName);
+    if (userName.empty())
+    {
+        log<level::DEBUG>("User name not set / invalid");
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+    std::string priv = convertToSystemPrivilege(
+        static_cast<CommandPrivilege>(privAccess.privilege));
+    if (priv.empty())
+    {
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+    uint8_t syncIndex = getUsrMgmtSyncIndex();
+    if (chNum == syncIndex &&
+        privAccess.privilege != userInfo->userPrivAccess[syncIndex].privilege)
+    {
+        std::string userPath = std::string(userObjBasePath) + "/" + userName;
+        setDbusProperty(bus, getUserServiceName().c_str(), userPath.c_str(),
+                        usersInterface, userPrivProperty, priv);
+    }
+    userInfo->userPrivAccess[chNum].privilege = privAccess.privilege;
+
+    if (otherPrivUpdates)
+    {
+        userInfo->userPrivAccess[chNum].ipmiEnabled = privAccess.ipmiEnabled;
+        userInfo->userPrivAccess[chNum].linkAuthEnabled =
+            privAccess.linkAuthEnabled;
+        userInfo->userPrivAccess[chNum].accessCallback =
+            privAccess.accessCallback;
+    }
+    try
+    {
+        writeUserData();
+    }
+    catch (const std::exception& e)
+    {
+        log<level::DEBUG>("Write user data failed");
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+    return IPMI_CC_OK;
+}
+
+uint8_t UserAccess::getUserId(const std::string& userName)
+{
+    boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
+        userLock{*userMutex};
+    checkAndReloadUserData();
+    // user index 0 is reserved, starts with 1
+    size_t usrIndex = 1;
+    for (; usrIndex <= ipmiMaxUsers; ++usrIndex)
+    {
+        std::string curName(
+            reinterpret_cast<char*>(usersTbl.user[usrIndex].userName), 0,
+            ipmiMaxUserName);
+        if (userName == curName)
+        {
+            break; // found the entry
+        }
+    }
+    if (usrIndex > ipmiMaxUsers)
+    {
+        log<level::DEBUG>("User not found",
+                          entry("USER_NAME=%s", userName.c_str()));
+        return invalidUserId;
+    }
+
+    return usrIndex;
+}
+
+ipmi_ret_t UserAccess::getUserName(const uint8_t& userId, std::string& userName)
+{
+    if (!isValidUserId(userId))
+    {
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+    UserInfo* userInfo = getUserInfo(userId);
+    userName.assign(reinterpret_cast<char*>(userInfo->userName), 0,
+                    ipmiMaxUserName);
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t UserAccess::setUserName(const uint8_t& userId,
+                                   const char* userNameInChar)
+{
+    if (!isValidUserId(userId))
+    {
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
+        userLock{*userMutex};
+    bool validUser = isValidUserName(userNameInChar);
+    std::string oldUser;
+    getUserName(userId, oldUser);
+    UserInfo* userInfo = getUserInfo(userId);
+
+    std::string newUser(userNameInChar, 0, ipmiMaxUserName);
+    if (newUser.empty() && !oldUser.empty())
+    {
+        // Delete existing user
+        std::string userPath = std::string(userObjBasePath) + "/" + oldUser;
+        try
+        {
+            auto method = bus.new_method_call(
+                getUserServiceName().c_str(), userPath.c_str(),
+                deleteUserInterface, deleteUserMethod);
+            auto reply = bus.call(method);
+        }
+        catch (const sdbusplus::exception::SdBusError& e)
+        {
+            log<level::DEBUG>("Failed to excute method",
+                              entry("METHOD=%s", deleteUserMethod),
+                              entry("PATH=%s", userPath.c_str()));
+            return IPMI_CC_UNSPECIFIED_ERROR;
+        }
+        std::fill(userInfo->userName,
+                  userInfo->userName + sizeof(userInfo->userName), 0);
+        ipmiClearUserEntryPassword(oldUser);
+        userInfo->userInSystem = false;
+    }
+    else if (oldUser.empty() && !newUser.empty() && validUser)
+    {
+        try
+        {
+            // Create new user
+            auto method = bus.new_method_call(
+                getUserServiceName().c_str(), userMgrObjBasePath,
+                userMgrInterface, createUserMethod);
+            // TODO: Fetch proper privilege & enable state once set User access
+            // is implemented if LAN Channel specified, then create user for all
+            // groups follow channel privilege for user creation.
+            method.append(newUser.c_str(), availableGroups, "priv-admin", true);
+            auto reply = bus.call(method);
+        }
+        catch (const sdbusplus::exception::SdBusError& e)
+        {
+            log<level::DEBUG>("Failed to excute method",
+                              entry("METHOD=%s", createUserMethod),
+                              entry("PATH=%s", userMgrObjBasePath));
+            return IPMI_CC_UNSPECIFIED_ERROR;
+        }
+        std::strncpy(reinterpret_cast<char*>(userInfo->userName),
+                     userNameInChar, ipmiMaxUserName);
+        userInfo->userInSystem = true;
+    }
+    else if (oldUser != newUser && validUser)
+    {
+        try
+        {
+            // User rename
+            auto method = bus.new_method_call(
+                getUserServiceName().c_str(), userMgrObjBasePath,
+                userMgrInterface, renameUserMethod);
+            method.append(oldUser.c_str(), newUser.c_str());
+            auto reply = bus.call(method);
+        }
+        catch (const sdbusplus::exception::SdBusError& e)
+        {
+            log<level::DEBUG>("Failed to excute method",
+                              entry("METHOD=%s", renameUserMethod),
+                              entry("PATH=%s", userMgrObjBasePath));
+            return IPMI_CC_UNSPECIFIED_ERROR;
+        }
+        std::fill(static_cast<uint8_t*>(userInfo->userName),
+                  static_cast<uint8_t*>(userInfo->userName) +
+                      sizeof(userInfo->userName),
+                  0);
+        std::strncpy(reinterpret_cast<char*>(userInfo->userName),
+                     userNameInChar, ipmiMaxUserName);
+        ipmiRenameUserEntryPassword(oldUser, newUser);
+        userInfo->userInSystem = true;
+    }
+    else if (!validUser)
+    {
+        return IPMI_CC_INVALID_FIELD_REQUEST;
+    }
+    try
+    {
+        writeUserData();
+    }
+    catch (const std::exception& e)
+    {
+        log<level::DEBUG>("Write user data failed");
+        return IPMI_CC_UNSPECIFIED_ERROR;
+    }
+    return IPMI_CC_OK;
+}
+
+static constexpr const char* jsonUserName = "user_name";
+static constexpr const char* jsonPriv = "privilege";
+static constexpr const char* jsonIpmiEnabled = "ipmi_enabled";
+static constexpr const char* jsonLinkAuthEnabled = "link_auth_enabled";
+static constexpr const char* jsonAccCallbk = "access_callback";
+static constexpr const char* jsonUserEnabled = "user_enabled";
+static constexpr const char* jsonUserInSys = "user_in_system";
+static constexpr const char* jsonFixedUser = "fixed_user_name";
+
+void UserAccess::readUserData()
+{
+    boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
+        userLock{*userMutex};
+
+    std::ifstream iUsrData(ipmiUserDataFile, std::ios::in | std::ios::binary);
+    if (!iUsrData.good())
+    {
+        log<level::ERR>("Error in reading IPMI user data file");
+        throw std::ios_base::failure("Error opening IPMI user data file");
+    }
+
+    Json jsonUsersTbl = Json::array();
+    jsonUsersTbl = Json::parse(iUsrData, nullptr, false);
+
+    if (jsonUsersTbl.size() != ipmiMaxUsers)
+    {
+        log<level::ERR>(
+            "Error in reading IPMI user data file - User count issues");
+        throw std::runtime_error(
+            "Corrupted IPMI user data file - invalid user count");
+    }
+    // user index 0 is reserved, starts with 1
+    for (size_t usrIndex = 1; usrIndex <= ipmiMaxUsers; ++usrIndex)
+    {
+        Json userInfo = jsonUsersTbl[usrIndex - 1]; // json array starts with 0.
+        if (userInfo.is_null())
+        {
+            log<level::ERR>("Error in reading IPMI user data file - "
+                            "user info corrupted");
+            throw std::runtime_error(
+                "Corrupted IPMI user data file - invalid user info");
+        }
+        std::string userName = userInfo[jsonUserName].get<std::string>();
+        std::strncpy(reinterpret_cast<char*>(usersTbl.user[usrIndex].userName),
+                     userName.c_str(), ipmiMaxUserName);
+
+        std::vector<std::string> privilege =
+            userInfo[jsonPriv].get<std::vector<std::string>>();
+        std::vector<bool> ipmiEnabled =
+            userInfo[jsonIpmiEnabled].get<std::vector<bool>>();
+        std::vector<bool> linkAuthEnabled =
+            userInfo[jsonLinkAuthEnabled].get<std::vector<bool>>();
+        std::vector<bool> accessCallback =
+            userInfo[jsonAccCallbk].get<std::vector<bool>>();
+        if (privilege.size() != ipmiMaxChannels ||
+            ipmiEnabled.size() != ipmiMaxChannels ||
+            linkAuthEnabled.size() != ipmiMaxChannels ||
+            accessCallback.size() != ipmiMaxChannels)
+        {
+            log<level::ERR>("Error in reading IPMI user data file - "
+                            "properties corrupted");
+            throw std::runtime_error(
+                "Corrupted IPMI user data file - properties");
+        }
+        for (size_t chIndex = 0; chIndex < ipmiMaxChannels; ++chIndex)
+        {
+            usersTbl.user[usrIndex].userPrivAccess[chIndex].privilege =
+                static_cast<uint8_t>(
+                    convertToIPMIPrivilege(privilege[chIndex]));
+            usersTbl.user[usrIndex].userPrivAccess[chIndex].ipmiEnabled =
+                ipmiEnabled[chIndex];
+            usersTbl.user[usrIndex].userPrivAccess[chIndex].linkAuthEnabled =
+                linkAuthEnabled[chIndex];
+            usersTbl.user[usrIndex].userPrivAccess[chIndex].accessCallback =
+                accessCallback[chIndex];
+        }
+        usersTbl.user[usrIndex].userEnabled =
+            userInfo[jsonUserEnabled].get<bool>();
+        usersTbl.user[usrIndex].userInSystem =
+            userInfo[jsonUserInSys].get<bool>();
+        usersTbl.user[usrIndex].fixedUserName =
+            userInfo[jsonFixedUser].get<bool>();
+    }
+
+    log<level::DEBUG>("User data read from IPMI data file");
+    iUsrData.close();
+    // Update the timestamp
+    fileLastUpdatedTime = getUpdatedFileTime();
+    return;
+}
+
+void UserAccess::writeUserData()
+{
+    boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
+        userLock{*userMutex};
+
+    static std::string tmpFile{std::string(ipmiUserDataFile) + "_tmp"};
+    std::ofstream oUsrData(tmpFile, std::ios::out | std::ios::binary);
+    if (!oUsrData.good())
+    {
+        log<level::ERR>("Error in creating temporary IPMI user data file");
+        throw std::ios_base::failure(
+            "Error in creating temporary IPMI user data file");
+    }
+
+    Json jsonUsersTbl = Json::array();
+    // user index 0 is reserved, starts with 1
+    for (size_t usrIndex = 1; usrIndex <= ipmiMaxUsers; ++usrIndex)
+    {
+        Json jsonUserInfo;
+        jsonUserInfo[jsonUserName] = std::string(
+            reinterpret_cast<char*>(usersTbl.user[usrIndex].userName), 0,
+            ipmiMaxUserName);
+        std::vector<std::string> privilege(ipmiMaxChannels);
+        std::vector<bool> ipmiEnabled(ipmiMaxChannels);
+        std::vector<bool> linkAuthEnabled(ipmiMaxChannels);
+        std::vector<bool> accessCallback(ipmiMaxChannels);
+        for (size_t chIndex = 0; chIndex < ipmiMaxChannels; chIndex++)
+        {
+            privilege[chIndex] =
+                convertToSystemPrivilege(static_cast<CommandPrivilege>(
+                    usersTbl.user[usrIndex].userPrivAccess[chIndex].privilege));
+            ipmiEnabled[chIndex] =
+                usersTbl.user[usrIndex].userPrivAccess[chIndex].ipmiEnabled;
+            linkAuthEnabled[chIndex] =
+                usersTbl.user[usrIndex].userPrivAccess[chIndex].linkAuthEnabled;
+            accessCallback[chIndex] =
+                usersTbl.user[usrIndex].userPrivAccess[chIndex].accessCallback;
+        }
+        jsonUserInfo[jsonPriv] = privilege;
+        jsonUserInfo[jsonIpmiEnabled] = ipmiEnabled;
+        jsonUserInfo[jsonLinkAuthEnabled] = linkAuthEnabled;
+        jsonUserInfo[jsonAccCallbk] = accessCallback;
+        jsonUserInfo[jsonUserEnabled] = usersTbl.user[usrIndex].userEnabled;
+        jsonUserInfo[jsonUserInSys] = usersTbl.user[usrIndex].userInSystem;
+        jsonUserInfo[jsonFixedUser] = usersTbl.user[usrIndex].fixedUserName;
+        jsonUsersTbl.push_back(jsonUserInfo);
+    }
+
+    oUsrData << jsonUsersTbl;
+    oUsrData.flush();
+    oUsrData.close();
+
+    if (std::rename(tmpFile.c_str(), ipmiUserDataFile) != 0)
+    {
+        log<level::ERR>("Error in renaming temporary IPMI user data file");
+        throw std::runtime_error("Error in renaming IPMI user data file");
+    }
+    // Update the timestamp
+    fileLastUpdatedTime = getUpdatedFileTime();
+    return;
+}
+
+bool UserAccess::addUserEntry(const std::string& userName,
+                              const std::string& sysPriv, const bool& enabled)
+{
+    UsersTbl* userData = getUsersTblPtr();
+    size_t freeIndex = 0xFF;
+    // user index 0 is reserved, starts with 1
+    for (size_t usrIndex = 1; usrIndex <= ipmiMaxUsers; ++usrIndex)
+    {
+        std::string curName(
+            reinterpret_cast<char*>(userData->user[usrIndex].userName), 0,
+            ipmiMaxUserName);
+        if (userName == curName)
+        {
+            log<level::DEBUG>("User name exists",
+                              entry("USER_NAME=%s", userName.c_str()));
+            return false; // user name exists.
+        }
+
+        if ((!userData->user[usrIndex].userInSystem) &&
+            (userData->user[usrIndex].userName[0] == '\0') &&
+            (freeIndex == 0xFF))
+        {
+            freeIndex = usrIndex;
+        }
+    }
+    if (freeIndex == 0xFF)
+    {
+        log<level::ERR>("No empty slots found");
+        return false;
+    }
+    std::strncpy(reinterpret_cast<char*>(userData->user[freeIndex].userName),
+                 userName.c_str(), ipmiMaxUserName);
+    uint8_t priv =
+        static_cast<uint8_t>(UserAccess::convertToIPMIPrivilege(sysPriv)) &
+        privMask;
+    for (size_t chIndex = 0; chIndex < ipmiMaxChannels; ++chIndex)
+    {
+        userData->user[freeIndex].userPrivAccess[chIndex].privilege = priv;
+        userData->user[freeIndex].userPrivAccess[chIndex].ipmiEnabled = true;
+        userData->user[freeIndex].userPrivAccess[chIndex].linkAuthEnabled =
+            true;
+        userData->user[freeIndex].userPrivAccess[chIndex].accessCallback = true;
+    }
+    userData->user[freeIndex].userInSystem = true;
+    userData->user[freeIndex].userEnabled = enabled;
+
+    return true;
+}
+
+void UserAccess::deleteUserIndex(const size_t& usrIdx)
+{
+    UsersTbl* userData = getUsersTblPtr();
+
+    std::string userName(
+        reinterpret_cast<char*>(userData->user[usrIdx].userName), 0,
+        ipmiMaxUserName);
+    ipmiClearUserEntryPassword(userName);
+    std::fill(static_cast<uint8_t*>(userData->user[usrIdx].userName),
+              static_cast<uint8_t*>(userData->user[usrIdx].userName) +
+                  sizeof(userData->user[usrIdx].userName),
+              0);
+    for (size_t chIndex = 0; chIndex < ipmiMaxChannels; ++chIndex)
+    {
+        userData->user[usrIdx].userPrivAccess[chIndex].privilege = privNoAccess;
+        userData->user[usrIdx].userPrivAccess[chIndex].ipmiEnabled = false;
+        userData->user[usrIdx].userPrivAccess[chIndex].linkAuthEnabled = false;
+        userData->user[usrIdx].userPrivAccess[chIndex].accessCallback = false;
+    }
+    userData->user[usrIdx].userInSystem = false;
+    userData->user[usrIdx].userEnabled = false;
+    return;
+}
+
+void UserAccess::checkAndReloadUserData()
+{
+    std::time_t updateTime = getUpdatedFileTime();
+    if (updateTime != fileLastUpdatedTime || updateTime == -EIO)
+    {
+        std::fill(reinterpret_cast<uint8_t*>(&usersTbl),
+                  reinterpret_cast<uint8_t*>(&usersTbl) + sizeof(usersTbl), 0);
+        readUserData();
+    }
+    return;
+}
+
+UsersTbl* UserAccess::getUsersTblPtr()
+{
+    // reload data before using it.
+    checkAndReloadUserData();
+    return &usersTbl;
+}
+
+void UserAccess::getSystemPrivAndGroups()
+{
+    std::map<std::string, PrivAndGroupType> properties;
+    try
+    {
+        auto method = bus.new_method_call(
+            getUserServiceName().c_str(), userMgrObjBasePath,
+            dBusPropertiesInterface, getAllPropertiesMethod);
+        method.append(userMgrInterface);
+
+        auto reply = bus.call(method);
+        reply.read(properties);
+    }
+    catch (const sdbusplus::exception::SdBusError& e)
+    {
+        log<level::DEBUG>("Failed to excute method",
+                          entry("METHOD=%s", getAllPropertiesMethod),
+                          entry("PATH=%s", userMgrObjBasePath));
+        return;
+    }
+    for (const auto& t : properties)
+    {
+        auto key = t.first;
+        if (key == allPrivProperty)
+        {
+            availablePrivileges = t.second.get<std::vector<std::string>>();
+        }
+        else if (key == allGrpProperty)
+        {
+            availableGroups = t.second.get<std::vector<std::string>>();
+        }
+    }
+    // TODO: Implement Supported Privilege & Groups verification logic
+    return;
+}
+
+std::time_t UserAccess::getUpdatedFileTime()
+{
+    struct stat fileStat;
+    if (stat(ipmiUserDataFile, &fileStat) != 0)
+    {
+        log<level::DEBUG>("Error in getting last updated time stamp");
+        return -EIO;
+    }
+    return fileStat.st_mtime;
+}
+
+void UserAccess::getUserProperties(const DbusUserObjProperties& properties,
+                                   std::vector<std::string>& usrGrps,
+                                   std::string& usrPriv, bool& usrEnabled)
+{
+    for (const auto& t : properties)
+    {
+        std::string key = t.first;
+        if (key == userPrivProperty)
+        {
+            usrPriv = t.second.get<std::string>();
+        }
+        else if (key == userGrpProperty)
+        {
+            usrGrps = t.second.get<std::vector<std::string>>();
+        }
+        else if (key == userEnabledProperty)
+        {
+            usrEnabled = t.second.get<bool>();
+        }
+    }
+    return;
+}
+
+int UserAccess::getUserObjProperties(const DbusUserObjValue& userObjs,
+                                     std::vector<std::string>& usrGrps,
+                                     std::string& usrPriv, bool& usrEnabled)
+{
+    auto usrObj = userObjs.find(usersInterface);
+    if (usrObj != userObjs.end())
+    {
+        getUserProperties(usrObj->second, usrGrps, usrPriv, usrEnabled);
+        return 0;
+    }
+    return -EIO;
+}
+
+void UserAccess::initUserDataFile()
+{
+    boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
+        userLock{*userMutex};
+    try
+    {
+        readUserData();
+    }
+    catch (const std::ios_base::failure& e)
+    { // File is empty, create it for the first time
+        std::fill(reinterpret_cast<uint8_t*>(&usersTbl),
+                  reinterpret_cast<uint8_t*>(&usersTbl) + sizeof(usersTbl), 0);
+        // user index 0 is reserved, starts with 1
+        for (size_t userIndex = 1; userIndex <= ipmiMaxUsers; ++userIndex)
+        {
+            for (size_t chIndex = 0; chIndex < ipmiMaxChannels; ++chIndex)
+            {
+                usersTbl.user[userIndex].userPrivAccess[chIndex].privilege =
+                    privNoAccess;
+            }
+        }
+        writeUserData();
+    }
+    std::map<DbusUserObjPath, DbusUserObjValue> managedObjs;
+    try
+    {
+        auto method = bus.new_method_call(getUserServiceName().c_str(),
+                                          userMgrObjBasePath, dBusObjManager,
+                                          getManagedObjectsMethod);
+        auto reply = bus.call(method);
+        reply.read(managedObjs);
+    }
+    catch (const sdbusplus::exception::SdBusError& e)
+    {
+        log<level::DEBUG>("Failed to excute method",
+                          entry("METHOD=%s", getSubTreeMethod),
+                          entry("PATH=%s", userMgrObjBasePath));
+        return;
+    }
+
+    UsersTbl* userData = &usersTbl;
+    // user index 0 is reserved, starts with 1
+    for (size_t usrIdx = 1; usrIdx <= ipmiMaxUsers; ++usrIdx)
+    {
+        if ((userData->user[usrIdx].userInSystem) &&
+            (userData->user[usrIdx].userName[0] != '\0'))
+        {
+            std::vector<std::string> usrGrps;
+            std::string usrPriv;
+            bool usrEnabled;
+
+            std::string userName(
+                reinterpret_cast<char*>(userData->user[usrIdx].userName), 0,
+                ipmiMaxUserName);
+            std::string usersPath =
+                std::string(userObjBasePath) + "/" + userName;
+
+            auto usrObj = managedObjs.find(usersPath);
+            if (usrObj != managedObjs.end())
+            {
+                // User exist. Lets check and update other fileds
+                getUserObjProperties(usrObj->second, usrGrps, usrPriv,
+                                     usrEnabled);
+                if (std::find(usrGrps.begin(), usrGrps.end(), ipmiGrpName) ==
+                    usrGrps.end())
+                {
+                    // Group "ipmi" is removed so lets remove user in IPMI
+                    deleteUserIndex(usrIdx);
+                }
+                else
+                {
+                    // Group "ipmi" is present so lets update other properties
+                    // in IPMI
+                    uint8_t priv =
+                        UserAccess::convertToIPMIPrivilege(usrPriv) & privMask;
+                    // Update all channels priv, only if it is not equivalent to
+                    // getUsrMgmtSyncIndex()
+                    if (userData->user[usrIdx]
+                            .userPrivAccess[getUsrMgmtSyncIndex()]
+                            .privilege != priv)
+                    {
+                        for (size_t chIndex = 0; chIndex < ipmiMaxChannels;
+                             ++chIndex)
+                        {
+                            userData->user[usrIdx]
+                                .userPrivAccess[chIndex]
+                                .privilege = priv;
+                        }
+                    }
+                    if (userData->user[usrIdx].userEnabled != usrEnabled)
+                    {
+                        userData->user[usrIdx].userEnabled = usrEnabled;
+                    }
+                }
+
+                // We are done with this obj. lets delete from MAP
+                managedObjs.erase(usrObj);
+            }
+            else
+            {
+                deleteUserIndex(usrIdx);
+            }
+        }
+    }
+
+    // Walk through remnaining managedObj users list
+    // Add them to ipmi data base
+    for (const auto& usrObj : managedObjs)
+    {
+        std::vector<std::string> usrGrps;
+        std::string usrPriv, userName;
+        bool usrEnabled;
+        std::string usrObjPath = std::string(usrObj.first);
+        if (getUserNameFromPath(usrObj.first.str, userName) != 0)
+        {
+            log<level::ERR>("Error in user object path");
+            continue;
+        }
+        getUserObjProperties(usrObj.second, usrGrps, usrPriv, usrEnabled);
+        // Add 'ipmi' group users
+        if (std::find(usrGrps.begin(), usrGrps.end(), ipmiGrpName) !=
+            usrGrps.end())
+        {
+            // CREATE NEW USER
+            if (true != addUserEntry(userName, usrPriv, usrEnabled))
+            {
+                break;
+            }
+        }
+    }
+
+    // All userData slots update done. Lets write the data
+    writeUserData();
+
+    return;
+}
+} // namespace ipmi
diff --git a/user_channel/user_mgmt.hpp b/user_channel/user_mgmt.hpp
new file mode 100644
index 0000000..16dbd31
--- /dev/null
+++ b/user_channel/user_mgmt.hpp
@@ -0,0 +1,295 @@
+/*
+// Copyright (c) 2018 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+#pragma once
+#include "user_layer.hpp"
+
+#include <host-ipmid/ipmid-api.h>
+
+#include <boost/interprocess/sync/file_lock.hpp>
+#include <boost/interprocess/sync/named_recursive_mutex.hpp>
+#include <cstdint>
+#include <ctime>
+#include <sdbusplus/bus.hpp>
+
+namespace ipmi
+{
+
+using DbusUserPropVariant =
+    sdbusplus::message::variant<std::vector<std::string>, std::string, bool>;
+
+using DbusUserObjPath = sdbusplus::message::object_path;
+
+using DbusUserObjProperties =
+    std::vector<std::pair<std::string, DbusUserPropVariant>>;
+
+using DbusUserObjValue = std::map<std::string, DbusUserObjProperties>;
+
+enum class UserUpdateEvent
+{
+    reservedEvent,
+    userCreated,
+    userDeleted,
+    userRenamed,
+    userGrpUpdated,
+    userPrivUpdated,
+    userStateUpdated
+};
+
+struct UserPrivAccess
+{
+    uint8_t privilege;
+    bool ipmiEnabled;
+    bool linkAuthEnabled;
+    bool accessCallback;
+};
+
+struct UserInfo
+{
+    uint8_t userName[ipmiMaxUserName];
+    UserPrivAccess userPrivAccess[ipmiMaxChannels];
+    bool userEnabled;
+    bool userInSystem;
+    bool fixedUserName;
+};
+
+struct UsersTbl
+{
+    //+1 to map with UserId directly. UserId 0 is reserved.
+    UserInfo user[ipmiMaxUsers + 1];
+};
+
+class UserAccess;
+
+UserAccess& getUserAccessObject();
+
+class UserAccess
+{
+  public:
+    UserAccess(const UserAccess&) = delete;
+    UserAccess& operator=(const UserAccess&) = delete;
+    UserAccess(UserAccess&&) = delete;
+    UserAccess& operator=(UserAccess&&) = delete;
+
+    ~UserAccess();
+    UserAccess();
+
+    /** @brief determines valid channel
+     *
+     *  @param[in] chNum - channel number
+     *
+     *  @return true if valid, false otherwise
+     */
+    static bool isValidChannel(const uint8_t& chNum);
+
+    /** @brief determines valid userId
+     *
+     *  @param[in] userId - user id
+     *
+     *  @return true if valid, false otherwise
+     */
+    static bool isValidUserId(const uint8_t& userId);
+
+    /** @brief determines valid user privilege
+     *
+     *  @param[in] priv - Privilege
+     *
+     *  @return true if valid, false otherwise
+     */
+    static bool isValidPrivilege(const uint8_t& priv);
+
+    /** @brief determines sync index to be mapped with common-user-management
+     *
+     *  @return Index which will be used as sync index
+     */
+    static uint8_t getUsrMgmtSyncIndex();
+
+    /** @brief Converts system privilege to IPMI privilege
+     *
+     *  @param[in] value - Privilege in string
+     *
+     *  @return CommandPrivilege - IPMI privilege type
+     */
+    static CommandPrivilege convertToIPMIPrivilege(const std::string& value);
+
+    /** @brief Converts IPMI privilege to system privilege
+     *
+     *  @param[in] value - IPMI privilege
+     *
+     *  @return System privilege in string
+     */
+    static std::string convertToSystemPrivilege(const CommandPrivilege& value);
+
+    /** @brief determines whether user name is valid
+     *
+     *  @param[in] userNameInChar - user name
+     *
+     *  @return true if valid, false otherwise
+     */
+    bool isValidUserName(const char* userNameInChar);
+
+    /** @brief provides user id of the user
+     *
+     *  @param[in] userName - user name
+     *
+     *  @return user id of the user, else invalid user id (0xFF), if user not
+     * found
+     */
+    uint8_t getUserId(const std::string& userName);
+
+    /** @brief provides user information
+     *
+     *  @param[in] userId - user id
+     *
+     *  @return UserInfo for the specified user id
+     */
+    UserInfo* getUserInfo(const uint8_t& userId);
+
+    /** @brief sets user information
+     *
+     *  @param[in] userId - user id
+     *  @param[in] userInfo - user information
+     *
+     */
+    void setUserInfo(const uint8_t& userId, UserInfo* userInfo);
+
+    /** @brief provides user name
+     *
+     *  @param[in] userId - user id
+     *  @param[out] userName - user name
+     *
+     *  @return IPMI_CC_OK for success, others for failure.
+     */
+    ipmi_ret_t getUserName(const uint8_t& userId, std::string& userName);
+
+    /** @brief to set user name
+     *
+     *  @param[in] userId - user id
+     *  @param[in] userNameInChar - user name
+     *
+     *  @return IPMI_CC_OK for success, others for failure.
+     */
+    ipmi_ret_t setUserName(const uint8_t& userId, const char* userNameInChar);
+
+    /** @brief to set user privilege and access details
+     *
+     *  @param[in] userId - user id
+     *  @param[in] chNum - channel number
+     *  @param[in] privAccess - privilege access
+     *  @param[in] otherPrivUpdates - other privilege update flag to update ipmi
+     * enable, link authentication and access callback
+     *
+     *  @return IPMI_CC_OK for success, others for failure.
+     */
+    ipmi_ret_t setUserPrivilegeAccess(const uint8_t& userId,
+                                      const uint8_t& chNum,
+                                      const UserPrivAccess& privAccess,
+                                      const bool& otherPrivUpdates);
+
+    /** @brief reads user management related data from configuration file
+     *
+     */
+    void readUserData();
+
+    /** @brief writes user management related data to configuration file
+     *
+     */
+    void writeUserData();
+
+    /** @brief Funtion which checks and reload configuration file data if
+     * needed.
+     *
+     */
+    void checkAndReloadUserData();
+
+    /** @brief provides user details from D-Bus user property data
+     *
+     *  @param[in] properties - D-Bus user property
+     *  @param[out] usrGrps - user group details
+     *  @param[out] usrPriv - user privilege
+     *  @param[out] usrEnabled - enabled state of the user.
+     *
+     *  @return 0 for success, -errno for failure.
+     */
+    void getUserProperties(const DbusUserObjProperties& properties,
+                           std::vector<std::string>& usrGrps,
+                           std::string& usrPriv, bool& usrEnabled);
+
+    /** @brief provides user details from D-Bus user object data
+     *
+     *  @param[in] userObjs - D-Bus user object
+     *  @param[out] usrGrps - user group details
+     *  @param[out] usrPriv - user privilege
+     *  @param[out] usrEnabled - enabled state of the user.
+     *
+     *  @return 0 for success, -errno for failure.
+     */
+    int getUserObjProperties(const DbusUserObjValue& userObjs,
+                             std::vector<std::string>& usrGrps,
+                             std::string& usrPriv, bool& usrEnabled);
+
+    /** @brief function to add user entry information to the configuration
+     *
+     *  @param[in] userName - user name
+     *  @param[in] priv - privilege of the user
+     *  @param[in] enabled - enabled state of the user
+     *
+     *  @return true for success, false for failure
+     */
+    bool addUserEntry(const std::string& userName, const std::string& priv,
+                      const bool& enabled);
+
+    /** @brief function to delete user entry based on user index
+     *
+     *  @param[in] usrIdx - user index
+     *
+     */
+    void deleteUserIndex(const size_t& usrIdx);
+
+    /** @brief function to get users table
+     *
+     */
+    UsersTbl* getUsersTblPtr();
+
+    std::unique_ptr<boost::interprocess::named_recursive_mutex> userMutex{
+        nullptr};
+
+  private:
+    UsersTbl usersTbl;
+    std::vector<std::string> availablePrivileges;
+    std::vector<std::string> availableGroups;
+    sdbusplus::bus::bus bus;
+    std::time_t fileLastUpdatedTime;
+    bool signalHndlrObject = false;
+    boost::interprocess::file_lock sigHndlrLock;
+    boost::interprocess::file_lock mutexCleanupLock;
+
+    /** @brief function to get user configuration file timestamp
+     *
+     *  @return time stamp or -EIO for failure
+     */
+    std::time_t getUpdatedFileTime();
+
+    /** @brief function to available system privileges and groups
+     *
+     */
+    void getSystemPrivAndGroups();
+
+    /** @brief function to init user data from configuration & D-Bus objects
+     *
+     */
+    void initUserDataFile();
+};
+} // namespace ipmi
diff --git a/user_channel/usercommands.cpp b/user_channel/usercommands.cpp
new file mode 100644
index 0000000..0ed5b8f
--- /dev/null
+++ b/user_channel/usercommands.cpp
@@ -0,0 +1,473 @@
+/*
+// Copyright (c) 2018 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+
+#include "usercommands.hpp"
+
+#include "apphandler.hpp"
+#include "user_layer.hpp"
+
+#include <host-ipmid/ipmid-api.h>
+#include <security/pam_appl.h>
+
+#include <phosphor-logging/log.hpp>
+#include <regex>
+
+namespace ipmi
+{
+
+using namespace phosphor::logging;
+
+static constexpr uint8_t maxIpmi20PasswordSize = 20;
+static constexpr uint8_t maxIpmi15PasswordSize = 16;
+static constexpr uint8_t disableUser = 0x00;
+static constexpr uint8_t enableUser = 0x01;
+static constexpr uint8_t setPassword = 0x02;
+static constexpr uint8_t testPassword = 0x03;
+
+struct SetUserAccessReq
+{
+#if BYTE_ORDER == LITTLE_ENDIAN
+    uint8_t chNum : 4;
+    uint8_t ipmiEnabled : 1;
+    uint8_t linkAuthEnabled : 1;
+    uint8_t accessCallback : 1;
+    uint8_t bitsUpdate : 1;
+    uint8_t userId : 6;
+    uint8_t reserved1 : 2;
+    uint8_t privilege : 4;
+    uint8_t reserved2 : 4;
+    uint8_t sessLimit : 4; // optional byte 4
+    uint8_t reserved3 : 4;
+#endif
+#if BYTE_ORDER == BIG_ENDIAN
+    uint8_t bitsUpdate : 1;
+    uint8_t accessCallback : 1;
+    uint8_t linkAuthEnabled : 1;
+    uint8_t ipmiEnabled : 1;
+    uint8_t chNum : 4;
+    uint8_t reserved1 : 2;
+    uint8_t userId : 6;
+    uint8_t reserved2 : 4;
+    uint8_t privilege : 4;
+    uint8_t reserved3 : 4;
+    uint8_t sessLimit : 4; // optional byte 4
+#endif
+
+} __attribute__((packed));
+
+struct GetUserAccessReq
+{
+#if BYTE_ORDER == LITTLE_ENDIAN
+    uint8_t chNum : 4;
+    uint8_t reserved1 : 4;
+    uint8_t userId : 6;
+    uint8_t reserved2 : 2;
+#endif
+#if BYTE_ORDER == BIG_ENDIAN
+    uint8_t reserved1 : 4;
+    uint8_t chNum : 4;
+    uint8_t reserved2 : 2;
+    uint8_t userId : 6;
+#endif
+} __attribute__((packed));
+
+struct GetUserAccessResp
+{
+#if BYTE_ORDER == LITTLE_ENDIAN
+    uint8_t maxChUsers : 6;
+    uint8_t reserved1 : 2;
+    uint8_t enabledUsers : 6;
+    uint8_t enabledStatus : 2;
+    uint8_t fixedUsers : 6;
+    uint8_t reserved2 : 2;
+#endif
+#if BYTE_ORDER == BIG_ENDIAN
+    uint8_t reserved1 : 2;
+    uint8_t maxChUsers : 6;
+    uint8_t enabledStatus : 2;
+    uint8_t enabledUsers : 6;
+    uint8_t reserved2 : 2;
+    uint8_t fixedUsers : 6;
+#endif
+    PrivAccess privAccess;
+} __attribute__((packed));
+
+struct SetUserNameReq
+{
+#if BYTE_ORDER == LITTLE_ENDIAN
+    uint8_t userId : 6;
+    uint8_t reserved1 : 2;
+#endif
+#if BYTE_ORDER == BIG_ENDIAN
+    uint8_t reserved1 : 2;
+    uint8_t userId : 6;
+#endif
+    uint8_t userName[16];
+} __attribute__((packed));
+
+struct GetUserNameReq
+{
+#if BYTE_ORDER == LITTLE_ENDIAN
+    uint8_t userId : 6;
+    uint8_t reserved1 : 2;
+#endif
+#if BYTE_ORDER == BIG_ENDIAN
+    uint8_t reserved1 : 2;
+    uint8_t userId : 6;
+#endif
+} __attribute__((packed));
+
+struct GetUserNameResp
+{
+    uint8_t userName[16];
+} __attribute__((packed));
+
+struct SetUserPasswordReq
+{
+#if BYTE_ORDER == LITTLE_ENDIAN
+    uint8_t userId : 6;
+    uint8_t reserved1 : 1;
+    uint8_t ipmi20 : 1;
+    uint8_t operation : 2;
+    uint8_t reserved2 : 6;
+#endif
+#if BYTE_ORDER == BIG_ENDIAN
+    uint8_t ipmi20 : 1;
+    uint8_t reserved1 : 1;
+    uint8_t userId : 6;
+    uint8_t reserved2 : 6;
+    uint8_t operation : 2;
+#endif
+    uint8_t userPassword[maxIpmi20PasswordSize];
+} __attribute__((packed));
+
+ipmi_ret_t ipmiSetUserAccess(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+                             ipmi_request_t request, ipmi_response_t response,
+                             ipmi_data_len_t dataLen, ipmi_context_t context)
+{
+    const SetUserAccessReq* req = static_cast<SetUserAccessReq*>(request);
+    size_t reqLength = *dataLen;
+
+    if (!(reqLength == sizeof(*req) ||
+          (reqLength == (sizeof(*req) - sizeof(uint8_t) /* skip optional*/))))
+    {
+        log<level::DEBUG>("Set user access - Invalid Length");
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+    if (req->reserved1 != 0 || req->reserved2 != 0 || req->reserved3 != 0 ||
+        req->sessLimit != 0 ||
+        (!ipmiUserIsValidChannel(req->chNum) ||
+         (!ipmiUserIsValidPrivilege(req->privilege))))
+    // TODO: Need to check for session support and return invalid field in
+    // request
+    {
+        log<level::DEBUG>("Set user access - Invalid field in request");
+        return IPMI_CC_INVALID_FIELD_REQUEST;
+    }
+    if (!ipmiUserIsValidUserId(req->userId))
+    {
+        log<level::DEBUG>("Set user access - Parameter out of range");
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+    // TODO: Determine the Channel number 0xE (Self Channel number ?)
+    uint8_t chNum = req->chNum;
+    PrivAccess privAccess = {0};
+    if (req->bitsUpdate)
+    {
+        privAccess.ipmiEnabled = req->ipmiEnabled;
+        privAccess.linkAuthEnabled = req->linkAuthEnabled;
+        privAccess.accessCallback = req->accessCallback;
+    }
+    privAccess.privilege = req->privilege;
+    ipmiUserSetPrivilegeAccess(req->userId, chNum, privAccess, req->bitsUpdate);
+
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t ipmiGetUserAccess(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+                             ipmi_request_t request, ipmi_response_t response,
+                             ipmi_data_len_t dataLen, ipmi_context_t context)
+{
+    const GetUserAccessReq* req = static_cast<GetUserAccessReq*>(request);
+    size_t reqLength = *dataLen;
+
+    *dataLen = 0;
+
+    if (reqLength != sizeof(*req))
+    {
+        log<level::DEBUG>("Get user access - Invalid Length");
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+    if (req->reserved1 != 0 || req->reserved2 != 0 ||
+        (!ipmiUserIsValidChannel(req->chNum)))
+    // TODO: Need to check for session support and return invalid field in
+    // request
+    {
+        log<level::DEBUG>("Get user access - Invalid field in request");
+        return IPMI_CC_INVALID_FIELD_REQUEST;
+    }
+    if (!ipmiUserIsValidUserId(req->userId))
+    {
+        log<level::DEBUG>("Get user access - Parameter out of range");
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    uint8_t maxChUsers = 0, enabledUsers = 0, fixedUsers = 0;
+    bool enabledState = false;
+    // TODO: Determine the Channel number 0xE (Self Channel number ?)
+    uint8_t chNum = req->chNum;
+    GetUserAccessResp* resp = static_cast<GetUserAccessResp*>(response);
+
+    std::fill(reinterpret_cast<uint8_t*>(resp),
+              reinterpret_cast<uint8_t*>(resp) + sizeof(*resp), 0);
+
+    ipmiUserGetAllCounts(maxChUsers, enabledUsers, fixedUsers);
+    resp->maxChUsers = maxChUsers;
+    resp->enabledUsers = enabledUsers;
+    resp->fixedUsers = fixedUsers;
+
+    ipmiUserCheckEnabled(req->userId, enabledState);
+    resp->enabledStatus = enabledState ? userIdEnabledViaSetPassword
+                                       : userIdDisabledViaSetPassword;
+    ipmiUserGetPrivilegeAccess(req->userId, chNum, resp->privAccess);
+    *dataLen = sizeof(*resp);
+
+    return IPMI_CC_OK;
+}
+
+ipmi_ret_t ipmiSetUserName(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+                           ipmi_request_t request, ipmi_response_t response,
+                           ipmi_data_len_t dataLen, ipmi_context_t context)
+{
+    const SetUserNameReq* req = static_cast<SetUserNameReq*>(request);
+    size_t reqLength = *dataLen;
+    *dataLen = 0;
+
+    if (reqLength != sizeof(*req))
+    {
+        log<level::DEBUG>("Set user name - Invalid Length");
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+    if (req->reserved1)
+    {
+        return IPMI_CC_INVALID_FIELD_REQUEST;
+    }
+    if (!ipmiUserIsValidUserId(req->userId))
+    {
+        log<level::DEBUG>("Set user name - Invalid user id");
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+    return ipmiUserSetUserName(req->userId,
+                               reinterpret_cast<const char*>(req->userName));
+}
+
+/** @brief implementes the get user name command
+ *  @param[in] netfn - specifies netfn.
+ *  @param[in] cmd   - specifies cmd number.
+ *  @param[in] request - pointer to request data.
+ *  @param[in, out] dataLen - specifies request data length, and returns
+ * response data length.
+ *  @param[in] context - ipmi context.
+ *  @returns ipmi completion code.
+ */
+ipmi_ret_t ipmiGetUserName(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+                           ipmi_request_t request, ipmi_response_t response,
+                           ipmi_data_len_t dataLen, ipmi_context_t context)
+{
+    const GetUserNameReq* req = static_cast<GetUserNameReq*>(request);
+    size_t reqLength = *dataLen;
+
+    *dataLen = 0;
+
+    if (reqLength != sizeof(*req))
+    {
+        log<level::DEBUG>("Get user name - Invalid Length");
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    std::string userName;
+    if (ipmiUserGetUserName(req->userId, userName) != IPMI_CC_OK)
+    { // Invalid User ID
+        log<level::DEBUG>("User Name not found",
+                          entry("USER-ID:%d", (uint8_t)req->userId));
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+    GetUserNameResp* resp = static_cast<GetUserNameResp*>(response);
+    std::fill(reinterpret_cast<uint8_t*>(resp),
+              reinterpret_cast<uint8_t*>(resp) + sizeof(*resp), 0);
+    userName.copy(reinterpret_cast<char*>(resp->userName),
+                  sizeof(resp->userName), 0);
+    *dataLen = sizeof(*resp);
+
+    return IPMI_CC_OK;
+}
+
+int pamFunctionConversation(int numMsg, const struct pam_message** msg,
+                            struct pam_response** resp, void* appdataPtr)
+{
+    if (appdataPtr == nullptr)
+    {
+        return PAM_AUTH_ERR;
+    }
+    size_t passSize = std::strlen(reinterpret_cast<char*>(appdataPtr)) + 1;
+    char* pass = reinterpret_cast<char*>(malloc(passSize));
+    std::strncpy(pass, reinterpret_cast<char*>(appdataPtr), passSize);
+
+    *resp = reinterpret_cast<pam_response*>(
+        calloc(numMsg, sizeof(struct pam_response)));
+
+    for (int i = 0; i < numMsg; ++i)
+    {
+        if (msg[i]->msg_style != PAM_PROMPT_ECHO_OFF)
+        {
+            continue;
+        }
+        resp[i]->resp = pass;
+    }
+    return PAM_SUCCESS;
+}
+
+bool pamUpdatePasswd(const char* username, const char* password)
+{
+    const struct pam_conv localConversation = {pamFunctionConversation,
+                                               const_cast<char*>(password)};
+    pam_handle_t* localAuthHandle = NULL; // this gets set by pam_start
+
+    if (pam_start("passwd", username, &localConversation, &localAuthHandle) !=
+        PAM_SUCCESS)
+    {
+        return false;
+    }
+    int retval = pam_chauthtok(localAuthHandle, PAM_SILENT);
+
+    if (retval != PAM_SUCCESS)
+    {
+        if (retval == PAM_AUTHTOK_ERR)
+        {
+            log<level::DEBUG>("Authentication Failure");
+        }
+        else
+        {
+            log<level::DEBUG>("pam_chauthtok returned failure",
+                              entry("ERROR=%d", retval));
+        }
+        pam_end(localAuthHandle, retval);
+        return false;
+    }
+    if (pam_end(localAuthHandle, PAM_SUCCESS) != PAM_SUCCESS)
+    {
+        return false;
+    }
+    return true;
+}
+
+/** @brief implementes the set user password command
+ *  @param[in] netfn - specifies netfn.
+ *  @param[in] cmd   - specifies cmd number.
+ *  @param[in] request - pointer to request data.
+ *  @param[in, out] dataLen - specifies request data length, and returns
+ * response data length.
+ *  @param[in] context - ipmi context.
+ *  @returns ipmi completion code.
+ */
+ipmi_ret_t ipmiSetUserPassword(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+                               ipmi_request_t request, ipmi_response_t response,
+                               ipmi_data_len_t dataLen, ipmi_context_t context)
+{
+    const SetUserPasswordReq* req = static_cast<SetUserPasswordReq*>(request);
+    size_t reqLength = *dataLen;
+    // subtract 2 bytes header to know the password length - including NULL
+    uint8_t passwordLength = *dataLen - 2;
+    *dataLen = 0;
+
+    // verify input length based on operation. Required password size is 20
+    // bytes as  we support only IPMI 2.0, but in order to be compatible with
+    // tools, accept 16 bytes of password size too.
+    if (reqLength < 2 ||
+        // If enable / disable user, reqLength has to be >=2 & <= 22
+        ((req->operation == disableUser || req->operation == enableUser) &&
+         ((reqLength < 2) || (reqLength > sizeof(SetUserPasswordReq)))))
+    {
+        log<level::DEBUG>("Invalid Length");
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+    // If set / test password then password length has to be 16 or 20 bytes
+    if (((req->operation == setPassword) || (req->operation == testPassword)) &&
+        ((passwordLength != maxIpmi20PasswordSize) &&
+         (passwordLength != maxIpmi15PasswordSize)))
+    {
+        log<level::DEBUG>("Invalid Length");
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    std::string userName;
+    if (ipmiUserGetUserName(req->userId, userName) != IPMI_CC_OK)
+    {
+        log<level::DEBUG>("User Name not found",
+                          entry("USER-ID:%d", (uint8_t)req->userId));
+        return IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+    if (req->operation == setPassword)
+    {
+        std::string passwd;
+        passwd.assign(reinterpret_cast<const char*>(req->userPassword), 0,
+                      maxIpmi20PasswordSize);
+        if (!std::regex_match(passwd.c_str(),
+                              std::regex("[a-zA-z_0-9][a-zA-Z_0-9,?:`!\"]*")))
+        {
+            log<level::DEBUG>("Invalid password fields",
+                              entry("USER-ID:%d", (uint8_t)req->userId));
+            return IPMI_CC_INVALID_FIELD_REQUEST;
+        }
+        if (!pamUpdatePasswd(userName.c_str(), passwd.c_str()))
+        {
+            log<level::DEBUG>("Failed to update password",
+                              entry("USER-ID:%d", (uint8_t)req->userId));
+            return IPMI_CC_UNSPECIFIED_ERROR;
+        }
+    }
+    else
+    {
+        // TODO: test the password by reading the encrypted file
+        log<level::ERR>(
+            "Other operations not implemented - TODO yet to implement");
+        return IPMI_CC_INVALID_FIELD_REQUEST;
+    }
+    return IPMI_CC_OK;
+}
+
+void registerUserIpmiFunctions()
+{
+    ipmiUserInit();
+    ipmi_register_callback(NETFUN_APP, IPMI_CMD_SET_USER_ACCESS, NULL,
+                           ipmiSetUserAccess, PRIVILEGE_ADMIN);
+
+    ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_USER_ACCESS, NULL,
+                           ipmiGetUserAccess, PRIVILEGE_OPERATOR);
+
+    ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_USER_NAME, NULL,
+                           ipmiGetUserName, PRIVILEGE_OPERATOR);
+
+    ipmi_register_callback(NETFUN_APP, IPMI_CMD_SET_USER_NAME, NULL,
+                           ipmiSetUserName, PRIVILEGE_ADMIN);
+
+    ipmi_register_callback(NETFUN_APP, IPMI_CMD_SET_USER_PASSWORD, NULL,
+                           ipmiSetUserPassword, PRIVILEGE_ADMIN);
+
+    return;
+}
+} // namespace ipmi
diff --git a/user_channel/usercommands.hpp b/user_channel/usercommands.hpp
new file mode 100644
index 0000000..ee33b5a
--- /dev/null
+++ b/user_channel/usercommands.hpp
@@ -0,0 +1,36 @@
+/*
+// Copyright (c) 2018 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+
+#pragma once
+#include <cstdint>
+
+namespace ipmi
+{
+// IPMI commands for user command NETFN:APP.
+enum ipmi_netfn_user_cmds
+{
+    IPMI_CMD_SET_USER_ACCESS = 0x43,
+    IPMI_CMD_GET_USER_ACCESS = 0x44,
+    IPMI_CMD_SET_USER_NAME = 0x45,
+    IPMI_CMD_GET_USER_NAME = 0x46,
+    IPMI_CMD_SET_USER_PASSWORD = 0x47,
+};
+
+static constexpr uint8_t userIdEnabledViaSetPassword = 0x1;
+static constexpr uint8_t userIdDisabledViaSetPassword = 0x2;
+
+void registerUserIpmiFunctions();
+} // namespace ipmi
