summaryrefslogtreecommitdiff
path: root/src/ccapi/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/ccapi/lib')
-rw-r--r--src/ccapi/lib/Makefile.in61
-rw-r--r--src/ccapi/lib/ccapi.exports1
-rw-r--r--src/ccapi/lib/ccapi_ccache.c793
-rw-r--r--src/ccapi/lib/ccapi_ccache.h105
-rw-r--r--src/ccapi/lib/ccapi_ccache_iterator.c291
-rw-r--r--src/ccapi/lib/ccapi_ccache_iterator.h51
-rw-r--r--src/ccapi/lib/ccapi_context.c831
-rw-r--r--src/ccapi/lib/ccapi_context.h86
-rw-r--r--src/ccapi/lib/ccapi_context_change_time.c199
-rw-r--r--src/ccapi/lib/ccapi_context_change_time.h41
-rw-r--r--src/ccapi/lib/ccapi_credentials.c165
-rw-r--r--src/ccapi/lib/ccapi_credentials.h43
-rw-r--r--src/ccapi/lib/ccapi_credentials_iterator.c246
-rw-r--r--src/ccapi/lib/ccapi_credentials_iterator.h51
-rw-r--r--src/ccapi/lib/ccapi_err.et74
-rw-r--r--src/ccapi/lib/ccapi_ipc.c119
-rw-r--r--src/ccapi/lib/ccapi_ipc.h45
-rw-r--r--src/ccapi/lib/ccapi_os_ipc.h39
-rw-r--r--src/ccapi/lib/ccapi_string.c101
-rw-r--r--src/ccapi/lib/ccapi_string.h36
-rw-r--r--src/ccapi/lib/ccapi_v2.c917
-rw-r--r--src/ccapi/lib/ccapi_v2.exports23
-rw-r--r--src/ccapi/lib/deps86
-rw-r--r--src/ccapi/lib/libkrb5-ccapi.exports1
-rw-r--r--src/ccapi/lib/mac/ccapi_os_ipc.c50
-rw-r--r--src/ccapi/lib/mac/ccapi_vector.c838
-rw-r--r--src/ccapi/lib/mac/ccapi_vector.exports59
-rw-r--r--src/ccapi/lib/mac/ccapi_vector.h227
-rw-r--r--src/ccapi/lib/unix/Makefile.in12
-rw-r--r--src/ccapi/lib/unix/deps1
-rw-r--r--src/ccapi/lib/unix/stubs.c10
-rw-r--r--src/ccapi/lib/win/Makefile.in123
-rw-r--r--src/ccapi/lib/win/OldCC/ccapi.h280
-rw-r--r--src/ccapi/lib/win/OldCC/client.cxx427
-rw-r--r--src/ccapi/lib/win/OldCC/client.h60
-rw-r--r--src/ccapi/lib/win/WINCCAPI.sln20
-rw-r--r--src/ccapi/lib/win/WINCCAPI.vcproj111
-rw-r--r--src/ccapi/lib/win/ccapi_os_ipc.cxx380
-rw-r--r--src/ccapi/lib/win/ccs_reply_proc.c95
-rw-r--r--src/ccapi/lib/win/debug.exports11
-rw-r--r--src/ccapi/lib/win/dllmain.cxx222
-rw-r--r--src/ccapi/lib/win/dllmain.h41
42 files changed, 7372 insertions, 0 deletions
diff --git a/src/ccapi/lib/Makefile.in b/src/ccapi/lib/Makefile.in
new file mode 100644
index 000000000000..14e7d7b6ea18
--- /dev/null
+++ b/src/ccapi/lib/Makefile.in
@@ -0,0 +1,61 @@
+mydir=ccapi$(S)lib
+BUILDTOP=$(REL)..$(S)..
+SUBDIRS=unix
+LOCALINCLUDES=-I$(srcdir)/../common -I.
+
+SHLIB_EXPDEPS= $(COM_ERR_DEPLIB) $(SUPPORT_DEPLIB)
+SHLIB_EXPLIBS=-lcom_err $(SUPPORT_LIB)
+RELDIR=../ccapi/lib
+
+LIBBASE=krb5-ccapi
+LIBMAJOR=1
+LIBMINOR=0
+
+STOBJLISTS= \
+ OBJS.ST \
+ unix/OBJS.ST
+
+STLIBOBJS= \
+ ccapi_ccache.o \
+ ccapi_ccache_iterator.o \
+ ccapi_context.o \
+ ccapi_context_change_time.o \
+ ccapi_credentials.o \
+ ccapi_credentials_iterator.o \
+ ccapi_err.o \
+ ccapi_ipc.o \
+ ccapi_string.o \
+ ccapi_v2.o
+
+OBJS= \
+ $(OUTPRE)ccapi_ccache.$(OUTPRE) \
+ $(OUTPRE)ccapi_ccache_iterator.$(OUTPRE) \
+ $(OUTPRE)ccapi_context.$(OUTPRE) \
+ $(OUTPRE)ccapi_context_change_time.$(OUTPRE) \
+ $(OUTPRE)ccapi_credentials.$(OUTPRE) \
+ $(OUTPRE)ccapi_credentials_iterator.$(OUTPRE) \
+ $(OUTPRE)ccapi_err.$(OUTPRE) \
+ $(OUTPRE)ccapi_ipc.$(OUTPRE) \
+ $(OUTPRE)ccapi_string.$(OUTPRE) \
+ $(OUTPRE)ccapi_v2.$(OUTPRE)
+
+SRCS= \
+ ccapi_ccache.c \
+ ccapi_ccache_iterator.c \
+ ccapi_context.c \
+ ccapi_context_change_time.c \
+ ccapi_credentials.c \
+ ccapi_credentials_iterator.c \
+ ccapi_err.c \
+ ccapi_ipc.c \
+ ccapi_string.c \
+ ccapi_v2.c
+
+ccapi_err.c ccapi_err.h : ccapi_err.et
+
+all-unix: all-libobjs all-liblinks
+clean-unix:: clean-libobjs clean-liblinks clean-libs
+
+@lib_frag@
+@libobj_frag@
+
diff --git a/src/ccapi/lib/ccapi.exports b/src/ccapi/lib/ccapi.exports
new file mode 100644
index 000000000000..92c859bd745f
--- /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 000000000000..9e8ba36c5c4e
--- /dev/null
+++ b/src/ccapi/lib/ccapi_ccache.c
@@ -0,0 +1,793 @@
+/* ccapi/lib/ccapi_ccache.c */
+/*
+ * Copyright 2006, 2007 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"
+
+/* ------------------------------------------------------------------------ */
+
+typedef struct cci_ccache_d {
+ cc_ccache_f *functions;
+#if TARGET_OS_MAC
+ cc_ccache_f *vector_functions;
+#endif
+ cci_identifier_t identifier;
+ cc_time_t last_wait_for_change_time;
+ cc_uint32 compat_version;
+} *cci_ccache_t;
+
+/* ------------------------------------------------------------------------ */
+
+struct cci_ccache_d cci_ccache_initializer = {
+ NULL
+ VECTOR_FUNCTIONS_INITIALIZER,
+ NULL,
+ 0
+};
+
+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,
+ k5_ipc_stream 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);
+}
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+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);
+
+ 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;
+ k5_ipc_stream 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 = krb5int_ipc_stream_read_uint32 (reply, out_credentials_version);
+ }
+
+ krb5int_ipc_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;
+ k5_ipc_stream 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 = krb5int_ipc_stream_read_string (reply, &name);
+ }
+
+ if (!err) {
+ err = cci_string_new (out_name, name);
+ }
+
+ krb5int_ipc_stream_release (reply);
+ krb5int_ipc_stream_free_string (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;
+ k5_ipc_stream request = NULL;
+ k5_ipc_stream reply = NULL;
+ char *principal = NULL;
+
+ if (!in_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_principal) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = krb5int_ipc_stream_new (&request);
+ }
+
+ if (!err) {
+ err = krb5int_ipc_stream_write_uint32 (request, in_credentials_version);
+ }
+
+ if (!err) {
+ err = cci_ipc_send (cci_ccache_get_principal_msg_id,
+ ccache->identifier,
+ request,
+ &reply);
+ }
+
+ if (!err) {
+ err = krb5int_ipc_stream_read_string (reply, &principal);
+ }
+
+ if (!err) {
+ err = cci_string_new (out_principal, principal);
+ }
+
+ krb5int_ipc_stream_release (request);
+ krb5int_ipc_stream_release (reply);
+ krb5int_ipc_stream_free_string (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;
+ k5_ipc_stream request = NULL;
+
+ if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_principal) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = krb5int_ipc_stream_new (&request);
+ }
+
+ if (!err) {
+ err = krb5int_ipc_stream_write_uint32 (request, in_credentials_version);
+ }
+
+ if (!err) {
+ err = krb5int_ipc_stream_write_string (request, in_principal);
+ }
+
+ if (!err) {
+ err = cci_ipc_send (cci_ccache_set_principal_msg_id,
+ ccache->identifier,
+ request,
+ NULL);
+ }
+
+ krb5int_ipc_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;
+ k5_ipc_stream request = NULL;
+
+ if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_credentials_union) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = krb5int_ipc_stream_new (&request);
+ }
+
+ if (!err) {
+ err = cci_credentials_union_write (in_credentials_union, request);
+ }
+
+ if (!err) {
+ err = cci_ipc_send (cci_ccache_store_credentials_msg_id,
+ ccache->identifier,
+ request,
+ NULL);
+ }
+
+ krb5int_ipc_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;
+ k5_ipc_stream request = NULL;
+
+ if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_credentials) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = krb5int_ipc_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);
+ }
+
+ krb5int_ipc_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;
+ k5_ipc_stream 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);
+ }
+
+ krb5int_ipc_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;
+ k5_ipc_stream request = NULL;
+
+ if (!io_source_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_destination_ccache) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = krb5int_ipc_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);
+ }
+
+ krb5int_ipc_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;
+ k5_ipc_stream request = NULL;
+
+ if (!io_ccache) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = krb5int_ipc_stream_new (&request);
+ }
+
+ if (!err) {
+ err = krb5int_ipc_stream_write_uint32 (request, in_lock_type);
+ }
+
+ if (!err) {
+ err = krb5int_ipc_stream_write_uint32 (request, in_block);
+ }
+
+ if (!err) {
+ err = cci_ipc_send (cci_ccache_lock_msg_id,
+ ccache->identifier,
+ request,
+ NULL);
+ }
+
+ krb5int_ipc_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;
+ k5_ipc_stream 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 = krb5int_ipc_stream_read_time (reply, out_last_default_time);
+ }
+
+ krb5int_ipc_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;
+ k5_ipc_stream 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 = krb5int_ipc_stream_read_time (reply, out_change_time);
+ }
+
+ krb5int_ipc_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;
+ k5_ipc_stream request = NULL;
+ k5_ipc_stream reply = NULL;
+
+ if (!in_ccache) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = krb5int_ipc_stream_new (&request);
+ }
+
+ if (!err) {
+ err = krb5int_ipc_stream_write_time (request, ccache->last_wait_for_change_time);
+ }
+
+ if (!err) {
+ err = cci_ipc_send (cci_ccache_wait_for_change_msg_id,
+ ccache->identifier,
+ request,
+ &reply);
+ }
+
+ if (!err) {
+ err = krb5int_ipc_stream_read_time (reply, &ccache->last_wait_for_change_time);
+ }
+
+ krb5int_ipc_stream_release (request);
+ krb5int_ipc_stream_release (reply);
+
+ 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;
+ k5_ipc_stream request = NULL;
+ k5_ipc_stream reply = NULL;
+
+ if (!in_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_time_offset) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = krb5int_ipc_stream_new (&request);
+ }
+
+ if (!err) {
+ err = krb5int_ipc_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 = krb5int_ipc_stream_read_time (reply, out_time_offset);
+ }
+
+ krb5int_ipc_stream_release (request);
+ krb5int_ipc_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;
+ k5_ipc_stream request = NULL;
+
+ if (!io_ccache) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = krb5int_ipc_stream_new (&request);
+ }
+
+ if (!err) {
+ err = krb5int_ipc_stream_write_uint32 (request, in_credentials_version);
+ }
+
+ if (!err) {
+ err = krb5int_ipc_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);
+ }
+
+ krb5int_ipc_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;
+ k5_ipc_stream request = NULL;
+
+ if (!io_ccache) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = krb5int_ipc_stream_new (&request);
+ }
+
+ if (!err) {
+ err = krb5int_ipc_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);
+ }
+
+ krb5int_ipc_stream_release (request);
+
+ return cci_check_error (err);
+}
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 cci_ccache_get_compat_version (cc_ccache_t in_ccache,
+ cc_uint32 *out_compat_version)
+{
+ cc_int32 err = ccNoError;
+ cci_ccache_t ccache = (cci_ccache_t) in_ccache;
+
+ if (!in_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_compat_version) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ *out_compat_version = ccache->compat_version;
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 cci_ccache_set_compat_version (cc_ccache_t io_ccache,
+ cc_uint32 in_compat_version)
+{
+ cc_int32 err = ccNoError;
+ cci_ccache_t ccache = (cci_ccache_t) io_ccache;
+
+ if (!io_ccache) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ ccache->compat_version = in_compat_version;
+ }
+
+ 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 000000000000..e6fc129abbe8
--- /dev/null
+++ b/src/ccapi/lib/ccapi_ccache.h
@@ -0,0 +1,105 @@
+/* ccapi/lib/ccapi_ccache.h */
+/*
+ * 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,
+ k5_ipc_stream 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);
+
+cc_int32 cci_ccache_get_compat_version (cc_ccache_t in_ccache,
+ cc_uint32 *out_compat_version);
+
+cc_int32 cci_ccache_set_compat_version (cc_ccache_t io_ccache,
+ cc_uint32 in_compat_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 000000000000..795610d974f8
--- /dev/null
+++ b/src/ccapi/lib/ccapi_ccache_iterator.c
@@ -0,0 +1,291 @@
+/* ccapi/lib/ccapi_ccache_iterator.c */
+/*
+ * 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;
+ char *saved_ccache_name;
+} *cci_ccache_iterator_t;
+
+/* ------------------------------------------------------------------------ */
+
+struct cci_ccache_iterator_d cci_ccache_iterator_initializer = {
+ NULL
+ VECTOR_FUNCTIONS_INITIALIZER,
+ NULL,
+ 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,
+ k5_ipc_stream 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) {
+ cc_uint32 initialized = 0;
+
+ err = cci_identifier_is_initialized (ccache_iterator->identifier,
+ &initialized);
+
+ if (!err && initialized) {
+ err = cci_ipc_send (cci_ccache_iterator_release_msg_id,
+ ccache_iterator->identifier,
+ NULL,
+ NULL);
+ if (err) {
+ cci_debug_printf ("%s: cci_ipc_send failed with error %d",
+ __FUNCTION__, err);
+ err = ccNoError;
+ }
+ }
+ }
+
+ if (!err) {
+ free ((char *) ccache_iterator->functions);
+ cci_identifier_release (ccache_iterator->identifier);
+ free (ccache_iterator->saved_ccache_name);
+ 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;
+ k5_ipc_stream 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);
+ }
+
+ krb5int_ipc_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;
+ k5_ipc_stream 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);
+ krb5int_ipc_stream_release (reply);
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 cci_ccache_iterator_get_saved_ccache_name (cc_ccache_iterator_t in_ccache_iterator,
+ const char **out_saved_ccache_name)
+{
+ 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 (!out_saved_ccache_name) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ *out_saved_ccache_name = ccache_iterator->saved_ccache_name;
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 cci_ccache_iterator_set_saved_ccache_name (cc_ccache_iterator_t io_ccache_iterator,
+ const char *in_saved_ccache_name)
+{
+ cc_int32 err = ccNoError;
+ cci_ccache_iterator_t ccache_iterator = (cci_ccache_iterator_t) io_ccache_iterator;
+ char *new_saved_ccache_name = NULL;
+
+ if (!io_ccache_iterator) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err && in_saved_ccache_name) {
+ new_saved_ccache_name = strdup (in_saved_ccache_name);
+ if (!new_saved_ccache_name) { err = ccErrNoMem; }
+ }
+
+ if (!err) {
+ free (ccache_iterator->saved_ccache_name);
+
+ ccache_iterator->saved_ccache_name = new_saved_ccache_name;
+ new_saved_ccache_name = NULL; /* take ownership */
+ }
+
+ free (new_saved_ccache_name);
+
+ 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 000000000000..88947eafd9d6
--- /dev/null
+++ b/src/ccapi/lib/ccapi_ccache_iterator.h
@@ -0,0 +1,51 @@
+/* ccapi/lib/ccapi_ccache_iterator.h */
+/*
+ * 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,
+ k5_ipc_stream 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);
+
+cc_int32 cci_ccache_iterator_get_saved_ccache_name (cc_ccache_iterator_t in_ccache_iterator,
+ const char **out_saved_ccache_name);
+
+cc_int32 cci_ccache_iterator_set_saved_ccache_name (cc_ccache_iterator_t io_ccache_iterator,
+ const char *in_saved_ccache_name);
+
+#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 000000000000..cf677fc55142
--- /dev/null
+++ b/src/ccapi/lib/ccapi_context.c
@@ -0,0 +1,831 @@
+/* ccapi/lib/ccapi_context.c */
+/*
+ * Copyright 2006, 2007 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 "ccapi_err.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;
+ cc_time_t last_wait_for_change_time;
+} *cci_context_t;
+
+/* ------------------------------------------------------------------------ */
+
+struct cci_context_d cci_context_initializer = {
+ NULL
+ VECTOR_FUNCTIONS_INITIALIZER,
+ NULL,
+ 0,
+ 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);
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+MAKE_INIT_FUNCTION(cci_process_init);
+MAKE_FINI_FUNCTION(cci_process_fini);
+
+/* ------------------------------------------------------------------------ */
+
+static int cci_process_init (void)
+{
+ cc_int32 err = ccNoError;
+
+ if (!err) {
+ err = cci_context_change_time_thread_init ();
+ }
+
+ if (!err) {
+ err = cci_ipc_process_init ();
+ }
+
+ if (!err) {
+ add_error_table (&et_CAPI_error_table);
+ }
+
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static void cci_process_fini (void)
+{
+ if (!INITIALIZER_RAN (cci_process_init) || PROGRAM_EXITING ()) {
+ return;
+ }
+
+ remove_error_table(&et_CAPI_error_table);
+ cci_context_change_time_thread_fini ();
+}
+
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+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_process_init);
+ }
+
+ if (!err) {
+ switch (in_version) {
+ case ccapi_version_2:
+ case ccapi_version_3:
+ case ccapi_version_4:
+ case ccapi_version_5:
+ case ccapi_version_6:
+ case ccapi_version_7:
+ 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);
+}
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+/* ------------------------------------------------------------------------ */
+/*
+ * Currently does not need to talk to the server since the server must
+ * handle cleaning up resources from crashed clients anyway.
+ *
+ * NOTE: if server communication is ever added here, make sure that
+ * krb5_stdcc_shutdown calls an internal function which does not talk to the
+ * server. krb5_stdcc_shutdown is called from thread fini functions and may
+ * crash talking to the server depending on what order the OS calls the fini
+ * functions (ie: if the ipc layer fini function is called first).
+ */
+
+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) {
+ 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;
+ k5_ipc_stream 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 && krb5int_ipc_stream_size (reply) > 0) {
+ cc_time_t change_time = 0;
+
+ /* got a response from the server */
+ err = krb5int_ipc_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);
+ }
+
+ krb5int_ipc_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;
+ k5_ipc_stream request = NULL;
+ k5_ipc_stream reply = NULL;
+
+ if (!in_context) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = krb5int_ipc_stream_new (&request);
+ }
+
+ if (!err) {
+ err = krb5int_ipc_stream_write_time (request, context->last_wait_for_change_time);
+ }
+
+ if (!err) {
+ err = cci_context_sync (context, 1);
+ }
+
+ if (!err) {
+ err = cci_ipc_send (cci_context_wait_for_change_msg_id,
+ context->identifier,
+ request,
+ &reply);
+ }
+
+ if (!err) {
+ err = krb5int_ipc_stream_read_time (reply, &context->last_wait_for_change_time);
+ }
+
+ krb5int_ipc_stream_release (request);
+ krb5int_ipc_stream_release (reply);
+
+ 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;
+ k5_ipc_stream 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 (krb5int_ipc_stream_size (reply) > 0) {
+ /* got a response from the server */
+ err = krb5int_ipc_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);
+ }
+
+ krb5int_ipc_stream_release (reply);
+ krb5int_ipc_stream_free_string (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;
+ k5_ipc_stream request = NULL;
+ k5_ipc_stream 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 = krb5int_ipc_stream_new (&request);
+ }
+
+ if (!err) {
+ err = krb5int_ipc_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 && !(krb5int_ipc_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);
+ krb5int_ipc_stream_release (reply);
+ krb5int_ipc_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;
+ k5_ipc_stream 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 && !(krb5int_ipc_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);
+ krb5int_ipc_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;
+ k5_ipc_stream request = NULL;
+ k5_ipc_stream 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 = krb5int_ipc_stream_new (&request);
+ }
+
+ if (!err) {
+ err = krb5int_ipc_stream_write_string (request, in_name);
+ }
+
+ if (!err) {
+ err = krb5int_ipc_stream_write_uint32 (request, in_cred_vers);
+ }
+
+ if (!err) {
+ err = krb5int_ipc_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);
+ krb5int_ipc_stream_release (reply);
+ krb5int_ipc_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;
+ k5_ipc_stream request = NULL;
+ k5_ipc_stream 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 = krb5int_ipc_stream_new (&request);
+ }
+
+ if (!err) {
+ err = krb5int_ipc_stream_write_uint32 (request, in_cred_vers);
+ }
+
+ if (!err) {
+ err = krb5int_ipc_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);
+ krb5int_ipc_stream_release (reply);
+ krb5int_ipc_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;
+ k5_ipc_stream request = NULL;
+ k5_ipc_stream 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 = krb5int_ipc_stream_new (&request);
+ }
+
+ if (!err) {
+ err = krb5int_ipc_stream_write_uint32 (request, in_cred_vers);
+ }
+
+ if (!err) {
+ err = krb5int_ipc_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);
+ krb5int_ipc_stream_release (reply);
+ krb5int_ipc_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;
+ k5_ipc_stream 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 (krb5int_ipc_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);
+ }
+
+ krb5int_ipc_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;
+ k5_ipc_stream request = NULL;
+
+ if (!in_context) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = krb5int_ipc_stream_new (&request);
+ }
+
+ if (!err) {
+ err = krb5int_ipc_stream_write_uint32 (request, in_lock_type);
+ }
+
+ if (!err) {
+ err = krb5int_ipc_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);
+ }
+
+ krb5int_ipc_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);
+}
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+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;
+ k5_ipc_stream 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 (krb5int_ipc_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);
+ krb5int_ipc_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 000000000000..51b8982e6bdd
--- /dev/null
+++ b/src/ccapi/lib/ccapi_context.h
@@ -0,0 +1,86 @@
+/* ccapi/lib/ccapi_context.h */
+/*
+ * 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"
+
+/* Used for freeing ccapi context in thread fini calls
+ * Does not tell the server you are exiting. */
+cc_int32 cci_context_destroy (cc_context_t in_context);
+
+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);
+
+#ifdef WIN32
+void cci_thread_init__auxinit();
+#endif
+
+
+#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 000000000000..ec6b955e9f7d
--- /dev/null
+++ b/src/ccapi/lib/ccapi_context_change_time.c
@@ -0,0 +1,199 @@
+/* ccapi/lib/ccapi_context_change_time.c */
+/*
+ * Copyright 2006, 2007 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);
+}
+
+/* ------------------------------------------------------------------------ */
+
+void cci_context_change_time_thread_fini (void)
+{
+ k5_mutex_destroy(&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);
+}
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 cci_context_change_time_get (cc_time_t *out_change_time)
+{
+ cc_int32 err = ccNoError;
+
+ k5_mutex_lock (&g_change_time_mutex);
+
+ *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;
+ k5_mutex_lock (&g_change_time_mutex);
+
+ 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);
+ }
+
+ 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_uint32 server_ids_match = 0;
+ cc_uint32 server_was_running = 0;
+ cc_uint32 server_is_running = 0;
+
+ k5_mutex_lock (&g_change_time_mutex);
+
+ 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);
+ }
+
+ 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 000000000000..b1fa110e3451
--- /dev/null
+++ b/src/ccapi/lib/ccapi_context_change_time.h
@@ -0,0 +1,41 @@
+/* ccapi/lib/ccapi_context_change_time.h */
+/*
+ * 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);
+void cci_context_change_time_thread_fini (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 000000000000..cb175a31bdc7
--- /dev/null
+++ b/src/ccapi/lib/ccapi_credentials.c
@@ -0,0 +1,165 @@
+/* ccapi/lib/ccapi_credentials.c */
+/*
+ * 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_credentials_union_initializer = {
+ 0,
+ { NULL }
+};
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 cci_credentials_read (cc_credentials_t *out_credentials,
+ k5_ipc_stream 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_credentials_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,
+ k5_ipc_stream 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_credentials_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 000000000000..aea6a412ecb7
--- /dev/null
+++ b/src/ccapi/lib/ccapi_credentials.h
@@ -0,0 +1,43 @@
+/* ccapi/lib/ccapi_credentials.h */
+/*
+ * 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,
+ k5_ipc_stream in_stream);
+
+cc_int32 cci_credentials_write (cc_credentials_t in_credentials,
+ k5_ipc_stream 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 000000000000..f1efc7f8d0ed
--- /dev/null
+++ b/src/ccapi/lib/ccapi_credentials_iterator.c
@@ -0,0 +1,246 @@
+/* ccapi/lib/ccapi_credentials_iterator.c */
+/*
+ * 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;
+ cc_uint32 compat_version;
+} *cci_credentials_iterator_t;
+
+/* ------------------------------------------------------------------------ */
+
+struct cci_credentials_iterator_d cci_credentials_iterator_initializer = {
+ NULL
+ VECTOR_FUNCTIONS_INITIALIZER,
+ NULL,
+ 0
+};
+
+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,
+ k5_ipc_stream 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) {
+ err = cci_ipc_send (cci_credentials_iterator_release_msg_id,
+ credentials_iterator->identifier,
+ NULL,
+ NULL);
+ if (err) {
+ cci_debug_printf ("%s: cci_ipc_send failed with error %d",
+ __FUNCTION__, err);
+ err = ccNoError;
+ }
+ }
+
+ 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;
+ k5_ipc_stream 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);
+ }
+
+ krb5int_ipc_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;
+ k5_ipc_stream 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);
+ }
+
+ krb5int_ipc_stream_release (reply);
+ cci_identifier_release (identifier);
+
+ return cci_check_error (err);
+}
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 cci_credentials_iterator_get_compat_version (cc_credentials_iterator_t in_credentials_iterator,
+ cc_uint32 *out_compat_version)
+{
+ 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 (!out_compat_version ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ *out_compat_version = credentials_iterator->compat_version;
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 cci_credentials_iterator_set_compat_version (cc_credentials_iterator_t io_credentials_iterator,
+ cc_uint32 in_compat_version)
+{
+ cc_int32 err = ccNoError;
+ cci_credentials_iterator_t credentials_iterator = (cci_credentials_iterator_t) io_credentials_iterator;
+
+ if (!io_credentials_iterator) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ credentials_iterator->compat_version = in_compat_version;
+ }
+
+ 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 000000000000..56c4505d9590
--- /dev/null
+++ b/src/ccapi/lib/ccapi_credentials_iterator.h
@@ -0,0 +1,51 @@
+/* ccapi/lib/ccapi_credentials_iterator.h */
+/*
+ * 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,
+ k5_ipc_stream 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);
+
+cc_int32 cci_credentials_iterator_get_compat_version (cc_credentials_iterator_t in_credentials_iterator,
+ cc_uint32 *out_compat_version);
+
+cc_int32 cci_credentials_iterator_set_compat_version (cc_credentials_iterator_t io_credentials_iterator,
+ cc_uint32 in_compat_version);
+
+#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 000000000000..44cd2d0b5e53
--- /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 000000000000..2c1fcba61029
--- /dev/null
+++ b/src/ccapi/lib/ccapi_ipc.c
@@ -0,0 +1,119 @@
+/* ccapi/lib/ccapi_ipc.c */
+/*
+ * 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_process_init (void)
+{
+ return cci_os_ipc_process_init ();
+}
+
+/* ------------------------------------------------------------------------ */
+
+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,
+ k5_ipc_stream in_request_data,
+ k5_ipc_stream *out_reply_data)
+{
+ cc_int32 err = ccNoError;
+ k5_ipc_stream request = NULL;
+ k5_ipc_stream 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 = krb5int_ipc_stream_write (request,
+ krb5int_ipc_stream_data (in_request_data),
+ krb5int_ipc_stream_size (in_request_data));
+ }
+
+ if (!err) {
+ err = cci_os_ipc (in_launch_server, request, &reply);
+
+ if (!err && krb5int_ipc_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 */
+ }
+
+ krb5int_ipc_stream_release (request);
+ krb5int_ipc_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,
+ k5_ipc_stream in_request_data,
+ k5_ipc_stream *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,
+ k5_ipc_stream in_request_data,
+ k5_ipc_stream *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 000000000000..a23772b29f7b
--- /dev/null
+++ b/src/ccapi/lib/ccapi_ipc.h
@@ -0,0 +1,45 @@
+/* ccapi/lib/ccapi_ipc.h */
+/*
+ * 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_process_init (void);
+
+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,
+ k5_ipc_stream in_request_data,
+ k5_ipc_stream *out_reply_data);
+
+cc_int32 cci_ipc_send_no_launch (enum cci_msg_id_t in_request_name,
+ cci_identifier_t in_identifier,
+ k5_ipc_stream in_request_data,
+ k5_ipc_stream *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 000000000000..fe7c87a08c9b
--- /dev/null
+++ b/src/ccapi/lib/ccapi_os_ipc.h
@@ -0,0 +1,39 @@
+/* ccapi/lib/ccapi_os_ipc.h */
+/*
+ * 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"
+
+cc_int32 cci_os_ipc_process_init (void);
+
+cc_int32 cci_os_ipc_thread_init (void);
+
+cc_int32 cci_os_ipc (cc_int32 in_launch_server,
+ k5_ipc_stream in_request_stream,
+ k5_ipc_stream *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 000000000000..ab84dfe39aff
--- /dev/null
+++ b/src/ccapi/lib/ccapi_string.c
@@ -0,0 +1,101 @@
+/* ccapi/lib/ccapi_string.c */
+/*
+ * 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 = strdup (in_cstring);
+ if (!string->data) {
+ 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 000000000000..02debde9d1f3
--- /dev/null
+++ b/src/ccapi/lib/ccapi_string.h
@@ -0,0 +1,36 @@
+/* ccapi/lib/ccapi_string.h */
+/*
+ * 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 000000000000..8a831d796abb
--- /dev/null
+++ b/src/ccapi/lib/ccapi_v2.c
@@ -0,0 +1,917 @@
+/* ccapi/lib/ccapi_v2.c */
+/*
+ * 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 "ccapi_string.h"
+#include "ccapi_context.h"
+#include "ccapi_ccache.h"
+#include "ccapi_ccache_iterator.h"
+#include "ccapi_credentials.h"
+#include "ccapi_credentials_iterator.h"
+#include <CredentialsCache2.h>
+
+infoNC infoNC_initializer = { NULL, NULL, CC_CRED_UNKNOWN };
+
+/* ------------------------------------------------------------------------ */
+
+static cc_int32 cci_remap_version (cc_int32 in_v2_version,
+ cc_uint32 *out_v3_version)
+{
+ cc_result err = ccNoError;
+
+ if (!out_v3_version) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ if (in_v2_version == CC_CRED_V4) {
+ *out_v3_version = cc_credentials_v4;
+
+ } else if (in_v2_version == CC_CRED_V5) {
+ *out_v3_version = cc_credentials_v5;
+
+ } else {
+ err = ccErrBadCredentialsVersion;
+ }
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_result _cci_remap_error (cc_result in_error,
+ const char *in_function,
+ const char *in_file,
+ int in_line)
+{
+ _cci_check_error (in_error, in_function, in_file, in_line);
+
+ if (in_error >= CC_NOERROR && in_error <= CC_ERR_CRED_VERSION) {
+ return in_error;
+ }
+
+ switch (in_error) {
+ case ccNoError:
+ return CC_NOERROR;
+
+ case ccIteratorEnd:
+ return CC_END;
+
+ case ccErrBadParam:
+ case ccErrContextNotFound:
+ case ccErrInvalidContext:
+ case ccErrInvalidCredentials:
+ case ccErrInvalidCCacheIterator:
+ case ccErrInvalidCredentialsIterator:
+ case ccErrInvalidLock:
+ case ccErrBadLockType:
+ return CC_BAD_PARM;
+
+ case ccErrNoMem:
+ return CC_NOMEM;
+
+ case ccErrInvalidCCache:
+ case ccErrCCacheNotFound:
+ return CC_NO_EXIST;
+
+ case ccErrCredentialsNotFound:
+ return CC_NOTFOUND;
+
+ case ccErrBadName:
+ return CC_BADNAME;
+
+ case ccErrBadCredentialsVersion:
+ return CC_ERR_CRED_VERSION;
+
+ case ccErrBadAPIVersion:
+ return CC_BAD_API_VERSION;
+
+ case ccErrContextLocked:
+ case ccErrContextUnlocked:
+ case ccErrCCacheLocked:
+ case ccErrCCacheUnlocked:
+ return CC_LOCKED;
+
+ case ccErrServerUnavailable:
+ case ccErrServerInsecure:
+ case ccErrServerCantBecomeUID:
+ case ccErrBadInternalMessage:
+ case ccErrClientNotFound:
+ return CC_IO;
+
+ case ccErrNotImplemented:
+ return CC_NOT_SUPP;
+
+ default:
+ cci_debug_printf ("%s(): Unhandled error", __FUNCTION__);
+ return CC_BAD_PARM;
+ }
+}
+#define cci_remap_error(err) _cci_remap_error(err, __FUNCTION__, __FILE__, __LINE__)
+
+
+#if TARGET_OS_MAC
+#pragma mark -
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_shutdown (apiCB **io_context)
+{
+ cc_result err = ccNoError;
+
+ if (!io_context) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccapi_context_release (*io_context);
+ }
+
+ if (!err) {
+ *io_context = NULL;
+ }
+
+ return cci_remap_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_get_change_time (apiCB *in_context,
+ cc_time_t *out_change_time)
+{
+ cc_result err = ccNoError;
+
+ if (!in_context ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_change_time) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccapi_context_get_change_time (in_context, out_change_time);
+ }
+
+ return cci_remap_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_get_NC_info (apiCB *in_context,
+ infoNC ***out_info)
+{
+ cc_result err = CC_NOERROR;
+ infoNC **info = NULL;
+ cc_uint64 count = 0; /* Preflight the size */
+ cc_uint64 i;
+
+ if (!in_context) { err = cci_check_error (ccErrBadParam); }
+ if (!out_info ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ ccache_cit *iterator = NULL;
+
+ err = cc_seq_fetch_NCs_begin (in_context, &iterator);
+
+ while (!err) {
+ ccache_p *ccache = NULL;
+
+ err = cc_seq_fetch_NCs_next (in_context, &ccache, iterator);
+
+ if (!err) { count++; }
+
+ if (ccache) { cc_close (in_context, &ccache); }
+ }
+ if (err == CC_END) { err = CC_NOERROR; }
+
+ if (!err) {
+ err = cc_seq_fetch_NCs_end (in_context, &iterator);
+ }
+ }
+
+ if (!err) {
+ info = malloc (sizeof (*info) * (count + 1));
+ if (info) {
+ for (i = 0; i < count + 1; i++) { info[i] = NULL; }
+ } else {
+ err = cci_check_error (CC_NOMEM);
+ }
+ }
+
+ if (!err) {
+ ccache_cit *iterator = NULL;
+
+ err = cc_seq_fetch_NCs_begin (in_context, &iterator);
+
+ for (i = 0; !err && i < count; i++) {
+ ccache_p *ccache = NULL;
+
+ err = cc_seq_fetch_NCs_next (in_context, &ccache, iterator);
+
+ if (!err) {
+ info[i] = malloc (sizeof (*info[i]));
+ if (info[i]) {
+ *info[i] = infoNC_initializer;
+ } else {
+ err = cci_check_error (CC_NOMEM);
+ }
+ }
+
+ if (!err) {
+ err = cc_get_name (in_context, ccache, &info[i]->name);
+ }
+
+ if (!err) {
+ err = cc_get_principal (in_context, ccache, &info[i]->principal);
+ }
+
+ if (!err) {
+ err = cc_get_cred_version (in_context, ccache, &info[i]->vers);
+ }
+
+ if (ccache) { cc_close (in_context, &ccache); }
+ }
+
+ if (!err) {
+ err = cc_seq_fetch_NCs_end (in_context, &iterator);
+ }
+ }
+
+ if (!err) {
+ *out_info = info;
+ info = NULL;
+ }
+
+ if (info) { cc_free_NC_info (in_context, &info); }
+
+ return cci_check_error (err);
+}
+
+#if TARGET_OS_MAC
+#pragma mark -
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 cc_open (apiCB *in_context,
+ const char *in_name,
+ cc_int32 in_version,
+ cc_uint32 in_flags,
+ ccache_p **out_ccache)
+{
+ cc_result err = ccNoError;
+ cc_ccache_t ccache = NULL;
+ cc_uint32 compat_version;
+ cc_uint32 real_version;
+
+ 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_remap_version (in_version, &compat_version);
+ }
+
+ if (!err) {
+ err = ccapi_context_open_ccache (in_context, in_name, &ccache);
+ }
+
+ /* We must not allow a CCAPI v2 caller to open a v5-only ccache
+ as a v4 ccache and vice versa. Allowing that would break
+ (valid) assumptions made by CCAPI v2 callers. */
+
+ if (!err) {
+ err = ccapi_ccache_get_credentials_version (ccache, &real_version);
+ }
+
+ if (!err) {
+ /* check the version and set up the ccache to use it */
+ if (compat_version & real_version) {
+ err = cci_ccache_set_compat_version (ccache, compat_version);
+ } else {
+ err = ccErrBadCredentialsVersion;
+ }
+ }
+
+ if (!err) {
+ *out_ccache = ccache;
+ ccache = NULL;
+ }
+
+ if (ccache) { ccapi_ccache_release (ccache); }
+
+ return cci_remap_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+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)
+{
+ cc_result err = ccNoError;
+ cc_ccache_t ccache = NULL;
+ cc_uint32 compat_version;
+
+ 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_remap_version (in_version, &compat_version);
+ }
+
+ if (!err) {
+ err = ccapi_context_create_ccache (in_context, in_name, compat_version,
+ in_principal, &ccache);
+ }
+
+ if (!err) {
+ err = cci_ccache_set_compat_version (ccache, compat_version);
+ }
+
+ if (!err) {
+ *out_ccache = ccache;
+ ccache = NULL;
+ }
+
+ if (ccache) { ccapi_ccache_release (ccache); }
+
+ return cci_remap_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_close (apiCB *in_context,
+ ccache_p **io_ccache)
+{
+ cc_result err = ccNoError;
+
+ if (!in_context) { err = cci_check_error (ccErrBadParam); }
+ if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccapi_ccache_release (*io_ccache);
+ }
+
+ if (!err) {
+ *io_ccache = NULL;
+ }
+
+ return cci_remap_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_destroy (apiCB *in_context,
+ ccache_p **io_ccache)
+{
+ cc_result err = ccNoError;
+
+ if (!in_context) { err = cci_check_error (ccErrBadParam); }
+ if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccapi_ccache_destroy (*io_ccache);
+ }
+
+ if (!err) {
+ *io_ccache = NULL;
+ }
+
+ return cci_remap_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_get_name (apiCB *in_context,
+ ccache_p *in_ccache,
+ char **out_name)
+{
+ cc_result err = ccNoError;
+ cc_string_t name = NULL;
+
+ if (!in_context) { err = cci_check_error (ccErrBadParam); }
+ if (!in_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_name ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccapi_ccache_get_name (in_ccache, &name);
+ }
+
+ if (!err) {
+ char *string = strdup (name->data);
+ if (string) {
+ *out_name = string;
+ } else {
+ err = cci_check_error (ccErrNoMem);
+ }
+ }
+
+ if (name) { ccapi_string_release (name); }
+
+ return cci_remap_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_get_cred_version (apiCB *in_context,
+ ccache_p *in_ccache,
+ cc_int32 *out_version)
+{
+ cc_result err = ccNoError;
+ cc_uint32 compat_version;
+
+ if (!in_context ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_version) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_ccache_get_compat_version (in_ccache, &compat_version);
+ }
+
+ if (!err) {
+ if (compat_version == cc_credentials_v4) {
+ *out_version = CC_CRED_V4;
+
+ } else if (compat_version == cc_credentials_v5) {
+ *out_version = CC_CRED_V5;
+
+ } else {
+ err = ccErrBadCredentialsVersion;
+ }
+ }
+
+ return cci_remap_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_set_principal (apiCB *in_context,
+ ccache_p *io_ccache,
+ cc_int32 in_version,
+ char *in_principal)
+{
+ cc_result err = ccNoError;
+ cc_uint32 version;
+ cc_uint32 compat_version;
+
+ if (!in_context ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_principal) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_remap_version (in_version, &version);
+ }
+
+ if (!err) {
+ err = cci_ccache_get_compat_version (io_ccache, &compat_version);
+ }
+
+ if (!err && version != compat_version) {
+ err = cci_check_error (ccErrBadCredentialsVersion);
+ }
+
+ if (!err) {
+ err = ccapi_ccache_set_principal (io_ccache, version, in_principal);
+ }
+
+ return cci_remap_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_get_principal (apiCB *in_context,
+ ccache_p *in_ccache,
+ char **out_principal)
+{
+ cc_result err = ccNoError;
+ cc_uint32 compat_version;
+ cc_string_t principal = NULL;
+
+ if (!in_context ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_principal) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_ccache_get_compat_version (in_ccache, &compat_version);
+ }
+
+ if (!err) {
+ err = ccapi_ccache_get_principal (in_ccache, compat_version, &principal);
+ }
+
+ if (!err) {
+ char *string = strdup (principal->data);
+ if (string) {
+ *out_principal = string;
+ } else {
+ err = cci_check_error (ccErrNoMem);
+ }
+ }
+
+ if (principal) { ccapi_string_release (principal); }
+
+ return cci_remap_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_store (apiCB *in_context,
+ ccache_p *io_ccache,
+ cred_union in_credentials)
+{
+ cc_result err = ccNoError;
+ cc_credentials_union *creds_union = NULL;
+
+ if (!in_context) { err = cci_check_error (ccErrBadParam); }
+ if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_cred_union_to_credentials_union (&in_credentials,
+ &creds_union);
+ }
+
+ if (!err) {
+ err = ccapi_ccache_store_credentials (io_ccache, creds_union);
+ }
+
+ if (creds_union) { cci_credentials_union_release (creds_union); }
+ return cci_remap_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_remove_cred (apiCB *in_context,
+ ccache_p *in_ccache,
+ cred_union in_credentials)
+{
+ cc_result err = ccNoError;
+ cc_credentials_iterator_t iterator = NULL;
+ cc_uint32 found = 0;
+
+ if (!in_context) { err = cci_check_error (ccErrBadParam); }
+ if (!in_ccache ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccapi_ccache_new_credentials_iterator (in_ccache, &iterator);
+ }
+
+ while (!err && !found) {
+ cc_credentials_t creds = NULL;
+
+ err = ccapi_credentials_iterator_next (iterator, &creds);
+
+ if (!err) {
+ err = cci_cred_union_compare_to_credentials_union (&in_credentials,
+ creds->data,
+ &found);
+ }
+
+ if (!err && found) {
+ err = ccapi_ccache_remove_credentials (in_ccache, creds);
+ }
+
+ ccapi_credentials_release (creds);
+ }
+ if (err == ccIteratorEnd) { err = cci_check_error (ccErrCredentialsNotFound); }
+
+ return cci_remap_error (err);
+}
+
+#if TARGET_OS_MAC
+#pragma mark -
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_seq_fetch_NCs_begin (apiCB *in_context,
+ ccache_cit **out_iterator)
+{
+ cc_result err = ccNoError;
+ cc_ccache_iterator_t iterator = NULL;
+
+ if (!in_context ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_iterator) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccapi_context_new_ccache_iterator (in_context, &iterator);
+ }
+
+ if (!err) {
+ *out_iterator = (ccache_cit *) iterator;
+ iterator = NULL; /* take ownership */
+ }
+
+ if (iterator) { ccapi_ccache_iterator_release (iterator); }
+
+ return cci_remap_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_seq_fetch_NCs_next (apiCB *in_context,
+ ccache_p **out_ccache,
+ ccache_cit *in_iterator)
+{
+ cc_result err = ccNoError;
+ cc_ccache_iterator_t iterator = (cc_ccache_iterator_t) in_iterator;
+ cc_ccache_t ccache = NULL;
+ const char *saved_ccache_name;
+
+ if (!in_context ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_iterator) { err = cci_check_error (ccErrBadParam); }
+
+ /* CCache iterators need to return some ccaches twice (when v3 ccache has
+ * two kinds of credentials). To do that, we return such ccaches twice
+ * v4 first, then v5. */
+
+ if (!err) {
+ err = cci_ccache_iterator_get_saved_ccache_name (iterator,
+ &saved_ccache_name);
+ }
+
+ if (!err) {
+ if (saved_ccache_name) {
+ err = ccapi_context_open_ccache (in_context, saved_ccache_name,
+ &ccache);
+
+ if (!err) {
+ err = cci_ccache_set_compat_version (ccache, cc_credentials_v5);
+ }
+
+ if (!err) {
+ err = cci_ccache_iterator_set_saved_ccache_name (iterator, NULL);
+ }
+
+ } else {
+ cc_uint32 version = 0;
+
+ err = ccapi_ccache_iterator_next (iterator, &ccache);
+
+ if (!err) {
+ err = ccapi_ccache_get_credentials_version (ccache, &version);
+ }
+
+ if (!err) {
+ if (version == cc_credentials_v4_v5) {
+ cc_string_t name = NULL;
+
+ err = cci_ccache_set_compat_version (ccache, cc_credentials_v4);
+
+ if (!err) {
+ err = ccapi_ccache_get_name (ccache, &name);
+ }
+
+ if (!err) {
+ err = cci_ccache_iterator_set_saved_ccache_name (iterator,
+ name->data);
+ }
+
+ if (name) { ccapi_string_release (name); }
+
+ } else {
+ err = cci_ccache_set_compat_version (ccache, version);
+ }
+ }
+ }
+ }
+
+ if (!err) {
+ *out_ccache = ccache;
+ ccache = NULL; /* take ownership */
+ }
+
+ if (ccache) { ccapi_ccache_release (ccache); }
+
+ return cci_remap_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_seq_fetch_NCs_end (apiCB *in_context,
+ ccache_cit **io_iterator)
+{
+ cc_result err = ccNoError;
+ cc_ccache_iterator_t iterator = (cc_ccache_iterator_t) *io_iterator;
+
+ if (!in_context ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_iterator) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccapi_ccache_iterator_release (iterator);
+ }
+
+ if (!err) {
+ *io_iterator = NULL;
+ }
+
+ return cci_remap_error (err);
+}
+
+#if TARGET_OS_MAC
+#pragma mark -
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_seq_fetch_creds_begin (apiCB *in_context,
+ const ccache_p *in_ccache,
+ ccache_cit **out_iterator)
+{
+ cc_result err = ccNoError;
+ cc_credentials_iterator_t iterator = NULL;
+ cc_uint32 compat_version;
+
+ if (!in_context ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_ccache ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_iterator) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_ccache_get_compat_version ((cc_ccache_t) in_ccache,
+ &compat_version);
+ }
+
+ if (!err) {
+ err = ccapi_ccache_new_credentials_iterator ((cc_ccache_t) in_ccache,
+ &iterator);
+ }
+
+ if (!err) {
+ err = cci_credentials_iterator_set_compat_version (iterator,
+ compat_version);
+ }
+
+ if (!err) {
+ *out_iterator = (ccache_cit *) iterator;
+ iterator = NULL; /* take ownership */
+ }
+
+ if (iterator) { ccapi_credentials_iterator_release (iterator); }
+
+ return cci_remap_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_seq_fetch_creds_next (apiCB *in_context,
+ cred_union **out_creds,
+ ccache_cit *in_iterator)
+{
+ cc_result err = ccNoError;
+ cc_credentials_iterator_t iterator = (cc_credentials_iterator_t) in_iterator;
+ cc_uint32 compat_version;
+
+ if (!in_context ) { err = cci_check_error (ccErrBadParam); }
+ if (!out_creds ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_iterator) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_credentials_iterator_get_compat_version (iterator,
+ &compat_version);
+ }
+
+ while (!err) {
+ cc_credentials_t credentials = NULL;
+
+ err = ccapi_credentials_iterator_next (iterator, &credentials);
+
+ if (!err && (credentials->data->version & compat_version)) {
+ /* got the next credentials for the correct version */
+ err = cci_credentials_union_to_cred_union (credentials->data,
+ out_creds);
+ break;
+ }
+
+ if (credentials) { ccapi_credentials_release (credentials); }
+ }
+
+ return cci_remap_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_seq_fetch_creds_end (apiCB *in_context,
+ ccache_cit **io_iterator)
+{
+ cc_result err = ccNoError;
+ cc_credentials_iterator_t iterator = (cc_credentials_iterator_t) *io_iterator;
+
+ if (!in_context ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_iterator) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccapi_credentials_iterator_release (iterator);
+ }
+
+ if (!err) {
+ *io_iterator = NULL;
+ }
+
+ return cci_remap_error (err);
+}
+
+#if TARGET_OS_MAC
+#pragma mark -
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_free_principal (apiCB *in_context,
+ char **io_principal)
+{
+ cc_result err = ccNoError;
+
+ if (!in_context ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_principal) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ free (*io_principal);
+ *io_principal = NULL;
+ }
+
+ return cci_remap_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_free_name (apiCB *in_context,
+ char **io_name)
+{
+ cc_result err = ccNoError;
+
+ if (!in_context) { err = cci_check_error (ccErrBadParam); }
+ if (!io_name ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ free (*io_name);
+ *io_name = NULL;
+ }
+
+ return cci_remap_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_free_creds (apiCB *in_context,
+ cred_union **io_credentials)
+{
+ cc_result err = ccNoError;
+
+ if (!in_context ) { err = cci_check_error (ccErrBadParam); }
+ if (!io_credentials) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = cci_cred_union_release (*io_credentials);
+ if (!err) { *io_credentials = NULL; }
+ }
+
+ return cci_remap_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_free_NC_info (apiCB *in_context,
+ infoNC ***io_info)
+{
+ cc_result err = ccNoError;
+
+ if (!in_context) { err = cci_check_error (ccErrBadParam); }
+ if (!io_info ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err && *io_info) {
+ infoNC **data = *io_info;
+ int i;
+
+ for (i = 0; data[i] != NULL; i++) {
+ cc_free_principal (in_context, &data[i]->principal);
+ cc_free_name (in_context, &data[i]->name);
+ free (data[i]);
+ }
+ free (data);
+
+ *io_info = NULL;
+ }
+
+ return cci_remap_error (err);
+}
diff --git a/src/ccapi/lib/ccapi_v2.exports b/src/ccapi/lib/ccapi_v2.exports
new file mode 100644
index 000000000000..efa9fcec7ba5
--- /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/deps b/src/ccapi/lib/deps
new file mode 100644
index 000000000000..ad996d9fab9e
--- /dev/null
+++ b/src/ccapi/lib/deps
@@ -0,0 +1,86 @@
+#
+# Generated makefile dependencies follow.
+#
+ccapi_ccache.so ccapi_ccache.po $(OUTPRE)ccapi_ccache.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(COM_ERR_DEPS) $(top_srcdir)/include/CredentialsCache.h \
+ $(top_srcdir)/include/CredentialsCache2.h $(top_srcdir)/include/k5-ipc_stream.h \
+ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \
+ $(srcdir)/../common/cci_common.h $(srcdir)/../common/cci_cred_union.h \
+ $(srcdir)/../common/cci_debugging.h $(srcdir)/../common/cci_identifier.h \
+ $(srcdir)/../common/cci_message.h $(srcdir)/../common/cci_types.h \
+ ccapi_ccache.c ccapi_ccache.h ccapi_credentials.h ccapi_credentials_iterator.h \
+ ccapi_ipc.h ccapi_string.h
+ccapi_ccache_iterator.so ccapi_ccache_iterator.po $(OUTPRE)ccapi_ccache_iterator.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(COM_ERR_DEPS) $(top_srcdir)/include/CredentialsCache.h \
+ $(top_srcdir)/include/CredentialsCache2.h $(top_srcdir)/include/k5-ipc_stream.h \
+ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \
+ $(srcdir)/../common/cci_common.h $(srcdir)/../common/cci_cred_union.h \
+ $(srcdir)/../common/cci_debugging.h $(srcdir)/../common/cci_identifier.h \
+ $(srcdir)/../common/cci_message.h $(srcdir)/../common/cci_types.h \
+ ccapi_ccache.h ccapi_ccache_iterator.c ccapi_ccache_iterator.h \
+ ccapi_ipc.h
+ccapi_context.so ccapi_context.po $(OUTPRE)ccapi_context.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(COM_ERR_DEPS) $(top_srcdir)/include/CredentialsCache.h \
+ $(top_srcdir)/include/CredentialsCache2.h $(top_srcdir)/include/k5-ipc_stream.h \
+ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \
+ $(srcdir)/../common/cci_common.h $(srcdir)/../common/cci_cred_union.h \
+ $(srcdir)/../common/cci_debugging.h $(srcdir)/../common/cci_identifier.h \
+ $(srcdir)/../common/cci_message.h $(srcdir)/../common/cci_types.h \
+ ccapi_ccache.h ccapi_ccache_iterator.h ccapi_context.c \
+ ccapi_context.h ccapi_context_change_time.h ccapi_err.h \
+ ccapi_ipc.h ccapi_string.h
+ccapi_context_change_time.so ccapi_context_change_time.po \
+ $(OUTPRE)ccapi_context_change_time.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+ $(COM_ERR_DEPS) $(top_srcdir)/include/CredentialsCache.h \
+ $(top_srcdir)/include/CredentialsCache2.h $(top_srcdir)/include/k5-ipc_stream.h \
+ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \
+ $(srcdir)/../common/cci_common.h $(srcdir)/../common/cci_cred_union.h \
+ $(srcdir)/../common/cci_debugging.h $(srcdir)/../common/cci_identifier.h \
+ $(srcdir)/../common/cci_message.h $(srcdir)/../common/cci_types.h \
+ ccapi_context_change_time.c ccapi_context_change_time.h
+ccapi_credentials.so ccapi_credentials.po $(OUTPRE)ccapi_credentials.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(COM_ERR_DEPS) $(top_srcdir)/include/CredentialsCache.h \
+ $(top_srcdir)/include/CredentialsCache2.h $(top_srcdir)/include/k5-ipc_stream.h \
+ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \
+ $(srcdir)/../common/cci_common.h $(srcdir)/../common/cci_cred_union.h \
+ $(srcdir)/../common/cci_debugging.h $(srcdir)/../common/cci_identifier.h \
+ $(srcdir)/../common/cci_message.h $(srcdir)/../common/cci_types.h \
+ ccapi_credentials.c ccapi_credentials.h ccapi_string.h
+ccapi_credentials_iterator.so ccapi_credentials_iterator.po \
+ $(OUTPRE)ccapi_credentials_iterator.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+ $(COM_ERR_DEPS) $(top_srcdir)/include/CredentialsCache.h \
+ $(top_srcdir)/include/CredentialsCache2.h $(top_srcdir)/include/k5-ipc_stream.h \
+ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \
+ $(srcdir)/../common/cci_common.h $(srcdir)/../common/cci_cred_union.h \
+ $(srcdir)/../common/cci_debugging.h $(srcdir)/../common/cci_identifier.h \
+ $(srcdir)/../common/cci_message.h $(srcdir)/../common/cci_types.h \
+ ccapi_credentials.h ccapi_credentials_iterator.c ccapi_credentials_iterator.h \
+ ccapi_ipc.h
+ccapi_err.so ccapi_err.po $(OUTPRE)ccapi_err.$(OBJEXT): \
+ $(COM_ERR_DEPS) ccapi_err.c
+ccapi_ipc.so ccapi_ipc.po $(OUTPRE)ccapi_ipc.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(COM_ERR_DEPS) $(top_srcdir)/include/CredentialsCache.h \
+ $(top_srcdir)/include/CredentialsCache2.h $(top_srcdir)/include/k5-ipc_stream.h \
+ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \
+ $(srcdir)/../common/cci_common.h $(srcdir)/../common/cci_cred_union.h \
+ $(srcdir)/../common/cci_debugging.h $(srcdir)/../common/cci_identifier.h \
+ $(srcdir)/../common/cci_message.h $(srcdir)/../common/cci_types.h \
+ ccapi_ipc.c ccapi_ipc.h ccapi_os_ipc.h
+ccapi_string.so ccapi_string.po $(OUTPRE)ccapi_string.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(COM_ERR_DEPS) $(top_srcdir)/include/CredentialsCache.h \
+ $(top_srcdir)/include/CredentialsCache2.h $(top_srcdir)/include/k5-ipc_stream.h \
+ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \
+ $(srcdir)/../common/cci_common.h $(srcdir)/../common/cci_cred_union.h \
+ $(srcdir)/../common/cci_debugging.h $(srcdir)/../common/cci_identifier.h \
+ $(srcdir)/../common/cci_message.h $(srcdir)/../common/cci_types.h \
+ ccapi_string.c ccapi_string.h
+ccapi_v2.so ccapi_v2.po $(OUTPRE)ccapi_v2.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(COM_ERR_DEPS) $(top_srcdir)/include/CredentialsCache.h \
+ $(top_srcdir)/include/CredentialsCache2.h $(top_srcdir)/include/k5-ipc_stream.h \
+ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \
+ $(srcdir)/../common/cci_common.h $(srcdir)/../common/cci_cred_union.h \
+ $(srcdir)/../common/cci_debugging.h $(srcdir)/../common/cci_identifier.h \
+ $(srcdir)/../common/cci_message.h $(srcdir)/../common/cci_types.h \
+ ccapi_ccache.h ccapi_ccache_iterator.h ccapi_context.h \
+ ccapi_credentials.h ccapi_credentials_iterator.h ccapi_string.h \
+ ccapi_v2.c
diff --git a/src/ccapi/lib/libkrb5-ccapi.exports b/src/ccapi/lib/libkrb5-ccapi.exports
new file mode 100644
index 000000000000..1a8560f0bc70
--- /dev/null
+++ b/src/ccapi/lib/libkrb5-ccapi.exports
@@ -0,0 +1 @@
+cc_close
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 000000000000..d6b9a6caecc8
--- /dev/null
+++ b/src/ccapi/lib/mac/ccapi_os_ipc.c
@@ -0,0 +1,50 @@
+/* ccapi/lib/mac/ccapi_os_ipc.c */
+/*
+ * 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 "k5_mig_client.h"
+
+#define cci_server_bundle_id "edu.mit.Kerberos.CCacheServer"
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 cci_os_ipc_thread_init (void)
+{
+ /* k5_ipc_send_request handles all thread data for us */
+ return 0;
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 cci_os_ipc (cc_int32 in_launch_server,
+ k5_ipc_stream in_request_stream,
+ k5_ipc_stream *out_reply_stream)
+{
+ return cci_check_error (k5_ipc_send_request (cci_server_bundle_id,
+ in_launch_server,
+ in_request_stream,
+ out_reply_stream));
+}
diff --git a/src/ccapi/lib/mac/ccapi_vector.c b/src/ccapi/lib/mac/ccapi_vector.c
new file mode 100644
index 000000000000..155599d81a34
--- /dev/null
+++ b/src/ccapi/lib/mac/ccapi_vector.c
@@ -0,0 +1,838 @@
+/* ccapi/lib/mac/ccapi_vector.c */
+/*
+ * 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 000000000000..0f02e4148f9a
--- /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 000000000000..803257cdcdf3
--- /dev/null
+++ b/src/ccapi/lib/mac/ccapi_vector.h
@@ -0,0 +1,227 @@
+/* ccapi/lib/mac/ccapi_vector.h */
+/*
+ * 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);
diff --git a/src/ccapi/lib/unix/Makefile.in b/src/ccapi/lib/unix/Makefile.in
new file mode 100644
index 000000000000..ce47d65d9277
--- /dev/null
+++ b/src/ccapi/lib/unix/Makefile.in
@@ -0,0 +1,12 @@
+mydir=ccapi$(S)lib$(S)unix
+BUILDTOP=$(REL)..$(S)..$(S)..
+LOCALINCLUDES= -I$(srcdir)/.. -I$(srcdir)/../../common
+
+STLIBOBJS= stubs.o
+OBJS= $(OUTPRE)stubs.$(OBJEXT)
+
+all-unix: all-libobjs
+clean-unix:: clean-libobjs
+
+@libobj_frag@
+
diff --git a/src/ccapi/lib/unix/deps b/src/ccapi/lib/unix/deps
new file mode 100644
index 000000000000..2feac3c9d388
--- /dev/null
+++ b/src/ccapi/lib/unix/deps
@@ -0,0 +1 @@
+# No dependencies here.
diff --git a/src/ccapi/lib/unix/stubs.c b/src/ccapi/lib/unix/stubs.c
new file mode 100644
index 000000000000..3afd8f10eeb0
--- /dev/null
+++ b/src/ccapi/lib/unix/stubs.c
@@ -0,0 +1,10 @@
+#include <errno.h>
+#include "ccapi_os_ipc.h"
+
+cc_int32 cci_os_ipc_thread_init (void)
+{
+ return EINVAL;
+}
+void cci_os_ipc_thread_fini (void)
+{
+}
diff --git a/src/ccapi/lib/win/Makefile.in b/src/ccapi/lib/win/Makefile.in
new file mode 100644
index 000000000000..45676092ed33
--- /dev/null
+++ b/src/ccapi/lib/win/Makefile.in
@@ -0,0 +1,123 @@
+# makefile: Constructs the Kerberos for Windows CCAPI DLL.
+#
+OBJS = $(OUTPRE)ccapi_ccache.obj \
+ $(OUTPRE)ccapi_ccache_iterator.obj \
+ $(OUTPRE)ccapi_context.obj \
+ $(OUTPRE)ccapi_context_change_time.obj \
+ $(OUTPRE)ccapi_credentials.obj \
+ $(OUTPRE)ccapi_credentials_iterator.obj \
+ $(OUTPRE)ccapi_ipc.obj \
+ $(OUTPRE)ccapi_err.obj \
+ $(OUTPRE)ccapi_os_ipc.obj \
+ $(OUTPRE)ccapi_string.obj \
+ $(OUTPRE)ccapi_v2.obj \
+ $(OUTPRE)cci_array_internal.obj \
+ $(OUTPRE)cci_cred_union.obj \
+ $(OUTPRE)cci_debugging.obj \
+ $(OUTPRE)cci_identifier.obj \
+ $(OUTPRE)cci_message.obj \
+ $(OUTPRE)cci_os_debugging.obj \
+ $(OUTPRE)cci_os_identifier.obj \
+ $(OUTPRE)ccs_reply_proc.obj \
+ $(OUTPRE)ccs_reply_s.obj \
+ $(OUTPRE)ccs_request_c.obj \
+ $(OUTPRE)ccutils.obj \
+ $(OUTPRE)client.obj \
+ $(OUTPRE)dllmain.obj \
+ $(OUTPRE)init.obj \
+ $(OUTPRE)secure.obj \
+ $(OUTPRE)tls.obj \
+ $(OUTPRE)util.obj \
+ $(OUTPRE)win-utils.obj
+
+##### Options
+# Set NODEBUG if building release instead of debug
+
+#BUILDTOP is krb5/src and is relative to krb5/src/ccapi/lib/win, for making Makefile.
+BUILDTOP= ..\..\..
+CCAPI = $(BUILDTOP)\CCAPI
+CO = $(CCAPI)\common
+COWIN = $(CCAPI)\common\win
+CCUTIL = $(CCAPI)\common\win\OldCC
+LIBDIR = $(CCAPI)\lib
+LIBWIN = $(LIBDIR)\win
+POSIX = $(BUILDTOP)\lib\krb5\posix
+OLDCC = $(LIBWIN)\OldCC
+SRCTMP = $(LIBWIN)\srctmp
+
+!if defined(KRB5_KFW_COMPILE)
+KFWINC= /I$(BUILDTOP)\..\..\krbcc\include
+!endif
+
+# Because all the sources are pulled together into the temp directory SRCTMP,
+# the only includes we need are to directories outside of ccapi.
+LOCALINCLUDES = /I..\$(BUILDTOP) /I..\$(BUILDTOP)\include /I..\$(BUILDTOP)\include\krb5 $(KFWINC) \
+ -I..\$(BUILDTOP)\util\et
+MIDLINCLUDES = /I..\$(BUILDTOP)\include
+
+CPPFLAGS = $(CPPFLAGS) /EHsc -D_CRTAPI1=_cdecl -D_CRTAPI2=_cdecl -DWINVER=0x0501 \
+-D_WIN32_WINNT=0x0501 -D_CRT_SECURE_NO_WARNINGS $(cvarsdll)
+
+
+##### Linker
+LINK = link
+LIBS = ..\$(CLIB) ..\$(SLIB) kernel32.lib ws2_32.lib user32.lib advapi32.lib
+LFLAGS = /nologo $(LOPTS)
+
+all: Makefile copysrc midl $(OUTPRE)$(CCLIB).dll finish
+
+ccs_request.h ccs_request_c.c ccs_request_s.c : ccs_request.idl ccs_request.acf
+ midl $(MIDL_OPTIMIZATION) $(MIDLI) -oldnames -cpp_cmd $(CC) -cpp_opt "-E" \
+ ccs_request.idl
+
+ccs_reply.h ccs_reply_c.c ccs_reply_s.c : ccs_reply.idl ccs_reply.acf
+ midl $(MIDL_OPTIMIZATION) $(MIDLI) -oldnames -cpp_cmd $(CC) -cpp_opt "-E" \
+ ccs_reply.idl
+
+copysrc :
+ echo "Copying all sources needed to build $(CCLIB).dll to $(SRCTMP)"
+ if NOT exist $(SRCTMP)\nul mkdir $(SRCTMP)
+ xcopy /D/Y $(CO)\*.* $(SRCTMP)
+ xcopy /D/Y $(COWIN)\*.* $(SRCTMP)
+ xcopy /D/Y $(CCUTIL)\*.* $(SRCTMP)
+ xcopy /D/Y $(LIBDIR)\*.* $(SRCTMP)
+ xcopy /D/Y $(LIBWIN)\*.* $(SRCTMP)
+ xcopy /D/Y $(OLDCC)\*.* $(SRCTMP)
+ cd $(SRCTMP)
+ if NOT exist $(OUTPRE)\nul mkdir $(OUTPRE)
+
+midl : ccs_request.h ccs_reply.h
+
+VERSIONRC = $(BUILDTOP)\..\windows\version.rc
+CCLIBRES = $(OUTPRE)$(CCLIB).res
+# Main program:
+$(CCLIBRES): $(VERSIONRC)
+ $(RC) $(RCFLAGS) -DCCAPI_LIB -fo $@ -r $**
+
+$(OUTPRE)$(CCLIB).dll: $(OBJS) $(CCLIB).def $(CCLIBRES)
+ $(LINK) $(LFLAGS) -entry:$(ENTRYPOINT) -dll /map:$*.map /out:$@ /DEF:$(CCLIB).def $(OBJS) \
+ /implib:$(CCLIB).lib $(dllflags) $(LIBS) $(KFWLIB) $(SCLIB) $(CCLIBRES) rpcrt4.lib $(conlibsdll) $(conflags)
+
+$(CCLIB).def:
+ echo ;$(CCLIB).def is generated by a Makefile rule. > $(CCLIB).def
+ echo HEAPSIZE 8192 >> $(CCLIB).def
+ echo EXPORTS >> $(CCLIB).def
+ type ccapi.exports >> $(CCLIB).def
+ type ccapi_v2.exports >> $(CCLIB).def
+ type debug.exports >> $(CCLIB).def
+
+finish:
+ echo "Finished in ccapi/lib/win."
+ cd ..
+
+install:
+ echo "Doing nothing for make install"
+
+clean:
+ if exist $(OUTPRE)*.exe del $(OUTPRE)*.exe
+ if exist $(OUTPRE)*.obj del $(OUTPRE)*.obj
+ if exist $(OUTPRE)*.res del $(OUTPRE)*.res
+ if exist $(OUTPRE)*.map del $(OUTPRE)*.map
+ if exist $(OUTPRE)*.pdb del $(OUTPRE)*.pdb
+ if exist *.err del *.err
+ if exist $(SRCTMP) rmdir /s /q $(SRCTMP)
diff --git a/src/ccapi/lib/win/OldCC/ccapi.h b/src/ccapi/lib/win/OldCC/ccapi.h
new file mode 100644
index 000000000000..82512771a85e
--- /dev/null
+++ b/src/ccapi/lib/win/OldCC/ccapi.h
@@ -0,0 +1,280 @@
+/* this ALWAYS GENERATED file contains the definitions for the interfaces */
+
+
+ /* File created by MIDL compiler version 6.00.0366 */
+/* at Fri Nov 30 10:06:16 2007
+ */
+/* Compiler settings for ccapi.idl:
+ Oic, W1, Zp8, env=Win32 (32b run)
+ protocol : dce , ms_ext, c_ext, oldnames
+ error checks: allocation ref bounds_check enum stub_data
+ VC __declspec() decoration level:
+ __declspec(uuid()), __declspec(selectany), __declspec(novtable)
+ DECLSPEC_UUID(), MIDL_INTERFACE()
+*/
+//@@MIDL_FILE_HEADING( )
+
+#pragma warning( disable: 4049 ) /* more than 64k source lines */
+
+
+/* verify that the <rpcndr.h> version is high enough to compile this file*/
+#ifndef __REQUIRED_RPCNDR_H_VERSION__
+#define __REQUIRED_RPCNDR_H_VERSION__ 440
+#endif
+
+#include "rpc.h"
+#include "rpcndr.h"
+
+#ifndef __ccapi_h__
+#define __ccapi_h__
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once
+#endif
+
+/* Forward Declarations */
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+void * __RPC_USER MIDL_user_allocate(size_t);
+void __RPC_USER MIDL_user_free( void * );
+
+#ifndef __ccapi_INTERFACE_DEFINED__
+#define __ccapi_INTERFACE_DEFINED__
+
+/* interface ccapi */
+/* [implicit_handle][unique][version][uuid] */
+
+typedef /* [context_handle] */ struct opaque_handle_CTX *HCTX;
+
+typedef /* [context_handle] */ struct opaque_handle_CACHE *HCACHE;
+
+typedef /* [context_handle] */ struct opaque_handle_CACHE_ITER *HCACHE_ITER;
+
+typedef /* [context_handle] */ struct opaque_handle_CRED_ITER *HCRED_ITER;
+
+typedef unsigned char CC_CHAR;
+
+typedef unsigned char CC_UCHAR;
+
+typedef int CC_INT32;
+
+typedef unsigned int CC_UINT32;
+
+typedef CC_INT32 CC_TIME_T;
+
+
+enum __MIDL_ccapi_0001
+ { STK_AFS = 0,
+ STK_DES = 1
+ } ;
+
+enum __MIDL_ccapi_0002
+ { CC_API_VER_1 = 1,
+ CC_API_VER_2 = 2
+ } ;
+
+enum __MIDL_ccapi_0003
+ { KRB_NAME_SZ = 40,
+ KRB_INSTANCE_SZ = 40,
+ KRB_REALM_SZ = 40,
+ MAX_V4_CRED_LEN = 1250
+ } ;
+typedef struct _NC_INFO
+ {
+ /* [string] */ CC_CHAR *name;
+ /* [string] */ CC_CHAR *principal;
+ CC_INT32 vers;
+ } NC_INFO;
+
+typedef struct _NC_INFO_LIST
+ {
+ CC_UINT32 length;
+ /* [size_is] */ NC_INFO *info;
+ } NC_INFO_LIST;
+
+typedef struct _V4_CRED
+ {
+ CC_UCHAR kversion;
+ CC_CHAR principal[ 41 ];
+ CC_CHAR principal_instance[ 41 ];
+ CC_CHAR service[ 41 ];
+ CC_CHAR service_instance[ 41 ];
+ CC_CHAR realm[ 41 ];
+ CC_UCHAR session_key[ 8 ];
+ CC_INT32 kvno;
+ CC_INT32 str_to_key;
+ CC_INT32 issue_date;
+ CC_INT32 lifetime;
+ CC_UINT32 address;
+ CC_INT32 ticket_sz;
+ CC_UCHAR ticket[ 1250 ];
+ } V4_CRED;
+
+typedef struct _CC_DATA
+ {
+ CC_UINT32 type;
+ CC_UINT32 length;
+ /* [size_is] */ CC_UCHAR *data;
+ } CC_DATA;
+
+typedef struct _CC_DATA_LIST
+ {
+ CC_UINT32 count;
+ /* [size_is] */ CC_DATA *data;
+ } CC_DATA_LIST;
+
+typedef struct _V5_CRED
+ {
+ /* [string] */ CC_CHAR *client;
+ /* [string] */ CC_CHAR *server;
+ CC_DATA keyblock;
+ CC_TIME_T authtime;
+ CC_TIME_T starttime;
+ CC_TIME_T endtime;
+ CC_TIME_T renew_till;
+ CC_UINT32 is_skey;
+ CC_UINT32 ticket_flags;
+ CC_DATA_LIST addresses;
+ CC_DATA ticket;
+ CC_DATA second_ticket;
+ CC_DATA_LIST authdata;
+ } V5_CRED;
+
+typedef /* [switch_type] */ union _CRED_PTR_UNION
+ {
+ /* [case()] */ V4_CRED *pV4Cred;
+ /* [case()] */ V5_CRED *pV5Cred;
+ } CRED_PTR_UNION;
+
+typedef struct _CRED_UNION
+ {
+ CC_INT32 cred_type;
+ /* [switch_is] */ CRED_PTR_UNION cred;
+ } CRED_UNION;
+
+CC_INT32 rcc_initialize(
+ /* [out] */ HCTX *pctx);
+
+CC_INT32 rcc_shutdown(
+ /* [out][in] */ HCTX *pctx);
+
+CC_INT32 rcc_get_change_time(
+ /* [in] */ HCTX ctx,
+ /* [out] */ CC_TIME_T *time);
+
+CC_INT32 rcc_create(
+ /* [in] */ HCTX ctx,
+ /* [string][in] */ const CC_CHAR *name,
+ /* [string][in] */ const CC_CHAR *principal,
+ /* [in] */ CC_INT32 vers,
+ /* [in] */ CC_UINT32 flags,
+ /* [out] */ HCACHE *pcache);
+
+CC_INT32 rcc_open(
+ /* [in] */ HCTX ctx,
+ /* [string][in] */ const CC_CHAR *name,
+ /* [in] */ CC_INT32 vers,
+ /* [in] */ CC_UINT32 flags,
+ /* [out] */ HCACHE *pcache);
+
+CC_INT32 rcc_close(
+ /* [out][in] */ HCACHE *pcache);
+
+CC_INT32 rcc_destroy(
+ /* [out][in] */ HCACHE *pcache);
+
+CC_INT32 rcc_seq_fetch_NCs_begin(
+ /* [in] */ HCTX ctx,
+ /* [out] */ HCACHE_ITER *piter);
+
+CC_INT32 rcc_seq_fetch_NCs_end(
+ /* [out][in] */ HCACHE_ITER *piter);
+
+CC_INT32 rcc_seq_fetch_NCs_next(
+ /* [in] */ HCACHE_ITER iter,
+ /* [out] */ HCACHE *pcache);
+
+CC_INT32 rcc_seq_fetch_NCs(
+ /* [in] */ HCTX ctx,
+ /* [out][in] */ HCACHE_ITER *piter,
+ /* [out] */ HCACHE *pcache);
+
+CC_INT32 rcc_get_NC_info(
+ /* [in] */ HCTX ctx,
+ /* [out] */ NC_INFO_LIST **info_list);
+
+CC_INT32 rcc_get_name(
+ /* [in] */ HCACHE cache,
+ /* [string][out] */ CC_CHAR **name);
+
+CC_INT32 rcc_set_principal(
+ /* [in] */ HCACHE cache,
+ /* [in] */ CC_INT32 vers,
+ /* [string][in] */ const CC_CHAR *principal);
+
+CC_INT32 rcc_get_principal(
+ /* [in] */ HCACHE cache,
+ /* [string][out] */ CC_CHAR **principal);
+
+CC_INT32 rcc_get_cred_version(
+ /* [in] */ HCACHE cache,
+ /* [out] */ CC_INT32 *vers);
+
+CC_INT32 rcc_lock_request(
+ /* [in] */ HCACHE cache,
+ /* [in] */ CC_INT32 lock_type);
+
+CC_INT32 rcc_store(
+ /* [in] */ HCACHE cache,
+ /* [in] */ CRED_UNION cred);
+
+CC_INT32 rcc_remove_cred(
+ /* [in] */ HCACHE cache,
+ /* [in] */ CRED_UNION cred);
+
+CC_INT32 rcc_seq_fetch_creds(
+ /* [in] */ HCACHE cache,
+ /* [out][in] */ HCRED_ITER *piter,
+ /* [out] */ CRED_UNION **cred);
+
+CC_INT32 rcc_seq_fetch_creds_begin(
+ /* [in] */ HCACHE cache,
+ /* [out] */ HCRED_ITER *piter);
+
+CC_INT32 rcc_seq_fetch_creds_end(
+ /* [out][in] */ HCRED_ITER *piter);
+
+CC_INT32 rcc_seq_fetch_creds_next(
+ /* [in] */ HCRED_ITER iter,
+ /* [out] */ CRED_UNION **cred);
+
+CC_UINT32 Connect(
+ /* [string][in] */ CC_CHAR *name);
+
+void Shutdown( void);
+
+
+extern handle_t ccapi_IfHandle;
+
+
+extern RPC_IF_HANDLE ccapi_ClientIfHandle;
+extern RPC_IF_HANDLE ccapi_ServerIfHandle;
+#endif /* __ccapi_INTERFACE_DEFINED__ */
+
+/* Additional Prototypes for ALL interfaces */
+
+void __RPC_USER HCTX_rundown( HCTX );
+void __RPC_USER HCACHE_rundown( HCACHE );
+void __RPC_USER HCACHE_ITER_rundown( HCACHE_ITER );
+void __RPC_USER HCRED_ITER_rundown( HCRED_ITER );
+
+/* end of Additional Prototypes */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/ccapi/lib/win/OldCC/client.cxx b/src/ccapi/lib/win/OldCC/client.cxx
new file mode 100644
index 000000000000..4b2d718cc431
--- /dev/null
+++ b/src/ccapi/lib/win/OldCC/client.cxx
@@ -0,0 +1,427 @@
+/*
+ * $Header$
+ *
+ * Copyright 2008 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 "stdio.h" // KPKDBG
+
+#include "ccs_request.h"
+
+#include "ccapi.h"
+#include "util.h"
+
+extern "C" {
+#include "cci_debugging.h"
+#include "tls.h" // KPKDBG
+ }
+
+#include "client.h"
+#include "init.hxx"
+#include "name.h"
+#include "secure.hxx"
+
+#define SECONDS_TO_WAIT 10
+
+#define STARTUP "CLIENT STARTUP: "
+#define DISCONNECT "CLIENT DISCONNECT: "
+
+bool Client::s_init = false;
+CcOsLock Client::sLock;
+
+static DWORD bind_client(char* ep OPTIONAL, Init::InitInfo& info, LPSTR* endpoint) {
+ DWORD status = 0;
+ unsigned char * pszStringBinding = NULL;
+
+ if (!ep) {
+ status = alloc_name(endpoint, "ep", isNT());
+ }
+ else {
+ *endpoint = ep;
+ }
+
+ if (!status) {
+ /* Use a convenience function to concatenate the elements of */
+ /* the string binding into the proper sequence. */
+ status = RpcStringBindingCompose(0, // uuid
+ (unsigned char*)"ncalrpc", // protseq
+ 0, // address
+ (unsigned char*)(*endpoint), // endpoint
+ 0, // options
+ &pszStringBinding);
+ cci_check_error(status);
+ }
+
+ if (!status) {
+ /* Set the binding handle that will be used to bind to the server. */
+ status = RpcBindingFromStringBinding(pszStringBinding, &ccs_request_IfHandle);
+ cci_check_error(status);
+ }
+
+ if (!status) {
+ // Win9x might call RpcBindingSetAuthInfo (not Ex), but it does not
+ // quite work on Win9x...
+ if (isNT()) {
+ RPC_SECURITY_QOS qos;
+ qos.Version = RPC_C_SECURITY_QOS_VERSION;
+ qos.Capabilities = RPC_C_QOS_CAPABILITIES_DEFAULT;
+ qos.IdentityTracking = RPC_C_QOS_IDENTITY_STATIC;
+ qos.ImpersonationType = RPC_C_IMP_LEVEL_IDENTIFY;
+
+ status = info.fRpcBindingSetAuthInfoEx(ccs_request_IfHandle,
+ 0, // principal
+ RPC_C_AUTHN_LEVEL_CONNECT,
+ RPC_C_AUTHN_WINNT,
+ 0, // current address space
+ RPC_C_AUTHZ_NAME,
+ &qos);
+ cci_check_error(status);
+ }
+ }
+
+ if (pszStringBinding) {
+ DWORD status = RpcStringFree(&pszStringBinding);
+ cci_check_error(status);
+ }
+ return cci_check_error(status);
+ }
+
+DWORD find_server(Init::InitInfo& info, LPSTR endpoint) {
+ DWORD status = 0;
+ LPSTR event_name = 0;
+ HANDLE hEvent = 0;
+ SECURITY_ATTRIBUTES sa = { 0 };
+ PSECURITY_ATTRIBUTES psa = 0;
+ STARTUPINFO si = { 0 };
+ PROCESS_INFORMATION pi = { 0 };
+ char* szExe = 0;
+ char* szDir = 0;
+ BOOL bRes = FALSE;
+ char* cmdline = NULL;
+#if 0
+ HANDLE hToken = 0;
+#endif
+
+ psa = isNT() ? &sa : 0;
+
+ cci_debug_printf("%s Looking for server; ccs_request_IfHandle:0x%X", __FUNCTION__, ccs_request_IfHandle);
+ status = cci_check_error(RpcMgmtIsServerListening(ccs_request_IfHandle));
+ if (status == RPC_S_NOT_LISTENING) {
+ cci_debug_printf(" Server *NOT* found!");
+ si.cb = sizeof(si);
+
+ status = alloc_module_dir_name(CCAPI_DLL, &szDir);
+
+ if (!status) {
+ status = alloc_module_dir_name_with_file(CCAPI_DLL, CCAPI_EXE, &szExe);
+ }
+
+ if (!status) {
+ status = alloc_name(&event_name, "startup", isNT());
+ cci_check_error(status);
+ }
+
+ if (!status) {
+ if (isNT()) {
+ sa.nLength = sizeof(sa);
+ status = alloc_own_security_descriptor_NT(&sa.lpSecurityDescriptor);
+ cci_check_error(status);
+ }
+ }
+
+ if (!status) {
+ hEvent = CreateEvent(psa, FALSE, FALSE, event_name);
+ cci_debug_printf(" CreateEvent(... %s) returned hEvent 0x%X", event_name, hEvent);
+ if (!hEvent) status = GetLastError();
+ }
+
+ if (!status) {
+
+#if 0
+ if (SecureClient::IsImp()) {
+ cci_debug_printf(STARTUP "Token is impersonation token"));
+ SecureClient::DuplicateImpAsPrimary(hToken);
+ }
+ else {
+ cci_debug_printf(STARTUP "Token is NOT impersonation token"));
+ }
+#endif
+
+#if 0
+ if (hToken)
+ bRes = CreateProcessAsUser(hToken,
+ szExe, // app name
+ NULL, // cmd line
+ psa, // SA
+ psa, // SA
+ FALSE,
+ CREATE_NEW_PROCESS_GROUP |
+ //CREATE_NEW_CONSOLE |
+ NORMAL_PRIORITY_CLASS |
+ // CREATE_NO_WINDOW |
+ DETACHED_PROCESS |
+ 0
+ ,
+ NULL, // environment
+ szDir, // current dir
+ &si,
+ &pi);
+ else
+#endif
+ alloc_cmdline_2_args(szExe, endpoint, "-D", &cmdline);
+ bRes = CreateProcess( szExe, // app name
+ NULL, //cmdline, // cmd line is <server endpoint -[DC]>
+ psa, // SA
+ psa, // SA
+ FALSE,
+ CREATE_NEW_PROCESS_GROUP |
+ NORMAL_PRIORITY_CLASS |
+#ifdef CCAPI_LAUNCH_SERVER_WITH_CONSOLE
+ CREATE_NEW_CONSOLE |
+#else
+ DETACHED_PROCESS |
+#endif
+ 0,
+ NULL, // environment
+ szDir, // current dir
+ &si,
+ &pi);
+ if (!bRes) {
+ status = GetLastError();
+ cci_debug_printf(" CreateProcess returned %d; LastError: %d", bRes, status);
+ }
+ cci_debug_printf(" Waiting...");
+ }
+ cci_check_error(status);
+
+ if (!status) {
+ status = WaitForSingleObject(hEvent, (SECONDS_TO_WAIT)*1000);
+ status = RpcMgmtIsServerListening(ccs_request_IfHandle);
+ }
+ }
+ else if (status) {
+ cci_debug_printf(" unexpected error while looking for server: 0D%d / 0U%u / 0X%X", status, status, status);
+ }
+
+#if 0
+ if (hToken)
+ CloseHandle(hToken);
+#endif
+ if (szDir) free_alloc_p(&szDir);
+ if (szExe) free_alloc_p(&szExe);
+ if (hEvent) CloseHandle(hEvent);
+ if (pi.hThread) CloseHandle(pi.hThread);
+ if (pi.hProcess) CloseHandle(pi.hProcess);
+ if (sa.lpSecurityDescriptor) free_alloc_p(&sa.lpSecurityDescriptor);
+ return cci_check_error(status);
+
+}
+
+static
+DWORD
+make_random_challenge(DWORD *challenge_out) {
+ HCRYPTPROV provider;
+ DWORD status = 0;
+ *challenge_out = 0;
+ if (!CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL,
+ CRYPT_VERIFYCONTEXT)) {
+ status = GetLastError();
+ cci_check_error(status);
+ return status;
+ }
+ if (!CryptGenRandom(provider, sizeof(*challenge_out),
+ (BYTE *)challenge_out)) {
+ status = GetLastError();
+ cci_check_error(status);
+ return status;
+ }
+ if (!CryptReleaseContext(provider, 0)) {
+ /*
+ * Note: even though CryptReleaseContext() failed, we don't really
+ * care since a) we've already successfully obtained our challenge
+ * anyway and b) at least one of the potential errors, "ERROR_BUSY"
+ * does not really seem to be an error at all. So GetLastError() is
+ * logged for informational purposes only and should not be returned.
+ */
+ cci_check_error(GetLastError());
+ }
+ return status;
+}
+
+static
+DWORD
+authenticate_server(Init::InitInfo& info) {
+ DWORD challenge, desired_response;
+ HANDLE hMap = 0;
+ LPSTR mem_name = 0;
+ PDWORD pvalue = 0;
+ CC_UINT32 response = 0;
+ SECURITY_ATTRIBUTES sa = { 0 };
+ DWORD status = 0;
+
+ cci_debug_printf("%s entry", __FUNCTION__);
+
+ status = alloc_name(&mem_name, "auth", isNT());
+ cci_check_error(status);
+
+ if (!status) {
+ status = make_random_challenge(&challenge);
+ desired_response = challenge + 1;
+ cci_check_error(status);
+ }
+
+ if (!status) {
+ if (isNT()) {
+ sa.nLength = sizeof(sa);
+ status = alloc_own_security_descriptor_NT(&sa.lpSecurityDescriptor);
+ }
+ }
+ cci_check_error(status);
+
+ if (!status) {
+ hMap = CreateFileMapping(INVALID_HANDLE_VALUE, isNT() ? &sa : 0,
+ PAGE_READWRITE, 0, sizeof(DWORD), mem_name);
+ if (!hMap)
+ status = GetLastError();
+ }
+ cci_check_error(status);
+
+ if (!status) {
+ pvalue = (PDWORD)MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
+ if (!pvalue) status = GetLastError();
+ }
+ cci_check_error(status);
+
+ if (!status) {
+ *pvalue = challenge;
+
+ RpcTryExcept {
+ response = ccs_authenticate( (CC_CHAR*)mem_name );
+ }
+ RpcExcept(1) {
+ status = RpcExceptionCode();
+ cci_check_error(status);
+ }
+ RpcEndExcept;
+ }
+ cci_check_error(status);
+
+ if (!status) {
+ // Check response
+ if ((response != desired_response) && (*pvalue != desired_response)) {
+ cci_debug_printf(" Could not authenticate server.");
+ status = ERROR_ACCESS_DENIED; // XXX - CO_E_NOMATCHINGSIDFOUND?
+ }
+ else {
+ cci_debug_printf(" Server authenticated!");
+ }
+ cci_check_error(status);
+ }
+
+ free_alloc_p(&mem_name);
+ free_alloc_p(&sa.lpSecurityDescriptor);
+ if (pvalue) {
+ BOOL ok = UnmapViewOfFile(pvalue);
+// DEBUG_ASSERT(ok);
+ }
+ if (hMap) CloseHandle(hMap);
+ return status;
+}
+
+DWORD
+Client::Disconnect() {
+ DWORD status = 0;
+ if (ccs_request_IfHandle) {
+ /* The calls to the remote procedures are complete. */
+ /* Free the binding handle */
+ status = RpcBindingFree(&ccs_request_IfHandle);
+ }
+ s_init = false;
+ return status;
+ }
+
+DWORD
+Client::Connect(char* ep OPTIONAL) {
+ LPSTR endpoint = 0;
+ DWORD status = 0;
+
+ if (!ccs_request_IfHandle) {
+ Init::InitInfo info;
+
+ status = Init::Info(info);
+ cci_check_error(status);
+
+ if (!status) {
+ status = bind_client(ep, info, &endpoint);
+ cci_check_error(status);
+ }
+
+ if (!status) {
+ status = find_server(info, endpoint);
+ cci_check_error(status);
+ }
+
+ if (!status) {
+ status = authenticate_server(info);
+ cci_check_error(status);
+ }
+ }
+
+
+ if (endpoint && (endpoint != ep)) free_alloc_p(&endpoint);
+
+ if (status) Client::Disconnect();
+ return status;
+ }
+
+DWORD Client::Initialize(char* ep OPTIONAL) {
+ CcAutoTryLock AL(Client::sLock);
+ if (!AL.IsLocked() || s_init)
+ return 0;
+ SecureClient s;
+ ccs_request_IfHandle = NULL;
+ DWORD status = Client::Connect(ep);
+ if (!status) s_init = true;
+ return status;
+ }
+
+DWORD Client::Cleanup() {
+ CcAutoLock AL(Client::sLock);
+ SecureClient s;
+ return Client::Disconnect();
+ }
+
+DWORD Client::Reconnect(char* ep OPTIONAL) {
+ CcAutoLock AL(Client::sLock);
+ SecureClient s;
+ DWORD status = 0;
+
+ if (Initialized()) {
+ DWORD status = Client::Cleanup();
+ }
+ if ( (!status) ) {
+ status = Client::Initialize(ep);
+ }
+
+ return status;
+ }
diff --git a/src/ccapi/lib/win/OldCC/client.h b/src/ccapi/lib/win/OldCC/client.h
new file mode 100644
index 000000000000..1c67acd147b1
--- /dev/null
+++ b/src/ccapi/lib/win/OldCC/client.h
@@ -0,0 +1,60 @@
+/* ccapi/lib/win/OldCC/client.h */
+/*
+ * Copyright 2008 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 __DLL_CLIENT_H__
+#define __DLL_CLIENT_H__
+
+#include "autolock.hxx"
+#include "init.hxx"
+
+class Client {
+public:
+ static DWORD Initialize(char* ep OPTIONAL);
+ static DWORD Cleanup();
+ static DWORD Reconnect(char* ep OPTIONAL);
+
+ static bool Initialized() { return s_init; }
+
+ static CcOsLock sLock;
+
+private:
+ static bool s_init;
+
+ static DWORD Disconnect();
+ static DWORD Connect(char* ep OPTIONAL);
+ };
+
+#define CLIENT_INIT_EX(trap, error) \
+do \
+{ \
+ INIT_INIT_EX(trap, error); \
+ if (!Client::Initialized()) \
+ { \
+ DWORD status = Client::Initialize(0); \
+ if (status) return (trap) ? (error) : status; \
+ } \
+} while(0)
+
+#endif
diff --git a/src/ccapi/lib/win/WINCCAPI.sln b/src/ccapi/lib/win/WINCCAPI.sln
new file mode 100644
index 000000000000..cee989151932
--- /dev/null
+++ b/src/ccapi/lib/win/WINCCAPI.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WINCCAPI", "WINCCAPI.vcproj", "{1137FC16-E53E-48C1-8293-085B4BE68C32}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {1137FC16-E53E-48C1-8293-085B4BE68C32}.Debug|Win32.ActiveCfg = Debug|Win32
+ {1137FC16-E53E-48C1-8293-085B4BE68C32}.Debug|Win32.Build.0 = Debug|Win32
+ {1137FC16-E53E-48C1-8293-085B4BE68C32}.Release|Win32.ActiveCfg = Release|Win32
+ {1137FC16-E53E-48C1-8293-085B4BE68C32}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/src/ccapi/lib/win/WINCCAPI.vcproj b/src/ccapi/lib/win/WINCCAPI.vcproj
new file mode 100644
index 000000000000..9af0e21a0b91
--- /dev/null
+++ b/src/ccapi/lib/win/WINCCAPI.vcproj
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="WINCCAPI"
+ ProjectGUID="{1137FC16-E53E-48C1-8293-085B4BE68C32}"
+ RootNamespace="WINCCAPI"
+ Keyword="MakeFileProj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="0"
+ >
+ <Tool
+ Name="VCNMakeTool"
+ BuildCommandLine="nmake"
+ ReBuildCommandLine="nmake"
+ CleanCommandLine="nmake clean"
+ Output="output.log"
+ PreprocessorDefinitions="WIN32;_DEBUG;"
+ IncludeSearchPath=""
+ ForcedIncludes=""
+ AssemblySearchPath=""
+ ForcedUsingAssemblies=""
+ CompileAsManaged=""
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="0"
+ >
+ <Tool
+ Name="VCNMakeTool"
+ BuildCommandLine="nmake"
+ ReBuildCommandLine="nmake"
+ CleanCommandLine="nmake clean"
+ Output="output.log"
+ PreprocessorDefinitions="WIN32;NDEBUG;"
+ IncludeSearchPath=""
+ ForcedIncludes=""
+ AssemblySearchPath=""
+ ForcedUsingAssemblies=""
+ CompileAsManaged=""
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\..\common\win\win-utils.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\common\win\ccs_reply.Idl"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\win\ccs_request.idl"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\win\win-utils.c"
+ >
+ </File>
+ </Filter>
+ <File
+ RelativePath="..\..\common\win\ccs_reply.Acf"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\win\ccs_request.Acf"
+ >
+ </File>
+ <File
+ RelativePath=".\Makefile"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/src/ccapi/lib/win/ccapi_os_ipc.cxx b/src/ccapi/lib/win/ccapi_os_ipc.cxx
new file mode 100644
index 000000000000..35589a54f881
--- /dev/null
+++ b/src/ccapi/lib/win/ccapi_os_ipc.cxx
@@ -0,0 +1,380 @@
+/*
+ * $Header$
+ *
+ * Copyright 2008 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.
+ */
+
+extern "C" {
+#include "k5-thread.h"
+#include "ccapi_os_ipc.h"
+#include "cci_debugging.h"
+#include "ccs_reply.h"
+#include "ccs_request.h"
+#include "ccutils.h"
+#include "tls.h"
+#include "util.h"
+#include "win-utils.h"
+ }
+
+#include "autolock.hxx"
+#include "CredentialsCache.h"
+#include "secure.hxx"
+#include "opts.hxx"
+#include "client.h"
+
+extern "C" DWORD GetTlsIndex();
+
+#define SECONDS_TO_WAIT 10
+#define CLIENT_REQUEST_RPC_HANDLE ccs_request_IfHandle
+
+extern HANDLE hCCAPIv2Mutex;
+ParseOpts::Opts opts = { 0 };
+PSECURITY_ATTRIBUTES psa = 0;
+SECURITY_ATTRIBUTES sa = { 0 };
+
+/* The layout of the rest of this module:
+
+ The entrypoints defined in ccs_os_ipc.h:
+ cci_os_ipc_thread_init
+ cci_os_ipc
+
+ Other routines needed by those four.
+ cci_os_connect
+ handle_exception
+ */
+
+cc_int32 ccapi_connect(const struct tspdata* tsp);
+static DWORD handle_exception(DWORD code, struct tspdata* ptspdata);
+
+extern "C" {
+cc_int32 cci_os_ipc_msg( cc_int32 in_launch_server,
+ k5_ipc_stream in_request_stream,
+ cc_int32 in_msg,
+ k5_ipc_stream* out_reply_stream);
+ }
+
+/* ------------------------------------------------------------------------ */
+
+extern "C" cc_int32 cci_os_ipc_process_init (void) {
+ RPC_STATUS status;
+
+ if (!isNT()) {
+ status = RpcServerRegisterIf(ccs_reply_ServerIfHandle, // interface
+ NULL, // MgrTypeUuid
+ NULL); // MgrEpv; null means use default
+ }
+ else {
+ status = RpcServerRegisterIfEx(ccs_reply_ServerIfHandle, // interface
+ NULL, // MgrTypeUuid
+ NULL, // MgrEpv; 0 means default
+ RPC_IF_ALLOW_SECURE_ONLY,
+ RPC_C_LISTEN_MAX_CALLS_DEFAULT,
+ NULL); // No security callback.
+ }
+ cci_check_error(status);
+
+ if (!status) {
+ status = RpcServerRegisterAuthInfo(0, // server principal
+ RPC_C_AUTHN_WINNT,
+ 0,
+ 0 );
+ cci_check_error(status);
+ }
+
+ return status; // ugh. needs translation
+}
+
+/* ------------------------------------------------------------------------ */
+
+extern "C" cc_int32 cci_os_ipc_thread_init (void) {
+ cc_int32 err = ccNoError;
+ struct tspdata* ptspdata;
+ HANDLE replyEvent = NULL;
+ UUID __RPC_FAR uuid;
+ RPC_CSTR __RPC_FAR uuidString = NULL;
+ char* endpoint = NULL;
+
+ if (!GetTspData(GetTlsIndex(), &ptspdata)) return ccErrNoMem;
+
+ err = cci_check_error(UuidCreate(&uuid)); // Get a UUID
+ if (err == RPC_S_OK) { // Convert to string
+ err = UuidToString(&uuid, &uuidString);
+ cci_check_error(err);
+ }
+ if (!err) { // Save in thread local storage
+ tspdata_setUUID(ptspdata, uuidString);
+ endpoint = clientEndpoint((const char *)uuidString);
+ err = RpcServerUseProtseqEp((RPC_CSTR)"ncalrpc",
+ RPC_C_PROTSEQ_MAX_REQS_DEFAULT,
+ (RPC_CSTR)endpoint,
+ sa.lpSecurityDescriptor); // SD
+ free(endpoint);
+ cci_check_error(err);
+ }
+
+#if 0
+ cci_debug_printf("%s UUID:<%s>", __FUNCTION__, tspdata_getUUID(ptspdata));
+#endif
+ // Initialize old CCAPI if necessary:
+ if (!err) if (!Init:: Initialized()) err = Init:: Initialize( );
+ if (!err) if (!Client::Initialized()) err = Client::Initialize(0);
+
+ if (!err) {
+ /* Whenever a reply to an RPC request is received, the RPC caller needs to
+ know when the reply has been received. It does that by waiting for a
+ client-specific event to be set. Define the event name to be <UUID>_reply: */
+ replyEvent = createThreadEvent((char*)uuidString, REPLY_SUFFIX);
+ }
+
+ if (!err) {
+ static bool bListening = false;
+ if (!bListening) {
+ err = RpcServerListen(1, RPC_C_LISTEN_MAX_CALLS_DEFAULT, TRUE);
+ cci_check_error(err);
+ }
+ bListening = err == 0;
+ }
+
+ if (replyEvent) tspdata_setReplyEvent(ptspdata, replyEvent);
+ else err = cci_check_error(GetLastError());
+
+ if (uuidString) RpcStringFree(&uuidString);
+
+ return cci_check_error(err);
+ }
+
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 cci_os_ipc (cc_int32 in_launch_server,
+ k5_ipc_stream in_request_stream,
+ k5_ipc_stream* out_reply_stream) {
+ return cci_os_ipc_msg( in_launch_server,
+ in_request_stream,
+ CCMSG_REQUEST,
+ out_reply_stream);
+ }
+
+extern "C" cc_int32 cci_os_ipc_msg( cc_int32 in_launch_server,
+ k5_ipc_stream in_request_stream,
+ cc_int32 in_msg,
+ k5_ipc_stream* out_reply_stream) {
+
+ cc_int32 err = ccNoError;
+ cc_int32 done = FALSE;
+ cc_int32 try_count = 0;
+ cc_int32 server_died = FALSE;
+ TCHAR* pszStringBinding= NULL;
+ struct tspdata* ptspdata = NULL;
+ char* uuid = NULL;
+ int lenUUID = 0;
+ unsigned int trycount = 0;
+ time_t sst = 0;
+ STARTUPINFO si = { 0 };
+ PROCESS_INFORMATION pi = { 0 };
+ HANDLE replyEvent = 0;
+ BOOL bCCAPI_Connected= FALSE;
+ BOOL bListening = FALSE;
+ unsigned char tspdata_handle[8] = { 0 };
+
+ if (!in_request_stream) { err = cci_check_error (ccErrBadParam); }
+ if (!out_reply_stream ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!GetTspData(GetTlsIndex(), &ptspdata)) {return ccErrBadParam;}
+ bListening = tspdata_getListening(ptspdata);
+ if (!bListening) {
+ err = cci_check_error(cci_os_ipc_thread_init());
+ bListening = !err;
+ tspdata_setListening(ptspdata, bListening);
+ }
+
+ bCCAPI_Connected = tspdata_getConnected (ptspdata);
+ replyEvent = tspdata_getReplyEvent (ptspdata);
+ sst = tspdata_getSST (ptspdata);
+ uuid = tspdata_getUUID(ptspdata);
+
+ // The lazy connection to the server has been put off as long as possible!
+ // ccapi_connect starts listening for replies as an RPC server and then
+ // calls ccs_rpc_connect.
+ if (!err && !bCCAPI_Connected) {
+ err = cci_check_error(ccapi_connect(ptspdata));
+ bCCAPI_Connected = !err;
+ tspdata_setConnected(ptspdata, bCCAPI_Connected);
+ }
+
+ // Clear replyEvent so we can detect when a reply to our request has been received:
+ ResetEvent(replyEvent);
+
+ //++ Use the old CCAPI implementation to try to talk to the server:
+ // It has all the code to use the RPC in a thread-safe way, make the endpoint,
+ // (re)connect and (re)start the server.
+ // Note: the old implementation wrapped the thread-safety stuff in a macro.
+ // Here it is expanded and thus duplicated for each RPC call. The new code has
+ // a very limited number of RPC calls, unlike the older code.
+ WaitForSingleObject( hCCAPIv2Mutex, INFINITE );
+ SecureClient* s = 0;
+ SecureClient::Start(s);
+ CcAutoLock* a = 0;
+ CcAutoLock::Start(a, Client::sLock);
+
+ // New code using new RPC procedures for sending the data and receiving a reply:
+ if (!err) {
+ RpcTryExcept {
+ if (!GetTspData(GetTlsIndex(), &ptspdata)) {return ccErrBadParam;}
+ uuid = tspdata_getUUID(ptspdata);
+ lenUUID = 1 + strlen(uuid); /* 1+ includes terminating \0. */
+#if 0
+ cci_debug_printf("%s calling remote ccs_rpc_request tsp*:0x%X", __FUNCTION__, ptspdata);
+ cci_debug_printf(" rpcmsg:%d; UUID[%d]:<%s> SST:%ld", in_msg, lenUUID, uuid, sst);
+#endif
+ /* copy ptr into handle; ptr may be 4 or 8 bytes, depending on platform; handle is always 8 */
+ memcpy(tspdata_handle, &ptspdata, sizeof(ptspdata));
+ ccs_rpc_request( /* make call with user message: */
+ in_msg, /* Message type */
+ tspdata_handle, /* Our tspdata* will be sent back to the reply proc. */
+ (unsigned char*)uuid,
+ krb5int_ipc_stream_size(in_request_stream),
+ (unsigned char*)krb5int_ipc_stream_data(in_request_stream), /* Data buffer */
+ sst, /* session start time */
+ (long*)(&err) ); /* Return code */
+ }
+ RpcExcept(1) {
+ err = handle_exception(RpcExceptionCode(), ptspdata);
+ }
+ RpcEndExcept;
+ }
+
+ cci_check_error(err);
+ CcAutoLock::Stop(a);
+ SecureClient::Stop(s);
+ ReleaseMutex(hCCAPIv2Mutex);
+ //-- Use the old CCAPI implementation to try to talk to the server.
+
+ // Wait for reply handler to set event:
+ if (!err) {
+ err = cci_check_error(WaitForSingleObject(replyEvent, INFINITE));//(SECONDS_TO_WAIT)*1000));
+ }
+
+ if (!err) {
+ err = cci_check_error(RpcMgmtIsServerListening(CLIENT_REQUEST_RPC_HANDLE));
+ }
+
+ if (!err && server_died) {
+ err = cci_check_error (ccErrServerUnavailable);
+ }
+#if 0
+ if (err == BOOTSTRAP_UNKNOWN_SERVICE && !in_launch_server) {
+ err = ccNoError; /* If the server is not running just return an empty stream. */
+ }
+#endif
+
+ if (!err) {
+ *out_reply_stream = tspdata_getStream(ptspdata);
+ }
+
+ return cci_check_error (err);
+ }
+
+
+
+static DWORD handle_exception(DWORD code, struct tspdata* ptspdata) {
+ cci_debug_printf("%s code %u; ccs_request_IfHandle:0x%X", __FUNCTION__, code, ccs_request_IfHandle);
+ if ( (code == RPC_S_SERVER_UNAVAILABLE) || (code == RPC_S_INVALID_BINDING) ) {
+ Client::Cleanup();
+ tspdata_setConnected(ptspdata, FALSE);
+ }
+ return code;
+ }
+
+
+/* Establish a CCAPI connection with the server.
+ * The connect logic here is identical to the logic in the send request code.
+ * TODO: merge this connect code with that request code.
+ */
+cc_int32 ccapi_connect(const struct tspdata* tsp) {
+ BOOL bListen = TRUE;
+ HANDLE replyEvent = 0;
+ RPC_STATUS status = FALSE;
+ char* uuid = NULL;
+ unsigned char tspdata_handle[8] = {0};
+
+ /* Start listening to our uuid before establishing the connection,
+ * so that when the server tries to call ccapi_listen, we will be ready.
+ */
+
+ /* Build complete RPC uuid using previous CCAPI implementation: */
+ replyEvent = tspdata_getReplyEvent(tsp);
+ uuid = tspdata_getUUID(tsp);
+
+ cci_debug_printf("%s is listening ...", __FUNCTION__);
+
+ // Clear replyEvent so we can detect when a reply to our connect request has been received:
+ ResetEvent(replyEvent);
+
+ // We use the old CCAPI implementation to try to talk to the server.
+ // It has all the code to make the uuid, (re)connect and (re)start the server.
+ WaitForSingleObject( hCCAPIv2Mutex, INFINITE );
+ SecureClient* s = 0;
+ SecureClient::Start(s);
+ CcAutoLock* a = 0;
+ CcAutoLock::Start(a, Client::sLock);
+
+ // Initialize old CCAPI if necessary:
+ if (!status) if (!Init:: Initialized()) status = Init:: Initialize( );
+ if (!status) if (!Client::Initialized()) status = Client::Initialize(0);
+
+ // New code using new RPC procedures for sending the data and receiving a reply:
+ if (!status) {
+ memcpy(tspdata_handle, &tsp, sizeof(tsp));
+ RpcTryExcept {
+ ccs_rpc_connect( /* make call with user message: */
+ CCMSG_CONNECT, /* Message type */
+ tspdata_handle, /* Our tspdata* will be sent back to the reply proc. */
+ (unsigned char*)uuid,
+ (long*)(&status) ); /* Return code */
+ }
+ RpcExcept(1) {
+ cci_check_error(RpcExceptionCode());
+ status = ccErrBadInternalMessage;
+ }
+ RpcEndExcept;
+ }
+
+ CcAutoLock::Stop(a);
+ SecureClient::Stop(s);
+ ReleaseMutex(hCCAPIv2Mutex);
+
+ if (!status) {
+#if 0
+ cci_debug_printf("%s Waiting for replyEvent.", __FUNCTION__);
+#endif
+ status = WaitForSingleObject(replyEvent, INFINITE);//(SECONDS_TO_WAIT)*1000);
+ status = cci_check_error(RpcMgmtIsServerListening(CLIENT_REQUEST_RPC_HANDLE));
+ cci_debug_printf(" Server %sFOUND!", (status) ? "NOT " : "");
+ }
+ if (status) {
+ cci_debug_printf(" unexpected error while looking for server... (%u)", status);
+ }
+
+ return status;
+ }
diff --git a/src/ccapi/lib/win/ccs_reply_proc.c b/src/ccapi/lib/win/ccs_reply_proc.c
new file mode 100644
index 000000000000..bf8c7f4f4158
--- /dev/null
+++ b/src/ccapi/lib/win/ccs_reply_proc.c
@@ -0,0 +1,95 @@
+/* ccapi/lib/win/ccs_reply_proc.c */
+/*
+ * Copyright 2008 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 <stdio.h>
+#include <stdlib.h>
+#include <windows.h>
+
+#include "cci_debugging.h"
+#include "ccs_reply.h" /* generated by MIDL compiler */
+#include "ccutils.h"
+#include "tls.h"
+#include "win-utils.h"
+
+
+void ccs_rpc_request_reply(
+ const long rpcmsg, /* Message type */
+ const char tspHandle[], /* Client's tspdata* */
+ const char* uuid, /* uuid for making thread-specific event name */
+ const long srvStartTime, /* Server Start Time */
+ const long cbIn, /* Length of buffer */
+ const char* chIn, /* Data buffer */
+ long* ret_status ) { /* Return code */
+
+ HANDLE hEvent = openThreadEvent(uuid, REPLY_SUFFIX);
+ struct tspdata* tsp;
+ k5_ipc_stream stream;
+ long status = 0;
+#if 0
+ cci_debug_printf("%s! msg#:%d SST:%ld uuid:%s", __FUNCTION__, rpcmsg, srvStartTime, uuid);
+#endif
+ memcpy(&tsp, tspHandle, sizeof(tsp));
+ if (!status) {
+ status = krb5int_ipc_stream_new (&stream); /* Create a stream for the request data */
+ }
+
+ if (!status) { /* Put the data into the stream */
+ status = krb5int_ipc_stream_write (stream, chIn, cbIn);
+ }
+
+ if (!status) { /* Put the data into the stream */
+ tspdata_setStream(tsp, stream);
+ }
+
+ SetEvent(hEvent);
+ CloseHandle(hEvent);
+ *ret_status = status;
+ }
+
+void ccs_rpc_connect_reply(
+ const long rpcmsg, /* Message type */
+ const char tspHandle[], /* Client's tspdata* */
+ const char* uuid, /* uuid for making thread-specific event name */
+ const long srvStartTime, /* Server Start Time */
+ long* status ) { /* Return code */
+
+ HANDLE hEvent = openThreadEvent(uuid, REPLY_SUFFIX);
+ DWORD* p = (DWORD*)(tspHandle);
+#if 0
+ cci_debug_printf("%s! msg#:%d SST:%ld uuid:%s", __FUNCTION__, rpcmsg, srvStartTime, uuid);
+#endif
+ SetEvent(hEvent);
+ CloseHandle(hEvent);
+ }
+
+void ccapi_listen(
+ RPC_ASYNC_STATE* rpcState,
+ handle_t hBinding,
+ const long rpcmsg, /* Message type */
+ long* status ) { /* Return code */
+
+ cci_debug_printf("%s %s!", __FUNCTION__, rpcState->UserInfo);
+ *status = 0;
+ }
diff --git a/src/ccapi/lib/win/debug.exports b/src/ccapi/lib/win/debug.exports
new file mode 100644
index 000000000000..6dc1fc083a2a
--- /dev/null
+++ b/src/ccapi/lib/win/debug.exports
@@ -0,0 +1,11 @@
+ cci_debug_printf
+ _cci_check_error
+ cci_os_ipc
+ cci_os_ipc_msg
+ cci_os_ipc_thread_init
+ krb5int_ipc_stream_data
+ krb5int_ipc_stream_write
+ krb5int_ipc_stream_new
+
+ ccs_authenticate
+ cci_os_ipc_process_init
diff --git a/src/ccapi/lib/win/dllmain.cxx b/src/ccapi/lib/win/dllmain.cxx
new file mode 100644
index 000000000000..82cacad9c87c
--- /dev/null
+++ b/src/ccapi/lib/win/dllmain.cxx
@@ -0,0 +1,222 @@
+/*
+ * $Header$
+ *
+ * Copyright 2008 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.
+ */
+
+extern "C" {
+#include <windows.h>
+#include <LMCons.h>
+
+#include "dllmain.h"
+#include "tls.h"
+#include "cci_debugging.h"
+#include "ccapi_context.h"
+#include "ccapi_ipc.h"
+#include "client.h"
+
+void cci_process_init__auxinit();
+ }
+
+
+#define CCAPI_V2_MUTEX_NAME TEXT("MIT_CCAPI_V4_MUTEX")
+
+// Process-specific data:
+static DWORD dwTlsIndex;
+static char _user[UNLEN+1]; // Username is used as part of the server and client endpoints.
+static HANDLE sessionToken;
+static char* ep_prefices[] = {"CCS", "CCAPI"};
+HANDLE hCCAPIv2Mutex = NULL;
+DWORD firstThreadID = 0;
+
+// These data structures are used by the old CCAPI implementation
+// to keep track of the state of the RPC connection. All data is static.
+static Init init;
+static Client client;
+
+DWORD GetTlsIndex() {return dwTlsIndex;}
+
+// DllMain() is the entry-point function for this DLL.
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, // DLL module handle
+ DWORD fdwReason, // reason called
+ LPVOID lpvReserved) { // reserved
+
+ struct tspdata* ptspdata;
+ BOOL fIgnore;
+ BOOL bStatus;
+ DWORD status = 0; // 0 is success.
+ DWORD maxUN = sizeof(_user);
+ unsigned int i = 0;
+ unsigned int j = 0;
+
+ switch (fdwReason) {
+ // The DLL is loading due to process initialization or a call to LoadLibrary:
+ case DLL_PROCESS_ATTACH:
+ cci_debug_printf("%s DLL_PROCESS_ATTACH", __FUNCTION__);
+ // Process-wide mutex used to allow only one thread at a time into the RPC code:
+ hCCAPIv2Mutex = CreateMutex(NULL, FALSE, CCAPI_V2_MUTEX_NAME);
+
+ // Figure out our username; it's process-wide:
+ bStatus = GetUserName(_user, &maxUN);
+ if (!bStatus) return bStatus;
+
+ // Remove any characters that aren't valid endpoint characters:
+ while (_user[j] != 0) {
+ if (isalnum(_user[j])) _user[i++] = _user[j];
+ j++;
+ }
+ _user[i] = '\0';
+
+ // Our logon session is determined in client.cxx, old CCAPI code carried
+ // over to this implementation.
+
+ // Allocate a TLS index:
+ if ((dwTlsIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES) return FALSE;
+
+ cci_process_init__auxinit();
+ // Don't break; fallthrough: Initialize the TLS index for first thread.
+
+ // The attached process creates a new thread:
+ case DLL_THREAD_ATTACH:
+ cci_debug_printf("%s DLL_THREAD_ATTACH", __FUNCTION__);
+ // Don't actually rely on this case for allocation of resources.
+ // Applications (like SecureCRT) may have threads already
+ // created (say 'A' and 'B') before the dll is loaded. If the dll
+ // is loaded in thread 'A' but then used in thread 'B', thread 'B'
+ // will never execute this code.
+ fIgnore = TlsSetValue(dwTlsIndex, NULL);
+
+ // Do not call cci_ipc_thread_init() yet; defer until we actually
+ // need it. On XP, cci_ipc_thread_init() will cause additional
+ // threads to be immediately spawned, which will bring us right
+ // back here again ad infinitum, until windows
+ // resources are exhausted.
+ break;
+
+ // The thread of the attached process terminates:
+ case DLL_THREAD_DETACH:
+ cci_debug_printf("%s DLL_THREAD_DETACH", __FUNCTION__);
+ // Release the allocated memory for this thread
+ ptspdata = (struct tspdata*)TlsGetValue(dwTlsIndex);
+ if (ptspdata != NULL) {
+ free(ptspdata);
+ TlsSetValue(dwTlsIndex, NULL);
+ }
+ break;
+
+ // DLL unload due to process termination or FreeLibrary:
+ case DLL_PROCESS_DETACH:
+ cci_debug_printf("%s DLL_PROCESS_DETACH", __FUNCTION__);
+ //++ Copied from previous implementation:
+ // Process Teardown "Problem"
+ //
+ // There are two problems that occur during process teardown:
+ //
+ // 1) Windows (NT/9x/2000) does not keep track of load/unload
+ // ordering dependencies for use in process teardown.
+ //
+ // 2) The RPC exception handling in the RPC calls do not work
+ // during process shutdown in Win9x.
+ //
+ // When a process is being torn down in Windows, the krbcc DLL
+ // may get a DLL_PROCESS_DETACH before other DLLs are done
+ // with it. Thus, it may disconnect from the RPC server
+ // before the last shutdown RPC call.
+ //
+ // On NT/2000, this is ok because the RPC call will fail and just
+ // return an error.
+ //
+ // On Win9x/Me, the RPC exception will not be caught.
+ // However, Win9x ignores exceptions during process shutdown,
+ // so the exception will never be seen unless a debugger is
+ // attached to the proccess.
+ //
+ // A good potential woraround would be to have a global
+ // variable that denotes whether the DLL is attached to the
+ // process. If it is not, all entrypoints into the DLL should
+ // return failure.
+ //
+ // A not as good workaround is below but ifdefed out.
+ //
+ // However, we can safely ignore this problem since it can
+ // only affects people running debuggers under 9x/Me who are
+ // using multiple DLLs that use this DLL.
+ //
+ WaitForSingleObject( hCCAPIv2Mutex, INFINITE );
+#if 0
+ bool process_teardown_workaround = false;
+ if (lpvReserved) {
+ Init::InitInfo info;
+ status = Init::Info(info);
+ if (status) break;
+ if (!info.isNT) process_teardown_workaround = true;
+ }
+ if (process_teardown_workaround)
+ break;
+#endif
+ // return value is ignored, so we set status for debugging purposes
+ status = Client::Cleanup();
+ status = Init::Cleanup();
+ ReleaseMutex( hCCAPIv2Mutex );
+ CloseHandle( hCCAPIv2Mutex );
+ //-- Copied from previous implementation.
+
+ // Release the allocated memory for this thread:
+ ptspdata = (struct tspdata*)TlsGetValue(dwTlsIndex);
+ if (ptspdata != NULL)
+ free(ptspdata);
+ TlsFree(dwTlsIndex); // Release the TLS index.
+ // Ideally, we would enumerate all other threads here and
+ // release their thread local storage as well.
+ break;
+
+ default:
+ cci_debug_printf("%s unexpected reason %d", __FUNCTION__, fdwReason);
+ break;
+ }
+
+ UNREFERENCED_PARAMETER(hinstDLL); // no whining!
+ UNREFERENCED_PARAMETER(lpvReserved);
+ return status ? FALSE : TRUE;
+}
+
+
+#ifdef __cplusplus // If used by C++ code,
+extern "C" { // we need to export the C interface
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/*********************************************************************/
+/* MIDL allocate and free */
+/*********************************************************************/
+
+extern "C" void __RPC_FAR * __RPC_USER MIDL_user_allocate(size_t len) {
+ return(malloc(len));
+ }
+
+extern "C" void __RPC_USER MIDL_user_free(void __RPC_FAR * ptr) {
+ free(ptr);
+ }
diff --git a/src/ccapi/lib/win/dllmain.h b/src/ccapi/lib/win/dllmain.h
new file mode 100644
index 000000000000..8238566e4c8f
--- /dev/null
+++ b/src/ccapi/lib/win/dllmain.h
@@ -0,0 +1,41 @@
+/* ccapi/lib/win/dllmain.h */
+/*
+ * Copyright 2008 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 _dll_h
+#define _dll_h
+
+#include "windows.h"
+
+#ifdef __cplusplus // If used by C++ code,
+extern "C" { // we need to export the C interface
+#endif
+
+DWORD GetTlsIndex();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif _dll_h