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
