env KRB5CCNAME=/tmp/foocc kinit ignores the env

The problem is that fcc_get_cache_next() is called in a context where
context->default_cc_name is not set.  We should call
krb5_cc_default_name(), and that fixes the problem.  There's a comment
warning that this can result in reentering krb5_cc_cache_match(), but
nothing in libkrb5 calls krb5_cc_cache_match(), so the comment is wrong,
at least in the github tree.

An alternative would be to call krb5_cc_set_default_name(NULL) in
kuser/kinit.c before calling krb5_cc_cache_match(), however, that seems
like an insufficiently general solution.  Also, the semantics of
krb5_cc_cache_match() would differ from MIT's -- it seems better to
match MIT's semantics.
This commit is contained in:
Nicolas Williams
2014-03-10 20:20:49 -05:00
parent 46e0bd3c68
commit c9f65fc942

View File

@@ -1114,8 +1114,8 @@ fcc_get_cache_next(krb5_context context, krb5_cc_cursor cursor, krb5_ccache *id)
{ {
struct fcache_iter *iter = cursor; struct fcache_iter *iter = cursor;
krb5_error_code ret; krb5_error_code ret;
const char *fn; const char *fn, *cc_type;
char *expandedfn = NULL; krb5_ccache cc;
if (iter == NULL) if (iter == NULL)
return krb5_einval(context, 2); return krb5_einval(context, 2);
@@ -1127,36 +1127,25 @@ fcc_get_cache_next(krb5_context context, krb5_cc_cursor cursor, krb5_ccache *id)
iter->first = 0; iter->first = 0;
/* /*
* Can't call krb5_cc_default_name here since it refers back to * Note: do not allow krb5_cc_default_name() to recurse via
* krb5_cc_cache_match() which will call back into this function. * krb5_cc_cache_match().
* * Note that context->default_cc_name will be NULL even though
* Just use the default value if its set, otherwise, use the * KRB5CCNAME is set in the environment if
* default hardcoded value. * krb5_cc_set_default_name() hasn't
*/ */
fn = context->default_cc_name; fn = krb5_cc_default_name(context);
if (fn == NULL || strncasecmp(fn, "FILE:", 5) != 0) { ret = krb5_cc_resolve(context, fn, &cc);
ret = _krb5_expand_default_cc_name(context, if (ret != 0)
KRB5_DEFAULT_CCNAME_FILE, return ret;
&expandedfn); cc_type = krb5_cc_get_type(context, cc);
if (ret) if (strcmp(cc_type, "FILE") != 0) {
return ret; krb5_cc_close(context, cc);
fn = expandedfn; return KRB5_CC_END;
} }
/* check if file exists, don't return a non existant "next" */
if (strncasecmp(fn, "FILE:", 5) == 0) {
struct stat sb;
ret = stat(fn + 5, &sb);
if (ret) {
ret = KRB5_CC_END;
goto out;
}
}
ret = krb5_cc_resolve(context, fn, id);
out:
if (expandedfn)
free(expandedfn);
return ret; *id = cc;
return 0;
} }
static krb5_error_code KRB5_CALLCONV static krb5_error_code KRB5_CALLCONV