Doxygen is stupid, so delete doxygen comments.
[freeradius.git] / src / modules / rlm_krb5 / krb5.c
index 81ed1d4..b70d0d1 100644 (file)
@@ -27,7 +27,7 @@ RCSID("$Id$")
 #include <freeradius-devel/radiusd.h>
 #include "krb5.h"
 
-#ifdef HEIMDAL_KRB5
+#ifdef HAVE_KRB5_GET_ERROR_MESSAGE
 #  define KRB5_STRERROR_BUFSIZE (2048)
 
 fr_thread_local_setup(char *, krb5_error_buffer)       /* macro */
@@ -69,7 +69,18 @@ char const *rlm_krb5_error(krb5_context context, krb5_error_code code)
        msg = krb5_get_error_message(context, code);
        if (msg) {
                strlcpy(buffer, msg, KRB5_STRERROR_BUFSIZE);
+#ifdef HAVE_KRB5_FREE_ERROR_MESSAGE
                krb5_free_error_message(context, msg);
+#elif defined(HAVE_KRB5_FREE_ERROR_STRING)
+               {
+                       char *free;
+
+                       memcpy(&free, &msg, sizeof(free));
+                       krb5_free_error_string(context, free);
+               }
+#else
+#  error "No way to free error strings, missing krb5_free_error_message() and krb5_free_error_string()"
+#endif
        } else {
                strlcpy(buffer, "Unknown error", KRB5_STRERROR_BUFSIZE);
        }
@@ -78,17 +89,6 @@ char const *rlm_krb5_error(krb5_context context, krb5_error_code code)
 }
 #endif
 
-/** Frees a krb5 context
- *
- * @param instance rlm_krb5 instance.
- * @param handle to destroy.
- * @return 0 (always indicates success).
- */
-int mod_conn_delete(UNUSED void *instance, void *handle)
-{
-       return talloc_free((krb5_context *) handle);
-}
-
 /** Frees libkrb5 resources associated with the handle
  *
  * Must not be called directly.
@@ -96,12 +96,19 @@ int mod_conn_delete(UNUSED void *instance, void *handle)
  * @param conn to free.
  * @return 0 (always indicates success).
  */
-static int _free_handle(rlm_krb5_handle_t *conn) {
+static int _mod_conn_free(rlm_krb5_handle_t *conn) {
        krb5_free_context(conn->context);
 
        if (conn->keytab) {
                krb5_kt_close(conn->context, conn->keytab);
        }
+
+#ifdef HEIMDAL_KRB5
+       if (conn->ccache) {
+               krb5_cc_destroy(conn->context, conn->ccache);
+       }
+#endif
+
        return 0;
 }
 
@@ -110,25 +117,22 @@ static int _free_handle(rlm_krb5_handle_t *conn) {
  * libkrb5(s) can talk to the KDC over TCP. Were assuming something sane is implemented
  * by libkrb5 and that it does connection caching associated with contexts, so it's
  * worth using a connection pool to preserve connections when workers die.
- *
- * @param instance rlm_krb5 instance instance.
- * @return A new context or NULL on error.
  */
-void *mod_conn_create(void *instance)
+void *mod_conn_create(TALLOC_CTX *ctx, void *instance)
 {
        rlm_krb5_t *inst = instance;
        rlm_krb5_handle_t *conn;
        krb5_error_code ret;
 
-       MEM(conn = talloc_zero(instance, rlm_krb5_handle_t));
+       MEM(conn = talloc_zero(ctx, rlm_krb5_handle_t));
        ret = krb5_init_context(&conn->context);
        if (ret) {
-               EDEBUG("rlm_krb5 (%s): Context initialisation failed: %s", inst->xlat_name,
+               ERROR("rlm_krb5 (%s): Context initialisation failed: %s", inst->xlat_name,
                       rlm_krb5_error(NULL, ret));
 
                return NULL;
        }
-       talloc_set_destructor(conn, _free_handle);
+       talloc_set_destructor(conn, _mod_conn_free);
 
        ret = inst->keytabname ?
                krb5_kt_resolve(conn->context, inst->keytabname, &conn->keytab) :
@@ -140,14 +144,13 @@ void *mod_conn_create(void *instance)
        }
 
 #ifdef HEIMDAL_KRB5
-       /*
-        *      Setup krb5_verify_user options
-        *
-        *      Not entirely sure this is necessary, but as we use context
-        *      to get the cache handle, we probably do have to do this with
-        *      the cloned context.
-        */
-       krb5_cc_default(conn->context, &conn->ccache);
+       ret = krb5_cc_new_unique(conn->context, "MEMORY", NULL, &conn->ccache);
+       if (ret) {
+               ERROR("rlm_krb5 (%s): Credential cache creation failed: %s", inst->xlat_name,
+                     rlm_krb5_error(conn->context, ret));
+
+               return NULL;
+       }
 
        krb5_verify_opt_init(&conn->options);
        krb5_verify_opt_set_ccache(&conn->options, conn->ccache);