/*
// 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 "channel_layer.hpp"
#include "user_layer.hpp"

#include <security/pam_appl.h>

#include <ipmid/api.hpp>
#include <phosphor-logging/lg2.hpp>

#include <regex>

namespace ipmi
{

static constexpr uint8_t enableOperation = 0x00;
static constexpr uint8_t disableOperation = 0x01;

static constexpr uint8_t userIdEnabledViaSetPassword = 0x01;
static constexpr uint8_t userIdDisabledViaSetPassword = 0x02;

/** IPMI set password return codes (refer spec sec 22.30) */
constexpr Cc ccPasswdFailMismatch = 0x80;

static inline auto responsePasswdFailMismatch()
{
    return response(ccPasswdFailMismatch);
}

/** @brief implements the set user access command
 *  @param ctx - IPMI context pointer (for channel)
 *  @param channel - channel number
 *  @param ipmiEnabled - indicates ipmi messaging state
 *  @param linkAuthEnabled - indicates link authentication state
 *  @param accessCallback - indicates callback state
 *  @param bitsUpdate - indicates update request
 *  @param userId - user id
 *  @param reserved1 - skip 2 bits
 *  @param privilege - user privilege
 *  @param reserved2 - skip 4 bits
 *  @param sessionLimit - optional - unused for now
 *
 *  @returns ipmi completion code
 */
ipmi::RspType<> ipmiSetUserAccess(
    ipmi::Context::ptr ctx, uint4_t channel, uint1_t ipmiEnabled,
    uint1_t linkAuthEnabled, uint1_t accessCallback, uint1_t bitsUpdate,

    uint6_t userId, uint2_t reserved1,

    uint4_t privilege, uint4_t reserved2,

    std::optional<uint8_t> sessionLimit)
{
    uint8_t sessLimit = sessionLimit.value_or(0);
    if (reserved1 || reserved2 || sessLimit ||
        !ipmiUserIsValidPrivilege(static_cast<uint8_t>(privilege)))
    {
        lg2::debug("Set user access - Invalid field in request");
        return ipmi::responseInvalidFieldRequest();
    }

    uint8_t chNum =
        convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel);
    if (!isValidChannel(chNum))
    {
        lg2::debug("Set user access - Invalid channel request: {CHANNEL}",
                   "CHANNEL", chNum);
        return ipmi::response(invalidChannel);
    }
    if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
    {
        lg2::debug("Set user access - No support on channel");
        return ipmi::responseActionNotSupportedForChannel();
    }
    if (!ipmiUserIsValidUserId(static_cast<uint8_t>(userId)))
    {
        lg2::debug("Set user access - Parameter out of range");
        return ipmi::responseParmOutOfRange();
    }

    PrivAccess privAccess = {};
    if (bitsUpdate)
    {
        privAccess.ipmiEnabled = static_cast<uint8_t>(ipmiEnabled);
        privAccess.linkAuthEnabled = static_cast<uint8_t>(linkAuthEnabled);
        privAccess.accessCallback = static_cast<uint8_t>(accessCallback);
    }
    privAccess.privilege = static_cast<uint8_t>(privilege);
    return ipmi::response(
        ipmiUserSetPrivilegeAccess(static_cast<uint8_t>(userId), chNum,
                                   privAccess, static_cast<bool>(bitsUpdate)));
}

/** @brief implements the set user access command
 *  @param ctx - IPMI context pointer (for channel)
 *  @param channel - channel number
 *  @param reserved1 - skip 4 bits
 *  @param userId - user id
 *  @param reserved2 - skip 2 bits
 *
 *  @returns ipmi completion code plus response data
 *   - maxChUsers - max channel users
 *   - reserved1 - skip 2 bits
 *   - enabledUsers - enabled users count
 *   - enabledStatus - enabled status
 *   - fixedUsers - fixed users count
 *   - reserved2 - skip 2 bits
 *   - privilege - user privilege
 *   - ipmiEnabled - ipmi messaging state
 *   - linkAuthEnabled - link authenticatin state
 *   - accessCallback - callback state
 *   - reserved - skip 1 bit
 */
