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