Annotation of 43BSDReno/kerberosIV/kerberos/kerberos.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.