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