ipmi::RspType<uint6_t, // max channel users
              uint2_t, // reserved1

              uint6_t, // enabled users count
              uint2_t, // enabled status

              uint6_t, // fixed users count
              uint2_t, // reserved2

              uint4_t, // privilege
              uint1_t, // ipmi messaging state
              uint1_t, // link authentication state
              uint1_t, // access callback state
              uint1_t  // reserved3
              >
    ipmiGetUserAccess(ipmi::Context::ptr ctx, uint4_t channel,
                      uint4_t reserved1,

                      uint6_t userId, uint2_t reserved2)
{
    uint8_t chNum =
        convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel);

    if (reserved1 || reserved2 || !isValidChannel(chNum))
    {
        lg2::debug("Get user access - Invalid field in request");
        return ipmi::responseInvalidFieldRequest();
    }

    if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
    {
        lg2::debug("Get user access - No support on channel");
        return ipmi::responseActionNotSupportedForChannel();
    }
    if (!ipmiUserIsValidUserId(static_cast<uint8_t>(userId)))
    {
        lg2::debug("Get user access - Parameter out of range");
        return ipmi::responseParmOutOfRange();
    }

    uint8_t maxChUsers = 0, enabledUsers = 0, fixedUsers = 0;
    ipmi::Cc retStatus;
    retStatus = ipmiUserGetAllCounts(maxChUsers, enabledUsers, fixedUsers);
    if (retStatus != ccSuccess)
    {
        return ipmi::response(retStatus);
    }

    bool enabledState = false;
    retStatus =
        ipmiUserCheckEnabled(static_cast<uint8_t>(userId), enabledState);
    if (retStatus != ccSuccess)
    {
        return ipmi::response(retStatus);
    }

    uint2_t enabledStatus = enabledState ? userIdEnabledViaSetPassword
                                         : userIdDisabledViaSetPassword;
    PrivAccess privAccess{};
    retStatus = ipmiUserGetPrivilegeAccess(static_cast<uint8_t>(userId), chNum,
                                           privAccess);
    if (retStatus != ccSuccess)
    {
        return ipmi::response(retStatus);
    }
    constexpr uint2_t res2Bits = 0;
    return ipmi::responseSuccess(
        static_cast<uint6_t>(maxChUsers), res2Bits,

        static_cast<uint6_t>(enabledUsers), enabledStatus,

        static_cast<uint6_t>(fixedUsers), res2Bits,

        static_cast<uint4_t>(privAccess.privilege),
        static_cast<uint1_t>(privAccess.ipmiEnabled),
        static_cast<uint1_t>(privAccess.linkAuthEnabled),
        static_cast<uint1_t>(privAccess.accessCallback),
        static_cast<uint1_t>(privAccess.reserved));
}

/** @brief implementes the get user name command
 *  @param[in] ctx - ipmi command context
 *  @param[in] userId - 6-bit user ID
 *  @param[in] reserved - 2-bits reserved
 *  @param[in] name - 16-byte array for username

 *  @returns ipmi response
 */
ipmi::RspType<> ipmiSetUserName(
    [[maybe_unused]] ipmi::Context::ptr ctx, uint6_t id, uint2_t reserved,
    const std::array<uint8_t, ipmi::ipmiMaxUserName>& name)
{
    if (reserved)
    {
        return ipmi::responseInvalidFieldRequest();
    }
    uint8_t userId = static_cast<uint8_t>(id);
    if (!ipmiUserIsValidUserId(userId))
    {
        lg2::debug("Set user name - Invalid user id");
        return ipmi::responseParmOutOfRange();
    }

    size_t nameLen = strnlen(reinterpret_cast<const char*>(name.data()),
                             ipmi::ipmiMaxUserName);
    const std::string strUserName(reinterpret_cast<const char*>(name.data()),
                                  nameLen);

    ipmi::Cc res = ipmiUserSetUserName(userId, strUserName);
    return ipmi::response(res);
}

/** @brief implementes the get user name command
 *  @param[in] ctx - ipmi command context
 *  @param[in] userId - 6-bit user ID
 *  @param[in] reserved - 2-bits reserved

 *  @returns ipmi response with 16-byte username
 */
