#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 */
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);
}
}
#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.
* @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;
}
* 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) :
}
#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);