/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2002 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" /* * user.c: support for the scadm useradd, userdel, usershow, userpassword, * userperm options (administration of service processor users) */ #include #include #include #include #include #include /* required by librsc.h */ #include "librsc.h" #include "adm.h" static void ADM_Get_Password(char *password); static void ADM_Destroy_Password(char *password); static void max_username(); static void malformed_username(); static void wrong_response(); static void no_user(); static void no_info(); static void userperm_usage(); static void show_header(); static void cleanup(); /* Globals so that exit routine can clean up echo */ static int echoOff = 0; static struct termios oldOpts; typedef union { char DataBuffer[DP_MAX_MSGLEN]; void *DataBuffer_p; } data_buffer_t; void ADM_Process_useradd(int argc, char *argv[]) { static data_buffer_t dataBuffer; rscp_msg_t Message; struct timespec Timeout; dp_user_adm_t *admMessage; dp_user_adm_r_t *admResponse; char *userName; if (argc != 3) { (void) fprintf(stderr, "\n%s\n\n", gettext("USAGE: scadm useradd ")); exit(-1); } ADM_Start(); if (strlen(argv[2]) > DP_USER_NAME_SIZE) { max_username(); exit(-1); } admMessage = (dp_user_adm_t *)&dataBuffer; userName = (char *)(&((char *)admMessage)[sizeof (dp_user_adm_t)]); admMessage->command = DP_USER_CMD_ADD; (void) strcpy(userName, argv[2]); Message.type = DP_USER_ADM; Message.len = sizeof (dp_user_adm_t) + strlen(userName) + 1; Message.data = admMessage; ADM_Send(&Message); Timeout.tv_nsec = 0; Timeout.tv_sec = ADM_SEPROM_TIMEOUT; ADM_Recv(&Message, &Timeout, DP_USER_ADM_R, sizeof (dp_user_adm_r_t)); admResponse = (dp_user_adm_r_t *)Message.data; if (admResponse->command != DP_USER_CMD_ADD) { wrong_response(); exit(-1); } if (admResponse->status == DP_ERR_USER_FULL) { (void) fprintf(stderr, "\n%s\n\n", gettext("scadm: all user slots are full")); exit(-1); } else if (admResponse->status == DP_ERR_USER_THERE) { (void) fprintf(stderr, "\n%s\n\n", gettext("scadm: user already exists")); exit(-1); } else if (admResponse->status == DP_ERR_USER_WARNING) { (void) fprintf(stderr, "\n%s\n\n", gettext("scadm: username did not start with letter\n" " or did not contain lower case letter\n")); exit(-1); } else if (admResponse->status == DP_ERR_USER_BAD) { malformed_username(); exit(-1); } else if (admResponse->status != 0) { (void) fprintf(stderr, "\n%s\n\n", gettext("scadm: couldn't add user")); exit(-1); } ADM_Free(&Message); } void ADM_Process_userdel(int argc, char *argv[]) { static data_buffer_t dataBuffer; rscp_msg_t Message; struct timespec Timeout; dp_user_adm_t *admMessage; dp_user_adm_r_t *admResponse; char *userName; if (argc != 3) { (void) fprintf(stderr, "\n%s\n\n", gettext("USAGE: scadm userdel ")); exit(-1); } ADM_Start(); if (strlen(argv[2]) > DP_USER_NAME_SIZE) { max_username(); exit(-1); } admMessage = (dp_user_adm_t *)&dataBuffer; userName = (char *)(&((char *)admMessage)[sizeof (dp_user_adm_t)]); admMessage->command = DP_USER_CMD_DEL; (void) strcpy(userName, argv[2]); Message.type = DP_USER_ADM; Message.len = sizeof (dp_user_adm_t) + strlen(userName) + 1; Message.data = admMessage; ADM_Send(&Message); Timeout.tv_nsec = 0; Timeout.tv_sec = ADM_SEPROM_TIMEOUT; ADM_Recv(&Message, &Timeout, DP_USER_ADM_R, sizeof (dp_user_adm_r_t)); admResponse = (dp_user_adm_r_t *)Message.data; if (admResponse->command != DP_USER_CMD_DEL) { wrong_response(); exit(-1); } if (admResponse->status == DP_ERR_USER_NONE) { no_user(); exit(-1); } else if (admResponse->status == DP_ERR_USER_BAD) { malformed_username(); exit(-1); } else if (admResponse->status != 0) { (void) fprintf(stderr, "\n%s\n\n", gettext("scadm: couldn't delete user")); exit(-1); } ADM_Free(&Message); } void ADM_Process_usershow(int argc, char *argv[]) { static data_buffer_t dataBuffer; rscp_msg_t Message; struct timespec Timeout; dp_user_adm_t *admMessage; dp_user_adm_r_t *admResponse; char *userName; char *permissions; char *passwd; int index; if ((argc != 2) && (argc != 3)) { (void) fprintf(stderr, "\n%s\n\n", gettext("USAGE: scadm usershow [username]")); exit(-1); } ADM_Start(); if (argc == 3) { admMessage = (dp_user_adm_t *)&dataBuffer; admMessage->command = DP_USER_CMD_SHOW; Message.type = DP_USER_ADM; Message.data = admMessage; if (strlen(argv[2]) > DP_USER_NAME_SIZE) { max_username(); exit(-1); } userName = (char *)(&((char *)admMessage)[ sizeof (dp_user_adm_t)]); (void) strcpy(userName, argv[2]); admMessage->parm = DP_USER_SHOW_USERNAME; Message.len = sizeof (dp_user_adm_t) + strlen(userName) + 1; ADM_Send(&Message); Timeout.tv_nsec = 0; Timeout.tv_sec = ADM_SEPROM_TIMEOUT; ADM_Recv(&Message, &Timeout, DP_USER_ADM_R, sizeof (dp_user_adm_r_t)); admResponse = (dp_user_adm_r_t *)Message.data; if (admResponse->command != DP_USER_CMD_SHOW) { wrong_response(); exit(-1); } if (admResponse->status == DP_ERR_USER_NONE) { no_user(); exit(-1); } else if (admResponse->status == DP_ERR_USER_BAD) { malformed_username(); exit(-1); } else if (admResponse->status != 0) { no_info(); exit(-1); } userName = &(((char *)admResponse)[ sizeof (dp_user_adm_r_t)]); permissions = &userName[strlen(userName)+1]; passwd = &permissions[strlen(permissions)+1]; show_header(); (void) printf(" %-16s %-15s ", userName, permissions); if (strncmp(passwd, "Assigned", 12) == 0) { (void) printf("%s\n\n", gettext("Assigned")); } else if (strncmp(passwd, "None", 12) == 0) { (void) printf("%s\n\n", gettext("None")); } else { (void) printf("%-12s\n\n", passwd); } ADM_Free(&Message); } else { show_header(); for (index = 1; index <= DP_USER_MAX; index++) { admMessage = (dp_user_adm_t *)&dataBuffer; admMessage->command = DP_USER_CMD_SHOW; admMessage->parm = index; Message.type = DP_USER_ADM; Message.data = admMessage; Message.len = sizeof (dp_user_adm_t); ADM_Send(&Message); Timeout.tv_nsec = 0; Timeout.tv_sec = ADM_SEPROM_TIMEOUT; ADM_Recv(&Message, &Timeout, DP_USER_ADM_R, sizeof (dp_user_adm_r_t)); admResponse = (dp_user_adm_r_t *)Message.data; if (admResponse->command != DP_USER_CMD_SHOW) { wrong_response(); exit(-1); } if (admResponse->status == DP_ERR_USER_NONE) { ADM_Free(&Message); continue; } else if (admResponse->status == DP_ERR_USER_BAD) { malformed_username(); exit(-1); } else if (admResponse->status != 0) { no_info(); exit(-1); } userName = &(((char *)admResponse)[ sizeof (dp_user_adm_r_t)]); permissions = &userName[strlen(userName)+1]; passwd = &permissions[strlen(permissions)+1]; (void) printf(" %-16s %-15s ", userName, permissions); if (strncmp(passwd, "Assigned", 12) == 0) { (void) printf("%s\n", gettext("Assigned")); } else if (strncmp(passwd, "None", 12) == 0) { (void) printf("%s\n", gettext("None")); } else { (void) printf("%-12s\n", passwd); } ADM_Free(&Message); } (void) printf("\n"); } } void ADM_Process_userpassword(int argc, char *argv[]) { static data_buffer_t dataBuffer; rscp_msg_t Message; struct timespec Timeout; dp_user_adm_t *admMessage; dp_user_adm_r_t *admResponse; char *userName; char *password; int passTry; /* Try to set password up to 3 times on Malformed password */ passTry = 3; if (argc != 3) { (void) fprintf(stderr, "\n%s\n\n", gettext("USAGE: scadm userpassword ")); exit(-1); } ADM_Start(); if (strlen(argv[2]) > DP_USER_NAME_SIZE) { max_username(); exit(-1); } admMessage = (dp_user_adm_t *)&dataBuffer; admMessage->command = DP_USER_CMD_PASSWORD; userName = (&((char *)admMessage)[sizeof (dp_user_adm_t)]); (void) strcpy(userName, argv[2]); password = (&((char *)admMessage)[sizeof (dp_user_adm_t) + strlen(userName) + 1]); for (;;) { ADM_Get_Password(password); Message.type = DP_USER_ADM; Message.len = sizeof (dp_user_adm_t) + strlen(userName) + strlen(password) + 2; Message.data = admMessage; ADM_Send(&Message); ADM_Destroy_Password(password); Timeout.tv_nsec = 0; Timeout.tv_sec = ADM_SEPROM_TIMEOUT; ADM_Recv(&Message, &Timeout, DP_USER_ADM_R, sizeof (dp_user_adm_r_t)); admResponse = (dp_user_adm_r_t *)Message.data; if (admResponse->command != DP_USER_CMD_PASSWORD) { wrong_response(); exit(-1); } if (admResponse->status == DP_ERR_USER_NONE) { no_user(); exit(-1); } else if (admResponse->status == DP_ERR_USER_BAD) { malformed_username(); exit(-1); } else if (admResponse->status == DP_ERR_USER_PASSWD) { (void) fprintf(stderr, "\n%s\n\n", gettext("scadm: malformed password\n" " A valid password is between 6 and 8 " "characters,\n" " has at least two alphabetic characters, " "and at\n" " least one numeric or special character. " "The\n" " password must differ from the user's " "login name\n" " and any reverse or circular shift of that " "login\n" " name.\n")); passTry--; if (passTry > 0) { ADM_Free(&Message); continue; } else exit(-1); } else if (admResponse->status != 0) { (void) fprintf(stderr, "\n%s\n\n", gettext("scadm: couldn't change password")); exit(-1); } /* password was changed successfully, get out of while */ break; } ADM_Free(&Message); } void ADM_Process_userperm(int argc, char *argv[]) { static data_buffer_t dataBuffer; rscp_msg_t Message; struct timespec Timeout; dp_user_adm_t *admMessage; dp_user_adm_r_t *admResponse; char *userName; int permissions; int index; if ((argc != 3) && (argc != 4)) { userperm_usage(); exit(-1); } if (argc == 3) { permissions = 0; } else { if ((strlen(argv[3]) > 4) || (strlen(argv[3]) < 1)) { userperm_usage(); exit(-1); } permissions = 0; for (index = 0; index < strlen(argv[3]); index++) { if ((argv[3][index] != 'c') && (argv[3][index] != 'C') && (argv[3][index] != 'u') && (argv[3][index] != 'U') && (argv[3][index] != 'a') && (argv[3][index] != 'A') && (argv[3][index] != 'r') && (argv[3][index] != 'R')) { userperm_usage(); exit(-1); } if ((argv[3][index] == 'c') || (argv[3][index] == 'C')) { /* See if this field was entered twice */ if ((permissions & DP_USER_PERM_C) != 0) { userperm_usage(); exit(-1); } permissions = permissions | DP_USER_PERM_C; } if ((argv[3][index] == 'u') || (argv[3][index] == 'U')) { /* See if this field was enetered twice */ if ((permissions & DP_USER_PERM_U) != 0) { userperm_usage(); exit(-1); } permissions = permissions | DP_USER_PERM_U; } if ((argv[3][index] == 'a') || (argv[3][index] == 'A')) { /* See if this field was enetered twice */ if ((permissions & DP_USER_PERM_A) != 0) { userperm_usage(); exit(-1); } permissions = permissions | DP_USER_PERM_A; } if ((argv[3][index] == 'r') || (argv[3][index] == 'R')) { /* See if this field was enetered twice */ if ((permissions & DP_USER_PERM_R) != 0) { userperm_usage(); exit(-1); } permissions = permissions | DP_USER_PERM_R; } } } ADM_Start(); if (strlen(argv[2]) > DP_USER_NAME_SIZE) { max_username(); exit(-1); } admMessage = (dp_user_adm_t *)&dataBuffer; admMessage->command = DP_USER_CMD_PERM; admMessage->parm = permissions; userName = (char *)(&((char *)admMessage)[sizeof (dp_user_adm_t)]); (void) strcpy(userName, argv[2]); Message.type = DP_USER_ADM; Message.len = sizeof (dp_user_adm_t) + strlen(userName) + 1; Message.data = admMessage; ADM_Send(&Message); Timeout.tv_nsec = 0; Timeout.tv_sec = ADM_SEPROM_TIMEOUT; ADM_Recv(&Message, &Timeout, DP_USER_ADM_R, sizeof (dp_user_adm_r_t)); admResponse = (dp_user_adm_r_t *)Message.data; if (admResponse->command != DP_USER_CMD_PERM) { wrong_response(); exit(-1); } if (admResponse->status == DP_ERR_USER_NONE) { no_user(); exit(-1); } else if (admResponse->status == DP_ERR_USER_BAD) { malformed_username(); exit(-1); } else if (admResponse->status != 0) { (void) fprintf(stderr, "\n%s\n\n", gettext("scadm: couldn't change permissions")); exit(-1); } ADM_Free(&Message); } static void ADM_Get_Password(char *password) { static char pass1[64]; static char pass2[64]; static struct termios newOpts; int passTry; int validPass; validPass = 0; passTry = 3; if (signal(SIGINT, cleanup) == SIG_ERR) { (void) fprintf(stderr, "\n%s\n\n", gettext("scadm: cleanup() registration failed")); exit(-1); } echoOff = 1; (void) tcgetattr(0, &oldOpts); newOpts = oldOpts; newOpts.c_lflag &= ~ECHO; (void) tcsetattr(0, TCSANOW, &newOpts); while ((passTry > 0) && (validPass == 0)) { passTry = passTry - 1; (void) printf("%s", gettext("Password: ")); (void) scanf("%s", pass1); (void) printf("\n"); (void) fflush(stdin); (void) printf("%s", gettext("Re-enter Password: ")); (void) scanf("%s", pass2); (void) printf("\n"); /* Truncate at 8 characters */ pass1[8] = pass2[8] = '\0'; if ((strcmp(pass1, pass2) != 0) && (passTry > 0)) { ADM_Destroy_Password(pass1); ADM_Destroy_Password(pass2); (void) fprintf(stderr, "%s\n\n", gettext("Passwords didn't match, try again")); } else if ((strcmp(pass1, pass2) != 0) && (passTry <= 0)) { ADM_Destroy_Password(pass1); ADM_Destroy_Password(pass2); (void) fprintf(stderr, "\n%s\n\n", gettext("scadm: ERROR, passwords didn't match")); (void) tcsetattr(0, TCSANOW, &oldOpts); exit(-1); } else { validPass = 1; } } (void) tcsetattr(0, TCSANOW, &oldOpts); echoOff = 0; (void) strcpy(password, pass1); ADM_Destroy_Password(pass1); ADM_Destroy_Password(pass2); } static void cleanup() { if (echoOff) (void) tcsetattr(0, TCSANOW, &oldOpts); exit(-1); } static void ADM_Destroy_Password(char *password) { int index; for (index = 0; index < strlen(password); index++) password[index] = 0x1; } static void max_username() { (void) fprintf(stderr, gettext("\nscadm: maximum username length is %d\n\n"), DP_USER_NAME_SIZE); } static void malformed_username() { (void) fprintf(stderr, "\n%s\n\n", gettext("scadm: malformed username")); } static void wrong_response() { (void) fprintf(stderr, "\n%s\n\n", gettext("scadm: SC returned wrong response")); } static void no_user() { (void) fprintf(stderr, "\n%s\n\n", gettext("scadm: username does not exist")); } static void no_info() { (void) fprintf(stderr, "\n%s\n\n", gettext("scadm: couldn't get information on user")); } static void userperm_usage() { (void) fprintf(stderr, "\n%s\n\n", gettext("USAGE: scadm userperm [cuar]")); } static void show_header() { int i; int usernLen = strlen(gettext("username")); int permLen = strlen(gettext("permissions")); int pwdLen = strlen(gettext("password")); (void) printf("\n"); (void) putchar(' '); (void) printf("%s", gettext("username")); for (i = 0; i < (20 - usernLen); i++) (void) putchar(' '); (void) printf("%s", gettext("permissions")); for (i = 0; i < (19 - permLen); i++) (void) putchar(' '); (void) printf("%s\n", gettext("password")); (void) putchar(' '); for (i = 0; i < usernLen; i++) (void) putchar('-'); for (; i < 20; i++) (void) putchar(' '); for (i = 0; i < permLen; i++) (void) putchar('-'); for (; i < 19; i++) (void) putchar(' '); for (i = 0; i < pwdLen; i++) (void) putchar('-'); (void) printf("\n"); }