logo_kerberos.gif

Difference between revisions of "Projects/Credential cache collection improvements"

From K5Wiki
Jump to: navigation, search
(APIs)
Line 1: Line 1:
 
{{project-early}}
 
{{project-early}}
   
This project page is a grab-bag of credential cache collection issues and improvements, some user-visible and some internal. As it proposes only loosely-related internal improvements, it will probably not become a formal project page.
 
  +
This project intends to formalize the concept of a credential cache collection and improve the behavior of programs and library functions which store initial credentials within a collection.
   
 
==Background==
 
==Background==
Line 7: Line 7:
 
The concept of a credential cache collection began in release 1.6 with the introduction of the krb5_cccol APIs. In release 1.10, the [[Projects/Client_principal_selection|client principal selection]] project implemented the collection-enabled DIR credential cache type, collection behavior for kinit, klist, and kdestroy, and added the new kswitch command. The behavior of tools on credential cache collections was based largely on the behavior of Heimdal, whose collection semantics in turn were based loosely on Kerberos for Macintosh.
 
The concept of a credential cache collection began in release 1.6 with the introduction of the krb5_cccol APIs. In release 1.10, the [[Projects/Client_principal_selection|client principal selection]] project implemented the collection-enabled DIR credential cache type, collection behavior for kinit, klist, and kdestroy, and added the new kswitch command. The behavior of tools on credential cache collections was based largely on the behavior of Heimdal, whose collection semantics in turn were based loosely on Kerberos for Macintosh.
   
Credential cache types are either collection-enabled (such as DIR) or not (such as FILE). For a collection-enabled type, the residual string may identify a collection (such as DIR:/path/to/directory) or a subsidiary cache within the collection (such as DIR::/path/to/directory/tktXXXXXX). A collection has a primary cache which can be altered by krb5_cc_switch or the kswitch command. Resolving the name of a collection yields a cache whose name is the primary cache within that collection.
+
Credential cache types are either collection-enabled (such as DIR) or not (such as FILE). For a collection-enabled type, the residual string may identify a collection (such as DIR:/path/to/directory) or a subsidiary cache within the collection (such as DIR::/path/to/directory/tktXXXXXX). A collection has a primary cache which can be altered by krb5_cc_switch or the kswitch command. Resolving the name of a collection yields a cache handle for the primary cache within that collection.
   
