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