Index: Makefile.in
===================================================================
RCS file: /cvs/openssh/Makefile.in,v
retrieving revision 1.199
diff -u -r1.199 Makefile.in
--- Makefile.in	13 Mar 2002 02:19:42 -0000	1.199
+++ Makefile.in	26 Mar 2002 11:30:29 -0000
@@ -54,7 +54,7 @@
 
 SSHOBJS= ssh.o sshconnect.o sshconnect1.o sshconnect2.o sshtty.o readconf.o clientloop.o
 
-SSHDOBJS= sshd.o auth.o auth1.o auth2.o auth-chall.o auth2-chall.o auth-rhosts.o auth-options.o auth-krb4.o auth-pam.o auth2-pam.o auth-passwd.o auth-rsa.o auth-rh-rsa.o auth-sia.o sshpty.o sshlogin.o loginrec.o servconf.o serverloop.o md5crypt.o session.o groupaccess.o auth-skey.o auth-bsdauth.o
+SSHDOBJS= sshd.o auth.o auth1.o auth2.o auth-chall.o auth2-chall.o auth-rhosts.o auth-options.o auth-krb4.o auth-krb5.o auth-pam.o auth2-pam.o auth-passwd.o auth-rsa.o auth-rh-rsa.o auth-sia.o sshpty.o sshlogin.o loginrec.o servconf.o serverloop.o md5crypt.o session.o groupaccess.o auth-skey.o auth-bsdauth.o
 
 MANPAGES	= scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out
 MANPAGES_IN	= scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1
Index: acconfig.h
===================================================================
RCS file: /cvs/openssh/acconfig.h,v
retrieving revision 1.122
diff -u -r1.122 acconfig.h
--- acconfig.h	26 Feb 2002 16:40:49 -0000	1.122
+++ acconfig.h	26 Mar 2002 11:31:00 -0000
@@ -178,6 +178,12 @@
 /* Define if libc defines __progname */
 #undef HAVE___PROGNAME
 
+/* Define if you want Kerberos 5 support */
+#undef KRB5
+
+/* Define this if you are using Heimdal version of Kerberos V5 */
+#undef HEIMDAL
+
 /* Define if you want Kerberos 4 support */
 #undef KRB4
 
Index: auth-krb5.c
===================================================================
RCS file: /cvs/openssh/auth-krb5.c,v
retrieving revision 1.5
diff -u -r1.5 auth-krb5.c
--- auth-krb5.c	5 Mar 2002 01:53:04 -0000	1.5
+++ auth-krb5.c	26 Mar 2002 11:31:10 -0000
@@ -18,6 +18,9 @@
 
 #ifdef KRB5
 #include <krb5.h>
+#ifndef HEIMDAL
+#define krb5_get_err_text(context,code) error_message(code)
+#endif /* !HEIMDAL */
 
 extern ServerOptions	 options;
 
@@ -70,8 +73,15 @@
 		goto err;
 
 	fd = packet_get_connection_in();
+#ifdef HEIMDAL
 	problem = krb5_auth_con_setaddrs_from_fd(authctxt->krb5_ctx,
 	    authctxt->krb5_auth_ctx, &fd);
+#else
+	problem = krb5_auth_con_genaddrs(authctxt->krb5_ctx, 
+	    authctxt->krb5_auth_ctx,fd,
+	    KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR |
+	    KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR);
+#endif
 	if (problem)
 		goto err;
 
@@ -85,8 +95,14 @@
 	if (problem)
 		goto err;
 
+#ifdef HEIMDAL
 	problem = krb5_copy_principal(authctxt->krb5_ctx, ticket->client,
 	    &authctxt->krb5_user);
+#else
+	problem = krb5_copy_principal(authctxt->krb5_ctx, 
+				      ticket->enc_part2->client,
+				      &authctxt->krb5_user);
+#endif
 	if (problem)
 		goto err;
 
@@ -137,13 +153,37 @@
 	krb5_error_code problem;
 	krb5_ccache ccache = NULL;
 	char *pname;
