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 /* ipmi_print_user_summary - print User statistics for given channel 384 * 385 * @intf - IPMI interface 386 * @channel_number - channel number 387 * 388 * returns - 0 on success, (-1) on error 389 */ 390 static int 391 ipmi_print_user_summary(struct ipmi_intf *intf, uint8_t channel_number) 392 { 393 struct user_access_t user_access = {0}; 394 int ccode = 0; 395 user_access.channel = channel_number; 396 user_access.user_id = 1; 397 ccode = _ipmi_get_user_access(intf, &user_access); 398 if (eval_ccode(ccode) != 0) { 399 return (-1); 400 } 401 if (csv_output) { 402 printf("%" PRIu8 ",%" PRIu8 ",%" PRIu8 "\n", 403 user_access.max_user_ids, 404 user_access.enabled_user_ids, 405 user_access.fixed_user_ids); 406 } else { 407 printf("Maximum IDs : %" PRIu8 "\n", 408 user_access.max_user_ids); 409 printf("Enabled User Count : %" PRIu8 "\n", 410 user_access.enabled_user_ids); 411 printf("Fixed Name Count : %" PRIu8 "\n", 412 user_access.fixed_user_ids); 413 } 414 return 0; 415 } 416 417 /* 418 * ipmi_user_set_username 419 */ 420 static int 421 ipmi_user_set_username( 422 struct ipmi_intf *intf, 423 uint8_t user_id, 424 const char *name) 425 { 426 struct ipmi_rs * rsp; 427 struct ipmi_rq req; 428 uint8_t msg_data[17]; 429 430 /* 431 * Ensure there is space for the name in the request message buffer 432 */ 433 if (strlen(name) >= sizeof(msg_data)) { 434 return -1; 435 } 436 437 memset(&req, 0, sizeof(req)); 438 req.msg.netfn = IPMI_NETFN_APP; /* 0x06 */ 439 req.msg.cmd = IPMI_SET_USER_NAME; /* 0x45 */ 440 req.msg.data = msg_data; 441 req.msg.data_len = sizeof(msg_data); 442 memset(msg_data, 0, sizeof(msg_data)); 443 444 /* The channel number will remain constant throughout this function */ 445 msg_data[0] = user_id; 446 strncpy((char *)(msg_data + 1), name, strlen(name)); 447 448 rsp = intf->sendrecv(intf, &req); 449 450 if (rsp == NULL) { 451 lprintf(LOG_ERR, "Set User Name command failed (user %d, name %s)", 452 user_id, name); 453 return -1; 454 } 455 if (rsp->ccode > 0) { 456 lprintf(LOG_ERR, "Set User Name command failed (user %d, name %s): %s", 457 user_id, name, val2str(rsp->ccode, completion_code_vals)); 458 return -1; 459 } 460 461 return 0; 462 } 463 464 static int 465 ipmi_user_set_userpriv( 466 struct ipmi_intf *intf, 467 uint8_t channel, 468 uint8_t user_id, 469 const unsigned char privLevel) 470 { 471 struct ipmi_rs *rsp; 472 struct ipmi_rq req; 473 uint8_t msg_data[4] = {0, 0, 0, 0}; 474 475 memset(&req, 0, sizeof(req)); 476 req.msg.netfn = IPMI_NETFN_APP; /* 0x06 */ 477 req.msg.cmd = IPMI_SET_USER_ACCESS; /* 0x43 */ 478 req.msg.data = msg_data; 479 req.msg.data_len = 4; 480 481 /* The channel number will remain constant throughout this function */ 482 msg_data[0] = (channel & 0x0f); 483 msg_data[1] = (user_id & 0x3f); 484 msg_data[2] = (privLevel & 0x0f); 485 msg_data[3] = 0; 486 487 rsp = intf->sendrecv(intf, &req); 488 489 if (rsp == NULL) 490 { 491 lprintf(LOG_ERR, "Set Privilege Level command failed (user %d)", 492 user_id); 493 return -1; 494 } 495 if (rsp->ccode > 0) 496 { 497 lprintf(LOG_ERR, "Set Privilege Level command failed (user %d): %s", 498 user_id, val2str(rsp->ccode, completion_code_vals)); 499 return -1; 500 } 501 502 return 0; 503 } 504 505 /* 506 * ipmi_user_set_password 507 * 508 * This function is responsible for 4 things 509 * Enabling/Disabling users 510 * Setting/Testing passwords 511 */ 512 static int 513 ipmi_user_set_password( 514 struct ipmi_intf * intf, 515 uint8_t user_id, 516 uint8_t operation, 517 const char *password, 518 int is_twenty_byte_password) 519 { 520 struct ipmi_rs * rsp; 521 struct ipmi_rq req; 522 uint8_t msg_data[22]; 523 524 int password_length = (is_twenty_byte_password? 20 : 16); 525 526 memset(&req, 0, sizeof(req)); 527 req.msg.netfn = IPMI_NETFN_APP; /* 0x06 */ 528 req.msg.cmd = IPMI_SET_USER_PASSWORD; /* 0x47 */ 529 req.msg.data = msg_data; 530 req.msg.data_len = password_length + 2; 531 532 533 /* The channel number will remain constant throughout this function */ 534 msg_data[0] = user_id; 535 536 if (is_twenty_byte_password) 537 msg_data[0] |= 0x80; 538 539 msg_data[1] = operation; 540 541 memset(msg_data + 2, 0, password_length); 542 543 if (password != NULL) 544 strncpy((char *)(msg_data + 2), password, password_length); 545 546 rsp = intf->sendrecv(intf, &req); 547 548 if (rsp == NULL) { 549 lprintf(LOG_ERR, "Set User Password command failed (user %d)", 550 user_id); 551 return -1; 552 } 553 if (rsp->ccode > 0) { 554 lprintf(LOG_ERR, "Set User Password command failed (user %d): %s", 555 user_id, val2str(rsp->ccode, completion_code_vals)); 556 return rsp->ccode; 557 } 558 559 return 0; 560 } 561 562 563 564 /* 565 * ipmi_user_test_password 566 * 567 * Call ipmi_user_set_password, and interpret the result 568 */ 569 static int 570 ipmi_user_test_password( 571 struct ipmi_intf * intf, 572 uint8_t user_id, 573 const char * password, 574 int is_twenty_byte_password) 575 { 576 int ret; 577 578 ret = ipmi_user_set_password(intf, 579 user_id, 580 IPMI_PASSWORD_TEST_PASSWORD, 581 password, 582 is_twenty_byte_password); 583 584 switch (ret) { 585 case 0: 586 printf("Success\n"); 587 break; 588 case 0x80: 589 printf("Failure: password incorrect\n"); 590 break; 591 case 0x81: 592 printf("Failure: wrong password size\n"); 593 break; 594 default: 595 printf("Unknown error\n"); 596 } 597 598 return ((ret == 0) ? 0 : -1); 599 } 600 601 602 /* 603 * print_user_usage 604 */ 605 static void 606 print_user_usage(void) 607 { 608 lprintf(LOG_NOTICE, 609 "User Commands:"); 610 lprintf(LOG_NOTICE, 611 " summary [<channel number>]"); 612 lprintf(LOG_NOTICE, 613 " list [<channel number>]"); 614 lprintf(LOG_NOTICE, 615 " set name <user id> <username>"); 616 lprintf(LOG_NOTICE, 617 " set password <user id> [<password> <16|20>]"); 618 lprintf(LOG_NOTICE, 619 " disable <user id>"); 620 lprintf(LOG_NOTICE, 621 " enable <user id>"); 622 lprintf(LOG_NOTICE, 623 " priv <user id> <privilege level> [<channel number>]"); 624 lprintf(LOG_NOTICE, 625 " Privilege levels:"); 626 lprintf(LOG_NOTICE, 627 " * 0x1 - Callback"); 628 lprintf(LOG_NOTICE, 629 " * 0x2 - User"); 630 lprintf(LOG_NOTICE, 631 " * 0x3 - Operator"); 632 lprintf(LOG_NOTICE, 633 " * 0x4 - Administrator"); 634 lprintf(LOG_NOTICE, 635 " * 0x5 - OEM Proprietary"); 636 lprintf(LOG_NOTICE, 637 " * 0xF - No Access"); 638 lprintf(LOG_NOTICE, ""); 639 lprintf(LOG_NOTICE, 640 " test <user id> <16|20> [<password]>"); 641 lprintf(LOG_NOTICE, ""); 642 } 643 644 645 const char * 646 ipmi_user_build_password_prompt(uint8_t user_id) 647 { 648 static char prompt[128]; 649 memset(prompt, 0, 128); 650 snprintf(prompt, 128, "Password for user %d: ", user_id); 651 return prompt; 652 } 653 654 /* ask_password - ask user for password 655 * 656 * @user_id: User ID which will be built-in into text 657 * 658 * @returns pointer to char with password 659 */ 660 char * 661 ask_password(uint8_t user_id) 662 { 663 const char *password_prompt = 664 ipmi_user_build_password_prompt(user_id); 665 # ifdef HAVE_GETPASSPHRASE 666 return getpassphrase(password_prompt); 667 # else 668 return (char*)getpass(password_prompt); 669 # endif 670 } 671 672 int 673 ipmi_user_summary(struct ipmi_intf *intf, int argc, char **argv) 674 { 675 /* Summary*/ 676 uint8_t channel; 677 if (argc == 1) { 678 channel = 0x0E; /* Ask about the current channel */ 679 } else if (argc == 2) { 680 if (is_ipmi_channel_num(argv[1], &channel) != 0) { 681 return (-1); 682 } 683 } else { 684 print_user_usage(); 685 return (-1); 686 } 687 return ipmi_print_user_summary(intf, channel); 688 } 689 690 int 691 ipmi_user_list(struct ipmi_intf *intf, int argc, char **argv) 692 { 693 /* List */ 694 uint8_t channel; 695 if (argc == 1) { 696 channel = 0x0E; /* Ask about the current channel */ 697 } else if (argc == 2) { 698 if (is_ipmi_channel_num(argv[1], &channel) != 0) { 699 return (-1); 700 } 701 } else { 702 print_user_usage(); 703 return (-1); 704 } 705 return ipmi_print_user_list(intf, channel); 706 } 707 708 int 709 ipmi_user_test(struct ipmi_intf *intf, int argc, char **argv) 710 { 711 /* Test */ 712 char *password = NULL; 713 int password_length = 0; 714 uint8_t user_id = 0; 715 /* a little irritating, isn't it */ 716 if (argc != 3 && argc != 4) { 717 print_user_usage(); 718 return (-1); 719 } 720 if (is_ipmi_user_id(argv[1], &user_id)) { 721 return (-1); 722 } 723 if (str2int(argv[2], &password_length) != 0 724 || (password_length != 16 && password_length != 20)) { 725 lprintf(LOG_ERR, 726 "Given password length '%s' is invalid.", 727 argv[2]); 728 lprintf(LOG_ERR, "Expected value is either 16 or 20."); 729 return (-1); 730 } 731 if (argc == 3) { 732 /* We need to prompt for a password */ 733 password = ask_password(user_id); 734 if (password == NULL) { 735 lprintf(LOG_ERR, "ipmitool: malloc failure"); 736 return (-1); 737 } 738 } else { 739 password = argv[3]; 740 } 741 return ipmi_user_test_password(intf, 742 user_id, 743 password, 744 password_length == 20); 745 } 746 747 int 748 ipmi_user_priv(struct ipmi_intf *intf, int argc, char **argv) 749 { 750 uint8_t channel = 0x0e; /* Use channel running on */ 751 uint8_t priv_level = 0; 752 uint8_t user_id = 0; 753 754 if (argc != 3 && argc != 4) { 755 print_user_usage(); 756 return (-1); 757 } 758 if (argc == 4) { 759 if (is_ipmi_channel_num(argv[3], &channel) != 0) { 760 return (-1); 761 } 762 channel = (channel & 0x0f); 763 } 764 if (is_ipmi_user_priv_limit(argv[2], &priv_level) != 0 765 || is_ipmi_user_id(argv[1], &user_id) != 0) { 766 return (-1); 767 } 768 priv_level = (priv_level & 0x0f); 769 return ipmi_user_set_userpriv(intf,channel,user_id,priv_level); 770 } 771 772 int 773 ipmi_user_mod(struct ipmi_intf *intf, int argc, char **argv) 774 { 775 /* Disable / Enable */ 776 uint8_t user_id; 777 uint8_t operation; 778 char null_password[16]; /* Not used, but required */ 779 780 if (argc != 2) { 781 print_user_usage(); 782 return (-1); 783 } 784 if (is_ipmi_user_id(argv[1], &user_id)) { 785 return (-1); 786 } 787 memset(null_password, 0, sizeof(null_password)); 788 operation = (strncmp(argv[0], "disable", 7) == 0) ? 789 IPMI_PASSWORD_DISABLE_USER : IPMI_PASSWORD_ENABLE_USER; 790 791 /* Last parameter is ignored */ 792 return ipmi_user_set_password(intf, user_id, operation, null_password, 0); 793 } 794 795 int 796 ipmi_user_password(struct ipmi_intf *intf, int argc, char **argv) 797 { 798 char *password = NULL; 799 uint8_t password_type = 16; 800 uint8_t user_id = 0; 801 if (is_ipmi_user_id(argv[2], &user_id)) { 802 return (-1); 803 } 804 805 if (argc == 3) { 806 /* We need to prompt for a password */ 807 char *tmp; 808 password = ask_password(user_id); 809 if (password == NULL) { 810 lprintf(LOG_ERR, "ipmitool: malloc failure"); 811 return (-1); 812 } 813 tmp = ask_password(user_id); 814 if (tmp == NULL) { 815 lprintf(LOG_ERR, "ipmitool: malloc failure"); 816 return (-1); 817 } 818 if (strlen(password) != strlen(tmp) 819 || strncmp(password, tmp, strlen(tmp))) { 820 lprintf(LOG_ERR, "Passwords do not match."); 821 return (-1); 822 } 823 } else { 824 password = argv[3]; 825 if (argc > 4) { 826 if ((str2uchar(argv[4], &password_type) != 0) 827 || (password_type != 16 && password_type != 20)) { 828 lprintf(LOG_ERR, "Invalid password length '%s'", argv[4]); 829 return (-1); 830 } 831 } else { 832 password_type = 16; 833 } 834 } 835 836 if (password == NULL) { 837 lprintf(LOG_ERR, "Unable to parse password argument."); 838 return (-1); 839 } else if (strlen(password) > 20) { 840 lprintf(LOG_ERR, "Password is too long (> 20 bytes)"); 841 return (-1); 842 } 843 844 return ipmi_user_set_password(intf, 845 user_id, 846 IPMI_PASSWORD_SET_PASSWORD, 847 password, 848 password_type > 16); 849 } 850 851 int 852 ipmi_user_name(struct ipmi_intf *intf, int argc, char **argv) 853 { 854 /* Set Name */ 855 uint8_t user_id = 0; 856 if (argc != 4) { 857 print_user_usage(); 858 return (-1); 859 } 860 if (is_ipmi_user_id(argv[2], &user_id)) { 861 return (-1); 862 } 863 if (strlen(argv[3]) > 16) { 864 lprintf(LOG_ERR, "Username is too long (> 16 bytes)"); 865 return (-1); 866 } 867 868 return ipmi_user_set_username(intf, user_id, argv[3]); 869 } 870 871 /* 872 * ipmi_user_main 873 * 874 * Upon entry to this function argv should contain our arguments 875 * specific to this subcommand 876 */ 877 int 878 ipmi_user_main(struct ipmi_intf *intf, int argc, char **argv) 879 { 880 if (argc == 0) { 881 lprintf(LOG_ERR, "Not enough parameters given."); 882 print_user_usage(); 883 return (-1); 884 } 885 if (strncmp(argv[0], "help", 4) == 0) { 886 /* Help */ 887 print_user_usage(); 888 return 0; 889 } else if (strncmp(argv[0], "summary", 7) == 0) { 890 return ipmi_user_summary(intf, argc, argv); 891 } else if (strncmp(argv[0], "list", 4) == 0) { 892 return ipmi_user_list(intf, argc, argv); 893 } else if (strncmp(argv[0], "test", 4) == 0) { 894 return ipmi_user_test(intf, argc, argv); 895 } else if (strncmp(argv[0], "set", 3) == 0) { 896 /* Set */ 897 if ((argc >= 3) 898 && (strncmp("password", argv[1], 8) == 0)) { 899 return ipmi_user_password(intf, argc, argv); 900 } else if ((argc >= 2) 901 && (strncmp("name", argv[1], 4) == 0)) { 902 return ipmi_user_name(intf, argc, argv); 903 } else { 904 print_user_usage(); 905 return (-1); 906 } 907 } else if (strncmp(argv[0], "priv", 4) == 0) { 908 return ipmi_user_priv(intf, argc, argv); 909 } else if ((strncmp(argv[0], "disable", 7) == 0) 910 || (strncmp(argv[0], "enable", 6) == 0)) { 911 return ipmi_user_mod(intf, argc, argv); 912 } else { 913 lprintf(LOG_ERR, "Invalid user command: '%s'\n", argv[0]); 914 print_user_usage(); 915 return (-1); 916 } 917 } 918