|
|
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.