+	krb5_creds **creds;
 
 	if (authctxt->pw == NULL || authctxt->krb5_user == NULL)
 		return (0);
 
 	temporarily_use_uid(authctxt->pw);
 
+#ifdef HEIMDAL
 	problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_fcc_ops, &ccache);
+#else
+{
+	char ccname[40];
+	int tmpfd;
+	
+	snprintf(ccname,sizeof(ccname),"FILE:/tmp/krb5cc_%d_XXXXXX",geteuid());
+	
+	if ((tmpfd = mkstemp(ccname+strlen("FILE:")))==-1) {
+		log("mkstemp(): %.100s", strerror(errno));
+		problem = errno;
+		goto fail;
+	}
+	if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) {
+		log("fchmod(): %.100s", strerror(errno));
+		close(tmpfd);
+		problem = errno;
+		goto fail;
+	}
+	close(tmpfd);
+	problem = krb5_cc_resolve(authctxt->krb5_ctx, ccname, &ccache);
+}
+#endif
 	if (problem)
 		goto fail;
 
@@ -152,10 +192,20 @@
 	if (problem)
 		goto fail;
 
+#ifdef HEIMDAL
 	problem = krb5_rd_cred2(authctxt->krb5_ctx, authctxt->krb5_auth_ctx,
 	    ccache, tgt);
 	if (problem)
 		goto fail;
+#else
+	problem = krb5_rd_cred(authctxt->krb5_ctx, authctxt->krb5_auth_ctx,
+	    tgt, &creds, NULL);
+	if (problem)
+		goto fail;
+	problem = krb5_cc_store_cred(authctxt->krb5_ctx, ccache, *creds);
+	if (problem)
+		goto fail;
+#endif
 
 	authctxt->krb5_fwd_ccache = ccache;
 	ccache = NULL;
@@ -188,6 +238,12 @@
 int
 auth_krb5_password(Authctxt *authctxt, const char *password)
 {
+#ifndef HEIMDAL
+	krb5_creds creds;
+	krb5_principal server;
+	char ccname[40];
+	int tmpfd;
+#endif	
 	krb5_error_code problem;
 
 	if (authctxt->pw == NULL)
@@ -204,6 +260,7 @@
 	if (problem)
 		goto out;
 
+#ifdef HEIMDAL
 	problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_mcc_ops,
 	    &authctxt->krb5_fwd_ccache);
 	if (problem)
@@ -222,13 +279,69 @@
 	if (problem)
 		goto out;
 
+#else
+	problem = krb5_get_init_creds_password(authctxt->krb5_ctx, &creds,
+	    authctxt->krb5_user, (char *)password, NULL, NULL, 0, NULL, NULL);
+	if (problem)
+		goto out;
+
+	problem = krb5_sname_to_principal(authctxt->krb5_ctx, NULL, NULL,
+	    KRB5_NT_SRV_HST, &server);
+	if (problem)
+		goto out;
+
+	restore_uid();
+	problem = krb5_verify_init_creds(authctxt->krb5_ctx, &creds, server,
+	    NULL, NULL, NULL);
+	krb5_free_principal(authctxt->krb5_ctx, server);
+	temporarily_use_uid(authctxt->pw);
+	if (problem)
+		goto out;
+	
+	if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, 
+			  authctxt->pw->pw_name)) {
+	 	problem = -1;
+		goto out;
+	} 
+
+	snprintf(ccname,sizeof(ccname),"FILE:/tmp/krb5cc_%d_XXXXXX",geteuid());
+	
+	if ((tmpfd = mkstemp(ccname+strlen("FILE:")))==-1) {
+		log("mkstemp(): %.100s", strerror(errno));
+		problem = errno;
+		goto out;
+	}
+	
+	if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) {
+		log("fchmod(): %.100s", strerror(errno));
+		close(tmpfd);
+		problem = errno;
+		goto out;
+	}
+	close(tmpfd);
+
+	problem = krb5_cc_resolve(authctxt->krb5_ctx, ccname, &authctxt->krb5_fwd_ccache);
+	if (problem)
+		goto out;
+
+	problem = krb5_cc_initialize(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache,
+				     authctxt->krb5_user);
+	if (problem)
+		goto out;
+				
+	problem= krb5_cc_store_cred(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache,
+				 &creds);
+	if (problem)
+		goto out;
+#endif		
+
 	authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
 
  out:
 	restore_uid();
 
 	if (problem) {
-		if (authctxt->krb5_ctx != NULL)
+		if (authctxt->krb5_ctx != NULL && problem!=-1)
 			debug("Kerberos password authentication failed: %s",
 			    krb5_get_err_text(authctxt->krb5_ctx, problem));
 		else
Index: configure.ac
===================================================================
RCS file: /cvs/openssh/configure.ac,v
retrieving revision 1.26
diff -u -r1.26 configure.ac
--- configure.ac	17 Mar 2002 20:17:35 -0000	1.26
+++ configure.ac	26 Mar 2002 11:33:28 -0000
@@ -1656,7 +1656,43 @@
 	]
 )
 
