1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2002 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* 28 * user.c: support for the scadm useradd, userdel, usershow, userpassword, 29 * userperm options (administration of service processor users) 30 */ 31 32 #include <libintl.h> 33 #include <signal.h> 34 #include <stdio.h> 35 #include <string.h> 36 #include <termios.h> 37 #include <time.h> /* required by librsc.h */ 38 39 #include "librsc.h" 40 #include "adm.h" 41 42 43 static void ADM_Get_Password(char *password); 44 static void ADM_Destroy_Password(char *password); 45 static void max_username(); 46 static void malformed_username(); 47 static void wrong_response(); 48 static void no_user(); 49 static void no_info(); 50 static void userperm_usage(); 51 static void show_header(); 52 static void cleanup(); 53 54 55 /* Globals so that exit routine can clean up echo */ 56 static int echoOff = 0; 57 static struct termios oldOpts; 58 59 typedef union { 60 char DataBuffer[DP_MAX_MSGLEN]; 61 void *DataBuffer_p; 62 } data_buffer_t; 63 64 65 void 66 ADM_Process_useradd(int argc, char *argv[]) 67 { 68 static data_buffer_t dataBuffer; 69 rscp_msg_t Message; 70 struct timespec Timeout; 71 dp_user_adm_t *admMessage; 72 dp_user_adm_r_t *admResponse; 73 char *userName; 74 75 76 if (argc != 3) { 77 (void) fprintf(stderr, "\n%s\n\n", 78 gettext("USAGE: scadm useradd <username>")); 79 exit(-1); 80 } 81 82 ADM_Start(); 83 84 if (strlen(argv[2]) > DP_USER_NAME_SIZE) { 85 max_username(); 86 exit(-1); 87 } 88 89 admMessage = (dp_user_adm_t *)&dataBuffer; 90 userName = (char *)(&((char *)admMessage)[sizeof (dp_user_adm_t)]); 91 admMessage->command = DP_USER_CMD_ADD; 92 (void) strcpy(userName, argv[2]); 93 94 Message.type = DP_USER_ADM; 95 Message.len = sizeof (dp_user_adm_t) + strlen(userName) + 1; 96 Message.data = admMessage; 97 ADM_Send(&Message); 98 99 Timeout.tv_nsec = 0; 100 Timeout.tv_sec = ADM_SEPROM_TIMEOUT; 101 ADM_Recv(&Message, &Timeout, DP_USER_ADM_R, sizeof (dp_user_adm_r_t)); 102 103 admResponse = (dp_user_adm_r_t *)Message.data; 104 if (admResponse->command != DP_USER_CMD_ADD) { 105 wrong_response(); 106 exit(-1); 107 } 108 109 if (admResponse->status == DP_ERR_USER_FULL) { 110 (void) fprintf(stderr, "\n%s\n\n", 111 gettext("scadm: all user slots are full")); 112 exit(-1); 113 } else if (admResponse->status == DP_ERR_USER_THERE) { 114 (void) fprintf(stderr, "\n%s\n\n", 115 gettext("scadm: user already exists")); 116 exit(-1); 117 } else if (admResponse->status == DP_ERR_USER_WARNING) { 118 (void) fprintf(stderr, "\n%s\n\n", 119 gettext("scadm: username did not start with letter\n" 120 " or did not contain lower case letter\n")); 121 exit(-1); 122 } else if (admResponse->status == DP_ERR_USER_BAD) { 123 malformed_username(); 124 exit(-1); 125 } else if (admResponse->status != 0) { 126 (void) fprintf(stderr, "\n%s\n\n", 127 gettext("scadm: couldn't add user")); 128 exit(-1); 129 } 130 131 ADM_Free(&Message); 132 } 133 134 135 void 136 ADM_Process_userdel(int argc, char *argv[]) 137 { 138 static data_buffer_t dataBuffer; 139 rscp_msg_t Message; 140 struct timespec Timeout; 141 dp_user_adm_t *admMessage; 142 dp_user_adm_r_t *admResponse; 143 char *userName; 144 145 146 if (argc != 3) { 147 (void) fprintf(stderr, "\n%s\n\n", 148 gettext("USAGE: scadm userdel <username>")); 149 exit(-1); 150 } 151 152 ADM_Start(); 153 154 if (strlen(argv[2]) > DP_USER_NAME_SIZE) { 155 max_username(); 156 exit(-1); 157 } 158 159 admMessage = (dp_user_adm_t *)&dataBuffer; 160 userName = (char *)(&((char *)admMessage)[sizeof (dp_user_adm_t)]); 161 admMessage->command = DP_USER_CMD_DEL; 162 (void) strcpy(userName, argv[2]); 163 164 Message.type = DP_USER_ADM; 165 Message.len = sizeof (dp_user_adm_t) + strlen(userName) + 1; 166 Message.data = admMessage; 167 ADM_Send(&Message); 168 169 Timeout.tv_nsec = 0; 170 Timeout.tv_sec = ADM_SEPROM_TIMEOUT; 171 ADM_Recv(&Message, &Timeout, DP_USER_ADM_R, sizeof (dp_user_adm_r_t)); 172 173 admResponse = (dp_user_adm_r_t *)Message.data; 174 if (admResponse->command != DP_USER_CMD_DEL) { 175 wrong_response(); 176 exit(-1); 177 } 178 179 if (admResponse->status == DP_ERR_USER_NONE) { 180 no_user(); 181 exit(-1); 182 } else if (admResponse->status == DP_ERR_USER_BAD) { 183 malformed_username(); 184 exit(-1); 185 } else if (admResponse->status != 0) { 186 (void) fprintf(stderr, "\n%s\n\n", 187 gettext("scadm: couldn't delete user")); 188 exit(-1); 189 } 190 191 ADM_Free(&Message); 192 } 193 194 195 void 196 ADM_Process_usershow(int argc, char *argv[]) 197 { 198 static data_buffer_t dataBuffer; 199 rscp_msg_t Message; 200 struct timespec Timeout; 201 dp_user_adm_t *admMessage; 202 dp_user_adm_r_t *admResponse; 203 char *userName; 204 char *permissions; 205 char *passwd; 206 int index; 207 208 209 210 if ((argc != 2) && (argc != 3)) { 211 (void) fprintf(stderr, "\n%s\n\n", 212 gettext("USAGE: scadm usershow [username]")); 213 exit(-1); 214 } 215 216 ADM_Start(); 217 218 if (argc == 3) { 219 admMessage = (dp_user_adm_t *)&dataBuffer; 220 admMessage->command = DP_USER_CMD_SHOW; 221 Message.type = DP_USER_ADM; 222 Message.data = admMessage; 223 224 if (strlen(argv[2]) > DP_USER_NAME_SIZE) { 225 max_username(); 226 exit(-1); 227 } 228 userName = (char *)(&((char *)admMessage)[ 229 sizeof (dp_user_adm_t)]); 230 (void) strcpy(userName, argv[2]); 231 admMessage->parm = DP_USER_SHOW_USERNAME; 232 Message.len = sizeof (dp_user_adm_t) + strlen(userName) + 1; 233 ADM_Send(&Message); 234 235 Timeout.tv_nsec = 0; 236 Timeout.tv_sec = ADM_SEPROM_TIMEOUT; 237 ADM_Recv(&Message, &Timeout, 238 DP_USER_ADM_R, sizeof (dp_user_adm_r_t)); 239 240 admResponse = (dp_user_adm_r_t *)Message.data; 241 if (admResponse->command != DP_USER_CMD_SHOW) { 242 wrong_response(); 243 exit(-1); 244 } 245 246 if (admResponse->status == DP_ERR_USER_NONE) { 247 no_user(); 248 exit(-1); 249 } else if (admResponse->status == DP_ERR_USER_BAD) { 250 malformed_username(); 251 exit(-1); 252 } else if (admResponse->status != 0) { 253 no_info(); 254 exit(-1); 255 } 256 257 userName = &(((char *)admResponse)[ 258 sizeof (dp_user_adm_r_t)]); 259 permissions = &userName[strlen(userName)+1]; 260 passwd = &permissions[strlen(permissions)+1]; 261 show_header(); 262 (void) printf(" %-16s %-15s ", userName, permissions); 263 if (strncmp(passwd, "Assigned", 12) == 0) { 264 (void) printf("%s\n\n", gettext("Assigned")); 265 } else if (strncmp(passwd, "None", 12) == 0) { 266 (void) printf("%s\n\n", gettext("None")); 267 } else { 268 (void) printf("%-12s\n\n", passwd); 269 } 270 ADM_Free(&Message); 271 } else { 272 show_header(); 273 for (index = 1; index <= DP_USER_MAX; index++) { 274 admMessage = (dp_user_adm_t *)&dataBuffer; 275 admMessage->command = DP_USER_CMD_SHOW; 276 admMessage->parm = index; 277 278 Message.type = DP_USER_ADM; 279 Message.data = admMessage; 280 Message.len = sizeof (dp_user_adm_t); 281 ADM_Send(&Message); 282 283 Timeout.tv_nsec = 0; 284 Timeout.tv_sec = ADM_SEPROM_TIMEOUT; 285 ADM_Recv(&Message, &Timeout, 286 DP_USER_ADM_R, sizeof (dp_user_adm_r_t)); 287 288 admResponse = (dp_user_adm_r_t *)Message.data; 289 if (admResponse->command != DP_USER_CMD_SHOW) { 290 wrong_response(); 291 exit(-1); 292 } 293 294 if (admResponse->status == DP_ERR_USER_NONE) { 295 ADM_Free(&Message); 296 continue; 297 } else if (admResponse->status == DP_ERR_USER_BAD) { 298 malformed_username(); 299 exit(-1); 300 } else if (admResponse->status != 0) { 301 no_info(); 302 exit(-1); 303 } 304 305 userName = &(((char *)admResponse)[ 306 sizeof (dp_user_adm_r_t)]); 307 permissions = &userName[strlen(userName)+1]; 308 passwd = &permissions[strlen(permissions)+1]; 309 (void) printf(" %-16s %-15s ", 310 userName, permissions); 311 if (strncmp(passwd, "Assigned", 12) == 0) { 312 (void) printf("%s\n", gettext("Assigned")); 313 } else if (strncmp(passwd, "None", 12) == 0) { 314 (void) printf("%s\n", gettext("None")); 315 } else { 316 (void) printf("%-12s\n", passwd); 317 } 318 319 ADM_Free(&Message); 320 } 321 (void) printf("\n"); 322 } 323 } 324 325 326 void 327 ADM_Process_userpassword(int argc, char *argv[]) 328 { 329 static data_buffer_t dataBuffer; 330 rscp_msg_t Message; 331 struct timespec Timeout; 332 dp_user_adm_t *admMessage; 333 dp_user_adm_r_t *admResponse; 334 char *userName; 335 char *password; 336 int passTry; 337 338 339 /* Try to set password up to 3 times on Malformed password */ 340 passTry = 3; 341 342 if (argc != 3) { 343 (void) fprintf(stderr, "\n%s\n\n", 344 gettext("USAGE: scadm userpassword <username>")); 345 exit(-1); 346 } 347 348 ADM_Start(); 349 350 if (strlen(argv[2]) > DP_USER_NAME_SIZE) { 351 max_username(); 352 exit(-1); 353 } 354 355 admMessage = (dp_user_adm_t *)&dataBuffer; 356 admMessage->command = DP_USER_CMD_PASSWORD; 357 userName = (&((char *)admMessage)[sizeof (dp_user_adm_t)]); 358 (void) strcpy(userName, argv[2]); 359 password = (&((char *)admMessage)[sizeof (dp_user_adm_t) + 360 strlen(userName) + 1]); 361 362 for (;;) { 363 ADM_Get_Password(password); 364 365 Message.type = DP_USER_ADM; 366 Message.len = sizeof (dp_user_adm_t) + strlen(userName) + 367 strlen(password) + 2; 368 Message.data = admMessage; 369 ADM_Send(&Message); 370 371 ADM_Destroy_Password(password); 372 Timeout.tv_nsec = 0; 373 Timeout.tv_sec = ADM_SEPROM_TIMEOUT; 374 ADM_Recv(&Message, &Timeout, 375 DP_USER_ADM_R, sizeof (dp_user_adm_r_t)); 376 377 admResponse = (dp_user_adm_r_t *)Message.data; 378 if (admResponse->command != DP_USER_CMD_PASSWORD) { 379 wrong_response(); 380 exit(-1); 381 } 382 383 if (admResponse->status == DP_ERR_USER_NONE) { 384 no_user(); 385 exit(-1); 386 } else if (admResponse->status == DP_ERR_USER_BAD) { 387 malformed_username(); 388 exit(-1); 389 } else if (admResponse->status == DP_ERR_USER_PASSWD) { 390 (void) fprintf(stderr, "\n%s\n\n", 391 gettext("scadm: malformed password\n" 392 " A valid password is between 6 and 8 " 393 "characters,\n" 394 " has at least two alphabetic characters, " 395 "and at\n" 396 " least one numeric or special character. " 397 "The\n" 398 " password must differ from the user's " 399 "login name\n" 400 " and any reverse or circular shift of that " 401 "login\n" 402 " name.\n")); 403 passTry--; 404 if (passTry > 0) { 405 ADM_Free(&Message); 406 continue; 407 } else 408 exit(-1); 409 } else if (admResponse->status != 0) { 410 (void) fprintf(stderr, "\n%s\n\n", 411 gettext("scadm: couldn't change password")); 412 exit(-1); 413 } 414 415 /* password was changed successfully, get out of while */ 416 break; 417 } 418 419 ADM_Free(&Message); 420 } 421 422 423 void 424 ADM_Process_userperm(int argc, char *argv[]) 425 { 426 static data_buffer_t dataBuffer; 427 rscp_msg_t Message; 428 struct timespec Timeout; 429 dp_user_adm_t *admMessage; 430 dp_user_adm_r_t *admResponse; 431 char *userName; 432 int permissions; 433 int index; 434 435 436 if ((argc != 3) && (argc != 4)) { 437 userperm_usage(); 438 exit(-1); 439 } 440 441 if (argc == 3) { 442 permissions = 0; 443 } else { 444 if ((strlen(argv[3]) > 4) || (strlen(argv[3]) < 1)) { 445 userperm_usage(); 446 exit(-1); 447 } 448 449 permissions = 0; 450 for (index = 0; index < strlen(argv[3]); index++) { 451 if ((argv[3][index] != 'c') && 452 (argv[3][index] != 'C') && 453 (argv[3][index] != 'u') && 454 (argv[3][index] != 'U') && 455 (argv[3][index] != 'a') && 456 (argv[3][index] != 'A') && 457 (argv[3][index] != 'r') && 458 (argv[3][index] != 'R')) { 459 userperm_usage(); 460 exit(-1); 461 } 462 463 if ((argv[3][index] == 'c') || 464 (argv[3][index] == 'C')) { 465 /* See if this field was entered twice */ 466 if ((permissions & DP_USER_PERM_C) != 0) { 467 userperm_usage(); 468 exit(-1); 469 } 470 permissions = permissions | DP_USER_PERM_C; 471 } 472 473 if ((argv[3][index] == 'u') || 474 (argv[3][index] == 'U')) { 475 /* See if this field was enetered twice */ 476 if ((permissions & DP_USER_PERM_U) != 0) { 477 userperm_usage(); 478 exit(-1); 479 } 480 permissions = permissions | DP_USER_PERM_U; 481 } 482 483 if ((argv[3][index] == 'a') || 484 (argv[3][index] == 'A')) { 485 /* See if this field was enetered twice */ 486 if ((permissions & DP_USER_PERM_A) != 0) { 487 userperm_usage(); 488 exit(-1); 489 } 490 permissions = permissions | DP_USER_PERM_A; 491 } 492 493 if ((argv[3][index] == 'r') || 494 (argv[3][index] == 'R')) { 495 /* See if this field was enetered twice */ 496 if ((permissions & DP_USER_PERM_R) != 0) { 497 userperm_usage(); 498 exit(-1); 499 } 500 permissions = permissions | DP_USER_PERM_R; 501 } 502 } 503 } 504 505 ADM_Start(); 506 507 if (strlen(argv[2]) > DP_USER_NAME_SIZE) { 508 max_username(); 509 exit(-1); 510 } 511 512 admMessage = (dp_user_adm_t *)&dataBuffer; 513 admMessage->command = DP_USER_CMD_PERM; 514 admMessage->parm = permissions; 515 userName = (char *)(&((char *)admMessage)[sizeof (dp_user_adm_t)]); 516 (void) strcpy(userName, argv[2]); 517 518 Message.type = DP_USER_ADM; 519 Message.len = sizeof (dp_user_adm_t) + strlen(userName) + 1; 520 Message.data = admMessage; 521 ADM_Send(&Message); 522 523 Timeout.tv_nsec = 0; 524 Timeout.tv_sec = ADM_SEPROM_TIMEOUT; 525 ADM_Recv(&Message, &Timeout, DP_USER_ADM_R, sizeof (dp_user_adm_r_t)); 526 527 admResponse = (dp_user_adm_r_t *)Message.data; 528 if (admResponse->command != DP_USER_CMD_PERM) { 529 wrong_response(); 530 exit(-1); 531 } 532 533 if (admResponse->status == DP_ERR_USER_NONE) { 534 no_user(); 535 exit(-1); 536 } else if (admResponse->status == DP_ERR_USER_BAD) { 537 malformed_username(); 538 exit(-1); 539 } else if (admResponse->status != 0) { 540 (void) fprintf(stderr, "\n%s\n\n", 541 gettext("scadm: couldn't change permissions")); 542 exit(-1); 543 } 544 545 ADM_Free(&Message); 546 } 547 548 549 static void 550 ADM_Get_Password(char *password) 551 { 552 static char pass1[64]; 553 static char pass2[64]; 554 static struct termios newOpts; 555 int passTry; 556 int validPass; 557 558 559 validPass = 0; 560 passTry = 3; 561 562 if (signal(SIGINT, cleanup) == SIG_ERR) { 563 (void) fprintf(stderr, "\n%s\n\n", 564 gettext("scadm: cleanup() registration failed")); 565 exit(-1); 566 } 567 568 echoOff = 1; 569 (void) tcgetattr(0, &oldOpts); 570 newOpts = oldOpts; 571 newOpts.c_lflag &= ~ECHO; 572 (void) tcsetattr(0, TCSANOW, &newOpts); 573 574 while ((passTry > 0) && (validPass == 0)) { 575 passTry = passTry - 1; 576 (void) printf("%s", gettext("Password: ")); 577 (void) scanf("%s", pass1); 578 (void) printf("\n"); 579 (void) fflush(stdin); 580 (void) printf("%s", gettext("Re-enter Password: ")); 581 (void) scanf("%s", pass2); 582 (void) printf("\n"); 583 584 /* Truncate at 8 characters */ 585 pass1[8] = pass2[8] = '\0'; 586 587 if ((strcmp(pass1, pass2) != 0) && (passTry > 0)) { 588 ADM_Destroy_Password(pass1); 589 ADM_Destroy_Password(pass2); 590 (void) fprintf(stderr, "%s\n\n", 591 gettext("Passwords didn't match, try again")); 592 } else if ((strcmp(pass1, pass2) != 0) && (passTry <= 0)) { 593 ADM_Destroy_Password(pass1); 594 ADM_Destroy_Password(pass2); 595 (void) fprintf(stderr, "\n%s\n\n", 596 gettext("scadm: ERROR, passwords didn't match")); 597 (void) tcsetattr(0, TCSANOW, &oldOpts); 598 exit(-1); 599 } else { 600 validPass = 1; 601 } 602 } 603 604 (void) tcsetattr(0, TCSANOW, &oldOpts); 605 echoOff = 0; 606 (void) strcpy(password, pass1); 607 ADM_Destroy_Password(pass1); 608 ADM_Destroy_Password(pass2); 609 } 610 611 612 static void 613 cleanup() 614 { 615 if (echoOff) 616 (void) tcsetattr(0, TCSANOW, &oldOpts); 617 618 exit(-1); 619 } 620 621 622 static void 623 ADM_Destroy_Password(char *password) 624 { 625 int index; 626 627 for (index = 0; index < strlen(password); index++) 628 password[index] = 0x1; 629 } 630 631 632 static void 633 max_username() 634 { 635 (void) fprintf(stderr, 636 gettext("\nscadm: maximum username length is %d\n\n"), 637 DP_USER_NAME_SIZE); 638 } 639 640 641 static void 642 malformed_username() 643 { 644 (void) fprintf(stderr, 645 "\n%s\n\n", gettext("scadm: malformed username")); 646 } 647 648 649 static void 650 wrong_response() 651 { 652 (void) fprintf(stderr, "\n%s\n\n", 653 gettext("scadm: SC returned wrong response")); 654 } 655 656 657 static void 658 no_user() 659 { 660 (void) fprintf(stderr, 661 "\n%s\n\n", gettext("scadm: username does not exist")); 662 } 663 664 665 static void 666 no_info() 667 { 668 (void) fprintf(stderr, "\n%s\n\n", 669 gettext("scadm: couldn't get information on user")); 670 } 671 672 673 static void 674 userperm_usage() 675 { 676 (void) fprintf(stderr, "\n%s\n\n", 677 gettext("USAGE: scadm userperm <username> [cuar]")); 678 } 679 680 681 static void 682 show_header() 683 { 684 int i; 685 int usernLen = strlen(gettext("username")); 686 int permLen = strlen(gettext("permissions")); 687 int pwdLen = strlen(gettext("password")); 688 689 (void) printf("\n"); 690 (void) putchar(' '); 691 (void) printf("%s", gettext("username")); 692 for (i = 0; i < (20 - usernLen); i++) 693 (void) putchar(' '); 694 695 (void) printf("%s", gettext("permissions")); 696 for (i = 0; i < (19 - permLen); i++) 697 (void) putchar(' '); 698 699 (void) printf("%s\n", gettext("password")); 700 701 (void) putchar(' '); 702 for (i = 0; i < usernLen; i++) 703 (void) putchar('-'); 704 for (; i < 20; i++) 705 (void) putchar(' '); 706 707 for (i = 0; i < permLen; i++) 708 (void) putchar('-'); 709 for (; i < 19; i++) 710 (void) putchar(' '); 711 712 for (i = 0; i < pwdLen; i++) 713 (void) putchar('-'); 714 (void) printf("\n"); 715 } 716