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_get_error_message(krb5_context context, krb5_error_code code)
{
char *str;
HEIMDAL_MUTEX_lock(context->mutex);
if (context->error_string &&
(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);
char *str = NULL;
const char *cstr = NULL;
char buf[128];
int free_context = 0;
if (code == 0)
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;
char buf[128];
msg = com_right_r(context->et_list, code, buf, sizeof(buf));
if (msg)
return strdup(msg);
HEIMDAL_MUTEX_lock(context->mutex);
if (context->error_string &&
(code == context->error_code || context->error_code == 0))
{
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)
return NULL;