-# Check whether user wants Kerberos support
+# Check whether user wants Kerberos 5 support
+AC_ARG_WITH(kerberos5,
+        [  --with-kerberos5=PATH   Enable Kerberos 5 support],
+        [
+                if test "x$withval" != "xno" ; then
+                        if test "x$withval" = "xyes" ; then
+                                KRB5ROOT="/usr/local"
+                        else
+                                KRB5ROOT=${withval}
+                        fi
+			CPPFLAGS="$CPPFLAGS -I${KRB5ROOT}/include"
+                        LDFLAGS="$LDFLAGS -L${KRB5ROOT}/lib"
+                        AC_DEFINE(KRB5)
+                        AC_MSG_CHECKING(whether we are using Heimdal)
+                        AC_TRY_COMPILE([ #include <krb5.h> ],
+                                       [ char *tmp = heimdal_version; ],
+                                       [ AC_MSG_RESULT(yes)
+                                         AC_DEFINE(HEIMDAL)
+                                         K5LIBS="-lkrb5 -ldes -lcom_err -lasn1 -lroken"
+                                       ],
+                                       [ AC_MSG_RESULT(no)
+                                         K5LIBS="-lkrb5 -lk5crypto -lcom_err"
+                                       ]
+                        )
+                        if test ! -z "$need_dash_r" ; then
+                                LDFLAGS="$LDFLAGS -R${KRB5ROOT}/lib"
+                        fi
+                        if test ! -z "$blibpath" ; then
+                                blibpath="$blibpath:${KRB5ROOT}/lib"
+                        fi
+                        AC_CHECK_LIB(resolv, dn_expand, , )
+
+                        KRB5=yes
+                fi
+        ]
+)
+# Check whether user wants Kerberos 4 support
 KRB4_MSG="no" 
 AC_ARG_WITH(kerberos4,
 	[  --with-kerberos4=PATH   Enable Kerberos 4 support],
@@ -1736,7 +1772,7 @@
 		fi
 	]
 )
-LIBS="$LIBS $KLIBS"
+LIBS="$LIBS $KLIBS $K5LIBS"
 
 # Looking for programs, paths and files
 AC_ARG_WITH(rsh,
Index: servconf.c
===================================================================
RCS file: /cvs/openssh/servconf.c,v
retrieving revision 1.79
diff -u -r1.79 servconf.c
--- servconf.c	13 Mar 2002 02:19:43 -0000	1.79
+++ servconf.c	26 Mar 2002 11:36:26 -0000
@@ -12,8 +12,17 @@
 #include "includes.h"
 RCSID("$OpenBSD: servconf.c,v 1.101 2002/02/04 12:15:25 markus Exp $");
 
-#if defined(KRB4) || defined(KRB5)
+#if defined(KRB4)
 #include <krb.h>
+#endif
+#if defined(KRB5)
+#ifdef HEIMDAL
+#include <krb.h>
+#else
+/* Bodge - but then, so is using the kerberos IV KEYFILE to get a Kerberos V
+ * keytab */
+#define KEYFILE "/etc/krb5.keytab"
+#endif
 #endif
 #ifdef AFS
 #include <kafs.h>
Index: sshconnect1.c
===================================================================
RCS file: /cvs/openssh/sshconnect1.c,v
retrieving revision 1.46
diff -u -r1.46 sshconnect1.c
--- sshconnect1.c	13 Feb 2002 02:54:29 -0000	1.46
+++ sshconnect1.c	26 Mar 2002 11:39:56 -0000
@@ -23,6 +23,9 @@
 #endif
 #ifdef KRB5
 #include <krb5.h>
+#ifndef HEIMDAL
+#define krb5_get_err_text(context,code) error_message(code)
+#endif /* !HEIMDAL */
 #endif
 #ifdef AFS
 #include <kafs.h>
@@ -519,6 +522,23 @@
 		ret = 0;
 		goto out;
 	}
