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