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