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