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 <ipmid/api.hpp> 22 #include <sdbusplus/bus.hpp> 23 24 #include <cstdint> 25 #include <ctime> 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 std::string& userName); 169 170 /** @brief determines whether ipmi is in available groups list 171 * 172 * @return true if ipmi group is present, false otherwise 173 */ 174 bool isIpmiInAvailableGroupList(); 175 176 /** @brief provides user id of the user 177 * 178 * @param[in] userName - user name 179 * 180 * @return user id of the user, else invalid user id (0xFF), if user not 181 * found 182 */ 183 uint8_t getUserId(const std::string& userName); 184 185 /** @brief provides user information 186 * 187 * @param[in] userId - user id 188 * 189 * @return UserInfo for the specified user id 190 */ 191 UserInfo* getUserInfo(const uint8_t userId); 192 193 /** @brief sets user information 194 * 195 * @param[in] userId - user id 196 * @param[in] userInfo - user information 197 * 198 */ 199 void setUserInfo(const uint8_t userId, UserInfo* userInfo); 200 201 /** @brief provides user name 202 * 203 * @param[in] userId - user id 204 * @param[out] userName - user name 205 * 206 * @return ccSuccess for success, others for failure. 207 */ 208 Cc getUserName(const uint8_t userId, std::string& userName); 209 210 /** @brief to set user name 211 * 212 * @param[in] userId - user id 213 * @param[in] userName - user name 214 * 215 * @return ccSuccess for success, others for failure. 216 */ 217 Cc setUserName(const uint8_t userId, const std::string& userName); 218 219 /** @brief to set user enabled state 220 * 221 * @param[in] userId - user id 222 * @param[in] enabledState - enabled state of the user 223 * 224 * @return ccSuccess for success, others for failure. 225 */ 226 Cc setUserEnabledState(const uint8_t userId, 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 ccSuccess for success, others for failure. 234 */ 235 Cc 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 ccSuccess for success, others for failure. 243 */ 244 Cc setSpecialUserPassword(const std::string& userName, 245 const SecureString& 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 ccSuccess for success, others for failure. 256 */ 257 Cc 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 ccSuccess for success, others for failure. 305 */ 306 Cc setUserPayloadAccess(const uint8_t chNum, const uint8_t operation, 307 const uint8_t userId, 308 const PayloadAccess& payloadAccess); 309 310 /** @brief reads user management related data from configuration file 311 * 312 */ 313 void readUserData(); 314 315 /** @brief writes user management related data to configuration file 316 * 317 */ 318 void writeUserData(); 319 320 /** @brief Funtion which checks and reload configuration file data if 321 * needed. 322 * 323 */ 324 void checkAndReloadUserData(); 325 326 /** @brief provides user details from D-Bus user property data 327 * 328 * @param[in] properties - D-Bus user property 329 * @param[out] usrGrps - user group details 330 * @param[out] usrPriv - user privilege 331 * @param[out] usrEnabled - enabled state of the user. 332 * 333 * @return 0 for success, -errno for failure. 334 */ 335 void getUserProperties(const DbusUserObjProperties& properties, 336 std::vector<std::string>& usrGrps, 337 std::string& usrPriv, bool& usrEnabled); 338 339 /** @brief provides user details from D-Bus user object data 340 * 341 * @param[in] userObjs - D-Bus user object 342 * @param[out] usrGrps - user group details 343 * @param[out] usrPriv - user privilege 344 * @param[out] usrEnabled - enabled state of the user. 345 * 346 * @return 0 for success, -errno for failure. 347 */ 348 int getUserObjProperties(const DbusUserObjValue& userObjs, 349 std::vector<std::string>& usrGrps, 350 std::string& usrPriv, bool& usrEnabled); 351 352 /** @brief function to add user entry information to the configuration 353 * 354 * @param[in] userName - user name 355 * @param[in] priv - privilege of the user 356 * @param[in] enabled - enabled state of the user 357 * 358 * @return true for success, false for failure 359 */ 360 bool addUserEntry(const std::string& userName, const std::string& priv, 361 const bool& enabled); 362 363 /** @brief function to delete user entry based on user index 364 * 365 * @param[in] usrIdx - user index 366 * 367 */ 368 void deleteUserIndex(const size_t& usrIdx); 369 370 /** @brief function to get users table 371 * 372 */ 373 UsersTbl* getUsersTblPtr(); 374 375 std::unique_ptr<boost::interprocess::named_recursive_mutex> userMutex{ 376 nullptr}; 377 378 private: 379 UsersTbl usersTbl; 380 std::vector<std::string> availablePrivileges; 381 std::vector<std::string> availableGroups; 382 sdbusplus::bus_t bus; 383 std::timespec fileLastUpdatedTime; 384 bool signalHndlrObject = false; 385 boost::interprocess::file_lock sigHndlrLock; 386 boost::interprocess::file_lock mutexCleanupLock; 387 388 /** @brief function to get user configuration file timestamp 389 * 390 * @return time stamp or -EIO for failure 391 */ 392 std::timespec getUpdatedFileTime(); 393 394 /** @brief function to available system privileges and groups 395 * 396 */ 397 void getSystemPrivAndGroups(); 398 399 /** @brief function to init user data from configuration & D-Bus objects 400 * and to register for signals 401 * 402 */ 403 void cacheUserDataFile(); 404 }; 405 406 } // namespace ipmi 407