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