If the default credential cache name uses a collection-enabled type, command-line tools behave differently as described in [[Projects/Client_principal_selection#Tool_alterations_to_use_cache_collection|the client principal selection project page]]. Also, GSSAPI client applications will automatically select client principals based on the $HOME/.k5identity file or the realm of the target server.
 
  +
The krb5_cccol APIs define "the collection" as the union of all per-type collections. These APIs do not accept the name of a particular collection, but the default ccache name of the krb5_context object influences what is in per-type collections. Except for MEMORY and API, no ccache type adds caches to the collection unless it is used by the default ccache name. If the default ccache name indicates a subsidiary cache for a collection-enabled type, the ccache type only adds the subsidiary cache to the collection, not the full collection contents.
   
The krb5_cccol APIs define "the collection" as the union of all per-type collections. These APIs do not accept the name of a particular collection, but the default ccache name of the krb5_context object influences what is in per-type collections. Except for MEMORY, no ccache type adds caches to the collection unless it is used by the default ccache name. If the default ccache name indicates a subsidiary cache for a collection-enabled type, the ccache type only adds the subsidiary cache to the collection, not the full collection contents.
 
  +
ccache type implementations of krb5_cc_new_unique may also use the default ccache name to determine what collection to create a new cache in.
   
==Possible improvements==
 
  +
GSSAPI client applications will automatically select caches from the collection based on the $HOME/.k5identity file or the realm of the target server.
   
===Documentation improvements===
 
  +
If the default cache name uses a switchable type, kinit will scan the collection for a cache with the same principal as it is acquiring credentials for, and will refresh that cache if one is found. If one is not found, it will create a new cache of the same type using krb5_cc_new_unique. When credentials are successfully acquired, the ccache used will be made the primary cache for the collection using krb5_cc_switch.
   
Collection behavior is described in various parts of the documentation, but there is no documentation dedicated to its use. There is also no documentation of how a ccache type should implementation collection semantics; this documentation would be of internal use only for the moment, but could become public-facing if we implement loadable ccache modules.
 
  +
The krb5 GSSAPI mechanism's gss_acquire_cred uses similar logic to pick a cache when acquiring new credentials, with a few differences: (1) if the default cache type is not switchable, it will not overwrite existing credentials in the default cache unless they have the same client principal name; (2) when acquiring credentials with a password, it will prefer an uninitialized primary cache to a new cache within the collection; and (3) it never switches the primary cache within the collection.
   
===Getting credentials for secondary use===
 
  +
ksu also uses similar logic to kinit to pick a cache, operating on the default cache name of the target user. It never switches the primary cache within the collection. If the default cache type is not switchable, it does not overwrite the default cache; instead, it creates a unique cache name by extending the default cache name.
   
"kinit princname" with a collection-enabled default cache switches the primary cache to the newly-obtained credentials. If the credentials are being acquired for secondary use, this is inconvenient, as it typically affects all shells and applications within the login system. There are several common use cases like this: the user may be acquiring root instance credentials for use with specific commands, or credentials in a second realm for use only in contacting servers of that realm.
 
  +
gss_store_cred does not yet implement collection semantics; see {{bug|8010}}.
   
Heimdal implements kinit --no-change-default which overrides this behavior; we do not yet implement it. Implementing this flag in MIT krb5 would be complicated by the lack of long option support in the Unix versions of our tools. It should perhaps have a short option name anyway for convenience.
 
  +
There are inherent concurrency issues in the cache collection and base credential cache API functions. Two processes obtaining new credentials within a collection for the same principal at the same time could wind up creating separate unique caches within the collection, instead of choosing the same cache. {{bug|7707}} describes issues surrounding atomic reinitialization of caches, and proposes using krb5_cc_move to solve them.
   
Explicitly using secondary credentials for an individual shell command is not as easy as it should be; the user has to use "klist -l" to identify the subsidiary cache name, then set the KRB5CCNAME environment variable to that name. One possible solution is to make kswitch support running a command with KRB5CCNAME set to a subsidiary ccache, instead of switching the primary cache for the collection.
 
  +
==New collection architecture==
   
===Memory caches===
 
  +
As before, a credential cache name identifies either a collection or an individual cache, a collection has a switchable primary cache, and resolving a collection name results in a handle to the primary cache. For collection-enabled cache types, a new method will distinguish between residual strings which identify collections and residual strings which identify individual caches.
   
The MEMORY cache type should probably behave like the FILE cache type, adding no caches to the collection except for the default cache if it is a MEMORY cache. Since 1.10, we have not encountered any benefits of adding all MEMORY caches to the collection, and have encountered minor costs (such as ksu having to use a bogus client principal name for its temporary memory cache).
 
  +
New APIs will allow operation on named collections, using a credential cache name to identify the collection. Where it makes sense for these APIs, a credential cache name identifying a single cache will be treated as a singleton collection containing only one cache. Existing APIs will operate on the default cache name of the krb5_context object. There will no longer be a global connection containing the union of per-type collections; as the collection APIs always operate on a ccache name, iterating over the collection will yield only caches of one type. New APIs will be needed to amend krb5_cccol_cursor_new, krb5_cc_cache_match, krb5_cc_new_unique, and krb5_cc_switch. (TBD: flesh out these new APIs.)
   
===APIs===
 
  +
A new API will copy credentials from an existing cache (typically a MEMORY cache) into a named collection, optionally replacing credentials and switching the primary cache. This API can operate atomically when the cache type permits. kinit, gss_acquire_cred, gss_store_cred, gss_store_cred_into, and ksu will be modified to use this API. The same API can be used to reinitialize a specific cache by specifying a cache name instead of a collection name. (TBD: flesh out these new APIs. Open question: if there is a flag for setting the default, should we insist on it being set if the ccname is not a collection?)
   
At least three parts of the system (kinit, ksu, and gss_acquire_cred) decide where to place new credentials for a principal using similar logic, and gss_store_cred will likely do so in the future (see {{bug|8010}}). We could provide a library API which implements this logic.
 
  +
===Behavior differences===
   
Deciding whether to use collection-enabled semantics currently relies on the result of krb5_cc_support_switch on the cache type. This creates some edge cases which are arguably bugs; for example, if KRB5CCNAME is set to a subsidiary cache name for "kinit princname", kinit will report a confusing error rather than overwriting the cache with a different principal. We could instead introduce a krb5_cc_is_collection API which accepts a ccache name.
 
  +
MEMORY and API caches will no longer appear within the collection when the default cache name does not use those types.
   
If the MEMORY cache behavior is changed as proposed above, then the krb5_cccol APIs, instead of iterating over all types, could call into the cache type of the default cache name, with the residual string as an argument. If krb5_cc_is_collection is implemented, cccursor.c could take care of returning a singleton collection when the default cache name does not indicate a collection. This would simplify the ptcursor_new/ptcursor_next methods of all ccache types and would mean FILE and MEMORY would not have to implement those methods. We could also provide a variant of krb5_cccol_cursor_new which accepts a cache name instead of using the default cache name for the context.
 
  +
If the default cache name uses a switchable type but identifies a single cache within the collection, kinit/gss_acquire_cred/ksu will store into that specific cache rather than trying to apply collection semantics.
  +
  +
kinit -c and gss_store_cred_into, when given a ccache name identifying a collection, will use collection semantics for choosing a cache within the collection, rather than storing into the primary cache of the collection.
  +
  +
===Ancillary improvements===
  +
  +
A new kinit option (probably -N, and --no-change-default if long options are supported) will allow obtaining new tickets with kinit without switching the default. (Open question: if the specified ccache name is not a collection and the cache contains credentials for a different principal, should this fail?)
  +
  +
kswitch will intuit the -c or -p flag based on the argument. If the argument begins with a / or \ or contains a colon, we will assume that it is a cache name (-c); otherwise we will assume that it is a principal name (-p). If additional arguments are given, they will be treated as a command to be run with the selected cache as the default cache, and the primary cache of the collection will remain unchanged. This will allow usage like "kinit -N user/root" followed by kswitch user/root ssh root@hostname".
  +
  +
==Documentation==
  +
  +
We will add new pages to doc/user and to doc/appdev describing cache collections from the user and API viewpoints.
  +
  +
There existing documentation of collection behavior in gssapi.rst, ccache_def.rst, ccselect.rst, klist.rst, kinit.rst, kswitch.rst, kdestroy.rst, k5identity.rst, env_variables.rst, and krb5_conf.rst will be updated to reflect the new architecture.
   
 
==Other discussions==
 
==Other discussions==

Revision as of 13:02, 16 September 2014

This is an early stage project for MIT Kerberos. It is being fleshed out by its proponents. Feel free to help flesh out the details of this project. After the project is ready, it will be presented for review and approval.


This project intends to formalize the concept of a credential cache collection and improve the behavior of programs and library functions which store initial credentials within a collection.

Background

The concept of a credential cache collection began in release 1.6 with the introduction of the krb5_cccol APIs. In release 1.10, the client principal selection project implemented the collection-enabled DIR credential cache type, collection behavior for kinit, klist, and kdestroy, and added the new kswitch command. The behavior of tools on credential cache collections was based largely on the behavior of Heimdal, whose collection semantics in turn were based loosely on Kerberos for Macintosh.

Credential cache types are either collection-enabled (such as DIR) or not (such as FILE). For a collection-enabled type, the residual string may identify a collection (such as DIR:/path/to/directory) or a subsidiary cache within the collection (such as DIR::/path/to/directory/tktXXXXXX). A collection has a primary cache which can be altered by krb5_cc_switch or the kswitch command. Resolving the name of a collection yields a cache handle for the primary cache within that collection.

The krb5_cccol APIs define "the collection" as the union of all per-type collections. These APIs do not accept the name of a particular collection, but the default ccache name of the krb5_context object influences what is in per-type collections. Except for MEMORY and API, no ccache type adds caches to the collection unless it is used by the default ccache name. If the default ccache name indicates a subsidiary cache for a collection-enabled type, the ccache type only adds the subsidiary cache to the collection, not the full collection contents.

ccache type implementations of krb5_cc_new_unique may also use the default ccache name to determine what collection to create a new cache in.

GSSAPI client applications will automatically select caches from the collection based on the $HOME/.k5identity file or the realm of the target server.

If the default cache name uses a switchable type, kinit will scan the collection for a cache with the same principal as it is acquiring credentials for, and will refresh that cache if one is found. If one is not found, it will create a new cache of the same type using krb5_cc_new_unique. When credentials are successfully acquired, the ccache used will be made the primary cache for the collection using krb5_cc_switch.

The krb5 GSSAPI mechanism's gss_acquire_cred uses similar logic to pick a cache when acquiring new credentials, with a few differences: (1) if the default cache type is not switchable, it will not overwrite existing credentials in the default cache unless they have the same client principal name; (2) when acquiring credentials with a password, it will prefer an uninitialized primary cache to a new cache within the collection; and (3) it never switches the primary cache within the collection.

ksu also uses similar logic to kinit to pick a cache, operating on the default cache name of the target user. It never switches the primary cache within the collection. If the default cache type is not switchable, it does not overwrite the default cache; instead, it creates a unique cache name by extending the default cache name.

gss_store_cred does not yet implement collection semantics; see [krbdev.mit.edu #8010].

There are inherent concurrency issues in the cache collection and base credential cache API functions. Two processes obtaining new credentials within a collection for the same principal at the same time could wind up creating separate unique caches within the collection, instead of choosing the same cache. [krbdev.mit.edu #7707] describes issues surrounding atomic reinitialization of caches, and proposes using krb5_cc_move to solve them.

New collection architecture

As before, a credential cache name identifies either a collection or an individual cache, a collection has a switchable primary cache, and resolving a collection name results in a handle to the primary cache. For collection-enabled cache types, a new method will distinguish between residual strings which identify collections and residual strings which identify individual caches.

New APIs will allow operation on named collections, using a credential cache name to identify the collection. Where it makes sense for these APIs, a credential cache name identifying a single cache will be treated as a singleton collection containing only one cache. Existing APIs will operate on the default cache name of the krb5_context object. There will no longer be a global connection containing the union of per-type collections; as the collection APIs always operate on a ccache name, iterating over the collection will yield only caches of one type. New APIs will be needed to amend krb5_cccol_cursor_new, krb5_cc_cache_match, krb5_cc_new_unique, and krb5_cc_switch. (TBD: flesh out these new APIs.)

A new API will copy credentials from an existing cache (typically a MEMORY cache) into a named collection, optionally replacing credentials and switching the primary cache. This API can operate atomically when the cache type permits. kinit, gss_acquire_cred, gss_store_cred, gss_store_cred_into, and ksu will be modified to use this API. The same API can be used to reinitialize a specific cache by specifying a cache name instead of a collection name. (TBD: flesh out these new APIs. Open question: if there is a flag for setting the default, should we insist on it being set if the ccname is not a collection?)

Behavior differences

MEMORY and API caches will no longer appear within the collection when the default cache name does not use those types.

If the default cache name uses a switchable type but identifies a single cache within the collection, kinit/gss_acquire_cred/ksu will store into that specific cache rather than trying to apply collection semantics.

kinit -c and gss_store_cred_into, when given a ccache name identifying a collection, will use collection semantics for choosing a cache within the collection, rather than storing into the primary cache of the collection.

Ancillary improvements

A new kinit option (probably -N, and --no-change-default if long options are supported) will allow obtaining new tickets with kinit without switching the default. (Open question: if the specified ccache name is not a collection and the cache contains credentials for a different principal, should this fail?)

kswitch will intuit the -c or -p flag based on the argument. If the argument begins with a / or \ or contains a colon, we will assume that it is a cache name (-c); otherwise we will assume that it is a principal name (-p). If additional arguments are given, they will be treated as a command to be run with the selected cache as the default cache, and the primary cache of the collection will remain unchanged. This will allow usage like "kinit -N user/root" followed by kswitch user/root ssh root@hostname".

Documentation

We will add new pages to doc/user and to doc/appdev describing cache collections from the user and API viewpoints.

There existing documentation of collection behavior in gssapi.rst, ccache_def.rst, ccselect.rst, klist.rst, kinit.rst, kswitch.rst, kdestroy.rst, k5identity.rst, env_variables.rst, and krb5_conf.rst will be updated to reflect the new architecture.

Other discussions

   http://news.gmane.org/gmane.comp.encryption.kerberos.heimdal.general