/* * Free an error string if necessary. If we returned a static string, make * sure we don't free it. * * This code assumes that the set of implementations that have * krb5_free_error_message is a subset of those with krb5_get_error_message. * If this assumption ever breaks, we may call the wrong free function. */ void krb5_free_error_message(krb5_context ctx UNUSED, const char *msg) { if (msg == error_unknown) return; # if defined(HAVE_KRB5_GET_ERROR_STRING) krb5_free_error_string(ctx, (char *) msg); # elif defined(HAVE_KRB5_SVC_GET_MSG) krb5_free_string(ctx, (char *) msg); # endif }
static void ka_krb5_free_error_message (krb5_context context, const char *msg) { #if defined(HAVE_KRB5_FREE_ERROR_MESSAGE) krb5_free_error_message (context, msg); #elif defined(HAVE_KRB5_FREE_ERROR_STRING) krb5_free_error_string (context, (char *) msg); #else # error No way to free error string. #endif }
char const *rlm_krb5_error(krb5_context context, krb5_error_code code) { char const *msg; char *buffer; buffer = fr_thread_local_init(krb5_error_buffer, _krb5_logging_free); if (!buffer) { int ret; /* * malloc is thread safe, talloc is not */ buffer = malloc(sizeof(char) * KRB5_STRERROR_BUFSIZE); if (!buffer) { ERROR("Failed allocating memory for krb5 error buffer"); return NULL; } ret = fr_thread_local_set(krb5_error_buffer, buffer); if (ret != 0) { ERROR("Failed setting up TLS for krb5 error buffer: %s", fr_syserror(ret)); free(buffer); return NULL; } } 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); } return buffer; }