ipmi::RspType<std::array<uint8_t, ipmi::ipmiMaxUserName>> // user name
    ipmiGetUserName([[maybe_unused]] ipmi::Context::ptr ctx, uint6_t id,
                    uint2_t reserved)
{
    if (reserved)
    {
        return ipmi::responseInvalidFieldRequest();
    }

    uint8_t userId = static_cast<uint8_t>(id);
    std::string userName;
    if (ipmiUserGetUserName(userId, userName) != ccSuccess)
    { // Invalid User ID
        lg2::debug("User Name not found, user Id: {USER_ID}", "USER_ID",
                   userId);
        return ipmi::responseParmOutOfRange();
    }
    // copy the std::string into a fixed array
    if (userName.size() > ipmi::ipmiMaxUserName)
    {
        return ipmi::responseUnspecifiedError();
    }
    std::array<uint8_t, ipmi::ipmiMaxUserName> userNameFixed;
    std::fill(userNameFixed.begin(), userNameFixed.end(), 0);
    std::copy(userName.begin(), userName.end(), userNameFixed.begin());
    return ipmi::responseSuccess(std::move(userNameFixed));
}

/** @brief implementes the get user name command
 *  @param[in] ctx - ipmi command context
 *  @param[in] userId - 6-bit user ID
 *  @param[in] reserved - 2-bits reserved

 *  @returns ipmi response with 16-byte username
 */
ipmi::RspType<> // user name
    ipmiSetUserPassword([[maybe_unused]] ipmi::Context::ptr ctx, uint6_t id,
                        bool reserved1, bool pwLen20, uint2_t operation,
                        uint6_t reserved2, SecureBuffer& userPassword)
{
    if (reserved1 || reserved2)
    {
        lg2::debug("Invalid data field in request");
        return ipmi::responseInvalidFieldRequest();
    }

    static constexpr uint2_t opDisableUser = 0x00;
    static constexpr uint2_t opEnableUser = 0x01;
    static constexpr uint2_t opSetPassword = 0x02;
    static constexpr uint2_t opTestPassword = 0x03;

    // If set / test password operation then password size has to be 16 or 20
    // bytes based on the password size bit
    if (((operation == opSetPassword) || (operation == opTestPassword)) &&
        ((pwLen20 && (userPassword.size() != maxIpmi20PasswordSize)) ||
         (!pwLen20 && (userPassword.size() != maxIpmi15PasswordSize))))
    {
        lg2::debug("Invalid Length");
        return ipmi::responseReqDataLenInvalid();
    }

    size_t passwordLength = userPassword.size();

    uint8_t userId = static_cast<uint8_t>(id);
    std::string userName;
    if (ipmiUserGetUserName(userId, userName) != ccSuccess)
    {
        lg2::debug("User Name not found, user Id: {USER_ID}", "USER_ID",
                   userId);
        return ipmi::responseParmOutOfRange();
    }

    if (operation == opSetPassword)
    {
        // turn the non-nul terminated SecureBuffer into a SecureString
        SecureString password(
            reinterpret_cast<const char*>(userPassword.data()), passwordLength);
        ipmi::Cc res = ipmiUserSetUserPassword(userId, password.data());
        return ipmi::response(res);
    }
    else if (operation == opEnableUser || operation == opDisableUser)
    {
        ipmi::Cc res =
            ipmiUserUpdateEnabledState(userId, static_cast<bool>(operation));
        return ipmi::response(res);
    }
    else if (operation == opTestPassword)
    {
        SecureString password = ipmiUserGetPassword(userName);
        // extend with zeros, if needed
        if (password.size() < passwordLength)
        {
            password.resize(passwordLength, '\0');
        }
        SecureString testPassword(
            reinterpret_cast<const char*>(userPassword.data()), passwordLength);
        // constant time string compare: always compare exactly as many bytes
        // as the length of the input, resizing the actual password to match,
        // maintaining a knowledge if the sizes differed originally
        static const std::array<char, maxIpmi20PasswordSize> empty = {'\0'};
        size_t cmpLen = testPassword.size();
        bool pwLenDiffers = password.size() != cmpLen;
        const char* cmpPassword = nullptr;
        if (pwLenDiffers)
        {
            cmpPassword = empty.data();
        }
        else
        {
            cmpPassword = password.data();
        }
        bool pwBad = CRYPTO_memcmp(cmpPassword, testPassword.data(), cmpLen);
        pwBad |= pwLenDiffers;
        if (pwBad)
        {
            lg2::debug("Test password failed, user Id: {USER_ID}", "USER_ID",
                       userId);
            return ipmi::responsePasswdFailMismatch();
        }
        return ipmi::responseSuccess();
    }
    return ipmi::responseInvalidFieldRequest();
}

