]> andersk Git - moira.git/blame - reg_svr/reg_svr.c
Rearranged timeouts, max retransmits.
[moira.git] / reg_svr / reg_svr.c
CommitLineData
47baf534 1/*
2 * $Source$
3 * $Author$
4 * $Header$
5 *
6 * Copyright (C) 1987 by the Massachusetts Institute of Technology
7 *
8 * Server for user registration with SMS and Kerberos.
9 *
10 * This program is a client of the SMS server and the Kerberos
11 * admin_server, and is a server for the userreg program.
12 *
13 * $Log$
78eff417 14 * Revision 1.3 1987-09-03 03:05:18 wesommer
15 * Version used for userreg tests.
47baf534 16 *
78eff417 17 * Revision 1.2 87/08/22 18:39:45 wesommer
18 * User registration server.
19 *
f46fccfa 20 * Revision 1.1 87/07/31 15:48:13 wesommer
21 * Initial revision
22 *
47baf534 23 */
24
25#ifndef lint
26static char *rcsid_reg_svr_c = "$Header$";
27#endif lint
28
29#include <stdio.h>
30#include <sys/types.h>
31#include <sys/file.h>
32#include <sys/socket.h>
33#include <netinet/in.h>
34#include <netdb.h>
35#include <des.h>
36#include <errno.h>
37#include <ctype.h>
38#include "ureg_err.h"
39#include "ureg_proto.h"
40#include "../../include/sms.h"
f46fccfa 41#include "admin_server.h"
42#include "admin_err.h"
47baf534 43#include <strings.h>
44
45extern void abort();
f46fccfa 46extern char *strdup();
47extern char *malloc();
48extern int krb_err_base;
49extern char admin_errmsg[];
47baf534 50
f46fccfa 51long now;
52#define STAMP { time (&now); printf(ctime(&now)); }
53
47baf534 54struct msg {
55 u_long version;
56 u_long request;
57 char *first;
58 char *last;
59 char *sealed;
60 int sealed_len;
61};
62
63static char retval[BUFSIZ];
64
47baf534 65main()
66{
67 struct sockaddr_in sin;
68 struct servent *sp;
69 int s;
70 int status;
71 int addrlen, len;
72 char buf[BUFSIZ];
73 extern int errno;
74 u_long seqno;
75 struct msg message;
f46fccfa 76 extern char *whoami;
78eff417 77 int i;
78
f46fccfa 79 setlinebuf(stderr);
80 whoami = "reg_svr";
47baf534 81
82 init_ureg_err_tbl();
78eff417 83
47baf534 84 sp = getservbyname("sms_ureg", "udp");
85 if (sp == NULL) {
86 fprintf(stderr, "Unknown service sms_ureg/udp\n");
87 exit(1);
88 }
89 s = socket(AF_INET, SOCK_DGRAM, 0);
90 if (s < 0) {
91 perror("socket");
92 exit(1);
93 }
94 bzero((char *)&sin, sizeof(sin));
95
96 sin.sin_family = AF_INET;
97 sin.sin_port = sp->s_port;
98 sin.sin_addr.s_addr = INADDR_ANY;
99
100 if (bind(s, &sin, sizeof(sin)) < 0) {
101 perror("bind");
102 exit(1);
103 }
78eff417 104
105 status = sms_connect();
106 if (status != 0) {
107 com_err("reg_svr", status, " on connect");
108 exit(1);
109 }
110 status = sms_auth();
111 if (status != 0) {
112 com_err("reg_svr", status, " on auth");
113 exit(1);
114 }
47baf534 115
116 for (;;) {
78eff417 117 printf("waiting..");
118 fflush(stdout);
47baf534 119 addrlen = sizeof(sin);
120 bzero(retval, BUFSIZ);
121 len = recvfrom(s, buf, BUFSIZ, 0, &sin, &addrlen);
122 if (len < 0) {
123 perror("recvfrom");
124 if (errno == EINTR) continue;
125
126 exit(1);
127 }
128 /* Parse a request packet */
129 status = parse_pkt(buf, len, &seqno, &message);
130 if (status != 0) {
131 len = BUFSIZ;
132 format_pkt(buf, &len, seqno, status, (char *)NULL);
133 (void) sendto(s, buf, len, 0, &sin, addrlen);
134 continue;
135 }
136 /* do action */
137 switch((int)message.request) {
138 case UREG_VERIFY_USER:
139 status = verify_user(&message);
140 break;
141 case UREG_RESERVE_LOGIN:
142 status = reserve_user(&message);
143 break;
144 case UREG_SET_PASSWORD:
145 status = set_password(&message);
146 break;
147
148 default:
149 status = UREG_UNKNOWN_REQUEST;
150 break;
151 }
152 len = BUFSIZ;
153 format_pkt(buf, &len, seqno, status, retval);
154
155 sendto(s, buf, len, 0, &sin, addrlen);
156 }
157}
158
47baf534 159int got_one;
160int reg_status;
161char *mit_id;
162char *reg_misc;
163int reg_misc_len;
f46fccfa 164int user_id;
165
47baf534 166#define min(a,b) ((a)>(b)?(b):(a))
167
168int validate_idno(message, db_mit_id, first, last)
169 struct msg *message;
170 char *db_mit_id;
171 char *first, *last;
172{
173 C_Block key;
174 Key_schedule sched;
f46fccfa 175 static char decrypt[BUFSIZ];
47baf534 176 char recrypt[14];
177 static char hashid[14];
178 char idnumber[BUFSIZ];
179 char *temp;
180 int len;
181
182 int i;
183#ifdef notdef
184 for (i = 0; i < message->sealed_len; i++) {
185 printf("%02x ", (unsigned char)message->sealed[i]);
186 }
187 printf("\n");
188#endif notdef
189 mit_id = 0;
190
191 string_to_key(db_mit_id, key);
192 key_sched(key, sched);
193 pcbc_encrypt(message->sealed, decrypt, message->sealed_len, sched, key, 0);
194
195#ifdef notdef
196 for (i = 0; i < message->sealed_len; i++) {
197 printf("%02x ", (unsigned char)decrypt[i]);
198 }
199 printf("\n");
200 for (i = 0; i < message->sealed_len; i++) {
201 if (isprint(decrypt[i]))
202 printf("%c ", (unsigned char)decrypt[i]);
203 else printf(". ");
204 }
205 printf("\n");
206#endif notdef
207 (void) strncpy(idnumber, decrypt, message->sealed_len);
208 temp = decrypt + strlen(idnumber) + 1;
209 len = message->sealed_len - (temp - decrypt);
210
211 (void) strncpy(hashid, temp, min(len, 14));
212 temp += strlen(hashid) + 1;
213 len = message->sealed_len - (temp - decrypt);
214
215 if (strcmp(hashid, db_mit_id)) return 1;
216 encrypt_mitid(recrypt, idnumber, first, last);
217 if (strcmp(recrypt, db_mit_id)) return 1;
218
219 reg_misc = temp;
220 reg_misc_len = len;
221 mit_id = hashid;
47baf534 222 return 0;
223}
224
f46fccfa 225static int status_in_db;
226
47baf534 227vfy_callbk(argc, argv, p_message)
228 int argc; /* Should sanity check this.. */
229 char **argv;
230 char *p_message;
231{
232 struct msg *message = (struct msg *)p_message;
233 char *db_mit_id;
234 char *firstname, *lastname;
235 int status;
236
f46fccfa 237#ifdef debug
47baf534 238 printf("Callback: %s %s %s\n", argv[8], argv[5], argv[4]);
f46fccfa 239#endif debug
47baf534 240 if (got_one) return 0;
241 reg_status = 0;
242
243 db_mit_id = argv[8];
244 firstname = argv[5];
245 lastname = argv[4];
246
247 status = validate_idno(message, db_mit_id, firstname, lastname);
248 if (status) return 0; /* Nope; decryption failed */
f46fccfa 249
250 status_in_db = atoi(argv[7]);
251 reg_status = status_in_db;
252
253 if (status_in_db != 0) {
47baf534 254 (void) strcpy(retval, argv[0]);
255 }
f46fccfa 256 user_id = atoi(argv[1]);
47baf534 257 got_one = 1;
258 return 0;
259}
260
261encrypt_mitid(buf, idnumber, first, last)
262 char *buf, *idnumber, *first, *last;
263{
264 char salt[3];
265 extern char *crypt();
266
267#define _tolower(c) ((c)|0x60)
268
269 salt[0] = _tolower(last[0]);
270 salt[1] = _tolower(first[0]);
271 salt[2] = 0;
272
273 (void) strcpy(buf, crypt(&idnumber[2], salt));
274}
275
276int verify_user(message)
277 struct msg *message;
278
279{
280 char *argv[3];
281 int status;
282
283 printf("verify_user\n");
284 argv[0] = "get_user_by_first_and_last";
285 argv[1] = message->first;
286 argv[2] = message->last;
287 got_one = 0;
288
289 status = sms_query_internal(3, argv, vfy_callbk, (char *)message);
290
291 if (status == SMS_NO_MATCH) status = UREG_USER_NOT_FOUND;
292 if (!got_one && !status)
293 status = UREG_USER_NOT_FOUND;
294
295 if (status != 0) goto punt;
296
f46fccfa 297 if (reg_status == 1) status = UREG_ALREADY_REGISTERED;
298 if (reg_status == 2) status = UREG_NO_PASSWD_YET;
47baf534 299
300punt:
301 return status;
302}
303
304reserve_user(message)
305 struct msg *message;
306{
307 char *argv[3];
308 int status;
309 int i;
310 char *login;
f46fccfa 311 char uid_buf[20];
47baf534 312
f46fccfa 313 STAMP;
47baf534 314 printf("reserve_user\n");
315
316 argv[0] = "gufl"; /* get_user_by_first_and_last */
317 argv[1] = message->first;
318 argv[2] = message->last;
319 got_one = 0;
f46fccfa 320
47baf534 321 status = sms_query_internal(3, argv, vfy_callbk, (char *)message);
322
f46fccfa 323 STAMP;
324
47baf534 325 if (status == SMS_NO_MATCH) status = UREG_USER_NOT_FOUND;
326 if (!got_one && !status)
327 status = UREG_USER_NOT_FOUND;
328
329 if (status != 0) goto punt;
330 if (reg_status != 0) {
f46fccfa 331 status = UREG_ALREADY_REGISTERED;
332 goto punt;
333 }
334 /*
335 * He's made it past this phase already.
336 */
337 if (status_in_db == 2) {
338 status = 0;
47baf534 339 goto punt;
340 }
47baf534 341 /* Sanity check requested login name. */
342 printf("reg_misc_len = %d\n", reg_misc_len);
343
344 for (i = 0; i < reg_misc_len && reg_misc[i]; i++) {
345 if (!islower(reg_misc[i])) {
346 status = UREG_INVALID_UNAME;
347 goto punt;
348 }
349 }
350 if (i < 3 || i > 8) {
351 status = UREG_INVALID_UNAME;
352 goto punt;
353 }
354 login = reg_misc;
355
356 /* Send request to kerberos admin_server for login name */
f46fccfa 357 /* get keys */
358 printf("get_svc_in_tkt\n");
359 status = get_svc_in_tkt("register", "kerberos", "ATHENA.MIT.EDU",
360 "changepw", "kerberos",
361 1, "/etc/srvtab");
362 if (status) {
363 status += krb_err_base;
364 goto punt;
365 }
366 STAMP;
367
368 printf("admin_call\n");
369 /* send set password request to kerberos admin_server */
370 (void) sprintf(uid_buf, "%013d", user_id); /* 13 chars of placebo */
371 /* for backwards-compat. */
372
373 status = admin_call(ADMIN_ADD_NEW_KEY_ATTR, login, "",
374 "", uid_buf);
47baf534 375
f46fccfa 376 if (status) {
377 if (status == ADMIN_SERVER_ERROR) {
378 printf("Server error: %s\n", admin_errmsg);
379
380 if (strcmp(admin_errmsg,
381 "Principal already in kerberos database.") ==0)
382 status = UREG_LOGIN_USED;
383 }
384 goto punt;
385 }
386
387 dest_tkt();
388 /* If valid: */
389 STAMP;
47baf534 390
f46fccfa 391 /* Set login name */
392 status = set_login(login, mit_id);
78eff417 393
394
f46fccfa 395 if (status) {
396 com_err("set_login", status, 0);
397 goto punt;
398 }
47baf534 399 /* choose post office */
f46fccfa 400 STAMP;
401
402 status = choose_pobox(login);
403 if (status) {
404 com_err("choose_pobox", status, 0);
405 goto punt;
406 }
78eff417 407 /* create group */
f46fccfa 408 STAMP;
409
78eff417 410 status = create_group(login);
411 if (status == SMS_LIST) status = UREG_LOGIN_USED;
412
f46fccfa 413 if (status) {
78eff417 414 com_err("create_group", status, 0);
f46fccfa 415 goto punt;
416 }
78eff417 417 /* set quota entry, create filsys */
f46fccfa 418 STAMP;
419
78eff417 420 status = alloc_filsys(login, SMS_FS_STUDENT, 0, 0);
421 if (status == SMS_FILESYS_EXISTS) status = UREG_LOGIN_USED;
f46fccfa 422 if (status) {
78eff417 423 com_err("alloc_filsys", status, 0);
f46fccfa 424 goto punt;
425 }
47baf534 426 /* set filsys and status in SMS database */
f46fccfa 427 STAMP;
47baf534 428
f46fccfa 429 status = set_status_filsys(reg_misc, mit_id);
430 if (status) {
431 com_err("set_filsys", status, 0);
432 goto punt;
433 }
47baf534 434punt:
f46fccfa 435 dest_tkt();
436 STAMP;
47baf534 437 printf("reserve_user returning %s\n", error_message(status));
438 return status;
439}
440
f46fccfa 441set_password(message)
442 struct msg *message;
47baf534 443{
f46fccfa 444 char *argv[3];
445 int status;
446
447 printf("set_password\n");
47baf534 448
f46fccfa 449 /* validate that user is who he claims to be */
47baf534 450
f46fccfa 451 argv[0] = "get_user_by_first_and_last";
452 argv[1] = message->first;
453 argv[2] = message->last;
454 got_one = 0;
455
456 status = sms_query_internal(3, argv, vfy_callbk, (char *)message);
457
458 if (status == SMS_NO_MATCH) status = UREG_USER_NOT_FOUND;
459 if (!got_one && !status)
460 status = UREG_USER_NOT_FOUND;
47baf534 461
f46fccfa 462 if (status != 0) goto punt;
463
464 /* validate that state is equal to '2' (login, but no password) */
465
466 if (reg_status != 2) {
467 status = UREG_NO_LOGIN_YET;
468 goto punt;
47baf534 469 }
47baf534 470
f46fccfa 471 printf("password for %s would be set to %s\n", retval ,reg_misc);
472
473 /* get keys */
474 status = get_svc_in_tkt("register", "kerberos", "ATHENA.MIT.EDU",
475 "changepw", "kerberos",
476 1, "/etc/srvtab");
477 if (status) {
478 status += krb_err_base;
479 goto punt;
47baf534 480 }
f46fccfa 481 /* send set password request to kerberos admin_server */
482 status = admin_call(ADMIN_SET_KDC_PASSWORD, retval, "",
483 reg_misc, "BBBBBBBBBBBBB");
47baf534 484
f46fccfa 485 if (status) goto punt;
486 dest_tkt();
47baf534 487
f46fccfa 488 status = set_final_status(retval, mit_id);
489
490 /* reflect reply to client */
491punt:
492 dest_tkt();
47baf534 493 return status;
494}
495
47baf534 496parse_pkt(buf, len, seqnop, messagep)
497 char *buf;
498 int len;
499 u_long *seqnop;
500 struct msg *messagep;
501{
502 if (len < 4) return UREG_BROKEN_PACKET;
503 bcopy(buf, (char *)&messagep->version, sizeof(long));
504 messagep->version = ntohl(messagep->version);
505 if (messagep->version != 1) return UREG_WRONG_VERSION;
506
507 buf += 4;
508 len -= 4;
509
510 if (len < 4) return UREG_BROKEN_PACKET;
511 bcopy(buf, (char *)seqnop, sizeof(long));
512
513 buf += 4;
514 len -= 4;
515
516 if (len < 4) return UREG_BROKEN_PACKET;
517 bcopy(buf, (char *)(&messagep->request), sizeof(long));
518 messagep->request = ntohl(messagep->request);
519 buf += 4;
520 len -= 4;
521
522 messagep->first = buf;
523
524 for (; *buf && len > 0; --len, ++buf) continue;
525 if (len <= 0) return UREG_BROKEN_PACKET;
526
527 buf++, len--;
528
529 messagep->last = buf;
530
531 for (; *buf && len > 0; --len, ++buf) continue;
532 if (len <= 0) return UREG_BROKEN_PACKET;
533
534 buf++, len--;
535
536 if (len <= 0) return UREG_BROKEN_PACKET;
537
538 messagep->sealed = buf;
539 messagep->sealed_len = len;
540
541 return 0;
542}
543
544format_pkt(buf, lenp, seqno, status, message)
545 char *buf;
546 int *lenp;
547 u_long seqno;
548 int status;
549 char *message;
550{
551 u_long vers = htonl((u_long)1);
552 status = htonl((u_long)status);
553
554 bcopy((char *)&vers, buf, sizeof(long));
555 bcopy((char *)&seqno, buf+sizeof(long), sizeof(long));
556 bcopy((char *)&status, buf+ 2*sizeof(long), sizeof(long));
557 *lenp = sizeof(long) * 3;
558 (void) strcpy(buf+3*sizeof(long), message);
559 (*lenp) += strlen(message);
560}
561
562store_user(argc, argv, argp)
563 int argc;
564 char **argv;
565 char *argp;
566{
567 char **retv = (char **) argp;
568 int i;
569
570 for (i = 0; i < argc; i++) {
571 if (retv[i]) {
572 free(retv[i]);
573 retv[i]=0;
574 }
575 retv[i] = strdup(argv[i]);
576 }
577 return 0;
578}
579
580
581/*
582 * Set login name of user with "idnumber" to be "username"
583 */
584
585set_login(username, idnumber)
586 char *username;
587 char *idnumber;
588{
589 char *argv[2];
590 int status, i;
f46fccfa 591 char *retv[13];
47baf534 592
593 argv[0] = "get_user_by_mitid";
594 argv[1] = idnumber;
595
f46fccfa 596 for (i=0; i<13; i++) {
47baf534 597 retv[i] = 0;
598 }
599
600 status = sms_query_internal(2, argv, store_user, (char *)(retv+1));
601 if (status) return status;
602
603 retv[0] = retv[1];
604 retv[1] = username;
f46fccfa 605 if (retv[4]) free(retv[4]);
606 retv[4] = "null"; /* No such filesystem */
47baf534 607
608 printf("Update_user(%s, %s)\n", retv[0], retv[1]);
609
610 status = sms_query("update_user", 12, retv, abort, 0);
f46fccfa 611 retv[1] = 0;
612 retv[4] = 0;
613
47baf534 614 for (i=1; i<12; i++) {
615 if (retv[i]) free(retv[i]);
616 retv[i] = 0;
617 }
618
619 return status;
620}
621
622/*
623 * Set the status and filsys of user with username "uname" and filesys filsys.
624 */
625
626set_status_filsys(username, idnumber)
627 char *username;
628 char *idnumber;
629{
630 char *argv[2];
631 int status, i;
f46fccfa 632 char *retv[13];
47baf534 633
634 argv[0] = "get_user_by_mitid";
635 argv[1] = idnumber;
636
f46fccfa 637 for (i=0; i<13; i++) {
47baf534 638 retv[i] = 0;
639 }
640
641 status = sms_query_internal(2, argv, store_user, (char *)(retv+1));
642 if (status) return status;
643
644 retv[0] = retv[1];
645
646 free(retv[4]);
647 retv[4] = username;
648
649 free(retv[8]);
650 retv[8] = "2";
651
652 printf("Update_user(%s, %s)\n", retv[0], retv[1]);
653
654 status = sms_query("update_user", 12, retv, abort, 0);
655 retv[4] = 0;
656 retv[8] = 0;
657 for (i=1; i<12; i++) {
658 if (retv[i]) free(retv[i]);
659 retv[i] = 0;
660 }
661 return status;
662}
f46fccfa 663/*
664 * Set the status and filsys of user with username "uname" and filesys filsys.
665 */
47baf534 666
f46fccfa 667set_final_status(username, idnumber)
668 char *username;
669 char *idnumber;
47baf534 670{
f46fccfa 671 char *argv[2];
672 int status, i;
673 char *retv[13];
674
675 argv[0] = "get_user_by_mitid";
676 argv[1] = idnumber;
677
678 for (i=0; i<13; i++) {
679 retv[i] = 0;
47baf534 680 }
47baf534 681
f46fccfa 682 status = sms_query_internal(2, argv, store_user, (char *)(retv+1));
683 if (status) return status;
684
685 retv[0] = retv[1];
47baf534 686
f46fccfa 687 free(retv[8]);
688 retv[8] = "1";
689
690 printf("Update_user(%s, %s)\n", retv[0], retv[1]);
691
692 status = sms_query("update_user", 12, retv, abort, 0);
693 retv[8] = 0;
694 for (i=1; i<12; i++) {
695 if (retv[i]) free(retv[i]);
696 retv[i] = 0;
697 }
698 return status;
699}
700
701create_group(login)
47baf534 702 char *login;
703{
47baf534 704 int status;
f46fccfa 705 static char *cr[] = {
706 "add_user_group",
707 0,
708 };
47baf534 709
f46fccfa 710 cr[1] = login;
47baf534 711
f46fccfa 712 return sms_query_internal(2, cr, abort, 0);
713}
47baf534 714/*
715 * Local Variables:
716 * mode: c
717 * c-indent-level: 4
718 * c-continued-statement-offset: 4
719 * c-brace-offset: -4
720 * c-argdecl-indent: 4
721 * c-label-offset: -4
722 * End:
723 */
f46fccfa 724char *get_krbhst(a1, a2)
725 char *a1;
726 char *a2;
727{
728 strcpy(a1, "ICARUS.MIT.EDU");
729 return 0;
730}
731
732char *get_krbrlm(a1)
733 char *a1;
734{
735 strcpy(a1, "ATHENA.MIT.EDU");
736 return 0;
737}
738
This page took 0.174044 seconds and 5 git commands to generate.