Kerberos Login API

| # Macintosh Development

[Home] [About Us] [People] [Information Systems]
[Kerberos for Macintosh] [Applications] [Miscellaneous Documentation]

| Kerberos Login API

> This documentation applies to Mac OS X 10.2 and later.

> ## Table of Contents

> Types

> - KLPrincipal
> - KLLoginOptions
> - KLStatus
> - KLKerberosVersion
> - KLDefaultLoginOption
> - KLLoginMode
> - KLDialogIdentifier
> - KLIndex
> - KLLifetime
> - KLTime
> - KLSize
> - KLRefCon
> - KLBoolean

> Constants

> - Kerberos Version Constants
> - Dialog Identifier Constants
> - Option Identifier Constants
> - Realm Index Constants

> Login Library Behavior

> Terminology Notes

> Functions

> - High-Level Login Functions
>   - KLAcquireInitialTickets
>   - KLAcquireNewInitialTickets
>   - KLDestroyTickets
>   - KLChangePassword
> - Low-Level Login Functions
>   - KLAcquireInitialTicketsWithPassword
>   - KLAcquireNewInitialTicketsWithPassword
>   - KLAcquireNewInitialTicketCredentialsWithPassword
>   - KLStoreNewInitialTicketCredentials
>   - KLVerifyInitialTickets
>   - KLVerifyInitialTicketCredentials
>   - KLAcquireNewInitialTicketsWithKeytab
>   - KLRenewInitialTickets
>   - KLValidateInitialTickets
>   - KLLastChangedTime
>   - KLCacheHasValidTickets
>   - KLTicketStartTime
>   - KLTicketExpirationTime
>   - KLSetSystemDefaultCache
>   - KLHandleError
>   - KLGetErrorString
>   - KLCancelAllDialogs
> - Low-Level Change Password Functions
>   - KLChangePasswordWithPasswords
> - Application Defined Functions
>   - KerberosLoginIdleCallback
> - Application Configuration Functions
>   - KLSetIdleCallback
>   - KLGetIdleCallback
> - Library Configuration Functions
>   - Description of configuration options, types, and allowed values
>   - KLGetDefaultLoginOption
>   - KLSetDefaultLoginOption
> - Realms Configuration Functions
>   - KLFindKerberosRealmByName
>   - KLGetKerberosRealm
>   - KLSetKerberosRealm
>   - KLRemoveKerberosRealm
>   - KLInsertKerberosRealm
>   - KLRemoveAllKerberosRealms
>   - KLCountKerberosRealms
>   - KLGetKerberosDefaultRealm
>   - KLGetKerberosDefaultRealmByName
>   - KLSetKerberosDefaultRealm
>   - KLSetKerberosDefaultRealmByName
> - KLPrincipal Functions
>   - KLCreatePrincipalFromTriplet
>   - KLCreatePrincipalFromString
>   - KLGetTripletFromPrincipal
>   - KLGetStringFromPrincipal
>   - KLGetDisplayStringFromPrincipal
>   - KLComparePrincipal
>   - KLDisposePrincipal
> - KLLoginOptions Functions
>   - KLCreateLoginOptions
>   - KLLoginOptionsSetTicketLifetime
>   - KLLoginOptionsSetForwardable
>   - KLLoginOptionsSetProxiable
>   - KLLoginOptionsSetRenewableLifetime
>   - KLLoginOptionsSetAddressless
>   - KLLoginOptionsSetTicketStartTime
>   - KLLoginOptionsSetServiceName
>   - KLDisposeLoginOptions
> - Miscellaneous Functions
>   - KLDisposeString
> - Internal Use Functions
>   - __KLInternalAcquireTicketsForCache
>   - __KLInternalAcquireNewKerberos4TicketsFromKerberos5Tickets

> ## Types

> ### KLPrincipal

>     struct KLPrincipal;

> `KLPrincipal` is an opaque structure. Use the `KLPrincipal` manipulation functions to get information about the principal contained in the structure. `KLPrincipal` should be capable of retaining and reproducing both Kerberos v4 and v5 representations of the fully qualified principal. `nil` is an acceptable value for a `KLPrincipal`.

> ### KLLoginOptions

>     struct KLLoginOptions;

> KLLoginOptions is an opaque structure. Use the KLLoginOptions manipulation functions to get information about the options contained in the structure. KLLoginOptions is used to determine ticket options for logging (eg: ticket lifetime).

> ### KLStatus

> The Kerberos Login Library error code type (an integer type).

> ### KLKerberosVersion

> A Kerberos version. One of KLEKerberosVersion (an integer type).

> ### KLDefaultLoginOption

> One of KLEDefaultLoginOptions, used to set default login options (an integer type). See KLGetDefaultLoginOptions or KLSetDefaultLoginOptions.

> ### KLLoginMode

> One of KLELoginMode (an integer type). Used to specifiy if the login dialog will come up in basic or advanced mode.

> ### KLDialogIdentifier

> One of KLEDialogIdentifiers (an integer type). Used to tell the error dialog which dialog the error is for.

> ### KLIndex

> An index into the realm list (an integer type).

> ### KLLifetime

> The ticket lifetime in seconds (an integer type).

> ### KLTime

> Unix time (seconds since 1/1/1970 00:00:00 GMT) (an integer type).

> ### KLSize

> The size of a buffer (for KLGetDefaultLoginOptions or KLSetDefaultLoginOptions) or the size of the realm list (returned by CountKerberosRealms). An integer type.

> ### KLRefCon

> The application refCon which is returned to your application event filter (an integer type). Pass in a pointer to your globals.

> ### KLBoolean

> A Boolean value (an integer type). 0 is false, everything else is true.

> ## Constants

> ### Kerberos Version Constants

> These are used by the KLPrincipal and cache manipulation functions to specify protocol versions of Kerberos for credentials and principals. The Kerberos version is either represented as a bitfield of the versions (ie: `kerberosVersion_V4 & kerberosVersion_V5` is represents both versions) or as one of two magic values. `kerberosVersion_Any` refers to one or more Kerberos version and `kerberosVersion_All` refers to all Kerberos versions which are valid for the current realm (ie: in a version 4-only realm, `kerberosVersion_All` would be equivalent to `kerberosVersion_V4`).

>     enum KLEKerberosVersion {
>          kerberosVersion_Any     = 0,
>          kerberosVersion_V4      = 1,
>          kerberosVersion_V5      = 2,
>          kerberosVersion_All     = 0xFFFFFFFF
>     };

> ### Dialog Identifier Constants

> These are used by Kerberos Login Event Filter functions to identify which dialog they were called from.

>     num KLELoginDialogIdentifers {
>     	loginLibrary_LoginDialog,
>     	loginLibrary_OptionsDialog,
>     	loginLibrary_ChangePasswordDialog,
>     	loginLibrary_ProgressDialog,
>     	loginLibrary_PrompterDialog,
>     	loginLibrary_UnknownDialog = -1
>     };

> ### Option Identifier Constants

> These constants are the configuration option flags used by `KLGetLoginOption()` and `KLSetLoginOption()` . For further descriptions of them, see Library Configuration Functions.

>     enum KLEDefaultLoginOptions {
>     	/* Initial values and ranges */
>     	loginOption_LoginName                     = 'name',

>     	loginOption_RememberPrincipal             = 'prin',
>     	loginOption_RememberExtras                = 'extr',

>     	loginOption_MinimalTicketLifetime         = '-lif',
>     	loginOption_MaximalTicketLifetime         = '+lif',
>     	loginOption_DefaultTicketLifetime         = '0lif',
>     	loginOption_LongTicketLifetimeDisplay     = 'hms ',

>     	loginOption_DefaultRenewableTicket        = '0rtx',
>         loginOption_MinimalRenewableLifetime      = '-rlf',
>     	loginOption_MaximalRenewableLifetime      = '+rlf',
>     	loginOption_DefaultRenewableLifetime      = '0rlf',

>     	loginOption_DefaultForwardableTicket      = '0fwd',
>     	loginOption_DefaultProxiableTicket		  = '0prx',
>         loginOption_DefaultAddresslessTicket      = '0adr'
>     };

> ### Realm Index Constants

> These constants are the configuration option flags used by `KLInsertKerberosRealm()`

>     enum KLERealmListIndexes {
>          realmList_Start     = 0,
>          realmList_End       = 0xFFFF
>     };

> ## Login Library Behavior

> | Principal specified | No principal specified
> | Valid tickets exist for it | No valid tickets exist for it | Valid tickets exist in system default cache | No valid tickets in system default cache
> `KLAcquireInitialTickets()` (primarily for applications that need service tickets) | No user interface displayed No new tickets obtained System default cache unchanged Name of credential cache corresponding to principal is returned | Displays user interface (with non-editable principal) New tickets obtained Credential cache corresponding to principal is made system default if no other tickets exist in cache collection Name of new credential cache corresponding to principal is returned | No user interface displayed No new tickets obtained System default cache unchanged Name of system default cache is returned | Displays user interface(with editable principal) New tickets obtained Credential cache corresponding to principal is made system default Name of new credential cache corresponding to principal is returned
> `KLAcquireNewInitialTickets()` (primarily for management applications) | Displays user interface (with non-editable principal) New tickets obtained, replacing existing tickets System default cache unchanged Name of new credential cache corresponding to principal is returned | Displays user interface (with non-editable principal) New tickets obtained Credential cache corresponding to principal is made system default if no other tickets exist in cache collection Name of new credential cache corresponding to principal is returned | Displays user interface(with editable principal) New tickets obtained - if they are for a principal already in the cache, they replace the existing tickets Name of new credential cache corresponding to principal is returned | Displays user interface(with editable principal) New tickets obtained - if they are for a principal already in the cache, they replace the existing tickets Credential cache corresponding to principal is made system default Name of new credential cache corresponding to principal is returned

> `KLAcquireInitialTicketsWithPassword()` behaves identically to `KLAcquireInitialTickets()` with "principal specified," but the user interface is never displayed under any conditions.

> `KLAcquireNewInitialTicketsWithPassword()` behaves identically to `KLAcquireNewInitialTickets()` with "principal specified," but the user interface is never displayed under any conditions.

> `KLAcquireInitialTickets...()` does not set the system default cache when principal is non-nil because it's called when applications want service tickets, and we don't want the system default changing constantly. It will set the system default if there are no existing credential caches.

> `KLAcquireNewInitialTickets...()` does not set the system default cache because we want to allow explicit renews that don't change the defaults.

> So if an explicit renew wants to change the defaults, it must call `KLAcquireNewInitialTickets...()` and a default cache changing function.

> Originally the Login Library API was going to change the "application default cache" as well, however, Kerberos 5 doesn't have the concept of application default caches -- only context default caches. The only way the Login API could have changed these is if the caller passed in the current Kerberos v5 context, and we decided it would be bad to have the Login API depend on Kerberos 5 structures. So instead a credentials cache name is returned by functions that attempt to acquire tickets, and it is up to the caller to change the application or context defaults using that information.

> ## Terminology Notes

> The multiple uses of the word "cache" may be confusing. We have tried to distinguish between them by using different phrases. They are:

> "cache collection" - the conglomeration of all credential caches

> "credentials cache" - a single set of credentials for a specific principal and Kerberos version

