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