1 /* 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 <string.h> 35 #include <stdio.h> 36 #include <sys/types.h> 37 #include <sys/select.h> 38 #include <sys/time.h> 39 #include <signal.h> 40 #include <unistd.h> 41 42 #include <ipmitool/helper.h> 43 #include <ipmitool/log.h> 44 #include <ipmitool/ipmi.h> 45 #include <ipmitool/ipmi_intf.h> 46 #include <ipmitool/ipmi_user.h> 47 #include <ipmitool/ipmi_constants.h> 48 #include <ipmitool/ipmi_strings.h> 49 #include <ipmitool/bswap.h> 50 51 52 extern int verbose; 53 extern int csv_output; 54 55 56 #define IPMI_PASSWORD_DISABLE_USER 0x00 57 #define IPMI_PASSWORD_ENABLE_USER 0x01 58 #define IPMI_PASSWORD_SET_PASSWORD 0x02 59 #define IPMI_PASSWORD_TEST_PASSWORD 0x03 60 61 /* 62 * ipmi_get_user_access 63 * 64 * param intf [in] 65 * param channel_number [in] 66 * param user_id [in] 67 * param user_access [out] 68 * 69 * return 0 on succes 70 * 1 on failure 71 */ 72 static int 73 ipmi_get_user_access( 74 struct ipmi_intf *intf, 75 uint8_t channel_number, 76 uint8_t user_id, 77 struct user_access_rsp *user_access) 78 { 79 struct ipmi_rs * rsp; 80 struct ipmi_rq req; 81 uint8_t msg_data[2]; 82 83 memset(&req, 0, sizeof(req)); 84 req.msg.netfn = IPMI_NETFN_APP; /* 0x06 */ 85 req.msg.cmd = IPMI_GET_USER_ACCESS; /* 0x44 */ 86 req.msg.data = msg_data; 87 req.msg.data_len = 2; 88 89 90 /* The channel number will remain constant throughout this function */ 91 msg_data[0] = channel_number; 92 msg_data[1] = user_id; 93 94 rsp = intf->sendrecv(intf, &req); 95 96 if (rsp == NULL) { 97 lprintf(LOG_ERR, "Get User Access command failed " 98 "(channel %d, user %d)", channel_number, user_id); 99 return -1; 100 } 101 if (rsp->ccode > 0) { 102 lprintf(LOG_ERR, "Get User Access command failed " 103 "(channel %d, user %d): %s", channel_number, user_id, 104 val2str(rsp->ccode, completion_code_vals)); 105 return -1; 106 } 107 108 memcpy(user_access, 109 rsp->data, 110 sizeof(struct user_access_rsp)); 111 112 return 0; 113 } 114 115 116 117 /* 118 * ipmi_get_user_name 119 * 120 * param intf [in] 121 * param channel_number [in] 122 * param user_id [in] 123 * param user_name [out] 124 * 125 * return 0 on succes 126 * 1 on failure 127 */ 128 static int 129 ipmi_get_user_name( 130 struct ipmi_intf *intf, 131 uint8_t user_id, 132 char *user_name) 133 { 134 struct ipmi_rs * rsp; 135 struct ipmi_rq req; 136 uint8_t msg_data[1]; 137 138 memset(user_name, 0, 17); 139 140 memset(&req, 0, sizeof(req)); 141 req.msg.netfn = IPMI_NETFN_APP; /* 0x06 */ 142 req.msg.cmd = IPMI_GET_USER_NAME; /* 0x45 */ 143 req.msg.data = msg_data; 144 req.msg.data_len = 1; 145 146 msg_data[0] = user_id; 147 148 rsp = intf->sendrecv(intf, &req); 149 150 if (rsp == NULL) { 151 lprintf(LOG_ERR, "Get User Name command failed (user %d)", 152 user_id); 153 return -1; 154 } 155 if (rsp->ccode > 0) { 156 if (rsp->ccode == 0xcc) 157 return 0; 158 lprintf(LOG_ERR, "Get User Name command failed (user %d): %s", 159 user_id, val2str(rsp->ccode, completion_code_vals)); 160 return -1; 161 } 162 163 memcpy(user_name, rsp->data, 16); 164 165 return 0; 166 } 167 168 169 170 171 static void 172 dump_user_access( 173 uint8_t user_id, 174 const char * user_name, 175 struct user_access_rsp * user_access) 176 { 177 static int printed_header = 0; 178 179 if (! printed_header) 180 { 181 printf("ID Name Callin Link Auth IPMI Msg " 182 "Channel Priv Limit\n"); 183 printed_header = 1; 184 } 185 186 printf("%-4d%-17s%-8s%-11s%-11s%-s\n", 187 user_id, 188 user_name, 189 user_access->no_callin_access? "false": "true ", 190 user_access->link_auth_access? "true ": "false", 191 user_access->ipmi_messaging_access? "true ": "false", 192 val2str(user_access->channel_privilege_limit, 193 ipmi_privlvl_vals)); 194 } 195 196 197 198 static void 199 dump_user_access_csv( 200 uint8_t user_id, 201 const char *user_name, 202 struct user_access_rsp *user_access) 203 { 204 printf("%d,%s,%s,%s,%s,%s\n", 205 user_id, 206 user_name, 207 user_access->no_callin_access? "false": "true", 208 user_access->link_auth_access? "true": "false", 209 user_access->ipmi_messaging_access? "true": "false", 210 val2str(user_access->channel_privilege_limit, 211 ipmi_privlvl_vals)); 212 } 213 214 static int 215 ipmi_print_user_list( 216 struct ipmi_intf *intf, 217 uint8_t channel_number) 218 { 219 /* This is where you were! */ 220 char user_name[17]; 221 struct user_access_rsp user_access; 222 uint8_t current_user_id = 1; 223 224 225 do 226 { 227 if (ipmi_get_user_access(intf, 228 channel_number, 229 current_user_id, 230 &user_access)) 231 return -1; 232 233 234 if (ipmi_get_user_name(intf, 235 current_user_id, 236 user_name)) 237 return -1; 238 239 if ((current_user_id == 0) || 240 user_access.link_auth_access || 241 user_access.ipmi_messaging_access || 242 strcmp("", user_name)) 243 { 244 if (csv_output) 245 dump_user_access_csv(current_user_id, 246 user_name, &user_access); 247 else 248 dump_user_access(current_user_id, 249 user_name, 250 &user_access); 251 } 252 253 254 ++current_user_id; 255 } while((current_user_id <= user_access.maximum_ids) && 256 (current_user_id <= IPMI_UID_MAX)); /* Absolute maximum allowed by spec */ 257 258 259 return 0; 260 } 261 262 263 264 static int 265 ipmi_print_user_summary( 266 struct ipmi_intf * intf, 267 uint8_t channel_number) 268 { 269 struct user_access_rsp user_access; 270 271 if (ipmi_get_user_access(intf, 272 channel_number, 273 1, 274 &user_access)) 275 return -1; 276 277 if (csv_output) 278 { 279 printf("%d,%d,%d\n", 280 user_access.maximum_ids, 281 user_access.enabled_user_count, 282 user_access.fixed_name_count); 283 } 284 else 285 { 286 printf("Maximum IDs : %d\n", 287 user_access.maximum_ids); 288 printf("Enabled User Count : %d\n", 289 user_access.enabled_user_count); 290 printf("Fixed Name Count : %d\n", 291 user_access.fixed_name_count); 292 } 293 294 return 0; 295 } 296 297 298 299 /* 300 * ipmi_user_set_username 301 */ 302 static int 303 ipmi_user_set_username( 304 struct ipmi_intf *intf, 305 uint8_t user_id, 306 const char *name) 307 { 308 struct ipmi_rs * rsp; 309 struct ipmi_rq req; 310 uint8_t msg_data[17]; 311 312 /* 313 * Ensure there is space for the name in the request message buffer 314 */ 315 if (strlen(name) >= sizeof(msg_data)) { 316 return -1; 317 } 318 319 memset(&req, 0, sizeof(req)); 320 req.msg.netfn = IPMI_NETFN_APP; /* 0x06 */ 321 req.msg.cmd = IPMI_SET_USER_NAME; /* 0x45 */ 322 req.msg.data = msg_data; 323 req.msg.data_len = sizeof(msg_data); 324 memset(msg_data, 0, sizeof(msg_data)); 325 326 /* The channel number will remain constant throughout this function */ 327 msg_data[0] = user_id; 328 strncpy((char *)(msg_data + 1), name, strlen(name)); 329 330 rsp = intf->sendrecv(intf, &req); 331 332 if (rsp == NULL) { 333 lprintf(LOG_ERR, "Set User Name command failed (user %d, name %s)", 334 user_id, name); 335 return -1; 336 } 337 if (rsp->ccode > 0) { 338 lprintf(LOG_ERR, "Set User Name command failed (user %d, name %s): %s", 339 user_id, name, val2str(rsp->ccode, completion_code_vals)); 340 return -1; 341 } 342 343 return 0; 344 } 345 346 static int 347 ipmi_user_set_userpriv( 348 struct ipmi_intf *intf, 349 uint8_t channel, 350 uint8_t user_id, 351 const unsigned char privLevel) 352 { 353 struct ipmi_rs *rsp; 354 struct ipmi_rq req; 355 uint8_t msg_data[4] = {0, 0, 0, 0}; 356 357 memset(&req, 0, sizeof(req)); 358 req.msg.netfn = IPMI_NETFN_APP; /* 0x06 */ 359 req.msg.cmd = IPMI_SET_USER_ACCESS; /* 0x43 */ 360 req.msg.data = msg_data; 361 req.msg.data_len = 4; 362 363 /* The channel number will remain constant throughout this function */ 364 msg_data[0] = (channel & 0x0f); 365 msg_data[1] = (user_id & 0x3f); 366 msg_data[2] = (privLevel & 0x0f); 367 msg_data[3] = 0; 368 369 rsp = intf->sendrecv(intf, &req); 370 371 if (rsp == NULL) 372 { 373 lprintf(LOG_ERR, "Set Privilege Level command failed (user %d)", 374 user_id); 375 return -1; 376 } 377 if (rsp->ccode > 0) 378 { 379 lprintf(LOG_ERR, "Set Privilege Level command failed (user %d): %s", 380 user_id, val2str(rsp->ccode, completion_code_vals)); 381 return -1; 382 } 383 384 return 0; 385 } 386 387 /* 388 * ipmi_user_set_password 389 * 390 * This function is responsible for 4 things 391 * Enabling/Disabling users 392 * Setting/Testing passwords 393 */ 394 static int 395 ipmi_user_set_password( 396 struct ipmi_intf * intf, 397 uint8_t user_id, 398 uint8_t operation, 399 const char *password, 400 int is_twenty_byte_password) 401 { 402 struct ipmi_rs * rsp; 403 struct ipmi_rq req; 404 uint8_t msg_data[22]; 405 406 int password_length = (is_twenty_byte_password? 20 : 16); 407 408 memset(&req, 0, sizeof(req)); 409 req.msg.netfn = IPMI_NETFN_APP; /* 0x06 */ 410 req.msg.cmd = IPMI_SET_USER_PASSWORD; /* 0x47 */ 411 req.msg.data = msg_data; 412 req.msg.data_len = password_length + 2; 413 414 415 /* The channel number will remain constant throughout this function */ 416 msg_data[0] = user_id; 417 418 if (is_twenty_byte_password) 419 msg_data[0] |= 0x80; 420 421 msg_data[1] = operation; 422 423 memset(msg_data + 2, 0, password_length); 424 425 if (password != NULL) 426 strncpy((char *)(msg_data + 2), password, password_length); 427 428 rsp = intf->sendrecv(intf, &req); 429 430 if (rsp == NULL) { 431 lprintf(LOG_ERR, "Set User Password command failed (user %d)", 432 user_id); 433 return -1; 434 } 435 if (rsp->ccode > 0) { 436 lprintf(LOG_ERR, "Set User Password command failed (user %d): %s", 437 user_id, val2str(rsp->ccode, completion_code_vals)); 438 return rsp->ccode; 439 } 440 441 return 0; 442 } 443 444 445 446 /* 447 * ipmi_user_test_password 448 * 449 * Call ipmi_user_set_password, and interpret the result 450 */ 451 static int 452 ipmi_user_test_password( 453 struct ipmi_intf * intf, 454 uint8_t user_id, 455 const char * password, 456 int is_twenty_byte_password) 457 { 458 int ret; 459 460 ret = ipmi_user_set_password(intf, 461 user_id, 462 IPMI_PASSWORD_TEST_PASSWORD, 463 password, 464 is_twenty_byte_password); 465 466 switch (ret) { 467 case 0: 468 printf("Success\n"); 469 break; 470 case 0x80: 471 printf("Failure: password incorrect\n"); 472 break; 473 case 0x81: 474 printf("Failure: wrong password size\n"); 475 break; 476 default: 477 printf("Unknown error\n"); 478 } 479 480 return ((ret == 0) ? 0 : -1); 481 } 482 483 484 /* 485 * print_user_usage 486 */ 487 static void 488 print_user_usage(void) 489 { 490 lprintf(LOG_NOTICE, 491 "User Commands:"); 492 lprintf(LOG_NOTICE, 493 " summary [<channel number>]"); 494 lprintf(LOG_NOTICE, 495 " list [<channel number>]"); 496 lprintf(LOG_NOTICE, 497 " set name <user id> <username>"); 498 lprintf(LOG_NOTICE, 499 " set password <user id> [<password> <16|20>]"); 500 lprintf(LOG_NOTICE, 501 " disable <user id>"); 502 lprintf(LOG_NOTICE, 503 " enable <user id>"); 504 lprintf(LOG_NOTICE, 505 " priv <user id> <privilege level> [<channel number>]"); 506 lprintf(LOG_NOTICE, 507 " Privilege levels:"); 508 lprintf(LOG_NOTICE, 509 " * 0x1 - Callback"); 510 lprintf(LOG_NOTICE, 511 " * 0x2 - User"); 512 lprintf(LOG_NOTICE, 513 " * 0x3 - Operator"); 514 lprintf(LOG_NOTICE, 515 " * 0x4 - Administrator"); 516 lprintf(LOG_NOTICE, 517 " * 0x5 - OEM Proprietary"); 518 lprintf(LOG_NOTICE, 519 " * 0xF - No Access"); 520 lprintf(LOG_NOTICE, ""); 521 lprintf(LOG_NOTICE, 522 " test <user id> <16|20> [<password]>"); 523 lprintf(LOG_NOTICE, ""); 524 } 525 526 527 const char * 528 ipmi_user_build_password_prompt(uint8_t user_id) 529 { 530 static char prompt[128]; 531 memset(prompt, 0, 128); 532 snprintf(prompt, 128, "Password for user %d: ", user_id); 533 return prompt; 534 } 535 536 /* ask_password - ask user for password 537 * 538 * @user_id: User ID which will be built-in into text 539 * 540 * @returns pointer to char with password 541 */ 542 char * 543 ask_password(uint8_t user_id) 544 { 545 const char *password_prompt = 546 ipmi_user_build_password_prompt(user_id); 547 # ifdef HAVE_GETPASSPHRASE 548 return getpassphrase(password_prompt); 549 # else 550 return (char*)getpass(password_prompt); 551 # endif 552 } 553 554 int 555 ipmi_user_summary(struct ipmi_intf *intf, int argc, char **argv) 556 { 557 /* Summary*/ 558 uint8_t channel; 559 if (argc == 1) { 560 channel = 0x0E; /* Ask about the current channel */ 561 } else if (argc == 2) { 562 if (is_ipmi_channel_num(argv[1], &channel) != 0) { 563 return (-1); 564 } 565 } else { 566 print_user_usage(); 567 return (-1); 568 } 569 return ipmi_print_user_summary(intf, channel); 570 } 571 572 int 573 ipmi_user_list(struct ipmi_intf *intf, int argc, char **argv) 574 { 575 /* List */ 576 uint8_t channel; 577 if (argc == 1) { 578 channel = 0x0E; /* Ask about the current channel */ 579 } else if (argc == 2) { 580 if (is_ipmi_channel_num(argv[1], &channel) != 0) { 581 return (-1); 582 } 583 } else { 584 print_user_usage(); 585 return (-1); 586 } 587 return ipmi_print_user_list(intf, channel); 588 } 589 590 int 591 ipmi_user_test(struct ipmi_intf *intf, int argc, char **argv) 592 { 593 /* Test */ 594 char *password = NULL; 595 int password_length = 0; 596 uint8_t user_id = 0; 597 /* a little irritating, isn't it */ 598 if (argc != 3 && argc != 4) { 599 print_user_usage(); 600 return (-1); 601 } 602 if (is_ipmi_user_id(argv[1], &user_id)) { 603 return (-1); 604 } 605 if (str2int(argv[2], &password_length) != 0 606 || (password_length != 16 && password_length != 20)) { 607 lprintf(LOG_ERR, 608 "Given password length '%s' is invalid.", 609 argv[2]); 610 lprintf(LOG_ERR, "Expected value is either 16 or 20."); 611 return (-1); 612 } 613 if (argc == 3) { 614 /* We need to prompt for a password */ 615 password = ask_password(user_id); 616 if (password == NULL) { 617 lprintf(LOG_ERR, "ipmitool: malloc failure"); 618 return (-1); 619 } 620 } else { 621 password = argv[3]; 622 } 623 return ipmi_user_test_password(intf, 624 user_id, 625 password, 626 password_length == 20); 627 } 628 629 int 630 ipmi_user_priv(struct ipmi_intf *intf, int argc, char **argv) 631 { 632 uint8_t user_id; 633 uint8_t priv_level; 634 uint8_t channel = 0x0e; /* Use channel running on */ 635 636 if (argc != 3 && argc != 4) { 637 print_user_usage(); 638 return (-1); 639 } 640 if (argc == 4) { 641 if (is_ipmi_channel_num(argv[3], &channel) != 0) { 642 return (-1); 643 } 644 channel = (channel & 0x0f); 645 } 646 if (is_ipmi_user_priv_limit(argv[2], &priv_level) != 0 647 && is_ipmi_user_id(argv[1], &user_id)) { 648 return (-1); 649 } 650 priv_level = (priv_level & 0x0f); 651 return ipmi_user_set_userpriv(intf,channel,user_id,priv_level); 652 } 653 654 int 655 ipmi_user_mod(struct ipmi_intf *intf, int argc, char **argv) 656 { 657 /* Disable / Enable */ 658 uint8_t user_id; 659 uint8_t operation; 660 char null_password[16]; /* Not used, but required */ 661 662 if (argc != 2) { 663 print_user_usage(); 664 return (-1); 665 } 666 if (is_ipmi_user_id(argv[1], &user_id)) { 667 return (-1); 668 } 669 memset(null_password, 0, sizeof(null_password)); 670 operation = (strncmp(argv[0], "disable", 7) == 0) ? 671 IPMI_PASSWORD_DISABLE_USER : IPMI_PASSWORD_ENABLE_USER; 672 673 /* Last parameter is ignored */ 674 return ipmi_user_set_password(intf, user_id, operation, null_password, 0); 675 } 676 677 int 678 ipmi_user_password(struct ipmi_intf *intf, int argc, char **argv) 679 { 680 char *password = NULL; 681 uint8_t password_type = 16; 682 uint8_t user_id = 0; 683 if (is_ipmi_user_id(argv[2], &user_id)) { 684 return (-1); 685 } 686 687 if (argc == 3) { 688 /* We need to prompt for a password */ 689 char *tmp; 690 password = ask_password(user_id); 691 if (password == NULL) { 692 lprintf(LOG_ERR, "ipmitool: malloc failure"); 693 return (-1); 694 } 695 tmp = ask_password(user_id); 696 if (tmp == NULL) { 697 lprintf(LOG_ERR, "ipmitool: malloc failure"); 698 return (-1); 699 } 700 if (strlen(password) != strlen(tmp) 701 || strncmp(password, tmp, strlen(tmp))) { 702 lprintf(LOG_ERR, "Passwords do not match."); 703 return (-1); 704 } 705 } else { 706 password = argv[3]; 707 if (argc > 4) { 708 if ((str2uchar(argv[4], &password_type) != 0) 709 || (password_type != 16 && password_type != 20)) { 710 lprintf(LOG_ERR, "Invalid password length '%s'", argv[4]); 711 return (-1); 712 } 713 } else { 714 password_type = 16; 715 } 716 } 717 718 if (password == NULL) { 719 lprintf(LOG_ERR, "Unable to parse password argument."); 720 return (-1); 721 } else if (strlen(password) > 20) { 722 lprintf(LOG_ERR, "Password is too long (> 20 bytes)"); 723 return (-1); 724 } 725 726 return ipmi_user_set_password(intf, 727 user_id, 728 IPMI_PASSWORD_SET_PASSWORD, 729 password, 730 password_type > 16); 731 } 732 733 int 734 ipmi_user_name(struct ipmi_intf *intf, int argc, char **argv) 735 { 736 /* Set Name */ 737 uint8_t user_id = 0; 738 if (argc != 4) { 739 print_user_usage(); 740 return (-1); 741 } 742 if (is_ipmi_user_id(argv[2], &user_id)) { 743 return (-1); 744 } 745 if (strlen(argv[3]) > 16) { 746 lprintf(LOG_ERR, "Username is too long (> 16 bytes)"); 747 return (-1); 748 } 749 750 return ipmi_user_set_username(intf, user_id, argv[3]); 751 } 752 753 /* 754 * ipmi_user_main 755 * 756 * Upon entry to this function argv should contain our arguments 757 * specific to this subcommand 758 */ 759 int 760 ipmi_user_main(struct ipmi_intf *intf, int argc, char **argv) 761 { 762 if (argc == 0) { 763 lprintf(LOG_ERR, "Not enough parameters given."); 764 print_user_usage(); 765 return (-1); 766 } 767 if (strncmp(argv[0], "help", 4) == 0) { 768 /* Help */ 769 print_user_usage(); 770 return 0; 771 } else if (strncmp(argv[0], "summary", 7) == 0) { 772 return ipmi_user_summary(intf, argc, argv); 773 } else if (strncmp(argv[0], "list", 4) == 0) { 774 return ipmi_user_list(intf, argc, argv); 775 } else if (strncmp(argv[0], "test", 4) == 0) { 776 return ipmi_user_test(intf, argc, argv); 777 } else if (strncmp(argv[0], "set", 3) == 0) { 778 /* Set */ 779 if ((argc >= 3) 780 && (strncmp("password", argv[1], 8) == 0)) { 781 return ipmi_user_password(intf, argc, argv); 782 } else if ((argc >= 2) 783 && (strncmp("name", argv[1], 4) == 0)) { 784 return ipmi_user_name(intf, argc, argv); 785 } else { 786 print_user_usage(); 787 return (-1); 788 } 789 } else if (strncmp(argv[0], "priv", 4) == 0) { 790 return ipmi_user_priv(intf, argc, argv); 791 } else if ((strncmp(argv[0], "disable", 7) == 0) 792 || (strncmp(argv[0], "enable", 6) == 0)) { 793 return ipmi_user_mod(intf, argc, argv); 794 } else { 795 lprintf(LOG_ERR, "Invalid user command: '%s'\n", argv[0]); 796 print_user_usage(); 797 return (-1); 798 } 799 } 800