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