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