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 /* 7.2 release compatibility */
31 #ifndef KADM_INSECURE_PW
32 #define KADM_INSECURE_PW (-1783126240L)
38 struct user user, db_user;
40 char typed_mit_id[100];
46 int user_is_valid = 0;
47 int user_has_login = 0;
48 int already_registered = 0;
50 extern char *disabled();
54 signal(sig, SIG_IGN); /* let us clean up, please */
66 register int reencrypt;
67 char line[100], *when, *msg;
69 char tmpfirst[100], tmplast[100], tmpmid[100];
73 com_err(argv[0], status, "while trying to initialize");
77 if (when = disabled(&msg)) {
78 printf("We're sorry, the registration service is unavailable right now\n");
80 printf("because %s\n", msg);
81 printf("You should be able to register after %s", when);
82 printf("\nPress ENTER or RETURN to continue ");
88 /* stash the realm for later use */
89 if ((status = krb_get_lrealm(realm, 1)) != KSUCCESS) {
90 printf("System error; please try another workstation.");
96 signal(SIGINT, fix_display);
97 signal(SIGQUIT, fix_display);
98 signal(SIGHUP, fix_display);
105 display_text(WELCOME, "");
110 strcpy(tmpfirst, user.u_first);
111 strcpy(tmplast, user.u_last);
112 FixName(tmplast, tmpfirst, user.u_last, user.u_first, tmpmid);
120 display_text_line(0);
121 display_text_line("Sorry, you still cannot be found in the database.");
122 display_text_line(" ");
123 display_text_line("Please call an accounts consultant at x3-1325 for help.");
127 display_text_line(0); /* clear the window */
128 display_text_line("You could not be found in the database.");
129 display_text_line("Do you want to change some input (for example, the spelling");
130 display_text_line("of part of your name) and try again?");
131 if (askyn("Do you want to try again ? ") == YES) {
133 display_text_line(0);
135 "You entered your first name as \"%s\"", user.u_first);
136 display_text_line(line);
137 if (askyn("Do you want to change it? ") == YES) {
139 strcpy(tmpfirst, user.u_first);
140 strcpy(tmplast, user.u_last);
141 FixName(tmplast, tmpfirst, user.u_last, user.u_first, tmpmid);
145 display_text_line(0);
147 "You entered your middle initial as \"%s\"", user.u_mid_init);
148 display_text_line(line);
149 if (askyn("Do you want to change it? ") == YES)
151 display_text_line(0);
153 "You entered your family name as \"%s\"", user.u_last);
154 display_text_line(line);
155 if (askyn("Do you want to change it? ") == YES) {
157 strcpy(tmpfirst, user.u_first);
158 strcpy(tmplast, user.u_last);
159 FixName(tmplast, tmpfirst, user.u_last, user.u_first, tmpmid);
163 display_text_line(0);
165 "You entered your MIT id number as \"%s\"", typed_mit_id);
166 display_text_line(line);
167 if (askyn("Do you want to change it? ") == YES) {
172 EncryptID(user.u_mit_id, typed_mit_id,
173 user.u_first, user.u_last);
178 if (!user_is_valid || already_registered) {
183 if (!user_has_login) {
184 if (negotiate_login() == -1) {
189 if (negotiate_passwd() == -1) {
195 display_text(FINISHED, user.u_login);
197 display_text(FINISHEDE, user.u_login);
198 if (askyn("Do you wish to set your mailbox now? (Yes or No) ")) {
203 kinit(user.u_login, user.u_password);
204 system(NAMESPACE_PROG);
221 bzero(&user, sizeof(user));
223 already_registered = 0;
230 /* do the database lookup */
238 display_text_line(0);
239 display_text_line("Looking you up in the database.... This may take from 30 seconds to 10");
240 display_text_line("minutes, depending on how busy the system is at the moment.");
243 result = verify_user(user.u_first, user.u_last,
244 typed_mit_id, user.u_mit_id, db_user.u_login);
246 display_text_line(0);
251 display_text_line("You have been located in the user registration database.");
256 case UREG_HALF_ENROLLED:
258 /* fall through to: */
259 case UREG_NO_PASSWD_YET:
262 display_text_line ("You have chosen a login name, but you have not yet chosen a password.");
263 sprintf(line, "Remember: the username you chose was '%s'",
265 strcpy(user.u_login, db_user.u_login);
266 display_text_line(line);
271 case UREG_ALREADY_REGISTERED:
272 already_registered = 1;
274 * we have to reset this so we dont ask for a
278 display_text_line("You are already registered. An account for you probably already exists");
279 display_text_line("(if not, it will appear within 12 hours).");
280 display_text_line("");
281 display_text_line("Refer to the document 'Getting Started on Athena' for help logging in.");
282 strcpy(user.u_login, db_user.u_login);
283 sprintf(line, "Remember, the username you chose was '%s'",
285 display_text_line(line);
290 display_text(DELETED_ACCT, db_user.u_login);
294 case UREG_NOT_ALLOWED:
295 display_text(OFFER_ENROLL, db_user.u_login);
297 if (!askyn("Continue choosing a name and password (Y/N)? ")) {
298 already_registered = 1;
305 case UREG_ENROLL_NOT_ALLOWED:
306 display_text(NOT_ALLOWED, db_user.u_login);
311 display_text(IMPROPER_LOGIN, db_user.u_login);
314 case UREG_USER_NOT_FOUND:
319 case UREG_MISC_ERROR:
320 display_text(NETWORK_DOWN, db_user.u_login);
321 display_text_line(" ");
322 sprintf(line, "The specific error was: %s",
323 error_message(result));
324 display_text_line(line);
329 display_text_line("An unexpected error occurred while trying to access the database");
330 display_text_line(error_message(result));
338 /* Get a login name from the user and register it. There are several steps
339 * to this: display help message, get name, check name, display confirmation
340 * message, get confirmation, register name.
346 char line[100], old_login[LOGIN_SIZE+2];
349 /* build suggested username */
351 if (isalpha(user.u_first[0]))
352 *cp++ = user.u_first[0];
353 if (isalpha(user.u_mid_init[0]))
354 *cp++ = user.u_mid_init[0];
355 for (i = 0; user.u_last[i] && cp - user.u_login < 8; i++)
356 if (isalpha(user.u_last[i]))
357 *cp++ = user.u_last[i];
358 for (i=0; user.u_login[i]; i++)
359 if (isupper(user.u_login[i]))
360 user.u_login[i]=tolower(user.u_login[i]);
361 strcpy(old_login, user.u_login);
364 display_text(USERNAME_BLURB, user.u_login);
367 /* get name from user */
370 display_text_line(0);
371 display_text_line("Testing that username...");
373 if (strlen(user.u_login) < 3)
374 error = "Your username must be at least 3 characters long.";
375 else if (strlen(user.u_login) > 8)
376 error = "Your username cannot be longer than 8 characters.";
377 else if (!isalpha(user.u_login[0]) || !islower(user.u_login[0]))
378 error = "Your username must start with a lowercase letter.";
379 else for (i = 1; i < strlen(user.u_login); i++)
380 if (!islower(user.u_login[i]) &&
381 !isdigit(user.u_login[i]) &&
382 user.u_login[i] != '_')
383 error = "Your username must contain only lower case letters, numbers, and underscore";
385 result = krb_get_pw_in_tkt(user.u_login, "", realm,
386 "krbtgt", realm, 1, "");
388 if (*error == 0 && result != KDC_PR_UNKNOWN)
389 error = "That username is already taken.";
391 /* if it's bad, get another name from user */
393 strcpy(user.u_login, old_login);
395 display_text_line(error);
396 display_text_line("Please choose another username.");
400 /* name is OK, make sure */
401 display_text(USERNAME_BLURB2, user.u_login);
402 if (!askyn("Do you want to register this username? (Yes or No) "))
405 display_text_line(0);
406 display_text_line("Trying to assign that username... This may take a few minutes.");
411 result = grab_login(user.u_first, user.u_last,
412 typed_mit_id, user.u_mit_id,
415 result = enroll_login(user.u_first, user.u_last,
416 typed_mit_id, user.u_mit_id,
423 if (result == UREG_LOGIN_USED) {
424 /* name was in moira but not kerberos */
425 error = "Sorry, that username really was in use after all.";
426 strcpy(user.u_login, old_login);
428 display_text_line(error);
429 display_text_line("Please choose another username.");
433 display_text(NETWORK_DOWN, "");
434 display_text_line(" ");
435 sprintf(buf, "The specific error was: %s", error_message(result));
436 display_text_line(buf);
441 /* at this point we have successfully negotiated a username */
442 sprintf(line, "O.K. your username will be \"%s\".", user.u_login);
443 display_text_line(0);
444 display_text_line(line);
453 char *passwd, *error;
454 char old_passwd[256], fullname[256], tktstring[256], inst[INST_SZ];
455 char login[ANAME_SZ], lpassword[PASSWORD_SIZE];
461 display_text(PASSWORD_BLURB, "");
464 /* validate password */
466 passwd = user.u_password;
467 sprintf(fullname, "%s%s", user.u_first, user.u_last);
468 if (strlen(passwd) < 6)
469 error = "Please choose a longer password.";
470 if (!strpasscmp(passwd, user.u_first) ||
471 !strpasscmp(passwd, user.u_last) ||
472 !strpasscmp(passwd, user.u_login) ||
473 !strpasscmp(passwd, fullname) ||
474 !strpasscmp(passwd, typed_mit_id))
475 error = "Please do not use your name or ID number for your password.";
477 in = fopen(LOGIN_INFO, "r");
479 fgets(login, sizeof(login), in);
480 /* trim trailing newline */
482 login[strlen(login) - 1] = 0;
483 fgets(lpassword, sizeof(lpassword), in);
484 /* trim trailing newline */
485 if (strlen(lpassword))
486 lpassword[strlen(lpassword) - 1] = 0;
489 strcpy(login, "moira");
490 strcpy(lpassword, "moira");
493 sprintf(tktstring, "/tmp/tkt_cpw_%d", getpid());
494 krb_set_tkt_string(tktstring);
495 des_string_to_key(passwd, key);
498 result = krb_get_pw_in_tkt(login, inst, realm, PWSERV_NAME,
499 KADM_SINST, 1, lpassword);
500 if (result == KSUCCESS)
501 result = kadm_init_link(PWSERV_NAME, KRB_MASTER, realm);
502 if (result == KSUCCESS)
503 result = kadm_check_pw(key, passwd, &error);
505 if (result == KADM_INSECURE_PW) {
506 error = "You have chosen a passsword that is in the dictionary of commonly\nselected user passwords. You will have to choose a better password.";
507 } else if (result != KSUCCESS) {
508 display_text(NETWORK_DOWN);
509 display_text_line(" ");
510 sprintf(fullname, "%s while verifying password",
511 error_message(result));
512 display_text_line(fullname);
519 display_text_line(0);
520 display_text_line(error);
525 display_text(PASSWORD_BLURB2, "");
526 strcpy(old_passwd, user.u_password);
528 if (strcmp(old_passwd, user.u_password)) {
529 display_text_line(0);
530 display_text_line("What you just typed did not match the password you gave the first time.");
535 display_text_line("Storing password in the database... This may take a few minutes.");
539 display_text_line("done.");
545 /* input the first name */
546 char buf[FIRST_NAME_SIZE+2];
548 signal(SIGALRM, fix_display);
549 input("Enter first Name:", buf, FIRST_NAME_SIZE+1,
550 FIRSTNAME_TIMEOUT, TRUE);
551 strncpy(user.u_first, buf, FIRST_NAME_SIZE);
552 user.u_first[FIRST_NAME_SIZE - 1] = '\0';
553 canon_name(user.u_first);
559 /* input the last name */
560 char buf[LAST_NAME_SIZE+2];
562 signal(SIGALRM, restart);
563 input("Enter family Name:", buf, LAST_NAME_SIZE+1,
564 LASTNAME_TIMEOUT, FALSE);
565 strncpy(user.u_last, buf, LAST_NAME_SIZE);
566 user.u_last[LAST_NAME_SIZE - 1] = '\0';
567 canon_name(user.u_last);
574 char new_password[PASSWORD_SIZE + 1];
576 signal(SIGALRM, restart);
577 input_no_echo("Enter password:", new_password,
578 PASSWORD_SIZE, NEW_PASSWORD_TIMEOUT);
579 strcpy(user.u_password, new_password);
588 char buf[LOGIN_SIZE+2];
590 user.u_login[0] = '\0';
591 signal(SIGALRM, restart);
592 input("Enter username:", buf, LOGIN_SIZE, USERNAME_TIMEOUT, FALSE);
593 strcpy(user.u_login, buf);
602 register char *nbuf = buf;
605 signal(SIGALRM, restart);
606 input("Enter MIT Id:", buf, 14, MITID_TIMEOUT, FALSE);
609 while (*nbuf != '\0') {
610 if (*nbuf == ' ' || *nbuf == '-') {
614 if (!isdigit(*nbuf)) {
618 typed_mit_id[i] = *nbuf;
624 "Your MIT id must be a nine-digit number. Please try again.");
627 typed_mit_id[9] = '\0';
629 EncryptID(user.u_mit_id, typed_mit_id, user.u_first, user.u_last);
634 /* get middle initial */
635 char buf[MID_INIT_SIZE+2];
637 signal(SIGALRM, restart);
638 input("Enter Middle Initial:", buf, MID_INIT_SIZE+1, MI_TIMEOUT, TRUE);
639 strncpy(user.u_mid_init, buf, MID_INIT_SIZE);
640 user.u_mid_init[MID_INIT_SIZE - 1] = '\0';
641 canon_name(user.u_mid_init);
647 /* exit quickly, not saving anything in the database */
648 bzero(&user, sizeof(user));
649 typed_mit_id[0] = '\0';
651 already_registered = 0;
653 sleep(2); /* give the user a chance to see the screen */
654 display_text_line(0);
665 * replaces a user in the database. If there is an error, it informs
666 * the user and calls qexit(); It returns only if is is successful
670 status = set_password(user.u_first, user.u_last, typed_mit_id,
671 user.u_mit_id, user.u_password);
673 status = get_krb(user.u_first, user.u_last, typed_mit_id,
674 user.u_mit_id, user.u_password);
678 display_text (NETWORK_DOWN);
679 display_text_line(" ");
680 sprintf(buf, "The specific error was: %s",
681 error_message(status));
682 display_text_line(buf);
696 status = krb_get_pw_in_tkt(user, inst, realm, "krbtgt",
697 realm, DEFAULT_TKT_LIFE, 0);
703 #define _toupper(c) ((c) & ~0x20)
706 lenient_strcmp(string1, string2)
707 register char *string1, *string2;
710 * a primitive case insensitive string comparison. It returns only 0
711 * if the strings are equal (ignoring case) and 1 if they are
712 * different. Also ignores spaces.
716 if (*string1 == '\0' && *string2 == '\0') {
719 if (*string1 == ' ' || *string1 == '.' || *string1 == '-' ||
720 *string1 == '\'' || *string1 == '_') {
724 if (*string2 == ' ' || *string2 == '.' || *string2 == '-' ||
725 *string2 == '\'' || *string2 == '_') {
729 if (_toupper(*string1) != _toupper(*string2)) {
738 /* See if the strings match in forward & reverse direction, ignoring
739 * case and spaces/punctuation.
745 char buf[256], *from, *to;
747 if (!lenient_strcmp(s1, s2))
749 /* if s2 is empty, say OK */
753 from = &s2[strlen(s2)];
755 for (to = &buf[0]; from >= s2; from--)
758 return(lenient_strcmp(s1, buf));
763 * Input timeout handler. Loop back to asking for the first name.
767 /* Go to asking for first name. */
776 register char *p2 = cp;
778 /* Trim whitespace off both ends. */
779 for (; *p2 && isspace(*p2); p2++) ;
782 p2 = cp + strlen(cp);
784 while (p2 >= cp && isspace(*p2)) *(--p2) = '\0';
786 /* Make it capitalized */