1 /* -*-mode: C; indent-tabs-mode: t; -*- 2 * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * Redistribution of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 11 * Redistribution in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * Neither the name of Sun Microsystems, Inc. or the names of 16 * contributors may be used to endorse or promote products derived 17 * from this software without specific prior written permission. 18 * 19 * This software is provided "AS IS," without a warranty of any kind. 20 * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, 21 * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A 22 * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. 23 * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE 24 * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING 25 * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL 26 * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, 27 * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR 28 * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF 29 * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, 30 * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 31 */ 32 33 #include <stdlib.h> 34 #include <stdio.h> 35 #include <string.h> 36 #include <strings.h> 37 #include <sys/types.h> 38 #include <sys/socket.h> 39 #include <netinet/in.h> 40 #include <arpa/inet.h> 41 #include <errno.h> 42 #include <unistd.h> 43 #include <signal.h> 44 45 #include <ipmitool/ipmi.h> 46 #include <ipmitool/ipmi_intf.h> 47 #include <ipmitool/helper.h> 48 #include <ipmitool/log.h> 49 #include <ipmitool/ipmi_lanp.h> 50 #include <ipmitool/ipmi_channel.h> 51 #include <ipmitool/ipmi_strings.h> 52 #include <ipmitool/ipmi_constants.h> 53 #include <ipmitool/ipmi_user.h> 54 55 extern int csv_output; 56 extern int verbose; 57 58 void printf_channel_usage(void); 59 60 /* _ipmi_get_channel_access - Get Channel Access for given channel. Results are 61 * stored into passed struct. 62 * 63 * @intf - IPMI interface 64 * @channel_access - ptr to channel_access_t with Channel set. 65 * @get_volatile_settings - get volatile if != 0, else non-volatile settings. 66 * 67 * returns - negative number means error, positive is a ccode. 68 */ 69 int 70 _ipmi_get_channel_access(struct ipmi_intf *intf, 71 struct channel_access_t *channel_access, 72 uint8_t get_volatile_settings) 73 { 74 struct ipmi_rs *rsp; 75 struct ipmi_rq req = {0}; 76 uint8_t data[2]; 77 78 if (channel_access == NULL) { 79 return (-3); 80 } 81 data[0] = channel_access->channel & 0x0F; 82 /* volatile - 0x80; non-volatile - 0x40 */ 83 data[1] = get_volatile_settings ? 0x80 : 0x40; 84 req.msg.netfn = IPMI_NETFN_APP; 85 req.msg.cmd = IPMI_GET_CHANNEL_ACCESS; 86 req.msg.data = data; 87 req.msg.data_len = 2; 88 89 rsp = intf->sendrecv(intf, &req); 90 if (rsp == NULL) { 91 return (-1); 92 } else if (rsp->ccode != 0) { 93 return rsp->ccode; 94 } else if (rsp->data_len != 2) { 95 return (-2); 96 } 97 channel_access->alerting = rsp->data[0] & 0x20; 98 channel_access->per_message_auth = rsp->data[0] & 0x10; 99 channel_access->user_level_auth = rsp->data[0] & 0x08; 100 channel_access->access_mode = rsp->data[0] & 0x07; 101 channel_access->privilege_limit = rsp->data[1] & 0x0F; 102 return 0; 103 } 104 105 /* _ipmi_get_channel_info - Get Channel Info for given channel. Results are 106 * stored into passed struct. 107 * 108 * @intf - IPMI interface 109 * @channel_info - ptr to channel_info_t with Channel set. 110 * 111 * returns - negative number means error, positive is a ccode. 112 */ 113 int 114 _ipmi_get_channel_info(struct ipmi_intf *intf, 115 struct channel_info_t *channel_info) 116 { 117 struct ipmi_rs *rsp; 118 struct ipmi_rq req = {0}; 119 uint8_t data[1]; 120 121 if (channel_info == NULL) { 122 return (-3); 123 } 124 data[0] = channel_info->channel & 0x0F; 125 req.msg.netfn = IPMI_NETFN_APP; 126 req.msg.cmd = IPMI_GET_CHANNEL_INFO; 127 req.msg.data = data; 128 req.msg.data_len = 1; 129 130 rsp = intf->sendrecv(intf, &req); 131 if (rsp == NULL) { 132 return (-1); 133 } else if (rsp->ccode != 0) { 134 return rsp->ccode; 135 } else if (rsp->data_len != 9) { 136 return (-2); 137 } 138 channel_info->channel = rsp->data[0] & 0x0F; 139 channel_info->medium = rsp->data[1] & 0x7F; 140 channel_info->protocol = rsp->data[2] & 0x1F; 141 channel_info->session_support = rsp->data[3] & 0xC0; 142 channel_info->active_sessions = rsp->data[3] & 0x3F; 143 memcpy(channel_info->vendor_id, &rsp->data[4], 144 sizeof(channel_info->vendor_id)); 145 memcpy(channel_info->aux_info, &rsp->data[7], 146 sizeof(channel_info->aux_info)); 147 return 0; 148 } 149 150 /* _ipmi_set_channel_access - Set Channel Access values for given channel. 151 * 152 * @intf - IPMI interface 153 * @channel_access - channel_access_t with desired values and channel set. 154 * @access_option: 155 * - 0 = don't set/change Channel Access 156 * - 1 = set non-volatile settings of Channel Access 157 * - 2 = set volatile settings of Channel Access 158 * @privilege_option: 159 * - 0 = don't set/change Privilege Level Limit 160 * - 1 = set non-volatile settings of Privilege Limit 161 * - 2 = set volatile settings of Privilege Limit 162 * 163 * returns - negative number means error, positive is a ccode. See IPMI 164 * specification for further information on ccodes for Set Channel Access. 165 * 0x82 - set not supported on selected channel, eg. session-less channel. 166 * 0x83 - access mode not supported 167 */ 168 int 169 _ipmi_set_channel_access(struct ipmi_intf *intf, 170 struct channel_access_t channel_access, 171 uint8_t access_option, 172 uint8_t privilege_option) 173 { 174 struct ipmi_rs *rsp; 175 struct ipmi_rq req; 176 uint8_t data[3]; 177 /* Only values from <0..2> are accepted as valid. */ 178 if (access_option > 2 || privilege_option > 2) { 179 return (-3); 180 } 181 182 memset(&data, 0, sizeof(data)); 183 data[0] = channel_access.channel & 0x0F; 184 data[1] = (access_option << 6); 185 if (channel_access.alerting) { 186 data[1] |= 0x20; 187 } 188 if (channel_access.per_message_auth) { 189 data[1] |= 0x10; 190 } 191 if (channel_access.user_level_auth) { 192 data[1] |= 0x08; 193 } 194 data[1] |= (channel_access.access_mode & 0x07); 195 data[2] = (privilege_option << 6); 196 data[2] |= (channel_access.privilege_limit & 0x0F); 197 198 memset(&req, 0, sizeof(req)); 199 req.msg.netfn = IPMI_NETFN_APP; 200 req.msg.cmd = IPMI_SET_CHANNEL_ACCESS; 201 req.msg.data = data; 202 req.msg.data_len = 3; 203 204 rsp = intf->sendrecv(intf, &req); 205 if (rsp == NULL) { 206 return (-1); 207 } 208 return rsp->ccode; 209 } 210 211 static const char * 212 iana_string(uint32_t iana) 213 { 214 static char s[10]; 215 216 if (iana) { 217 sprintf(s, "%06x", iana); 218 return s; 219 } else { 220 return "N/A"; 221 } 222 } 223 224 /** 225 * ipmi_1_5_authtypes 226 * 227 * Create a string describing the supported authentication types as 228 * specificed by the parameter n 229 */ 230 static const char * 231 ipmi_1_5_authtypes(uint8_t n) 232 { 233 uint32_t i; 234 static char supportedTypes[128]; 235 236 memset(supportedTypes, 0, sizeof(supportedTypes)); 237 for (i = 0; ipmi_authtype_vals[i].val != 0; i++) { 238 if (n & ipmi_authtype_vals[i].val) { 239 strcat(supportedTypes, ipmi_authtype_vals[i].str); 240 strcat(supportedTypes, " "); 241 } 242 } 243 244 return supportedTypes; 245 } 246 247 uint8_t 248 ipmi_current_channel_medium(struct ipmi_intf *intf) 249 { 250 return ipmi_get_channel_medium(intf, 0xE); 251 } 252 253 /** 254 * ipmi_get_channel_auth_cap 255 * 256 * return 0 on success 257 * -1 on failure 258 */ 259 int 260 ipmi_get_channel_auth_cap(struct ipmi_intf *intf, uint8_t channel, uint8_t priv) 261 { 262 struct ipmi_rs *rsp; 263 struct ipmi_rq req; 264 struct get_channel_auth_cap_rsp auth_cap; 265 uint8_t msg_data[2]; 266 267 /* Ask for IPMI v2 data as well */ 268 msg_data[0] = channel | 0x80; 269 msg_data[1] = priv; 270 271 memset(&req, 0, sizeof(req)); 272 req.msg.netfn = IPMI_NETFN_APP; 273 req.msg.cmd = IPMI_GET_CHANNEL_AUTH_CAP; 274 req.msg.data = msg_data; 275 req.msg.data_len = 2; 276 277 rsp = intf->sendrecv(intf, &req); 278 279 if ((rsp == NULL) || (rsp->ccode > 0)) { 280 /* 281 * It's very possible that this failed because we asked for IPMI v2 data 282 * Ask again, without requesting IPMI v2 data 283 */ 284 msg_data[0] &= 0x7F; 285 286 rsp = intf->sendrecv(intf, &req); 287 if (rsp == NULL) { 288 lprintf(LOG_ERR, "Unable to Get Channel Authentication Capabilities"); 289 return (-1); 290 } 291 if (rsp->ccode > 0) { 292 lprintf(LOG_ERR, "Get Channel Authentication Capabilities failed: %s", 293 val2str(rsp->ccode, completion_code_vals)); 294 return (-1); 295 } 296 } 297 298 memcpy(&auth_cap, rsp->data, sizeof(struct get_channel_auth_cap_rsp)); 299 300 printf("Channel number : %d\n", 301 auth_cap.channel_number); 302 printf("IPMI v1.5 auth types : %s\n", 303 ipmi_1_5_authtypes(auth_cap.enabled_auth_types)); 304 305 if (auth_cap.v20_data_available) { 306 printf("KG status : %s\n", 307 (auth_cap.kg_status) ? "non-zero" : "default (all zeroes)"); 308 } 309 310 printf("Per message authentication : %sabled\n", 311 (auth_cap.per_message_auth) ? "dis" : "en"); 312 printf("User level authentication : %sabled\n", 313 (auth_cap.user_level_auth) ? "dis" : "en"); 314 315 printf("Non-null user names exist : %s\n", 316 (auth_cap.non_null_usernames) ? "yes" : "no"); 317 printf("Null user names exist : %s\n", 318 (auth_cap.null_usernames) ? "yes" : "no"); 319 printf("Anonymous login enabled : %s\n", 320 (auth_cap.anon_login_enabled) ? "yes" : "no"); 321 322 if (auth_cap.v20_data_available) { 323 printf("Channel supports IPMI v1.5 : %s\n", 324 (auth_cap.ipmiv15_support) ? "yes" : "no"); 325 printf("Channel supports IPMI v2.0 : %s\n", 326 (auth_cap.ipmiv20_support) ? "yes" : "no"); 327 } 328 329 /* 330 * If there is support for an OEM authentication type, there is some 331 * information. 332 */ 333 if (auth_cap.enabled_auth_types & IPMI_1_5_AUTH_TYPE_BIT_OEM) { 334 printf("IANA Number for OEM : %d\n", 335 auth_cap.oem_id[0] | 336 auth_cap.oem_id[1] << 8 | 337 auth_cap.oem_id[2] << 16); 338 printf("OEM Auxiliary Data : 0x%x\n", 339 auth_cap.oem_aux_data); 340 } 341 342 return 0; 343 } 344 345 static int 346 ipmi_get_channel_cipher_suites(struct ipmi_intf *intf, const char *payload_type, 347 uint8_t channel) 348 { 349 struct ipmi_rs *rsp; 350 struct ipmi_rq req; 351 352 uint8_t rqdata[3]; 353 uint32_t iana; 354 uint8_t auth_alg, integrity_alg, crypt_alg; 355 uint8_t cipher_suite_id; 356 uint8_t list_index = 0; 357 /* 0x40 sets * 16 bytes per set */ 358 uint8_t cipher_suite_data[1024]; 359 uint16_t offset = 0; 360 /* how much was returned, total */ 361 uint16_t cipher_suite_data_length = 0; 362 363 memset(cipher_suite_data, 0, sizeof(cipher_suite_data)); 364 365 memset(&req, 0, sizeof(req)); 366 req.msg.netfn = IPMI_NETFN_APP; 367 req.msg.cmd = IPMI_GET_CHANNEL_CIPHER_SUITES; 368 req.msg.data = rqdata; 369 req.msg.data_len = 3; 370 371 rqdata[0] = channel; 372 rqdata[1] = ((strncmp(payload_type, "ipmi", 4) == 0)? 0: 1); 373 /* Always ask for cipher suite format */ 374 rqdata[2] = 0x80; 375 376 rsp = intf->sendrecv(intf, &req); 377 if (rsp == NULL) { 378 lprintf(LOG_ERR, "Unable to Get Channel Cipher Suites"); 379 return -1; 380 } 381 if (rsp->ccode > 0) { 382 lprintf(LOG_ERR, "Get Channel Cipher Suites failed: %s", 383 val2str(rsp->ccode, completion_code_vals)); 384 return -1; 385 } 386 387 388 /* 389 * Grab the returned channel number once. We assume it's the same 390 * in future calls. 391 */ 392 if (rsp->data_len >= 1) { 393 channel = rsp->data[0]; 394 } 395 396 while ((rsp->data_len > 1) && (rsp->data_len == 17) && (list_index < 0x3F)) { 397 /* 398 * We got back cipher suite data -- store it. 399 * printf("copying data to offset %d\n", offset); 400 * printbuf(rsp->data + 1, rsp->data_len - 1, "this is the data"); 401 */ 402 memcpy(cipher_suite_data + offset, rsp->data + 1, rsp->data_len - 1); 403 offset += rsp->data_len - 1; 404 405 /* 406 * Increment our list for the next call 407 */ 408 ++list_index; 409 rqdata[2] = (rqdata[2] & 0x80) + list_index; 410 411 rsp = intf->sendrecv(intf, &req); 412 if (rsp == NULL) { 413 lprintf(LOG_ERR, "Unable to Get Channel Cipher Suites"); 414 return -1; 415 } 416 if (rsp->ccode > 0) { 417 lprintf(LOG_ERR, "Get Channel Cipher Suites failed: %s", 418 val2str(rsp->ccode, completion_code_vals)); 419 return -1; 420 } 421 } 422 423 /* Copy last chunk */ 424 if(rsp->data_len > 1) { 425 /* 426 * We got back cipher suite data -- store it. 427 * printf("copying data to offset %d\n", offset); 428 * printbuf(rsp->data + 1, rsp->data_len - 1, "this is the data"); 429 */ 430 memcpy(cipher_suite_data + offset, rsp->data + 1, rsp->data_len - 1); 431 offset += rsp->data_len - 1; 432 } 433 434 /* We can chomp on all our data now. */ 435 cipher_suite_data_length = offset; 436 offset = 0; 437 438 if (! csv_output) { 439 printf("ID IANA Auth Alg Integrity Alg Confidentiality Alg\n"); 440 } 441 while (offset < cipher_suite_data_length) { 442 if (cipher_suite_data[offset++] == 0xC0) { 443 /* standard type */ 444 iana = 0; 445 446 /* Verify that we have at least a full record left; id + 3 algs */ 447 if ((cipher_suite_data_length - offset) < 4) { 448 lprintf(LOG_ERR, "Incomplete data record in cipher suite data"); 449 return -1; 450 } 451 cipher_suite_id = cipher_suite_data[offset++]; 452 } else if (cipher_suite_data[offset++] == 0xC1) { 453 /* OEM record type */ 454 /* Verify that we have at least a full record left 455 * id + iana + 3 algs 456 */ 457 if ((cipher_suite_data_length - offset) < 4) { 458 lprintf(LOG_ERR, "Incomplete data record in cipher suite data"); 459 return -1; 460 } 461 462 cipher_suite_id = cipher_suite_data[offset++]; 463 464 /* Grab the IANA */ 465 iana = 466 cipher_suite_data[offset] | 467 (cipher_suite_data[offset + 1] << 8) | 468 (cipher_suite_data[offset + 2] << 16); 469 offset += 3; 470 } else { 471 lprintf(LOG_ERR, "Bad start of record byte in cipher suite data"); 472 return -1; 473 } 474 475 /* 476 * Grab the algorithms for this cipher suite. I guess we can't be 477 * sure of what order they'll come in. Also, I suppose we default 478 * to the NONE algorithm if one were absent. This part of the spec is 479 * poorly written -- I have read the errata document. For now, I'm only 480 * allowing one algorithm per type (auth, integrity, crypt) because I 481 * don't I understand how it could be otherwise. 482 */ 483 auth_alg = IPMI_AUTH_RAKP_NONE; 484 integrity_alg = IPMI_INTEGRITY_NONE; 485 crypt_alg = IPMI_CRYPT_NONE; 486 487 while (((cipher_suite_data[offset] & 0xC0) != 0xC0) && 488 ((cipher_suite_data_length - offset) > 0)) 489 { 490 switch (cipher_suite_data[offset] & 0xC0) 491 { 492 case 0x00: 493 /* Authentication algorithm specifier */ 494 auth_alg = cipher_suite_data[offset++] & 0x3F; 495 break; 496 case 0x40: 497 /* Interity algorithm specifier */ 498 integrity_alg = cipher_suite_data[offset++] & 0x3F; 499 break; 500 case 0x80: 501 /* Confidentiality algorithm specifier */ 502 crypt_alg = cipher_suite_data[offset++] & 0x3F; 503 break; 504 } 505 } 506 /* We have everything we need to spit out a cipher suite record */ 507 printf((csv_output? "%d,%s,%s,%s,%s\n" : 508 "%-4d %-7s %-15s %-15s %-15s\n"), 509 cipher_suite_id, 510 iana_string(iana), 511 val2str(auth_alg, ipmi_auth_algorithms), 512 val2str(integrity_alg, ipmi_integrity_algorithms), 513 val2str(crypt_alg, ipmi_encryption_algorithms)); 514 } 515 return 0; 516 } 517 518 /** 519 * ipmi_get_channel_info 520 * 521 * returns 0 on success 522 * -1 on failure 523 * 524 */ 525 int 526 ipmi_get_channel_info(struct ipmi_intf *intf, uint8_t channel) 527 { 528 struct channel_info_t channel_info = {0}; 529 struct channel_access_t channel_access = {0}; 530 int ccode = 0; 531 532 channel_info.channel = channel; 533 ccode = _ipmi_get_channel_info(intf, &channel_info); 534 if (eval_ccode(ccode) != 0) { 535 lprintf(LOG_ERR, "Unable to Get Channel Info"); 536 return (-1); 537 } 538 539 printf("Channel 0x%x info:\n", channel_info.channel); 540 printf(" Channel Medium Type : %s\n", 541 val2str(channel_info.medium, 542 ipmi_channel_medium_vals)); 543 printf(" Channel Protocol Type : %s\n", 544 val2str(channel_info.protocol, 545 ipmi_channel_protocol_vals)); 546 printf(" Session Support : "); 547 switch (channel_info.session_support) { 548 case IPMI_CHANNEL_SESSION_LESS: 549 printf("session-less\n"); 550 break; 551 case IPMI_CHANNEL_SESSION_SINGLE: 552 printf("single-session\n"); 553 break; 554 case IPMI_CHANNEL_SESSION_MULTI: 555 printf("multi-session\n"); 556 break; 557 case IPMI_CHANNEL_SESSION_BASED: 558 printf("session-based\n"); 559 break; 560 default: 561 printf("unknown\n"); 562 break; 563 } 564 printf(" Active Session Count : %d\n", 565 channel_info.active_sessions); 566 printf(" Protocol Vendor ID : %d\n", 567 channel_info.vendor_id[0] | 568 channel_info.vendor_id[1] << 8 | 569 channel_info.vendor_id[2] << 16); 570 571 /* only proceed if this is LAN channel */ 572 if (channel_info.medium != IPMI_CHANNEL_MEDIUM_LAN 573 && channel_info.medium != IPMI_CHANNEL_MEDIUM_LAN_OTHER) { 574 return 0; 575 } 576 577 channel_access.channel = channel_info.channel; 578 ccode = _ipmi_get_channel_access(intf, &channel_access, 1); 579 if (eval_ccode(ccode) != 0) { 580 lprintf(LOG_ERR, "Unable to Get Channel Access (volatile)"); 581 return (-1); 582 } 583 584 printf(" Volatile(active) Settings\n"); 585 printf(" Alerting : %sabled\n", 586 (channel_access.alerting) ? "dis" : "en"); 587 printf(" Per-message Auth : %sabled\n", 588 (channel_access.per_message_auth) ? "dis" : "en"); 589 printf(" User Level Auth : %sabled\n", 590 (channel_access.user_level_auth) ? "dis" : "en"); 591 printf(" Access Mode : "); 592 switch (channel_access.access_mode) { 593 case 0: 594 printf("disabled\n"); 595 break; 596 case 1: 597 printf("pre-boot only\n"); 598 break; 599 case 2: 600 printf("always available\n"); 601 break; 602 case 3: 603 printf("shared\n"); 604 break; 605 default: 606 printf("unknown\n"); 607 break; 608 } 609 610 memset(&channel_access, 0, sizeof(channel_access)); 611 channel_access.channel = channel_info.channel; 612 /* get non-volatile settings */ 613 ccode = _ipmi_get_channel_access(intf, &channel_access, 0); 614 if (eval_ccode(ccode) != 0) { 615 lprintf(LOG_ERR, "Unable to Get Channel Access (non-volatile)"); 616 return (-1); 617 } 618 619 printf(" Non-Volatile Settings\n"); 620 printf(" Alerting : %sabled\n", 621 (channel_access.alerting) ? "dis" : "en"); 622 printf(" Per-message Auth : %sabled\n", 623 (channel_access.per_message_auth) ? "dis" : "en"); 624 printf(" User Level Auth : %sabled\n", 625 (channel_access.user_level_auth) ? "dis" : "en"); 626 printf(" Access Mode : "); 627 switch (channel_access.access_mode) { 628 case 0: 629 printf("disabled\n"); 630 break; 631 case 1: 632 printf("pre-boot only\n"); 633 break; 634 case 2: 635 printf("always available\n"); 636 break; 637 case 3: 638 printf("shared\n"); 639 break; 640 default: 641 printf("unknown\n"); 642 break; 643 } 644 return 0; 645 } 646 647 /* ipmi_get_channel_medium - Return Medium of given IPMI Channel. 648 * 649 * @channel - IPMI Channel 650 * 651 * returns - IPMI Channel Medium, IPMI_CHANNEL_MEDIUM_RESERVED if ccode > 0, 652 * 0 on error. 653 */ 654 uint8_t 655 ipmi_get_channel_medium(struct ipmi_intf *intf, uint8_t channel) 656 { 657 struct channel_info_t channel_info = {0}; 658 int ccode = 0; 659 660 channel_info.channel = channel; 661 ccode = _ipmi_get_channel_info(intf, &channel_info); 662 if (ccode == 0xCC) { 663 return IPMI_CHANNEL_MEDIUM_RESERVED; 664 } else if (ccode < 0 && eval_ccode(ccode) != 0) { 665 return 0; 666 } else if (ccode > 0) { 667 lprintf(LOG_ERR, "Get Channel Info command failed: %s", 668 val2str(ccode, completion_code_vals)); 669 return IPMI_CHANNEL_MEDIUM_RESERVED; 670 } 671 lprintf(LOG_DEBUG, "Channel type: %s", 672 val2str(channel_info.medium, ipmi_channel_medium_vals)); 673 return channel_info.medium; 674 } 675 676 /* ipmi_get_user_access - Get User Access for given Channel and User or Users. 677 * 678 * @intf - IPMI interface 679 * @channel - IPMI Channel we're getting access for 680 * @user_id - User ID. If 0 is passed, all IPMI users will be listed 681 * 682 * returns - 0 on success, (-1) on error 683 */ 684 static int 685 ipmi_get_user_access(struct ipmi_intf *intf, uint8_t channel, uint8_t user_id) 686 { 687 struct user_access_t user_access; 688 struct user_name_t user_name; 689 int ccode = 0; 690 int curr_uid; 691 int init = 1; 692 int max_uid = 0; 693 694 curr_uid = user_id ? user_id : 1; 695 do { 696 memset(&user_access, 0, sizeof(user_access)); 697 user_access.channel = channel; 698 user_access.user_id = curr_uid; 699 ccode = _ipmi_get_user_access(intf, &user_access); 700 if (eval_ccode(ccode) != 0) { 701 lprintf(LOG_ERR, 702 "Unable to Get User Access (channel %d id %d)", 703 channel, curr_uid); 704 return (-1); 705 } 706 707 memset(&user_name, 0, sizeof(user_name)); 708 user_name.user_id = curr_uid; 709 ccode = _ipmi_get_user_name(intf, &user_name); 710 if (eval_ccode(ccode) != 0) { 711 lprintf(LOG_ERR, "Unable to Get User Name (id %d)", curr_uid); 712 return (-1); 713 } 714 if (init) { 715 printf("Maximum User IDs : %d\n", user_access.max_user_ids); 716 printf("Enabled User IDs : %d\n", user_access.enabled_user_ids); 717 max_uid = user_access.max_user_ids; 718 init = 0; 719 } 720 721 printf("\n"); 722 printf("User ID : %d\n", curr_uid); 723 printf("User Name : %s\n", user_name.user_name); 724 printf("Fixed Name : %s\n", 725 (curr_uid <= user_access.fixed_user_ids) ? "Yes" : "No"); 726 printf("Access Available : %s\n", 727 (user_access.callin_callback) ? "callback" : "call-in / callback"); 728 printf("Link Authentication : %sabled\n", 729 (user_access.link_auth) ? "en" : "dis"); 730 printf("IPMI Messaging : %sabled\n", 731 (user_access.ipmi_messaging) ? "en" : "dis"); 732 printf("Privilege Level : %s\n", 733 val2str(user_access.privilege_limit, ipmi_privlvl_vals)); 734 735 curr_uid ++; 736 } while (!user_id && curr_uid <= max_uid); 737 738 return 0; 739 } 740 741 /* ipmi_set_user_access - Query BMC for current Channel ACLs, parse CLI args 742 * and update current ACLs. 743 * 744 * returns - 0 on success, (-1) on error 745 */ 746 int 747 ipmi_set_user_access(struct ipmi_intf *intf, int argc, char **argv) 748 { 749 struct user_access_t user_access = {0}; 750 int ccode = 0; 751 int i = 0; 752 uint8_t channel = 0; 753 uint8_t priv = 0; 754 uint8_t user_id = 0; 755 if (argc > 0 && strncmp(argv[0], "help", 4) == 0) { 756 printf_channel_usage(); 757 return 0; 758 } else if (argc < 3) { 759 lprintf(LOG_ERR, "Not enough parameters given."); 760 printf_channel_usage(); 761 return (-1); 762 } 763 if (is_ipmi_channel_num(argv[0], &channel) != 0 764 || is_ipmi_user_id(argv[1], &user_id) != 0) { 765 return (-1); 766 } 767 user_access.channel = channel; 768 user_access.user_id = user_id; 769 ccode = _ipmi_get_user_access(intf, &user_access); 770 if (eval_ccode(ccode) != 0) { 771 lprintf(LOG_ERR, 772 "Unable to Get User Access (channel %d id %d)", 773 channel, user_id); 774 return (-1); 775 } 776 for (i = 3; i < argc; i ++) { 777 if (strncmp(argv[i], "callin=", 7) == 0) { 778 if (strncmp(argv[i] + 7, "off", 3) == 0) { 779 user_access.callin_callback = 1; 780 } else { 781 user_access.callin_callback = 0; 782 } 783 } else if (strncmp(argv[i], "link=", 5) == 0) { 784 if (strncmp(argv[i] + 5, "off", 3) == 0) { 785 user_access.link_auth = 0; 786 } else { 787 user_access.link_auth = 1; 788 } 789 } else if (strncmp(argv[i], "ipmi=", 5) == 0) { 790 if (strncmp(argv[i] + 5, "off", 3) == 0) { 791 user_access.ipmi_messaging = 0; 792 } else { 793 user_access.ipmi_messaging = 1; 794 } 795 } else if (strncmp(argv[i], "privilege=", 10) == 0) { 796 if (str2uchar(argv[i] + 10, &priv) != 0) { 797 lprintf(LOG_ERR, 798 "Numeric value expected, but '%s' given.", 799 argv[i] + 10); 800 return (-1); 801 } 802 user_access.privilege_limit = priv; 803 } else { 804 lprintf(LOG_ERR, "Invalid option: %s\n", argv[i]); 805 return (-1); 806 } 807 } 808 ccode = _ipmi_set_user_access(intf, &user_access, 0); 809 if (eval_ccode(ccode) != 0) { 810 lprintf(LOG_ERR, 811 "Unable to Set User Access (channel %d id %d)", 812 channel, user_id); 813 return (-1); 814 } 815 printf("Set User Access (channel %d id %d) successful.\n", 816 channel, user_id); 817 return 0; 818 } 819 820 int 821 ipmi_channel_main(struct ipmi_intf *intf, int argc, char **argv) 822 { 823 int retval = 0; 824 uint8_t channel; 825 uint8_t priv = 0; 826 if (argc < 1) { 827 lprintf(LOG_ERR, "Not enough parameters given."); 828 printf_channel_usage(); 829 return (-1); 830 } else if (strncmp(argv[0], "help", 4) == 0) { 831 printf_channel_usage(); 832 return 0; 833 } else if (strncmp(argv[0], "authcap", 7) == 0) { 834 if (argc != 3) { 835 printf_channel_usage(); 836 return (-1); 837 } 838 if (is_ipmi_channel_num(argv[1], &channel) != 0 839 || is_ipmi_user_priv_limit(argv[2], &priv) != 0) { 840 return (-1); 841 } 842 retval = ipmi_get_channel_auth_cap(intf, channel, priv); 843 } else if (strncmp(argv[0], "getaccess", 10) == 0) { 844 uint8_t user_id = 0; 845 if ((argc < 2) || (argc > 3)) { 846 lprintf(LOG_ERR, "Not enough parameters given."); 847 printf_channel_usage(); 848 return (-1); 849 } 850 if (is_ipmi_channel_num(argv[1], &channel) != 0) { 851 return (-1); 852 } 853 if (argc == 3) { 854 if (is_ipmi_user_id(argv[2], &user_id) != 0) { 855 return (-1); 856 } 857 } 858 retval = ipmi_get_user_access(intf, channel, user_id); 859 } else if (strncmp(argv[0], "setaccess", 9) == 0) { 860 return ipmi_set_user_access(intf, (argc - 1), &(argv[1])); 861 } else if (strncmp(argv[0], "info", 4) == 0) { 862 channel = 0xE; 863 if (argc > 2) { 864 printf_channel_usage(); 865 return (-1); 866 } 867 if (argc == 2) { 868 if (is_ipmi_channel_num(argv[1], &channel) != 0) { 869 return (-1); 870 } 871 } 872 retval = ipmi_get_channel_info(intf, channel); 873 } else if (strncmp(argv[0], "getciphers", 10) == 0) { 874 /* channel getciphers <ipmi|sol> [channel] */ 875 channel = 0xE; 876 if ((argc < 2) || (argc > 3) || 877 (strncmp(argv[1], "ipmi", 4) && strncmp(argv[1], "sol", 3))) { 878 printf_channel_usage(); 879 return (-1); 880 } 881 if (argc == 3) { 882 if (is_ipmi_channel_num(argv[1], &channel) != 0) { 883 return (-1); 884 } 885 } 886 retval = ipmi_get_channel_cipher_suites(intf, 887 argv[1], /* ipmi | sol */ 888 channel); 889 } else { 890 lprintf(LOG_ERR, "Invalid CHANNEL command: %s\n", argv[0]); 891 printf_channel_usage(); 892 retval = -1; 893 } 894 return retval; 895 } 896 897 /* printf_channel_usage - print-out help. */ 898 void 899 printf_channel_usage() 900 { 901 lprintf(LOG_NOTICE, 902 "Channel Commands: authcap <channel number> <max privilege>"); 903 lprintf(LOG_NOTICE, 904 " getaccess <channel number> [user id]"); 905 lprintf(LOG_NOTICE, 906 " setaccess <channel number> " 907 "<user id> [callin=on|off] [ipmi=on|off] [link=on|off] [privilege=level]"); 908 lprintf(LOG_NOTICE, 909 " info [channel number]"); 910 lprintf(LOG_NOTICE, 911 " getciphers <ipmi | sol> [channel]"); 912 lprintf(LOG_NOTICE, 913 ""); 914 lprintf(LOG_NOTICE, 915 "Possible privilege levels are:"); 916 lprintf(LOG_NOTICE, 917 " 1 Callback level"); 918 lprintf(LOG_NOTICE, 919 " 2 User level"); 920 lprintf(LOG_NOTICE, 921 " 3 Operator level"); 922 lprintf(LOG_NOTICE, 923 " 4 Administrator level"); 924 lprintf(LOG_NOTICE, 925 " 5 OEM Proprietary level"); 926 lprintf(LOG_NOTICE, 927 " 15 No access"); 928 } 929