]> andersk Git - moira.git/blame - clients/userreg/userreg.c
grammatical improvements; fix buffer sizes for login & password;
[moira.git] / clients / userreg / userreg.c
CommitLineData
989a2c2c 1/*
569ee3f8 2 * $Source$
3 * $Author$
4 * $Locker$
5 * $Header$
7189310c 6 *
7 * (c) Copyright 1988 by the Massachusetts Institute of Technology.
8 * For copying and distribution information, please see the file
9 * <mit-copyright.h>.
989a2c2c 10 */
11
12#ifndef lint
569ee3f8 13static char *rcsid_userreg_c = "$Header$";
989a2c2c 14#endif lint
15
7189310c 16#include <mit-copyright.h>
989a2c2c 17#include <curses.h>
989a2c2c 18#include <signal.h>
19#include <sys/time.h>
20#include <setjmp.h>
6f742fd0 21#include <ctype.h>
6f742fd0 22#include <krb.h>
23#include <errno.h>
f05412e4 24#include "userreg.h"
25#include "ureg_err.h"
26
989a2c2c 27#define EXIT -1
28
29
569ee3f8 30struct user user, db_user;
31struct alias alias;
32char typed_mit_id[100];
989a2c2c 33
569ee3f8 34jmp_buf redo;
35int restart();
989a2c2c 36
569ee3f8 37extern int errno;
38int user_is_valid = 0;
6f742fd0 39int user_has_login = 0;
569ee3f8 40int already_registered = 0;
b92a6895 41extern char *disabled();
989a2c2c 42
569ee3f8 43fix_display(sig)
989a2c2c 44{
569ee3f8 45 signal(sig, SIG_IGN); /* let us clean up, please */
989a2c2c 46 noraw();
47 echo();
48 endwin();
569ee3f8 49 exit(1);
989a2c2c 50}
51
569ee3f8 52main(argc, argv)
53 int argc;
54 char **argv;
989a2c2c 55{
569ee3f8 56 register int ntimes;
57 register int reencrypt;
b92a6895 58 char line[100], *when, *msg;
6f742fd0 59 int status;
c16914a2 60 char tmpfirst[100], tmplast[100], tmpmid[100];
6f742fd0 61
62 status = ureg_init();
63 if (status) {
64 com_err(argv[0], status, "while trying to initialize");
65 exit(1);
66 }
569ee3f8 67
b92a6895 68 if (when = disabled(&msg)) {
69 printf("We're sorry, the registration service is unavailable right now\n");
70 if (msg)
71 printf("because %s\n", msg);
72 printf("You should be able to register after %s", when);
ce36e992 73 printf("\nPress ENTER or RETURN to continue ");
74 fflush(stdout);
75 getchar();
b92a6895 76 exit(0);
77 }
78
569ee3f8 79 setup_display();
80
81 signal(SIGINT, fix_display);
82 signal(SIGQUIT, fix_display);
83 signal(SIGHUP, fix_display);
84
85 do {
c16914a2 86
569ee3f8 87 setjmp(redo);
88 reset();
89 ntimes = 0;
90
91 display_text(WELCOME);
92
93 gfirst();
94 gmi();
95 glast();
c16914a2 96 strcpy(tmpfirst, user.u_first);
97 strcpy(tmplast, user.u_last);
98 FixName(tmplast, tmpfirst, user.u_last, user.u_first, tmpmid);
99 redisp();
100
569ee3f8 101 gmitid();
c16914a2 102
569ee3f8 103 while (dolook()) {
104 ntimes++;
105 if (ntimes > 3) {
ce36e992 106 display_text_line(0);
569ee3f8 107 display_text_line("Sorry, you still cannot be found in the database.");
108 display_text_line(" ");
ce36e992 109 display_text_line("Please call the account administrator at x3-1325 for help.");
110 wait_for_user();
569ee3f8 111 break;
112 }
113 display_text_line(0); /* clear the window */
ce36e992 114 display_text_line("You could not be found in the database.");
569ee3f8 115 display_text_line("Do you want to change some input (for example, the spelling");
116 display_text_line("of part of your name) and try again?");
117 if (askyn("Do you want to try again ? ") == YES) {
118 reencrypt = 0;
119 display_text_line(0);
120 sprintf(line,
121 "You entered your first name as \"%s\"", user.u_first);
122 display_text_line(line);
123 if (askyn("Do you want to change it? ") == YES) {
124 gfirst();
c16914a2 125 strcpy(tmpfirst, user.u_first);
126 strcpy(tmplast, user.u_last);
127 FixName(tmplast, tmpfirst, user.u_last, user.u_first, tmpmid);
128 redisp();
569ee3f8 129 reencrypt = 1;
130 }
131 display_text_line(0);
132 sprintf(line,
133 "You entered your middle initial as \"%s\"", user.u_mid_init);
134 display_text_line(line);
135 if (askyn("Do you want to change it? ") == YES)
136 gmi();
137 display_text_line(0);
138 sprintf(line,
f05412e4 139 "You entered your family name as \"%s\"", user.u_last);
569ee3f8 140 display_text_line(line);
141 if (askyn("Do you want to change it? ") == YES) {
142 glast();
c16914a2 143 strcpy(tmpfirst, user.u_first);
144 strcpy(tmplast, user.u_last);
145 FixName(tmplast, tmpfirst, user.u_last, user.u_first, tmpmid);
146 redisp();
569ee3f8 147 reencrypt = 1;
148 }
149 display_text_line(0);
150 sprintf(line,
151 "You entered your MIT id number as \"%s\"", typed_mit_id);
152 display_text_line(line);
153 if (askyn("Do you want to change it? ") == YES) {
154 gmitid();
155 reencrypt = 0;
156 }
157 if (reencrypt) {
158 encrypt_mitid();
159 }
160 } else
161 break;
162 }
163 if (!user_is_valid || already_registered) {
164 qexit();
165 continue;
166 }
167 redisp();
6f742fd0 168 if (!user_has_login) {
169 if (negotiate_login() == -1) {
170 qexit();
171 continue;
172 }
173 }
174 if (negotiate_passwd() == -1) {
569ee3f8 175 qexit();
176 continue;
177 }
178 sleep(1);
179 display_text_line(0);
180 display_text_line("You are now registered to get an Athena account.");
181 sprintf(line, "Please remember your username of \"%s\" and the password",
182 user.u_login);
183 display_text_line(line);
184 display_text_line("you typed in earlier.");
c16914a2 185 display_text_line("");
7eb8fc4d 186 display_text_line("Your account should be created by tomorrow\n");
c16914a2 187
569ee3f8 188 display_text_line("");
189 display_text_line("You are now finished. Thank you!");
ce36e992 190 wait_for_user();
569ee3f8 191 qexit();
192 } while (getuid() == 0);/* Loop forever if we're root */
193 restore_display();
194 exit(0);
989a2c2c 195}
196
569ee3f8 197reset()
198{
199 reset_display();
200 bzero(&user, sizeof(user));
201 user_is_valid = 0;
202 already_registered = 0;
203 redisp();
989a2c2c 204}
205
569ee3f8 206dolook()
207{
208 /* do the database lookup */
989a2c2c 209
569ee3f8 210 char line[100];
211 register int result;
212 if (user_is_valid) {
213 /* !! */
214 return (0);
215 }
216 display_text_line(0);
ce36e992 217 display_text_line("Looking you up in the database.... This may take from 30 seconds to 10");
218 display_text_line("minutes, depending on how busy the system is at the moment.");
6f742fd0 219
c16914a2 220 timer_off();
6f742fd0 221 result = verify_user(user.u_first, user.u_last,
222 typed_mit_id, user.u_mit_id, db_user.u_login);
ce36e992 223 wfeep();
224 display_text_line(0);
c16914a2 225 timer_on();
6f742fd0 226 switch(result) {
227 case 0:
5615ce71 228 case UREG_ENROLLED:
6f742fd0 229 display_text_line("You have been located in the user registration database.");
230 user_is_valid = 1;
231 user_has_login = 0;
232 sleep(1);
233 return 0;
234 case UREG_NO_PASSWD_YET:
235 user_is_valid = 1;
236 user_has_login = 1;
237 display_text_line ("You have chosen a login name, but you have not yet chosen a password.");
238 sprintf(line, "Remember: the username you chose was '%s'",
239 db_user.u_login);
240 strcpy(user.u_login, db_user.u_login);
241 display_text_line(line);
242 redisp();
243 sleep(5);
244 return (0);
245
246 case UREG_ALREADY_REGISTERED:
247 already_registered = 1;
248 /*
249 * we have to reset this so we dont ask for a
250 * new username
251 */
252 user_is_valid = 0;
253 display_text_line("You are already registered. An account for you probably already exists");
254 display_text_line("(if not, it will appear within 12 hours).");
255 display_text_line("");
5615ce71 256 display_text_line("Refer to the document 'Getting Started on Athena' for help logging in.");
6f742fd0 257 strcpy(user.u_login, db_user.u_login);
5615ce71 258 sprintf(line, "Remember, the username you chose was '%s'",
6f742fd0 259 db_user.u_login);
260 display_text_line(line);
261 redisp();
ce36e992 262 wait_for_user();
6f742fd0 263 return (0);
b92a6895 264 case UREG_DELETED:
265 display_text(DELETED_ACCT);
ce36e992 266 wait_for_user();
b92a6895 267 restore_display();
268 exit(0);
269 case UREG_NOT_ALLOWED:
5615ce71 270 case UREG_ENROLL_NOT_ALLOWED:
b92a6895 271 display_text(NOT_ALLOWED);
ce36e992 272 wait_for_user();
b92a6895 273 restore_display();
274 exit(0);
275 case UREG_KRB_TAKEN:
276 display_text(IMPROPER_LOGIN);
ce36e992 277 wait_for_user();
b92a6895 278 return(0);
6f742fd0 279 case UREG_USER_NOT_FOUND:
280 return (1);
c16914a2 281
6f742fd0 282 case ECONNREFUSED:
c16914a2 283 case ETIMEDOUT:
b92a6895 284 case UREG_MISC_ERROR:
569ee3f8 285 display_text(NETWORK_DOWN);
ce36e992 286 wait_for_user();
6f742fd0 287 return (0);
288
289 default:
290 display_text_line("An unexpected error occurred while trying to access the database");
291 display_text_line(error_message(result));
292 redisp();
ce36e992 293 wait_for_user();
6f742fd0 294 return(1);
989a2c2c 295 }
989a2c2c 296}
297
6f742fd0 298negotiate_login()
569ee3f8 299{
b92a6895 300 register int result;
569ee3f8 301 char line[100];
5615ce71 302 char old_login[LOGIN_SIZE+2];
f05412e4 303 char realm[REALM_SZ];
6f742fd0 304 int i;
c16914a2 305 char *cp;
6f742fd0 306
569ee3f8 307 display_text(USERNAME_BLURB);
c16914a2 308 cp = user.u_login;
309 if (isalpha(user.u_first[0]))
310 *cp++ = user.u_first[0];
311 if (isalpha(user.u_mid_init[0]))
312 *cp++ = user.u_mid_init[0];
313
314 for (i = 0; user.u_last[i] && cp - user.u_login < 8; i++) {
315 if (isalpha(user.u_last[i])) *cp++ = user.u_last[i];
316 }
317
6f742fd0 318 for (i=0; user.u_login[i]; i++)
319 if (isupper(user.u_login[i]))
320 user.u_login[i]=tolower(user.u_login[i]);
321
569ee3f8 322 strcpy(old_login, user.u_login);
323 sprintf(line, "We suggest the username '%s'.", user.u_login);
324 display_text_line(line);
325 display_text_line(
ce36e992 326 "If you are sure you would prefer another username, feel free to enter");
569ee3f8 327 display_text_line(
5615ce71 328 "a different one. Keep in mind that it will remain with you for all the ");
6f742fd0 329 display_text_line("time you are at MIT.");
569ee3f8 330
569ee3f8 331 while (1) {
332 glogin();
6f742fd0 333
569ee3f8 334 display_text_line(0);
ce36e992 335 display_text_line("Trying to assign that username... This may take a few minutes.");
c16914a2 336 timer_off();
6f742fd0 337 /*
338 * Rather than bother SMS with a bunch of different
339 * usernames, all in use, we first try and see if this
340 * guy is known to Kerberos.
341 */
f4f2cbe9 342 if ((result = krb_get_lrealm(realm, 1)) != KSUCCESS) {
343 display_text_line("System error; please try another workstation.");
f05412e4 344 continue;
345 }
f4f2cbe9 346 result = krb_get_pw_in_tkt(user.u_login, "", realm,
347 "krbtgt", realm, 1, "");
c16914a2 348 timer_on();
6f742fd0 349 if (result != KDC_PR_UNKNOWN) {
350 in_use:
569ee3f8 351 strcpy(user.u_login, old_login);
352 redisp();
ce36e992 353 display_text_line("That username is already taken. Please try again with a different username");
569ee3f8 354 continue;
569ee3f8 355 }
c16914a2 356
6f742fd0 357 /*
358 * If he isn't, let's try through SMS.
359 */
c16914a2 360 timer_off();
6f742fd0 361 result = grab_login(user.u_first, user.u_last,
362 typed_mit_id, user.u_mit_id,
363 user.u_login);
ce36e992 364 wfeep();
c16914a2 365 timer_on();
6f742fd0 366 if (result != 0) {
ce36e992 367 char buf[BUFSIZ];
368
6f742fd0 369 if (result == UREG_LOGIN_USED) goto in_use;
370 display_text(NETWORK_DOWN);
ce36e992 371 display_text_line(" ");
372 sprintf(buf, "The specific error was: %s",
373 error_message(result));
374 display_text_line(buf);
375 wait_for_user();
6f742fd0 376 return (qexit());
377 } else break;
569ee3f8 378 }
569ee3f8 379 /* at this point we have successfully negotiated a username */
380
6f742fd0 381 sprintf(line, "O.K. your username will be \"%s\".", user.u_login);
569ee3f8 382 display_text_line(0);
383 display_text_line(line);
384 redisp();
385 sleep(3);
6f742fd0 386 return 0;
387}
388negotiate_passwd()
389{
569ee3f8 390 display_text_line(0);
391 display_text(PASSWORD_BLURB);
6f742fd0 392
569ee3f8 393 gpass();
6f742fd0 394 display_text_line("Storing password in the database... This may take a few minutes.");
569ee3f8 395 if (do_replace()) {
396 return (-1);
397 }
398 display_text_line("done.");
b92a6895 399 return(0);
989a2c2c 400}
401
569ee3f8 402gfirst()
403{
404 /* input the first name */
ce36e992 405 char buf[FIRST_NAME_SIZE+2];
569ee3f8 406
407 signal(SIGALRM, restart);
ce36e992 408 input("Enter first Name:", buf, FIRST_NAME_SIZE+1,
409 FIRSTNAME_TIMEOUT, TRUE);
569ee3f8 410 strncpy(user.u_first, buf, FIRST_NAME_SIZE);
411 user.u_first[FIRST_NAME_SIZE - 1] = '\0';
6f742fd0 412 canon_name(user.u_first);
569ee3f8 413 redisp();
414}
989a2c2c 415
569ee3f8 416glast()
417{
418 /* input the last name */
ce36e992 419 char buf[LAST_NAME_SIZE+2];
569ee3f8 420
421 signal(SIGALRM, restart);
ce36e992 422 input("Enter family Name:", buf, LAST_NAME_SIZE+1,
423 LASTNAME_TIMEOUT, FALSE);
569ee3f8 424 strncpy(user.u_last, buf, LAST_NAME_SIZE);
425 user.u_last[LAST_NAME_SIZE - 1] = '\0';
6f742fd0 426 canon_name(user.u_last);
569ee3f8 427 redisp();
989a2c2c 428}
429
569ee3f8 430gpass()
431{
432 /* input password */
5615ce71 433 char new_password[PASSWORD_SIZE+1];
434 char new_password_again[PASSWORD_SIZE+1];
569ee3f8 435
569ee3f8 436do_input:
437 signal(SIGALRM, restart);
438 input_no_echo("Enter password:", new_password,
439 PASSWORD_SIZE, NEW_PASSWORD_TIMEOUT);
440 if (strlen(new_password) < 4) {
441 display_text_line("Please use a password of at least 4 characters.");
442 goto do_input;
443 }
5615ce71 444 wfeep();
569ee3f8 445 signal(SIGALRM, restart);
5615ce71 446 input_no_echo("Enter your password again:", new_password_again,
569ee3f8 447 PASSWORD_SIZE, REENTER_PASSWORD_TIMEOUT);
448 if (strcmp(new_password, new_password_again)) {
449 display_text_line("Sorry, the two passwords you just typed in don't match.");
450 display_text_line("Please try again.");
451 goto do_input;
452 }
569ee3f8 453
6f742fd0 454 strcpy(user.u_password, new_password);
569ee3f8 455 redisp();
989a2c2c 456}
457
569ee3f8 458glogin()
459{
460 /* get login name */
461 register int i;
ce36e992 462 char buf[LOGIN_SIZE+2];
569ee3f8 463 register char *nbuf = buf;
464
465input_login:
466 i = 0;
467 user.u_login[0] = '\0';
468 nbuf = &buf[0];
469 signal(SIGALRM, restart);
5615ce71 470 input("Enter username:", buf, LOGIN_SIZE, USERNAME_TIMEOUT, FALSE);
ce36e992 471 if (!islower(*nbuf) && !isdigit(*nbuf)) {
5615ce71 472 user.u_login[0] = 0;
473 display_text_line("Your username must start with a lower case letter or number.");
ce36e992 474 goto input_login;
475 }
569ee3f8 476 while (*nbuf != '\0') {
22c45376 477 if (!islower(*nbuf) && !isdigit(*nbuf)
5615ce71 478 && (*nbuf != '_')) {
479 user.u_login[0] = 0;
480 display_text_line("Your username must be all lowercase letters or numbers.");
569ee3f8 481 goto input_login;
482 }
483 user.u_login[i] = *nbuf++;
484 i++;
5615ce71 485 if (i > LOGIN_SIZE) {
486 user.u_login[0] = 0;
569ee3f8 487 display_text_line("Your username must be no more than 8 characters long.");
488 goto input_login;
489 }
490 }
491 if (i != 0) {
492 user.u_login[i] = '\0';
493 }
c16914a2 494 if (strlen(user.u_login) < 3) {
5615ce71 495 user.u_login[0] = 0;
c16914a2 496 display_text_line("Your username must be 3 or more characters long.\n");
569ee3f8 497 goto input_login;
498 }
569ee3f8 499 redisp();
989a2c2c 500}
501
569ee3f8 502gmitid()
503{
504 /* get mid id */
505 register int i;
ce36e992 506 char buf[15];
569ee3f8 507 register char *nbuf = buf;
508
509input_mit_id:
510 signal(SIGALRM, restart);
ce36e992 511 input("Enter MIT Id:", buf, 14, MITID_TIMEOUT, FALSE);
569ee3f8 512 i = 0;
513 nbuf = &buf[0];
514 while (*nbuf != '\0') {
515 if (*nbuf == ' ' || *nbuf == '-') {
516 nbuf++;
517 continue;
518 }
519 if (!isdigit(*nbuf)) {
520 i = 0;
521 break;
522 }
523 typed_mit_id[i] = *nbuf;
524 nbuf++;
525 i++;
526 }
527 if (i != 9) {
528 display_text_line(
529 "Your MIT id must be a nine-digit number. Please try again.");
530 goto input_mit_id;
531 }
532 typed_mit_id[9] = '\0';
533 redisp();
534 encrypt_mitid();
989a2c2c 535}
536
569ee3f8 537encrypt_mitid()
538{
539 char salt[3];
989a2c2c 540
569ee3f8 541 make_salt(salt, user.u_first, user.u_last);
542 strcpy(user.u_mit_id, crypt(&typed_mit_id[2], salt));
989a2c2c 543}
544
545
546#define _tolower(c) ((c)|0x60)
547
569ee3f8 548make_salt(salt, first, last)
549 char *salt, *first, *last;
989a2c2c 550{
569ee3f8 551 salt[0] = _tolower(last[0]);
552 salt[1] = _tolower(first[0]);
989a2c2c 553}
554
555
569ee3f8 556gmi()
557{
558 /* get middle initial */
ce36e992 559 char buf[MID_INIT_SIZE+2];
569ee3f8 560
561 signal(SIGALRM, restart);
ce36e992 562 input("Enter Middle Initial:", buf, MID_INIT_SIZE+1, MI_TIMEOUT, TRUE);
569ee3f8 563 strncpy(user.u_mid_init, buf, MID_INIT_SIZE);
564 user.u_mid_init[MID_INIT_SIZE - 1] = '\0';
6f742fd0 565 canon_name(user.u_mid_init);
569ee3f8 566 redisp();
989a2c2c 567}
568
569ee3f8 569qexit()
570{
571 /* exit quickly, not saving anything in the database */
572 bzero(&user, sizeof(user));
573 typed_mit_id[0] = '\0';
574 user_is_valid = 0;
575 already_registered = 0;
ce36e992 576 sleep(2); /* give the user a chance to see the screen */
569ee3f8 577 display_text_line(0);
578 return (EXIT);
989a2c2c 579}
580
581
569ee3f8 582do_replace()
583{
6f742fd0 584 int status;
585
569ee3f8 586 /*
587 * replaces a user in the database. If there is an error, it informs
588 * the user and calls qexit(); It returns only if is is successful
589 */
c16914a2 590 timer_off();
6f742fd0 591 status = set_password(user.u_first, user.u_last, typed_mit_id,
c16914a2 592 user.u_mit_id, user.u_password);
ce36e992 593 wfeep();
c16914a2 594 timer_on();
6f742fd0 595 if (status) {
596 display_text (NETWORK_DOWN);
569ee3f8 597 return (-1);
6f742fd0 598 } else return 0;
989a2c2c 599}
600
601#define _toupper(c) ((c) & ~0x20)
602
569ee3f8 603lenient_strcmp(string1, string2)
604 register char *string1, *string2;
989a2c2c 605{
569ee3f8 606 /*
607 * a primitive case insensitive string comparison. It returns only 0
608 * if the strings are equal (ignoring case) and 1 if they are
609 * different. Also ignores spaces.
610 */
611
612 while (1) {
613 if (*string1 == '\0' && *string2 == '\0') {
614 return (0);
615 }
616 if (*string1 == ' ' || *string1 == '.' || *string1 == '-' || *string1 == '\'') {
617 string1++;
618 continue;
619 }
620 if (*string2 == ' ' || *string2 == '.' || *string2 == '-' || *string2 == '\'') {
621 string2++;
622 continue;
623 }
624 if (_toupper(*string1) != _toupper(*string2)) {
625 return (1);
626 }
627 string1++;
628 string2++;
629 }
989a2c2c 630}
631
569ee3f8 632/*
633 * Input timeout handler. Loop back to asking for the first name.
989a2c2c 634 */
635
636restart()
637/* Go to asking for first name. */
638{
569ee3f8 639 qexit();
640 longjmp(redo);
989a2c2c 641}
6f742fd0 642
643canon_name(cp)
644 register char *cp;
645{
646 register char *p2 = cp;
647
648 /* Trim whitespace off both ends. */
649 for (; *p2 && isspace(*p2); p2++) ;
650 if (*p2) {
651 strcpy(cp, p2);
652 p2 = cp + strlen(cp);
653 --p2;
654 while (p2 >= cp && isspace(*p2)) *(--p2) = '\0';
655 }
656 /* Make it capitalized */
657 for (p2=cp; *p2; p2++) {
658 if (isupper(*p2)) *p2 = tolower(*p2);
659 }
660 if (islower(*cp)) *cp=toupper(*cp);
661}
This page took 0.17626 seconds and 5 git commands to generate.