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
ADM_Process_useradd(int argc,char * argv[])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
ADM_Process_userdel(int argc,char * argv[])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
ADM_Process_usershow(int argc,char * argv[])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
ADM_Process_userpassword(int argc,char * argv[])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
ADM_Process_userperm(int argc,char * argv[])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
ADM_Get_Password(char * password)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
cleanup()613 cleanup()
614 {
615 if (echoOff)
616 (void) tcsetattr(0, TCSANOW, &oldOpts);
617
618 exit(-1);
619 }
620
621
622 static void
ADM_Destroy_Password(char * password)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
max_username()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
malformed_username()642 malformed_username()
643 {
644 (void) fprintf(stderr,
645 "\n%s\n\n", gettext("scadm: malformed username"));
646 }
647
648
649 static void
wrong_response()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
no_user()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
no_info()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
userperm_usage()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
show_header()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