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 17 #include "usercommands.hpp" 18 19 #include "apphandler.hpp" 20 #include "channel_layer.hpp" 21 #include "user_layer.hpp" 22 23 #include <security/pam_appl.h> 24 25 #include <ipmid/api.hpp> 26 #include <phosphor-logging/log.hpp> 27 #include <regex> 28 29 namespace ipmi 30 { 31 32 using namespace phosphor::logging; 33 34 static constexpr uint8_t disableUser = 0x00; 35 static constexpr uint8_t enableUser = 0x01; 36 static constexpr uint8_t setPassword = 0x02; 37 static constexpr uint8_t testPassword = 0x03; 38 static constexpr uint8_t passwordKeySize20 = 1; 39 static constexpr uint8_t passwordKeySize16 = 0; 40 static constexpr uint8_t enableOperation = 0x00; 41 static constexpr uint8_t disableOperation = 0x01; 42 43 /** @struct SetUserNameReq 44 * 45 * Structure for set user name request command (refer spec sec 22.28) 46 */ 47 struct SetUserNameReq 48 { 49 #if BYTE_ORDER == LITTLE_ENDIAN 50 uint8_t userId : 6; 51 uint8_t reserved1 : 2; 52 #endif 53 #if BYTE_ORDER == BIG_ENDIAN 54 uint8_t reserved1 : 2; 55 uint8_t userId : 6; 56 #endif 57 uint8_t userName[16]; 58 } __attribute__((packed)); 59 60 /** @struct GetUserNameReq 61 * 62 * Structure for get user name request command (refer spec sec 22.29) 63 */ 64 struct GetUserNameReq 65 { 66 #if BYTE_ORDER == LITTLE_ENDIAN 67 uint8_t userId : 6; 68 uint8_t reserved1 : 2; 69 #endif 70 #if BYTE_ORDER == BIG_ENDIAN 71 uint8_t reserved1 : 2; 72 uint8_t userId : 6; 73 #endif 74 } __attribute__((packed)); 75 76 /** @struct GetUserNameResp 77 * 78 * Structure for get user name response command (refer spec sec 22.29) 79 */ 80 struct GetUserNameResp 81 { 82 uint8_t userName[16]; 83 } __attribute__((packed)); 84 85 /** @struct SetUserPasswordReq 86 * 87 * Structure for set user password request command (refer spec sec 22.30) 88 */ 89 struct SetUserPasswordReq 90 { 91 #if BYTE_ORDER == LITTLE_ENDIAN 92 uint8_t userId : 6; 93 uint8_t reserved1 : 1; 94 uint8_t ipmi20 : 1; 95 uint8_t operation : 2; 96 uint8_t reserved2 : 6; 97 #endif 98 #if BYTE_ORDER == BIG_ENDIAN 99 uint8_t ipmi20 : 1; 100 uint8_t reserved1 : 1; 101 uint8_t userId : 6; 102 uint8_t reserved2 : 6; 103 uint8_t operation : 2; 104 #endif 105 uint8_t userPassword[maxIpmi20PasswordSize]; 106 } __attribute__((packed)); 107 108 /** @brief implements the set user access command 109 * @param ctx - IPMI context pointer (for channel) 110 * @param channel - channel number 111 * @param ipmiEnabled - indicates ipmi messaging state 112 * @param linkAuthEnabled - indicates link authentication state 113 * @param accessCallback - indicates callback state 114 * @param bitsUpdate - indicates update request 115 * @param userId - user id 116 * @param reserved1 - skip 2 bits 117 * @param privilege - user privilege 118 * @param reserved2 - skip 4 bits 119 * @param sessionLimit - optional - unused for now 120 * 121 * @returns ipmi completion code 122 */ 123 ipmi::RspType<> ipmiSetUserAccess(ipmi::Context::ptr ctx, uint4_t channel, 124 uint1_t ipmiEnabled, uint1_t linkAuthEnabled, 125 uint1_t accessCallback, uint1_t bitsUpdate, 126 127 uint6_t userId, uint2_t reserved1, 128 129 uint4_t privilege, uint4_t reserved2, 130 131 std::optional<uint8_t> sessionLimit) 132 { 133 uint8_t sessLimit = sessionLimit.value_or(0); 134 uint8_t chNum = 135 convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel); 136 if (reserved1 != 0 || reserved2 != 0 || sessLimit != 0 || 137 (!isValidChannel(chNum)) || 138 (!ipmiUserIsValidPrivilege(static_cast<uint8_t>(privilege))) || 139 (EChannelSessSupported::none == getChannelSessionSupport(chNum))) 140 { 141 log<level::DEBUG>("Set user access - Invalid field in request"); 142 return ipmi::responseInvalidFieldRequest(); 143 } 144 if (!ipmiUserIsValidUserId(static_cast<uint8_t>(userId))) 145 { 146 log<level::DEBUG>("Set user access - Parameter out of range"); 147 return ipmi::responseParmOutOfRange(); 148 } 149 150 PrivAccess privAccess = {0}; 151 if (bitsUpdate) 152 { 153 privAccess.ipmiEnabled = static_cast<uint8_t>(ipmiEnabled); 154 privAccess.linkAuthEnabled = static_cast<uint8_t>(linkAuthEnabled); 155 privAccess.accessCallback = static_cast<uint8_t>(accessCallback); 156 } 157 privAccess.privilege = static_cast<uint8_t>(privilege); 158 return ipmi::response( 159 ipmiUserSetPrivilegeAccess(static_cast<uint8_t>(userId), chNum, 160 privAccess, static_cast<bool>(bitsUpdate))); 161 } 162 163 /** @brief implements the set user access command 164 * @param ctx - IPMI context pointer (for channel) 165 * @param channel - channel number 166 * @param reserved1 - skip 4 bits 167 * @param userId - user id 168 * @param reserved2 - skip 2 bits 169 * 170 * @returns ipmi completion code plus response data 171 * - maxChUsers - max channel users 172 * - reserved1 - skip 2 bits 173 * - enabledUsers - enabled users count 174 * - enabledStatus - enabled status 175 * - fixedUsers - fixed users count 176 * - reserved2 - skip 2 bits 177 * - privilege - user privilege 178 * - ipmiEnabled - ipmi messaging state 179 * - linkAuthEnabled - link authenticatin state 180 * - accessCallback - callback state 181 * - reserved - skip 1 bit 182 */ 183 ipmi::RspType<uint6_t, // max channel users 184 uint2_t, // reserved1 185 186 uint6_t, // enabled users count 187 uint2_t, // enabled status 188 189 uint6_t, // fixed users count 190 uint2_t, // reserved2 191 192 uint4_t, // privilege 193 uint1_t, // ipmi messaging state 194 uint1_t, // link authentication state 195 uint1_t, // access callback state 196 uint1_t // reserved3 197 > 198 ipmiGetUserAccess(ipmi::Context::ptr ctx, uint4_t channel, 199 uint4_t reserved1, 200 201 uint6_t userId, uint2_t reserved2) 202 { 203 uint8_t chNum = 204 convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel); 205 if (reserved1 != 0 || reserved2 != 0 || (!isValidChannel(chNum)) || 206 (EChannelSessSupported::none == getChannelSessionSupport(chNum))) 207 { 208 log<level::DEBUG>("Get user access - Invalid field in request"); 209 return ipmi::responseInvalidFieldRequest(); 210 } 211 if (!ipmiUserIsValidUserId(static_cast<uint8_t>(userId))) 212 { 213 log<level::DEBUG>("Get user access - Parameter out of range"); 214 return ipmi::responseParmOutOfRange(); 215 } 216 217 uint8_t maxChUsers = 0, enabledUsers = 0, fixedUsers = 0; 218 ipmi::Cc retStatus; 219 retStatus = ipmiUserGetAllCounts(maxChUsers, enabledUsers, fixedUsers); 220 if (retStatus != IPMI_CC_OK) 221 { 222 return ipmi::response(retStatus); 223 } 224 225 bool enabledState = false; 226 retStatus = 227 ipmiUserCheckEnabled(static_cast<uint8_t>(userId), enabledState); 228 if (retStatus != IPMI_CC_OK) 229 { 230 return ipmi::response(retStatus); 231 } 232 233 uint2_t enabledStatus = enabledState ? userIdEnabledViaSetPassword 234 : userIdDisabledViaSetPassword; 235 PrivAccess privAccess{}; 236 retStatus = ipmiUserGetPrivilegeAccess(static_cast<uint8_t>(userId), chNum, 237 privAccess); 238 if (retStatus != IPMI_CC_OK) 239 { 240 return ipmi::response(retStatus); 241 } 242 constexpr uint2_t res2Bits = 0; 243 return ipmi::responseSuccess( 244 static_cast<uint6_t>(maxChUsers), res2Bits, 245 246 static_cast<uint6_t>(enabledUsers), enabledStatus, 247 248 static_cast<uint6_t>(fixedUsers), res2Bits, 249 250 static_cast<uint4_t>(privAccess.privilege), 251 static_cast<uint1_t>(privAccess.ipmiEnabled), 252 static_cast<uint1_t>(privAccess.linkAuthEnabled), 253 static_cast<uint1_t>(privAccess.accessCallback), 254 static_cast<uint1_t>(privAccess.reserved)); 255 } 256 257 ipmi_ret_t ipmiSetUserName(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 258 ipmi_request_t request, ipmi_response_t response, 259 ipmi_data_len_t dataLen, ipmi_context_t context) 260 { 261 const SetUserNameReq* req = static_cast<SetUserNameReq*>(request); 262 size_t reqLength = *dataLen; 263 *dataLen = 0; 264 265 if (reqLength != sizeof(*req)) 266 { 267 log<level::DEBUG>("Set user name - Invalid Length"); 268 return IPMI_CC_REQ_DATA_LEN_INVALID; 269 } 270 if (req->reserved1) 271 { 272 return IPMI_CC_INVALID_FIELD_REQUEST; 273 } 274 if (!ipmiUserIsValidUserId(req->userId)) 275 { 276 log<level::DEBUG>("Set user name - Invalid user id"); 277 return IPMI_CC_PARM_OUT_OF_RANGE; 278 } 279 280 return ipmiUserSetUserName(req->userId, 281 reinterpret_cast<const char*>(req->userName)); 282 } 283 284 /** @brief implementes the get user name command 285 * @param[in] netfn - specifies netfn. 286 * @param[in] cmd - specifies cmd number. 287 * @param[in] request - pointer to request data. 288 * @param[in, out] dataLen - specifies request data length, and returns 289 * response data length. 290 * @param[in] context - ipmi context. 291 * @returns ipmi completion code. 292 */ 293 ipmi_ret_t ipmiGetUserName(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 294 ipmi_request_t request, ipmi_response_t response, 295 ipmi_data_len_t dataLen, ipmi_context_t context) 296 { 297 const GetUserNameReq* req = static_cast<GetUserNameReq*>(request); 298 size_t reqLength = *dataLen; 299 300 *dataLen = 0; 301 302 if (reqLength != sizeof(*req)) 303 { 304 log<level::DEBUG>("Get user name - Invalid Length"); 305 return IPMI_CC_REQ_DATA_LEN_INVALID; 306 } 307 308 std::string userName; 309 if (ipmiUserGetUserName(req->userId, userName) != IPMI_CC_OK) 310 { // Invalid User ID 311 log<level::DEBUG>("User Name not found", 312 entry("USER-ID:%d", (uint8_t)req->userId)); 313 return IPMI_CC_PARM_OUT_OF_RANGE; 314 } 315 GetUserNameResp* resp = static_cast<GetUserNameResp*>(response); 316 std::fill(reinterpret_cast<uint8_t*>(resp), 317 reinterpret_cast<uint8_t*>(resp) + sizeof(*resp), 0); 318 userName.copy(reinterpret_cast<char*>(resp->userName), 319 sizeof(resp->userName), 0); 320 *dataLen = sizeof(*resp); 321 322 return IPMI_CC_OK; 323 } 324 325 /** @brief implementes the set user password command 326 * @param[in] netfn - specifies netfn. 327 * @param[in] cmd - specifies cmd number. 328 * @param[in] request - pointer to request data. 329 * @param[in, out] dataLen - specifies request data length, and returns 330 * response data length. 331 * @param[in] context - ipmi context. 332 * @returns ipmi completion code. 333 */ 334 ipmi_ret_t ipmiSetUserPassword(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 335 ipmi_request_t request, ipmi_response_t response, 336 ipmi_data_len_t dataLen, ipmi_context_t context) 337 { 338 const SetUserPasswordReq* req = static_cast<SetUserPasswordReq*>(request); 339 size_t reqLength = *dataLen; 340 // subtract 2 bytes header to know the password length - including NULL 341 uint8_t passwordLength = *dataLen - 2; 342 *dataLen = 0; 343 344 // verify input length based on operation. Required password size is 20 345 // bytes as we support only IPMI 2.0, but in order to be compatible with 346 // tools, accept 16 bytes of password size too. 347 if (reqLength < 2 || 348 // If enable / disable user, reqLength has to be >=2 & <= 22 349 ((req->operation == disableUser || req->operation == enableUser) && 350 ((reqLength < 2) || (reqLength > sizeof(SetUserPasswordReq))))) 351 { 352 log<level::DEBUG>("Invalid Length"); 353 return IPMI_CC_REQ_DATA_LEN_INVALID; 354 } 355 // If set / test password then password length has to be 16 or 20 bytes 356 // based on the password size bit. 357 if (((req->operation == setPassword) || (req->operation == testPassword)) && 358 (((req->ipmi20 == passwordKeySize20) && 359 (passwordLength != maxIpmi20PasswordSize)) || 360 ((req->ipmi20 == passwordKeySize16) && 361 (passwordLength != maxIpmi15PasswordSize)))) 362 { 363 log<level::DEBUG>("Invalid Length"); 364 return IPMI_CC_REQ_DATA_LEN_INVALID; 365 } 366 367 std::string userName; 368 if (ipmiUserGetUserName(req->userId, userName) != IPMI_CC_OK) 369 { 370 log<level::DEBUG>("User Name not found", 371 entry("USER-ID:%d", (uint8_t)req->userId)); 372 return IPMI_CC_PARM_OUT_OF_RANGE; 373 } 374 if (req->operation == setPassword) 375 { 376 return ipmiUserSetUserPassword( 377 req->userId, reinterpret_cast<const char*>(req->userPassword)); 378 } 379 else if (req->operation == enableUser || req->operation == disableUser) 380 { 381 return ipmiUserUpdateEnabledState(req->userId, 382 static_cast<bool>(req->operation)); 383 } 384 else if (req->operation == testPassword) 385 { 386 auto password = ipmiUserGetPassword(userName); 387 std::string testPassword( 388 reinterpret_cast<const char*>(req->userPassword), 0, 389 passwordLength); 390 // Note: For security reasons password size won't be compared and 391 // wrong password size completion code will not be returned if size 392 // doesn't match as specified in IPMI specification. 393 if (password != testPassword) 394 { 395 log<level::DEBUG>("Test password failed", 396 entry("USER-ID:%d", (uint8_t)req->userId)); 397 return static_cast<ipmi_ret_t>( 398 IPMISetPasswordReturnCodes::ipmiCCPasswdFailMismatch); 399 } 400 return IPMI_CC_OK; 401 } 402 return IPMI_CC_INVALID_FIELD_REQUEST; 403 } 404 405 /** @brief implements the get channel authentication command 406 * @param ctx - IPMI context pointer (for channel) 407 * @param extData - get IPMI 2.0 extended data 408 * @param reserved1 - skip 3 bits 409 * @param chNum - channel number to get info about 410 * @param reserved2 - skip 4 bits 411 * @param privLevel - requested privilege level 412 413 * @returns ipmi completion code plus response data 414 * - channel number 415 * - rmcpAuthTypes - RMCP auth types (IPMI 1.5) 416 * - reserved1 417 * - extDataSupport - true for IPMI 2.0 extensions 418 * - anonymousLogin - true for anonymous login enabled 419 * - nullUsers - true for null user names enabled 420 * - nonNullUsers - true for non-null usernames enabled 421 * - userAuth - false for user authentication enabled 422 * - perMessageAuth - false for per message authentication enabled 423 * - KGStatus - true for Kg required for authentication 424 * - reserved2 425 * - rmcp - RMCP (IPMI 1.5) connection support 426 * - rmcpp - RMCP+ (IPMI 2.0) connection support 427 * - reserved3 428 * - oemID - OEM IANA of any OEM auth support 429 * - oemAuxillary - OEM data for auth 430 */ 431 ipmi::RspType<uint8_t, // channel number 432 uint6_t, // rmcpAuthTypes 433 bool, // reserved1 434 bool, // extDataSupport 435 bool, // anonymousLogin 436 bool, // nullUsers 437 bool, // nonNullUsers 438 bool, // userAuth 439 bool, // perMessageAuth 440 bool, // KGStatus 441 uint2_t, // reserved2 442 bool, // rmcp 443 bool, // rmcpp 444 uint6_t, // reserved3 445 uint24_t, // oemID 446 uint8_t // oemAuxillary 447 > 448 ipmiGetChannelAuthenticationCapabilities(ipmi::Context::ptr ctx, 449 uint4_t chNum, uint3_t reserved1, 450 bool extData, uint4_t privLevel, 451 uint4_t reserved2) 452 { 453 454 uint8_t channel = 455 convertCurrentChannelNum(static_cast<uint8_t>(chNum), ctx->channel); 456 457 if (reserved1 || reserved2 || !isValidChannel(channel) || 458 !isValidPrivLimit(static_cast<uint8_t>(privLevel)) || 459 (EChannelSessSupported::none == getChannelSessionSupport(channel))) 460 { 461 return ipmi::response(ccInvalidFieldRequest); 462 } 463 464 constexpr bool extDataSupport = true; // true for IPMI 2.0 extensions 465 constexpr bool reserved3 = false; 466 constexpr uint6_t rmcpAuthTypes = 0; // IPMI 1.5 auth types - not supported 467 constexpr uint2_t reserved4 = 0; 468 constexpr bool KGStatus = false; // Not supporting now. 469 constexpr bool perMessageAuth = false; // Per message auth - enabled 470 constexpr bool userAuth = false; // User authentication - enabled 471 constexpr bool nullUsers = false; // Null user names - not supported 472 constexpr bool anonymousLogin = false; // Anonymous login - not supported 473 constexpr uint6_t reserved5 = 0; 474 constexpr bool rmcpp = true; // IPMI 2.0 - supported 475 constexpr bool rmcp = false; // IPMI 1.5 - not supported 476 constexpr uint24_t oemID = 0; 477 constexpr uint8_t oemAuxillary = 0; 478 479 bool nonNullUsers = 0; 480 uint8_t maxChUsers = 0, enabledUsers = 0, fixedUsers = 0; 481 ipmi::ipmiUserGetAllCounts(maxChUsers, enabledUsers, fixedUsers); 482 nonNullUsers = enabledUsers > 0; 483 484 return ipmi::responseSuccess( 485 channel, rmcpAuthTypes, reserved3, extDataSupport, anonymousLogin, 486 nullUsers, nonNullUsers, userAuth, perMessageAuth, KGStatus, reserved4, 487 rmcp, rmcpp, reserved5, oemID, oemAuxillary); 488 } 489 490 /** @brief implements the set user payload access command. 491 * @param ctx - IPMI context pointer (for channel) 492 * @param channel - channel number (4 bits) 493 * @param reserved1 - skip 4 bits 494 * @param userId - user id (6 bits) 495 * @param operation - access ENABLE /DISABLE. (2 bits) 496 * @param stdPayload0 - IPMI - reserved. (1 bit) 497 * @param stdPayload1 - SOL. (1 bit) 498 * @param stdPayload2 - (1 bit) 499 * @param stdPayload3 - (1 bit) 500 * @param stdPayload4 - (1 bit) 501 * @param stdPayload5 - (1 bit) 502 * @param stdPayload6 - (1 bit) 503 * @param stdPayload7 - (1 bit) 504 * @param stdPayloadEnables2Reserved - (8 bits) 505 * @param oemPayload0 - (1 bit) 506 * @param oemPayload1 - (1 bit) 507 * @param oemPayload2 - (1 bit) 508 * @param oemPayload3 - (1 bit) 509 * @param oemPayload4 - (1 bit) 510 * @param oemPayload5 - (1 bit) 511 * @param oemPayload6 - (1 bit) 512 * @param oemPayload7 - (1 bit) 513 * @param oemPayloadEnables2Reserved - (8 bits) 514 * 515 * @returns IPMI completion code 516 */ 517 ipmi::RspType<> ipmiSetUserPayloadAccess( 518 ipmi::Context::ptr ctx, 519 520 uint4_t channel, uint4_t reserved, 521 522 uint6_t userId, uint2_t operation, 523 524 bool stdPayload0ipmiReserved, bool stdPayload1SOL, bool stdPayload2, 525 bool stdPayload3, bool stdPayload4, bool stdPayload5, bool stdPayload6, 526 bool stdPayload7, 527 528 uint8_t stdPayloadEnables2Reserved, 529 530 bool oemPayload0, bool oemPayload1, bool oemPayload2, bool oemPayload3, 531 bool oemPayload4, bool oemPayload5, bool oemPayload6, bool oemPayload7, 532 533 uint8_t oemPayloadEnables2Reserved) 534 { 535 // Validate the reserved args. Only SOL payload is supported as on date. 536 if (reserved || stdPayload0ipmiReserved || stdPayload2 || stdPayload3 || 537 stdPayload4 || stdPayload5 || stdPayload6 || stdPayload7 || 538 oemPayload0 || oemPayload1 || oemPayload2 || oemPayload3 || 539 oemPayload4 || oemPayload5 || oemPayload6 || oemPayload7 || 540 stdPayloadEnables2Reserved || oemPayloadEnables2Reserved) 541 { 542 return ipmi::responseInvalidFieldRequest(); 543 } 544 545 auto chNum = 546 convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel); 547 if ((operation != enableOperation && operation != disableOperation) || 548 (!isValidChannel(chNum)) || 549 (getChannelSessionSupport(chNum) == EChannelSessSupported::none)) 550 { 551 return ipmi::responseInvalidFieldRequest(); 552 } 553 554 if (!ipmiUserIsValidUserId(static_cast<uint8_t>(userId))) 555 { 556 return ipmi::responseParmOutOfRange(); 557 } 558 559 PayloadAccess payloadAccess = {0}; 560 payloadAccess.stdPayloadEnables1[1] = stdPayload1SOL; 561 562 return ipmi::response(ipmiUserSetUserPayloadAccess( 563 chNum, static_cast<uint8_t>(operation), static_cast<uint8_t>(userId), 564 payloadAccess)); 565 } 566 567 /** @brief implements the get user payload access command 568 * This command returns information about user payload enable settings 569 * that were set using the 'Set User Payload Access' Command. 570 * 571 * @param ctx - IPMI context pointer (for channel) 572 * @param channel - channel number 573 * @param reserved1 - skip 4 bits 574 * @param userId - user id 575 * @param reserved2 - skip 2 bits 576 * 577 * @returns IPMI completion code plus response data 578 * - stdPayload0ipmiReserved - IPMI payload (reserved). 579 * - stdPayload1SOL - SOL payload 580 * - stdPayload2 581 * - stdPayload3 582 * - stdPayload4 583 * - stdPayload5 584 * - stdPayload6 585 * - stdPayload7 586 587 * - stdPayloadEnables2Reserved - Reserved. 588 589 * - oemPayload0 590 * - oemPayload1 591 * - oemPayload2 592 * - oemPayload3 593 * - oemPayload4 594 * - oemPayload5 595 * - oemPayload6 596 * - oemPayload7 597 598 * - oemPayloadEnables2Reserved - Reserved 599 */ 600 ipmi::RspType<bool, // stdPayload0ipmiReserved 601 bool, // stdPayload1SOL 602 bool, // stdPayload2 603 bool, // stdPayload3 604 bool, // stdPayload4 605 bool, // stdPayload5 606 bool, // stdPayload6 607 bool, // stdPayload7 608 609 uint8_t, // stdPayloadEnables2Reserved 610 611 bool, // oemPayload0 612 bool, // oemPayload1 613 bool, // oemPayload2 614 bool, // oemPayload3 615 bool, // oemPayload4 616 bool, // oemPayload5 617 bool, // oemPayload6 618 bool, // oemPayload7 619 620 uint8_t // oemPayloadEnables2Reserved 621 > 622 ipmiGetUserPayloadAccess(ipmi::Context::ptr ctx, 623 624 uint4_t channel, uint4_t reserved1, 625 626 uint6_t userId, uint2_t reserved2) 627 { 628 uint8_t chNum = 629 convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel); 630 if (reserved1 != 0 || reserved2 != 0 || (!isValidChannel(chNum)) || 631 (getChannelSessionSupport(chNum) == EChannelSessSupported::none)) 632 { 633 return ipmi::responseInvalidFieldRequest(); 634 } 635 if (!ipmiUserIsValidUserId(static_cast<uint8_t>(userId))) 636 { 637 return ipmi::responseParmOutOfRange(); 638 } 639 640 ipmi::Cc retStatus; 641 PayloadAccess payloadAccess = {}; 642 retStatus = ipmiUserGetUserPayloadAccess( 643 chNum, static_cast<uint8_t>(userId), payloadAccess); 644 if (retStatus != IPMI_CC_OK) 645 { 646 return ipmi::response(retStatus); 647 } 648 constexpr uint8_t res8bits = 0; 649 return ipmi::responseSuccess(payloadAccess.stdPayloadEnables1.test(0), 650 payloadAccess.stdPayloadEnables1.test(1), 651 payloadAccess.stdPayloadEnables1.test(2), 652 payloadAccess.stdPayloadEnables1.test(3), 653 payloadAccess.stdPayloadEnables1.test(4), 654 payloadAccess.stdPayloadEnables1.test(5), 655 payloadAccess.stdPayloadEnables1.test(6), 656 payloadAccess.stdPayloadEnables1.test(7), 657 658 res8bits, 659 660 payloadAccess.oemPayloadEnables1.test(0), 661 payloadAccess.oemPayloadEnables1.test(1), 662 payloadAccess.oemPayloadEnables1.test(2), 663 payloadAccess.oemPayloadEnables1.test(3), 664 payloadAccess.oemPayloadEnables1.test(4), 665 payloadAccess.oemPayloadEnables1.test(5), 666 payloadAccess.oemPayloadEnables1.test(6), 667 payloadAccess.oemPayloadEnables1.test(7), 668 669 res8bits); 670 } 671 672 void registerUserIpmiFunctions() __attribute__((constructor)); 673 void registerUserIpmiFunctions() 674 { 675 ipmiUserInit(); 676 ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp, 677 ipmi::app::cmdSetUserAccessCommand, 678 ipmi::Privilege::Admin, ipmiSetUserAccess); 679 680 ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp, 681 ipmi::app::cmdGetUserAccessCommand, 682 ipmi::Privilege::Operator, ipmiGetUserAccess); 683 684 ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_USER_NAME, NULL, 685 ipmiGetUserName, PRIVILEGE_OPERATOR); 686 687 ipmi_register_callback(NETFUN_APP, IPMI_CMD_SET_USER_NAME, NULL, 688 ipmiSetUserName, PRIVILEGE_ADMIN); 689 690 ipmi_register_callback(NETFUN_APP, IPMI_CMD_SET_USER_PASSWORD, NULL, 691 ipmiSetUserPassword, PRIVILEGE_ADMIN); 692 693 ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp, 694 ipmi::app::cmdGetChannelAuthCapabilities, 695 ipmi::Privilege::Callback, 696 ipmiGetChannelAuthenticationCapabilities); 697 698 ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp, 699 ipmi::app::cmdSetUserPayloadAccess, 700 ipmi::Privilege::Admin, ipmiSetUserPayloadAccess); 701 702 ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp, 703 ipmi::app::cmdGetUserPayloadAccess, 704 ipmi::Privilege::Operator, ipmiGetUserPayloadAccess); 705 706 return; 707 } 708 } // namespace ipmi 709