1/*
2 * $Header$
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
52extern "C" {
53#endif /* __cplusplus */
54
55#if TARGET_OS_MAC
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 both Kerberos v5 and v4. The idea behind this API is that
108 * multiple Kerberos implementations can share a single collection of
109 * credentials caches, mediated by this API specification. On the Mac OS
110 * and Microsoft Windows platforms this will allow single-login, even when
111 * more 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 stores both
119 * Kerberos v4 and v5 credentials 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 */
247enum {
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 */
260enum {
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
309 * between Kerberos v4 and Kerberos v5. Not all values are valid
310 * inputs and outputs for all functions; function specifications
311 * below detail the allowed values.
312 *
313 * Kerberos version constants will always be a bit-field, and can be
314 * tested as such; for example the following test will tell you if
315 * a ccacheVersion includes v5 credentials:
316 *
317 * if ((ccacheVersion & cc_credentials_v5) != 0)
318 */
319enum cc_credential_versions {
320    cc_credentials_v4 = 1,
321    cc_credentials_v5 = 2,
322    cc_credentials_v4_v5 = 3
323};
324
325/*!
326 * Lock types
327 *
328 * These constants are used in the locking functions to describe the
329 * type of lock requested.  Note that all CCAPI locks are advisory
330 * so only callers using the lock calls will be blocked by each other.
331 * This is because locking functions were introduced after the CCAPI
332 * came into common use and we did not want to break existing callers.
333 */
334enum cc_lock_types {
335    cc_lock_read = 0,
336    cc_lock_write = 1,
337    cc_lock_upgrade = 2,
338    cc_lock_downgrade = 3
339};
340
341/*!
342 * Locking Modes
343 *
344 * These constants are used in the advisory locking functions to
345 * describe whether or not the lock function should block waiting for
346 * a lock or return an error immediately.   For example, attempting to
347 * acquire a lock with a non-blocking call will result in an error if the
348 * lock cannot be acquired; otherwise, the call will block until the lock
349 * can be acquired.
350 */
351enum cc_lock_modes {
352    cc_lock_noblock = 0,
353    cc_lock_block = 1
354};
355
356/*!
357 * Sizes of fields in cc_credentials_v4_t.
358 */
359enum {
360    /* Make sure all of these are multiples of four (for alignment sanity) */
361    cc_v4_name_size     = 40,
362    cc_v4_instance_size	= 40,
363    cc_v4_realm_size    = 40,
364    cc_v4_ticket_size   = 1254,
365    cc_v4_key_size      = 8
366};
367
368/*!
369 * String to key type (Kerberos v4 only)
370 */
371enum cc_string_to_key_type {
372    cc_v4_stk_afs = 0,
373    cc_v4_stk_des = 1,
374    cc_v4_stk_columbia_special = 2,
375    cc_v4_stk_krb5 = 3,
376    cc_v4_stk_unknown = 4
377};
378
379/*!@}*/
380
381/*!
382 * \defgroup ccapi_types_reference Basic Types
383 * @{
384 */
385
386/*! Unsigned 32-bit integer type */
387typedef uint32_t            cc_uint32;
388/*! Signed 32-bit integer type */
389typedef int32_t             cc_int32;
390#if defined (WIN32)
391typedef __int64             cc_int64;
392typedef unsigned __int64    cc_uint64;
393#else
394/*! Unsigned 64-bit integer type */
395typedef int64_t             cc_int64;
396/*! Signed 64-bit integer type */
397typedef uint64_t            cc_uint64;
398#endif
399/*!
400 * The cc_time_t type is used to represent a time in seconds. The time must
401 * be stored as the number of seconds since midnight GMT on January 1, 1970.
402 */
403typedef cc_uint32           cc_time_t;
404
405/*!@}*/
406
407/*!
408 * \defgroup cc_context_reference cc_context_t Overview
409 * @{
410 *
411 * The cc_context_t type gives the caller access to a ccache collection.
412 * Before being able to call any functions in the CCache API, the caller
413 * needs to acquire an instance of cc_context_t by calling cc_initialize().
414 *
415 * For API function documentation see \ref cc_context_f.
416 */
417struct cc_context_f;
418typedef struct cc_context_f cc_context_f;
419
420struct cc_context_d {
421    const cc_context_f *functions;
422#if TARGET_OS_MAC
423    const cc_context_f *vector_functions;
424#endif
425};
426typedef struct cc_context_d cc_context_d;
427typedef cc_context_d *cc_context_t;
428
429/*!@}*/
430
431/*!
432 * \defgroup cc_ccache_reference cc_ccache_t Overview
433 * @{
434 *
435 * The cc_ccache_t type represents a reference to a ccache.
436 * Callers can access a ccache and the credentials stored in it
437 * via a cc_ccache_t. A cc_ccache_t can be acquired via
438 * cc_context_open_ccache(), cc_context_open_default_ccache(), or
439 * cc_ccache_iterator_next().
440 *
441 * For API function documentation see \ref cc_ccache_f.
442 */
443struct cc_ccache_f;
444typedef struct cc_ccache_f cc_ccache_f;
445
446struct cc_ccache_d {
447    const cc_ccache_f *functions;
448#if TARGET_OS_MAC
449    const cc_ccache_f *vector_functions;
450#endif
451};
452typedef struct cc_ccache_d cc_ccache_d;
453typedef cc_ccache_d *cc_ccache_t;
454
455/*!@}*/
456
457/*!
458 * \defgroup cc_ccache_iterator_reference cc_ccache_iterator_t Overview
459 * @{
460 *
461 * The cc_ccache_iterator_t type represents an iterator that
462 * iterates over a set of ccaches and returns them in all in some
463 * order. A new instance of this type can be obtained by calling
464 * cc_context_new_ccache_iterator().
465 *
466 * For API function documentation see \ref cc_ccache_iterator_f.
467 */
468struct cc_ccache_iterator_f;
469typedef struct cc_ccache_iterator_f cc_ccache_iterator_f;
470
471struct cc_ccache_iterator_d {
472    const cc_ccache_iterator_f *functions;
473#if TARGET_OS_MAC
474    const cc_ccache_iterator_f *vector_functions;
475#endif
476};
477typedef struct cc_ccache_iterator_d cc_ccache_iterator_d;
478typedef cc_ccache_iterator_d *cc_ccache_iterator_t;
479/*!@}*/
480
481/*!
482 * \defgroup cc_credentials_reference cc_credentials_t Overview
483 * @{
484 *
485 * The cc_credentials_t type is used to store a single set of
486 * credentials for either Kerberos v4 or Kerberos v5. In addition
487 * to its only function, release(), it contains a pointer to a
488 * cc_credentials_union structure. A cc_credentials_union
489 * structure contains an integer of the enumerator type
490 * cc_credentials_version, which is either #cc_credentials_v4 or
491 * #cc_credentials_v5, and a pointer union, which contains either a
492 * cc_credentials_v4_t pointer or a cc_credentials_v5_t pointer,
493 * depending on the value in version.
494 *
495 * Variables of the type cc_credentials_t are allocated by the CCAPI
496 * implementation, and should be released with their release()
497 * function. API functions which receive credentials structures
498 * from the caller always accept cc_credentials_union, which is
499 * allocated by the caller, and accordingly disposed by the caller.
500 *
501 * For API functions see \ref cc_credentials_f.
502 */
503
504/*!
505 * If a cc_credentials_t variable is used to store Kerberos v4
506 * credentials, then credentials.credentials_v4 points to a v4
507 * credentials structure.  This structure is similar to a
508 * krb4 API CREDENTIALS structure.
509 */
510struct cc_credentials_v4_t {
511    cc_uint32       version;
512    /*! A properly quoted string representation of the first component of the client principal */
513    char            principal [cc_v4_name_size];
514    /*! A properly quoted string representation of the second component of the client principal */
515    char            principal_instance [cc_v4_instance_size];
516    /*! A properly quoted string representation of the first component of the service principal */
517    char            service [cc_v4_name_size];
518    /*! A properly quoted string representation of the second component of the service principal */
519    char            service_instance [cc_v4_instance_size];
520    /*! A properly quoted string representation of the realm */
521    char            realm [cc_v4_realm_size];
522    /*! Ticket session key */
523    unsigned char   session_key [cc_v4_key_size];
524    /*! Key version number */
525    cc_int32        kvno;
526    /*! String to key type used.  See cc_string_to_key_type for valid values */
527    cc_int32        string_to_key_type;
528    /*! Time when the ticket was issued */
529    cc_time_t       issue_date;
530    /*! Ticket lifetime in 5 minute units */
531    cc_int32        lifetime;
532    /*! IPv4 address of the client the ticket was issued for */
533    cc_uint32       address;
534    /*! Ticket size (no greater than cc_v4_ticket_size) */
535    cc_int32        ticket_size;
536    /*! Ticket data */
537    unsigned char   ticket [cc_v4_ticket_size];
538};
539typedef struct cc_credentials_v4_t cc_credentials_v4_t;
540
541/*!
542 * The CCAPI data structure.  This structure is similar to a krb5_data structure.
543 * In a v5 credentials structure, cc_data structures are used
544 * to store tagged variable-length binary data. Specifically,
545 * for cc_credentials_v5.ticket and
546 * cc_credentials_v5.second_ticket, the cc_data.type field must
547 * be zero. For the cc_credentials_v5.addresses,
548 * cc_credentials_v5.authdata, and cc_credentials_v5.keyblock,
549 * the cc_data.type field should be the address type,
550 * authorization data type, and encryption type, as defined by
551 * the Kerberos v5 protocol definition.
552 */
553struct cc_data {
554    /*! The type of the data as defined by the krb5_data structure. */
555    cc_uint32			type;
556    /*! The length of \a data. */
557    cc_uint32			length;
558    /*! The data buffer. */
559    void*			data;
560};
561typedef struct cc_data cc_data;
562
563/*!
564 * If a cc_credentials_t variable is used to store Kerberos v5 c
565 * redentials, and then credentials.credentials_v5 points to a
566 * v5 credentials structure.  This structure is similar to a
567 * krb5_creds structure.
568 */
569struct cc_credentials_v5_t {
570    /*! A properly quoted string representation of the client principal. */
571    char*      client;
572    /*! A properly quoted string representation of the service principal. */
573    char*      server;
574    /*! Session encryption key info. */
575    cc_data    keyblock;
576    /*! The time when the ticket was issued. */
577    cc_time_t  authtime;
578    /*! The time when the ticket becomes valid. */
579    cc_time_t  starttime;
580    /*! The time when the ticket expires. */
581    cc_time_t  endtime;
582    /*! The time when the ticket becomes no longer renewable (if renewable). */
583    cc_time_t  renew_till;
584    /*! 1 if the ticket is encrypted in another ticket's key, or 0 otherwise. */
585    cc_uint32  is_skey;
586    /*! Ticket flags, as defined by the Kerberos 5 API. */
587    cc_uint32  ticket_flags;
588    /*! The the list of network addresses of hosts that are allowed to authenticate
589     * using this ticket. */
590    cc_data**  addresses;
591    /*! Ticket data. */
592    cc_data    ticket;
593    /*! Second ticket data. */
594    cc_data    second_ticket;
595    /*! Authorization data. */
596    cc_data**  authdata;
597};
598typedef struct cc_credentials_v5_t cc_credentials_v5_t;
599
600struct cc_credentials_union {
601    /*! The credentials version of this credentials object. */
602    cc_uint32			version;
603    /*! The credentials. */
604    union {
605	/*! If \a version is #cc_credentials_v4, a pointer to a cc_credentials_v4_t. */
606        cc_credentials_v4_t*	credentials_v4;
607	/*! If \a version is #cc_credentials_v5, a pointer to a cc_credentials_v5_t. */
608        cc_credentials_v5_t*	credentials_v5;
609    }				credentials;
610};
611typedef struct cc_credentials_union cc_credentials_union;
612
613struct cc_credentials_f;
614typedef struct cc_credentials_f cc_credentials_f;
615
616struct cc_credentials_d {
617    const cc_credentials_union *data;
618    const cc_credentials_f *functions;
619#if TARGET_OS_MAC
620    const cc_credentials_f *otherFunctions;
621#endif
622};
623typedef struct cc_credentials_d cc_credentials_d;
624typedef cc_credentials_d *cc_credentials_t;
625/*!@}*/
626
627/*!
628 * \defgroup cc_credentials_iterator_reference cc_credentials_iterator_t
629 * @{
630 * The cc_credentials_iterator_t type represents an iterator that
631 * iterates over a set of credentials. A new instance of this type
632 * can be obtained by calling cc_ccache_new_credentials_iterator().
633 *
634 * For API function documentation see \ref cc_credentials_iterator_f.
635 */
636struct cc_credentials_iterator_f;
637typedef struct cc_credentials_iterator_f cc_credentials_iterator_f;
638
639struct cc_credentials_iterator_d {
640    const cc_credentials_iterator_f *functions;
641#if TARGET_OS_MAC
642    const cc_credentials_iterator_f *vector_functions;
643#endif
644};
645typedef struct cc_credentials_iterator_d cc_credentials_iterator_d;
646typedef cc_credentials_iterator_d *cc_credentials_iterator_t;
647/*!@}*/
648
649/*!
650 * \defgroup cc_string_reference cc_string_t Overview
651 * @{
652 * The cc_string_t represents a C string returned by the API.
653 * It has a pointer to the string data and a release() function.
654 * This type is used for both principal names and ccache names
655 * returned by the API. Principal names may contain UTF-8 encoded
656 * strings for internationalization purposes.
657 *
658 * For API function documentation see \ref cc_string_f.
659 */
660struct cc_string_f;
661typedef struct cc_string_f cc_string_f;
662
663struct cc_string_d {
664    const char *data;
665    const cc_string_f *functions;
666#if TARGET_OS_MAC
667    const cc_string_f *vector_functions;
668#endif
669};
670typedef struct cc_string_d cc_string_d;
671typedef cc_string_d *cc_string_t;
672/*!@}*/
673
674/*!
675 * Function pointer table for cc_context_t.  For more information see
676 * \ref cc_context_reference.
677 */
678struct cc_context_f {
679    /*!
680     * \param io_context the context object to free.
681     * \return On success, #ccNoError.  On failure, an error code representing the failure.
682     * \brief \b cc_context_release(): Release memory associated with a cc_context_t.
683     */
684    cc_int32 (*release) (cc_context_t io_context);
685
686    /*!
687     * \param in_context the context object for the cache collection to examine.
688     * \param out_time on exit, the time of the most recent change for the entire ccache collection.
689     * \return On success, #ccNoError.  On failure, an error code representing the failure.
690     * \brief \b cc_context_get_change_time(): Get the last time the cache collection changed.
691     *
692     * This function returns the time of the most recent change for the entire ccache collection.
693     * By maintaining a local copy the caller can deduce whether or not the ccache collection has
694     * been modified since the previous call to cc_context_get_change_time().
695     *
696     * The time returned by cc_context_get_changed_time() increases whenever:
697     *
698     * \li a ccache is created
699     * \li a ccache is destroyed
700     * \li a credential is stored
701     * \li a credential is removed
702     * \li a ccache principal is changed
703     * \li the default ccache is changed
704     *
705     * \note In order to be able to compare two values returned by cc_context_get_change_time(),
706     * the caller must use the same context to acquire them. Callers should maintain a single
707     * context in memory for cc_context_get_change_time() calls rather than creating a new
708     * context for every call.
709     *
710     * \sa wait_for_change
711     */
712    cc_int32 (*get_change_time) (cc_context_t  in_context,
713                                 cc_time_t    *out_time);
714
715    /*!
716     * \param in_context the context object for the cache collection.
717     * \param out_name on exit, the name of the default ccache.
718     * \return On success, #ccNoError.  On failure, an error code representing the failure.
719     * \brief \b cc_context_get_default_ccache_name(): Get the name of the default ccache.
720     *
721     * This function returns the name of the default ccache. When the default ccache
722     * exists, its name is returned. If there are no ccaches in the collection, and
723     * thus there is no default ccache, the name that the default ccache should have
724     * is returned. The ccache with that name will be used as the default ccache by
725     * all processes which initialized Kerberos libraries before the ccache was created.
726     *
727     * If there is no default ccache, and the client is creating a new ccache, it
728     * should be created with the default name. If there already is a default ccache,
729     * and the client wants to create a new ccache (as opposed to reusing an existing
730     * ccache), it should be created with any unique name; #create_new_ccache()
731     * can be used to accomplish that more easily.
732     *
733     * If the first ccache is created with a name other than the default name, then
734     * the processes already running will not notice the credentials stored in the
735     * new ccache, which is normally undesirable.
736     */
737    cc_int32 (*get_default_ccache_name) (cc_context_t  in_context,
738                                         cc_string_t  *out_name);
739
740    /*!
741     * \param in_context the context object for the cache collection.
742     * \param in_name the name of the ccache to open.
743     * \param out_ccache on exit, a ccache object for the ccache
744     * \return On success, #ccNoError.  If no ccache named \a in_name exists,
745     * #ccErrCCacheNotFound. On failure, an error code representing the failure.
746     * \brief \b cc_context_open_ccache(): Open a ccache.
747     *
748     * Opens an already existing ccache identified by its name. It returns a reference
749     * to the ccache in \a out_ccache.
750     *
751     * The list of all ccache names, principals, and credentials versions may be retrieved
752     * by calling cc_context_new_cache_iterator(), cc_ccache_get_name(),
753     * cc_ccache_get_principal(), and cc_ccache_get_cred_version().
754     */
755    cc_int32 (*open_ccache) (cc_context_t  in_context,
756                             const char   *in_name,
757                             cc_ccache_t  *out_ccache);
758
759     /*!
760      * \param in_context the context object for the cache collection.
761      * \param out_ccache on exit, a ccache object for the default ccache
762      * \return On success, #ccNoError.  If no default ccache exists,
763      * #ccErrCCacheNotFound. On failure, an error code representing the failure.
764      * \brief \b cc_context_open_default_ccache(): Open the default ccache.
765      *
766      * Opens the default ccache. It returns a reference to the ccache in *ccache.
767      *
768      * This function performs the same function as calling
769      * cc_context_get_default_ccache_name followed by cc_context_open_ccache,
770      * but it performs it atomically.
771      */
772    cc_int32 (*open_default_ccache) (cc_context_t  in_context,
773                                     cc_ccache_t  *out_ccache);
774
775     /*!
776      * \param in_context the context object for the cache collection.
777      * \param in_name the name of the new ccache to create
778      * \param in_cred_vers the version of the credentials the new ccache will hold
779      * \param in_principal the client principal of the credentials the new ccache will hold
780      * \param out_ccache on exit, a ccache object for the newly created ccache
781      * \return On success, #ccNoError.  On failure, an error code representing the failure.
782      * \brief \b cc_context_create_ccache(): Create a new ccache.
783      *
784      * Create a new credentials cache. The ccache is uniquely identified by its name.
785      * The principal given is also associated with the ccache and the credentials
786      * version specified. A NULL name is not allowed (and ccErrBadName is returned
787      * if one is passed in). Only cc_credentials_v4 and cc_credentials_v5 are valid
788      * input values for cred_vers. If you want to create a new ccache that will hold
789      * both versions of credentials, call cc_context_create_ccache() with one version,
790      * and then cc_ccache_set_principal() with the other version.
791      *
792      * If you want to create a new ccache (with a unique name), you should use
793      * cc_context_create_new_ccache() instead. If you want to create or reinitialize
794      * the default cache, you should use cc_context_create_default_ccache().
795      *
796      * If name is non-NULL and there is already a ccache named name:
797      *
798      * \li the credentials in the ccache whose version is cred_vers are removed
799      * \li the principal (of the existing ccache) associated with cred_vers is set to principal
800      * \li a handle for the existing ccache is returned and all existing handles for the ccache remain valid
801      *
802      * If no ccache named name already exists:
803      *
804      * \li a new empty ccache is created
805      * \li the principal of the new ccache associated with cred_vers is set to principal
806      * \li a handle for the new ccache is returned
807      *
808      * For a new ccache, the name should be any unique string. The name is not
809      * intended to be presented to users.
810      *
811      * If the created ccache is the first ccache in the collection, it is made
812      * the default ccache. Note that normally it is undesirable to create the first
813      * ccache with a name different from the default ccache name (as returned by
814      * cc_context_get_default_ccache_name()); see the description of
815      * cc_context_get_default_ccache_name() for details.
816      *
817      * The principal should be a C string containing an unparsed Kerberos principal
818      * in the format of the appropriate Kerberos version, i.e. \verbatim foo.bar/@BAZ
819      * \endverbatim for Kerberos v4 and \verbatim foo/bar/@BAZ \endverbatim
820      * for Kerberos v5.
821      */
822     cc_int32 (*create_ccache) (cc_context_t  in_context,
823                               const char   *in_name,
824                               cc_uint32     in_cred_vers,
825                               const char   *in_principal,
826                               cc_ccache_t  *out_ccache);
827
828     /*!
829      * \param in_context the context object for the cache collection.
830      * \param in_cred_vers the version of the credentials the new default ccache will hold
831      * \param in_principal the client principal of the credentials the new default ccache will hold
832      * \param out_ccache on exit, a ccache object for the newly created default ccache
833      * \return On success, #ccNoError.  On failure, an error code representing the failure.
834      * \brief \b cc_context_create_default_ccache(): Create a new default ccache.
835      *
836      * Create the default credentials cache. The behavior of this function is
837      * similar to that of cc_create_ccache(). If there is a default ccache
838      * (which is always the case except when there are no ccaches at all in
839      * the collection), it is initialized with the specified credentials version
840      * and principal, as per cc_create_ccache(); otherwise, a new ccache is
841      * created, and its name is the name returned by
842      * cc_context_get_default_ccache_name().
843      */
844     cc_int32 (*create_default_ccache) (cc_context_t  in_context,
845                                       cc_uint32     in_cred_vers,
846                                       const char   *in_principal,
847                                       cc_ccache_t  *out_ccache);
848
849     /*!
850      * \param in_context the context object for the cache collection.
851      * \param in_cred_vers the version of the credentials the new ccache will hold
852      * \param in_principal the client principal of the credentials the new ccache will hold
853      * \param out_ccache on exit, a ccache object for the newly created ccache
854      * \return On success, #ccNoError.  On failure, an error code representing the failure.
855      * \brief \b cc_context_create_new_ccache(): Create a new uniquely named ccache.
856      *
857      * Create a new unique credentials cache. The behavior of this function
858      * is similar to that of cc_create_ccache(). If there are no ccaches, and
859      * therefore no default ccache, the new ccache is created with the default
860      * ccache name as would be returned by get_default_ccache_name(). If there
861      * are some ccaches, and therefore there is a default ccache, the new ccache
862      * is created with a new unique name. Clearly, this function never reinitializes
863      * a ccache, since it always uses a unique name.
864      */
865     cc_int32 (*create_new_ccache) (cc_context_t in_context,
866                                   cc_uint32    in_cred_vers,
867                                   const char  *in_principal,
868                                   cc_ccache_t *out_ccache);
869
870     /*!
871      * \param in_context the context object for the cache collection.
872      * \param out_iterator on exit, a ccache iterator object for the ccache collection.
873      * \return On success, #ccNoError.  On failure, an error code representing the failure.
874      * \brief \b cc_context_new_ccache_iterator(): Get an iterator for the cache collection.
875      *
876      * Used to allocate memory and initialize iterator. Successive calls to iterator's
877      * next() function will return ccaches in the collection.
878      *
879      * If changes are made to the collection while an iterator is being used
880      * on it, the iterator must return at least the intersection, and at most
881      * the union, of the set of ccaches that were present when the iteration
882      * began and the set of ccaches that are present when it ends.
883      */
884     cc_int32 (*new_ccache_iterator) (cc_context_t          in_context,
885                                     cc_ccache_iterator_t *out_iterator);
886
887     /*!
888      * \param in_context the context object for the cache collection.
889      * \param in_lock_type the type of lock to obtain.
890      * \param in_block whether or not the function should block if the lock cannot be obtained immediately.
891      * \return On success, #ccNoError.  On failure, an error code representing the failure.
892      * \brief \b cc_context_lock(): Lock the cache collection.
893      *
894      * Attempts to acquire an advisory lock for the ccache collection. Allowed values
895      * for lock_type are:
896      *
897      * \li cc_lock_read: a read lock.
898      * \li cc_lock_write: a write lock
899      * \li cc_lock_upgrade: upgrade an already-obtained read lock to a write lock
900      * \li cc_lock_downgrade: downgrade an already-obtained write lock to a read lock
901      *
902      * If block is cc_lock_block, lock() will not return until the lock is acquired.
903      * If block is cc_lock_noblock, lock() will return immediately, either acquiring
904      * the lock and returning ccNoError, or failing to acquire the lock and returning
905      * an error explaining why.
906      *
907      * Locks apply only to the list of ccaches, not the contents of those ccaches.  To
908      * prevent callers participating in the advisory locking from changing the credentials
909      * in a cache you must also lock that ccache with cc_ccache_lock().  This is so
910      * that you can get the list of ccaches without preventing applications from
911      * simultaneously obtaining service tickets.
912      *
913      * To avoid having to deal with differences between thread semantics on different
914      * platforms, locks are granted per context, rather than per thread or per process.
915      * That means that different threads of execution have to acquire separate contexts
916      * in order to be able to synchronize with each other.
917      *
918      * The lock should be unlocked by using cc_context_unlock().
919      *
920      * \note All locks are advisory.  For example, callers which do not call
921      * cc_context_lock() and cc_context_unlock() will not be prevented from writing
922      * to the cache collection when you have a read lock.  This is because the CCAPI
923      * locking was added after the first release and thus adding mandatory locks would
924      * have changed the user experience and performance of existing applications.
925      */
926     cc_int32 (*lock) (cc_context_t in_context,
927                      cc_uint32    in_lock_type,
928                      cc_uint32    in_block);
929
930     /*!
931      * \param in_context the context object for the cache collection.
932      * \return On success, #ccNoError.  On failure, an error code representing the failure.
933      * \brief \b cc_context_unlock(): Unlock the cache collection.
934      */
935     cc_int32 (*unlock) (cc_context_t in_cc_context);
936
937     /*!
938      * \param in_context a context object.
939      * \param in_compare_to_context a context object to compare with \a in_context.
940      * \param out_equal on exit, whether or not the two contexts refer to the same cache collection.
941      * \return On success, #ccNoError.  On failure, an error code representing the failure.
942      * \brief \b cc_context_compare(): Compare two context objects.
943      */
944     cc_int32 (*compare) (cc_context_t  in_cc_context,
945			  cc_context_t  in_compare_to_context,
946			  cc_uint32    *out_equal);
947
948     /*!
949      * \param in_context a context object.
950      * \return On success, #ccNoError.  On failure, an error code representing the failure.
951      * \brief \b cc_context_wait_for_change(): Wait for the next change in the cache collection.
952      *
953      * This function blocks until the next change is made to the cache collection
954      * ccache collection. By repeatedly calling cc_context_wait_for_change() from
955      * a worker thread the caller can effectively receive callbacks whenever the
956      * cache collection changes.  This is considerably more efficient than polling
957      * with cc_context_get_change_time().
958      *
959      * cc_context_wait_for_change() will return whenever:
960      *
961      * \li a ccache is created
962      * \li a ccache is destroyed
963      * \li a credential is stored
964      * \li a credential is removed
965      * \li a ccache principal is changed
966      * \li the default ccache is changed
967      *
968      * \note In order to make sure that the caller doesn't miss any changes,
969      * cc_context_wait_for_change() always returns immediately after the first time it
970      * is called on a new context object. Callers must use the same context object
971      * for successive calls to cc_context_wait_for_change() rather than creating a new
972      * context for every call.
973      *
974      * \sa get_change_time
975      */
976     cc_int32 (*wait_for_change) (cc_context_t in_cc_context);
977};
978
979/*!
980 * Function pointer table for cc_ccache_t.  For more information see
981 * \ref cc_ccache_reference.
982 */
983struct cc_ccache_f {
984    /*!
985     * \param io_ccache the ccache object to release.
986     * \return On success, #ccNoError.  On failure, an error code representing the failure.
987     * \brief \b cc_ccache_release(): Release memory associated with a cc_ccache_t object.
988     * \note Does not modify the ccache.  If you wish to remove the ccache see cc_ccache_destroy().
989     */
990    cc_int32 (*release) (cc_ccache_t io_ccache);
991
992    /*!
993     * \param io_ccache the ccache object to destroy and release.
994     * \return On success, #ccNoError.  On failure, an error code representing the failure.
995     * \brief \b cc_ccache_destroy(): Destroy a ccache.
996     *
997     * Destroy the ccache referred to by \a io_ccache and releases memory associated with
998     * the \a io_ccache object.  After this call \a io_ccache becomes invalid.  If
999     * \a io_ccache was the default ccache, the next ccache in the cache collection (if any)
1000     * becomes the new default.
1001     */
1002    cc_int32 (*destroy) (cc_ccache_t io_ccache);
1003
1004    /*!
1005     * \param io_ccache a ccache object to make the new default ccache.
1006     * \return On success, #ccNoError.  On failure, an error code representing the failure.
1007     * \brief \b cc_ccache_set_default(): Make a ccache the default ccache.
1008     */
1009    cc_int32 (*set_default) (cc_ccache_t io_ccache);
1010
1011    /*!
1012     * \param in_ccache a ccache object.
1013     * \param out_credentials_version on exit, the credentials version of \a in_ccache.
1014     * \return On success, #ccNoError.  On failure, an error code representing the failure.
1015     * \brief \b cc_ccache_get_credentials_version(): Get the credentials version of a ccache.
1016     *
1017     * cc_ccache_get_credentials_version() returns one value of the enumerated type
1018     * cc_credentials_vers. The possible return values are #cc_credentials_v4
1019     * (if ccache's v4 principal has been set), #cc_credentials_v5
1020     * (if ccache's v5 principal has been set), or #cc_credentials_v4_v5
1021     * (if both ccache's v4 and v5 principals have been set). A ccache's
1022     * principal is set with one of cc_context_create_ccache(),
1023     * cc_context_create_new_ccache(), cc_context_create_default_ccache(), or
1024     * cc_ccache_set_principal().
1025     */
1026    cc_int32 (*get_credentials_version) (cc_ccache_t  in_ccache,
1027                                         cc_uint32   *out_credentials_version);
1028
1029    /*!
1030     * \param in_ccache a ccache object.
1031     * \param out_name on exit, a cc_string_t representing the name of \a in_ccache.
1032     * \a out_name must be released with cc_string_release().
1033     * \return On success, #ccNoError.  On failure, an error code representing the failure.
1034     * \brief \b cc_ccache_get_name(): Get the name of a ccache.
1035     */
1036    cc_int32 (*get_name) (cc_ccache_t  in_ccache,
1037                          cc_string_t *out_name);
1038
1039    /*!
1040     * \param in_ccache a ccache object.
1041     * \param in_credentials_version the credentials version to get the principal for.
1042     * \param out_principal on exit, a cc_string_t representing the principal of \a in_ccache.
1043     * \a out_principal must be released with cc_string_release().
1044     * \return On success, #ccNoError.  On failure, an error code representing the failure.
1045     * \brief \b cc_ccache_get_principal(): Get the principal of a ccache.
1046     *
1047     * Return the principal for the ccache that was set via cc_context_create_ccache(),
1048     * cc_context_create_default_ccache(), cc_context_create_new_ccache(), or
1049     * cc_ccache_set_principal(). Principals for v4 and v5 are separate, but
1050     * should be kept synchronized for each ccache; they can be retrieved by
1051     * passing cc_credentials_v4 or cc_credentials_v5 in cred_vers. Passing
1052     * cc_credentials_v4_v5 will result in the error ccErrBadCredentialsVersion.
1053     */
1054    cc_int32 (*get_principal) (cc_ccache_t  in_ccache,
1055                               cc_uint32    in_credentials_version,
1056                               cc_string_t *out_principal);
1057
1058
1059    /*!
1060     * \param in_ccache a ccache object.
1061     * \param in_credentials_version the credentials version to set the principal for.
1062     * \param in_principal a C string representing the new principal of \a in_ccache.
1063     * \return On success, #ccNoError.  On failure, an error code representing the failure.
1064     * \brief \b cc_ccache_set_principal(): Set the principal of a ccache.
1065     *
1066     * Set the a principal for ccache. The v4 and v5 principals can be set
1067     * independently, but they should always be kept equal, up to differences in
1068     * string representation between v4 and v5. Passing cc_credentials_v4_v5 in
1069     * cred_vers will result in the error ccErrBadCredentialsVersion.
1070     */
1071    cc_int32 (*set_principal) (cc_ccache_t  io_ccache,
1072                               cc_uint32    in_credentials_version,
1073                               const char  *in_principal);
1074
1075    /*!
1076     * \param io_ccache a ccache object.
1077     * \param in_credentials_union the credentials to store in \a io_ccache.
1078     * \return On success, #ccNoError.  On failure, an error code representing the failure.
1079     * \brief \b cc_ccache_store_credentials(): Store credentials in a ccache.
1080     *
1081     * Store a copy of credentials in the ccache.
1082     *
1083     * See the description of the credentials types for the meaning of
1084     * cc_credentials_union fields.
1085     *
1086     * Before credentials of a specific credential type can be stored in a ccache,
1087     * the corresponding principal version has to be set. For example, before you can
1088     * store Kerberos v4 credentials in a ccache, the Kerberos v4 principal has to be set
1089     * either by cc_context_create_ccache(), cc_context_create_default_ccache(),
1090     * cc_context_create_new_ccache(), or cc_ccache_set_principal(); likewise for
1091     * Kerberos v5. Otherwise, ccErrBadCredentialsVersion is returned.
1092     */
1093    cc_int32 (*store_credentials) (cc_ccache_t                 io_ccache,
1094                                   const cc_credentials_union *in_credentials_union);
1095
1096    /*!
1097     * \param io_ccache a ccache object.
1098     * \param in_credentials the credentials to remove from \a io_ccache.
1099     * \return On success, #ccNoError.  On failure, an error code representing the failure.
1100     * \brief \b cc_ccache_remove_credentials(): Remove credentials from a ccache.
1101     *
1102     * Removes credentials from a ccache. Note that credentials must be previously
1103     * acquired from the CCache API; only exactly matching credentials will be
1104     * removed. (This places the burden of determining exactly which credentials
1105     * to remove on the caller, but ensures there is no ambigity about which
1106     * credentials will be removed.) cc_credentials_t objects can be obtained by
1107     * iterating over the ccache's credentials with cc_ccache_new_credentials_iterator().
1108     *
1109     * If found, the credentials are removed from the ccache. The credentials
1110     * parameter is not modified and should be freed by the caller. It is
1111     * legitimate to call this function while an iterator is traversing the
1112     * ccache, and the deletion of a credential already returned by
1113     * cc_credentials_iterator_next() will not disturb sequence of credentials
1114     * returned by cc_credentials_iterator_next().
1115     */
1116    cc_int32 (*remove_credentials) (cc_ccache_t      io_ccache,
1117                                    cc_credentials_t in_credentials);
1118
1119    /*!
1120     * \param in_ccache a ccache object.
1121     * \param out_credentials_iterator a credentials iterator for \a io_ccache.
1122     * \return On success, #ccNoError.  On failure, an error code representing the failure.
1123     * \brief \b cc_ccache_new_credentials_iterator(): Iterate over credentials in a ccache.
1124     *
1125     * Allocates memory for iterator and initializes it. Successive calls to
1126     * cc_credentials_iterator_next() will return credentials from the ccache.
1127     *
1128     * If changes are made to the ccache while an iterator is being used on it,
1129     * the iterator must return at least the intersection, and at most the union,
1130     * of the set of credentials that were in the ccache when the iteration began
1131     * and the set of credentials that are in the ccache when it ends.
1132     */
1133    cc_int32 (*new_credentials_iterator) (cc_ccache_t                in_ccache,
1134                                          cc_credentials_iterator_t *out_credentials_iterator);
1135
1136    /*!
1137     * \param io_source_ccache a ccache object to move.
1138     * \param io_destination_ccache a ccache object replace with the contents of \a io_source_ccache.
1139     * \return On success, #ccNoError.  On failure, an error code representing the failure.
1140     * \brief \b cc_ccache_move(): Move the contents of one ccache into another, destroying the source.
1141     *
1142     * cc_ccache_move() atomically copies the credentials, credential versions and principals
1143     * from one ccache to another.  On successful completion \a io_source_ccache will be
1144     * released and the ccache it points to will be destroyed.  Any credentials previously
1145     * in \a io_destination_ccache will be replaced with credentials from \a io_source_ccache.
1146     * The only part of \a io_destination_ccache which remains constant is the name.  Any other
1147     * callers referring to \a io_destination_ccache will suddenly see new data in it.
1148     *
1149     * Typically cc_ccache_move() is used when the caller wishes to safely overwrite the
1150     * contents of a ccache with new data which requires several steps to generate.
1151     * cc_ccache_move() allows the caller to create a temporary ccache
1152     * (which can be destroyed if any intermediate step fails) and the atomically copy
1153     * the temporary cache into the destination.
1154     */
1155    cc_int32 (*move) (cc_ccache_t io_source_ccache,
1156                      cc_ccache_t io_destination_ccache);
1157
1158    /*!
1159     * \param io_ccache the ccache object for the ccache you wish to lock.
1160     * \param in_lock_type the type of lock to obtain.
1161     * \param in_block whether or not the function should block if the lock cannot be obtained immediately.
1162     * \return On success, #ccNoError.  On failure, an error code representing the failure.
1163     * \brief \b cc_ccache_lock(): Lock a ccache.
1164     *
1165     * Attempts to acquire an advisory lock for a ccache. Allowed values for lock_type are:
1166     *
1167     * \li cc_lock_read: a read lock.
1168     * \li cc_lock_write: a write lock
1169     * \li cc_lock_upgrade: upgrade an already-obtained read lock to a write lock
1170     * \li cc_lock_downgrade: downgrade an already-obtained write lock to a read lock
1171     *
1172     * If block is cc_lock_block, lock() will not return until the lock is acquired.
1173     * If block is cc_lock_noblock, lock() will return immediately, either acquiring
1174     * the lock and returning ccNoError, or failing to acquire the lock and returning
1175     * an error explaining why.
1176     *
1177     * To avoid having to deal with differences between thread semantics on different
1178     * platforms, locks are granted per ccache, rather than per thread or per process.
1179     * That means that different threads of execution have to acquire separate contexts
1180     * in order to be able to synchronize with each other.
1181     *
1182     * The lock should be unlocked by using cc_ccache_unlock().
1183     *
1184     * \note All locks are advisory.  For example, callers which do not call
1185     * cc_ccache_lock() and cc_ccache_unlock() will not be prevented from writing
1186     * to the ccache when you have a read lock.  This is because the CCAPI
1187     * locking was added after the first release and thus adding mandatory locks would
1188     * have changed the user experience and performance of existing applications.
1189     */
1190    cc_int32 (*lock) (cc_ccache_t io_ccache,
1191                      cc_uint32   in_lock_type,
1192                      cc_uint32   in_block);
1193
1194    /*!
1195     * \param io_ccache a ccache object.
1196     * \return On success, #ccNoError.  On failure, an error code representing the failure.
1197     * \brief \b cc_ccache_unlock(): Unlock a ccache.
1198     */
1199    cc_int32 (*unlock) (cc_ccache_t io_ccache);
1200
1201    /*!
1202     * \param in_ccache a cache object.
1203     * \param out_last_default_time on exit, the last time the ccache was default.
1204     * \return On success, #ccNoError.  On failure, an error code representing the failure.
1205     * \brief \b cc_ccache_get_change_time(): Get the last time a ccache was the default ccache.
1206     *
1207     * This function returns the last time when the ccache was made the default ccache.
1208     * This allows clients to sort the ccaches by how recently they were default, which
1209     * is useful for user listing of ccaches. If the ccache was never default,
1210     * ccErrNeverDefault is returned.
1211     */
1212    cc_int32 (*get_last_default_time) (cc_ccache_t  in_ccache,
1213                                       cc_time_t   *out_last_default_time);
1214
1215    /*!
1216     * \param in_ccache a cache object.
1217     * \param out_change_time on exit, the last time the ccache changed.
1218     * \return On success, #ccNoError.  If the ccache was never the default ccache,
1219     * #ccErrNeverDefault.  Otherwise, an error code representing the failure.
1220     * \brief \b cc_ccache_get_change_time(): Get the last time a ccache changed.
1221     *
1222     * This function returns the time of the most recent change made to a ccache.
1223     * By maintaining a local copy the caller can deduce whether or not the ccache has
1224     * been modified since the previous call to cc_ccache_get_change_time().
1225     *
1226     * The time returned by cc_ccache_get_change_time() increases whenever:
1227     *
1228     * \li a credential is stored
1229     * \li a credential is removed
1230     * \li a ccache principal is changed
1231     * \li the ccache becomes the default ccache
1232     * \li the ccache is no longer the default ccache
1233     *
1234     * \note In order to be able to compare two values returned by cc_ccache_get_change_time(),
1235     * the caller must use the same ccache object to acquire them. Callers should maintain a
1236     * single ccache object in memory for cc_ccache_get_change_time() calls rather than
1237     * creating a new ccache object for every call.
1238     *
1239     * \sa wait_for_change
1240     */
1241    cc_int32 (*get_change_time) (cc_ccache_t  in_ccache,
1242                                 cc_time_t   *out_change_time);
1243
1244    /*!
1245     * \param in_ccache a ccache object.
1246     * \param in_compare_to_ccache a ccache object to compare with \a in_ccache.
1247     * \param out_equal on exit, whether or not the two ccaches refer to the same ccache.
1248     * \return On success, #ccNoError.  On failure, an error code representing the failure.
1249     * \brief \b cc_ccache_compare(): Compare two ccache objects.
1250     */
1251    cc_int32 (*compare) (cc_ccache_t  in_ccache,
1252                         cc_ccache_t  in_compare_to_ccache,
1253                         cc_uint32   *out_equal);
1254
1255    /*!
1256     * \param in_ccache a ccache object.
1257     * \param in_credentials_version the credentials version to get the time offset for.
1258     * \param out_time_offset on exit, the KDC time offset for \a in_ccache for credentials version
1259     * \a in_credentials_version.
1260     * \return On success, #ccNoError if a time offset was obtained or #ccErrTimeOffsetNotSet
1261     * if a time offset has not been set.  On failure, an error code representing the failure.
1262     * \brief \b cc_ccache_get_kdc_time_offset(): Get the KDC time offset for credentials in a ccache.
1263     * \sa set_kdc_time_offset, clear_kdc_time_offset
1264     *
1265     * Sometimes the KDC and client's clocks get out of sync.  cc_ccache_get_kdc_time_offset()
1266     * returns the difference between the KDC and client's clocks at the time credentials were
1267     * acquired.  This offset allows callers to figure out how much time is left on a given
1268     * credential even though the end_time is based on the KDC's clock not the client's clock.
1269     */
1270    cc_int32 (*get_kdc_time_offset) (cc_ccache_t  in_ccache,
1271                                     cc_uint32    in_credentials_version,
1272                                     cc_time_t   *out_time_offset);
1273
1274    /*!
1275     * \param in_ccache a ccache object.
1276     * \param in_credentials_version the credentials version to get the time offset for.
1277     * \param in_time_offset the new KDC time offset for \a in_ccache for credentials version
1278     * \a in_credentials_version.
1279     * \return On success, #ccNoError.  On failure, an error code representing the failure.
1280     * \brief \b cc_ccache_set_kdc_time_offset(): Set the KDC time offset for credentials in a ccache.
1281     * \sa get_kdc_time_offset, clear_kdc_time_offset
1282     *
1283     * Sometimes the KDC and client's clocks get out of sync.  cc_ccache_set_kdc_time_offset()
1284     * sets the difference between the KDC and client's clocks at the time credentials were
1285     * acquired.  This offset allows callers to figure out how much time is left on a given
1286     * credential even though the end_time is based on the KDC's clock not the client's clock.
1287     */
1288    cc_int32 (*set_kdc_time_offset) (cc_ccache_t io_ccache,
1289                                     cc_uint32   in_credentials_version,
1290                                     cc_time_t   in_time_offset);
1291
1292    /*!
1293     * \param in_ccache a ccache object.
1294     * \param in_credentials_version the credentials version to get the time offset for.
1295     * \return On success, #ccNoError.  On failure, an error code representing the failure.
1296     * \brief \b cc_ccache_clear_kdc_time_offset(): Clear the KDC time offset for credentials in a ccache.
1297     * \sa get_kdc_time_offset, set_kdc_time_offset
1298     *
1299     * Sometimes the KDC and client's clocks get out of sync.  cc_ccache_clear_kdc_time_offset()
1300     * clears the difference between the KDC and client's clocks at the time credentials were
1301     * acquired.  This offset allows callers to figure out how much time is left on a given
1302     * credential even though the end_time is based on the KDC's clock not the client's clock.
1303     */
1304    cc_int32 (*clear_kdc_time_offset) (cc_ccache_t io_ccache,
1305                                       cc_uint32   in_credentials_version);
1306
1307    /*!
1308     * \param in_ccache a ccache object.
1309     * \return On success, #ccNoError.  On failure, an error code representing the failure.
1310     * \brief \b cc_ccache_wait_for_change(): Wait for the next change to a ccache.
1311     *
1312     * This function blocks until the next change is made to the ccache referenced by
1313     * \a in_ccache. By repeatedly calling cc_ccache_wait_for_change() from
1314     * a worker thread the caller can effectively receive callbacks whenever the
1315     * ccache changes.  This is considerably more efficient than polling
1316     * with cc_ccache_get_change_time().
1317     *
1318     * cc_ccache_wait_for_change() will return whenever:
1319     *
1320     * \li a credential is stored
1321     * \li a credential is removed
1322     * \li the ccache principal is changed
1323     * \li the ccache becomes the default ccache
1324     * \li the ccache is no longer the default ccache
1325     *
1326     * \note In order to make sure that the caller doesn't miss any changes,
1327     * cc_ccache_wait_for_change() always returns immediately after the first time it
1328     * is called on a new ccache object. Callers must use the same ccache object
1329     * for successive calls to cc_ccache_wait_for_change() rather than creating a new
1330     * ccache object for every call.
1331     *
1332     * \sa get_change_time
1333     */
1334    cc_int32 (*wait_for_change) (cc_ccache_t in_ccache);
1335};
1336
1337/*!
1338 * Function pointer table for cc_string_t.  For more information see
1339 * \ref cc_string_reference.
1340 */
1341struct cc_string_f {
1342    /*!
1343     * \param io_string the string object to release.
1344     * \return On success, #ccNoError.  On failure, an error code representing the failure.
1345     * \brief \b cc_string_release(): Release memory associated with a cc_string_t object.
1346     */
1347    cc_int32 (*release) (cc_string_t io_string);
1348};
1349
1350/*!
1351 * Function pointer table for cc_credentials_t.  For more information see
1352 * \ref cc_credentials_reference.
1353 */
1354struct cc_credentials_f {
1355    /*!
1356     * \param io_credentials the credentials object to release.
1357     * \return On success, #ccNoError.  On failure, an error code representing the failure.
1358     * \brief \b cc_credentials_release(): Release memory associated with a cc_credentials_t object.
1359     */
1360    cc_int32 (*release) (cc_credentials_t  io_credentials);
1361
1362    /*!
1363     * \param in_credentials a credentials object.
1364     * \param in_compare_to_credentials a credentials object to compare with \a in_credentials.
1365     * \param out_equal on exit, whether or not the two credentials objects refer to the
1366     * same credentials in the cache collection.
1367     * \return On success, #ccNoError.  On failure, an error code representing the failure.
1368     * \brief \b cc_credentials_compare(): Compare two credentials objects.
1369     */
1370    cc_int32 (*compare) (cc_credentials_t  in_credentials,
1371                         cc_credentials_t  in_compare_to_credentials,
1372                         cc_uint32        *out_equal);
1373};
1374
1375/*!
1376 * Function pointer table for cc_ccache_iterator_t.  For more information see
1377 * \ref cc_ccache_iterator_reference.
1378 */
1379struct cc_ccache_iterator_f {
1380    /*!
1381     * \param io_ccache_iterator the ccache iterator object to release.
1382     * \return On success, #ccNoError.  On failure, an error code representing the failure.
1383     * \brief \b cc_ccache_iterator_release(): Release memory associated with a cc_ccache_iterator_t object.
1384     */
1385    cc_int32 (*release) (cc_ccache_iterator_t io_ccache_iterator);
1386
1387    /*!
1388     * \param in_ccache_iterator a ccache iterator object.
1389     * \param out_ccache on exit, the next ccache in the cache collection.
1390     * \return On success, #ccNoError if the next ccache in the cache collection was
1391     * obtained or #ccIteratorEnd if there are no more ccaches.
1392     * On failure, an error code representing the failure.
1393     * \brief \b cc_ccache_iterator_next(): Get the next ccache in the cache collection.
1394     */
1395    cc_int32 (*next) (cc_ccache_iterator_t  in_ccache_iterator,
1396                      cc_ccache_t          *out_ccache);
1397
1398    /*!
1399     * \param in_ccache_iterator a ccache iterator object.
1400     * \param out_ccache_iterator on exit, a copy of \a in_ccache_iterator.
1401     * \return On success, #ccNoError.  On failure, an error code representing the failure.
1402     * \brief \b cc_ccache_iterator_clone(): Make a copy of a ccache iterator.
1403     */
1404    cc_int32 (*clone) (cc_ccache_iterator_t  in_ccache_iterator,
1405                       cc_ccache_iterator_t *out_ccache_iterator);
1406};
1407
1408/*!
1409 * Function pointer table for cc_credentials_iterator_t.  For more information see
1410 * \ref cc_credentials_iterator_reference.
1411 */
1412struct cc_credentials_iterator_f {
1413    /*!
1414     * \param io_credentials_iterator the credentials iterator object to release.
1415     * \return On success, #ccNoError.  On failure, an error code representing the failure.
1416     * \brief \b cc_credentials_iterator_release(): Release memory associated with a cc_credentials_iterator_t object.
1417     */
1418    cc_int32 (*release) (cc_credentials_iterator_t io_credentials_iterator);
1419
1420    /*!
1421     * \param in_credentials_iterator a credentials iterator object.
1422     * \param out_credentials on exit, the next credentials in the ccache.
1423     * \return On success, #ccNoError if the next credential in the ccache was obtained
1424     * or #ccIteratorEnd if there are no more credentials.
1425     * On failure, an error code representing the failure.
1426     * \brief \b cc_credentials_iterator_next(): Get the next credentials in the ccache.
1427     */
1428    cc_int32 (*next) (cc_credentials_iterator_t  in_credentials_iterator,
1429                      cc_credentials_t          *out_credentials);
1430
1431    /*!
1432     * \ingroup cc_credentials_iterator_reference
1433     * \param in_credentials_iterator a credentials iterator object.
1434     * \param out_credentials_iterator on exit, a copy of \a in_credentials_iterator.
1435     * \return On success, #ccNoError.  On failure, an error code representing the failure.
1436     * \brief \b cc_credentials_iterator_clone(): Make a copy of a credentials iterator.
1437     */
1438    cc_int32 (*clone) (cc_credentials_iterator_t  in_credentials_iterator,
1439                       cc_credentials_iterator_t *out_credentials_iterator);
1440};
1441
1442/*!
1443 * \ingroup cc_context_reference
1444 * \param out_context on exit, a new context object.  Must be free with cc_context_release().
1445 * \param in_version  the requested API version.  This should be the maximum version the
1446 * application supports.
1447 * \param out_supported_version if non-NULL, on exit contains the maximum API version
1448 * supported by the implementation.
1449 * \param out_vendor if non-NULL, on exit contains a pointer to a read-only C string which
1450 * contains a string describing the vendor which implemented the credentials cache API.
1451 * \return On success, #ccNoError.  On failure, an error code representing the failure.
1452 * May return CCAPI v2 error CC_BAD_API_VERSION if #ccapi_version_2 is passed in.
1453 * \brief Initialize a new cc_context.
1454 */
1455CCACHE_API cc_int32 cc_initialize (cc_context_t  *out_context,
1456                                   cc_int32       in_version,
1457                                   cc_int32      *out_supported_version,
1458                                   char const   **out_vendor);
1459
1460
1461/*! \defgroup helper_macros CCAPI Function Helper Macros
1462 * @{ */
1463
1464/*! Helper macro for cc_context_f release() */
1465#define		cc_context_release(context) \
1466			((context) -> functions -> release (context))
1467/*! Helper macro for cc_context_f get_change_time() */
1468#define		cc_context_get_change_time(context, change_time) \
1469			((context) -> functions -> get_change_time (context, change_time))
1470/*! Helper macro for cc_context_f get_default_ccache_name() */
1471#define		cc_context_get_default_ccache_name(context, name) \
1472			((context) -> functions -> get_default_ccache_name (context, name))
1473/*! Helper macro for cc_context_f open_ccache() */
1474#define		cc_context_open_ccache(context, name, ccache) \
1475			((context) -> functions -> open_ccache (context, name, ccache))
1476/*! Helper macro for cc_context_f open_default_ccache() */
1477#define		cc_context_open_default_ccache(context, ccache) \
1478			((context) -> functions -> open_default_ccache (context, ccache))
1479/*! Helper macro for cc_context_f create_ccache() */
1480#define		cc_context_create_ccache(context, name, version, principal, ccache) \
1481			((context) -> functions -> create_ccache (context, name, version, principal, ccache))
1482/*! Helper macro for cc_context_f create_default_ccache() */
1483#define		cc_context_create_default_ccache(context, version, principal, ccache) \
1484			((context) -> functions -> create_default_ccache (context, version, principal, ccache))
1485/*! Helper macro for cc_context_f create_new_ccache() */
1486#define		cc_context_create_new_ccache(context, version, principal, ccache) \
1487			((context) -> functions -> create_new_ccache (context, version, principal, ccache))
1488/*! Helper macro for cc_context_f new_ccache_iterator() */
1489#define		cc_context_new_ccache_iterator(context, iterator) \
1490			((context) -> functions -> new_ccache_iterator (context, iterator))
1491/*! Helper macro for cc_context_f lock() */
1492#define		cc_context_lock(context, type, block) \
1493			((context) -> functions -> lock (context, type, block))
1494/*! Helper macro for cc_context_f unlock() */
1495#define		cc_context_unlock(context) \
1496			((context) -> functions -> unlock (context))
1497/*! Helper macro for cc_context_f compare() */
1498#define		cc_context_compare(context, compare_to, equal) \
1499			((context) -> functions -> compare (context, compare_to, equal))
1500/*! Helper macro for cc_context_f wait_for_change() */
1501#define		cc_context_wait_for_change(context) \
1502			((context) -> functions -> wait_for_change (context))
1503
1504/*! Helper macro for cc_ccache_f release() */
1505#define		cc_ccache_release(ccache) \
1506			((ccache) -> functions -> release (ccache))
1507/*! Helper macro for cc_ccache_f destroy() */
1508#define		cc_ccache_destroy(ccache) \
1509			((ccache) -> functions -> destroy (ccache))
1510/*! Helper macro for cc_ccache_f set_default() */
1511#define		cc_ccache_set_default(ccache) \
1512			((ccache) -> functions -> set_default (ccache))
1513/*! Helper macro for cc_ccache_f get_credentials_version() */
1514#define		cc_ccache_get_credentials_version(ccache, version) \
1515			((ccache) -> functions -> get_credentials_version (ccache, version))
1516/*! Helper macro for cc_ccache_f get_name() */
1517#define		cc_ccache_get_name(ccache, name) \
1518			((ccache) -> functions -> get_name (ccache, name))
1519/*! Helper macro for cc_ccache_f get_principal() */
1520#define		cc_ccache_get_principal(ccache, version, principal) \
1521			((ccache) -> functions -> get_principal (ccache, version, principal))
1522/*! Helper macro for cc_ccache_f set_principal() */
1523#define		cc_ccache_set_principal(ccache, version, principal) \
1524			((ccache) -> functions -> set_principal (ccache, version, principal))
1525/*! Helper macro for cc_ccache_f store_credentials() */
1526#define		cc_ccache_store_credentials(ccache, credentials) \
1527			((ccache) -> functions -> store_credentials (ccache, credentials))
1528/*! Helper macro for cc_ccache_f remove_credentials() */
1529#define		cc_ccache_remove_credentials(ccache, credentials) \
1530			((ccache) -> functions -> remove_credentials (ccache, credentials))
1531/*! Helper macro for cc_ccache_f new_credentials_iterator() */
1532#define		cc_ccache_new_credentials_iterator(ccache, iterator) \
1533			((ccache) -> functions -> new_credentials_iterator (ccache, iterator))
1534/*! Helper macro for cc_ccache_f lock() */
1535#define		cc_ccache_lock(ccache, type, block) \
1536			((ccache) -> functions -> lock (ccache, type, block))
1537/*! Helper macro for cc_ccache_f unlock() */
1538#define		cc_ccache_unlock(ccache) \
1539			((ccache) -> functions -> unlock (ccache))
1540/*! Helper macro for cc_ccache_f get_last_default_time() */
1541#define		cc_ccache_get_last_default_time(ccache, last_default_time) \
1542			((ccache) -> functions -> get_last_default_time (ccache, last_default_time))
1543/*! Helper macro for cc_ccache_f get_change_time() */
1544#define		cc_ccache_get_change_time(ccache, change_time) \
1545			((ccache) -> functions -> get_change_time (ccache, change_time))
1546/*! Helper macro for cc_ccache_f move() */
1547#define		cc_ccache_move(source, destination) \
1548			((source) -> functions -> move (source, destination))
1549/*! Helper macro for cc_ccache_f compare() */
1550#define		cc_ccache_compare(ccache, compare_to, equal) \
1551			((ccache) -> functions -> compare (ccache, compare_to, equal))
1552/*! Helper macro for cc_ccache_f get_kdc_time_offset() */
1553#define		cc_ccache_get_kdc_time_offset(ccache, version, time_offset) \
1554                        ((ccache) -> functions -> get_kdc_time_offset (ccache, version, time_offset))
1555/*! Helper macro for cc_ccache_f set_kdc_time_offset() */
1556#define		cc_ccache_set_kdc_time_offset(ccache, version, time_offset) \
1557                        ((ccache) -> functions -> set_kdc_time_offset (ccache, version, time_offset))
1558/*! Helper macro for cc_ccache_f clear_kdc_time_offset() */
1559#define		cc_ccache_clear_kdc_time_offset(ccache, version) \
1560                        ((ccache) -> functions -> clear_kdc_time_offset (ccache, version))
1561/*! Helper macro for cc_ccache_f wait_for_change() */
1562#define		cc_ccache_wait_for_change(ccache) \
1563                        ((ccache) -> functions -> wait_for_change (ccache))
1564
1565/*! Helper macro for cc_string_f release() */
1566#define		cc_string_release(string) \
1567			((string) -> functions -> release (string))
1568
1569/*! Helper macro for cc_credentials_f release() */
1570#define		cc_credentials_release(credentials) \
1571			((credentials) -> functions -> release (credentials))
1572/*! Helper macro for cc_credentials_f compare() */
1573#define		cc_credentials_compare(credentials, compare_to, equal) \
1574			((credentials) -> functions -> compare (credentials, compare_to, equal))
1575
1576/*! Helper macro for cc_ccache_iterator_f release() */
1577#define		cc_ccache_iterator_release(iterator) \
1578			((iterator) -> functions -> release (iterator))
1579/*! Helper macro for cc_ccache_iterator_f next() */
1580#define		cc_ccache_iterator_next(iterator, ccache) \
1581			((iterator) -> functions -> next (iterator, ccache))
1582/*! Helper macro for cc_ccache_iterator_f clone() */
1583#define		cc_ccache_iterator_clone(iterator, new_iterator) \
1584			((iterator) -> functions -> clone (iterator, new_iterator))
1585
1586/*! Helper macro for cc_credentials_iterator_f release() */
1587#define		cc_credentials_iterator_release(iterator) \
1588			((iterator) -> functions -> release (iterator))
1589/*! Helper macro for cc_credentials_iterator_f next() */
1590#define		cc_credentials_iterator_next(iterator, credentials) \
1591			((iterator) -> functions -> next (iterator, credentials))
1592/*! Helper macro for cc_credentials_iterator_f clone() */
1593#define		cc_credentials_iterator_clone(iterator, new_iterator) \
1594			((iterator) -> functions -> clone (iterator, new_iterator))
1595/*!@}*/
1596
1597#if TARGET_OS_MAC
1598#pragma pack(pop)
1599#endif
1600
1601#ifdef __cplusplus
1602}
1603#endif /* __cplusplus */
1604
1605#endif /* __CREDENTIALSCACHE__ */
1606