From 49861eb2c5012a6508af461f4e6397d61b1e1fda Mon Sep 17 00:00:00 2001 From: Viktor Dukhovni Date: Fri, 6 Feb 2015 23:14:52 -0500 Subject: [PATCH] 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. ] --- lib/krb5/context.c | 11 ++--------- lib/krb5/keytab.c | 34 +++++++++++++++++++++++++--------- 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/lib/krb5/context.c b/lib/krb5/context.c index e738916d0..bd344f1c5 100644 --- a/lib/krb5/context.c +++ b/lib/krb5/context.c @@ -147,15 +147,8 @@ 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"); + INIT_FIELD(context, string, default_keytab, + KEYTAB_DEFAULT, "default_keytab_name"); INIT_FIELD(context, string, default_keytab_modify, NULL, "default_keytab_modify_name"); diff --git a/lib/krb5/keytab.c b/lib/krb5/keytab.c index 9cebe8d70..7aee42f9f 100644 --- a/lib/krb5/keytab.c +++ b/lib/krb5/keytab.c @@ -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); } /**