Skip to content

Commit

Permalink
kinit: get_switched_ccache
Browse files Browse the repository at this point in the history
Provide a new internal function called get_switched() to encapsulate
the algorithm for selecting a credential cache when the selected
ccache type supports switching.  There is no change in behavior for
UNIX which always calls krb5_cc_new_unique().  However, on Windows
alternate behavior is provided when the ccache type is API or MSLSA.

For the API ccache the default ccache name is stored in the Windows
registry which is shared across all logon sessions belonging to a
user.  For users that are members of the Administrators group this
includes both the UAC restricted and elevated sessions sharing the
same desktop.  It is very disconcerting when the elevated session obtains
credentials for the same client principal as the restricted session
and then all apps in the restricted session lose access to their
credential cache.   For Windows, the API credential caches are named
after the principal that is stored within them.  It provides for a
better end user experience.

For the MSLSA ccache tickets belonging to multiple principals are
all stored within the MSLSA ccache.  As a result, all attempts to
switch ccache names default back to the one and only one name.

Change-Id: I7865cd044cff01ff38ab107ec0961e42788fa073
  • Loading branch information
jaltman committed May 15, 2014
1 parent f5b10e5 commit 69c2872
Showing 1 changed file with 55 additions and 1 deletion.
56 changes: 55 additions & 1 deletion kuser/kinit.c
Expand Up @@ -1137,6 +1137,59 @@ get_princ_kt(krb5_context context,
free(def_realm);
}

static krb5_error_code
get_switched_ccache(krb5_context context,
const char * type,
krb5_principal principal,
krb5_ccache *ccache)
{
krb5_error_code ret;

#ifdef _WIN32
if (strcmp(type, "API") == 0) {
/*
* Windows stores the default ccache name in the
* registry which is shared across multiple logon
* sessions for the same user. The API credential
* cache provides a unique name space per logon
* session. Therefore there is no need to generate
* a unique ccache name. Instead use the principal
* name. This provides a friendlier user experience.
*/
char * unparsed_name;
char * cred_cache;

ret = krb5_unparse_name(context, principal,
&unparsed_name);
if (ret)
krb5_err(context, 1, ret,
N_("unparsing principal name", ""));

ret = asprintf(&cred_cache, "API:%s", unparsed_name);
krb5_free_unparsed_name(context, unparsed_name);
if (ret == -1 || cred_cache == NULL)
krb5_err(context, 1, ret,
N_("building credential cache name", ""));

ret = krb5_cc_resolve(context, cred_cache, ccache);
free(cred_cache);
} else if (strcmp(type, "MSLSA") == 0) {
/*
* The Windows MSLSA cache when it is writeable
* stores tickets for multiple client principals
* in a single credential cache.
*/
ret = krb5_cc_resolve(context, "MSLSA:", ccache);
} else {
ret = krb5_cc_new_unique(context, type, NULL, ccache);
}
#else /* !_WIN32 */
ret = krb5_cc_new_unique(context, type, NULL, ccache);
#endif /* _WIN32 */

return ret;
}

int
main(int argc, char **argv)
{
Expand Down Expand Up @@ -1255,7 +1308,8 @@ main(int argc, char **argv)
type = krb5_cc_get_type(context, ccache);
if (krb5_cc_support_switch(context, type)) {
krb5_cc_close(context, ccache);
ret = krb5_cc_new_unique(context, type, NULL, &ccache);
ret = get_switched_ccache(context, type, principal,
&ccache);
}
}
}
Expand Down

0 comments on commit 69c2872

Please sign in to comment.