- (djm) Add KrbV support patch from Simon Wilkinson <simon@sxw.org.uk>
diff --git a/auth-krb5.c b/auth-krb5.c
index f878b51..76c2419 100644
--- a/auth-krb5.c
+++ b/auth-krb5.c
@@ -41,6 +41,9 @@
 
 #ifdef KRB5
 #include <krb5.h>
+#ifndef HEIMDAL
+#define krb5_get_err_text(context,code) error_message(code)
+#endif /* !HEIMDAL */
 
 extern ServerOptions	 options;
 
@@ -93,8 +96,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;
 
@@ -108,8 +118,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;
 
@@ -160,13 +176,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;
 
@@ -175,10 +215,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;
@@ -211,6 +261,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)
@@ -227,6 +283,7 @@
 	if (problem)
 		goto out;
 
+#ifdef HEIMDAL
 	problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_mcc_ops,
 	    &authctxt->krb5_fwd_ccache);
 	if (problem)
@@ -245,13 +302,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