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 return ipmiUserSetUserName(req->userId, 296 reinterpret_cast<const char*>(req->userName)); 297 } 298 299 /** @brief implementes the get user name command 300 * @param[in] netfn - specifies netfn. 301 * @param[in] cmd - specifies cmd number. 302 * @param[in] request - pointer to request data. 303 * @param[in, out] dataLen - specifies request data length, and returns 304 * response data length. 305 * @param[in] context - ipmi context. 306 * @returns ipmi completion code. 307 */ 308 Cc ipmiGetUserName(ipmi_netfn_t netfn, ipmi_cmd_t cmd, ipmi_request_t request, 309 ipmi_response_t response, ipmi_data_len_t dataLen, 310 ipmi_context_t context) 311 { 312 const GetUserNameReq* req = static_cast<GetUserNameReq*>(request); 313 size_t reqLength = *dataLen; 314 315 *dataLen = 0; 316 317 if (reqLength != sizeof(*req)) 318 { 319 log<level::DEBUG>("Get user name - Invalid Length"); 320 return ccReqDataLenInvalid; 321 } 322 323 std::string userName; 324 if (ipmiUserGetUserName(req->userId, userName) != ccSuccess) 325 { // Invalid User ID 326 log<level::DEBUG>("User Name not found", 327 entry("USER-ID=%d", (uint8_t)req->userId)); 328 return ccParmOutOfRange; 329 } 330 GetUserNameResp* resp = static_cast<GetUserNameResp*>(response); 331 std::fill(reinterpret_cast<uint8_t*>(resp), 332 reinterpret_cast<uint8_t*>(resp) + sizeof(*resp), 0); 333 userName.copy(reinterpret_cast<char*>(resp->userName), 334 sizeof(resp->userName), 0); 335 *dataLen = sizeof(*resp); 336 337 return ccSuccess; 338 } 339 340 /** @brief implementes the set user password command 341 * @param[in] netfn - specifies netfn. 342 * @param[in] cmd - specifies cmd number. 343 * @param[in] request - pointer to request data. 344 * @param[in, out] dataLen - specifies request data length, and returns 345 * response data length. 346 * @param[in] context - ipmi context. 347 * @returns ipmi completion code. 348 */ 349 Cc ipmiSetUserPassword(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 350 ipmi_request_t request, ipmi_response_t response, 351 ipmi_data_len_t dataLen, ipmi_context_t context) 352 { 353 const SetUserPasswordReq* req = static_cast<SetUserPasswordReq*>(request); 354 size_t reqLength = *dataLen; 355 // subtract 2 bytes header to know the password length - including NULL 356 uint8_t passwordLength = *dataLen - 2; 357 *dataLen = 0; 358 359 // verify input length based on operation. Required password size is 20 360 // bytes as we support only IPMI 2.0, but in order to be compatible with 361 // tools, accept 16 bytes of password size too. 362 if (reqLength < 2 || 363 // If enable / disable user, reqLength has to be >=2 & <= 22 364 ((req->operation == disableUser || req->operation == enableUser) && 365 ((reqLength < 2) || (reqLength > sizeof(SetUserPasswordReq))))) 366 { 367 log<level::DEBUG>("Invalid Length"); 368 return ccReqDataLenInvalid; 369 } 370 // If set / test password then password length has to be 16 or 20 bytes 371 // based on the password size bit. 372 if (((req->operation == setPassword) || (req->operation == testPassword)) && 373 (((req->ipmi20 == passwordKeySize20) && 374 (passwordLength != maxIpmi20PasswordSize)) || 375 ((req->ipmi20 == passwordKeySize16) && 376 (passwordLength != maxIpmi15PasswordSize)))) 377 { 378 log<level::DEBUG>("Invalid Length"); 379 return ccReqDataLenInvalid; 380 } 381 382 std::string userName; 383 if (ipmiUserGetUserName(req->userId, userName) != ccSuccess) 384 { 385 log<level::DEBUG>("User Name not found", 386 entry("USER-ID=%d", (uint8_t)req->userId)); 387 return ccParmOutOfRange; 388 } 389 if (req->operation == setPassword) 390 { 391 return ipmiUserSetUserPassword( 392 req->userId, reinterpret_cast<const char*>(req->userPassword)); 393 } 394 else if (req->operation == enableUser || req->operation == disableUser) 395 { 396 return ipmiUserUpdateEnabledState(req->userId, 397 static_cast<bool>(req->operation)); 398 } 399 else if (req->operation == testPassword) 400 { 401 auto password = ipmiUserGetPassword(userName); 402 std::string testPassword( 403 reinterpret_cast<const char*>(req->userPassword), 0, 404 passwordLength); 405 // Note: For security reasons password size won't be compared and 406 // wrong password size completion code will not be returned if size 407 // doesn't match as specified in IPMI specification. 408 if (password != testPassword) 409 { 410 log<level::DEBUG>("Test password failed", 411 entry("USER-ID=%d", (uint8_t)req->userId)); 412 return static_cast<Cc>( 413 IPMISetPasswordReturnCodes::ipmiCCPasswdFailMismatch); 414 } 415 return ccSuccess; 416 } 417 return ccInvalidFieldRequest; 418 } 419 420 /** @brief implements the get channel authentication command 421 * @param ctx - IPMI context pointer (for channel) 422 * @param extData - get IPMI 2.0 extended data 423 * @param reserved1 - skip 3 bits 424 * @param chNum - channel number to get info about 425 * @param reserved2 - skip 4 bits 426 * @param privLevel - requested privilege level 427 428 * @returns ipmi completion code plus response data 429 * - channel number 430 * - rmcpAuthTypes - RMCP auth types (IPMI 1.5) 431 * - reserved1 432 * - extDataSupport - true for IPMI 2.0 extensions 433 * - anonymousLogin - true for anonymous login enabled 434 * - nullUsers - true for null user names enabled 435 * - nonNullUsers - true for non-null usernames enabled 436 * - userAuth - false for user authentication enabled 437 * - perMessageAuth - false for per message authentication enabled 438 * - KGStatus - true for Kg required for authentication 439 * - reserved2 440 * - rmcp - RMCP (IPMI 1.5) connection support 441 * - rmcpp - RMCP+ (IPMI 2.0) connection support 442 * - reserved3 443 * - oemID - OEM IANA of any OEM auth support 444 * - oemAuxillary - OEM data for auth 445 */ 446 ipmi::RspType<uint8_t, // channel number 447 uint6_t, // rmcpAuthTypes 448 bool, // reserved1 449 bool, // extDataSupport 450 bool, // anonymousLogin 451 bool, // nullUsers 452 bool, // nonNullUsers 453 bool, // userAuth 454 bool, // perMessageAuth 455 bool, // KGStatus 456 uint2_t, // reserved2 457 bool, // rmcp 458 bool, // rmcpp 459 uint6_t, // reserved3 460 uint24_t, // oemID 461 uint8_t // oemAuxillary 462 > 463 ipmiGetChannelAuthenticationCapabilities(ipmi::Context::ptr ctx, 464 uint4_t chNum, uint3_t reserved1, 465 bool extData, uint4_t privLevel, 466 uint4_t reserved2) 467 { 468 uint8_t channel = 469 convertCurrentChannelNum(static_cast<uint8_t>(chNum), ctx->channel); 470 471 if (reserved1 || reserved2 || !isValidChannel(channel) || 472 !isValidPrivLimit(static_cast<uint8_t>(privLevel))) 473 { 474 log<level::DEBUG>( 475 "Get channel auth capabilities - Invalid field in request"); 476 return ipmi::responseInvalidFieldRequest(); 477 } 478 479 if (getChannelSessionSupport(channel) == EChannelSessSupported::none) 480 { 481 log<level::DEBUG>( 482 "Get channel auth capabilities - No support on channel"); 483 return ipmi::response(ccActionNotSupportedForChannel); 484 } 485 486 constexpr bool extDataSupport = true; // true for IPMI 2.0 extensions 487 constexpr bool reserved3 = false; 488 constexpr uint6_t rmcpAuthTypes = 0; // IPMI 1.5 auth types - not supported 489 constexpr uint2_t reserved4 = 0; 490 constexpr bool KGStatus = false; // Not supporting now. 491 constexpr bool perMessageAuth = false; // Per message auth - enabled 492 constexpr bool userAuth = false; // User authentication - enabled 493 constexpr bool nullUsers = false; // Null user names - not supported 494 constexpr bool anonymousLogin = false; // Anonymous login - not supported 495 constexpr uint6_t reserved5 = 0; 496 constexpr bool rmcpp = true; // IPMI 2.0 - supported 497 constexpr bool rmcp = false; // IPMI 1.5 - not supported 498 constexpr uint24_t oemID = 0; 499 constexpr uint8_t oemAuxillary = 0; 500 501 bool nonNullUsers = 0; 502 uint8_t maxChUsers = 0, enabledUsers = 0, fixedUsers = 0; 503 ipmi::ipmiUserGetAllCounts(maxChUsers, enabledUsers, fixedUsers); 504 nonNullUsers = enabledUsers > 0; 505 506 return ipmi::responseSuccess( 507 channel, rmcpAuthTypes, reserved3, extDataSupport, anonymousLogin, 508 nullUsers, nonNullUsers, userAuth, perMessageAuth, KGStatus, reserved4, 509 rmcp, rmcpp, reserved5, oemID, oemAuxillary); 510 } 511 512 /** @brief implements the set user payload access command. 513 * @param ctx - IPMI context pointer (for channel) 514 * @param channel - channel number (4 bits) 515 * @param reserved1 - skip 4 bits 516 * @param userId - user id (6 bits) 517 * @param operation - access ENABLE /DISABLE. (2 bits) 518 * @param stdPayload0 - IPMI - reserved. (1 bit) 519 * @param stdPayload1 - SOL. (1 bit) 520 * @param stdPayload2 - (1 bit) 521 * @param stdPayload3 - (1 bit) 522 * @param stdPayload4 - (1 bit) 523 * @param stdPayload5 - (1 bit) 524 * @param stdPayload6 - (1 bit) 525 * @param stdPayload7 - (1 bit) 526 * @param stdPayloadEnables2Reserved - (8 bits) 527 * @param oemPayload0 - (1 bit) 528 * @param oemPayload1 - (1 bit) 529 * @param oemPayload2 - (1 bit) 530 * @param oemPayload3 - (1 bit) 531 * @param oemPayload4 - (1 bit) 532 * @param oemPayload5 - (1 bit) 533 * @param oemPayload6 - (1 bit) 534 * @param oemPayload7 - (1 bit) 535 * @param oemPayloadEnables2Reserved - (8 bits) 536 * 537 * @returns IPMI completion code 538 */ 539 ipmi::RspType<> ipmiSetUserPayloadAccess( 540 ipmi::Context::ptr ctx, 541 542 uint4_t channel, uint4_t reserved, 543 544 uint6_t userId, uint2_t operation, 545 546 bool stdPayload0ipmiReserved, bool stdPayload1SOL, bool stdPayload2, 547 bool stdPayload3, bool stdPayload4, bool stdPayload5, bool stdPayload6, 548 bool stdPayload7, 549 550 uint8_t stdPayloadEnables2Reserved, 551 552 bool oemPayload0, bool oemPayload1, bool oemPayload2, bool oemPayload3, 553 bool oemPayload4, bool oemPayload5, bool oemPayload6, bool oemPayload7, 554 555 uint8_t oemPayloadEnables2Reserved) 556 { 557 auto chNum = 558 convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel); 559 // Validate the reserved args. Only SOL payload is supported as on date. 560 if (reserved || stdPayload0ipmiReserved || stdPayload2 || stdPayload3 || 561 stdPayload4 || stdPayload5 || stdPayload6 || stdPayload7 || 562 oemPayload0 || oemPayload1 || oemPayload2 || oemPayload3 || 563 oemPayload4 || oemPayload5 || oemPayload6 || oemPayload7 || 564 stdPayloadEnables2Reserved || oemPayloadEnables2Reserved || 565 !isValidChannel(chNum)) 566 { 567 return ipmi::responseInvalidFieldRequest(); 568 } 569 570 if ((operation != enableOperation && operation != disableOperation)) 571 { 572 return ipmi::responseInvalidFieldRequest(); 573 } 574 if (getChannelSessionSupport(chNum) == EChannelSessSupported::none) 575 { 576 return ipmi::response(ccActionNotSupportedForChannel); 577 } 578 if (!ipmiUserIsValidUserId(static_cast<uint8_t>(userId))) 579 { 580 return ipmi::responseParmOutOfRange(); 581 } 582 583 PayloadAccess payloadAccess = {0}; 584 payloadAccess.stdPayloadEnables1[1] = stdPayload1SOL; 585 586 return ipmi::response(ipmiUserSetUserPayloadAccess( 587 chNum, static_cast<uint8_t>(operation), static_cast<uint8_t>(userId), 588 payloadAccess)); 589 } 590 591 /** @brief implements the get user payload access command 592 * This command returns information about user payload enable settings 593 * that were set using the 'Set User Payload Access' Command. 594 * 595 * @param ctx - IPMI context pointer (for channel) 596 * @param channel - channel number 597 * @param reserved1 - skip 4 bits 598 * @param userId - user id 599 * @param reserved2 - skip 2 bits 600 * 601 * @returns IPMI completion code plus response data 602 * - stdPayload0ipmiReserved - IPMI payload (reserved). 603 * - stdPayload1SOL - SOL payload 604 * - stdPayload2 605 * - stdPayload3 606 * - stdPayload4 607 * - stdPayload5 608 * - stdPayload6 609 * - stdPayload7 610 611 * - stdPayloadEnables2Reserved - Reserved. 612 613 * - oemPayload0 614 * - oemPayload1 615 * - oemPayload2 616 * - oemPayload3 617 * - oemPayload4 618 * - oemPayload5 619 * - oemPayload6 620 * - oemPayload7 621 622 * - oemPayloadEnables2Reserved - Reserved 623 */ 624 ipmi::RspType<bool, // stdPayload0ipmiReserved 625 bool, // stdPayload1SOL 626 bool, // stdPayload2 627 bool, // stdPayload3 628 bool, // stdPayload4 629 bool, // stdPayload5 630 bool, // stdPayload6 631 bool, // stdPayload7 632 633 uint8_t, // stdPayloadEnables2Reserved 634 635 bool, // oemPayload0 636 bool, // oemPayload1 637 bool, // oemPayload2 638 bool, // oemPayload3 639 bool, // oemPayload4 640 bool, // oemPayload5 641 bool, // oemPayload6 642 bool, // oemPayload7 643 644 uint8_t // oemPayloadEnables2Reserved 645 > 646 ipmiGetUserPayloadAccess(ipmi::Context::ptr ctx, 647 648 uint4_t channel, uint4_t reserved1, 649 650 uint6_t userId, uint2_t reserved2) 651 { 652 uint8_t chNum = 653 convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel); 654 655 if (reserved1 || reserved2 || !isValidChannel(chNum)) 656 { 657 return ipmi::responseInvalidFieldRequest(); 658 } 659 if (getChannelSessionSupport(chNum) == EChannelSessSupported::none) 660 { 661 return ipmi::response(ccActionNotSupportedForChannel); 662 } 663 if (!ipmiUserIsValidUserId(static_cast<uint8_t>(userId))) 664 { 665 return ipmi::responseParmOutOfRange(); 666 } 667 668 ipmi::Cc retStatus; 669 PayloadAccess payloadAccess = {}; 670 retStatus = ipmiUserGetUserPayloadAccess( 671 chNum, static_cast<uint8_t>(userId), payloadAccess); 672 if (retStatus != ccSuccess) 673 { 674 return ipmi::response(retStatus); 675 } 676 constexpr uint8_t res8bits = 0; 677 return ipmi::responseSuccess(payloadAccess.stdPayloadEnables1.test(0), 678 payloadAccess.stdPayloadEnables1.test(1), 679 payloadAccess.stdPayloadEnables1.test(2), 680 payloadAccess.stdPayloadEnables1.test(3), 681 payloadAccess.stdPayloadEnables1.test(4), 682 payloadAccess.stdPayloadEnables1.test(5), 683 payloadAccess.stdPayloadEnables1.test(6), 684 payloadAccess.stdPayloadEnables1.test(7), 685 686 res8bits, 687 688 payloadAccess.oemPayloadEnables1.test(0), 689 payloadAccess.oemPayloadEnables1.test(1), 690 payloadAccess.oemPayloadEnables1.test(2), 691 payloadAccess.oemPayloadEnables1.test(3), 692 payloadAccess.oemPayloadEnables1.test(4), 693 payloadAccess.oemPayloadEnables1.test(5), 694 payloadAccess.oemPayloadEnables1.test(6), 695 payloadAccess.oemPayloadEnables1.test(7), 696 697 res8bits); 698 } 699 700 void registerUserIpmiFunctions() __attribute__((constructor)); 701 void registerUserIpmiFunctions() 702 { 703 post_work([]() { ipmiUserInit(); }); 704 ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp, 705 ipmi::app::cmdSetUserAccessCommand, 706 ipmi::Privilege::Admin, ipmiSetUserAccess); 707 708 ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp, 709 ipmi::app::cmdGetUserAccessCommand, 710 ipmi::Privilege::Operator, ipmiGetUserAccess); 711 712 ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_USER_NAME, NULL, 713 ipmiGetUserName, PRIVILEGE_OPERATOR); 714 715 ipmi_register_callback(NETFUN_APP, IPMI_CMD_SET_USER_NAME, NULL, 716 ipmiSetUserName, PRIVILEGE_ADMIN); 717 718 ipmi_register_callback(NETFUN_APP, IPMI_CMD_SET_USER_PASSWORD, NULL, 719 ipmiSetUserPassword, PRIVILEGE_ADMIN); 720 721 ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp, 722 ipmi::app::cmdGetChannelAuthCapabilities, 723 ipmi::Privilege::Callback, 724 ipmiGetChannelAuthenticationCapabilities); 725 726 ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp, 727 ipmi::app::cmdSetUserPayloadAccess, 728 ipmi::Privilege::Admin, ipmiSetUserPayloadAccess); 729 730 ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp, 731 ipmi::app::cmdGetUserPayloadAccess, 732 ipmi::Privilege::Operator, ipmiGetUserPayloadAccess); 733 734 return; 735 } 736 } // namespace ipmi 737