/** @brief implements the get channel authentication command
 *  @param ctx - IPMI context pointer (for channel)
 *  @param extData - get IPMI 2.0 extended data
 *  @param reserved1 - skip 3 bits
 *  @param chNum - channel number to get info about
 *  @param reserved2 - skip 4 bits
 *  @param privLevel - requested privilege level

 *  @returns ipmi completion code plus response data
 *   - channel number
 *   - rmcpAuthTypes - RMCP auth types (IPMI 1.5)
 *   - reserved1
 *   - extDataSupport - true for IPMI 2.0 extensions
 *   - anonymousLogin - true for anonymous login enabled
 *   - nullUsers - true for null user names enabled
 *   - nonNullUsers - true for non-null usernames enabled
 *   - userAuth - false for user authentication enabled
 *   - perMessageAuth - false for per message authentication enabled
 *   - KGStatus - true for Kg required for authentication
 *   - reserved2
 *   - rmcp - RMCP (IPMI 1.5) connection support
 *   - rmcpp - RMCP+ (IPMI 2.0) connection support
 *   - reserved3
 *   - oemID - OEM IANA of any OEM auth support
 *   - oemAuxillary - OEM data for auth
 */
ipmi::RspType<uint8_t,  // channel number
              uint6_t,  // rmcpAuthTypes
              bool,     // reserved1
              bool,     // extDataSupport
              bool,     // anonymousLogin
              bool,     // nullUsers
              bool,     // nonNullUsers
              bool,     // userAuth
              bool,     // perMessageAuth
              bool,     // KGStatus
              uint2_t,  // reserved2
              bool,     // rmcp
              bool,     // rmcpp
              uint6_t,  // reserved3
              uint24_t, // oemID
              uint8_t   // oemAuxillary
              >
    ipmiGetChannelAuthenticationCapabilities(
        ipmi::Context::ptr ctx, uint4_t chNum, uint3_t reserved1,
        [[maybe_unused]] bool extData, uint4_t privLevel, uint4_t reserved2)
{
    uint8_t channel =
        convertCurrentChannelNum(static_cast<uint8_t>(chNum), ctx->channel);

    if (reserved1 || reserved2 || !isValidChannel(channel) ||
        !isValidPrivLimit(static_cast<uint8_t>(privLevel)))
    {
        lg2::debug("Get channel auth capabilities - Invalid field in request");
        return ipmi::responseInvalidFieldRequest();
    }

    if (getChannelSessionSupport(channel) == EChannelSessSupported::none)
    {
        lg2::debug("Get channel auth capabilities - No support on channel");
        return ipmi::responseActionNotSupportedForChannel();
    }

    constexpr bool extDataSupport = true; // true for IPMI 2.0 extensions
    constexpr bool reserved3 = false;
    constexpr uint6_t rmcpAuthTypes = 0;  // IPMI 1.5 auth types - not supported
    constexpr uint2_t reserved4 = 0;
    constexpr bool KGStatus = false;      // Not supporting now.
    constexpr bool perMessageAuth = false; // Per message auth - enabled
    constexpr bool userAuth = false;       // User authentication - enabled
    constexpr bool nullUsers = false;      // Null user names - not supported
    constexpr bool anonymousLogin = false; // Anonymous login - not supported
    constexpr uint6_t reserved5 = 0;
    constexpr bool rmcpp = true;           // IPMI 2.0 - supported
    constexpr bool rmcp = false;           // IPMI 1.5 - not supported
    constexpr uint24_t oemID = 0;
    constexpr uint8_t oemAuxillary = 0;

    bool nonNullUsers = 0;
    uint8_t maxChUsers = 0, enabledUsers = 0, fixedUsers = 0;
    ipmi::ipmiUserGetAllCounts(maxChUsers, enabledUsers, fixedUsers);
    nonNullUsers = enabledUsers > 0;

    return ipmi::responseSuccess(
        channel, rmcpAuthTypes, reserved3, extDataSupport, anonymousLogin,
        nullUsers, nonNullUsers, userAuth, perMessageAuth, KGStatus, reserved4,
        rmcp, rmcpp, reserved5, oemID, oemAuxillary);
}

