Delay KRB5_KTNAME lookup until keytab resolution.

Previously getenv("KRB5_KTNAME") happened in

    init_context_from_config_file()

which would capture the environment value as an override without
using strdup() to get a private copy, so it would get trashed in
applications that dynamically update the environment (e.g. Perl
code that has a tied %ENV).

The patch delays getenv("KRB5_KTNAME") until the context's value
of default_keytab is actually needed, and the environment can preempt
the context's default at that time.

[ Do we need to worry about issuid() being true initially when the
  context is created, but not later, because the application changes
  both the real and effective uid?  If so the issuid() state should
  be saved when the context is created and the saved value queried. ]
This commit is contained in:
Viktor Dukhovni
2015-02-06 23:14:52 -05:00
committed by Viktor Dukhovni
parent c1564e2cdb
commit 49861eb2c5
2 changed files with 27 additions and 18 deletions

View File

@@ -147,13 +147,6 @@ init_context_from_config_file(krb5_context context)
free(context->permitted_enctypes);
context->permitted_enctypes = tmptypes;
/* default keytab name */
tmp = NULL;
if(!issuid())
tmp = getenv("KRB5_KTNAME");
if(tmp != NULL)
context->default_keytab = tmp;
else
INIT_FIELD(context, string, default_keytab,
KEYTAB_DEFAULT, "default_keytab_name");

View File

@@ -242,6 +242,21 @@ krb5_kt_resolve(krb5_context context,
return ret;
}
/*
* Default ktname from context with possible environment
* override
*/
static const char *default_ktname(krb5_context context)
{
const char *tmp = NULL;
if(!issuid())
tmp = getenv("KRB5_KTNAME");
if(tmp != NULL)
return tmp;
return context->default_keytab;
}
/**
* copy the name of the default keytab into `name'.
*
@@ -257,7 +272,7 @@ krb5_kt_resolve(krb5_context context,
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_kt_default_name(krb5_context context, char *name, size_t namesize)
{
if (strlcpy (name, context->default_keytab, namesize) >= namesize) {
if (strlcpy (name, default_ktname(context), namesize) >= namesize) {
krb5_clear_error_message (context);
return KRB5_CONFIG_NOTENUFSPACE;
}
@@ -279,17 +294,18 @@ krb5_kt_default_name(krb5_context context, char *name, size_t namesize)
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_kt_default_modify_name(krb5_context context, char *name, size_t namesize)
{
const char *kt = NULL;
const char *kt;
if(context->default_keytab_modify == NULL) {
if(strncasecmp(context->default_keytab, "ANY:", 4) != 0)
kt = context->default_keytab;
else {
size_t len = strcspn(context->default_keytab + 4, ",");
if(len >= namesize) {
kt = default_ktname(context);
if (strncasecmp(kt, "ANY:", 4) == 0) {
size_t len = strcspn(kt + 4, ",");
if (len >= namesize) {
krb5_clear_error_message(context);
return KRB5_CONFIG_NOTENUFSPACE;
}
strlcpy(name, context->default_keytab + 4, namesize);
strlcpy(name, kt + 4, namesize);
name[len] = '\0';
return 0;
}
@@ -316,7 +332,7 @@ krb5_kt_default_modify_name(krb5_context context, char *name, size_t namesize)
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_kt_default(krb5_context context, krb5_keytab *id)
{
return krb5_kt_resolve (context, context->default_keytab, id);
return krb5_kt_resolve (context, default_ktname(context), id);
}
/**