1 /* 2 // Copyright (c) 2018 Intel Corporation 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 */ 16 #pragma once 17 #include "user_layer.hpp" 18 19 #include <ipmid/api.h> 20 21 #include <boost/interprocess/sync/file_lock.hpp> 22 #include <boost/interprocess/sync/named_recursive_mutex.hpp> 23 #include <cstdint> 24 #include <ctime> 25 #include <sdbusplus/bus.hpp> 26 #include <variant> 27 28 namespace ipmi 29 { 30 31 using DbusUserPropVariant = 32 std::variant<std::vector<std::string>, std::string, bool>; 33 34 using DbusUserObjPath = sdbusplus::message::object_path; 35 36 using DbusUserObjProperties = 37 std::vector<std::pair<std::string, DbusUserPropVariant>>; 38 39 using DbusUserObjValue = std::map<std::string, DbusUserObjProperties>; 40 41 /** 42 * @enum User update events. 43 */ 44 enum class UserUpdateEvent 45 { 46 reservedEvent, 47 userCreated, 48 userDeleted, 49 userRenamed, 50 userGrpUpdated, 51 userPrivUpdated, 52 userStateUpdated 53 }; 54 55 /** @struct UserPrivAccess 56 * 57 * Structure for user privilege access (refer spec sec 22.22) 58 */ 59 struct UserPrivAccess 60 { 61 uint8_t privilege; 62 bool ipmiEnabled; 63 bool linkAuthEnabled; 64 bool accessCallback; 65 }; 66 67 /** @struct UserInfo 68 * 69 * Structure for user related information 70 */ 71 struct UserInfo 72 { 73 uint8_t userName[ipmiMaxUserName]; 74 UserPrivAccess userPrivAccess[ipmiMaxChannels]; 75 bool userEnabled; 76 bool userInSystem; 77 bool fixedUserName; 78 PayloadAccess payloadAccess[ipmiMaxChannels]; 79 }; 80 81 /** @struct UsersTbl 82 * 83 * Structure for array of user related information 84 */ 85 struct UsersTbl 86 { 87 //+1 to map with UserId directly. UserId 0 is reserved. 88 UserInfo user[ipmiMaxUsers + 1]; 89 }; 90 91 /** @brief PAM User Authentication check 92 * 93 * @param[in] username - username in string 94 * @param[in] password - password in string 95 * 96 * @return status 97 */ 98 bool pamUserCheckAuthenticate(std::string_view username, 99 std::string_view password); 100 101 class UserAccess; 102 103 UserAccess& getUserAccessObject(); 104 105 class UserAccess 106 { 107 public: 108 UserAccess(const UserAccess&) = delete; 109 UserAccess& operator=(const UserAccess&) = delete; 110 UserAccess(UserAccess&&) = delete; 111 UserAccess& operator=(UserAccess&&) = delete; 112 113 ~UserAccess(); 114 UserAccess(); 115 116 /** @brief determines valid channel 117 * 118 * @param[in] chNum - channel number 119 * 120 * @return true if valid, false otherwise 121 */ 122 static bool isValidChannel(const uint8_t chNum); 123 124 /** @brief determines valid userId 125 * 126 * @param[in] userId - user id 127 * 128 * @return true if valid, false otherwise 129 */ 130 static bool isValidUserId(const uint8_t userId); 131 132 /** @brief determines valid user privilege 133 * 134 * @param[in] priv - Privilege 135 * 136 * @return true if valid, false otherwise 137 */ 138 static bool isValidPrivilege(const uint8_t priv); 139 140 /** @brief determines sync index to be mapped with common-user-management 141 * 142 * @return Index which will be used as sync index 143 */ 144 static uint8_t getUsrMgmtSyncIndex(); 145 146 /** @brief Converts system privilege to IPMI privilege 147 * 148 * @param[in] value - Privilege in string 149 * 150 * @return CommandPrivilege - IPMI privilege type 151 */ 152 static CommandPrivilege convertToIPMIPrivilege(const std::string& value); 153 154 /** @brief Converts IPMI privilege to system privilege 155 * 156 * @param[in] value - IPMI privilege 157 * 158 * @return System privilege in string 159 */ 160 static std::string convertToSystemPrivilege(const CommandPrivilege& value); 161 162 /** @brief determines whether user name is valid 163 * 164 * @param[in] userNameInChar - user name 165 * 166 * @return true if valid, false otherwise 167 */ 168 bool isValidUserName(const char* userNameInChar); 169 170 /** @brief provides user id of the user 171 * 172 * @param[in] userName - user name 173 * 174 * @return user id of the user, else invalid user id (0xFF), if user not 175 * found 176 */ 177 uint8_t getUserId(const std::string& userName); 178 179 /** @brief provides user information 180 * 181 * @param[in] userId - user id 182 * 183 * @return UserInfo for the specified user id 184 */ 185 UserInfo* getUserInfo(const uint8_t userId); 186 187 /** @brief sets user information 188 * 189 * @param[in] userId - user id 190 * @param[in] userInfo - user information 191 * 192 */ 193 void setUserInfo(const uint8_t userId, UserInfo* userInfo); 194 195 /** @brief provides user name 196 * 197 * @param[in] userId - user id 198 * @param[out] userName - user name 199 * 200 * @return IPMI_CC_OK for success, others for failure. 201 */ 202 ipmi_ret_t getUserName(const uint8_t userId, std::string& userName); 203 204 /** @brief to set user name 205 * 206 * @param[in] userId - user id 207 * @param[in] userNameInChar - user name 208 * 209 * @return IPMI_CC_OK for success, others for failure. 210 */ 211 ipmi_ret_t setUserName(const uint8_t userId, const char* userNameInChar); 212 213 /** @brief to set user enabled state 214 * 215 * @param[in] userId - user id 216 * @param[in] enabledState - enabled state of the user 217 * 218 * @return IPMI_CC_OK for success, others for failure. 219 */ 220 ipmi_ret_t setUserEnabledState(const uint8_t userId, 221 const bool& enabledState); 222 223 /** @brief to set user password 224 * 225 * @param[in] userId - user id 226 * @param[in] userPassword - new password of the user 227 * 228 * @return IPMI_CC_OK for success, others for failure. 229 */ 230 ipmi_ret_t setUserPassword(const uint8_t userId, const char* userPassword); 231 232 /** @brief to set special user password 233 * 234 * @param[in] userName - user name 235 * @param[in] userPassword - new password of the user 236 * 237 * @return IPMI_CC_OK for success, others for failure. 238 */ 239 ipmi_ret_t setSpecialUserPassword(const std::string& userName, 240 const std::string& userPassword); 241 242 /** @brief to set user privilege and access details 243 * 244 * @param[in] userId - user id 245 * @param[in] chNum - channel number 246 * @param[in] privAccess - privilege access 247 * @param[in] otherPrivUpdates - other privilege update flag to update ipmi 248 * enable, link authentication and access callback 249 * 250 * @return IPMI_CC_OK for success, others for failure. 251 */ 252 ipmi_ret_t setUserPrivilegeAccess(const uint8_t userId, const uint8_t chNum, 253 const UserPrivAccess& privAccess, 254 const bool& otherPrivUpdates); 255 256 /** @brief to get user payload access details from userInfo entry. 257 * 258 * @param[in] userInfo - userInfo entry in usersTbl. 259 * @param[out] stdPayload - stdPayloadEnables1 in a 2D-array. 260 * @param[out] oemPayload - oemPayloadEnables1 in a 2D-array. 261 * 262 * @details Update the given 2D-arrays using the payload access details 263 * available in the given userInfo entry (from usersTbl). 264 * This 2D-array will be mapped to a JSON object (which will be written to 265 * a JSON file subsequently). 266 */ 267 void readPayloadAccessFromUserInfo( 268 const UserInfo& userInfo, 269 std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>& 270 stdPayload, 271 std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>& 272 oemPayload); 273 274 /** @brief to update user payload access details in userInfo entry. 275 * 276 * @param[in] stdPayload - stdPayloadEnables1 in a 2D-array. 277 * @param[in] oemPayload - oemPayloadEnables1 in a 2D-array. 278 * @param[out] userInfo - userInfo entry in usersTbl. 279 * 280 * @details Update user payload access details of a given userInfo 281 * entry (in usersTbl) with the information provided in given 2D-arrays. 282 * This 2D-array was created out of a JSON object (which was created by 283 * parsing a JSON file). 284 */ 285 void updatePayloadAccessInUserInfo( 286 const std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>& 287 stdPayload, 288 const std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>& 289 oemPayload, 290 UserInfo& userInfo); 291 292 /** @brief to set user payload access details 293 * 294 * @param[in] chNum - channel number 295 * @param[in] operation - Enable / Disable 296 * @param[in] userId - user id 297 * @param[in] payloadAccess - payload access 298 * 299 * @return IPMI_CC_OK for success, others for failure. 300 */ 301 ipmi_ret_t setUserPayloadAccess(const uint8_t chNum, 302 const uint8_t operation, 303 const uint8_t userId, 304 const PayloadAccess& payloadAccess); 305 306 /** @brief reads user management related data from configuration file 307 * 308 */ 309 void readUserData(); 310 311 /** @brief writes user management related data to configuration file 312 * 313 */ 314 void writeUserData(); 315 316 /** @brief Funtion which checks and reload configuration file data if 317 * needed. 318 * 319 */ 320 void checkAndReloadUserData(); 321 322 /** @brief provides user details from D-Bus user property data 323 * 324 * @param[in] properties - D-Bus user property 325 * @param[out] usrGrps - user group details 326 * @param[out] usrPriv - user privilege 327 * @param[out] usrEnabled - enabled state of the user. 328 * 329 * @return 0 for success, -errno for failure. 330 */ 331 void getUserProperties(const DbusUserObjProperties& properties, 332 std::vector<std::string>& usrGrps, 333 std::string& usrPriv, bool& usrEnabled); 334 335 /** @brief provides user details from D-Bus user object data 336 * 337 * @param[in] userObjs - D-Bus user object 338 * @param[out] usrGrps - user group details 339 * @param[out] usrPriv - user privilege 340 * @param[out] usrEnabled - enabled state of the user. 341 * 342 * @return 0 for success, -errno for failure. 343 */ 344 int getUserObjProperties(const DbusUserObjValue& userObjs, 345 std::vector<std::string>& usrGrps, 346 std::string& usrPriv, bool& usrEnabled); 347 348 /** @brief function to add user entry information to the configuration 349 * 350 * @param[in] userName - user name 351 * @param[in] priv - privilege of the user 352 * @param[in] enabled - enabled state of the user 353 * 354 * @return true for success, false for failure 355 */ 356 bool addUserEntry(const std::string& userName, const std::string& priv, 357 const bool& enabled); 358 359 /** @brief function to delete user entry based on user index 360 * 361 * @param[in] usrIdx - user index 362 * 363 */ 364 void deleteUserIndex(const size_t& usrIdx); 365 366 /** @brief function to get users table 367 * 368 */ 369 UsersTbl* getUsersTblPtr(); 370 371 std::unique_ptr<boost::interprocess::named_recursive_mutex> userMutex{ 372 nullptr}; 373 374 private: 375 UsersTbl usersTbl; 376 std::vector<std::string> availablePrivileges; 377 std::vector<std::string> availableGroups; 378 sdbusplus::bus::bus bus; 379 std::time_t fileLastUpdatedTime; 380 bool signalHndlrObject = false; 381 boost::interprocess::file_lock sigHndlrLock; 382 boost::interprocess::file_lock mutexCleanupLock; 383 384 /** @brief function to get user configuration file timestamp 385 * 386 * @return time stamp or -EIO for failure 387 */ 388 std::time_t getUpdatedFileTime(); 389 390 /** @brief function to available system privileges and groups 391 * 392 */ 393 void getSystemPrivAndGroups(); 394 395 /** @brief function to init user data from configuration & D-Bus objects 396 * 397 */ 398 void initUserDataFile(); 399 }; 400 } // namespace ipmi 401