From c4b56a12db5e59539f64a3a65ac07852ed34d21f Mon Sep 17 00:00:00 2001
From: Geoffrey Thomas <geofft@mit.edu>
Date: Sat, 29 May 2010 20:31:36 -0400
Subject: [PATCH] send_zephyr: Send without authentication on auth failure.

This used to be barnowl's behavior; I'm not sure if something changed in
newer versions of the zephyr libraries.

To make this work, add a check for krb5 headers (but not libs) in
configure.h, so it doesn't break on systems without krb5 that for
whatever reason do have zephyr.

Cc: Karl Ramm <kcr@1ts.org>
Signed-off-by: Geoffrey Thomas <geofft@mit.edu>
---
 configure.ac |   10 ++++++++++
 functions.c  |    2 +-
 zephyr.c     |   29 ++++++++++++++++++++++++++++-
 3 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/configure.ac b/configure.ac
index f219356..01a3a1d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -47,6 +47,16 @@ AS_IF([test "x$with_zephyr" != xno],
       CFLAGS="${CFLAGS} ${LIBCRYPTO_CFLAGS}"
       LIBS="${LIBS} ${LIBCRYPTO_LIBS}"
      ])
+   AC_MSG_CHECKING([for Kerberos V])
+   AS_IF([krb5-config krb5 --cflags >/dev/null 2>&1],
+     [AC_MSG_RESULT([yes])
+      AC_DEFINE([HAVE_KERBEROS_V], [1], [Define if you have kerberos V])
+      CFLAGS="${CFLAGS} `krb5-config krb5 --cflags`"
+      dnl Since we don't need to explicitly link the krb5 libraries (just the
+      dnl header file is used in zephyr.c for com_err values), I'm leaving the
+      dnl libs line out. Re-include it if we end up using the krb5 API.
+     ],
+     [])
    AC_CHECK_LIB([zephyr], [ZGetSender],
    [LIBS="$LIBS -lzephyr"
     AC_DEFINE([HAVE_LIBZEPHYR], [1],
diff --git a/functions.c b/functions.c
index ae9cd84..19d59eb 100644
--- a/functions.c
+++ b/functions.c
@@ -1207,7 +1207,7 @@ void owl_function_debugmsg(const char *fmt, ...)
     int fd = open(owl_global_get_debug_file(&g),
                    O_WRONLY|O_CREAT|O_EXCL|O_SYNC,
                    0600);
-    if (!fd) /* XXX should report this */
+    if (fd < 0) /* XXX should report this */
       return;
     file = fdopen(fd, "w");
     if (!file) /* XXX should report this too */
diff --git a/zephyr.c b/zephyr.c
index 7db4520..9b0a02d 100644
--- a/zephyr.c
+++ b/zephyr.c
@@ -6,6 +6,25 @@
 #include <string.h>
 #include "owl.h"
 
+#ifdef HAVE_KERBEROS_IV
+#include <kerberosIV/krb_err.h>
+#define KRB4_UNUSABLE_TICKET_CASES \
+    case KRBET_RD_AP_EXP: \
+    case KRBET_RD_AP_TIME:
+#else
+#define KRB4_UNUSABLE_TICKET_CASES
+#endif
+
+#ifdef HAVE_KERBEROS_V
+#include <krb5/krb5.h>
+#define KRB5_UNUSABLE_TICKET_CASES \
+    case KRB5KRB_AP_ERR_TKT_EXPIRED: \
+    case KRB5KRB_AP_ERR_SKEW:
+#else
+#define KRB5_UNUSABLE_TICKET_CASES
+#endif
+
+
 #ifdef HAVE_LIBZEPHYR
 static GList *deferred_subs = NULL;
 
@@ -698,7 +717,15 @@ int send_zephyr(const char *opcode, const char *zsig, const char *class, const c
 
   /* ret=ZSendNotice(&notice, ZAUTH); */
   ret=ZSrvSendNotice(&notice, ZAUTH, send_zephyr_helper);
-  
+
+  /* Try resending without authentication if that would help. */
+  switch (ret) {
+    KRB4_UNUSABLE_TICKET_CASES
+    KRB5_UNUSABLE_TICKET_CASES
+      ret=ZSrvSendNotice(&notice, ZNOAUTH, send_zephyr_helper);
+      break;
+  }
+
   /* free then check the return */
   owl_free(notice.z_message);
   ZFreeNotice(&notice);
-- 
1.6.5