> "system default cache" - a credentials cache that an application/service/context will use by default after the first time it is launched/created (in Kerberos v4, the application default cache will be set to the system default cache when the application is first launched; in v5 a context's default cache will be set the system default cache when the context is first created)

> ## High-Level Login Functions

> ### KLAcquireInitialTickets

>     KLStatus KLAcquireInitialTickets (
>          KLPrincipal    inPrincipal,
>          KLLoginOptions inLoginOptions,
>          KLPrincipal   *outPrincipal
>          char         **outCredCacheName);

> #### Requires:

> The `KLAcquireInitialTickets()` function requires the following:

> - `inPrincipal` is either NULL or a pointer to a valid `KLPrincipal`.
> - `inLoginOptions` is either NULL or a pointer to a valid `KLLoginOptions`.

> #### Effects:

> The `KLAcquireInitialTickets()` function attempts to insure that a valid ticket-granting ticket is available in the cache collection, prompting the user to obtain a new one if necessary. Its main purpose is to be used by client applications that want to make sure some tickets exist before using a Kerberos service.

> If `inLoginOptions` is not `nil` and new tickets are obtained, they are obtained with the login options specified by `inLoginOptions`.

> The name of the principal for which tickets are obtained (or found) is returned in `outPrincipal`.

> The name of the cache into which tickets are placed (or which is found if no new tickets are obtained) is returned in `outCredCacheName` so that the caller can change the application/context default cache if desired. This returned name can be used in Credential Cache API, Kerberos 4, or Kerberos 5 calls (if "API:" is prepended to the name).

> If `inPrincipal` is not `nil` (a principal is specified),

> - and no valid tickets for that principal are in the cache collection, `KLAcquireInitialTickets()` presents the Kerberos Login dialog to obtain user information and then attempts to acquire tickets with that information. If successful and no tickets at all were previously in the cache, the cache containing those tickets is made the system default cache;
> - or, valid tickets for that principal are available in the cache collection, no user interface is displayed.

> If `inPrincipal` is `nil` (no principal is specified),

> - and no valid tickets for any user are in the system default cache, `KLAcquireInitialTickets()` presents the Kerberos Login dialog to obtain user information and then attempts to acquire tickets with that information. If successful, the credentials cache corresponding to that principal is made the system default cache.
> - or, valid tickets are available in the system default cache, no user interface is displayed and the system default cache name is returned.

> `KLAcquireInitialTickets()` does not necessarily present the user interface. If you always want to bring up the user interface, use `KLAcquireNewInitialTickets()`.

> `KLAcquireInitialTickets()` will take care of presenting error dialogs to the user as necessary (ie: for problems such as unknown principal, incorrect password, etc.). You do not need to call `KLHandleError()` after this function.

> If both Kerberos v4 and Kerberos v5 are available for the realm of the principal, either both v4 and v5 ticket-granting tickets will be available in the cache collection (and the credentials cache containing them will possibly be set as the system default cache, as specified above) upon return, or `KLAcquireInitialTickets()` will return an error code.

> If both Kerberos v4 and Kerberos v5 are available for the realm of the principal, and valid tickets for only one version but not the other are available in the cache collection, `KLAcquireInitialTickets()` will treat this as the same as the no valid tickets case -- new tickets will be obtained for both Kerberos versions, replacing the current "orphan" ones.

> If only one of Kerberos v4 and Kerberos v5 is available for the realm of the principal, either a ticket-granting ticket for the appropriate version will be available in the cache collection (and the credentials cache containing them will be possibly set as the system default cache) as specified above upon return, or `KLAcquireInitialTickets()` will return an error code`.`

> #### Results:

> If `KLAcquireInitialTickets()` returns `klNoErr`, then:

> - tickets are available in the cache collection;
> - if `outPrincipal` is not `nil`, a new `KLPrincipal` is returned in `*outPrincipal`. The returned `KLPrincipal` should be freed using the `KLDisposePrincipal()` function. If `outPrincipal` is `nil`, nothing is returned.
> - if `outCredCacheName` is not `nil`, a C string containing one of the following is returned in `*outCredCacheName`: the name of the credentials cache corresponding to the principal; or if no principal was specified and no new tickets were necessary, it is the name of the system default credentials cache. The returned string should be freed using the `KLDisposeString()` function. If `outCredCacheName` is `nil`, nothing is returned.

> Otherwise, `outPrincipal` and `outCredCacheName` are unchanged and `KLAcquireInitialTickets()` returns one of the following error codes:

> `klParameterErr` | Invalid option passed into function (check your variables).
> `klBadPrincipalErr` | Invalid `KLPrincipal` passed into function.
> `klBadLoginOptionsErr` | Invalid `KLLoginOptions` passed into function.
> `klUserCanceledErr` | The user cancelled the dialog.
> `klMemFullErr` | Out of memory.
> `klRealmDoesNotExistErr` | The specified realm does not exist.
> `klFatalDialogErr` | The dialog failed to load because the resources are corrupt or missing.

> ### KLAcquireNewTickets

>     KLStatus KLAcquireNewInitialTickets (
>          KLPrincipal    inPrincipal,
>          KLLoginOptions inLoginOptions,
>          KLPrincipal   *outPrincipal
>          char         **outCredCacheName);

> #### Requires:

> The `KLAcquireNewInitialTickets()` function requires the following:

> - `inPrincipal` is either NULL or a pointer to a valid `KLPrincipal`.
> - `inLoginOptions` is either NULL or a pointer to a valid `KLLoginOptions`.

> #### Effects:

> The `KLAcquireNewInitialTickets()` function always attempts to get a new valid ticket-granting ticket, either for a new principal or replacing (renewing) the existing tickets for a principal already in the cache collection. The Kerberos Login dialog is always displayed. The main purpose of this function is to be used by administrative applications that want to provide a way to login new principals or renew existing tickets.

> The name of the principal for which tickets are obtained is returned in `outPrincipal`.

> The name of the cache into which tickets are placed is returned in `outCredCacheName` so that the caller can change the application/context default cache if desired. This returned name can be used in Credential Cache API, Kerberos 4, or Kerberos 5 calls (if "API:" is prepended to the name).

> If ``inPrincipal`` is not `nil` (a principal is specified),

> - and no valid tickets for that principal are in the cache collection, `KLAcquireNewInitialTickets()` presents the Kerberos Login dialog and then attempts to acquire tickets with that information. If successful, a valid ticket-granting ticket for that principal is placed in the cache collection. If successful and there are no other tickets in the cache collection, the credentials cache corresponding to that principal is made the system default cache.
> - or, valid tickets for that principal are available in the cache collection, `KLAcquireNewInitialTickets()` presents the Kerberos Login dialog and then attempts to acquire tickets with that information. If successful, the principal's existing tickets are replaced by a new ticket-granting ticket (possibly with a different lifetime and different ticket properties). No change is made to the system default cache. If unsuccessful, the principal's existing tickets are unchanged.

> If `inPrincipal` is `nil` (no principal is specified),

> - `KLAcquireNewInitialTickets()` presents the Kerberos Login dialog and attempts to acquire tickets with that information. If successful, a valid ticket-granting ticket for that principal is placed in the cache collection. If the user enters a principal with tickets already in the cache collection, that principal's existing tickets are replaced by a new ticket-granting ticket (possibly with a different lifetime and different ticket properties) by a successful login attempt, or left alone if an unsuccessful attempt is made. If successful and there are no other tickets in the cache collection, the credentials cache corresponding to that principal is made the system default cache. If unsuccessful, no changes to the cache collection are made.

> `KLAcquireNewInitialTickets()` will take care of presenting error dialogs to the user as necessary (for problems such as unknown principal, incorrect password, etc.). You do not need to call `KLHandleError()` after this function.

> If both Kerberos v4 and Kerberos v5 are available for the realm of the principal, `KLAcquireNewInitialTickets()` will either return an error code, or both new v4 and new v5 ticket-granting tickets will be available in the cache collection and possibly set the credentials cache containing them to be the system default cache (as specified above) upon return of `KLAcquireNewInitialTickets()`.

> If both Kerberos v4 and Kerberos v5 are available for the realm of the principal, and valid tickets for only one version but not the other are available in the cache collection, `KLAcquireNewInitialTickets()` will treat this as the same as the no valid tickets case -- new tickets will be obtained for both Kerberos versions, replacing the current "orphan" ones.

> If only one of Kerberos v4 and Kerberos v5 is available for the realm of the principal, `KLAcquireNewInitialTickets()` will either return an error code, or an appropriate new ticket-granting ticket will be available in the credentials cache and possibly set the credentials cache containing them to be the system default cache (as specified above) upon return of `KLAcquireNewInitialTickets()`.

> #### Results:

> If `KLAcquireNewInitialTickets()` returns `klNoErr`, then:

> - new tickets are available in the cache collection;
> - if `outPrincipal` is not `nil`, a new `KLPrincipal` is returned in `*outPrincipal`. The returned `KLPrincipal` should be freed using the `KLDisposePrincipal()` function. If `outPrincipal` is `nil`, nothing is returned.
> - if `outCredCacheName` is not `nil`, a C string containing the the name of the credentials cache into which new tickets were placed is returned in `*outCredCacheName`. The returned string should be freed using the `KLDisposeString()` function. If `outCredCacheName` is `nil`, nothing is returned.

> Otherwise, `outPrincipal` and `outCredCacheName` are unchanged and `KLAcquireNewInitialTickets()` returns one of the following error codes:

> `klParameterErr` | Invalid option passed into function (check your variables).
> `klBadPrincipalErr` | Invalid `KLPrincipal` passed into function.
> `klBadLoginOptionsErr` | Invalid `KLLoginOptions` passed into function.
> `klUserCanceledErr` | The user cancelled the dialog.
> `klMemFullErr` | Out of memory.
> `klRealmDoesNotExistErr` | The specified realm does not exist.
> `klFatalDialogErr` | The dialog failed to load because the resources are corrupt or missing.

> ### KLDestroyTickets

>     KLStatus KLDestroyTickets (
>     	KLPrincipal inPrincipal);

> #### Requires:

> The `KLDestroyTickets()` function requires the following:

> - `inPrincipal` is either NULL or a pointer to a valid `KLPrincipal`.

> #### Effects:

> `KLDestroyTickets()` removes all tickets, both for v4 and v5, for the principal specified in the `inPrincipal` structure from the cache collection. If inPrincipal is nil (no principal is specified), `KLDestroyTickets()` removes all tickets in the system default cache.

> If the credentials cache removed was the system default cache, `KLDestroyTickets()` sets the system default cache to another credentials cache (exactly which credentials cache is implementation dependent; in the MIT Kerberos for Macintosh implementation, the defaults are switched as per the Credentials Cache API).

> #### Results:

> If `KLDestroyTickets()` returns `klNoErr`, then credentials for the specified principal (or system default cache) were located in the cache collection and successfully removed.

> Otherwise, the cache collection is unchanged, and `KLDestroyTickets()` returns one of the following error codes:

> `klParameterErr` | Invalid option passed into function (check your variables).
> `klBadPrincipalErr` | Invalid `KLPrincipal` passed into function.
> `klMemFullErr` | Out of memory.
> `klPrincipalDoesNotExistErr` | The `KLPrincipal` passed in does not correspond to any cache in the cache collection.
> `klSystemDefaultDoesNotExistErr` | There is no system default cache (the cache collection is empty).

> ### KLChangePassword

>     KLStatus KLChangePassword (
>     	KLPrincipal inPrincipal);

> #### Requires:

> The `KLChangePassword()` function requires the following:

> - `inPrincipal` is a pointer to a valid `KLPrincipal`.

> #### Effects:

> The `KLChangePassword()` function attempts to change the password of the principal specified by `inPrincipal`.

> `KLChangePassword()` creates and displays the Kerberos Change Password dialog

> `KLChangePassword()` will take care of presenting error dialogs to the user as necessary (for problems such as unknown principal, incorrect password, etc.). You do not need to call `KLHandleError()` after this function.

> `KLChangePassword()` will either return an error code, or the principal's Kerberos password will have been changed.

> #### Results:

> If `KLChangePassword()` returns `klNoErr`, then the principal's password has been changed.

> Otherwise, `KLChangePassword()` returns one of the following error codes:

> `klParameterErr` | Invalid option passed into function (check your variables).
> `klBadPrincipalErr` | Invalid `KLPrincipal` passed into function.
> `klUserCanceledErr` | The user cancelled the dialog.
> `klMemFullErr` | Out of memory.
> `klRealmDoesNotExistErr` | The specified realm does not exist.
> `klFatalDialogErr` | The dialog failed to load because the resources are corrupt or missing.

> ## Low-Level Login Functions

> ### KLAcquireInitialTicketsWithPassword

>     KLStatus KLAcquireInitialTicketsWithPassword (
>          KLPrincipal      inPrincipal,
>          KLLoginOptions   inLoginOptions,
>          const char      *inPassword,
>          char           **outCredCacheName);

> #### Requires:

> The `KLAcquireInitialTicketsWithPassword()` function requires the following:

> - `inPrincipal` is a pointer to a valid `KLPrincipal`.
> - `inLoginOptions` is either NULL or a pointer to a valid `KLLoginOptions`.
> - `inPassword` points to a null-terminated C string;

> #### Effects:

> The `KLAcquireInitialTicketsWithPassword()` function attempts to insure that the cache collection contains a valid ticket-granting ticket for the Kerberos principal specified by `inPrincipal`. If your site uses hardware preauth, `KLAcquireInitialTicketsWithPassword()`will display a prompter dialog or prompt via the command line. If no UI is available, it will return an error.

> The name of the cache into which tickets are placed is returned in `outCredCacheName` so that the caller can change the application/context default cache if desired. This returned name can be used in Credential Cache API, Kerberos 4, or Kerberos 5 calls. The returned string must be freed by `KLDisposeString()`. If you pass in nil to this argument, the credentials cache name will not be allocated for you.

> If no valid ticket-granting ticket for the specified principal is available in the cache collection, then `KLAcquireInitialTicketsWithPassword()` will use the password in `inPassword` to attempt to acquire the tickets with the properties specified by `inLoginOptions`. If `inLoginOptions` is `nil`, the defaults (as specified by `KLSetDefaultLoginOption``()`) are used. If successful, and if no tickets at all were previously in the cache collection, the credentials cache corresponding to the principal is made the system default cache. If not successful, the cache collection is unchanged.

> If a valid ticket-granting ticket for the specified principal already exists in the cache collection, no action is taken beyond setting `outCredCacheName`.

> If both Kerberos v4 and Kerberos v5 are available for the realm of the principal, either both v4 and v5 ticket-granting tickets will be available in the cache collection (and possibly made the system default cache, as above) upon return, or `KLAcquireInitialTicketsWithPassword()` will return an error code.

> If both Kerberos v4 and Kerberos v5 are available for the realm of the principal, and valid tickets for only one version but not the other are available in the cache collection, `KLAcquireInitialTicketsWithPassword()` will treat this as the same as the no valid tickets case -- new tickets will be obtained for both Kerberos versions, replacing the current "orphan" ones.

> If only one of Kerberos v4 and Kerberos v5 is available for the realm of the principal, either a ticket-granting ticket for the appropriate Kerberos version will be available in the cache collection (and possibly made the system default cache, as above) upon return, or `KLAcquireInitialTicketsWithPassword()` will return an error code.

> #### Results:

> If `KLAcquireInitialTicketsWithPassword()` returns `klNoErr`, then:

> - tickets for the desired principal are available in the cache collection;
> - if `outCredCacheName` is not `nil`, a C string containing one of the following is returned in `*outCredCacheName`: the name of the credentials cache into which new tickets were placed; or if no new tickets were necessary because credentials for the principal were already in the cache collection, it is the name of the credentials cache corresponding to the principal; or if no principal was specified and no new tickets were necessary, it is the name of the system default credentials cache. The returned string should be freed using the `KLDisposeString()` function. If `outCredCacheName` is `nil`, nothing is returned.

> Otherwise, `KLAcquireInitialTicketsWithPassword()` returns one of the following error codes:

> `klParameterErr` | Invalid option passed into function (check your variables).
> `klBadPrincipalErr` | Invalid `KLPrincipal` passed into function.
> `klUserCanceledErr` | The user cancelled the dialog (only with hardware preauth).
> `klMemFullErr` | Out of memory.
> `klRealmDoesNotExistErr` | The specified realm does not exist.
> `klFatalDialogErr` | Dialog failed to load because the resources are corrupt or missing (only with hardware preauth).
> Any Kerberos 5 error | Use `KLHandleError ()` or `KLGetErrorString ()` to report these errors to the user.
> Any Kerberos 4 error | Use `KLHandleError ()` or `KLGetErrorString ()` to report these errors to the user.

> ### KLAcquireNewInitialTicketsWithPassword

>     KLStatus KLAcquireNewInitialTicketsWithPassword (
>          KLPrincipal      inPrincipal,
>          KLLoginOptions   inLoginOptions,
>          const char      *inPassword,
>          char           **outCredCacheName);

> #### Requires:

> The `KLAcquireNewInitialTicketsWithPassword()` function requires the following:

> - `inPrincipal` is a pointer to a valid `KLPrincipal`.
> - `inLoginOptions` is either NULL or a pointer to a valid `KLLoginOptions`.
> - `inPassword` points to a nul-terminated C string;

> #### Effects:

> The `KLAcquireNewInitialTicketsWithPassword()` function attempts to get a new valid ticket-granting ticket, either for a new principal or replacing (renewing) the existing tickets for a principal already in the cache collection. `KLAcquireNewInitialTicketsWithPassword()`will display a prompter dialog or prompt via the command line. If no UI is available, it will return an error.

> The name of the cache into which tickets are placed is returned in `outCredCacheName` so that the caller can change the application/context default cache if desired. This returned name can be used in Credential Cache API, Kerberos 4, or Kerberos 5 calls. The returned string must be freed by `KLDisposeString ()`. If you pass in nil to this argument, the credentials cache name will not be allocated for you.

> `KLAcquireNewInitialTicketsWithPassword()` will use the password in `inPassword` to attempt to acquire the tickets with the properties specified by `inLoginOptions`. If `inLoginOptions` is `nil`, the defaults (as specified by `KLSetDefaultLoginOption```` ()`) are used. If successful, and if no tickets at all were previously in the cache collection, the credentials cache corresponding to the principal is made the system default cache. If not successful, the cache collection is unchanged.

> `KLAcquireNewInitialTicketsWithPassword()` never changes the system default cache.

> If both Kerberos v4 and Kerberos v5 are available for the realm of the principal, either both new v4 and new v5 ticket-granting tickets will be available in the credentials cache upon return, or `KLAcquireNewInitialTicketsWithPassword()` will return an error code.

> If both Kerberos v4 and Kerberos v5 are available for the realm of the principal, and valid tickets for only one version but not the other are available in the cache collection, `KLAcquireNewInitialTicketsWithPassword()` will treat this as the same as the no valid tickets case -- new tickets will be obtained for both Kerberos versions, replacing the current "orphan" ones.

> If only one of Kerberos v4 and Kerberos v5 is available for the realm of the principal, either a ticket-granting ticket for the appropriate Kerberos version will be available in the cache collection upon return, or `KLAcquireNewInitialTicketsWithPassword()` will return an error code.

> #### Results:

> If `KLAcquireNewInitialTicketsWithPassword()` returns `klNoErr`, then:

> - new tickets for the desired principal are available in the cache collection.
> - if `outCredCacheName` is not `nil`, a C string containing the the name of the credentials cache into which new tickets were placed is returned in `*outCredCacheName`. The returned string should be freed using the `KLDisposeString()` function. If `outCredCacheName` is `nil`, nothing is returned.

> Otherwise, `KLAcquireNewInitialTicketsWithPassword()` returns one of the following error codes:

> `klParameterErr` | Invalid option passed into function (check your variables).
> `klBadPrincipalErr` | Invalid `KLPrincipal` passed into function.
> `klUserCanceledErr` | The user cancelled the dialog (only with hardware preauth).
> `klMemFullErr` | Out of memory.
> `klRealmDoesNotExistErr` | The specified realm does not exist.
> `klFatalDialogErr` | Dialog failed to load because the resources are corrupt or missing (only with hardware preauth).
> Any Kerberos 5 error | Use `KLHandleError ()` or `KLGetErrorString ()` to report these errors to the user.
> Any Kerberos 4 error | Use `KLHandleError ()` or `KLGetErrorString ()` to report these errors to the user.

> ### KLAcquireNewInitialTicketCredentialsWithPassword

>     KLStatus KLAcquireNewInitialTicketCredentialsWithPassword (
>     		KLPrincipal         inPrincipal,
>     		KLLoginOptions      inLoginOptions,
>     		const char         *inPassword,
>     		krb5_context        inV5Context,
>     		KLBoolean          *outGotV4Credentials,
>     		KLBoolean          *outGotV5Credentials,
>     		CREDENTIALS        *outV4Credentials,
>     		krb5_creds         *outV5Credentials);

> #### Requires:

> The `KLAcquireNewInitialTicketCredentialsWithPassword()` function requires the following:

> - Kerberos Login Library API 2.2 (part of Kerberos for Macintosh 4.5) or later
> - `inPassword` points to a nul-terminated C string;
> - `outV4Credentials` is either NULL or a pointer to a caller-allocated `CREDENTIALS` structure.
> - `inV5Context` is either NULL or a valid `krb5_context` which has been initialized with either `krb5_init_context()` or `krb5_init_secure_context()`. `inV5Context` must be a valid `krb5_context` if `inV5Credentials` is not `NULL`.
> - `outV5Credentials` is either NULL or a pointer to a caller-allocated `krb5_creds` structure.

> #### Effects:

> The `KLAcquireNewInitialTicketCredentialsWithPassword()` function attempts to get a new valid ticket-granting ticket for `inPrincipal`. `KLAcquireNewInitialTicketCredentialsWithPassword()` will display a prompter dialog or prompt the user via the command line. If no UI is available, it will return an error.

> #### Results:

> If `KLAcquireNewInitialTicketCredentialsWithPassword()` returns `klNoErr`, then:

> If `outGotV4Credentials` is non-NULL, it will be filled out with a boolean value indicating whether Kerberos 4 credentials could be obtained by the user.

> If `outV4Credentials` is non-NULL and `outGotV4Credentials` is true, then Kerberos 4 credentials will be placed in `outV4Credentials`.

> If `outGotV5Credentials` is non-NULL, it will be filled out with a boolean value indicating whether Kerberos 5 credentials could be obtained by the user.

> If `outV5Credentials` and `inV5Context` are both non-NULL and `outGotV5Credentials` is true, then Kerberos 5 credentials will be placed in `outV5Credentials`. Note that `inV5Context` is used to allocate the pointers inside the `krb5_creds` structure and must be used to free `outV5Credentials` with `krb5_free_creds_contents()`

> Otherwise, `KLAcquireNewInitialTicketCredentialsWithPassword()` returns one of the following error codes:

> `klParameterErr` | Invalid option passed into function (check your variables).
> `klBadPrincipalErr` | Invalid `KLPrincipal` passed into function.
> `klUserCanceledErr` | The user cancelled the dialog (only with hardware preauth).
> `klMemFullErr` | Out of memory.
> `klRealmDoesNotExistErr` | The specified realm does not exist.
> `klFatalDialogErr` | Dialog failed to load because the resources are corrupt or missing (only with hardware preauth).
> Any Kerberos 5 error | Use `KLHandleError ()` or `KLGetErrorString ()` to report these errors to the user.
> Any Kerberos 4 error | Use `KLHandleError ()` or `KLGetErrorString ()` to report these errors to the user.

> ### KLStoreNewInitialTicketCredentials

>     KLStatus KLStoreNewInitialTicketCredentials (KLPrincipal     inPrincipal,
>                                                  krb5_context    inV5Context,
>                                                  CREDENTIALS    *inV4Credentials,
>                                                  krb5_creds     *inV5Credentials,
>                                                  char          **outCredCacheName);

> #### Requires:

> The `KLStoreNewInitialTicketCredentials()` function requires the following:

> - Kerberos Login Library API 2.3 (part of Kerberos for Macintosh 5.0) or later
> - `inPrincipal` points to a valid principal;
> - `inV4Credentials` is either NULL or points to a valid `CREDENTIALS` structure.
> - `inV5Credentials` is either NULL or points to a valid `krb5_creds` structure.
> - `inV5Context` is either `NULL` or a valid `krb5_context` which has been initialized with either `krb5_init_context()` or `krb5_init_secure_context()`. `inV5Context` must be a valid `krb5_context` if `inV5Credentials` is not `NULL`.

> #### Effects:

> The `KLStoreNewInitialTicketCredentials()` stores the Kerberos 4 and Kerberos 5 tickets in the `inV5Credentials` and `inV5Credentials` structures in a ccache corresponding to `inPrincipal`. If there was already a ccache for `inPrincipal`, the contents of that cache are replaced (ie: not merged with) with the new credentials.

> #### Results:

> If `KLStoreNewInitialTicketCredentials()` returns `klNoErr`, then:

> If `inV4Credentials` is not `NULL`, the ccache for `inPrincipal` will contain the credentials in `inV4Credentials`.

> If `inV5Credentials` is not `NULL`, the ccache for `inPrincipal` will also contain the credentials in `inV5Credentials`.

> - if `outCredCacheName` is not `NULL`, a C string containing the the name of the credentials cache into which new tickets were placed is returned in `*outCredCacheName`. The returned string should be freed using the `KLDisposeString()` function. If `outCredCacheName` is `nil`, nothing is returned.

> Otherwise, `KLStoreNewInitialTicketCredentials()` returns one of the following error codes:

> `klParameterErr` | Invalid option passed into function (check your variables).
> `klBadPrincipalErr` | Invalid `KLPrincipal` passed into function.
> `klMemFullErr` | Out of memory.
> `klRealmDoesNotExistErr` | The specified realm does not exist.
> Any Kerberos 5 error | Use `KLHandleError ()` or `KLGetErrorString ()` to report these errors to the user.
> Any Kerberos 4 error | Use `KLHandleError ()` or `KLGetErrorString ()` to report these errors to the user.

> ### KLVerifyInitialTickets

>     KLStatus KLVerifyInitialTickets (
>             KLPrincipal 	    inPrincipal,
>             KLBoolean           inFailIfNoHostKey,
>             char 	          **outCredCacheName);

> #### Requires:

> The `KLVerifyInitialTickets()` function requires the following:

> - Kerberos Login Library API 2.2 (part of Kerberos for Macintosh 4.5) or later
> - `inPrincipal` points to valid `KLPrincipal` structure or nil.

> #### Effects:

> `KLVerifyInitialTickets()` verifies that the credentials for the principal `inPrincipal` are actually from the machine's local realm using the local machine's keytab (v5) or srvtab (v4). If no host key is available and `inFailIfNoHostKey` is `true`, then `KLVerifyInitialTicketCredentials()` will return an error, otherwise it will return success despite the fact that the tickets were not entirely verified.

> This function is used to prevent the Zanarotti Attack.

> #### Results:

> If `KLVerifyInitialTicketCredentials()` returns `klNoErr`, then:

> - The credentials were successfully verified or `inFailIfNoHostKey` is false.
> - if `outCredCacheName` is not `nil`, a C string containing the the name of the credentials cache which was verified is returned in `*outCredCacheName`. The returned string should be freed using the `KLDisposeString()` function. If `outCredCacheName` is `nil`, nothing is returned.

> Otherwise, `KLVerifyInitialTicketCredentials()` returns one of the following error codes:

> `klParameterErr` | Invalid option passed into function (check your variables).
> `klBadPrincipalErr` | Invalid `KLPrincipal` passed into function.
> `klUserCanceledErr` | The user cancelled the dialog (only with hardware preauth).
> `klMemFullErr` | Out of memory.
> `klRealmDoesNotExistErr` | The specified realm does not exist.
> Any Kerberos 5 error | Use `KLHandleError ()` or `KLGetErrorString ()` to report these errors to the user.
> Any Kerberos 4 error | Use `KLHandleError ()` or `KLGetErrorString ()` to report these errors to the user.

> ### KLVerifyInitialTicketCredentials

>     KLStatus KLVerifyInitialTicketCredentials (
>             CREDENTIALS        *inV4Credentials,
>             krb5_creds 	       *inV5Credentials,
>             KLBoolean           inFailIfNoHostKey);

> #### Requires:

> The `KLVerifyInitialTicketCredentials()` function requires the following:

> - Kerberos Login Library API 2.2 (part of Kerberos for Macintosh 4.5) or later
> - `inV4Credentials` points to valid `CREDENTIALS` structure or nil.
> - `inV5Credentials` points to valid `krb5_creds` structure or nil.

> #### Effects:

> `KLVerifyInitialTicketCredentials()` verifies that `inV4Credentials` and/or `inV5Credentials` are actually from the machine's local realm using the local machine's keytab (v5) or srvtab (v4). If no host key is available and `inFailIfNoHostKey` is `true`, then `KLVerifyInitialTicketCredentials()` will return an error, otherwise it will return success despite the fact that the tickets were not entirely verified.

> This function is used to prevent the Zanarotti Attack.

> #### Results:

> If `KLVerifyInitialTicketCredentials()` returns `klNoErr`, then:

> - The credentials were successfully verified or `inFailIfNoHostKey` is false.

> Otherwise, `KLVerifyInitialTicketCredentials()` returns one of the following error codes:

> `klParameterErr` | Invalid option passed into function (check your variables).
> `klUserCanceledErr` | The user cancelled the dialog (only with hardware preauth).
> `klMemFullErr` | Out of memory.
> `klRealmDoesNotExistErr` | The specified realm does not exist.
> Any Kerberos 5 error | Use `KLHandleError ()` or `KLGetErrorString ()` to report these errors to the user.
> Any Kerberos 4 error | Use `KLHandleError ()` or `KLGetErrorString ()` to report these errors to the user.

> ### KLAcquireNewInitialTicketsWithKeytab

>     KLStatus KLAcquireNewInitialTicketsWithKeytab (
>          KLPrincipal         inPrincipal,
>          KLLoginOptions      inLoginOptions,
>          const char         *inKeytabName,
>          char              **outCredCacheName);

> #### Requires:

> The `KLAcquireNewInitialTicketsWithKeytab()` function requires the following:

> - Kerberos Login Library API 2.2 (part of Kerberos for Macintosh 4.5) or later
> - `inKeytabName` points to a nul-terminated C string;

> #### Effects:

> `KLAcquireNewInitialTicketsWithKeytab()` will use the keytab in `inKeytab` to attempt to acquire the tickets with the properties specified by `inLoginOptions`. If `inLoginOptions` is `nil`, the defaults (as specified by `KLSetDefaultLoginOption```` ()`) are used.

> `KLAcquireNewInitialTicketsWithKeytab()` never changes the system default cache.

> #### Results:

> If `KLAcquireNewInitialTicketsWithKeytab()` returns `klNoErr`, then:

> - new tickets for the desired principal are available in the cache collection.
> - if `outCredCacheName` is not `NULL`, a C string containing the the name of the credentials cache into which new tickets were placed is returned in `*outCredCacheName`. The returned string should be freed using the `KLDisposeString()` function. If `outCredCacheName` is `nil`, nothing is returned.

> Otherwise, `KLAcquireNewInitialTicketsWithKeytab()` returns one of the following error codes:

> `klParameterErr` | Invalid option passed into function (check your variables).
> `klBadPrincipalErr` | Invalid `KLPrincipal` passed into function.
> `klUserCanceledErr` | The user cancelled the dialog (only with hardware preauth).
> `klMemFullErr` | Out of memory.
> `klRealmDoesNotExistErr` | The specified realm does not exist.
> Any Kerberos 5 error | Use `KLHandleError ()` or `KLGetErrorString()` to report these errors to the user.
> Any Kerberos 4 error | Use `KLHandleError ()` or `KLGetErrorString ()` to report these errors to the user.

> ### KLRenewInitialTickets

>     KLStatus KLRenewInitialTickets (
>          KLPrincipal         inPrincipal,
>          KLLoginOptions      inLoginOptions,
>          KLPrincipal        *outPrincipal,
>          char              **outCredCacheName);

> #### Requires:

> The `KLRenewInitialTickets()` function requires the following:

> - Kerberos Login Library API 2.2 (part of Kerberos for Macintosh 4.5) or later
> - `inPrincipal` points to a valid `KLPrincipal` for which there are renewable tickets in the credentials cache;

> #### Effects:

> `KLRenewInitialTickets()` attemps to renew tickets for principal `inPrincipal` with the properties specified by `inLoginOptions`. If `inLoginOptions` is `NULL`, the defaults (as specified by `KLSetDefaultLoginOption()`) are used.

> `KLRenewInitialTickets()` never changes the system default cache.

> #### Results:

> If `KLRenewInitialTickets()` returns `klNoErr`, then:

> - Renewed tickets for the desired principal are available in the cache collection.
> - If `outPrincipal` is not `NULL`, the name of the principal for which tickets are obtained is returned in `outPrincipal`. The returned principal should be freed using the `KLDisposePrincipal()` function. If `outPrincipal` is `NULL`, nothing is returned.
> - If `outCredCacheName` is not `NULL`, a C string containing the the name of the credentials cache into which new tickets were placed is returned in `*outCredCacheName`. The returned string should be freed using the `KLDisposeString()` function. If `outCredCacheName` is `NULL`, nothing is returned.

> Otherwise, `KLRenewInitialTickets()` returns one of the following error codes:

> `klParameterErr` | Invalid option passed into function (check your variables).
> `klBadPrincipalErr` | Invalid `KLPrincipal` passed into function.
> `klUserCanceledErr` | The user cancelled the dialog (only with hardware preauth).
> `klMemFullErr` | Out of memory.
> `klRealmDoesNotExistErr` | The specified realm does not exist.
> Any Kerberos 5 error | Use `KLHandleError ()` or `KLGetErrorString ()` to report these errors to the user.
> Any Kerberos 4 error | Use `KLHandleError ()` or `KLGetErrorString ()` to report these errors to the user.

> ### KLValidateInitialTickets

>     KLStatus KLValidateInitialTickets (
>          KLPrincipal         inPrincipal,
>          KLLoginOptions      inLoginOptions,
>          char              **outCredCacheName);

> #### Requires:

> The `KLValidateInitialTickets()` function requires the following:

> - Kerberos Login Library API 2.2 (part of Kerberos for Macintosh 4.5) or later
> - `inPrincipal` points to a valid `KLPrincipal` for which there are postdated tickets in the credentials cache;

> #### Effects:

> `KLValidateInitialTickets()` attempts to validate tickets for principal `inPrincipals` with the properties specified by `inLoginOptions`. If `inLoginOptions` is `nil`, the defaults (as specified by `KLSetDefaultLoginOption```` ()`) are used. Tickets which were acquired post-dated must be validated before they can be used.

> `KLValidateInitialTickets()` never changes the system default cache.

> #### Results:

> If `KLValidateInitialTickets()` returns `klNoErr`, then:

> - validated tickets for the desired principal are available in the cache collection.
> - if `outCredCacheName` is not `NULL`, a C string containing the the name of the credentials cache into which new tickets were placed is returned in `*outCredCacheName`. The returned string should be freed using the `KLDisposeString()` function. If `outCredCacheName` is `nil`, nothing is returned.

> Otherwise, `KLValidateInitialTickets()` returns one of the following error codes:

> `klParameterErr` | Invalid option passed into function (check your variables).
> `klBadPrincipalErr` | Invalid `KLPrincipal` passed into function.
> `klUserCanceledErr` | The user cancelled the dialog (only with hardware preauth).
> `klMemFullErr` | Out of memory.
> `klRealmDoesNotExistErr` | The specified realm does not exist.
> Any Kerberos 5 error | Use `KLHandleError ()` or `KLGetErrorString ()` to report these errors to the user.

> ### KLLastChangedTime

>     KLStatus KLLastChangedTime (
>          KLTime        *outLastChangedTime);

> #### Requires:

> The `KLLastChangedTime ()` function requires the following:

> - Kerberos Login Library API 2.1 (part of Kerberos for Macintosh 3.5) or later

> #### Effects:

> `KLLastChangedTime()` returns the last time the state or validity of the cache collection changed in seconds since GMT midnight January 1, 1970.

> `KLLastChangedTime()` should be used by applications which wish to frequently call `KLCacheHasValidTickets()`, `KLTicketStartTime()` or `KLExpirationTime()`. The time returned by `KLLastChangedTime()` will change if and only if the validity, start or expiration times of the cache collection changes. Your application can check this time to determine when you should call one of `KLCacheHasValidTickets()`, `KLTicketStartTime()` or `KLExpirationTime()`.

> `KLCacheHasValidTickets()`, `KLTicketStartTime()` and `KLExpirationTime()` are `O(n)` where `n` is the number of caches in the cache collection. Calling them frequently may negatively impact the performance of your application. `KLLastChangedTime()` is `O(1)`, so your application can safely call it as often as every 1/60 of a second.

> If an error code is returned, `outLastChangedTime` is unchanged.

> #### Results:

> If no errors occur, `klNoErr` is returned. Other possible errors are:

> `klMemFullErr` | Out of memory.
> `klPreferencesReadErr` | The preferences file is inaccessible or corrupt.

> ### KLCacheHasValidTickets

>     KLStatus KLCacheHasValidTickets (
>     	KLPrincipal         inPrincipal,
>          KLKerberosVersion   inKerberosVersion,
>          KLBoolean          *outFoundValidTickets,
>          KLPrincipal        *outPrincipal,
>          char              **outCredCacheName);

> #### Requires:

> The `KLCacheHasValidTickets()` function requires the following:

> - `outFoundValidTickets` is a valid pointer (otherwise `klParameterErr` is returned).

> #### Effects:

> `KLCacheHasValidTickets()` looks in the cache collection to see if it contains valid ticket-granting tickets.

> If `inPrincipal` is not `nil` (a principal is specified), `KLCacheHasValidTickets()` returns in `outFoundValidTickets` whether there are valid tickets of the version specified by ``inKerberosVersion```` in the cache collection for that principal. If `outPrincipal` is not `nil`, the principal is returned in `outPrincipal`. If `outCredCacheName` is not `nil`, the name of the credentials cache corresponding to that principal is returned in `outCredCacheName`.

> If `inPrincipal` is `nil` (no principal is specified), `KLCacheHasValidTickets()` returns in `outFoundValidTickets` whether or not any valid tickets of the version specified by ``inKerberosVersion`` are in the system default cache. If `outPrincipal` is not `nil`, the principal of the system default credentials cache is returned in `outPrincipal`. If `outCredCacheName` is not `nil`, the name of the system default credentials cache is returned in `outCredCacheName`.

> If `outPrincipal` is nil, nothing is returned in it.

> If `outCredCacheName` is `nil`, nothing is returned in it.

> ``inKerberosVersion`` is `kerberosVersion_All`: If and only if valid tickets of all the versions of Kerberos supported by `inPrincipal`'s realm (or the realm of the system default cache's principal if `inPrincipal == nil`) exist for `inPrincipal`, then `outFoundValidTickets` is filled out as `true`.

