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 return static_cast<Cc>( 417 IPMISetPasswordReturnCodes::ipmiCCPasswdFailMismatch); 418 } 419 return ccSuccess; 420 } 421 return ccInvalidFieldRequest; 422 } 423 424 /** @brief implements the get channel authentication command 425 * @param ctx - IPMI context pointer (for channel) 426 * @param extData - get IPMI 2.0 extended data 427 * @param reserved1 - skip 3 bits 428 * @param chNum - channel number to get info about 429 * @param reserved2 - skip 4 bits 430 * @param privLevel - requested privilege level 431 432 * @returns ipmi completion code plus response data 433 * - channel number 434 * - rmcpAuthTypes - RMCP auth types (IPMI 1.5) 435 * - reserved1 436 * - extDataSupport - true for IPMI 2.0 extensions 437 * - anonymousLogin - true for anonymous login enabled 438 * - nullUsers - true for null user names enabled 439 * - nonNullUsers - true for non-null usernames enabled 440 * - userAuth - false for user authentication enabled 441 * - perMessageAuth - false for per message authentication enabled 442 * - KGStatus - true for Kg required for authentication 443 * - reserved2 444 * - rmcp - RMCP (IPMI 1.5) connection support 445 * - rmcpp - RMCP+ (IPMI 2.0) connection support 446 * - reserved3 447 * - oemID - OEM IANA of any OEM auth support 448 * - oemAuxillary - OEM data for auth 449 */ 450 ipmi::RspType<uint8_t, // channel number 451 uint6_t, // rmcpAuthTypes 452 bool, // reserved1 453 bool, // extDataSupport 454 bool, // anonymousLogin 455 bool, // nullUsers 456 bool, // nonNullUsers 457 bool, // userAuth 458 bool, // perMessageAuth 459 bool, // KGStatus 460 uint2_t, // reserved2 461 bool, // rmcp 462 bool, // rmcpp 463 uint6_t, // reserved3 464 uint24_t, // oemID 465 uint8_t // oemAuxillary 466 > 467 ipmiGetChannelAuthenticationCapabilities(ipmi::Context::ptr ctx, 468 uint4_t chNum, uint3_t reserved1, 469 bool extData, uint4_t privLevel, 470 uint4_t reserved2) 471 { 472 uint8_t channel = 473 convertCurrentChannelNum(static_cast<uint8_t>(chNum), ctx->channel); 474 475 if (reserved1 || reserved2 || !isValidChannel(channel) || 476 !isValidPrivLimit(static_cast<uint8_t>(privLevel))) 477 { 478 log<level::DEBUG>( 479 "Get channel auth capabilities - Invalid field in request"); 480 return ipmi::responseInvalidFieldRequest(); 481 } 482 483 if (getChannelSessionSupport(channel) == EChannelSessSupported::none) 484 { 485 log<level::DEBUG>( 486 "Get channel auth capabilities - No support on channel"); 487 return ipmi::response(ccActionNotSupportedForChannel); 488 } 489 490 constexpr bool extDataSupport = true; // true for IPMI 2.0 extensions 491 constexpr bool reserved3 = false; 492 constexpr uint6_t rmcpAuthTypes = 0; // IPMI 1.5 auth types - not supported 493 constexpr uint2_t reserved4 = 0; 494 constexpr bool KGStatus = false; // Not supporting now. 495 constexpr bool perMessageAuth = false; // Per message auth - enabled 496 constexpr bool userAuth = false; // User authentication - enabled 497 constexpr bool nullUsers = false; // Null user names - not supported 498 constexpr bool anonymousLogin = false; // Anonymous login - not supported 499 constexpr uint6_t reserved5 = 0; 500 constexpr bool rmcpp = true; // IPMI 2.0 - supported 501 constexpr bool rmcp = false; // IPMI 1.5 - not supported 502 constexpr uint24_t oemID = 0; 503 constexpr uint8_t oemAuxillary = 0; 504 505 bool nonNullUsers = 0; 506 uint8_t maxChUsers = 0, enabledUsers = 0, fixedUsers = 0; 507 ipmi::ipmiUserGetAllCounts(maxChUsers, enabledUsers, fixedUsers); 508 nonNullUsers = enabledUsers > 0; 509 510 return ipmi::responseSuccess( 511 channel, rmcpAuthTypes, reserved3, extDataSupport, anonymousLogin, 512 nullUsers, nonNullUsers, userAuth, perMessageAuth, KGStatus, reserved4, 513 rmcp, rmcpp, reserved5, oemID, oemAuxillary); 514 } 515 516 /** @brief implements the set user payload access command. 517 * @param ctx - IPMI context pointer (for channel) 518 * @param channel - channel number (4 bits) 519 * @param reserved1 - skip 4 bits 520 * @param userId - user id (6 bits) 521 * @param operation - access ENABLE /DISABLE. (2 bits) 522 * @param stdPayload0 - IPMI - reserved. (1 bit) 523 * @param stdPayload1 - SOL. (1 bit) 524 * @param stdPayload2 - (1 bit) 525 * @param stdPayload3 - (1 bit) 526 * @param stdPayload4 - (1 bit) 527 * @param stdPayload5 - (1 bit) 528 * @param stdPayload6 - (1 bit) 529 * @param stdPayload7 - (1 bit) 530 * @param stdPayloadEnables2Reserved - (8 bits) 531 * @param oemPayload0 - (1 bit) 532 * @param oemPayload1 - (1 bit) 533 * @param oemPayload2 - (1 bit) 534 * @param oemPayload3 - (1 bit) 535 * @param oemPayload4 - (1 bit) 536 * @param oemPayload5 - (1 bit) 537 * @param oemPayload6 - (1 bit) 538 * @param oemPayload7 - (1 bit) 539 * @param oemPayloadEnables2Reserved - (8 bits) 540 * 541 * @returns IPMI completion code 542 */ 543 ipmi::RspType<> ipmiSetUserPayloadAccess( 544 ipmi::Context::ptr ctx, 545 546 uint4_t channel, uint4_t reserved, 547 548 uint6_t userId, uint2_t operation, 549 550 bool stdPayload0ipmiReserved, bool stdPayload1SOL, bool stdPayload2, 551 bool stdPayload3, bool stdPayload4, bool stdPayload5, bool stdPayload6, 552 bool stdPayload7, 553 554 uint8_t stdPayloadEnables2Reserved, 555 556 bool oemPayload0, bool oemPayload1, bool oemPayload2, bool oemPayload3, 557 bool oemPayload4, bool oemPayload5, bool oemPayload6, bool oemPayload7, 558 559 uint8_t oemPayloadEnables2Reserved) 560 { 561 auto chNum = 562 convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel); 563 // Validate the reserved args. Only SOL payload is supported as on date. 564 if (reserved || stdPayload0ipmiReserved || stdPayload2 || stdPayload3 || 565 stdPayload4 || stdPayload5 || stdPayload6 || stdPayload7 || 566 oemPayload0 || oemPayload1 || oemPayload2 || oemPayload3 || 567 oemPayload4 || oemPayload5 || oemPayload6 || oemPayload7 || 568 stdPayloadEnables2Reserved || oemPayloadEnables2Reserved || 569 !isValidChannel(chNum)) 570 { 571 return ipmi::responseInvalidFieldRequest(); 572 } 573 574 if ((operation != enableOperation && operation != disableOperation)) 575 { 576 return ipmi::responseInvalidFieldRequest(); 577 } 578 if (getChannelSessionSupport(chNum) == EChannelSessSupported::none) 579 { 580 return ipmi::response(ccActionNotSupportedForChannel); 581 } 582 if (!ipmiUserIsValidUserId(static_cast<uint8_t>(userId))) 583 { 584 return ipmi::responseParmOutOfRange(); 585 } 586 587 PayloadAccess payloadAccess = {0}; 588 payloadAccess.stdPayloadEnables1[1] = stdPayload1SOL; 589 590 return ipmi::response(ipmiUserSetUserPayloadAccess( 591 chNum, static_cast<uint8_t>(operation), static_cast<uint8_t>(userId), 592 payloadAccess)); 593 } 594 595 /** @brief implements the get user payload access command 596 * This command returns information about user payload enable settings 597 * that were set using the 'Set User Payload Access' Command. 598 * 599 * @param ctx - IPMI context pointer (for channel) 600 * @param channel - channel number 601 * @param reserved1 - skip 4 bits 602 * @param userId - user id 603 * @param reserved2 - skip 2 bits 604 * 605 * @returns IPMI completion code plus response data 606 * - stdPayload0ipmiReserved - IPMI payload (reserved). 607 * - stdPayload1SOL - SOL payload 608 * - stdPayload2 609 * - stdPayload3 610 * - stdPayload4 611 * - stdPayload5 612 * - stdPayload6 613 * - stdPayload7 614 615 * - stdPayloadEnables2Reserved - Reserved. 616 617 * - oemPayload0 618 * - oemPayload1 619 * - oemPayload2 620 * - oemPayload3 621 * - oemPayload4 622 * - oemPayload5 623 * - oemPayload6 624 * - oemPayload7 625 626 * - oemPayloadEnables2Reserved - Reserved 627 */ 628 ipmi::RspType<bool, // stdPayload0ipmiReserved 629 bool, // stdPayload1SOL 630 bool, // stdPayload2 631 bool, // stdPayload3 632 bool, // stdPayload4 633 bool, // stdPayload5 634 bool, // stdPayload6 635 bool, // stdPayload7 636 637 uint8_t, // stdPayloadEnables2Reserved 638 639 bool, // oemPayload0 640 bool, // oemPayload1 641 bool, // oemPayload2 642 bool, // oemPayload3 643 bool, // oemPayload4 644 bool, // oemPayload5 645 bool, // oemPayload6 646 bool, // oemPayload7 647 648 uint8_t // oemPayloadEnables2Reserved 649 > 650 ipmiGetUserPayloadAccess(ipmi::Context::ptr ctx, 651 652 uint4_t channel, uint4_t reserved1, 653 654 uint6_t userId, uint2_t reserved2) 655 { 656 uint8_t chNum = 657 convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel); 658 659 if (reserved1 || reserved2 || !isValidChannel(chNum)) 660 { 661 return ipmi::responseInvalidFieldRequest(); 662 } 663 if (getChannelSessionSupport(chNum) == EChannelSessSupported::none) 664 { 665 return ipmi::response(ccActionNotSupportedForChannel); 666 } 667 if (!ipmiUserIsValidUserId(static_cast<uint8_t>(userId))) 668 { 669 return ipmi::responseParmOutOfRange(); 670 } 671 672 ipmi::Cc retStatus; 673 PayloadAccess payloadAccess = {}; 674 retStatus = ipmiUserGetUserPayloadAccess( 675 chNum, static_cast<uint8_t>(userId), payloadAccess); 676 if (retStatus != ccSuccess) 677 { 678 return ipmi::response(retStatus); 679 } 680 constexpr uint8_t res8bits = 0; 681 return ipmi::responseSuccess(payloadAccess.stdPayloadEnables1.test(0), 682 payloadAccess.stdPayloadEnables1.test(1), 683 payloadAccess.stdPayloadEnables1.test(2), 684 payloadAccess.stdPayloadEnables1.test(3), 685 payloadAccess.stdPayloadEnables1.test(4), 686 payloadAccess.stdPayloadEnables1.test(5), 687 payloadAccess.stdPayloadEnables1.test(6), 688 payloadAccess.stdPayloadEnables1.test(7), 689 690 res8bits, 691 692 payloadAccess.oemPayloadEnables1.test(0), 693 payloadAccess.oemPayloadEnables1.test(1), 694 payloadAccess.oemPayloadEnables1.test(2), 695 payloadAccess.oemPayloadEnables1.test(3), 696 payloadAccess.oemPayloadEnables1.test(4), 697 payloadAccess.oemPayloadEnables1.test(5), 698 payloadAccess.oemPayloadEnables1.test(6), 699 payloadAccess.oemPayloadEnables1.test(7), 700 701 res8bits); 702 } 703 704 void registerUserIpmiFunctions() __attribute__((constructor)); 705 void registerUserIpmiFunctions() 706 { 707 post_work([]() { ipmiUserInit(); }); 708 ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp, 709 ipmi::app::cmdSetUserAccessCommand, 710 ipmi::Privilege::Admin, ipmiSetUserAccess); 711 712 ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp, 713 ipmi::app::cmdGetUserAccessCommand, 714 ipmi::Privilege::Operator, ipmiGetUserAccess); 715 716 ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_USER_NAME, NULL, 717 ipmiGetUserName, PRIVILEGE_OPERATOR); 718 719 ipmi_register_callback(NETFUN_APP, IPMI_CMD_SET_USER_NAME, NULL, 720 ipmiSetUserName, PRIVILEGE_ADMIN); 721 722 ipmi_register_callback(NETFUN_APP, IPMI_CMD_SET_USER_PASSWORD, NULL, 723 ipmiSetUserPassword, PRIVILEGE_ADMIN); 724 725 ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp, 726 ipmi::app::cmdGetChannelAuthCapabilities, 727 ipmi::Privilege::Callback, 728 ipmiGetChannelAuthenticationCapabilities); 729 730 ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp, 731 ipmi::app::cmdSetUserPayloadAccess, 732 ipmi::Privilege::Admin, ipmiSetUserPayloadAccess); 733 734 ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp, 735 ipmi::app::cmdGetUserPayloadAccess, 736 ipmi::Privilege::Operator, ipmiGetUserPayloadAccess); 737 738 return; 739 } 740 } // namespace ipmi 741