blob: d77317ae78283da737795823dac4552ec7a44da9 [file] [log] [blame]
/*
// 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 <boost/interprocess/sync/file_lock.hpp>
#include <boost/interprocess/sync/named_recursive_mutex.hpp>
#include <cstdint>
#include <ctime>
#include <ipmid/api.hpp>
#include <sdbusplus/bus.hpp>
#include <variant>
namespace ipmi
{
using DbusUserPropVariant =
std::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 User update events.
*/
enum class UserUpdateEvent
{
reservedEvent,
userCreated,
userDeleted,
userRenamed,
userGrpUpdated,
userPrivUpdated,
userStateUpdated
};
/** @struct UserPrivAccess
*
* Structure for user privilege access (refer spec sec 22.22)
*/
struct UserPrivAccess
{
uint8_t privilege;
bool ipmiEnabled;
bool linkAuthEnabled;
bool accessCallback;
};
/** @struct UserInfo
*
* Structure for user related information
*/
struct UserInfo
{
uint8_t userName[ipmiMaxUserName];
UserPrivAccess userPrivAccess[ipmiMaxChannels];
bool userEnabled;
bool userInSystem;
bool fixedUserName;
PayloadAccess payloadAccess[ipmiMaxChannels];
};
/** @struct UsersTbl
*
* Structure for array of user related information
*/
struct UsersTbl
{
//+1 to map with UserId directly. UserId 0 is reserved.
UserInfo user[ipmiMaxUsers + 1];
};
/** @brief PAM User Authentication check
*
* @param[in] username - username in string
* @param[in] password - password in string
*
* @return status
*/
bool pamUserCheckAuthenticate(std::string_view username,
std::string_view password);
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 determines whether ipmi is in available groups list
*
* @return true if ipmi group is present, false otherwise
*/
bool isIpmiInAvailableGroupList();
/** @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 ccSuccess for success, others for failure.
*/
Cc getUserName(const uint8_t userId, std::string& userName);
/** @brief to set user name
*
* @param[in] userId - user id
* @param[in] userName - user name
*
* @return ccSuccess for success, others for failure.
*/
Cc setUserName(const uint8_t userId, const char* userNameInChar);
/** @brief to set user enabled state
*
* @param[in] userId - user id
* @param[in] enabledState - enabled state of the user
*
* @return ccSuccess for success, others for failure.
*/
Cc setUserEnabledState(const uint8_t userId, const bool& enabledState);
/** @brief to set user password
*
* @param[in] userId - user id
* @param[in] userPassword - new password of the user
*
* @return ccSuccess for success, others for failure.
*/
Cc setUserPassword(const uint8_t userId, const char* userPassword);
/** @brief to set special user password
*
* @param[in] userName - user name
* @param[in] userPassword - new password of the user
*
* @return ccSuccess for success, others for failure.
*/
Cc setSpecialUserPassword(const std::string& userName,
const std::string& userPassword);
/** @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 ccSuccess for success, others for failure.
*/
Cc setUserPrivilegeAccess(const uint8_t userId, const uint8_t chNum,
const UserPrivAccess& privAccess,
const bool& otherPrivUpdates);
/** @brief to get user payload access details from userInfo entry.
*
* @param[in] userInfo - userInfo entry in usersTbl.
* @param[out] stdPayload - stdPayloadEnables1 in a 2D-array.
* @param[out] oemPayload - oemPayloadEnables1 in a 2D-array.
*
* @details Update the given 2D-arrays using the payload access details
* available in the given userInfo entry (from usersTbl).
* This 2D-array will be mapped to a JSON object (which will be written to
* a JSON file subsequently).
*/
void readPayloadAccessFromUserInfo(
const UserInfo& userInfo,
std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>&
stdPayload,
std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>&
oemPayload);
/** @brief to update user payload access details in userInfo entry.
*
* @param[in] stdPayload - stdPayloadEnables1 in a 2D-array.
* @param[in] oemPayload - oemPayloadEnables1 in a 2D-array.
* @param[out] userInfo - userInfo entry in usersTbl.
*
* @details Update user payload access details of a given userInfo
* entry (in usersTbl) with the information provided in given 2D-arrays.
* This 2D-array was created out of a JSON object (which was created by
* parsing a JSON file).
*/
void updatePayloadAccessInUserInfo(
const std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>&
stdPayload,
const std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>&
oemPayload,
UserInfo& userInfo);
/** @brief to set user payload access details
*
* @param[in] chNum - channel number
* @param[in] operation - Enable / Disable
* @param[in] userId - user id
* @param[in] payloadAccess - payload access
*
* @return ccSuccess for success, others for failure.
*/
Cc setUserPayloadAccess(const uint8_t chNum, const uint8_t operation,
const uint8_t userId,
const PayloadAccess& payloadAccess);
/** @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
* and to register for signals
*
*/
void cacheUserDataFile();
};
} // namespace ipmi