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