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