diff --git a/user_mgr.cpp b/user_mgr.cpp
new file mode 100644
index 0000000..3987088
--- /dev/null
+++ b/user_mgr.cpp
@@ -0,0 +1,598 @@
+/*
+// 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 <shadow.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <fstream>
+#include <grp.h>
+#include <pwd.h>
+#include <regex>
+#include <algorithm>
+#include <numeric>
+#include <boost/process/child.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
+#include <xyz/openbmc_project/User/Common/error.hpp>
+#include <phosphor-logging/log.hpp>
+#include <phosphor-logging/elog.hpp>
+#include <phosphor-logging/elog-errors.hpp>
+#include "shadowlock.hpp"
+#include "file.hpp"
+#include "user_mgr.hpp"
+#include "users.hpp"
+#include "config.h"
+
+namespace phosphor
+{
+namespace user
+{
+
+static constexpr const char *passwdFileName = "/etc/passwd";
+static constexpr size_t ipmiMaxUsers = 15;
+static constexpr size_t ipmiMaxUserNameLen = 16;
+static constexpr size_t systemMaxUserNameLen = 30;
+static constexpr size_t maxSystemUsers = 30;
+static constexpr const char *grpSsh = "ssh";
+
+using namespace phosphor::logging;
+using InsufficientPermission =
+    sdbusplus::xyz::openbmc_project::Common::Error::InsufficientPermission;
+using InternalFailure =
+    sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
+using InvalidArgument =
+    sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument;
+using UserNameExists =
+    sdbusplus::xyz::openbmc_project::User::Common::Error::UserNameExists;
+using UserNameDoesNotExist =
+    sdbusplus::xyz::openbmc_project::User::Common::Error::UserNameDoesNotExist;
+using UserNameGroupFail =
+    sdbusplus::xyz::openbmc_project::User::Common::Error::UserNameGroupFail;
+
+using NoResource =
+    sdbusplus::xyz::openbmc_project::User::Common::Error::NoResource;
+
+using Argument = xyz::openbmc_project::Common::InvalidArgument;
+
+template <typename... ArgTypes>
+static void executeCmd(const char *path, ArgTypes &&... tArgs)
+{
+    boost::process::child execProg(path, const_cast<char *>(tArgs)...);
+    execProg.wait();
+    int retCode = execProg.exit_code();
+    if (retCode)
+    {
+        log<level::ERR>("Command execution failed", entry("PATH=%s", path),
+                        entry("RETURN_CODE:%d", retCode));
+        elog<InternalFailure>();
+    }
+    return;
+}
+
+static std::string getCSVFromVector(std::vector<std::string> vec)
+{
+    switch (vec.size())
+    {
+        case 0:
+        {
+            return "";
+        }
+        break;
+
+        case 1:
+        {
+            return std::string{vec[0]};
+        }
+        break;
+
+        default:
+        {
+            return std::accumulate(
+                std::next(vec.begin()), vec.end(), vec[0],
+                [](std::string a, std::string b) { return a + ',' + b; });
+        }
+    }
+}
+
+static bool removeStringFromCSV(std::string &csvStr, const std::string &delStr)
+{
+    std::string::size_type delStrPos = csvStr.find(delStr);
+    if (delStrPos != std::string::npos)
+    {
+        // need to also delete the comma char
+        if (delStrPos == 0)
+        {
+            csvStr.erase(delStrPos, delStr.size() + 1);
+        }
+        else
+        {
+            csvStr.erase(delStrPos - 1, delStr.size() + 1);
+        }
+        return true;
+    }
+    return false;
+}
+
+bool UserMgr::isUserExist(const std::string &userName)
+{
+    if (userName.empty())
+    {
+        log<level::ERR>("User name is empty");
+        elog<InvalidArgument>(Argument::ARGUMENT_NAME("User name"),
+                              Argument::ARGUMENT_VALUE("Null"));
+    }
+    if (usersList.find(userName) == usersList.end())
+    {
+        return false;
+    }
+    return true;
+}
+
+void UserMgr::throwForUserDoesNotExist(const std::string &userName)
+{
+    if (isUserExist(userName) == false)
+    {
+        log<level::ERR>("User does not exist",
+                        entry("USER_NAME=%s", userName.c_str()));
+        elog<UserNameDoesNotExist>();
+    }
+}
+
+void UserMgr::throwForUserExists(const std::string &userName)
+{
+    if (isUserExist(userName) == true)
+    {
+        log<level::ERR>("User already exists",
+                        entry("USER_NAME=%s", userName.c_str()));
+        elog<UserNameExists>();
+    }
+}
+
+void UserMgr::throwForUserNameConstraints(
+    const std::string &userName, const std::vector<std::string> &groupNames)
+{
+    if (std::find(groupNames.begin(), groupNames.end(), "ipmi") !=
+        groupNames.end())
+    {
+        if (userName.length() > ipmiMaxUserNameLen)
+        {
+            log<level::ERR>("IPMI user name length limitation",
+                            entry("SIZE=%d", userName.length()));
+            elog<UserNameGroupFail>(
+                xyz::openbmc_project::User::Common::UserNameGroupFail::REASON(
+                    "IPMI length"));
+        }
+    }
+    if (userName.length() > systemMaxUserNameLen)
+    {
+        log<level::ERR>("User name length limitation",
+                        entry("SIZE=%d", userName.length()));
+        elog<InvalidArgument>(Argument::ARGUMENT_NAME("User name"),
+                              Argument::ARGUMENT_VALUE("Invalid length"));
+    }
+    if (!std::regex_match(userName.c_str(),
+                          std::regex("[a-zA-z_][a-zA-Z_0-9]*")))
+    {
+        log<level::ERR>("Invalid user name",
+                        entry("USER_NAME=%s", userName.c_str()));
+        elog<InvalidArgument>(Argument::ARGUMENT_NAME("User name"),
+                              Argument::ARGUMENT_VALUE("Invalid data"));
+    }
+}
+
+void UserMgr::throwForMaxGrpUserCount(
+    const std::vector<std::string> &groupNames)
+{
+    if (std::find(groupNames.begin(), groupNames.end(), "ipmi") !=
+        groupNames.end())
+    {
+        if (getIpmiUsersCount() >= ipmiMaxUsers)
+        {
+            log<level::ERR>("IPMI user limit reached");
+            elog<NoResource>(
+                xyz::openbmc_project::User::Common::NoResource::REASON(
+                    "ipmi user count reached"));
+        }
+    }
+    else
+    {
+        if (usersList.size() > 0 && (usersList.size() - getIpmiUsersCount()) >=
+                                        (maxSystemUsers - ipmiMaxUsers))
+        {
+            log<level::ERR>("Non-ipmi User limit reached");
+            elog<NoResource>(
+                xyz::openbmc_project::User::Common::NoResource::REASON(
+                    "Non-ipmi user count reached"));
+        }
+    }
+    return;
+}
+
+void UserMgr::throwForInvalidPrivilege(const std::string &priv)
+{
+    if (!priv.empty() &&
+        (std::find(privMgr.begin(), privMgr.end(), priv) == privMgr.end()))
+    {
+        log<level::ERR>("Invalid privilege");
+        elog<InvalidArgument>(Argument::ARGUMENT_NAME("Privilege"),
+                              Argument::ARGUMENT_VALUE(priv.c_str()));
+    }
+}
+
+void UserMgr::throwForInvalidGroups(const std::vector<std::string> &groupNames)
+{
+    for (auto &group : groupNames)
+    {
+        if (std::find(groupsMgr.begin(), groupsMgr.end(), group) ==
+            groupsMgr.end())
+        {
+            log<level::ERR>("Invalid Group Name listed");
+            elog<InvalidArgument>(Argument::ARGUMENT_NAME("GroupName"),
+                                  Argument::ARGUMENT_VALUE(group.c_str()));
+        }
+    }
+}
+
+void UserMgr::createUser(std::string userName,
+                         std::vector<std::string> groupNames, std::string priv,
+                         bool enabled)
+{
+    throwForInvalidPrivilege(priv);
+    throwForInvalidGroups(groupNames);
+    // All user management lock has to be based on /etc/shadow
+    phosphor::user::shadow::Lock lock();
+    throwForUserExists(userName);
+    throwForUserNameConstraints(userName, groupNames);
+    throwForMaxGrpUserCount(groupNames);
+
+    std::string groups = getCSVFromVector(groupNames);
+    bool sshRequested = removeStringFromCSV(groups, grpSsh);
+
+    // treat privilege as a group - This is to avoid using different file to
+    // store the same.
+    if (groups.size() != 0)
+    {
+        groups += ",";
+    }
+    groups += priv;
+
+    try
+    {
+        executeCmd("/usr/sbin/useradd", userName.c_str(), "-G", groups.c_str(),
+                   "-M", "-N", "-s",
+                   (sshRequested ? "/bin/sh" : "/bin/nologin"), "-e",
+                   (enabled ? "" : "1970-01-02"));
+    }
+    catch (const InternalFailure &e)
+    {
+        log<level::ERR>("Unable to create new user");
+        elog<InternalFailure>();
+    }
+
+    // Add the users object before sending out the signal
+    std::string userObj = std::string(usersObjPath) + "/" + userName;
+    std::sort(groupNames.begin(), groupNames.end());
+    usersList.emplace(
+        userName, std::move(std::make_unique<phosphor::user::Users>(
+                      bus, userObj.c_str(), groupNames, priv, enabled, *this)));
+
+    log<level::INFO>("User created successfully",
+                     entry("USER_NAME=%s", userName.c_str()));
+    return;
+}
+
+void UserMgr::deleteUser(std::string userName)
+{
+    // All user management lock has to be based on /etc/shadow
+    phosphor::user::shadow::Lock lock();
+    throwForUserDoesNotExist(userName);
+    try
+    {
+        executeCmd("/usr/sbin/userdel", userName.c_str());
+    }
+    catch (const InternalFailure &e)
+    {
+        log<level::ERR>("User delete failed",
+                        entry("USER_NAME=%s", userName.c_str()));
+        elog<InternalFailure>();
+    }
+
+    usersList.erase(userName);
+
+    log<level::INFO>("User deleted successfully",
+                     entry("USER_NAME=%s", userName.c_str()));
+    return;
+}
+
+void UserMgr::renameUser(std::string userName, std::string newUserName)
+{
+    // All user management lock has to be based on /etc/shadow
+    phosphor::user::shadow::Lock lock();
+    throwForUserDoesNotExist(userName);
+    throwForUserExists(newUserName);
+    throwForUserNameConstraints(newUserName,
+                                usersList[userName].get()->userGroups());
+    try
+    {
+        executeCmd("/usr/sbin/usermod", "-l", newUserName.c_str(),
+                   userName.c_str());
+    }
+    catch (const InternalFailure &e)
+    {
+        log<level::ERR>("User rename failed",
+                        entry("USER_NAME=%s", userName.c_str()));
+        elog<InternalFailure>();
+    }
+    const auto &user = usersList[userName];
+    std::string priv = user.get()->userPrivilege();
+    std::vector<std::string> groupNames = user.get()->userGroups();
+    bool enabled = user.get()->userEnabled();
+    std::string newUserObj = std::string(usersObjPath) + "/" + newUserName;
+    // Special group 'ipmi' needs a way to identify user renamed, in order to
+    // update encrypted password. It can't rely only on InterfacesRemoved &
+    // InterfacesAdded. So first send out userRenamed signal.
+    this->userRenamed(userName, newUserName);
+    usersList.erase(userName);
+    usersList.emplace(
+        newUserName,
+        std::move(std::make_unique<phosphor::user::Users>(
+            bus, newUserObj.c_str(), groupNames, priv, enabled, *this)));
+    return;
+}
+
+void UserMgr::updateGroupsAndPriv(const std::string &userName,
+                                  const std::vector<std::string> &groupNames,
+                                  const std::string &priv)
+{
+    throwForInvalidPrivilege(priv);
+    throwForInvalidGroups(groupNames);
+    // All user management lock has to be based on /etc/shadow
+    phosphor::user::shadow::Lock lock();
+    throwForUserDoesNotExist(userName);
+    const std::vector<std::string> &oldGroupNames =
+        usersList[userName].get()->userGroups();
+    std::vector<std::string> groupDiff;
+    // Note: already dealing with sorted group lists.
+    std::set_symmetric_difference(oldGroupNames.begin(), oldGroupNames.end(),
+                                  groupNames.begin(), groupNames.end(),
+                                  std::back_inserter(groupDiff));
+    if (std::find(groupDiff.begin(), groupDiff.end(), "ipmi") !=
+        groupDiff.end())
+    {
+        throwForUserNameConstraints(userName, groupNames);
+        throwForMaxGrpUserCount(groupNames);
+    }
+
+    std::string groups = getCSVFromVector(groupNames);
+    bool sshRequested = removeStringFromCSV(groups, grpSsh);
+
+    // treat privilege as a group - This is to avoid using different file to
+    // store the same.
+    if (groups.size() != 0)
+    {
+        groups += ",";
+    }
+    groups += priv;
+    try
+    {
+        executeCmd("/usr/sbin/usermod", userName.c_str(), "-G", groups.c_str(),
+                   "-s", (sshRequested ? "/bin/sh" : "/bin/nologin"));
+    }
+    catch (const InternalFailure &e)
+    {
+        log<level::ERR>("Unable to modify user privilege / groups");
+        elog<InternalFailure>();
+    }
+
+    log<level::INFO>("User groups / privilege updated successfully",
+                     entry("USER_NAME=%s", userName.c_str()));
+    return;
+}
+
+void UserMgr::userEnable(const std::string &userName, bool enabled)
+{
+    // All user management lock has to be based on /etc/shadow
+    phosphor::user::shadow::Lock lock();
+    throwForUserDoesNotExist(userName);
+    try
+    {
+        executeCmd("/usr/sbin/usermod", userName.c_str(), "-e",
+                   (enabled ? "" : "1970-01-02"));
+    }
+    catch (const InternalFailure &e)
+    {
+        log<level::ERR>("Unable to modify user enabled state");
+        elog<InternalFailure>();
+    }
+
+    log<level::INFO>("User enabled/disabled state updated successfully",
+                     entry("USER_NAME=%s", userName.c_str()),
+                     entry("ENABLED=%d", enabled));
+    return;
+}
+
+UserSSHLists UserMgr::getUserAndSshGrpList()
+{
+    // All user management lock has to be based on /etc/shadow
+    phosphor::user::shadow::Lock lock();
+
+    std::vector<std::string> userList;
+    std::vector<std::string> sshUsersList;
+    struct passwd pw, *pwp = nullptr;
+    std::array<char, 1024> buffer{};
+
+    phosphor::user::File passwd(passwdFileName, "r");
+    if ((passwd)() == NULL)
+    {
+        log<level::ERR>("Error opening the passwd file");
+        elog<InternalFailure>();
+    }
+
+    while (true)
+    {
+        auto r = fgetpwent_r((passwd)(), &pw, buffer.data(), buffer.max_size(),
+                             &pwp);
+        if ((r != 0) || (pwp == NULL))
+        {
+            // Any error, break the loop.
+            break;
+        }
+        // All users whose UID >= 1000 and < 65534
+        if ((pwp->pw_uid >= 1000) && (pwp->pw_uid < 65534))
+        {
+            std::string userName(pwp->pw_name);
+            userList.emplace_back(userName);
+
+            // ssh doesn't have separate group. Check login shell entry to
+            // get all users list which are member of ssh group.
+            std::string loginShell(pwp->pw_shell);
+            if (loginShell == "/bin/sh")
+            {
+                sshUsersList.emplace_back(userName);
+            }
+        }
+    }
+    endpwent();
+    return std::make_pair(std::move(userList), std::move(sshUsersList));
+}
+
+size_t UserMgr::getIpmiUsersCount()
+{
+    std::vector<std::string> userList = getUsersInGroup("ipmi");
+    return userList.size();
+}
+
+bool UserMgr::isUserEnabled(const std::string &userName)
+{
+    // All user management lock has to be based on /etc/shadow
+    phosphor::user::shadow::Lock lock();
+    std::array<char, 4096> buffer{};
+    struct spwd spwd;
+    struct spwd *resultPtr = nullptr;
+    int status = getspnam_r(userName.c_str(), &spwd, buffer.data(),
+                            buffer.max_size(), &resultPtr);
+    if (!status && (&spwd == resultPtr))
+    {
+        if (resultPtr->sp_expire >= 0)
+        {
+            return false; // user locked out
+        }
+        return true;
+    }
+    return false; // assume user is disabled for any error.
+}
+
+std::vector<std::string> UserMgr::getUsersInGroup(const std::string &groupName)
+{
+    std::vector<std::string> usersInGroup;
+    // Should be more than enough to get the pwd structure.
+    std::array<char, 4096> buffer{};
+    struct group grp;
+    struct group *resultPtr = nullptr;
+
+    int status = getgrnam_r(groupName.c_str(), &grp, buffer.data(),
+                            buffer.max_size(), &resultPtr);
+
+    if (!status && (&grp == resultPtr))
+    {
+        for (; *(grp.gr_mem) != NULL; ++(grp.gr_mem))
+        {
+            usersInGroup.emplace_back(*(grp.gr_mem));
+        }
+    }
+    else
+    {
+        log<level::ERR>("Group not found",
+                        entry("GROUP=%s", groupName.c_str()));
+        // Don't throw error, just return empty userList - fallback
+    }
+    return usersInGroup;
+}
+
+void UserMgr::initUserObjects(void)
+{
+    // All user management lock has to be based on /etc/shadow
+    phosphor::user::shadow::Lock lock();
+    std::vector<std::string> userNameList;
+    std::vector<std::string> sshGrpUsersList;
+    UserSSHLists userSSHLists = getUserAndSshGrpList();
+    userNameList = std::move(userSSHLists.first);
+    sshGrpUsersList = std::move(userSSHLists.second);
+
+    if (!userNameList.empty())
+    {
+        std::map<std::string, std::vector<std::string>> groupLists;
+        for (auto &grp : groupsMgr)
+        {
+            if (grp == grpSsh)
+            {
+                groupLists.emplace(grp, sshGrpUsersList);
+            }
+            else
+            {
+                std::vector<std::string> grpUsersList = getUsersInGroup(grp);
+                groupLists.emplace(grp, grpUsersList);
+            }
+        }
+        for (auto &grp : privMgr)
+        {
+            std::vector<std::string> grpUsersList = getUsersInGroup(grp);
+            groupLists.emplace(grp, grpUsersList);
+        }
+
+        for (auto &user : userNameList)
+        {
+            std::vector<std::string> userGroups;
+            std::string userPriv;
+            for (const auto &grp : groupLists)
+            {
+                std::vector<std::string> tempGrp = grp.second;
+                if (std::find(tempGrp.begin(), tempGrp.end(), user) !=
+                    tempGrp.end())
+                {
+                    if (std::find(privMgr.begin(), privMgr.end(), grp.first) !=
+                        privMgr.end())
+                    {
+                        userPriv = grp.first;
+                    }
+                    else
+                    {
+                        userGroups.emplace_back(grp.first);
+                    }
+                }
+            }
+            // Add user objects to the Users path.
+            auto objPath = std::string(usersObjPath) + "/" + user;
+            std::sort(userGroups.begin(), userGroups.end());
+            usersList.emplace(user,
+                              std::move(std::make_unique<phosphor::user::Users>(
+                                  bus, objPath.c_str(), userGroups, userPriv,
+                                  isUserEnabled(user), *this)));
+        }
+    }
+}
+
+UserMgr::UserMgr(sdbusplus::bus::bus &bus, const char *path) :
+    UserMgrIface(bus, path), bus(bus), path(path)
+{
+    UserMgrIface::allPrivileges(privMgr);
+    std::sort(groupsMgr.begin(), groupsMgr.end());
+    UserMgrIface::allGroups(groupsMgr);
+    initUserObjects();
+}
+
+} // namespace user
+} // namespace phosphor
