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