7 * (c) Copyright 1988 by the Massachusetts Institute of Technology.
8 * For copying and distribution information, please see the file
13 static char *rcsid_userreg_c = "$Header$";
16 #include <mit-copyright.h>
30 struct user user, db_user;
32 char typed_mit_id[100];
38 int user_is_valid = 0;
39 int user_has_login = 0;
40 int already_registered = 0;
41 extern char *disabled();
45 signal(sig, SIG_IGN); /* let us clean up, please */
57 register int reencrypt;
58 char line[100], *when, *msg;
60 char tmpfirst[100], tmplast[100], tmpmid[100];
64 com_err(argv[0], status, "while trying to initialize");
68 if (when = disabled(&msg)) {
69 printf("We're sorry, the registration service is unavailable right now\n");
71 printf("because %s\n", msg);
72 printf("You should be able to register after %s", when);
73 printf("\nPress ENTER or RETURN to continue ");
81 signal(SIGINT, fix_display);
82 signal(SIGQUIT, fix_display);
83 signal(SIGHUP, fix_display);
91 display_text(WELCOME);
96 strcpy(tmpfirst, user.u_first);
97 strcpy(tmplast, user.u_last);
98 FixName(tmplast, tmpfirst, user.u_last, user.u_first, tmpmid);
106 display_text_line(0);
107 display_text_line("Sorry, you still cannot be found in the database.");
108 display_text_line(" ");
109 display_text_line("Please call the account administrator at x3-1325 for help.");
113 display_text_line(0); /* clear the window */
114 display_text_line("You could not be found in the database.");
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) {
119 display_text_line(0);
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) {
125 strcpy(tmpfirst, user.u_first);
126 strcpy(tmplast, user.u_last);
127 FixName(tmplast, tmpfirst, user.u_last, user.u_first, tmpmid);
131 display_text_line(0);
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)
137 display_text_line(0);
139 "You entered your family name as \"%s\"", user.u_last);
140 display_text_line(line);
141 if (askyn("Do you want to change it? ") == YES) {
143 strcpy(tmpfirst, user.u_first);
144 strcpy(tmplast, user.u_last);
145 FixName(tmplast, tmpfirst, user.u_last, user.u_first, tmpmid);
149 display_text_line(0);
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) {
163 if (!user_is_valid || already_registered) {
168 if (!user_has_login) {
169 if (negotiate_login() == -1) {
174 if (negotiate_passwd() == -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",
183 display_text_line(line);
184 display_text_line("you typed in earlier.");
185 display_text_line("");
186 display_text_line("Your account should be created by tomorrow\n");
188 display_text_line("");
189 display_text_line("You are now finished. Thank you!");
192 } while (getuid() == 0);/* Loop forever if we're root */
200 bzero(&user, sizeof(user));
202 already_registered = 0;
208 /* do the database lookup */
216 display_text_line(0);
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.");
221 result = verify_user(user.u_first, user.u_last,
222 typed_mit_id, user.u_mit_id, db_user.u_login);
224 display_text_line(0);
229 display_text_line("You have been located in the user registration database.");
234 case UREG_NO_PASSWD_YET:
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'",
240 strcpy(user.u_login, db_user.u_login);
241 display_text_line(line);
246 case UREG_ALREADY_REGISTERED:
247 already_registered = 1;
249 * we have to reset this so we dont ask for a
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("");
256 display_text_line("Refer to the document 'Getting Started on Athena' for help logging in.");
257 strcpy(user.u_login, db_user.u_login);
258 sprintf(line, "Remember, the username you chose was '%s'",
260 display_text_line(line);
265 display_text(DELETED_ACCT);
269 case UREG_NOT_ALLOWED:
270 case UREG_ENROLL_NOT_ALLOWED:
271 display_text(NOT_ALLOWED);
276 display_text(IMPROPER_LOGIN);
279 case UREG_USER_NOT_FOUND:
284 case UREG_MISC_ERROR:
285 display_text(NETWORK_DOWN);
290 display_text_line("An unexpected error occurred while trying to access the database");
291 display_text_line(error_message(result));
302 char old_login[LOGIN_SIZE+2];
303 char realm[REALM_SZ];
307 display_text(USERNAME_BLURB);
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];
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];
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]);
322 strcpy(old_login, user.u_login);
323 sprintf(line, "We suggest the username '%s'.", user.u_login);
324 display_text_line(line);
326 "If you are sure you would prefer another username, feel free to enter");
328 "a different one. Keep in mind that it will remain with you for all the ");
329 display_text_line("time you are at MIT.");
334 display_text_line(0);
335 display_text_line("Trying to assign that username... This may take a few minutes.");
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.
342 if ((result = krb_get_lrealm(realm, 1)) != KSUCCESS) {
343 display_text_line("System error; please try another workstation.");
346 result = krb_get_pw_in_tkt(user.u_login, "", realm,
347 "krbtgt", realm, 1, "");
349 if (result != KDC_PR_UNKNOWN) {
351 strcpy(user.u_login, old_login);
353 display_text_line("That username is already taken. Please try again with a different username");
358 * If he isn't, let's try through SMS.
361 result = grab_login(user.u_first, user.u_last,
362 typed_mit_id, user.u_mit_id,
369 if (result == UREG_LOGIN_USED) goto in_use;
370 display_text(NETWORK_DOWN);
371 display_text_line(" ");
372 sprintf(buf, "The specific error was: %s",
373 error_message(result));
374 display_text_line(buf);
379 /* at this point we have successfully negotiated a username */
381 sprintf(line, "O.K. your username will be \"%s\".", user.u_login);
382 display_text_line(0);
383 display_text_line(line);
390 display_text_line(0);
391 display_text(PASSWORD_BLURB);
394 display_text_line("Storing password in the database... This may take a few minutes.");
398 display_text_line("done.");
404 /* input the first name */
405 char buf[FIRST_NAME_SIZE+2];
407 signal(SIGALRM, fix_display);
408 input("Enter first Name:", buf, FIRST_NAME_SIZE+1,
409 FIRSTNAME_TIMEOUT, TRUE);
410 strncpy(user.u_first, buf, FIRST_NAME_SIZE);
411 user.u_first[FIRST_NAME_SIZE - 1] = '\0';
412 canon_name(user.u_first);
418 /* input the last name */
419 char buf[LAST_NAME_SIZE+2];
421 signal(SIGALRM, restart);
422 input("Enter family Name:", buf, LAST_NAME_SIZE+1,
423 LASTNAME_TIMEOUT, FALSE);
424 strncpy(user.u_last, buf, LAST_NAME_SIZE);
425 user.u_last[LAST_NAME_SIZE - 1] = '\0';
426 canon_name(user.u_last);
433 char new_password[PASSWORD_SIZE+1];
434 char new_password_again[PASSWORD_SIZE+1];
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.");
445 signal(SIGALRM, restart);
446 input_no_echo("Enter your password again:", new_password_again,
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.");
454 strcpy(user.u_password, new_password);
462 char buf[LOGIN_SIZE+2];
463 register char *nbuf = buf;
467 user.u_login[0] = '\0';
469 signal(SIGALRM, restart);
470 input("Enter username:", buf, LOGIN_SIZE, USERNAME_TIMEOUT, FALSE);
471 if (!islower(*nbuf) && !isdigit(*nbuf)) {
473 display_text_line("Your username must start with a lower case letter or number.");
476 while (*nbuf != '\0') {
477 if (!islower(*nbuf) && !isdigit(*nbuf)
480 display_text_line("Your username must be all lowercase letters or numbers.");
483 user.u_login[i] = *nbuf++;
485 if (i > LOGIN_SIZE) {
487 display_text_line("Your username must be no more than 8 characters long.");
492 user.u_login[i] = '\0';
494 if (strlen(user.u_login) < 3) {
496 display_text_line("Your username must be 3 or more characters long.\n");
507 register char *nbuf = buf;
510 signal(SIGALRM, restart);
511 input("Enter MIT Id:", buf, 14, MITID_TIMEOUT, FALSE);
514 while (*nbuf != '\0') {
515 if (*nbuf == ' ' || *nbuf == '-') {
519 if (!isdigit(*nbuf)) {
523 typed_mit_id[i] = *nbuf;
529 "Your MIT id must be a nine-digit number. Please try again.");
532 typed_mit_id[9] = '\0';
541 make_salt(salt, user.u_first, user.u_last);
542 strcpy(user.u_mit_id, crypt(&typed_mit_id[2], salt));
546 #define _tolower(c) ((c)|0x60)
548 make_salt(salt, first, last)
549 char *salt, *first, *last;
551 salt[0] = _tolower(last[0]);
552 salt[1] = _tolower(first[0]);
558 /* get middle initial */
559 char buf[MID_INIT_SIZE+2];
561 signal(SIGALRM, restart);
562 input("Enter Middle Initial:", buf, MID_INIT_SIZE+1, MI_TIMEOUT, TRUE);
563 strncpy(user.u_mid_init, buf, MID_INIT_SIZE);
564 user.u_mid_init[MID_INIT_SIZE - 1] = '\0';
565 canon_name(user.u_mid_init);
571 /* exit quickly, not saving anything in the database */
572 bzero(&user, sizeof(user));
573 typed_mit_id[0] = '\0';
575 already_registered = 0;
576 sleep(2); /* give the user a chance to see the screen */
577 display_text_line(0);
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
591 status = set_password(user.u_first, user.u_last, typed_mit_id,
592 user.u_mit_id, user.u_password);
596 display_text (NETWORK_DOWN);
601 #define _toupper(c) ((c) & ~0x20)
603 lenient_strcmp(string1, string2)
604 register char *string1, *string2;
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.
613 if (*string1 == '\0' && *string2 == '\0') {
616 if (*string1 == ' ' || *string1 == '.' || *string1 == '-' || *string1 == '\'') {
620 if (*string2 == ' ' || *string2 == '.' || *string2 == '-' || *string2 == '\'') {
624 if (_toupper(*string1) != _toupper(*string2)) {
633 * Input timeout handler. Loop back to asking for the first name.
637 /* Go to asking for first name. */
646 register char *p2 = cp;
648 /* Trim whitespace off both ends. */
649 for (; *p2 && isspace(*p2); p2++) ;
652 p2 = cp + strlen(cp);
654 while (p2 >= cp && isspace(*p2)) *(--p2) = '\0';
656 /* Make it capitalized */
657 for (p2=cp; *p2; p2++) {
658 if (isupper(*p2)) *p2 = tolower(*p2);
660 if (islower(*cp)) *cp=toupper(*cp);