Permit NULL context to krb5_get_error_message()

Application developers have a tendency to use krb5_get_error_message()
as a drop in replacement for error_message() and under various
circumstances they pass in a NULL context.  This method works fine
for MIT's implementation which ignores the context but in Heimdal
passing in a NULL context would dump core.

This patch set modifies krb5_get_error_message() in order to
permit the passing of a NULL context.  First, if the context
is NULL, an attempt will be made to allocate one locally for
the purpose of evaluating the error code.  Second, if a local
context cannot be allocated, fall back on calling error_message().
If error_message() fails to return a string, then generate an
"unknown error" response.

Only if all of the above fails is NULL returned.

Change-Id: If4baf7d6c428cf0baf11c044b8dfd5c2b3cdf7e4
This commit is contained in:
Jeffrey Altman
2011-09-27 14:21:22 -04:00
parent 03df77d491
commit cbf126bede

View File

@@ -206,29 +206,53 @@ krb5_vprepend_error_message(krb5_context context, krb5_error_code ret,
KRB5_LIB_FUNCTION const char * KRB5_LIB_CALL KRB5_LIB_FUNCTION const char * KRB5_LIB_CALL
krb5_get_error_message(krb5_context context, krb5_error_code code) krb5_get_error_message(krb5_context context, krb5_error_code code)
{ {
char *str; char *str = NULL;
const char *cstr = NULL;
HEIMDAL_MUTEX_lock(context->mutex); char buf[128];
if (context->error_string && int free_context = 0;
(code == context->error_code || context->error_code == 0))
{
str = strdup(context->error_string);
if (str) {
HEIMDAL_MUTEX_unlock(context->mutex);
return str;
}
}
HEIMDAL_MUTEX_unlock(context->mutex);
if (code == 0) if (code == 0)
return strdup("Success"); return strdup("Success");
/*
* The MIT version of this function ignores the krb5_context
* and several widely deployed applications call krb5_get_error_message()
* with a NULL context in order to translate an error code as a
* replacement for error_message(). Another reason a NULL context
* might be provided is if the krb5_init_context() call itself
* failed.
*/
if (context)
{ {
const char *msg; HEIMDAL_MUTEX_lock(context->mutex);
char buf[128]; if (context->error_string &&
msg = com_right_r(context->et_list, code, buf, sizeof(buf)); (code == context->error_code || context->error_code == 0))
if (msg) {
return strdup(msg); str = strdup(context->error_string);
}
HEIMDAL_MUTEX_unlock(context->mutex);
if (str)
return str;
} }
else
{
if (krb5_init_context(&context) == 0)
free_context = 1;
}
if (context)
cstr = com_right_r(context->et_list, code, buf, sizeof(buf));
if (free_context)
krb5_free_context(context);
if (cstr)
return strdup(cstr);
cstr = error_message(code);
if (cstr)
return strdup(cstr);
if (asprintf(&str, "<unknown error: %d>", (int)code) == -1 || str == NULL) if (asprintf(&str, "<unknown error: %d>", (int)code) == -1 || str == NULL)
return NULL; return NULL;