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 std::string& userName); 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 ccSuccess for success, others for failure. 206 */ 207 Cc 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] userName - user name 213 * 214 * @return ccSuccess for success, others for failure. 215 */ 216 Cc setUserName(const uint8_t userId, const std::string& userName); 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 ccSuccess for success, others for failure. 224 */ 225 Cc setUserEnabledState(const uint8_t userId, const bool& enabledState); 226 227 /** @brief to set user password 228 * 229 * @param[in] userId - user id 230 * @param[in] userPassword - new password of the user 231 * 232 * @return ccSuccess for success, others for failure. 233 */ 234 Cc setUserPassword(const uint8_t userId, const char* userPassword); 235 236 /** @brief to set special user password 237 * 238 * @param[in] userName - user name 239 * @param[in] userPassword - new password of the user 240 * 241 * @return ccSuccess for success, others for failure. 242 */ 243 Cc setSpecialUserPassword(const std::string& userName, 244 const std::string& userPassword); 245 246 /** @brief to set user privilege and access details 247 * 248 * @param[in] userId - user id 249 * @param[in] chNum - channel number 250 * @param[in] privAccess - privilege access 251 * @param[in] otherPrivUpdates - other privilege update flag to update ipmi 252 * enable, link authentication and access callback 253 * 254 * @return ccSuccess for success, others for failure. 255 */ 256 Cc setUserPrivilegeAccess(const uint8_t userId, const uint8_t chNum, 257 const UserPrivAccess& privAccess, 258 const bool& otherPrivUpdates); 259 260 /** @brief to get user payload access details from userInfo entry. 261 * 262 * @param[in] userInfo - userInfo entry in usersTbl. 263 * @param[out] stdPayload - stdPayloadEnables1 in a 2D-array. 264 * @param[out] oemPayload - oemPayloadEnables1 in a 2D-array. 265 * 266 * @details Update the given 2D-arrays using the payload access details 267 * available in the given userInfo entry (from usersTbl). 268 * This 2D-array will be mapped to a JSON object (which will be written to 269 * a JSON file subsequently). 270 */ 271 void readPayloadAccessFromUserInfo( 272 const UserInfo& userInfo, 273 std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>& 274 stdPayload, 275 std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>& 276 oemPayload); 277 278 /** @brief to update user payload access details in userInfo entry. 279 * 280 * @param[in] stdPayload - stdPayloadEnables1 in a 2D-array. 281 * @param[in] oemPayload - oemPayloadEnables1 in a 2D-array. 282 * @param[out] userInfo - userInfo entry in usersTbl. 283 * 284 * @details Update user payload access details of a given userInfo 285 * entry (in usersTbl) with the information provided in given 2D-arrays. 286 * This 2D-array was created out of a JSON object (which was created by 287 * parsing a JSON file). 288 */ 289 void updatePayloadAccessInUserInfo( 290 const std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>& 291 stdPayload, 292 const std::array<std::array<bool, ipmiMaxChannels>, payloadsPerByte>& 293 oemPayload, 294 UserInfo& userInfo); 295 296 /** @brief to set user payload access details 297 * 298 * @param[in] chNum - channel number 299 * @param[in] operation - Enable / Disable 300 * @param[in] userId - user id 301 * @param[in] payloadAccess - payload access 302 * 303 * @return ccSuccess for success, others for failure. 304 */ 305 Cc setUserPayloadAccess(const uint8_t chNum, const uint8_t operation, 306 const uint8_t userId, 307 const PayloadAccess& payloadAccess); 308 309 /** @brief reads user management related data from configuration file 310 * 311 */ 312 void readUserData(); 313 314 /** @brief writes user management related data to configuration file 315 * 316 */ 317 void writeUserData(); 318 319 /** @brief Funtion which checks and reload configuration file data if 320 * needed. 321 * 322 */ 323 void checkAndReloadUserData(); 324 325 /** @brief provides user details from D-Bus user property data 326 * 327 * @param[in] properties - D-Bus user property 328 * @param[out] usrGrps - user group details 329 * @param[out] usrPriv - user privilege 330 * @param[out] usrEnabled - enabled state of the user. 331 * 332 * @return 0 for success, -errno for failure. 333 */ 334 void getUserProperties(const DbusUserObjProperties& properties, 335 std::vector<std::string>& usrGrps, 336 std::string& usrPriv, bool& usrEnabled); 337 338 /** @brief provides user details from D-Bus user object data 339 * 340 * @param[in] userObjs - D-Bus user object 341 * @param[out] usrGrps - user group details 342 * @param[out] usrPriv - user privilege 343 * @param[out] usrEnabled - enabled state of the user. 344 * 345 * @return 0 for success, -errno for failure. 346 */ 347 int getUserObjProperties(const DbusUserObjValue& userObjs, 348 std::vector<std::string>& usrGrps, 349 std::string& usrPriv, bool& usrEnabled); 350 351 /** @brief function to add user entry information to the configuration 352 * 353 * @param[in] userName - user name 354 * @param[in] priv - privilege of the user 355 * @param[in] enabled - enabled state of the user 356 * 357 * @return true for success, false for failure 358 */ 359 bool addUserEntry(const std::string& userName, const std::string& priv, 360 const bool& enabled); 361 362 /** @brief function to delete user entry based on user index 363 * 364 * @param[in] usrIdx - user index 365 * 366 */ 367 void deleteUserIndex(const size_t& usrIdx); 368 369 /** @brief function to get users table 370 * 371 */ 372 UsersTbl* getUsersTblPtr(); 373 374 std::unique_ptr<boost::interprocess::named_recursive_mutex> userMutex{ 375 nullptr}; 376 377 private: 378 UsersTbl usersTbl; 379 std::vector<std::string> availablePrivileges; 380 std::vector<std::string> availableGroups; 381 sdbusplus::bus::bus bus; 382 std::time_t fileLastUpdatedTime; 383 bool signalHndlrObject = false; 384 boost::interprocess::file_lock sigHndlrLock; 385 boost::interprocess::file_lock mutexCleanupLock; 386 387 /** @brief function to get user configuration file timestamp 388 * 389 * @return time stamp or -EIO for failure 390 */ 391 std::time_t getUpdatedFileTime(); 392 393 /** @brief function to available system privileges and groups 394 * 395 */ 396 void getSystemPrivAndGroups(); 397 398 /** @brief function to init user data from configuration & D-Bus objects 399 * and to register for signals 400 * 401 */ 402 void cacheUserDataFile(); 403 }; 404 } // namespace ipmi 405