kinit: get_switched_ccache
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
This commit is contained in:
@@ -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)
|
||||
{
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user