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
45static void ADM_Get_Password(char  *password);
46static void ADM_Destroy_Password(char  *password);
47static void max_username();
48static void malformed_username();
49static void wrong_response();
50static void no_user();
51static void no_info();
52static void userperm_usage();
53static void show_header();
54static void cleanup();
55
56
57/* Globals so that exit routine can clean up echo */
58static int		echoOff = 0;
59static struct termios	oldOpts;
60
61typedef union {
62	char	DataBuffer[DP_MAX_MSGLEN];
63	void	*DataBuffer_p;
64} data_buffer_t;
65
66
67void
68ADM_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
137void
138ADM_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
197void
198ADM_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
328void
329ADM_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
425void
426ADM_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
551static void
552ADM_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
614static void
615cleanup()
616{
617	if (echoOff)
618		(void) tcsetattr(0, TCSANOW, &oldOpts);
619
620	exit(-1);
621}
622
623
624static void
625ADM_Destroy_Password(char *password)
626{
627	int index;
628
629	for (index = 0; index < strlen(password); index++)
630		password[index] = 0x1;
631}
632
633
634static void
635max_username()
636{
637	(void) fprintf(stderr,
638	    gettext("\nscadm: maximum username length is %d\n\n"),
639	    DP_USER_NAME_SIZE);
640}
641
642
643static void
644malformed_username()
645{
646	(void) fprintf(stderr,
647	    "\n%s\n\n", gettext("scadm: malformed username"));
648}
649
650
651static void
652wrong_response()
653{
654	(void) fprintf(stderr, "\n%s\n\n",
655	    gettext("scadm: SC returned wrong response"));
656}
657
658
659static void
660no_user()
661{
662	(void) fprintf(stderr,
663	    "\n%s\n\n", gettext("scadm: username does not exist"));
664}
665
666
667static void
668no_info()
669{
670	(void) fprintf(stderr, "\n%s\n\n",
671	    gettext("scadm: couldn't get information on user"));
672}
673
674
675static void
676userperm_usage()
677{
678	(void) fprintf(stderr, "\n%s\n\n",
679	    gettext("USAGE: scadm userperm <username> [cuar]"));
680}
681
682
683static void
684show_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