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