In the KDC, remove krb4 request handling support and fakeka code
authorGreg Hudson <ghudson@mit.edu>
Mon, 15 Dec 2008 18:32:44 +0000 (18:32 +0000)
committerGreg Hudson <ghudson@mit.edu>
Mon, 15 Dec 2008 18:32:44 +0000 (18:32 +0000)
ticket: 6303
status: open

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@21448 dc483132-0cff-0310-8789-dd5450dbe970

src/kdc/Makefile.in
src/kdc/dispatch.c
src/kdc/fakeka.M [deleted file]
src/kdc/fakeka.c [deleted file]
src/kdc/kdc_util.h
src/kdc/kerberos_v4.c [deleted file]
src/kdc/krb5kdc.M
src/kdc/main.c

index ecba3275db8a67af3b4779461e998552fd19a181..c7ecf4bfcf4714fba98d032b1bebf4d583651ee4 100644 (file)
@@ -12,15 +12,13 @@ RUN_SETUP = @KRB5_RUN_ENV@
 PROG_LIBPATH=-L$(TOPLIBD) $(KRB4_LIBPATH)
 KDB5_LIB_DEPS=$(DL_LIB) $(THREAD_LINKOPTS)
 PROG_RPATH=$(KRB5_LIBDIR)
-FAKEKA=@FAKEKA@
 DEFS=-DLIBDIR=\"$(KRB5_LIBDIR)\"
-#EXTRADEPSRCS= fakeka.c
 
-all:: krb5kdc rtest $(FAKEKA)
+all:: krb5kdc rtest
 
 # DEFINES = -DBACKWARD_COMPAT $(KRB4DEF)
 
-LOCALINCLUDES = @KRB4_INCLUDES@ -I.
+LOCALINCLUDES = -I.
 SRCS= \
        kdc5_err.c \
        $(srcdir)/dispatch.c \
@@ -33,8 +31,7 @@ SRCS= \
        $(srcdir)/policy.c \
        $(srcdir)/extern.c \
        $(srcdir)/replay.c \
-       $(srcdir)/kdc_authdata.c \
-       $(srcdir)/kerberos_v4.c
+       $(srcdir)/kdc_authdata.c
 
 OBJS= \
        kdc5_err.o \
@@ -48,8 +45,7 @@ OBJS= \
        policy.o \
        extern.o \
        replay.o \
-       kdc_authdata.o \
-       kerberos_v4.o
+       kdc_authdata.o
 
 RT_OBJS= rtest.o \
        kdc_util.o \
@@ -64,15 +60,12 @@ kdc5_err.h: kdc5_err.et
 
 kdc5_err.o: kdc5_err.h
 
-krb5kdc: $(OBJS) $(KADMSRV_DEPLIBS) $(KRB4COMPAT_DEPLIBS) $(APPUTILS_DEPLIB)
-       $(CC_LINK) -o krb5kdc $(OBJS) $(KADMSRV_LIBS) $(KRB4COMPAT_LIBS) $(APPUTILS_LIB)
+krb5kdc: $(OBJS) $(KADMSRV_DEPLIBS) $(KRB5_BASE_DEPLIBS) $(APPUTILS_DEPLIB)
+       $(CC_LINK) -o krb5kdc $(OBJS) $(KADMSRV_LIBS) $(KRB5_BASE_LIBS) $(APPUTILS_LIB)
 
 rtest: $(RT_OBJS) $(KDB5_DEPLIBS) $(KADM_COMM_DEPLIBS) $(KRB5_BASE_DEPLIBS)
        $(CC_LINK) -o rtest $(RT_OBJS) $(KDB5_LIBS) $(KADM_COMM_LIBS) $(KRB5_BASE_LIBS)
 
-fakeka: fakeka.o $(KADMSRV_DEPLIBS) $(KRB4COMPAT_DEPLIBS) $(APPUTILS_DEPLIB)
-       $(CC_LINK) -o fakeka fakeka.o $(KADMSRV_LIBS) $(KRB4COMPAT_LIBS) $(APPUTILS_LIB)
-
 check-unix:: rtest
        KRB5_CONFIG=$(SRCTOP)/config-files/krb5.conf ; export KRB5_CONFIG ;\
        $(RUN_SETUP) $(VALGRIND) $(srcdir)/rtscript > test.out
@@ -82,14 +75,9 @@ check-unix:: rtest
 install::
        $(INSTALL_PROGRAM) krb5kdc ${DESTDIR}$(SERVER_BINDIR)/krb5kdc
        $(INSTALL_DATA) $(srcdir)/krb5kdc.M ${DESTDIR}$(SERVER_MANDIR)/krb5kdc.8
-       f=$(FAKEKA); \
-       if test -n "$$f" ; then \
-               $(INSTALL_PROGRAM) $$f ${DESTDIR}$(SERVER_BINDIR)/$$f; \
-               $(INSTALL_DATA) $(srcdir)/fakeka.M ${DESTDIR}$(SERVER_MANDIR)/fakeka.8; \
-       fi
 
 clean::
-       $(RM) kdc5_err.h kdc5_err.c krb5kdc rtest.o rtest fakeka.o fakeka
+       $(RM) kdc5_err.h kdc5_err.c krb5kdc rtest.o rtest
 
 # +++ Dependency line eater +++
 # 
@@ -221,13 +209,3 @@ $(OUTPRE)kdc_authdata.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
   $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \
   $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
   extern.h kdc_authdata.c kdc_util.h
-$(OUTPRE)kerberos_v4.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
-  $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
-  $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h \
-  $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \
-  $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \
-  $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \
-  $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \
-  $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \
-  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
-  kerberos_v4.c
index ac0eb485d8bd36d87beaa43d59a5add3f153941b..77415af82d5915091804c51e2633f86025c2179a 100644 (file)
@@ -99,10 +99,6 @@ dispatch(krb5_data *pkt, const krb5_fulladdr *from, krb5_data **response)
            krb5_free_kdc_req(kdc_context, as_req);
        }
     }
-#ifdef KRB5_KRB4_COMPAT
-    else if (pkt->data[0] == 4)                /* old version */
-       retval = process_v4(pkt, from, response);
-#endif
     else
        retval = KRB5KRB_AP_ERR_MSG_TYPE;
 #ifndef NOCACHE
