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