/** @brief implements the set user payload access command.
 *  @param ctx - IPMI context pointer (for channel)
 *  @param channel - channel number (4 bits)
 *  @param reserved1 - skip 4 bits
 *  @param userId - user id (6 bits)
 *  @param operation - access ENABLE /DISABLE. (2 bits)
 *  @param stdPayload0 - IPMI - reserved. (1 bit)
 *  @param stdPayload1 - SOL.             (1 bit)
 *  @param stdPayload2 -                  (1 bit)
 *  @param stdPayload3 -                  (1 bit)
 *  @param stdPayload4 -                  (1 bit)
 *  @param stdPayload5 -                  (1 bit)
 *  @param stdPayload6 -                  (1 bit)
 *  @param stdPayload7 -                  (1 bit)
 *  @param stdPayloadEnables2Reserved -   (8 bits)
 *  @param oemPayload0 -                  (1 bit)
 *  @param oemPayload1 -                  (1 bit)
 *  @param oemPayload2 -                  (1 bit)
 *  @param oemPayload3 -                  (1 bit)
 *  @param oemPayload4 -                  (1 bit)
 *  @param oemPayload5 -                  (1 bit)
 *  @param oemPayload6 -                  (1 bit)
 *  @param oemPayload7 -                  (1 bit)
 *  @param oemPayloadEnables2Reserved -   (8 bits)
 *
 *  @returns IPMI completion code
 */
ipmi::RspType<> ipmiSetUserPayloadAccess(
    ipmi::Context::ptr ctx,

    uint4_t channel, uint4_t reserved,

    uint6_t userId, uint2_t operation,

    bool stdPayload0ipmiReserved, bool stdPayload1SOL, bool stdPayload2,
    bool stdPayload3, bool stdPayload4, bool stdPayload5, bool stdPayload6,
    bool stdPayload7,

    uint8_t stdPayloadEnables2Reserved,

    bool oemPayload0, bool oemPayload1, bool oemPayload2, bool oemPayload3,
    bool oemPayload4, bool oemPayload5, bool oemPayload6, bool oemPayload7,

    uint8_t oemPayloadEnables2Reserved)
{
    auto chNum =
        convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel);
    // Validate the reserved args. Only SOL payload is supported as on date.
    if (reserved || stdPayload0ipmiReserved || stdPayload2 || stdPayload3 ||
        stdPayload4 || stdPayload5 || stdPayload6 || stdPayload7 ||
        oemPayload0 || oemPayload1 || oemPayload2 || oemPayload3 ||
        oemPayload4 || oemPayload5 || oemPayload6 || oemPayload7 ||
        stdPayloadEnables2Reserved || oemPayloadEnables2Reserved ||
        !isValidChannel(chNum))
    {
        return ipmi::responseInvalidFieldRequest();
    }

    if ((operation != enableOperation && operation != disableOperation))
    {
        return ipmi::responseInvalidFieldRequest();
    }
    if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
    {
        return ipmi::responseActionNotSupportedForChannel();
    }
    if (!ipmiUserIsValidUserId(static_cast<uint8_t>(userId)))
    {
        return ipmi::responseParmOutOfRange();
    }

    PayloadAccess payloadAccess = {};
    payloadAccess.stdPayloadEnables1[1] = stdPayload1SOL;

    return ipmi::response(ipmiUserSetUserPayloadAccess(
        chNum, static_cast<uint8_t>(operation), static_cast<uint8_t>(userId),
        payloadAccess));
}

/** @brief implements the get user payload access command
 *  This command returns information about user payload enable settings
 *  that were set using the 'Set User Payload Access' Command.
 *
 *  @param ctx - IPMI context pointer (for channel)
 *  @param channel - channel number
 *  @param reserved1 - skip 4 bits
 *  @param userId - user id
 *  @param reserved2 - skip 2 bits
 *
 *  @returns IPMI completion code plus response data
 *   - stdPayload0ipmiReserved - IPMI payload (reserved).
 *   - stdPayload1SOL - SOL payload
 *   - stdPayload2
 *   - stdPayload3
 *   - stdPayload4
 *   - stdPayload5
 *   - stdPayload6
 *   - stdPayload7

 *   - stdPayloadEnables2Reserved - Reserved.

 *   - oemPayload0
 *   - oemPayload1
 *   - oemPayload2
 *   - oemPayload3
 *   - oemPayload4
 *   - oemPayload5
 *   - oemPayload6
 *   - oemPayload7

 *  - oemPayloadEnables2Reserved - Reserved
 */