diff --git a/src/kdc/fakeka.M b/src/kdc/fakeka.M
deleted file mode 100644 (file)
index 80ea015..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-.\" kdc/fakeka.M
-.\"
-.\" Copyright 2005 by the Massachusetts Institute of Technology.
-.\"
-.\" Export of this software from the United States of America may
-.\"   require a specific license from the United States Government.
-.\"   It is the responsibility of any person or organization contemplating
-.\"   export to obtain such a license before exporting.
-.\"
-.\" WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-.\" distribute this software and its documentation for any purpose and
-.\" without fee is hereby granted, provided that the above copyright
-.\" notice appear in all copies and that both that copyright notice and
-.\" this permission notice appear in supporting documentation, and that
-.\" the name of M.I.T. not be used in advertising or publicity pertaining
-.\" to distribution of the software without specific, written prior
-.\" permission.  Furthermore if you modify this software you must label
-.\" your software as modified software and not distribute it in such a
-.\" fashion that it might be confused with the original M.I.T. software.
-.\" M.I.T. makes no representations about the suitability of
-.\" this software for any purpose.  It is provided "as is" without express
-.\" or implied warranty.
-.\" "
-.TH FAKEKA 8
-.SH NAME
-fakeka \- Fake kaserver for AFS clients
-.SH SYNOPSIS
-\fBfakeka\fP [\fB\-dm\fP] [\fB\-c\fP \fIcell\fP] [\fB\-f\fP \fIforwarder\fP]
-[\fB\-l\fP \fBfacility\fP] [\fB\-p\fP \fBport\fP] [\fB\-r\fP \fIrealm\fP]
-.br
-.SH DESCRIPTION
-.I fakeka
-is a fake kaserver that speaks just enough of the AFS RX protocol to make
-klog work.  It is used in conjunction with a Kerberos V5 KDC to support
-existing AFS clients, and is usually used with ka-forwarder.
-.I fakeka
-must run on the same host as your Kerberos V5 KDC, since it needs access
-to the KDC database.  ka-forwarder should run on each of your AFS database
-servers, pointing to your Kerberos V5 KDCs.
-.I fakeka
-should then be running on each of the KDCs, with the AFS database servers
-listed as arguments to the
-.B -f
-option.
-.PP
-Note that principals you wish to use
-.I fakeka
-with must have either a V4-style key (des:v4) or an AFS-style key
-(des:afs3).  V5 enctypes won't work.
-.SH OPTIONS
-.TP
-\fB\-c\fP \fIcell\fP
-The AFS cell for which
-.I fakeka
-will be handling requests.  If not given, this defaults to the same as the
-Kerberos V5 realm (see
-.B \-r
-below).
-.TP
-.B \-d
-Enables debugging.  When this flag is given,
-.I fakeka
-will run in the foreground and print debugging information to standard
-error.  Overrides
-.BR \-m .
-.TP
-\fB\-f\fP \fIforwarder\fP
-Allows forwarded requests from
-.IR forwarder ,
-which is generally an AFS database server running ka-forwarder.  This
-option can be given multiple times (up to 10).  Each system running
-ka-forwarder should be specified with the
-.B \-f
-flag or forwarded requests from that host will not be answered.  (The
-forwarders append their own address to the packet.
-.TP
-\fB\-l\fP \fIfacility\fP
-Log actions via syslog with the given
-.I facility
-rather than the default of LOG_DAEMON.
-.I facility
-must be one of KERN, USER, MAIL, DAEMON, AUTH, LPR, NEWS, UUCP, CRON,
-LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, or LOCAL7.  This
-option is case-sensitive.  Not all of these facilities may be available,
-depending on what pre-defined syslog facilities your system provides.
-.TP
-.B \-m
-Fork and background when starting.  You will usually always want to give
-this flag.
-.TP
-\fB\-p\fP \fIport\fP
-Listen on the specified port rather than the default of 7004 (which is
-what klog expects).
-.I port
-may be a number or a service name from
-.IR /etc/services .
-.TP
-\fB\-r\fP \fIrealm\fP
-The Kerberos V5 realm to which the requests are being translated.  The
-default is the local default realm.
-.SH EXAMPLES
-Handle requests for a local cell whose name matches the local realm,
-accepting forwarded queries from afs1.example.com and afs2.example.com:
-.IP "" 4
-fakeka -m -f afs1.example.com -f afs2.example.com
-.PP
-If the cell name doesn't match the realm name,
-.B \-c
-would need to be added, specifying the cell name.
-.SH SEE ALSO
-ka-forwarder(8)
diff --git a/src/kdc/fakeka.c b/src/kdc/fakeka.c
deleted file mode 100644 (file)
index 3991664..0000000
+++ /dev/null
@@ -1,1397 +0,0 @@
-/*
- * COPYRIGHT NOTICE
- * Copyright (c) 1994 Carnegie Mellon University
- * All Rights Reserved.
- * 
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- *  Software Distribution Coordinator  or  Software_Distribution@CS.CMU.EDU
- *  School of Computer Science
- *  Carnegie Mellon University
- *  Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- *
- * Converted to Kerberos 5 by Ken Hornstein <kenh@cmf.nrl.navy.mil>
- */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <stdio.h>
-#include <string.h>
-#include <syslog.h>
-#include <ctype.h>
-#include <errno.h>
-#include <netdb.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_MEMORY_H
-#include <memory.h>
-#endif
-
-#include <krb5.h>
-#include <kadm5/admin.h>
-#include <com_err.h>
-#include <kerberosIV/krb.h>
-#include <kerberosIV/des.h>
-#include <k5-platform.h>
-
-#ifndef LINT
-static char rcsid[]=
-       "$Id$";
-#endif
-
-/*
- * Misc macros
- */
-
-#define PAD_TO(x, a) (((u_long)(x) + (a) - 1) & ~((a) - 1))
-#define min(a, b) ((a) < (b) ? (a) : (b))
-#define MAXFORWARDERS 10
-#define HEADER_LEN 8
-
-/*
- * Error values from kautils.h
- * 
- * The security errors are:
- *     KABADTICKET, KABADSERVER, KABADUSER, and KACLOCKSKEW
- */
-
-#define KADATABASEINCONSISTENT                   (180480L)
-#define KANOENT                                  (180484L)
-#define KABADREQUEST                             (180490L)     
-#define KABADTICKET                              (180504L)
-#define KABADSERVER                              (180507L)
-#define KABADUSER                                (180508L)
-#define KACLOCKSKEW                              (180514L)
-#define KAINTERNALERROR                          (180518L)
-
-
-/*
- * Type definitions
- */
-
-typedef struct packet {
-    char *base;
-    int len;
-    char data[1024];
-} *packet_t;
-
-typedef struct rx_header {
-    u_int rx_epoch;
-    u_int rx_cid;
-    u_int rx_callnum;
-    u_int rx_seq;
-    u_int rx_serial;
-    u_char rx_type;
-    u_char rx_flags;
-    u_char rx_userstatus;
-    u_char rx_securityindex;
-    u_short rx_spare;
-    u_short rx_service;
-    u_int rx_request;
-} *rx_t;
-
-
-/*
- * Global vars
- */
-
-char *progname = "fakeka";             /* needed by libkdb.a */
-char *localrealm = NULL;
-char *localcell = NULL;
-krb5_timestamp req_time;
-kadm5_config_params realm_params;
-int debug = 0;
-
-
-/*
- * This is a table for the "infamous" CMU ticket lifetime conversion.  If
- * the lifetime is greater than 128, use this table
- */
-#define MAX_TICKET_LIFETIME 2592000
-static long cmu_seconds[] =
-{
-  38400,  41055,  43894,  46929,  50174,  53643,  57352,  61318,
-  65558,  70091,  74937,  80119,  85658,  91581,  97914,  104684,
-  111922,  119661,  127935,  136781,  146239,  156350,  167161,  178720,
-  191077,  204289,  218415,  233517,  249663,  266926,  285383,  305116,
-  326213,  348769,  372885,  398668,  426233,  455705,  487215,  520903,
-  556921,  595430,  636600,  680618,  727679,  777995,  831789,  889303,
-  950794,  1016536,  1086825,  1161973,  1242317,  1328217,  1420057,  1518246,
-  1623225,  1735463,  1855462,  1983757,  2120924,  2267575,  2424366, 2591999,
-  0
-};
-
-#if    __STDC__
-/*
- * Prototypes for all the functions we define
- */
-
-void perrorexit(char *);
-void pexit(char *);
-char *kaerror(int);
-int get_princ_key(krb5_context, void *, kadm5_principal_ent_t, des_cblock,
-                 des_key_schedule);
-int check_princ(krb5_context, void *, char *, char *, kadm5_principal_ent_t);
-
-int make_reply_packet(krb5_context, void *, packet_t, int, int, int,
-                     char *, char *, char *, char *,
-                     des_cblock, des_key_schedule, char *);
-
-int Authenticate(krb5_context, void *, char *, packet_t, packet_t);
-int GetTicket(krb5_context, void *, char *, packet_t, packet_t);
-void process(krb5_context, void *, char *, packet_t, packet_t);
-#endif
-
-
-/*
- * Helpers for exiting with errors
- */
-
-void perrorexit(str)
-char *str;
-{
-    perror(str);
-    exit(1);
-}
-
-void pexit(str)
-char *str;
-{
-    printf("%s\n", str);
-    exit(1);
-}
-
-
-/*
- * Translate error codes into strings.
- */
-
-char *kaerror(e)
-int e;
-{
-    static char buf[1024];
-
-    switch (e) {
-    case KADATABASEINCONSISTENT:
-       return "database is inconsistent";
-    case KANOENT:
-       return "principal does not exist";
-    case KABADREQUEST:
-       return "request was malformed (bad password)";
-    case KABADTICKET:
-       return "ticket was malformed, invalid, or expired";
-    case KABADSERVER:
-       return "cannot issue tickets for this service";
-    case KABADUSER:
-       return "principal expired";
-    case KACLOCKSKEW:
-       return "client time is too far skewed";
-    case KAINTERNALERROR:
-       return "internal error in fakeka, help!";
-    default:
-       snprintf(buf, sizeof(buf), "impossible error code %d, help!", e);
-       return buf;
-    }
-    /*NOTREACHED*/
-}
-
-/*
- * Syslog facilities
- */
-typedef struct {
-       int num;
-       char *string;
-} facility_mapping;
-
-static facility_mapping mappings[] = {
-#ifdef LOG_KERN   
-       { LOG_KERN, "KERN" },
-#endif
-#ifdef LOG_USER
-       { LOG_USER, "USER" },
-#endif
-#ifdef LOG_MAIL
-       { LOG_MAIL, "MAIL" },
-#endif
-#ifdef LOG_DAEMON
-       { LOG_DAEMON, "DAEMON" },
-#endif
-#ifdef LOG_AUTH
-       { LOG_AUTH, "AUTH" },
-#endif
-#ifdef LOG_LPR
-       { LOG_LPR, "LPR" },
-#endif
-#ifdef LOG_NEWS
-       { LOG_NEWS, "NEWS" },
-#endif
-#ifdef LOG_UUCP
-       { LOG_UUCP, "UUCP" },
-#endif
-#ifdef LOG_CRON
-       { LOG_CRON, "CRON" },
-#endif
-#ifdef LOG_LOCAL0
-       { LOG_LOCAL0, "LOCAL0" },
-#endif
-#ifdef LOG_LOCAL1
-       { LOG_LOCAL1, "LOCAL1" },
-#endif
-#ifdef LOG_LOCAL2
-       { LOG_LOCAL2, "LOCAL2" },
-#endif
-#ifdef LOG_LOCAL3
-       { LOG_LOCAL3, "LOCAL3" },
-#endif
-#ifdef LOG_LOCAL4
-       { LOG_LOCAL4, "LOCAL4" },
-#endif
-#ifdef LOG_LOCAL5
-       { LOG_LOCAL5, "LOCAL5" },
-#endif
-#ifdef LOG_LOCAL6
-       { LOG_LOCAL6, "LOCAL6" },
-#endif
-#ifdef LOG_LOCAL7
-       { LOG_LOCAL7, "LOCAL7" },
-#endif
-       { 0, NULL }
-};
-
-
-/*
- * Get the principal's key and key schedule from the db record.
- *
- * Life is more complicated in the V5 world.  Since we can have different
- * encryption types, we have to make sure that we get back a DES key.
- * Also, we have to try to get back a AFS3 or V4 salted key, since AFS
- * doesn't know about a V5 style salt.
- */
-
-int get_princ_key(context, handle, p, k, s)
-krb5_context context;
-void *handle;
-kadm5_principal_ent_t p;
-des_cblock k;
-des_key_schedule s;
-{      
-    int rv;
-    krb5_keyblock kb;
-    kadm5_ret_t retval;
-
-    /*
-     * We need to call kadm5_decrypt_key to decrypt the key data
-     * from the principal record.  We _must_ have a encryption type
-     * of DES_CBC_CRC, and we prefer having a salt type of AFS 3 (but
-     * a V4 salt will work as well).  If that fails, then return any
-     * type of key we can find.
-     *
-     * Note that since this uses kadm5_decrypt_key, it means it has to
-     * be compiled with the kadm5srv library.
-     */
-
-    if ((retval = kadm5_decrypt_key(handle, p, ENCTYPE_DES_CBC_CRC,
-                                   KRB5_KDB_SALTTYPE_AFS3, 0, &kb,
-                                   NULL, NULL)))
-       if ((retval = kadm5_decrypt_key(handle, p, ENCTYPE_DES_CBC_CRC,
-                                       KRB5_KDB_SALTTYPE_V4, 0, &kb,
-                                       NULL, NULL)))
-               if ((retval = kadm5_decrypt_key(handle, p, ENCTYPE_DES_CBC_CRC,
-                                               -1, 0, &kb, NULL, NULL))) {
-                       syslog(LOG_ERR, "Couldn't find any matching key: %s",
-                              error_message(retval));
-                       return KAINTERNALERROR;
-               }
-
-    /*
-     * Copy the data from our krb5_keyblock to the des_cblock.  Make sure
-     * the size of our key matches the V4/AFS des_cblock.
-     */
-
-    if (kb.length != sizeof(des_cblock)) {
-       krb5_free_keyblock_contents(context, &kb);
-       syslog(LOG_ERR, "Principal key size of %d didn't match C_Block size"
-              " %d", kb.length, sizeof(des_cblock));
-       return KAINTERNALERROR;
-    }
-
-    memcpy((char *) k, (char *) kb.contents, sizeof(des_cblock));
-
-    krb5_free_keyblock_contents(context, &kb);
-
-    /*
-     * Calculate the des key schedule
-     */
-
-    rv = des_key_sched(k, s);
-    if (rv) {
-       memset((void *) k, 0, sizeof(k));
-       memset((void *)s, 0, sizeof(s));
-       return KAINTERNALERROR;
-    }
-    return 0;
-}
-
-
-/*
- * Fetch principal from db and validate it.
- *
- * Note that this always fetches the key data from the principal (but it
- * doesn't decrypt it).
- */
-
-int check_princ(context, handle, name, inst, p)
-krb5_context context;
-void *handle;
-char *name, *inst;
-kadm5_principal_ent_t p;
-{
-    krb5_principal princ;
-    krb5_error_code code;
-    kadm5_ret_t retcode;
-
-    /*
-     * Screen out null principals. They are causing crashes here
-     * under HPUX-10.20. - vwelch@ncsa.uiuc.edu 1/6/98
-     */
-    if (!name || (name[0] == '\0')) {
-       syslog(LOG_ERR, "screening out null principal");
-       return KANOENT;
-    }
-
-    /*
-     * Build a principal from the name and instance (the realm is always
-     * the same).
-     */
-
-    if ((code = krb5_build_principal_ext(context, &princ, strlen(localrealm),
-                                        localrealm, strlen(name), name,
-                                        strlen(inst), inst, 0))) {
-       syslog(LOG_ERR, "could not build principal: %s", error_message(code));
-       return KAINTERNALERROR;
-    }
-
-    /*
-     * Fetch the principal from the database -- also fetch the key data.
-     * Note that since this retrieves the key data, it has to be linked with
-     * the kadm5srv library.
-     */
-
-    if ((retcode = kadm5_get_principal(handle, princ, p,
-                                      KADM5_PRINCIPAL_NORMAL_MASK |
-                                      KADM5_KEY_DATA))) {
-       if (retcode == KADM5_UNK_PRINC) {
-           krb5_free_principal(context, princ);
-           syslog(LOG_INFO, "principal %s.%s does not exist", name, inst);
-           return KANOENT;
-       } else {
-           krb5_free_principal(context, princ);
-           syslog(LOG_ERR, "kadm5_get_principal failed: %s",
-                  error_message(retcode));
-           return KAINTERNALERROR;
-       }
-    }
-
-    krb5_free_principal(context, princ);
-
-    /*
-     * Check various things - taken from the KDC code.
-     *
-     * Since we're essentially bypassing the KDC, we need to make sure
-     * that we don't give out a ticket that we shouldn't.
-     */
-
-    /*
-     * Has the principal expired?
-     */
-
-    if (p->princ_expire_time && p->princ_expire_time < req_time) {
-       kadm5_free_principal_ent(handle, p);
-       return KABADUSER;
-    }
-
-    /*
-     * Has the principal's password expired?  Note that we don't
-     * check for the PWCHANGE_SERVICE flag here, since we don't
-     * support password changing.  We do support the REQUIRES_PWCHANGE
-     * flag, though.
-     */
-
-    if ((p->pw_expiration && p->pw_expiration < req_time) ||
-       (p->attributes & KRB5_KDB_REQUIRES_PWCHANGE)) {
-       kadm5_free_principal_ent(handle, p);
-       return KABADUSER;
-    }
-
-    /*
-     * See if the principal is locked out
-     */
-
-    if (p->attributes & KRB5_KDB_DISALLOW_ALL_TIX) {
-       kadm5_free_principal_ent(handle, p);
-       return KABADUSER;
-    }
-
-    /*
-     * There's no way we can handle hardware preauth, so
-     * disallow tickets with this flag set.
-     */
-
-    if (p->attributes & KRB5_KDB_REQUIRES_HW_AUTH) {
-       kadm5_free_principal_ent(handle, p);
-       return KABADUSER;
-    }
-
-    /*
-     * Must be okay, then
-     */
-
-    return 0;
-}
-
-
-/*
- * Create an rx reply packet in "packet" using the provided data.
- * The caller is responsible for zeroing key and sched.
- */
-
-int make_reply_packet(context, handle, reply, challenge_response, start_time,
-                     end_time, cname, cinst, sname, sinst, key, sched, label)
-krb5_context context;
-void *handle;
-packet_t reply;
-int challenge_response, start_time, end_time;
-char *cname, *cinst, *sname, *sinst;
-des_cblock key;
-des_key_schedule sched;
-char *label;
-{
-    int rv, n, maxn, v4life, *enclenp, *ticklenp;
-    u_char *p, *enc, *ticket;
-    kadm5_principal_ent_rec cprinc, sprinc;
-    des_cblock skey, new_session_key;
-    des_key_schedule ssched;
-    krb5_deltat lifetime;
-
-    rv = 0;
-
-    rv = check_princ(context, handle, cname, cinst, &cprinc);
-    if (rv)
-       return rv;
-
-    rv = check_princ(context, handle, sname, sinst, &sprinc);
-    if (rv) {
-       kadm5_free_principal_ent(handle, &cprinc);
-       return rv;
-    }
-
-    /* 
-     * Bound ticket lifetime by max lifetimes of user and service.
-     *
-     * Since V5 already stores everything in Unix epoch timestamps like
-     * AFS, these calculations are much simpler.
-     */
-
-    lifetime = end_time - start_time;
-    lifetime = min(lifetime, cprinc.max_life);
-    lifetime = min(lifetime, sprinc.max_life);
-    lifetime = min(lifetime, realm_params.max_life);
-
-    end_time = start_time + lifetime;
-
-    /*
-     * But we have to convert back to V4-style lifetimes
-     */
-
-    v4life = lifetime / 300;
-    if (v4life > 127) {
-       /*
-        * Use the CMU algorithm instead
-        */
-       long *clist = cmu_seconds;
-       while (*clist && *clist < lifetime) clist++;
-       v4life = 128 + (clist - cmu_seconds);
-    }
-
-    /*
-     * If this is for afs and the instance is the local cell name
-     * then we assume we added the instance in GetTickets to
-     * identify the afs key in the kerberos database. This is for
-     * cases where the afs cell name is different from the kerberos
-     * realm name. We now want to remove the instance so it doesn't
-     * cause klog to barf.
-     */
-    if (!strcmp(sname, "afs") && (strcasecmp(sinst, localcell) == 0))
-       sinst[0] = '\0';
-
-    /*
-     * All the data needed to construct the ticket is ready, so do it.
-     */
-
-    p = (unsigned char *) reply->base;
-    maxn = reply->len;
-    n = 0;
-
-#define ERR(x) do { rv = x ; goto error; } while (0)
-#define ADVANCE(x) { if ((n += x) > maxn) ERR(KAINTERNALERROR); else p += x;}
-#define PUT_CHAR(x) { *p = (x); ADVANCE(1); }
-#define PUT_INT(x) { int q = ntohl(x); memcpy(p, (char *)&q, 4); ADVANCE(4); }
-#define PUT_STR(x) { strcpy((char *) p, x); ADVANCE(strlen(x) + 1); }
-
-    ADVANCE(28);
-    PUT_INT(0x2bc);
-
-    enclenp = (int *)p;
-    PUT_INT(0);                /* filled in later */
-
-    enc = p;
-    PUT_INT(0);
-    PUT_INT(challenge_response);
-
-    /*
-     * new_session_key is created here, and remains in the clear
-     * until just before we return.
-     */
-    des_new_random_key(new_session_key);
-    memcpy(p, new_session_key, 8);
-
-    ADVANCE(8);
-    PUT_INT(start_time);
-    PUT_INT(end_time);
-    PUT_INT(sprinc.kvno);
-
-    ticklenp = (int *)p;
-    PUT_INT(0);                /* filled in later */
-
-    PUT_STR(cname);
-    PUT_STR(cinst);
-    PUT_STR("");
-    PUT_STR(sname);
-    PUT_STR(sinst);
-
-    ticket = p;
-    PUT_CHAR(0);       /* flags, always 0 */
-    PUT_STR(cname);
-    PUT_STR(cinst);
-    PUT_STR("");
-    PUT_INT(0);                /* would be ip address */
-
-    memcpy(p, new_session_key, 8);
-
-    ADVANCE(8);
-
-    PUT_CHAR(v4life);
-    PUT_INT(start_time);
-    PUT_STR(sname);
-    PUT_STR(sinst);
-
-    ADVANCE(PAD_TO(p - ticket, 8) - (p - ticket));
-
-    *ticklenp = ntohl(p - ticket);
-
-    rv = get_princ_key(context, handle, &sprinc, skey, ssched);
-    if (rv)
-       return rv;
-    des_pcbc_encrypt((C_Block *) ticket, (C_Block *) ticket, p - ticket,
-                    ssched, (C_Block *) skey, ENCRYPT);
-    memset(skey, 0, sizeof(skey));
-    memset(ssched, 0, sizeof(ssched));
-
-    PUT_STR(label);    /* "tgsT" or "gtkt" */
-    ADVANCE(-1);       /* back up over string terminator */
-
-    ADVANCE(PAD_TO(p - enc, 8) - (p - enc));
-#undef ERR
-#undef ADVANCE
-#undef PUT_CHAR
-#undef PUT_INT
-#undef PUT_STR
-
-    *enclenp = ntohl(p - enc);
-    des_pcbc_encrypt((C_Block *) enc, (C_Block *) enc, p - enc, sched,
-                    (C_Block *) key, ENCRYPT);
-    reply->len = n;
-
-  error:
-    memset(new_session_key, 0, sizeof(new_session_key));
-    kadm5_free_principal_ent(handle, &cprinc);
-    kadm5_free_principal_ent(handle, &sprinc);
-
-    return rv;
-}
-
-#define ERR(x) do { rv = x; goto error; } while (0)
-#define ADVANCE(x) { if ((n += x) > maxn) ERR(KABADREQUEST); else p += x; }
-#define GET_INT(x) { int q; memcpy((char *)&q, p, 4); x = ntohl(q); ADVANCE(4); }
-#define GET_CHAR(x) { x = *p; ADVANCE(1); }
-#define GET_PSTR(x) \
-    { \
-       GET_INT(len); \
-       if (len > sizeof(x) - 1) ERR(KABADREQUEST); \
-       memcpy(x, p, len); \
-       x[len] = 0; \
-       ADVANCE(PAD_TO(len, 4)); \
-    }
-
-#define GET_STR(x) \
-    { \
-       len = strlen(p); \
-       if (len > sizeof(x) - 1) ERR(KABADREQUEST); \
-       strcpy(x, p); \
-       ADVANCE(len + 1); \
-    }
-
-
-/*
- * Process an Authenticate request.
- */
-
-int Authenticate(context, handle, from, req, reply)
-krb5_context context;
-void *handle;
-char *from;
-packet_t req, reply;
-{
-    int rv, n, maxn;
-    int len, start_time, end_time, challenge;
-    char name[ANAME_SZ+1], inst[INST_SZ+1], *p;
-    kadm5_principal_ent_rec cprinc;
-    des_cblock ckey;
-    des_key_schedule csched;
-    int free_princ_ent = 0;
-
-    rv = 0;
-
-    p = req->base;
-    maxn = req->len;
-    n = 0;
-
-    ADVANCE(32);
-
-    GET_PSTR(name);
-    GET_PSTR(inst);
-
-    if (debug)
-       fprintf(stderr, "Authenticating %s.%s\n", name, inst);
-
-    rv = check_princ(context, handle, name, inst, &cprinc);
-    if (rv)
-       ERR(rv);
-
-    free_princ_ent = 1;
-
-    GET_INT(start_time);
-    GET_INT(end_time);
-
-    GET_INT(len);
-    if (len != 8)
-       ERR(KABADREQUEST);
-
-    /*
-     * ckey and csched are set here and remain in the clear
-     * until just before we return.
-     */
-
-    rv = get_princ_key(context, handle, &cprinc, ckey, csched);
-    if (rv)
-       ERR(rv);
-    des_pcbc_encrypt((C_Block *) p, (C_Block *) p, 8, csched,
-                    (C_Block *) ckey, DECRYPT);
-
-    GET_INT(challenge);
-
-    rv = memcmp(p, "gTGS", 4);
-    if (rv)
-       ERR(KABADREQUEST);
-    ADVANCE(4);
-
-    /* ignore the rest */
-    ADVANCE(8);
-
-    /*
-     * We have all the data from the request, now generate the reply.
-     */
-
-    rv =  make_reply_packet(context, handle, reply, challenge + 1, start_time,
-                           end_time, name, inst, "krbtgt", localcell,
-                           ckey, csched, "tgsT");
-  error:
-    memset(ckey, 0, sizeof(ckey));
-    memset(csched, 0, sizeof(csched));
-
-    syslog(LOG_INFO, "authenticate: %s.%s from %s", name, inst, from);
-    if (rv) {
-       syslog(LOG_INFO, "... failed due to %s", kaerror(rv));
-    }
-    if (free_princ_ent)
-       kadm5_free_principal_ent(handle, &cprinc);
-    return rv;
-}
-
-
-/*
- * Process a GetTicket rpc.
- */
-
-int GetTicket(context, handle, from, req, reply)
-krb5_context context;
-void *handle;
-char *from;
-packet_t req, reply;
-{
-    int rv, n, maxn, len, ticketlen;
-    char *p;
-    u_int kvno, start_time, end_time, times[2], flags, ipaddr;
-    u_int tgt_start_time, tgt_end_time, lifetime;
-    char rname[ANAME_SZ+1], rinst[INST_SZ+1];  /* requested principal */
-    char sname[ANAME_SZ+1], sinst[INST_SZ+1];  /* service principal (TGT) */
-    char cname[ANAME_SZ+1], cinst[INST_SZ+1];  /* client principal */
-    char cell[REALM_SZ+1], realm[REALM_SZ+1];
-    char enctimes[8 + 1], ticket[1024];
-    u_char tgt_lifetime;
-    kadm5_principal_ent_rec cprinc;
-    des_cblock ckey, session_key;
-    des_key_schedule csched, session_sched;
-    int free_princ_ent = 0;
-
-    rv = 0;
-
-    /* 
-     * Initialize these so we don't crash trying to print them in
-     * case they don't get filled in.
-     */
-    strlcpy(rname, "Unknown", sizeof(rname));
-    strlcpy(rinst, "Unknown", sizeof(rinst));
-    strlcpy(sname, "Unknown", sizeof(sname));
-    strlcpy(sinst, "Unknown", sizeof(sinst));
-    strlcpy(cname, "Unknown", sizeof(cname));
-    strlcpy(cinst, "Unknown", sizeof(cinst));
-    strlcpy(cell, "Unknown", sizeof(cell));
-    strlcpy(realm, "Unknown", sizeof(realm));
-    
-    p = req->base;
-    maxn = req->len;
-    n = 0;
-
-    ADVANCE(32);
-
-    GET_INT(kvno);
-
-    GET_PSTR(cell);
-    if (!cell[0])
-      strlcpy(cell, localcell, sizeof(cell));
-
-    if (debug)
-       fprintf(stderr, "Cell is %s\n", cell);
-
-    memset(ticket, 0, sizeof(ticket));
-    GET_PSTR(ticket);
-    ticketlen = len;   /* hacky hack hack */
-    GET_PSTR(rname);
-    GET_PSTR(rinst);
-
-    if (debug)
-       fprintf(stderr, "Request for %s/%s\n", rname, rinst);
-
-    GET_PSTR(enctimes);        /* still encrypted */
-    if (len != 8)      /* hack and hack again */
-       ERR(KABADREQUEST);
-
-    /* ignore the rest */
-    ADVANCE(8);
-
-    /*
-     * That's it for the packet, now decode the embedded ticket.
-     */
-
-    rv = check_princ(context, handle, "krbtgt", cell, &cprinc);
-    if (rv)
-       ERR(rv);
-
-    free_princ_ent = 1;
-
-    rv = get_princ_key(context, handle, &cprinc, ckey, csched);
-    if (rv)
-       ERR(rv);
-    des_pcbc_encrypt((C_Block *) ticket, (C_Block *) ticket, ticketlen, csched,
-                    (C_Block *) ckey, DECRYPT);
-    memset(ckey, 0, sizeof(ckey));
-    memset(csched, 0, sizeof(csched));
-
-    /*
-     * The ticket's session key is now in the clear in the ticket buffer.
-     * We zero it just before returning.
-     */
-
-    p = ticket;
-    maxn = ticketlen;
-    n = 0;
-
-    GET_CHAR(flags);
-    GET_STR(cname);
-    GET_STR(cinst);
-    GET_STR(realm);
-    GET_INT(ipaddr);
-    memcpy(session_key, p, 8);
-    ADVANCE(8);
-
-    GET_CHAR(tgt_lifetime);
-    GET_INT(tgt_start_time);
-    GET_STR(sname);
-    GET_STR(sinst);
-
-    if (debug)
-       fprintf(stderr,
-               "ticket: %s.%s@%s for %s.%s\n",
-               cname, cinst, realm, sname, sinst);
-
-    /*
-     * ok, we've got the ticket unpacked.
-     * now decrypt the start and end times.
-     */
-
-    rv = des_key_sched(session_key, session_sched);
-    if (rv) 
-       ERR(KABADTICKET);
-
-    des_ecb_encrypt((C_Block *) enctimes, (C_Block *) times, session_sched,
-                   DECRYPT);
-    start_time = ntohl(times[0]);
-    end_time = ntohl(times[1]);
-
-    /*
-     * All the info we need is now available.
-     * Now validate the request.
-     */
-
-    /*
-     * This translator requires that the flags and IP address
-     * in the ticket be zero, because we always set them that way,
-     * and we want to accept only tickets that we generated.
-     * 
-     * Are the flags and IP address fields 0?
-     */
-    if (flags || ipaddr) {
-       if (debug)
-           fprintf(stderr, "ERROR: flags or ipaddr field non-zero\n");
-       ERR(KABADTICKET);
-    }
-    /*
-     * Is the supplied ticket a tgt?
-     */
-    if (strcmp(sname, "krbtgt")) {
-       if (debug)
-           fprintf(stderr, "ERROR: not for krbtgt service\n");
-       ERR(KABADTICKET);
-    }
-
-    /*
-     * This translator does not allow MIT-style cross-realm access.
-     * Is this a cross-realm ticket?
-     */
-    if (strcasecmp(sinst, localcell)) {
-       if (debug)
-           fprintf(stderr,
-                   "ERROR: Service instance (%s) differs from local cell\n",
-                   sinst);
-       ERR(KABADTICKET);
-    }
-
-    /*
-     * This translator does not issue cross-realm tickets,
-     * since klog doesn't use this feature.
-     * Is the request for a cross-realm ticket?
-     */
-    if (strcasecmp(cell, localcell)) {
-       if (debug)
-           fprintf(stderr, "ERROR: Cell %s != local cell", cell);
-       ERR(KABADTICKET);
-    }
-
-    /*
-     * Even if we later decide to issue cross-realm tickets,
-     * we should not permit "realm hopping".
-     * This means that the client's realm should match
-     * the realm of the tgt with whose key we are supposed
-     * to decrypt the ticket.  I think.
-     */
-    if (*realm && strcasecmp(realm, cell)) {
-       if (debug)
-           fprintf(stderr, "ERROR: Realm %s != cell %s\n", realm, cell);
-       ERR(KABADTICKET);
-    }
-
-    /*
-     * This translator issues service tickets only for afs,
-     * since klog is the only client that should be using it.
-     * Is the requested service afs?
-     *
-     * Note: to make EMT work, we're allowing tickets for emt/admin and
-     * adm/admin.
-     */
-    if (! ((strcmp(rname, "afs") == 0 && ! *rinst) ||
-          (strcmp(rname, "emt") == 0 && strcmp(rinst, "admin") == 0) ||
-          (strcmp(rname, "adm") == 0 && strcmp(rinst, "admin") == 0)))
-       ERR(KABADSERVER);
-
-    /*
-     * If the local realm name and cell name differ and the user
-     * is in the local cell and has requested a ticket of afs. (no
-     * instance, then we actually want to get a ticket for
-     * afs/<cell name>@<realm name>
-     */
-    if ((strcmp(rname, "afs") == 0) && !*rinst &&
-       strcmp(localrealm, localcell) &&
-       (strcasecmp(cell, localcell) == 0)) {
-       char *c;
-
-       strlcpy(rinst, localcell, sizeof(rinst));
-
-       for (c = rinst; *c != NULL; c++)
-           *c = (char) tolower( (int) *c);
-
-       if (debug)
-           fprintf(stderr, "Getting ticket for afs/%s\n", localcell);
-    }
-   
-    /*
-     * Even if we later decide to issue service tickets for
-     * services other than afs, we should still disallow
-     * the "changepw" and "krbtgt" services.
-     */
-    if (!strcmp(rname, "changepw") || !strcmp(rname, "krbtgt"))
-       ERR(KABADSERVER);
-
-    /*
-     * Is the tgt valid yet?  (ie. is the start time in the future)
-     */
-    if (req_time < tgt_start_time - CLOCK_SKEW) {
-       if (debug)
-           fprintf(stderr, "ERROR: Ticket not yet valid\n");
-       ERR(KABADTICKET);
-    }
-
-    /*
-     * Has the tgt expired?  (ie. is the end time in the past)
-     *
-     * Sigh, convert from V4 lifetimes back to Unix epoch times.
-     */
-
-    if (tgt_lifetime < 128)
-       tgt_end_time = tgt_start_time + tgt_lifetime * 300;
-    else if (tgt_lifetime < 192)
-       tgt_end_time = tgt_start_time + cmu_seconds[tgt_lifetime - 128];
-    else
-       tgt_end_time = tgt_start_time + MAX_TICKET_LIFETIME;
-
-    if (tgt_end_time < req_time) {
-       if (debug)
-           fprintf(stderr, "ERROR: Ticket expired\n");
-       ERR(KABADTICKET);
-    }
-
-    /*
-     * This translator uses the requested start time as a cheesy
-     * authenticator, since the KA protocol does not have an
-     * explicit authenticator.  We can do this since klog always
-     * requests a start time equal to the current time.
-     * 
-     * Is the requested start time approximately now?
-     */
-    if (abs(req_time - start_time) > CLOCK_SKEW)
-       ERR(KACLOCKSKEW);
-
-    /*
-     * The new ticket's lifetime is the minimum of:
-     * 1.  remainder of tgt's lifetime
-     * 2.  requested lifetime
-     * 
-     * This is further limited by the client and service's max lifetime
-     * in make_reply_packet().
-     */
-
-    lifetime = tgt_end_time - req_time;
-    lifetime = min(lifetime, end_time - start_time);
-    end_time = req_time + lifetime;
-
-    /*
-     * We have all the data from the request, now generate the reply.
-     */
-
-    rv = make_reply_packet(context, handle, reply, 0, start_time, end_time,
-                          cname, cinst, rname, rinst,
-                          session_key, session_sched, "gtkt");
-  error:
-    memset(ticket, 0, sizeof(ticket));
-    memset(session_key, 0, sizeof(session_key));
-    memset(session_sched, 0, sizeof(session_sched));
-
-    if (free_princ_ent)
-       kadm5_free_principal_ent(handle, &cprinc);
-
-    syslog(LOG_INFO, "getticket: %s.%s from %s for %s.%s",
-          cname, cinst, from, rname, rinst);
-    if (rv) {
-       syslog(LOG_INFO, "... failed due to %s", kaerror(rv));
-    }
-    return rv;
-}
-
-
-#undef ERR
-#undef ADVANCE
-#undef GET_INT
-#undef GET_PSTR
-#undef GET_STR
-
-/*
- * Convert the request into a reply.
- * Returns 0 on success.
- */
-
-void process(context, handle, from, req, reply)
-krb5_context context;
-void *handle;
-char *from;
-packet_t req, reply;
-{
-    int rv;
-    rx_t req_rx = (rx_t)req->base;
-    rx_t reply_rx = (rx_t)reply->base;
-    int service, request;
-
-    service = ntohs(req_rx->rx_service);
-    request = ntohl(req_rx->rx_request);
-
-    /* ignore everything but type 1 */
-    if (req_rx->rx_type != 1) {
-       reply->len = 0;
-       return;
-    }
-
-    /* copy the rx header and change the flags */
-    *reply_rx = *req_rx;
-    reply_rx->rx_flags = 4;
-
-    rv = -1;
-
-    if (service == 0x2db && (request == 0x15 || request == 0x16)) {
-       if (debug)
-           fprintf(stderr, "Handling Authenticate request\n");
-       rv = Authenticate(context, handle, from, req, reply);
-    }
-    if (service == 0x2dc && request == 0x17) {
-       if (debug)
-           fprintf(stderr, "Handling GetTicket request\n");
-       rv = GetTicket(context, handle, from, req, reply);
-    }
-/*
-    if (service == 0x2db && request == 0x1) {
-       rv = Authenticate_old(from, req, reply);
-    }
-    if (service == 0x2dc && request == 0x3) {
-       rv = GetTicket_old(from, req, reply);
-    }
- */
-    if (rv == -1) {
-       syslog(LOG_INFO, "bogus request %d/%d", service, request);
-       rv = KABADREQUEST;
-    }
-
-    if (rv) {
-       /* send the error back to rx */
-       reply->len = sizeof (*reply_rx);
-
-       reply_rx->rx_type = 4;
-       reply_rx->rx_flags = 0;
-       reply_rx->rx_request = ntohl(rv);
-    }
-}
-
-
-int main(argc, argv)
-int argc;
-char **argv;
-{
-    int s, rv, ch, mflag = 0;
-    u_short port;
-    struct sockaddr_in sin;
-    int forwarders[MAXFORWARDERS], num_forwarders;
-    krb5_context context;
-    krb5_error_code code;
-    krb5_keyblock mkey;
-    krb5_principal master_princ;
-    kadm5_principal_ent_rec master_princ_rec;
-    void *handle;
-    facility_mapping *mapping;
-    int facility = LOG_DAEMON;
-
-    extern char *optarg;
-
-    port = 7004;
-    num_forwarders = 0;
-
-    /*
-     * Parse args.
-     */
-    while ((ch = getopt(argc, argv, "c:df:l:mp:r:")) != -1) {
-       switch (ch) {
-       case 'c':
-           localcell = optarg;
-           break;
-       case 'd':
-           debug++;
-           break;
-       case 'f': {
-           struct hostent *hp;
-
-           if (num_forwarders++ >= MAXFORWARDERS)
-               pexit("too many forwarders\n");
-
-           hp = gethostbyname(optarg);
-           if (!hp) {
-               printf("unknown host %s\n", optarg);
-               exit(1);
-           }
-           forwarders[num_forwarders - 1] = *(int *)hp->h_addr;
-
-           break;
-       }
-       case 'l':
-           for (mapping = mappings; mapping->string != NULL; mapping++)
-               if (strcmp(mapping->string, optarg) == 0)
-                   break;
-
-               if (mapping->string == NULL) {
-                   printf("Unknown facility \"%s\"\n", optarg);
-                   exit(1);
-               }
-
-               facility = mapping->num;
-               break;
-       case 'm':
-           mflag = 1;
-           break;
-       case 'p':
-           if (isdigit(*optarg)) {
-               port = atoi(optarg);
-           }
-           else {
-               struct servent *sp;
-
-               sp = getservbyname(optarg, "udp");
-               if (!sp) {
-                   printf("unknown service %s\n", optarg);
-                   exit(1);
-               }
-               port = sp->s_port;
-           }
-           break;
-       case 'r':
-           localrealm = optarg;
-           break;
-       default:
-           printf("usage: %s [-c cell] [-d] [-f forwarder-host] [-l facility ] [-p port] [-r realm]\n",
-                  argv[0]);
-           exit(1);
-       }
-    }
-
-    openlog("fakeka", LOG_PID, facility);
-
-    port = htons(port);
-
-    /*
-     * Set up the socket.
-     */
-
-    s = socket(AF_INET, SOCK_DGRAM, 0);
-    if (s < 0)
-       perrorexit("Couldn't create socket");
-    set_cloexec_fd(s);
-
-    sin.sin_family = AF_INET;
-    sin.sin_addr.s_addr = 0;
-    sin.sin_port = port;
-
-    rv = bind(s, (struct sockaddr *)&sin, sizeof(sin));
-    if (rv < 0)
-       perrorexit("Couldn't bind socket");
-
-    /*
-     * Initialize kerberos stuff and kadm5 stuff.
-     */
-
-    if ((code = krb5int_init_context_kdc(&context))) {
-       com_err(argv[0], code, "while initializing Kerberos");
-       exit(1);
-    }
-
-    if (!localrealm && (code = krb5_get_default_realm(context, &localrealm))) {
-       com_err(argv[0], code, "while getting local realm");
-       exit(1);
-    }
-
-    if (!localcell)
-       localcell = localrealm;
-
-    if ((code = kadm5_init_with_password(progname, NULL, KADM5_ADMIN_SERVICE,
-                                        NULL, KADM5_STRUCT_VERSION,
-                                        KADM5_API_VERSION_2,
-                                        (char **) NULL, /* db_args */
-                                        &handle))) {
-       com_err(argv[0], code, "while initializing Kadm5");
-       exit(1);
-    }
-
-    if ((code = kadm5_get_config_params(context, 1, NULL,
-                                       &realm_params))) {
-       com_err(argv[0], code, "while getting realm parameters");
-       exit(1);
-    }
-
-    if (! (realm_params.mask & KADM5_CONFIG_MAX_LIFE)) {
-       fprintf(stderr, "Cannot determine maximum ticket lifetime\n");
-       exit(1);
-    }
-
-    /*
-     * We need to initialize the random number generator for DES.  Use
-     * the master key to do this.
-     */
-
-    if ((code = krb5_parse_name(context, realm_params.mask &
-                               KADM5_CONFIG_MKEY_NAME ?
-                               realm_params.mkey_name : "K/M",
-                               &master_princ))) {
-       com_err(argv[0], code, "while parsing master key name");
-       exit(1);
-    }
-
-    if ((code = kadm5_get_principal(handle, master_princ, &master_princ_rec,
-                                   KADM5_KEY_DATA))) {
-       com_err(argv[0], code, "while getting master key data");
-       exit(1);
-    }
-
-    if ((code = kadm5_decrypt_key(handle, &master_princ_rec,
-                                 ENCTYPE_DES_CBC_CRC, -1, 0, &mkey, NULL,
-                                 NULL))) {
-       com_err(argv[0], code, "while decrypting the master key");
-       exit(1);
-    }
-
-    des_init_random_number_generator(mkey.contents);
-
-    krb5_free_keyblock_contents(context, &mkey);
-
-    kadm5_free_principal_ent(handle, &master_princ_rec);
-
-    krb5_free_principal(context, master_princ);
-
-    /*
-     * Fork and go into the background, if requested
-     */
-
-    if (!debug && mflag && daemon(0, 0)) {
-       com_err(argv[0], errno, "while detaching from tty");
-    }
-
-    /*
-     * rpc server loop.
-     */
-
-    for (;;) {
-       struct packet req, reply;
-       int sinlen, packetlen, i, forwarded;
-       char *from;
-
-       sinlen = sizeof(sin);
-       forwarded = 0;
-
-       memset(req.data, 0, sizeof(req.data));
-       rv = recvfrom(s, req.data, sizeof(req.data),
-                     0, (struct sockaddr *)&sin, &sinlen);
-
-       if (rv < 0) {
-           syslog(LOG_ERR, "recvfrom failed: %m");
-           sleep(1);
-           continue;
-       }
-       packetlen = rv;
-
-       for (i = 0; i < num_forwarders; i++) {
-           if (sin.sin_addr.s_addr == forwarders[i]) {
-               forwarded = 1;
-               break;
-           }
-       }
-
-       if ((code = krb5_timeofday(context, &req_time))) {
-               syslog(LOG_ERR, "krb5_timeofday failed: %s",
-                      error_message(code));
-               continue;
-       }
-
-       memset(reply.data, 0, sizeof(reply.data));
-       req.len = packetlen;
-       req.base = req.data;
-       reply.base = reply.data;
-       reply.len = sizeof(reply.data);
-
-       if (forwarded) {
-           struct in_addr ia;
-
-           memcpy(&ia.s_addr, req.data, 4);
-           from = inet_ntoa(ia);
-           /*
-            * copy the forwarder header and adjust the bases and lengths.
-            */
-           memcpy(reply.data, req.data, HEADER_LEN);
-           req.base += HEADER_LEN;
-           req.len -= HEADER_LEN;
-           reply.base += HEADER_LEN;
-           reply.len -= HEADER_LEN;
-       }
-       else {
-           from = inet_ntoa(sin.sin_addr);
-       }
-
-       process(context, handle, from, &req, &reply);
-
-       if (reply.len == 0)
-           continue;
-
-       if (forwarded) {
-           /* re-adjust the length to account for the forwarder header */
-           reply.len += HEADER_LEN;
-       }
-
-       rv = sendto(s, reply.data, reply.len,
-                   0, (struct sockaddr *)&sin, sinlen);
-       if (rv < 0) {
-           syslog(LOG_ERR, "sendto failed: %m");
-           sleep(1);
-       }
-    }
-    /*NOTREACHED*/
-}
index b535acd819d46d4894314f728b12ed909febf76a..ca644ac6d1cee40aa1c5ce0a64b1658e4d0cd14e 100644 (file)
@@ -192,16 +192,6 @@ get_principal (krb5_context kcontext,
 #define setflag(flagfield, flag) (flagfield |= (flag))
 #define clear(flagfield, flag) (flagfield &= ~(flag))
 
-#ifdef KRB5_KRB4_COMPAT
-krb5_error_code process_v4 (const krb5_data *,
-                                     const krb5_fulladdr *,
-                                     krb5_data **);
-void process_v4_mode (const char *, const char *);
-void enable_v4_crossrealm(char *);
-#else
-#define process_v4(foo,bar,quux,foobar)        KRB5KRB_AP_ERR_BADVERSION
-#endif
-
 #ifndef        min
 #define        min(a, b)       ((a) < (b) ? (a) : (b))
 #define        max(a, b)       ((a) > (b) ? (a) : (b))
diff --git a/src/kdc/kerberos_v4.c b/src/kdc/kerberos_v4.c
deleted file mode 100644 (file)
index a0c74a1..0000000
+++ /dev/null
@@ -1,1188 +0,0 @@
-/*
- * kdc/kerberos_v4.c
- *
- * Copyright 1985, 1986, 1987, 1988,1991,2007 by the Massachusetts Institute
- * of Technology.
- * All Rights Reserved.
- *
- * Export of this software from the United States of America may
- *   require a specific license from the United States Government.
- *   It is the responsibility of any person or organization contemplating
- *   export to obtain such a license before exporting.
- * 
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of M.I.T. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission.  Furthermore if you modify this software you must label
- * your software as modified software and not distribute it in such a
- * fashion that it might be confused with the original M.I.T. software.
- * M.I.T. makes no representations about the suitability of
- * this software for any purpose.  It is provided "as is" without express
- * or implied warranty.
- * 
- */
-
-#include "autoconf.h"
-#ifdef KRB5_KRB4_COMPAT
-#define BACKWARD_COMPAT
-
-#include "k5-int.h"
-#include "kdc_util.h"
-#include "adm_proto.h"
-
-#include <stdarg.h>
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <signal.h>
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#ifdef TIME_WITH_SYS_TIME
-#include <time.h>
-#endif
-#else
-#include <time.h>
-#endif
-#include <sys/file.h>
-#include <ctype.h>
-#include <syslog.h>
-#include <string.h>
-#include <errno.h>
-
-/* v4 include files:
- */
-#include <krb.h>
-#include <des.h>
-#include <klog.h>
-#include <prot.h>
-#include <krb_db.h>
-
-#ifdef NEED_SWAB_PROTO
-extern void swab(const void *, void *, size_t );
-#endif
-
-static int compat_decrypt_key (krb5_key_data *, C_Block,
-                                        krb5_keyblock *, int);
-static int kerb_get_principal (char *, char *, Principal *,
-                                        int *, krb5_keyblock *, krb5_kvno,
-                                        int, krb5_deltat *);
-static int check_princ (char *, char *, int, Principal *,
-                                 krb5_keyblock *, int, krb5_deltat *);
-
-static char * v4_klog (int, const char *, ...)
-#if !defined(__cplusplus) && (__GNUC__ > 2)
-    __attribute__((__format__(__printf__, 2, 3)))
-#endif
-    ;
-#define klog v4_klog
-
-/* Byte ordering */
-/*#define              MSB_FIRST               0       / * 68000, IBM RT/PC */
-/*#define              LSB_FIRST               1       / * Vax, PC8086 */
-#if defined K5_LE
-# define HOST_BYTE_ORDER 1
-#elif defined K5_BE
-# define HOST_BYTE_ORDER 0
-#else
-static int krbONE = 1;
-# define HOST_BYTE_ORDER (* (char *) &krbONE)
-#endif
-
-#ifndef BACKWARD_COMPAT
-static Key_schedule master_key_schedule;
-static C_Block master_key;
-#endif
-
-static struct timeval kerb_time;
-static Principal a_name_data;  /* for requesting user */
-static Principal s_name_data;  /* for services requested */
-static C_Block session_key;
-
-static char log_text[512];
-static char *lt;
-
-/* fields within the received request packet */
-static u_char req_msg_type;
-static u_char req_version;
-static char *req_name_ptr;
-static char *req_inst_ptr;
-static char *req_realm_ptr;
-
-static krb5_ui_4 req_time_ws;
-
-static char local_realm[REALM_SZ];
-
-static long n_auth_req;
-static long n_appl_req;
-
-static long pause_int = -1;
-
-static void hang(void);
-
-
-/* v4/v5 backwards-compatibility stub routines,
- * which allow the v5 server to handle v4 packets
- * by invoking substantially-unaltered v4 server code.
- * this is only necessary during the installation's conversion to v5.
- * process_v4() is invoked by v5's dispatch() routine;
- * when the v4 server needs to access the v5 database,
- * it calls the other stubs.
- *
- * until all kerberized application-programs are updated,
- * this approach inflates the v5 server's code size,
- * but it's easier to debug than a concurrent, subordinate v4 server would be.
- */
-
-/*
- * v5 include files:
- */
-#include "com_err.h"
-#include "extern.h"            /* to pick up master_princ */
-
-static krb5_data *kerberos_v4 (struct sockaddr_in *, KTEXT);
-static krb5_data *kerb_err_reply (struct sockaddr_in *, KTEXT, long, char *);
-static int set_tgtkey (char *, krb5_kvno, krb5_boolean);
-
-/* Attributes converted from V5 to V4 - internal representation */
-#define V4_KDB_REQUIRES_PREAUTH  0x1
-#define V4_KDB_DISALLOW_ALL_TIX  0x2
-#define V4_KDB_REQUIRES_PWCHANGE 0x4
-#define V4_KDB_DISALLOW_SVR      0x8
-
-/* v4 compatibitly mode switch */
-#define KDC_V4_NONE            0       /* Don't even respond to packets */
-#define KDC_V4_DISABLE         1       /* V4 requests return an error */
-#define        KDC_V4_FULL             2       /* Preauth required go through */
-#define KDC_V4_NOPREAUTH       3       /* Preauth required disallowed */
-
-#define KDC_V4_DEFAULT_MODE KDC_V4_NONE
-/* Flag on how to handle v4 */
-static int             kdc_v4;
-
-struct v4mode_lookup_entry {
-    int                 mode;                   /* Mode setting */
-    const char *       v4_specifier;           /* How to recognize it  */
-};
-
-static const struct v4mode_lookup_entry  v4mode_table[] = {
-/*  mode                input specifier */
-{ KDC_V4_NONE,          "none"          },
-{ KDC_V4_DISABLE,       "disable"       }, 
-{ KDC_V4_FULL,          "full"          },
-{ KDC_V4_NOPREAUTH,     "nopreauth"     }
-};
-
-static const int v4mode_table_nents = sizeof(v4mode_table)/
-                                     sizeof(v4mode_table[0]);
-
-static int allow_v4_crossrealm = 0;
-
-void process_v4_mode(const char *program_name, const char *string)
-{
-    int i, found;
-
-    found = 0;
-    kdc_v4 = KDC_V4_DEFAULT_MODE;
-
-    if(!string) return;  /* Set to default mode */
-    
-    for (i=0; i<v4mode_table_nents; i++) {
-       if (!strcasecmp(string, v4mode_table[i].v4_specifier)) {
-           found = 1;
-           kdc_v4 = v4mode_table[i].mode;
-           break;
-       }
-    }
-
-    if(!found) {
-      /* It is considered fatal if we request a mode that is not found */
-       com_err(program_name, 0, "invalid v4_mode %s", string);
-       exit(1);
-    }
-    return;
-}
-
-void enable_v4_crossrealm ( char *programname) {
-    allow_v4_crossrealm = 1;
-    krb5_klog_syslog(LOG_ERR, "Enabling v4 cross-realm compatibility; this is a known security hole");
-}
-
-krb5_error_code
-process_v4(const krb5_data *pkt, const krb5_fulladdr *client_fulladdr,
-          krb5_data **resp)
-{
-    struct sockaddr_in client_sockaddr;
-    krb5_address *addr = client_fulladdr->address;
-    krb5_error_code retval;
-    krb5_timestamp now;
-    KTEXT_ST v4_pkt;
-    char *lrealm;
-
-    /* Check if disabled completely */
-    if (kdc_v4 == KDC_V4_NONE) {
-       (void) klog(L_KRB_PERR, "Disabled KRB V4 request");
-       return KRB5KDC_ERR_BAD_PVNO;
-    }
-
-    
-    if ((retval = krb5_timeofday(kdc_context, &now)))
-        return(retval);
-    kerb_time.tv_sec = now;
-
-    if (!*local_realm) {               /* local-realm name already set up */
-       lrealm = master_princ->realm.data;
-       if (master_princ->realm.length < sizeof(local_realm)) {
-           memcpy(local_realm, lrealm, master_princ->realm.length);
-           local_realm[master_princ->realm.length] = '\0';
-       } else
-           retval = KRB5_CONFIG_NOTENUFSPACE;
-    }
-    /* convert client_fulladdr to client_sockaddr:
-     */
-    client_sockaddr.sin_family = AF_INET;
-    client_sockaddr.sin_port   = client_fulladdr->port;
-    if (client_fulladdr->address->addrtype != ADDRTYPE_INET) {
-       klog(L_KRB_PERR, "got krb4 request from non-ipv4 address");
-       client_sockaddr.sin_addr.s_addr = 0;
-    } else
-       memcpy(&client_sockaddr.sin_addr, addr->contents, 
-              sizeof client_sockaddr.sin_addr);
-    memset( client_sockaddr.sin_zero, 0, sizeof client_sockaddr.sin_zero);
-
-    /* convert v5 packet structure to v4's.
-     * this copy is gross, but necessary:
-     */
-    if (pkt->length > MAX_KTXT_LEN) {
-           (void) klog(L_KRB_PERR, "V4 request too long.");
-           return KRB5KRB_ERR_FIELD_TOOLONG;
-    }
-    memset( &v4_pkt, 0, sizeof(v4_pkt));
-    v4_pkt.length = pkt->length;
-    v4_pkt.mbz = 0;
-    memcpy( v4_pkt.dat, pkt->data, pkt->length);
-
-    *resp = kerberos_v4( &client_sockaddr, &v4_pkt);
-    return(retval);
-}
-
-static char * v4_klog( int type, const char *format, ...)
-{
-    int logpri = LOG_INFO;
-    va_list pvar;
-    va_start(pvar, format);
-
-    switch (type) {
-    case L_ERR_SEXP:
-    case L_ERR_NKY:
-    case L_ERR_NUN:
-    case L_ERR_UNK:
-    case L_KRB_PERR:
-       logpri = LOG_ERR;
-    case L_INI_REQ:
-    case L_NTGT_INTK:
-    case L_TKT_REQ:
-    case L_APPL_REQ:
-       strlcpy(log_text, "PROCESS_V4:", sizeof(log_text));
-       vsnprintf(log_text+strlen(log_text),
-                 sizeof(log_text) - strlen(log_text),
-                 format, pvar);
-       krb5_klog_syslog(logpri, "%s", log_text);
-    default:
-       /* ignore the other types... */
-       ;
-    }
-    va_end(pvar);
-    return(log_text);
-}
-
-static
-krb5_data *make_response(const char *msg, int len)
-{
-    krb5_data *response;
-
-    if (  !(response = (krb5_data *) malloc( sizeof *response))) {
-       return 0;
-    }
-    if ( !(response->data = (char *) malloc( len))) {
-       krb5_free_data(kdc_context,  response);
-       return 0;
-    }
-    response->length = len;
-    memcpy( response->data, msg, len);
-    return response;
-}
-static void
-hang(void)
-{
-    if (pause_int == -1) {
-        klog(L_KRB_PERR, "Kerberos will pause so as not to loop init");
-     /* for (;;)
-            pause(); */
-    } else {
-        char buf[256];
-        snprintf(buf, sizeof(buf),
-          "Kerberos will wait %d seconds before dying so as not to loop init",
-               (int) pause_int);
-        klog(L_KRB_PERR, buf);
-        sleep((unsigned) pause_int);
-        klog(L_KRB_PERR, "Do svedania....\n");
-     /* exit(1); */
-    }
-}
-#define kdb_encrypt_key( in, out, mk, mks, e_d_flag)
-#define LONGLEN 4
-#define K4KDC_ENCTYPE_OK(e)                    \
-((e) == ENCTYPE_DES_CBC_CRC                    \
- || (e) == ENCTYPE_DES_CBC_MD4                 \
- || (e) == ENCTYPE_DES_CBC_MD5                 \
- || (e) == ENCTYPE_DES_CBC_RAW)
-
-/* take a v5 keyblock, masquerading as a v4 key,
- * decrypt it, and convert the resulting v5 keyblock
- * to a real v4 key.
- * this is ugly, but it saves changing more v4 code.
- *
- * Also, keep old krb5_keyblock around in case we want to use it later.
- */
-static int
-compat_decrypt_key (krb5_key_data *in5, unsigned char *out4,
-                   krb5_keyblock *out5, int issrv)
-{
-    krb5_error_code retval;
-
-    out5->contents = NULL;
-    memset(out4, 0, sizeof(out4));
-    retval = krb5_dbekd_decrypt_key_data(kdc_context, &master_keyblock,
-                                        in5, out5, NULL);
-    if (retval) {
-       lt = klog(L_DEATH_REQ, "KDC can't decrypt principal's key.");
-       out5->contents = NULL;
-       return(retval);
-    }
-    if (K4KDC_ENCTYPE_OK(out5->enctype)) {
-       if (out5->length == KRB5_MIT_DES_KEYSIZE) 
-           memcpy(out4, out5->contents, out5->length);
-       else {
-           lt = klog(L_DEATH_REQ, "internal keysize error in kdc");
-           krb5_free_keyblock_contents(kdc_context, out5);
-           out5->contents = NULL;
-           retval = -1;
-       }
-    } else {
-       if (!issrv) {
-           lt = klog(L_DEATH_REQ, "incompatible principal key type.");
-           krb5_free_keyblock_contents(kdc_context, out5);
-           out5->contents = NULL;
-           retval = -1;
-       } else {
-           /* KLUDGE! If it's a non-raw des3 key, bash its enctype */
-           if (out5->enctype == ENCTYPE_DES3_CBC_SHA1 )
-               out5->enctype = ENCTYPE_DES3_CBC_RAW;
-       }
-    }
-    return(retval);
-}
-
-/* array of name-components + NULL ptr
- */
-
-/*
- * Previously this code returned either a v4 key or a v5 key  and you
- * could tell from the enctype of the v5 key whether the v4 key was
- * useful.  Now we return both keys so the code can try both des3 and
- * des decryption.  We fail if the ticket doesn't have a v4 key.
- * Also, note as a side effect, the v5 key is basically useless  in
- * the client case.  It is still returned so the caller can free it.
- */
-static int
-kerb_get_principal(char *name, char *inst, /* could have wild cards */
-                  Principal *principal,
-                  int *more,   /* more tuples than room for */
-                  krb5_keyblock *k5key, krb5_kvno kvno,
-                  int issrv,   /* true if retrieving a service key */
-                  krb5_deltat *k5life)
-{
-    /* Note that this structure should not be passed to the
-       krb5_free* functions, because the pointers within it point
-       to data with other references.  */
-    krb5_principal search;
-
-    krb5_db_entry entries;     /* filled in by krb5_db_get_principal() */
-    int nprinc;                        /* how many found */
-    krb5_boolean more5;                /* are there more? */
-    C_Block k;
-    short toggle = 0;
-    unsigned long *date;
-    char* text;
-    struct tm *tp;
-    krb5_key_data *pkey;
-    krb5_error_code retval;
-
-    *more = 0;
-    /* begin setting up the principal structure
-     * with the first info we have:
-     */
-    memcpy( principal->name,     name, 1 + strlen( name));
-    memcpy( principal->instance, inst, 1 + strlen( inst));
-
-    /* the principal-name format changed between v4 & v5:
-     *     v4: name.instance@realm
-     *     v5: realm/name/instance
-     *     in v5, null instance means the null-component doesn't exist.
-     */
-
-    if ((retval = krb5_425_conv_principal(kdc_context, name, inst, 
-                                         local_realm, &search)))
-       return(0);
-
-    /* The krb4 support in the KDC is not thread-safe yet, so maintain
-       the global lock until that gets fixed.  */
-    if ((retval = get_principal_locked(kdc_context, search, &entries, 
-                                      &nprinc, &more5))) {
-        krb5_free_principal(kdc_context, search);
-        return(0);
-    }
-    principal->key_low = principal->key_high = 0;
-    krb5_free_principal(kdc_context, search);
-
-    if (nprinc < 1) {
-        *more = (int)more5 || (nprinc > 1);
-        return(nprinc);
-    } 
-
-    if (!issrv) {
-       if (krb5_dbe_find_enctype(kdc_context,
-                                 &entries,
-                                 ENCTYPE_DES_CBC_CRC,
-                                 KRB5_KDB_SALTTYPE_V4,
-                                 kvno,
-                                 &pkey) &&
-           krb5_dbe_find_enctype(kdc_context,
-                                 &entries,
-                                 ENCTYPE_DES_CBC_CRC,
-                                 -1,
-                                 kvno,
-                                 &pkey)) {
-           lt = klog(L_KRB_PERR,
-                     "KDC V4: principal %s.%s isn't V4 compatible",
-                     name, inst);
-           krb5_db_free_principal(kdc_context, &entries, nprinc);
-           return(0);
-       }
-    } else {
-       if ( krb5_dbe_find_enctype(kdc_context, &entries,
-                                 ENCTYPE_DES_CBC_CRC,
-                                 KRB5_KDB_SALTTYPE_V4, kvno, &pkey) &&
-           krb5_dbe_find_enctype(kdc_context, &entries,
-                                 ENCTYPE_DES_CBC_CRC,
-                                 -1, kvno, &pkey)) {
-           lt = klog(L_KRB_PERR,
-                     "KDC V4: failed to find key for %s.%s #%d",
-                     name, inst, kvno);
-           krb5_db_free_principal(kdc_context, &entries, nprinc);
-           return(0);
-       }
-    }
-
-    if (!compat_decrypt_key(pkey, k, k5key, issrv)) {
-       memcpy( &principal->key_low, k, LONGLEN);
-               memcpy( &principal->key_high, (krb5_ui_4 *) k + 1, LONGLEN);
-    }
-    memset(k, 0, sizeof k);
-    if (issrv) {
-       krb5_free_keyblock_contents (kdc_context, k5key);
-       if (krb5_dbe_find_enctype(kdc_context, &entries,
-                                 ENCTYPE_DES3_CBC_RAW,
-                                 -1, kvno, &pkey) &&
-           krb5_dbe_find_enctype(kdc_context, &entries,
-                                 ENCTYPE_DES3_CBC_SHA1,
-                                 -1, kvno, &pkey) &&
-           krb5_dbe_find_enctype(kdc_context, &entries,
-                                 ENCTYPE_DES_CBC_CRC,
-                                 KRB5_KDB_SALTTYPE_V4, kvno, &pkey) &&
-           krb5_dbe_find_enctype(kdc_context, &entries,
-                                 ENCTYPE_DES_CBC_CRC,
-                                 -1, kvno, &pkey)) {
-           lt = klog(L_KRB_PERR,
-                     "KDC V4: failed to find key for %s.%s #%d (after having found it once)",
-                     name, inst, kvno);
-           krb5_db_free_principal(kdc_context, &entries, nprinc);
-           return(0);
-       }
-       compat_decrypt_key(pkey, k, k5key, issrv);
-       memset (k, 0, sizeof k);
-    }
-
-
-    /*
-     * Convert v5's entries struct to v4's Principal struct:
-     * v5's time-unit for lifetimes is 1 sec, while v4 uses 5 minutes,
-     * and gets weirder above (128 * 300) seconds.
-     */
-    principal->max_life = krb_time_to_life(0, entries.max_life);
-    if (k5life != NULL)
-       *k5life = entries.max_life;
-    /*
-     * This is weird, but the intent is that the expiration is the minimum
-     * of the principal expiration and key expiration
-     */
-    principal->exp_date = (unsigned long) 
-        entries.expiration && entries.pw_expiration ?
-        min(entries.expiration, entries.pw_expiration) :
-        (entries.pw_expiration ? entries.pw_expiration :
-        entries.expiration);
-/*    principal->mod_date = (unsigned long) entries.mod_date; */
-/* Set the master key version to 1. It's not really useful because all keys
- * will be encrypted in the same master key version, and digging out the 
- * actual key version will be harder than it's worth --proven */
-/*    principal->kdc_key_ver = entries.mkvno; */
-    principal->kdc_key_ver = 1;
-    principal->key_version = pkey->key_data_kvno;
-    /* We overload the attributes with the relevant v5 ones */
-    principal->attributes = 0;
-    if (isflagset(entries.attributes,  KRB5_KDB_REQUIRES_HW_AUTH) ||
-       isflagset(entries.attributes,  KRB5_KDB_REQUIRES_PRE_AUTH)) {
-          principal->attributes |= V4_KDB_REQUIRES_PREAUTH;
-    }
-    if (isflagset(entries.attributes,  KRB5_KDB_DISALLOW_ALL_TIX)) {
-          principal->attributes |= V4_KDB_DISALLOW_ALL_TIX;
-    }
-    if (issrv && isflagset(entries.attributes, KRB5_KDB_DISALLOW_SVR)) {
-       principal->attributes |= V4_KDB_DISALLOW_SVR;
-    }
-    if (isflagset(entries.attributes,  KRB5_KDB_REQUIRES_PWCHANGE)) {
-          principal->attributes |= V4_KDB_REQUIRES_PWCHANGE;
-    }
-
-    /* set up v4 format of each date's text: */
-    for ( date = &principal->exp_date, text = principal->exp_date_txt;
-         toggle ^= 1;
-         date = &principal->mod_date, text = principal->mod_date_txt) {
-       tp = localtime( (time_t *) date);
-       snprintf(text, sizeof(principal->mod_date_txt), "%4d-%02d-%02d",
-                tp->tm_year > 1900 ? tp->tm_year : tp->tm_year + 1900,
-                tp->tm_mon + 1, tp->tm_mday); /* January is 0, not 1 */
-    }
-    /*
-     * free the storage held by the v5 entry struct,
-     * which was allocated by krb5_db_get_principal().
-     * this routine clears the keyblock's contents for us.
-     */
-    krb5_db_free_principal(kdc_context, &entries, nprinc);
-    *more = (int) more5 || (nprinc > 1);
-    return( nprinc);
-}
-
-static void str_length_check(char *str, int max_size)
-{
-       int     i;
-       char    *cp;
-
-       for (i=0, cp = str; i < max_size-1; i++, cp++) {
-               if (*cp == 0)
-                       return;
-       }
-       *cp = 0;
-}
-
-static krb5_data *
-kerberos_v4(struct sockaddr_in *client, KTEXT pkt)
-{
-    static KTEXT_ST rpkt_st;
-    KTEXT   rpkt = &rpkt_st;
-    static KTEXT_ST ciph_st;
-    KTEXT   ciph = &ciph_st;
-    static KTEXT_ST tk_st;
-    KTEXT   tk = &tk_st;
-    static KTEXT_ST auth_st;
-    KTEXT   auth = &auth_st;
-    AUTH_DAT ad_st;
-    AUTH_DAT *ad = &ad_st;
-    krb5_data *response = 0;
-
-    static struct in_addr client_host;
-    static int msg_byte_order;
-    static int swap_bytes;
-    static u_char k_flags;
- /* char   *p_name, *instance; */
-    int     lifetime = 0;
-    int     i;
-    C_Block key;
-    Key_schedule key_s;
-    char   *ptr;
-
-    krb5_keyblock k5key;
-    krb5_kvno kvno;
-    krb5_deltat sk5life, ck5life;
-    KRB4_32 v4endtime, v4req_end;
-
-    k5key.contents = NULL;     /* in case we have to free it */
-
-    ciph->length = 0;
-
-    client_host = client->sin_addr;
-
-    /* eval macros and correct the byte order and alignment as needed */
-    req_version = pkt_version(pkt);    /* 1 byte, version */
-    req_msg_type = pkt_msg_type(pkt);  /* 1 byte, Kerberos msg type */
-
-    /* set these to point to something safe */
-    req_name_ptr = req_inst_ptr = req_realm_ptr = "";
-
-    /* check if disabled, but we tell client */
-    if (kdc_v4 == KDC_V4_DISABLE) {
-       lt = klog(L_KRB_PERR,
-       "KRB will not handle v4 request from %s",
-                 inet_ntoa(client_host));
-       /* send an error reply */
-       req_name_ptr = req_inst_ptr = req_realm_ptr = "";
-       return kerb_err_reply(client, pkt, KERB_ERR_PKT_VER, lt);
-    }
-
-    /* check packet version */
-    if (req_version != KRB_PROT_VERSION) {
-       lt = klog(L_KRB_PERR,
-                 "KRB prot version mismatch: KRB =%d request = %d",
-                 KRB_PROT_VERSION, req_version);
-       /* send an error reply */
-       req_name_ptr = req_inst_ptr = req_realm_ptr = "";
-       return kerb_err_reply(client, pkt, KERB_ERR_PKT_VER, lt);
-    }
-    msg_byte_order = req_msg_type & 1;
-
-    swap_bytes = 0;
-    if (msg_byte_order != HOST_BYTE_ORDER) {
-       swap_bytes++;
-    }
-    klog(L_KRB_PINFO,
-       "Prot version: %d, Byte order: %d, Message type: %d",
-        (int) req_version, msg_byte_order, req_msg_type);
-
-    switch (req_msg_type & ~1) {
-
-    case AUTH_MSG_KDC_REQUEST:
-       {
-           int    req_life;    /* Requested liftime */
-           unsigned int request_backdate =  0; /*How far to backdate
-                                                 in seconds.*/
-           char   *service;    /* Service name */
-           char   *instance;   /* Service instance */
-#ifdef notdef
-           int     kerno;      /* Kerberos error number */
-#endif
-           n_auth_req++;
-           tk->length = 0;
-           k_flags = 0;        /* various kerberos flags */
-
-
-           /* set up and correct for byte order and alignment */
-           req_name_ptr = (char *) pkt_a_name(pkt);
-           str_length_check(req_name_ptr, ANAME_SZ);
-           req_inst_ptr = (char *) pkt_a_inst(pkt);
-           str_length_check(req_inst_ptr, INST_SZ);
-           req_realm_ptr = (char *) pkt_a_realm(pkt);
-           str_length_check(req_realm_ptr, REALM_SZ);
-           memcpy(&req_time_ws, pkt_time_ws(pkt), sizeof(req_time_ws));
-           /* time has to be diddled */
-           if (swap_bytes) {
-               swap_u_long(req_time_ws);
-           }
-           ptr = (char *) pkt_time_ws(pkt) + 4;
-
-           req_life = (*ptr++) & 0xff;
-
-           service = ptr;
-           str_length_check(service, SNAME_SZ);
-           instance = ptr + strlen(service) + 1;
-           str_length_check(instance, INST_SZ);
-
-           rpkt = &rpkt_st;
-
-           klog(L_INI_REQ,
-                "Initial ticket request Host: %s User: \"%s\" \"%s\"",
-                inet_ntoa(client_host), req_name_ptr, req_inst_ptr);
-
-           if ((i = check_princ(req_name_ptr, req_inst_ptr, 0,
-                                &a_name_data, &k5key, 0, &ck5life))) {
-               response = kerb_err_reply(client, pkt, i, "check_princ failed");
-               a_name_data.key_low = a_name_data.key_high = 0;
-               krb5_free_keyblock_contents(kdc_context, &k5key);
-               return response;
-           }
-           /* don't use k5key for client */
-           krb5_free_keyblock_contents(kdc_context, &k5key);
-           tk->length = 0;     /* init */
-           if (strcmp(service, "krbtgt"))
-               klog(L_NTGT_INTK,
-                    "INITIAL request from %s.%s for %s.%s", req_name_ptr,
-                    req_inst_ptr, service, instance);
-           /* this does all the checking */
-           if ((i = check_princ(service, instance, lifetime,
-                                &s_name_data, &k5key, 1, &sk5life))) {
-               response = kerb_err_reply(client, pkt, i, "check_princ failed");
-               a_name_data.key_high = a_name_data.key_low = 0;
-               s_name_data.key_high = s_name_data.key_low = 0;
-               krb5_free_keyblock_contents(kdc_context, &k5key);
-               return response;
-           }
-           /* Bound requested lifetime with service and user */
-           v4req_end = krb_life_to_time(kerb_time.tv_sec, req_life);
-           v4req_end = min(v4req_end, kerb_time.tv_sec + ck5life);
-           v4req_end = min(v4req_end, kerb_time.tv_sec + sk5life);
-           lifetime = krb_time_to_life(kerb_time.tv_sec, v4req_end);
-           v4endtime = krb_life_to_time(kerb_time.tv_sec, lifetime);
-           /*
-            * Adjust issue time backwards if necessary, due to
-            * roundup in krb_time_to_life().
-            */
-           if (v4endtime > v4req_end)
-               request_backdate = v4endtime - v4req_end;
-
-#ifdef NOENCRYPTION
-           memset(session_key, 0, sizeof(C_Block));
-#else
-           /* random session key */
-           des_new_random_key(session_key);
-#endif
-
-           /* unseal server's key from master key */
-           memcpy( key,                &s_name_data.key_low,  4);
-           memcpy( ((krb5_ui_4 *) key) + 1, &s_name_data.key_high, 4);
-
-           s_name_data.key_low = s_name_data.key_high = 0;
-           kdb_encrypt_key(key, key, master_key,
-                           master_key_schedule, DECRYPT);
-           /* construct and seal the ticket */
-           /* We always issue des tickets; the 3des tickets are a broken hack*/
-           krb_create_ticket(tk, k_flags, a_name_data.name,
-                             a_name_data.instance, local_realm,
-                             client_host.s_addr, (char *) session_key,
-                             lifetime, kerb_time.tv_sec - request_backdate,
-                             s_name_data.name, s_name_data.instance,
-                             key);
-
-           krb5_free_keyblock_contents(kdc_context, &k5key);
-           memset(key, 0, sizeof(key));
-           memset(key_s, 0, sizeof(key_s));
-
-           /*
-            * get the user's key, unseal it from the server's key, and
-            * use it to seal the cipher 
-            */
-
-           /* a_name_data.key_low a_name_data.key_high */
-           memcpy( key,                &a_name_data.key_low,  4);
-           memcpy( ((krb5_ui_4 *) key) + 1, &a_name_data.key_high, 4);
-           a_name_data.key_low= a_name_data.key_high = 0;
-
-           /* unseal the a_name key from the master key */
-           kdb_encrypt_key(key, key, master_key, 
-                           master_key_schedule, DECRYPT);
-
-           create_ciph(ciph, session_key, s_name_data.name,
-                       s_name_data.instance, local_realm, lifetime,
-                 s_name_data.key_version, tk, kerb_time.tv_sec, key);
-
-           /* clear session key */
-           memset(session_key, 0, sizeof(session_key));
-
-           memset(key, 0, sizeof(key));
-
-
-
-           /* always send a reply packet */
-           rpkt = create_auth_reply(req_name_ptr, req_inst_ptr,
-               req_realm_ptr, req_time_ws, 0, a_name_data.exp_date,
-               a_name_data.key_version, ciph);
-           response = make_response((char *) rpkt->dat, rpkt->length);
-           memset(&a_name_data, 0, sizeof(a_name_data));
-           memset(&s_name_data, 0, sizeof(s_name_data));
-           break;
-       }
-    case AUTH_MSG_APPL_REQUEST:
-       {
-           krb5_ui_4  time_ws; /* Workstation time */
-           int    req_life;    /* Requested liftime */
-           char   *service;    /* Service name */
-           char   *instance;   /* Service instance */
-           int     kerno = 0;  /* Kerberos error number */
-           unsigned int request_backdate =  0; /*How far to backdate
-                                                 in seconds.*/
-           char    tktrlm[REALM_SZ];
-
-           n_appl_req++;
-           tk->length = 0;
-           k_flags = 0;        /* various kerberos flags */
-
-           auth->mbz = 0;      /* pkt->mbz already zeroed */
-           auth->length = 4 + strlen((char *)pkt->dat + 3);
-           if (auth->length + 1 >= MAX_KTXT_LEN) {
-               lt = klog(L_KRB_PERR,
-                         "APPL request with realm length too long from %s",
-                         inet_ntoa(client_host));
-               return kerb_err_reply(client, pkt, RD_AP_INCON,
-                                     "realm length too long");
-           }
-
-           auth->length += (int) *(pkt->dat + auth->length) +
-               (int) *(pkt->dat + auth->length + 1) + 2;
-           if (auth->length > MAX_KTXT_LEN) {
-               lt = klog(L_KRB_PERR,
-                         "APPL request with funky tkt or req_id length from %s",
-                         inet_ntoa(client_host));
-               return kerb_err_reply(client, pkt, RD_AP_INCON,
-                                     "funky tkt or req_id length");
-           }
-
-           memcpy(auth->dat, pkt->dat, auth->length);
-
-           strncpy(tktrlm, (char *)auth->dat + 3, REALM_SZ);
-           tktrlm[REALM_SZ-1] = '\0';
-           kvno = (krb5_kvno)auth->dat[2];
-           if ((!allow_v4_crossrealm)&&strcmp(tktrlm, local_realm) != 0) {
-               lt = klog(L_ERR_UNK,
-                         "Cross realm ticket from %s denied by policy,", tktrlm);
-               return kerb_err_reply(client, pkt,
-                                     KERB_ERR_PRINCIPAL_UNKNOWN, lt);
-           }
-           if (set_tgtkey(tktrlm, kvno, 0)) {
-               lt = klog(L_ERR_UNK,
-                         "FAILED set_tgtkey realm %s, kvno %d. Host: %s ",
-                         tktrlm, kvno, inet_ntoa(client_host));
-               /* no better error code */
-               return kerb_err_reply(client, pkt,
-                                     KERB_ERR_PRINCIPAL_UNKNOWN, lt);
-           }
-           kerno = krb_rd_req(auth, "krbtgt", tktrlm, client_host.s_addr,
-                              ad, 0);
-           if (kerno) {
-               if (set_tgtkey(tktrlm, kvno, 1)) {
-                   lt = klog(L_ERR_UNK,
-                             "FAILED 3des set_tgtkey realm %s, kvno %d. Host: %s ",
-                             tktrlm, kvno, inet_ntoa(client_host));
-                   /* no better error code */
-                   return kerb_err_reply(client, pkt,
-                                         KERB_ERR_PRINCIPAL_UNKNOWN, lt);
-               }
-               kerno = krb_rd_req(auth, "krbtgt", tktrlm, client_host.s_addr,
-                                  ad, 0);
-           }
-
-           if (kerno) {
-               klog(L_ERR_UNK, "FAILED krb_rd_req from %s: %s",
-                    inet_ntoa(client_host), krb_get_err_text(kerno));
-               req_name_ptr = req_inst_ptr = req_realm_ptr = "";
-               return kerb_err_reply(client, pkt, kerno, "krb_rd_req failed");
-           }
-           ptr = (char *) pkt->dat + auth->length;
-
-           memcpy(&time_ws, ptr, 4);
-           ptr += 4;
-
-           req_life = (*ptr++) & 0xff;
-
-           service = ptr;
-           str_length_check(service, SNAME_SZ);
-           instance = ptr + strlen(service) + 1;
-           str_length_check(instance, INST_SZ);
-
-           klog(L_APPL_REQ, "APPL Request %s.%s@%s on %s for %s.%s",
-                ad->pname, ad->pinst, ad->prealm,
-                inet_ntoa(client_host), service, instance);
-           req_name_ptr = ad->pname;
-           req_inst_ptr = ad->pinst;
-           req_realm_ptr = ad->prealm;
-
-           if (strcmp(ad->prealm, tktrlm)) {
-               return kerb_err_reply(client, pkt, KERB_ERR_PRINCIPAL_UNKNOWN,
-                                     "Can't hop realms");
-           }
-           if (!strcmp(service, "changepw")) {
-               return kerb_err_reply(client, pkt, KERB_ERR_PRINCIPAL_UNKNOWN,
-                             "Can't authorize password changed based on TGT");
-           }
-           kerno = check_princ(service, instance, req_life,
-                               &s_name_data, &k5key, 1, &sk5life);
-           if (kerno) {
-               response = kerb_err_reply(client, pkt, kerno,
-                                         "check_princ failed");
-               s_name_data.key_high = s_name_data.key_low = 0;
-               krb5_free_keyblock_contents(kdc_context, &k5key);
-               return response;
-           }
-           /* Bound requested lifetime with service and user */
-           v4endtime = krb_life_to_time((KRB4_32)ad->time_sec, ad->life);
-           v4req_end = krb_life_to_time(kerb_time.tv_sec, req_life);
-           v4req_end = min(v4endtime, v4req_end);
-           v4req_end = min(v4req_end, kerb_time.tv_sec + sk5life);
-
-           lifetime = krb_time_to_life(kerb_time.tv_sec, v4req_end);
-           v4endtime = krb_life_to_time(kerb_time.tv_sec, lifetime);
-           /*
-            * Adjust issue time backwards if necessary, due to
-            * roundup in krb_time_to_life().
-            */
-           if (v4endtime > v4req_end)
-               request_backdate = v4endtime - v4req_end;
-
-           /* unseal server's key from master key */
-           memcpy(key,                &s_name_data.key_low,  4);
-           memcpy(((krb5_ui_4 *) key) + 1, &s_name_data.key_high, 4);
-           s_name_data.key_low = s_name_data.key_high = 0;
-           kdb_encrypt_key(key, key, master_key,
-                           master_key_schedule, DECRYPT);
-           /* construct and seal the ticket */
-
-#ifdef NOENCRYPTION
-           memset(session_key, 0, sizeof(C_Block));
-#else
-           /* random session key */
-           des_new_random_key(session_key);
-#endif
-
-           /* ALways issue des tickets*/
-           krb_create_ticket(tk, k_flags, ad->pname, ad->pinst,
-                             ad->prealm, client_host.s_addr,
-                             (char *) session_key, lifetime,
-                             kerb_time.tv_sec - request_backdate,
-                             s_name_data.name, s_name_data.instance,
-                             key);
-           krb5_free_keyblock_contents(kdc_context, &k5key);
-           memset(key, 0, sizeof(key));
-           memset(key_s, 0, sizeof(key_s));
-
-           create_ciph(ciph, session_key, service, instance,
-                       local_realm,
-                       lifetime, s_name_data.key_version, tk,
-                       kerb_time.tv_sec, ad->session);
-
-           /* clear session key */
-           memset(session_key, 0, sizeof(session_key));
-
-           memset(ad->session, 0, sizeof(ad->session));
-
-           rpkt = create_auth_reply(ad->pname, ad->pinst,
-                                    ad->prealm, time_ws,
-                                    0, 0, 0, ciph);
-           response = make_response((char *) rpkt->dat, rpkt->length);
-           memset(&s_name_data, 0, sizeof(s_name_data));
-           break;
-       }
-
-
-#ifdef notdef_DIE
-    case AUTH_MSG_DIE:
-       {
-           lt = klog(L_DEATH_REQ,
-               "Host: %s User: \"%s\" \"%s\" Kerberos killed",
-               inet_ntoa(client_host), req_name_ptr, req_inst_ptr, 0);
-           exit(0);
-       }
-#endif /* notdef_DIE */
-
-    default:
-       {
-           lt = klog(L_KRB_PERR,
-               "Unknown message type: %d from %s port %u",
-               req_msg_type, inet_ntoa(client_host),
-               ntohs(client->sin_port));
-           break;
-       }
-    }
-    return response;
-}
-
-
-
-/*
- * kerb_er_reply creates an error reply packet and sends it to the
- * client. 
- */
-
-static krb5_data *
-kerb_err_reply(struct sockaddr_in *client, KTEXT pkt, long int err, char *string)
-{
-    static KTEXT_ST e_pkt_st;
-    KTEXT   e_pkt = &e_pkt_st;
-    static char e_msg[128];
-
-    snprintf(e_msg, sizeof(e_msg), "\nKerberos error -- %s", string);
-    cr_err_reply(e_pkt, req_name_ptr, req_inst_ptr, req_realm_ptr,
-                req_time_ws, err, e_msg);
-    return make_response((char *) e_pkt->dat, e_pkt->length);
-}
-
-static int
-check_princ(char *p_name, char *instance, int lifetime, Principal *p,
-           krb5_keyblock *k5key, int issrv, krb5_deltat *k5life)
-{
-    static int n;
-    static int more;
- /* long trans; */
-
-    n = kerb_get_principal(p_name, instance, p, &more, k5key, 0,
-                          issrv, k5life);
-    klog(L_ALL_REQ,
-        "Principal: \"%s\", Instance: \"%s\" Lifetime = %d n = %d",
-        p_name, instance, lifetime, n);
-    
-    if (n < 0) {
-       lt = klog(L_KRB_PERR, "Database unavailable!");
-       p->key_high = p->key_low = 0;    
-       hang();
-    }
-    
-    /*
-     * if more than one p_name, pick one, randomly create a session key,
-     * compute maximum lifetime, lookup authorizations if applicable,
-     * and stuff into cipher. 
-     */
-    if (n == 0) {
-       /* service unknown, log error, skip to next request */
-       lt = klog(L_ERR_UNK, "UNKNOWN \"%s\" \"%s\"", p_name, instance);
-       return KERB_ERR_PRINCIPAL_UNKNOWN;
-    }
-    if (more) {
-       /* not unique, log error */
-       lt = klog(L_ERR_NUN, "Principal NOT UNIQUE \"%s\" \"%s\"",
-                 p_name, instance);
-       return KERB_ERR_PRINCIPAL_NOT_UNIQUE;
-    }
-
-    /*
-     * Check our V5 stuff first.
-     */
-
-    /*
-     * Does the principal have REQUIRES_PWCHANGE set?
-     */
-    if (isflagset(p->attributes, V4_KDB_REQUIRES_PWCHANGE)) {
-       lt = klog(L_ERR_SEXP, "V5 REQUIRES_PWCHANGE set "
-                 "\"%s\" \"%s\"", p_name, instance);
-       return KERB_ERR_NAME_EXP;
-    }
-
-    /*
-     * Does the principal have DISALLOW_ALL_TIX set?
-     */
-    if (isflagset(p->attributes, V4_KDB_DISALLOW_ALL_TIX)) {
-       lt = klog(L_ERR_SEXP, "V5 DISALLOW_ALL_TIX set: "
-                 "\"%s\" \"%s\"", p_name, instance);
-       /* Not sure of a better error to return */
-       return KERB_ERR_NAME_EXP;
-    }
-
-    if (isflagset(p->attributes, V4_KDB_DISALLOW_SVR)) {
-       lt = klog(L_ERR_SEXP, "V5 DISALLOW_SVR set: "
-                 "\"%s\" \"%s\"", p_name, instance);
-       /* Not sure of a better error to return */
-       return KERB_ERR_NAME_EXP;
-    }
-
-    /*
-     * Does the principal require preauthentication?
-     */
-    if ((kdc_v4 == KDC_V4_NOPREAUTH) &&
-       isflagset(p->attributes, V4_KDB_REQUIRES_PREAUTH)) {
-        lt = klog(L_ERR_SEXP, "V5 REQUIRES_PREAUTH set: "
-                 "\"%s\" \"%s\"", p_name, instance);
-       /* Not sure of a better error to return */
-       return KERB_ERR_AUTH_EXP;
-/*     return KERB_ERR_NAME_EXP;*/
-    }
-
-    /* If the user's key is null, we want to return an error */
-    if (k5key->contents != NULL && K4KDC_ENCTYPE_OK(k5key->enctype)) {
-       if ((p->key_low == 0) && (p->key_high == 0)) {
-           /* User has a null key */
-           lt = klog(L_ERR_NKY, "Null key \"%s\" \"%s\"", p_name, instance);
-           return KERB_ERR_NULL_KEY;
-       }
-    }
-    /* make sure the service hasn't expired */
-    if (((u_long) p->exp_date != 0)&&
-       ((u_long) p->exp_date <(u_long) kerb_time.tv_sec)) {
-       /* service did expire, log it */
-       char timestr[40];
-       struct tm *tm;
-       time_t t = p->exp_date;
-
-       tm = localtime(&t);
-       if (!strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S", tm))
-           timestr[0] = '\0';
-       lt = klog(L_ERR_SEXP,
-                 "EXPIRED \"%s\" \"%s\"  %s", p->name, p->instance, timestr);
-       return KERB_ERR_NAME_EXP;
-    }
-    /* ok is zero */
-    return 0;
-}
-
-
-/* Set the key for krb_rd_req so we can check tgt */
-static int
-set_tgtkey(char *r, krb5_kvno kvno, krb5_boolean use_3des)
-{
-    int     n;
-    static char lastrealm[REALM_SZ] = "";
-    static int last_kvno = 0;
-    static krb5_boolean last_use_3des = 0;
-    static int more;
-    Principal p_st;
-    Principal *p = &p_st;
-    C_Block key;
-    krb5_keyblock k5key;
-
-    k5key.contents = NULL;
-    if (!strcmp(lastrealm, r) && last_kvno == kvno && last_use_3des == use_3des)
-       return (KSUCCESS);
-
-/*  log("Getting key for %s", r); */
-
-    n = kerb_get_principal("krbtgt", r, p, &more, &k5key, kvno, 1, NULL);
-    if (n == 0)
-       return (KFAILURE);
-
-    if (isflagset(p->attributes, V4_KDB_DISALLOW_ALL_TIX)) {
-       lt = klog(L_ERR_SEXP,
-                 "V5 DISALLOW_ALL_TIX set: \"krbtgt\" \"%s\"", r);
-       krb5_free_keyblock_contents(kdc_context, &k5key);
-       return KFAILURE;
-    }
-
-    if (isflagset(p->attributes, V4_KDB_DISALLOW_SVR)) {
-       lt = klog(L_ERR_SEXP, "V5 DISALLOW_SVR set: \"krbtgt\" \"%s\"", r);
-       krb5_free_keyblock_contents(kdc_context, &k5key);
-       return KFAILURE;
-    }
-
-    if (use_3des&&!K4KDC_ENCTYPE_OK(k5key.enctype)) {
-       krb_set_key_krb5(kdc_context, &k5key);
-       strncpy(lastrealm, r, sizeof(lastrealm) - 1);
-       lastrealm[sizeof(lastrealm) - 1] = '\0';
-       last_kvno = kvno;
-       last_use_3des = use_3des;
-    } else {
-       /* unseal tgt key from master key */
-       memcpy(key,                &p->key_low,  4);
-       memcpy(((krb5_ui_4 *) key) + 1, &p->key_high, 4);
-       kdb_encrypt_key(key, key, master_key,
-                       master_key_schedule, DECRYPT);
-       krb_set_key((char *) key, 0);
-       strncpy(lastrealm, r, sizeof(lastrealm) - 1);
-       lastrealm[sizeof(lastrealm) - 1] = '\0';
-       last_kvno = kvno;
-    }
-    krb5_free_keyblock_contents(kdc_context, &k5key);
-    return (KSUCCESS);
-}
-
-#else  /* KRB5_KRB4_COMPAT */
-#include "k5-int.h"
-#endif /* KRB5_KRB4_COMPAT */
index e8758dade3f378fe324225b4566a11c7a246e7ee..80e232023e3b1101b7c54d39bef3c9a8d372867c 100644 (file)
@@ -47,9 +47,6 @@ krb5kdc \- Kerberos V5 KDC
 .B \-r
 .I realm
 ] [
-.B \-4
-.I v4mode
-] [
 .B \-n
 ]
 .br
@@ -131,23 +128,6 @@ option specifies that the master database password should be fetched
 from the keyboard rather than from a file on disk.
 .PP
 The
-.B \-4
-option specifies how the KDC responds to kerberos IV requests for
-tickets.  The command line option overrides the value in the KDC
-profile.  The possible values are 
-.I none,
-.I disable,
-.I full
-or
-.I nopreauth.
-These instruct the KDC to not respond to V4 packets, to
-respond with a version skew error, to issue tickets for all database
-entries, and to issue tickets for all but preauthentication required
-database entries respectively. The default behaviour is as if 
-.I none
-was specified.
-.PP
-The
 .B \-n
 option specifies that the KDC does not put itself in the background
 and does not disassociate itself from the terminal.  In normal
index 9416cbbd8a986c5df6b59f8d0e21a57c938ac53e..fabaca9b2a9ce10e13cfa8c1c31967d6e88e215c 100644 (file)
 #include <netinet/in.h>
 #endif
 
-#ifdef KRB5_KRB4_COMPAT
-#include <des.h>
-#endif
-
 #if defined(NEED_DAEMON_PROTO)
 extern int daemon(int, int);
 #endif
@@ -310,9 +306,6 @@ init_realm(char *progname, kdc_realm_t *rdp, char *realm,
 
     if (!rkey_init_done) {
        krb5_data seed;
-#ifdef KRB5_KRB4_COMPAT
-       krb5_keyblock temp_key;
-#endif
        /*
         * If all that worked, then initialize the random key
         * generators.
@@ -325,17 +318,6 @@ init_realm(char *progname, kdc_realm_t *rdp, char *realm,
                                             KRB5_C_RANDSOURCE_TRUSTEDPARTY, &seed)))
            goto whoops;
 
-#ifdef KRB5_KRB4_COMPAT
-       if ((kret = krb5_c_make_random_key(rdp->realm_context,
-                                          ENCTYPE_DES_CBC_CRC, &temp_key))) {
-           com_err(progname, kret,
-                   "while initializing V4 random key generator");
-           goto whoops;
-       }
-
-       (void) des_init_random_number_generator(temp_key.contents);
-       krb5_free_keyblock_contents(rdp->realm_context, &temp_key);
-#endif
        rkey_init_done = 1;
     }
  whoops:
@@ -405,7 +387,7 @@ setup_sam(void)
 void
 usage(char *name)
 {
-    fprintf(stderr, "usage: %s [-x db_args]* [-d dbpathname] [-r dbrealmname]\n\t\t[-R replaycachename] [-m] [-k masterenctype] [-M masterkeyname]\n\t\t[-p port] [-4 v4mode] [-X] [-n]\n"
+    fprintf(stderr, "usage: %s [-x db_args]* [-d dbpathname] [-r dbrealmname]\n\t\t[-R replaycachename] [-m] [-k masterenctype] [-M masterkeyname]\n\t\t[-p port] [-n]\n"
            "\nwhere,\n\t[-x db_args]* - Any number of database specific arguments.  Look at\n"
            "\t\t\teach database module documentation for supported\n\t\t\targuments\n",
            name);
@@ -431,9 +413,6 @@ initialize_realms(krb5_context kcontext, int argc, char **argv)
     char               **db_args      = NULL;
     int                  db_args_size = 0;
 
-#ifdef KRB5_KRB4_COMPAT
-    char                *v4mode = 0;
-#endif
     extern char *optarg;
 
     if (!krb5_aprof_init(DEFAULT_KDC_PROFILE, KDC_PROFILE_ENV, &aprof)) {
@@ -445,11 +424,6 @@ initialize_realms(krb5_context kcontext, int argc, char **argv)
        hierarchy[1] = "kdc_tcp_ports";
        if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &default_tcp_ports))
            default_tcp_ports = 0;
-#ifdef KRB5_KRB4_COMPAT
-       hierarchy[1] = "v4_mode";
-       if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &v4mode))
-           v4mode = 0;
-#endif
        /* aprof_init can return 0 with aprof == NULL */
        if (aprof)
             krb5_aprof_finish(aprof);
@@ -559,17 +533,9 @@ initialize_realms(krb5_context kcontext, int argc, char **argv)
 #endif
            break;
        case '4':
-#ifdef KRB5_KRB4_COMPAT
-           if (v4mode)
-               free(v4mode);
-           v4mode = strdup(optarg);
-#endif
            break;
        case 'X':
-#ifdef KRB5_KRB4_COMPAT
-               enable_v4_crossrealm(argv[0]);
-#endif
-               break;
+           break;
        case '?':
        default:
            usage(argv[0]);
@@ -577,14 +543,6 @@ initialize_realms(krb5_context kcontext, int argc, char **argv)
        }
     }
 
-#ifdef KRB5_KRB4_COMPAT
-    /*
-     * Setup the v4 mode 
-     */
-    process_v4_mode(argv[0], v4mode);
-    free(v4mode);
-#endif
-
     /*
      * Check to see if we processed any realms.
      */