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