ipmi::RspType<bool,    // stdPayload0ipmiReserved
              bool,    // stdPayload1SOL
              bool,    // stdPayload2
              bool,    // stdPayload3
              bool,    // stdPayload4
              bool,    // stdPayload5
              bool,    // stdPayload6
              bool,    // stdPayload7

              uint8_t, // stdPayloadEnables2Reserved

              bool,    // oemPayload0
              bool,    // oemPayload1
              bool,    // oemPayload2
              bool,    // oemPayload3
              bool,    // oemPayload4
              bool,    // oemPayload5
              bool,    // oemPayload6
              bool,    // oemPayload7

              uint8_t  // oemPayloadEnables2Reserved
              >
    ipmiGetUserPayloadAccess(ipmi::Context::ptr ctx,

                             uint4_t channel, uint4_t reserved1,

                             uint6_t userId, uint2_t reserved2)
{
    uint8_t chNum =
        convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel);

    if (reserved1 || reserved2 || !isValidChannel(chNum))
    {
        return ipmi::responseInvalidFieldRequest();
    }
    if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
    {
        return ipmi::responseActionNotSupportedForChannel();
    }
    if (!ipmiUserIsValidUserId(static_cast<uint8_t>(userId)))
    {
        return ipmi::responseParmOutOfRange();
    }

    ipmi::Cc retStatus;
    PayloadAccess payloadAccess = {};
    retStatus = ipmiUserGetUserPayloadAccess(
        chNum, static_cast<uint8_t>(userId), payloadAccess);
    if (retStatus != ccSuccess)
    {
        return ipmi::response(retStatus);
    }
    constexpr uint8_t res8bits = 0;
    return ipmi::responseSuccess(
        payloadAccess.stdPayloadEnables1.test(0),
        payloadAccess.stdPayloadEnables1.test(1),
        payloadAccess.stdPayloadEnables1.test(2),
        payloadAccess.stdPayloadEnables1.test(3),
        payloadAccess.stdPayloadEnables1.test(4),
        payloadAccess.stdPayloadEnables1.test(5),
        payloadAccess.stdPayloadEnables1.test(6),
        payloadAccess.stdPayloadEnables1.test(7),

        res8bits,

        payloadAccess.oemPayloadEnables1.test(0),
        payloadAccess.oemPayloadEnables1.test(1),
        payloadAccess.oemPayloadEnables1.test(2),
        payloadAccess.oemPayloadEnables1.test(3),
        payloadAccess.oemPayloadEnables1.test(4),
        payloadAccess.oemPayloadEnables1.test(5),
        payloadAccess.oemPayloadEnables1.test(6),
        payloadAccess.oemPayloadEnables1.test(7),

        res8bits);
}

void registerUserIpmiFunctions() __attribute__((constructor));
void registerUserIpmiFunctions()
{
    post_work([]() { ipmiUserInit(); });
    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
                          ipmi::app::cmdSetUserAccessCommand,
                          ipmi::Privilege::Admin, ipmiSetUserAccess);

    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
                          ipmi::app::cmdGetUserAccessCommand,
                          ipmi::Privilege::Admin, ipmiGetUserAccess);

    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
                          ipmi::app::cmdGetUserNameCommand,
                          ipmi::Privilege::Admin, ipmiGetUserName);

    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
                          ipmi::app::cmdSetUserName, ipmi::Privilege::Admin,
                          ipmiSetUserName);

    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
                          ipmi::app::cmdSetUserPasswordCommand,
                          ipmi::Privilege::Admin, ipmiSetUserPassword);

    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
                          ipmi::app::cmdGetChannelAuthCapabilities,
                          ipmi::Privilege::Callback,
                          ipmiGetChannelAuthenticationCapabilities);

    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
                          ipmi::app::cmdSetUserPayloadAccess,
                          ipmi::Privilege::Admin, ipmiSetUserPayloadAccess);

    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
                          ipmi::app::cmdGetUserPayloadAccess,
                          ipmi::Privilege::Operator, ipmiGetUserPayloadAccess);

    return;
}
} // namespace ipmi
