9 static char *rcsid_userreg_c = "$Header$";
25 struct user user, db_user;
27 char typed_mit_id[100];
33 int user_is_valid = 0;
34 int user_has_login = 0;
35 int already_registered = 0;
36 extern char *disabled();
40 signal(sig, SIG_IGN); /* let us clean up, please */
52 register int reencrypt;
53 char line[100], *when, *msg;
55 char tmpfirst[100], tmplast[100], tmpmid[100];
59 com_err(argv[0], status, "while trying to initialize");
63 if (when = disabled(&msg)) {
64 printf("We're sorry, the registration service is unavailable right now\n");
66 printf("because %s\n", msg);
67 printf("You should be able to register after %s", when);
68 printf("\nPress ENTER or RETURN to continue ");
76 signal(SIGINT, fix_display);
77 signal(SIGQUIT, fix_display);
78 signal(SIGHUP, fix_display);
86 display_text(WELCOME);
91 strcpy(tmpfirst, user.u_first);
92 strcpy(tmplast, user.u_last);
93 FixName(tmplast, tmpfirst, user.u_last, user.u_first, tmpmid);
101 display_text_line(0);
102 display_text_line("Sorry, you still cannot be found in the database.");
103 display_text_line(" ");
104 display_text_line("Please call the account administrator at x3-1325 for help.");
108 display_text_line(0); /* clear the window */
109 display_text_line("You could not be found in the database.");
110 display_text_line("Do you want to change some input (for example, the spelling");
111 display_text_line("of part of your name) and try again?");
112 if (askyn("Do you want to try again ? ") == YES) {
114 display_text_line(0);
116 "You entered your first name as \"%s\"", user.u_first);
117 display_text_line(line);
118 if (askyn("Do you want to change it? ") == YES) {
120 strcpy(tmpfirst, user.u_first);
121 strcpy(tmplast, user.u_last);
122 FixName(tmplast, tmpfirst, user.u_last, user.u_first, tmpmid);
126 display_text_line(0);
128 "You entered your middle initial as \"%s\"", user.u_mid_init);
129 display_text_line(line);
130 if (askyn("Do you want to change it? ") == YES)
132 display_text_line(0);
134 "You entered your family name as \"%s\"", user.u_last);
135 display_text_line(line);
136 if (askyn("Do you want to change it? ") == YES) {
138 strcpy(tmpfirst, user.u_first);
139 strcpy(tmplast, user.u_last);
140 FixName(tmplast, tmpfirst, user.u_last, user.u_first, tmpmid);
144 display_text_line(0);
146 "You entered your MIT id number as \"%s\"", typed_mit_id);
147 display_text_line(line);
148 if (askyn("Do you want to change it? ") == YES) {
158 if (!user_is_valid || already_registered) {
163 if (!user_has_login) {
164 if (negotiate_login() == -1) {
169 if (negotiate_passwd() == -1) {
174 display_text_line(0);
175 display_text_line("You are now registered to get an Athena account.");
176 sprintf(line, "Please remember your username of \"%s\" and the password",
178 display_text_line(line);
179 display_text_line("you typed in earlier.");
180 display_text_line("");
181 display_text_line("Your account should be created within about 12 hours\n");
183 display_text_line("");
184 display_text_line("You are now finished. Thank you!");
187 } while (getuid() == 0);/* Loop forever if we're root */
195 bzero(&user, sizeof(user));
197 already_registered = 0;
203 /* do the database lookup */
211 display_text_line(0);
212 display_text_line("Looking you up in the database.... This may take from 30 seconds to 10");
213 display_text_line("minutes, depending on how busy the system is at the moment.");
216 result = verify_user(user.u_first, user.u_last,
217 typed_mit_id, user.u_mit_id, db_user.u_login);
219 display_text_line(0);
223 display_text_line("You have been located in the user registration database.");
228 case UREG_NO_PASSWD_YET:
231 display_text_line ("You have chosen a login name, but you have not yet chosen a password.");
232 sprintf(line, "Remember: the username you chose was '%s'",
234 strcpy(user.u_login, db_user.u_login);
235 display_text_line(line);
240 case UREG_ALREADY_REGISTERED:
241 already_registered = 1;
243 * we have to reset this so we dont ask for a
247 display_text_line("You are already registered. An account for you probably already exists");
248 display_text_line("(if not, it will appear within 12 hours).");
249 display_text_line("");
250 display_text_line("Refer to the documents 'Essential Athena' and 'Essential Unix'");
251 strcpy(user.u_login, db_user.u_login);
252 sprintf(line, "for help logging in. Remember, the username you chose was '%s'",
254 display_text_line(line);
259 display_text(DELETED_ACCT);
263 case UREG_NOT_ALLOWED:
264 display_text(NOT_ALLOWED);
269 display_text(IMPROPER_LOGIN);
272 case UREG_USER_NOT_FOUND:
277 case UREG_MISC_ERROR:
278 display_text(NETWORK_DOWN);
283 display_text_line("An unexpected error occurred while trying to access the database");
284 display_text_line(error_message(result));
295 char old_login[LOGIN_SIZE];
296 char realm[REALM_SZ];
300 display_text(USERNAME_BLURB);
302 if (isalpha(user.u_first[0]))
303 *cp++ = user.u_first[0];
304 if (isalpha(user.u_mid_init[0]))
305 *cp++ = user.u_mid_init[0];
307 for (i = 0; user.u_last[i] && cp - user.u_login < 8; i++) {
308 if (isalpha(user.u_last[i])) *cp++ = user.u_last[i];
311 for (i=0; user.u_login[i]; i++)
312 if (isupper(user.u_login[i]))
313 user.u_login[i]=tolower(user.u_login[i]);
315 strcpy(old_login, user.u_login);
316 sprintf(line, "We suggest the username '%s'.", user.u_login);
317 display_text_line(line);
319 "If you are sure you would prefer another username, feel free to enter");
321 "a different one, but keep in mind that it will remain with you for all the ");
322 display_text_line("time you are at MIT.");
327 display_text_line(0);
328 display_text_line("Trying to assign that username... This may take a few minutes.");
331 * Rather than bother SMS with a bunch of different
332 * usernames, all in use, we first try and see if this
333 * guy is known to Kerberos.
335 if ((result = get_krbrlm(realm, 1)) != KSUCCESS) {
336 display_text_line("System error, please try another workstation.");
339 result = get_in_tkt(user.u_login, "", realm, "krbtgt", realm, 1, "");
341 if (result != KDC_PR_UNKNOWN) {
343 strcpy(user.u_login, old_login);
345 display_text_line("That username is already taken. Please try again with a different username");
350 * If he isn't, let's try through SMS.
353 result = grab_login(user.u_first, user.u_last,
354 typed_mit_id, user.u_mit_id,
361 if (result == UREG_LOGIN_USED) goto in_use;
362 display_text(NETWORK_DOWN);
363 display_text_line(" ");
364 sprintf(buf, "The specific error was: %s",
365 error_message(result));
366 display_text_line(buf);
371 /* at this point we have successfully negotiated a username */
373 sprintf(line, "O.K. your username will be \"%s\".", user.u_login);
374 display_text_line(0);
375 display_text_line(line);
382 display_text_line(0);
383 display_text(PASSWORD_BLURB);
386 display_text_line("Storing password in the database... This may take a few minutes.");
390 display_text_line("done.");
396 /* input the first name */
397 char buf[FIRST_NAME_SIZE+2];
399 signal(SIGALRM, restart);
400 input("Enter first Name:", buf, FIRST_NAME_SIZE+1,
401 FIRSTNAME_TIMEOUT, TRUE);
402 strncpy(user.u_first, buf, FIRST_NAME_SIZE);
403 user.u_first[FIRST_NAME_SIZE - 1] = '\0';
404 canon_name(user.u_first);
410 /* input the last name */
411 char buf[LAST_NAME_SIZE+2];
413 signal(SIGALRM, restart);
414 input("Enter family Name:", buf, LAST_NAME_SIZE+1,
415 LASTNAME_TIMEOUT, FALSE);
416 strncpy(user.u_last, buf, LAST_NAME_SIZE);
417 user.u_last[LAST_NAME_SIZE - 1] = '\0';
418 canon_name(user.u_last);
425 char new_password[PASSWORD_SIZE];
426 char new_password_again[PASSWORD_SIZE];
429 signal(SIGALRM, restart);
430 input_no_echo("Enter password:", new_password,
431 PASSWORD_SIZE, NEW_PASSWORD_TIMEOUT);
432 if (strlen(new_password) < 4) {
433 display_text_line("Please use a password of at least 4 characters.");
436 signal(SIGALRM, restart);
437 input_no_echo("Enter password again:", new_password_again,
438 PASSWORD_SIZE, REENTER_PASSWORD_TIMEOUT);
439 if (strcmp(new_password, new_password_again)) {
440 display_text_line("Sorry, the two passwords you just typed in don't match.");
441 display_text_line("Please try again.");
445 strcpy(user.u_password, new_password);
453 char buf[LOGIN_SIZE+2];
454 register char *nbuf = buf;
458 user.u_login[0] = '\0';
460 signal(SIGALRM, restart);
461 input("Enter username:", buf, LOGIN_SIZE+1, USERNAME_TIMEOUT, FALSE);
462 if (!islower(*nbuf) && !isdigit(*nbuf)) {
463 display_text_line("Your username must start with a letter or number.");
466 while (*nbuf != '\0') {
467 if (!islower(*nbuf) && !isdigit(*nbuf)
468 && (*nbuf != '_') && (*nbuf != '.')) {
469 display_text_line("Your username must be all lowercase alphabetic characters.");
472 user.u_login[i] = *nbuf++;
474 if (i > LOGIN_SIZE - 1) {
475 display_text_line("Your username must be no more than 8 characters long.");
480 user.u_login[i] = '\0';
482 if (strlen(user.u_login) < 3) {
483 display_text_line("Your username must be 3 or more characters long.\n");
494 register char *nbuf = buf;
497 signal(SIGALRM, restart);
498 input("Enter MIT Id:", buf, 14, MITID_TIMEOUT, FALSE);
501 while (*nbuf != '\0') {
502 if (*nbuf == ' ' || *nbuf == '-') {
506 if (!isdigit(*nbuf)) {
510 typed_mit_id[i] = *nbuf;
516 "Your MIT id must be a nine-digit number. Please try again.");
519 typed_mit_id[9] = '\0';
528 make_salt(salt, user.u_first, user.u_last);
529 strcpy(user.u_mit_id, crypt(&typed_mit_id[2], salt));
533 #define _tolower(c) ((c)|0x60)
535 make_salt(salt, first, last)
536 char *salt, *first, *last;
538 salt[0] = _tolower(last[0]);
539 salt[1] = _tolower(first[0]);
545 /* get middle initial */
546 char buf[MID_INIT_SIZE+2];
548 signal(SIGALRM, restart);
549 input("Enter Middle Initial:", buf, MID_INIT_SIZE+1, MI_TIMEOUT, TRUE);
550 strncpy(user.u_mid_init, buf, MID_INIT_SIZE);
551 user.u_mid_init[MID_INIT_SIZE - 1] = '\0';
552 canon_name(user.u_mid_init);
558 /* exit quickly, not saving anything in the database */
559 bzero(&user, sizeof(user));
560 typed_mit_id[0] = '\0';
562 already_registered = 0;
563 sleep(2); /* give the user a chance to see the screen */
564 display_text_line(0);
574 * replaces a user in the database. If there is an error, it informs
575 * the user and calls qexit(); It returns only if is is successful
578 status = set_password(user.u_first, user.u_last, typed_mit_id,
579 user.u_mit_id, user.u_password);
583 display_text (NETWORK_DOWN);
588 #define _toupper(c) ((c) & ~0x20)
590 lenient_strcmp(string1, string2)
591 register char *string1, *string2;
594 * a primitive case insensitive string comparison. It returns only 0
595 * if the strings are equal (ignoring case) and 1 if they are
596 * different. Also ignores spaces.
600 if (*string1 == '\0' && *string2 == '\0') {
603 if (*string1 == ' ' || *string1 == '.' || *string1 == '-' || *string1 == '\'') {
607 if (*string2 == ' ' || *string2 == '.' || *string2 == '-' || *string2 == '\'') {
611 if (_toupper(*string1) != _toupper(*string2)) {
620 * Input timeout handler. Loop back to asking for the first name.
624 /* Go to asking for first name. */
633 register char *p2 = cp;
635 /* Trim whitespace off both ends. */
636 for (; *p2 && isspace(*p2); p2++) ;
639 p2 = cp + strlen(cp);
641 while (p2 >= cp && isspace(*p2)) *(--p2) = '\0';
643 /* Make it capitalized */
644 for (p2=cp; *p2; p2++) {
645 if (isupper(*p2)) *p2 = tolower(*p2);
647 if (islower(*cp)) *cp=toupper(*cp);