> ``inKerberosVersion`` is `kerberosVersion_Any:` If and only if valid tickets of any version of Kerberos supported by `inPrincipal`'s realm (or the realm of the system default cache's principal if `inPrincipal == nil`) exist for `inPrincipal`, then `outFoundValidTickets` is filled out as `true`.

> ``inKerberosVersion`` is one or more specific versions of Kerberos 'OR'ed together as a bitfield`:` if and only if valid tickets of the specified version(s) of Kerberos exist for `inPrincipal` (the system default cache's principal if `inPrincipal == nil`), then `outFoundValidTickets` is filled out as `true`.

> If no valid tickets are found of the version specified by ``inKerberosVersion`` (either no tickets for the principal exist, tickets do not exist for all the requested Kerberos versions, a ticket is expired, or a ticket is for an IP address different from the current one), `outFoundValidTickets` is filled out as `false````` and one of `klNoCredentialsErr`, `klCredentialsExpiredErr`, or `klCredentialsBadAddressErr` is returned.

> If an error code is returned, `outPrincipal` and `outCredCacheName` are unchanged. For compatibility, `outFoundValidTickets` is set to false.

> #### Results:

> If no errors while searching the cache collection occurs, `klNoErr` is returned. Other possible errors are:

> `klParameterErr` | Invalid option passed into function (check your variables).
> `klBadPrincipalErr` | Invalid `KLPrincipal` passed into function.
> `klInvalidVersionErr` | Invalid Kerberos version.
> `klMemFullErr` | Out of memory.
> `klPreferencesReadErr` | The preferences file is inaccessible or corrupt.
> `klV5InitializationFailedErr` | Failed to initialize a krb5 context.
> `klPrincipalDoesNotExistErr` | The `KLPrincipal` passed in does not correspond to any cache in the cache collection.
> `klSystemDefaultDoesNotExistErr` | There is no system default cache (the cache collection is empty).
> `klCredentialsExpiredErr` | The credentials for the specified `KLPrincipal` (or system default) are expired.
> `klCredentialsBadAddressErr` | The credentials for the specified `KLPrincipal` (or system default) contain a different IP address from the current one.
> `klNoCredentialsErr` | There are no credentials for the specified `KLPrincipal` (or no system default).
> `klRealmDoesNotExistErr` | The specified realm does not exist.

> ### KLTicketStartTime

>     KLStatus KLTicketStartTime (
>     	KLPrincipal        inPrincipal,
>          KLKerberosVersion  inKerberosVersion,
>          KLTime            *outStartTime);

> #### Requires:

> The `KLTicketStartTime()` function requires the following:

> - Kerberos Login Library API 2.1 (part of Kerberos for Macintosh 3.5) or later

> #### Effects:

> `KLTicketStartTime()` looks in the cache collection to return the maximum absolute start time of any valid ticket-granting tickets of the Kerberos version specified by ``inKerberosVersion``. If `KLCacheHasValidTickets()` would have returned false for the same `inPrincipal` and ``inKerberosVersion``, `KLTicketStartTime``()` returns `klNoCredentialsErr` or `klCredentialsExpiredErr`.

> If a principal is specified by `inPrincipal`, `KLTicketStartTime()` returns the maximum absolute start time for that principal.

> If no is specified by `inPrincipal`, `KLTicketStartTime()` returns the maximum absolute start time for the tickets in the system default cache (if one exists).

> If valid ticket-granting tickets exist, `outStartTime` is filled out with the absolute time the ticket-granting ticket first became valid in seconds since GMT midnight January 1, 1970.

> If tickets for multiple versions of Kerberos exist for the principal and ``inKerberosVersion`` is `kerberosVersion_All` or the aforementioned versions of Kerberos 'OR'ed together as a bitfield, the greater of the times for the two ticket-granting tickets is returned. If ``inKerberosVersion`` is `kerberosVersion_Any`, the minimum of the two expiration times is returned. Otherwise, the time for the specified version is returned.

> If an error occurs, `outStartTime` is unchanged.

> #### Results:

> If no errors while searching the cache collection occurs, `klNoErr` is returned. Other possible errors are:

> `klParameterErr` | Invalid option passed into function (check your variables).
> `klBadPrincipalErr` | Invalid `KLPrincipal` passed into function.
> `klInvalidVersionErr` | Invalid Kerberos version.
> `klMemFullErr` | Out of memory.
> `klPrincipalDoesNotExistErr` | The `KLPrincipal` passed in does not correspond to any cache in the cache collection.
> `klSystemDefaultDoesNotExistErr` | There is no system default cache (the cache collection is empty).
> `klNoCredentialsErr` | The credentials for the specified `KLPrincipal` and `inKerberosVersion` do not exist.
> `klCredentialsExpiredErr` | The credentials for the specified `KLPrincipal` (or system default) are no longer valid.
> `klCredentialsBadAddressErr` | The credentials for the specified `KLPrincipal` (or system default) contain a different IP address from the current one.
> `klRealmDoesNotExistErr` | The specified realm does not exist.

> ### KLTicketExpirationTime

>     KLStatus KLTicketExpirationTime (
>     	KLPrincipal        inPrincipal,
>          KLKerberosVersion  inKerberosVersion,
>          KLTime            *outExpirationTime);

> #### Requires:

> The `KLTicketExpirationTime()` function requires the following:

> - `inPrincipal` is either NULL or a valid `KLPrincipal`.

> #### Effects:

> `KLTicketExpirationTime()` looks in the cache collection to return the minimum absolute expiration time of any valid ticket-granting tickets of the Kerberos version specified by ``inKerberosVersion``. If `KLCacheHasValidTickets()` would have returned false for the same `inPrincipal` and ``inKerberosVersion``, `KLTicketExpirationTime()` returns `klNoCredentialsErr` or `klCredentialsExpiredErr`.

> If a principal is specified by `inPrincipal`, `KLTicketExpirationTime()` returns the minimum absolute expiration time for that principal.

> If no is specified by `inPrincipal`, `KLTicketExpirationTime()` returns the minimum absolute expiration time for the tickets in the system default cache (if one exists).

> If valid ticket-granting tickets exist, `outExpirationTime` is filled out with the absolute time the ticket-granting ticket is valid until (as opposed to the relative length of time the ticket will remain valid) in seconds since GMT midnight January 1, 1970.

> If tickets for multiple versions of Kerberos exist for the principal and ``inKerberosVersion`` is `kerberosVersion_All` or the aforementioned versions of Kerberos 'OR'ed together as a bitfield, the minimum of the times for the two ticket-granting tickets is returned. If ``inKerberosVersion`` is `kerberosVersion_Any`, the maximum of the ticket times is returned. Otherwise, the time for the specified version is returned.

> If an error occurs, `outExpirationTime` is unchanged.

> #### Results:

> If no errors while searching the cache collection occurs, `klNoErr` is returned. Other possible errors are:

> `klParameterErr` | Invalid option passed into function (check your variables).
> `klBadPrincipalErr` | Invalid `KLPrincipal` passed into function.
> `klInvalidVersionErr` | Invalid Kerberos version.
> `klMemFullErr` | Out of memory.
> `klPrincipalDoesNotExistErr` | The `KLPrincipal` passed in does not correspond to any cache in the cache collection.
> `klSystemDefaultDoesNotExistErr` | There is no system default cache (the cache collection is empty).
> `klNoCredentialsErr` | The credentials for the specified `KLPrincipal` and `inKerberosVersion` do not exist.
> `klCredentialsExpiredErr` | The credentials for the specified `KLPrincipal` (or system default) are no longer valid.
> `klCredentialsBadAddressErr` | The credentials for the specified `KLPrincipal` (or system default) contain a different IP address from the current one.
> `klRealmDoesNotExistErr` | The specified realm does not exist.

> ### KLSetSystemDefaultCache

>     KLStatus KLSetSystemDefaultCache (
>     	KLPrincipal inPrincipal);

> #### Requires:

> The `KLSetSystemDefaultCache()` function requires the following:

> - `inPrincipal` is a valid `KLPrincipal`.

> #### Effects:

> `KLSetSystemDefaultCache()` sets the system (global) default credentials cache to be the credentials cache which corresponds to the principal specified in `inPrincipal`, that is, to be the credentials cache that an application/service/context will use by default after the first time it is launched/created (in Kerberos v4, the application default cache will be set to the system default cache when the application is first launched; in v5 a context's default cache will be set the system default cache when the context is first created).

> If both Kerberos v4 and Kerberos v5 are available for the realm of the principal, the system default is set to the credentials cache corresponding to the specified principal for both v4 and v5.

> If only one of Kerberos v4 and Kerberos v5 is available for the realm of the principal, the appropriate version's system default is set to the credentials cache corresponding to the specified principal.

> #### Results:

> If there is a credentials cache corresponding to the specified principal and that credentials cache is set successfully as the system default, `klNoErr` is returned. Other possible errors are:

> `klBadPrincipalErr` | Invalid `KLPrincipal` passed into function.
> `klMemFullErr` | Out of memory.
> `klPreferencesReadErr` | The preferences file is inaccessible or corrupt.
> `klV5InitializationFailedErr` | Failed to initialize a krb5 context.
> `klPrincipalDoesNotExistErr` | The `KLPrincipal` passed in does not correspond to any cache in the cache collection.
> `klRealmDoesNotExistErr` | The specified realm does not exist.

> ### KLHandleError

>     KLStatus KLHandleError (
>     	KLStatus           inError,
>     	KLDialogIdentifier inDialogIdentifier,
>     	KLBoolean          inShowAlert);

> #### Effects:

> The `KLHandleError()` function handles errors that occur while attempting to acquire tickets or change passwords. After you call `KLLoginDialogHandleEvents()` or `KLChangePasswordDialogHandleEvents()` to process events in a dialog, you use the information from the dialog to acquire tickets or change password for the user. If an error occurs while you are acquiring the tickets or changing the password, you must call `KLHandleError()` with an appropriate error code. This will ensure that the Login Library will behave correctly on subsequent calls -- for example, if the user typed an incorrect password, the password will be selected on the next call to `KLLoginDialogHandleEvents()` or `KLChangePasswordDialogHandleEvents()`.

> In general, you should call `KLHandleError()` with `inShowAlert` set to `true`, in which case Login Library will display an appropriate error message to the user. However, if for some reason you need to provide different user feedback, you should pass `false` in `inShowAlert`. In either case, you must call `KLHandleError()` with an appropriate error code.

> `KLHandleError()` can distinguish which of the two dialogs it was called from by using the `inDialogIdentifier` parameter (see the Dialog Identifier Constants above) .

> Valid input values for `inError` are any error code returned by any Login Library function. Usually you only want to pass the error codes from `KLAcquire*TicketsWithPassword()` and `KLChangePasswordWithPasswords().`

> #### Results:

> `KLHandleError()` returns `klNoErr` if no error occurs, or one of the following error codes:

> `klParameterErr` | Invalid option passed into function (check your error code).
> `klMemFullErr` | Out of memory.

> ### KLGetErrorString

>     KLStatus KLGetErrorString (
>     	KLStatus   inError,
>     	char     **outString);

> #### Requires:

> The `KLHandleError()` function requires that:

> - `inError` be an error returned from a Kerberos Login Library function.

> #### Effects:

> The `KLGetErrorString ()` function takes a Kerberos Login Library error code and returns a C string containing a user-presentable message explaining the error. This is the same error message as would have been presented by `KLHandleError ()`. You will need to dispose of the string with `KLDisposeString ()` after you are through using it.

> #### Results:

> `KLGetErrorString()` returns `klNoErr` if no error occurs, or one of the following error codes:

> `klParameterErr` | Invalid option passed into function (check your error code).
> `klMemFullErr` | Out of memory.

> ### KLCancelAllDialogs

>     KLStatus KLCancelAllDialogs (void);

> #### Effects:

> The `KLCancelAllDialogs()` function cancels all the login library dialogs on the screen when the function is called. This function should be called from an application event handler when a quit AppleEvent comes in. Note that if a Kerberos operation is in progress, the dialogs will cancel when the operation completes.

> You should not expect the dialogs to be gone when `KLCancelAllDialogs()` returns to the caller. You should instead wait until `KLAcquireInitialTickets()` or the relevant KClient call that popped up the dialog returns before exitting.

> #### Results:

> `KLCancelAllDialogs()` returns `klNoErr` if no error occurs, or one of the following error codes:

> `klDialogDoesNotExist` | No dialogs to cancel.

> ## Low-Level Password Dialog Functions

> ### KLChangePasswordWithPasswords

>     KLStatus KLChangePasswordWithPasswords (
>     	KLPrincipal inPrincipal,
>          const char *inOldPassword,
>          const char *inNewPassword);

> #### Requires:

> The `KLChangePasswordWithPasswords()` function requires the following:

> - `inPrincipal` is a valid `KLPrincipal`.
> - `inOldPassword` is a valid C string.
> - `inNewPassword` is a valid C string.

> #### Effects:

> The `KLChangePasswordWithPasswords()` function attempts to change the Kerberos password for the principal specified by `inPrincipal`. `KLChangePasswordWithPasswords()` may display user interface if your site supports hardward preauth. If it is unable to display a dialog or prompt via the command line, it will return an error.

> #### Results:

> If `KLChangePasswordWithPasswords()` returns `klNoErr`, then the password for the desired principal has been changed.

> Otherwise, the principal's passwords unchanged and `KLChangePasswordWithPasswords()` returns one of the following error codes:

> `klBadPrincipalErr` | Invalid `KLPrincipal` passed into function.
> `klBadPasswordErr` | Password incorrect or `nil`.
> `klMemFullErr` | Out of memory.
> `klPreferencesReadErr` | The preferences file is inaccessible or corrupt.
> `klPasswordChangeFailedErr` | Change password operation failed.
> Any Kerberos 5 error | Use `KLHandleError ()` or `KLGetErrorString ()` to report these errors to the user.
> Any Kerberos 4 error | Use `KLHandleError ()` or `KLGetErrorString ()` to report these errors to the user.

> ## Application-Defined Functions

> ### KerberosLoginIdleCallback

>     void KerberosLoginIdleCallback (
>     	      KLRefCon     inAppData);

> #### Requires:

> - Mac OS 10.1 or greater (KfM 4.0 or greater)
> - Mach-O object formation (installing a PEF KerberosLoginIdleCallback will cause a crash)

> A KerberosLoginIdleCallback function is guaranteed that

> - `inAppData` is the application data, as set by the last call to `KLSetIdleCallback()`.

> #### Effects:

> A KerberosLoginIdleCallback function is allowed to do anything that makes sense for the application to do. Most importantly, it can call `WaitNextEvent()` or receive Carbon/Cocoa events. It can cancel the dialogs by calling `KLCancelAllDialogs ()` if it receives a quit event.

> A KerberosLoginIdleCallback function should not assume anything about the current resource file; if it needs to use resources, it must set the current resource file and restore it before returning.

> A KerberosLoginIdleCallback function should not block on resources in the callback. This will hurt performance and possibly have confusing side effects. For example, verify that there is an event in the queue before calling `WaitNextEvent()`.

> A Kerberos Login event filter function must not manipulate the controlling terminal (ie: stdin, stdout and stderr). The Kerberos Login library may be in the middle of reading a password from the controlling terminal.

> ## Application Configuration Functions

> ### KLSetIdleCallback

>     KLStatus KLSetIdleCallback (
>     	const KLIdleCallback inIdleCallback,
>     	const KLRefCon       inIdleRefCon);

> #### Requires:

> - Mac OS X 10.1 or later (KfM 4.0 or later)
> - the idling function passed in `inIdleCallback` is a Mach-O function pointer to a valid KerberosLoginIdleCallback function (or `NULL`).

> #### Effects:

> The `KLSetIdleCallback()` function sets the idling callback which is called while your application waits for the Login dialog. If you wish to cancel the login dialogs from your application, you should call `KLCancelAllDialogs()` from the callback function.

> The meanings of the fields are

> - `inIdleCallback` is used as the idle function whenever your application is waiting for KerberosLoginServer (the application which presents the login dialog. Pass in NULL to remove the idle callback.
> - `inIdleRefCon` is a value passed to the subsequent calls to the idle callback; it is not interpreted by the Login Library and its use is entirely up to the application

> #### Results:

> `KLSetIdleCallback()` returns `klNoErr` if no error occurs, or one of the following error codes:

> `klParameterErr` | Invalid option passed into function (check your variables).
> `klMemFullErr` | Out of memory.

> ### KLGetIdleCallback

>     KLStatus KLGetIdleCallback (
>     	KLIdleCallback* outIdleCallback,
>     	KLRefCon*       outIdleRefCon);

> #### Requires:

> - Mac OS X 10.1 or later (KfM 4.0 or later)
> - `outIdleCallback` and `outIdleRefCon` are pointers to valid data or NULL.

> #### Effects:

> The `KLGetIdleCallback()` function returns the idling callback which will be called while your application waits for the Login dialog.

> The meanings of the fields are

> - `outIdleCallback` is used as the idle function whenever your application is waiting for KerberosLoginServer (the application which presents the login dialog. A value of NULL indicates no idle callback is installed.
> - `outIdleRefCon` is a value passed to the subsequent calls to the idle callback; it is not interpreted by the Login Library and its use is entirely up to the application

> #### Results:

> `KLGetIdleCallback()` returns `klNoErr` if no error occurs, or one of the following error codes:

> `klParameterErr` | Invalid option passed into function (check your variables).
> `klMemFullErr` | Out of memory.

> ## Library Configuration Functions

> Library configuration consists of a set of options and their values; all options are global. The options and their types and allowed values are:

> - `loginOption_LoginName`
>   Type: char *
>   This option determines what name is used in the username field in the login dialog by default. Pass in a C string with `ioBufferSize` set to the length of the string (not including the NUL at the end). When getting this option you will need to NUL-terminate the buffer after calling KLGetDefaultLoginOption.
> - `loginOption_RememberPrincipal`
>   Type: KLBoolean
>   Range: 0, 1
>   This option determines whether principal (username, instance, and selected realm) will be remembered between successful logins. The remembered principal can be overridden by an application by passing the username, etc. to `KLLoginDialogBegin()`, `KLAcquireTickets()`, or `KLAcquireNewTickets()`
> - `loginOption_RememberExtras`
>   Type: KLBoolean
>   Range: 0, 1
>   This option determines whether "extra" settings, such as the values of the Forwardable Tickets checkbox and Ticket Lifetime slider, will be remembered between successful logins.
> - `loginOption_MinimalTicketLifetime`
>   Type: KLLifetime
>   Range: 0 .. 2^32 - 1
>   This option determines the left end of the ticket lifetime slider range in seconds.
> - `loginOption_MaximalTicketLifetime`
>   Type: KLLifetime
>   Range: 0 .. 2^32 - 1
>   This option determines the right end of the ticket lifetime slider range in seconds.
> - `loginOption_DefaultTicketLifetime`
>   Type: KLLifetime
>   Range: minimal ticket lifetime .. maximal ticket lifetime
>   This option determines the default value of the ticket lifetime slider in seconds.
> - `loginOption_LongTicketLifetimeDisplay`
>   Type: KLBoolean
>   Range: 0, 1
>   This option determines whether the ticket lifetime caption displays time in long format (xx hours, yy minutes, zz seconds) or short format (xx:yy:zz). Value of 0 means short lifetime display, value of 1 means long lifetime display
> - `loginOption_MinimalRenewableLifetime`
>   Type: KLLifetime
>   Range: 0 .. 2^32 - 1
>   This option determines the left end of the renewable lifetime slider range in seconds.
> - `loginOption_MaximalRenewableLifetime`
>   Type: KLLifetime
>   Range: 0 .. 2^32 - 1
>   This option determines the right end of the renewable lifetime slider range in seconds.
> - `loginOption_DefaultRenewableLifetime`
>   Type: KLLifetime
>   Range: minimal renewable lifetime .. maximal renewable lifetime
>   This option determines the default value of the renewable lifetime slider in seconds.
> - `loginOption_DefaultRenewableTicket`
>   Type: KLBoolean
>   Range: 0, 1
>   This option determines the default value of the renewable ticket checkbox.
> - `loginOption_DefaultForwardableTicket`
>   Type: KLBoolean
>   Range: 0, 1
>   This option determines the default value of the forwardable ticket checkbox.
> - `loginOption_DefaultProxiableTicket`
>   Type: KLBoolean
>   Range: 0, 1
>   This option determines the default value of the proxiable ticket checkbox.
> - `loginOption_DefaultAddresslessTicket`
>   Type: KLBoolean
>   Range: 0, 1
>   This option determines the default value of the addressless ticket checkbox.

> ### KLGetDefaultLoginOption

>     KLStatus KLGetLoginOption (
>     	KLDefaultLoginOption   inOption,
>     	void                  *ioBuffer,
>     	KLSize                *ioBufferSize);

> #### Requires:

> - `ioBuffer` points to a buffer with at least `*ioBufferSize` bytes of storage, or `ioBuffer` is `nil`.

> #### Effects:

> Returns the size and the value of the specified library option.

> If `ioBuffer` is not `nil`, `inOption` is a valid option, and `ioBufferSize` is sufficient to hold the value of the option (1 byte for KLBoolean values, 4 bytes for KLLifetime or KLLoginMode values), the value is put in `ioBuffer` and its actual size is returned in `ioBufferSize`.

> If `ioBuffer` is `nil` and `inOption` is a valid option, the size of the option is put returned in `ioBufferSize`.

> If `inOption` is not a valid option, or `ioBufferSize` is too small, `ioBuffer` and `ioBufferSize` are unchanged.

> #### Results:

> If successful, klNoErr is returned. Otherwise, one of the following error codes is returned instead:

> `klParameterErr` | Invalid option passed into function (check your variables).
> `klMemFullErr` | Out of memory.
> `klPreferencesReadErr` | The preferences file is inaccessible or corrupt.
> `klPreferencesWriteErr` | The preferences file is locked.
> `klBufferTooSmallErr` | The buffer passed in is too small to hold the login option.
> `klInvalidOptionErr` | The requested login option does not exist.

> ### KLSetDefaultLoginOption

>     KLStatus KLSetLoginOption (
>     	KLDefaultLoginOption  inOption,
>     	void                 *inBuffer,
>     	KLSize                inBufferSize);

> #### Requires:

> - `ioBuffer` points to a buffer with at least `inBufferSize` bytes of storage

> #### Effects:

> If `inOption` is a valid option, `inBufferSize` is the correct size for `inOption`, and value in `inBuffer` is in the valid range of `inOption`, then value of `inOption` is set to the value in `inBuffer`. Otherwise, no option values are changed.

> #### Results:

> If successful, klNoErr is returned. Otherwise, one of the following error codes is returned instead:

> `klParameterErr` | Invalid option passed into function (check your variables).
> `klMemFullErr` | Out of memory.
> `klPreferencesReadErr` | The preferences file is inaccessible or corrupt.
> `klPreferencesWriteErr` | The preferences file is locked.
> `klBufferTooSmallErr` | The buffer passed in is too small to hold the login option.
> `klBufferTooLargeErr` | The buffer passed in is too large to refer to this login option.
> `klInvalidOptionErr` | The requested login option does not exist.
> `klBadOptionValueErr` | The login option you have specified is invalid.

> ## Realms Configuration Functions

> The functions below manipulate the list of realms displayed by the Login Library in pop-up menu of the login dialog. This list may be a subset of the realms listed in the Kerberos configuration file. The "default realm" is the realm that is selected in the pop-up menu by default.

> ### KLFindKerberosRealmByName

>     KLStatus KLFindKerberosRealmByName (
>     	char      *inRealmName,
>     	KLIndex   *outIndex );

> #### Requires:

> - `inRealmName` is a null-terminated C string

> #### Effects:

> Finds the realm with the name inRealmName in the realm list and returns the index.

> Realm indices are 0-based.

> #### Results:

> If successful, klNoErr is returned. Otherwise, one of the following error codes is returned instead:

> `klParameterErr` | Invalid option passed into function (check your variables).
> `klMemFullErr` | Out of memory.
> `klPreferencesReadErr` | The preferences file is inaccessible or corrupt.
> `klNoRealmsErr` | The favorite realms list is empty.
> `klRealmDoesNotExistErr` | The specified realm does not exist.

> ### KLGetKerberosRealm

>     KLStatus KLGetKerberosRealm (
>     	KLIndex   inIndex,
>     	char    **outRealmName);

> #### Effects:

> Reads the name of the realm with index `inIndex` in the realm list and returns it as a C string in `outRealmName`. The returned string should be freed using the `KLDisposeString()` function.

> Realm indices are 0-based.

> #### Results:

> If successful, klNoErr is returned. Otherwise, one of the following error codes is returned instead:

> `klParameterErr` | Invalid option passed into function (check your variables).
> `klMemFullErr` | Out of memory.
> `klPreferencesReadErr` | The preferences file is inaccessible or corrupt.
> `klNoRealmsErr` | The favorite realms list is empty.
> `klRealmDoesNotExistErr` | The specified realm does not exist.

> ### KLSetKerberosRealm

>     KLStatus KLSetKerberosRealm (
>     	KLIndex     inIndex,
>     	const char *inRealmName);

> #### Requires:

> - `inRealmName` is a nul-terminated C string

> #### Effects:

> Sets the name of the realm with index `inIndex` in the realm list to the name specified in `inRealmName`. Realm indices are 0-based.

> Note: If another realm with the name `inRealmName` is already in the list, `KLSetKerberosRealm` removes the old entry before setting the entry at `inIndex`. Because the old entry may be before `inIndex` in the list, the realm name may actually be placed at a different index (one less than `inIndex`). As a result, you should either make sure you are setting only one realm of each name, or you should not use `inIndex` after calling `KLSetKerberosRealm`.

> #### Results:

> If successful, klNoErr is returned. Otherwise, one of the following error codes is returned instead:

> `klParameterErr` | Invalid option passed into function (check your variables).
> `klMemFullErr` | Out of memory.
> `klPreferencesReadErr` | The preferences file is inaccessible or corrupt.
> `klPreferencesWriteErr` | The preferences file is locked.
> `klNoRealmsErr` | The favorite realms list is empty.
> `klRealmDoesNotExistErr` | The specified realm does not exist.

> ### KLRemoveKerberosRealm

>     KLStatus KLRemoveKerberosRealm (
>     	KLIndex inIndex);

> #### Effects:

> Removes the realm specified by the index `inIndex` from the realm list. Realm indices are 0-based.

> Note: Kerberos Login Library does not support removing the Kerberos default realm (ie: the `default_realm` in the `lib_defaults` section of the Kerberos Preferences). If you attempt to remove the Kerberos default realm from the realm list, it will be added back to the beginning of the realm list. If you want to remove this realm, please change the Kerberos default realm.

> #### Results:

> If successful, klNoErr is returned. Otherwise, one of the following error codes is returned instead:

> `klParameterErr` | Invalid option passed into function (check your variables).
> `klMemFullErr` | Out of memory.
> `klPreferencesReadErr` | The preferences file is inaccessible or corrupt.
> `klPreferencesWriteErr` | The preferences file is locked.
> `klNoRealmsErr` | The favorite realms list is empty.
> `klRealmDoesNotExistErr` | The specified realm does not exist.

> ### KLInsertKerberosRealm

>     KLStatus KLInsertKerberosRealm (
>     	KLIndex     inInsertBeforeIndex,
>     	const char *inRealmName);

> #### Requires:

> - `inRealmName` is a nul-terminated C string

> #### Effects:

> Inserts a realm with the name specified in `inRealmName` before index `inInsertBeforeIndex`, or at the end if `inInsertBeforeIndex` is equal to `KLCountKerberosRealms()`. Realm indices are 0-based.

> Note: If another realm with the name `inRealmName` is already in the list, `KLInsertKerberosRealm` moves the realm before index `inInsertBeforeIndex`. Because the old realm may be before this index in the list, the new realm may actually be placed at a different index (two less than `inInsertBeforeIndex`). As a result, you should either make sure you are adding only one realm of each name, or you should not use `inInsertBeforeIndex` after calling `KLInsertKerberosRealm`.

> #### Results:

> If successful, klNoErr is returned. Otherwise, one of the following error codes is returned instead:

> `klParameterErr` | Invalid option passed into function (check your variables).
> `klMemFullErr` | Out of memory.
> `klPreferencesReadErr` | The preferences file is inaccessible or corrupt.
> `klPreferencesWriteErr` | The preferences file is locked.
> `klNoRealmsErr` | The favorite realms list is empty.
> `klRealmDoesNotExistErr` | The specified realm does not exist.

> ### KLRemoveAllKerberosRealms

>     KLStatus KLRemoveAllKerberosRealms (void);

> #### Effects:

> Clears the entire realm list except for the Kerberos configuration default realm.

> Note: Kerberos Login Library does not support removing the Kerberos default realm (ie: the `default_realm` in the `lib_defaults` section of the Kerberos Preferences). If you attempt to remove the Kerberos default realm from the realm list, it will be added to the beginning of the realm list. If you want to remove this realm, please change the Kerberos default realm.

> #### Results:

> If successful, klNoErr is returned. Otherwise, one of the following error codes is returned instead:

> `klParameterErr` | Invalid option passed into function (check your variables).
> `klMemFullErr` | Out of memory.
> `klPreferencesReadErr` | The preferences file is inaccessible or corrupt.
> `klPreferencesWriteErr` | The preferences file is locked.

> ### KLCountKerberosRealms

>     KLSize KLCountKerberosRealms (void);

> #### Effects:

> Returns the total number of realms in the list.

> ### KLGetKerberosDefaultRealm

>     KLStatus KLGetKerberosDefaultRealm(
>          KLIndex *outIndex);

> #### Effects:

> Returns the index of the default realm in the login dialog box in `outIndex`. If there are no realms in the list, function returns a `klEmptyRealmListErr` error and `outIndex` is unchanged.

> Realm indices are 0-based.

> #### Results:

> If successful, klNoErr is returned. Otherwise, one of the following error codes is returned instead:

> `klParameterErr` | Invalid option passed into function (check your variables).
> `klMemFullErr` | Out of memory.
> `klPreferencesReadErr` | The preferences file is inaccessible or corrupt.
> `klNoRealmsErr` | The favorite realms list is empty.
> `klRealmDoesNotExistErr` | The specified realm does not exist.

> ### KLGetKerberosDefaultRealmByName

>     KLStatus KLGetKerberosDefaultRealm (
>     	char **outRealmName);

> #### Effects:

> Returns the name of the default realm in the login dialog box as a C string in `outRealmName`. The returned string should be freed using the `KLDisposeString()` function. If there are no realms in the list, function returns a `klEmptyRealmListErr` error and `outRealmName` is unchanged.

> #### Results:

> If successful, klNoErr is returned. Otherwise, one of the following error codes is returned instead:

> `klParameterErr` | Invalid option passed into function (check your variables).
> `klMemFullErr` | Out of memory.
> `klPreferencesReadErr` | The preferences file is inaccessible or corrupt.
> `klNoRealmsErr` | The favorite realms list is empty.
> `klRealmDoesNotExistErr` | The specified realm does not exist.

> ### KLSetKerberosDefaultRealm

>     KLStatus KLSetKerberosDefaultRealm (
>     	KLIndex inIndex);

> #### Effects:

> Sets the default realm in the login dialog box to be the realm specified by `inIndex`. Returns `noErr` if the index passed in is valid, or `paramErr` if the index is invalid (i.e. the index is out of range).

> Realm indices are 0-based.

> #### Results:

> If successful, klNoErr is returned. Otherwise, one of the following error codes is returned instead:

> `klParameterErr` | Invalid option passed into function (check your variables).
> `klMemFullErr` | Out of memory.
> `klPreferencesReadErr` | The preferences file is inaccessible or corrupt.
> `klPreferencesWriteErr` | The preferences file is locked.
> `klNoRealmsErr` | The favorite realms list is empty.
> `klRealmDoesNotExistErr` | The specified realm does not exist.

> ### KLSetKerberosDefaultRealmByName

>     KLStatus KLSetKerberosDefaultRealmByName (
>     	const char *inRealmName);

> #### Requires:

> - `inRealmName` is a null-terminated C string

> #### Effects:

> Sets the default realm in the login dialog box to be the realm specified by `inRealmName`. Returns `noErr` if the name passed in is valid, or `paramErr` if the name is invalid (i.e. the index is not among the known realms).

> #### Results:

> If successful, klNoErr is returned. Otherwise, one of the following error codes is returned instead:

> `klParameterErr` | Invalid option passed into function (check your variables).
> `klMemFullErr` | Out of memory.
> `klPreferencesReadErr` | The preferences file is inaccessible or corrupt.
> `klPreferencesWriteErr` | The preferences file is locked.
> `klNoRealmsErr` | The favorite realms list is empty.
> `klRealmDoesNotExistErr` | The specified realm does not exist.

> ## KLPrincipal Functions

> ### KLCreatePrincipalFromTriplet

>     KLStatus KLCreatePrincipalFromTriplet(
>          const char  *inName,
>          const char  *inInstance,
>          const char  *inRealm,
>          KLPrincipal *outPrincipal);

> #### Requires:

> - `inName`, `inInstance`, `inRealm` point to C strings;

> #### Effects:

> Creates a new `KLPrincipal` to be used with other Login Library API functions from the triplet provided.

> The returned `KLPrincipal` should be freed using the `KLDisposePrincipal()` function.

> #### Results:

> If successful, klNoErr is returned. Otherwise, one of the following error codes is returned instead:

> `klParameterErr` | Invalid option passed into function (check your variables).
> `klBadPrincipalErr` | Invalid `KLPrincipal` passed into function.
> `klMemFullErr` | Out of memory.
> `klV5InitializationFailedErr` | Failed to initialize a krb5 context.
> Any error returned by a principal translation plugin | A principal translation returned an error.

> Note that this function may return error codes reported by a principal translation function. Therefore, your code should expect to get an unknown error code, and be able to handle it gracefully -- by calling `KLGetErrorString()`.

> ### KLCreatePrincipalFromString

>     KLStatus KLCreatePrincipalFromString(
>         const char        *inFullPrincipal,
>         KLKerberosVersion  inKerberosVersion,
>         KLPrincipal       *outPrincipal);

> #### Requires:

> - `inFullPrincipal` points to a C string;

> #### Effects:

> Creates a new `KLPrincipal` to be used with other Login Library API functions from the string provided. The "string" form of a principal is "user/instance@realm" (for the v5 case) or "user.instance@realm".

> The `inKerberosVersion` parameter should be either `kerberosVersion_V4` or `kerberosVersion_V5`, specifying whether the string contains a Kerberos v4 or Kerberos v5 principal (this affects how it is parsed).

> The returned `KLPrincipal` should be freed using the `KLDisposePrincipal()` function.

> #### Results:

> If successful, klNoErr is returned. Otherwise, one of the following error codes is returned instead:

> `klParameterErr` | Invalid option passed into function (check your variables).
> `klBadPrincipalErr` | Invalid `KLPrincipal` passed into function.
> `klInvalidVersionErr` | Invalid Kerberos version passed into function.
> `klMemFullErr` | Out of memory.
> `klV5InitializationFailedErr` | Failed to initialize a krb5 context.

> ### KLGetTripletFromPrincipal

>     KLStatus KLGetTripletFromPrincipal(
>         KLPrincipal   inPrincipal,
>         char        **outName,
>         char        **outInstance,
>         char        **outRealm);

> #### Requires:

> - `inPrincipal` is a valid `KLPrincipal`.

> #### Effects:

> Returns three C strings representing a Kerberos triplet equivalent to the `KLPrincipal` passed in. Kerberos v5 principals with two or more instances are not currently supported.

> `KLGetTripletFromPrincipal()` allocates the memory for the strings `outName`, `outInstance`, and `outRealm`. The strings returned should then be freed using the `KLDisposeString()` function.

> #### Results:

> If successful, klNoErr is returned. Otherwise, one of the following error codes is returned instead:

> `klParameterErr` | Invalid option passed into function (check your variables).
> `klBadPrincipalErr` | Invalid `KLPrincipal` passed into function.
> `klMemFullErr` | Out of memory.
> `klV5InitializationFailedErr` | Failed to initialize a krb5 context.

> ### KLGetStringFromPrincipal

>     KLStatus KLGetStringFromPrincipal(
>         KLPrincipal         inPrincipal,
>         KLKerberosVersion   inKerberosVersion,
>         char              **outFullPrincipal);

> #### Requires:

> - `inPrincipal` is a valid `KLPrincipal`.

> - `inKerberosVersion` is a valid `KLKerberosVersion`.

>   #### Effects:

>   Returns a C string representation of the `KLPrincipal` passed in (e.g. "user/instance@realm").

>   The `inKerberosVersion` parameter should be either `kerberosVersion_V4` or `kerberosVersion_V5`, specifying which representation (Kerberos v4 or Kerberos v5) the string should use.

>   `KLGetStringFromPrincipal()` allocates the memory for the string `outFullPrincipal`. The string returned should then be freed using the `KLDisposeString()` function.

>   If an error occurs `outFullPrincipal` is unchanged.

>   #### Results:

>   If successful, klNoErr is returned. Otherwise, one of the following error codes is returned instead:

>   `klParameterErr` | Invalid option passed into function (check your variables).
>   `klBadPrincipalErr` | Invalid `KLPrincipal` passed into function.
>   `klInvalidVersionErr` | Invalid Kerberos version passed into function.
>   `klMemFullErr` | Out of memory.
>   `klV5InitializationFailedErr` | Failed to initialize a krb5 context.

>   ### KLGetDisplayStringFromPrincipal

>       KLStatus KLGetDisplayStringFromPrincipal(
>           KLPrincipal         inPrincipal,
>           KLKerberosVersion   inKerberosVersion,
>           char              **outFullPrincipal);

>   #### Requires:

> - `inPrincipal` is a valid `KLPrincipal`.

> - `inKerberosVersion` is a valid `KLKerberosVersion`.

>   #### Effects:

>   Returns a C string representation of the `KLPrincipal` passed in (e.g. "user/instance@realm"), and removes any backslash characters used to quote special characters in the principal. The returned string cannot be converted back to a principal, and therefore should be used only for display purposes.

>   The `inKerberosVersion` parameter should be either `kerberosVersion_V4` or `kerberosVersion_V5`, specifying which representation (Kerberos v4 or Kerberos v5) the string should use.

>   `KLGetStringFromPrincipal()` allocates the memory for the string `outFullPrincipal`. The string returned should then be freed using the `KLDisposeString()` function.

>   If an error occurs `outFullPrincipal` is unchanged.

>   #### Results:

>   If successful, klNoErr is returned. Otherwise, one of the following error codes is returned instead:

>   `klParameterErr` | Invalid option passed into function (check your variables).
>   `klBadPrincipalErr` | Invalid `KLPrincipal` passed into function.
>   `klInvalidVersionErr` | Invalid Kerberos version passed into function.
>   `klMemFullErr` | Out of memory.
>   `klV5InitializationFailedErr` | Failed to initialize a krb5 context.

>   ### KLComparePrincipal

>       KLStatus KLComparePrincipal(
>           KLPrincipal   inFirstPrincipal,
>           KLPrincipal   inSecondPrincipal,
>           KLBoolean    *outAreEquivalent);

>   #### Requires:

> - `inFirstPrincipal` and `inSecondPrincipal` are valid `KLPrincipal`s.

>   #### Effects:

>   If no errors occur, `inFirstPrincipal` and `inSecondPrincipal` are equivalent, returns `true` in `outAreEquivalent`. Otherwise, returns `false`.

>   If an error occurs, `outAreEquivalent` is unchanged.

>   #### Results:

>   If successful, klNoErr is returned. Otherwise, one of the following error codes is returned instead:

>   `klParameterErr` | Invalid option passed into function (check your variables).
>   `klBadPrincipalErr` | Invalid `KLPrincipal` passed into function.
>   `klMemFullErr` | Out of memory.
>   `klV5InitializationFailedErr` | Failed to initialize a krb5 context.

>   ### KLDisposePrincipal

>       KLStatus KLDisposePrincipal(
>            KLPrincipal inPrincipal);

>   #### Requires:

> - `inPrincipal` is a valid `KLPrincipal`s.

>   #### Effects:

>   Releases memory associated with the `KLPrincipal` passed in. The reference is no longer valid after the call to `KLDisposePrincipal()`.

>   #### Results:

>   If successful, klNoErr is returned. Otherwise, one of the following error codes is returned instead:

>   `klBadPrincipalErr` | Invalid `KLPrincipal` passed into function.
>   `klMemFullErr` | Out of memory.
>   `klPreferencesReadErr` | The preferences file is inaccessible or corrupt.

>   ## KLLoginOptions Functions

>   ### KLCreateLoginOptions

>       KLStatus KLCreateLoginOptions (
>            KLLoginOptions *outOptions);

>   #### Requires:

>   (none)

>   #### Effects:

>   Creates a new `KLLoginOptions` to be used with other Login Library API functions. The login options are set to the KerberosLogin defaults for those values.

>   The returned `KLLoginOptions` should be freed using the `KLDisposeLoginOptions ()` function.

>   #### Results:

>   If successful, klNoErr is returned. Otherwise, one of the following error codes is returned instead:

>   `klBadLoginOptionsErr` | Invalid `KLLoginOptions` passed into function.
>   `klMemFullErr` | Out of memory.
>   `klPreferencesReadErr` | The preferences file is inaccessible or corrupt.
>   `klV5InitializationFailedErr` | Failed to initialize a krb5 context.

>   ### KLLoginOptionsSetTicketLifetime

>       KLStatus KLLoginOptionsSetTicketLifetime (
>            KLLoginOptions   ioOptions,
>            KLLifetime       inTicketLifetime);

>   #### Requires:

>   - `ioOptions` is a valid `KLLoginOptions` created with `KLCreateLoginOptions ()`

>   #### Effects:

>   Sets the ticket lifetime in the `KLLoginOptions` provided.

>   #### Results:

>   If successful, klNoErr is returned. Otherwise, one of the following error codes is returned instead:

>   `klBadLoginOptionsErr` | Invalid `KLLoginOptions` passed into function.
>   `klMemFullErr` | Out of memory.
>   `klPreferencesReadErr` | The preferences file is inaccessible or corrupt.
>   `klV5InitializationFailedErr` | Failed to initialize a krb5 context.

>   ### KLLoginOptionsSetForwardable

>       KLStatus KLLoginOptionsSetForwardable (
>            KLLoginOptions   ioOptions,
>            KLBoolean        inProxiable);

>   #### Requires:

>   - `ioOptions` is a valid `KLLoginOptions` created with `KLCreateLoginOptions ()`

>   #### Effects:

>   Sets the forwardable tickets flag in the `KLLoginOptions` provided.

>   #### Results:

>   If successful, klNoErr is returned. Otherwise, one of the following error codes is returned instead:

>   `klBadLoginOptionsErr` | Invalid `KLLoginOptions` passed into function.
>   `klMemFullErr` | Out of memory.
>   `klPreferencesReadErr` | The preferences file is inaccessible or corrupt.
>   `klV5InitializationFailedErr` | Failed to initialize a krb5 context.

>   ### KLLoginOptionsSetProxiable

>       KLStatus KLLoginOptionsSetProxiable (
>            KLLoginOptions   ioOptions,
>            KLBoolean        inProxiable);

>   #### Requires:

>   - `ioOptions` is a valid `KLLoginOptions` created with `KLCreateLoginOptions ()`

>   #### Effects:

>   Sets the proxiable tickets flag in the `KLLoginOptions` provided.

>   #### Results:

>   If successful, klNoErr is returned. Otherwise, one of the following error codes is returned instead:

>   `klBadLoginOptionsErr` | Invalid `KLLoginOptions` passed into function.
>   `klMemFullErr` | Out of memory.
>   `klPreferencesReadErr` | The preferences file is inaccessible or corrupt.
>   `klV5InitializationFailedErr` | Failed to initialize a krb5 context.

>   ### KLLoginOptionsSetRenewableLifetime

>       KLStatus KLLoginOptionsSetRenewableLifetime (
>            KLLoginOptions   ioOptions,
>            KLLifetime       inRenewableLifetime);

>   #### Requires:

>   - Kerberos Login Library API 2.2 (part of Kerberos for Macintosh 4.5) or later
>   - `ioOptions` is a valid `KLLoginOptions` created with `KLCreateLoginOptions ()`

>   #### Effects:

>   Sets the renewable lifetime in the `KLLoginOptions` provided.

>   #### Results:

>   If successful, klNoErr is returned. Otherwise, one of the following error codes is returned instead:

>   `klBadLoginOptionsErr` | Invalid `KLLoginOptions` passed into function.
>   `klMemFullErr` | Out of memory.
>   `klPreferencesReadErr` | The preferences file is inaccessible or corrupt.
>   `klV5InitializationFailedErr` | Failed to initialize a krb5 context.

>   ### KLLoginOptionsSetAddressless

>       KLStatus KLLoginOptionsSetAddressless (
>            KLLoginOptions   ioOptions,
>            KLBoolean        inAddressless);

>   #### Requires:

>   - Kerberos Login Library API 2.2 (part of Kerberos for Macintosh 4.5) or later
>   - `ioOptions` is a valid `KLLoginOptions` created with `KLCreateLoginOptions ()`

>   #### Effects:

>   Sets whether tickets contain in the `KLLoginOptions` provided.

>   #### Results:

>   If successful, klNoErr is returned. Otherwise, one of the following error codes is returned instead:

>   `klBadLoginOptionsErr` | Invalid `KLLoginOptions` passed into function.
>   `klMemFullErr` | Out of memory.
>   `klPreferencesReadErr` | The preferences file is inaccessible or corrupt.
>   `klV5InitializationFailedErr` | Failed to initialize a krb5 context.

>   ### KLLoginOptionsSetTicketStartTime

>       KLStatus KLLoginOptionsSetTicketStartTime (
>            KLLoginOptions   ioOptions,
>            KLTime           inStartTime);

>   #### Requires:

>   - Kerberos Login Library API 2.2 (part of Kerberos for Macintosh 4.5) or later
>   - `ioOptions` is a valid `KLLoginOptions` created with `KLCreateLoginOptions ()`

>   #### Effects:

>   Sets the time when tickets become valid in the `KLLoginOptions` provided.

>   #### Results:

>   If successful, klNoErr is returned. Otherwise, one of the following error codes is returned instead:

>   `klBadLoginOptionsErr` | Invalid `KLLoginOptions` passed into function.
>   `klMemFullErr` | Out of memory.
>   `klPreferencesReadErr` | The preferences file is inaccessible or corrupt.
>   `klV5InitializationFailedErr` | Failed to initialize a krb5 context.

>   ### KLLoginOptionsSetServiceName

>       KLStatus KLLoginOptionsSetServiceName (
>            KLLoginOptions   ioOptions,
>            const char      *inServiceName);

>   #### Requires:

>   - Kerberos Login Library API 2.2 (part of Kerberos for Macintosh 4.5) or later
>   - `ioOptions` is a valid `KLLoginOptions` created with `KLCreateLoginOptions ()`

>   #### Effects:

>   Sets the service principal name in the `KLLoginOptions` provided.

>   #### Results:

>   If successful, klNoErr is returned. Otherwise, one of the following error codes is returned instead:

>   `klBadLoginOptionsErr` | Invalid `KLLoginOptions` passed into function.
>   `klMemFullErr` | Out of memory.
>   `klPreferencesReadErr` | The preferences file is inaccessible or corrupt.
>   `klV5InitializationFailedErr` | Failed to initialize a krb5 context.

>   ### KLDisposeLoginOptions

>       KLStatus KLDisposeLoginOptions (
>            KLLoginOptions inOptions);

>   #### Requires:

>   (none)

>   #### Effects:

>   Releases memory associated with the `KLLoginOptions` passed in. The reference is no longer valid after the call to `KLDisposeLoginOptions()`.

>   #### Results:

>   If successful, klNoErr is returned. Otherwise, one of the following error codes is returned instead:

>   `klBadLoginOptionsErr` | Invalid `KLLoginOptions` passed into function.
>   `klMemFullErr` | Out of memory.
>   `klPreferencesReadErr` | The preferences file is inaccessible or corrupt.

>   ## Miscellaneous Functions

>   ### KLDisposeString

>       KLStatus KLDisposeString(
>            char *inStringToDispose);

>   #### Requires:

>   - `inStringToDispose` is a string allocated by the Login Library API.

>   #### Effects:

>   Zeros the memory associated with the string passed in, and then releases the memory. (Zeroing the memory first is useful for when disposing of password strings allocated by the Login Library API.) The string may have been allocated by functions including `KLLoginDialogHandleEvents(), KLChangePasswordDialogHandleEvents(), KLGetStringFromPrincipal()` or `KLGetTripletFromPrincipal()`.

>   #### Results:

>   If successful, klNoErr is returned. Otherwise, one of the following error codes is returned instead:

>   `klParameterErr` | Invalid option passed into function (check your variables).
>   `klMemFullErr` | Out of memory.

>   ## Internal Use Functions

>   ### __KLInternalAcquireTicketsForCache

>       KLStatus __KLInternalAcquireTicketsForCache (
>            KLPrincipal         inPrincipal,
>            const char         *inCacheName,
>            KLKerberosVersion   inKerberosVersion,
>            KLPrincipal        *outPrincipal,
>            char              **outCacheName);

>   #### Requires:

>   The `__KLInternalAcquireTicketsForCache` `()` function requires the following:

>   - `outCacheName` and `inCacheName` are both non-nil. `inCacheName` may be prefixed by the Kerberos 5 "API:" (`__KLInternalAcquireTicketsForCache` ( ) will handle this case).
>   - `inKerberosVersion` is a valid version of Kerberos.

>   #### Effects:

>   The `__KLInternalAcquireTicketsForCache``()` function attempts to insure that a valid ticket-granting ticket of the Kerberos version `inKerberosVersion` is available in the cache `inCacheName` and, if specified, for the principal `inPrincipal`, prompting the user to obtain a new one if necessary. Its main purpose is to be used interally by Kerberos5 and Kerberos4 libraries to verify the existance of the appropriate ticket granting tickets for the current session before obtaining a Kerberos service ticket.

>   The name of the principal for which tickets are obtained (or found) is returned in `outPrincipal`.

>   The name of the cache into which tickets are placed (or which is found if no new tickets are obtained) is returned in `outCacheName` so that the caller can change the application/context default cache if desired. This returned name can be used in Credential Cache API, Kerberos 4, or Kerberos 5 calls.

>   If `inPrincipal` is not `nil` (a principal is specified) and `inKerberosVersion` is a valid version for that principal (if not, `klBadPrincipal` is returned),

>   - and no valid tickets for that principal are in the the cache specified by `inCacheName`, `__KLInternalAcquireTicketsForCache` `()` presents the user interface as specified by `KLLoginDialogBegin()` for obtaining user information and then attempts to acquire tickets with that information into a new cache. If successful and no tickets at all were previously in the cache collection, the newly created cache is made the system default cache;
>   - or, valid tickets for that principal are available in the cache specified by `inCacheName`, no user interface is displayed.

>   If `inPrincipal` is `nil` (no principal is specified),

>   - and no valid tickets for any user are in the cache specified by `inCacheName`, `KLAcquireTickets()` presents the user interface as specified by `KLLoginDialogBegin()` for obtaining user information and then attempts to acquire tickets with that information and place them in a new cache. If successful and the cache collection is empty, the credentials cache corresponding to that principal are made the system default cache.
>   - or, valid tickets are available in the cache specified by `inCacheName`, no user interface is displayed and `inCacheName` is returned.

>   `__KLInternalAcquireTicketsForCache``()` does not necessarily present the user interface. If you always want to bring up the user interface, use `KLAcquireNewTickets()`.

>   `__KLInternalAcquireTicketsForCache``()` will take care of presenting error dialogs to the user as necessary (for problems such as unknown principal, incorrect password, etc.). You do not need to call `KLHandleError()` after this function.

>   If both Kerberos v4 and Kerberos v5 are available for the realm of the principal, either both v4 and v5 ticket-granting tickets will be available in the cache collection (and the credentials cache containing them will possibly be set as the system default cache, as specified above) upon return, or `__KLInternalAcquireTicketsForCache``()` will return an error code.

>   If both Kerberos v4 and Kerberos v5 are available for the realm of the principal, and valid tickets for only one version but not the other are available in the cache collection, `__KLInternalAcquireTicketsForCache``()` will treat this as the same as the no valid tickets case -- new tickets will be obtained for both Kerberos versions, replacing the current "orphan" ones.

>   If only one of Kerberos v4 and Kerberos v5 is available for the realm of the principal, either a ticket-granting ticket for the appropriate version will be available in the cache collection (and the credentials cache containing them will be possibly set as the system default cache) as specified above upon return, or `__KLInternalAcquireTicketsForCache``()` will return an error code`.`

>   #### Results:

>   If `__KLInternalAcquireTicketsForCache``()` returns `klNoErr`, then:

>   - tickets are available in the cache collection specified by `outCacheName`;
>   - if `outPrincipal` is not `nil`, a new `KLPrincipal` is returned in `*outPrincipal`. The returned `KLPrincipal` should be freed using the `KLDisposePrincipal()` function. If `outPrincipal` is `nil`, nothing is returned.

>   Otherwise, `outPrincipal` and `outCredCacheName` are unchanged and `__KLInternalAcquireTicketsForCache` `()` returns one of the following error codes:

>   `klParameterErr` | Invalid option passed into function (check your variables).
>   `klBadPrincipalErr` | Invalid `KLPrincipal` passed into function or version does not match principal.
>   `klBadVersionErr` | Invalid Kerberos version passed into function.
>   `klUserCanceledErr` | The user cancelled the dialog.
>   `klMemFullErr` | Out of memory.
>   `klRealmDoesNotExistErr` | The specified realm does not exist.

>   ### __KLInternalAcquireNewKerberos4TicketsFromKerberos5Tickets

>       KLStatus __KLInternalAcquireNewKerberos4TicketsFromKerberos5Tickets (
>               KLPrincipal       inPrincipal,
>       		KLPrincipal		 *outPrincipal,
>       		char 			**outCredCacheName);

>   #### Requires:

>   The `__KLInternalAcquireNewKerberos4TicketsFromKerberos5Tickets()` function requires the following:

>   - `inPrincipal` is a valid `KLPrincipal`.

>   #### Effects:

>   `__KLInternalAcquireNewKerberos4TicketsFromKerberos5Tickets()` attempts to obtain a new Kerberos 4 credential for `inPrincipal` from an existing Kerberos 5 credential for the same principal using the krb524 service.

>   The name of the principal for which the Kerberos 4 ticket is obtained is returned in `outPrincipal`.

>   The name of the cache into which the Kerberos 4 ticket is placed is returned in `outCacheName`. This returned name can be used in Credential Cache API, Kerberos 4, or Kerberos 5 calls.

>   #### Results:

>   If `__KLInternalAcquireNewKerberos4TicketsFromKerberos5Tickets()` returns `klNoErr`, then:

>   - A new Kerberos 4 ticket is available in the cache collection specified by `outCacheName`;
>   - if `outPrincipal` is not `nil`, a new `KLPrincipal` is returned in `*outPrincipal`. The returned `KLPrincipal` should be freed using the `KLDisposePrincipal()` function. If `outPrincipal` is `nil`, nothing is returned.

>   Otherwise, `outPrincipal` and `outCredCacheName` are unchanged and `__KLInternalAcquireNewKerberos4TicketsFromKerberos5Tickets()` returns one of the following error codes:

>   `klParameterErr` | Invalid option passed into function (check your variables).
>   `klBadPrincipalErr` | Invalid `KLPrincipal` passed into function or version does not match principal.
>   `klBadVersionErr` | Invalid Kerberos version passed into function.
>   `klUserCanceledErr` | The user cancelled the dialog.
>   `klMemFullErr` | Out of memory.
>   `klRealmDoesNotExistErr` | The specified realm does not exist.
>   Any Kerberos 5 error | Use `KLHandleError ()` or `KLGetErrorString ()` to report these errors to the user.
>   Any Kerberos 4 error | Use `KLHandleError ()` or `KLGetErrorString ()` to report these errors to the user.

Questions or comments? Send mail to macdev@mit.edu
Last updated on $Date: 2003/11/18 21:11:48 $
Last modified by $Author: smcguire $