+	
+	problem = krb5_auth_con_init(*context, auth_context);
+	if (problem) {
+		debug("Kerberos v5: krb5_auth_con_init failed");
+		ret = 0;
+		goto out;
+	}
+
+#ifndef HEIMDAL
+	problem = krb5_auth_con_setflags(*context, *auth_context,
+					 KRB5_AUTH_CONTEXT_RET_TIME);
+	if (problem) {
+		debug("Keberos v5: krb5_auth_con_setflags failed");
+		ret = 0;
+		goto out;
+	}
+#endif
 
 	tkfile = krb5_cc_default_name(*context);
 	if (strncmp(tkfile, "FILE:", 5) == 0)
@@ -595,7 +615,11 @@
 	if (reply != NULL)
 		krb5_free_ap_rep_enc_part(*context, reply);
 	if (ap.length > 0)
+#ifdef HEIMDAL
 		krb5_data_free(&ap);
+#else
+		krb5_free_data_contents(*context, &ap);
+#endif
 
 	return (ret);
 }
@@ -608,7 +632,11 @@
 	krb5_data outbuf;
 	krb5_ccache ccache = NULL;
 	krb5_creds creds;
+#ifdef HEIMDAL
 	krb5_kdc_flags flags;
+#else
+	int forwardable;
+#endif
 	const char *remotehost;
 
 	memset(&creds, 0, sizeof(creds));
@@ -616,7 +644,13 @@
 
 	fd = packet_get_connection_in();
 
+#ifdef HEIMDAL
 	problem = krb5_auth_con_setaddrs_from_fd(context, auth_context, &fd);
+#else
+	problem = krb5_auth_con_genaddrs(context, auth_context, fd,
+			KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR |
+			KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR);
+#endif
 	if (problem)
 		goto out;
 
@@ -628,23 +662,35 @@
 	if (problem)
 		goto out;
 
+	remotehost = get_canonical_hostname(1);
+	
+#ifdef HEIMDAL
 	problem = krb5_build_principal(context, &creds.server,
 	    strlen(creds.client->realm), creds.client->realm,
 	    "krbtgt", creds.client->realm, NULL);
+#else
+	problem = krb5_build_principal(context, &creds.server,
+	    creds.client->realm.length, creds.client->realm.data,
+	    "host", remotehost, NULL);
+#endif
 	if (problem)
 		goto out;
 
 	creds.times.endtime = 0;
 
+#ifdef HEIMDAL
 	flags.i = 0;
 	flags.b.forwarded = 1;
 	flags.b.forwardable = krb5_config_get_bool(context,  NULL,
 	    "libdefaults", "forwardable", NULL);
-
-	remotehost = get_canonical_hostname(1);
-
 	problem = krb5_get_forwarded_creds(context, auth_context,
 	    ccache, flags.i, remotehost, &creds, &outbuf);
+#else
+	forwardable = 1;
+	problem = krb5_fwd_tgt_creds(context, auth_context, remotehost,
+	    creds.client, creds.server, ccache, forwardable, &outbuf);
+#endif
+
 	if (problem)
 		goto out;
 
