summaryrefslogtreecommitdiffstats
path: root/src/ccapi/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/ccapi/lib')
-rw-r--r--src/ccapi/lib/ccapi.exports1
-rw-r--r--src/ccapi/lib/ccapi_ccache.c736
-rw-r--r--src/ccapi/lib/ccapi_ccache.h99
-rw-r--r--src/ccapi/lib/ccapi_ccache_iterator.c224
-rw-r--r--src/ccapi/lib/ccapi_ccache_iterator.h46
-rw-r--r--src/ccapi/lib/ccapi_context.c789
-rw-r--r--src/ccapi/lib/ccapi_context.h78
-rw-r--r--src/ccapi/lib/ccapi_context_change_time.c200
-rw-r--r--src/ccapi/lib/ccapi_context_change_time.h41
-rw-r--r--src/ccapi/lib/ccapi_credentials.c166
-rw-r--r--src/ccapi/lib/ccapi_credentials.h44
-rw-r--r--src/ccapi/lib/ccapi_credentials_iterator.c194
-rw-r--r--src/ccapi/lib/ccapi_credentials_iterator.h46
-rw-r--r--src/ccapi/lib/ccapi_err.et74
-rw-r--r--src/ccapi/lib/ccapi_ipc.c113
-rw-r--r--src/ccapi/lib/ccapi_ipc.h44
-rw-r--r--src/ccapi/lib/ccapi_os_ipc.h38
-rw-r--r--src/ccapi/lib/ccapi_string.c104
-rw-r--r--src/ccapi/lib/ccapi_string.h37
-rw-r--r--src/ccapi/lib/ccapi_v2.c232
-rw-r--r--src/ccapi/lib/ccapi_v2.exports23
-rw-r--r--src/ccapi/lib/mac/ccapi_os_ipc.c266
-rw-r--r--src/ccapi/lib/mac/ccapi_vector.c839
-rw-r--r--src/ccapi/lib/mac/ccapi_vector.exports59
-rw-r--r--src/ccapi/lib/mac/ccapi_vector.h228
25 files changed, 4721 insertions, 0 deletions
diff --git a/src/ccapi/lib/ccapi.exports b/src/ccapi/lib/ccapi.exports
new file mode 100644
index 0000000000..92c859bd74
--- /dev/null
+++ b/src/ccapi/lib/ccapi.exports
@@ -0,0 +1 @@
+cc_initialize
diff --git a/src/ccapi/lib/ccapi_ccache.c b/src/ccapi/lib/ccapi_ccache.c
new file mode 100644
index 0000000000..5a975810c2
--- /dev/null
+++ b/src/ccapi/lib/ccapi_ccache.c
@@ -0,0 +1,736 @@
+/*
+ * $Header$
+ *
+ * Copyright 2006 Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#include "ccapi_ccache.h"
+
+#include "ccapi_string.h"
+#include "ccapi_credentials.h"
+#include "ccapi_credentials_iterator.h"
+#include "ccapi_ipc.h"
+
+#if TARGET_OS_MAC
+#warning Workaround for AppleConnect crash causes leak
+#include <CoreFoundation/CoreFoundation.h>
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+typedef struct cci_ccache_d {
+ cc_ccache_f *functions;
+#if TARGET_OS_MAC
+ cc_ccache_f *vector_functions;
+#endif
+ cci_identifier_t identifier;
+} *cci_ccache_t;
+
+/* ------------------------------------------------------------------------ */
+
+struct cci_ccache_d cci_ccache_initializer = {
+ NULL
+ VECTOR_FUNCTIONS_INITIALIZER,
+ NULL,
+};
+
+cc_ccache_f cci_ccache_f_initializer = {
+ ccapi_ccache_release,
+ ccapi_ccache_destroy,
+ ccapi_ccache_set_default,
+ ccapi_ccache_get_credentials_version,
+ ccapi_ccache_get_name,
+ ccapi_ccache_get_principal,
+ ccapi_ccache_set_principal,
+ ccapi_ccache_store_credentials,
+ ccapi_ccache_remove_credentials,
+ ccapi_ccache_new_credentials_iterator,
+ ccapi_ccache_move,
+ ccapi_ccache_lock,
+ ccapi_ccache_unlock,
+ ccapi_ccache_get_last_default_time,
+ ccapi_ccache_get_change_time,
+ ccapi_ccache_compare,
+ ccapi_ccache_get_kdc_time_offset,
+ ccapi_ccache_set_kdc_time_offset,
+ ccapi_ccache_clear_kdc_time_offset,
+ ccapi_ccache_wait_for_change
+};
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 cci_ccache_new (cc_ccache_t *out_ccache,
+ cci_identifier_t in_identifier)
+{
+ cc_int32 err = ccNoError;
+ cci_ccache_t ccache = NULL;
+
+ if (!out_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_identifier) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ ccache = malloc (sizeof (*ccache));
+ if (ccache) {
+ *ccache = cci_ccache_initializer;
+ } else {
+ err = cci_check_error (ccErrNoMem);
+ }
+ }
+
+ if (!err) {
+ ccache->functions = malloc (sizeof (*ccache->functions));
+ if (ccache->functions) {
+ *ccache->functions = cci_ccache_f_initializer;
+ } else {
+ err = cci_check_error (ccErrNoMem);
+ }
+ }
+
+ if (!err) {
+ err = cci_identifier_copy (&ccache->identifier, in_identifier);
+ }
+
+ if (!err) {
+ *out_ccache = (cc_ccache_t) ccache;
+ ccache = NULL; /* take ownership */
+ }
+
+ ccapi_ccache_release ((cc_ccache_t) ccache);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 cci_ccache_write (cc_ccache_t in_ccache,
+ cci_stream_t in_stream)
+{
+ cc_int32 err = ccNoError;
+ cci_ccache_t ccache = (cci_ccache_t) in_ccache;
+
+ if (!in_ccache) { err = cci_check_error (ccErrBadParam); }
+ if (!in_stream) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_identifier_write (ccache->identifier, in_stream);
+ }
+
+ return cci_check_error (err);
+}
+
+#pragma mark -
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccapi_ccache_release (cc_ccache_t io_ccache)
+{
+ cc_int32 err = ccNoError;
+ cci_ccache_t ccache = (cci_ccache_t) io_ccache;
+
+ if (!io_ccache) { err = ccErrBadParam; }
+
+ if (!err) {
+ cci_identifier_release (ccache->identifier);
+
+#if TARGET_OS_MAC
+#warning Workaround for AppleConnect crash causes leak
+ CFBundleRef main_bundle = CFBundleGetMainBundle ();
+ if (main_bundle) {
+ CFStringRef bundle_id = CFBundleGetIdentifier (main_bundle);
+ if (bundle_id) {
+ CFStringRef ac_id = CFSTR("com.apple.ist.ds.appleconnect");
+ if (CFStringCompare (bundle_id, ac_id, 0) == kCFCompareEqualTo) {
+ return ccNoError;
+ }
+ }
+ }
+#endif
+ free ((char *) ccache->functions);
+ free (ccache);
+ }
+
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccapi_ccache_destroy (cc_ccache_t io_ccache)
+{
+ cc_int32 err = ccNoError;
+ cci_ccache_t ccache = (cci_ccache_t) io_ccache;
+
+ if (!io_ccache) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_ipc_send (cci_ccache_destroy_msg_id,
+ ccache->identifier,
+ NULL,
+ NULL);
+ }
+
+ if (!err) {
+ err = ccapi_ccache_release (io_ccache);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccapi_ccache_set_default (cc_ccache_t io_ccache)
+{
+ cc_int32 err = ccNoError;
+ cci_ccache_t ccache = (cci_ccache_t) io_ccache;
+
+ if (!io_ccache) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_ipc_send (cci_ccache_set_default_msg_id,
+ ccache->identifier,
+ NULL,
+ NULL);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccapi_ccache_get_credentials_version (cc_ccache_t in_ccache,
+ cc_uint32 *out_credentials_version)
+{
+ cc_int32 err = ccNoError;
+ cci_ccache_t ccache = (cci_ccache_t) in_ccache;
+ cci_stream_t reply = NULL;
+
+ if (!in_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_credentials_version) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_ipc_send (cci_ccache_get_credentials_version_msg_id,
+ ccache->identifier,
+ NULL,
+ &reply);
+ }
+
+ if (!err) {
+ err = cci_stream_read_uint32 (reply, out_credentials_version);
+ }
+
+ cci_stream_release (reply);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccapi_ccache_get_name (cc_ccache_t in_ccache,
+ cc_string_t *out_name)
+{
+ cc_int32 err = ccNoError;
+ cci_ccache_t ccache = (cci_ccache_t) in_ccache;
+ cci_stream_t reply = NULL;
+ char *name = NULL;
+
+ if (!in_ccache) { err = cci_check_error (ccErrBadParam); }
+ if (!out_name ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_ipc_send (cci_ccache_get_name_msg_id,
+ ccache->identifier,
+ NULL,
+ &reply);
+ }
+
+ if (!err) {
+ err = cci_stream_read_string (reply, &name);
+ }
+
+ if (!err) {
+ err = cci_string_new (out_name, name);
+ }
+
+ cci_stream_release (reply);
+ free (name);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccapi_ccache_get_principal (cc_ccache_t in_ccache,
+ cc_uint32 in_credentials_version,
+ cc_string_t *out_principal)
+{
+ cc_int32 err = ccNoError;
+ cci_ccache_t ccache = (cci_ccache_t) in_ccache;
+ cci_stream_t reply = NULL;
+ char *principal = NULL;
+
+ if (!in_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_principal) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_ipc_send (cci_ccache_get_principal_msg_id,
+ ccache->identifier,
+ NULL,
+ &reply);
+ }
+
+ if (!err) {
+ err = cci_stream_read_string (reply, &principal);
+ }
+
+ if (!err) {
+ err = cci_string_new (out_principal, principal);
+ }
+
+ cci_stream_release (reply);
+ free (principal);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccapi_ccache_set_principal (cc_ccache_t io_ccache,
+ cc_uint32 in_credentials_version,
+ const char *in_principal)
+{
+ cc_int32 err = ccNoError;
+ cci_ccache_t ccache = (cci_ccache_t) io_ccache;
+ cci_stream_t request = NULL;
+
+ if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_principal) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_stream_new (&request);
+ }
+
+ if (!err) {
+ err = cci_stream_write_string (request, in_principal);
+ }
+
+ if (!err) {
+ err = cci_ipc_send (cci_ccache_set_principal_msg_id,
+ ccache->identifier,
+ request,
+ NULL);
+ }
+
+ cci_stream_release (request);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccapi_ccache_store_credentials (cc_ccache_t io_ccache,
+ const cc_credentials_union *in_credentials_union)
+{
+ cc_int32 err = ccNoError;
+ cci_ccache_t ccache = (cci_ccache_t) io_ccache;
+ cci_stream_t request = NULL;
+
+ if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_credentials_union) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_stream_new (&request);
+ }
+
+ if (!err) {
+ err = cci_cred_union_write (in_credentials_union, request);
+ }
+
+ if (!err) {
+ err = cci_ipc_send (cci_ccache_store_credentials_msg_id,
+ ccache->identifier,
+ request,
+ NULL);
+ }
+
+ cci_stream_release (request);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccapi_ccache_remove_credentials (cc_ccache_t io_ccache,
+ cc_credentials_t in_credentials)
+{
+ cc_int32 err = ccNoError;
+ cci_ccache_t ccache = (cci_ccache_t) io_ccache;
+ cci_stream_t request = NULL;
+
+ if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_credentials) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_stream_new (&request);
+ }
+
+ if (!err) {
+ err = cci_credentials_write (in_credentials, request);
+ }
+
+ if (!err) {
+ err = cci_ipc_send (cci_ccache_remove_credentials_msg_id,
+ ccache->identifier,
+ request,
+ NULL);
+ }
+
+ cci_stream_release (request);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccapi_ccache_new_credentials_iterator (cc_ccache_t in_ccache,
+ cc_credentials_iterator_t *out_credentials_iterator)
+{
+ cc_int32 err = ccNoError;
+ cci_ccache_t ccache = (cci_ccache_t) in_ccache;
+ cci_stream_t reply = NULL;
+ cci_identifier_t identifier = NULL;
+
+ if (!in_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_credentials_iterator) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_ipc_send (cci_ccache_new_credentials_iterator_msg_id,
+ ccache->identifier,
+ NULL,
+ &reply);
+ }
+
+ if (!err) {
+ err = cci_identifier_read (&identifier, reply);
+ }
+
+ if (!err) {
+ err = cci_credentials_iterator_new (out_credentials_iterator, identifier);
+ }
+
+ cci_stream_release (reply);
+ cci_identifier_release (identifier);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+/* Note: message is sent as the destination to avoid extra work on the */
+/* server when deleting it the source ccache. */
+
+cc_int32 ccapi_ccache_move (cc_ccache_t io_source_ccache,
+ cc_ccache_t io_destination_ccache)
+{
+ cc_int32 err = ccNoError;
+ cci_ccache_t source_ccache = (cci_ccache_t) io_source_ccache;
+ cci_ccache_t destination_ccache = (cci_ccache_t) io_destination_ccache;
+ cci_stream_t request = NULL;
+
+ if (!io_source_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_destination_ccache) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_stream_new (&request);
+ }
+
+ if (!err) {
+ err = cci_identifier_write (source_ccache->identifier, request);
+ }
+
+ if (!err) {
+ err = cci_ipc_send (cci_ccache_move_msg_id,
+ destination_ccache->identifier,
+ request,
+ NULL);
+ }
+
+ cci_stream_release (request);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccapi_ccache_lock (cc_ccache_t io_ccache,
+ cc_uint32 in_lock_type,
+ cc_uint32 in_block)
+{
+ cc_int32 err = ccNoError;
+ cci_ccache_t ccache = (cci_ccache_t) io_ccache;
+ cci_stream_t request = NULL;
+
+ if (!io_ccache) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_stream_new (&request);
+ }
+
+ if (!err) {
+ err = cci_stream_write_uint32 (request, in_lock_type);
+ }
+
+ if (!err) {
+ err = cci_stream_write_uint32 (request, in_block);
+ }
+
+ if (!err) {
+ err = cci_ipc_send (cci_ccache_lock_msg_id,
+ ccache->identifier,
+ request,
+ NULL);
+ }
+
+ cci_stream_release (request);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccapi_ccache_unlock (cc_ccache_t io_ccache)
+{
+ cc_int32 err = ccNoError;
+ cci_ccache_t ccache = (cci_ccache_t) io_ccache;
+
+ if (!io_ccache) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_ipc_send (cci_ccache_unlock_msg_id,
+ ccache->identifier,
+ NULL,
+ NULL);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccapi_ccache_get_last_default_time (cc_ccache_t in_ccache,
+ cc_time_t *out_last_default_time)
+{
+ cc_int32 err = ccNoError;
+ cci_ccache_t ccache = (cci_ccache_t) in_ccache;
+ cci_stream_t reply = NULL;
+
+ if (!in_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_last_default_time) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_ipc_send (cci_ccache_get_last_default_time_msg_id,
+ ccache->identifier,
+ NULL,
+ &reply);
+ }
+
+ if (!err) {
+ err = cci_stream_read_time (reply, out_last_default_time);
+ }
+
+ cci_stream_release (reply);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccapi_ccache_get_change_time (cc_ccache_t in_ccache,
+ cc_time_t *out_change_time)
+{
+ cc_int32 err = ccNoError;
+ cci_ccache_t ccache = (cci_ccache_t) in_ccache;
+ cci_stream_t reply = NULL;
+
+ if (!in_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_change_time) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_ipc_send (cci_ccache_get_change_time_msg_id,
+ ccache->identifier,
+ NULL,
+ &reply);
+ }
+
+ if (!err) {
+ err = cci_stream_read_time (reply, out_change_time);
+ }
+
+ cci_stream_release (reply);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccapi_ccache_wait_for_change (cc_ccache_t in_ccache)
+{
+ cc_int32 err = ccNoError;
+ cci_ccache_t ccache = (cci_ccache_t) in_ccache;
+
+ if (!in_ccache) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_ipc_send (cci_ccache_wait_for_change_msg_id,
+ ccache->identifier,
+ NULL, NULL);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccapi_ccache_compare (cc_ccache_t in_ccache,
+ cc_ccache_t in_compare_to_ccache,
+ cc_uint32 *out_equal)
+{
+ cc_int32 err = ccNoError;
+ cci_ccache_t ccache = (cci_ccache_t) in_ccache;
+ cci_ccache_t compare_to_ccache = (cci_ccache_t) in_compare_to_ccache;
+
+ if (!in_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_compare_to_ccache) { err = cci_check_error (ccErrBadParam); }
+ if (!out_equal ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_identifier_compare (ccache->identifier,
+ compare_to_ccache->identifier,
+ out_equal);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccapi_ccache_get_kdc_time_offset (cc_ccache_t in_ccache,
+ cc_uint32 in_credentials_version,
+ cc_time_t *out_time_offset)
+{
+ cc_int32 err = ccNoError;
+ cci_ccache_t ccache = (cci_ccache_t) in_ccache;
+ cci_stream_t request = NULL;
+ cci_stream_t reply = NULL;
+
+ if (!in_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_time_offset) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_stream_new (&request);
+ }
+
+ if (!err) {
+ err = cci_stream_write_uint32 (request, in_credentials_version);
+ }
+
+ if (!err) {
+ err = cci_ipc_send (cci_ccache_get_kdc_time_offset_msg_id,
+ ccache->identifier,
+ request,
+ &reply);
+ }
+
+ if (!err) {
+ err = cci_stream_read_time (reply, out_time_offset);
+ }
+
+ cci_stream_release (request);
+ cci_stream_release (reply);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccapi_ccache_set_kdc_time_offset (cc_ccache_t io_ccache,
+ cc_uint32 in_credentials_version,
+ cc_time_t in_time_offset)
+{
+ cc_int32 err = ccNoError;
+ cci_ccache_t ccache = (cci_ccache_t) io_ccache;
+ cci_stream_t request = NULL;
+
+ if (!io_ccache) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_stream_new (&request);
+ }
+
+ if (!err) {
+ err = cci_stream_write_uint32 (request, in_credentials_version);
+ }
+
+ if (!err) {
+ err = cci_stream_write_time (request, in_time_offset);
+ }
+
+ if (!err) {
+ err = cci_ipc_send (cci_ccache_set_kdc_time_offset_msg_id,
+ ccache->identifier,
+ request,
+ NULL);
+ }
+
+ cci_stream_release (request);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccapi_ccache_clear_kdc_time_offset (cc_ccache_t io_ccache,
+ cc_uint32 in_credentials_version)
+{
+ cc_int32 err = ccNoError;
+ cci_ccache_t ccache = (cci_ccache_t) io_ccache;
+ cci_stream_t request = NULL;
+
+ if (!io_ccache) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_stream_new (&request);
+ }
+
+ if (!err) {
+ err = cci_stream_write_uint32 (request, in_credentials_version);
+ }
+
+ if (!err) {
+ err = cci_ipc_send (cci_ccache_clear_kdc_time_offset_msg_id,
+ ccache->identifier,
+ request,
+ NULL);
+ }
+
+ cci_stream_release (request);
+
+ return cci_check_error (err);
+}
diff --git a/src/ccapi/lib/ccapi_ccache.h b/src/ccapi/lib/ccapi_ccache.h
new file mode 100644
index 0000000000..82a9f6c1c4
--- /dev/null
+++ b/src/ccapi/lib/ccapi_ccache.h
@@ -0,0 +1,99 @@
+/*
+ * $Header$
+ *
+ * Copyright 2006 Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#ifndef CCAPI_CCACHE_H
+#define CCAPI_CCACHE_H
+
+#include "cci_common.h"
+
+cc_int32 cci_ccache_new (cc_ccache_t *out_ccache,
+ cci_identifier_t in_identifier);
+
+cc_int32 ccapi_ccache_release (cc_ccache_t io_ccache);
+
+cc_int32 cci_ccache_write (cc_ccache_t in_ccache,
+ cci_stream_t in_stream);
+
+cc_int32 ccapi_ccache_destroy (cc_ccache_t io_ccache);
+
+cc_int32 ccapi_ccache_set_default (cc_ccache_t io_ccache);
+
+cc_int32 ccapi_ccache_get_credentials_version (cc_ccache_t in_ccache,
+ cc_uint32 *out_credentials_version);
+
+cc_int32 ccapi_ccache_get_name (cc_ccache_t in_ccache,
+ cc_string_t *out_name);
+
+cc_int32 ccapi_ccache_get_principal (cc_ccache_t in_ccache,
+ cc_uint32 in_credentials_version,
+ cc_string_t *out_principal);
+
+cc_int32 ccapi_ccache_set_principal (cc_ccache_t io_ccache,
+ cc_uint32 in_credentials_version,
+ const char *in_principal);
+
+cc_int32 ccapi_ccache_store_credentials (cc_ccache_t io_ccache,
+ const cc_credentials_union *in_credentials_union);
+
+cc_int32 ccapi_ccache_remove_credentials (cc_ccache_t io_ccache,
+ cc_credentials_t in_credentials);
+
+cc_int32 ccapi_ccache_new_credentials_iterator (cc_ccache_t in_ccache,
+ cc_credentials_iterator_t *out_credentials_iterator);
+
+cc_int32 ccapi_ccache_move (cc_ccache_t io_source_ccache,
+ cc_ccache_t io_destination_ccache);
+
+cc_int32 ccapi_ccache_lock (cc_ccache_t io_ccache,
+ cc_uint32 in_lock_type,
+ cc_uint32 in_block);
+
+cc_int32 ccapi_ccache_unlock (cc_ccache_t io_ccache);
+
+cc_int32 ccapi_ccache_get_last_default_time (cc_ccache_t in_ccache,
+ cc_time_t *out_last_default_time);
+
+cc_int32 ccapi_ccache_get_change_time (cc_ccache_t in_ccache,
+ cc_time_t *out_change_time);
+
+cc_int32 ccapi_ccache_wait_for_change (cc_ccache_t in_ccache);
+
+cc_int32 ccapi_ccache_compare (cc_ccache_t in_ccache,
+ cc_ccache_t in_compare_to_ccache,
+ cc_uint32 *out_equal);
+
+cc_int32 ccapi_ccache_get_kdc_time_offset (cc_ccache_t in_ccache,
+ cc_uint32 in_credentials_version,
+ cc_time_t *out_time_offset);
+
+cc_int32 ccapi_ccache_set_kdc_time_offset (cc_ccache_t io_ccache,
+ cc_uint32 in_credentials_version,
+ cc_time_t in_time_offset);
+
+cc_int32 ccapi_ccache_clear_kdc_time_offset (cc_ccache_t io_ccache,
+ cc_uint32 in_credentials_version);
+
+#endif /* CCAPI_CCACHE_H */
diff --git a/src/ccapi/lib/ccapi_ccache_iterator.c b/src/ccapi/lib/ccapi_ccache_iterator.c
new file mode 100644
index 0000000000..815da36f19
--- /dev/null
+++ b/src/ccapi/lib/ccapi_ccache_iterator.c
@@ -0,0 +1,224 @@
+/*
+ * $Header$
+ *
+ * Copyright 2006 Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#include "ccapi_ccache_iterator.h"
+#include "ccapi_ccache.h"
+#include "ccapi_ipc.h"
+
+/* ------------------------------------------------------------------------ */
+
+typedef struct cci_ccache_iterator_d {
+ cc_ccache_iterator_f *functions;
+#if TARGET_OS_MAC
+ cc_ccache_iterator_f *vector_functions;
+#endif
+ cci_identifier_t identifier;
+} *cci_ccache_iterator_t;
+
+/* ------------------------------------------------------------------------ */
+
+struct cci_ccache_iterator_d cci_ccache_iterator_initializer = {
+ NULL
+ VECTOR_FUNCTIONS_INITIALIZER,
+ NULL
+};
+
+cc_ccache_iterator_f cci_ccache_iterator_f_initializer = {
+ ccapi_ccache_iterator_release,
+ ccapi_ccache_iterator_next,
+ ccapi_ccache_iterator_clone
+};
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 cci_ccache_iterator_new (cc_ccache_iterator_t *out_ccache_iterator,
+ cci_identifier_t in_identifier)
+{
+ cc_int32 err = ccNoError;
+ cci_ccache_iterator_t ccache_iterator = NULL;
+
+ if (!in_identifier ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_ccache_iterator) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ ccache_iterator = malloc (sizeof (*ccache_iterator));
+ if (ccache_iterator) {
+ *ccache_iterator = cci_ccache_iterator_initializer;
+ } else {
+ err = cci_check_error (ccErrNoMem);
+ }
+ }
+
+ if (!err) {
+ ccache_iterator->functions = malloc (sizeof (*ccache_iterator->functions));
+ if (ccache_iterator->functions) {
+ *ccache_iterator->functions = cci_ccache_iterator_f_initializer;
+ } else {
+ err = cci_check_error (ccErrNoMem);
+ }
+ }
+
+ if (!err) {
+ err = cci_identifier_copy (&ccache_iterator->identifier, in_identifier);
+ }
+
+ if (!err) {
+ *out_ccache_iterator = (cc_ccache_iterator_t) ccache_iterator;
+ ccache_iterator = NULL; /* take ownership */
+ }
+
+ ccapi_ccache_iterator_release ((cc_ccache_iterator_t) ccache_iterator);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 cci_ccache_iterator_write (cc_ccache_iterator_t in_ccache_iterator,
+ cci_stream_t in_stream)
+{
+ cc_int32 err = ccNoError;
+ cci_ccache_iterator_t ccache_iterator = (cci_ccache_iterator_t) in_ccache_iterator;
+
+ if (!in_ccache_iterator) { err = cci_check_error (ccErrBadParam); }
+ if (!in_stream ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_identifier_write (ccache_iterator->identifier, in_stream);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccapi_ccache_iterator_release (cc_ccache_iterator_t io_ccache_iterator)
+{
+ cc_int32 err = ccNoError;
+ cci_ccache_iterator_t ccache_iterator = (cci_ccache_iterator_t) io_ccache_iterator;
+
+ if (!io_ccache_iterator) { err = ccErrBadParam; }
+
+ if (!err) {
+ free ((char *) ccache_iterator->functions);
+ cci_identifier_release (ccache_iterator->identifier);
+ free (ccache_iterator);
+ }
+
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccapi_ccache_iterator_next (cc_ccache_iterator_t in_ccache_iterator,
+ cc_ccache_t *out_ccache)
+{
+ cc_int32 err = ccNoError;
+ cci_ccache_iterator_t ccache_iterator = (cci_ccache_iterator_t) in_ccache_iterator;
+ cci_stream_t reply = NULL;
+ cci_identifier_t identifier = NULL;
+
+ if (!in_ccache_iterator) { err = cci_check_error (ccErrBadParam); }
+ if (!out_ccache ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ cc_uint32 initialized = 0;
+
+ err = cci_identifier_is_initialized (ccache_iterator->identifier,
+ &initialized);
+
+ if (!err && !initialized) {
+ /* server doesn't actually exist. Pretend we're empty. */
+ err = cci_check_error (ccIteratorEnd);
+ }
+ }
+
+ if (!err) {
+ err = cci_ipc_send (cci_ccache_iterator_next_msg_id,
+ ccache_iterator->identifier,
+ NULL,
+ &reply);
+ }
+
+ if (!err) {
+ err = cci_identifier_read (&identifier, reply);
+ }
+
+ if (!err) {
+ err = cci_ccache_new (out_ccache, identifier);
+ }
+
+ cci_stream_release (reply);
+ cci_identifier_release (identifier);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccapi_ccache_iterator_clone (cc_ccache_iterator_t in_ccache_iterator,
+ cc_ccache_iterator_t *out_ccache_iterator)
+{
+ cc_int32 err = ccNoError;
+ cci_ccache_iterator_t ccache_iterator = (cci_ccache_iterator_t) in_ccache_iterator;
+ cci_stream_t reply = NULL;
+ cc_uint32 initialized = 0;
+ cci_identifier_t identifier = NULL;
+
+ if (!in_ccache_iterator ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_ccache_iterator) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_identifier_is_initialized (ccache_iterator->identifier,
+ &initialized);
+ }
+
+ if (!err) {
+ if (initialized) {
+ err = cci_ipc_send (cci_ccache_iterator_next_msg_id,
+ ccache_iterator->identifier,
+ NULL,
+ &reply);
+
+ if (!err) {
+ err = cci_identifier_read (&identifier, reply);
+ }
+
+ } else {
+ /* server doesn't actually exist. Make another dummy one. */
+ identifier = cci_identifier_uninitialized;
+ }
+ }
+
+ if (!err) {
+ err = cci_ccache_iterator_new (out_ccache_iterator, identifier);
+ }
+
+ cci_identifier_release (identifier);
+ cci_stream_release (reply);
+
+ return cci_check_error (err);
+}
diff --git a/src/ccapi/lib/ccapi_ccache_iterator.h b/src/ccapi/lib/ccapi_ccache_iterator.h
new file mode 100644
index 0000000000..0a5a4f4567
--- /dev/null
+++ b/src/ccapi/lib/ccapi_ccache_iterator.h
@@ -0,0 +1,46 @@
+/*
+ * $Header$
+ *
+ * Copyright 2006 Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#ifndef CCAPI_CCACHE_ITERATOR_H
+#define CCAPI_CCACHE_ITERATOR_H
+
+#include "cci_common.h"
+
+cc_int32 cci_ccache_iterator_new (cc_ccache_iterator_t *out_ccache_iterator,
+ cci_identifier_t in_identifier);
+
+cc_int32 cci_ccache_iterator_write (cc_ccache_iterator_t in_ccache_iterator,
+ cci_stream_t in_stream);
+
+cc_int32 ccapi_ccache_iterator_release (cc_ccache_iterator_t io_ccache_iterator);
+
+cc_int32 ccapi_ccache_iterator_next (cc_ccache_iterator_t in_ccache_iterator,
+ cc_ccache_t *out_ccache);
+
+cc_int32 ccapi_ccache_iterator_clone (cc_ccache_iterator_t in_ccache_iterator,
+ cc_ccache_iterator_t *out_ccache_iterator);
+
+#endif /* CCAPI_CCACHE_ITERATOR_H */
diff --git a/src/ccapi/lib/ccapi_context.c b/src/ccapi/lib/ccapi_context.c
new file mode 100644
index 0000000000..7a24f2248b
--- /dev/null
+++ b/src/ccapi/lib/ccapi_context.c
@@ -0,0 +1,789 @@
+/*
+ * $Header$
+ *
+ * Copyright 2006 Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#include "ccapi_context.h"
+
+#include "k5-platform.h"
+
+#include "ccapi_ccache.h"
+#include "ccapi_ccache_iterator.h"
+#include "ccapi_string.h"
+#include "ccapi_ipc.h"
+#include "ccapi_context_change_time.h"
+
+#include <CredentialsCache2.h>
+
+typedef struct cci_context_d {
+ cc_context_f *functions;
+#if TARGET_OS_MAC
+ cc_context_f *vector_functions;
+#endif
+ cci_identifier_t identifier;
+ cc_uint32 synchronized;
+} *cci_context_t;
+
+/* ------------------------------------------------------------------------ */
+
+struct cci_context_d cci_context_initializer = {
+ NULL
+ VECTOR_FUNCTIONS_INITIALIZER,
+ NULL,
+ 0
+};
+
+cc_context_f cci_context_f_initializer = {
+ ccapi_context_release,
+ ccapi_context_get_change_time,
+ ccapi_context_get_default_ccache_name,
+ ccapi_context_open_ccache,
+ ccapi_context_open_default_ccache,
+ ccapi_context_create_ccache,
+ ccapi_context_create_default_ccache,
+ ccapi_context_create_new_ccache,
+ ccapi_context_new_ccache_iterator,
+ ccapi_context_lock,
+ ccapi_context_unlock,
+ ccapi_context_compare,
+ ccapi_context_wait_for_change
+};
+
+static cc_int32 cci_context_sync (cci_context_t in_context,
+ cc_uint32 in_launch);
+
+#pragma mark -
+
+MAKE_INIT_FUNCTION(cci_thread_init);
+
+/* ------------------------------------------------------------------------ */
+
+static int cci_thread_init (void)
+{
+ cc_int32 err = ccNoError;
+
+ if (!err) {
+ err = cci_context_change_time_thread_init ();
+ }
+
+ if (!err) {
+ err = cci_ipc_thread_init ();
+ }
+
+ return err;
+}
+
+#pragma mark -
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 cc_initialize (cc_context_t *out_context,
+ cc_int32 in_version,
+ cc_int32 *out_supported_version,
+ char const **out_vendor)
+{
+ cc_int32 err = ccNoError;
+ cci_context_t context = NULL;
+ static char *vendor_string = "MIT Kerberos CCAPI";
+
+ if (!out_context) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = CALL_INIT_FUNCTION (cci_thread_init);
+ }
+
+ if (!err) {
+ switch (in_version) {
+ case ccapi_version_2:
+ err = CC_NOT_SUPP;
+ break;
+
+ case ccapi_version_3:
+ case ccapi_version_4:
+ case ccapi_version_5:
+ case ccapi_version_6:
+ break;
+
+ default:
+ err = ccErrBadAPIVersion;
+ break;
+ }
+ }
+
+ if (!err) {
+ context = malloc (sizeof (*context));
+ if (context) {
+ *context = cci_context_initializer;
+ } else {
+ err = cci_check_error (ccErrNoMem);
+ }
+ }
+
+ if (!err) {
+ context->functions = malloc (sizeof (*context->functions));
+ if (context->functions) {
+ *context->functions = cci_context_f_initializer;
+ } else {
+ err = cci_check_error (ccErrNoMem);
+ }
+ }
+
+ if (!err) {
+ context->identifier = cci_identifier_uninitialized;
+
+ *out_context = (cc_context_t) context;
+ context = NULL; /* take ownership */
+
+ if (out_supported_version) {
+ *out_supported_version = ccapi_version_max;
+ }
+
+ if (out_vendor) {
+ *out_vendor = vendor_string;
+ }
+ }
+
+ ccapi_context_release ((cc_context_t) context);
+
+ return cci_check_error (err);
+}
+
+#pragma mark -
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccapi_context_release (cc_context_t in_context)
+{
+ cc_int32 err = ccNoError;
+ cci_context_t context = (cci_context_t) in_context;
+
+ if (!in_context) { err = ccErrBadParam; }
+
+ if (!err) {
+ err = cci_context_sync (context, 0);
+ }
+
+ if (!err) {
+ err = cci_ipc_send_no_launch (cci_context_release_msg_id,
+ context->identifier,
+ NULL,
+ NULL);
+ }
+
+ if (!err) {
+ cci_identifier_release (context->identifier);
+ free (context->functions);
+ free (context);
+ }
+
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccapi_context_get_change_time (cc_context_t in_context,
+ cc_time_t *out_change_time)
+{
+ cc_int32 err = ccNoError;
+ cci_context_t context = (cci_context_t) in_context;
+ cci_stream_t reply = NULL;
+
+ if (!in_context ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_change_time) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_context_sync (context, 0);
+ }
+
+ if (!err) {
+ err = cci_ipc_send_no_launch (cci_context_get_change_time_msg_id,
+ context->identifier,
+ NULL, &reply);
+ }
+
+ if (!err && cci_stream_size (reply) > 0) {
+ cc_time_t change_time = 0;
+
+ /* got a response from the server */
+ err = cci_stream_read_time (reply, &change_time);
+
+ if (!err) {
+ err = cci_context_change_time_update (context->identifier,
+ change_time);
+ }
+ }
+
+ if (!err) {
+ err = cci_context_change_time_get (out_change_time);
+ }
+
+ cci_stream_release (reply);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccapi_context_wait_for_change (cc_context_t in_context)
+{
+ cc_int32 err = ccNoError;
+ cci_context_t context = (cci_context_t) in_context;
+
+ if (!in_context) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_context_sync (context, 0);
+ }
+
+ if (!err) {
+ err = cci_ipc_send_no_launch (cci_context_wait_for_change_msg_id,
+ context->identifier,
+ NULL, NULL);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccapi_context_get_default_ccache_name (cc_context_t in_context,
+ cc_string_t *out_name)
+{
+ cc_int32 err = ccNoError;
+ cci_context_t context = (cci_context_t) in_context;
+ cci_stream_t reply = NULL;
+ char *reply_name = NULL;
+ char *name = NULL;
+
+ if (!in_context) { err = cci_check_error (ccErrBadParam); }
+ if (!out_name ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_context_sync (context, 0);
+ }
+
+ if (!err) {
+ err = cci_ipc_send_no_launch (cci_context_get_default_ccache_name_msg_id,
+ context->identifier,
+ NULL,
+ &reply);
+ }
+
+ if (!err) {
+ if (cci_stream_size (reply) > 0) {
+ /* got a response from the server */
+ err = cci_stream_read_string (reply, &reply_name);
+
+ if (!err) {
+ name = reply_name;
+ }
+ } else {
+ name = k_cci_context_initial_ccache_name;
+ }
+ }
+
+ if (!err) {
+ err = cci_string_new (out_name, name);
+ }
+
+ cci_stream_release (reply);
+ free (reply_name);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccapi_context_open_ccache (cc_context_t in_context,
+ const char *in_name,
+ cc_ccache_t *out_ccache)
+{
+ cc_int32 err = ccNoError;
+ cci_context_t context = (cci_context_t) in_context;
+ cci_stream_t request = NULL;
+ cci_stream_t reply = NULL;
+ cci_identifier_t identifier = NULL;
+
+ if (!in_context ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_name ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_ccache ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_stream_new (&request);
+ }
+
+ if (!err) {
+ err = cci_stream_write_string (request, in_name);
+ }
+
+ if (!err) {
+ err = cci_context_sync (context, 0);
+ }
+
+ if (!err) {
+ err = cci_ipc_send_no_launch (cci_context_open_ccache_msg_id,
+ context->identifier,
+ request,
+ &reply);
+ }
+
+ if (!err && !(cci_stream_size (reply) > 0)) {
+ err = ccErrCCacheNotFound;
+ }
+
+ if (!err) {
+ err = cci_identifier_read (&identifier, reply);
+ }
+
+ if (!err) {
+ err = cci_ccache_new (out_ccache, identifier);
+ }
+
+ cci_identifier_release (identifier);
+ cci_stream_release (reply);
+ cci_stream_release (request);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccapi_context_open_default_ccache (cc_context_t in_context,
+ cc_ccache_t *out_ccache)
+{
+ cc_int32 err = ccNoError;
+ cci_context_t context = (cci_context_t) in_context;
+ cci_stream_t reply = NULL;
+ cci_identifier_t identifier = NULL;
+
+ if (!in_context) { err = cci_check_error (ccErrBadParam); }
+ if (!out_ccache) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_context_sync (context, 0);
+ }
+
+ if (!err) {
+ err = cci_ipc_send_no_launch (cci_context_open_default_ccache_msg_id,
+ context->identifier,
+ NULL,
+ &reply);
+ }
+
+ if (!err && !(cci_stream_size (reply) > 0)) {
+ err = ccErrCCacheNotFound;
+ }
+
+ if (!err) {
+ err = cci_identifier_read (&identifier, reply);
+ }
+
+ if (!err) {
+ err = cci_ccache_new (out_ccache, identifier);
+ }
+
+ cci_identifier_release (identifier);
+ cci_stream_release (reply);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccapi_context_create_ccache (cc_context_t in_context,
+ const char *in_name,
+ cc_uint32 in_cred_vers,
+ const char *in_principal,
+ cc_ccache_t *out_ccache)
+{
+ cc_int32 err = ccNoError;
+ cci_context_t context = (cci_context_t) in_context;
+ cci_stream_t request = NULL;
+ cci_stream_t reply = NULL;
+ cci_identifier_t identifier = NULL;
+
+ if (!in_context ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_name ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_principal) { err = cci_check_error (ccErrBadParam); }
+ if (!out_ccache ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_stream_new (&request);
+ }
+
+ if (!err) {
+ err = cci_stream_write_string (request, in_name);
+ }
+
+ if (!err) {
+ err = cci_stream_write_uint32 (request, in_cred_vers);
+ }
+
+ if (!err) {
+ err = cci_stream_write_string (request, in_principal);
+ }
+
+ if (!err) {
+ err = cci_context_sync (context, 1);
+ }
+
+ if (!err) {
+ err = cci_ipc_send (cci_context_create_ccache_msg_id,
+ context->identifier,
+ request,
+ &reply);
+ }
+
+ if (!err) {
+ err = cci_identifier_read (&identifier, reply);
+ }
+
+ if (!err) {
+ err = cci_ccache_new (out_ccache, identifier);
+ }
+
+ cci_identifier_release (identifier);
+ cci_stream_release (reply);
+ cci_stream_release (request);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccapi_context_create_default_ccache (cc_context_t in_context,
+ cc_uint32 in_cred_vers,
+ const char *in_principal,
+ cc_ccache_t *out_ccache)
+{
+ cc_int32 err = ccNoError;
+ cci_context_t context = (cci_context_t) in_context;
+ cci_stream_t request = NULL;
+ cci_stream_t reply = NULL;
+ cci_identifier_t identifier = NULL;
+
+ if (!in_context ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_principal) { err = cci_check_error (ccErrBadParam); }
+ if (!out_ccache ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_stream_new (&request);
+ }
+
+ if (!err) {
+ err = cci_stream_write_uint32 (request, in_cred_vers);
+ }
+
+ if (!err) {
+ err = cci_stream_write_string (request, in_principal);
+ }
+
+ if (!err) {
+ err = cci_context_sync (context, 1);
+ }
+
+ if (!err) {
+ err = cci_ipc_send (cci_context_create_default_ccache_msg_id,
+ context->identifier,
+ request,
+ &reply);
+ }
+
+ if (!err) {
+ err = cci_identifier_read (&identifier, reply);
+ }
+
+ if (!err) {
+ err = cci_ccache_new (out_ccache, identifier);
+ }
+
+ cci_identifier_release (identifier);
+ cci_stream_release (reply);
+ cci_stream_release (request);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccapi_context_create_new_ccache (cc_context_t in_context,
+ cc_uint32 in_cred_vers,
+ const char *in_principal,
+ cc_ccache_t *out_ccache)
+{
+ cc_int32 err = ccNoError;
+ cci_context_t context = (cci_context_t) in_context;
+ cci_stream_t request = NULL;
+ cci_stream_t reply = NULL;
+ cci_identifier_t identifier = NULL;
+
+ if (!in_context ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_principal) { err = cci_check_error (ccErrBadParam); }
+ if (!out_ccache ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_stream_new (&request);
+ }
+
+ if (!err) {
+ err = cci_stream_write_uint32 (request, in_cred_vers);
+ }
+
+ if (!err) {
+ err = cci_stream_write_string (request, in_principal);
+ }
+
+ if (!err) {
+ err = cci_context_sync (context, 1);
+ }
+
+ if (!err) {
+ err = cci_ipc_send (cci_context_create_new_ccache_msg_id,
+ context->identifier,
+ request,
+ &reply);
+ }
+
+ if (!err) {
+ err = cci_identifier_read (&identifier, reply);
+ }
+
+ if (!err) {
+ err = cci_ccache_new (out_ccache, identifier);
+ }
+
+ cci_identifier_release (identifier);
+ cci_stream_release (reply);
+ cci_stream_release (request);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccapi_context_new_ccache_iterator (cc_context_t in_context,
+ cc_ccache_iterator_t *out_iterator)
+{
+ cc_int32 err = ccNoError;
+ cci_context_t context = (cci_context_t) in_context;
+ cci_stream_t reply = NULL;
+ cci_identifier_t identifier = NULL;
+
+ if (!in_context ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_iterator) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_context_sync (context, 0);
+ }
+
+ if (!err) {
+ err = cci_ipc_send_no_launch (cci_context_new_ccache_iterator_msg_id,
+ context->identifier,
+ NULL,
+ &reply);
+ }
+
+ if (!err) {
+ if (cci_stream_size (reply) > 0) {
+ err = cci_identifier_read (&identifier, reply);
+ } else {
+ identifier = cci_identifier_uninitialized;
+ }
+ }
+
+ if (!err) {
+ err = cci_ccache_iterator_new (out_iterator, identifier);
+ }
+
+ cci_stream_release (reply);
+ cci_identifier_release (identifier);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccapi_context_lock (cc_context_t in_context,
+ cc_uint32 in_lock_type,
+ cc_uint32 in_block)
+{
+ cc_int32 err = ccNoError;
+ cci_context_t context = (cci_context_t) in_context;
+ cci_stream_t request = NULL;
+
+ if (!in_context) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_stream_new (&request);
+ }
+
+ if (!err) {
+ err = cci_stream_write_uint32 (request, in_lock_type);
+ }
+
+ if (!err) {
+ err = cci_stream_write_uint32 (request, in_block);
+ }
+
+ if (!err) {
+ err = cci_context_sync (context, 1);
+ }
+
+ if (!err) {
+ err = cci_ipc_send (cci_context_lock_msg_id,
+ context->identifier,
+ request,
+ NULL);
+ }
+
+ cci_stream_release (request);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccapi_context_unlock (cc_context_t in_context)
+{
+ cc_int32 err = ccNoError;
+ cci_context_t context = (cci_context_t) in_context;
+
+ if (!in_context) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_context_sync (context, 1);
+ }
+
+ if (!err) {
+ err = cci_ipc_send (cci_context_unlock_msg_id,
+ context->identifier,
+ NULL,
+ NULL);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccapi_context_compare (cc_context_t in_context,
+ cc_context_t in_compare_to_context,
+ cc_uint32 *out_equal)
+{
+ cc_int32 err = ccNoError;
+ cci_context_t context = (cci_context_t) in_context;
+ cci_context_t compare_to_context = (cci_context_t) in_compare_to_context;
+
+ if (!in_context ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_compare_to_context) { err = cci_check_error (ccErrBadParam); }
+ if (!out_equal ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_context_sync (context, 0);
+ }
+
+ if (!err) {
+ err = cci_context_sync (compare_to_context, 0);
+ }
+
+ if (!err) {
+ /* If both contexts can't talk to the server, then
+ * we assume they are equivalent */
+ err = cci_identifier_compare (context->identifier,
+ compare_to_context->identifier,
+ out_equal);
+ }
+
+ return cci_check_error (err);
+}
+
+#pragma mark -
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 cci_context_sync (cci_context_t in_context,
+ cc_uint32 in_launch)
+{
+ cc_int32 err = ccNoError;
+ cci_context_t context = (cci_context_t) in_context;
+ cci_stream_t reply = NULL;
+ cci_identifier_t new_identifier = NULL;
+
+ if (!in_context) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ /* Use the uninitialized identifier because we may be talking */
+ /* to a different server which would reject our identifier and */
+ /* the point of this message is to sync with the server's id */
+ if (in_launch) {
+ err = cci_ipc_send (cci_context_sync_msg_id,
+ cci_identifier_uninitialized,
+ NULL,
+ &reply);
+ } else {
+ err = cci_ipc_send_no_launch (cci_context_sync_msg_id,
+ cci_identifier_uninitialized,
+ NULL,
+ &reply);
+ }
+ }
+
+ if (!err) {
+ if (cci_stream_size (reply) > 0) {
+ err = cci_identifier_read (&new_identifier, reply);
+ } else {
+ new_identifier = cci_identifier_uninitialized;
+ }
+ }
+
+ if (!err) {
+ cc_uint32 equal = 0;
+
+ err = cci_identifier_compare (context->identifier, new_identifier, &equal);
+
+ if (!err && !equal) {
+ if (context->identifier) {
+ cci_identifier_release (context->identifier);
+ }
+ context->identifier = new_identifier;
+ new_identifier = NULL; /* take ownership */
+ }
+ }
+
+ if (!err && context->synchronized) {
+ err = cci_context_change_time_sync (context->identifier);
+ }
+
+ if (!err && !context->synchronized) {
+ /* Keep state about whether this is the first call to avoid always */
+ /* modifying the global change time on the context's first ipc call. */
+ context->synchronized = 1;
+ }
+
+ cci_identifier_release (new_identifier);
+ cci_stream_release (reply);
+
+ return cci_check_error (err);
+}
+
diff --git a/src/ccapi/lib/ccapi_context.h b/src/ccapi/lib/ccapi_context.h
new file mode 100644
index 0000000000..4ac0b06c3a
--- /dev/null
+++ b/src/ccapi/lib/ccapi_context.h
@@ -0,0 +1,78 @@
+/*
+ * $Header$
+ *
+ * Copyright 2006 Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#ifndef CCAPI_CONTEXT_H
+#define CCAPI_CONTEXT_H
+
+#include "cci_common.h"
+
+cc_int32 ccapi_context_release (cc_context_t in_context);
+
+cc_int32 ccapi_context_get_change_time (cc_context_t in_context,
+ cc_time_t *out_time);
+
+cc_int32 ccapi_context_wait_for_change (cc_context_t in_context);
+
+cc_int32 ccapi_context_get_default_ccache_name (cc_context_t in_context,
+ cc_string_t *out_name);
+
+cc_int32 ccapi_context_open_ccache (cc_context_t in_context,
+ const char *in_name,
+ cc_ccache_t *out_ccache);
+
+cc_int32 ccapi_context_open_default_ccache (cc_context_t in_context,
+ cc_ccache_t *out_ccache);
+
+cc_int32 ccapi_context_create_ccache (cc_context_t in_context,
+ const char *in_name,
+ cc_uint32 in_cred_vers,
+ const char *in_principal,
+ cc_ccache_t *out_ccache);
+
+cc_int32 ccapi_context_create_default_ccache (cc_context_t in_context,
+ cc_uint32 in_cred_vers,
+ const char *in_principal,
+ cc_ccache_t *out_ccache);
+
+cc_int32 ccapi_context_create_new_ccache (cc_context_t in_context,
+ cc_uint32 in_cred_vers,
+ const char *in_principal,
+ cc_ccache_t *out_ccache);
+
+cc_int32 ccapi_context_new_ccache_iterator (cc_context_t in_context,
+ cc_ccache_iterator_t *out_iterator);
+
+cc_int32 ccapi_context_lock (cc_context_t in_context,
+ cc_uint32 in_lock_type,
+ cc_uint32 in_block);
+
+cc_int32 ccapi_context_unlock (cc_context_t in_context);
+
+cc_int32 ccapi_context_compare (cc_context_t in_context,
+ cc_context_t in_compare_to_context,
+ cc_uint32 *out_equal);
+
+#endif /* CCAPI_CONTEXT_H */
diff --git a/src/ccapi/lib/ccapi_context_change_time.c b/src/ccapi/lib/ccapi_context_change_time.c
new file mode 100644
index 0000000000..fb5b7ddae8
--- /dev/null
+++ b/src/ccapi/lib/ccapi_context_change_time.c
@@ -0,0 +1,200 @@
+/*
+ * $Header$
+ *
+ * Copyright 2006 Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#include "ccapi_context_change_time.h"
+#include "cci_common.h"
+
+#include "k5-thread.h"
+
+static cci_identifier_t g_change_time_identifer = NULL;
+static cc_time_t g_change_time = 0;
+static cc_time_t g_change_time_offset = 0;
+static k5_mutex_t g_change_time_mutex = K5_MUTEX_PARTIAL_INITIALIZER;
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 cci_context_change_time_thread_init (void)
+{
+ return k5_mutex_finish_init(&g_change_time_mutex);
+}
+
+/* ------------------------------------------------------------------------ */
+/* WARNING! Mutex must be locked when calling this! */
+
+static cc_int32 cci_context_change_time_update_identifier (cci_identifier_t in_new_identifier,
+ cc_uint32 *out_server_ids_match,
+ cc_uint32 *out_old_server_running,
+ cc_uint32 *out_new_server_running)
+{
+ cc_int32 err = ccNoError;
+ cc_uint32 server_ids_match = 0;
+ cc_uint32 old_server_running = 0;
+ cc_uint32 new_server_running = 0;
+
+ if (!in_new_identifier) { err = cci_check_error (err); }
+
+ if (!err && !g_change_time_identifer) {
+ g_change_time_identifer = cci_identifier_uninitialized;
+ }
+
+ if (!err) {
+ err = cci_identifier_compare_server_id (g_change_time_identifer,
+ in_new_identifier,
+ &server_ids_match);
+ }
+
+ if (!err && out_old_server_running) {
+ err = cci_identifier_is_initialized (g_change_time_identifer, &old_server_running);
+ }
+
+ if (!err && out_new_server_running) {
+ err = cci_identifier_is_initialized (in_new_identifier, &new_server_running);
+ }
+
+ if (!err && !server_ids_match) {
+ cci_identifier_t new_change_time_identifer = NULL;
+
+ err = cci_identifier_copy (&new_change_time_identifer, in_new_identifier);
+
+ if (!err) {
+ /* Save the new identifier */
+ if (g_change_time_identifer) {
+ cci_identifier_release (g_change_time_identifer);
+ }
+ g_change_time_identifer = new_change_time_identifer;
+ }
+ }
+
+ if (!err) {
+ if (out_server_ids_match ) { *out_server_ids_match = server_ids_match; }
+ if (out_old_server_running) { *out_old_server_running = old_server_running; }
+ if (out_new_server_running) { *out_new_server_running = new_server_running; }
+ }
+
+
+ return cci_check_error (err);
+}
+
+#pragma mark -
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 cci_context_change_time_get (cc_time_t *out_change_time)
+{
+ cc_int32 err = ccNoError;
+
+ err = k5_mutex_lock (&g_change_time_mutex);
+
+ if (!err) {
+ *out_change_time = g_change_time + g_change_time_offset;
+ k5_mutex_unlock (&g_change_time_mutex);
+ }
+
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 cci_context_change_time_update (cci_identifier_t in_identifier,
+ cc_time_t in_new_change_time)
+{
+ cc_int32 err = ccNoError;
+ cc_int32 lock_err = err = k5_mutex_lock (&g_change_time_mutex);
+
+ if (!err) {
+ if (!in_identifier) { err = cci_check_error (err); }
+ }
+
+ if (!err) {
+ if (g_change_time < in_new_change_time) {
+ /* Only update if it increases the time. May be a different server. */
+ g_change_time = in_new_change_time;
+ cci_debug_printf ("%s: setting change time to %d",
+ __FUNCTION__, in_new_change_time);
+ }
+ }
+
+ if (!err) {
+ err = cci_context_change_time_update_identifier (in_identifier,
+ NULL, NULL, NULL);
+ }
+
+ if (!lock_err) {
+ k5_mutex_unlock (&g_change_time_mutex);
+ }
+
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 cci_context_change_time_sync (cci_identifier_t in_new_identifier)
+{
+ cc_int32 err = ccNoError;
+ cc_int32 lock_err = err = k5_mutex_lock (&g_change_time_mutex);
+ cc_uint32 server_ids_match = 0;
+ cc_uint32 server_was_running = 0;
+ cc_uint32 server_is_running = 0;
+
+ if (!err) {
+ if (!in_new_identifier) { err = cci_check_error (err); }
+ }
+
+ if (!err) {
+ err = cci_context_change_time_update_identifier (in_new_identifier,
+ &server_ids_match,
+ &server_was_running,
+ &server_is_running);
+ }
+
+ if (!err && !server_ids_match) {
+ /* Increment the change time so callers re-read */
+ g_change_time_offset++;
+
+ /* If the server died, absorb the offset */
+ if (server_was_running && !server_is_running) {
+ cc_time_t now = time (NULL);
+
+ g_change_time += g_change_time_offset;
+ g_change_time_offset = 0;
+
+ /* Make sure the change time increases, ideally with the current time */
+ g_change_time = (g_change_time < now) ? now : g_change_time;
+ }
+
+ cci_debug_printf ("%s noticed server changed ("
+ "server_was_running = %d; server_is_running = %d; "
+ "g_change_time = %d; g_change_time_offset = %d",
+ __FUNCTION__, server_was_running, server_is_running,
+ g_change_time, g_change_time_offset);
+ }
+
+ if (!lock_err) {
+ k5_mutex_unlock (&g_change_time_mutex);
+ }
+
+ return err;
+}
diff --git a/src/ccapi/lib/ccapi_context_change_time.h b/src/ccapi/lib/ccapi_context_change_time.h
new file mode 100644
index 0000000000..536c492d88
--- /dev/null
+++ b/src/ccapi/lib/ccapi_context_change_time.h
@@ -0,0 +1,41 @@
+/*
+ * $Header$
+ *
+ * Copyright 2006 Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#ifndef CCAPI_CONTEXT_CHANGE_TIME_H
+#define CCAPI_CONTEXT_CHANGE_TIME_H
+
+#include "cci_common.h"
+
+cc_int32 cci_context_change_time_thread_init (void);
+
+cc_int32 cci_context_change_time_get (cc_time_t *out_change_time);
+
+cc_int32 cci_context_change_time_update (cci_identifier_t in_identifier,
+ cc_time_t in_new_change_time);
+
+cc_int32 cci_context_change_time_sync (cci_identifier_t in_new_identifier);
+
+#endif /* CCAPI_CONTEXT_CHANGE_TIME_H */
diff --git a/src/ccapi/lib/ccapi_credentials.c b/src/ccapi/lib/ccapi_credentials.c
new file mode 100644
index 0000000000..4e1f48e016
--- /dev/null
+++ b/src/ccapi/lib/ccapi_credentials.c
@@ -0,0 +1,166 @@
+/*
+ * $Header$
+ *
+ * Copyright 2006 Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#include "ccapi_credentials.h"
+
+#include "ccapi_string.h"
+
+/* ------------------------------------------------------------------------ */
+
+typedef struct cci_credentials_d {
+ cc_credentials_union *data;
+ cc_credentials_f *functions;
+#if TARGET_OS_MAC
+ cc_credentials_f *vector_functions;
+#endif
+ cci_identifier_t identifier;
+} *cci_credentials_t;
+
+/* ------------------------------------------------------------------------ */
+
+struct cci_credentials_d cci_credentials_initializer = {
+ NULL,
+ NULL
+ VECTOR_FUNCTIONS_INITIALIZER,
+ NULL
+};
+
+cc_credentials_f cci_credentials_f_initializer = {
+ ccapi_credentials_release,
+ ccapi_credentials_compare
+};
+
+cc_credentials_union cci_cred_union_initializer = {
+ 0,
+ { NULL }
+};
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 cci_credentials_read (cc_credentials_t *out_credentials,
+ cci_stream_t in_stream)
+{
+ cc_int32 err = ccNoError;
+ cci_credentials_t credentials = NULL;
+
+ if (!out_credentials) { err = cci_check_error (ccErrBadParam); }
+ if (!in_stream ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ credentials = malloc (sizeof (*credentials));
+ if (credentials) {
+ *credentials = cci_credentials_initializer;
+ } else {
+ err = cci_check_error (ccErrNoMem);
+ }
+ }
+
+ if (!err) {
+ credentials->functions = malloc (sizeof (*credentials->functions));
+ if (credentials->functions) {
+ *credentials->functions = cci_credentials_f_initializer;
+ } else {
+ err = cci_check_error (ccErrNoMem);
+ }
+ }
+
+ if (!err) {
+ err = cci_identifier_read (&credentials->identifier, in_stream);
+ }
+
+ if (!err) {
+ err = cci_cred_union_read (&credentials->data, in_stream);
+ }
+
+ if (!err) {
+ *out_credentials = (cc_credentials_t) credentials;
+ credentials = NULL; /* take ownership */
+ }
+
+ if (credentials) { ccapi_credentials_release ((cc_credentials_t) credentials); }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 cci_credentials_write (cc_credentials_t in_credentials,
+ cci_stream_t in_stream)
+{
+ cc_int32 err = ccNoError;
+ cci_credentials_t credentials = (cci_credentials_t) in_credentials;
+
+ if (!in_credentials) { err = cci_check_error (ccErrBadParam); }
+ if (!in_stream ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_identifier_write (credentials->identifier, in_stream);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccapi_credentials_compare (cc_credentials_t in_credentials,
+ cc_credentials_t in_compare_to_credentials,
+ cc_uint32 *out_equal)
+{
+ cc_int32 err = ccNoError;
+ cci_credentials_t credentials = (cci_credentials_t) in_credentials;
+ cci_credentials_t compare_to_credentials = (cci_credentials_t) in_compare_to_credentials;
+
+ if (!in_credentials ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_compare_to_credentials) { err = cci_check_error (ccErrBadParam); }
+ if (!out_equal ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_identifier_compare (credentials->identifier,
+ compare_to_credentials->identifier,
+ out_equal);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccapi_credentials_release (cc_credentials_t io_credentials)
+{
+ cc_int32 err = ccNoError;
+ cci_credentials_t credentials = (cci_credentials_t) io_credentials;
+
+ if (!io_credentials) { err = ccErrBadParam; }
+
+ if (!err) {
+ cci_cred_union_release (credentials->data);
+ free ((char *) credentials->functions);
+ cci_identifier_release (credentials->identifier);
+ free (credentials);
+ }
+
+ return err;
+}
diff --git a/src/ccapi/lib/ccapi_credentials.h b/src/ccapi/lib/ccapi_credentials.h
new file mode 100644
index 0000000000..bde0b2c03d
--- /dev/null
+++ b/src/ccapi/lib/ccapi_credentials.h
@@ -0,0 +1,44 @@
+/*
+ * $Header$
+ *
+ * Copyright 2006 Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#ifndef CCAPI_CREDENTIALS_H
+#define CCAPI_CREDENTIALS_H
+
+#include "cci_common.h"
+
+cc_int32 cci_credentials_read (cc_credentials_t *out_credentials,
+ cci_stream_t in_stream);
+
+cc_int32 cci_credentials_write (cc_credentials_t in_credentials,
+ cci_stream_t in_stream);
+
+cc_int32 ccapi_credentials_compare (cc_credentials_t in_credentials,
+ cc_credentials_t in_compare_to_credentials,
+ cc_uint32 *out_equal);
+
+cc_int32 ccapi_credentials_release (cc_credentials_t io_credentials);
+
+#endif /* CCAPI_CREDENTIALS_H */
diff --git a/src/ccapi/lib/ccapi_credentials_iterator.c b/src/ccapi/lib/ccapi_credentials_iterator.c
new file mode 100644
index 0000000000..a99e52b499
--- /dev/null
+++ b/src/ccapi/lib/ccapi_credentials_iterator.c
@@ -0,0 +1,194 @@
+/*
+ * $Header$
+ *
+ * Copyright 2006 Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#include "ccapi_credentials_iterator.h"
+#include "ccapi_credentials.h"
+#include "ccapi_ipc.h"
+
+/* ------------------------------------------------------------------------ */
+
+typedef struct cci_credentials_iterator_d {
+ cc_credentials_iterator_f *functions;
+#if TARGET_OS_MAC
+ cc_credentials_iterator_f *vector_functions;
+#endif
+ cci_identifier_t identifier;
+} *cci_credentials_iterator_t;
+
+/* ------------------------------------------------------------------------ */
+
+struct cci_credentials_iterator_d cci_credentials_iterator_initializer = {
+ NULL
+ VECTOR_FUNCTIONS_INITIALIZER,
+ NULL
+};
+
+cc_credentials_iterator_f cci_credentials_iterator_f_initializer = {
+ ccapi_credentials_iterator_release,
+ ccapi_credentials_iterator_next,
+ ccapi_credentials_iterator_clone
+};
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 cci_credentials_iterator_new (cc_credentials_iterator_t *out_credentials_iterator,
+ cci_identifier_t in_identifier)
+{
+ cc_int32 err = ccNoError;
+ cci_credentials_iterator_t credentials_iterator = NULL;
+
+ if (!out_credentials_iterator) { err = cci_check_error (ccErrBadParam); }
+ if (!in_identifier ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ credentials_iterator = malloc (sizeof (*credentials_iterator));
+ if (credentials_iterator) {
+ *credentials_iterator = cci_credentials_iterator_initializer;
+ } else {
+ err = cci_check_error (ccErrNoMem);
+ }
+ }
+
+ if (!err) {
+ credentials_iterator->functions = malloc (sizeof (*credentials_iterator->functions));
+ if (credentials_iterator->functions) {
+ *credentials_iterator->functions = cci_credentials_iterator_f_initializer;
+ } else {
+ err = cci_check_error (ccErrNoMem);
+ }
+ }
+
+ if (!err) {
+ err = cci_identifier_copy (&credentials_iterator->identifier, in_identifier);
+ }
+
+ if (!err) {
+ *out_credentials_iterator = (cc_credentials_iterator_t) credentials_iterator;
+ credentials_iterator = NULL; /* take ownership */
+ }
+
+ if (credentials_iterator) { ccapi_credentials_iterator_release ((cc_credentials_iterator_t) credentials_iterator); }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 cci_credentials_iterator_write (cc_credentials_iterator_t in_credentials_iterator,
+ cci_stream_t in_stream)
+{
+ cc_int32 err = ccNoError;
+ cci_credentials_iterator_t credentials_iterator = (cci_credentials_iterator_t) in_credentials_iterator;
+
+ if (!in_credentials_iterator) { err = cci_check_error (ccErrBadParam); }
+ if (!in_stream ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_identifier_write (credentials_iterator->identifier, in_stream);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccapi_credentials_iterator_release (cc_credentials_iterator_t io_credentials_iterator)
+{
+ cc_int32 err = ccNoError;
+ cci_credentials_iterator_t credentials_iterator = (cci_credentials_iterator_t) io_credentials_iterator;
+
+ if (!io_credentials_iterator) { err = ccErrBadParam; }
+
+ if (!err) {
+ free ((char *) credentials_iterator->functions);
+ cci_identifier_release (credentials_iterator->identifier);
+ free (credentials_iterator);
+ }
+
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccapi_credentials_iterator_next (cc_credentials_iterator_t in_credentials_iterator,
+ cc_credentials_t *out_credentials)
+{
+ cc_int32 err = ccNoError;
+ cci_credentials_iterator_t credentials_iterator = (cci_credentials_iterator_t) in_credentials_iterator;
+ cci_stream_t reply = NULL;
+
+ if (!in_credentials_iterator) { err = cci_check_error (ccErrBadParam); }
+ if (!out_credentials ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_ipc_send (cci_credentials_iterator_next_msg_id,
+ credentials_iterator->identifier,
+ NULL,
+ &reply);
+ }
+
+ if (!err) {
+ err = cci_credentials_read (out_credentials, reply);
+ }
+
+ cci_stream_release (reply);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccapi_credentials_iterator_clone (cc_credentials_iterator_t in_credentials_iterator,
+ cc_credentials_iterator_t *out_credentials_iterator)
+{
+ cc_int32 err = ccNoError;
+ cci_credentials_iterator_t credentials_iterator = (cci_credentials_iterator_t) in_credentials_iterator;
+ cci_stream_t reply = NULL;
+ cci_identifier_t identifier = NULL;
+
+ if (!in_credentials_iterator ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_credentials_iterator) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_ipc_send (cci_credentials_iterator_next_msg_id,
+ credentials_iterator->identifier,
+ NULL,
+ &reply);
+ }
+
+ if (!err) {
+ err = cci_identifier_read (&identifier, reply);
+ }
+
+ if (!err) {
+ err = cci_credentials_iterator_new (out_credentials_iterator, identifier);
+ }
+
+ cci_stream_release (reply);
+ cci_identifier_release (identifier);
+
+ return cci_check_error (err);
+}
diff --git a/src/ccapi/lib/ccapi_credentials_iterator.h b/src/ccapi/lib/ccapi_credentials_iterator.h
new file mode 100644
index 0000000000..7ffbd23011
--- /dev/null
+++ b/src/ccapi/lib/ccapi_credentials_iterator.h
@@ -0,0 +1,46 @@
+/*
+ * $Header$
+ *
+ * Copyright 2006 Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#ifndef CCAPI_CREDENTIALS_ITERATOR_H
+#define CCAPI_CREDENTIALS_ITERATOR_H
+
+#include "cci_common.h"
+
+cc_int32 cci_credentials_iterator_new (cc_credentials_iterator_t *out_credentials_iterator,
+ cci_identifier_t in_identifier);
+
+cc_int32 cci_credentials_iterator_write (cc_credentials_iterator_t in_credentials_iterator,
+ cci_stream_t in_stream);
+
+cc_int32 ccapi_credentials_iterator_release (cc_credentials_iterator_t io_credentials_iterator);
+
+cc_int32 ccapi_credentials_iterator_next (cc_credentials_iterator_t in_credentials_iterator,
+ cc_credentials_t *out_credentials);
+
+cc_int32 ccapi_credentials_iterator_clone (cc_credentials_iterator_t in_credentials_iterator,
+ cc_credentials_iterator_t *out_credentials_iterator);
+
+#endif /* CCAPI_CREDENTIALS_ITERATOR_H */
diff --git a/src/ccapi/lib/ccapi_err.et b/src/ccapi/lib/ccapi_err.et
new file mode 100644
index 0000000000..44cd2d0b5e
--- /dev/null
+++ b/src/ccapi/lib/ccapi_err.et
@@ -0,0 +1,74 @@
+#
+# $Header$
+#
+# Copyright 1998-2006 Massachusetts Institute of Technology.
+# All Rights Reserved.
+#
+# Export of this software from the United States of America may
+# require a specific license from the United States Government.
+# It is the responsibility of any person or organization contemplating
+# export to obtain such a license before exporting.
+#
+# WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+# distribute this software and its documentation for any purpose and
+# without fee is hereby granted, provided that the above copyright
+# notice appear in all copies and that both that copyright notice and
+# this permission notice appear in supporting documentation, and that
+# the name of M.I.T. not be used in advertising or publicity pertaining
+# to distribution of the software without specific, written prior
+# permission. Furthermore if you modify this software you must label
+# your software as modified software and not distribute it in such a
+# fashion that it might be confused with the original M.I.T. software.
+# M.I.T. makes no representations about the suitability of
+# this software for any purpose. It is provided "as is" without express
+# or implied warranty.
+#
+
+error_table_base 201
+error_table_manager "Credentials Cache"
+error_table CAPI
+
+# 201
+error_code ccIteratorEnd, "Reached end of iterator"
+error_code ccErrBadParam, "Invalid argument"
+error_code ccErrNoMem, "Out of memory"
+error_code ccErrInvalidContext, "Invalid credentials cache context"
+error_code ccErrInvalidCCache, "Invalid credentials cache"
+
+# 206
+index 5
+error_code ccErrInvalidString, "Invalid credentials cache string"
+error_code ccErrInvalidCredentials, "Invalid credentials"
+error_code ccErrInvalidCCacheIterator, "Invalid credentials cache iterator"
+error_code ccErrInvalidCredentialsIterator, "Invalid credentials iterator"
+error_code ccErrInvalidLock, "Invalid iterator"
+
+# 211
+index 10
+error_code ccErrBadName, "Invalid credentials cache name"
+error_code ccErrBadCredentialsVersion, "Invalid credentials cache version (not 4 or 5)"
+error_code ccErrBadAPIVersion, "Invalid CCAPI version"
+error_code ccErrContextLocked, "Credentials cache context is already locked"
+error_code ccErrContextUnlocked, "Credentials cache context is already unlocked"
+
+# 216
+index 15
+error_code ccErrCCacheLocked, "Credentials cache is already locked"
+error_code ccErrCCacheUnlocked, "Credentials cache is already unlocked"
+error_code ccErrBadLockType, "Invalid credentials cache lock type"
+error_code ccErrNeverDefault, "Credentials cache has never been the default cache"
+error_code ccErrCredentialsNotFound, "Credentials not found"
+
+# 221
+index 20
+error_code ccErrCCacheNotFound, "Credentials cache not found"
+error_code ccErrContextNotFound, "Credentials cache context not found"
+error_code ccErrServerUnavailable, "Credentials cache server unavailable"
+error_code ccErrServerInsecure, "Credentials cache server in this bootstrap is owned by another user"
+error_code ccErrServerCantBecomeUID, "Credentials cache server failed to change effective uids"
+
+# 226
+index 25
+error_code ccErrTimeOffsetNotSet, "Credentials cache time offset not set"
+
+end
diff --git a/src/ccapi/lib/ccapi_ipc.c b/src/ccapi/lib/ccapi_ipc.c
new file mode 100644
index 0000000000..4d2e4314d5
--- /dev/null
+++ b/src/ccapi/lib/ccapi_ipc.c
@@ -0,0 +1,113 @@
+/*
+ * $Header$
+ *
+ * Copyright 2006 Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#include "ccapi_ipc.h"
+#include "ccapi_os_ipc.h"
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 cci_ipc_thread_init (void)
+{
+ return cci_os_ipc_thread_init ();
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 _cci_ipc_send (enum cci_msg_id_t in_request_name,
+ cc_int32 in_launch_server,
+ cci_identifier_t in_identifier,
+ cci_stream_t in_request_data,
+ cci_stream_t *out_reply_data)
+{
+ cc_int32 err = ccNoError;
+ cci_stream_t request = NULL;
+ cci_stream_t reply = NULL;
+ cc_int32 reply_error = 0;
+
+ if (!in_identifier) { err = cci_check_error (ccErrBadParam); }
+ /* in_request_data may be NULL */
+ /* out_reply_data may be NULL */
+
+ if (!err) {
+ err = cci_message_new_request_header (&request,
+ in_request_name,
+ in_identifier);
+ }
+
+ if (!err && in_request_data) {
+ err = cci_stream_write (request,
+ cci_stream_data (in_request_data),
+ cci_stream_size (in_request_data));
+ }
+
+ if (!err) {
+ err = cci_os_ipc (in_launch_server, request, &reply);
+
+ if (!err && cci_stream_size (reply) > 0) {
+ err = cci_message_read_reply_header (reply, &reply_error);
+ }
+ }
+
+ if (!err && reply_error) {
+ err = reply_error;
+ }
+
+ if (!err && out_reply_data) {
+ *out_reply_data = reply;
+ reply = NULL; /* take ownership */
+ }
+
+ cci_stream_release (request);
+ cci_stream_release (reply);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 cci_ipc_send (enum cci_msg_id_t in_request_name,
+ cci_identifier_t in_identifier,
+ cci_stream_t in_request_data,
+ cci_stream_t *out_reply_data)
+{
+ return cci_check_error (_cci_ipc_send (in_request_name, 1,
+ in_identifier,
+ in_request_data,
+ out_reply_data));
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 cci_ipc_send_no_launch (enum cci_msg_id_t in_request_name,
+ cci_identifier_t in_identifier,
+ cci_stream_t in_request_data,
+ cci_stream_t *out_reply_data)
+{
+ return cci_check_error (_cci_ipc_send (in_request_name, 0,
+ in_identifier,
+ in_request_data,
+ out_reply_data));
+}
diff --git a/src/ccapi/lib/ccapi_ipc.h b/src/ccapi/lib/ccapi_ipc.h
new file mode 100644
index 0000000000..73c5b24972
--- /dev/null
+++ b/src/ccapi/lib/ccapi_ipc.h
@@ -0,0 +1,44 @@
+/*
+ * $Header$
+ *
+ * Copyright 2006 Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#ifndef CCAPI_IPC_H
+#define CCAPI_IPC_H
+
+#include "cci_common.h"
+
+cc_int32 cci_ipc_thread_init (void);
+
+cc_int32 cci_ipc_send (enum cci_msg_id_t in_request_name,
+ cci_identifier_t in_identifier,
+ cci_stream_t in_request_data,
+ cci_stream_t *out_reply_data);
+
+cc_int32 cci_ipc_send_no_launch (enum cci_msg_id_t in_request_name,
+ cci_identifier_t in_identifier,
+ cci_stream_t in_request_data,
+ cci_stream_t *out_reply_data);
+
+#endif /* CCAPI_IPC_H */
diff --git a/src/ccapi/lib/ccapi_os_ipc.h b/src/ccapi/lib/ccapi_os_ipc.h
new file mode 100644
index 0000000000..8cce06c60e
--- /dev/null
+++ b/src/ccapi/lib/ccapi_os_ipc.h
@@ -0,0 +1,38 @@
+/*
+ * $Header$
+ *
+ * Copyright 2006 Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#ifndef CCAPI_OS_IPC_H
+#define CCAPI_OS_IPC_H
+
+#include "cci_common.h"
+
+inline cc_int32 cci_os_ipc_thread_init (void);
+
+cc_int32 cci_os_ipc (cc_int32 in_launch_server,
+ cci_stream_t in_request_stream,
+ cci_stream_t *out_reply_stream);
+
+#endif /* CCAPI_OS_IPC_H */
diff --git a/src/ccapi/lib/ccapi_string.c b/src/ccapi/lib/ccapi_string.c
new file mode 100644
index 0000000000..4acd9a89d4
--- /dev/null
+++ b/src/ccapi/lib/ccapi_string.c
@@ -0,0 +1,104 @@
+/*
+ * $Header$
+ *
+ * Copyright 2006 Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#include "ccapi_string.h"
+
+/* ------------------------------------------------------------------------ */
+
+cc_string_d cci_string_d_initializer = {
+ NULL,
+ NULL
+ VECTOR_FUNCTIONS_INITIALIZER };
+
+cc_string_f cci_string_f_initializer = {
+ ccapi_string_release
+};
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 cci_string_new (cc_string_t *out_string,
+ char *in_cstring)
+{
+ cc_int32 err = ccNoError;
+ cc_string_t string = NULL;
+
+ if (!out_string) { err = cci_check_error (ccErrBadParam); }
+ if (!in_cstring) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ string = malloc (sizeof (*string));
+ if (string) {
+ *string = cci_string_d_initializer;
+ } else {
+ err = cci_check_error (ccErrNoMem);
+ }
+ }
+
+ if (!err) {
+ string->functions = malloc (sizeof (*string->functions));
+ if (string->functions) {
+ *((cc_string_f *) string->functions) = cci_string_f_initializer;
+ } else {
+ err = cci_check_error (ccErrNoMem);
+ }
+ }
+
+ if (!err) {
+ string->data = malloc (strlen (in_cstring) + 1);
+ if (string->data) {
+ strcpy ((char *)string->data, in_cstring);
+ } else {
+ err = cci_check_error (ccErrNoMem);
+ }
+
+ }
+
+ if (!err) {
+ *out_string = string;
+ string = NULL; /* take ownership */
+ }
+
+ if (string) { ccapi_string_release (string); }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccapi_string_release (cc_string_t in_string)
+{
+ cc_int32 err = ccNoError;
+
+ if (!in_string) { err = ccErrBadParam; }
+
+ if (!err) {
+ free ((char *) in_string->data);
+ free ((char *) in_string->functions);
+ free (in_string);
+ }
+
+ return err;
+}
diff --git a/src/ccapi/lib/ccapi_string.h b/src/ccapi/lib/ccapi_string.h
new file mode 100644
index 0000000000..dec7a7cc72
--- /dev/null
+++ b/src/ccapi/lib/ccapi_string.h
@@ -0,0 +1,37 @@
+/*
+ * $Header$
+ *
+ * Copyright 2006 Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#ifndef CCAPI_STRING_H
+#define CCAPI_STRING_H
+
+#include "cci_common.h"
+
+cc_int32 cci_string_new (cc_string_t *out_string,
+ char *in_cstring);
+
+cc_int32 ccapi_string_release (cc_string_t in_string);
+
+#endif /* CCAPI_STRING_H */
diff --git a/src/ccapi/lib/ccapi_v2.c b/src/ccapi/lib/ccapi_v2.c
new file mode 100644
index 0000000000..0036c70d31
--- /dev/null
+++ b/src/ccapi/lib/ccapi_v2.c
@@ -0,0 +1,232 @@
+/*
+ * $Header$
+ *
+ * Copyright 2006 Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#include "cci_common.h"
+#include <CredentialsCache2.h>
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_shutdown (apiCB **io_context)
+{
+ return CC_NOT_SUPP;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_get_NC_info (apiCB *in_context,
+ infoNC ***out_info)
+{
+ return CC_NOT_SUPP;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_get_change_time (apiCB *in_context,
+ cc_time_t *out_change_time)
+{
+ return CC_NOT_SUPP;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 cc_open (apiCB *in_context,
+ const char *in_name,
+ cc_int32 in_version,
+ cc_uint32 in_flags,
+ ccache_p **out_ccache)
+{
+ return CC_NOT_SUPP;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_create (apiCB *in_context,
+ const char *in_name,
+ const char *in_principal,
+ cc_int32 in_version,
+ cc_uint32 in_flags,
+ ccache_p **out_ccache)
+{
+ return CC_NOT_SUPP;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_close (apiCB *in_context,
+ ccache_p **io_ccache)
+{
+ return CC_NOT_SUPP;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_destroy (apiCB *in_context,
+ ccache_p **io_ccache)
+{
+ return CC_NOT_SUPP;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_seq_fetch_NCs_begin (apiCB *in_context,
+ ccache_cit **out_iterator)
+{
+ return CC_NOT_SUPP;
+}
+
+/* ------------------------------------------------------------------------ */
+
+// CCache iterators need to return some ccaches twice (when v3 ccache has
+// two kinds of credentials). To do that, we use a single v3 iterator, but
+// sometimes don't advance it.
+
+cc_result cc_seq_fetch_NCs_next (apiCB *in_context,
+ ccache_p **out_ccache,
+ ccache_cit *in_iterator)
+{
+ return CC_NOT_SUPP;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_seq_fetch_NCs_end (apiCB *in_context,
+ ccache_cit **io_iterator)
+{
+ return CC_NOT_SUPP;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_get_name (apiCB *in_context,
+ ccache_p *in_ccache,
+ char **out_name)
+{
+ return CC_NOT_SUPP;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_get_cred_version (apiCB *in_context,
+ ccache_p *in_ccache,
+ cc_int32 *out_version)
+{
+ return CC_NOT_SUPP;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_set_principal (apiCB *in_context,
+ ccache_p *io_ccache,
+ cc_int32 in_version,
+ char *in_principal)
+{
+ return CC_NOT_SUPP;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_get_principal (apiCB *in_context,
+ ccache_p *in_ccache,
+ char **out_principal)
+{
+ return CC_NOT_SUPP;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_store (apiCB *in_context,
+ ccache_p *io_ccache,
+ cred_union in_credentials)
+{
+ return CC_NOT_SUPP;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_remove_cred (apiCB *in_context,
+ ccache_p *in_ccache,
+ cred_union in_credentials)
+{
+ return CC_NOT_SUPP;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_seq_fetch_creds_begin (apiCB *in_context,
+ const ccache_p *in_ccache,
+ ccache_cit **out_iterator)
+{
+ return CC_NOT_SUPP;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_seq_fetch_creds_next (apiCB *in_context,
+ cred_union **out_creds,
+ ccache_cit *in_iterator)
+{
+ return CC_NOT_SUPP;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_seq_fetch_creds_end (apiCB *in_context,
+ ccache_cit **io_iterator)
+{
+ return CC_NOT_SUPP;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_free_principal (apiCB *in_context,
+ char **io_principal)
+{
+ return CC_NOT_SUPP;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_free_name (apiCB *in_context,
+ char **io_name)
+{
+ return CC_NOT_SUPP;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_free_creds (apiCB *in_context,
+ cred_union **io_credentials)
+{
+ return CC_NOT_SUPP;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_free_NC_info (apiCB *in_context,
+ infoNC ***io_info)
+{
+ return CC_NOT_SUPP;
+}
diff --git a/src/ccapi/lib/ccapi_v2.exports b/src/ccapi/lib/ccapi_v2.exports
new file mode 100644
index 0000000000..efa9fcec7b
--- /dev/null
+++ b/src/ccapi/lib/ccapi_v2.exports
@@ -0,0 +1,23 @@
+cc_shutdown
+cc_create
+cc_close
+cc_destroy
+cc_get_change_time
+cc_open
+cc_store
+cc_remove_cred
+cc_set_principal
+cc_get_principal
+cc_get_cred_version
+cc_get_name
+cc_seq_fetch_NCs_begin
+cc_seq_fetch_NCs_next
+cc_seq_fetch_NCs_end
+cc_seq_fetch_creds_begin
+cc_seq_fetch_creds_next
+cc_seq_fetch_creds_end
+cc_get_NC_info
+cc_free_principal
+cc_free_name
+cc_free_creds
+cc_free_NC_info
diff --git a/src/ccapi/lib/mac/ccapi_os_ipc.c b/src/ccapi/lib/mac/ccapi_os_ipc.c
new file mode 100644
index 0000000000..ea3b548f87
--- /dev/null
+++ b/src/ccapi/lib/mac/ccapi_os_ipc.c
@@ -0,0 +1,266 @@
+/*
+ * $Header$
+ *
+ * Copyright 2006 Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#include "ccapi_os_ipc.h"
+
+#include <Kerberos/kipc_client.h>
+#include "cci_mig_request.h"
+#include "cci_mig_replyServer.h"
+#include "k5-thread.h"
+
+#define cci_server_bundle_id "edu.mit.Kerberos.CCacheServer"
+#define cci_server_path "/System/Library/CoreServices/CCacheServer.app/Contents/MacOS/CCacheServer"
+
+static pthread_key_t g_request_port_key = 0;
+static pthread_key_t g_reply_stream_key = 0;
+static pthread_key_t g_server_died_key = 0;
+
+/* ------------------------------------------------------------------------ */
+
+inline cc_int32 cci_os_ipc_thread_init (void)
+{
+ cc_int32 err = ccNoError;
+
+ err = pthread_key_create (&g_request_port_key, free);
+
+ if (!err) {
+ err = pthread_key_create (&g_reply_stream_key, NULL);
+ }
+
+ if (!err) {
+ err = pthread_key_create (&g_server_died_key, NULL);
+ }
+
+ return err;
+}
+
+#pragma mark -
+
+/* ------------------------------------------------------------------------ */
+
+static boolean_t cci_server_demux (mach_msg_header_t *request,
+ mach_msg_header_t *reply)
+{
+ boolean_t handled = false;
+
+ if (!handled && request->msgh_id == MACH_NOTIFY_NO_SENDERS) {
+ cc_int32 *server_died = pthread_getspecific (g_server_died_key);
+ if (!server_died) {
+ *server_died = 1;
+ }
+
+ handled = 1; /* server died */
+ }
+
+ if (!handled) {
+ handled = cci_server (request, reply);
+ }
+
+ return handled;
+}
+
+/* ------------------------------------------------------------------------ */
+
+kern_return_t cci_mipc_reply (mach_port_t in_reply_port,
+ cci_mipc_inl_reply_t in_inl_reply,
+ mach_msg_type_number_t in_inl_replyCnt,
+ cci_mipc_ool_reply_t in_ool_reply,
+ mach_msg_type_number_t in_ool_replyCnt)
+{
+ kern_return_t err = KERN_SUCCESS;
+ cci_stream_t reply_stream = NULL;
+
+ if (!err) {
+ reply_stream = pthread_getspecific (g_reply_stream_key);
+ if (!reply_stream) { err = cci_check_error (ccErrBadInternalMessage); }
+ }
+
+ if (!err) {
+ if (in_inl_replyCnt) {
+ err = cci_stream_write (reply_stream, in_inl_reply, in_inl_replyCnt);
+
+ } else if (in_ool_replyCnt) {
+ err = cci_stream_write (reply_stream, in_ool_reply, in_ool_replyCnt);
+
+ } else {
+ err = cci_check_error (ccErrBadInternalMessage);
+ }
+ }
+
+ if (in_ool_replyCnt) { vm_deallocate (mach_task_self (), (vm_address_t) in_ool_reply, in_ool_replyCnt); }
+
+ return cci_check_error (err);
+}
+
+#pragma mark -
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 cci_os_ipc (cc_int32 in_launch_server,
+ cci_stream_t in_request_stream,
+ cci_stream_t *out_reply_stream)
+{
+ cc_int32 err = ccNoError;
+ cc_int32 done = 0;
+ cc_int32 try_count = 0;
+ cc_int32 server_died = 0;
+ mach_port_t server_port = MACH_PORT_NULL;
+ mach_port_t *request_port = NULL;
+ mach_port_t reply_port = MACH_PORT_NULL;
+ const char *inl_request = NULL; /* char * so we can pass the buffer in directly */
+ mach_msg_type_number_t inl_request_length = 0;
+ cci_mipc_ool_request_t ool_request = NULL;
+ mach_msg_type_number_t ool_request_length = 0;
+ cci_stream_t reply_stream = NULL;
+
+ if (!in_request_stream) { err = cci_check_error (ccErrBadParam); }
+ if (!out_reply_stream ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = kipc_client_lookup_server (cci_server_bundle_id, cci_server_path,
+ in_launch_server, &server_port);
+ }
+
+ if (!err) {
+ /* depending on how big the message is, use the fast inline buffer or
+ * the slow dynamically allocated buffer */
+ mach_msg_type_number_t request_length = cci_stream_size (in_request_stream);
+
+ if (request_length > kCCAPIMaxILMsgSize) {
+ cci_debug_printf ("%s choosing out of line buffer (size is %d)",
+ __FUNCTION__, request_length);
+
+ err = vm_read (mach_task_self (),
+ (vm_address_t) cci_stream_data (in_request_stream), request_length,
+ (vm_address_t *) &ool_request, &ool_request_length);
+ } else {
+ //cci_debug_printf ("%s choosing in line buffer (size is %d)",
+ // __FUNCTION__, request_length);
+
+ inl_request_length = request_length;
+ inl_request = cci_stream_data (in_request_stream);
+ }
+ }
+
+ if (!err) {
+ request_port = pthread_getspecific (g_request_port_key);
+
+ if (!request_port) {
+ request_port = malloc (sizeof (mach_port_t));
+ if (!request_port) { err = cci_check_error (ccErrNoMem); }
+
+ if (!err) {
+ *request_port = MACH_PORT_NULL;
+ err = pthread_setspecific (g_request_port_key, request_port);
+ }
+ }
+ }
+
+ if (!err) {
+ err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, &reply_port);
+ }
+
+ while (!err && !done) {
+ if (!err && !MACH_PORT_VALID (*request_port)) {
+ err = cci_mipc_create_client_connection (server_port, request_port);
+ }
+
+ if (!err) {
+ err = cci_mipc_request (*request_port, reply_port,
+ inl_request, inl_request_length,
+ ool_request, ool_request_length);
+
+ }
+
+ if (err == MACH_SEND_INVALID_DEST) {
+ if (request_port && MACH_PORT_VALID (*request_port)) {
+ mach_port_mod_refs (mach_task_self(), *request_port, MACH_PORT_RIGHT_SEND, -1 );
+ *request_port = MACH_PORT_NULL;
+ }
+
+ if (try_count < 2) {
+ try_count++;
+ err = ccNoError;
+ }
+ } else {
+ /* Talked to server, though we may have gotten an error */
+ done = 1;
+
+ /* Because we use ",dealloc" ool_request will be freed by mach.
+ * Don't double free it. */
+ ool_request = NULL;
+ ool_request_length = 0;
+ }
+ }
+
+ if (!err) {
+ err = cci_stream_new (&reply_stream);
+ }
+
+ if (!err) {
+ err = pthread_setspecific (g_reply_stream_key, reply_stream);
+ }
+
+ if (!err) {
+ err = pthread_setspecific (g_server_died_key, &server_died);
+ }
+
+ if (!err) {
+ mach_port_t old_notification_target = MACH_PORT_NULL;
+
+ /* request no-senders notification so we can get a message when server dies */
+ err = mach_port_request_notification (mach_task_self (), reply_port,
+ MACH_NOTIFY_NO_SENDERS, 1, reply_port,
+ MACH_MSG_TYPE_MAKE_SEND_ONCE,
+ &old_notification_target );
+ }
+
+ if (!err) {
+ err = mach_msg_server_once (cci_server_demux, kkipc_max_message_size,
+ reply_port, MACH_MSG_TIMEOUT_NONE);
+ }
+
+ if (!err && server_died) {
+ err = cci_check_error (ccErrServerUnavailable);
+ }
+
+ if (err == BOOTSTRAP_UNKNOWN_SERVICE && !in_launch_server) {
+ err = ccNoError; /* If the server is not running just return an empty stream. */
+ }
+
+ if (!err) {
+ *out_reply_stream = reply_stream;
+ reply_stream = NULL;
+ }
+
+ pthread_setspecific (g_reply_stream_key, NULL);
+ pthread_setspecific (g_server_died_key, NULL);
+ if (MACH_PORT_VALID (reply_port)) { mach_port_deallocate (mach_task_self (), reply_port); }
+ if (ool_request_length ) { vm_deallocate (mach_task_self (), (vm_address_t) ool_request, ool_request_length); }
+ if (reply_stream ) { cci_stream_release (reply_stream); }
+
+ return cci_check_error (err);
+}
diff --git a/src/ccapi/lib/mac/ccapi_vector.c b/src/ccapi/lib/mac/ccapi_vector.c
new file mode 100644
index 0000000000..ea749c0893
--- /dev/null
+++ b/src/ccapi/lib/mac/ccapi_vector.c
@@ -0,0 +1,839 @@
+/*
+ * $Header$
+ *
+ * Copyright 2006 Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#include "ccapi_vector.h"
+
+#include "ccapi_context.h"
+#include "ccapi_string.h"
+#include "ccapi_ccache.h"
+#include "ccapi_credentials.h"
+#include "ccapi_ccache_iterator.h"
+#include "ccapi_credentials_iterator.h"
+
+/* ------------------------------------------------------------------------ */
+
+static void cci_swap_string_functions (cc_string_t io_string)
+{
+ cc_string_f temp = *(io_string->functions);
+ *((cc_string_f *)io_string->functions) = *(io_string->vector_functions);
+ *((cc_string_f *)io_string->vector_functions) = temp;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static void cci_swap_context_functions (cc_context_t io_context)
+{
+ cc_context_f temp = *(io_context->functions);
+ *((cc_context_f *)io_context->functions) = *(io_context->vector_functions);
+ *((cc_context_f *)io_context->vector_functions) = temp;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static void cci_swap_ccache_functions (cc_ccache_t io_ccache)
+{
+ cc_ccache_f temp = *(io_ccache->functions);
+ *((cc_ccache_f *)io_ccache->functions) = *(io_ccache->vector_functions);
+ *((cc_ccache_f *)io_ccache->vector_functions) = temp;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static void cci_swap_credentials_functions (cc_credentials_t io_credentials)
+{
+ cc_credentials_f temp = *(io_credentials->functions);
+ *((cc_credentials_f *)io_credentials->functions) = *(io_credentials->otherFunctions);
+ *((cc_credentials_f *)io_credentials->otherFunctions) = temp;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static void cci_swap_ccache_iterator_functions (cc_ccache_iterator_t io_ccache_iterator)
+{
+ cc_ccache_iterator_f temp = *(io_ccache_iterator->functions);
+ *((cc_ccache_iterator_f *)io_ccache_iterator->functions) = *(io_ccache_iterator->vector_functions);
+ *((cc_ccache_iterator_f *)io_ccache_iterator->vector_functions) = temp;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static void cci_swap_credentials_iterator_functions (cc_credentials_iterator_t io_credentials_iterator)
+{
+ cc_credentials_iterator_f temp = *(io_credentials_iterator->functions);
+ *((cc_credentials_iterator_f *)io_credentials_iterator->functions) = *(io_credentials_iterator->vector_functions);
+ *((cc_credentials_iterator_f *)io_credentials_iterator->vector_functions) = temp;
+}
+
+#pragma mark -
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_initialize_vector (cc_context_t *out_context,
+ cc_int32 in_version,
+ cc_int32 *out_supported_version,
+ char const **out_vendor)
+{
+ return cc_initialize (out_context, in_version, out_supported_version, out_vendor);
+}
+
+#pragma mark -
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_string_release_vector (cc_string_t in_string)
+{
+ cci_swap_string_functions (in_string);
+ return ccapi_string_release (in_string);
+}
+
+#pragma mark -
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_context_release_vector (cc_context_t io_context)
+{
+ cci_swap_context_functions (io_context);
+ return ccapi_context_release (io_context);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_context_get_change_time_vector (cc_context_t in_context,
+ cc_time_t *out_change_time)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_context_functions (in_context);
+ err = ccapi_context_get_change_time (in_context, out_change_time);
+ cci_swap_context_functions (in_context);
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_context_get_default_ccache_name_vector (cc_context_t in_context,
+ cc_string_t *out_name)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_context_functions (in_context);
+ err = ccapi_context_get_default_ccache_name (in_context, out_name);
+ cci_swap_context_functions (in_context);
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_context_open_ccache_vector (cc_context_t in_context,
+ const char *in_name,
+ cc_ccache_t *out_ccache)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_context_functions (in_context);
+ err = ccapi_context_open_ccache (in_context, in_name, out_ccache);
+ cci_swap_context_functions (in_context);
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_context_open_default_ccache_vector (cc_context_t in_context,
+ cc_ccache_t *out_ccache)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_context_functions (in_context);
+ err = ccapi_context_open_default_ccache (in_context, out_ccache);
+ cci_swap_context_functions (in_context);
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_context_create_ccache_vector (cc_context_t in_context,
+ const char *in_name,
+ cc_uint32 in_cred_vers,
+ const char *in_principal,
+ cc_ccache_t *out_ccache)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_context_functions (in_context);
+ err = ccapi_context_create_ccache (in_context, in_name, in_cred_vers, in_principal, out_ccache);
+ cci_swap_context_functions (in_context);
+ return err;
+}
+
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_context_create_default_ccache_vector (cc_context_t in_context,
+ cc_uint32 in_cred_vers,
+ const char *in_principal,
+ cc_ccache_t *out_ccache)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_context_functions (in_context);
+ err = ccapi_context_create_default_ccache (in_context, in_cred_vers, in_principal, out_ccache);
+ cci_swap_context_functions (in_context);
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_context_create_new_ccache_vector (cc_context_t in_context,
+ cc_uint32 in_cred_vers,
+ const char *in_principal,
+ cc_ccache_t *out_ccache)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_context_functions (in_context);
+ err = ccapi_context_create_new_ccache (in_context, in_cred_vers, in_principal, out_ccache);
+ cci_swap_context_functions (in_context);
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_context_new_ccache_iterator_vector (cc_context_t in_context,
+ cc_ccache_iterator_t *out_iterator)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_context_functions (in_context);
+ err = ccapi_context_new_ccache_iterator (in_context, out_iterator);
+ cci_swap_context_functions (in_context);
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_context_lock_vector (cc_context_t in_context,
+ cc_uint32 in_lock_type,
+ cc_uint32 in_block)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_context_functions (in_context);
+ err = ccapi_context_lock (in_context, in_lock_type, in_block);
+ cci_swap_context_functions (in_context);
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_context_unlock_vector (cc_context_t in_context)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_context_functions (in_context);
+ err = ccapi_context_unlock (in_context);
+ cci_swap_context_functions (in_context);
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_context_compare_vector (cc_context_t in_context,
+ cc_context_t in_compare_to_context,
+ cc_uint32 *out_equal)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_context_functions (in_context);
+ err = ccapi_context_compare (in_context, in_compare_to_context, out_equal);
+ cci_swap_context_functions (in_context);
+ return err;
+}
+
+#pragma mark -
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_ccache_release_vector (cc_ccache_t io_ccache)
+{
+ cci_swap_ccache_functions (io_ccache);
+ return ccapi_ccache_release (io_ccache);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_ccache_destroy_vector (cc_ccache_t io_ccache)
+{
+ cci_swap_ccache_functions (io_ccache);
+ return ccapi_ccache_destroy (io_ccache);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_ccache_set_default_vector (cc_ccache_t io_ccache)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_ccache_functions (io_ccache);
+ err = ccapi_ccache_set_default (io_ccache);
+ cci_swap_ccache_functions (io_ccache);
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_uint32 __cc_ccache_get_credentials_version_vector (cc_ccache_t in_ccache,
+ cc_uint32 *out_credentials_version)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_ccache_functions (in_ccache);
+ err = ccapi_ccache_get_credentials_version (in_ccache, out_credentials_version);
+ cci_swap_ccache_functions (in_ccache);
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_ccache_get_name_vector (cc_ccache_t in_ccache,
+ cc_string_t *out_name)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_ccache_functions (in_ccache);
+ err = ccapi_ccache_get_name (in_ccache, out_name);
+ cci_swap_ccache_functions (in_ccache);
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_ccache_get_principal_vector (cc_ccache_t in_ccache,
+ cc_uint32 in_credentials_version,
+ cc_string_t *out_principal)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_ccache_functions (in_ccache);
+ err = ccapi_ccache_get_principal (in_ccache, in_credentials_version, out_principal);
+ cci_swap_ccache_functions (in_ccache);
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_ccache_set_principal_vector (cc_ccache_t io_ccache,
+ cc_uint32 in_credentials_version,
+ const char *in_principal)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_ccache_functions (io_ccache);
+ err = ccapi_ccache_set_principal (io_ccache, in_credentials_version, in_principal);
+ cci_swap_ccache_functions (io_ccache);
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_ccache_store_credentials_vector (cc_ccache_t io_ccache,
+ const cc_credentials_union *in_credentials_union)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_ccache_functions (io_ccache);
+ err = ccapi_ccache_store_credentials (io_ccache, in_credentials_union);
+ cci_swap_ccache_functions (io_ccache);
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_ccache_remove_credentials_vector (cc_ccache_t io_ccache,
+ cc_credentials_t in_credentials)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_ccache_functions (io_ccache);
+ cci_swap_credentials_functions (in_credentials);
+ err = ccapi_ccache_remove_credentials (io_ccache, in_credentials);
+ cci_swap_ccache_functions (io_ccache);
+ cci_swap_credentials_functions (in_credentials);
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_ccache_new_credentials_iterator_vector (cc_ccache_t in_ccache,
+ cc_credentials_iterator_t *out_credentials_iterator)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_ccache_functions (in_ccache);
+ err = ccapi_ccache_new_credentials_iterator (in_ccache, out_credentials_iterator);
+ cci_swap_ccache_functions (in_ccache);
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_ccache_move_vector (cc_ccache_t io_source_ccache,
+ cc_ccache_t io_destination_ccache)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_ccache_functions (io_source_ccache);
+ cci_swap_ccache_functions (io_destination_ccache);
+ err = ccapi_ccache_move (io_source_ccache, io_destination_ccache);
+ cci_swap_ccache_functions (io_source_ccache);
+ cci_swap_ccache_functions (io_destination_ccache);
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_ccache_lock_vector (cc_ccache_t io_ccache,
+ cc_uint32 in_lock_type,
+ cc_uint32 in_block)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_ccache_functions (io_ccache);
+ err = ccapi_ccache_lock (io_ccache, in_lock_type, in_block);
+ cci_swap_ccache_functions (io_ccache);
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_ccache_unlock_vector (cc_ccache_t io_ccache)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_ccache_functions (io_ccache);
+ err = ccapi_ccache_unlock (io_ccache);
+ cci_swap_ccache_functions (io_ccache);
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_ccache_get_last_default_time_vector (cc_ccache_t in_ccache,
+ cc_time_t *out_last_default_time)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_ccache_functions (in_ccache);
+ err = ccapi_ccache_get_last_default_time (in_ccache, out_last_default_time);
+ cci_swap_ccache_functions (in_ccache);
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_ccache_get_change_time_vector (cc_ccache_t in_ccache,
+ cc_time_t *out_change_time)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_ccache_functions (in_ccache);
+ err = ccapi_ccache_get_change_time (in_ccache, out_change_time);
+ cci_swap_ccache_functions (in_ccache);
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_ccache_compare_vector (cc_ccache_t in_ccache,
+ cc_ccache_t in_compare_to_ccache,
+ cc_uint32 *out_equal)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_ccache_functions (in_ccache);
+ cci_swap_ccache_functions (in_compare_to_ccache);
+ err = ccapi_ccache_compare (in_ccache, in_compare_to_ccache, out_equal);
+ cci_swap_ccache_functions (in_ccache);
+ cci_swap_ccache_functions (in_compare_to_ccache);
+ return err;
+}
+
+#pragma mark -
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_credentials_release_vector (cc_credentials_t io_credentials)
+{
+ cci_swap_credentials_functions (io_credentials);
+ return ccapi_credentials_release (io_credentials);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_credentials_compare_vector (cc_credentials_t in_credentials,
+ cc_credentials_t in_compare_to_credentials,
+ cc_uint32 *out_equal)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_credentials_functions (in_credentials);
+ cci_swap_credentials_functions (in_compare_to_credentials);
+ err = ccapi_credentials_compare (in_credentials, in_compare_to_credentials, out_equal);
+ cci_swap_credentials_functions (in_credentials);
+ cci_swap_credentials_functions (in_compare_to_credentials);
+ return err;
+}
+
+#pragma mark -
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_ccache_iterator_release_vector (cc_ccache_iterator_t io_ccache_iterator)
+{
+ cci_swap_ccache_iterator_functions (io_ccache_iterator);
+ return ccapi_ccache_iterator_release (io_ccache_iterator);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_ccache_iterator_next_vector (cc_ccache_iterator_t in_ccache_iterator,
+ cc_ccache_t *out_ccache)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_ccache_iterator_functions (in_ccache_iterator);
+ err = ccapi_ccache_iterator_next (in_ccache_iterator, out_ccache);
+ cci_swap_ccache_iterator_functions (in_ccache_iterator);
+ return err;
+}
+
+#pragma mark -
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_credentials_iterator_release_vector (cc_credentials_iterator_t io_credentials_iterator)
+{
+ cci_swap_credentials_iterator_functions (io_credentials_iterator);
+ return ccapi_credentials_iterator_release (io_credentials_iterator);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_credentials_iterator_next_vector (cc_credentials_iterator_t in_credentials_iterator,
+ cc_credentials_t *out_credentials)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_credentials_iterator_functions (in_credentials_iterator);
+ err = ccapi_credentials_iterator_next (in_credentials_iterator, out_credentials);
+ cci_swap_credentials_iterator_functions (in_credentials_iterator);
+ return err;
+}
+
+#pragma mark -
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_shutdown_vector (apiCB **io_context)
+{
+ cci_swap_context_functions (*io_context);
+ return cc_shutdown (io_context);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_get_NC_info_vector (apiCB *in_context,
+ infoNC ***out_info)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_context_functions (in_context);
+ err = cc_get_NC_info (in_context, out_info);
+ cci_swap_context_functions (in_context);
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_get_change_time_vector (apiCB *in_context,
+ cc_time_t *out_change_time)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_context_functions (in_context);
+ err = cc_get_change_time (in_context, out_change_time);
+ cci_swap_context_functions (in_context);
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_open_vector (apiCB *in_context,
+ const char *in_name,
+ cc_int32 in_version,
+ cc_uint32 in_flags,
+ ccache_p **out_ccache)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_context_functions (in_context);
+ err = cc_open (in_context, in_name, in_version, in_flags, out_ccache);
+ cci_swap_context_functions (in_context);
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_create_vector (apiCB *in_context,
+ const char *in_name,
+ const char *in_principal,
+ cc_int32 in_version,
+ cc_uint32 in_flags,
+ ccache_p **out_ccache)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_context_functions (in_context);
+ err = cc_create (in_context, in_name, in_principal, in_version, in_flags, out_ccache);
+ cci_swap_context_functions (in_context);
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_close_vector (apiCB *in_context,
+ ccache_p **io_ccache)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_context_functions (in_context);
+ cci_swap_ccache_functions (*io_ccache);
+ err = cc_close (in_context, io_ccache);
+ cci_swap_context_functions (in_context);
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_destroy_vector (apiCB *in_context,
+ ccache_p **io_ccache)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_context_functions (in_context);
+ cci_swap_ccache_functions (*io_ccache);
+ err = cc_destroy (in_context, io_ccache);
+ cci_swap_context_functions (in_context);
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_seq_fetch_NCs_begin_vector (apiCB *in_context,
+ ccache_cit **out_iterator)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_context_functions (in_context);
+ err = cc_seq_fetch_NCs_begin (in_context, out_iterator);
+ cci_swap_context_functions (in_context);
+ return err;
+}
+
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_seq_fetch_NCs_next_vector (apiCB *in_context,
+ ccache_p **out_ccache,
+ ccache_cit *in_iterator)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_context_functions (in_context);
+ cci_swap_ccache_iterator_functions ((ccache_cit_ccache *)in_iterator);
+ err = cc_seq_fetch_NCs_next (in_context, out_ccache, in_iterator);
+ cci_swap_context_functions (in_context);
+ cci_swap_ccache_iterator_functions ((ccache_cit_ccache *)in_iterator);
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_seq_fetch_NCs_end_vector (apiCB *in_context,
+ ccache_cit **io_iterator)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_context_functions (in_context);
+ cci_swap_ccache_iterator_functions ((ccache_cit_ccache *) *io_iterator);
+ err = cc_seq_fetch_NCs_end (in_context, io_iterator);
+ cci_swap_context_functions (in_context);
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_get_name_vector (apiCB *in_context,
+ ccache_p *in_ccache,
+ char **out_name)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_context_functions (in_context);
+ cci_swap_ccache_functions (in_ccache);
+ err = cc_get_name (in_context, in_ccache, out_name);
+ cci_swap_context_functions (in_context);
+ cci_swap_ccache_functions (in_ccache);
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_get_cred_version_vector (apiCB *in_context,
+ ccache_p *in_ccache,
+ cc_int32 *out_version)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_context_functions (in_context);
+ cci_swap_ccache_functions (in_ccache);
+ err = cc_get_cred_version (in_context, in_ccache, out_version);
+ cci_swap_context_functions (in_context);
+ cci_swap_ccache_functions (in_ccache);
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_set_principal_vector (apiCB *in_context,
+ ccache_p *io_ccache,
+ cc_int32 in_version,
+ char *in_principal)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_context_functions (in_context);
+ cci_swap_ccache_functions (io_ccache);
+ err = cc_set_principal (in_context, io_ccache, in_version, in_principal);
+ cci_swap_context_functions (in_context);
+ cci_swap_ccache_functions (io_ccache);
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_get_principal_vector (apiCB *in_context,
+ ccache_p *in_ccache,
+ char **out_principal)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_context_functions (in_context);
+ cci_swap_ccache_functions (in_ccache);
+ err = cc_get_principal (in_context, in_ccache, out_principal);
+ cci_swap_context_functions (in_context);
+ cci_swap_ccache_functions (in_ccache);
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_store_vector (apiCB *in_context,
+ ccache_p *io_ccache,
+ cred_union in_credentials)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_context_functions (in_context);
+ cci_swap_ccache_functions (io_ccache);
+ err = cc_store (in_context, io_ccache, in_credentials);
+ cci_swap_context_functions (in_context);
+ cci_swap_ccache_functions (io_ccache);
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_remove_cred_vector (apiCB *in_context,
+ ccache_p *in_ccache,
+ cred_union in_credentials)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_context_functions (in_context);
+ cci_swap_ccache_functions (in_ccache);
+ err = cc_remove_cred (in_context, in_ccache, in_credentials);
+ cci_swap_context_functions (in_context);
+ cci_swap_ccache_functions (in_ccache);
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_seq_fetch_creds_begin_vector (apiCB *in_context,
+ const ccache_p *in_ccache,
+ ccache_cit **out_iterator)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_context_functions (in_context);
+ cci_swap_ccache_functions ((ccache_p *)in_ccache);
+ err = cc_seq_fetch_creds_begin (in_context, in_ccache, out_iterator);
+ cci_swap_context_functions (in_context);
+ cci_swap_ccache_functions ((ccache_p *)in_ccache);
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_seq_fetch_creds_next_vector (apiCB *in_context,
+ cred_union **out_creds,
+ ccache_cit *in_iterator)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_context_functions (in_context);
+ cci_swap_credentials_iterator_functions ((ccache_cit_creds *)in_iterator);
+ err = cc_seq_fetch_creds_next (in_context, out_creds, in_iterator);
+ cci_swap_context_functions (in_context);
+ cci_swap_credentials_iterator_functions ((ccache_cit_creds *)in_iterator);
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_seq_fetch_creds_end_vector (apiCB *in_context,
+ ccache_cit **io_iterator)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_context_functions (in_context);
+ cci_swap_credentials_iterator_functions ((ccache_cit_creds *) *io_iterator);
+ err = cc_seq_fetch_creds_end (in_context, io_iterator);
+ cci_swap_context_functions (in_context);
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_free_principal_vector (apiCB *in_context,
+ char **io_principal)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_context_functions (in_context);
+ err = cc_free_principal (in_context, io_principal);
+ cci_swap_context_functions (in_context);
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_free_name_vector (apiCB *in_context,
+ char **io_name)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_context_functions (in_context);
+ err = cc_free_name (in_context, io_name);
+ cci_swap_context_functions (in_context);
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_free_creds_vector (apiCB *in_context,
+ cred_union **io_credentials)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_context_functions (in_context);
+ err = cc_free_creds (in_context, io_credentials);
+ cci_swap_context_functions (in_context);
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 __cc_free_NC_info_vector (apiCB *in_context,
+ infoNC ***io_info)
+{
+ cc_int32 err = ccNoError;
+ cci_swap_context_functions (in_context);
+ err = cc_free_NC_info (in_context, io_info);
+ cci_swap_context_functions (in_context);
+ return err;
+}
diff --git a/src/ccapi/lib/mac/ccapi_vector.exports b/src/ccapi/lib/mac/ccapi_vector.exports
new file mode 100644
index 0000000000..0f02e4148f
--- /dev/null
+++ b/src/ccapi/lib/mac/ccapi_vector.exports
@@ -0,0 +1,59 @@
+__cc_context_release_vector
+__cc_context_get_change_time_vector
+__cc_context_get_default_ccache_name_vector
+__cc_context_open_ccache_vector
+__cc_context_open_default_ccache_vector
+__cc_context_create_ccache_vector
+__cc_context_create_default_ccache_vector
+__cc_context_create_new_ccache_vector
+__cc_context_new_ccache_iterator_vector
+__cc_context_lock_vector
+__cc_context_unlock_vector
+__cc_context_compare_vector
+__cc_ccache_release_vector
+__cc_ccache_destroy_vector
+__cc_ccache_set_default_vector
+__cc_ccache_get_credentials_version_vector
+__cc_ccache_get_name_vector
+__cc_ccache_get_principal_vector
+__cc_ccache_set_principal_vector
+__cc_ccache_store_credentials_vector
+__cc_ccache_remove_credentials_vector
+__cc_ccache_new_credentials_iterator_vector
+__cc_ccache_move_vector
+__cc_ccache_lock_vector
+__cc_ccache_unlock_vector
+__cc_ccache_get_last_default_time_vector
+__cc_ccache_get_change_time_vector
+__cc_ccache_compare_vector
+__cc_string_release_vector
+__cc_credentials_release_vector
+__cc_credentials_compare_vector
+__cc_ccache_iterator_release_vector
+__cc_ccache_iterator_next_vector
+__cc_credentials_iterator_release_vector
+__cc_credentials_iterator_next_vector
+__cc_initialize_vector
+__cc_shutdown_vector
+__cc_get_NC_info_vector
+__cc_get_change_time_vector
+__cc_open_vector
+__cc_create_vector
+__cc_close_vector
+__cc_destroy_vector
+__cc_seq_fetch_NCs_begin_vector
+__cc_seq_fetch_NCs_next_vector
+__cc_seq_fetch_NCs_end_vector
+__cc_get_name_vector
+__cc_get_cred_version_vector
+__cc_set_principal_vector
+__cc_get_principal_vector
+__cc_store_vector
+__cc_remove_cred_vector
+__cc_seq_fetch_creds_begin_vector
+__cc_seq_fetch_creds_next_vector
+__cc_seq_fetch_creds_end_vector
+__cc_free_principal_vector
+__cc_free_name_vector
+__cc_free_creds_vector
+__cc_free_NC_info_vector
diff --git a/src/ccapi/lib/mac/ccapi_vector.h b/src/ccapi/lib/mac/ccapi_vector.h
new file mode 100644
index 0000000000..80840f1111
--- /dev/null
+++ b/src/ccapi/lib/mac/ccapi_vector.h
@@ -0,0 +1,228 @@
+/*
+ * $Header$
+ *
+ * Copyright 2006 Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#include <CredentialsCache2.h>
+
+
+cc_int32 __cc_initialize_vector (cc_context_t *out_context,
+ cc_int32 in_version,
+ cc_int32 *out_supported_version,
+ char const **out_vendor);
+
+cc_int32 __cc_string_release_vector (cc_string_t in_string);
+
+cc_int32 __cc_context_release_vector (cc_context_t io_context);
+
+cc_int32 __cc_context_get_change_time_vector (cc_context_t in_context,
+ cc_time_t *out_change_time);
+
+cc_int32 __cc_context_get_default_ccache_name_vector (cc_context_t in_context,
+ cc_string_t *out_name);
+
+cc_int32 __cc_context_open_ccache_vector (cc_context_t in_context,
+ const char *in_name,
+ cc_ccache_t *out_ccache);
+
+cc_int32 __cc_context_open_default_ccache_vector (cc_context_t in_context,
+ cc_ccache_t *out_ccache);
+
+cc_int32 __cc_context_create_ccache_vector (cc_context_t in_context,
+ const char *in_name,
+ cc_uint32 in_cred_vers,
+ const char *in_principal,
+ cc_ccache_t *out_ccache);
+
+cc_int32 __cc_context_create_default_ccache_vector (cc_context_t in_context,
+ cc_uint32 in_cred_vers,
+ const char *in_principal,
+ cc_ccache_t *out_ccache);
+
+cc_int32 __cc_context_create_new_ccache_vector (cc_context_t in_context,
+ cc_uint32 in_cred_vers,
+ const char *in_principal,
+ cc_ccache_t *out_ccache);
+
+cc_int32 __cc_context_new_ccache_iterator_vector (cc_context_t in_context,
+ cc_ccache_iterator_t *out_iterator);
+
+cc_int32 __cc_context_lock_vector (cc_context_t in_context,
+ cc_uint32 in_lock_type,
+ cc_uint32 in_block);
+
+cc_int32 __cc_context_unlock_vector (cc_context_t in_context);
+
+cc_int32 __cc_context_compare_vector (cc_context_t in_context,
+ cc_context_t in_compare_to_context,
+ cc_uint32 *out_equal);
+
+cc_int32 __cc_ccache_release_vector (cc_ccache_t io_ccache);
+
+cc_int32 __cc_ccache_destroy_vector (cc_ccache_t io_ccache);
+
+cc_int32 __cc_ccache_set_default_vector (cc_ccache_t io_ccache);
+
+cc_uint32 __cc_ccache_get_credentials_version_vector (cc_ccache_t in_ccache,
+ cc_uint32 *out_credentials_version);
+
+cc_int32 __cc_ccache_get_name_vector (cc_ccache_t in_ccache,
+ cc_string_t *out_name);
+
+cc_int32 __cc_ccache_get_principal_vector (cc_ccache_t in_ccache,
+ cc_uint32 in_credentials_version,
+ cc_string_t *out_principal);
+
+cc_int32 __cc_ccache_set_principal_vector (cc_ccache_t io_ccache,
+ cc_uint32 in_credentials_version,
+ const char *in_principal);
+
+cc_int32 __cc_ccache_store_credentials_vector (cc_ccache_t io_ccache,
+ const cc_credentials_union *in_credentials_union);
+
+cc_int32 __cc_ccache_remove_credentials_vector (cc_ccache_t io_ccache,
+ cc_credentials_t in_credentials);
+
+cc_int32 __cc_ccache_new_credentials_iterator_vector (cc_ccache_t in_ccache,
+ cc_credentials_iterator_t *out_credentials_iterator);
+
+cc_int32 __cc_ccache_move_vector (cc_ccache_t io_source_ccache,
+ cc_ccache_t io_destination_ccache);
+
+cc_int32 __cc_ccache_lock_vector (cc_ccache_t io_ccache,
+ cc_uint32 in_lock_type,
+ cc_uint32 in_block);
+
+cc_int32 __cc_ccache_unlock_vector (cc_ccache_t io_ccache);
+
+cc_int32 __cc_ccache_get_last_default_time_vector (cc_ccache_t in_ccache,
+ cc_time_t *out_last_default_time);
+
+cc_int32 __cc_ccache_get_change_time_vector (cc_ccache_t in_ccache,
+ cc_time_t *out_change_time);
+
+cc_int32 __cc_ccache_compare_vector (cc_ccache_t in_ccache,
+ cc_ccache_t in_compare_to_ccache,
+ cc_uint32 *out_equal);
+
+cc_int32 __cc_credentials_release_vector (cc_credentials_t io_credentials);
+
+cc_int32 __cc_credentials_compare_vector (cc_credentials_t in_credentials,
+ cc_credentials_t in_compare_to_credentials,
+ cc_uint32 *out_equal);
+
+cc_int32 __cc_ccache_iterator_release_vector (cc_ccache_iterator_t io_ccache_iterator);
+
+cc_int32 __cc_ccache_iterator_next_vector (cc_ccache_iterator_t in_ccache_iterator,
+ cc_ccache_t *out_ccache);
+
+cc_int32 __cc_credentials_iterator_release_vector (cc_credentials_iterator_t io_credentials_iterator);
+
+cc_int32 __cc_credentials_iterator_next_vector (cc_credentials_iterator_t in_credentials_iterator,
+ cc_credentials_t *out_credentials);
+
+cc_int32 __cc_shutdown_vector (apiCB **io_context);
+
+cc_int32 __cc_get_NC_info_vector (apiCB *in_context,
+ infoNC ***out_info);
+
+cc_int32 __cc_get_change_time_vector (apiCB *in_context,
+ cc_time_t *out_change_time);
+
+cc_int32 __cc_open_vector (apiCB *in_context,
+ const char *in_name,
+ cc_int32 in_version,
+ cc_uint32 in_flags,
+ ccache_p **out_ccache);
+
+cc_int32 __cc_create_vector (apiCB *in_context,
+ const char *in_name,
+ const char *in_principal,
+ cc_int32 in_version,
+ cc_uint32 in_flags,
+ ccache_p **out_ccache);
+
+cc_int32 __cc_close_vector (apiCB *in_context,
+ ccache_p **io_ccache);
+
+cc_int32 __cc_destroy_vector (apiCB *in_context,
+ ccache_p **io_ccache);
+
+cc_int32 __cc_seq_fetch_NCs_begin_vector (apiCB *in_context,
+ ccache_cit **out_iterator);
+
+cc_int32 __cc_seq_fetch_NCs_next_vector (apiCB *in_context,
+ ccache_p **out_ccache,
+ ccache_cit *in_iterator);
+
+cc_int32 __cc_seq_fetch_NCs_end_vector (apiCB *in_context,
+ ccache_cit **io_iterator);
+
+cc_int32 __cc_get_name_vector (apiCB *in_context,
+ ccache_p *in_ccache,
+ char **out_name);
+
+cc_int32 __cc_get_cred_version_vector (apiCB *in_context,
+ ccache_p *in_ccache,
+ cc_int32 *out_version);
+
+cc_int32 __cc_set_principal_vector (apiCB *in_context,
+ ccache_p *io_ccache,
+ cc_int32 in_version,
+ char *in_principal);
+
+cc_int32 __cc_get_principal_vector (apiCB *in_context,
+ ccache_p *in_ccache,
+ char **out_principal);
+
+cc_int32 __cc_store_vector (apiCB *in_context,
+ ccache_p *io_ccache,
+ cred_union in_credentials);
+
+cc_int32 __cc_remove_cred_vector (apiCB *in_context,
+ ccache_p *in_ccache,
+ cred_union in_credentials);
+
+cc_int32 __cc_seq_fetch_creds_begin_vector (apiCB *in_context,
+ const ccache_p *in_ccache,
+ ccache_cit **out_iterator);
+
+cc_int32 __cc_seq_fetch_creds_next_vector (apiCB *in_context,
+ cred_union **out_creds,
+ ccache_cit *in_iterator);
+
+cc_int32 __cc_seq_fetch_creds_end_vector (apiCB *in_context,
+ ccache_cit **io_iterator);
+
+cc_int32 __cc_free_principal_vector (apiCB *in_context,
+ char **io_principal);
+
+cc_int32 __cc_free_name_vector (apiCB *in_context,
+ char **io_name);
+
+cc_int32 __cc_free_creds_vector (apiCB *in_context,
+ cred_union **io_credentials);
+
+cc_int32 __cc_free_NC_info_vector (apiCB *in_context,
+ infoNC ***io_info);