6 * Copyright (C) 1987 by the Massachusetts Institute of Technology
8 * Server for user registration with SMS and Kerberos.
10 * This program is a client of the SMS server and the Kerberos
11 * admin_server, and is a server for the userreg program.
14 * Revision 1.1 1987-07-31 15:48:13 wesommer
20 static char *rcsid_reg_svr_c = "$Header$";
24 #include <sys/types.h>
26 #include <sys/socket.h>
27 #include <netinet/in.h>
33 #include "ureg_proto.h"
34 #include "../../include/sms.h"
48 static char retval[BUFSIZ];
50 #if defined(vax) || defined(ibm032) || defined(sun)
51 #define MAXINT 0x7fffffff
53 Hey turkey! What's the biggest integer on this machine?
58 struct sockaddr_in sin;
70 status = sms_connect();
72 com_err("reg_svr", status, "");
77 com_err("reg_svr", status, "");
81 sp = getservbyname("sms_ureg", "udp");
83 fprintf(stderr, "Unknown service sms_ureg/udp\n");
86 s = socket(AF_INET, SOCK_DGRAM, 0);
91 bzero((char *)&sin, sizeof(sin));
93 sin.sin_family = AF_INET;
94 sin.sin_port = sp->s_port;
95 sin.sin_addr.s_addr = INADDR_ANY;
97 if (bind(s, &sin, sizeof(sin)) < 0) {
103 addrlen = sizeof(sin);
104 bzero(retval, BUFSIZ);
105 len = recvfrom(s, buf, BUFSIZ, 0, &sin, &addrlen);
108 if (errno == EINTR) continue;
112 /* Parse a request packet */
113 status = parse_pkt(buf, len, &seqno, &message);
116 format_pkt(buf, &len, seqno, status, (char *)NULL);
117 (void) sendto(s, buf, len, 0, &sin, addrlen);
121 switch((int)message.request) {
122 case UREG_VERIFY_USER:
123 status = verify_user(&message);
125 case UREG_RESERVE_LOGIN:
126 status = reserve_user(&message);
128 case UREG_SET_PASSWORD:
129 status = set_password(&message);
133 status = UREG_UNKNOWN_REQUEST;
137 format_pkt(buf, &len, seqno, status, retval);
139 sendto(s, buf, len, 0, &sin, addrlen);
143 set_password(message)
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 */
158 #define min(a,b) ((a)>(b)?(b):(a))
160 int validate_idno(message, db_mit_id, first, last)
167 char decrypt[BUFSIZ];
169 static char hashid[14];
170 char idnumber[BUFSIZ];
176 for (i = 0; i < message->sealed_len; i++) {
177 printf("%02x ", (unsigned char)message->sealed[i]);
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);
188 for (i = 0; i < message->sealed_len; i++) {
189 printf("%02x ", (unsigned char)decrypt[i]);
192 for (i = 0; i < message->sealed_len; i++) {
193 if (isprint(decrypt[i]))
194 printf("%c ", (unsigned char)decrypt[i]);
199 (void) strncpy(idnumber, decrypt, message->sealed_len);
200 temp = decrypt + strlen(idnumber) + 1;
201 len = message->sealed_len - (temp - decrypt);
203 (void) strncpy(hashid, temp, min(len, 14));
204 temp += strlen(hashid) + 1;
205 len = message->sealed_len - (temp - decrypt);
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;
218 vfy_callbk(argc, argv, p_message)
219 int argc; /* Should sanity check this.. */
223 struct msg *message = (struct msg *)p_message;
225 char *firstname, *lastname;
228 printf("Callback: %s %s %s\n", argv[8], argv[5], argv[4]);
230 if (got_one) return 0;
237 status = validate_idno(message, db_mit_id, firstname, lastname);
238 if (status) return 0; /* Nope; decryption failed */
240 if (atoi(argv[7]) == 1) {
241 reg_status = UREG_ALREADY_REGISTERED;
242 (void) strcpy(retval, argv[0]);
248 encrypt_mitid(buf, idnumber, first, last)
249 char *buf, *idnumber, *first, *last;
252 extern char *crypt();
254 #define _tolower(c) ((c)|0x60)
256 salt[0] = _tolower(last[0]);
257 salt[1] = _tolower(first[0]);
260 (void) strcpy(buf, crypt(&idnumber[2], salt));
263 int verify_user(message)
270 printf("verify_user\n");
271 argv[0] = "get_user_by_first_and_last";
272 argv[1] = message->first;
273 argv[2] = message->last;
276 status = sms_query_internal(3, argv, vfy_callbk, (char *)message);
278 if (status == SMS_NO_MATCH) status = UREG_USER_NOT_FOUND;
279 if (!got_one && !status)
280 status = UREG_USER_NOT_FOUND;
282 if (status != 0) goto punt;
284 if (reg_status != 0) status = reg_status;
290 reserve_user(message)
298 printf("reserve_user\n");
300 argv[0] = "gufl"; /* get_user_by_first_and_last */
301 argv[1] = message->first;
302 argv[2] = message->last;
305 status = sms_query_internal(3, argv, vfy_callbk, (char *)message);
307 if (status == SMS_NO_MATCH) status = UREG_USER_NOT_FOUND;
308 if (!got_one && !status)
309 status = UREG_USER_NOT_FOUND;
311 if (status != 0) goto punt;
312 if (reg_status != 0) {
317 /* Sanity check requested login name. */
318 printf("reg_misc_len = %d\n", reg_misc_len);
320 for (i = 0; i < reg_misc_len && reg_misc[i]; i++) {
321 if (!islower(reg_misc[i])) {
322 status = UREG_INVALID_UNAME;
326 if (i < 3 || i > 8) {
327 status = UREG_INVALID_UNAME;
332 /* Send request to kerberos admin_server for login name */
336 set_login(login, mit_id);
338 /* choose post office */
341 /* set quota entry, create filsys */
344 /* set filsys and status in SMS database */
345 set_status_filsys(reg_misc, mit_id);
348 printf("reserve_user returning %s\n", error_message(status));
352 extern char *malloc();
357 int len = strlen(cp) + 1;
358 char *np = malloc(len);
364 static int min_usage;
366 static po_callbk(argc, argv, argp)
370 if (!isdigit(*argv[6])) {
371 printf("non-digit value_1 field??\n");
375 if (atoi(argv[6]) < min_usage) {
376 min_usage = atoi(argv[6]);
377 if (pohost) free(pohost);
378 pohost = strdup(argv[1]);
388 static char *argv[3]={
393 static char *apoa[5] = {
402 min_usage = MAXINT; /* MAXINT */
403 status = sms_query_internal(3, argv, po_callbk,(char *)&min_usage);
405 com_err("reg_svr", status, "finding pobox");
406 printf("Can't find postoffices\n");
409 printf("Chose %s\n", pohost);
410 apoa[1] = apoa[4] = login;
412 status = sms_query_internal(5, apoa, abort, 0);
414 if (status == SMS_EXISTS) status = 0;
417 com_err("reg_svr", status, "adding pobox");
423 parse_pkt(buf, len, seqnop, messagep)
427 struct msg *messagep;
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;
437 if (len < 4) return UREG_BROKEN_PACKET;
438 bcopy(buf, (char *)seqnop, sizeof(long));
443 if (len < 4) return UREG_BROKEN_PACKET;
444 bcopy(buf, (char *)(&messagep->request), sizeof(long));
445 messagep->request = ntohl(messagep->request);
449 messagep->first = buf;
451 for (; *buf && len > 0; --len, ++buf) continue;
452 if (len <= 0) return UREG_BROKEN_PACKET;
456 messagep->last = buf;
458 for (; *buf && len > 0; --len, ++buf) continue;
459 if (len <= 0) return UREG_BROKEN_PACKET;
463 if (len <= 0) return UREG_BROKEN_PACKET;
465 messagep->sealed = buf;
466 messagep->sealed_len = len;
471 format_pkt(buf, lenp, seqno, status, message)
478 u_long vers = htonl((u_long)1);
479 status = htonl((u_long)status);
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);
489 store_user(argc, argv, argp)
494 char **retv = (char **) argp;
497 for (i = 0; i < argc; i++) {
502 retv[i] = strdup(argv[i]);
509 * Set login name of user with "idnumber" to be "username"
512 set_login(username, idnumber)
520 argv[0] = "get_user_by_mitid";
523 for (i=0; i<12; i++) {
527 status = sms_query_internal(2, argv, store_user, (char *)(retv+1));
528 if (status) return status;
533 printf("Update_user(%s, %s)\n", retv[0], retv[1]);
535 status = sms_query("update_user", 12, retv, abort, 0);
536 for (i=1; i<12; i++) {
537 if (retv[i]) free(retv[i]);
545 * Set the status and filsys of user with username "uname" and filesys filsys.
548 set_status_filsys(username, idnumber)
556 argv[0] = "get_user_by_mitid";
559 for (i=0; i<12; i++) {
563 status = sms_query_internal(2, argv, store_user, (char *)(retv+1));
564 if (status) return status;
574 printf("Update_user(%s, %s)\n", retv[0], retv[1]);
576 status = sms_query("update_user", 12, retv, abort, 0);
579 for (i=1; i<12; i++) {
580 if (retv[i]) free(retv[i]);
586 static char *nfs_device;
587 static char *nfs_dir;
588 static char *nfs_host;
589 static int nfs_alloc;
592 static afcb(argc, argv, argp)
597 if ((atoi(argv[3]) & 1) == 0) return 0; /* not free for alloc. */
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]);
612 * Allocate home filesystem.
618 static char *argv[] = {
621 static char *alocv[] = {
632 status = sms_query_internal(1, argv, afcb, 0);
634 com_err("reg_svr", status, "while doing get_all_nfsphys");
639 alocv[3] = nfs_device;
640 printf("add_locker(%s, %s, %s)\n", login, nfs_host, nfs_device);
642 status = sms_query_internal(5, alocv, abort, 0);
644 com_err("reg_svr", status, "while adding locker");
653 * c-continued-statement-offset: 4
655 * c-argdecl-indent: 4