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
