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