1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* include/CredentialsCache.h */
3 /*
4  * Copyright 1998-2006 Massachusetts Institute of Technology.
5  * All Rights Reserved.
6  *
7  * Export of this software from the United States of America may
8  * require a specific license from the United States Government.
9  * It is the responsibility of any person or organization contemplating
10  * export to obtain such a license before exporting.
11  *
12  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13  * distribute this software and its documentation for any purpose and
14  * without fee is hereby granted, provided that the above copyright
15  * notice appear in all copies and that both that copyright notice and
16  * this permission notice appear in supporting documentation, and that
17  * the name of M.I.T. not be used in advertising or publicity pertaining
18  * to distribution of the software without specific, written prior
19  * permission.  Furthermore if you modify this software you must label
20  * your software as modified software and not distribute it in such a
21  * fashion that it might be confused with the original M.I.T. software.
22  * M.I.T. makes no representations about the suitability of
23  * this software for any purpose.  It is provided "as is" without express
24  * or implied warranty.
25  */
26 
27 #ifndef __CREDENTIALSCACHE__
28 #define __CREDENTIALSCACHE__
29 
30 #if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__))
31 #include <TargetConditionals.h>
32 
33 /* Notifications which are sent when the ccache collection or a ccache change.
34  * Notifications are sent to the distributed notification center.
35  * The object for kCCAPICacheCollectionChangedNotification is NULL.
36  * The object for kCCAPICCacheChangedNotification is a CFString containing the
37  * name of the ccache.
38  *
39  * Note: Notifications are not sent if the CCacheServer crashes.  */
40 #define kCCAPICacheCollectionChangedNotification CFSTR ("CCAPICacheCollectionChangedNotification")
41 #define kCCAPICCacheChangedNotification          CFSTR ("CCAPICCacheChangedNotification")
42 #endif
43 
44 #if defined(_WIN32)
45 #include <winsock.h>
46 #include "win-mac.h"
47 #else
48 #include <stdint.h>
49 #endif
50 
51 #ifdef __cplusplus
52 extern "C" {
53 #endif /* __cplusplus */
54 
55 #if defined(__APPLE__) && (defined(__ppc__) || defined(__ppc64__) || defined(__i386__) || defined(__x86_64__))
56 #pragma pack(push,2)
57 #endif
58 
59 #if defined(_WIN32)
60 #define CCACHE_API      __declspec(dllexport)
61 
62 #if _INTEGRAL_MAX_BITS >= 64 && _MSC_VER >= 1500 && !defined(_WIN64) && !defined(_USE_32BIT_TIME_T)
63 #if defined(_TIME_T_DEFINED) || defined(_INC_IO) || defined(_INC_TIME) || defined(_INC_WCHAR)
64 #error time_t has been defined as a 64-bit integer which is incompatible with Kerberos on this platform.
65 #endif /* _TIME_T_DEFINED */
66 #define _USE_32BIT_TIME_T
67 #endif
68 #else
69 #define CCACHE_API
70 #endif
71 
72 /*!
73  * \mainpage Credentials Cache API (CCAPI) Documentation
74  *
75  * \section toc Table of Contents
76  *
77  * \li \ref introduction
78  * \li \ref error_handling
79  * \li \ref synchronization_atomicity
80  * \li \ref memory_management
81  * \li \ref opaque_types
82  *
83  * \li \ref ccapi_constants_reference
84  * \li \ref ccapi_types_reference
85  *
86  * \li \ref cc_context_reference
87  * \li \ref cc_context_f "cc_context_t Functions"
88  *
89  * \li \ref cc_ccache_reference
90  * \li \ref cc_ccache_f "cc_ccache_t Functions"
91  *
92  * \li \ref cc_credentials_reference
93  * \li \ref cc_credentials_f "cc_credentials_t Functions"
94  *
95  * \li \ref cc_ccache_iterator_reference
96  * \li \ref cc_ccache_iterator_f "cc_ccache_iterator_t Functions"
97  *
98  * \li \ref cc_credentials_iterator_reference
99  * \li \ref cc_credentials_iterator_f "cc_credentials_iterator_t Functions"
100  *
101  * \li \ref cc_string_reference
102  * \li \ref cc_string_f "cc_string_t Functions"
103  *
104  * \section introduction Introduction
105  *
106  * This is the specification for an API which provides Credentials Cache
107  * services for Kerberos v5 (and previously v4). The idea behind this API is
108  * that multiple Kerberos implementations can share a single collection of
109  * credentials caches, mediated by this API specification. On the Mac OS and
110  * Microsoft Windows platforms this will allow single-login, even when more
111  * than one Kerberos shared library is in use on a particular system.
112  *
113  * Abstractly, a credentials cache collection contains one or more credentials
114  * caches, or ccaches. A ccache is uniquely identified by its name, which is
115  * a string internal to the API and not intended to be presented to users.
116  * The user presentable identifier of a ccache is its principal.
117  *
118  * Unlike the previous versions of the API, version 3 of the API could store
119  * credentials for multiple Kerberos versions in the same ccache.
120  *
121  * At any given time, one ccache is the "default" ccache. The exact meaning
122  * of a default ccache is OS-specific; refer to implementation requirements
123  * for details.
124  *
125  * \section error_handling Error Handling
126  *
127  * All functions of the API return some of the error constants listed FIXME;
128  * the exact list of error constants returned by any API function is provided
129  * in the function descriptions below.
130  *
131  * When returning an error constant other than ccNoError or ccIteratorEnd, API
132  * functions never modify any of the values passed in by reference.
133  *
134  * \section synchronization_atomicity Synchronization and Atomicity
135  *
136  * Every function in the API is atomic.  In order to make a series of calls
137  * atomic, callers should lock the ccache or cache collection they are working
138  * with to advise other callers not to modify that container.  Note that
139  * advisory locks are per container so even if you have a read lock on the cache
140  * collection other callers can obtain write locks on ccaches in that cache
141  * collection.
142  *
143  * Note that iterators do not iterate over ccaches and credentials atomically
144  * because locking ccaches and the cache collection over every iteration would
145  * degrade performance considerably under high load.  However, iterators do
146  * guarantee a consistent view of items they are iterating over.  Iterators
147  * will never return duplicate entries or skip entries when items are removed
148  * or added to the container they are iterating over.
149  *
150  * An application can always lock a ccache or the cache collection to guarantee
151  * that other callers participating in the advisory locking system do not
152  * modify the ccache or cache collection.
153  *
154  * Implementations should not use copy-on-write techniques to implement locks
155  * because those techniques imply that same parts of the ccache collection
156  * remain visible to some callers even though they are not present in the
157  * collection, which is a potential security risk. For example, a copy-on-write
158  * technique might make a copy of the entire collection when a read lock is
159  * acquired, so as to allow the owner of the lock to access the collection in
160  * an apparently unmodified state, while also allowing others to make
161  * modifications to the collection. However, this would also enable the owner
162  * of the lock to indefinitely (until the expiration time) use credentials that
163  * have actually been deleted from the collection.
164  *
165  * \section memory_management Object Memory Management
166  *
167  * The lifetime of an object returned by the API is until release() is called
168  * for it. Releasing one object has no effect on existence of any other object.
169  * For example, a ccache obtained within a context continue to exist when the
170  * context is released.
171  *
172  * Every object returned by the API (cc_context_t, cc_ccache_t, cc_ccache_iterator_t,
173  * cc_credentials_t, cc_credentials_iterator_t, cc_string_t) is owned by the
174  * caller of the API, and it is the responsibility of the caller to call release()
175  * for every object to prevent memory leaks.
176  *
177  * \section opaque_types Opaque Types
178  *
179  * All of the opaque high-level types in CCache API are implemented as structures
180  * of function pointers and private data. To perform some operation on a type, the
181  * caller of the API has to first obtain an instance of that type, and then call the
182  * appropriate function pointer from that instance. For example, to call
183  * get_change_time() on a cc_context_t, one would call cc_initialize() which creates
184  * a new cc_context_t and then call its get_change_time(), like this:
185  *
186  * \code
187  * cc_context_t context;
188  * cc_int32 err = cc_initialize (&context, ccapi_version_3, nil, nil);
189  * if (err == ccNoError)
190  * time = context->functions->get_change_time (context)
191  * \endcode
192  *
193  * All API functions also have convenience preprocessor macros, which make the API
194  * seem completely function-based. For example, cc_context_get_change_time
195  * (context, time) is equivalent to context->functions->get_change_time
196  * (context, time). The convenience macros follow the following naming convention:
197  *
198  * The API function some_function()
199  * \code
200  * cc_type_t an_object;
201  * result = an_object->functions->some_function (opaque_pointer, args)
202  * \endcode
203  *
204  * has an equivalent convenience macro of the form cc_type_some_function():
205  * \code
206  * cc_type_t an_object;
207  * result = cc_type_some_function (an_object, args)
208  * \endcode
209  *
210  * The specifications below include the names for both the functions and the
211  * convenience macros, in that order. For clarity, it is recommended that clients
212  * using the API use the convenience macros, but that is merely a stylistic choice.
213  *
214  * Implementing the API in this manner allows us to extend and change the interface
215  * in the future, while preserving compatibility with older clients.
216  *
217  * For example, consider the case when the signature or the semantics of a cc_ccache_t
218  * function is changed. The API version number is incremented. The library
219  * implementation contains both a function with the old signature and semantics and
220  * a function with the new signature and semantics. When a context is created, the API
221  * version number used in that context is stored in the context, and therefore it can
222  * be used whenever a ccache is created in that context. When a ccache is created in a
223  * context with the old API version number, the function pointer structure for the
224  * ccache is filled with pointers to functions implementing the old semantics; when a
225  * ccache is created in a context with the new API version number, the function pointer
226  * structure for the ccache is filled with poitners to functions implementing the new
227  * semantics.
228  *
229  * Similarly, if a function is added to the API, the version number in the context can
230  * be used to decide whether to include the implementation of the new function in the
231  * appropriate function pointer structure or not.
232  */
233 
234 /*!
235  * \defgroup ccapi_constants_reference Constants
236  * @{
237  */
238 
239 /*!
240  * API version numbers
241  *
242  * These constants are passed into cc_initialize() to indicate the version
243  * of the API the caller wants to use.
244  *
245  * CCAPI v1 and v2 are deprecated and should not be used.
246  */
247 enum {
248     ccapi_version_2 = 2,
249     ccapi_version_3 = 3,
250     ccapi_version_4 = 4,
251     ccapi_version_5 = 5,
252     ccapi_version_6 = 6,
253     ccapi_version_7 = 7,
254     ccapi_version_max = ccapi_version_7
255 };
256 
257 /*!
258  * Error codes
259  */
260 enum {
261 
262     ccNoError = 0,  /*!< Success. */
263 
264     ccIteratorEnd = 201,  /*!< Iterator is done iterating. */
265     ccErrBadParam,  /*!< Bad parameter (NULL or invalid pointer where valid pointer expected). */
266     ccErrNoMem,  /*!< Not enough memory to complete the operation. */
267     ccErrInvalidContext,  /*!< Context is invalid (e.g., it was released). */
268     ccErrInvalidCCache,  /*!< CCache is invalid (e.g., it was released or destroyed). */
269 
270     /* 206 */
271     ccErrInvalidString,  /*!< String is invalid (e.g., it was released). */
272     ccErrInvalidCredentials,  /*!< Credentials are invalid (e.g., they were released), or they have a bad version. */
273     ccErrInvalidCCacheIterator,  /*!< CCache iterator is invalid (e.g., it was released). */
274     ccErrInvalidCredentialsIterator,  /*!< Credentials iterator is invalid (e.g., it was released). */
275     ccErrInvalidLock,  /*!< Lock is invalid (e.g., it was released). */
276 
277     /* 211 */
278     ccErrBadName,  /*!< Bad credential cache name format. */
279     ccErrBadCredentialsVersion,  /*!< Credentials version is invalid. */
280     ccErrBadAPIVersion,  /*!< Unsupported API version. */
281     ccErrContextLocked,  /*!< Context is already locked. */
282     ccErrContextUnlocked,  /*!< Context is not locked by the caller. */
283 
284     /* 216 */
285     ccErrCCacheLocked,   /*!< CCache is already locked. */
286     ccErrCCacheUnlocked,  /*!< CCache is not locked by the caller. */
287     ccErrBadLockType,  /*!< Bad lock type. */
288     ccErrNeverDefault,  /*!< CCache was never default. */
289     ccErrCredentialsNotFound,  /*!< Matching credentials not found in the ccache. */
290 
291     /* 221 */
292     ccErrCCacheNotFound,  /*!< Matching ccache not found in the collection. */
293     ccErrContextNotFound,  /*!< Matching cache collection not found. */
294     ccErrServerUnavailable,  /*!< CCacheServer is unavailable. */
295     ccErrServerInsecure,  /*!< CCacheServer has detected that it is running as the wrong user. */
296     ccErrServerCantBecomeUID,  /*!< CCacheServer failed to start running as the user. */
297 
298     /* 226 */
299     ccErrTimeOffsetNotSet,  /*!< KDC time offset not set for this ccache. */
300     ccErrBadInternalMessage,  /*!< The client and CCacheServer can't communicate (e.g., a version mismatch). */
301     ccErrNotImplemented,  /*!< API function not supported by this implementation. */
302     ccErrClientNotFound  /*!< CCacheServer has no record of the caller's process (e.g., the server crashed). */
303 };
304 
305 /*!
306  * Credentials versions
307  *
308  * These constants are used in several places in the API to discern Kerberos
309  * versions. Not all values are valid inputs and outputs for all functions;
310  * function specifications below detail the allowed values.
311  *
312  * Kerberos version constants will always be a bit-field, and can be
313  * tested as such; for example the following test will tell you if
314  * a ccacheVersion includes v5 credentials:
315  *
316  * if ((ccacheVersion & cc_credentials_v5) != 0)
317  */
318 enum cc_credential_versions {
319     /* cc_credentials_v4 = 1, */
320     cc_credentials_v5 = 2,
321     /* cc_credentials_v4_v5 = 3 */
322 };
323 
324 /*!
325  * Lock types
326  *
327  * These constants are used in the locking functions to describe the
328  * type of lock requested.  Note that all CCAPI locks are advisory
329  * so only callers using the lock calls will be blocked by each other.
330  * This is because locking functions were introduced after the CCAPI
331  * came into common use and we did not want to break existing callers.
332  */
333 enum cc_lock_types {
334     cc_lock_read = 0,
335     cc_lock_write = 1,
336     cc_lock_upgrade = 2,
337     cc_lock_downgrade = 3
338 };
339 
340 /*!
341  * Locking Modes
342  *
343  * These constants are used in the advisory locking functions to
344  * describe whether or not the lock function should block waiting for
345  * a lock or return an error immediately.   For example, attempting to
346  * acquire a lock with a non-blocking call will result in an error if the
347  * lock cannot be acquired; otherwise, the call will block until the lock
348  * can be acquired.
349  */
350 enum cc_lock_modes {
351     cc_lock_noblock = 0,
352     cc_lock_block = 1
353 };
354 
355 /*!@}*/
356 
357 /*!
358  * \defgroup ccapi_types_reference Basic Types
359  * @{
360  */
361 
362 /*! Unsigned 32-bit integer type */
363 typedef uint32_t            cc_uint32;
364 /*! Signed 32-bit integer type */
365 typedef int32_t             cc_int32;
366 #if defined (WIN32)
367 typedef __int64             cc_int64;
368 typedef unsigned __int64    cc_uint64;
369 #else
370 /*! Unsigned 64-bit integer type */
371 typedef int64_t             cc_int64;
372 /*! Signed 64-bit integer type */
373 typedef uint64_t            cc_uint64;
374 #endif
375 /*!
376  * The cc_time_t type is used to represent a time in seconds. The time must
377  * be stored as the number of seconds since midnight GMT on January 1, 1970.
378  */
379 typedef cc_uint32           cc_time_t;
380 
381 /*!@}*/
382 
383 /*!
384  * \defgroup cc_context_reference cc_context_t Overview
385  * @{
386  *
387  * The cc_context_t type gives the caller access to a ccache collection.
388  * Before being able to call any functions in the CCache API, the caller
389  * needs to acquire an instance of cc_context_t by calling cc_initialize().
390  *
391  * For API function documentation see \ref cc_context_f.
392  */
393 struct cc_context_f;
394 typedef struct cc_context_f cc_context_f;
395 
396 struct cc_context_d {
397     const cc_context_f *functions;
398 #if TARGET_OS_MAC
399     const cc_context_f *vector_functions;
400 #endif
401 };
402 typedef struct cc_context_d cc_context_d;
403 typedef cc_context_d *cc_context_t;
404 
405 /*!@}*/
406 
407 /*!
408  * \defgroup cc_ccache_reference cc_ccache_t Overview
409  * @{
410  *
411  * The cc_ccache_t type represents a reference to a ccache.
412  * Callers can access a ccache and the credentials stored in it
413  * via a cc_ccache_t. A cc_ccache_t can be acquired via
414  * cc_context_open_ccache(), cc_context_open_default_ccache(), or
415  * cc_ccache_iterator_next().
416  *
417  * For API function documentation see \ref cc_ccache_f.
418  */
419 struct cc_ccache_f;
420 typedef struct cc_ccache_f cc_ccache_f;
421 
422 struct cc_ccache_d {
423     const cc_ccache_f *functions;
424 #if TARGET_OS_MAC
425     const cc_ccache_f *vector_functions;
426 #endif
427 };
428 typedef struct cc_ccache_d cc_ccache_d;
429 typedef cc_ccache_d *cc_ccache_t;
430 
431 /*!@}*/
432 
433 /*!
434  * \defgroup cc_ccache_iterator_reference cc_ccache_iterator_t Overview
435  * @{
436  *
437  * The cc_ccache_iterator_t type represents an iterator that
438  * iterates over a set of ccaches and returns them in all in some
439  * order. A new instance of this type can be obtained by calling
440  * cc_context_new_ccache_iterator().
441  *
442  * For API function documentation see \ref cc_ccache_iterator_f.
443  */
444 struct cc_ccache_iterator_f;
445 typedef struct cc_ccache_iterator_f cc_ccache_iterator_f;
446 
447 struct cc_ccache_iterator_d {
448     const cc_ccache_iterator_f *functions;
449 #if TARGET_OS_MAC
450     const cc_ccache_iterator_f *vector_functions;
451 #endif
452 };
453 typedef struct cc_ccache_iterator_d cc_ccache_iterator_d;
454 typedef cc_ccache_iterator_d *cc_ccache_iterator_t;
455 /*!@}*/
456 
457 /*!
458  * \defgroup cc_credentials_reference cc_credentials_t Overview
459  * @{
460  *
461  * The cc_credentials_t type is used to store a single set of credentials for
462  * Kerberos v5. In addition to its only function, release(), it contains a
463  * pointer to a cc_credentials_union structure. A cc_credentials_union
464  * structure contains an integer of the enumerator type
465  * cc_credentials_version, which is #cc_credentials_v5, and a pointer union,
466  * which contains a cc_credentials_v5_t pointer, depending on the value in
467  * version.
468  *
469  * Variables of the type cc_credentials_t are allocated by the CCAPI
470  * implementation, and should be released with their release()
471  * function. API functions which receive credentials structures
472  * from the caller always accept cc_credentials_union, which is
473  * allocated by the caller, and accordingly disposed by the caller.
474  *
475  * For API functions see \ref cc_credentials_f.
476  */
477 
478 /*!
479  * The CCAPI data structure.  This structure is similar to a krb5_data structure.
480  * In a v5 credentials structure, cc_data structures are used
481  * to store tagged variable-length binary data. Specifically,
482  * for cc_credentials_v5.ticket and
483  * cc_credentials_v5.second_ticket, the cc_data.type field must
484  * be zero. For the cc_credentials_v5.addresses,
485  * cc_credentials_v5.authdata, and cc_credentials_v5.keyblock,
486  * the cc_data.type field should be the address type,
487  * authorization data type, and encryption type, as defined by
488  * the Kerberos v5 protocol definition.
489  */
490 struct cc_data {
491     /*! The type of the data as defined by the krb5_data structure. */
492     cc_uint32                   type;
493     /*! The length of \a data. */
494     cc_uint32                   length;
495     /*! The data buffer. */
496     void*                       data;
497 };
498 typedef struct cc_data cc_data;
499 
500 /*!
501  * If a cc_credentials_t variable is used to store Kerberos v5 c
502  * redentials, and then credentials.credentials_v5 points to a
503  * v5 credentials structure.  This structure is similar to a
504  * krb5_creds structure.
505  */
506 struct cc_credentials_v5_t {
507     /*! A properly quoted string representation of the client principal. */
508     char*      client;
509     /*! A properly quoted string representation of the service principal. */
510     char*      server;
511     /*! Session encryption key info. */
512     cc_data    keyblock;
513     /*! The time when the ticket was issued. */
514     cc_time_t  authtime;
515     /*! The time when the ticket becomes valid. */
516     cc_time_t  starttime;
517     /*! The time when the ticket expires. */
518     cc_time_t  endtime;
519     /*! The time when the ticket becomes no longer renewable (if renewable). */
520     cc_time_t  renew_till;
521     /*! 1 if the ticket is encrypted in another ticket's key, or 0 otherwise. */
522     cc_uint32  is_skey;
523     /*! Ticket flags, as defined by the Kerberos 5 API. */
524     cc_uint32  ticket_flags;
525     /*! The the list of network addresses of hosts that are allowed to authenticate
526      * using this ticket. */
527     cc_data**  addresses;
528     /*! Ticket data. */
529     cc_data    ticket;
530     /*! Second ticket data. */
531     cc_data    second_ticket;
532     /*! Authorization data. */
533     cc_data**  authdata;
534 };
535 typedef struct cc_credentials_v5_t cc_credentials_v5_t;
536 
537 struct cc_credentials_union {
538     /*! The credentials version of this credentials object. */
539     cc_uint32                   version;
540     /*! The credentials. */
541     union {
542         /*! If \a version is #cc_credentials_v5, a pointer to a cc_credentials_v5_t. */
543         cc_credentials_v5_t*    credentials_v5;
544     }                           credentials;
545 };
546 typedef struct cc_credentials_union cc_credentials_union;
547 
548 struct cc_credentials_f;
549 typedef struct cc_credentials_f cc_credentials_f;
550 
551 struct cc_credentials_d {
552     const cc_credentials_union *data;
553     const cc_credentials_f *functions;
554 #if TARGET_OS_MAC
555     const cc_credentials_f *otherFunctions;
556 #endif
557 };
558 typedef struct cc_credentials_d cc_credentials_d;
559 typedef cc_credentials_d *cc_credentials_t;
560 /*!@}*/
561 
562 /*!
563  * \defgroup cc_credentials_iterator_reference cc_credentials_iterator_t
564  * @{
565  * The cc_credentials_iterator_t type represents an iterator that
566  * iterates over a set of credentials. A new instance of this type
567  * can be obtained by calling cc_ccache_new_credentials_iterator().
568  *
569  * For API function documentation see \ref cc_credentials_iterator_f.
570  */
571 struct cc_credentials_iterator_f;
572 typedef struct cc_credentials_iterator_f cc_credentials_iterator_f;
573 
574 struct cc_credentials_iterator_d {
575     const cc_credentials_iterator_f *functions;
576 #if TARGET_OS_MAC
577     const cc_credentials_iterator_f *vector_functions;
578 #endif
579 };
580 typedef struct cc_credentials_iterator_d cc_credentials_iterator_d;
581 typedef cc_credentials_iterator_d *cc_credentials_iterator_t;
582 /*!@}*/
583 
584 /*!
585  * \defgroup cc_string_reference cc_string_t Overview
586  * @{
587  * The cc_string_t represents a C string returned by the API.
588  * It has a pointer to the string data and a release() function.
589  * This type is used for both principal names and ccache names
590  * returned by the API. Principal names may contain UTF-8 encoded
591  * strings for internationalization purposes.
592  *
593  * For API function documentation see \ref cc_string_f.
594  */
595 struct cc_string_f;
596 typedef struct cc_string_f cc_string_f;
597 
598 struct cc_string_d {
599     const char *data;
600     const cc_string_f *functions;
601 #if TARGET_OS_MAC
602     const cc_string_f *vector_functions;
603 #endif
604 };
605 typedef struct cc_string_d cc_string_d;
606 typedef cc_string_d *cc_string_t;
607 /*!@}*/
608 
609 /*!
610  * Function pointer table for cc_context_t.  For more information see
611  * \ref cc_context_reference.
612  */
613 struct cc_context_f {
614     /*!
615      * \param io_context the context object to free.
616      * \return On success, #ccNoError.  On failure, an error code representing the failure.
617      * \brief \b cc_context_release(): Release memory associated with a cc_context_t.
618      */
619     cc_int32 (*release) (cc_context_t io_context);
620 
621     /*!
622      * \param in_context the context object for the cache collection to examine.
623      * \param out_time on exit, the time of the most recent change for the entire ccache collection.
624      * \return On success, #ccNoError.  On failure, an error code representing the failure.
625      * \brief \b cc_context_get_change_time(): Get the last time the cache collection changed.
626      *
627      * This function returns the time of the most recent change for the entire ccache collection.
628      * By maintaining a local copy the caller can deduce whether or not the ccache collection has
629      * been modified since the previous call to cc_context_get_change_time().
630      *
631      * The time returned by cc_context_get_changed_time() increases whenever:
632      *
633      * \li a ccache is created
634      * \li a ccache is destroyed
635      * \li a credential is stored
636      * \li a credential is removed
637      * \li a ccache principal is changed
638      * \li the default ccache is changed
639      *
640      * \note In order to be able to compare two values returned by cc_context_get_change_time(),
641      * the caller must use the same context to acquire them. Callers should maintain a single
642      * context in memory for cc_context_get_change_time() calls rather than creating a new
643      * context for every call.
644      *
645      * \sa wait_for_change
646      */
647     cc_int32 (*get_change_time) (cc_context_t  in_context,
648                                  cc_time_t    *out_time);
649 
650     /*!
651      * \param in_context the context object for the cache collection.
652      * \param out_name on exit, the name of the default ccache.
653      * \return On success, #ccNoError.  On failure, an error code representing the failure.
654      * \brief \b cc_context_get_default_ccache_name(): Get the name of the default ccache.
655      *
656      * This function returns the name of the default ccache. When the default ccache
657      * exists, its name is returned. If there are no ccaches in the collection, and
658      * thus there is no default ccache, the name that the default ccache should have
659      * is returned. The ccache with that name will be used as the default ccache by
660      * all processes which initialized Kerberos libraries before the ccache was created.
661      *
662      * If there is no default ccache, and the client is creating a new ccache, it
663      * should be created with the default name. If there already is a default ccache,
664      * and the client wants to create a new ccache (as opposed to reusing an existing
665      * ccache), it should be created with any unique name; #create_new_ccache()
666      * can be used to accomplish that more easily.
667      *
668      * If the first ccache is created with a name other than the default name, then
669      * the processes already running will not notice the credentials stored in the
670      * new ccache, which is normally undesirable.
671      */
672     cc_int32 (*get_default_ccache_name) (cc_context_t  in_context,
673                                          cc_string_t  *out_name);
674 
675     /*!
676      * \param in_context the context object for the cache collection.
677      * \param in_name the name of the ccache to open.
678      * \param out_ccache on exit, a ccache object for the ccache
679      * \return On success, #ccNoError.  If no ccache named \a in_name exists,
680      * #ccErrCCacheNotFound. On failure, an error code representing the failure.
681      * \brief \b cc_context_open_ccache(): Open a ccache.
682      *
683      * Opens an already existing ccache identified by its name. It returns a reference
684      * to the ccache in \a out_ccache.
685      *
686      * The list of all ccache names, principals, and credentials versions may be retrieved
687      * by calling cc_context_new_cache_iterator(), cc_ccache_get_name(),
688      * cc_ccache_get_principal(), and cc_ccache_get_cred_version().
689      */
690     cc_int32 (*open_ccache) (cc_context_t  in_context,
691                              const char   *in_name,
692                              cc_ccache_t  *out_ccache);
693 
694     /*!
695      * \param in_context the context object for the cache collection.
696      * \param out_ccache on exit, a ccache object for the default ccache
697      * \return On success, #ccNoError.  If no default ccache exists,
698      * #ccErrCCacheNotFound. On failure, an error code representing the failure.
699      * \brief \b cc_context_open_default_ccache(): Open the default ccache.
700      *
701      * Opens the default ccache. It returns a reference to the ccache in *ccache.
702      *
703      * This function performs the same function as calling
704      * cc_context_get_default_ccache_name followed by cc_context_open_ccache,
705      * but it performs it atomically.
706      */
707     cc_int32 (*open_default_ccache) (cc_context_t  in_context,
708                                      cc_ccache_t  *out_ccache);
709 
710     /*!
711      * \param in_context the context object for the cache collection.
712      * \param in_name the name of the new ccache to create
713      * \param in_cred_vers the version of the credentials the new ccache will hold
714      * \param in_principal the client principal of the credentials the new ccache will hold
715      * \param out_ccache on exit, a ccache object for the newly created ccache
716      * \return On success, #ccNoError.  On failure, an error code representing the failure.
717      * \brief \b cc_context_create_ccache(): Create a new ccache.
718      *
719      * Create a new credentials cache. The ccache is uniquely identified by
720      * its name.  The principal given is also associated with the ccache and
721      * the credentials version specified. A NULL name is not allowed (and
722      * ccErrBadName is returned if one is passed in). Only cc_credentials_v5
723      * can be an input value for cred_vers.
724      *
725      * If you want to create a new ccache (with a unique name), you should use
726      * cc_context_create_new_ccache() instead. If you want to create or reinitialize
727      * the default cache, you should use cc_context_create_default_ccache().
728      *
729      * If name is non-NULL and there is already a ccache named name:
730      *
731      * \li the credentials in the ccache whose version is cred_vers are removed
732      * \li the principal (of the existing ccache) associated with cred_vers is set to principal
733      * \li a handle for the existing ccache is returned and all existing handles for the ccache remain valid
734      *
735      * If no ccache named name already exists:
736      *
737      * \li a new empty ccache is created
738      * \li the principal of the new ccache associated with cred_vers is set to principal
739      * \li a handle for the new ccache is returned
740      *
741      * For a new ccache, the name should be any unique string. The name is not
742      * intended to be presented to users.
743      *
744      * If the created ccache is the first ccache in the collection, it is made
745      * the default ccache. Note that normally it is undesirable to create the first
746      * ccache with a name different from the default ccache name (as returned by
747      * cc_context_get_default_ccache_name()); see the description of
748      * cc_context_get_default_ccache_name() for details.
749      *
750      * The principal should be a C string containing an unparsed Kerberos
751      * principal in the format of the appropriate Kerberos version,
752      * i.e. \verbatim foo/bar/@BAZ \endverbatim for Kerberos v5.
753      */
754     cc_int32 (*create_ccache) (cc_context_t  in_context,
755                                const char   *in_name,
756                                cc_uint32     in_cred_vers,
757                                const char   *in_principal,
758                                cc_ccache_t  *out_ccache);
759 
760     /*!
761      * \param in_context the context object for the cache collection.
762      * \param in_cred_vers the version of the credentials the new default ccache will hold
763      * \param in_principal the client principal of the credentials the new default ccache will hold
764      * \param out_ccache on exit, a ccache object for the newly created default ccache
765      * \return On success, #ccNoError.  On failure, an error code representing the failure.
766      * \brief \b cc_context_create_default_ccache(): Create a new default ccache.
767      *
768      * Create the default credentials cache. The behavior of this function is
769      * similar to that of cc_create_ccache(). If there is a default ccache
770      * (which is always the case except when there are no ccaches at all in
771      * the collection), it is initialized with the specified credentials version
772      * and principal, as per cc_create_ccache(); otherwise, a new ccache is
773      * created, and its name is the name returned by
774      * cc_context_get_default_ccache_name().
775      */
776     cc_int32 (*create_default_ccache) (cc_context_t  in_context,
777                                        cc_uint32     in_cred_vers,
778                                        const char   *in_principal,
779                                        cc_ccache_t  *out_ccache);
780 
781     /*!
782      * \param in_context the context object for the cache collection.
783      * \param in_cred_vers the version of the credentials the new ccache will hold
784      * \param in_principal the client principal of the credentials the new ccache will hold
785      * \param out_ccache on exit, a ccache object for the newly created ccache
786      * \return On success, #ccNoError.  On failure, an error code representing the failure.
787      * \brief \b cc_context_create_new_ccache(): Create a new uniquely named ccache.
788      *
789      * Create a new unique credentials cache. The behavior of this function
790      * is similar to that of cc_create_ccache(). If there are no ccaches, and
791      * therefore no default ccache, the new ccache is created with the default
792      * ccache name as would be returned by get_default_ccache_name(). If there
793      * are some ccaches, and therefore there is a default ccache, the new ccache
794      * is created with a new unique name. Clearly, this function never reinitializes
795      * a ccache, since it always uses a unique name.
796      */
797     cc_int32 (*create_new_ccache) (cc_context_t in_context,
798                                    cc_uint32    in_cred_vers,
799                                    const char  *in_principal,
800                                    cc_ccache_t *out_ccache);
801 
802     /*!
803      * \param in_context the context object for the cache collection.
804      * \param out_iterator on exit, a ccache iterator object for the ccache collection.
805      * \return On success, #ccNoError.  On failure, an error code representing the failure.
806      * \brief \b cc_context_new_ccache_iterator(): Get an iterator for the cache collection.
807      *
808      * Used to allocate memory and initialize iterator. Successive calls to iterator's
809      * next() function will return ccaches in the collection.
810      *
811      * If changes are made to the collection while an iterator is being used
812      * on it, the iterator must return at least the intersection, and at most
813      * the union, of the set of ccaches that were present when the iteration
814      * began and the set of ccaches that are present when it ends.
815      */
816     cc_int32 (*new_ccache_iterator) (cc_context_t          in_context,
817                                      cc_ccache_iterator_t *out_iterator);
818 
819     /*!
820      * \param in_context the context object for the cache collection.
821      * \param in_lock_type the type of lock to obtain.
822      * \param in_block whether or not the function should block if the lock cannot be obtained immediately.
823      * \return On success, #ccNoError.  On failure, an error code representing the failure.
824      * \brief \b cc_context_lock(): Lock the cache collection.
825      *
826      * Attempts to acquire an advisory lock for the ccache collection. Allowed values
827      * for lock_type are:
828      *
829      * \li cc_lock_read: a read lock.
830      * \li cc_lock_write: a write lock
831      * \li cc_lock_upgrade: upgrade an already-obtained read lock to a write lock
832      * \li cc_lock_downgrade: downgrade an already-obtained write lock to a read lock
833      *
834      * If block is cc_lock_block, lock() will not return until the lock is acquired.
835      * If block is cc_lock_noblock, lock() will return immediately, either acquiring
836      * the lock and returning ccNoError, or failing to acquire the lock and returning
837      * an error explaining why.
838      *
839      * Locks apply only to the list of ccaches, not the contents of those ccaches.  To
840      * prevent callers participating in the advisory locking from changing the credentials
841      * in a cache you must also lock that ccache with cc_ccache_lock().  This is so
842      * that you can get the list of ccaches without preventing applications from
843      * simultaneously obtaining service tickets.
844      *
845      * To avoid having to deal with differences between thread semantics on different
846      * platforms, locks are granted per context, rather than per thread or per process.
847      * That means that different threads of execution have to acquire separate contexts
848      * in order to be able to synchronize with each other.
849      *
850      * The lock should be unlocked by using cc_context_unlock().
851      *
852      * \note All locks are advisory.  For example, callers which do not call
853      * cc_context_lock() and cc_context_unlock() will not be prevented from writing
854      * to the cache collection when you have a read lock.  This is because the CCAPI
855      * locking was added after the first release and thus adding mandatory locks would
856      * have changed the user experience and performance of existing applications.
857      */
858     cc_int32 (*lock) (cc_context_t in_context,
859                       cc_uint32    in_lock_type,
860                       cc_uint32    in_block);
861 
862     /*!
863      * \param in_context the context object for the cache collection.
864      * \return On success, #ccNoError.  On failure, an error code representing the failure.
865      * \brief \b cc_context_unlock(): Unlock the cache collection.
866      */
867     cc_int32 (*unlock) (cc_context_t in_cc_context);
868 
869     /*!
870      * \param in_context a context object.
871      * \param in_compare_to_context a context object to compare with \a in_context.
872      * \param out_equal on exit, whether or not the two contexts refer to the same cache collection.
873      * \return On success, #ccNoError.  On failure, an error code representing the failure.
874      * \brief \b cc_context_compare(): Compare two context objects.
875      */
876     cc_int32 (*compare) (cc_context_t  in_cc_context,
877                          cc_context_t  in_compare_to_context,
878                          cc_uint32    *out_equal);
879 
880     /*!
881      * \param in_context a context object.
882      * \return On success, #ccNoError.  On failure, an error code representing the failure.
883      * \brief \b cc_context_wait_for_change(): Wait for the next change in the cache collection.
884      *
885      * This function blocks until the next change is made to the cache collection
886      * ccache collection. By repeatedly calling cc_context_wait_for_change() from
887      * a worker thread the caller can effectively receive callbacks whenever the
888      * cache collection changes.  This is considerably more efficient than polling
889      * with cc_context_get_change_time().
890      *
891      * cc_context_wait_for_change() will return whenever:
892      *
893      * \li a ccache is created
894      * \li a ccache is destroyed
895      * \li a credential is stored
896      * \li a credential is removed
897      * \li a ccache principal is changed
898      * \li the default ccache is changed
899      *
900      * \note In order to make sure that the caller doesn't miss any changes,
901      * cc_context_wait_for_change() always returns immediately after the first time it
902      * is called on a new context object. Callers must use the same context object
903      * for successive calls to cc_context_wait_for_change() rather than creating a new
904      * context for every call.
905      *
906      * \sa get_change_time
907      */
908     cc_int32 (*wait_for_change) (cc_context_t in_cc_context);
909 };
910 
911 /*!
912  * Function pointer table for cc_ccache_t.  For more information see
913  * \ref cc_ccache_reference.
914  */
915 struct cc_ccache_f {
916     /*!
917      * \param io_ccache the ccache object to release.
918      * \return On success, #ccNoError.  On failure, an error code representing the failure.
919      * \brief \b cc_ccache_release(): Release memory associated with a cc_ccache_t object.
920      * \note Does not modify the ccache.  If you wish to remove the ccache see cc_ccache_destroy().
921      */
922     cc_int32 (*release) (cc_ccache_t io_ccache);
923 
924     /*!
925      * \param io_ccache the ccache object to destroy and release.
926      * \return On success, #ccNoError.  On failure, an error code representing the failure.
927      * \brief \b cc_ccache_destroy(): Destroy a ccache.
928      *
929      * Destroy the ccache referred to by \a io_ccache and releases memory associated with
930      * the \a io_ccache object.  After this call \a io_ccache becomes invalid.  If
931      * \a io_ccache was the default ccache, the next ccache in the cache collection (if any)
932      * becomes the new default.
933      */
934     cc_int32 (*destroy) (cc_ccache_t io_ccache);
935 
936     /*!
937      * \param io_ccache a ccache object to make the new default ccache.
938      * \return On success, #ccNoError.  On failure, an error code representing the failure.
939      * \brief \b cc_ccache_set_default(): Make a ccache the default ccache.
940      */
941     cc_int32 (*set_default) (cc_ccache_t io_ccache);
942 
943     /*!
944      * \param in_ccache a ccache object.
945      * \param out_credentials_version on exit, the credentials version of \a in_ccache.
946      * \return On success, #ccNoError.  On failure, an error code representing the failure.
947      * \brief \b cc_ccache_get_credentials_version(): Get the credentials version of a ccache.
948      *
949      * cc_ccache_get_credentials_version() returns one value of the enumerated
950      * type cc_credentials_vers. The return value is #cc_credentials_v5 (if
951      * ccache's v5 principal has been set).  A ccache's principal is set with
952      * one of cc_context_create_ccache(), cc_context_create_new_ccache(),
953      * cc_context_create_default_ccache(), or cc_ccache_set_principal().
954      */
955     cc_int32 (*get_credentials_version) (cc_ccache_t  in_ccache,
956                                          cc_uint32   *out_credentials_version);
957 
958     /*!
959      * \param in_ccache a ccache object.
960      * \param out_name on exit, a cc_string_t representing the name of \a in_ccache.
961      * \a out_name must be released with cc_string_release().
962      * \return On success, #ccNoError.  On failure, an error code representing the failure.
963      * \brief \b cc_ccache_get_name(): Get the name of a ccache.
964      */
965     cc_int32 (*get_name) (cc_ccache_t  in_ccache,
966                           cc_string_t *out_name);
967 
968     /*!
969      * \param in_ccache a ccache object.
970      * \param in_credentials_version the credentials version to get the principal for.
971      * \param out_principal on exit, a cc_string_t representing the principal of \a in_ccache.
972      * \a out_principal must be released with cc_string_release().
973      * \return On success, #ccNoError.  On failure, an error code representing the failure.
974      * \brief \b cc_ccache_get_principal(): Get the principal of a ccache.
975      *
976      * Return the principal for the ccache that was set via cc_context_create_ccache(),
977      * cc_context_create_default_ccache(), cc_context_create_new_ccache(), or
978      * cc_ccache_set_principal().
979      */
980     cc_int32 (*get_principal) (cc_ccache_t  in_ccache,
981                                cc_uint32    in_credentials_version,
982                                cc_string_t *out_principal);
983 
984 
985     /*!
986      * \param in_ccache a ccache object.
987      * \param in_credentials_version the credentials version to set the principal for.
988      * \param in_principal a C string representing the new principal of \a in_ccache.
989      * \return On success, #ccNoError.  On failure, an error code representing the failure.
990      * \brief \b cc_ccache_set_principal(): Set the principal of a ccache.
991      *
992      * Set the a principal for ccache.
993      */
994     cc_int32 (*set_principal) (cc_ccache_t  io_ccache,
995                                cc_uint32    in_credentials_version,
996                                const char  *in_principal);
997 
998     /*!
999      * \param io_ccache a ccache object.
1000      * \param in_credentials_union the credentials to store in \a io_ccache.
1001      * \return On success, #ccNoError.  On failure, an error code representing the failure.
1002      * \brief \b cc_ccache_store_credentials(): Store credentials in a ccache.
1003      *
1004      * Store a copy of credentials in the ccache.
1005      *
1006      * See the description of the credentials types for the meaning of
1007      * cc_credentials_union fields.
1008      *
1009      * Before credentials of a specific credential type can be stored in a
1010      * ccache, the corresponding principal version has to be set.  That is,
1011      * before you can store Kerberos v5 credentials in a ccache, the Kerberos
1012      * v5 principal has to be set either by cc_context_create_ccache(),
1013      * cc_context_create_default_ccache(), cc_context_create_new_ccache(), or
1014      * cc_ccache_set_principal(); otherwise, ccErrBadCredentialsVersion is
1015      * returned.
1016      */
1017     cc_int32 (*store_credentials) (cc_ccache_t                 io_ccache,
1018                                    const cc_credentials_union *in_credentials_union);
1019 
1020     /*!
1021      * \param io_ccache a ccache object.
1022      * \param in_credentials the credentials to remove from \a io_ccache.
1023      * \return On success, #ccNoError.  On failure, an error code representing the failure.
1024      * \brief \b cc_ccache_remove_credentials(): Remove credentials from a ccache.
1025      *
1026      * Removes credentials from a ccache. Note that credentials must be previously
1027      * acquired from the CCache API; only exactly matching credentials will be
1028      * removed. (This places the burden of determining exactly which credentials
1029      * to remove on the caller, but ensures there is no ambigity about which
1030      * credentials will be removed.) cc_credentials_t objects can be obtained by
1031      * iterating over the ccache's credentials with cc_ccache_new_credentials_iterator().
1032      *
1033      * If found, the credentials are removed from the ccache. The credentials
1034      * parameter is not modified and should be freed by the caller. It is
1035      * legitimate to call this function while an iterator is traversing the
1036      * ccache, and the deletion of a credential already returned by
1037      * cc_credentials_iterator_next() will not disturb sequence of credentials
1038      * returned by cc_credentials_iterator_next().
1039      */
1040     cc_int32 (*remove_credentials) (cc_ccache_t      io_ccache,
1041                                     cc_credentials_t in_credentials);
1042 
1043     /*!
1044      * \param in_ccache a ccache object.
1045      * \param out_credentials_iterator a credentials iterator for \a io_ccache.
1046      * \return On success, #ccNoError.  On failure, an error code representing the failure.
1047      * \brief \b cc_ccache_new_credentials_iterator(): Iterate over credentials in a ccache.
1048      *
1049      * Allocates memory for iterator and initializes it. Successive calls to
1050      * cc_credentials_iterator_next() will return credentials from the ccache.
1051      *
1052      * If changes are made to the ccache while an iterator is being used on it,
1053      * the iterator must return at least the intersection, and at most the union,
1054      * of the set of credentials that were in the ccache when the iteration began
1055      * and the set of credentials that are in the ccache when it ends.
1056      */
1057     cc_int32 (*new_credentials_iterator) (cc_ccache_t                in_ccache,
1058                                           cc_credentials_iterator_t *out_credentials_iterator);
1059 
1060     /*!
1061      * \param io_source_ccache a ccache object to move.
1062      * \param io_destination_ccache a ccache object replace with the contents of \a io_source_ccache.
1063      * \return On success, #ccNoError.  On failure, an error code representing the failure.
1064      * \brief \b cc_ccache_move(): Move the contents of one ccache into another, destroying the source.
1065      *
1066      * cc_ccache_move() atomically copies the credentials, credential versions and principals
1067      * from one ccache to another.  On successful completion \a io_source_ccache will be
1068      * released and the ccache it points to will be destroyed.  Any credentials previously
1069      * in \a io_destination_ccache will be replaced with credentials from \a io_source_ccache.
1070      * The only part of \a io_destination_ccache which remains constant is the name.  Any other
1071      * callers referring to \a io_destination_ccache will suddenly see new data in it.
1072      *
1073      * Typically cc_ccache_move() is used when the caller wishes to safely overwrite the
1074      * contents of a ccache with new data which requires several steps to generate.
1075      * cc_ccache_move() allows the caller to create a temporary ccache
1076      * (which can be destroyed if any intermediate step fails) and the atomically copy
1077      * the temporary cache into the destination.
1078      */
1079     cc_int32 (*move) (cc_ccache_t io_source_ccache,
1080                       cc_ccache_t io_destination_ccache);
1081 
1082     /*!
1083      * \param io_ccache the ccache object for the ccache you wish to lock.
1084      * \param in_lock_type the type of lock to obtain.
1085      * \param in_block whether or not the function should block if the lock cannot be obtained immediately.
1086      * \return On success, #ccNoError.  On failure, an error code representing the failure.
1087      * \brief \b cc_ccache_lock(): Lock a ccache.
1088      *
1089      * Attempts to acquire an advisory lock for a ccache. Allowed values for lock_type are:
1090      *
1091      * \li cc_lock_read: a read lock.
1092      * \li cc_lock_write: a write lock
1093      * \li cc_lock_upgrade: upgrade an already-obtained read lock to a write lock
1094      * \li cc_lock_downgrade: downgrade an already-obtained write lock to a read lock
1095      *
1096      * If block is cc_lock_block, lock() will not return until the lock is acquired.
1097      * If block is cc_lock_noblock, lock() will return immediately, either acquiring
1098      * the lock and returning ccNoError, or failing to acquire the lock and returning
1099      * an error explaining why.
1100      *
1101      * To avoid having to deal with differences between thread semantics on different
1102      * platforms, locks are granted per ccache, rather than per thread or per process.
1103      * That means that different threads of execution have to acquire separate contexts
1104      * in order to be able to synchronize with each other.
1105      *
1106      * The lock should be unlocked by using cc_ccache_unlock().
1107      *
1108      * \note All locks are advisory.  For example, callers which do not call
1109      * cc_ccache_lock() and cc_ccache_unlock() will not be prevented from writing
1110      * to the ccache when you have a read lock.  This is because the CCAPI
1111      * locking was added after the first release and thus adding mandatory locks would
1112      * have changed the user experience and performance of existing applications.
1113      */
1114     cc_int32 (*lock) (cc_ccache_t io_ccache,
1115                       cc_uint32   in_lock_type,
1116                       cc_uint32   in_block);
1117 
1118     /*!
1119      * \param io_ccache a ccache object.
1120      * \return On success, #ccNoError.  On failure, an error code representing the failure.
1121      * \brief \b cc_ccache_unlock(): Unlock a ccache.
1122      */
1123     cc_int32 (*unlock) (cc_ccache_t io_ccache);
1124 
1125     /*!
1126      * \param in_ccache a cache object.
1127      * \param out_last_default_time on exit, the last time the ccache was default.
1128      * \return On success, #ccNoError.  On failure, an error code representing the failure.
1129      * \brief \b cc_ccache_get_change_time(): Get the last time a ccache was the default ccache.
1130      *
1131      * This function returns the last time when the ccache was made the default ccache.
1132      * This allows clients to sort the ccaches by how recently they were default, which
1133      * is useful for user listing of ccaches. If the ccache was never default,
1134      * ccErrNeverDefault is returned.
1135      */
1136     cc_int32 (*get_last_default_time) (cc_ccache_t  in_ccache,
1137                                        cc_time_t   *out_last_default_time);
1138 
1139     /*!
1140      * \param in_ccache a cache object.
1141      * \param out_change_time on exit, the last time the ccache changed.
1142      * \return On success, #ccNoError.  If the ccache was never the default ccache,
1143      * #ccErrNeverDefault.  Otherwise, an error code representing the failure.
1144      * \brief \b cc_ccache_get_change_time(): Get the last time a ccache changed.
1145      *
1146      * This function returns the time of the most recent change made to a ccache.
1147      * By maintaining a local copy the caller can deduce whether or not the ccache has
1148      * been modified since the previous call to cc_ccache_get_change_time().
1149      *
1150      * The time returned by cc_ccache_get_change_time() increases whenever:
1151      *
1152      * \li a credential is stored
1153      * \li a credential is removed
1154      * \li a ccache principal is changed
1155      * \li the ccache becomes the default ccache
1156      * \li the ccache is no longer the default ccache
1157      *
1158      * \note In order to be able to compare two values returned by cc_ccache_get_change_time(),
1159      * the caller must use the same ccache object to acquire them. Callers should maintain a
1160      * single ccache object in memory for cc_ccache_get_change_time() calls rather than
1161      * creating a new ccache object for every call.
1162      *
1163      * \sa wait_for_change
1164      */
1165     cc_int32 (*get_change_time) (cc_ccache_t  in_ccache,
1166                                  cc_time_t   *out_change_time);
1167 
1168     /*!
1169      * \param in_ccache a ccache object.
1170      * \param in_compare_to_ccache a ccache object to compare with \a in_ccache.
1171      * \param out_equal on exit, whether or not the two ccaches refer to the same ccache.
1172      * \return On success, #ccNoError.  On failure, an error code representing the failure.
1173      * \brief \b cc_ccache_compare(): Compare two ccache objects.
1174      */
1175     cc_int32 (*compare) (cc_ccache_t  in_ccache,
1176                          cc_ccache_t  in_compare_to_ccache,
1177                          cc_uint32   *out_equal);
1178 
1179     /*!
1180      * \param in_ccache a ccache object.
1181      * \param in_credentials_version the credentials version to get the time offset for.
1182      * \param out_time_offset on exit, the KDC time offset for \a in_ccache for credentials version
1183      * \a in_credentials_version.
1184      * \return On success, #ccNoError if a time offset was obtained or #ccErrTimeOffsetNotSet
1185      * if a time offset has not been set.  On failure, an error code representing the failure.
1186      * \brief \b cc_ccache_get_kdc_time_offset(): Get the KDC time offset for credentials in a ccache.
1187      * \sa set_kdc_time_offset, clear_kdc_time_offset
1188      *
1189      * Sometimes the KDC and client's clocks get out of sync.  cc_ccache_get_kdc_time_offset()
1190      * returns the difference between the KDC and client's clocks at the time credentials were
1191      * acquired.  This offset allows callers to figure out how much time is left on a given
1192      * credential even though the end_time is based on the KDC's clock not the client's clock.
1193      */
1194     cc_int32 (*get_kdc_time_offset) (cc_ccache_t  in_ccache,
1195                                      cc_uint32    in_credentials_version,
1196                                      cc_time_t   *out_time_offset);
1197 
1198     /*!
1199      * \param in_ccache a ccache object.
1200      * \param in_credentials_version the credentials version to get the time offset for.
1201      * \param in_time_offset the new KDC time offset for \a in_ccache for credentials version
1202      * \a in_credentials_version.
1203      * \return On success, #ccNoError.  On failure, an error code representing the failure.
1204      * \brief \b cc_ccache_set_kdc_time_offset(): Set the KDC time offset for credentials in a ccache.
1205      * \sa get_kdc_time_offset, clear_kdc_time_offset
1206      *
1207      * Sometimes the KDC and client's clocks get out of sync.  cc_ccache_set_kdc_time_offset()
1208      * sets the difference between the KDC and client's clocks at the time credentials were
1209      * acquired.  This offset allows callers to figure out how much time is left on a given
1210      * credential even though the end_time is based on the KDC's clock not the client's clock.
1211      */
1212     cc_int32 (*set_kdc_time_offset) (cc_ccache_t io_ccache,
1213                                      cc_uint32   in_credentials_version,
1214                                      cc_time_t   in_time_offset);
1215 
1216     /*!
1217      * \param in_ccache a ccache object.
1218      * \param in_credentials_version the credentials version to get the time offset for.
1219      * \return On success, #ccNoError.  On failure, an error code representing the failure.
1220      * \brief \b cc_ccache_clear_kdc_time_offset(): Clear the KDC time offset for credentials in a ccache.
1221      * \sa get_kdc_time_offset, set_kdc_time_offset
1222      *
1223      * Sometimes the KDC and client's clocks get out of sync.  cc_ccache_clear_kdc_time_offset()
1224      * clears the difference between the KDC and client's clocks at the time credentials were
1225      * acquired.  This offset allows callers to figure out how much time is left on a given
1226      * credential even though the end_time is based on the KDC's clock not the client's clock.
1227      */
1228     cc_int32 (*clear_kdc_time_offset) (cc_ccache_t io_ccache,
1229                                        cc_uint32   in_credentials_version);
1230 
1231     /*!
1232      * \param in_ccache a ccache object.
1233      * \return On success, #ccNoError.  On failure, an error code representing the failure.
1234      * \brief \b cc_ccache_wait_for_change(): Wait for the next change to a ccache.
1235      *
1236      * This function blocks until the next change is made to the ccache referenced by
1237      * \a in_ccache. By repeatedly calling cc_ccache_wait_for_change() from
1238      * a worker thread the caller can effectively receive callbacks whenever the
1239      * ccache changes.  This is considerably more efficient than polling
1240      * with cc_ccache_get_change_time().
1241      *
1242      * cc_ccache_wait_for_change() will return whenever:
1243      *
1244      * \li a credential is stored
1245      * \li a credential is removed
1246      * \li the ccache principal is changed
1247      * \li the ccache becomes the default ccache
1248      * \li the ccache is no longer the default ccache
1249      *
1250      * \note In order to make sure that the caller doesn't miss any changes,
1251      * cc_ccache_wait_for_change() always returns immediately after the first time it
1252      * is called on a new ccache object. Callers must use the same ccache object
1253      * for successive calls to cc_ccache_wait_for_change() rather than creating a new
1254      * ccache object for every call.
1255      *
1256      * \sa get_change_time
1257      */
1258     cc_int32 (*wait_for_change) (cc_ccache_t in_ccache);
1259 };
1260 
1261 /*!
1262  * Function pointer table for cc_string_t.  For more information see
1263  * \ref cc_string_reference.
1264  */
1265 struct cc_string_f {
1266     /*!
1267      * \param io_string the string object to release.
1268      * \return On success, #ccNoError.  On failure, an error code representing the failure.
1269      * \brief \b cc_string_release(): Release memory associated with a cc_string_t object.
1270      */
1271     cc_int32 (*release) (cc_string_t io_string);
1272 };
1273 
1274 /*!
1275  * Function pointer table for cc_credentials_t.  For more information see
1276  * \ref cc_credentials_reference.
1277  */
1278 struct cc_credentials_f {
1279     /*!
1280      * \param io_credentials the credentials object to release.
1281      * \return On success, #ccNoError.  On failure, an error code representing the failure.
1282      * \brief \b cc_credentials_release(): Release memory associated with a cc_credentials_t object.
1283      */
1284     cc_int32 (*release) (cc_credentials_t  io_credentials);
1285 
1286     /*!
1287      * \param in_credentials a credentials object.
1288      * \param in_compare_to_credentials a credentials object to compare with \a in_credentials.
1289      * \param out_equal on exit, whether or not the two credentials objects refer to the
1290      * same credentials in the cache collection.
1291      * \return On success, #ccNoError.  On failure, an error code representing the failure.
1292      * \brief \b cc_credentials_compare(): Compare two credentials objects.
1293      */
1294     cc_int32 (*compare) (cc_credentials_t  in_credentials,
1295                          cc_credentials_t  in_compare_to_credentials,
1296                          cc_uint32        *out_equal);
1297 };
1298 
1299 /*!
1300  * Function pointer table for cc_ccache_iterator_t.  For more information see
1301  * \ref cc_ccache_iterator_reference.
1302  */
1303 struct cc_ccache_iterator_f {
1304     /*!
1305      * \param io_ccache_iterator the ccache iterator object to release.
1306      * \return On success, #ccNoError.  On failure, an error code representing the failure.
1307      * \brief \b cc_ccache_iterator_release(): Release memory associated with a cc_ccache_iterator_t object.
1308      */
1309     cc_int32 (*release) (cc_ccache_iterator_t io_ccache_iterator);
1310 
1311     /*!
1312      * \param in_ccache_iterator a ccache iterator object.
1313      * \param out_ccache on exit, the next ccache in the cache collection.
1314      * \return On success, #ccNoError if the next ccache in the cache collection was
1315      * obtained or #ccIteratorEnd if there are no more ccaches.
1316      * On failure, an error code representing the failure.
1317      * \brief \b cc_ccache_iterator_next(): Get the next ccache in the cache collection.
1318      */
1319     cc_int32 (*next) (cc_ccache_iterator_t  in_ccache_iterator,
1320                       cc_ccache_t          *out_ccache);
1321 
1322     /*!
1323      * \param in_ccache_iterator a ccache iterator object.
1324      * \param out_ccache_iterator on exit, a copy of \a in_ccache_iterator.
1325      * \return On success, #ccNoError.  On failure, an error code representing the failure.
1326      * \brief \b cc_ccache_iterator_clone(): Make a copy of a ccache iterator.
1327      */
1328     cc_int32 (*clone) (cc_ccache_iterator_t  in_ccache_iterator,
1329                        cc_ccache_iterator_t *out_ccache_iterator);
1330 };
1331 
1332 /*!
1333  * Function pointer table for cc_credentials_iterator_t.  For more information see
1334  * \ref cc_credentials_iterator_reference.
1335  */
1336 struct cc_credentials_iterator_f {
1337     /*!
1338      * \param io_credentials_iterator the credentials iterator object to release.
1339      * \return On success, #ccNoError.  On failure, an error code representing the failure.
1340      * \brief \b cc_credentials_iterator_release(): Release memory associated with a cc_credentials_iterator_t object.
1341      */
1342     cc_int32 (*release) (cc_credentials_iterator_t io_credentials_iterator);
1343 
1344     /*!
1345      * \param in_credentials_iterator a credentials iterator object.
1346      * \param out_credentials on exit, the next credentials in the ccache.
1347      * \return On success, #ccNoError if the next credential in the ccache was obtained
1348      * or #ccIteratorEnd if there are no more credentials.
1349      * On failure, an error code representing the failure.
1350      * \brief \b cc_credentials_iterator_next(): Get the next credentials in the ccache.
1351      */
1352     cc_int32 (*next) (cc_credentials_iterator_t  in_credentials_iterator,
1353                       cc_credentials_t          *out_credentials);
1354 
1355     /*!
1356      * \ingroup cc_credentials_iterator_reference
1357      * \param in_credentials_iterator a credentials iterator object.
1358      * \param out_credentials_iterator on exit, a copy of \a in_credentials_iterator.
1359      * \return On success, #ccNoError.  On failure, an error code representing the failure.
1360      * \brief \b cc_credentials_iterator_clone(): Make a copy of a credentials iterator.
1361      */
1362     cc_int32 (*clone) (cc_credentials_iterator_t  in_credentials_iterator,
1363                        cc_credentials_iterator_t *out_credentials_iterator);
1364 };
1365 
1366 /*!
1367  * \ingroup cc_context_reference
1368  * \param out_context on exit, a new context object.  Must be free with cc_context_release().
1369  * \param in_version  the requested API version.  This should be the maximum version the
1370  * application supports.
1371  * \param out_supported_version if non-NULL, on exit contains the maximum API version
1372  * supported by the implementation.
1373  * \param out_vendor if non-NULL, on exit contains a pointer to a read-only C string which
1374  * contains a string describing the vendor which implemented the credentials cache API.
1375  * \return On success, #ccNoError.  On failure, an error code representing the failure.
1376  * May return CCAPI v2 error CC_BAD_API_VERSION if #ccapi_version_2 is passed in.
1377  * \brief Initialize a new cc_context.
1378  */
1379 CCACHE_API cc_int32 cc_initialize (cc_context_t  *out_context,
1380                                    cc_int32       in_version,
1381                                    cc_int32      *out_supported_version,
1382                                    char const   **out_vendor);
1383 
1384 
1385 /*! \defgroup helper_macros CCAPI Function Helper Macros
1386  * @{ */
1387 
1388 /*! Helper macro for cc_context_f release() */
1389 #define         cc_context_release(context)             \
1390     ((context) -> functions -> release (context))
1391 /*! Helper macro for cc_context_f get_change_time() */
1392 #define         cc_context_get_change_time(context, change_time)        \
1393     ((context) -> functions -> get_change_time (context, change_time))
1394 /*! Helper macro for cc_context_f get_default_ccache_name() */
1395 #define         cc_context_get_default_ccache_name(context, name)       \
1396     ((context) -> functions -> get_default_ccache_name (context, name))
1397 /*! Helper macro for cc_context_f open_ccache() */
1398 #define         cc_context_open_ccache(context, name, ccache)           \
1399     ((context) -> functions -> open_ccache (context, name, ccache))
1400 /*! Helper macro for cc_context_f open_default_ccache() */
1401 #define         cc_context_open_default_ccache(context, ccache)         \
1402     ((context) -> functions -> open_default_ccache (context, ccache))
1403 /*! Helper macro for cc_context_f create_ccache() */
1404 #define         cc_context_create_ccache(context, name, version, principal, ccache) \
1405     ((context) -> functions -> create_ccache (context, name, version, principal, ccache))
1406 /*! Helper macro for cc_context_f create_default_ccache() */
1407 #define         cc_context_create_default_ccache(context, version, principal, ccache) \
1408     ((context) -> functions -> create_default_ccache (context, version, principal, ccache))
1409 /*! Helper macro for cc_context_f create_new_ccache() */
1410 #define         cc_context_create_new_ccache(context, version, principal, ccache) \
1411     ((context) -> functions -> create_new_ccache (context, version, principal, ccache))
1412 /*! Helper macro for cc_context_f new_ccache_iterator() */
1413 #define         cc_context_new_ccache_iterator(context, iterator)       \
1414     ((context) -> functions -> new_ccache_iterator (context, iterator))
1415 /*! Helper macro for cc_context_f lock() */
1416 #define         cc_context_lock(context, type, block)           \
1417     ((context) -> functions -> lock (context, type, block))
1418 /*! Helper macro for cc_context_f unlock() */
1419 #define         cc_context_unlock(context)              \
1420     ((context) -> functions -> unlock (context))
1421 /*! Helper macro for cc_context_f compare() */
1422 #define         cc_context_compare(context, compare_to, equal)          \
1423     ((context) -> functions -> compare (context, compare_to, equal))
1424 /*! Helper macro for cc_context_f wait_for_change() */
1425 #define         cc_context_wait_for_change(context)             \
1426     ((context) -> functions -> wait_for_change (context))
1427 
1428 /*! Helper macro for cc_ccache_f release() */
1429 #define         cc_ccache_release(ccache)       \
1430     ((ccache) -> functions -> release (ccache))
1431 /*! Helper macro for cc_ccache_f destroy() */
1432 #define         cc_ccache_destroy(ccache)       \
1433     ((ccache) -> functions -> destroy (ccache))
1434 /*! Helper macro for cc_ccache_f set_default() */
1435 #define         cc_ccache_set_default(ccache)           \
1436     ((ccache) -> functions -> set_default (ccache))
1437 /*! Helper macro for cc_ccache_f get_credentials_version() */
1438 #define         cc_ccache_get_credentials_version(ccache, version)      \
1439     ((ccache) -> functions -> get_credentials_version (ccache, version))
1440 /*! Helper macro for cc_ccache_f get_name() */
1441 #define         cc_ccache_get_name(ccache, name)        \
1442     ((ccache) -> functions -> get_name (ccache, name))
1443 /*! Helper macro for cc_ccache_f get_principal() */
1444 #define         cc_ccache_get_principal(ccache, version, principal)     \
1445     ((ccache) -> functions -> get_principal (ccache, version, principal))
1446 /*! Helper macro for cc_ccache_f set_principal() */
1447 #define         cc_ccache_set_principal(ccache, version, principal)     \
1448     ((ccache) -> functions -> set_principal (ccache, version, principal))
1449 /*! Helper macro for cc_ccache_f store_credentials() */
1450 #define         cc_ccache_store_credentials(ccache, credentials)        \
1451     ((ccache) -> functions -> store_credentials (ccache, credentials))
1452 /*! Helper macro for cc_ccache_f remove_credentials() */
1453 #define         cc_ccache_remove_credentials(ccache, credentials)       \
1454     ((ccache) -> functions -> remove_credentials (ccache, credentials))
1455 /*! Helper macro for cc_ccache_f new_credentials_iterator() */
1456 #define         cc_ccache_new_credentials_iterator(ccache, iterator)    \
1457     ((ccache) -> functions -> new_credentials_iterator (ccache, iterator))
1458 /*! Helper macro for cc_ccache_f lock() */
1459 #define         cc_ccache_lock(ccache, type, block)             \
1460     ((ccache) -> functions -> lock (ccache, type, block))
1461 /*! Helper macro for cc_ccache_f unlock() */
1462 #define         cc_ccache_unlock(ccache)        \
1463     ((ccache) -> functions -> unlock (ccache))
1464 /*! Helper macro for cc_ccache_f get_last_default_time() */
1465 #define         cc_ccache_get_last_default_time(ccache, last_default_time) \
1466     ((ccache) -> functions -> get_last_default_time (ccache, last_default_time))
1467 /*! Helper macro for cc_ccache_f get_change_time() */
1468 #define         cc_ccache_get_change_time(ccache, change_time)          \
1469     ((ccache) -> functions -> get_change_time (ccache, change_time))
1470 /*! Helper macro for cc_ccache_f move() */
1471 #define         cc_ccache_move(source, destination)             \
1472     ((source) -> functions -> move (source, destination))
1473 /*! Helper macro for cc_ccache_f compare() */
1474 #define         cc_ccache_compare(ccache, compare_to, equal)            \
1475     ((ccache) -> functions -> compare (ccache, compare_to, equal))
1476 /*! Helper macro for cc_ccache_f get_kdc_time_offset() */
1477 #define         cc_ccache_get_kdc_time_offset(ccache, version, time_offset) \
1478     ((ccache) -> functions -> get_kdc_time_offset (ccache, version, time_offset))
1479 /*! Helper macro for cc_ccache_f set_kdc_time_offset() */
1480 #define         cc_ccache_set_kdc_time_offset(ccache, version, time_offset) \
1481     ((ccache) -> functions -> set_kdc_time_offset (ccache, version, time_offset))
1482 /*! Helper macro for cc_ccache_f clear_kdc_time_offset() */
1483 #define         cc_ccache_clear_kdc_time_offset(ccache, version)        \
1484     ((ccache) -> functions -> clear_kdc_time_offset (ccache, version))
1485 /*! Helper macro for cc_ccache_f wait_for_change() */
1486 #define         cc_ccache_wait_for_change(ccache)       \
1487     ((ccache) -> functions -> wait_for_change (ccache))
1488 
1489 /*! Helper macro for cc_string_f release() */
1490 #define         cc_string_release(string)       \
1491     ((string) -> functions -> release (string))
1492 
1493 /*! Helper macro for cc_credentials_f release() */
1494 #define         cc_credentials_release(credentials)             \
1495     ((credentials) -> functions -> release (credentials))
1496 /*! Helper macro for cc_credentials_f compare() */
1497 #define         cc_credentials_compare(credentials, compare_to, equal)  \
1498     ((credentials) -> functions -> compare (credentials, compare_to, equal))
1499 
1500 /*! Helper macro for cc_ccache_iterator_f release() */
1501 #define         cc_ccache_iterator_release(iterator)    \
1502     ((iterator) -> functions -> release (iterator))
1503 /*! Helper macro for cc_ccache_iterator_f next() */
1504 #define         cc_ccache_iterator_next(iterator, ccache)       \
1505     ((iterator) -> functions -> next (iterator, ccache))
1506 /*! Helper macro for cc_ccache_iterator_f clone() */
1507 #define         cc_ccache_iterator_clone(iterator, new_iterator)        \
1508     ((iterator) -> functions -> clone (iterator, new_iterator))
1509 
1510 /*! Helper macro for cc_credentials_iterator_f release() */
1511 #define         cc_credentials_iterator_release(iterator)       \
1512     ((iterator) -> functions -> release (iterator))
1513 /*! Helper macro for cc_credentials_iterator_f next() */
1514 #define         cc_credentials_iterator_next(iterator, credentials)     \
1515     ((iterator) -> functions -> next (iterator, credentials))
1516 /*! Helper macro for cc_credentials_iterator_f clone() */
1517 #define         cc_credentials_iterator_clone(iterator, new_iterator)   \
1518     ((iterator) -> functions -> clone (iterator, new_iterator))
1519 /*!@}*/
1520 
1521 #if defined(__APPLE__) && (defined(__ppc__) || defined(__ppc64__) || defined(__i386__) || defined(__x86_64__))
1522 #pragma pack(pop)
1523 #endif
1524 
1525 #ifdef __cplusplus
1526 }
1527 #endif /* __cplusplus */
1528 
1529 #endif /* __CREDENTIALSCACHE__ */
1530