Added context declaration
[mod_auth_kerb.cvs/.git] / src / mod_auth_kerb.c
index 64a0a12..7414b99 100644 (file)
@@ -11,7 +11,7 @@
  */
 
 /*
- * Copyright (c) 2004-2005 Masarykova universita
+ * Copyright (c) 2004-2006 Masarykova universita
  * (Masaryk University, Brno, Czech Republic)
  * All rights reserved.
  *
@@ -50,7 +50,7 @@
 #include <stdio.h>
 #include <stdarg.h>
 
-#define MODAUTHKERB_VERSION "5.0-rc6"
+#define MODAUTHKERB_VERSION "5.0"
 
 #define MECH_NEGOTIATE "Negotiate"
 #define SERVICE_NAME "HTTP"
 #ifdef STANDARD20_MODULE_STUFF
 #include <apr_strings.h>
 #include <apr_base64.h>
-
-#define ap_null_cleanup NULL
-#define ap_register_cleanup apr_pool_cleanup_register
-
-#define ap_pstrdup apr_pstrdup
-#define ap_pstrcat apr_pstrcat
-#define ap_pcalloc apr_pcalloc
-#define ap_psprintf apr_psprintf
-
-#define ap_base64decode_len apr_base64_decode_len
-#define ap_base64decode apr_base64_decode
-#define ap_base64encode_len apr_base64_encode_len
-#define ap_base64encode apr_base64_encode
-
-#define ap_table_setn apr_table_setn
-#define ap_table_add apr_table_add
+#include <apr_compat.h>
+#include <apu_compat.h>
 #else
 #define ap_pstrchr_c strchr
 #endif /* STANDARD20_MODULE_STUFF */
