|
|
1.1 root 1: /*
2: * $Source: /usr/src/kerberosIV/kerberos/RCS/kerberos.c,v $
3: * $Author: kfall $
4: *
5: * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
6: * of Technology.
7: *
8: * For copying and distribution information, please see the file
9: * <mit-copyright.h>.
10: */
11:
12: #ifndef lint
13: static char *rcsid_kerberos_c =
14: "$Header: /usr/src/kerberosIV/kerberos/RCS/kerberos.c,v 4.20 90/06/25 20:59:31 kfall Exp $";
15: #endif lint
16:
17: #include <mit-copyright.h>
18: #include <stdio.h>
19: #include <sys/types.h>
20: #include <sys/socket.h>
21: #include <netinet/in.h>
22: #include <netdb.h>
23: #include <signal.h>
24: #include <sgtty.h>
25: #include <sys/ioctl.h>
26: #include <sys/time.h>
27: #include <sys/file.h>
28: #include <ctype.h>
29:
30: #include <des.h>
31: #include <krb.h>
32: #include <klog.h>
33: #include <prot.h>
34: #include <krb_db.h>
35: #include <kdc.h>
36:
37: extern int errno;
38:
39: struct sockaddr_in sin = {AF_INET};
40: int f;
41:
42: /* XXX several files in libkdb know about this */
43: char *progname;
44:
45: static Key_schedule master_key_schedule;
46: static C_Block master_key;
47:
48: static struct timeval kerb_time;
49: static Principal a_name_data; /* for requesting user */
50: static Principal s_name_data; /* for services requested */
51: static C_Block session_key;
52: static C_Block user_key;
53: static C_Block service_key;
54: static u_char master_key_version;
55: static char k_instance[INST_SZ];
56: static char log_text[128];
57: static char *lt;
58: static int more;
59:
60: static int mflag; /* Are we invoked manually? */
61: static int lflag; /* Have we set an alterate log file? */
62: static char *log_file; /* name of alt. log file */
63: static int nflag; /* don't check max age */
64: static int rflag; /* alternate realm specified */
65:
66: /* fields within the received request packet */
67: static u_char req_msg_type;
68: static u_char req_version;
69: static char *req_name_ptr;
70: static char *req_inst_ptr;
71: static char *req_realm_ptr;
72: static u_char req_no_req;
73: static u_long req_time_ws;
74:
75: int req_act_vno = KRB_PROT_VERSION; /* Temporary for version skew */
76:
77: static char local_realm[REALM_SZ];
78:
79: /* statistics */
80: static long q_bytes; /* current bytes remaining in queue */
81: static long q_n; /* how many consecutive non-zero
82: * q_bytes */
83: static long max_q_bytes;
84: static long max_q_n;
85: static long n_auth_req;
86: static long n_appl_req;
87: static long n_packets;
88: static long n_user;
89: static long n_server;
90:
91: extern char *sys_errlist[];
92: static long max_age = -1;
93: static long pause_int = -1;
94:
95: static void check_db_age();
96: static void hang();
97:
98: /*
99: * Print usage message and exit.
100: */
101: static void usage()
102: {
103: fprintf(stderr, "Usage: %s [-s] [-m] [-n] [-p pause_seconds]%s%s\n", progname,
104: " [-a max_age] [-l log_file] [-r realm]"
105: ," [database_pathname]"
106: );
107: exit(1);
108: }
109:
110:
111: main(argc, argv)
112: int argc;
113: char **argv;
114: {
115: struct sockaddr_in from;
116: register int n;
117: int on = 1;
118: int child;
119: struct servent *sp;
120: int fromlen;
121: static KTEXT_ST pkt_st;
122: KTEXT pkt = &pkt_st;
123: Principal *p;
124: int more, kerror;
125: C_Block key;
126: int c;
127: extern char *optarg;
128: extern int optind;
129:
130: progname = argv[0];
131:
132: while ((c = getopt(argc, argv, "snmp:a:l:r:")) != EOF) {
133: switch(c) {
134: case 's':
135: /*
136: * Set parameters to slave server defaults.
137: */
138: if (max_age == -1 && !nflag)
139: max_age = ONE_DAY; /* 24 hours */
140: if (pause_int == -1)
141: pause_int = FIVE_MINUTES; /* 5 minutes */
142: if (lflag == 0) {
143: log_file = KRBSLAVELOG;
144: lflag++;
145: }
146: break;
147: case 'n':
148: max_age = -1; /* don't check max age. */
149: nflag++;
150: break;
151: case 'm':
152: mflag++; /* running manually; prompt for master key */
153: break;
154: case 'p':
155: /* Set pause interval. */
156: if (!isdigit(optarg[0]))
157: usage();
158: pause_int = atoi(optarg);
159: if ((pause_int < 5) || (pause_int > ONE_HOUR)) {
160: fprintf(stderr, "pause_int must be between 5 and 3600 seconds.\n");
161: usage();
162: }
163: break;
164: case 'a':
165: /* Set max age. */
166: if (!isdigit(optarg[0]))
167: usage();
168: max_age = atoi(optarg);
169: if ((max_age < ONE_HOUR) || (max_age > THREE_DAYS)) {
170: fprintf(stderr, "max_age must be between one hour and three days, in seconds\n");
171: usage();
172: }
173: break;
174: case 'l':
175: /* Set alternate log file */
176: lflag++;
177: log_file = optarg;
178: break;
179: case 'r':
180: /* Set realm name */
181: rflag++;
182: strcpy(local_realm, optarg);
183: break;
184: default:
185: usage();
186: break;
187: }
188: }
189:
190: if (optind == (argc-1)) {
191: if (kerb_db_set_name(argv[optind]) != 0) {
192: fprintf(stderr, "Could not set alternate database name\n");
193: exit(1);
194: }
195: optind++;
196: }
197:
198: if (optind != argc)
199: usage();
200:
201: printf("Kerberos server starting\n");
202:
203: if ((!nflag) && (max_age != -1))
204: printf("\tMaximum database age: %d seconds\n", max_age);
205: if (pause_int != -1)
206: printf("\tSleep for %d seconds on error\n", pause_int);
207: else
208: printf("\tSleep forever on error\n");
209: if (mflag)
210: printf("\tMaster key will be entered manually\n");
211:
212: printf("\tLog file is %s\n", lflag ? log_file : KRBLOG);
213:
214: if (lflag)
215: kset_logfile(log_file);
216:
217: /* find our hostname, and use it as the instance */
218: if (gethostname(k_instance, INST_SZ)) {
219: fprintf(stderr, "%s: gethostname error\n", progname);
220: exit(1);
221: }
222:
223: if ((sp = getservbyname("kerberos", "udp")) == 0) {
224: fprintf(stderr, "%s: udp/kerberos unknown service\n", progname);
225: exit(1);
226: }
227: sin.sin_port = sp->s_port;
228:
229: if ((f = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
230: fprintf(stderr, "%s: Can't open socket\n", progname);
231: exit(1);
232: }
233: if (setsockopt(f, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
234: fprintf(stderr, "%s: setsockopt (SO_REUSEADDR)\n", progname);
235:
236: if (bind(f, &sin, S_AD_SZ, 0) < 0) {
237: fprintf(stderr, "%s: Can't bind socket\n", progname);
238: exit(1);
239: }
240: /* do all the database and cache inits */
241: if (n = kerb_init()) {
242: if (mflag) {
243: printf("Kerberos db and cache init ");
244: printf("failed = %d ...exiting\n", n);
245: exit(-1);
246: } else {
247: klog(L_KRB_PERR,
248: "Kerberos db and cache init failed = %d ...exiting", n);
249: hang();
250: }
251: }
252:
253: /* Make sure database isn't stale */
254: check_db_age();
255:
256: /* setup master key */
257: if (kdb_get_master_key (mflag, master_key, master_key_schedule) != 0) {
258: klog (L_KRB_PERR, "kerberos: couldn't get master key.\n");
259: exit (-1);
260: }
261: kerror = kdb_verify_master_key (master_key, master_key_schedule, stdout);
262: if (kerror < 0) {
263: klog (L_KRB_PERR, "Can't verify master key.");
264: bzero (master_key, sizeof (master_key));
265: bzero (master_key_schedule, sizeof (master_key_schedule));
266: exit (-1);
267: }
268:
269: master_key_version = (u_char) kerror;
270:
271: fprintf(stdout, "\nCurrent Kerberos master key version is %d\n",
272: master_key_version);
273:
274: if (!rflag) {
275: /* Look up our local realm */
276: krb_get_lrealm(local_realm, 1);
277: }
278: fprintf(stdout, "Local realm: %s\n", local_realm);
279: fflush(stdout);
280:
281: if (set_tgtkey(local_realm)) {
282: /* Ticket granting service unknown */
283: klog(L_KRB_PERR, "Ticket granting ticket service unknown");
284: fprintf(stderr, "Ticket granting ticket service unknown\n");
285: exit(1);
286: }
287: if (mflag) {
288: if ((child = fork()) != 0) {
289: printf("Kerberos started, PID=%d\n", child);
290: exit(0);
291: }
292: setup_disc();
293: }
294: /* receive loop */
295: for (;;) {
296: fromlen = S_AD_SZ;
297: n = recvfrom(f, pkt->dat, MAX_PKT_LEN, 0, &from, &fromlen);
298: if (n > 0) {
299: pkt->length = n;
300: pkt->mbz = 0; /* force zeros to catch runaway strings */
301: /* see what is left in the input queue */
302: ioctl(f, FIONREAD, &q_bytes);
303: gettimeofday(&kerb_time, NULL);
304: q_n++;
305: max_q_n = max(max_q_n, q_n);
306: n_packets++;
307: klog(L_NET_INFO,
308: "q_byt %d, q_n %d, rd_byt %d, mx_q_b %d, mx_q_n %d, n_pkt %d",
309: q_bytes, q_n, n, max_q_bytes, max_q_n, n_packets, 0);
310: max_q_bytes = max(max_q_bytes, q_bytes);
311: if (!q_bytes)
312: q_n = 0; /* reset consecutive packets */
313: kerberos(&from, pkt);
314: } else
315: klog(L_NET_ERR,
316: "%s: bad recvfrom n = %d errno = %d", progname, n, errno, 0);
317: }
318: }
319:
320:
321: kerberos(client, pkt)
322: struct sockaddr_in *client;
323: KTEXT pkt;
324: {
325: static KTEXT_ST rpkt_st;
326: KTEXT rpkt = &rpkt_st;
327: static KTEXT_ST ciph_st;
328: KTEXT ciph = &ciph_st;
329: static KTEXT_ST tk_st;
330: KTEXT tk = &tk_st;
331: static KTEXT_ST auth_st;
332: KTEXT auth = &auth_st;
333: AUTH_DAT ad_st;
334: AUTH_DAT *ad = &ad_st;
335:
336:
337: static struct in_addr client_host;
338: static int msg_byte_order;
339: static int swap_bytes;
340: static u_char k_flags;
341: char *p_name, *instance;
342: u_long lifetime;
343: int i;
344: C_Block key;
345: Key_schedule key_s;
346: char *ptr;
347:
348:
349:
350: ciph->length = 0;
351:
352: client_host = client->sin_addr;
353:
354: /* eval macros and correct the byte order and alignment as needed */
355: req_version = pkt_version(pkt); /* 1 byte, version */
356: req_msg_type = pkt_msg_type(pkt); /* 1 byte, Kerberos msg type */
357:
358: req_act_vno = req_version;
359:
360: /* check packet version */
361: if (req_version != KRB_PROT_VERSION) {
362: lt = klog(L_KRB_PERR,
363: "KRB prot version mismatch: KRB =%d request = %d",
364: KRB_PROT_VERSION, req_version, 0);
365: /* send an error reply */
366: kerb_err_reply(client, pkt, KERB_ERR_PKT_VER, lt);
367: return;
368: }
369: msg_byte_order = req_msg_type & 1;
370:
371: swap_bytes = 0;
372: if (msg_byte_order != HOST_BYTE_ORDER) {
373: swap_bytes++;
374: }
375: klog(L_KRB_PINFO,
376: "Prot version: %d, Byte order: %d, Message type: %d",
377: req_version, msg_byte_order, req_msg_type);
378:
379: switch (req_msg_type & ~1) {
380:
381: case AUTH_MSG_KDC_REQUEST:
382: {
383: u_long time_ws; /* Workstation time */
384: u_long req_life; /* Requested liftime */
385: char *service; /* Service name */
386: char *instance; /* Service instance */
387: int kerno; /* Kerberos error number */
388: n_auth_req++;
389: tk->length = 0;
390: k_flags = 0; /* various kerberos flags */
391:
392:
393: /* set up and correct for byte order and alignment */
394: req_name_ptr = (char *) pkt_a_name(pkt);
395: req_inst_ptr = (char *) pkt_a_inst(pkt);
396: req_realm_ptr = (char *) pkt_a_realm(pkt);
397: bcopy(pkt_time_ws(pkt), &req_time_ws, sizeof(req_time_ws));
398: /* time has to be diddled */
399: if (swap_bytes) {
400: swap_u_long(req_time_ws);
401: }
402: ptr = (char *) pkt_time_ws(pkt) + 4;
403:
404: req_life = (u_long) (*ptr++);
405:
406: service = ptr;
407: instance = ptr + strlen(service) + 1;
408:
409: rpkt = &rpkt_st;
410: klog(L_INI_REQ,
411: "Initial ticket request Host: %s User: \"%s\" \"%s\"",
412: inet_ntoa(client_host), req_name_ptr, req_inst_ptr, 0);
413:
414: if (i = check_princ(req_name_ptr, req_inst_ptr, 0,
415: &a_name_data)) {
416: kerb_err_reply(client, pkt, i, lt);
417: return;
418: }
419: tk->length = 0; /* init */
420: if (strcmp(service, "krbtgt"))
421: klog(L_NTGT_INTK,
422: "INITIAL request from %s.%s for %s.%s",
423: req_name_ptr, req_inst_ptr, service, instance, 0);
424: /* this does all the checking */
425: if (i = check_princ(service, instance, lifetime,
426: &s_name_data)) {
427: kerb_err_reply(client, pkt, i, lt);
428: return;
429: }
430: /* Bound requested lifetime with service and user */
431: lifetime = min(req_life, ((u_long) s_name_data.max_life));
432: lifetime = min(lifetime, ((u_long) a_name_data.max_life));
433: #ifdef NOENCRYPTION
434: bzero(session_key, sizeof(C_Block));
435: #else
436: /* random session key */
437: random_key(session_key);
438: #endif
439:
440: /* unseal server's key from master key */
441: bcopy(&s_name_data.key_low, key, 4);
442: bcopy(&s_name_data.key_high, ((long *) key) + 1, 4);
443: kdb_encrypt_key(key, key, master_key,
444: master_key_schedule, DECRYPT);
445: /* construct and seal the ticket */
446: krb_create_ticket(tk, k_flags, a_name_data.name,
447: a_name_data.instance, local_realm,
448: client_host.s_addr, session_key, lifetime, kerb_time.tv_sec,
449: s_name_data.name, s_name_data.instance, key);
450: bzero(key, sizeof(key));
451: bzero(key_s, sizeof(key_s));
452:
453: /*
454: * get the user's key, unseal it from the server's key, and
455: * use it to seal the cipher
456: */
457:
458: /* a_name_data.key_low a_name_data.key_high */
459: bcopy(&a_name_data.key_low, key, 4);
460: bcopy(&a_name_data.key_high, ((long *) key) + 1, 4);
461:
462: /* unseal the a_name key from the master key */
463: kdb_encrypt_key(key, key, master_key,
464: master_key_schedule, DECRYPT);
465:
466: create_ciph(ciph, session_key, s_name_data.name,
467: s_name_data.instance, local_realm, lifetime,
468: s_name_data.key_version, tk, kerb_time.tv_sec, key);
469:
470: /* clear session key */
471: bzero(session_key, sizeof(session_key));
472:
473: bzero(key, sizeof(key));
474:
475:
476:
477: /* always send a reply packet */
478: rpkt = create_auth_reply(req_name_ptr, req_inst_ptr,
479: req_realm_ptr, req_time_ws, 0, a_name_data.exp_date,
480: a_name_data.key_version, ciph);
481: sendto(f, rpkt->dat, rpkt->length, 0, client, S_AD_SZ);
482: bzero(&a_name_data, sizeof(a_name_data));
483: bzero(&s_name_data, sizeof(s_name_data));
484: break;
485: }
486: case AUTH_MSG_APPL_REQUEST:
487: {
488: u_long time_ws; /* Workstation time */
489: u_long req_life; /* Requested liftime */
490: char *service; /* Service name */
491: char *instance; /* Service instance */
492: int kerno; /* Kerberos error number */
493: char tktrlm[REALM_SZ];
494:
495: n_appl_req++;
496: tk->length = 0;
497: k_flags = 0; /* various kerberos flags */
498:
499: auth->length = 4 + strlen(pkt->dat + 3);
500: auth->length += (int) *(pkt->dat + auth->length) +
501: (int) *(pkt->dat + auth->length + 1) + 2;
502:
503: bcopy(pkt->dat, auth->dat, auth->length);
504:
505: strncpy(tktrlm, auth->dat + 3, REALM_SZ);
506: if (set_tgtkey(tktrlm)) {
507: lt = klog(L_ERR_UNK,
508: "FAILED realm %s unknown. Host: %s ",
509: tktrlm, inet_ntoa(client_host));
510: kerb_err_reply(client, pkt, kerno, lt);
511: return;
512: }
513: kerno = krb_rd_req(auth, "ktbtgt", tktrlm, client_host.s_addr,
514: ad, 0);
515:
516: if (kerno) {
517: klog(L_ERR_UNK, "FAILED krb_rd_req from %s: %s",
518: inet_ntoa(client_host), krb_err_txt[kerno]);
519: kerb_err_reply(client, pkt, kerno, "krb_rd_req failed");
520: return;
521: }
522: ptr = (char *) pkt->dat + auth->length;
523:
524: bcopy(ptr, &time_ws, 4);
525: ptr += 4;
526:
527: req_life = (u_long) (*ptr++);
528:
529: service = ptr;
530: instance = ptr + strlen(service) + 1;
531:
532: klog(L_APPL_REQ, "APPL Request %s.%s@%s on %s for %s.%s",
533: ad->pname, ad->pinst, ad->prealm, inet_ntoa(client_host),
534: service, instance, 0);
535:
536: if (strcmp(ad->prealm, tktrlm)) {
537: kerb_err_reply(client, pkt, KERB_ERR_PRINCIPAL_UNKNOWN,
538: "Can't hop realms");
539: return;
540: }
541: if (!strcmp(service, "changepw")) {
542: kerb_err_reply(client, pkt, KERB_ERR_PRINCIPAL_UNKNOWN,
543: "Can't authorize password changed based on TGT");
544: return;
545: }
546: kerno = check_princ(service, instance, req_life,
547: &s_name_data);
548: if (kerno) {
549: kerb_err_reply(client, pkt, kerno, lt);
550: return;
551: }
552: /* Bound requested lifetime with service and user */
553: lifetime = min(req_life,
554: (ad->life - ((kerb_time.tv_sec - ad->time_sec) / 300)));
555: lifetime = min(lifetime, ((u_long) s_name_data.max_life));
556:
557: /* unseal server's key from master key */
558: bcopy(&s_name_data.key_low, key, 4);
559: bcopy(&s_name_data.key_high, ((long *) key) + 1, 4);
560: kdb_encrypt_key(key, key, master_key,
561: master_key_schedule, DECRYPT);
562: /* construct and seal the ticket */
563:
564: #ifdef NOENCRYPTION
565: bzero(session_key, sizeof(C_Block));
566: #else
567: /* random session key */
568: random_key(session_key);
569: #endif
570:
571: krb_create_ticket(tk, k_flags, ad->pname, ad->pinst,
572: ad->prealm, client_host.s_addr,
573: session_key, lifetime, kerb_time.tv_sec,
574: s_name_data.name, s_name_data.instance,
575: key);
576: bzero(key, sizeof(key));
577: bzero(key_s, sizeof(key_s));
578:
579: create_ciph(ciph, session_key, service, instance,
580: local_realm,
581: lifetime, s_name_data.key_version, tk,
582: kerb_time.tv_sec, ad->session);
583:
584: /* clear session key */
585: bzero(session_key, sizeof(session_key));
586:
587: bzero(ad->session, sizeof(ad->session));
588:
589: rpkt = create_auth_reply(ad->pname, ad->pinst,
590: ad->prealm, time_ws,
591: 0, 0, 0, ciph);
592: sendto(f, rpkt->dat, rpkt->length, 0, client, S_AD_SZ);
593: bzero(&s_name_data, sizeof(s_name_data));
594: break;
595: }
596:
597:
598: #ifdef notdef_DIE
599: case AUTH_MSG_DIE:
600: {
601: lt = klog(L_DEATH_REQ,
602: "Host: %s User: \"%s\" \"%s\" Kerberos killed",
603: inet_ntoa(client_host), req_name_ptr, req_inst_ptr, 0);
604: exit(0);
605: }
606: #endif notdef_DIE
607:
608: default:
609: {
610: lt = klog(L_KRB_PERR,
611: "Unknown message type: %d from %s port %u",
612: req_msg_type, inet_ntoa(client_host),
613: ntohs(client->sin_port));
614: break;
615: }
616: }
617: }
618:
619:
620: /*
621: * setup_disc
622: *
623: * disconnect all descriptors, remove ourself from the process
624: * group that spawned us.
625: */
626:
627: setup_disc()
628: {
629:
630: int s;
631:
632: for (s = 0; s < 3; s++) {
633: (void) close(s);
634: }
635:
636: (void) open("/dev/null", 0);
637: (void) dup2(0, 1);
638: (void) dup2(0, 2);
639:
640: s = open("/dev/tty", 2);
641:
642: if (s >= 0) {
643: ioctl(s, TIOCNOTTY, (struct sgttyb *) 0);
644: (void) close(s);
645: }
646: (void) chdir("/tmp");
647: return;
648: }
649:
650:
651: /*
652: * kerb_er_reply creates an error reply packet and sends it to the
653: * client.
654: */
655:
656: kerb_err_reply(client, pkt, err, string)
657: struct sockaddr_in *client;
658: KTEXT pkt;
659: long err;
660: char *string;
661:
662: {
663: static KTEXT_ST e_pkt_st;
664: KTEXT e_pkt = &e_pkt_st;
665: static char e_msg[128];
666:
667: strcpy(e_msg, "\nKerberos error -- ");
668: strcat(e_msg, string);
669: cr_err_reply(e_pkt, req_name_ptr, req_inst_ptr, req_realm_ptr,
670: req_time_ws, err, e_msg);
671: sendto(f, e_pkt->dat, e_pkt->length, 0, client, S_AD_SZ);
672:
673: }
674:
675: /*
676: * Make sure that database isn't stale.
677: *
678: * Exit if it is; we don't want to tell lies.
679: */
680:
681: static void check_db_age()
682: {
683: long age;
684:
685: if (max_age != -1) {
686: /* Requires existance of kerb_get_db_age() */
687: gettimeofday(&kerb_time, 0);
688: age = kerb_get_db_age();
689: if (age == 0) {
690: klog(L_KRB_PERR, "Database currently being updated!");
691: hang();
692: }
693: if ((age + max_age) < kerb_time.tv_sec) {
694: klog(L_KRB_PERR, "Database out of date!");
695: hang();
696: /* NOTREACHED */
697: }
698: }
699: }
700:
701: check_princ(p_name, instance, lifetime, p)
702: char *p_name;
703: char *instance;
704: unsigned lifetime;
705:
706: Principal *p;
707: {
708: static int n;
709: static int more;
710: long trans;
711:
712: n = kerb_get_principal(p_name, instance, p, 1, &more);
713: klog(L_ALL_REQ,
714: "Principal: \"%s\", Instance: \"%s\" Lifetime = %d n = %d",
715: p_name, instance, lifetime, n, 0);
716:
717: if (n < 0) {
718: lt = klog(L_KRB_PERR, "Database unavailable!");
719: hang();
720: }
721:
722: /*
723: * if more than one p_name, pick one, randomly create a session key,
724: * compute maximum lifetime, lookup authorizations if applicable,
725: * and stuff into cipher.
726: */
727: if (n == 0) {
728: /* service unknown, log error, skip to next request */
729: lt = klog(L_ERR_UNK, "UNKNOWN \"%s\" \"%s\"", p_name,
730: instance, 0);
731: return KERB_ERR_PRINCIPAL_UNKNOWN;
732: }
733: if (more) {
734: /* not unique, log error */
735: lt = klog(L_ERR_NUN, "Principal NOT UNIQUE \"%s\" \"%s\"",
736: p_name, instance, 0);
737: return KERB_ERR_PRINCIPAL_NOT_UNIQUE;
738: }
739: /* If the user's key is null, we want to return an error */
740: if ((p->key_low == 0) && (p->key_high == 0)) {
741: /* User has a null key */
742: lt = klog(L_ERR_NKY, "Null key \"%s\" \"%s\"", p_name,
743: instance, 0);
744: return KERB_ERR_NULL_KEY;
745: }
746: if (master_key_version != p->kdc_key_ver) {
747: /* log error reply */
748: lt = klog(L_ERR_MKV,
749: "Key vers incorrect, KRB = %d, \"%s\" \"%s\" = %d",
750: master_key_version, p->name, p->instance, p->kdc_key_ver,
751: 0);
752: return KERB_ERR_NAME_MAST_KEY_VER;
753: }
754: /* make sure the service hasn't expired */
755: if ((u_long) p->exp_date < (u_long) kerb_time.tv_sec) {
756: /* service did expire, log it */
757: lt = klog(L_ERR_SEXP,
758: "EXPIRED \"%s\" \"%s\" %s", p->name, p->instance,
759: stime(&(p->exp_date)), 0);
760: return KERB_ERR_NAME_EXP;
761: }
762: /* ok is zero */
763: return 0;
764: }
765:
766:
767: /* Set the key for krb_rd_req so we can check tgt */
768: set_tgtkey(r)
769: char *r; /* Realm for desired key */
770: {
771: int n;
772: static char lastrealm[REALM_SZ];
773: Principal p_st;
774: Principal *p = &p_st;
775: C_Block key;
776:
777: if (!strcmp(lastrealm, r))
778: return (KSUCCESS);
779:
780: log("Getting key for %s", r);
781:
782: n = kerb_get_principal("krbtgt", r, p, 1, &more);
783: if (n == 0)
784: return (KFAILURE);
785:
786: /* unseal tgt key from master key */
787: bcopy(&p->key_low, key, 4);
788: bcopy(&p->key_high, ((long *) key) + 1, 4);
789: kdb_encrypt_key(key, key, master_key,
790: master_key_schedule, DECRYPT);
791: krb_set_key(key, 0);
792: strcpy(lastrealm, r);
793: return (KSUCCESS);
794: }
795:
796: static void
797: hang()
798: {
799: if (pause_int == -1) {
800: klog(L_KRB_PERR, "Kerberos will pause so as not to loop init");
801: for (;;)
802: pause();
803: } else {
804: char buf[256];
805: sprintf(buf, "Kerberos will wait %d seconds before dying so as not to loop init", pause_int);
806: klog(L_KRB_PERR, buf);
807: sleep(pause_int);
808: klog(L_KRB_PERR, "Do svedania....\n");
809: exit(1);
810: }
811: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.