@@ -154,7 +140,9 @@ typedef struct {
        const char *krb_service_name;
        int krb_authoritative;
        int krb_delegate_basic;
+#if 0
        int krb_ssl_preauthentication;
+#endif
 #ifdef KRB5
        char *krb_5_keytab;
        int krb_method_gssapi;
@@ -207,8 +195,10 @@ static const command_rec kerb_auth_cmds[] = {
    command("KrbDelegateBasic", ap_set_flag_slot, krb_delegate_basic,
      FLAG, "Always offer Basic authentication regardless of KrbMethodK5Pass and pass on authentication to lower modules if Basic headers arrive."),
 
+#if 0
    command("KrbEnableSSLPreauthentication", ap_set_flag_slot, krb_ssl_preauthentication,
      FLAG, "Don't do Kerberos authentication if the user is already authenticated using SSL and her client certificate."),
+#endif
 
 #ifdef KRB5
    command("Krb5Keytab", ap_set_file_slot, krb_5_keytab,
@@ -308,7 +298,9 @@ static void *kerb_dir_create_config(MK_POOL *p, char *d)
        ((kerb_auth_config *)rec)->krb_service_name = NULL;
        ((kerb_auth_config *)rec)->krb_authoritative = 1;
        ((kerb_auth_config *)rec)->krb_delegate_basic = 0;
+#if 0
        ((kerb_auth_config *)rec)->krb_ssl_preauthentication = 0;
+#endif
 #ifdef KRB5
        ((kerb_auth_config *)rec)->krb_method_k5pass = 1;
        ((kerb_auth_config *)rec)->krb_method_gssapi = 1;
@@ -1133,6 +1125,7 @@ get_gss_creds(request_rec *r,
    char buf[1024];
    int have_server_princ;
 
+
    have_server_princ = conf->krb_service_name && strchr(conf->krb_service_name, '/') != NULL;
    if (have_server_princ)
       strncpy(buf, conf->krb_service_name, sizeof(buf));
@@ -1193,11 +1186,15 @@ get_gss_creds(request_rec *r,
    {
       krb5_gss_cred_id_t gss_creds = (krb5_gss_cred_id_t) *server_creds;
 
-      if (gss_creds && gss_creds->rcache && gss_creds->rcache->ops &&
-         gss_creds->rcache->ops->type &&  
-         memcmp(gss_creds->rcache->ops->type, "dfl", 3) == 0)
+      /* First we try to verify we are linked with 1.3.x to prevent from
+         crashing when linked with 1.4.x */
+      if (gss_creds && (gss_creds->usage == GSS_C_ACCEPT)) {
+        if (gss_creds->rcache && gss_creds->rcache->ops &&
+            gss_creds->rcache->ops->type &&  
+            memcmp(gss_creds->rcache->ops->type, "dfl", 3) == 0)
           /* Override the rcache operations */
         gss_creds->rcache->ops = &mod_auth_kerb_rc_ops;
+      }
    }
 #endif
    
@@ -1375,7 +1372,7 @@ authenticate_user_gss(request_rec *r, kerb_auth_config *conf,
   if (GSS_ERROR(major_status)) {
     log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
               "%s", get_gss_error(r->pool, major_status, minor_status,
-                                  "gss_export_name() failed"));
+                                  "gss_display_name() failed"));
     ret = HTTP_INTERNAL_SERVER_ERROR;
     goto end;
   }
@@ -1487,6 +1484,7 @@ kerb_authenticate_user(request_rec *r)
    else
       return DECLINED;
 
+#if 0
    if (conf->krb_ssl_preauthentication) {
       const char *ssl_client_verify = ssl_var_lookup(r->pool, r->server,
                r->connection, r, "SSL_CLIENT_VERIFY");
@@ -1494,6 +1492,7 @@ kerb_authenticate_user(request_rec *r)
       if (ssl_client_verify && strcmp(ssl_client_verify, "SUCCESS") == 0)
         return OK;
    }
+#endif
 
    /* get what the user sent us in the HTTP header */
    auth_line = MK_TABLE_GET(r->headers_in, (r->proxyreq == PROXYREQ_PROXY)
@@ -1547,14 +1546,46 @@ kerb_authenticate_user(request_rec *r)
    return ret;
 }
 
+int
+have_rcache_type(const char *type)
+{
+   krb5_error_code ret;
+   krb5_context context;
+   krb5_rcache id;
+   int found;
+
+   memset(&id, 0, sizeof(id));
+
+   ret = krb5_init_context(&context);
+   if (ret)
+      return 0;
+
+   ret = krb5_rc_resolve_type(context, id, type);
+   found = (ret == 0);
+
+   krb5_free_context(context);
+
+   return found;
+}
 
 /*************************************************************************** 
  Module Setup/Configuration
  ***************************************************************************/
 #ifndef STANDARD20_MODULE_STUFF
+static void
+kerb_module_init(server_rec *dummy, pool *p)
+{
+#ifndef HEIMDAL
+   /* Suppress the MIT replay cache.  Requires MIT Kerberos 1.4.0 or later.
+      1.3.x are covered by the hack overiding the replay calls */
+   if (getenv("KRB5RCACHETYPE") == NULL && have_rcache_type("none"))
+      putenv(strdup("KRB5RCACHETYPE=none"));
+#endif
+}
+
 module MODULE_VAR_EXPORT auth_kerb_module = {
        STANDARD_MODULE_STUFF,
-       NULL,                           /*      module initializer            */
+       kerb_module_init,               /*      module initializer            */
        kerb_dir_create_config,         /*      per-directory config creator  */
        NULL,                           /*      per-directory config merger   */
        NULL,                           /*      per-server    config creator  */
@@ -1585,6 +1616,13 @@ kerb_init_handler(apr_pool_t *p, apr_pool_t *plog,
                  apr_pool_t *ptemp, server_rec *s)
 {
    ap_add_version_component(p, "mod_auth_kerb/" MODAUTHKERB_VERSION);
+#ifndef HEIMDAL
+   /* Suppress the MIT replay cache.  Requires MIT Kerberos 1.4.0 or later.
+      1.3.x are covered by the hack overiding the replay calls */
+   if (getenv("KRB5RCACHETYPE") == NULL && have_rcache_type("none"))
+      putenv(strdup("KRB5RCACHETYPE=none"));
+#endif
+   
    return OK;
 }